source: EcnlProtoTool/trunk/asp3_dcre/tinet/net/ppp_fsm.c@ 270

Last change on this file since 270 was 270, checked in by coas-nagasima, 7 years ago

mruby版ECNLプロトタイピング・ツールを追加

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
  • Property svn:mime-type set to text/x-csrc
File size: 20.8 KB
Line 
1/*
2 * TINET (TCP/IP Protocol Stack)
3 *
4 * Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
5 * Tomakomai National College of Technology, JAPAN
6 *
7 * 上記著作権者
8は,以下の (1)~(4) の条件か,Free Software Foundation
9 * によってå…
10¬è¡¨ã•ã‚Œã¦ã„ã‚‹ GNU General Public License の Version 2 に記
11 * 述されている条件を満たす場合に限り,本ソフトウェア(本ソフトウェア
12 * を改変したものを含む.以下同じ)を使用・複製・改変・再é…
13å¸ƒï¼ˆä»¥ä¸‹ï¼Œ
14 * 利用と呼ぶ)することを無償で許諾する.
15 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
16 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
17 * スコード中に含まれていること.
18 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
19 * 用できる形で再é…
20å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œå†é…
21å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨
22 * 者
23マニュアルなど)に,上記の著作権表示,この利用条件および下記
24 * の無保証規定を掲載すること.
25 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
26 * 用できない形で再é…
27å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œæ¬¡ã®æ¡ä»¶ã‚’満たすこと.
28 * (a) 再é…
29å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨è€…
30マニュアルなど)に,上記の著
31 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
32 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
33 * 害からも,上記著作権者
34およびTOPPERSプロジェクトをå…
35è²¬ã™ã‚‹ã“と.
36 *
37 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者
38お
39 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,その適用可能性も
40 * 含めて,いかなる保証も行わない.また,本ソフトウェアの利用により直
41 * 接的または間接的に生じたいかなる損害に関しても,その責任を負わない.
42 *
43 * @(#) $Id: ppp_fsm.c 270 2017-02-09 04:03:47Z coas-nagasima $
44 */
45
46/*
47 * fsm->c - {Link, IP} Control Protocol Finite State Machine.
48 *
49 * Copyright (c) 1989 Carnegie Mellon University.
50 * All rights reserved.
51 *
52 * Redistribution and use in source and binary forms are permitted
53 * provided that the above copyright notice and this paragraph are
54 * duplicated in all such forms and that any documentation,
55 * advertising materials, and other materials related to such
56 * distribution and use acknowledge that the software was developed
57 * by Carnegie Mellon University. The name of the
58 * University may not be used to endorse or promote products derived
59 * from this software without specific prior written permission.
60 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
61 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
62 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
63 */
64
65/*
66 * PPP Finite State Machine for LCP/IPCP
67 *
68 * Written by Toshiharu OHNO (tony-o@iij.ad.jp)
69 *
70 * Copyright (C) 1993, Internet Initiative Japan, Inc. All rights reserverd.
71 *
72 * Redistribution and use in source and binary forms are permitted
73 * provided that the above copyright notice and this paragraph are
74 * duplicated in all such forms and that any documentation,
75 * advertising materials, and other materials related to such
76 * distribution and use acknowledge that the software was developed
77 * by the Internet Initiative Japan, Inc. The name of the
78 * IIJ may not be used to endorse or promote products derived
79 * from this software without specific prior written permission.
80 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
81 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
82 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
83 *
84 * $FreeBSD: src/usr.sbin/ppp/fsm->c,v 1.52.2.3 2000/08/19 09:30:03 brian Exp $
85 *
86 * TODO:
87 */
88
89#include <string.h>
90
91#include <s_services.h>
92#include <t_services.h>
93
94#include <tinet_defs.h>
95#include <tinet_config.h>
96
97#include <net/if.h>
98#include <net/if_ppp.h>
99#include <net/net.h>
100#include <net/net_timer.h>
101#include <net/net_buf.h>
102#include <net/net_count.h>
103#include <net/ppp.h>
104#include <net/ppp_var.h>
105#include <net/ppp_hdlc.h>
106#include <net/ppp_fsm.h>
107
108#include <netinet/in.h>
109
110#ifdef SUPPORT_PPP
111
112/*
113 * å…
114¨åŸŸå¤‰æ•°
115 */
116
117uint8_t ppp_open_mode = PPP_OPEN_PASSIVE; /* オープン時の動作モード */
118
119/*
120 * 関数
121 */
122
123static void fsm_sconfreq (T_PPP_FSM *fsm, int_t retansmit);
124static void fsm_rconfreq (T_PPP_FSM *fsm, uint8_t id, T_NET_BUF *input);
125static void fsm_rconfack (T_PPP_FSM *fsm, uint8_t id, T_NET_BUF *input);
126static void fsm_rconfnakrej (T_PPP_FSM *fsm, uint8_t code, uint8_t id, T_NET_BUF *input);
127static void fsm_rtermreq (T_PPP_FSM *fsm, uint8_t id, T_NET_BUF *input);
128static void fsm_rtermack (T_PPP_FSM *fsm, T_NET_BUF *input);
129static void fsm_rcoderej (T_PPP_FSM *fsm, T_NET_BUF *input);
130static void fsm_stermreq (T_PPP_FSM *fsm, uint8_t id);
131static void fsm_timeout (void *arg);
132
133/*
134 * fsm_sconfreq -- Configure-Request を送信する。
135 */
136
137static void
138fsm_sconfreq (T_PPP_FSM *fsm, int_t retransmit)
139{
140 T_NET_BUF *output;
141 uint16_t len;
142
143 if (!(fsm->state == PPP_FSM_REQSENT ||
144 fsm->state == PPP_FSM_ACKRCVD ||
145 fsm->state == PPP_FSM_ACKSENT)) {
146 /* まだネゴをしていない。オプションをリセットする。 */
147 if (fsm->callbacks->resetci)
148 (*fsm->callbacks->resetci)(fsm);
149 fsm->failures = 0;
150 }
151 if (retransmit == 0) {
152 /* 新しいリクエスト。再送カウンタをリセットし、新しい ID を設定する。 */
153 fsm->retrans = MAX_PPP_CONFIGURES;
154 fsm->reqid = ++ fsm->id;
155 }
156
157 fsm->seen_ack = 0;
158
159 if (fsm->callbacks->cilen && fsm->callbacks->addci) {
160 /* 構成情
161報パケットを作る。 */
162 len = (*fsm->callbacks->cilen)(fsm);
163
164 syscall(get_net_buf(&output, len + sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR)));
165 (*fsm->callbacks->addci)(fsm, output);
166
167 /* 構成情
168報パケットを送信する。 */
169 IF_SET_PROTO(output, fsm->proto);
170 ppp_cp_output(PPP_CONFREQ, fsm->reqid, output);
171
172 -- fsm->retrans;
173 timeout((FP)fsm_timeout, fsm, DEF_PPP_TIMEOUT);
174 }
175 }
176
177/*
178 * fsm_rconfreq -- Configure-Request を受信したときの処理
179 */
180
181static void
182fsm_rconfreq (T_PPP_FSM *fsm, uint8_t id, T_NET_BUF *input)
183{
184 T_NET_BUF *output;
185 uint16_t code;
186
187 switch (fsm->state) {
188 case PPP_FSM_CLOSED:
189 syscall(get_net_buf(&output, sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR)));
190 memcpy(output->buf, input->buf, sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR));
191 ppp_cp_output(PPP_TERMACK, id, output);
192 return;
193 break;
194
195 case PPP_FSM_CLOSING:
196 case PPP_FSM_STOPPING:
197 return;
198 break;
199
200 case PPP_FSM_OPENED:
201 /* 上位層を停止して、ネゴに移る。 */
202 if (fsm->callbacks->down != NULL)
203 (*fsm->callbacks->down)(fsm);
204 fsm_sconfreq(fsm, 0); /* 最初の Configure-Request を送る。 */
205 break;
206
207 case PPP_FSM_STOPPED:
208 /* 相手からネゴが開始された */
209 fsm_sconfreq(fsm, 0); /* 最初の Configure-Request を送る。 */
210 fsm->state = PPP_FSM_REQSENT;
211 break;
212
213 }
214
215 syscall(get_net_buf(&output, input->len));
216
217 /* 上位プロトコルに要求された Configure-Request を送る。 */
218 if (fsm->callbacks->reqci != NULL) /* 構成情
219報をチェックする。 */
220 code = (*fsm->callbacks->reqci)(fsm, input, output);
221 else if (output->len > sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR))
222 code = PPP_CONFREJ;
223 else
224 code = PPP_CONFACK;
225
226 /* 相手に ACK, NAK または REJ を送信する。 */
227 ppp_cp_output(code, id, output);
228
229 if (code == PPP_CONFACK) {
230 if (fsm->state == PPP_FSM_ACKRCVD) {
231 untimeout((FP)fsm_timeout, fsm);
232 fsm->state = PPP_FSM_OPENED;
233 if (fsm->callbacks->up != NULL)
234 (*fsm->callbacks->up)(fsm);
235 }
236 else
237 fsm->state = PPP_FSM_ACKSENT;
238 fsm->failures = 0;
239 }
240 else {
241 /* ACK か REJ を送る */
242 if (fsm->state != PPP_FSM_ACKRCVD)
243 fsm->state = PPP_FSM_REQSENT;
244 if (code == PPP_CONFNAK)
245 fsm->failures ++;
246 }
247 }
248
249/*
250 * fsm_rconfnakrej -- Configure-NAK/REJ を受信したときの処理
251 */
252
253static void
254fsm_rconfnakrej (T_PPP_FSM *fsm, uint8_t code, uint8_t id, T_NET_BUF *input)
255{
256 int_t ret = 0;
257 T_NET_BUF *output;
258
259 /* 予期した ID でないか、NAK/REJ を予期していないときは終了する。*/
260 if (id != fsm->reqid || fsm->seen_ack) {
261 syslog(LOG_WARNING, "[PPP/FSM] bad ID or unexp NAK/REJ.");
262 return;
263 }
264
265 if (code == PPP_CONFNAK) {
266 if (fsm->callbacks->nakci != NULL && (ret = (*fsm->callbacks->nakci)(fsm, input)) == 0) {
267 syslog(LOG_WARNING, "[PPP/FSM] bad NAK.");
268 return;
269 }
270 }
271 else {
272 if (fsm->callbacks->rejci != NULL && (ret = (*fsm->callbacks->rejci)(fsm, input)) == 0) {
273 syslog(LOG_WARNING, "[PPP/FSM] bad REJ.");
274 return;
275 }
276 }
277
278 fsm->seen_ack = 1;
279
280 switch (fsm->state) {
281 case PPP_FSM_CLOSED:
282 case PPP_FSM_STOPPED:
283 syscall(get_net_buf(&output, sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR)));
284 memcpy(output->buf, input->buf, sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR));
285 ppp_cp_output(PPP_TERMACK, id, output);
286 return;
287 break;
288
289 case PPP_FSM_REQSENT:
290 case PPP_FSM_ACKSENT:
291 untimeout((FP)fsm_timeout, fsm);
292 if (ret < 0) /* 送信した Conf-Req が破損し空の NAK/REJ が届いた。*/
293 fsm->state = PPP_FSM_STOPPED;
294 else
295 fsm_sconfreq(fsm, 0);
296 break;
297
298 case PPP_FSM_ACKRCVD:
299 untimeout((FP)fsm_timeout, fsm);
300 fsm_sconfreq(fsm, 0);
301 fsm->state = PPP_FSM_REQSENT;
302 break;
303
304 case PPP_FSM_OPENED:
305 /* 再起動し、ネゴをやり直す。*/
306 if (fsm->callbacks->down != NULL)
307 (*fsm->callbacks->down)(fsm);
308 fsm_sconfreq(fsm, 0);
309 fsm->state = PPP_FSM_REQSENT;
310 break;
311 }
312 }
313
314/*
315 * fsm_rconfack -- Configure-ACK を受信したときの処理
316 */
317
318static void
319fsm_rconfack (T_PPP_FSM *fsm, uint8_t id, T_NET_BUF *input)
320{
321 T_NET_BUF *output;
322
323 /* 予期した ID でないか、ACK を予期していないときは終了する。*/
324 if (id != fsm->reqid || fsm->seen_ack) {
325 syslog(LOG_WARNING, "[PPP/FSM] bad ID or unexp ACK.");
326 return;
327 }
328
329 if (fsm->callbacks->ackci != NULL) {
330 if ((*fsm->callbacks->ackci)(fsm, input) != true) {
331 syslog(LOG_WARNING, "[PPP/FSM] bad ACK.");
332 return;
333 }
334 }
335 else if (input->len - (sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR)) != 0) {
336 syslog(LOG_WARNING, "[PPP/FSM] bad ACK.");
337 return;
338 }
339
340 fsm->seen_ack = 1;
341
342 switch (fsm->state) {
343 case PPP_FSM_CLOSED:
344 case PPP_FSM_STOPPED:
345 syscall(get_net_buf(&output, sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR)));
346 memcpy(output->buf, input->buf, sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR));
347 ppp_cp_output(PPP_TERMACK, id, output);
348 break;
349
350 case PPP_FSM_REQSENT:
351 fsm->state = PPP_FSM_ACKRCVD;
352 fsm->retrans = MAX_PPP_CONFIGURES;
353 break;
354
355 case PPP_FSM_ACKRCVD:
356 untimeout((FP)fsm_timeout, fsm);
357 fsm_sconfreq(fsm, 0);
358 fsm->state = PPP_FSM_REQSENT;
359 break;
360
361 case PPP_FSM_ACKSENT:
362 untimeout((FP)fsm_timeout, fsm);
363 fsm->state = PPP_FSM_OPENED;
364 fsm->retrans = MAX_PPP_CONFIGURES;
365 if (fsm->callbacks->up != NULL)
366 (*fsm->callbacks->up)(fsm);
367 break;
368
369 case PPP_FSM_OPENED:
370 /* 再起動し、ネゴをやり直す。*/
371 if (fsm->callbacks->down != NULL)
372 (*fsm->callbacks->down)(fsm);
373 fsm_sconfreq(fsm, 0);
374 fsm->state = PPP_FSM_REQSENT;
375 break;
376
377 default :
378 syslog(LOG_WARNING, "[PPP/FSM] unexp state: %d in recv Conf-ACK.", fsm->state);
379 break;
380 }
381
382 }
383
384/*
385 * fsm_rtermreq -- Terminate-Request を受信したときの処理
386 */
387
388static void
389fsm_rtermreq (T_PPP_FSM *fsm, uint8_t id, T_NET_BUF *input)
390{
391 T_NET_BUF *output;
392
393 switch (fsm->state) {
394 case PPP_FSM_ACKRCVD:
395 case PPP_FSM_ACKSENT:
396 fsm->state = PPP_FSM_REQSENT;
397 break;
398
399 case PPP_FSM_OPENED:
400 if (fsm->callbacks->down != NULL)
401 (*fsm->callbacks->down)(fsm);
402 fsm->retrans = 0;
403 fsm->state = PPP_FSM_STOPPING;
404 timeout((FP)fsm_timeout, fsm, DEF_PPP_TIMEOUT);
405 break;
406 }
407 syscall(get_net_buf(&output, sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR)));
408 memcpy(output->buf, input->buf, sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR));
409 ppp_cp_output(PPP_TERMACK, id, output);
410 }
411
412/*
413 * fsm_rtermack -- Terminate-ACK を受信したときの処理
414 */
415
416static void
417fsm_rtermack (T_PPP_FSM *fsm, T_NET_BUF *input)
418{
419 switch (fsm->state) {
420 case PPP_FSM_CLOSING:
421 untimeout((FP)fsm_timeout, fsm);
422#if 0 /* 本来の動作は CLOSED に遷移する。*/
423 fsm->state = PPP_FSM_CLOSED;
424#else /* of #if 0 */
425 fsm->state = PPP_FSM_STOPPED;
426#endif /* of #if 0 */
427 if (fsm->callbacks->finished != NULL)
428 (*fsm->callbacks->finished)(fsm);
429 break;
430
431 case PPP_FSM_STOPPING:
432 untimeout((FP)fsm_timeout, fsm);
433 fsm->state = PPP_FSM_STOPPED;
434 if (fsm->callbacks->finished != NULL)
435 (*fsm->callbacks->finished)(fsm);
436 break;
437
438 case PPP_FSM_ACKRCVD:
439 fsm->state = PPP_FSM_REQSENT;
440 break;
441
442 case PPP_FSM_OPENED:
443 if (fsm->callbacks->down != NULL)
444 (*fsm->callbacks->down)(fsm);
445 fsm_sconfreq(fsm, 0);
446 break;
447 }
448 }
449
450/*
451 * fsm_rcoderej -- Code-REJ を受信したときの処理
452 */
453
454static void
455fsm_rcoderej (T_PPP_FSM *fsm, T_NET_BUF *input)
456{
457 T_PPP_CP_HDR *hdr;
458
459 /* PPP リンク制御 (CP) ヘッダより短ければエラー */
460 if (input->len < sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR)) {
461 syslog(LOG_WARNING, "[PPP/FSM] bad len: %d in recv Code-REJ.", input->len);
462 return;
463 }
464
465 hdr = GET_PPP_CP_HDR(input);
466
467 syslog(LOG_WARNING, "[PPP/FSM] recv Code-REJ, code=%d, id=%d.", hdr->code, hdr->id);
468
469 if (fsm->state == PPP_FSM_ACKRCVD)
470 fsm->state = PPP_FSM_REQSENT;
471 }
472
473/*
474 * fsm_timeout -- タイムアウト処理
475 */
476
477static void
478fsm_timeout (void *arg)
479{
480 T_PPP_FSM *fsm = (T_PPP_FSM*)arg;
481
482 switch (fsm->state) {
483 case PPP_FSM_CLOSING:
484 case PPP_FSM_STOPPING:
485 if (fsm->retrans <= 0) {
486 /* 最大再送回数を超
487えたときの処理 */
488#if 0 /* 本来の動作は CLOSED に遷移する。*/
489 fsm->state = (fsm->state == PPP_FSM_CLOSING) ? PPP_FSM_CLOSED : PPP_FSM_STOPPED;
490#else /* of #if 0 */
491 fsm->state = PPP_FSM_STOPPED;
492#endif /* of #if 0 */
493 if (fsm->callbacks->finished != NULL)
494 (*fsm->callbacks->finished)(fsm);
495 }
496 else {
497 /* Terminate-Request を送信する。*/
498 fsm_stermreq(fsm, ++ fsm->id);
499 }
500 break;
501 case PPP_FSM_REQSENT:
502 case PPP_FSM_ACKRCVD:
503 case PPP_FSM_ACKSENT:
504 if (fsm->retrans <= 0) {
505 /* 最大再送回数を超
506えたときの処理 */
507 syslog(LOG_WARNING, "[PPP/FSM] retrans Conf-Req.");
508 fsm->state = PPP_FSM_STOPPED;
509 if (ppp_open_mode != PPP_OPEN_PASSIVE && fsm->callbacks->finished)
510 (*fsm->callbacks->finished)(fsm);
511 }
512 else {
513 /* Configure-Request を再送する。*/
514 if (fsm->callbacks->retrans != NULL)
515 (*fsm->callbacks->retrans)(fsm);
516 fsm_sconfreq(fsm, 1);
517 if (fsm->state == PPP_FSM_ACKRCVD)
518 fsm->state = PPP_FSM_REQSENT;
519 }
520
521 break;
522
523 default :
524 syslog(LOG_WARNING, "[PPP/FSM] unexp state: %d in timeout.", fsm->state);
525 break;
526 }
527 }
528
529/*
530 * fsm_stermreq -- Terminate-Request を送信する。
531 */
532
533static void
534fsm_stermreq (T_PPP_FSM *fsm, uint8_t id)
535{
536 T_NET_BUF *input;
537
538 syscall(get_net_buf(&input, sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR)));
539 IF_SET_PROTO(input, fsm->proto);
540 ppp_cp_output(PPP_TERMREQ, id, input);
541
542 timeout((FP)fsm_timeout, fsm, DEF_PPP_TIMEOUT);
543 fsm->retrans --;
544 }
545
546/*
547 * fsm_init -- FSM モジュールの初期化
548 */
549
550void
551fsm_init (T_PPP_FSM *fsm)
552{
553 fsm->state = PPP_FSM_INITIAL;
554 fsm->id = 0;
555 }
556
557/*
558 * fsm_lowerup -- FSM 下位層を起動する。
559 */
560
561void
562fsm_lowerup (T_PPP_FSM *fsm)
563{
564 switch (fsm->state) {
565 case PPP_FSM_INITIAL:
566 fsm->state = PPP_FSM_CLOSED;
567 break;
568
569 case PPP_FSM_STARTING:
570 if (ppp_open_mode == PPP_OPEN_PASSIVE)
571 fsm->state = PPP_FSM_STOPPED;
572 else {
573 fsm_sconfreq(fsm, 0);
574 fsm->state = PPP_FSM_REQSENT;
575 }
576 break;
577
578 default :
579 syslog(LOG_WARNING, "[PPP/FSM] unexp state: %d in lowerup", fsm->state);
580 break;
581 }
582 }
583
584/*
585 * fsm_lowerdown -- FSM 下位層を停止する。
586 */
587
588void
589fsm_lowerdown (T_PPP_FSM *fsm)
590{
591 switch (fsm->state) {
592 case PPP_FSM_CLOSED:
593 fsm->state = PPP_FSM_INITIAL;
594 break;
595
596 case PPP_FSM_STOPPED:
597 fsm->state = PPP_FSM_STARTING;
598 if (fsm->callbacks->starting != NULL)
599 (*fsm->callbacks->starting)(fsm);
600 break;
601
602 case PPP_FSM_CLOSING:
603 fsm->state = PPP_FSM_INITIAL;
604 untimeout((FP)fsm_timeout, fsm);
605 break;
606
607 case PPP_FSM_STOPPING:
608 case PPP_FSM_REQSENT:
609 case PPP_FSM_ACKRCVD:
610 case PPP_FSM_ACKSENT:
611 fsm->state = PPP_FSM_STARTING;
612 untimeout((FP)fsm_timeout, fsm);
613 break;
614
615 case PPP_FSM_OPENED:
616 if (fsm->callbacks->down != NULL)
617 (*fsm->callbacks->down)(fsm);
618 fsm->state = PPP_FSM_STARTING;
619 break;
620
621 default :
622 syslog(LOG_WARNING, "[PPP/FSM] unexp state: %d in lowerdown", fsm->state);
623 break;
624 }
625 }
626
627/*
628 * fsm_open -- FSM のオープン
629 */
630
631void
632fsm_open (T_PPP_FSM *fsm)
633{
634 switch (fsm->state) {
635 case PPP_FSM_INITIAL:
636 fsm->state = PPP_FSM_STARTING;
637 if (fsm->callbacks->starting != NULL)
638 (*fsm->callbacks->starting)(fsm);
639 break;
640
641 case PPP_FSM_CLOSED:
642 if (ppp_open_mode == PPP_OPEN_PASSIVE)
643 fsm->state = PPP_FSM_STOPPED;
644 else {
645 fsm_sconfreq(fsm, 0);
646 fsm->state = PPP_FSM_REQSENT;
647 }
648 break;
649
650 case PPP_FSM_CLOSING:
651 fsm->state = PPP_FSM_STOPPING;
652 /* nobreak; 下に落ちる */
653
654 case PPP_FSM_STOPPED:
655 case PPP_FSM_OPENED:
656 fsm_lowerdown(fsm);
657 fsm_lowerup(fsm);
658 break;
659 }
660 }
661
662/*
663 * fsm_close -- リンクの切断を開始する。
664 */
665
666void
667fsm_close (T_PPP_FSM *fsm)
668{
669 switch (fsm->state) {
670 case PPP_FSM_STARTING:
671 fsm->state = PPP_FSM_INITIAL;
672 break;
673
674#if 0 /* 本来の動作は CLOSED に遷移する。*/
675 case PPP_FSM_STOPPED:
676 fsm->state = PPP_FSM_CLOSED;
677 break;
678#endif /* of #if 0 */
679
680 case PPP_FSM_STOPPING:
681 fsm->state = PPP_FSM_CLOSING;
682 break;
683
684 case PPP_FSM_REQSENT:
685 case PPP_FSM_ACKRCVD:
686 case PPP_FSM_ACKSENT:
687 case PPP_FSM_OPENED:
688 if (fsm->state != PPP_FSM_OPENED)
689 untimeout((FP)fsm_timeout, fsm);
690 else if (fsm->callbacks->down != NULL)
691 (*fsm->callbacks->down)(fsm);
692
693 /* タイムアウトを設定し、Terminate-Request を送信する。*/
694 fsm->retrans = MAX_PPP_TERMINATES;
695 fsm_stermreq(fsm, fsm->reqid = ++ fsm->id);
696 fsm->state = PPP_FSM_CLOSING;
697 break;
698 }
699 }
700
701/*
702 * fsm_input -- å…
703¥åŠ›ã€PPP リンク制御 (CP) の制御コードにより適当な関数を呼出す
704 */
705
706void
707fsm_input (T_PPP_FSM *fsm, T_NET_BUF *input)
708{
709 T_PPP_CP_HDR *hdr;
710 T_NET_BUF *output;
711
712 /* PPP リンク制御 (CP) ヘッダより短ければエラー */
713 if (input->len < (sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR))) {
714 syslog(LOG_WARNING, "[PPP/FSM] short hdr: %d.", input->len);
715 return;
716 }
717
718 hdr = GET_PPP_CP_HDR(input);
719
720 /* ヘッダの長さとå…
721¥åŠ›ãƒ‡ãƒ¼ã‚¿ã‚µã‚¤ã‚ºãŒä¸€è‡´ã—なければエラー */
722 if (hdr->len != input->len - sizeof(T_PPP_HDR)) {
723 syslog(LOG_WARNING, "[PPP/FSM] bad len: %d.", hdr->len);
724 return;
725 }
726
727 /* 状æ…
728‹ãŒ INITIAL か STARTING ならエラー */
729 if (fsm->state == PPP_FSM_INITIAL || fsm->state == PPP_FSM_STARTING) {
730 syslog(LOG_WARNING, "[PPP/FSM] unexp state: %d in input.", fsm->state);
731 return;
732 }
733
734 /*
735 * 制御コードにより適当な関数を呼出す
736 */
737
738 switch (hdr->code) {
739 case PPP_CONFREQ:
740 fsm_rconfreq(fsm, hdr->id, input);
741 break;
742
743 case PPP_CONFACK:
744 fsm_rconfack(fsm, hdr->id, input);
745 break;
746
747 case PPP_CONFNAK:
748 case PPP_CONFREJ:
749 fsm_rconfnakrej(fsm, hdr->code, hdr->id, input);
750 break;
751
752 case PPP_TERMREQ:
753 fsm_rtermreq(fsm, hdr->id, input);
754 break;
755
756 case PPP_TERMACK:
757 fsm_rtermack(fsm, input);
758 break;
759
760 case PPP_CODEREJ:
761 fsm_rcoderej(fsm, input);
762 break;
763
764 default:
765 if (fsm->callbacks->extcode == NULL ||
766 (*fsm->callbacks->extcode)(fsm, hdr->code, hdr->id, input) != true) {
767 syscall(get_net_buf(&output, sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR)));
768 memcpy(output->buf, input->buf, sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR));
769 ppp_cp_output(PPP_CODEREJ, ++ fsm->id, output);
770 }
771 break;
772 }
773 }
774
775/*
776 * fsm_protoreject -- Proto-REJ を受信したときの処理
777 */
778
779void
780fsm_protreject (T_PPP_FSM *fsm)
781{
782 switch (fsm->state) {
783 case PPP_FSM_CLOSING:
784 untimeout((FP)fsm_timeout, fsm);
785
786#if 0 /* 本来の動作は CLOSED に遷移する。*/
787 /* 下に落ちる */
788#else /* of #if 0 */
789 fsm->state = PPP_FSM_STOPPED;
790 if (fsm->callbacks->finished != NULL)
791 (*fsm->callbacks->finished)(fsm);
792 break;
793#endif /* of #if 0 */
794
795 case PPP_FSM_CLOSED:
796 fsm->state = PPP_FSM_CLOSED;
797 if (fsm->callbacks->finished != NULL)
798 (*fsm->callbacks->finished)(fsm);
799 break;
800
801 case PPP_FSM_STOPPING:
802 case PPP_FSM_REQSENT:
803 case PPP_FSM_ACKRCVD:
804 case PPP_FSM_ACKSENT:
805 untimeout((FP)fsm_timeout, fsm);
806 /* 下に落ちる */
807
808 case PPP_FSM_STOPPED:
809 fsm->state = PPP_FSM_STOPPED;
810 if (fsm->callbacks->finished != NULL)
811 (*fsm->callbacks->finished)(fsm);
812 break;
813
814 case PPP_FSM_OPENED:
815 if (fsm->callbacks->down != NULL)
816 (*fsm->callbacks->down)(fsm);
817
818 /* タイムアウトを設定し、Terminate-Request を送信する。*/
819 fsm->retrans = MAX_PPP_TERMINATES;
820 fsm_stermreq(fsm, fsm->reqid = ++ fsm->id);
821 fsm->state = PPP_FSM_STOPPING;
822 break;
823
824 }
825 }
826
827#endif /* fo #ifdef SUPPORT_PPP */
Note: See TracBrowser for help on using the repository browser.