source: asp3_gr_sakura/trunk/tinet/netinet/in4_subr.c@ 318

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

プロパティの文字コードにUTF-8を追加、キーワードを削除

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc; charset=UTF-8
File size: 14.1 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/*
35 * Copyright (c) 1982, 1986, 1988, 1993
36 * The Regents of the University of California. 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. All advertising materials mentioning features or use of this software
47 * must display the following acknowledgement:
48 * This product includes software developed by the University of
49 * California, Berkeley and its contributors.
50 * 4. Neither the name of the University nor the names of its contributors
51 * may be used to endorse or promote products derived from this software
52 * without specific prior written permission.
53 *
54 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
55 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
56 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
57 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
58 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
59 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
60 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
61 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
62 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
63 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
64 * SUCH DAMAGE.
65 */
66
67#include <string.h>
68
69#ifdef TARGET_KERNEL_ASP
70
71#include <kernel.h>
72#include <sil.h>
73#include "kernel_cfg.h"
74
75#endif /* of #ifdef TARGET_KERNEL_ASP */
76
77#ifdef TARGET_KERNEL_JSP
78
79#include <s_services.h>
80#include <t_services.h>
81#include "kernel_id.h"
82
83#endif /* of #ifdef TARGET_KERNEL_JSP */
84
85#include <tinet_defs.h>
86#include <tinet_config.h>
87
88#include <net/if.h>
89#include <net/if_loop.h>
90#include <net/if_ppp.h>
91#include <net/ethernet.h>
92//#include <net/ppp_ipcp.h>
93#include <net/net.h>
94#include <net/net_endian.h>
95#include <net/net_buf.h>
96#include <net/net_timer.h>
97
98#include <netinet/in.h>
99#include <netinet/in_var.h>
100#include <netinet/ip.h>
101#include <netinet/ip_var.h>
102
103#include <net/if_var.h>
104
105#if defined(_IP4_CFG)
106
107#if NUM_IN4_REDIRECT_ROUTE_ENTRY > 0
108
109/*
110 * in_rtinit -- ルーティング表を初期化する。
111 */
112
113void
114in_rtinit (void)
115{
116 int_t ix;
117
118 for (ix = 0; ix < NUM_IN4_STATIC_ROUTE_ENTRY; ix ++)
119 routing4_tbl[ix].flags = IN_RTF_DEFINED;
120
121 for ( ; ix < NUM_IN4_ROUTE_ENTRY; ix ++)
122 routing4_tbl[ix].flags = 0;
123 }
124
125/*
126 * in_rtnewentry -- 新しいエントリを獲得する。
127 */
128
129T_IN4_RTENTRY *
130in_rtnewentry (uint8_t flags, uint32_t tmo)
131{
132 SYSTIM now;
133 T_IN4_RTENTRY *rt, *frt = NULL;
134 int_t ix;
135
136 /* 空きエントリを探す。*/
137 for (ix = NUM_IN4_STATIC_ROUTE_ENTRY; ix < NUM_IN4_ROUTE_ENTRY; ix ++) {
138 rt = &routing4_tbl[ix];
139 if ((routing4_tbl[ix].flags & IN_RTF_DEFINED) == 0) {
140 frt = rt;
141 break;
142 }
143 }
144
145 /* expire の単位は [s]。*/
146 syscall(get_tim(&now));
147 now /= SYSTIM_HZ;
148
149 if (frt == NULL) {
150 /* 空きがなければ、有効時間がもっとも短いエントリを空きにする。*/
151 T_IN4_RTENTRY *srt = NULL;
152 int_t diff, sdiff = INT_MAX;
153
154 syscall(wai_sem(SEM_IN4_ROUTING_TBL));
155 for (ix = NUM_IN4_STATIC_ROUTE_ENTRY; ix < NUM_IN4_ROUTE_ENTRY; ix ++) {
156 rt = &routing4_tbl[ix];
157 diff = (int_t)(rt->expire - now);
158 if (diff <= 0) { /* rt->expire <= now */
159 /* 既に、有効時間が過ぎている。*/
160 frt = rt;
161 break;
162 }
163 else if (diff < sdiff) {
164 srt = rt;
165 sdiff = diff;
166 }
167 }
168 if (frt == NULL)
169 frt = srt;
170 frt->flags = 0;
171 syscall(sig_sem(SEM_IN4_ROUTING_TBL));
172 }
173
174 frt->flags = (uint8_t)(flags | IN_RTF_DEFINED);
175 frt->expire = now + tmo / SYSTIM_HZ;
176 return frt;
177 }
178
179/*
180 * in_rttimer -- ルーティング表の管理タイマー
181 */
182
183void
184in_rttimer (void)
185{
186 SYSTIM now;
187 int_t ix;
188
189 /* expire の単位は [s]。*/
190 syscall(get_tim(&now));
191 now /= SYSTIM_HZ;
192
193 syscall(wai_sem(SEM_IN4_ROUTING_TBL));
194 for (ix = NUM_IN4_STATIC_ROUTE_ENTRY; ix < NUM_IN4_ROUTE_ENTRY; ix ++)
195 if ((routing4_tbl[ix].flags & IN_RTF_DEFINED) &&
196 (int_t)(routing4_tbl[ix].expire - now) <= 0)
197 routing4_tbl[ix].flags = 0;
198 syscall(sig_sem(SEM_IN4_ROUTING_TBL));
199 }
200
201#endif /* of #if NUM_IN4_REDIRECT_ROUTE_ENTRY > 0 */
202
203/*
204 * in4_get_maxnum_ifaddr -- インタフェースに設定可能な最大アドレス数を返す。
205 */
206
207uint_t
208in4_get_maxnum_ifaddr (void)
209{
210 return 1;
211 }
212
213/*
214 * in4_get_ifaddr -- インタフェースに設定されているアドレスを返す。
215 */
216
217const T_IN4_ADDR *
218in4_get_ifaddr (int_t index)
219{
220 T_IFNET *ifp = IF_GET_IFNET();
221
222 return &ifp->in4_ifaddr.addr;
223 }
224
225/*
226 * in4_set_header -- IPv4 ヘッダを設定する。
227 */
228
229ER
230in4_set_header (T_NET_BUF *nbuf, uint_t len,
231 T_IN4_ADDR *dstaddr, T_IN4_ADDR *srcaddr, uint8_t proto, uint8_t ttl)
232{
233 T_IP4_HDR *ip4h = GET_IP4_HDR(nbuf);
234 T_IFNET *ifp = IF_GET_IFNET();
235
236 /* IP ヘッダを設定する。*/
237 ip4h->vhl = IP4_MAKE_VHL(IPV4_VERSION, IP4_HDR_SIZE >> 2);
238 ip4h->len = htons(IP4_HDR_SIZE + len);
239 ip4h->proto = proto;
240 ip4h->ttl = ttl;
241 ip4h->type = 0;
242 ip4h->id = ip4h->flg_off = ip4h->sum = 0;
243
244 /* IP アドレスを設定する。*/
245 ip4h->dst = htonl(*dstaddr);
246
247 if (srcaddr == NULL || *srcaddr == IPV4_ADDRANY)
248 ip4h->src = htonl(ifp->in4_ifaddr.addr);
249 else
250 ip4h->src = htonl(*srcaddr);
251
252 return E_OK;
253 }
254
255/*
256 * in4_get_datagram -- IPv4 データグラムを獲得し、ヘッダを設定する。
257 */
258
259ER
260in4_get_datagram (T_NET_BUF **nbuf, uint_t len, uint_t maxlen,
261 T_IN4_ADDR *dstaddr, T_IN4_ADDR *srcaddr,
262 uint8_t proto, uint8_t ttl, ATR nbatr, TMO tmout)
263{
264 ER error;
265 uint_t align;
266
267 /* データ長を 4 オクテット境界に調整する。*/
268 align = (len + 3) >> 2 << 2;
269
270 /* ネットワークバッファを獲得する。*/
271 if ((error = tget_net_buf_ex(nbuf, (uint_t)(IF_IP4_HDR_SIZE + align),
272 (uint_t)(IF_IP4_HDR_SIZE + maxlen), nbatr, tmout)) != E_OK)
273 return error;
274
275 /*
276 * より大きなサイズのネットワークバッファを獲得する場合のみ長さを調整する。
277 * より小さなサイズのネットワークバッファの獲得は、送信ウィンドバッファの
278 * 省コピー機能で使用され、実際に送信するまで、データサイズは決定できない。
279 */
280 if ((nbatr & NBA_SEARCH_ASCENT) != 0)
281 (*nbuf)->len = (uint16_t)(IF_IP4_HDR_SIZE + len);
282
283 /* IP ヘッダを設定する。*/
284 if ((error = in4_set_header(*nbuf, len, dstaddr, srcaddr, proto, ttl)) != E_OK)
285 return error;
286
287 /* 4 オクテット境界までパディングで埋める。*/
288 if (align > len)
289 memset((GET_IP4_SDU(*nbuf) + len), 0, (size_t)(align - len));
290
291 return E_OK;
292 }
293
294/*
295 * in4_cksum -- IPv4 のトランスポート層ヘッダのチェックサムを計算する。
296 *
297 * 注意: 戻り値はネットワークバイトオーダ
298 */
299
300uint16_t
301in4_cksum (T_NET_BUF *nbuf, uint8_t proto, uint_t off, uint_t len)
302{
303 uint32_t sum;
304 uint_t align;
305
306 /* 4 オクテット境界のデータ長 */
307 align = (len + 3) >> 2 << 2;
308
309 /* 4 オクテット境界までパディングで埋める。*/
310 if (align > len)
311 memset((uint8_t*)nbuf->buf + off + len, 0, (size_t)(align - len));
312
313 sum = in_cksum_sum(nbuf->buf + off, align)
314 + in_cksum_sum(&GET_IP4_HDR(nbuf)->src, sizeof(T_IN4_ADDR) * 2)
315 + len + proto;
316 sum = in_cksum_carry(sum);
317
318 return (uint16_t)(~htons((uint16_t)sum));
319 }
320
321/*
322 * in_cksum -- チェックサム計算関数、IPv4、ICMPv4 用
323 *
324 * 注意: data は 4 オクテット単位でパディングすること。
325 * data が 2 オクテット単位にアラインされていないと
326 * 例外が発生する可能性がある。
327 * len は 4 オクテット単位にアラインされていること。
328 *
329 * 戻り値はネットワークバイトオーダ
330 */
331
332uint16_t
333in_cksum (void *data, uint_t len /*オクテット単位*/)
334{
335 uint16_t sum;
336
337 sum = (uint16_t)in_cksum_carry(in_cksum_sum(data, len));
338 return (uint16_t)(~htons(sum));
339 }
340
341/*
342 * in4_is_dstaddr_accept -- 宛先アドレスとして正しいかチェックする。
343 *
344 * 注意: dstaddr は、
345 * TINET-1.2 からネットワークバイトオーダ、
346 * TINET-1.1 までは、ホストバイトオーダ
347 */
348
349bool_t
350in4_is_dstaddr_accept (T_IN4_ADDR *myaddr, T_IN4_ADDR *dstaddr)
351{
352 if (*myaddr == IPV4_ADDRANY)
353 return ntohl(*dstaddr) == IF_GET_IFNET()->in4_ifaddr.addr;
354 else
355 return ntohl(*dstaddr) == *myaddr;
356 }
357
358/*
359 * inn4_is_dstaddr_accept -- 宛先アドレスとして正しいかチェックする。
360 *
361 * 注意: dstaddr は、
362 * TINET-1.2 からネットワークバイトオーダ、
363 * TINET-1.1 までは、ホストバイトオーダ
364 */
365
366bool_t
367inn4_is_dstaddr_accept (T_IN4_ADDR *myaddr, T_NET_BUF *nbuf)
368{
369 T_IP4_HDR *iph;
370
371 iph = GET_IP4_HDR(nbuf);
372 if (*myaddr == IPV4_ADDRANY)
373 return ntohl(iph->dst) == IF_GET_IFNET()->in4_ifaddr.addr;
374 else
375 return ntohl(iph->dst) == *myaddr;
376 }
377
378/*
379 * in4_addrwithifp -- 宛先アドレスにふさわしい送信元アドレスを、
380 * ネットワークインタフェースから探索する。
381 * in6_addrwithifp をシミュレートするだけで、
382 * エラーを返すことはない。
383 */
384
385T_IN4_ADDR *
386in4_addrwithifp (T_IFNET *ifp, T_IN4_ADDR *src, T_IN4_ADDR *dst)
387{
388 *src = ifp->in4_ifaddr.addr;
389 return src;
390 }
391
392/*
393 * in4_add_ifaddr -- インタフェースに IPv4 アドレスを設定する。
394 */
395
396ER
397in4_add_ifaddr (T_IN4_ADDR addr, T_IN4_ADDR mask)
398{
399 T_IFNET *ifp = IF_GET_IFNET();
400
401 ifp->in4_ifaddr.addr = addr;
402 ifp->in4_ifaddr.mask = mask;
403 return E_OK;
404 }
405
406#if NUM_IN4_ROUTE_ENTRY > 0
407
408/*
409 * in4_add_route -- 経路表にエントリを設定する。
410 */
411
412ER
413in4_add_route (int_t index, T_IN4_ADDR target, T_IN4_ADDR mask, T_IN4_ADDR gateway)
414{
415
416 if (0 <= index && index < NUM_IN4_STATIC_ROUTE_ENTRY) {
417 routing4_tbl[index].target = target;
418 routing4_tbl[index].mask = mask;
419 routing4_tbl[index].gateway = gateway;
420 return E_OK;
421 }
422 else
423 return E_PAR;
424 }
425
426#endif /* of #if NUM_IN4_ROUTE_ENTRY > 0 */
427
428/*
429 * in4_rtalloc -- ルーティング表を探索する。
430 */
431
432T_IN4_ADDR
433in4_rtalloc (T_IN4_ADDR dst)
434{
435 int_t ix;
436
437 for (ix = NUM_IN4_ROUTE_ENTRY; ix --; )
438 if ((routing4_tbl[ix].flags & IN_RTF_DEFINED) &&
439 (dst & routing4_tbl[ix].mask) == routing4_tbl[ix].target) {
440 if (routing4_tbl[ix].gateway == 0)
441 return dst;
442 else {
443 return routing4_tbl[ix].gateway;
444 }
445 }
446 return dst;
447 }
448
449#if NUM_IN4_REDIRECT_ROUTE_ENTRY > 0
450
451/*
452 * in4_rtredirect -- ルーティング表にエントリを登録する。
453 *
454 * 注意: 引数 tmo の単位は [ms]。
455 */
456
457void
458in4_rtredirect (T_IN4_ADDR gateway, T_IN4_ADDR target, uint8_t flags, uint32_t tmo)
459{
460 T_IN4_RTENTRY *frt;
461
462 frt = in_rtnewentry(flags, tmo);
463 frt->gateway = gateway;
464 frt->target = target;
465 frt->mask = 0xffffffff;
466 }
467
468#endif /* of #if NUM_IN4_REDIRECT_ROUTE_ENTRY > 0 */
469
470/*
471 * in4_timer -- IPv4 共通タイマー
472 *
473 * 1秒周期で起動される。
474 */
475
476static void
477in4_timer (void *ignore)
478{
479#if NUM_IN4_REDIRECT_ROUTE_ENTRY > 0
480
481 in_rttimer();
482
483#endif /* of #if NUM_IN4_REDIRECT_ROUTE_ENTRY > 0 */
484
485#ifdef IP4_CFG_FRAGMENT
486
487 ip_frag_timer();
488
489#endif /* of #ifdef IP4_CFG_FRAGMENT */
490
491 timeout(in4_timer, NULL, IN_TIMER_TMO);
492 }
493
494/*
495 * in4_init -- IPv4 共通機能を初期化する。
496 */
497
498void
499in4_init (void)
500{
501#if NUM_IN4_REDIRECT_ROUTE_ENTRY > 0
502
503 in_rtinit();
504
505#endif /* of #if NUM_IN4_REDIRECT_ROUTE_ENTRY > 0 */
506
507 timeout(in4_timer, NULL, IN_TIMER_TMO);
508 }
509
510#endif /* of #if defined(_IP4_CFG) */
Note: See TracBrowser for help on using the repository browser.