source: EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/in6.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: 14.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/* $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_buf.h>
129#include <net/net_timer.h>
130#include <net/net_count.h>
131
132#include <netinet6/in6.h>
133#include <netinet6/in6_var.h>
134#include <netinet6/nd6.h>
135#include <netinet6/in6_ifattach.h>
136
137#include <net/if6_var.h>
138
139#ifdef SUPPORT_INET6
140
141/*
142 * 全域変数
143 */
144
145T_IN6_ADDR in6_addr_unspecified =
146 IPV6_ADDR_UNSPECIFIED_INIT;
147
148T_IN6_ADDR in6_addr_linklocal_allnodes =
149 IPV6_ADDR_LINKLOCAL_ALLNODES_INIT;
150
151T_IN6_ADDR in6_addr_linklocal_allrouters =
152 IPV6_ADDR_LINKLOCAL_ALLROUTERS_INIT;
153
154/*
155 * in6_addmulti -- マルチキャストアドレスを登録する。
156 */
157
158static ER
159in6_addmulti (T_IFNET *ifp, T_IN6_ADDR *maddr)
160{
161 ER error = E_OK;
162
163 if ((error = if_addmulti(ifp, maddr, AT_INET6)) != E_OK)
164 return error;
165
166 return error;
167 }
168
169/*
170 * in6_ifinit -- インタフェースにアドレス情報を設定し、初期化する。
171 */
172
173static ER
174in6_ifinit (T_IFNET *ifp, T_IN6_IFADDR *ia, T_IN6_ADDR *addr, uint_t prefix_len)
175{
176 /* アドレスとプレフィックス長を設定する。*/
177 ia->addr = *addr;
178 ia->prefix_len = prefix_len;
179
180 /* フラグを初期化する。*/
181 ia->flags = 0;
182
183 /*
184 * 初めてアドレスが設定されたとき、インタフェース独自の初期化を行う。
185 */
186
187 return E_OK;
188 }
189
190/*
191 * in6_ifainit -- インタフェースアドレス構造体の初期化
192 */
193
194void
195in6_ifainit (void)
196{
197 T_IN6_IFADDR *ia = NULL;
198 T_IFNET *ifp = IF_GET_IFNET();
199 int_t ix;
200
201 for (ix = NUM_IN6_IFADDR_ENTRY; ix -- > 0; ) {
202 ia = &ifp->in_ifaddrs[ix];
203 memset(ia, sizeof(T_IN6_IFADDR), 0);
204 ia->router_index = IN6_RTR_IX_UNREACH;
205 ia->prefix_index = ND6_PREFIX_IX_INVALID;
206 }
207 }
208
209/*
210 * in6_if2idlen -- インタフェース ID 長を返す。
211 */
212
213int_t
214in6_if2idlen (T_IFNET *ifp)
215{
216#if IF_TYPE == IFT_ETHER
217 return 64;
218#else
219 return 64;
220#endif
221 }
222
223/*
224 * in6_addr2ifaix -- アドレスからインタフェースアドレス情報のインデックスに変換する。
225 */
226
227int_t
228in6_addr2ifaix (T_IN6_ADDR *addr)
229{
230 T_IFNET *ifp = IF_GET_IFNET();
231 T_IN6_IFADDR *ia;
232 int_t ix;
233
234 for (ix = NUM_IN6_IFADDR_ENTRY; ix -- > 0; ) {
235 ia = &ifp->in_ifaddrs[ix];
236 if ((ia->flags & IN6_IFF_DEFINED) != 0 &&
237 in6_are_prefix_equal(addr, &ia->addr, ia->prefix_len))
238 return ix;
239 }
240
241 return IPV6_IFADDR_IX_INVALID;
242 }
243
244/*
245 * in6_addr2maix -- アドレスからマルチキャストアドレスのインデックスに変換する。
246 */
247
248int_t
249in6_addr2maix (T_IN6_ADDR *addr)
250{
251 if (addr->s6_addr8[0] == 0xff) {
252 if (addr->s6_addr8[1] == 0x02) {
253 if (addr->s6_addr8[11] == 0x01 && addr->s6_addr8[12] == 0xff)
254 return IPV6_MADDR_IX_SOL_NODE;
255 else
256 return IPV6_MADDR_IX_LL_ALL_NODE;
257 }
258 else
259 return IPV6_MADDR_IX_EXTRA;
260 }
261 else
262 return IPV6_MADDR_IX_EXTRA;
263 }
264
265/*
266 * in6_update_ifa -- インタフェースのアドレス情報を更新する。
267 */
268
269ER
270in6_update_ifa (T_IFNET *ifp, T_IN6_IFADDR *ia, T_IN6_ADDR *addr,
271 uint_t prefix_len, uint32_t vltime, uint32_t pltime,
272 int_t router_index, int_t prefix_index, uint_t flags)
273{
274 T_IN6_ADDR llsol;
275 ER error = E_OK;
276 SYSTIM now;
277
278 /* 引数をチェックする。*/
279 if (addr == NULL)
280 return E_PAR;
281
282 /*
283 * 有効時間をチェックする。
284 * vltime (有効時間) と pltime (推奨有効時間) の単位は [s]。
285 */
286 syscall(get_tim(&now));
287 now /= SYSTIM_HZ;
288
289 if (((vltime != ND6_INFINITE_LIFETIME) && (vltime + now < now)) || vltime == 0)
290 return E_PAR;
291
292 if ((pltime != ND6_INFINITE_LIFETIME) && (pltime + now < now))
293 return E_PAR;
294
295 /* インタフェースを初期化する。*/
296 if ((error = in6_ifinit(ifp, ia, addr, prefix_len)) != E_OK)
297 return error;
298
299 if (IN6_IS_ADDR_LINKLOCAL(addr)) {
300
301 /* 要請マルチキャストアドレスを登録する。*/
302 llsol.s6_addr32[0] = IPV6_ADDR_INT32_MLL;
303 llsol.s6_addr32[1] = 0x00000000;
304 llsol.s6_addr32[2] = IPV6_ADDR_INT32_ONE;
305 llsol.s6_addr32[3] = addr->s6_addr32[3];
306 llsol.s6_addr8[12] = 0xff;
307 if ((error = in6_addmulti(ifp, &llsol)) != E_OK)
308 return error;
309
310 /* 全ノード・リンクローカル・マルチキャストアドレスを登録する。*/
311 llsol.s6_addr32[2] = 0x00000000;
312 llsol.s6_addr32[3] = IPV6_ADDR_INT32_ONE;
313 if ((error = in6_addmulti(ifp, &llsol)) != E_OK)
314 return error;
315
316 }
317
318 /* ルータインデックスを設定する。*/
319 ia->router_index = router_index;
320
321 /* プレフィックスインデックスを設定する。*/
322 ia->prefix_index = prefix_index;
323
324 /* フラグを設定する。*/
325 ia->flags = flags & ~(IN6_IFF_DUPLICATED | IN6_IFF_NODAD);
326 ia->flags |= IN6_IFF_DEFINED;
327
328 /*
329 * アドレス有効時間を設定する。
330 * vltime (有効時間) と pltime (推奨有効時間) の単位は [s]。
331 */
332 syscall(get_tim(&now));
333 now /= SYSTIM_HZ;
334
335 ia->lifetime.vltime = vltime;
336 if (vltime != ND6_INFINITE_LIFETIME)
337 ia->lifetime.expire = now + vltime;
338 else
339 ia->lifetime.expire = 0;
340
341 ia->lifetime.pltime = pltime;
342 if (pltime != ND6_INFINITE_LIFETIME)
343 ia->lifetime.preferred = now + pltime;
344 else
345 ia->lifetime.preferred = 0;
346
347 /* 近隣探索の初期設定を行う。*/
348 nd6_ifattach(ifp);
349
350 /* 重複アドレス検出を行う。*/
351 if ((flags & IN6_IFF_NODAD) == 0) {
352 ia->flags |= IN6_IFF_TENTATIVE;
353 nd6_dad_start(ifp, ia, NULL);
354 }
355
356 return error;
357 }
358
359/*
360 * in6ifa_ifpwithix -- インデックス番号から、ネットワークインタフェースに
361 * 割り当てられているアドレスを探索する。
362 */
363
364T_IN6_IFADDR *
365in6ifa_ifpwithix (T_IFNET *ifp, int_t ix)
366{
367 return ix < NUM_IN6_IFADDR_ENTRY? &ifp->in_ifaddrs[ix] : NULL;
368 }
369
370/*
371 * in6ifa_ifpwithrtrix -- ルータのインデックス番号から、ネットワークインタフェースに
372 * 割り当てられているアドレスを探索する。
373 */
374
375T_IN6_IFADDR *
376in6ifa_ifpwithrtrix (T_IFNET *ifp, int_t router_index)
377{
378 int_t ix;
379
380 for (ix = NUM_IN6_IFADDR_ENTRY; ix -- > 0; )
381 if (ifp->in_ifaddrs[ix].router_index == router_index)
382 return &ifp->in_ifaddrs[ix];
383 return NULL;
384 }
385
386/*
387 * in6_ifawithifp -- 宛先アドレスにふさわしい送信元アドレスを、
388 * ネットワークインタフェースから探索する。
389 */
390
391T_IN6_IFADDR *
392in6_ifawithifp (T_IFNET *ifp, T_IN6_ADDR *dst)
393{
394 uint_t scope;
395 int_t ix;
396
397 /* 宛先アドレスと同じスコープのアドレスを返す。*/
398 if ((ix = in6_addr2ifaix(dst)) != IPV6_IFADDR_IX_INVALID)
399 return &ifp->in_ifaddrs[ix];
400 else if ((ix = in6_addr2maix(dst)) == IPV6_MADDR_IX_SOL_NODE ||
401 ix == IPV6_MADDR_IX_LL_ALL_NODE)
402 return &ifp->in_ifaddrs[IPV6_IFADDR_IX_LINKLOCAL];
403 else {
404 scope = in6_addrscope(dst);
405 for (ix = NUM_IN6_IFADDR_ENTRY; ix -- > 0; ) {
406 if ((ifp->in_ifaddrs[ix].flags & IN6_IFF_DEFINED) &&
407 (ifp->in_ifaddrs[ix].flags & IN6_IFF_DETACHED) == 0 &&
408 in6_addrscope(&ifp->in_ifaddrs[ix].addr) == scope) {
409 return &ifp->in_ifaddrs[ix];
410 }
411 }
412 return NULL;
413 }
414 }
415
416/*
417 * in6_if_up -- インタフェース起動後の重複アドレス検出を行う。
418 */
419
420void
421in6_if_up (T_IFNET *ifp)
422{
423#if 0 /* 保留 */
424 int_t dad_delay, ix;
425#endif /* of #if 0 */
426
427 in6_ifattach(ifp);
428
429#if 0 /* 保留 */
430 /* 重複アドレス検出を行う。*/
431 dad_delay = 0;
432 for (ix = NUM_IN6_IFADDR_ENTRY; ix -- > 0; )
433 if ((ifp->in_ifaddrs[ix].flags & IN6_IFF_DEFINED) &&
434 (ifp->in_ifaddrs[ix].flags & IN6_IFF_TENTATIVE))
435 nd6_dad_start(ifp, &ifp->in_ifaddrs[ix], &dad_delay);
436#endif /* of #if 0 */
437
438#if NUM_ND6_RTR_SOL_RETRY > 0
439
440 /* ルータ要請を出力する。*/
441 nd6_rtrsol_ctl();
442
443#endif /* of #if NUM_ND6_RTR_SOL_RETRY > 0 */
444 }
445
446/*
447 * in6_are_prefix_equal -- プレフィックスが同一か調べる。
448 */
449
450bool_t
451in6_are_prefix_equal (T_IN6_ADDR *addr, T_IN6_ADDR *prefix, uint_t prefix_len)
452{
453 uint_t bitlen, bytelen;
454
455 bytelen = prefix_len / 8;
456 if (memcmp(&addr->s6_addr, &prefix->s6_addr, bytelen))
457 return false;
458
459 bitlen = prefix_len % 8;
460 if ( addr->s6_addr[bytelen] >> (8 - bitlen) !=
461 prefix->s6_addr[bytelen] >> (8 - bitlen))
462 return false;
463
464 return true;
465 }
466
467/*
468 * in6_ifaddr_timer -- ネットワークインタフェースのアドレスの管理タイマー
469 */
470
471void
472in6_ifaddr_timer (T_IFNET *ifp)
473{
474 T_IN6_IFADDR *ia;
475 SYSTIM now;
476 int_t ix;
477
478 syscall(get_tim(&now));
479 for (ix = NUM_IN6_IFADDR_ENTRY; ix -- > 0; ) {
480 ia = &ifp->in_ifaddrs[ix];
481
482 if ((ia->flags & IN6_IFF_DEFINED) == 0)
483 ;
484 else if (IFA6_IS_INVALID(ia, now)) {
485
486 /*
487 * 有効時間を過ぎたので削除する。
488 */
489 ia->flags &= ~IN6_IFF_DEFINED;
490 }
491
492 else if (IFA6_IS_DEPRECATED(ia, now)) {
493
494 /*
495 * 推奨有効時間を過ぎたので非推奨にする。
496 */
497 ia->flags |= IN6_IFF_DEPRECATED;
498 }
499 }
500 }
501
502#endif /* of #ifdef SUPPORT_INET6 */
Note: See TracBrowser for help on using the repository browser.