source: azure_iot_hub/trunk/asp3_dcre/tinet/netinet/in_subr.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: 13.9 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/net.h>
93#include <net/net_endian.h>
94#include <net/net_var.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#include <netinet/in_itron.h>
103
104#include <net/if_var.h>
105
106/*
107 * in_cksum_sum -- チェックサムの合計計算関数
108 *
109 * 注意: data は 4 オクテット単位でパディングすること。
110 * data が 2 オクテット単位にアラインされていないと
111 * 例外が発生する可能性がある。
112 * len は 4 オクテット単位にアラインされていること。
113 *
114 * 戻り値はホストバイトオーダ
115 */
116
117uint32_t
118in_cksum_sum (void *data, uint_t len /*オクテット単位*/)
119{
120 uint32_t sum = 0;
121
122 for ( ; len > 0; len -= 2) {
123 sum += *((uint16_t*)data);
124 data = (uint8_t*)data + 2;
125 }
126
127#if _NET_CFG_BYTE_ORDER == _NET_CFG_BIG_ENDIAN
128 return sum;
129#elif _NET_CFG_BYTE_ORDER == _NET_CFG_LITTLE_ENDIAN
130 return ((sum >> 8) & 0xffff) + ((sum & 0xff) << 8) + ((sum >> 24) & 0xff);
131#endif /* #if _NET_CFG_BYTE_ORDER == _NET_CFG_BIG_ENDIAN */
132
133 }
134
135/*
136 * in_cksum_carry -- チェックサムの桁上げ計算関数
137 *
138 * 注意: data は 4 オクテット単位でパディングすること。
139 * data が 2 オクテット単位にアラインされていないと
140 * 例外が発生する可能性がある。
141 * len は 4 オクテット単位にアラインされていること。
142 */
143
144uint32_t
145in_cksum_carry (uint32_t sum)
146{
147 uint32_t carry;
148
149 while (sum >= 0x00010000) {
150 carry = sum >> 16;
151 sum = (sum & 0xffff) + carry;
152 }
153
154 return sum;
155 }
156
157/*
158 * in_strtfn -- API 機能コードの文字表現を返す。
159 */
160
161typedef struct t_strtfn {
162 FN fncd; /* API 機能コード */
163 const char *str; /* 文字表現 */
164 } T_STRTFN;
165
166const T_STRTFN strtfn[] = {
167 { TEV_TCP_RCV_OOB, "TEV_TCP_RCV_OOB" },
168 { TFN_TCP_DEL_REP, "TFN_TCP_DEL_REP" },
169 { TFN_TCP_CRE_CEP, "TFN_TCP_CRE_CEP" },
170 { TFN_TCP_DEL_CEP, "TFN_TCP_DEL_CEP" },
171 { TFN_TCP_ACP_CEP, "TFN_TCP_ACP_CEP" },
172 { TFN_TCP_CON_CEP, "TFN_TCP_CON_CEP" },
173 { TFN_TCP_SHT_CEP, "TFN_TCP_SHT_CEP" },
174 { TFN_TCP_CLS_CEP, "TFN_TCP_CLS_CEP" },
175 { TFN_TCP_SND_DAT, "TFN_TCP_SND_DAT" },
176 { TFN_TCP_RCV_DAT, "TFN_TCP_RCV_DAT" },
177 { TFN_TCP_GET_BUF, "TFN_TCP_GET_BUF" },
178 { TFN_TCP_SND_BUF, "TFN_TCP_SND_BUF" },
179 { TFN_TCP_RCV_BUF, "TFN_TCP_RCV_BUF" },
180 { TFN_TCP_REL_BUF, "TFN_TCP_REL_BUF" },
181 { TFN_TCP_SND_OOB, "TFN_TCP_SND_OOB" },
182 { TFN_TCP_RCV_OOB, "TFN_TCP_RCV_OOB" },
183 { TFN_TCP_CAN_CEP, "TFN_TCP_CAN_CEP" },
184 { TFN_TCP_SET_OPT, "TFN_TCP_SET_OPT" },
185 { TFN_TCP_GET_OPT, "TFN_TCP_GET_OPT" },
186 { TFN_TCP_ALL, "TFN_TCP_ALL" },
187
188 { TEV_UDP_RCV_DAT, "TEV_UDP_RCV_DAT" },
189 { TFN_UDP_DEL_CEP, "TFN_UDP_DEL_CEP" },
190 { TFN_UDP_SND_DAT, "TFN_UDP_SND_DAT" },
191 { TFN_UDP_RCV_DAT, "TFN_UDP_RCV_DAT" },
192 { TFN_UDP_CAN_CEP, "TFN_UDP_CAN_CEP" },
193 { TFN_UDP_SET_OPT, "TFN_UDP_SET_OPT" },
194 { TFN_UDP_GET_OPT, "TFN_UDP_GET_OPT" },
195 };
196
197const char *
198in_strtfn (FN fncd)
199{
200 int_t ix;
201
202 for (ix = sizeof(strtfn) / sizeof(T_STRTFN); ix -- > 0; )
203 if (strtfn[ix].fncd == fncd)
204 return strtfn[ix].str;
205
206 return "unknown TFN";
207 }
208
209#if defined(_IP4_CFG)
210
211/*
212 * ipv42str -- IPv4 アドレスを文字列に変換する。
213 */
214
215char *
216ipv42str (char *buf, const T_IN4_ADDR *ipaddr)
217{
218 static char addr_sbuf[NUM_IPV4ADDR_STR_BUFF][sizeof("123.123.123.123")];
219 static int_t bix = NUM_IPV4ADDR_STR_BUFF;
220
221 char *start;
222
223 if (buf == NULL) {
224 syscall(wai_sem(SEM_IP2STR_BUFF_LOCK));
225 buf = addr_sbuf[-- bix];
226 if (bix <= 0)
227 bix = NUM_IPV4ADDR_STR_BUFF;
228 syscall(sig_sem(SEM_IP2STR_BUFF_LOCK));
229 }
230
231 start = buf;
232 buf += convert_hexdigit(buf, (uint_t)((*ipaddr >> 24) & 0xff), 10, 0, ' ');
233 *(buf ++) = '.';
234 buf += convert_hexdigit(buf, (uint_t)((*ipaddr >> 16) & 0xff), 10, 0, ' ');
235 *(buf ++) = '.';
236 buf += convert_hexdigit(buf, (uint_t)((*ipaddr >> 8) & 0xff), 10, 0, ' ');
237 *(buf ++) = '.';
238 buf += convert_hexdigit(buf, (uint_t)((*ipaddr ) & 0xff), 10, 0, ' ');
239 *buf = '\0';
240 return start;
241 }
242
243#endif /* of #if defined(_IP4_CFG) */
244
245/*
246 * in6_is_addr_ipv4mapped -- IPv4 射影アドレスである事を検査する。
247 */
248
249bool_t
250in6_is_addr_ipv4mapped (const T_IN6_ADDR *addr)
251{
252 return IN6_IS_ADDR_V4MAPPED(addr);
253 }
254
255#if defined(_IP6_CFG) && defined(_IP4_CFG)
256
257/*
258 * ip_exchg_addr -- IP アドレスを交換する。
259 */
260
261static void
262ip6_exchg_addr (T_NET_BUF *nbuf)
263{
264 T_IP6_HDR *iph;
265 T_IN6_ADDR ipaddr;
266
267 iph = GET_IP6_HDR(nbuf);
268
269 /* IPv6 アドレスを交換する。*/
270 ipaddr = iph->src;
271 iph->src = iph->dst;
272 iph->dst = ipaddr;
273 }
274
275static void
276ip4_exchg_addr (T_NET_BUF *nbuf)
277{
278 T_IP4_HDR *iph;
279 T_IN4_ADDR ipaddr;
280
281 iph = GET_IP4_HDR(nbuf);
282
283 /* IPv4 アドレスを交換する。*/
284 ipaddr = iph->src;
285 iph->src = iph->dst;
286 iph->dst = ipaddr;
287 }
288
289void
290ip_exchg_addr (T_NET_BUF *nbuf)
291{
292 if (GET_IP_VER(nbuf) == 6)
293 ip6_exchg_addr(nbuf);
294 else
295 ip4_exchg_addr(nbuf);
296 }
297
298#else /* of #if defined(_IP6_CFG) && defined(_IP4_CFG) */
299
300/*
301 * ip_exchg_addr -- IP アドレスを交換する。
302 */
303
304void
305ip_exchg_addr (T_NET_BUF *nbuf)
306{
307 T_IP_HDR *iph;
308 T_IN_ADDR ipaddr;
309
310 iph = GET_IP_HDR(nbuf);
311
312 /* IP アドレスを交換する。*/
313 ipaddr = iph->src;
314 iph->src = iph->dst;
315 iph->dst = ipaddr;
316 }
317
318#endif /* of #if defined(_IP6_CFG) && defined(_IP4_CFG) */
319
320#if defined(_IP6_CFG) && defined(_IP4_CFG)
321
322/*
323 * inn_is_dstaddr_accept -- 宛先アドレスとして正しいかチェックする。
324 */
325
326bool_t
327inn_is_dstaddr_accept (T_IN6_ADDR *myaddr, T_NET_BUF *nbuf)
328{
329 if (GET_IP_VER(nbuf)==IPV6_VERSION)
330 return INN6_IS_DSTADDR_ACCEPT(myaddr, nbuf);
331 else /*if (GET_IP_VER(nbuf)==IPV4_VERSION)*/ {
332 T_IP4_HDR *ip4h;
333
334 ip4h = GET_IP4_HDR(nbuf);
335 if (IN6_IS_ADDR_UNSPECIFIED(myaddr))
336 return ntohl(ip4h->dst) == IF_GET_IFNET()->in4_ifaddr.addr;
337 else {
338 T_IN6_ADDR dstaddr;
339
340 return IN6_ARE_ADDR_EQUAL(myaddr, in6_make_ipv4mapped(&dstaddr, ntohl(ip4h->dst)));
341 }
342 }
343 }
344
345/*
346 * inn_are_net_srcaddr_equal -- アドレスが同一かチェックする。
347 */
348
349bool_t
350inn_are_net_srcaddr_equal (T_IN6_ADDR *ipaddr, T_NET_BUF *nbuf)
351{
352 if (GET_IP_VER(nbuf)==IPV6_VERSION)
353 return IN6_ARE_ADDR_EQUAL(ipaddr, &GET_IP6_HDR(nbuf)->src);
354 else /*if (GET_IP_VER(nbuf)==IPV4_VERSION)*/ {
355
356
357 T_IN6_ADDR srcaddr;
358
359 return IN6_ARE_ADDR_EQUAL(ipaddr, in6_make_ipv4mapped(&srcaddr, ntohl(GET_IP4_HDR(nbuf)->src)));
360 }
361 }
362
363/*
364 * inn_copy_to_host -- IP ヘッダからホスト表現変換して、IP アドレスをコピーする。
365 */
366
367void
368inn_copy_to_host (T_IN6_ADDR *dst, T_NET_BUF *nbuf)
369{
370 if (GET_IP_VER(nbuf)==IPV6_VERSION)
371 memcpy(dst, &GET_IP6_HDR(nbuf)->src, sizeof(T_IN6_ADDR));
372 else /*if (GET_IP_VER(nbuf)==IPV4_VERSION)*/
373 in6_make_ipv4mapped(dst, ntohl(GET_IP4_HDR(nbuf)->src));
374
375 }
376
377/*
378 * inn_get_datagram -- IPv6/IPv4 データグラムを獲得し、ヘッダを設定する。
379 */
380
381ER
382inn_get_datagram (T_NET_BUF **nbuf, uint_t len, uint_t maxlen,
383 T_IN6_ADDR *dstaddr, T_IN6_ADDR *srcaddr,
384 uint8_t next, uint8_t hlim, ATR nbatr, TMO tmout)
385{
386 if (IN6_IS_ADDR_V4MAPPED(dstaddr)) {
387 T_IN4_ADDR ip4dstaddr, ip4srcaddr;
388
389 ip4dstaddr = ntohl(dstaddr->s6_addr32[3]);
390 if (IN6_IS_ADDR_UNSPECIFIED(srcaddr))
391 ip4srcaddr = IF_GET_IFNET()->in4_ifaddr.addr;
392 else
393 ip4srcaddr = ntohl(srcaddr->s6_addr32[3]);
394
395 return in4_get_datagram(nbuf, len, maxlen, &ip4dstaddr, &ip4srcaddr, next, hlim, nbatr, tmout);
396 }
397 else
398 return in6_get_datagram(nbuf, len, maxlen, dstaddr, srcaddr, next, hlim, nbatr, tmout);
399 }
400
401/*
402 * inn_addrwithifp -- 宛先アドレスにふさわしい送信元アドレスを、
403 * ネットワークインタフェースから探索する。
404 */
405
406T_IN6_ADDR *
407inn_addrwithifp (T_IFNET *ifp, T_IN6_ADDR *src, T_IN6_ADDR *dst)
408{
409 T_IN6_IFADDR *ifaddr;
410
411 if (IN6_IS_ADDR_V4MAPPED(dst))
412 return in6_make_ipv4mapped (src, ifp->in4_ifaddr.addr);
413 else if ((ifaddr = in6_ifawithifp(ifp, dst)) == NULL)
414 return NULL;
415 else {
416 *src = ifaddr->addr;
417 return src;
418 }
419 }
420
421/*
422 * inn_is_addr_multicast -- アドレスがマルチキャストアドレスかチェックする。
423 */
424
425bool_t
426inn_is_addr_multicast (T_IN6_ADDR *addr)
427{
428
429 if (IN6_IS_ADDR_V4MAPPED(addr))
430 return IN4_IS_ADDR_MULTICAST(ntohl(addr->s6_addr32[3]));
431 else
432 return IN6_IS_ADDR_MULTICAST(addr);
433 }
434
435#endif /* of #if defined(_IP6_CFG) && defined(_IP4_CFG) */
436
437/*
438 * バイトオーダ関数の定義
439 *
440 * tinet/net/net.h でもバイトオーダの定義を行っているが、
441 * tinet/net/net.h をインクルードしない
442 * アプリケーションプログラム用に
443 * ターゲット依存しないバイトオーダ関数を定義する。
444 */
445
446#if defined(_NET_CFG_BYTE_ORDER)
447
448#undef ntohs
449#undef htons
450#undef ntohl
451#undef htonl
452
453#if _NET_CFG_BYTE_ORDER == _NET_CFG_BIG_ENDIAN
454
455uint16_t
456ntohs (uint16_t net)
457{
458 return net;
459 }
460
461uint16_t
462htons (uint16_t host)
463{
464 return host;
465 }
466
467uint32_t
468ntohl (uint32_t net)
469{
470 return net;
471 }
472
473uint32_t
474htonl (uint32_t host)
475{
476 return host;
477 }
478
479#elif _NET_CFG_BYTE_ORDER == _NET_CFG_LITTLE_ENDIAN /* of #if _NET_CFG_BYTE_ORDER == _NET_CFG_BIG_ENDIAN */
480
481uint16_t
482ntohs (uint16_t net)
483{
484 return NET_REV_ENDIAN_HWORD(net);
485 }
486
487uint16_t
488htons (uint16_t host)
489{
490 return NET_REV_ENDIAN_HWORD(host);
491 }
492
493uint32_t
494ntohl (uint32_t net)
495{
496 return NET_REV_ENDIAN_WORD(net);
497 }
498
499uint32_t
500htonl (uint32_t host)
501{
502 return NET_REV_ENDIAN_WORD(host);
503 }
504
505#else /* #if _NET_CFG_BYTE_ORDER == _NET_CFG_BIG_ENDIAN */
506
507#error "_NET_CFG_BYTE_ORDER expected."
508
509#endif /* #if _NET_CFG_BYTE_ORDER == _NET_CFG_BIG_ENDIAN */
510
511#endif /* of #if defined(_NET_CFG_BYTE_ORDER) */
Note: See TracBrowser for help on using the repository browser.