source: azure_iot_hub/trunk/asp3_dcre/tinet/net/ppp_ipv6cp.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: 18.8 KB
RevLine 
[388]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_ipv6cp.c 388 2019-05-22 11:25:18Z coas-nagasima $
44 */
45
46/*
47 * ipv6cp.c - PPP IP Control Protocol.
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 IP Control Protocol (IPV6CP) Module
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/ipv6cp.c,v 1.90.2.4 2000/08/19 09:30:03 brian Exp $
85 *
86 * TODO:
87 * o Support IPADDRS properly
88 * o Validate the length in IpcpDecodeConfig
89 */
90
91#include <string.h>
92
93#include <s_services.h>
94#include <t_services.h>
95#include "kernel_id.h"
96
97#include <tinet_defs.h>
98#include <tinet_config.h>
99
100#include <net/if.h>
101#include <net/if_ppp.h>
102#include <net/net.h>
103#include <net/net_endian.h>
104#include <net/net_buf.h>
105#include <net/net_count.h>
106#include <net/ppp.h>
107#include <net/ppp_var.h>
108#include <net/ppp_fsm.h>
109#include <net/ppp_lcp.h>
110#include <net/ppp_ipv6cp.h>
111#include <net/ppp_modem.h>
112
113#include <netinet/in.h>
114#include <netinet/in_var.h>
115#include <netinet/ip.h>
116#include <netinet/tcp.h>
117#include <netinet/tcp_var.h>
118#include <netinet/tcp_timer.h>
119#include <netinet/udp_var.h>
120
121#include <net/if_var.h>
122
123#ifdef SUPPORT_PPP
124
125/*
126 * 関数
127 */
128
129static void ipv6cp_init (void);
130static void ipv6cp_input (T_NET_BUF *input);
131static void ipv6cp_protrej (void);
132static void ipv6cp_lowerup (void);
133static void ipv6cp_lowerdown (void);
134static void ipv6cp_open (void);
135static void ipv6cp_close (void);
136
137/*
138 * FSM から呼出されるコールバック関
139 */
140
141static void ipv6cp_resetci(T_PPP_FSM *fsm); /* 自構成情
142報をリセットする。 */
143static int_t ipv6cp_cilen (T_PPP_FSM *fsm); /* 構成情
144報の長さを返す。 */
145static void ipv6cp_addci (T_PPP_FSM *fsm, T_NET_BUF *output);
146 /* 自構成情
147報を追加する。 */
148static bool_t ipv6cp_ackci (T_PPP_FSM *fsm, T_NET_BUF *input);
149 /* ACK を受信したときの処理 */
150static bool_t ipv6cp_nakci (T_PPP_FSM *fsm, T_NET_BUF *input);
151 /* NAK を受信したときの処理 */
152static bool_t ipv6cp_rejci (T_PPP_FSM *fsm, T_NET_BUF *input);
153 /* REJ を受信したときの処理 */
154static int_t ipv6cp_reqci (T_PPP_FSM *fsm, T_NET_BUF *input, T_NET_BUF *output);
155 /* 相手の構成情
156報を確認する。 */
157static void ipv6cp_up (T_PPP_FSM *fsm); /* リンク接続を確立する。 */
158static void ipv6cp_down (T_PPP_FSM *fsm); /* リンク接続を解放する。 */
159static void ipv6cp_finished(T_PPP_FSM *fsm); /* 下位層を終了する。 */
160
161/*
162 * 変数
163 */
164
165static T_IFNET ipv6cp_local_def_cfg = { /* 自構成情
166報の規定値 */
167 NULL, /* ネットワークインタフェースのソフトウェア情
168å ± */
169 {}, /* IPv6 アドレス情
170å ± */
171 {}, /* マルチキャスト IPv6 アドレス */
172 0, /* フラグ */
173 };
174
175static T_IFNET ipv6cp_remote_def_cfg = { /* 相手の構成情
176報の規定値 */
177 NULL, /* ネットワークインタフェースのソフトウェア情
178å ± */
179 {}, /* IPv6 アドレス情
180å ± */
181 {}, /* マルチキャスト IPv6 アドレス */
182 0, /* フラグ */
183 };
184
185static T_IFNET ipv6cp_local_neg_cfg; /* ネゴ中の自構成情
186å ± */
187
188static T_IFNET ipv6cp_remote_neg_cfg; /* ネゴ中の相手の構成情
189å ± */
190
191/*
192 * å…
193¨åŸŸå¤‰æ•°
194 */
195
196T_PPP_FSM_CALLBACKS ipv6cp_callbacks = {
197 ipv6cp_resetci, /* 自構成情
198報をリセットする。 */
199 ipv6cp_cilen, /* 構成情
200報の長さを返す。 */
201 ipv6cp_addci, /* 自構成情
202報を追加する。 */
203 ipv6cp_ackci, /* ACK を受信したときの処理 */
204 ipv6cp_nakci, /* NAK を受信したときの処理 */
205 ipv6cp_rejci, /* REJ を受信したときの処理 */
206 ipv6cp_reqci, /* 相手の構成情
207報を確認する。 */
208 ipv6cp_up, /* リンク接続を確立する。 */
209 ipv6cp_down, /* リンク接続を解放する。 */
210 NULL, /* 下位層を開始する。 */
211 ipv6cp_finished, /* 下位層を終了する。 */
212 NULL, /* 再送する。 */
213 NULL, /* 不明な CP を受信したときの処理 */
214 };
215
216T_PPP_FSM ipv6cp_fsm = {
217 &ipv6cp_callbacks, /* コールバック関数 */
218 PPP_IPV6CP, /* プロトコル */
219 };
220
221T_PPP_PROTENT ipv6cp_protent = {
222 PPP_IPV6CP,
223 ipv6cp_init, /* 初期化 */
224 ipv6cp_input, /* å…
225¥åŠ› */
226 ipv6cp_protrej, /* Proto-REJ 受信処理 */
227 ipv6cp_lowerup, /* 下位層を起動する */
228 ipv6cp_lowerdown, /* 下位層を停止する */
229 ipv6cp_open, /* オープンする */
230 ipv6cp_close, /* クローズする */
231 ip6_input, /* データå…
232¥åŠ›ã€IPv6 å…
233¥åŠ› */
234 };
235
236T_IFNET ipv6cp_local_ack_cfg; /* 相手に許可されたの自構成情
237å ± */
238T_IFNET ipv6cp_remote_ack_cfg; /* 相手に許可した構成情
239å ± */
240
241/*
242 * ppp_get_ifnet -- ネットワークインタフェース構造体を返す。
243 */
244
245T_IFNET *
246ppp_get_ifnet (void)
247{
248 return &ipv6cp_local_ack_cfg;
249 }
250
251/*
252 * wait_ipv6cp -- IP 接続完了まで待
253つ。
254 *
255 * 戻り値: 接続に失敗したら E_OBJ を返す。
256 */
257
258ER
259wait_ipv6cp (void)
260{
261#ifdef PPP_CFG_MODEM
262 ER error;
263#endif /* of #ifdef PPP_CFG_MODEM */
264
265 if (ipv6cp_fsm.state <= PPP_FSM_STOPPED) {
266
267#ifdef PPP_CFG_MODEM
268
269 /* モデムの接続完了まで待
270つ。*/
271 if ((error = wait_modem()) != E_OK)
272 return error;
273
274#else /* of #ifdef PPP_CFG_MODEM */
275
276 /*
277 * 受動オープンし、相手からの接続待
278ちなら LCP を一度クローズし、
279 * 能動オープン状æ…
280‹ã§ã€å†ã‚ªãƒ¼ãƒ—ンする。
281 */
282 lcp_close();
283 lcp_open(PPP_OPEN_ACTIVE);
284
285#endif /* of #ifdef PPP_CFG_MODEM */
286
287 }
288
289 if (ipv6cp_fsm.state != PPP_FSM_OPENED) {
290 /* IP 接続完了まで待
291つ。*/
292 wai_sem(SEM_IPV6CP_READY);
293 if (ipv6cp_fsm.state != PPP_FSM_OPENED)
294 return E_OBJ;
295 }
296
297 return E_OK;
298 }
299
300/*
301 * ipv6cp_init -- IPV6CP モジュールの初期化
302 */
303
304static void
305ipv6cp_init (void)
306{
307 fsm_init(&ipv6cp_fsm);
308 }
309
310/*
311 * ipv6cp_input -- IPV6CP å…
312¥åŠ›
313 */
314
315static void
316ipv6cp_input (T_NET_BUF *input)
317{
318 NET_COUNT_PPP_IPV6CP(net_count_ppp_ipv6cp_in_octets, input->len);
319 NET_COUNT_PPP_IPV6CP(net_count_ppp_ipv6cp_in_packets, 1);
320 fsm_input(&ipv6cp_fsm, input);
321 }
322
323/*
324 * ipv6cp_resetci -- IPV6CPの構成情
325報をリセットする。
326 */
327
328static void
329ipv6cp_resetci (T_PPP_FSM *fsm)
330{
331 /* 自構成情
332報の初期設定 */
333 ipv6cp_local_neg_cfg = ipv6cp_local_def_cfg;
334 memset((void*)&ipv6cp_local_ack_cfg, 0, sizeof(T_IFNET));
335
336 /* 相手の構成情
337報の初期設定 */
338 ipv6cp_remote_neg_cfg = ipv6cp_remote_def_cfg;
339 memset((void*)&ipv6cp_remote_ack_cfg, 0, sizeof(T_IFNET));
340 }
341
342/*
343 * ipv6cp_cilen -- 構成情
344報の長さを返す。
345 */
346
347static int_t
348ipv6cp_cilen (T_PPP_FSM *fsm)
349{
350 int_t cilen = 0;
351
352 cilen += sizeof(T_PPP_CI_HDR) + sizeof(uint32_t); /* IPv6 アドレス */
353
354 return cilen;
355 }
356
357/*
358 * ipv6cp_addci -- IPV6CPの構成情
359報を追加する。
360 */
361
362static void
363ipv6cp_addci (T_PPP_FSM *fsm, T_NET_BUF *output)
364{
365 uint8_t *buf;
366
367 buf = output->buf + sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR);
368
369 /* IPv6 アドレスオプションを追加する。 */
370 *buf ++ = IPV6CP_CIT_ADDR;
371 *buf ++ = sizeof(T_PPP_CI_HDR) + sizeof(uint32_t);
372 ahtonl(buf, ipv6cp_local_neg_cfg.in6_ifaddrs[0].addr);
373 buf += sizeof(uint32_t);
374 }
375
376/*
377 * ipv6cp_ackci -- ACK を受信したときの処理
378 *
379 * 戻り値: true ACK は正常
380 * false ACK は異常
381 */
382
383static bool_t
384ipv6cp_ackci (T_PPP_FSM *fsm, T_NET_BUF *input)
385{
386 uint8_t *buf;
387 uint16_t len;
388
389 buf = input->buf + sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR);
390 len = input->len - (sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR));
391
392 /*
393 * 構成情
394報は送信した順に完å…
395¨ã«ä¸€è‡´ã—なければならない。
396 * 従って、ipv6cp_addci で作成した順に解析する。
397 */
398
399 /* ADDR オプションを解析する。 */
400 if (len < sizeof(T_PPP_CI_HDR) + sizeof(uint32_t) ||
401 *buf ++ != IPV6CP_CIT_ADDR ||
402 *buf ++ != sizeof(T_PPP_CI_HDR) + sizeof(uint32_t)||
403 nahcmpl(buf, ipv6cp_local_neg_cfg.in6_ifaddrs[0].addr))
404 return false;
405 buf += sizeof(uint32_t);
406 len -= sizeof(T_PPP_CI_HDR) + sizeof(uint32_t);
407
408 return true;
409 }
410
411/*
412 * ipv6cp_nakci -- NAK を受信したときの処理
413 *
414 * 戻り値: 1 NAK は正常
415 * 0 NAK は異常
416 */
417
418static int_t
419ipv6cp_nakci (T_PPP_FSM *fsm, T_NET_BUF *input)
420{
421 T_IFNET new_cfg;
422 uint32_t addr;
423 uint16_t len;
424 uint8_t *buf, cilen;
425
426 buf = input->buf + sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR);
427 len = input->len - (sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR));
428
429 new_cfg = ipv6cp_local_neg_cfg;
430
431 /* ADDR オプションを解析する。 */
432 if (len >= sizeof(T_PPP_CI_HDR) + sizeof(addr) &&
433 * buf == IPV6CP_CIT_ADDR &&
434 *(buf + 1) == sizeof(T_PPP_CI_HDR) + sizeof(addr)) {
435 memcpy(&new_cfg.in6_ifaddrs[0].addr, buf + 2, sizeof(addr));
436 buf += sizeof(T_PPP_CI_HDR) + sizeof(addr);
437 len -= sizeof(T_PPP_CI_HDR) + sizeof(addr);
438 }
439
440 /* 後は無視する。*/
441 while (len > sizeof(T_PPP_CI_HDR)) {
442 cilen = *(buf + 1);
443 if (len < cilen)
444 return 0;
445 buf += cilen;
446 len -= cilen;
447 }
448
449 /* 長さが 0 でなければエラー */
450 if (len != 0)
451 return 0;
452
453 /* 新しいオプションを設定する。*/
454 if (fsm->state != PPP_FSM_OPENED)
455 ipv6cp_local_neg_cfg = new_cfg;
456
457 return 1;
458 }
459
460/*
461 * ipv6cp_rejci -- REJ を受信したときの処理
462 *
463 * 戻り値: 1 REJ は正常
464 * 0 REJ は異常
465 */
466
467static int_t
468ipv6cp_rejci (T_PPP_FSM *fsm, T_NET_BUF *input)
469{
470 T_IFNET new_cfg;
471 uint8_t *buf;
472 uint16_t len;
473
474 buf = input->buf + sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR);
475 len = input->len - (sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR));
476
477 new_cfg = ipv6cp_local_neg_cfg;
478
479 /* ADDR オプションを解析する。 */
480 if (len >= sizeof(T_PPP_CI_HDR) + sizeof(new_cfg.in6_ifaddrs[0].addr) &&
481 * buf == IPV6CP_CIT_ADDR &&
482 *(buf + 1) == sizeof(T_PPP_CI_HDR) + sizeof(new_cfg.in6_ifaddrs[0].addr)) {
483 memcpy(&new_cfg.in6_ifaddrs[0].addr, &in6_addr_unspecified,
484 sizeof(new_cfg.in6_ifaddrs[0].addr));
485 buf += sizeof(T_PPP_CI_HDR) + sizeof(new_cfg.in6_ifaddrs[0].addr);
486 len -= sizeof(T_PPP_CI_HDR) + sizeof(new_cfg.in6_ifaddrs[0].addr);
487 }
488
489 /* 長さが 0 でなければエラー */
490 if (len != 0)
491 return 0;
492
493 /* 新しいオプションを設定する。*/
494 if (fsm->state != PPP_FSM_OPENED)
495 ipv6cp_local_neg_cfg = new_cfg;
496
497 return 1;
498 }
499
500/*
501 * ipv6cp_reqci -- 相手の構成情
502報を解析する。
503 */
504
505static int_t
506ipv6cp_reqci (T_PPP_FSM *fsm, T_NET_BUF *input, T_NET_BUF *output)
507{
508 T_IN6_ADDR addr;
509 uint16_t code, final, len, cilen;
510 uint8_t *np, *rp, *ap, *cp, type = 0;
511
512 rp = ap = input->buf + sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR);
513 /* rp: REJ、ap: ACK する CI のポインタ */
514 /* 拒否する場合は、引数 buf に上書きする。 */
515 len = input->len - (sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR));
516 np = output->buf + sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR);
517 final = PPP_CONFACK; /* 最終的に送信するコード */
518 while (len > 0) {
519 code = PPP_CONFACK;
520 cp = ap; /* cp: 現在処理中の CI */
521
522 if (len < sizeof(T_PPP_CI_HDR)) {
523
524 /* 残りが CI ヘッダより短い */
525 syslog(LOG_NOTICE, "[PPP/IPV6CP] bad CI len: %d.", len);
526 cilen = len; /* データ長が異常の場合の処置 */
527 len = 0; /* ループから抜ける。 */
528 code = PPP_CONFREJ;
529 goto endswitch;
530 }
531
532 type = *ap ++; /* CI の型 */
533 cilen = *ap ++; /* CI の長さ */
534 if (len < cilen) {
535
536 /* 残りが CI 長より短い */
537 syslog(LOG_NOTICE, "[PPP/IPV6CP] bad CI len: %d.", cilen);
538 cilen = len; /* データ長が異常の場合の処置 */
539 len = 0; /* ループから抜ける。 */
540 code = PPP_CONFREJ;
541 goto endswitch;
542 }
543 len -= sizeof(T_PPP_CI_HDR);
544
545 /* CI の型により分岐する。*/
546 switch (type) {
547
548 case IPV6CP_CIT_ADDR: /* IPv6 アドレス */
549
550 /* CI 長が、ヘッダ + 4 オクテットでなければエラー */
551 if (cilen != sizeof(T_PPP_CI_HDR) + sizeof(addr))
552 code = PPP_CONFREJ;
553 else {
554 memcpy((uint8_t*)&ipv6cp_remote_neg_cfg.in6_ifaddrs[0].addr, ap,
555 sizeof(ipv6cp_remote_neg_cfg.in6_ifaddrs[0].addr));
556 if (!IN6_ARE_ADDR_EQUAL(&addr, &ipv6cp_remote_neg_cfg.in6_ifaddrs[0].addr) &&
557 (IN6_IS_ADDR_UNSPECIFIED(&addr) ||
558 IN6_IS_ADDR_UNSPECIFIED(&ipv6cp_remote_neg_cfg.in6_ifaddrs[0].addr))) {
559 memcpy(np, (uint8_t*)&ipv6cp_remote_neg_cfg.in6_ifaddrs[0].addr,
560 sizeof(ipv6cp_remote_neg_cfg.in6_ifaddrs[0].addr));
561 *np ++ = IPV6CP_CIT_ADDR;
562 *np ++ = sizeof(T_PPP_CI_HDR) + sizeof(uint32_t);
563 np += sizeof(ipv6cp_remote_neg_cfg.in6_ifaddrs[0].addr);
564 code = PPP_CONFNAK;
565 }
566#if 1 /* 要確認 */
567 else if (IN6_IS_ADDR_UNSPECIFIED(&addr) &&
568 IN6_IS_ADDR_UNSPECIFIED(&ipv6cp_remote_neg_cfg.in6_ifaddrs[0]))
569#else
570 else if (IN6_IS_ADDR_UNSPECIFIED(&addr) ||
571 IN6_IS_ADDR_UNSPECIFIED(&ipv6cp_remote_neg_cfg.in6_ifaddrs[0]))
572#endif
573 code = PPP_CONFREJ;
574 else
575 ipv6cp_remote_neg_cfg.in6_ifaddrs[0].addr = addr;
576 }
577 break;
578
579 default:
580 syslog(LOG_INFO, "[PPP/IPV6CP] unexp opt: %d.", type);
581 code = PPP_CONFREJ;
582 break;
583 }
584endswitch:
585
586 if (code == PPP_CONFNAK) {
587 /* CI の型が Magic Number の場合を除いて、NAK の回数が */
588 /* 最大値 MAX_PPP_FAILURES を超
589えたら拒否する。 */
590 if (fsm->failures >= MAX_PPP_FAILURES)
591 code = PPP_CONFREJ;
592 else if (final != PPP_CONFREJ)
593 final = PPP_CONFNAK;
594 }
595
596 /* この CI を拒否する */
597 if (code == PPP_CONFREJ) {
598 if (rp < cp) /* 前に詰める。*/
599 memcpy(rp, cp, cilen);
600 rp += cilen;
601 final = PPP_CONFREJ;
602 }
603
604 ap += cilen - sizeof(T_PPP_CI_HDR);
605 len -= cilen - sizeof(T_PPP_CI_HDR);
606 }
607
608 /* 最終的な長さを調整する。*/
609 switch (final) {
610 case PPP_CONFNAK:
611 output->len = np - output->buf;
612 memcpy(output->buf, input->buf, sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR));
613 break;
614 case PPP_CONFREJ:
615 memcpy(output->buf, input->buf, output->len = rp - input->buf);
616 break;
617 case PPP_CONFACK:
618 memcpy(output->buf, input->buf, input->len);
619 break;
620 }
621
622 return final;
623 }
624
625/*
626 * ipv6cp_up -- リンク接続を確立する。
627 */
628
629static void
630ipv6cp_up (T_PPP_FSM *fsm)
631{
632 /* 自構成情
633報の初期設定 */
634 ipv6cp_local_ack_cfg = ipv6cp_local_neg_cfg;
635
636 sig_sem(SEM_IPV6CP_READY);
637
638 syslog(LOG_NOTICE, "[PPP/IPV6CP] up, Local IPv6 Addr: %s, Remote IPv6 Addr: %s.",
639 ipv62str(NULL, &ipv6cp_local_neg_cfg.in6_ifaddrs[0].addr),
640 ipv62str(NULL, &ipv6cp_remote_neg_cfg.in6_ifaddrs[0].addr));
641 }
642
643/*
644 * ipv6cp_down -- リンク接続を解放する。
645 */
646
647static void
648ipv6cp_down (T_PPP_FSM *fsm)
649{
650 sig_sem(SEM_IPV6CP_READY);
651 syslog(LOG_NOTICE, "[PPP/IPV6CP] down.");
652 }
653
654/*
655 * ipv6cp_finished -- 下位層を終了する。
656 */
657
658static void
659ipv6cp_finished (T_PPP_FSM *fsm)
660{
661 }
662
663/*
664 * ipv6cp_protrej -- Proto-REJ を受信したときの処理
665 */
666
667static void
668ipv6cp_protrej (void)
669{
670 fsm_lowerdown(&ipv6cp_fsm);
671 }
672
673/*
674 * ipv6cp_lowerup -- IPV6CP 下位層を起動する。
675 */
676
677static void
678ipv6cp_lowerup (void)
679{
680 fsm_lowerup(&ipv6cp_fsm);
681 }
682
683/*
684 * ipv6cp_lowerdown -- IPV6CP 下位層を停止する。
685 */
686
687static void
688ipv6cp_lowerdown (void)
689{
690 fsm_lowerdown(&ipv6cp_fsm);
691 }
692
693/*
694 * ipv6cp_open -- IPV6CP のオープン
695 */
696
697static void
698ipv6cp_open (void)
699{
700 fsm_open(&ipv6cp_fsm);
701 }
702
703/*
704 * ipv6cp_close -- IPV6CP のクローズ
705 */
706
707static void
708ipv6cp_close (void)
709{
710 fsm_close(&ipv6cp_fsm);
711 }
712
713#endif /* fo #ifdef SUPPORT_PPP */
Note: See TracBrowser for help on using the repository browser.