source: azure_iot_hub/trunk/asp3_dcre/tinet/net/ppp_fsm.c@ 388

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

Azure IoT Hub Device C SDK を使ったサンプルの追加

  • 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-2017 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 388 2019-05-22 11:25:18Z 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_endian.h>
101#include <net/net_timer.h>
102#include <net/net_buf.h>
103#include <net/net_count.h>
104#include <net/ppp.h>
105#include <net/ppp_var.h>
106#include <net/ppp_hdlc.h>
107#include <net/ppp_fsm.h>
108
109#include <netinet/in.h>
110
111#ifdef SUPPORT_PPP
112
113/*
114 * å…
115¨åŸŸå¤‰æ•°
116 */
117
118uint8_t ppp_open_mode = PPP_OPEN_PASSIVE; /* オープン時の動作モード */
119
120/*
121 * 関数
122 */
123
124static void fsm_sconfreq (T_PPP_FSM *fsm, int_t retansmit);
125static void fsm_rconfreq (T_PPP_FSM *fsm, uint8_t id, T_NET_BUF *input);
126static void fsm_rconfack (T_PPP_FSM *fsm, uint8_t id, T_NET_BUF *input);
127static void fsm_rconfnakrej (T_PPP_FSM *fsm, uint8_t code, uint8_t id, T_NET_BUF *input);
128static void fsm_rtermreq (T_PPP_FSM *fsm, uint8_t id, T_NET_BUF *input);
129static void fsm_rtermack (T_PPP_FSM *fsm, T_NET_BUF *input);
130static void fsm_rcoderej (T_PPP_FSM *fsm, T_NET_BUF *input);
131static void fsm_stermreq (T_PPP_FSM *fsm, uint8_t id);
132static void fsm_timeout (void *arg);
133
134/*
135 * fsm_sconfreq -- Configure-Request を送信する。
136 */
137
138static void
139fsm_sconfreq (T_PPP_FSM *fsm, int_t retransmit)
140{
141 T_NET_BUF *output;
142 uint16_t len;
143
144 if (!(fsm->state == PPP_FSM_REQSENT ||
145 fsm->state == PPP_FSM_ACKRCVD ||
146 fsm->state == PPP_FSM_ACKSENT)) {
147 /* まだネゴをしていない。オプションをリセットする。 */
148 if (fsm->callbacks->resetci)
149 (*fsm->callbacks->resetci)(fsm);
150 fsm->failures = 0;
151 }
152 if (retransmit == 0) {
153 /* 新しいリクエスト。再送カウンタをリセットし、新しい ID を設定する。 */
154 fsm->retrans = MAX_PPP_CONFIGURES;
155 fsm->reqid = ++ fsm->id;
156 }
157
158 fsm->seen_ack = 0;
159
160 if (fsm->callbacks->cilen && fsm->callbacks->addci) {
161 /* 構成情
162報パケットを作る。 */
163 len = (*fsm->callbacks->cilen)(fsm);
164
165 syscall(get_net_buf(&output, len + sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR)));
166 (*fsm->callbacks->addci)(fsm, output);
167
168 /* 構成情
169報パケットを送信する。 */
170 IF_SET_PROTO(output, fsm->proto);
171 ppp_cp_output(PPP_CONFREQ, fsm->reqid, output);
172
173 -- fsm->retrans;
174 timeout((FP)fsm_timeout, fsm, DEF_PPP_TIMEOUT);
175 }
176 }
177
178/*
179 * fsm_rconfreq -- Configure-Request を受信したときの処理
180 */
181
182static void
183fsm_rconfreq (T_PPP_FSM *fsm, uint8_t id, T_NET_BUF *input)
184{
185 T_NET_BUF *output;
186 uint16_t code;
187
188 switch (fsm->state) {
189 case PPP_FSM_CLOSED:
190 syscall(get_net_buf(&output, sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR)));
191 memcpy(output->buf, input->buf, sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR));
192 ppp_cp_output(PPP_TERMACK, id, output);
193 return;
194 break;
195
196 case PPP_FSM_CLOSING:
197 case PPP_FSM_STOPPING:
198 return;
199 break;
200
201 case PPP_FSM_OPENED:
202 /* 上位層を停止して、ネゴに移る。 */
203 if (fsm->callbacks->down != NULL)
204 (*fsm->callbacks->down)(fsm);
205 fsm_sconfreq(fsm, 0); /* 最初の Configure-Request を送る。 */
206 break;
207
208 case PPP_FSM_STOPPED:
209 /* 相手からネゴが開始された */
210 fsm_sconfreq(fsm, 0); /* 最初の Configure-Request を送る。 */
211 fsm->state = PPP_FSM_REQSENT;
212 break;
213
214 }
215
216 syscall(get_net_buf(&output, input->len));
217
218 /* 上位プロトコルに要求された Configure-Request を送る。 */
219 if (fsm->callbacks->reqci != NULL) /* 構成情
220報をチェックする。 */
221 code = (*fsm->callbacks->reqci)(fsm, input, output);
222 else if (output->len > sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR))
223 code = PPP_CONFREJ;
224 else
225 code = PPP_CONFACK;
226
227 /* 相手に ACK, NAK または REJ を送信する。 */
228 ppp_cp_output(code, id, output);
229
230 if (code == PPP_CONFACK) {
231 if (fsm->state == PPP_FSM_ACKRCVD) {
232 untimeout((FP)fsm_timeout, fsm);
233 fsm->state = PPP_FSM_OPENED;
234 if (fsm->callbacks->up != NULL)
235 (*fsm->callbacks->up)(fsm);
236 }
237 else
238 fsm->state = PPP_FSM_ACKSENT;
239 fsm->failures = 0;
240 }
241 else {
242 /* ACK か REJ を送る */
243 if (fsm->state != PPP_FSM_ACKRCVD)
244 fsm->state = PPP_FSM_REQSENT;
245 if (code == PPP_CONFNAK)
246 fsm->failures ++;
247 }
248 }
249
250/*
251 * fsm_rconfnakrej -- Configure-NAK/REJ を受信したときの処理
252 */
253
254static void
255fsm_rconfnakrej (T_PPP_FSM *fsm, uint8_t code, uint8_t id, T_NET_BUF *input)
256{
257 int_t ret = 0;
258 T_NET_BUF *output;
259
260 /* 予期した ID でないか、NAK/REJ を予期していないときは終了する。*/
261 if (id != fsm->reqid || fsm->seen_ack) {
262 syslog(LOG_WARNING, "[PPP/FSM] bad ID or unexp NAK/REJ.");
263 return;
264 }
265
266 if (code == PPP_CONFNAK) {
267 if (fsm->callbacks->nakci != NULL && (ret = (*fsm->callbacks->nakci)(fsm, input)) == 0) {
268 syslog(LOG_WARNING, "[PPP/FSM] bad NAK.");
269 return;
270 }
271 }
272 else {
273 if (fsm->callbacks->rejci != NULL && (ret = (*fsm->callbacks->rejci)(fsm, input)) == 0) {
274 syslog(LOG_WARNING, "[PPP/FSM] bad REJ.");
275 return;
276 }
277 }
278
279 fsm->seen_ack = 1;
280
281 switch (fsm->state) {
282 case PPP_FSM_CLOSED:
283 case PPP_FSM_STOPPED:
284 syscall(get_net_buf(&output, sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR)));
285 memcpy(output->buf, input->buf, sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR));
286 ppp_cp_output(PPP_TERMACK, id, output);
287 return;
288 break;
289
290 case PPP_FSM_REQSENT:
291 case PPP_FSM_ACKSENT:
292 untimeout((FP)fsm_timeout, fsm);
293 if (ret < 0) /* 送信した Conf-Req が破損し空の NAK/REJ が届いた。*/
294 fsm->state = PPP_FSM_STOPPED;
295 else
296 fsm_sconfreq(fsm, 0);
297 break;
298
299 case PPP_FSM_ACKRCVD:
300 untimeout((FP)fsm_timeout, fsm);
301 fsm_sconfreq(fsm, 0);
302 fsm->state = PPP_FSM_REQSENT;
303 break;
304
305 case PPP_FSM_OPENED:
306 /* 再起動し、ネゴをやり直す。*/
307 if (fsm->callbacks->down != NULL)
308 (*fsm->callbacks->down)(fsm);
309 fsm_sconfreq(fsm, 0);
310 fsm->state = PPP_FSM_REQSENT;
311 break;
312 }
313 }
314
315/*
316 * fsm_rconfack -- Configure-ACK を受信したときの処理
317 */
318
319static void
320fsm_rconfack (T_PPP_FSM *fsm, uint8_t id, T_NET_BUF *input)
321{
322 T_NET_BUF *output;
323
324 /* 予期した ID でないか、ACK を予期していないときは終了する。*/
325 if (id != fsm->reqid || fsm->seen_ack) {
326 syslog(LOG_WARNING, "[PPP/FSM] bad ID or unexp ACK.");
327 return;
328 }
329
330 if (fsm->callbacks->ackci != NULL) {
331 if ((*fsm->callbacks->ackci)(fsm, input) != true) {
332 syslog(LOG_WARNING, "[PPP/FSM] bad ACK.");
333 return;
334 }
335 }
336 else if (input->len - (sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR)) != 0) {
337 syslog(LOG_WARNING, "[PPP/FSM] bad ACK.");
338 return;
339 }
340
341 fsm->seen_ack = 1;
342
343 switch (fsm->state) {
344 case PPP_FSM_CLOSED:
345 case PPP_FSM_STOPPED:
346 syscall(get_net_buf(&output, sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR)));
347 memcpy(output->buf, input->buf, sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR));
348 ppp_cp_output(PPP_TERMACK, id, output);
349 break;
350
351 case PPP_FSM_REQSENT:
352 fsm->state = PPP_FSM_ACKRCVD;
353 fsm->retrans = MAX_PPP_CONFIGURES;
354 break;
355
356 case PPP_FSM_ACKRCVD:
357 untimeout((FP)fsm_timeout, fsm);
358 fsm_sconfreq(fsm, 0);
359 fsm->state = PPP_FSM_REQSENT;
360 break;
361
362 case PPP_FSM_ACKSENT:
363 untimeout((FP)fsm_timeout, fsm);
364 fsm->state = PPP_FSM_OPENED;
365 fsm->retrans = MAX_PPP_CONFIGURES;
366 if (fsm->callbacks->up != NULL)
367 (*fsm->callbacks->up)(fsm);
368 break;
369
370 case PPP_FSM_OPENED:
371 /* 再起動し、ネゴをやり直す。*/
372 if (fsm->callbacks->down != NULL)
373 (*fsm->callbacks->down)(fsm);
374 fsm_sconfreq(fsm, 0);
375 fsm->state = PPP_FSM_REQSENT;
376 break;
377
378 default :
379 syslog(LOG_WARNING, "[PPP/FSM] unexp state: %d in recv Conf-ACK.", fsm->state);
380 break;
381 }
382
383 }
384
385/*
386 * fsm_rtermreq -- Terminate-Request を受信したときの処理
387 */
388
389static void
390fsm_rtermreq (T_PPP_FSM *fsm, uint8_t id, T_NET_BUF *input)
391{
392 T_NET_BUF *output;
393
394 switch (fsm->state) {
395 case PPP_FSM_ACKRCVD:
396 case PPP_FSM_ACKSENT:
397 fsm->state = PPP_FSM_REQSENT;
398 break;
399
400 case PPP_FSM_OPENED:
401 if (fsm->callbacks->down != NULL)
402 (*fsm->callbacks->down)(fsm);
403 fsm->retrans = 0;
404 fsm->state = PPP_FSM_STOPPING;
405 timeout((FP)fsm_timeout, fsm, DEF_PPP_TIMEOUT);
406 break;
407 }
408 syscall(get_net_buf(&output, sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR)));
409 memcpy(output->buf, input->buf, sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR));
410 ppp_cp_output(PPP_TERMACK, id, output);
411 }
412
413/*
414 * fsm_rtermack -- Terminate-ACK を受信したときの処理
415 */
416
417static void
418fsm_rtermack (T_PPP_FSM *fsm, T_NET_BUF *input)
419{
420 switch (fsm->state) {
421 case PPP_FSM_CLOSING:
422 untimeout((FP)fsm_timeout, fsm);
423#if 0 /* 本来の動作は CLOSED に遷移する。*/
424 fsm->state = PPP_FSM_CLOSED;
425#else /* of #if 0 */
426 fsm->state = PPP_FSM_STOPPED;
427#endif /* of #if 0 */
428 if (fsm->callbacks->finished != NULL)
429 (*fsm->callbacks->finished)(fsm);
430 break;
431
432 case PPP_FSM_STOPPING:
433 untimeout((FP)fsm_timeout, fsm);
434 fsm->state = PPP_FSM_STOPPED;
435 if (fsm->callbacks->finished != NULL)
436 (*fsm->callbacks->finished)(fsm);
437 break;
438
439 case PPP_FSM_ACKRCVD:
440 fsm->state = PPP_FSM_REQSENT;
441 break;
442
443 case PPP_FSM_OPENED:
444 if (fsm->callbacks->down != NULL)
445 (*fsm->callbacks->down)(fsm);
446 fsm_sconfreq(fsm, 0);
447 break;
448 }
449 }
450
451/*
452 * fsm_rcoderej -- Code-REJ を受信したときの処理
453 */
454
455static void
456fsm_rcoderej (T_PPP_FSM *fsm, T_NET_BUF *input)
457{
458 T_PPP_CP_HDR *hdr;
459
460 /* PPP リンク制御 (CP) ヘッダより短ければエラー */
461 if (input->len < sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR)) {
462 syslog(LOG_WARNING, "[PPP/FSM] bad len: %d in recv Code-REJ.", input->len);
463 return;
464 }
465
466 hdr = GET_PPP_CP_HDR(input);
467
468 syslog(LOG_WARNING, "[PPP/FSM] recv Code-REJ, code=%d, id=%d.", hdr->code, hdr->id);
469
470 if (fsm->state == PPP_FSM_ACKRCVD)
471 fsm->state = PPP_FSM_REQSENT;
472 }
473
474/*
475 * fsm_timeout -- タイムアウト処理
476 */
477
478static void
479fsm_timeout (void *arg)
480{
481 T_PPP_FSM *fsm = (T_PPP_FSM*)arg;
482
483 switch (fsm->state) {
484 case PPP_FSM_CLOSING:
485 case PPP_FSM_STOPPING:
486 if (fsm->retrans <= 0) {
487 /* 最大再送回数を超
488えたときの処理 */
489#if 0 /* 本来の動作は CLOSED に遷移する。*/
490 fsm->state = (fsm->state == PPP_FSM_CLOSING) ? PPP_FSM_CLOSED : PPP_FSM_STOPPED;
491#else /* of #if 0 */
492 fsm->state = PPP_FSM_STOPPED;
493#endif /* of #if 0 */
494 if (fsm->callbacks->finished != NULL)
495 (*fsm->callbacks->finished)(fsm);
496 }
497 else {
498 /* Terminate-Request を送信する。*/
499 fsm_stermreq(fsm, ++ fsm->id);
500 }
501 break;
502 case PPP_FSM_REQSENT:
503 case PPP_FSM_ACKRCVD:
504 case PPP_FSM_ACKSENT:
505 if (fsm->retrans <= 0) {
506 /* 最大再送回数を超
507えたときの処理 */
508 syslog(LOG_WARNING, "[PPP/FSM] retrans Conf-Req.");
509 fsm->state = PPP_FSM_STOPPED;
510 if (ppp_open_mode != PPP_OPEN_PASSIVE && fsm->callbacks->finished)
511 (*fsm->callbacks->finished)(fsm);
512 }
513 else {
514 /* Configure-Request を再送する。*/
515 if (fsm->callbacks->retrans != NULL)
516 (*fsm->callbacks->retrans)(fsm);
517 fsm_sconfreq(fsm, 1);
518 if (fsm->state == PPP_FSM_ACKRCVD)
519 fsm->state = PPP_FSM_REQSENT;
520 }
521
522 break;
523
524 default :
525 syslog(LOG_WARNING, "[PPP/FSM] unexp state: %d in timeout.", fsm->state);
526 break;
527 }
528 }
529
530/*
531 * fsm_stermreq -- Terminate-Request を送信する。
532 */
533
534static void
535fsm_stermreq (T_PPP_FSM *fsm, uint8_t id)
536{
537 T_NET_BUF *input;
538
539 syscall(get_net_buf(&input, sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR)));
540 IF_SET_PROTO(input, fsm->proto);
541 ppp_cp_output(PPP_TERMREQ, id, input);
542
543 timeout((FP)fsm_timeout, fsm, DEF_PPP_TIMEOUT);
544 fsm->retrans --;
545 }
546
547/*
548 * fsm_init -- FSM モジュールの初期化
549 */
550
551void
552fsm_init (T_PPP_FSM *fsm)
553{
554 fsm->state = PPP_FSM_INITIAL;
555 fsm->id = 0;
556 }
557
558/*
559 * fsm_lowerup -- FSM 下位層を起動する。
560 */
561
562void
563fsm_lowerup (T_PPP_FSM *fsm)
564{
565 switch (fsm->state) {
566 case PPP_FSM_INITIAL:
567 fsm->state = PPP_FSM_CLOSED;
568 break;
569
570 case PPP_FSM_STARTING:
571 if (ppp_open_mode == PPP_OPEN_PASSIVE)
572 fsm->state = PPP_FSM_STOPPED;
573 else {
574 fsm_sconfreq(fsm, 0);
575 fsm->state = PPP_FSM_REQSENT;
576 }
577 break;
578
579 default :
580 syslog(LOG_WARNING, "[PPP/FSM] unexp state: %d in lowerup", fsm->state);
581 break;
582 }
583 }
584
585/*
586 * fsm_lowerdown -- FSM 下位層を停止する。
587 */
588
589void
590fsm_lowerdown (T_PPP_FSM *fsm)
591{
592 switch (fsm->state) {
593 case PPP_FSM_CLOSED:
594 fsm->state = PPP_FSM_INITIAL;
595 break;
596
597 case PPP_FSM_STOPPED:
598 fsm->state = PPP_FSM_STARTING;
599 if (fsm->callbacks->starting != NULL)
600 (*fsm->callbacks->starting)(fsm);
601 break;
602
603 case PPP_FSM_CLOSING:
604 fsm->state = PPP_FSM_INITIAL;
605 untimeout((FP)fsm_timeout, fsm);
606 break;
607
608 case PPP_FSM_STOPPING:
609 case PPP_FSM_REQSENT:
610 case PPP_FSM_ACKRCVD:
611 case PPP_FSM_ACKSENT:
612 fsm->state = PPP_FSM_STARTING;
613 untimeout((FP)fsm_timeout, fsm);
614 break;
615
616 case PPP_FSM_OPENED:
617 if (fsm->callbacks->down != NULL)
618 (*fsm->callbacks->down)(fsm);
619 fsm->state = PPP_FSM_STARTING;
620 break;
621
622 default :
623 syslog(LOG_WARNING, "[PPP/FSM] unexp state: %d in lowerdown", fsm->state);
624 break;
625 }
626 }
627
628/*
629 * fsm_open -- FSM のオープン
630 */
631
632void
633fsm_open (T_PPP_FSM *fsm)
634{
635 switch (fsm->state) {
636 case PPP_FSM_INITIAL:
637 fsm->state = PPP_FSM_STARTING;
638 if (fsm->callbacks->starting != NULL)
639 (*fsm->callbacks->starting)(fsm);
640 break;
641
642 case PPP_FSM_CLOSED:
643 if (ppp_open_mode == PPP_OPEN_PASSIVE)
644 fsm->state = PPP_FSM_STOPPED;
645 else {
646 fsm_sconfreq(fsm, 0);
647 fsm->state = PPP_FSM_REQSENT;
648 }
649 break;
650
651 case PPP_FSM_CLOSING:
652 fsm->state = PPP_FSM_STOPPING;
653 /* nobreak; 下に落ちる */
654
655 case PPP_FSM_STOPPED:
656 case PPP_FSM_OPENED:
657 fsm_lowerdown(fsm);
658 fsm_lowerup(fsm);
659 break;
660 }
661 }
662
663/*
664 * fsm_close -- リンクの切断を開始する。
665 */
666
667void
668fsm_close (T_PPP_FSM *fsm)
669{
670 switch (fsm->state) {
671 case PPP_FSM_STARTING:
672 fsm->state = PPP_FSM_INITIAL;
673 break;
674
675#if 0 /* 本来の動作は CLOSED に遷移する。*/
676 case PPP_FSM_STOPPED:
677 fsm->state = PPP_FSM_CLOSED;
678 break;
679#endif /* of #if 0 */
680
681 case PPP_FSM_STOPPING:
682 fsm->state = PPP_FSM_CLOSING;
683 break;
684
685 case PPP_FSM_REQSENT:
686 case PPP_FSM_ACKRCVD:
687 case PPP_FSM_ACKSENT:
688 case PPP_FSM_OPENED:
689 if (fsm->state != PPP_FSM_OPENED)
690 untimeout((FP)fsm_timeout, fsm);
691 else if (fsm->callbacks->down != NULL)
692 (*fsm->callbacks->down)(fsm);
693
694 /* タイムアウトを設定し、Terminate-Request を送信する。*/
695 fsm->retrans = MAX_PPP_TERMINATES;
696 fsm_stermreq(fsm, fsm->reqid = ++ fsm->id);
697 fsm->state = PPP_FSM_CLOSING;
698 break;
699 }
700 }
701
702/*
703 * fsm_input -- å…
704¥åŠ›ã€PPP リンク制御 (CP) の制御コードにより適当な関数を呼出す
705 */
706
707void
708fsm_input (T_PPP_FSM *fsm, T_NET_BUF *input)
709{
710 T_PPP_CP_HDR *hdr;
711 T_NET_BUF *output;
712
713 /* PPP リンク制御 (CP) ヘッダより短ければエラー */
714 if (input->len < (sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR))) {
715 syslog(LOG_WARNING, "[PPP/FSM] short hdr: %d.", input->len);
716 return;
717 }
718
719 hdr = GET_PPP_CP_HDR(input);
720
721 /* ヘッダの長さとå…
722¥åŠ›ãƒ‡ãƒ¼ã‚¿ã‚µã‚¤ã‚ºãŒä¸€è‡´ã—なければエラー */
723 if (hdr->len != input->len - sizeof(T_PPP_HDR)) {
724 syslog(LOG_WARNING, "[PPP/FSM] bad len: %d.", hdr->len);
725 return;
726 }
727
728 /* 状æ…
729‹ãŒ INITIAL か STARTING ならエラー */
730 if (fsm->state == PPP_FSM_INITIAL || fsm->state == PPP_FSM_STARTING) {
731 syslog(LOG_WARNING, "[PPP/FSM] unexp state: %d in input.", fsm->state);
732 return;
733 }
734
735 /*
736 * 制御コードにより適当な関数を呼出す
737 */
738
739 switch (hdr->code) {
740 case PPP_CONFREQ:
741 fsm_rconfreq(fsm, hdr->id, input);
742 break;
743
744 case PPP_CONFACK:
745 fsm_rconfack(fsm, hdr->id, input);
746 break;
747
748 case PPP_CONFNAK:
749 case PPP_CONFREJ:
750 fsm_rconfnakrej(fsm, hdr->code, hdr->id, input);
751 break;
752
753 case PPP_TERMREQ:
754 fsm_rtermreq(fsm, hdr->id, input);
755 break;
756
757 case PPP_TERMACK:
758 fsm_rtermack(fsm, input);
759 break;
760
761 case PPP_CODEREJ:
762 fsm_rcoderej(fsm, input);
763 break;
764
765 default:
766 if (fsm->callbacks->extcode == NULL ||
767 (*fsm->callbacks->extcode)(fsm, hdr->code, hdr->id, input) != true) {
768 syscall(get_net_buf(&output, sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR)));
769 memcpy(output->buf, input->buf, sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR));
770 ppp_cp_output(PPP_CODEREJ, ++ fsm->id, output);
771 }
772 break;
773 }
774 }
775
776/*
777 * fsm_protoreject -- Proto-REJ を受信したときの処理
778 */
779
780void
781fsm_protreject (T_PPP_FSM *fsm)
782{
783 switch (fsm->state) {
784 case PPP_FSM_CLOSING:
785 untimeout((FP)fsm_timeout, fsm);
786
787#if 0 /* 本来の動作は CLOSED に遷移する。*/
788 /* 下に落ちる */
789#else /* of #if 0 */
790 fsm->state = PPP_FSM_STOPPED;
791 if (fsm->callbacks->finished != NULL)
792 (*fsm->callbacks->finished)(fsm);
793 break;
794#endif /* of #if 0 */
795
796 case PPP_FSM_CLOSED:
797 fsm->state = PPP_FSM_CLOSED;
798 if (fsm->callbacks->finished != NULL)
799 (*fsm->callbacks->finished)(fsm);
800 break;
801
802 case PPP_FSM_STOPPING:
803 case PPP_FSM_REQSENT:
804 case PPP_FSM_ACKRCVD:
805 case PPP_FSM_ACKSENT:
806 untimeout((FP)fsm_timeout, fsm);
807 /* 下に落ちる */
808
809 case PPP_FSM_STOPPED:
810 fsm->state = PPP_FSM_STOPPED;
811 if (fsm->callbacks->finished != NULL)
812 (*fsm->callbacks->finished)(fsm);
813 break;
814
815 case PPP_FSM_OPENED:
816 if (fsm->callbacks->down != NULL)
817 (*fsm->callbacks->down)(fsm);
818
819 /* タイムアウトを設定し、Terminate-Request を送信する。*/
820 fsm->retrans = MAX_PPP_TERMINATES;
821 fsm_stermreq(fsm, fsm->reqid = ++ fsm->id);
822 fsm->state = PPP_FSM_STOPPING;
823 break;
824
825 }
826 }
827
828#endif /* fo #ifdef SUPPORT_PPP */
Note: See TracBrowser for help on using the repository browser.