Changeset 331 for EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/in_subr.c
- Timestamp:
- Jan 21, 2018, 12:10:09 AM (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/in_subr.c
r321 r331 2 2 * TINET (TCP/IP Protocol Stack) 3 3 * 4 * Copyright (C) 2001-20 09by Dep. of Computer Science and Engineering4 * Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering 5 5 * Tomakomai National College of Technology, JAPAN 6 6 * … … 71 71 #include <kernel.h> 72 72 #include <sil.h> 73 #include <t_syslog.h>74 73 #include "kernel_cfg.h" 75 74 … … 91 90 #include <net/if_ppp.h> 92 91 #include <net/ethernet.h> 93 #include <net/ppp_ipcp.h>94 92 #include <net/net.h> 93 #include <net/net_endian.h> 95 94 #include <net/net_var.h> 96 95 #include <net/net_buf.h> … … 98 97 99 98 #include <netinet/in.h> 100 #include <netinet6/in6.h>101 99 #include <netinet/in_var.h> 102 #include <netinet/in_itron.h>103 100 #include <netinet/ip.h> 104 101 #include <netinet/ip_var.h> 105 #include <netinet/ tcp_timer.h>102 #include <netinet/in_itron.h> 106 103 107 104 #include <net/if_var.h> 108 105 109 #if defined(SUPPORT_INET4) 110 111 /* 112 * in4_get_ifaddr -- インタフェースに設定されているアドレスを返す。 113 */ 114 115 const T_IN4_ADDR * 116 in4_get_ifaddr (int_t index) 117 { 118 T_IFNET *ifp = IF_GET_IFNET(); 119 120 return &ifp->in_ifaddr.addr; 121 } 122 123 /* 124 * ip2str -- IPv4 アドレスを文字列に変換する。 106 /* 107 * in_cksum_sum -- チェックサムの合計計算関数 108 * 109 * 注意: data は 4 オクテット単位でパディングすること。 110 * data が 2 オクテット単位にアラインされていないと 111 * 例外が発生する可能性がある。 112 * len は 4 オクテット単位にアラインされていること。 113 * 114 * 戻り値はホストバイトオーダ 115 */ 116 117 uint32_t 118 in_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 144 uint32_t 145 in_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 161 typedef struct t_strtfn { 162 FN fncd; /* API 機能コード */ 163 const char *str; /* 文字表現 */ 164 } T_STRTFN; 165 166 const 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 197 const char * 198 in_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 アドレスを文字列に変換する。 125 213 */ 126 214 127 215 char * 128 ip 2str (char *buf, const T_IN4_ADDR *ipaddr)216 ipv42str (char *buf, const T_IN4_ADDR *ipaddr) 129 217 { 130 218 static char addr_sbuf[NUM_IPV4ADDR_STR_BUFF][sizeof("123.123.123.123")]; … … 153 241 } 154 242 155 /* 156 * in4_set_header -- IPv4 ヘッダを設定する。 243 #endif /* of #if defined(_IP4_CFG) */ 244 245 /* 246 * in6_is_addr_ipv4mapped -- IPv4 射影アドレスである事を検査する。 247 */ 248 249 bool_t 250 in6_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 261 static void 262 ip6_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 275 static void 276 ip4_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 289 void 290 ip_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 304 void 305 ip_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 326 bool_t 327 inn_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 349 bool_t 350 inn_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 367 void 368 inn_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 データグラムを獲得し、ヘッダを設定する。 157 379 */ 158 380 159 381 ER 160 in4_set_header (T_NET_BUF *nbuf, uint_t len, 161 T_IN4_ADDR *dstaddr, T_IN4_ADDR *srcaddr, uint8_t proto, uint8_t ttl) 162 { 163 T_IP4_HDR *ip4h = GET_IP4_HDR(nbuf); 164 T_IFNET *ifp = IF_GET_IFNET(); 165 166 /* IP ヘッダを設定する。*/ 167 ip4h->vhl = IP4_MAKE_VHL(IPV4_VERSION, IP4_HDR_SIZE >> 2); 168 ip4h->len = htons(IP4_HDR_SIZE + len); 169 ip4h->proto = proto; 170 ip4h->ttl = ttl; 171 ip4h->type = 0; 172 ip4h->id = ip4h->flg_off = ip4h->sum = 0; 173 174 /* IP アドレスを設定する。*/ 175 ip4h->dst = htonl(*dstaddr); 176 177 if (srcaddr == NULL || *srcaddr == IPV4_ADDRANY) 178 ip4h->src = htonl(ifp->in_ifaddr.addr); 382 inn_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 } 179 397 else 180 ip4h->src = htonl(*srcaddr); 181 182 return E_OK; 183 } 184 185 /* 186 * in4_get_datagram -- IPv4 データグラムを獲得し、ヘッダを設定する。 187 */ 188 189 ER 190 in4_get_datagram (T_NET_BUF **nbuf, uint_t len, uint_t maxlen, 191 T_IN4_ADDR *dstaddr, T_IN4_ADDR *srcaddr, 192 uint8_t proto, uint8_t ttl, ATR nbatr, TMO tmout) 193 { 194 ER error; 195 uint_t align; 196 197 /* データ長を 4 オクテット境界に調整する。*/ 198 align = (len + 3) >> 2 << 2; 199 200 /* ネットワークバッファを獲得する。*/ 201 if ((error = tget_net_buf_ex(nbuf, (uint_t)(IF_IP4_HDR_SIZE + align), 202 (uint_t)(IF_IP4_HDR_SIZE + maxlen), nbatr, tmout)) != E_OK) 203 return error; 204 205 /* 206 * より大きなサイズのネットワークバッファを獲得する場合のみ長さを調整する。 207 * より小さなサイズのネットワークバッファの獲得は、送信ウィンドバッファの 208 * 省コピー機能で使用され、実際に送信するまで、データサイズは決定できない。 209 */ 210 if ((nbatr & NBA_SEARCH_ASCENT) != 0) 211 (*nbuf)->len = (uint16_t)(IF_IP4_HDR_SIZE + len); 212 213 /* IP ヘッダを設定する。*/ 214 if ((error = in4_set_header(*nbuf, len, dstaddr, srcaddr, proto, ttl)) != E_OK) 215 return error; 216 217 /* 4 オクテット境界までパディングで埋める。*/ 218 if (align > len) 219 memset((GET_IP4_SDU(*nbuf) + len), 0, (size_t)(align - len)); 220 221 return E_OK; 222 } 223 224 /* 225 * in4_cksum -- IPv4 のトランスポート層ヘッダのチェックサムを計算する。 226 * 227 * 注意: 戻り値はネットワークバイトオーダ 228 */ 398 return in6_get_datagram(nbuf, len, maxlen, dstaddr, srcaddr, next, hlim, nbatr, tmout); 399 } 400 401 /* 402 * inn_addrwithifp -- 宛先アドレスにふさわしい送信元アドレスを、 403 * ネットワークインタフェースから探索する。 404 */ 405 406 T_IN6_ADDR * 407 inn_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 425 bool_t 426 inn_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 229 454 230 455 uint16_t 231 in4_cksum (T_NET_BUF *nbuf, uint8_t proto, uint_t off, uint_t len) 232 { 233 uint32_t sum; 234 uint_t align; 235 236 /* 4 オクテット境界のデータ長 */ 237 align = (len + 3) >> 2 << 2; 238 239 /* 4 オクテット境界までパディングで埋める。*/ 240 if (align > len) 241 memset((uint8_t*)nbuf->buf + off + len, 0, (size_t)(align - len)); 242 243 sum = in_cksum_sum(nbuf->buf + off, align) 244 + in_cksum_sum(&GET_IP4_HDR(nbuf)->src, sizeof(T_IN4_ADDR) * 2) 245 + len + proto; 246 sum = in_cksum_carry(sum); 247 248 return (uint16_t)(~htons((uint16_t)sum)); 249 } 250 251 /* 252 * in_cksum -- チェックサム計算関数、IPv4、ICMPv4 用 253 * 254 * 注意: data は 4 オクテット単位でパディングすること。 255 * data が 2 オクテット単位にアラインされていないと 256 * 例外が発生する可能性がある。 257 * len は 4 オクテット単位にアラインされていること。 258 * 259 * 戻り値はネットワークバイトオーダ 260 */ 456 ntohs (uint16_t net) 457 { 458 return net; 459 } 261 460 262 461 uint16_t 263 in_cksum (void *data, uint_t len /*オクテット単位*/) 264 { 265 uint16_t sum; 266 267 sum = (uint16_t)in_cksum_carry(in_cksum_sum(data, len)); 268 return (uint16_t)(~htons(sum)); 269 } 270 271 /* 272 * in4_is_dstaddr_accept -- 宛先アドレスとして正しいかチェックする。 273 * 274 * 注意: dstaddr は、 275 * TINET-1.2 からネットワークバイトオーダ、 276 * TINET-1.1 までは、ホストバイトオーダ 277 */ 278 279 bool_t 280 in4_is_dstaddr_accept (T_IN4_ADDR *myaddr, T_IN4_ADDR *dstaddr) 281 { 282 if (*myaddr == IPV4_ADDRANY) 283 return ntohl(*dstaddr) == IF_GET_IFNET()->in_ifaddr.addr; 284 else 285 return ntohl(*dstaddr) == *myaddr; 286 } 287 288 /* 289 * in4_ifawithifp -- 宛先アドレスにふさわしい送信元アドレスを、 290 * ネットワークインタフェースから探索する。 291 * in6_ifawithifp をシミュレートするだけで、 292 * エラーを返すことはない。 293 */ 294 295 T_IN4_IFADDR * 296 in4_ifawithifp (T_IFNET *ifp, T_IN4_ADDR *dst) 297 { 298 return &ifp->in_ifaddr; 299 } 300 301 /* 302 * in4_add_ifaddr -- インタフェースに IPv4 アドレスを設定する。 303 */ 304 305 ER 306 in4_add_ifaddr (T_IN4_ADDR addr, T_IN4_ADDR mask) 307 { 308 T_IFNET *ifp = IF_GET_IFNET(); 309 310 ifp->in_ifaddr.addr = addr; 311 ifp->in_ifaddr.mask = mask; 312 return E_OK; 313 } 314 315 #if NUM_ROUTE_ENTRY > 0 316 317 /* 318 * in4_add_route -- 経路表にエントリを設定する。 319 */ 320 321 ER 322 in4_add_route (int_t index, T_IN4_ADDR target, T_IN4_ADDR mask, T_IN4_ADDR gateway) 323 { 324 325 if (0 <= index && index < NUM_STATIC_ROUTE_ENTRY) { 326 routing_tbl[index].target = target; 327 routing_tbl[index].mask = mask; 328 routing_tbl[index].gateway = gateway; 329 return E_OK; 330 } 331 else 332 return E_PAR; 333 } 334 335 #endif /* of #if NUM_ROUTE_ENTRY > 0 */ 336 337 /* 338 * in4_rtalloc -- ルーティング表を探索する。 339 */ 340 341 T_IN4_ADDR 342 in4_rtalloc (T_IN4_ADDR dst) 343 { 344 int_t ix; 345 346 for (ix = NUM_ROUTE_ENTRY; ix --; ) 347 if ((routing_tbl[ix].flags & IN_RTF_DEFINED) && 348 (dst & routing_tbl[ix].mask) == routing_tbl[ix].target) { 349 if (routing_tbl[ix].gateway == 0) 350 return dst; 351 else { 352 return routing_tbl[ix].gateway; 353 } 354 } 355 return dst; 356 } 357 358 #if NUM_REDIRECT_ROUTE_ENTRY > 0 359 360 /* 361 * in4_rtredirect -- ルーティング表にエントリを登録する。 362 * 363 * 注意: 引数 tmo の単位は [ms]。 364 */ 365 366 void 367 in4_rtredirect (T_IN4_ADDR gateway, T_IN4_ADDR target, uint8_t flags, uint32_t tmo) 368 { 369 T_IN_RTENTRY *frt; 370 371 frt = in_rtnewentry(flags, tmo); 372 frt->gateway = gateway; 373 frt->target = target; 374 frt->mask = 0xffffffff; 375 } 376 377 #endif /* of #if NUM_REDIRECT_ROUTE_ENTRY > 0 */ 378 379 /* 380 * in4_timer -- IPv4 共通タイマー 381 * 382 * 1秒周期で起動される。 383 */ 384 385 static void 386 in4_timer (void *ignore) 387 { 388 #if NUM_REDIRECT_ROUTE_ENTRY > 0 389 390 in_rttimer(); 391 392 #endif /* of #if NUM_REDIRECT_ROUTE_ENTRY > 0 */ 393 394 #ifdef IP4_CFG_FRAGMENT 395 396 ip_frag_timer(); 397 398 #endif /* of #ifdef IP4_CFG_FRAGMENT */ 399 400 timeout(in4_timer, NULL, IN_TIMER_TMO); 401 } 402 403 /* 404 * in4_init -- IPv4 共通機能を初期化する。 405 */ 406 407 void 408 in4_init (void) 409 { 410 #if NUM_REDIRECT_ROUTE_ENTRY > 0 411 412 in_rtinit(); 413 414 #endif /* of #if NUM_REDIRECT_ROUTE_ENTRY > 0 */ 415 416 timeout(in4_timer, NULL, IN_TIMER_TMO); 417 } 418 419 #endif /* of #if defined(SUPPORT_INET4) */ 420 421 #if NUM_REDIRECT_ROUTE_ENTRY > 0 422 423 /* 424 * in_rtinit -- ルーティング表を初期化する。 425 */ 426 427 void 428 in_rtinit (void) 429 { 430 int_t ix; 431 432 for (ix = 0; ix < NUM_STATIC_ROUTE_ENTRY; ix ++) 433 routing_tbl[ix].flags = IN_RTF_DEFINED; 434 435 for ( ; ix < NUM_ROUTE_ENTRY; ix ++) 436 routing_tbl[ix].flags = 0; 437 } 438 439 /* 440 * in_rtnewentry -- 新しいエントリを獲得する。 441 */ 442 443 T_IN_RTENTRY * 444 in_rtnewentry (uint8_t flags, uint32_t tmo) 445 { 446 SYSTIM now; 447 T_IN_RTENTRY *rt, *frt = NULL; 448 int_t ix; 449 450 /* 空きエントリを探す。*/ 451 for (ix = NUM_STATIC_ROUTE_ENTRY; ix < NUM_ROUTE_ENTRY; ix ++) { 452 rt = &routing_tbl[ix]; 453 if ((routing_tbl[ix].flags & IN_RTF_DEFINED) == 0) { 454 frt = rt; 455 break; 456 } 457 } 458 459 /* expire の単位は [s]。*/ 460 syscall(get_tim(&now)); 461 now /= SYSTIM_HZ; 462 463 if (frt == NULL) { 464 /* 空きがなければ、有効時間がもっとも短いエントリを空きにする。*/ 465 T_IN_RTENTRY *srt = NULL; 466 int_t diff, sdiff = INT_MAX; 467 468 syscall(wai_sem(SEM_IN_ROUTING_TBL)); 469 for (ix = NUM_STATIC_ROUTE_ENTRY; ix < NUM_ROUTE_ENTRY; ix ++) { 470 rt = &routing_tbl[ix]; 471 diff = (int_t)(rt->expire - now); 472 if (diff <= 0) { /* rt->expire <= now */ 473 /* 既に、有効時間が過ぎている。*/ 474 frt = rt; 475 break; 476 } 477 else if (diff < sdiff) { 478 srt = rt; 479 sdiff = diff; 480 } 481 } 482 if (frt == NULL) 483 frt = srt; 484 frt->flags = 0; 485 syscall(sig_sem(SEM_IN_ROUTING_TBL)); 486 } 487 488 frt->flags = (uint8_t)(flags | IN_RTF_DEFINED); 489 frt->expire = now + tmo / SYSTIM_HZ; 490 return frt; 491 } 492 493 /* 494 * in_rttimer -- ルーティング表の管理タイマー 495 */ 496 497 void 498 in_rttimer (void) 499 { 500 SYSTIM now; 501 int_t ix; 502 503 /* expire の単位は [s]。*/ 504 syscall(get_tim(&now)); 505 now /= SYSTIM_HZ; 506 507 syscall(wai_sem(SEM_IN_ROUTING_TBL)); 508 for (ix = NUM_STATIC_ROUTE_ENTRY; ix < NUM_ROUTE_ENTRY; ix ++) 509 if ((routing_tbl[ix].flags & IN_RTF_DEFINED) && 510 (int_t)(routing_tbl[ix].expire - now) <= 0) 511 routing_tbl[ix].flags = 0; 512 syscall(sig_sem(SEM_IN_ROUTING_TBL)); 513 } 514 515 #endif /* of #if NUM_REDIRECT_ROUTE_ENTRY > 0 */ 516 517 /* 518 * in_cksum_sum -- チェックサムの合計計算関数 519 * 520 * 注意: data は 4 オクテット単位でパディングすること。 521 * data が 2 オクテット単位にアラインされていないと 522 * 例外が発生する可能性がある。 523 * len は 4 オクテット単位にアラインされていること。 524 * 525 * 戻り値はホストバイトオーダ 526 */ 462 htons (uint16_t host) 463 { 464 return host; 465 } 527 466 528 467 uint32_t 529 in_cksum_sum (void *data, uint_t len /*オクテット単位*/) 530 { 531 uint32_t sum = 0; 532 533 for ( ; len > 0; len -= 2) { 534 sum += *((uint16_t*)data); 535 data = (uint8_t*)data + 2; 536 } 537 538 #if _NET_CFG_BYTE_ORDER == _NET_CFG_BIG_ENDIAN 539 return sum; 540 #elif _NET_CFG_BYTE_ORDER == _NET_CFG_LITTLE_ENDIAN 541 return ((sum >> 8) & 0xffff) + ((sum & 0xff) << 8) + ((sum >> 24) & 0xff); 468 ntohl (uint32_t net) 469 { 470 return net; 471 } 472 473 uint32_t 474 htonl (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 481 uint16_t 482 ntohs (uint16_t net) 483 { 484 return NET_REV_ENDIAN_HWORD(net); 485 } 486 487 uint16_t 488 htons (uint16_t host) 489 { 490 return NET_REV_ENDIAN_HWORD(host); 491 } 492 493 uint32_t 494 ntohl (uint32_t net) 495 { 496 return NET_REV_ENDIAN_WORD(net); 497 } 498 499 uint32_t 500 htonl (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 542 509 #endif /* #if _NET_CFG_BYTE_ORDER == _NET_CFG_BIG_ENDIAN */ 543 510 544 } 545 546 /* 547 * in_cksum_carry -- チェックサムの桁上げ計算関数 548 * 549 * 注意: data は 4 オクテット単位でパディングすること。 550 * data が 2 オクテット単位にアラインされていないと 551 * 例外が発生する可能性がある。 552 * len は 4 オクテット単位にアラインされていること。 553 */ 554 555 uint32_t 556 in_cksum_carry (uint32_t sum) 557 { 558 uint32_t carry; 559 560 while (sum >= 0x00010000) { 561 carry = sum >> 16; 562 sum = (sum & 0xffff) + carry; 563 } 564 565 return sum; 566 } 567 568 /* 569 * in_strtfn -- API 機能コードの文字表現を返す。 570 */ 571 572 const char * 573 in_strtfn (FN fncd) 574 { 575 switch (fncd) { 576 577 /* TCP 関係 */ 578 579 case TFN_TCP_CRE_REP: 580 return "TFN_TCP_CRE_REP"; 581 break; 582 case TFN_TCP_DEL_REP: 583 return "TFN_TCP_DEL_REP"; 584 break; 585 case TFN_TCP_CRE_CEP: 586 return "TFN_TCP_CRE_CEP"; 587 break; 588 case TFN_TCP_DEL_CEP: 589 return "TFN_TCP_DEL_CEP"; 590 break; 591 case TFN_TCP_ACP_CEP: 592 return "TFN_TCP_ACP_CEP"; 593 break; 594 case TFN_TCP_CON_CEP: 595 return "TFN_TCP_CON_CEP"; 596 break; 597 case TFN_TCP_SHT_CEP: 598 return "TFN_TCP_SHT_CEP"; 599 break; 600 case TFN_TCP_CLS_CEP: 601 return "TFN_TCP_CLS_CEP"; 602 break; 603 case TFN_TCP_SND_DAT: 604 return "TFN_TCP_SND_DAT"; 605 break; 606 case TFN_TCP_RCV_DAT: 607 return "TFN_TCP_RCV_DAT"; 608 break; 609 case TFN_TCP_GET_BUF: 610 return "TFN_TCP_GET_BUF"; 611 break; 612 case TFN_TCP_SND_BUF: 613 return "TFN_TCP_SND_BUF"; 614 break; 615 case TFN_TCP_RCV_BUF: 616 return "TFN_TCP_RCV_BUF"; 617 break; 618 case TFN_TCP_REL_BUF: 619 return "TFN_TCP_REL_BUF"; 620 break; 621 case TFN_TCP_SND_OOB: 622 return "TFN_TCP_SND_OOB"; 623 break; 624 case TFN_TCP_RCV_OOB: 625 return "TFN_TCP_RCV_OOB"; 626 break; 627 case TFN_TCP_CAN_CEP: 628 return "TFN_TCP_CAN_CEP"; 629 break; 630 case TFN_TCP_SET_OPT: 631 return "TFN_TCP_SET_OPT"; 632 break; 633 case TFN_TCP_GET_OPT: 634 return "TFN_TCP_GET_OPT"; 635 break; 636 case TFN_TCP_ALL: 637 return "ALL"; 638 break; 639 640 /* UDP 関係 */ 641 642 case TFN_UDP_CRE_CEP: 643 return "TFN_UDP_CRE_CEP"; 644 break; 645 case TFN_UDP_DEL_CEP: 646 return "TFN_UDP_DEL_CEP"; 647 break; 648 case TFN_UDP_SND_DAT: 649 return "TFN_UDP_SND_DAT"; 650 break; 651 case TFN_UDP_RCV_DAT: 652 return "TFN_UDP_RCV_DAT"; 653 break; 654 case TFN_UDP_CAN_CEP: 655 return "TFN_UDP_CAN_CEP"; 656 break; 657 case TFN_UDP_SET_OPT: 658 return "TFN_UDP_SET_OPT"; 659 break; 660 case TFN_UDP_GET_OPT: 661 return "TFN_UDP_GET_OPT"; 662 break; 663 664 default: 665 return "unknown TFN"; 666 } 667 } 511 #endif /* of #if defined(_NET_CFG_BYTE_ORDER) */
Note:
See TracChangeset
for help on using the changeset viewer.