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