Changeset 331 for EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/udp_input.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_input.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 * … … 72 72 #include <sil.h> 73 73 #include <t_syslog.h> 74 #include "tinet_cfg.h" 74 75 75 76 #endif /* of #ifdef TARGET_KERNEL_ASP */ … … 79 80 #include <s_services.h> 80 81 #include <t_services.h> 81 #include " kernel_id.h"82 #include "tinet_id.h" 82 83 83 84 #endif /* of #ifdef TARGET_KERNEL_JSP */ … … 92 93 #include <net/ppp_ipcp.h> 93 94 #include <net/net.h> 95 #include <net/net_endian.h> 94 96 #include <net/net_buf.h> 95 97 #include <net/net_count.h> … … 97 99 #include <netinet/in.h> 98 100 #include <netinet/in_var.h> 99 #include <netinet6/in6.h>100 #include <netinet6/in6_var.h>101 101 #include <netinet/in_itron.h> 102 102 #include <netinet/ip.h> 103 103 #include <netinet/ip_var.h> 104 #include <netinet/ip6.h>105 #include <netinet6/ip6_var.h>106 104 #include <netinet/ip_icmp.h> 107 #include <netinet/icmp6.h>108 109 105 #include <netinet/udp.h> 110 106 #include <netinet/udp_var.h> … … 124 120 #endif /* of #ifdef SUPPORT_MIB */ 125 121 126 #if defined(SUPPORT_INET4)127 128 #ifdef DHCP_CFG129 130 122 /* 131 * udp_dstaddr_accept -- UDP のあて先アドレスが正しいかチェックする。 132 * 133 * DHCP_CFG が定義されているときは、以下のデータグラムを受信する。 134 * 135 * ・あて先アドレスがブロードキャスト 136 * ・ローカルアドレスが未定義 123 * IPv6 と IPv4 で引数が異なる関数のコンパイル 137 124 */ 138 125 139 static bool_t 140 udp_is_dstaddr_accept (T_IN4_ADDR *myaddr, T_IN4_ADDR *dstaddr) 141 { 142 T_IFNET *ifp = IF_GET_IFNET(); 126 #undef IN_COPY_TO_HOST 143 127 144 if (ifp->in_ifaddr.addr == IPV4_ADDRANY || 145 ntohl(*dstaddr) == IPV4_ADDR_BROADCAST || 146 ntohl(*dstaddr) == ((ifp->in_ifaddr.addr & ifp->in_ifaddr.mask) | ~ifp->in_ifaddr.mask)) 147 return true; 148 else 149 return IN_IS_DSTADDR_ACCEPT(myaddr, dstaddr); 150 } 128 #if defined(_IP6_CFG) && TNUM_UDP6_CEPID > 0 151 129 152 #elif defined(ETHER_CFG_MULTICAST) 130 #define UDP_INPUT udp6_input 131 #define UDP_INPUT_SELECT udp6_input_select 132 #define UDP_REPLY_NO_PORT udp6_reply_no_port 133 #define UDP_FIND_CEP udp6_find_cep 134 #define GET_UDP_CEPID GET_UDP6_CEPID 135 #define T_UDP_CEP T_UDP6_CEP 136 #define API_PROTO API_PROTO_IPV6 153 137 154 /* 155 * udp_dstaddr_accept -- UDP のあて先アドレスが正しいかチェックする。 156 * 157 * 以下の場合もデータグラムを受信する。 158 * 159 * ・あて先アドレスがブロードキャスト 160 */ 138 #if defined(_IP4_CFG) 139 #define IN_COPY_TO_HOST inn_copy_to_host 140 #else 141 #define IN_COPY_TO_HOST IN6_COPY_TO_HOST 142 #endif 161 143 162 static bool_t 163 udp_is_dstaddr_accept (T_IN4_ADDR *myaddr, T_IN4_ADDR *dstaddr) 164 { 165 T_IFNET *ifp = IF_GET_IFNET(); 166 T_IN4_ADDR dst = ntohl(*dstaddr); 144 #include <netinet6/udp6_input.c> 145 #include <netinet/udpn_input.c> 167 146 168 if (dst == IPV4_ADDR_BROADCAST || 169 dst == ((ifp->in_ifaddr.addr & ifp->in_ifaddr.mask) | ~ifp->in_ifaddr.mask) || 170 IN4_IS_ADDR_MULTICAST(dst)) 171 return true; 172 else 173 return IN_IS_DSTADDR_ACCEPT(myaddr, dstaddr); 174 } 147 #undef UDP_INPUT 148 #undef UDP_INPUT_SELECT 149 #undef UDP_REPLY_NO_PORT 150 #undef UDP_FIND_CEP 151 #undef GET_UDP_CEPID 152 #undef T_UDP_CEP 153 #undef IN_COPY_TO_HOST 154 #undef API_PROTO 175 155 176 #e lse /* of #ifdef DHCP_CFG*/156 #endif /* of #if defined(_IP6_CFG) && TNUM_UDP6_CEPID > 0 */ 177 157 178 /* 179 * udp_dstaddr_accept -- UDP のあて先アドレスが正しいかチェックする。 180 * 181 * 以下の場合もデータグラムを受信する。 182 * 183 * ・あて先アドレスがブロードキャスト 184 */ 158 #if defined(_IP4_CFG) && ( (TNUM_UDP4_CEPID > 0) || \ 159 ((TNUM_UDP6_CEPID > 0) && defined(API_CFG_IP4MAPPED_ADDR))) 185 160 186 static bool_t 187 udp_is_dstaddr_accept (T_IN4_ADDR *myaddr, T_IN4_ADDR *dstaddr) 188 { 189 T_IFNET *ifp = IF_GET_IFNET(); 161 #define UDP_INPUT udp4_input 162 #define UDP_INPUT_SELECT udp4_input_select 163 #define UDP_REPLY_NO_PORT udp4_reply_no_port 164 #define UDP_FIND_CEP udp4_find_cep 165 #define GET_UDP_CEPID GET_UDP4_CEPID 166 #define T_UDP_CEP T_UDP4_CEP 167 #define IN_COPY_TO_HOST IN4_COPY_TO_HOST 168 #define API_PROTO API_PROTO_IPV4 190 169 191 if (ntohl(*dstaddr) == IPV4_ADDR_BROADCAST || 192 ntohl(*dstaddr) == ((ifp->in_ifaddr.addr & ifp->in_ifaddr.mask) | ~ifp->in_ifaddr.mask)) 193 return true; 194 else 195 return IN_IS_DSTADDR_ACCEPT(myaddr, dstaddr); 196 } 170 #include <netinet/udp4_input.c> 171 #include <netinet/udpn_input.c> 197 172 198 #endif /* of #ifdef DHCP_CFG */ 199 200 #endif /* of #if defined(SUPPORT_INET4) */ 201 202 #if defined(SUPPORT_INET6) 203 204 /* 205 * udp_dstaddr_accept -- UDP のあて先アドレスが正しいかチェックする。 206 * 207 * 以下の場合もデータグラムを受信する。 208 * 209 * ・あて先アドレスがマルチキャスト 210 */ 211 212 static bool_t 213 udp_is_dstaddr_accept (T_IN6_ADDR *myaddr, T_IN6_ADDR *dstaddr) 214 { 215 if (IN6_IS_ADDR_MULTICAST(dstaddr)) 216 return true; 217 else 218 return IN_IS_DSTADDR_ACCEPT(myaddr, dstaddr); 219 } 220 221 #endif /* of #if defined(SUPPORT_INET6) */ 222 223 /* 224 * udp_input -- UDP の入力関数 225 */ 226 227 uint_t 228 udp_input (T_NET_BUF **inputp, uint_t *offp, uint_t *nextp) 229 { 230 T_NET_BUF *input = *inputp; 231 T_UDP_CEP *cep; 232 T_UDP_HDR *udph; 233 T_IP_HDR *iph; 234 int_t ix; 235 uint_t len, hlen, ulen; 236 237 hlen = (uint_t)GET_IF_IP_HDR_SIZE(input); 238 239 NET_COUNT_UDP(net_count_udp.in_octets, input->len - hlen); 240 NET_COUNT_UDP(net_count_udp.in_packets, 1); 241 NET_COUNT_MIB(udp_stats.udpInDatagrams, 1); 242 243 /* ヘッダ長をチェックする。*/ 244 if (input->len < hlen + UDP_HDR_SIZE) 245 goto buf_rel; 246 247 udph = (T_UDP_HDR *)(input->buf + *offp); 248 249 /* データグラム長をチェックする */ 250 ulen = ntohs(udph->ulen); 251 if (ulen != input->len - hlen) 252 goto buf_rel; 253 254 /* 宛先ポートが 0 のデータグラムは破棄する。RFC768 */ 255 if (udph->dport == 0) 256 goto buf_rel; 257 258 #ifdef UDP_CFG_IN_CHECKSUM 259 260 /* チェックサムをチェックする */ 261 if (udph->sum && IN_CKSUM(input, IPPROTO_UDP, *offp, ulen) != 0) 262 goto buf_rel; 263 264 #endif /* of #ifdef UDP_CFG_IN_CHECKSUM */ 265 266 iph = GET_IP_HDR(input); 267 268 /* 宛先アドレスとポートをチェックする */ 269 for (ix = tmax_udp_ccepid; ix -- > 0; ) { 270 cep = &udp_cep[ix]; 271 if (VALID_UDP_CEP(cep) && 272 udp_is_dstaddr_accept(&cep->myaddr.ipaddr, &iph->dst) && 273 ntohs(udph->dport) == cep->myaddr.portno) { 274 len = (uint_t)(ntohs(udph->ulen) - UDP_HDR_SIZE); 275 276 if (cep->rcv_tskid != TA_NULL) { /* 非ノンブロッキングコールでペンディング中 */ 277 if (psnd_dtq(cep->rcvqid, (intptr_t)input) != E_OK) 278 goto buf_rel; 279 } 280 281 #ifdef UDP_CFG_NON_BLOCKING 282 283 else if (cep->rcv_p_dstaddr != NULL) { /* ノンブロッキングコールでペンディング中 */ 284 285 /* p_dstaddr を設定する。*/ 286 cep->rcv_p_dstaddr->portno = ntohs(udph->sport); 287 IN_COPY_TO_HOST(&cep->rcv_p_dstaddr->ipaddr, &GET_IP_HDR(input)->src); 288 289 /* データをバッファに移す。*/ 290 memcpy(cep->rcv_data, GET_UDP_SDU(input, *offp), 291 (size_t)(len < cep->rcv_len ? len : cep->rcv_len)); 292 syscall(rel_net_buf(input)); 293 294 if (IS_PTR_DEFINED(cep->callback)) 295 296 #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 297 298 (*cep->callback)(GET_UDP_CEPID(cep), TFN_UDP_RCV_DAT, (void*)(uint32_t)len); 299 300 #else /* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */ 301 302 (*cep->callback)(GET_UDP_CEPID(cep), TFN_UDP_RCV_DAT, (void*)&len); 303 304 #endif /* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */ 305 306 else 307 syslog(LOG_WARNING, "[UDP] no call back, CEP: %d.", GET_UDP_CEPID(cep)); 308 cep->rcv_p_dstaddr = NULL; 309 } 310 311 #endif /* of #ifdef UDP_CFG_NON_BLOCKING */ 312 313 else if (IS_PTR_DEFINED(cep->callback)) { 314 315 /* コールバック関数を呼び出す。*/ 316 cep->cb_netbuf = input; 317 318 #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 319 320 (*cep->callback)(GET_UDP_CEPID(cep), TEV_UDP_RCV_DAT, (void*)(uint32_t)len); 321 322 #else /* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */ 323 324 (*cep->callback)(GET_UDP_CEPID(cep), TEV_UDP_RCV_DAT, (void*)&len); 325 326 #endif /* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */ 327 328 /* 329 * ネットワークバッファがそのままであれば、コールバック関数内で 330 * データを読み出さなかったことになるので、捨てる。 331 */ 332 if (cep->cb_netbuf != NULL) 333 syscall(rel_net_buf(cep->cb_netbuf)); 334 } 335 else 336 goto buf_rel; 337 338 return IPPROTO_DONE; 339 } 340 } 341 342 NET_COUNT_MIB(udp_stats.udpNoPorts, 1); 343 344 #if defined(SUPPORT_INET4) 345 346 /* ローカル IP アドレスに届いたデータグラムのみ ICMP エラーを通知する。*/ 347 if (ntohl(iph->dst) == IF_GET_IFNET()->in_ifaddr.addr) { 348 syslog(LOG_INFO, "[UDP] unexp port: %d.", ntohs(udph->dport)); 349 350 icmp_error(ICMP4_UNREACH_PORT, input); 351 /* icmp_error では、ネットワークバッファ input を返却しないので下へ抜ける。*/ 352 } 353 354 #endif /* of #if defined(SUPPORT_INET4) */ 355 356 #if defined(SUPPORT_INET6) 357 358 /* マルチキャストアドレスに届いたデータグラムは ICMP エラーを通知しない。*/ 359 if (!IN6_IS_ADDR_MULTICAST(&iph->dst)) { 360 syslog(LOG_INFO, "[UDP] unexp port: %d.", ntohs(udph->dport)); 361 362 /* icmp6_error で、ネットワークバッファ input を返却する。*/ 363 icmp6_error(input, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_NOPORT, 0); 364 365 NET_COUNT_UDP(net_count_udp.in_err_packets, 1); 366 NET_COUNT_MIB(udp_stats.udpInErrors, 1); 367 return IPPROTO_DONE; 368 } 369 370 #endif /* of #if defined(SUPPORT_INET6) */ 371 372 buf_rel: 373 NET_COUNT_UDP(net_count_udp.in_err_packets, 1); 374 NET_COUNT_MIB(udp_stats.udpInErrors, 1); 375 syscall(rel_net_buf(input)); 376 return IPPROTO_DONE; 377 } 173 #endif /* of #if defined(_IP4_CFG) && TNUM_UDP4_CEPID > 0 */ 378 174 379 175 #endif /* of #ifdef SUPPORT_UDP */
Note:
See TracChangeset
for help on using the changeset viewer.