source: EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/in6_subr.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: 19.9 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) 1995, 1996, 1997, and 1998 WIDE Project.
36 * All rights reserved.
37 *
38 * Redistribution and use in source and binary forms, with or without
39 * modification, are permitted provided that the following conditions
40 * are met:
41 * 1. Redistributions of source code must retain the above copyright
42 * notice, this list of conditions and the following disclaimer.
43 * 2. Redistributions in binary form must reproduce the above copyright
44 * notice, this list of conditions and the following disclaimer in the
45 * documentation and/or other materials provided with the distribution.
46 * 3. Neither the name of the project nor the names of its contributors
47 * may be used to endorse or promote products derived from this software
48 * without specific prior written permission.
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
51 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
52 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
53 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
54 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
55 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
56 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
57 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
58 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
59 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
60 * SUCH DAMAGE.
61 */
62
63/*
64 * Copyright (c) 1985, 1986, 1993
65 * The Regents of the University of California. All rights reserved.
66 *
67 * Redistribution and use in source and binary forms, with or without
68 * modification, are permitted provided that the following conditions
69 * are met:
70 * 1. Redistributions of source code must retain the above copyright
71 * notice, this list of conditions and the following disclaimer.
72 * 2. Redistributions in binary form must reproduce the above copyright
73 * notice, this list of conditions and the following disclaimer in the
74 * documentation and/or other materials provided with the distribution.
75 * 3. All advertising materials mentioning features or use of this software
76 * must display the following acknowledgement:
77 * This product includes software developed by the University of
78 * California, Berkeley and its contributors.
79 * 4. Neither the name of the University nor the names of its contributors
80 * may be used to endorse or promote products derived from this software
81 * without specific prior written permission.
82 *
83 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
84 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
85 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
86 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
87 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
88 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
89 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
90 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
91 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
92 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
93 * SUCH DAMAGE.
94 */
95
96#include <string.h>
97
98#ifdef TARGET_KERNEL_ASP
99
100#include <kernel.h>
101#include <sil.h>
102#include "kernel_cfg.h"
103
104#endif /* of #ifdef TARGET_KERNEL_ASP */
105
106#ifdef TARGET_KERNEL_JSP
107
108#include <s_services.h>
109#include <t_services.h>
110#include "kernel_id.h"
111#include "tinet_id.h"
112
113#endif /* of #ifdef TARGET_KERNEL_JSP */
114
115#include <tinet_defs.h>
116#include <tinet_config.h>
117
118#include <net/if.h>
119#include <net/if_loop.h>
120#include <net/if_ppp.h>
121#include <net/ethernet.h>
122#include <net/if_arp.h>
123#include <net/net.h>
124#include <net/net_var.h>
125#include <net/net_buf.h>
126#include <net/net_timer.h>
127
128#include <netinet/in.h>
129#include <netinet/in_var.h>
130
131#include <netinet6/in6.h>
132#include <netinet6/in6_var.h>
133#include <netinet/ip6.h>
134#include <netinet6/ip6_var.h>
135#include <netinet6/ah.h>
136#include <netinet6/nd6.h>
137
138#include <net/if6_var.h>
139
140#ifdef SUPPORT_INET6
141
142#if NUM_IN6_HOSTCACHE_ENTRY > 0
143
144/*
145 * ホストキャッシュ
146 */
147
148static T_IN6_HOSTCACHE_ENTRY in6_hostcache[NUM_IN6_HOSTCACHE_ENTRY];
149
150#endif /* of #if NUM_IN6_HOSTCACHE_ENTRY > 0 */
151
152/*
153 * in6_lookup_ifaddr -- ネットワークインタフェースに割り当てられているアドレスを探索する。
154 */
155
156T_IN6_IFADDR *
157in6_lookup_ifaddr (T_IFNET *ifp, T_IN6_ADDR *addr)
158{
159 int_t ix;
160
161 for (ix = NUM_IN6_IFADDR_ENTRY; ix -- > 0; ) {
162 if ((ifp->in_ifaddrs[ix].flags & IN6_IFF_DEFINED) &&
163 IN6_ARE_ADDR_EQUAL(addr, &ifp->in_ifaddrs[ix].addr))
164 return &ifp->in_ifaddrs[ix];
165 }
166 return NULL;
167 }
168
169/*
170 * in6_lookup_multi -- ネットワークインタフェースのマルチキャストアドレスを検索する。
171 */
172
173bool_t
174in6_lookup_multi (T_IFNET *ifp, T_IN6_ADDR *maddr)
175{
176 int_t ix;
177
178 for (ix = MAX_IN6_MADDR_CNT; ix -- > 0; )
179 if (IN6_ARE_ADDR_EQUAL(maddr, &ifp->in_maddrs[ix]))
180 return true;
181 return false;
182 }
183
184/*
185 * in6_set_header -- IPv6 ヘッダを設定する。
186 */
187
188ER
189in6_set_header (T_NET_BUF *nbuf, uint_t len,
190 T_IN6_ADDR *dstaddr, T_IN6_ADDR *srcaddr,
191 uint8_t next, uint8_t hlim)
192{
193 T_IFNET *ifp = IF_GET_IFNET();
194 T_IP6_HDR *ip6h;
195 T_IN6_IFADDR *ia;
196
197 /*
198 * 宛先アドレスにふさわしい送信元アドレスを、
199 * ネットワークインタフェースから探索して利用する。
200 */
201 if (srcaddr == NULL || !IN6_IS_ADDR_UNSPECIFIED(srcaddr))
202 ;
203 else if ((ia = in6_ifawithifp(ifp, dstaddr)) == NULL)
204 return E_SYS;
205 else
206 srcaddr = &ia->addr;
207
208 /* IPv6 ヘッダを設定する。*/
209 ip6h = GET_IP6_HDR(nbuf);
210 ip6h->vcf = htonl(IP6_MAKE_VCF(IPV6_VERSION, 0));
211 ip6h->plen = htons(len);
212 ip6h->next = next;
213 ip6h->hlim = hlim;
214
215 if (dstaddr == NULL)
216 memset(&ip6h->dst, 0, sizeof(T_IN6_ADDR));
217 else
218 ip6h->dst = *dstaddr;
219
220 if (srcaddr == NULL)
221 memset(&ip6h->src, 0, sizeof(T_IN6_ADDR));
222 else
223 ip6h->src = *srcaddr;
224
225 return E_OK;
226 }
227
228/*
229 * in6_get_datagram -- IPv6 データグラムを獲得し、ヘッダを設定する。
230 */
231
232ER
233in6_get_datagram (T_NET_BUF **nbuf, uint_t len, uint_t maxlen,
234 T_IN6_ADDR *dstaddr, T_IN6_ADDR *srcaddr,
235 uint8_t next, uint8_t hlim, ATR nbatr, TMO tmout)
236{
237 ER error;
238 uint_t align;
239
240 /* データ長は 4 オクテット境界に調整する。 */
241 align = (len + 3) >> 2 << 2;
242
243 /* ネットワークバッファを獲得する。 */
244 if ((error = tget_net_buf_ex(nbuf, IF_IP6_HDR_SIZE + align,
245 IF_IP6_HDR_SIZE + maxlen, nbatr, tmout)) != E_OK)
246 return error;
247
248 /*
249 * より大きなサイズのネットワークバッファを獲得する場合のみ長さを調整する。
250 * より小さなサイズのネットワークバッファの獲得は、送信ウィンドバッファの
251 * 省コピー機能で使用され、実際に送信するまで、データサイズは決定できない。
252 */
253 if ((nbatr & NBA_SEARCH_ASCENT) != 0)
254 (*nbuf)->len = IF_IP6_HDR_SIZE + len;
255
256 /* IPv6 ヘッダを設定する。*/
257 if ((error = in6_set_header(*nbuf, len, dstaddr, srcaddr, next, hlim)) != E_OK)
258 return error;
259
260 /* 4 オクテット境界までパディングで埋める。*/
261 if (align > len)
262 memset(GET_IP6_SDU(*nbuf) + len, 0, align - len);
263
264 return E_OK;
265 }
266
267/*
268 * in6_get_maxnum_ifaddr -- インタフェースに設定可能な最大アドレス数を返す。
269 */
270
271ER_UINT
272in6_get_maxnum_ifaddr (void)
273{
274 return NUM_IN6_IFADDR_ENTRY;
275 }
276
277/*
278 * in6_get_ifaddr -- インタフェースに設定されているアドレスを返す。
279 */
280
281const T_IN6_ADDR *
282in6_get_ifaddr (int_t index)
283{
284 T_IFNET *ifp = IF_GET_IFNET();
285
286 if (index < NUM_IN6_IFADDR_ENTRY &&
287 (ifp->in_ifaddrs[index].flags & IN6_IFF_DEFINED))
288 return &ifp->in_ifaddrs[index].addr;
289 else
290 return NULL;
291 }
292
293/*
294 * ipv62str -- IPv6 アドレスを文字列に変換する。
295 */
296
297char *
298ipv62str (char *buf, const T_IN6_ADDR *p_ip6addr)
299{
300 static char addr_sbuf[NUM_IPV6ADDR_STR_BUFF][sizeof("0123:4567:89ab:cdef:0123:4567:89ab:cdef")];
301 static int_t bix = NUM_IPV6ADDR_STR_BUFF;
302
303 bool_t omit = false, zero = false;
304 char *start;
305 int_t ix;
306
307 if (buf == NULL) {
308 syscall(wai_sem(SEM_IP2STR_BUFF_LOCK));
309 buf = addr_sbuf[-- bix];
310 if (bix <= 0)
311 bix = NUM_IPV6ADDR_STR_BUFF;
312 syscall(sig_sem(SEM_IP2STR_BUFF_LOCK));
313 }
314
315 start = buf;
316 if (p_ip6addr == NULL) {
317 *buf ++ = ':';
318 *buf ++ = ':';
319 }
320 else {
321 for (ix = 0; ix < sizeof(T_IN6_ADDR) / 2; ix ++) {
322 if (omit) {
323 buf += convert_hexdigit(buf, ntohs(p_ip6addr->s6_addr16[ix]), 16, 0, ' ');
324 if (ix < 7)
325 *buf ++ = ':';
326 }
327 else if (ix > 0 && ix < 7 && p_ip6addr->s6_addr16[ix] == 0)
328 zero = true;
329 else {
330 if (zero) {
331 omit = true;
332 *buf ++ = ':';
333 }
334 buf += convert_hexdigit(buf, ntohs(p_ip6addr->s6_addr16[ix]), 16, 0, ' ');
335 if (ix < 7)
336 *buf ++ = ':';
337 }
338 }
339 }
340 *buf = '\0';
341 return start;
342 }
343
344/*
345 * in6_cksum -- IPv6 のトランスポート層ヘッダのチェックサムを計算する。
346 *
347 * 注意: 戻り値はネットワークバイトオーダ
348 */
349
350uint16_t
351in6_cksum (T_NET_BUF *nbuf, uint8_t proto, uint_t off, uint_t len)
352{
353 uint32_t sum;
354 uint_t align;
355
356 /* 4 オクテット境界のデータ長 */
357 align = (len + 3) >> 2 << 2;
358
359 /* 4 オクテット境界までパディングで埋める。*/
360 if (align > len)
361 memset((uint8_t*)nbuf->buf + off + len, 0, align - len);
362
363 sum = in_cksum_sum(nbuf->buf + off, align)
364 + in_cksum_sum(&GET_IP6_HDR(nbuf)->src, sizeof(T_IN6_ADDR) * 2)
365 + len + proto;
366 sum = in_cksum_carry(sum);
367
368 return ~htons((uint16_t)sum);
369 }
370
371/*
372 * in6_is_dstaddr_accept -- 宛先アドレスとして正しいかチェックする。
373 */
374
375bool_t
376in6_is_dstaddr_accept (T_IN6_ADDR *myaddr, T_IN6_ADDR *dstaddr)
377{
378 if (IN6_IS_ADDR_UNSPECIFIED(myaddr))
379 return in6_lookup_ifaddr(IF_GET_IFNET(), dstaddr) != NULL;
380 else
381 return IN6_ARE_ADDR_EQUAL(dstaddr, myaddr);
382 }
383
384/*
385 * get_ip6_hdr_size -- 拡張ヘッダも含めた IPv6 ヘッダ長を返す。
386 */
387
388uint_t
389get_ip6_hdr_size (T_IP6_HDR *iph)
390{
391 uint_t size = IP6_HDR_SIZE, hsize;
392 uint8_t curr = iph->next, next;
393 uint8_t *hdr = ((uint8_t *)iph) + IP6_HDR_SIZE;
394
395 while (1) {
396 next = *hdr;
397 if (curr ==IPPROTO_NONE) /* 次ヘッダ無し */
398 break;
399 else if (curr == IPPROTO_FRAGMENT) /* 断片化 */
400 hsize = sizeof(T_IP6_FRAG_HDR);
401 else if (curr == IPPROTO_AH) /* IPv6 認証 */
402 hsize = (((T_IP6_AH_HDR *)hdr)->len + 2) * 4;
403 else if (curr == IPPROTO_HOPOPTS || /* 中継点 (Hop-by-Hop) オプション */
404 curr == IPPROTO_DSTOPTS || /* IPv6 終点オプション */
405 curr == IPPROTO_ROUTING) /* 経路制御 */
406 hsize = (((T_IP6_EXT_HDR *)hdr)->len + 1) * 8;
407 else
408 break;
409 size += hsize;
410 hdr += hsize;
411 curr = next;
412 }
413 return size;
414 }
415
416/*
417 * in6_plen2pmask -- プレフィックス長からマスクを生成する。
418 */
419
420void
421in6_plen2pmask (T_IN6_ADDR *mask, uint_t prefix_len)
422{
423 uint8_t *ptr, bit;
424
425 memset(mask->s6_addr + prefix_len / 8, 0, (128 - prefix_len + 7) / 8);
426 for (ptr = mask->s6_addr; prefix_len > 0; ptr ++) {
427 for (bit = 0x80; bit && (prefix_len > 0); prefix_len --) {
428 *ptr |= bit;
429 bit >>= 1;
430 }
431 }
432 }
433
434/*
435 * in6_rtalloc -- ルーティング表を探索する。
436 */
437
438T_IN6_ADDR *
439in6_rtalloc (T_IFNET *ifp, T_IN6_ADDR *dst)
440{
441 if (IN6_IS_ADDR_LINKLOCAL(dst) || IN6_IS_ADDR_MULTICAST(dst))
442 return dst;
443 else {
444 T_IN6_IFADDR *ia;
445 SYSTIM now;
446 int_t ix;
447
448 /*
449 * サイトローカルアドレスか集約可能(グローバル)アドレスの場合は、
450 * 同一リンク内のノードであるかをチェックする。
451 */
452
453 syscall(get_tim(&now));
454 now /= SYSTIM_HZ;
455
456 /* 推奨有効時間内のアドレスを探索する。*/
457 for (ix = NUM_IN6_IFADDR_ENTRY; ix -- > 0; ) {
458 ia = &ifp->in_ifaddrs[ix];
459 if (IFA6_IS_READY(ia) &&
460 in6_are_prefix_equal(dst, &ia->addr, ia->prefix_len) &&
461 (int32_t)(ia->lifetime.preferred - now) > 0) {
462 /* ia->lifetime.preferred > now */
463 return dst;
464 }
465 }
466
467 /* 有効時間内のアドレスを探索する。*/
468 for (ix = NUM_IN6_IFADDR_ENTRY; ix -- > 0; ) {
469 ia = &ifp->in_ifaddrs[ix];
470 if (IFA6_IS_READY(ia) &&
471 in6_are_prefix_equal(dst, &ia->addr, ia->prefix_len) &&
472 (int32_t)(ia->lifetime.expire - now) > 0)
473 /* ia->lifetime.expire > now */
474 return dst;
475 }
476
477 /*
478 * プレフィックスを探索する。
479 */
480 if (nd6_onlink_prefix_lookup (dst) != NULL)
481 return dst;
482
483 /*
484 * 静的経路表を探索する。
485 */
486
487#if NUM_ROUTE_ENTRY > 0
488
489 syscall(wai_sem(SEM_IN_ROUTING_TBL));
490 for (ix = NUM_ROUTE_ENTRY; ix --; ) {
491 if ((routing_tbl[ix].flags & IN_RTF_DEFINED) &&
492 in6_are_prefix_equal(dst, &routing_tbl[ix].target,
493 routing_tbl[ix].prefix_len)) {
494
495 /*
496 * 向け直しによるエントリは、有効時間が切れる時刻を延長する。
497 * expire の単位は [s]。
498 * TMO_IN_REDIRECT の単位は [ms]。
499 */
500 if (ix > NUM_STATIC_ROUTE_ENTRY) {
501 SYSTIM now;
502
503 syscall(get_tim(&now));
504 routing_tbl[ix].expire = now / SYSTIM_HZ + TMO_IN_REDIRECT / 1000;
505 }
506
507 syscall(sig_sem(SEM_IN_ROUTING_TBL));
508 return &routing_tbl[ix].gateway;
509 }
510 }
511 syscall(sig_sem(SEM_IN_ROUTING_TBL));
512
513#endif /* of #if NUM_ROUTE_ENTRY > 0 */
514
515 /*
516 * ディフォルトルータ・リストを探索する。
517 */
518 return nd6_router_lookup();
519 }
520 }
521
522#if NUM_REDIRECT_ROUTE_ENTRY > 0
523
524/*
525 * in6_gateway_lookup -- ルーティング表のルータを探索する。
526 */
527
528T_IN_RTENTRY *
529in6_gateway_lookup (T_IN6_ADDR *gw)
530{
531 int_t ix;
532
533 for (ix = NUM_ROUTE_ENTRY; ix --; )
534 if ((routing_tbl[ix].flags & IN_RTF_DEFINED) &&
535 IN6_ARE_ADDR_EQUAL(&routing_tbl[ix].gateway, gw))
536 return &routing_tbl[ix];
537 return NULL;
538 }
539
540/*
541 * in6_rtredirect -- ルーティング表にエントリを登録する。
542 *
543 * 注意: 引数 tmo の単位は [ms]。
544 */
545
546void
547in6_rtredirect (T_IN6_ADDR *gateway, T_IN6_ADDR *target, uint_t prefix_len, uint8_t flags, uint32_t tmo)
548{
549 T_IN_RTENTRY *frt;
550
551 frt = in_rtnewentry(flags, tmo);
552 frt->gateway = *gateway;
553 frt->target = *target;
554 frt->prefix_len = prefix_len;
555 }
556
557#endif /* of #if NUM_REDIRECT_ROUTE_ENTRY > 0 */
558
559#if NUM_IN6_HOSTCACHE_ENTRY > 0
560
561/*
562 * in6_hostcache_lookup -- IPv6 ホストキャッシュを探索する。
563 */
564
565static T_IN6_HOSTCACHE_ENTRY*
566in6_hostcache_lookup (T_IN6_ADDR *dst)
567{
568 int_t ix;
569
570 for (ix = NUM_IN6_HOSTCACHE_ENTRY; ix -- > 0; ) {
571 if (IN6_ARE_ADDR_EQUAL(dst, &in6_hostcache[ix].dst))
572 return &in6_hostcache[ix];
573 }
574 return NULL;
575 }
576
577/*
578 * in6_hostcache_update -- IPv6 ホストキャッシュを更新する。
579 */
580
581void
582in6_hostcache_update (T_IN6_ADDR *dst, uint32_t mtu)
583{
584 T_IN6_HOSTCACHE_ENTRY *hc;
585 SYSTIM now, old;
586 int_t ix, oix;
587
588 syscall(get_tim(&now));
589
590 /* 既に登録されているか探索する。*/
591 if ((hc = in6_hostcache_lookup (dst)) == NULL) {
592
593 /* 空きのホストキャッシュを探す。*/
594 for (ix = NUM_IN6_HOSTCACHE_ENTRY; ix -- > 0; ) {
595 if (IN6_IS_HOSTCACHE_FREE(&in6_hostcache[ix]))
596 break;
597 }
598
599 if (ix < 0) {
600 /*
601 * 空きが無い時は、有効時間の切れる時間が、
602 * 最も短いホストキャッシュを置換する。
603 */
604 old = now - 1;
605 oix = 0;
606 for (ix = NUM_IN6_HOSTCACHE_ENTRY; ix -- > 0; ) {
607 hc = &in6_hostcache[ix];
608 if (IN6_IS_HOSTCACHE_BUSY(hc) && (int32_t)(hc->expire - old) < 0) {
609 /* hc->expire < old */
610 oix = ix;
611 old = hc->expire;
612 }
613 }
614 ix = oix;
615 }
616 hc = &in6_hostcache[ix];
617 }
618 else if (mtu > hc->mtu &&
619 (int32_t)(hc->expire - now) >= (IN6_HOSTCACHE_EXPIRE - IN6_HOSTCACHE_INCREASE)) {
620
621 /*
622 * 既に登録されていて、新しい MTU が、登録されている MTU より大きいとき、
623 * IN6_HOSTCACHE_INCREASE(推奨 10 分)間は更新しない。
624 */
625 return;
626 }
627 hc->dst = *dst;
628 hc->expire = now + IN6_HOSTCACHE_EXPIRE;
629 hc->mtu = mtu;
630 }
631
632/*
633 * in6_hostcache_getmtu -- IPv6 ホストキャッシュをから MTU を取得する。
634 *
635 * 戻り値が 0 であれば、ホストキャッシュに登録されていない。
636 */
637
638uint32_t
639in6_hostcache_getmtu (T_IN6_ADDR *dst)
640{
641 T_IN6_HOSTCACHE_ENTRY *hc;
642
643 /* 既に登録されているか探索する。*/
644 if ((hc = in6_hostcache_lookup(dst)) == NULL)
645 return 0;
646 else
647 return hc->mtu;
648 }
649
650/*
651 * in6_hostcache_timer -- IPv6 ホストキャッシュ更新タイマー
652 *
653 * 1秒周期で起動される。
654 */
655
656static void
657in6_hostcache_timer (void)
658{
659 static int_t interval = IN6_HOSTCACHE_PRUNE / SYSTIM_HZ;
660
661 SYSTIM now;
662
663 interval --;
664 if (interval <= 0) {
665 syscall(get_tim(&now));
666 interval = IN6_HOSTCACHE_PRUNE / SYSTIM_HZ;
667 }
668 }
669
670#endif /* of #if NUM_IN6_HOSTCACHE_ENTRY > 0 */
671
672/*
673 * in6_timer -- IPv6 共通タイマー
674 *
675 * 1秒周期で起動される。
676 */
677
678static void
679in6_timer (void)
680{
681#if NUM_REDIRECT_ROUTE_ENTRY > 0
682
683 in_rttimer();
684
685#endif /* of #if NUM_REDIRECT_ROUTE_ENTRY > 0 */
686
687#ifdef IP6_CFG_FRAGMENT
688
689 frag6_timer();
690
691#endif /* of #ifdef IP6_CFG_FRAGMENT */
692
693#if NUM_IN6_HOSTCACHE_ENTRY > 0
694
695 in6_hostcache_timer();
696
697#endif /* of #if NUM_IN6_HOSTCACHE_ENTRY > 0 */
698
699 timeout((callout_func)in6_timer, NULL, IN_TIMER_TMO);
700 }
701
702/*
703 * in6_init -- IPv6 共通機能を初期化する。
704 */
705
706void
707in6_init (void)
708{
709#if NUM_REDIRECT_ROUTE_ENTRY > 0
710
711 in_rtinit();
712
713#endif /* of #if NUM_REDIRECT_ROUTE_ENTRY > 0 */
714
715 timeout((callout_func)nd6_timer, NULL, ND6_TIMER_TMO);
716 timeout((callout_func)in6_timer, NULL, IN_TIMER_TMO);
717 }
718
719#endif /* of #ifdef SUPPORT_INET6 */
Note: See TracBrowser for help on using the repository browser.