Changeset 331 for EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/udp_usrreq.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/udp_usrreq.c
r321 r331 2 2 * TINET (UDP/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 * … … 78 78 #include <kernel.h> 79 79 #include <sil.h> 80 #include "tinet_cfg.h" 80 81 81 82 #endif /* of #ifdef TARGET_KERNEL_ASP */ … … 85 86 #include <s_services.h> 86 87 #include <t_services.h> 87 #include " kernel_id.h"88 #include "tinet_id.h" 88 89 89 90 #endif /* of #ifdef TARGET_KERNEL_JSP */ … … 97 98 #include <net/ethernet.h> 98 99 #include <net/net.h> 100 #include <net/net_endian.h> 99 101 #include <net/net_buf.h> 100 102 #include <net/net_count.h> … … 102 104 103 105 #include <netinet/in.h> 104 #include <netinet6/in6.h>105 106 #include <netinet/in_var.h> 106 107 #include <netinet/in_itron.h> … … 108 109 #include <netinet/ip_var.h> 109 110 #include <netinet/ip_icmp.h> 110 #include <netinet6/in6_var.h>111 #include <netinet/ip6.h>112 #include <netinet6/ip6_var.h>113 #include <netinet6/nd6.h>114 #include <netinet/icmp6.h>115 111 #include <netinet/udp.h> 116 112 #include <netinet/udp_var.h> 113 #include <netinet/ip_igmp.h> 117 114 118 115 #ifdef SUPPORT_UDP 119 120 /*121 * IPv4 と IPv6 の切り替えマクロ122 */123 124 #if defined(SUPPORT_INET4)125 126 #define UDP_CRE_CEP udp_cre_cep127 #define UDP_SND_DAT udp_snd_dat128 #define UDP_RCV_DAT udp_rcv_dat129 130 #endif /* of #if defined(SUPPORT_INET4) */131 132 #if defined(SUPPORT_INET6)133 134 #define UDP_CRE_CEP udp6_cre_cep135 #define UDP_SND_DAT udp6_snd_dat136 #define UDP_RCV_DAT udp6_rcv_dat137 138 #endif /* of #if defined(SUPPORT_INET6) */139 116 140 117 /* … … 158 135 #endif /* of #ifndef UDP_CFG_LIBRARY */ 159 136 160 #ifdef __udp_send_data 161 162 /* 163 * udp_send_data -- パケット送信の主要部 164 */ 165 166 ER_UINT 167 udp_send_data (T_UDP_CEP *cep, T_IPEP *p_dstaddr, void *data, int_t len, TMO tmout) 168 { 169 T_NET_BUF *output; 170 T_UDP_HDR *udph; 171 SYSTIM before, after; 172 ER error = E_OK; 173 174 #ifdef UDP_CFG_OUT_CHECKSUM 175 uint16_t sum; 176 #endif /* of #ifdef UDP_CFG_OUT_CHECKSUM */ 177 178 NET_COUNT_UDP(net_count_udp.out_octets, len); 179 NET_COUNT_UDP(net_count_udp.out_packets, 1); 180 181 /* IP データグラム割り当ての時間を tmout から減ずる。*/ 182 if (!(tmout == TMO_POL || tmout == TMO_FEVR)) 183 syscall(get_tim(&before)); 184 185 /* IP データグラムを割り当てる。*/ 186 if ((error = IN_GET_DATAGRAM(&output, (uint_t)(UDP_HDR_SIZE + len), 0, 187 &p_dstaddr->ipaddr, 188 &cep->myaddr.ipaddr, 189 IPPROTO_UDP, IP_DEFTTL, 190 NBA_SEARCH_ASCENT, tmout)) != E_OK) 191 goto err_ret; 192 193 /* IP データグラム割り当ての時間を tmout から減ずる。*/ 194 if (!(tmout == TMO_POL || tmout == TMO_FEVR)) { 195 syscall(get_tim(&after)); 196 if (after - before > tmout) { 197 syscall(rel_net_buf(output)); 198 error = E_TMOUT; 199 goto err_ret; 200 } 201 tmout -= (TMO)(after - before); 202 } 203 204 /* UDP ヘッダに情報を設定する。*/ 205 udph = GET_UDP_HDR(output, IF_IP_UDP_HDR_OFFSET); 206 udph->sport = htons(cep->myaddr.portno); 207 udph->dport = htons(p_dstaddr->portno); 208 udph->ulen = htons(UDP_HDR_SIZE + len); 209 udph->sum = 0; 210 211 /* データをコピーする。*/ 212 memcpy((void*)GET_UDP_SDU(output, IF_IP_UDP_HDR_OFFSET), data, (size_t)len); 213 214 #ifdef UDP_CFG_OUT_CHECKSUM 215 216 sum = IN_CKSUM(output, IPPROTO_UDP, IF_IP_UDP_HDR_OFFSET, (uint_t)(UDP_HDR_SIZE + len)); 217 218 /* 計算したチェックサムの値が 0 なら 0xffff を入れる。*/ 219 if (sum == 0) 220 sum = 0xffff; 221 udph->sum = sum; 222 223 #endif /* of #ifdef UDP_CFG_OUT_CHECKSUM */ 224 225 /* ネットワークバッファ長を調整する。*/ 226 output->len = (uint16_t)(IF_IP_UDP_HDR_SIZE + len); 227 228 /* ネットワーク層 (IP) の出力関数を呼び出す。*/ 229 if ((error = IP_OUTPUT(output, tmout)) == E_OK) { 230 NET_COUNT_MIB(udp_stats.udpOutDatagrams, 1); 231 cep->snd_tskid = TA_NULL; 232 return len; 233 } 234 235 err_ret: 236 NET_COUNT_UDP(net_count_udp.out_err_packets, 1); 237 cep->snd_tskid = TA_NULL; 238 return error; 239 } 240 241 #endif /* of #ifdef __udp_send_data */ 242 243 /* 244 * udp_cre_cep -- UDP 通信端点の生成【拡張機能】 245 */ 246 247 #ifdef __udp_cre_cep 248 249 #ifdef UDP_CFG_EXTENTIONS 250 251 ER 252 UDP_CRE_CEP (ID cepid, T_UDP_CCEP *pk_ccep) 253 { 254 T_UDP_CEP *cep; 255 ER error; 256 257 /* UDP 通信端点 ID をチェックする。*/ 258 if (!VALID_UDP_CEPID(cepid)) 259 return E_ID; 260 261 /* pk_ccep が NULL ならエラー */ 262 if (pk_ccep == NULL) 263 return E_PAR; 264 265 /* UDP 通信端点を得る。*/ 266 cep = GET_UDP_CEP(cepid); 267 268 /* UDP 通信端点をチェックする。*/ 269 if (VALID_UDP_CEP(cep)) 270 return E_OBJ; 271 272 /* UDP 通信端点が、動的生成用でなければエラー */ 273 if (!DYNAMIC_UDP_CEP(cep)) 274 return E_ID; 275 276 /* 通信端点をロックする。*/ 277 syscall(wai_sem(cep->semid_lock)); 278 279 /* 280 * UDP 通信端点をチェックする。生成済みであればエラー 281 */ 282 if (VALID_UDP_CEP(cep)) 283 error = E_OBJ; 284 else { 285 286 /* 287 * 自ポート番号が UDP_PORTANY なら、自動で割り当てる。 288 */ 289 if (pk_ccep->myaddr.portno == UDP_PORTANY) 290 error = udp_alloc_auto_port(cep); 291 else 292 error = udp_alloc_port(cep, pk_ccep->myaddr.portno); 293 294 if (error == E_OK) { 295 296 /* UDP 通信端点生成情報をコピーする。*/ 297 cep->cepatr = pk_ccep->cepatr; /* 通信端点属性 */ 298 cep->myaddr.ipaddr = pk_ccep->myaddr.ipaddr; /* 自分のアドレス */ 299 cep->callback = (void*)pk_ccep->callback; /* コールバック */ 300 301 /* UDP 通信端点を生成済みにする。*/ 302 cep->flags |= UDP_CEP_FLG_VALID; 303 } 304 } 305 306 /* 通信端点のロックを解除する。*/ 307 syscall(sig_sem(cep->semid_lock)); 308 309 return error; 310 } 311 312 #endif /* of #ifdef UDP_CFG_EXTENTIONS */ 313 314 #endif /* of #ifdef __udp_cre_cep */ 315 316 /* 317 * udp_del_cep -- UDP 通信端点の削除【拡張機能】 318 */ 319 320 #ifdef __udp_del_cep 321 322 #ifdef UDP_CFG_EXTENTIONS 323 324 ER 325 udp_del_cep (ID cepid) 326 { 327 T_UDP_CEP *cep; 328 ER error; 329 330 /* UDP 通信端点 ID をチェックする。*/ 331 if (!VALID_UDP_CEPID(cepid)) 332 return E_ID; 333 334 /* UDP 通信端点を得る。*/ 335 cep = GET_UDP_CEP(cepid); 336 337 /* UDP 通信端点をチェックする。*/ 338 if (!VALID_UDP_CEP(cep)) 339 return E_NOEXS; 340 341 /* UDP 通信端点が、動的生成用でなければエラー */ 342 if (!DYNAMIC_UDP_CEP(cep)) 343 return E_ID; 344 345 /* 通信端点をロックする。*/ 346 syscall(wai_sem(cep->semid_lock)); 347 348 /* 349 * UDP 通信端点をチェックする。未生成の場合はエラー 350 * ・未生成。 351 */ 352 if (!VALID_UDP_CEP(cep)) 353 error = E_NOEXS; 354 else { 355 udp_can_snd(cep, E_DLT); 356 udp_can_rcv(cep, E_DLT); 357 358 /* UDP 通信端点を未生成にする。*/ 359 cep->flags &= ~UDP_CEP_FLG_VALID; 360 error = E_OK; 361 } 362 363 /* 通信端点のロックを解除する。*/ 364 syscall(sig_sem(cep->semid_lock)); 365 366 return error; 367 } 368 369 #endif /* of #ifdef UDP_CFG_EXTENTIONS */ 370 371 #endif /* of #ifdef __udp_del_cep */ 137 /* 138 * IPv6 と IPv4 で引数が異なる関数のコンパイル 139 */ 140 141 #undef IN_GET_DATAGRAM 142 #undef IN_COPY_TO_HOST 143 144 #if defined(SUPPORT_INET6) && TNUM_UDP6_CEPID > 0 145 146 #define UDP_CANCEL_CEP udp6_cancel_cep 147 #define UDP_DELETE_CEP udp6_delete_cep 148 #define UDP_SET_OPTION udp6_set_option 149 #define UDP_GET_OPTION udp6_get_option 150 #define UDP_CRE_CEP udp6_cre_cep 151 #define UDP_DEL_CEP udp6_del_cep 152 #define UDP_SET_OPT udp6_set_opt 153 #define UDP_GET_OPT udp6_get_opt 154 #define UDP_SND_DAT udp6_snd_dat 155 #define UDP_RCV_DAT udp6_rcv_dat 156 #define UDP_CAN_SND udp6_can_snd 157 #define UDP_CAN_RCV udp6_can_rcv 158 #define UDP_ALLOC_AUTO_PORT udp6_alloc_auto_port 159 #define UDP_ALLOC_PORT udp6_alloc_port 160 #define UDP_SEND_DATA udp6_send_data 161 #define VALID_UDP_CEPID VALID_UDP6_CEPID 162 #define GET_UDP_CEP GET_UDP6_CEP 163 #define GET_UDP_CEPID GET_UDP6_CEPID 164 #define T_UDP_CEP T_UDP6_CEP 165 #define T_UDPN_CCEP T_UDP6_CCEP 166 #define T_IPEP T_IPV6EP 167 #define API_PROTO API_PROTO_IPV6 168 169 #if defined(_IP4_CFG) 170 #define IN_GET_DATAGRAM inn_get_datagram 171 #define IN_COPY_TO_HOST inn_copy_to_host 172 #else 173 #define IN_GET_DATAGRAM in6_get_datagram 174 #define IN_COPY_TO_HOST IN6_COPY_TO_HOST 175 #endif 176 177 #include <netinet/udpn_usrreq.c> 178 179 #undef UDP_CANCEL_CEP 180 #undef UDP_DELETE_CEP 181 #undef UDP_SET_OPTION 182 #undef UDP_GET_OPTION 183 #undef UDP_CRE_CEP 184 #undef UDP_DEL_CEP 185 #undef UDP_SET_OPT 186 #undef UDP_GET_OPT 187 #undef UDP_SND_DAT 188 #undef UDP_RCV_DAT 189 #undef UDP_CAN_SND 190 #undef UDP_CAN_RCV 191 #undef UDP_ALLOC_AUTO_PORT 192 #undef UDP_ALLOC_PORT 193 #undef UDP_SEND_DATA 194 #undef VALID_UDP_CEPID 195 #undef GET_UDP_CEP 196 #undef GET_UDP_CEPID 197 #undef T_UDP_CEP 198 #undef T_UDPN_CCEP 199 #undef T_IPEP 200 #undef API_PROTO 201 #undef IN_GET_DATAGRAM 202 #undef IN_COPY_TO_HOST 203 204 #endif /* of #if defined(SUPPORT_INET6) && TNUM_UDP6_CEPID > 0 */ 205 206 #if defined(SUPPORT_INET4) && TNUM_UDP4_CEPID > 0 207 208 #define UDP_CANCEL_CEP udp4_cancel_cep 209 #define UDP_DELETE_CEP udp4_delete_cep 210 #define UDP_SET_OPTION udp4_set_option 211 #define UDP_GET_OPTION udp4_get_option 212 #define UDP_CRE_CEP udp_cre_cep 213 #define UDP_DEL_CEP udp_del_cep 214 #define UDP_SET_OPT udp_set_opt 215 #define UDP_GET_OPT udp_get_opt 216 #define UDP_SND_DAT udp_snd_dat 217 #define UDP_RCV_DAT udp_rcv_dat 218 #define UDP_CAN_SND udp4_can_snd 219 #define UDP_CAN_RCV udp4_can_rcv 220 #define UDP_ALLOC_AUTO_PORT udp4_alloc_auto_port 221 #define UDP_ALLOC_PORT udp4_alloc_port 222 #define UDP_SEND_DATA udp4_send_data 223 #define VALID_UDP_CEPID VALID_UDP4_CEPID 224 #define GET_UDP_CEP GET_UDP4_CEP 225 #define GET_UDP_CEPID GET_UDP4_CEPID 226 #define T_UDP_CEP T_UDP4_CEP 227 #define T_UDPN_CCEP T_UDP_CCEP 228 #define T_IPEP T_IPV4EP 229 #define API_PROTO API_PROTO_IPV4 230 231 #define IN_COPY_TO_HOST IN4_COPY_TO_HOST 232 #define IN_GET_DATAGRAM in4_get_datagram 233 234 #include <netinet/udpn_usrreq.c> 235 236 #endif /* of #if defined(SUPPORT_INET4) && TNUM_UDP4_CEPID > 0 */ 237 238 #if defined(SUPPORT_INET6) && (defined(SUPPORT_INET4) && TNUM_UDP4_CEPID > 0) 239 240 /* 241 * udp_can_cep -- ペンディングしている処理のキャンセル【標準機能】 242 */ 372 243 373 244 #ifdef __udp_can_cep 374 375 /*376 * udp_can_cep -- ペンディングしている処理のキャンセル【標準機能】377 */378 245 379 246 ER 380 247 udp_can_cep (ID cepid, FN fncd) 381 248 { 382 T_UDP_CEP *cep; 383 ER error = E_OK, snd_err, rcv_err; 384 385 /* API 機能コードをチェックする。*/ 386 if (!VALID_TFN_UDP_CAN(fncd)) 387 return E_PAR; 388 389 /* UDP 通信端点 ID をチェックする。*/ 390 if (!VALID_UDP_CEPID(cepid)) 249 /* IPv6 用の UDP 通信端点 ID をチェックする。*/ 250 if (VALID_UDP6_CEPID(cepid)) { 251 252 /* UDP 通信端点を得てメイン関数を呼び出す。*/ 253 return udp6_cancel_cep(GET_UDP6_CEP(cepid), fncd); 254 } 255 256 /* IPv4 用の UDP 通信端点 ID をチェックする。*/ 257 else if (VALID_UDP4_CEPID(cepid)) { 258 259 /* UDP 通信端点を得てメイン関数を呼び出す。*/ 260 return udp4_cancel_cep(GET_UDP4_CEP(cepid), fncd); 261 } 262 263 else 391 264 return E_ID; 392 393 /* UDP 通信端点を得る。*/394 cep = GET_UDP_CEP(cepid);395 396 /* UDP 通信端点をチェックする。*/397 if (!VALID_UDP_CEP(cep))398 return E_NOEXS;399 400 /* 通信端点をロックする。*/401 syscall(wai_sem(cep->semid_lock));402 403 if (fncd == TFN_UDP_ALL) { /* TFN_UDP_ALL の処理 */404 405 snd_err = udp_can_snd(cep, E_RLWAI);406 rcv_err = udp_can_rcv(cep, E_RLWAI);407 408 /*409 * snd_err と rcv_err のどちらも EV_NOPND410 * なら、ペンディングしていないのでエラー411 */412 if (snd_err == EV_NOPND && rcv_err == EV_NOPND)413 error = E_OBJ;414 else {415 if (snd_err == EV_NOPND)416 snd_err = E_OK;417 if (rcv_err == EV_NOPND)418 rcv_err = E_OK;419 420 if (snd_err != E_OK)421 error = snd_err;422 else if (rcv_err != E_OK)423 error = rcv_err;424 }425 }426 else if (fncd == TFN_UDP_SND_DAT) { /* 送信処理のキャンセル */427 if ((error = udp_can_snd(cep, E_RLWAI)) == EV_NOPND)428 error = E_OBJ;429 }430 else if (fncd == TFN_UDP_RCV_DAT) { /* 受信処理のキャンセル */431 if ((error = udp_can_rcv(cep, E_RLWAI)) == EV_NOPND)432 error = E_OBJ;433 }434 else435 error = E_PAR;436 437 /* 通信端点をロックを解除する。*/438 syscall(sig_sem(cep->semid_lock));439 440 return error;441 265 } 442 266 443 267 #endif /* of #ifdef __udp_can_cep */ 444 268 445 /* 446 * udp_set_opt -- UDP 通信端点オプションの設定【拡張機能】 447 * 448 * 注意: 設定可能な UDP 通信端点オプションは無いため、E_PAR が返される。 449 */ 450 451 #ifdef __udp_set_opt 452 453 #ifdef UDP_CFG_EXTENTIONS 454 455 ER 456 udp_set_opt (ID cepid, int_t optname, void *optval, int_t optlen) 457 { 458 T_UDP_CEP *cep; 459 460 /* UDP 通信端点 ID をチェックする。*/ 461 if (!VALID_UDP_CEPID(cepid)) 462 return E_ID; 463 464 /* UDP 通信端点を得る。*/ 465 cep = GET_UDP_CEP(cepid); 466 467 /* UDP 通信端点をチェックする。*/ 468 if (!VALID_UDP_CEP(cep)) 469 return E_NOEXS; 470 471 return E_OK/*E_PAR*/; 472 } 473 474 #endif /* of #ifdef UDP_CFG_EXTENTIONS */ 475 476 #endif /* of #ifdef __udp_set_opt */ 477 478 /* 479 * udp_get_opt -- UDP 通信端点オプションの設定【拡張機能】 480 * 481 * 注意: 設定可能な UDP 通信端点オプションは無いため、E_PAR が返される。 482 */ 483 484 #ifdef __udp_get_opt 485 486 #ifdef UDP_CFG_EXTENTIONS 487 488 ER 489 udp_get_opt (ID cepid, int_t optname, void *optval, int_t optlen) 490 { 491 T_UDP_CEP *cep; 492 493 /* UDP 通信端点 ID をチェックする。*/ 494 if (!VALID_UDP_CEPID(cepid)) 495 return E_ID; 496 497 /* UDP 通信端点を得る。*/ 498 cep = GET_UDP_CEP(cepid); 499 500 /* UDP 通信端点をチェックする。*/ 501 if (!VALID_UDP_CEP(cep)) 502 return E_NOEXS; 503 504 return E_OK/*E_PAR*/; 505 } 506 507 #endif /* of #ifdef UDP_CFG_EXTENTIONS */ 508 509 #endif /* of #ifdef __udp_get_opt */ 510 511 #ifdef UDP_CFG_NON_BLOCKING 512 513 #include "udp_usrreq_nblk.c" 514 515 #else /* of #ifdef UDP_CFG_NON_BLOCKING */ 516 517 #ifdef __udp_can_snd 518 519 /* 520 * udp_can_snd -- ペンディングしている送信のキャンセル 521 */ 522 523 ER 524 udp_can_snd (T_UDP_CEP *cep, ER error) 525 { 526 if (cep->snd_tskid != TA_NULL) { /* 非ノンブロッキングコールでペンディング中 */ 527 528 #ifdef UDP_CFG_EXTENTIONS 529 530 /* 待ち中に発生したエラー情報を設定する。*/ 531 cep->error = error; 532 533 #endif /* of #ifdef UDP_CFG_EXTENTIONS */ 534 535 error = rel_wai(cep->snd_tskid); 536 cep->snd_tskid = TA_NULL; 537 } 538 else /* どちらでもないならペンディングしていない */ 539 error = EV_NOPND; 540 541 return error; 542 } 543 544 #endif /* of #ifdef __udp_can_snd */ 545 546 #ifdef __udp_can_rcv 547 548 /* 549 * udp_can_rcv -- ペンディングしている受信のキャンセル 550 */ 551 552 ER 553 udp_can_rcv (T_UDP_CEP *cep, ER error) 554 { 555 if (cep->rcv_tskid != TA_NULL) { /* 非ノンブロッキングコールでペンディング中 */ 556 557 #ifdef UDP_CFG_EXTENTIONS 558 559 /* 待ち中に発生したエラー情報を設定する。*/ 560 cep->error = error; 561 562 #endif /* of #ifdef UDP_CFG_EXTENTIONS */ 563 564 error = rel_wai(cep->rcv_tskid); 565 cep->rcv_tskid = TA_NULL; 566 } 567 else /* どちらでもないならペンディングしていない */ 568 error = EV_NOPND; 569 570 return error; 571 } 572 573 #endif /* of #ifdef __udp_can_rcv */ 574 575 #ifdef __udp_snd_dat 576 577 /* 578 * udp_snd_dat -- パケットの送信【標準機能】 579 */ 580 581 ER_UINT 582 UDP_SND_DAT (ID cepid, T_IPEP *p_dstaddr, void *data, int_t len, TMO tmout) 583 { 584 T_UDP_CEP *cep; 585 ER error; 586 587 /* p_dstaddr または data が NULL か、tmout が TMO_NBLK ならエラー */ 588 if (p_dstaddr == NULL || data == NULL || tmout == TMO_NBLK) 589 return E_PAR; 590 591 /* データ長をチェックする。*/ 592 if (len < 0 || len + IP_HDR_SIZE + UDP_HDR_SIZE > IF_MTU) 593 return E_PAR; 594 595 /* UDP 通信端点 ID をチェックする。*/ 596 if (!VALID_UDP_CEPID(cepid)) 597 return E_ID; 598 599 /* UDP 通信端点を得る。*/ 600 cep = GET_UDP_CEP(cepid); 601 602 /* UDP 通信端点をチェックする。*/ 603 if (!VALID_UDP_CEP(cep)) 604 return E_NOEXS; 605 606 /* 607 * 自ポート番号が UDP_PORTANY なら、自動で割り当てる。 608 */ 609 if (cep->myaddr.portno == UDP_PORTANY) { 610 if ((error = udp_alloc_auto_port(cep)) != E_OK) 611 return error; 612 } 613 614 /* 通信端点をロックする。*/ 615 syscall(wai_sem(cep->semid_lock)); 616 617 if (cep->snd_tskid != TA_NULL) { 618 619 /* 非ノンブロッキングコールでペンディング中 */ 620 error = E_QOVR; 621 622 /* 通信端点をロックを解除する。*/ 623 syscall(sig_sem(cep->semid_lock)); 624 } 625 else { 626 /* 現在のタスク識別子を記録する。*/ 627 get_tid(&(cep->snd_tskid)); 628 629 #ifdef UDP_CFG_EXTENTIONS 630 631 /* 待ち中に発生したエラー情報をリセットする。*/ 632 cep->error = E_OK; 633 634 #endif /* of #ifdef UDP_CFG_EXTENTIONS */ 635 636 /* 通信端点をロックを解除する。*/ 637 syscall(sig_sem(cep->semid_lock)); 638 639 /* パケットを送信する。*/ 640 error = udp_send_data(cep, p_dstaddr, data, len, tmout); 641 642 #ifdef UDP_CFG_EXTENTIONS 643 644 /* 待ち中に発生したエラー情報を返す。*/ 645 if (error == E_RLWAI) 646 error = cep->error; 647 648 #endif /* of #ifdef UDP_CFG_EXTENTIONS */ 649 } 650 651 return error; 652 } 653 654 #endif /* of #ifdef __udp_snd_dat */ 655 656 #ifdef __udp_rcv_dat 657 658 /* 659 * udp_rcv_dat -- パケットの受信【標準機能】 660 */ 661 662 ER_UINT 663 UDP_RCV_DAT (ID cepid, T_IPEP *p_dstaddr, void *data, int_t len, TMO tmout) 664 { 665 T_NET_BUF *input; 666 T_UDP_CEP *cep; 667 T_UDP_HDR *udph; 668 ER_UINT error; 669 uint_t ulen, uhoff; 670 671 /* p_dstaddr または data が NULL 、len < 0 か、tmout が TMO_NBLK ならエラー */ 672 if (p_dstaddr == NULL || data == NULL || len < 0 || tmout == TMO_NBLK) 673 return E_PAR; 674 675 /* UDP 通信端点 ID をチェックする。*/ 676 if (!VALID_UDP_CEPID(cepid)) 677 return E_ID; 678 679 /* UDP 通信端点を得る。*/ 680 cep = GET_UDP_CEP(cepid); 681 682 /* UDP 通信端点をチェックする。*/ 683 if (!VALID_UDP_CEP(cep)) 684 return E_NOEXS; 685 686 /* 通信端点をロックする。*/ 687 syscall(wai_sem(cep->semid_lock)); 688 689 if (cep->rcv_tskid != TA_NULL) { 690 691 /* 非ノンブロッキングコールでペンディング中 */ 692 error = E_QOVR; 693 694 /* 通信端点をロックを解除する。*/ 695 syscall(sig_sem(cep->semid_lock)); 696 } 697 else { 698 699 /* 現在のタスク識別子を記録する。*/ 700 get_tid(&(cep->rcv_tskid)); 701 702 #ifdef UDP_CFG_EXTENTIONS 703 704 /* 待ち中に発生したエラー情報をリセットする。*/ 705 cep->error = E_OK; 706 707 #endif /* of #ifdef UDP_CFG_EXTENTIONS */ 708 709 /* 通信端点をロックを解除する。*/ 710 syscall(sig_sem(cep->semid_lock)); 711 712 /* 入力があるまで待つ。*/ 713 if (cep->cb_netbuf != NULL) { 714 715 /* 716 * ここにくる場合は、コールバック関数の中から 717 * udp_rcv_dat を呼び出していることになり、 718 * すでに入力済みである。 719 */ 720 input = cep->cb_netbuf; 721 cep->cb_netbuf = NULL; 722 } 723 else if ((error = trcv_dtq(cep->rcvqid, (intptr_t*)&input, tmout)) != E_OK) { 724 725 #ifdef UDP_CFG_EXTENTIONS 726 727 /* 待ち中に発生したエラー情報を返す。*/ 728 if (error == E_RLWAI) 729 error = cep->error; 730 731 #endif /* of #ifdef UDP_CFG_EXTENTIONS */ 732 733 cep->rcv_tskid = TA_NULL; 734 return error; 735 } 736 737 /* p_dstaddr を設定する。*/ 738 uhoff = (uint_t)GET_UDP_HDR_OFFSET(input); 739 udph = GET_UDP_HDR(input, uhoff); 740 p_dstaddr->portno = ntohs(udph->sport); 741 IN_COPY_TO_HOST(&p_dstaddr->ipaddr, &GET_IP_HDR(input)->src); 742 743 /* データをバッファに移す。*/ 744 ulen = ntohs(udph->ulen); 745 if (ulen - UDP_HDR_SIZE > len) 746 error = E_BOVR; 747 else { 748 len = (uint_t)(ulen - UDP_HDR_SIZE); 749 error = (ER_UINT)(ulen - UDP_HDR_SIZE); 750 } 751 752 memcpy(data, GET_UDP_SDU(input, uhoff), (size_t)len); 753 754 syscall(rel_net_buf(input)); 755 756 cep->rcv_tskid = TA_NULL; 757 } 758 759 return error; 760 } 761 762 #endif /* of #ifdef __udp_rcv_dat */ 763 764 #endif /* of #ifdef UDP_CFG_NON_BLOCKING */ 269 #endif /* of #if defined(SUPPORT_INET6) && (defined(SUPPORT_INET4) && TNUM_UDP4_CEPID > 0) */ 765 270 766 271 #endif /* of #ifdef SUPPORT_UDP */
Note:
See TracChangeset
for help on using the changeset viewer.