source: EcnlProtoTool/trunk/asp3_dcre/tinet/net/ppp.c@ 321

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

文字コードを設定

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 10.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 * 上記著作権者は,以下の (1)~(4) の条件か,Free Software Foundation
8 * によって公表されている GNU General Public License の Version 2 に記
9 * 述されている条件を満たす場合に限り,本ソフトウェア(本ソフトウェア
10 * を改変したものを含む.以下同じ)を使用・複製・改変・再配布(以下,
11 * 利用と呼ぶ)することを無償で許諾する.
12 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
13 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
14 * スコード中に含まれていること.
15 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
16 * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
17 * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
18 * の無保証規定を掲載すること.
19 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
20 * 用できない形で再配布する場合には,次の条件を満たすこと.
21 * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
22 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
23 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
24 * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
25 *
26 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
27 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,その適用可能性も
28 * 含めて,いかなる保証も行わない.また,本ソフトウェアの利用により直
29 * 接的または間接的に生じたいかなる損害に関しても,その責任を負わない.
30 *
31 * @(#) $Id$
32 */
33
34/*
35 * Copyright (c) 1989 Carnegie Mellon University.
36 * All rights reserved.
37 *
38 * Redistribution and use in source and binary forms are permitted
39 * provided that the above copyright notice and this paragraph are
40 * duplicated in all such forms and that any documentation,
41 * advertising materials, and other materials related to such
42 * distribution and use acknowledge that the software was developed
43 * by Carnegie Mellon University. The name of the
44 * University may not be used to endorse or promote products derived
45 * from this software without specific prior written permission.
46 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
47 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
48 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
49 */
50
51/*
52 * Written by Toshiharu OHNO (tony-o@iij.ad.jp)
53 *
54 * Copyright (C) 1993, Internet Initiative Japan, Inc. All rights reserverd.
55 *
56 * Redistribution and use in source and binary forms are permitted
57 * provided that the above copyright notice and this paragraph are
58 * duplicated in all such forms and that any documentation,
59 * advertising materials, and other materials related to such
60 * distribution and use acknowledge that the software was developed
61 * by the Internet Initiative Japan. The name of the
62 * IIJ may not be used to endorse or promote products derived
63 * from this software without specific prior written permission.
64 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
65 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
66 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
67 */
68
69/*
70 * PPP 処理タスクの本体
71 */
72
73#include <s_services.h>
74#include <t_services.h>
75#include "kernel_id.h"
76
77#include <tinet_defs.h>
78#include <tinet_config.h>
79
80#include <net/if.h>
81#include <net/if_ppp.h>
82#include <net/net.h>
83#include <net/net_buf.h>
84#include <net/net_timer.h>
85#include <net/net_count.h>
86#include <net/ppp.h>
87#include <net/ppp_var.h>
88#include <net/ppp_hdlc.h>
89#include <net/ppp_fsm.h>
90#include <net/ppp_lcp.h>
91#include <net/ppp_ipcp.h>
92#include <net/ppp_ccp.h>
93#include <net/ppp_upap.h>
94#include <net/ppp_modem.h>
95
96#ifdef SUPPORT_PPP
97
98/*
99 * 全域変数
100 */
101
102uint8_t ppp_phase = PPP_PHASE_INITIALIZE; /* リンクの状態 */
103
104/*
105 * プロトコル表
106 */
107
108T_PPP_PROTENT *protocols[] = {
109 &lcp_protent,
110 &ipcp_protent,
111
112#ifdef SUPPORT_CCP
113 &ccp_protent,
114#endif /* #ifdef SUPPORT_CCP */
115
116#ifdef LCP_CFG_PAP
117 &pap_protent,
118#endif /* #ifdef LCP_CFG_PAP */
119
120#ifdef LCP_CFG_CHAP
121 &chap_protent,
122#endif /* #ifdef LCP_CFG_CHAP */
123
124 NULL
125 };
126
127/*
128 * 変数
129 */
130
131#ifdef PPP_IDLE_TIMEOUT
132
133static bool_t idle = false;
134
135#endif /* of #ifdef PPP_IDLE_TIMEOUT */
136
137/*
138 * 関数
139 */
140
141static void parse_input (T_NET_BUF *input);
142
143#ifdef PPP_IDLE_TIMEOUT
144
145static void idle_timeout (void *arg);
146
147#endif /* of #ifdef PPP_IDLE_TIMEOUT */
148
149/*
150 * PPP 入力の解析
151 */
152
153static void
154parse_input(T_NET_BUF *input)
155{
156 T_PPP_PROTENT *entry;
157 int_t ix;
158 uint16_t proto;
159
160 NET_COUNT_PPP(net_count_ppp.in_octets, input->len);
161 NET_COUNT_PPP(net_count_ppp.in_packets, 1);
162
163 /* フレーム長をチェックする */
164 if (input->len < sizeof(T_PPP_HDR)) { /* FreeBSD では PPP_HDRLEN は 4 */
165 syslog(LOG_NOTICE, "[PPP] recv short frame.");
166 goto buf_rel;
167 }
168
169 proto = ntohs(*GET_PPP_HDR(input));
170
171 /* プロトコルが LCP 以外で、LCP がオープンされていなければエラー */
172 if (proto != PPP_LCP && lcp_fsm.state != PPP_FSM_OPENED) {
173 syslog(LOG_NOTICE, "[PPP] LCP not open.");
174 goto buf_rel;
175 }
176
177 /* リンクが認証状態以前は、LCP、LQR、PAP、CHAP のみ受け付ける */
178 if (ppp_phase <= PPP_PHASE_AUTHENTICATE &&
179 !(proto == PPP_LCP || proto == PPP_LQR ||
180 proto == PPP_PAP || proto == PPP_CHAP)) {
181 syslog(LOG_NOTICE, "[PPP] disc proto: 0x%04x, phase: %d.", proto, ppp_phase);
182 goto buf_rel;
183 }
184
185 /* 上位プロトコルの入力関数を呼出す */
186 for (ix = 0; (entry = protocols[ix]) != NULL; ix ++) {
187 if (entry->proto == proto && entry->input != NULL) {
188 (*entry->input)(input);
189 syscall(rel_net_buf(input));
190 return;
191 }
192 if ((entry->proto & ~0x8000) == proto && entry->datainput != NULL) {
193 (*entry->datainput)(input);
194 return;
195 }
196 }
197
198 syslog(LOG_INFO, "[PPP] unexp proto: 0x%04x.", proto);
199 lcp_sprotrej(input);
200
201buf_rel:
202 NET_COUNT_PPP(net_count_ppp.in_err_packets, 1);
203 syscall(rel_net_buf(input));
204 }
205
206/*
207 * ppp_output -- PPP インタフェースの出力関数
208 */
209
210ER
211ppp_output (T_NET_BUF *output, TMO tmout)
212{
213 ER error = E_OK;
214
215#ifdef PPP_CFG_MODEM
216
217#if 0 /* 保留 */
218 /* モデムの接続完了まで待つ。*/
219 if ((error = wait_modem()) != E_OK)
220 goto buf_ret;
221#endif
222
223#endif /* of #ifdef PPP_CFG_MODEM */
224
225 /* IPCP の接続完了まで待つ。*/
226 if ((error = wait_ipcp()) != E_OK)
227 goto buf_ret;
228
229#ifdef PPP_IDLE_TIMEOUT
230 wai_sem(SEM_IDLE_TIMEOUT);
231 if (idle) {
232 untimeout((FP)idle_timeout, NULL);
233 idle = false;
234 }
235 sig_sem(SEM_IDLE_TIMEOUT);
236#endif /* of #ifdef PPP_IDLE_TIMEOUT */
237
238 /* PPP 出力キューに投入する。*/
239 if ((error = tsnd_dtq(DTQ_PPP_OUTPUT, output, tmout)) != E_OK)
240 goto buf_ret;
241
242#ifdef PPP_IDLE_TIMEOUT
243 wai_sem(SEM_IDLE_TIMEOUT);
244 if (!idle && ppp_phase == PPP_PHASE_NETWORK) {
245 timeout((FP)idle_timeout, NULL, PPP_IDLE_TIMEOUT);
246 idle = true;
247 }
248 sig_sem(SEM_IDLE_TIMEOUT);
249#endif /* of #ifdef PPP_IDLE_TIMEOUT */
250
251 return error;
252
253buf_ret:
254 syscall(rel_net_buf(output));
255 NET_COUNT_PPP(net_count_ppp.out_err_packets, 1);
256 return error;
257 }
258
259/*
260 * ppp_cp_output -- CP フレームの送信
261 */
262
263void
264ppp_cp_output (uint8_t code, uint8_t id, T_NET_BUF *output)
265{
266 T_PPP_CP_HDR *cph;
267
268 /* CP ヘッダを設定する */
269 cph = GET_PPP_CP_HDR(output);
270 cph->code = code;
271 cph->id = id;
272 cph->len = htons(output->len - sizeof(T_PPP_HDR));
273
274 /* PPP 出力キューに投入する。*/
275 if (snd_dtq(DTQ_PPP_OUTPUT, output) != E_OK) {
276 syscall(rel_net_buf(output));
277 NET_COUNT_PPP(net_count_ppp.out_err_packets, 1);
278 }
279 }
280
281/*
282 * PPP 入力タスク
283 */
284
285void
286ppp_input_task(intptr_t exinf)
287{
288 T_NET_BUF *input;
289 T_PPP_PROTENT *proto;
290 ID tskid;
291 int_t ix;
292
293 /* ポートを初期設定する */
294 syscall(serial_opn_por(HDLC_PORTID));
295 syscall(serial_ctl_por(HDLC_PORTID, IOCTL_FCSND | IOCTL_FCRCV));
296
297 get_tid(&tskid);
298
299#ifdef PPP_CFG_MODEM
300
301 init_modem();
302 syslog(LOG_NOTICE, "[PPP INPUT:%d] started with modem on port %d.", tskid, HDLC_PORTID);
303
304#else /* of #ifdef PPP_CFG_MODEM */
305
306 syslog(LOG_NOTICE, "[PPP INPUT:%d] started on port %d.", tskid, HDLC_PORTID);
307
308#endif /* of #ifdef PPP_CFG_MODEM */
309
310 /* ネットワークタイマタスクを起動する */
311 syscall(act_tsk(NET_TIMER_TASK));
312
313 /* 上位プロトコルを初期化する */
314 for (ix = 0; (proto = protocols[ix]) != NULL; ix ++)
315 if (proto->init != NULL)
316 (*proto->init)();
317
318 lcp_lowerup();
319 lcp_open(PPP_OPEN_PASSIVE);
320
321 /* PPP 出力タスクを起動する */
322 syscall(act_tsk(PPP_OUTPUT_TASK));
323
324 while (true) {
325 if (tget_net_buf(&input, IF_PDU_SIZE, TMO_PPP_GET_NET_BUF) == E_OK) {
326 while (HDLC_read(input, IF_PDU_SIZE) != E_OK)
327 ;
328 if (input->len > 0) {
329
330 #ifdef PPP_IDLE_TIMEOUT
331 wai_sem(SEM_IDLE_TIMEOUT);
332 if (idle && ntohs(*GET_PPP_HDR(input)) != PPP_LCP) {
333 untimeout((FP)idle_timeout, NULL);
334 idle = false;
335 }
336 sig_sem(SEM_IDLE_TIMEOUT);
337 #endif /* of #ifdef PPP_IDLE_TIMEOUT */
338
339 parse_input(input);
340 }
341 else
342 syscall(rel_net_buf(input));
343
344 #ifdef PPP_IDLE_TIMEOUT
345 wai_sem(SEM_IDLE_TIMEOUT);
346 if (!idle && ppp_phase == PPP_PHASE_NETWORK) {
347 timeout((FP)idle_timeout, NULL, PPP_IDLE_TIMEOUT);
348 idle = true;
349 }
350 else if (idle && ppp_phase != PPP_PHASE_NETWORK) {
351 untimeout((FP)idle_timeout, NULL);
352 idle = false;
353 }
354 sig_sem(SEM_IDLE_TIMEOUT);
355 #endif /* of #ifdef PPP_IDLE_TIMEOUT */
356
357 }
358 else {
359 HDLC_dummy_read();
360 NET_COUNT_PPP(net_count_ppp.in_err_packets, 1);
361 NET_COUNT_PPP(net_count_ppp_no_bufs, 1);
362 }
363 }
364 }
365
366/*
367 * PPP 出力タスク
368 */
369
370void
371ppp_output_task(intptr_t exinf)
372{
373 T_NET_BUF *output;
374 ID tskid;
375
376 get_tid(&tskid);
377 syslog(LOG_NOTICE, "[PPP OUTPUT:%d] started.", tskid);
378
379 while (true) {
380 while (rcv_dtq(DTQ_PPP_OUTPUT, (intptr_t*)&output) == E_OK) {
381 NET_COUNT_PPP(net_count_ppp.out_octets, output->len);
382 NET_COUNT_PPP(net_count_ppp.out_packets, 1);
383 syscall(HDLC_write(output));
384 syscall(rel_net_buf(output));
385 }
386 }
387 }
388
389#ifdef PPP_IDLE_TIMEOUT
390
391/*
392 * アイドルタイムアウト処理
393 */
394
395static void
396idle_timeout (void *arg)
397{
398 syslog(LOG_NOTICE, "[PPP] idel %d [s], disconnecting.", (uint16_t)(PPP_IDLE_TIMEOUT / NET_TIMER_HZ));
399 lcp_close();
400 }
401
402#endif /* of #ifdef PPP_IDLE_TIMEOUT */
403
404#endif /* fo #ifdef SUPPORT_PPP */
Note: See TracBrowser for help on using the repository browser.