1 /* $NetBSD: udp_usrreq.c,v 1.78 2001/06/02 16:17:11 thorpej 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 "opt_inet.h" 68 #include "opt_ipsec.h" 69 #include "opt_inet_csum.h" 70 #include "opt_ipkdb.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 84 #include <uvm/uvm_extern.h> 85 #include <sys/sysctl.h> 86 87 #include <net/if.h> 88 #include <net/route.h> 89 90 #include <netinet/in.h> 91 #include <netinet/in_systm.h> 92 #include <netinet/in_var.h> 93 #include <netinet/ip.h> 94 #include <netinet/in_pcb.h> 95 #include <netinet/ip_var.h> 96 #include <netinet/ip_icmp.h> 97 #include <netinet/udp.h> 98 #include <netinet/udp_var.h> 99 100 #ifdef INET6 101 #include <netinet/ip6.h> 102 #include <netinet/icmp6.h> 103 #include <netinet6/ip6_var.h> 104 #include <netinet6/in6_pcb.h> 105 #include <netinet6/udp6_var.h> 106 #endif 107 108 #ifdef PULLDOWN_TEST 109 #ifndef INET6 110 /* always need ip6.h for IP6_EXTHDR_GET */ 111 #include <netinet/ip6.h> 112 #endif 113 #endif 114 115 #include "faith.h" 116 #if defined(NFAITH) && NFAITH > 0 117 #include <net/if_faith.h> 118 #endif 119 120 #include <machine/stdarg.h> 121 122 #ifdef IPSEC 123 #include <netinet6/ipsec.h> 124 #include <netkey/key.h> 125 #endif /*IPSEC*/ 126 127 #ifdef IPKDB 128 #include <ipkdb/ipkdb.h> 129 #endif 130 131 /* 132 * UDP protocol implementation. 133 * Per RFC 768, August, 1980. 134 */ 135 #ifndef COMPAT_42 136 int udpcksum = 1; 137 #else 138 int udpcksum = 0; /* XXX */ 139 #endif 140 141 #ifdef INET 142 static void udp4_sendup __P((struct mbuf *, int, struct sockaddr *, 143 struct socket *)); 144 static int udp4_realinput __P((struct sockaddr_in *, struct sockaddr_in *, 145 struct mbuf *, int)); 146 #endif 147 #ifdef INET6 148 static void udp6_sendup __P((struct mbuf *, int, struct sockaddr *, 149 struct socket *)); 150 static int in6_mcmatch __P((struct in6pcb *, struct in6_addr *, 151 struct ifnet *)); 152 static int udp6_realinput __P((int, struct sockaddr_in6 *, 153 struct sockaddr_in6 *, struct mbuf *, int)); 154 #endif 155 #ifdef INET 156 static void udp_notify __P((struct inpcb *, int)); 157 #endif 158 159 #ifndef UDBHASHSIZE 160 #define UDBHASHSIZE 128 161 #endif 162 int udbhashsize = UDBHASHSIZE; 163 164 #ifdef UDP_CSUM_COUNTERS 165 #include <sys/device.h> 166 167 struct evcnt udp_hwcsum_bad = EVCNT_INITIALIZER(EVCNT_TYPE_MISC, 168 NULL, "udp", "hwcsum bad"); 169 struct evcnt udp_hwcsum_ok = EVCNT_INITIALIZER(EVCNT_TYPE_MISC, 170 NULL, "udp", "hwcsum ok"); 171 struct evcnt udp_hwcsum_data = EVCNT_INITIALIZER(EVCNT_TYPE_MISC, 172 NULL, "udp", "hwcsum data"); 173 struct evcnt udp_swcsum = EVCNT_INITIALIZER(EVCNT_TYPE_MISC, 174 NULL, "udp", "swcsum"); 175 176 #define UDP_CSUM_COUNTER_INCR(ev) (ev)->ev_count++ 177 178 #else 179 180 #define UDP_CSUM_COUNTER_INCR(ev) /* nothing */ 181 182 #endif /* UDP_CSUM_COUNTERS */ 183 184 void 185 udp_init() 186 { 187 188 #ifdef INET 189 in_pcbinit(&udbtable, udbhashsize, udbhashsize); 190 #endif 191 192 #ifdef UDP_CSUM_COUNTERS 193 evcnt_attach_static(&udp_hwcsum_bad); 194 evcnt_attach_static(&udp_hwcsum_ok); 195 evcnt_attach_static(&udp_hwcsum_data); 196 evcnt_attach_static(&udp_swcsum); 197 #endif /* UDP_CSUM_COUNTERS */ 198 } 199 200 #ifndef UDP6 201 #ifdef INET 202 void 203 #if __STDC__ 204 udp_input(struct mbuf *m, ...) 205 #else 206 udp_input(m, va_alist) 207 struct mbuf *m; 208 va_dcl 209 #endif 210 { 211 va_list ap; 212 struct sockaddr_in src, dst; 213 struct ip *ip; 214 struct udphdr *uh; 215 int iphlen, proto; 216 int len; 217 int n; 218 219 va_start(ap, m); 220 iphlen = va_arg(ap, int); 221 proto = va_arg(ap, int); 222 va_end(ap); 223 224 udpstat.udps_ipackets++; 225 226 #ifndef PULLDOWN_TEST 227 /* 228 * Strip IP options, if any; should skip this, 229 * make available to user, and use on returned packets, 230 * but we don't yet have a way to check the checksum 231 * with options still present. 232 */ 233 if (iphlen > sizeof (struct ip)) { 234 ip_stripoptions(m, (struct mbuf *)0); 235 iphlen = sizeof(struct ip); 236 } 237 #else 238 /* 239 * we may enable the above code if we save and pass IPv4 options 240 * to the userland. 241 */ 242 #endif 243 244 /* 245 * Get IP and UDP header together in first mbuf. 246 */ 247 ip = mtod(m, struct ip *); 248 #ifndef PULLDOWN_TEST 249 if (m->m_len < iphlen + sizeof(struct udphdr)) { 250 if ((m = m_pullup(m, iphlen + sizeof(struct udphdr))) == 0) { 251 udpstat.udps_hdrops++; 252 return; 253 } 254 ip = mtod(m, struct ip *); 255 } 256 uh = (struct udphdr *)((caddr_t)ip + iphlen); 257 #else 258 IP6_EXTHDR_GET(uh, struct udphdr *, m, iphlen, sizeof(struct udphdr)); 259 if (uh == NULL) { 260 udpstat.udps_hdrops++; 261 return; 262 } 263 #endif 264 265 /* destination port of 0 is illegal, based on RFC768. */ 266 if (uh->uh_dport == 0) 267 goto bad; 268 269 /* 270 * Make mbuf data length reflect UDP length. 271 * If not enough data to reflect UDP length, drop. 272 */ 273 len = ntohs((u_int16_t)uh->uh_ulen); 274 if (ip->ip_len != iphlen + len) { 275 if (ip->ip_len < iphlen + len || len < sizeof(struct udphdr)) { 276 udpstat.udps_badlen++; 277 goto bad; 278 } 279 m_adj(m, iphlen + len - ip->ip_len); 280 } 281 282 /* 283 * Checksum extended UDP header and data. 284 */ 285 if (uh->uh_sum) { 286 switch (m->m_pkthdr.csum_flags & 287 ((m->m_pkthdr.rcvif->if_csum_flags & M_CSUM_UDPv4) | 288 M_CSUM_TCP_UDP_BAD | M_CSUM_DATA)) { 289 case M_CSUM_UDPv4|M_CSUM_TCP_UDP_BAD: 290 UDP_CSUM_COUNTER_INCR(&udp_hwcsum_bad); 291 goto badcsum; 292 293 case M_CSUM_UDPv4|M_CSUM_DATA: 294 UDP_CSUM_COUNTER_INCR(&udp_hwcsum_data); 295 if ((m->m_pkthdr.csum_data ^ 0xffff) != 0) 296 goto badcsum; 297 break; 298 299 case M_CSUM_UDPv4: 300 /* Checksum was okay. */ 301 UDP_CSUM_COUNTER_INCR(&udp_hwcsum_ok); 302 break; 303 304 default: 305 /* Need to compute it ourselves. */ 306 UDP_CSUM_COUNTER_INCR(&udp_swcsum); 307 if (in4_cksum(m, IPPROTO_UDP, iphlen, len) != 0) 308 goto badcsum; 309 break; 310 } 311 } 312 313 /* construct source and dst sockaddrs. */ 314 bzero(&src, sizeof(src)); 315 src.sin_family = AF_INET; 316 src.sin_len = sizeof(struct sockaddr_in); 317 bcopy(&ip->ip_src, &src.sin_addr, sizeof(src.sin_addr)); 318 src.sin_port = uh->uh_sport; 319 bzero(&dst, sizeof(dst)); 320 dst.sin_family = AF_INET; 321 dst.sin_len = sizeof(struct sockaddr_in); 322 bcopy(&ip->ip_dst, &dst.sin_addr, sizeof(dst.sin_addr)); 323 dst.sin_port = uh->uh_dport; 324 325 n = udp4_realinput(&src, &dst, m, iphlen); 326 #ifdef INET6 327 if (IN_MULTICAST(ip->ip_dst.s_addr) || n == 0) { 328 struct sockaddr_in6 src6, dst6; 329 330 bzero(&src6, sizeof(src6)); 331 src6.sin6_family = AF_INET6; 332 src6.sin6_len = sizeof(struct sockaddr_in6); 333 src6.sin6_addr.s6_addr[10] = src6.sin6_addr.s6_addr[11] = 0xff; 334 bcopy(&ip->ip_src, &src6.sin6_addr.s6_addr[12], 335 sizeof(ip->ip_src)); 336 src6.sin6_port = uh->uh_sport; 337 bzero(&dst6, sizeof(dst6)); 338 dst6.sin6_family = AF_INET6; 339 dst6.sin6_len = sizeof(struct sockaddr_in6); 340 dst6.sin6_addr.s6_addr[10] = dst6.sin6_addr.s6_addr[11] = 0xff; 341 bcopy(&ip->ip_dst, &dst6.sin6_addr.s6_addr[12], 342 sizeof(ip->ip_dst)); 343 dst6.sin6_port = uh->uh_dport; 344 345 n += udp6_realinput(AF_INET, &src6, &dst6, m, iphlen); 346 } 347 #endif 348 349 if (n == 0) { 350 if (m->m_flags & (M_BCAST | M_MCAST)) { 351 udpstat.udps_noportbcast++; 352 goto bad; 353 } 354 udpstat.udps_noport++; 355 #ifdef IPKDB 356 if (checkipkdb(&ip->ip_src, uh->uh_sport, uh->uh_dport, 357 m, iphlen + sizeof(struct udphdr), 358 m->m_pkthdr.len - iphlen - sizeof(struct udphdr))) { 359 /* 360 * It was a debugger connect packet, 361 * just drop it now 362 */ 363 goto bad; 364 } 365 #endif 366 icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_PORT, 0, 0); 367 m = NULL; 368 } 369 370 bad: 371 if (m) 372 m_freem(m); 373 return; 374 375 badcsum: 376 m_freem(m); 377 udpstat.udps_badsum++; 378 } 379 #endif 380 381 #ifdef INET6 382 int 383 udp6_input(mp, offp, proto) 384 struct mbuf **mp; 385 int *offp, proto; 386 { 387 struct mbuf *m = *mp; 388 int off = *offp; 389 struct sockaddr_in6 src, dst; 390 struct ip6_hdr *ip6; 391 struct udphdr *uh; 392 u_int32_t plen, ulen; 393 394 #ifndef PULLDOWN_TEST 395 IP6_EXTHDR_CHECK(m, off, sizeof(struct udphdr), IPPROTO_DONE); 396 #endif 397 ip6 = mtod(m, struct ip6_hdr *); 398 399 #if defined(NFAITH) && 0 < NFAITH 400 if (faithprefix(&ip6->ip6_dst)) { 401 /* send icmp6 host unreach? */ 402 m_freem(m); 403 return IPPROTO_DONE; 404 } 405 #endif 406 407 udp6stat.udp6s_ipackets++; 408 409 /* check for jumbogram is done in ip6_input. we can trust pkthdr.len */ 410 plen = m->m_pkthdr.len - off; 411 #ifndef PULLDOWN_TEST 412 uh = (struct udphdr *)((caddr_t)ip6 + off); 413 #else 414 IP6_EXTHDR_GET(uh, struct udphdr *, m, off, sizeof(struct udphdr)); 415 if (uh == NULL) { 416 ip6stat.ip6s_tooshort++; 417 return IPPROTO_DONE; 418 } 419 #endif 420 ulen = ntohs((u_short)uh->uh_ulen); 421 /* 422 * RFC2675 section 4: jumbograms will have 0 in the UDP header field, 423 * iff payload length > 0xffff. 424 */ 425 if (ulen == 0 && plen > 0xffff) 426 ulen = plen; 427 428 if (plen != ulen) { 429 udp6stat.udp6s_badlen++; 430 goto bad; 431 } 432 433 /* destination port of 0 is illegal, based on RFC768. */ 434 if (uh->uh_dport == 0) 435 goto bad; 436 437 /* Be proactive about malicious use of IPv4 mapped address */ 438 if (IN6_IS_ADDR_V4MAPPED(&ip6->ip6_src) || 439 IN6_IS_ADDR_V4MAPPED(&ip6->ip6_dst)) { 440 /* XXX stat */ 441 goto bad; 442 } 443 444 /* 445 * Checksum extended UDP header and data. 446 */ 447 if (uh->uh_sum == 0) 448 udp6stat.udp6s_nosum++; 449 else if (in6_cksum(m, IPPROTO_UDP, off, ulen) != 0) { 450 udp6stat.udp6s_badsum++; 451 goto bad; 452 } 453 454 /* 455 * Construct source and dst sockaddrs. 456 * Note that ifindex (s6_addr16[1]) is already filled. 457 */ 458 bzero(&src, sizeof(src)); 459 src.sin6_family = AF_INET6; 460 src.sin6_len = sizeof(struct sockaddr_in6); 461 /* KAME hack: recover scopeid */ 462 (void)in6_recoverscope(&src, &ip6->ip6_src, m->m_pkthdr.rcvif); 463 src.sin6_port = uh->uh_sport; 464 bzero(&dst, sizeof(dst)); 465 dst.sin6_family = AF_INET6; 466 dst.sin6_len = sizeof(struct sockaddr_in6); 467 /* KAME hack: recover scopeid */ 468 (void)in6_recoverscope(&dst, &ip6->ip6_dst, m->m_pkthdr.rcvif); 469 dst.sin6_port = uh->uh_dport; 470 471 if (udp6_realinput(AF_INET6, &src, &dst, m, off) == 0) { 472 if (m->m_flags & M_MCAST) { 473 udp6stat.udp6s_noportmcast++; 474 goto bad; 475 } 476 udp6stat.udp6s_noport++; 477 icmp6_error(m, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_NOPORT, 0); 478 m = NULL; 479 } 480 481 bad: 482 if (m) 483 m_freem(m); 484 return IPPROTO_DONE; 485 } 486 #endif 487 488 #ifdef INET 489 static void 490 udp4_sendup(m, off, src, so) 491 struct mbuf *m; 492 int off; /* offset of data portion */ 493 struct sockaddr *src; 494 struct socket *so; 495 { 496 struct mbuf *opts = NULL; 497 struct mbuf *n; 498 struct inpcb *inp = NULL; 499 #ifdef INET6 500 struct in6pcb *in6p = NULL; 501 #endif 502 503 if (!so) 504 return; 505 switch (so->so_proto->pr_domain->dom_family) { 506 case AF_INET: 507 inp = sotoinpcb(so); 508 break; 509 #ifdef INET6 510 case AF_INET6: 511 in6p = sotoin6pcb(so); 512 break; 513 #endif 514 default: 515 return; 516 } 517 518 #ifdef IPSEC 519 /* check AH/ESP integrity. */ 520 if (so != NULL && ipsec4_in_reject_so(m, so)) { 521 ipsecstat.in_polvio++; 522 return; 523 } 524 #endif /*IPSEC*/ 525 526 if ((n = m_copy(m, 0, M_COPYALL)) != NULL) { 527 if (inp && (inp->inp_flags & INP_CONTROLOPTS 528 || so->so_options & SO_TIMESTAMP)) { 529 struct ip *ip = mtod(n, struct ip *); 530 ip_savecontrol(inp, &opts, ip, n); 531 } 532 533 m_adj(n, off); 534 if (sbappendaddr(&so->so_rcv, src, n, 535 opts) == 0) { 536 m_freem(n); 537 if (opts) 538 m_freem(opts); 539 } else 540 sorwakeup(so); 541 } 542 } 543 #endif 544 545 #ifdef INET6 546 static void 547 udp6_sendup(m, off, src, so) 548 struct mbuf *m; 549 int off; /* offset of data portion */ 550 struct sockaddr *src; 551 struct socket *so; 552 { 553 struct mbuf *opts = NULL; 554 struct mbuf *n; 555 struct in6pcb *in6p = NULL; 556 557 if (!so) 558 return; 559 if (so->so_proto->pr_domain->dom_family != AF_INET6) 560 return; 561 in6p = sotoin6pcb(so); 562 563 #ifdef IPSEC 564 /* check AH/ESP integrity. */ 565 if (so != NULL && ipsec6_in_reject_so(m, so)) { 566 ipsec6stat.in_polvio++; 567 return; 568 } 569 #endif /*IPSEC*/ 570 571 if ((n = m_copy(m, 0, M_COPYALL)) != NULL) { 572 if (in6p && (in6p->in6p_flags & IN6P_CONTROLOPTS 573 || in6p->in6p_socket->so_options & SO_TIMESTAMP)) { 574 struct ip6_hdr *ip6 = mtod(n, struct ip6_hdr *); 575 ip6_savecontrol(in6p, &opts, ip6, n); 576 } 577 578 m_adj(n, off); 579 if (sbappendaddr(&so->so_rcv, src, n, opts) == 0) { 580 m_freem(n); 581 if (opts) 582 m_freem(opts); 583 udp6stat.udp6s_fullsock++; 584 } else 585 sorwakeup(so); 586 } 587 } 588 #endif 589 590 #ifdef INET 591 static int 592 udp4_realinput(src, dst, m, off) 593 struct sockaddr_in *src; 594 struct sockaddr_in *dst; 595 struct mbuf *m; 596 int off; /* offset of udphdr */ 597 { 598 u_int16_t *sport, *dport; 599 int rcvcnt; 600 struct in_addr *src4, *dst4; 601 struct inpcb *inp; 602 603 rcvcnt = 0; 604 off += sizeof(struct udphdr); /* now, offset of payload */ 605 606 if (src->sin_family != AF_INET || dst->sin_family != AF_INET) 607 goto bad; 608 609 src4 = &src->sin_addr; 610 sport = &src->sin_port; 611 dst4 = &dst->sin_addr; 612 dport = &dst->sin_port; 613 614 if (IN_MULTICAST(dst4->s_addr) || 615 in_broadcast(*dst4, m->m_pkthdr.rcvif)) { 616 struct inpcb *last; 617 /* 618 * Deliver a multicast or broadcast datagram to *all* sockets 619 * for which the local and remote addresses and ports match 620 * those of the incoming datagram. This allows more than 621 * one process to receive multi/broadcasts on the same port. 622 * (This really ought to be done for unicast datagrams as 623 * well, but that would cause problems with existing 624 * applications that open both address-specific sockets and 625 * a wildcard socket listening to the same port -- they would 626 * end up receiving duplicates of every unicast datagram. 627 * Those applications open the multiple sockets to overcome an 628 * inadequacy of the UDP socket interface, but for backwards 629 * compatibility we avoid the problem here rather than 630 * fixing the interface. Maybe 4.5BSD will remedy this?) 631 */ 632 633 /* 634 * KAME note: usually we drop udpiphdr from mbuf here. 635 * we need udpiphdr for IPsec processing so we do that later. 636 */ 637 /* 638 * Locate pcb(s) for datagram. 639 */ 640 for (inp = udbtable.inpt_queue.cqh_first; 641 inp != (struct inpcb *)&udbtable.inpt_queue; 642 inp = inp->inp_queue.cqe_next) { 643 if (inp->inp_lport != *dport) 644 continue; 645 if (!in_nullhost(inp->inp_laddr)) { 646 if (!in_hosteq(inp->inp_laddr, *dst4)) 647 continue; 648 } 649 if (!in_nullhost(inp->inp_faddr)) { 650 if (!in_hosteq(inp->inp_faddr, *src4) || 651 inp->inp_fport != *sport) 652 continue; 653 } 654 655 last = inp; 656 udp4_sendup(m, off, (struct sockaddr *)src, 657 inp->inp_socket); 658 rcvcnt++; 659 660 /* 661 * Don't look for additional matches if this one does 662 * not have either the SO_REUSEPORT or SO_REUSEADDR 663 * socket options set. This heuristic avoids searching 664 * through all pcbs in the common case of a non-shared 665 * port. It assumes that an application will never 666 * clear these options after setting them. 667 */ 668 if ((inp->inp_socket->so_options & 669 (SO_REUSEPORT|SO_REUSEADDR)) == 0) 670 break; 671 } 672 673 #if 0 674 if (last == NULL) { 675 /* 676 * No matching pcb found; discard datagram. 677 * (No need to send an ICMP Port Unreachable 678 * for a broadcast or multicast datgram.) 679 */ 680 udpstat.udps_noportbcast++; 681 goto bad; 682 } 683 #endif 684 } else { 685 /* 686 * Locate pcb for datagram. 687 */ 688 inp = in_pcblookup_connect(&udbtable, *src4, *sport, *dst4, *dport); 689 if (inp == 0) { 690 ++udpstat.udps_pcbhashmiss; 691 inp = in_pcblookup_bind(&udbtable, *dst4, *dport); 692 if (inp == 0) { 693 #if 0 694 struct mbuf *n; 695 696 if (m->m_flags & (M_BCAST | M_MCAST)) { 697 udpstat.udps_noportbcast++; 698 goto bad; 699 } 700 udpstat.udps_noport++; 701 #ifdef IPKDB 702 if (checkipkdb(src4, *sport, *dport, m, off, 703 m->m_pkthdr.len - off)) { 704 /* 705 * It was a debugger connect packet, 706 * just drop it now 707 */ 708 goto bad; 709 } 710 #endif 711 if ((n = m_copy(m, 0, M_COPYALL)) != NULL) { 712 icmp_error(n, ICMP_UNREACH, 713 ICMP_UNREACH_PORT, 0, 0); 714 } 715 #endif 716 return rcvcnt; 717 } 718 } 719 720 udp4_sendup(m, off, (struct sockaddr *)src, inp->inp_socket); 721 rcvcnt++; 722 } 723 724 bad: 725 return rcvcnt; 726 } 727 #endif 728 729 #ifdef INET6 730 static int 731 in6_mcmatch(in6p, ia6, ifp) 732 struct in6pcb *in6p; 733 struct in6_addr *ia6; 734 struct ifnet *ifp; 735 { 736 struct ip6_moptions *im6o = in6p->in6p_moptions; 737 struct in6_multi_mship *imm; 738 739 if (im6o == NULL) 740 return 0; 741 742 for (imm = im6o->im6o_memberships.lh_first; imm != NULL; 743 imm = imm->i6mm_chain.le_next) { 744 if ((ifp == NULL || 745 imm->i6mm_maddr->in6m_ifp == ifp) && 746 IN6_ARE_ADDR_EQUAL(&imm->i6mm_maddr->in6m_addr, 747 ia6)) 748 return 1; 749 } 750 return 0; 751 } 752 753 static int 754 udp6_realinput(af, src, dst, m, off) 755 int af; /* af on packet */ 756 struct sockaddr_in6 *src; 757 struct sockaddr_in6 *dst; 758 struct mbuf *m; 759 int off; /* offset of udphdr */ 760 { 761 u_int16_t *sport, *dport; 762 int rcvcnt; 763 struct in6_addr *src6, *dst6; 764 struct in_addr *dst4; 765 struct in6pcb *in6p; 766 767 rcvcnt = 0; 768 off += sizeof(struct udphdr); /* now, offset of payload */ 769 770 if (af != AF_INET && af != AF_INET6) 771 goto bad; 772 if (src->sin6_family != AF_INET6 || dst->sin6_family != AF_INET6) 773 goto bad; 774 775 src6 = &src->sin6_addr; 776 sport = &src->sin6_port; 777 dst6 = &dst->sin6_addr; 778 dport = &dst->sin6_port; 779 dst4 = (struct in_addr *)&dst->sin6_addr.s6_addr32[12]; 780 781 if (IN6_IS_ADDR_MULTICAST(dst6) 782 || (af == AF_INET && IN_MULTICAST(dst4->s_addr))) { 783 struct in6pcb *last; 784 /* 785 * Deliver a multicast or broadcast datagram to *all* sockets 786 * for which the local and remote addresses and ports match 787 * those of the incoming datagram. This allows more than 788 * one process to receive multi/broadcasts on the same port. 789 * (This really ought to be done for unicast datagrams as 790 * well, but that would cause problems with existing 791 * applications that open both address-specific sockets and 792 * a wildcard socket listening to the same port -- they would 793 * end up receiving duplicates of every unicast datagram. 794 * Those applications open the multiple sockets to overcome an 795 * inadequacy of the UDP socket interface, but for backwards 796 * compatibility we avoid the problem here rather than 797 * fixing the interface. Maybe 4.5BSD will remedy this?) 798 */ 799 800 /* 801 * KAME note: usually we drop udpiphdr from mbuf here. 802 * we need udpiphdr for IPsec processing so we do that later. 803 */ 804 /* 805 * Locate pcb(s) for datagram. 806 */ 807 for (in6p = udb6.in6p_next; in6p != &udb6; 808 in6p = in6p->in6p_next) { 809 if (in6p->in6p_lport != *dport) 810 continue; 811 if (!IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_laddr)) { 812 if (!IN6_ARE_ADDR_EQUAL(&in6p->in6p_laddr, dst6) 813 && !in6_mcmatch(in6p, dst6, m->m_pkthdr.rcvif)) 814 continue; 815 } 816 #ifndef INET6_BINDV6ONLY 817 else { 818 if (IN6_IS_ADDR_V4MAPPED(dst6) 819 && (in6p->in6p_flags & IN6P_BINDV6ONLY)) 820 continue; 821 } 822 #endif 823 if (!IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_faddr)) { 824 if (!IN6_ARE_ADDR_EQUAL(&in6p->in6p_faddr, src6) 825 || in6p->in6p_fport != *sport) 826 continue; 827 } 828 #ifndef INET6_BINDV6ONLY 829 else { 830 if (IN6_IS_ADDR_V4MAPPED(src6) 831 && (in6p->in6p_flags & IN6P_BINDV6ONLY)) 832 continue; 833 } 834 #endif 835 836 last = in6p; 837 udp6_sendup(m, off, (struct sockaddr *)src, 838 in6p->in6p_socket); 839 rcvcnt++; 840 841 /* 842 * Don't look for additional matches if this one does 843 * not have either the SO_REUSEPORT or SO_REUSEADDR 844 * socket options set. This heuristic avoids searching 845 * through all pcbs in the common case of a non-shared 846 * port. It assumes that an application will never 847 * clear these options after setting them. 848 */ 849 if ((in6p->in6p_socket->so_options & 850 (SO_REUSEPORT|SO_REUSEADDR)) == 0) 851 break; 852 } 853 854 #if 0 855 if (last == NULL) { 856 /* 857 * No matching pcb found; discard datagram. 858 * (No need to send an ICMP Port Unreachable 859 * for a broadcast or multicast datgram.) 860 */ 861 switch (af) { 862 case AF_INET: 863 udpstat.udps_noportbcast++; 864 break; 865 case AF_INET6: 866 udp6stat.udp6s_noportmcast++; 867 break; 868 } 869 goto bad; 870 } 871 #endif 872 } else { 873 /* 874 * Locate pcb for datagram. 875 */ 876 in6p = in6_pcblookup_connect(&udb6, src6, *sport, 877 dst6, *dport, 0); 878 if (in6p == 0) { 879 ++udpstat.udps_pcbhashmiss; 880 in6p = in6_pcblookup_bind(&udb6, dst6, *dport, 0); 881 if (in6p == 0) { 882 #if 0 883 struct mbuf *n; 884 n = m_copy(m, 0, M_COPYALL); 885 switch (af) { 886 case AF_INET: 887 if (m->m_flags & (M_BCAST | M_MCAST)) { 888 udpstat.udps_noportbcast++; 889 goto bad; 890 } 891 udpstat.udps_noport++; 892 if (n != NULL) 893 icmp_error(n, ICMP_UNREACH, 894 ICMP_UNREACH_PORT, 0, 0); 895 break; 896 case AF_INET6: 897 if (m->m_flags & M_MCAST) { 898 udp6stat.udp6s_noportmcast++; 899 goto bad; 900 } 901 udp6stat.udp6s_noport++; 902 if (n != NULL) 903 icmp6_error(n, ICMP6_DST_UNREACH, 904 ICMP6_DST_UNREACH_NOPORT, 0); 905 break; 906 } 907 #endif 908 909 return rcvcnt; 910 } 911 } 912 913 udp6_sendup(m, off, (struct sockaddr *)src, in6p->in6p_socket); 914 rcvcnt++; 915 } 916 917 bad: 918 return rcvcnt; 919 } 920 #endif 921 922 #else /*UDP6*/ 923 924 void 925 #if __STDC__ 926 udp_input(struct mbuf *m, ...) 927 #else 928 udp_input(m, va_alist) 929 struct mbuf *m; 930 va_dcl 931 #endif 932 { 933 int proto; 934 struct ip *ip; 935 struct udphdr *uh; 936 struct inpcb *inp; 937 struct mbuf *opts = 0; 938 int len; 939 struct ip save_ip; 940 int iphlen; 941 va_list ap; 942 struct sockaddr_in udpsrc; 943 struct sockaddr *sa; 944 945 va_start(ap, m); 946 iphlen = va_arg(ap, int); 947 proto = va_arg(ap, int); 948 va_end(ap); 949 950 udpstat.udps_ipackets++; 951 952 /* 953 * Strip IP options, if any; should skip this, 954 * make available to user, and use on returned packets, 955 * but we don't yet have a way to check the checksum 956 * with options still present. 957 */ 958 if (iphlen > sizeof (struct ip)) { 959 ip_stripoptions(m, (struct mbuf *)0); 960 iphlen = sizeof(struct ip); 961 } 962 963 /* 964 * Get IP and UDP header together in first mbuf. 965 */ 966 ip = mtod(m, struct ip *); 967 if (m->m_len < iphlen + sizeof(struct udphdr)) { 968 if ((m = m_pullup(m, iphlen + sizeof(struct udphdr))) == 0) { 969 udpstat.udps_hdrops++; 970 return; 971 } 972 ip = mtod(m, struct ip *); 973 } 974 uh = (struct udphdr *)((caddr_t)ip + iphlen); 975 976 /* destination port of 0 is illegal, based on RFC768. */ 977 if (uh->uh_dport == 0) 978 goto bad; 979 980 /* 981 * Make mbuf data length reflect UDP length. 982 * If not enough data to reflect UDP length, drop. 983 */ 984 len = ntohs((u_int16_t)uh->uh_ulen); 985 if (ip->ip_len != iphlen + len) { 986 if (ip->ip_len < iphlen + len || len < sizeof(struct udphdr)) { 987 udpstat.udps_badlen++; 988 goto bad; 989 } 990 m_adj(m, iphlen + len - ip->ip_len); 991 } 992 /* 993 * Save a copy of the IP header in case we want restore it 994 * for sending an ICMP error message in response. 995 */ 996 save_ip = *ip; 997 998 /* 999 * Checksum extended UDP header and data. 1000 */ 1001 if (uh->uh_sum) { 1002 switch (m->m_pkthdr.csum_flags & 1003 ((m->m_pkthdr.rcvif->if_csum_flags & M_CSUM_UDPv4) | 1004 M_CSUM_TCP_UDP_BAD | M_CSUM_DATA)) { 1005 case M_CSUM_UDPv4|M_CSUM_TCP_UDP_BAD: 1006 UDP_CSUM_COUNTER_INCR(&udp_hwcsum_bad); 1007 goto badcsum; 1008 1009 case M_CSUM_UDPv4|M_CSUM_DATA: 1010 UDP_CSUM_COUNTER_INCR(&udp_hwcsum_data); 1011 if ((m->m_pkthdr.csum_data ^ 0xffff) != 0) 1012 goto badcsum; 1013 break; 1014 1015 case M_CSUM_UDPv4: 1016 /* Checksum was okay. */ 1017 UDP_CSUM_COUNTER_INCR(&udp_hwcsum_ok); 1018 break; 1019 1020 default: 1021 /* Need to compute it ourselves. */ 1022 UDP_CSUM_COUNTER_INCR(&udp_swcsum); 1023 bzero(((struct ipovly *)ip)->ih_x1, 1024 sizeof ((struct ipovly *)ip)->ih_x1); 1025 ((struct ipovly *)ip)->ih_len = uh->uh_ulen; 1026 if (in_cksum(m, len + sizeof (struct ip)) != 0) 1027 goto badcsum; 1028 break; 1029 } 1030 } 1031 1032 /* 1033 * Construct sockaddr format source address. 1034 */ 1035 udpsrc.sin_family = AF_INET; 1036 udpsrc.sin_len = sizeof(struct sockaddr_in); 1037 udpsrc.sin_addr = ip->ip_src; 1038 udpsrc.sin_port = uh->uh_sport; 1039 bzero((caddr_t)udpsrc.sin_zero, sizeof(udpsrc.sin_zero)); 1040 1041 if (IN_MULTICAST(ip->ip_dst.s_addr) || 1042 in_broadcast(ip->ip_dst, m->m_pkthdr.rcvif)) { 1043 struct inpcb *last; 1044 /* 1045 * Deliver a multicast or broadcast datagram to *all* sockets 1046 * for which the local and remote addresses and ports match 1047 * those of the incoming datagram. This allows more than 1048 * one process to receive multi/broadcasts on the same port. 1049 * (This really ought to be done for unicast datagrams as 1050 * well, but that would cause problems with existing 1051 * applications that open both address-specific sockets and 1052 * a wildcard socket listening to the same port -- they would 1053 * end up receiving duplicates of every unicast datagram. 1054 * Those applications open the multiple sockets to overcome an 1055 * inadequacy of the UDP socket interface, but for backwards 1056 * compatibility we avoid the problem here rather than 1057 * fixing the interface. Maybe 4.5BSD will remedy this?) 1058 */ 1059 1060 iphlen += sizeof(struct udphdr); 1061 /* 1062 * KAME note: usually we drop udpiphdr from mbuf here. 1063 * we need udpiphdr for IPsec processing so we do that later. 1064 */ 1065 /* 1066 * Locate pcb(s) for datagram. 1067 * (Algorithm copied from raw_intr().) 1068 */ 1069 last = NULL; 1070 for (inp = udbtable.inpt_queue.cqh_first; 1071 inp != (struct inpcb *)&udbtable.inpt_queue; 1072 inp = inp->inp_queue.cqe_next) { 1073 if (inp->inp_lport != uh->uh_dport) 1074 continue; 1075 if (!in_nullhost(inp->inp_laddr)) { 1076 if (!in_hosteq(inp->inp_laddr, ip->ip_dst)) 1077 continue; 1078 } 1079 if (!in_nullhost(inp->inp_faddr)) { 1080 if (!in_hosteq(inp->inp_faddr, ip->ip_src) || 1081 inp->inp_fport != uh->uh_sport) 1082 continue; 1083 } 1084 1085 if (last != NULL) { 1086 struct mbuf *n; 1087 1088 #ifdef IPSEC 1089 /* check AH/ESP integrity. */ 1090 if (last != NULL && ipsec4_in_reject(m, last)) { 1091 ipsecstat.in_polvio++; 1092 /* do not inject data to pcb */ 1093 } else 1094 #endif /*IPSEC*/ 1095 if ((n = m_copy(m, 0, M_COPYALL)) != NULL) { 1096 if (last->inp_flags & INP_CONTROLOPTS 1097 || last->inp_socket->so_options & 1098 SO_TIMESTAMP) { 1099 ip_savecontrol(last, &opts, 1100 ip, n); 1101 } 1102 m_adj(n, iphlen); 1103 sa = (struct sockaddr *)&udpsrc; 1104 if (sbappendaddr( 1105 &last->inp_socket->so_rcv, 1106 sa, n, opts) == 0) { 1107 m_freem(n); 1108 if (opts) 1109 m_freem(opts); 1110 } else 1111 sorwakeup(last->inp_socket); 1112 opts = 0; 1113 } 1114 } 1115 last = inp; 1116 /* 1117 * Don't look for additional matches if this one does 1118 * not have either the SO_REUSEPORT or SO_REUSEADDR 1119 * socket options set. This heuristic avoids searching 1120 * through all pcbs in the common case of a non-shared 1121 * port. It * assumes that an application will never 1122 * clear these options after setting them. 1123 */ 1124 if ((last->inp_socket->so_options & 1125 (SO_REUSEPORT|SO_REUSEADDR)) == 0) 1126 break; 1127 } 1128 1129 if (last == NULL) { 1130 /* 1131 * No matching pcb found; discard datagram. 1132 * (No need to send an ICMP Port Unreachable 1133 * for a broadcast or multicast datgram.) 1134 */ 1135 udpstat.udps_noportbcast++; 1136 goto bad; 1137 } 1138 #ifdef IPSEC 1139 /* check AH/ESP integrity. */ 1140 if (last != NULL && ipsec4_in_reject(m, last)) { 1141 ipsecstat.in_polvio++; 1142 goto bad; 1143 } 1144 #endif /*IPSEC*/ 1145 if (last->inp_flags & INP_CONTROLOPTS || 1146 last->inp_socket->so_options & SO_TIMESTAMP) 1147 ip_savecontrol(last, &opts, ip, m); 1148 m->m_len -= iphlen; 1149 m->m_pkthdr.len -= iphlen; 1150 m->m_data += iphlen; 1151 sa = (struct sockaddr *)&udpsrc; 1152 if (sbappendaddr(&last->inp_socket->so_rcv, sa, m, opts) == 0) { 1153 udpstat.udps_fullsock++; 1154 goto bad; 1155 } 1156 sorwakeup(last->inp_socket); 1157 return; 1158 } 1159 /* 1160 * Locate pcb for datagram. 1161 */ 1162 inp = in_pcblookup_connect(&udbtable, ip->ip_src, uh->uh_sport, 1163 ip->ip_dst, uh->uh_dport); 1164 if (inp == 0) { 1165 ++udpstat.udps_pcbhashmiss; 1166 inp = in_pcblookup_bind(&udbtable, ip->ip_dst, uh->uh_dport); 1167 if (inp == 0) { 1168 if (m->m_flags & (M_BCAST | M_MCAST)) { 1169 udpstat.udps_noportbcast++; 1170 goto bad; 1171 } 1172 udpstat.udps_noport++; 1173 *ip = save_ip; 1174 #ifdef IPKDB 1175 if (checkipkdb(&ip->ip_src, 1176 uh->uh_sport, 1177 uh->uh_dport, 1178 m, 1179 iphlen + sizeof(struct udphdr), 1180 len - sizeof(struct udphdr))) 1181 /* It was a debugger connect packet, just drop it now */ 1182 goto bad; 1183 #endif 1184 icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_PORT, 0, 0); 1185 return; 1186 } 1187 } 1188 #ifdef IPSEC 1189 if (inp != NULL && ipsec4_in_reject(m, inp)) { 1190 ipsecstat.in_polvio++; 1191 goto bad; 1192 } 1193 #endif /*IPSEC*/ 1194 1195 /* 1196 * Stuff source address and datagram in user buffer. 1197 */ 1198 if (inp->inp_flags & INP_CONTROLOPTS || 1199 inp->inp_socket->so_options & SO_TIMESTAMP) 1200 ip_savecontrol(inp, &opts, ip, m); 1201 iphlen += sizeof(struct udphdr); 1202 m->m_len -= iphlen; 1203 m->m_pkthdr.len -= iphlen; 1204 m->m_data += iphlen; 1205 sa = (struct sockaddr *)&udpsrc; 1206 if (sbappendaddr(&inp->inp_socket->so_rcv, sa, m, opts) == 0) { 1207 udpstat.udps_fullsock++; 1208 goto bad; 1209 } 1210 sorwakeup(inp->inp_socket); 1211 return; 1212 bad: 1213 m_freem(m); 1214 if (opts) 1215 m_freem(opts); 1216 return; 1217 1218 badcsum: 1219 udpstat.udps_badsum++; 1220 m_freem(m); 1221 } 1222 #endif /*UDP6*/ 1223 1224 #ifdef INET 1225 /* 1226 * Notify a udp user of an asynchronous error; 1227 * just wake up so that he can collect error status. 1228 */ 1229 static void 1230 udp_notify(inp, errno) 1231 struct inpcb *inp; 1232 int errno; 1233 { 1234 1235 inp->inp_socket->so_error = errno; 1236 sorwakeup(inp->inp_socket); 1237 sowwakeup(inp->inp_socket); 1238 } 1239 1240 void * 1241 udp_ctlinput(cmd, sa, v) 1242 int cmd; 1243 struct sockaddr *sa; 1244 void *v; 1245 { 1246 struct ip *ip = v; 1247 struct udphdr *uh; 1248 void (*notify) __P((struct inpcb *, int)) = udp_notify; 1249 int errno; 1250 1251 if (sa->sa_family != AF_INET 1252 || sa->sa_len != sizeof(struct sockaddr_in)) 1253 return NULL; 1254 if ((unsigned)cmd >= PRC_NCMDS) 1255 return NULL; 1256 errno = inetctlerrmap[cmd]; 1257 if (PRC_IS_REDIRECT(cmd)) 1258 notify = in_rtchange, ip = 0; 1259 else if (cmd == PRC_HOSTDEAD) 1260 ip = 0; 1261 else if (errno == 0) 1262 return NULL; 1263 if (ip) { 1264 uh = (struct udphdr *)((caddr_t)ip + (ip->ip_hl << 2)); 1265 in_pcbnotify(&udbtable, satosin(sa)->sin_addr, uh->uh_dport, 1266 ip->ip_src, uh->uh_sport, errno, notify); 1267 1268 /* XXX mapped address case */ 1269 } else 1270 in_pcbnotifyall(&udbtable, satosin(sa)->sin_addr, errno, 1271 notify); 1272 return NULL; 1273 } 1274 1275 int 1276 #if __STDC__ 1277 udp_output(struct mbuf *m, ...) 1278 #else 1279 udp_output(m, va_alist) 1280 struct mbuf *m; 1281 va_dcl 1282 #endif 1283 { 1284 struct inpcb *inp; 1285 struct udpiphdr *ui; 1286 int len = m->m_pkthdr.len; 1287 int error = 0; 1288 va_list ap; 1289 1290 va_start(ap, m); 1291 inp = va_arg(ap, struct inpcb *); 1292 va_end(ap); 1293 1294 /* 1295 * Calculate data length and get a mbuf 1296 * for UDP and IP headers. 1297 */ 1298 M_PREPEND(m, sizeof(struct udpiphdr), M_DONTWAIT); 1299 if (m == 0) { 1300 error = ENOBUFS; 1301 goto release; 1302 } 1303 1304 /* 1305 * Compute the packet length of the IP header, and 1306 * punt if the length looks bogus. 1307 */ 1308 if ((len + sizeof(struct udpiphdr)) > IP_MAXPACKET) { 1309 error = EMSGSIZE; 1310 goto release; 1311 } 1312 1313 /* 1314 * Fill in mbuf with extended UDP header 1315 * and addresses and length put into network format. 1316 */ 1317 ui = mtod(m, struct udpiphdr *); 1318 ui->ui_pr = IPPROTO_UDP; 1319 ui->ui_src = inp->inp_laddr; 1320 ui->ui_dst = inp->inp_faddr; 1321 ui->ui_sport = inp->inp_lport; 1322 ui->ui_dport = inp->inp_fport; 1323 ui->ui_ulen = htons((u_int16_t)len + sizeof(struct udphdr)); 1324 1325 /* 1326 * Set up checksum and output datagram. 1327 */ 1328 if (udpcksum) { 1329 /* 1330 * XXX Cache pseudo-header checksum part for 1331 * XXX "connected" UDP sockets. 1332 */ 1333 ui->ui_sum = in_cksum_phdr(ui->ui_src.s_addr, 1334 ui->ui_dst.s_addr, htons((u_int16_t)len + 1335 sizeof(struct udphdr) + IPPROTO_UDP)); 1336 m->m_pkthdr.csum_flags = M_CSUM_UDPv4; 1337 m->m_pkthdr.csum_data = offsetof(struct udphdr, uh_sum); 1338 } else 1339 ui->ui_sum = 0; 1340 ((struct ip *)ui)->ip_len = sizeof (struct udpiphdr) + len; 1341 ((struct ip *)ui)->ip_ttl = inp->inp_ip.ip_ttl; /* XXX */ 1342 ((struct ip *)ui)->ip_tos = inp->inp_ip.ip_tos; /* XXX */ 1343 udpstat.udps_opackets++; 1344 1345 #ifdef IPSEC 1346 if (ipsec_setsocket(m, inp->inp_socket) != 0) { 1347 error = ENOBUFS; 1348 goto release; 1349 } 1350 #endif /*IPSEC*/ 1351 1352 return (ip_output(m, inp->inp_options, &inp->inp_route, 1353 inp->inp_socket->so_options & (SO_DONTROUTE | SO_BROADCAST), 1354 inp->inp_moptions)); 1355 1356 release: 1357 m_freem(m); 1358 return (error); 1359 } 1360 1361 int udp_sendspace = 9216; /* really max datagram size */ 1362 int udp_recvspace = 40 * (1024 + sizeof(struct sockaddr_in)); 1363 /* 40 1K datagrams */ 1364 1365 /*ARGSUSED*/ 1366 int 1367 udp_usrreq(so, req, m, nam, control, p) 1368 struct socket *so; 1369 int req; 1370 struct mbuf *m, *nam, *control; 1371 struct proc *p; 1372 { 1373 struct inpcb *inp; 1374 int s; 1375 int error = 0; 1376 1377 if (req == PRU_CONTROL) 1378 return (in_control(so, (long)m, (caddr_t)nam, 1379 (struct ifnet *)control, p)); 1380 1381 if (req == PRU_PURGEIF) { 1382 in_purgeif((struct ifnet *)control); 1383 in_pcbpurgeif(&udbtable, (struct ifnet *)control); 1384 return (0); 1385 } 1386 1387 s = splsoftnet(); 1388 inp = sotoinpcb(so); 1389 #ifdef DIAGNOSTIC 1390 if (req != PRU_SEND && req != PRU_SENDOOB && control) 1391 panic("udp_usrreq: unexpected control mbuf"); 1392 #endif 1393 if (inp == 0 && req != PRU_ATTACH) { 1394 error = EINVAL; 1395 goto release; 1396 } 1397 1398 /* 1399 * Note: need to block udp_input while changing 1400 * the udp pcb queue and/or pcb addresses. 1401 */ 1402 switch (req) { 1403 1404 case PRU_ATTACH: 1405 if (inp != 0) { 1406 error = EISCONN; 1407 break; 1408 } 1409 if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) { 1410 error = soreserve(so, udp_sendspace, udp_recvspace); 1411 if (error) 1412 break; 1413 } 1414 error = in_pcballoc(so, &udbtable); 1415 if (error) 1416 break; 1417 inp = sotoinpcb(so); 1418 inp->inp_ip.ip_ttl = ip_defttl; 1419 #ifdef IPSEC 1420 error = ipsec_init_policy(so, &inp->inp_sp); 1421 if (error != 0) { 1422 in_pcbdetach(inp); 1423 break; 1424 } 1425 #endif /*IPSEC*/ 1426 break; 1427 1428 case PRU_DETACH: 1429 in_pcbdetach(inp); 1430 break; 1431 1432 case PRU_BIND: 1433 error = in_pcbbind(inp, nam, p); 1434 break; 1435 1436 case PRU_LISTEN: 1437 error = EOPNOTSUPP; 1438 break; 1439 1440 case PRU_CONNECT: 1441 error = in_pcbconnect(inp, nam); 1442 if (error) 1443 break; 1444 soisconnected(so); 1445 break; 1446 1447 case PRU_CONNECT2: 1448 error = EOPNOTSUPP; 1449 break; 1450 1451 case PRU_DISCONNECT: 1452 /*soisdisconnected(so);*/ 1453 so->so_state &= ~SS_ISCONNECTED; /* XXX */ 1454 in_pcbdisconnect(inp); 1455 inp->inp_laddr = zeroin_addr; /* XXX */ 1456 in_pcbstate(inp, INP_BOUND); /* XXX */ 1457 break; 1458 1459 case PRU_SHUTDOWN: 1460 socantsendmore(so); 1461 break; 1462 1463 case PRU_RCVD: 1464 error = EOPNOTSUPP; 1465 break; 1466 1467 case PRU_SEND: 1468 if (control && control->m_len) { 1469 m_freem(control); 1470 m_freem(m); 1471 error = EINVAL; 1472 break; 1473 } 1474 { 1475 struct in_addr laddr; /* XXX */ 1476 1477 if (nam) { 1478 laddr = inp->inp_laddr; /* XXX */ 1479 if ((so->so_state & SS_ISCONNECTED) != 0) { 1480 error = EISCONN; 1481 goto die; 1482 } 1483 error = in_pcbconnect(inp, nam); 1484 if (error) { 1485 die: 1486 m_freem(m); 1487 break; 1488 } 1489 } else { 1490 if ((so->so_state & SS_ISCONNECTED) == 0) { 1491 error = ENOTCONN; 1492 goto die; 1493 } 1494 } 1495 error = udp_output(m, inp); 1496 if (nam) { 1497 in_pcbdisconnect(inp); 1498 inp->inp_laddr = laddr; /* XXX */ 1499 in_pcbstate(inp, INP_BOUND); /* XXX */ 1500 } 1501 } 1502 break; 1503 1504 case PRU_SENSE: 1505 /* 1506 * stat: don't bother with a blocksize. 1507 */ 1508 splx(s); 1509 return (0); 1510 1511 case PRU_RCVOOB: 1512 error = EOPNOTSUPP; 1513 break; 1514 1515 case PRU_SENDOOB: 1516 m_freem(control); 1517 m_freem(m); 1518 error = EOPNOTSUPP; 1519 break; 1520 1521 case PRU_SOCKADDR: 1522 in_setsockaddr(inp, nam); 1523 break; 1524 1525 case PRU_PEERADDR: 1526 in_setpeeraddr(inp, nam); 1527 break; 1528 1529 default: 1530 panic("udp_usrreq"); 1531 } 1532 1533 release: 1534 splx(s); 1535 return (error); 1536 } 1537 1538 /* 1539 * Sysctl for udp variables. 1540 */ 1541 int 1542 udp_sysctl(name, namelen, oldp, oldlenp, newp, newlen) 1543 int *name; 1544 u_int namelen; 1545 void *oldp; 1546 size_t *oldlenp; 1547 void *newp; 1548 size_t newlen; 1549 { 1550 /* All sysctl names at this level are terminal. */ 1551 if (namelen != 1) 1552 return (ENOTDIR); 1553 1554 switch (name[0]) { 1555 case UDPCTL_CHECKSUM: 1556 return (sysctl_int(oldp, oldlenp, newp, newlen, &udpcksum)); 1557 case UDPCTL_SENDSPACE: 1558 return (sysctl_int(oldp, oldlenp, newp, newlen, 1559 &udp_sendspace)); 1560 case UDPCTL_RECVSPACE: 1561 return (sysctl_int(oldp, oldlenp, newp, newlen, 1562 &udp_recvspace)); 1563 default: 1564 return (ENOPROTOOPT); 1565 } 1566 /* NOTREACHED */ 1567 } 1568 #endif 1569