source: azure_iot_hub/trunk/asp3_dcre/tinet/netinet6/in6.c@ 389

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

ビルドが通るよう更新

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 15.4 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 * 上記著作権者は,以下の (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/* $FreeBSD: src/sys/netinet6/in6.c,v 1.21 2002/04/19 04:46:22 suz Exp $ */
35/* $KAME: in6.c,v 1.259 2002/01/21 11:37:50 keiichi Exp $ */
36
37/*
38 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
39 * All rights reserved.
40 *
41 * Redistribution and use in source and binary forms, with or without
42 * modification, are permitted provided that the following conditions
43 * are met:
44 * 1. Redistributions of source code must retain the above copyright
45 * notice, this list of conditions and the following disclaimer.
46 * 2. Redistributions in binary form must reproduce the above copyright
47 * notice, this list of conditions and the following disclaimer in the
48 * documentation and/or other materials provided with the distribution.
49 * 3. Neither the name of the project nor the names of its contributors
50 * may be used to endorse or promote products derived from this software
51 * without specific prior written permission.
52 *
53 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
54 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
55 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
56 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
57 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
58 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
59 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
60 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
61 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
62 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
63 * SUCH DAMAGE.
64 */
65
66/*
67 * Copyright (c) 1982, 1986, 1991, 1993
68 * The Regents of the University of California. All rights reserved.
69 *
70 * Redistribution and use in source and binary forms, with or without
71 * modification, are permitted provided that the following conditions
72 * are met:
73 * 1. Redistributions of source code must retain the above copyright
74 * notice, this list of conditions and the following disclaimer.
75 * 2. Redistributions in binary form must reproduce the above copyright
76 * notice, this list of conditions and the following disclaimer in the
77 * documentation and/or other materials provided with the distribution.
78 * 3. All advertising materials mentioning features or use of this software
79 * must display the following acknowledgement:
80 * This product includes software developed by the University of
81 * California, Berkeley and its contributors.
82 * 4. Neither the name of the University nor the names of its contributors
83 * may be used to endorse or promote products derived from this software
84 * without specific prior written permission.
85 *
86 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
87 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
88 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
89 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
90 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
91 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
92 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
93 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
94 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
95 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
96 * SUCH DAMAGE.
97 *
98 * @(#)in.c 8.2 (Berkeley) 11/15/93
99 */
100
101#include <string.h>
102
103#ifdef TARGET_KERNEL_ASP
104
105#include <kernel.h>
106#include <sil.h>
107
108#endif /* of #ifdef TARGET_KERNEL_ASP */
109
110#ifdef TARGET_KERNEL_JSP
111
112#include <s_services.h>
113#include <t_services.h>
114#include "kernel_id.h"
115
116#endif /* of #ifdef TARGET_KERNEL_JSP */
117
118#include <tinet_defs.h>
119#include <tinet_config.h>
120
121#include <net/if.h>
122#include <net/if_types.h>
123#include <net/if_ppp.h>
124#include <net/if_loop.h>
125#include <net/ethernet.h>
126#include <net/ppp_ipcp.h>
127#include <net/net.h>
128#include <net/net_endian.h>
129#include <net/net_buf.h>
130#include <net/net_timer.h>
131#include <net/net_count.h>
132
133#include <netinet/in.h>
134#include <netinet/in_var.h>
135
136#include <netinet6/in6.h>
137#include <netinet6/in6_var.h>
138#include <netinet6/nd6.h>
139#include <netinet6/in6_ifattach.h>
140
141#include <net/if_var.h>
142
143#ifdef _IP6_CFG
144
145/*
146 * 全域変数
147 */
148
149const T_IN6_ADDR in6_addr_unspecified =
150 IPV6_ADDR_UNSPECIFIED_INIT;
151
152const T_IN6_ADDR in6_addr_linklocal_allnodes =
153 IPV6_ADDR_LINKLOCAL_ALLNODES_INIT;
154
155const T_IN6_ADDR in6_addr_linklocal_allrouters =
156 IPV6_ADDR_LINKLOCAL_ALLROUTERS_INIT;
157
158/*
159 * in6_addmulti -- マルチキャストアドレスを登録する。
160 */
161
162static ER
163in6_addmulti (T_IFNET *ifp, T_IN6_ADDR *maddr)
164{
165 ER error = E_OK;
166
167 if ((error = if_addmulti(ifp, maddr, AT_INET6)) != E_OK)
168 return error;
169
170 return error;
171 }
172
173/*
174 * in6_ifinit -- インタフェースにアドレス情報を設定し、初期化する。
175 */
176
177static ER
178in6_ifinit (T_IFNET *ifp, T_IN6_IFADDR *ia, const T_IN6_ADDR *addr, uint_t prefix_len)
179{
180 /* アドレスとプレフィックス長を設定する。*/
181 ia->addr = *addr;
182 ia->prefix_len = prefix_len;
183
184 /* フラグを初期化する。*/
185 ia->flags = 0;
186
187 /*
188 * 初めてアドレスが設定されたとき、インタフェース独自の初期化を行う。
189 */
190
191 return E_OK;
192 }
193
194/*
195 * in6_ifainit -- インタフェースアドレス構造体の初期化
196 */
197
198void
199in6_ifainit (void)
200{
201 T_IN6_IFADDR *ia = NULL;
202 T_IFNET *ifp = IF_GET_IFNET();
203 int_t ix;
204
205 for (ix = NUM_IN6_IFADDR_ENTRY; ix -- > 0; ) {
206 ia = &ifp->in6_ifaddrs[ix];
207 memset(ia, sizeof(T_IN6_IFADDR), 0);
208 ia->router_index = IN6_RTR_IX_UNREACH;
209 ia->prefix_index = ND6_PREFIX_IX_INVALID;
210 }
211 }
212
213/*
214 * in6_if2idlen -- インタフェース ID 長を返す。
215 */
216
217int_t
218in6_if2idlen (T_IFNET *ifp)
219{
220#if IF_TYPE == IFT_ETHER
221 return 64;
222#else
223 return 64;
224#endif
225 }
226
227/*
228 * in6_addr2ifaix -- アドレスからインタフェースアドレス情報のインデックスに変換する。
229 */
230
231int_t
232in6_addr2ifaix (const T_IN6_ADDR *addr)
233{
234 T_IFNET *ifp = IF_GET_IFNET();
235 T_IN6_IFADDR *ia;
236 int_t ix;
237
238 for (ix = NUM_IN6_IFADDR_ENTRY; ix -- > 0; ) {
239 ia = &ifp->in6_ifaddrs[ix];
240 if ((ia->flags & IN6_IFF_DEFINED) != 0 &&
241 in6_are_prefix_equal(addr, &ia->addr, ia->prefix_len))
242 return ix;
243 }
244
245 return IPV6_IFADDR_IX_INVALID;
246 }
247
248/*
249 * in6_addr2maix -- アドレスからマルチキャストアドレスのインデックスに変換する。
250 */
251
252int_t
253in6_addr2maix (const T_IN6_ADDR *addr)
254{
255 if (addr->s6_addr8[0] == 0xff) {
256 if (addr->s6_addr8[1] == 0x02) {
257 if (addr->s6_addr8[11] == 0x01 && addr->s6_addr8[12] == 0xff)
258 return IPV6_MADDR_IX_SOL_NODE;
259 else
260 return IPV6_MADDR_IX_LL_ALL_NODE;
261 }
262 else
263 return IPV6_MADDR_IX_EXTRA;
264 }
265 else
266 return IPV6_MADDR_IX_EXTRA;
267 }
268
269/*
270 * in6_update_ifa -- インタフェースのアドレス情報を更新する。
271 */
272
273ER
274in6_update_ifa (T_IFNET *ifp, T_IN6_IFADDR *ia, const T_IN6_ADDR *addr,
275 uint_t prefix_len, uint32_t vltime, uint32_t pltime,
276 int_t router_index, int_t prefix_index, uint_t flags)
277{
278 T_IN6_ADDR llsol;
279 ER error = E_OK;
280 SYSTIM now;
281
282 /* 引数をチェックする。*/
283 if (addr == NULL)
284 return E_PAR;
285
286 /*
287 * 有効時間をチェックする。
288 * vltime (有効時間) と pltime (推奨有効時間) の単位は [s]。
289 */
290 syscall(get_tim(&now));
291 now /= SYSTIM_HZ;
292
293 if (((vltime != ND6_INFINITE_LIFETIME) && (vltime + now < now)) || vltime == 0)
294 return E_PAR;
295
296 if ((pltime != ND6_INFINITE_LIFETIME) && (pltime + now < now))
297 return E_PAR;
298
299 /* インタフェースを初期化する。*/
300 if ((error = in6_ifinit(ifp, ia, addr, prefix_len)) != E_OK)
301 return error;
302
303 if (IN6_IS_ADDR_LINKLOCAL(addr)) {
304
305 /* 要請マルチキャストアドレスを登録する。*/
306 llsol.s6_addr32[0] = IPV6_ADDR_INT32_MLL;
307 llsol.s6_addr32[1] = 0x00000000;
308 llsol.s6_addr32[2] = IPV6_ADDR_INT32_ONE;
309 llsol.s6_addr32[3] = addr->s6_addr32[3];
310 llsol.s6_addr8[12] = 0xff;
311 if ((error = in6_addmulti(ifp, &llsol)) != E_OK)
312 return error;
313
314 /* 全ノード・リンクローカル・マルチキャストアドレスを登録する。*/
315 llsol.s6_addr32[2] = 0x00000000;
316 llsol.s6_addr32[3] = IPV6_ADDR_INT32_ONE;
317 if ((error = in6_addmulti(ifp, &llsol)) != E_OK)
318 return error;
319
320 }
321
322 /* ルータインデックスを設定する。*/
323 ia->router_index = router_index;
324
325 /* プレフィックスインデックスを設定する。*/
326 ia->prefix_index = prefix_index;
327
328 /* フラグを設定する。*/
329 ia->flags = flags & ~(IN6_IFF_DUPLICATED | IN6_IFF_NODAD);
330 ia->flags |= IN6_IFF_DEFINED;
331
332 /*
333 * アドレス有効時間を設定する。
334 * vltime (有効時間) と pltime (推奨有効時間) の単位は [s]。
335 */
336 syscall(get_tim(&now));
337 now /= SYSTIM_HZ;
338
339 ia->lifetime.vltime = vltime;
340 if (vltime != ND6_INFINITE_LIFETIME)
341 ia->lifetime.expire = now + vltime;
342 else
343 ia->lifetime.expire = 0;
344
345 ia->lifetime.pltime = pltime;
346 if (pltime != ND6_INFINITE_LIFETIME)
347 ia->lifetime.preferred = now + pltime;
348 else
349 ia->lifetime.preferred = 0;
350
351 /* 近隣探索の初期設定を行う。*/
352 nd6_ifattach(ifp);
353
354 /* 重複アドレス検出を行う。*/
355 if ((flags & IN6_IFF_NODAD) == 0) {
356 ia->flags |= IN6_IFF_TENTATIVE;
357 nd6_dad_start(ifp, ia, NULL);
358 }
359
360 return error;
361 }
362
363/*
364 * in6ifa_ifpwithix -- インデックス番号から、ネットワークインタフェースに
365 * 割り当てられているアドレスを探索する。
366 */
367
368T_IN6_IFADDR *
369in6ifa_ifpwithix (T_IFNET *ifp, int_t ix)
370{
371 return ix < NUM_IN6_IFADDR_ENTRY? &ifp->in6_ifaddrs[ix] : NULL;
372 }
373
374/*
375 * in6ifa_ifpwithrtrix -- ルータのインデックス番号から、ネットワークインタフェースに
376 * 割り当てられているアドレスを探索する。
377 */
378
379T_IN6_IFADDR *
380in6ifa_ifpwithrtrix (T_IFNET *ifp, int_t router_index)
381{
382 int_t ix;
383
384 for (ix = NUM_IN6_IFADDR_ENTRY; ix -- > 0; )
385 if (ifp->in6_ifaddrs[ix].router_index == router_index)
386 return &ifp->in6_ifaddrs[ix];
387 return NULL;
388 }
389
390/*
391 * in6_ifawithifp -- 宛先アドレスにふさわしい送信元アドレス情報を、
392 * ネットワークインタフェースから探索する。
393 */
394
395T_IN6_IFADDR *
396in6_ifawithifp (T_IFNET *ifp, const T_IN6_ADDR *dst)
397{
398 uint_t scope;
399 int_t ix;
400
401 /* 宛先アドレスと同じスコープのアドレスを返す。*/
402 if ((ix = in6_addr2ifaix(dst)) != IPV6_IFADDR_IX_INVALID)
403 return &ifp->in6_ifaddrs[ix];
404 else if ((ix = in6_addr2maix(dst)) == IPV6_MADDR_IX_SOL_NODE ||
405 ix == IPV6_MADDR_IX_LL_ALL_NODE)
406 return &ifp->in6_ifaddrs[IPV6_IFADDR_IX_LINKLOCAL];
407 else {
408 scope = in6_addrscope(dst);
409 for (ix = NUM_IN6_IFADDR_ENTRY; ix -- > 0; ) {
410 if ((ifp->in6_ifaddrs[ix].flags & IN6_IFF_DEFINED) &&
411 (ifp->in6_ifaddrs[ix].flags & IN6_IFF_DETACHED) == 0 &&
412 in6_addrscope(&ifp->in6_ifaddrs[ix].addr) == scope) {
413 return &ifp->in6_ifaddrs[ix];
414 }
415 }
416 return NULL;
417 }
418 }
419
420/*
421 * in6_addrwithifp -- 宛先アドレスにふさわしい送信元アドレスを、
422 * ネットワークインタフェースから探索する。
423 */
424
425const T_IN6_ADDR *
426in6_addrwithifp (T_IFNET *ifp, T_IN6_ADDR *src, const T_IN6_ADDR *dst)
427{
428 T_IN6_IFADDR *ifaddr;
429
430 if ((ifaddr = in6_ifawithifp(ifp, dst)) == NULL)
431 return NULL;
432 else {
433 *src = ifaddr->addr;
434 return src;
435 }
436 }
437
438/*
439 * in6_if_up -- インタフェース起動後の重複アドレス検出を行う。
440 */
441
442void
443in6_if_up (T_IFNET *ifp)
444{
445#if 0 /* 保留 */
446 int_t dad_delay, ix;
447#endif /* of #if 0 */
448
449 in6_ifattach(ifp);
450
451#if 0 /* 保留 */
452 /* 重複アドレス検出を行う。*/
453 dad_delay = 0;
454 for (ix = NUM_IN6_IFADDR_ENTRY; ix -- > 0; )
455 if ((ifp->in6_ifaddrs[ix].flags & IN6_IFF_DEFINED) &&
456 (ifp->in6_ifaddrs[ix].flags & IN6_IFF_TENTATIVE))
457 nd6_dad_start(ifp, &ifp->in6_ifaddrs[ix], &dad_delay);
458#endif /* of #if 0 */
459
460#if NUM_ND6_RTR_SOL_RETRY > 0
461
462 /* ルータ要請を出力する。*/
463 nd6_rtrsol_ctl();
464
465#endif /* of #if NUM_ND6_RTR_SOL_RETRY > 0 */
466 }
467
468/*
469 * in6_are_prefix_equal -- プレフィックスが同一か調べる。
470 */
471
472bool_t
473in6_are_prefix_equal (const T_IN6_ADDR *addr, const T_IN6_ADDR *prefix, uint_t prefix_len)
474{
475 uint_t bitlen, bytelen;
476
477 bytelen = prefix_len / 8;
478 if (memcmp(&addr->s6_addr, &prefix->s6_addr, bytelen))
479 return false;
480
481 bitlen = prefix_len % 8;
482 if ( addr->s6_addr[bytelen] >> (8 - bitlen) !=
483 prefix->s6_addr[bytelen] >> (8 - bitlen))
484 return false;
485
486 return true;
487 }
488
489/*
490 * in6_ifaddr_timer -- ネットワークインタフェースのアドレスの管理タイマー
491 */
492
493void
494in6_ifaddr_timer (T_IFNET *ifp)
495{
496 T_IN6_IFADDR *ia;
497 SYSTIM now;
498 int_t ix;
499
500 syscall(get_tim(&now));
501 for (ix = NUM_IN6_IFADDR_ENTRY; ix -- > 0; ) {
502 ia = &ifp->in6_ifaddrs[ix];
503
504 if ((ia->flags & IN6_IFF_DEFINED) == 0)
505 ;
506 else if (IFA6_IS_INVALID(ia, now)) {
507
508 /*
509 * 有効時間を過ぎたので削除する。
510 */
511 ia->flags &= ~IN6_IFF_DEFINED;
512 }
513
514 else if (IFA6_IS_DEPRECATED(ia, now)) {
515
516 /*
517 * 推奨有効時間を過ぎたので非推奨にする。
518 */
519 ia->flags |= IN6_IFF_DEPRECATED;
520 }
521 }
522 }
523
524#endif /* of #ifdef _IP6_CFG */
Note: See TracBrowser for help on using the repository browser.