1 /* $NetBSD: udp_usrreq.c,v 1.104 2003/08/07 16:33:20 agc Exp $ */ 2 3 /* 4 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. Neither the name of the project nor the names of its contributors 16 * may be used to endorse or promote products derived from this software 17 * without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 */ 31 32 /* 33 * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1995 34 * The Regents of the University of California. All rights reserved. 35 * 36 * Redistribution and use in source and binary forms, with or without 37 * modification, are permitted provided that the following conditions 38 * are met: 39 * 1. Redistributions of source code must retain the above copyright 40 * notice, this list of conditions and the following disclaimer. 41 * 2. Redistributions in binary form must reproduce the above copyright 42 * notice, this list of conditions and the following disclaimer in the 43 * documentation and/or other materials provided with the distribution. 44 * 3. Neither the name of the University nor the names of its contributors 45 * may be used to endorse or promote products derived from this software 46 * without specific prior written permission. 47 * 48 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 49 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 50 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 51 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 52 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 53 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 54 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 55 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 57 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 58 * SUCH DAMAGE. 59 * 60 * @(#)udp_usrreq.c 8.6 (Berkeley) 5/23/95 61 */ 62 63 #include <sys/cdefs.h> 64 __KERNEL_RCSID(0, "$NetBSD: udp_usrreq.c,v 1.104 2003/08/07 16:33:20 agc Exp $"); 65 66 #include "opt_inet.h" 67 #include "opt_ipsec.h" 68 #include "opt_inet_csum.h" 69 #include "opt_ipkdb.h" 70 #include "opt_mbuftrace.h" 71 72 #include <sys/param.h> 73 #include <sys/malloc.h> 74 #include <sys/mbuf.h> 75 #include <sys/protosw.h> 76 #include <sys/socket.h> 77 #include <sys/socketvar.h> 78 #include <sys/errno.h> 79 #include <sys/stat.h> 80 #include <sys/systm.h> 81 #include <sys/proc.h> 82 #include <sys/domain.h> 83 #include <sys/sysctl.h> 84 85 #include <net/if.h> 86 #include <net/route.h> 87 88 #include <netinet/in.h> 89 #include <netinet/in_systm.h> 90 #include <netinet/in_var.h> 91 #include <netinet/ip.h> 92 #include <netinet/in_pcb.h> 93 #include <netinet/ip_var.h> 94 #include <netinet/ip_icmp.h> 95 #include <netinet/udp.h> 96 #include <netinet/udp_var.h> 97 98 #ifdef INET6 99 #include <netinet/ip6.h> 100 #include <netinet/icmp6.h> 101 #include <netinet6/ip6_var.h> 102 #include <netinet6/in6_pcb.h> 103 #include <netinet6/udp6_var.h> 104 #endif 105 106 #ifndef INET6 107 /* always need ip6.h for IP6_EXTHDR_GET */ 108 #include <netinet/ip6.h> 109 #endif 110 111 #include "faith.h" 112 #if defined(NFAITH) && NFAITH > 0 113 #include <net/if_faith.h> 114 #endif 115 116 #include <machine/stdarg.h> 117 118 #ifdef IPSEC 119 #include <netinet6/ipsec.h> 120 #include <netkey/key.h> 121 #endif /*IPSEC*/ 122 123 #ifdef IPKDB 124 #include <ipkdb/ipkdb.h> 125 #endif 126 127 /* 128 * UDP protocol implementation. 129 * Per RFC 768, August, 1980. 130 */ 131 #ifndef COMPAT_42 132 int udpcksum = 1; 133 #else 134 int udpcksum = 0; /* XXX */ 135 #endif 136 137 struct inpcbtable udbtable; 138 struct udpstat udpstat; 139 140 #ifdef INET 141 static void udp4_sendup __P((struct mbuf *, int, struct sockaddr *, 142 struct socket *)); 143 static int udp4_realinput __P((struct sockaddr_in *, struct sockaddr_in *, 144 struct mbuf *, int)); 145 #endif 146 #ifdef INET6 147 static void udp6_sendup __P((struct mbuf *, int, struct sockaddr *, 148 struct socket *)); 149 static int udp6_realinput __P((int, struct sockaddr_in6 *, 150 struct sockaddr_in6 *, struct mbuf *, int)); 151 #endif 152 #ifdef INET 153 static void udp_notify __P((struct inpcb *, int)); 154 #endif 155 156 #ifndef UDBHASHSIZE 157 #define UDBHASHSIZE 128 158 #endif 159 int udbhashsize = UDBHASHSIZE; 160 161 #ifdef MBUFTRACE 162 struct mowner udp_mowner = { "udp" }; 163 struct mowner udp_rx_mowner = { "udp", "rx" }; 164 struct mowner udp_tx_mowner = { "udp", "tx" }; 165 #endif 166 167 #ifdef UDP_CSUM_COUNTERS 168 #include <sys/device.h> 169 170 struct evcnt udp_hwcsum_bad = EVCNT_INITIALIZER(EVCNT_TYPE_MISC, 171 NULL, "udp", "hwcsum bad"); 172 struct evcnt udp_hwcsum_ok = EVCNT_INITIALIZER(EVCNT_TYPE_MISC, 173 NULL, "udp", "hwcsum ok"); 174 struct evcnt udp_hwcsum_data = EVCNT_INITIALIZER(EVCNT_TYPE_MISC, 175 NULL, "udp", "hwcsum data"); 176 struct evcnt udp_swcsum = EVCNT_INITIALIZER(EVCNT_TYPE_MISC, 177 NULL, "udp", "swcsum"); 178 179 #define UDP_CSUM_COUNTER_INCR(ev) (ev)->ev_count++ 180 181 #else 182 183 #define UDP_CSUM_COUNTER_INCR(ev) /* nothing */ 184 185 #endif /* UDP_CSUM_COUNTERS */ 186 187 void 188 udp_init() 189 { 190 191 #ifdef INET 192 in_pcbinit(&udbtable, udbhashsize, udbhashsize); 193 #endif 194 195 #ifdef UDP_CSUM_COUNTERS 196 evcnt_attach_static(&udp_hwcsum_bad); 197 evcnt_attach_static(&udp_hwcsum_ok); 198 evcnt_attach_static(&udp_hwcsum_data); 199 evcnt_attach_static(&udp_swcsum); 200 #endif /* UDP_CSUM_COUNTERS */ 201 202 MOWNER_ATTACH(&udp_tx_mowner); 203 MOWNER_ATTACH(&udp_rx_mowner); 204 MOWNER_ATTACH(&udp_mowner); 205 } 206 207 #ifdef INET 208 void 209 #if __STDC__ 210 udp_input(struct mbuf *m, ...) 211 #else 212 udp_input(m, va_alist) 213 struct mbuf *m; 214 va_dcl 215 #endif 216 { 217 va_list ap; 218 struct sockaddr_in src, dst; 219 struct ip *ip; 220 struct udphdr *uh; 221 int iphlen; 222 int len; 223 int n; 224 u_int16_t ip_len; 225 226 va_start(ap, m); 227 iphlen = va_arg(ap, int); 228 (void)va_arg(ap, int); /* ignore value, advance ap */ 229 va_end(ap); 230 231 MCLAIM(m, &udp_rx_mowner); 232 udpstat.udps_ipackets++; 233 234 /* 235 * Get IP and UDP header together in first mbuf. 236 */ 237 ip = mtod(m, struct ip *); 238 IP6_EXTHDR_GET(uh, struct udphdr *, m, iphlen, sizeof(struct udphdr)); 239 if (uh == NULL) { 240 udpstat.udps_hdrops++; 241 return; 242 } 243 KASSERT(UDP_HDR_ALIGNED_P(uh)); 244 245 /* destination port of 0 is illegal, based on RFC768. */ 246 if (uh->uh_dport == 0) 247 goto bad; 248 249 /* 250 * Make mbuf data length reflect UDP length. 251 * If not enough data to reflect UDP length, drop. 252 */ 253 ip_len = ntohs(ip->ip_len); 254 len = ntohs((u_int16_t)uh->uh_ulen); 255 if (ip_len != iphlen + len) { 256 if (ip_len < iphlen + len || len < sizeof(struct udphdr)) { 257 udpstat.udps_badlen++; 258 goto bad; 259 } 260 m_adj(m, iphlen + len - ip_len); 261 } 262 263 /* 264 * Checksum extended UDP header and data. 265 */ 266 if (uh->uh_sum) { 267 switch (m->m_pkthdr.csum_flags & 268 ((m->m_pkthdr.rcvif->if_csum_flags_rx & M_CSUM_UDPv4) | 269 M_CSUM_TCP_UDP_BAD | M_CSUM_DATA)) { 270 case M_CSUM_UDPv4|M_CSUM_TCP_UDP_BAD: 271 UDP_CSUM_COUNTER_INCR(&udp_hwcsum_bad); 272 goto badcsum; 273 274 case M_CSUM_UDPv4|M_CSUM_DATA: 275 UDP_CSUM_COUNTER_INCR(&udp_hwcsum_data); 276 if ((m->m_pkthdr.csum_data ^ 0xffff) != 0) 277 goto badcsum; 278 break; 279 280 case M_CSUM_UDPv4: 281 /* Checksum was okay. */ 282 UDP_CSUM_COUNTER_INCR(&udp_hwcsum_ok); 283 break; 284 285 default: 286 /* Need to compute it ourselves. */ 287 UDP_CSUM_COUNTER_INCR(&udp_swcsum); 288 if (in4_cksum(m, IPPROTO_UDP, iphlen, len) != 0) 289 goto badcsum; 290 break; 291 } 292 } 293 294 /* construct source and dst sockaddrs. */ 295 bzero(&src, sizeof(src)); 296 src.sin_family = AF_INET; 297 src.sin_len = sizeof(struct sockaddr_in); 298 bcopy(&ip->ip_src, &src.sin_addr, sizeof(src.sin_addr)); 299 src.sin_port = uh->uh_sport; 300 bzero(&dst, sizeof(dst)); 301 dst.sin_family = AF_INET; 302 dst.sin_len = sizeof(struct sockaddr_in); 303 bcopy(&ip->ip_dst, &dst.sin_addr, sizeof(dst.sin_addr)); 304 dst.sin_port = uh->uh_dport; 305 306 n = udp4_realinput(&src, &dst, m, iphlen); 307 #ifdef INET6 308 if (IN_MULTICAST(ip->ip_dst.s_addr) || n == 0) { 309 struct sockaddr_in6 src6, dst6; 310 311 bzero(&src6, sizeof(src6)); 312 src6.sin6_family = AF_INET6; 313 src6.sin6_len = sizeof(struct sockaddr_in6); 314 src6.sin6_addr.s6_addr[10] = src6.sin6_addr.s6_addr[11] = 0xff; 315 bcopy(&ip->ip_src, &src6.sin6_addr.s6_addr[12], 316 sizeof(ip->ip_src)); 317 src6.sin6_port = uh->uh_sport; 318 bzero(&dst6, sizeof(dst6)); 319 dst6.sin6_family = AF_INET6; 320 dst6.sin6_len = sizeof(struct sockaddr_in6); 321 dst6.sin6_addr.s6_addr[10] = dst6.sin6_addr.s6_addr[11] = 0xff; 322 bcopy(&ip->ip_dst, &dst6.sin6_addr.s6_addr[12], 323 sizeof(ip->ip_dst)); 324 dst6.sin6_port = uh->uh_dport; 325 326 n += udp6_realinput(AF_INET, &src6, &dst6, m, iphlen); 327 } 328 #endif 329 330 if (n == 0) { 331 if (m->m_flags & (M_BCAST | M_MCAST)) { 332 udpstat.udps_noportbcast++; 333 goto bad; 334 } 335 udpstat.udps_noport++; 336 #ifdef IPKDB 337 if (checkipkdb(&ip->ip_src, uh->uh_sport, uh->uh_dport, 338 m, iphlen + sizeof(struct udphdr), 339 m->m_pkthdr.len - iphlen - sizeof(struct udphdr))) { 340 /* 341 * It was a debugger connect packet, 342 * just drop it now 343 */ 344 goto bad; 345 } 346 #endif 347 icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_PORT, 0, 0); 348 m = NULL; 349 } 350 351 bad: 352 if (m) 353 m_freem(m); 354 return; 355 356 badcsum: 357 m_freem(m); 358 udpstat.udps_badsum++; 359 } 360 #endif 361 362 #ifdef INET6 363 int 364 udp6_input(mp, offp, proto) 365 struct mbuf **mp; 366 int *offp, proto; 367 { 368 struct mbuf *m = *mp; 369 int off = *offp; 370 struct sockaddr_in6 src, dst; 371 struct ip6_hdr *ip6; 372 struct udphdr *uh; 373 u_int32_t plen, ulen; 374 375 ip6 = mtod(m, struct ip6_hdr *); 376 377 #if defined(NFAITH) && 0 < NFAITH 378 if (faithprefix(&ip6->ip6_dst)) { 379 /* send icmp6 host unreach? */ 380 m_freem(m); 381 return IPPROTO_DONE; 382 } 383 #endif 384 385 udp6stat.udp6s_ipackets++; 386 387 /* check for jumbogram is done in ip6_input. we can trust pkthdr.len */ 388 plen = m->m_pkthdr.len - off; 389 IP6_EXTHDR_GET(uh, struct udphdr *, m, off, sizeof(struct udphdr)); 390 if (uh == NULL) { 391 ip6stat.ip6s_tooshort++; 392 return IPPROTO_DONE; 393 } 394 KASSERT(UDP_HDR_ALIGNED_P(uh)); 395 ulen = ntohs((u_short)uh->uh_ulen); 396 /* 397 * RFC2675 section 4: jumbograms will have 0 in the UDP header field, 398 * iff payload length > 0xffff. 399 */ 400 if (ulen == 0 && plen > 0xffff) 401 ulen = plen; 402 403 if (plen != ulen) { 404 udp6stat.udp6s_badlen++; 405 goto bad; 406 } 407 408 /* destination port of 0 is illegal, based on RFC768. */ 409 if (uh->uh_dport == 0) 410 goto bad; 411 412 /* Be proactive about malicious use of IPv4 mapped address */ 413 if (IN6_IS_ADDR_V4MAPPED(&ip6->ip6_src) || 414 IN6_IS_ADDR_V4MAPPED(&ip6->ip6_dst)) { 415 /* XXX stat */ 416 goto bad; 417 } 418 419 /* 420 * Checksum extended UDP header and data. 421 */ 422 if (uh->uh_sum == 0) 423 udp6stat.udp6s_nosum++; 424 else if (in6_cksum(m, IPPROTO_UDP, off, ulen) != 0) { 425 udp6stat.udp6s_badsum++; 426 goto bad; 427 } 428 429 /* 430 * Construct source and dst sockaddrs. 431 * Note that ifindex (s6_addr16[1]) is already filled. 432 */ 433 bzero(&src, sizeof(src)); 434 src.sin6_family = AF_INET6; 435 src.sin6_len = sizeof(struct sockaddr_in6); 436 /* KAME hack: recover scopeid */ 437 (void)in6_recoverscope(&src, &ip6->ip6_src, m->m_pkthdr.rcvif); 438 src.sin6_port = uh->uh_sport; 439 bzero(&dst, sizeof(dst)); 440 dst.sin6_family = AF_INET6; 441 dst.sin6_len = sizeof(struct sockaddr_in6); 442 /* KAME hack: recover scopeid */ 443 (void)in6_recoverscope(&dst, &ip6->ip6_dst, m->m_pkthdr.rcvif); 444 dst.sin6_port = uh->uh_dport; 445 446 if (udp6_realinput(AF_INET6, &src, &dst, m, off) == 0) { 447 if (m->m_flags & M_MCAST) { 448 udp6stat.udp6s_noportmcast++; 449 goto bad; 450 } 451 udp6stat.udp6s_noport++; 452 icmp6_error(m, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_NOPORT, 0); 453 m = NULL; 454 } 455 456 bad: 457 if (m) 458 m_freem(m); 459 return IPPROTO_DONE; 460 } 461 #endif 462 463 #ifdef INET 464 static void 465 udp4_sendup(m, off, src, so) 466 struct mbuf *m; 467 int off; /* offset of data portion */ 468 struct sockaddr *src; 469 struct socket *so; 470 { 471 struct mbuf *opts = NULL; 472 struct mbuf *n; 473 struct inpcb *inp = NULL; 474 475 if (!so) 476 return; 477 switch (so->so_proto->pr_domain->dom_family) { 478 case AF_INET: 479 inp = sotoinpcb(so); 480 break; 481 #ifdef INET6 482 case AF_INET6: 483 break; 484 #endif 485 default: 486 return; 487 } 488 489 #ifdef IPSEC 490 /* check AH/ESP integrity. */ 491 if (so != NULL && ipsec4_in_reject_so(m, so)) { 492 ipsecstat.in_polvio++; 493 return; 494 } 495 #endif /*IPSEC*/ 496 497 if ((n = m_copy(m, 0, M_COPYALL)) != NULL) { 498 if (inp && (inp->inp_flags & INP_CONTROLOPTS 499 || so->so_options & SO_TIMESTAMP)) { 500 struct ip *ip = mtod(n, struct ip *); 501 ip_savecontrol(inp, &opts, ip, n); 502 } 503 504 m_adj(n, off); 505 if (sbappendaddr(&so->so_rcv, src, n, 506 opts) == 0) { 507 m_freem(n); 508 if (opts) 509 m_freem(opts); 510 udpstat.udps_fullsock++; 511 } else 512 sorwakeup(so); 513 } 514 } 515 #endif 516 517 #ifdef INET6 518 static void 519 udp6_sendup(m, off, src, so) 520 struct mbuf *m; 521 int off; /* offset of data portion */ 522 struct sockaddr *src; 523 struct socket *so; 524 { 525 struct mbuf *opts = NULL; 526 struct mbuf *n; 527 struct in6pcb *in6p = NULL; 528 529 if (!so) 530 return; 531 if (so->so_proto->pr_domain->dom_family != AF_INET6) 532 return; 533 in6p = sotoin6pcb(so); 534 535 #ifdef IPSEC 536 /* check AH/ESP integrity. */ 537 if (so != NULL && ipsec6_in_reject_so(m, so)) { 538 ipsec6stat.in_polvio++; 539 return; 540 } 541 #endif /*IPSEC*/ 542 543 if ((n = m_copy(m, 0, M_COPYALL)) != NULL) { 544 if (in6p && (in6p->in6p_flags & IN6P_CONTROLOPTS 545 || in6p->in6p_socket->so_options & SO_TIMESTAMP)) { 546 struct ip6_hdr *ip6 = mtod(n, struct ip6_hdr *); 547 ip6_savecontrol(in6p, &opts, ip6, n); 548 } 549 550 m_adj(n, off); 551 if (sbappendaddr(&so->so_rcv, src, n, opts) == 0) { 552 m_freem(n); 553 if (opts) 554 m_freem(opts); 555 udp6stat.udp6s_fullsock++; 556 } else 557 sorwakeup(so); 558 } 559 } 560 #endif 561 562 #ifdef INET 563 static int 564 udp4_realinput(src, dst, m, off) 565 struct sockaddr_in *src; 566 struct sockaddr_in *dst; 567 struct mbuf *m; 568 int off; /* offset of udphdr */ 569 { 570 u_int16_t *sport, *dport; 571 int rcvcnt; 572 struct in_addr *src4, *dst4; 573 struct inpcb *inp; 574 575 rcvcnt = 0; 576 off += sizeof(struct udphdr); /* now, offset of payload */ 577 578 if (src->sin_family != AF_INET || dst->sin_family != AF_INET) 579 goto bad; 580 581 src4 = &src->sin_addr; 582 sport = &src->sin_port; 583 dst4 = &dst->sin_addr; 584 dport = &dst->sin_port; 585 586 if (IN_MULTICAST(dst4->s_addr) || 587 in_broadcast(*dst4, m->m_pkthdr.rcvif)) { 588 /* 589 * Deliver a multicast or broadcast datagram to *all* sockets 590 * for which the local and remote addresses and ports match 591 * those of the incoming datagram. This allows more than 592 * one process to receive multi/broadcasts on the same port. 593 * (This really ought to be done for unicast datagrams as 594 * well, but that would cause problems with existing 595 * applications that open both address-specific sockets and 596 * a wildcard socket listening to the same port -- they would 597 * end up receiving duplicates of every unicast datagram. 598 * Those applications open the multiple sockets to overcome an 599 * inadequacy of the UDP socket interface, but for backwards 600 * compatibility we avoid the problem here rather than 601 * fixing the interface. Maybe 4.5BSD will remedy this?) 602 */ 603 604 /* 605 * KAME note: traditionally we dropped udpiphdr from mbuf here. 606 * we need udpiphdr for IPsec processing so we do that later. 607 */ 608 /* 609 * Locate pcb(s) for datagram. 610 */ 611 CIRCLEQ_FOREACH(inp, &udbtable.inpt_queue, inp_queue) { 612 if (inp->inp_lport != *dport) 613 continue; 614 if (!in_nullhost(inp->inp_laddr)) { 615 if (!in_hosteq(inp->inp_laddr, *dst4)) 616 continue; 617 } 618 if (!in_nullhost(inp->inp_faddr)) { 619 if (!in_hosteq(inp->inp_faddr, *src4) || 620 inp->inp_fport != *sport) 621 continue; 622 } 623 624 udp4_sendup(m, off, (struct sockaddr *)src, 625 inp->inp_socket); 626 rcvcnt++; 627 628 /* 629 * Don't look for additional matches if this one does 630 * not have either the SO_REUSEPORT or SO_REUSEADDR 631 * socket options set. This heuristic avoids searching 632 * through all pcbs in the common case of a non-shared 633 * port. It assumes that an application will never 634 * clear these options after setting them. 635 */ 636 if ((inp->inp_socket->so_options & 637 (SO_REUSEPORT|SO_REUSEADDR)) == 0) 638 break; 639 } 640 } else { 641 /* 642 * Locate pcb for datagram. 643 */ 644 inp = in_pcblookup_connect(&udbtable, *src4, *sport, *dst4, *dport); 645 if (inp == 0) { 646 ++udpstat.udps_pcbhashmiss; 647 inp = in_pcblookup_bind(&udbtable, *dst4, *dport); 648 if (inp == 0) 649 return rcvcnt; 650 } 651 652 udp4_sendup(m, off, (struct sockaddr *)src, inp->inp_socket); 653 rcvcnt++; 654 } 655 656 bad: 657 return rcvcnt; 658 } 659 #endif 660 661 #ifdef INET6 662 static int 663 udp6_realinput(af, src, dst, m, off) 664 int af; /* af on packet */ 665 struct sockaddr_in6 *src; 666 struct sockaddr_in6 *dst; 667 struct mbuf *m; 668 int off; /* offset of udphdr */ 669 { 670 u_int16_t sport, dport; 671 int rcvcnt; 672 struct in6_addr src6, dst6; 673 const struct in_addr *dst4; 674 struct in6pcb *in6p; 675 676 rcvcnt = 0; 677 off += sizeof(struct udphdr); /* now, offset of payload */ 678 679 if (af != AF_INET && af != AF_INET6) 680 goto bad; 681 if (src->sin6_family != AF_INET6 || dst->sin6_family != AF_INET6) 682 goto bad; 683 684 in6_embedscope(&src6, src, NULL, NULL); 685 sport = src->sin6_port; 686 in6_embedscope(&dst6, dst, NULL, NULL); 687 dport = dst->sin6_port; 688 dst4 = (struct in_addr *)&dst->sin6_addr.s6_addr[12]; 689 690 if (IN6_IS_ADDR_MULTICAST(&dst6) || 691 (af == AF_INET && IN_MULTICAST(dst4->s_addr))) { 692 /* 693 * Deliver a multicast or broadcast datagram to *all* sockets 694 * for which the local and remote addresses and ports match 695 * those of the incoming datagram. This allows more than 696 * one process to receive multi/broadcasts on the same port. 697 * (This really ought to be done for unicast datagrams as 698 * well, but that would cause problems with existing 699 * applications that open both address-specific sockets and 700 * a wildcard socket listening to the same port -- they would 701 * end up receiving duplicates of every unicast datagram. 702 * Those applications open the multiple sockets to overcome an 703 * inadequacy of the UDP socket interface, but for backwards 704 * compatibility we avoid the problem here rather than 705 * fixing the interface. Maybe 4.5BSD will remedy this?) 706 */ 707 708 /* 709 * KAME note: traditionally we dropped udpiphdr from mbuf here. 710 * we need udpiphdr for IPsec processing so we do that later. 711 */ 712 /* 713 * Locate pcb(s) for datagram. 714 */ 715 for (in6p = udb6.in6p_next; in6p != &udb6; 716 in6p = in6p->in6p_next) { 717 if (in6p->in6p_lport != dport) 718 continue; 719 if (!IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_laddr)) { 720 if (!IN6_ARE_ADDR_EQUAL(&in6p->in6p_laddr, &dst6)) 721 continue; 722 } else { 723 if (IN6_IS_ADDR_V4MAPPED(&dst6) && 724 (in6p->in6p_flags & IN6P_IPV6_V6ONLY)) 725 continue; 726 } 727 if (!IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_faddr)) { 728 if (!IN6_ARE_ADDR_EQUAL(&in6p->in6p_faddr, 729 &src6) || in6p->in6p_fport != sport) 730 continue; 731 } else { 732 if (IN6_IS_ADDR_V4MAPPED(&src6) && 733 (in6p->in6p_flags & IN6P_IPV6_V6ONLY)) 734 continue; 735 } 736 737 udp6_sendup(m, off, (struct sockaddr *)src, 738 in6p->in6p_socket); 739 rcvcnt++; 740 741 /* 742 * Don't look for additional matches if this one does 743 * not have either the SO_REUSEPORT or SO_REUSEADDR 744 * socket options set. This heuristic avoids searching 745 * through all pcbs in the common case of a non-shared 746 * port. It assumes that an application will never 747 * clear these options after setting them. 748 */ 749 if ((in6p->in6p_socket->so_options & 750 (SO_REUSEPORT|SO_REUSEADDR)) == 0) 751 break; 752 } 753 } else { 754 /* 755 * Locate pcb for datagram. 756 */ 757 in6p = in6_pcblookup_connect(&udb6, &src6, sport, 758 &dst6, dport, 0); 759 if (in6p == 0) { 760 ++udpstat.udps_pcbhashmiss; 761 in6p = in6_pcblookup_bind(&udb6, &dst6, dport, 0); 762 if (in6p == 0) 763 return rcvcnt; 764 } 765 766 udp6_sendup(m, off, (struct sockaddr *)src, in6p->in6p_socket); 767 rcvcnt++; 768 } 769 770 bad: 771 return rcvcnt; 772 } 773 #endif 774 775 #ifdef INET 776 /* 777 * Notify a udp user of an asynchronous error; 778 * just wake up so that he can collect error status. 779 */ 780 static void 781 udp_notify(inp, errno) 782 struct inpcb *inp; 783 int errno; 784 { 785 786 inp->inp_socket->so_error = errno; 787 sorwakeup(inp->inp_socket); 788 sowwakeup(inp->inp_socket); 789 } 790 791 void * 792 udp_ctlinput(cmd, sa, v) 793 int cmd; 794 struct sockaddr *sa; 795 void *v; 796 { 797 struct ip *ip = v; 798 struct udphdr *uh; 799 void (*notify) __P((struct inpcb *, int)) = udp_notify; 800 int errno; 801 802 if (sa->sa_family != AF_INET 803 || sa->sa_len != sizeof(struct sockaddr_in)) 804 return NULL; 805 if ((unsigned)cmd >= PRC_NCMDS) 806 return NULL; 807 errno = inetctlerrmap[cmd]; 808 if (PRC_IS_REDIRECT(cmd)) 809 notify = in_rtchange, ip = 0; 810 else if (cmd == PRC_HOSTDEAD) 811 ip = 0; 812 else if (errno == 0) 813 return NULL; 814 if (ip) { 815 uh = (struct udphdr *)((caddr_t)ip + (ip->ip_hl << 2)); 816 in_pcbnotify(&udbtable, satosin(sa)->sin_addr, uh->uh_dport, 817 ip->ip_src, uh->uh_sport, errno, notify); 818 819 /* XXX mapped address case */ 820 } else 821 in_pcbnotifyall(&udbtable, satosin(sa)->sin_addr, errno, 822 notify); 823 return NULL; 824 } 825 826 int 827 #if __STDC__ 828 udp_output(struct mbuf *m, ...) 829 #else 830 udp_output(m, va_alist) 831 struct mbuf *m; 832 va_dcl 833 #endif 834 { 835 struct inpcb *inp; 836 struct udpiphdr *ui; 837 int len = m->m_pkthdr.len; 838 int error = 0; 839 va_list ap; 840 841 MCLAIM(m, &udp_tx_mowner); 842 va_start(ap, m); 843 inp = va_arg(ap, struct inpcb *); 844 va_end(ap); 845 846 /* 847 * Calculate data length and get a mbuf 848 * for UDP and IP headers. 849 */ 850 M_PREPEND(m, sizeof(struct udpiphdr), M_DONTWAIT); 851 if (m == 0) { 852 error = ENOBUFS; 853 goto release; 854 } 855 856 /* 857 * Compute the packet length of the IP header, and 858 * punt if the length looks bogus. 859 */ 860 if (len + sizeof(struct udpiphdr) > IP_MAXPACKET) { 861 error = EMSGSIZE; 862 goto release; 863 } 864 865 /* 866 * Fill in mbuf with extended UDP header 867 * and addresses and length put into network format. 868 */ 869 ui = mtod(m, struct udpiphdr *); 870 ui->ui_pr = IPPROTO_UDP; 871 ui->ui_src = inp->inp_laddr; 872 ui->ui_dst = inp->inp_faddr; 873 ui->ui_sport = inp->inp_lport; 874 ui->ui_dport = inp->inp_fport; 875 ui->ui_ulen = htons((u_int16_t)len + sizeof(struct udphdr)); 876 877 /* 878 * Set up checksum and output datagram. 879 */ 880 if (udpcksum) { 881 /* 882 * XXX Cache pseudo-header checksum part for 883 * XXX "connected" UDP sockets. 884 */ 885 ui->ui_sum = in_cksum_phdr(ui->ui_src.s_addr, 886 ui->ui_dst.s_addr, htons((u_int16_t)len + 887 sizeof(struct udphdr) + IPPROTO_UDP)); 888 m->m_pkthdr.csum_flags = M_CSUM_UDPv4; 889 m->m_pkthdr.csum_data = offsetof(struct udphdr, uh_sum); 890 } else 891 ui->ui_sum = 0; 892 ((struct ip *)ui)->ip_len = htons(sizeof (struct udpiphdr) + len); 893 ((struct ip *)ui)->ip_ttl = inp->inp_ip.ip_ttl; /* XXX */ 894 ((struct ip *)ui)->ip_tos = inp->inp_ip.ip_tos; /* XXX */ 895 udpstat.udps_opackets++; 896 897 #ifdef IPSEC 898 if (ipsec_setsocket(m, inp->inp_socket) != 0) { 899 error = ENOBUFS; 900 goto release; 901 } 902 #endif /*IPSEC*/ 903 904 return (ip_output(m, inp->inp_options, &inp->inp_route, 905 inp->inp_socket->so_options & (SO_DONTROUTE | SO_BROADCAST), 906 inp->inp_moptions)); 907 908 release: 909 m_freem(m); 910 return (error); 911 } 912 913 int udp_sendspace = 9216; /* really max datagram size */ 914 int udp_recvspace = 40 * (1024 + sizeof(struct sockaddr_in)); 915 /* 40 1K datagrams */ 916 917 /*ARGSUSED*/ 918 int 919 udp_usrreq(so, req, m, nam, control, p) 920 struct socket *so; 921 int req; 922 struct mbuf *m, *nam, *control; 923 struct proc *p; 924 { 925 struct inpcb *inp; 926 int s; 927 int error = 0; 928 929 if (req == PRU_CONTROL) 930 return (in_control(so, (long)m, (caddr_t)nam, 931 (struct ifnet *)control, p)); 932 933 if (req == PRU_PURGEIF) { 934 in_pcbpurgeif0(&udbtable, (struct ifnet *)control); 935 in_purgeif((struct ifnet *)control); 936 in_pcbpurgeif(&udbtable, (struct ifnet *)control); 937 return (0); 938 } 939 940 s = splsoftnet(); 941 inp = sotoinpcb(so); 942 #ifdef DIAGNOSTIC 943 if (req != PRU_SEND && req != PRU_SENDOOB && control) 944 panic("udp_usrreq: unexpected control mbuf"); 945 #endif 946 if (inp == 0 && req != PRU_ATTACH) { 947 error = EINVAL; 948 goto release; 949 } 950 951 /* 952 * Note: need to block udp_input while changing 953 * the udp pcb queue and/or pcb addresses. 954 */ 955 switch (req) { 956 957 case PRU_ATTACH: 958 if (inp != 0) { 959 error = EISCONN; 960 break; 961 } 962 #ifdef MBUFTRACE 963 so->so_mowner = &udp_mowner; 964 so->so_rcv.sb_mowner = &udp_rx_mowner; 965 so->so_snd.sb_mowner = &udp_tx_mowner; 966 #endif 967 if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) { 968 error = soreserve(so, udp_sendspace, udp_recvspace); 969 if (error) 970 break; 971 } 972 error = in_pcballoc(so, &udbtable); 973 if (error) 974 break; 975 inp = sotoinpcb(so); 976 inp->inp_ip.ip_ttl = ip_defttl; 977 break; 978 979 case PRU_DETACH: 980 in_pcbdetach(inp); 981 break; 982 983 case PRU_BIND: 984 error = in_pcbbind(inp, nam, p); 985 break; 986 987 case PRU_LISTEN: 988 error = EOPNOTSUPP; 989 break; 990 991 case PRU_CONNECT: 992 error = in_pcbconnect(inp, nam); 993 if (error) 994 break; 995 soisconnected(so); 996 break; 997 998 case PRU_CONNECT2: 999 error = EOPNOTSUPP; 1000 break; 1001 1002 case PRU_DISCONNECT: 1003 /*soisdisconnected(so);*/ 1004 so->so_state &= ~SS_ISCONNECTED; /* XXX */ 1005 in_pcbdisconnect(inp); 1006 inp->inp_laddr = zeroin_addr; /* XXX */ 1007 if (inp->inp_ia != NULL) { 1008 LIST_REMOVE(inp, inp_ialink); 1009 IFAFREE(&inp->inp_ia->ia_ifa); 1010 inp->inp_ia = NULL; 1011 } 1012 in_pcbstate(inp, INP_BOUND); /* XXX */ 1013 break; 1014 1015 case PRU_SHUTDOWN: 1016 socantsendmore(so); 1017 break; 1018 1019 case PRU_RCVD: 1020 error = EOPNOTSUPP; 1021 break; 1022 1023 case PRU_SEND: 1024 if (control && control->m_len) { 1025 m_freem(control); 1026 m_freem(m); 1027 error = EINVAL; 1028 break; 1029 } 1030 { 1031 struct in_addr laddr; /* XXX */ 1032 1033 if (nam) { 1034 laddr = inp->inp_laddr; /* XXX */ 1035 if ((so->so_state & SS_ISCONNECTED) != 0) { 1036 error = EISCONN; 1037 goto die; 1038 } 1039 error = in_pcbconnect(inp, nam); 1040 if (error) 1041 goto die; 1042 } else { 1043 if ((so->so_state & SS_ISCONNECTED) == 0) { 1044 error = ENOTCONN; 1045 goto die; 1046 } 1047 } 1048 error = udp_output(m, inp); 1049 m = NULL; 1050 if (nam) { 1051 in_pcbdisconnect(inp); 1052 inp->inp_laddr = laddr; /* XXX */ 1053 in_pcbstate(inp, INP_BOUND); /* XXX */ 1054 } 1055 die: 1056 if (inp->inp_ia != NULL && in_nullhost(inp->inp_laddr)) { 1057 LIST_REMOVE(inp, inp_ialink); 1058 IFAFREE(&inp->inp_ia->ia_ifa); 1059 inp->inp_ia = NULL; 1060 } 1061 if (m) 1062 m_freem(m); 1063 } 1064 break; 1065 1066 case PRU_SENSE: 1067 /* 1068 * stat: don't bother with a blocksize. 1069 */ 1070 splx(s); 1071 return (0); 1072 1073 case PRU_RCVOOB: 1074 error = EOPNOTSUPP; 1075 break; 1076 1077 case PRU_SENDOOB: 1078 m_freem(control); 1079 m_freem(m); 1080 error = EOPNOTSUPP; 1081 break; 1082 1083 case PRU_SOCKADDR: 1084 in_setsockaddr(inp, nam); 1085 break; 1086 1087 case PRU_PEERADDR: 1088 in_setpeeraddr(inp, nam); 1089 break; 1090 1091 default: 1092 panic("udp_usrreq"); 1093 } 1094 1095 release: 1096 splx(s); 1097 return (error); 1098 } 1099 1100 /* 1101 * Sysctl for udp variables. 1102 */ 1103 int 1104 udp_sysctl(name, namelen, oldp, oldlenp, newp, newlen) 1105 int *name; 1106 u_int namelen; 1107 void *oldp; 1108 size_t *oldlenp; 1109 void *newp; 1110 size_t newlen; 1111 { 1112 /* All sysctl names at this level are terminal. */ 1113 if (namelen != 1) 1114 return (ENOTDIR); 1115 1116 switch (name[0]) { 1117 case UDPCTL_CHECKSUM: 1118 return (sysctl_int(oldp, oldlenp, newp, newlen, &udpcksum)); 1119 case UDPCTL_SENDSPACE: 1120 return (sysctl_int(oldp, oldlenp, newp, newlen, 1121 &udp_sendspace)); 1122 case UDPCTL_RECVSPACE: 1123 return (sysctl_int(oldp, oldlenp, newp, newlen, 1124 &udp_recvspace)); 1125 default: 1126 return (ENOPROTOOPT); 1127 } 1128 /* NOTREACHED */ 1129 } 1130 #endif 1131