source: rubycfg_asp/trunk/asp_dcre/tinet/net/ppp.c@ 313

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

ソースを追加

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
  • Property svn:mime-type set to text/x-csrc
File size: 11.5 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.c 313 2017-07-23 04:50:32Z coas-nagasima $
44 */
45
46/*
47 * Copyright (c) 1989 Carnegie Mellon University.
48 * All rights reserved.
49 *
50 * Redistribution and use in source and binary forms are permitted
51 * provided that the above copyright notice and this paragraph are
52 * duplicated in all such forms and that any documentation,
53 * advertising materials, and other materials related to such
54 * distribution and use acknowledge that the software was developed
55 * by Carnegie Mellon University. The name of the
56 * University may not be used to endorse or promote products derived
57 * from this software without specific prior written permission.
58 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
59 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
60 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
61 */
62
63/*
64 * Written by Toshiharu OHNO (tony-o@iij.ad.jp)
65 *
66 * Copyright (C) 1993, Internet Initiative Japan, Inc. All rights reserverd.
67 *
68 * Redistribution and use in source and binary forms are permitted
69 * provided that the above copyright notice and this paragraph are
70 * duplicated in all such forms and that any documentation,
71 * advertising materials, and other materials related to such
72 * distribution and use acknowledge that the software was developed
73 * by the Internet Initiative Japan. The name of the
74 * IIJ may not be used to endorse or promote products derived
75 * from this software without specific prior written permission.
76 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
77 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
78 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
79 */
80
81/*
82 * PPP 処理タスクの本体
83 */
84
85#include <s_services.h>
86#include <t_services.h>
87#include "kernel_id.h"
88
89#include <tinet_defs.h>
90#include <tinet_config.h>
91
92#include <net/if.h>
93#include <net/if_ppp.h>
94#include <net/net.h>
95#include <net/net_endian.h>
96#include <net/net_var.h>
97#include <net/net_buf.h>
98#include <net/net_timer.h>
99#include <net/net_count.h>
100#include <net/ppp.h>
101#include <net/ppp_var.h>
102#include <net/ppp_hdlc.h>
103#include <net/ppp_fsm.h>
104#include <net/ppp_lcp.h>
105#include <net/ppp_ipv6cp.h>
106#include <net/ppp_ipcp.h>
107#include <net/ppp_ccp.h>
108#include <net/ppp_upap.h>
109#include <net/ppp_modem.h>
110
111#ifdef SUPPORT_PPP
112
113/*
114 * å…
115¨åŸŸå¤‰æ•°
116 */
117
118uint8_t ppp_phase = PPP_PHASE_INITIALIZE; /* リンクの状æ…
119‹ */
120
121/*
122 * プロトコル表
123 */
124
125T_PPP_PROTENT *protocols[] = {
126 &lcp_protent,
127
128#ifdef _IP6_CFG
129 &ipv6cp_protent,
130#endif /* of #ifdef _IP6_CFG */
131
132#ifdef _IP4_CFG
133 &ipcp_protent,
134#endif /* of #ifdef _IP4_CFG */
135
136#ifdef SUPPORT_CCP
137 &ccp_protent,
138#endif /* of #ifdef SUPPORT_CCP */
139
140#ifdef LCP_CFG_PAP
141 &pap_protent,
142#endif /* of #ifdef LCP_CFG_PAP */
143
144#ifdef LCP_CFG_CHAP
145 &chap_protent,
146#endif /* of #ifdef LCP_CFG_CHAP */
147
148 NULL
149 };
150
151/*
152 * 変数
153 */
154
155#ifdef PPP_IDLE_TIMEOUT
156
157static bool_t idle = false;
158
159#endif /* of #ifdef PPP_IDLE_TIMEOUT */
160
161/*
162 * 関数
163 */
164
165static void parse_input (T_NET_BUF *input);
166
167#ifdef PPP_IDLE_TIMEOUT
168
169static void idle_timeout (void *arg);
170
171#endif /* of #ifdef PPP_IDLE_TIMEOUT */
172
173/*
174 * PPP å…
175¥åŠ›ã®è§£æž
176 */
177
178static void
179parse_input(T_NET_BUF *input)
180{
181 T_PPP_PROTENT *entry;
182 int_t ix;
183 uint16_t proto;
184
185 NET_COUNT_PPP(net_count_ppp.in_octets, input->len);
186 NET_COUNT_PPP(net_count_ppp.in_packets, 1);
187
188 /* フレーム長をチェックする */
189 if (input->len < sizeof(T_PPP_HDR)) { /* FreeBSD では PPP_HDRLEN は 4 */
190 syslog(LOG_NOTICE, "[PPP] recv short frame.");
191 goto buf_rel;
192 }
193
194 proto = ntohs(*GET_PPP_HDR(input));
195
196 /* プロトコルが LCP 以外で、LCP がオープンされていなければエラー */
197 if (proto != PPP_LCP && lcp_fsm.state != PPP_FSM_OPENED) {
198 syslog(LOG_NOTICE, "[PPP] LCP not open.");
199 goto buf_rel;
200 }
201
202 /* リンクが認証状æ…
203‹ä»¥å‰ã¯ã€LCP、LQR、PAP、CHAP のみ受け付ける */
204 if (ppp_phase <= PPP_PHASE_AUTHENTICATE &&
205 !(proto == PPP_LCP || proto == PPP_LQR ||
206 proto == PPP_PAP || proto == PPP_CHAP)) {
207 syslog(LOG_NOTICE, "[PPP] disc proto: 0x%04x, phase: %d.", proto, ppp_phase);
208 goto buf_rel;
209 }
210
211 /* 上位プロトコルのå…
212¥åŠ›é–¢æ•°ã‚’呼出す */
213 for (ix = 0; (entry = protocols[ix]) != NULL; ix ++) {
214 if (entry->proto == proto && entry->input != NULL) {
215 (*entry->input)(input);
216 syscall(rel_net_buf(input));
217 return;
218 }
219 if ((entry->proto & ~0x8000) == proto && entry->datainput != NULL) {
220 (*entry->datainput)(input);
221 return;
222 }
223 }
224
225 syslog(LOG_INFO, "[PPP] unexp proto: 0x%04x.", proto);
226 lcp_sprotrej(input);
227
228buf_rel:
229 NET_COUNT_PPP(net_count_ppp.in_err_packets, 1);
230 syscall(rel_net_buf(input));
231 }
232
233/*
234 * ppp_output -- PPP インタフェースの出力関数
235 */
236
237ER
238ppp_output (T_NET_BUF *output, TMO tmout)
239{
240 ER error = E_OK;
241
242#ifdef PPP_CFG_MODEM
243
244#if 0 /* 保留 */
245 /* モデムの接続完了まで待
246つ。*/
247 if ((error = wait_modem()) != E_OK)
248 goto buf_ret;
249#endif
250
251#endif /* of #ifdef PPP_CFG_MODEM */
252
253#ifdef _IP6_CFG
254 /* IPV6CP の接続完了まで待
255つ。*/
256 if ((error = wait_ipv6cp()) != E_OK)
257 goto buf_ret;
258#endif /* of #ifdef _IP6_CFG */
259
260#ifdef _IP4_CFG
261 /* IPCP の接続完了まで待
262つ。*/
263 if ((error = wait_ipcp()) != E_OK)
264 goto buf_ret;
265#endif /* of #ifdef _IP4_CFG */
266
267#ifdef _IP4_CFG
268 /* IPCP の接続完了まで待
269つ。*/
270 if ((error = wait_ipcp()) != E_OK)
271 goto buf_ret;
272#endif /* of #ifdef _IP4_CFG */
273
274#ifdef PPP_IDLE_TIMEOUT
275 wai_sem(SEM_IDLE_TIMEOUT);
276 if (idle) {
277 untimeout((FP)idle_timeout, NULL);
278 idle = false;
279 }
280 sig_sem(SEM_IDLE_TIMEOUT);
281#endif /* of #ifdef PPP_IDLE_TIMEOUT */
282
283 /* PPP 出力キューに投å…
284¥ã™ã‚‹ã€‚*/
285 if ((error = tsnd_dtq(DTQ_PPP_OUTPUT, output, tmout)) != E_OK)
286 goto buf_ret;
287
288#ifdef PPP_IDLE_TIMEOUT
289 wai_sem(SEM_IDLE_TIMEOUT);
290 if (!idle && ppp_phase == PPP_PHASE_NETWORK) {
291 timeout((FP)idle_timeout, NULL, PPP_IDLE_TIMEOUT);
292 idle = true;
293 }
294 sig_sem(SEM_IDLE_TIMEOUT);
295#endif /* of #ifdef PPP_IDLE_TIMEOUT */
296
297 return error;
298
299buf_ret:
300 syscall(rel_net_buf(output));
301 NET_COUNT_PPP(net_count_ppp.out_err_packets, 1);
302 return error;
303 }
304
305/*
306 * ppp_cp_output -- CP フレームの送信
307 */
308
309void
310ppp_cp_output (uint8_t code, uint8_t id, T_NET_BUF *output)
311{
312 T_PPP_CP_HDR *cph;
313
314 /* CP ヘッダを設定する */
315 cph = GET_PPP_CP_HDR(output);
316 cph->code = code;
317 cph->id = id;
318 cph->len = htons(output->len - sizeof(T_PPP_HDR));
319
320 /* PPP 出力キューに投å…
321¥ã™ã‚‹ã€‚*/
322 if (snd_dtq(DTQ_PPP_OUTPUT, output) != E_OK) {
323 syscall(rel_net_buf(output));
324 NET_COUNT_PPP(net_count_ppp.out_err_packets, 1);
325 }
326 }
327
328/*
329 * PPP å…
330¥åŠ›ã‚¿ã‚¹ã‚¯
331 */
332
333void
334ppp_input_task(intptr_t exinf)
335{
336 T_NET_BUF *input;
337 T_PPP_PROTENT *proto;
338 ID tskid;
339 int_t ix;
340 uint8_t rcount = 0;
341
342 /* ポートを初期設定する */
343 syscall(serial_opn_por(HDLC_PORTID));
344 syscall(serial_ctl_por(HDLC_PORTID, IOCTL_FCSND | IOCTL_FCRCV));
345
346 get_tid(&tskid);
347
348#ifdef PPP_CFG_MODEM
349
350 init_modem();
351 syslog(LOG_NOTICE, "[PPP INPUT:%d] started with modem on port %d.", tskid, HDLC_PORTID);
352
353#else /* of #ifdef PPP_CFG_MODEM */
354
355 syslog(LOG_NOTICE, "[PPP INPUT:%d] started on port %d.", tskid, HDLC_PORTID);
356
357#endif /* of #ifdef PPP_CFG_MODEM */
358
359 /* ネットワークタイマタスクを起動する */
360 syscall(act_tsk(NET_TIMER_TASK));
361
362 /* 上位プロトコルを初期化する */
363 for (ix = 0; (proto = protocols[ix]) != NULL; ix ++)
364 if (proto->init != NULL)
365 (*proto->init)();
366
367 lcp_lowerup();
368 lcp_open(PPP_OPEN_PASSIVE);
369
370 /* PPP 出力タスクを起動する */
371 syscall(act_tsk(PPP_OUTPUT_TASK));
372
373 /* 乱数生成を初期化する。*/
374 net_srand(0);
375
376 while (true) {
377 if (tget_net_buf(&input, IF_PDU_SIZE, TMO_PPP_GET_NET_BUF) == E_OK) {
378 while (HDLC_read(input, IF_PDU_SIZE) != E_OK)
379 ;
380 if (input->len > 0) {
381
382 /* 乱数生成を初期化する。*/
383 if (rcount == 0)
384 net_srand(input->len);
385 rcount ++;
386
387#ifdef PPP_IDLE_TIMEOUT
388 wai_sem(SEM_IDLE_TIMEOUT);
389 if (idle && ntohs(*GET_PPP_HDR(input)) != PPP_LCP) {
390 untimeout((FP)idle_timeout, NULL);
391 idle = false;
392 }
393 sig_sem(SEM_IDLE_TIMEOUT);
394#endif /* of #ifdef PPP_IDLE_TIMEOUT */
395
396 parse_input(input);
397 }
398 else
399 syscall(rel_net_buf(input));
400
401#ifdef PPP_IDLE_TIMEOUT
402 wai_sem(SEM_IDLE_TIMEOUT);
403 if (!idle && ppp_phase == PPP_PHASE_NETWORK) {
404 timeout((FP)idle_timeout, NULL, PPP_IDLE_TIMEOUT);
405 idle = true;
406 }
407 else if (idle && ppp_phase != PPP_PHASE_NETWORK) {
408 untimeout((FP)idle_timeout, NULL);
409 idle = false;
410 }
411 sig_sem(SEM_IDLE_TIMEOUT);
412#endif /* of #ifdef PPP_IDLE_TIMEOUT */
413
414 }
415 else {
416 HDLC_dummy_read();
417 NET_COUNT_PPP(net_count_ppp.in_err_packets, 1);
418 NET_COUNT_PPP(net_count_ppp_no_bufs, 1);
419 }
420 }
421 }
422
423/*
424 * PPP 出力タスク
425 */
426
427void
428ppp_output_task(intptr_t exinf)
429{
430 T_NET_BUF *output;
431 ID tskid;
432
433 get_tid(&tskid);
434 syslog(LOG_NOTICE, "[PPP OUTPUT:%d] started.", tskid);
435
436 while (true) {
437 while (rcv_dtq(DTQ_PPP_OUTPUT, (intptr_t*)&output) == E_OK) {
438 NET_COUNT_PPP(net_count_ppp.out_octets, output->len);
439 NET_COUNT_PPP(net_count_ppp.out_packets, 1);
440 syscall(HDLC_write(output));
441 syscall(rel_net_buf(output));
442 }
443 }
444 }
445
446#ifdef PPP_IDLE_TIMEOUT
447
448/*
449 * アイドルタイムアウト処理
450 */
451
452static void
453idle_timeout (void *arg)
454{
455 syslog(LOG_NOTICE, "[PPP] idel %d [s], disconnecting.", (uint16_t)(PPP_IDLE_TIMEOUT / NET_TIMER_HZ));
456 lcp_close();
457 }
458
459#endif /* of #ifdef PPP_IDLE_TIMEOUT */
460
461#endif /* fo #ifdef SUPPORT_PPP */
Note: See TracBrowser for help on using the repository browser.