1 /* $NetBSD: udp_usrreq.c,v 1.92 2001/12/21 02:51:08 itojun 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.92 2001/12/21 02:51:08 itojun 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: traditionally we dropped 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: traditionally we dropped 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 } else { 753 if (IN6_IS_ADDR_V4MAPPED(&dst6) && 754 (in6p->in6p_flags & IN6P_IPV6_V6ONLY)) 755 continue; 756 } 757 if (!IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_faddr)) { 758 if (!IN6_ARE_ADDR_EQUAL(&in6p->in6p_faddr, 759 &src6) || in6p->in6p_fport != sport) 760 continue; 761 } else { 762 if (IN6_IS_ADDR_V4MAPPED(&src6) && 763 (in6p->in6p_flags & IN6P_IPV6_V6ONLY)) 764 continue; 765 } 766 767 last = in6p; 768 udp6_sendup(m, off, (struct sockaddr *)src, 769 in6p->in6p_socket); 770 rcvcnt++; 771 772 /* 773 * Don't look for additional matches if this one does 774 * not have either the SO_REUSEPORT or SO_REUSEADDR 775 * socket options set. This heuristic avoids searching 776 * through all pcbs in the common case of a non-shared 777 * port. It assumes that an application will never 778 * clear these options after setting them. 779 */ 780 if ((in6p->in6p_socket->so_options & 781 (SO_REUSEPORT|SO_REUSEADDR)) == 0) 782 break; 783 } 784 } else { 785 /* 786 * Locate pcb for datagram. 787 */ 788 in6p = in6_pcblookup_connect(&udb6, &src6, sport, 789 &dst6, dport, 0); 790 if (in6p == 0) { 791 ++udpstat.udps_pcbhashmiss; 792 in6p = in6_pcblookup_bind(&udb6, &dst6, dport, 0); 793 if (in6p == 0) 794 return rcvcnt; 795 } 796 797 udp6_sendup(m, off, (struct sockaddr *)src, in6p->in6p_socket); 798 rcvcnt++; 799 } 800 801 bad: 802 return rcvcnt; 803 } 804 #endif 805 806 #ifdef INET 807 /* 808 * Notify a udp user of an asynchronous error; 809 * just wake up so that he can collect error status. 810 */ 811 static void 812 udp_notify(inp, errno) 813 struct inpcb *inp; 814 int errno; 815 { 816 817 inp->inp_socket->so_error = errno; 818 sorwakeup(inp->inp_socket); 819 sowwakeup(inp->inp_socket); 820 } 821 822 void * 823 udp_ctlinput(cmd, sa, v) 824 int cmd; 825 struct sockaddr *sa; 826 void *v; 827 { 828 struct ip *ip = v; 829 struct udphdr *uh; 830 void (*notify) __P((struct inpcb *, int)) = udp_notify; 831 int errno; 832 833 if (sa->sa_family != AF_INET 834 || sa->sa_len != sizeof(struct sockaddr_in)) 835 return NULL; 836 if ((unsigned)cmd >= PRC_NCMDS) 837 return NULL; 838 errno = inetctlerrmap[cmd]; 839 if (PRC_IS_REDIRECT(cmd)) 840 notify = in_rtchange, ip = 0; 841 else if (cmd == PRC_HOSTDEAD) 842 ip = 0; 843 else if (errno == 0) 844 return NULL; 845 if (ip) { 846 uh = (struct udphdr *)((caddr_t)ip + (ip->ip_hl << 2)); 847 in_pcbnotify(&udbtable, satosin(sa)->sin_addr, uh->uh_dport, 848 ip->ip_src, uh->uh_sport, errno, notify); 849 850 /* XXX mapped address case */ 851 } else 852 in_pcbnotifyall(&udbtable, satosin(sa)->sin_addr, errno, 853 notify); 854 return NULL; 855 } 856 857 int 858 #if __STDC__ 859 udp_output(struct mbuf *m, ...) 860 #else 861 udp_output(m, va_alist) 862 struct mbuf *m; 863 va_dcl 864 #endif 865 { 866 struct inpcb *inp; 867 struct udpiphdr *ui; 868 int len = m->m_pkthdr.len; 869 int error = 0; 870 va_list ap; 871 872 va_start(ap, m); 873 inp = va_arg(ap, struct inpcb *); 874 va_end(ap); 875 876 /* 877 * Calculate data length and get a mbuf 878 * for UDP and IP headers. 879 */ 880 M_PREPEND(m, sizeof(struct udpiphdr), M_DONTWAIT); 881 if (m == 0) { 882 error = ENOBUFS; 883 goto release; 884 } 885 886 /* 887 * Compute the packet length of the IP header, and 888 * punt if the length looks bogus. 889 */ 890 if ((len + sizeof(struct udpiphdr)) > IP_MAXPACKET) { 891 error = EMSGSIZE; 892 goto release; 893 } 894 895 /* 896 * Fill in mbuf with extended UDP header 897 * and addresses and length put into network format. 898 */ 899 ui = mtod(m, struct udpiphdr *); 900 ui->ui_pr = IPPROTO_UDP; 901 ui->ui_src = inp->inp_laddr; 902 ui->ui_dst = inp->inp_faddr; 903 ui->ui_sport = inp->inp_lport; 904 ui->ui_dport = inp->inp_fport; 905 ui->ui_ulen = htons((u_int16_t)len + sizeof(struct udphdr)); 906 907 /* 908 * Set up checksum and output datagram. 909 */ 910 if (udpcksum) { 911 /* 912 * XXX Cache pseudo-header checksum part for 913 * XXX "connected" UDP sockets. 914 */ 915 ui->ui_sum = in_cksum_phdr(ui->ui_src.s_addr, 916 ui->ui_dst.s_addr, htons((u_int16_t)len + 917 sizeof(struct udphdr) + IPPROTO_UDP)); 918 m->m_pkthdr.csum_flags = M_CSUM_UDPv4; 919 m->m_pkthdr.csum_data = offsetof(struct udphdr, uh_sum); 920 } else 921 ui->ui_sum = 0; 922 ((struct ip *)ui)->ip_len = sizeof (struct udpiphdr) + len; 923 ((struct ip *)ui)->ip_ttl = inp->inp_ip.ip_ttl; /* XXX */ 924 ((struct ip *)ui)->ip_tos = inp->inp_ip.ip_tos; /* XXX */ 925 udpstat.udps_opackets++; 926 927 #ifdef IPSEC 928 if (ipsec_setsocket(m, inp->inp_socket) != 0) { 929 error = ENOBUFS; 930 goto release; 931 } 932 #endif /*IPSEC*/ 933 934 return (ip_output(m, inp->inp_options, &inp->inp_route, 935 inp->inp_socket->so_options & (SO_DONTROUTE | SO_BROADCAST), 936 inp->inp_moptions)); 937 938 release: 939 m_freem(m); 940 return (error); 941 } 942 943 int udp_sendspace = 9216; /* really max datagram size */ 944 int udp_recvspace = 40 * (1024 + sizeof(struct sockaddr_in)); 945 /* 40 1K datagrams */ 946 947 /*ARGSUSED*/ 948 int 949 udp_usrreq(so, req, m, nam, control, p) 950 struct socket *so; 951 int req; 952 struct mbuf *m, *nam, *control; 953 struct proc *p; 954 { 955 struct inpcb *inp; 956 int s; 957 int error = 0; 958 959 if (req == PRU_CONTROL) 960 return (in_control(so, (long)m, (caddr_t)nam, 961 (struct ifnet *)control, p)); 962 963 if (req == PRU_PURGEIF) { 964 in_pcbpurgeif0(&udbtable, (struct ifnet *)control); 965 in_purgeif((struct ifnet *)control); 966 in_pcbpurgeif(&udbtable, (struct ifnet *)control); 967 return (0); 968 } 969 970 s = splsoftnet(); 971 inp = sotoinpcb(so); 972 #ifdef DIAGNOSTIC 973 if (req != PRU_SEND && req != PRU_SENDOOB && control) 974 panic("udp_usrreq: unexpected control mbuf"); 975 #endif 976 if (inp == 0 && req != PRU_ATTACH) { 977 error = EINVAL; 978 goto release; 979 } 980 981 /* 982 * Note: need to block udp_input while changing 983 * the udp pcb queue and/or pcb addresses. 984 */ 985 switch (req) { 986 987 case PRU_ATTACH: 988 if (inp != 0) { 989 error = EISCONN; 990 break; 991 } 992 if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) { 993 error = soreserve(so, udp_sendspace, udp_recvspace); 994 if (error) 995 break; 996 } 997 error = in_pcballoc(so, &udbtable); 998 if (error) 999 break; 1000 inp = sotoinpcb(so); 1001 inp->inp_ip.ip_ttl = ip_defttl; 1002 break; 1003 1004 case PRU_DETACH: 1005 in_pcbdetach(inp); 1006 break; 1007 1008 case PRU_BIND: 1009 error = in_pcbbind(inp, nam, p); 1010 break; 1011 1012 case PRU_LISTEN: 1013 error = EOPNOTSUPP; 1014 break; 1015 1016 case PRU_CONNECT: 1017 error = in_pcbconnect(inp, nam); 1018 if (error) 1019 break; 1020 soisconnected(so); 1021 break; 1022 1023 case PRU_CONNECT2: 1024 error = EOPNOTSUPP; 1025 break; 1026 1027 case PRU_DISCONNECT: 1028 /*soisdisconnected(so);*/ 1029 so->so_state &= ~SS_ISCONNECTED; /* XXX */ 1030 in_pcbdisconnect(inp); 1031 inp->inp_laddr = zeroin_addr; /* XXX */ 1032 in_pcbstate(inp, INP_BOUND); /* XXX */ 1033 break; 1034 1035 case PRU_SHUTDOWN: 1036 socantsendmore(so); 1037 break; 1038 1039 case PRU_RCVD: 1040 error = EOPNOTSUPP; 1041 break; 1042 1043 case PRU_SEND: 1044 if (control && control->m_len) { 1045 m_freem(control); 1046 m_freem(m); 1047 error = EINVAL; 1048 break; 1049 } 1050 { 1051 struct in_addr laddr; /* XXX */ 1052 1053 if (nam) { 1054 laddr = inp->inp_laddr; /* XXX */ 1055 if ((so->so_state & SS_ISCONNECTED) != 0) { 1056 error = EISCONN; 1057 goto die; 1058 } 1059 error = in_pcbconnect(inp, nam); 1060 if (error) { 1061 die: 1062 m_freem(m); 1063 break; 1064 } 1065 } else { 1066 if ((so->so_state & SS_ISCONNECTED) == 0) { 1067 error = ENOTCONN; 1068 goto die; 1069 } 1070 } 1071 error = udp_output(m, inp); 1072 if (nam) { 1073 in_pcbdisconnect(inp); 1074 inp->inp_laddr = laddr; /* XXX */ 1075 in_pcbstate(inp, INP_BOUND); /* XXX */ 1076 } 1077 } 1078 break; 1079 1080 case PRU_SENSE: 1081 /* 1082 * stat: don't bother with a blocksize. 1083 */ 1084 splx(s); 1085 return (0); 1086 1087 case PRU_RCVOOB: 1088 error = EOPNOTSUPP; 1089 break; 1090 1091 case PRU_SENDOOB: 1092 m_freem(control); 1093 m_freem(m); 1094 error = EOPNOTSUPP; 1095 break; 1096 1097 case PRU_SOCKADDR: 1098 in_setsockaddr(inp, nam); 1099 break; 1100 1101 case PRU_PEERADDR: 1102 in_setpeeraddr(inp, nam); 1103 break; 1104 1105 default: 1106 panic("udp_usrreq"); 1107 } 1108 1109 release: 1110 splx(s); 1111 return (error); 1112 } 1113 1114 /* 1115 * Sysctl for udp variables. 1116 */ 1117 int 1118 udp_sysctl(name, namelen, oldp, oldlenp, newp, newlen) 1119 int *name; 1120 u_int namelen; 1121 void *oldp; 1122 size_t *oldlenp; 1123 void *newp; 1124 size_t newlen; 1125 { 1126 /* All sysctl names at this level are terminal. */ 1127 if (namelen != 1) 1128 return (ENOTDIR); 1129 1130 switch (name[0]) { 1131 case UDPCTL_CHECKSUM: 1132 return (sysctl_int(oldp, oldlenp, newp, newlen, &udpcksum)); 1133 case UDPCTL_SENDSPACE: 1134 return (sysctl_int(oldp, oldlenp, newp, newlen, 1135 &udp_sendspace)); 1136 case UDPCTL_RECVSPACE: 1137 return (sysctl_int(oldp, oldlenp, newp, newlen, 1138 &udp_recvspace)); 1139 default: 1140 return (ENOPROTOOPT); 1141 } 1142 /* NOTREACHED */ 1143 } 1144 #endif 1145