source: EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/in6_subr.c@ 270

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

mruby版ECNLプロトタイピング・ツールを追加

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