1 /*- 2 * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1995 3 * The Regents of the University of California. 4 * Copyright (c) 2008 Robert N. M. Watson 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 * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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 * @(#)udp_usrreq.c 8.6 (Berkeley) 5/23/95 32 */ 33 34 #include <sys/cdefs.h> 35 __FBSDID("$FreeBSD$"); 36 37 #include "opt_ipfw.h" 38 #include "opt_inet6.h" 39 #include "opt_ipsec.h" 40 41 #include <sys/param.h> 42 #include <sys/domain.h> 43 #include <sys/eventhandler.h> 44 #include <sys/jail.h> 45 #include <sys/kernel.h> 46 #include <sys/lock.h> 47 #include <sys/malloc.h> 48 #include <sys/mbuf.h> 49 #include <sys/priv.h> 50 #include <sys/proc.h> 51 #include <sys/protosw.h> 52 #include <sys/signalvar.h> 53 #include <sys/socket.h> 54 #include <sys/socketvar.h> 55 #include <sys/sx.h> 56 #include <sys/sysctl.h> 57 #include <sys/syslog.h> 58 #include <sys/systm.h> 59 #include <sys/vimage.h> 60 61 #include <vm/uma.h> 62 63 #include <net/if.h> 64 #include <net/route.h> 65 66 #include <netinet/in.h> 67 #include <netinet/in_pcb.h> 68 #include <netinet/in_systm.h> 69 #include <netinet/in_var.h> 70 #include <netinet/ip.h> 71 #ifdef INET6 72 #include <netinet/ip6.h> 73 #endif 74 #include <netinet/ip_icmp.h> 75 #include <netinet/icmp_var.h> 76 #include <netinet/ip_var.h> 77 #include <netinet/ip_options.h> 78 #ifdef INET6 79 #include <netinet6/ip6_var.h> 80 #endif 81 #include <netinet/udp.h> 82 #include <netinet/udp_var.h> 83 #include <netinet/vinet.h> 84 85 #ifdef IPSEC 86 #include <netipsec/ipsec.h> 87 #endif 88 89 #include <machine/in_cksum.h> 90 91 #include <security/mac/mac_framework.h> 92 93 /* 94 * UDP protocol implementation. 95 * Per RFC 768, August, 1980. 96 */ 97 98 #ifdef VIMAGE_GLOBALS 99 int udp_blackhole; 100 #endif 101 102 /* 103 * BSD 4.2 defaulted the udp checksum to be off. Turning off udp checksums 104 * removes the only data integrity mechanism for packets and malformed 105 * packets that would otherwise be discarded due to bad checksums, and may 106 * cause problems (especially for NFS data blocks). 107 */ 108 static int udp_cksum = 1; 109 SYSCTL_INT(_net_inet_udp, UDPCTL_CHECKSUM, checksum, CTLFLAG_RW, &udp_cksum, 110 0, "compute udp checksum"); 111 112 int udp_log_in_vain = 0; 113 SYSCTL_INT(_net_inet_udp, OID_AUTO, log_in_vain, CTLFLAG_RW, 114 &udp_log_in_vain, 0, "Log all incoming UDP packets"); 115 116 SYSCTL_V_INT(V_NET, vnet_inet, _net_inet_udp, OID_AUTO, blackhole, 117 CTLFLAG_RW, udp_blackhole, 0, 118 "Do not send port unreachables for refused connects"); 119 120 u_long udp_sendspace = 9216; /* really max datagram size */ 121 /* 40 1K datagrams */ 122 SYSCTL_ULONG(_net_inet_udp, UDPCTL_MAXDGRAM, maxdgram, CTLFLAG_RW, 123 &udp_sendspace, 0, "Maximum outgoing UDP datagram size"); 124 125 u_long udp_recvspace = 40 * (1024 + 126 #ifdef INET6 127 sizeof(struct sockaddr_in6) 128 #else 129 sizeof(struct sockaddr_in) 130 #endif 131 ); 132 133 SYSCTL_ULONG(_net_inet_udp, UDPCTL_RECVSPACE, recvspace, CTLFLAG_RW, 134 &udp_recvspace, 0, "Maximum space for incoming UDP datagrams"); 135 136 #ifdef VIMAGE_GLOBALS 137 struct inpcbhead udb; /* from udp_var.h */ 138 struct inpcbinfo udbinfo; 139 static uma_zone_t udpcb_zone; 140 struct udpstat udpstat; /* from udp_var.h */ 141 #endif 142 143 #ifndef UDBHASHSIZE 144 #define UDBHASHSIZE 128 145 #endif 146 147 SYSCTL_V_STRUCT(V_NET, vnet_inet, _net_inet_udp, UDPCTL_STATS, stats, 148 CTLFLAG_RW, udpstat, udpstat, 149 "UDP statistics (struct udpstat, netinet/udp_var.h)"); 150 151 static void udp_detach(struct socket *so); 152 static int udp_output(struct inpcb *, struct mbuf *, struct sockaddr *, 153 struct mbuf *, struct thread *); 154 155 static void 156 udp_zone_change(void *tag) 157 { 158 INIT_VNET_INET(curvnet); 159 160 uma_zone_set_max(V_udbinfo.ipi_zone, maxsockets); 161 uma_zone_set_max(V_udpcb_zone, maxsockets); 162 } 163 164 static int 165 udp_inpcb_init(void *mem, int size, int flags) 166 { 167 struct inpcb *inp; 168 169 inp = mem; 170 INP_LOCK_INIT(inp, "inp", "udpinp"); 171 return (0); 172 } 173 174 void 175 udp_init(void) 176 { 177 INIT_VNET_INET(curvnet); 178 179 V_udp_blackhole = 0; 180 181 INP_INFO_LOCK_INIT(&V_udbinfo, "udp"); 182 LIST_INIT(&V_udb); 183 #ifdef VIMAGE 184 V_udbinfo.ipi_vnet = curvnet; 185 #endif 186 V_udbinfo.ipi_listhead = &V_udb; 187 V_udbinfo.ipi_hashbase = hashinit(UDBHASHSIZE, M_PCB, 188 &V_udbinfo.ipi_hashmask); 189 V_udbinfo.ipi_porthashbase = hashinit(UDBHASHSIZE, M_PCB, 190 &V_udbinfo.ipi_porthashmask); 191 V_udbinfo.ipi_zone = uma_zcreate("udp_inpcb", sizeof(struct inpcb), 192 NULL, NULL, udp_inpcb_init, NULL, UMA_ALIGN_PTR, UMA_ZONE_NOFREE); 193 uma_zone_set_max(V_udbinfo.ipi_zone, maxsockets); 194 195 V_udpcb_zone = uma_zcreate("udpcb", sizeof(struct udpcb), 196 NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_NOFREE); 197 uma_zone_set_max(V_udpcb_zone, maxsockets); 198 199 EVENTHANDLER_REGISTER(maxsockets_change, udp_zone_change, NULL, 200 EVENTHANDLER_PRI_ANY); 201 } 202 203 int 204 udp_newudpcb(struct inpcb *inp) 205 { 206 INIT_VNET_INET(curvnet); 207 struct udpcb *up; 208 209 up = uma_zalloc(V_udpcb_zone, M_NOWAIT | M_ZERO); 210 if (up == NULL) 211 return (ENOBUFS); 212 inp->inp_ppcb = up; 213 return (0); 214 } 215 216 void 217 udp_discardcb(struct udpcb *up) 218 { 219 INIT_VNET_INET(curvnet); 220 221 uma_zfree(V_udpcb_zone, up); 222 } 223 224 #ifdef VIMAGE 225 void 226 udp_destroy(void) 227 { 228 INIT_VNET_INET(curvnet); 229 230 hashdestroy(V_udbinfo.ipi_hashbase, M_PCB, 231 V_udbinfo.ipi_hashmask); 232 hashdestroy(V_udbinfo.ipi_porthashbase, M_PCB, 233 V_udbinfo.ipi_porthashmask); 234 INP_INFO_LOCK_DESTROY(&V_udbinfo); 235 } 236 #endif 237 238 /* 239 * Subroutine of udp_input(), which appends the provided mbuf chain to the 240 * passed pcb/socket. The caller must provide a sockaddr_in via udp_in that 241 * contains the source address. If the socket ends up being an IPv6 socket, 242 * udp_append() will convert to a sockaddr_in6 before passing the address 243 * into the socket code. 244 */ 245 static void 246 udp_append(struct inpcb *inp, struct ip *ip, struct mbuf *n, int off, 247 struct sockaddr_in *udp_in) 248 { 249 struct sockaddr *append_sa; 250 struct socket *so; 251 struct mbuf *opts = 0; 252 #ifdef INET6 253 struct sockaddr_in6 udp_in6; 254 #endif 255 256 INP_RLOCK_ASSERT(inp); 257 258 #ifdef IPSEC 259 /* Check AH/ESP integrity. */ 260 if (ipsec4_in_reject(n, inp)) { 261 INIT_VNET_IPSEC(curvnet); 262 m_freem(n); 263 V_ipsec4stat.in_polvio++; 264 return; 265 } 266 #endif /* IPSEC */ 267 #ifdef MAC 268 if (mac_inpcb_check_deliver(inp, n) != 0) { 269 m_freem(n); 270 return; 271 } 272 #endif 273 if (inp->inp_flags & INP_CONTROLOPTS || 274 inp->inp_socket->so_options & (SO_TIMESTAMP | SO_BINTIME)) { 275 #ifdef INET6 276 if (inp->inp_vflag & INP_IPV6) 277 (void)ip6_savecontrol_v4(inp, n, &opts, NULL); 278 else 279 #endif 280 ip_savecontrol(inp, &opts, ip, n); 281 } 282 #ifdef INET6 283 if (inp->inp_vflag & INP_IPV6) { 284 bzero(&udp_in6, sizeof(udp_in6)); 285 udp_in6.sin6_len = sizeof(udp_in6); 286 udp_in6.sin6_family = AF_INET6; 287 in6_sin_2_v4mapsin6(udp_in, &udp_in6); 288 append_sa = (struct sockaddr *)&udp_in6; 289 } else 290 #endif 291 append_sa = (struct sockaddr *)udp_in; 292 m_adj(n, off); 293 294 so = inp->inp_socket; 295 SOCKBUF_LOCK(&so->so_rcv); 296 if (sbappendaddr_locked(&so->so_rcv, append_sa, n, opts) == 0) { 297 INIT_VNET_INET(so->so_vnet); 298 SOCKBUF_UNLOCK(&so->so_rcv); 299 m_freem(n); 300 if (opts) 301 m_freem(opts); 302 UDPSTAT_INC(udps_fullsock); 303 } else 304 sorwakeup_locked(so); 305 } 306 307 void 308 udp_input(struct mbuf *m, int off) 309 { 310 INIT_VNET_INET(curvnet); 311 int iphlen = off; 312 struct ip *ip; 313 struct udphdr *uh; 314 struct ifnet *ifp; 315 struct inpcb *inp; 316 struct udpcb *up; 317 int len; 318 struct ip save_ip; 319 struct sockaddr_in udp_in; 320 #ifdef IPFIREWALL_FORWARD 321 struct m_tag *fwd_tag; 322 #endif 323 324 ifp = m->m_pkthdr.rcvif; 325 UDPSTAT_INC(udps_ipackets); 326 327 /* 328 * Strip IP options, if any; should skip this, make available to 329 * user, and use on returned packets, but we don't yet have a way to 330 * check the checksum with options still present. 331 */ 332 if (iphlen > sizeof (struct ip)) { 333 ip_stripoptions(m, (struct mbuf *)0); 334 iphlen = sizeof(struct ip); 335 } 336 337 /* 338 * Get IP and UDP header together in first mbuf. 339 */ 340 ip = mtod(m, struct ip *); 341 if (m->m_len < iphlen + sizeof(struct udphdr)) { 342 if ((m = m_pullup(m, iphlen + sizeof(struct udphdr))) == 0) { 343 UDPSTAT_INC(udps_hdrops); 344 return; 345 } 346 ip = mtod(m, struct ip *); 347 } 348 uh = (struct udphdr *)((caddr_t)ip + iphlen); 349 350 /* 351 * Destination port of 0 is illegal, based on RFC768. 352 */ 353 if (uh->uh_dport == 0) 354 goto badunlocked; 355 356 /* 357 * Construct sockaddr format source address. Stuff source address 358 * and datagram in user buffer. 359 */ 360 bzero(&udp_in, sizeof(udp_in)); 361 udp_in.sin_len = sizeof(udp_in); 362 udp_in.sin_family = AF_INET; 363 udp_in.sin_port = uh->uh_sport; 364 udp_in.sin_addr = ip->ip_src; 365 366 /* 367 * Make mbuf data length reflect UDP length. If not enough data to 368 * reflect UDP length, drop. 369 */ 370 len = ntohs((u_short)uh->uh_ulen); 371 if (ip->ip_len != len) { 372 if (len > ip->ip_len || len < sizeof(struct udphdr)) { 373 UDPSTAT_INC(udps_badlen); 374 goto badunlocked; 375 } 376 m_adj(m, len - ip->ip_len); 377 /* ip->ip_len = len; */ 378 } 379 380 /* 381 * Save a copy of the IP header in case we want restore it for 382 * sending an ICMP error message in response. 383 */ 384 if (!V_udp_blackhole) 385 save_ip = *ip; 386 else 387 memset(&save_ip, 0, sizeof(save_ip)); 388 389 /* 390 * Checksum extended UDP header and data. 391 */ 392 if (uh->uh_sum) { 393 u_short uh_sum; 394 395 if (m->m_pkthdr.csum_flags & CSUM_DATA_VALID) { 396 if (m->m_pkthdr.csum_flags & CSUM_PSEUDO_HDR) 397 uh_sum = m->m_pkthdr.csum_data; 398 else 399 uh_sum = in_pseudo(ip->ip_src.s_addr, 400 ip->ip_dst.s_addr, htonl((u_short)len + 401 m->m_pkthdr.csum_data + IPPROTO_UDP)); 402 uh_sum ^= 0xffff; 403 } else { 404 char b[9]; 405 406 bcopy(((struct ipovly *)ip)->ih_x1, b, 9); 407 bzero(((struct ipovly *)ip)->ih_x1, 9); 408 ((struct ipovly *)ip)->ih_len = uh->uh_ulen; 409 uh_sum = in_cksum(m, len + sizeof (struct ip)); 410 bcopy(b, ((struct ipovly *)ip)->ih_x1, 9); 411 } 412 if (uh_sum) { 413 UDPSTAT_INC(udps_badsum); 414 m_freem(m); 415 return; 416 } 417 } else 418 UDPSTAT_INC(udps_nosum); 419 420 #ifdef IPFIREWALL_FORWARD 421 /* 422 * Grab info from PACKET_TAG_IPFORWARD tag prepended to the chain. 423 */ 424 fwd_tag = m_tag_find(m, PACKET_TAG_IPFORWARD, NULL); 425 if (fwd_tag != NULL) { 426 struct sockaddr_in *next_hop; 427 428 /* 429 * Do the hack. 430 */ 431 next_hop = (struct sockaddr_in *)(fwd_tag + 1); 432 ip->ip_dst = next_hop->sin_addr; 433 uh->uh_dport = ntohs(next_hop->sin_port); 434 435 /* 436 * Remove the tag from the packet. We don't need it anymore. 437 */ 438 m_tag_delete(m, fwd_tag); 439 } 440 #endif 441 442 INP_INFO_RLOCK(&V_udbinfo); 443 if (IN_MULTICAST(ntohl(ip->ip_dst.s_addr)) || 444 in_broadcast(ip->ip_dst, ifp)) { 445 struct inpcb *last; 446 struct ip_moptions *imo; 447 448 last = NULL; 449 LIST_FOREACH(inp, &V_udb, inp_list) { 450 if (inp->inp_lport != uh->uh_dport) 451 continue; 452 #ifdef INET6 453 if ((inp->inp_vflag & INP_IPV4) == 0) 454 continue; 455 #endif 456 if (inp->inp_laddr.s_addr != INADDR_ANY && 457 inp->inp_laddr.s_addr != ip->ip_dst.s_addr) 458 continue; 459 if (inp->inp_faddr.s_addr != INADDR_ANY && 460 inp->inp_faddr.s_addr != ip->ip_src.s_addr) 461 continue; 462 if (inp->inp_fport != 0 && 463 inp->inp_fport != uh->uh_sport) 464 continue; 465 466 INP_RLOCK(inp); 467 468 /* 469 * Handle socket delivery policy for any-source 470 * and source-specific multicast. [RFC3678] 471 */ 472 imo = inp->inp_moptions; 473 if (IN_MULTICAST(ntohl(ip->ip_dst.s_addr)) && 474 imo != NULL) { 475 struct sockaddr_in group; 476 int blocked; 477 478 bzero(&group, sizeof(struct sockaddr_in)); 479 group.sin_len = sizeof(struct sockaddr_in); 480 group.sin_family = AF_INET; 481 group.sin_addr = ip->ip_dst; 482 483 blocked = imo_multi_filter(imo, ifp, 484 (struct sockaddr *)&group, 485 (struct sockaddr *)&udp_in); 486 if (blocked != MCAST_PASS) { 487 if (blocked == MCAST_NOTGMEMBER) 488 IPSTAT_INC(ips_notmember); 489 if (blocked == MCAST_NOTSMEMBER || 490 blocked == MCAST_MUTED) 491 UDPSTAT_INC(udps_filtermcast); 492 INP_RUNLOCK(inp); 493 continue; 494 } 495 } 496 if (last != NULL) { 497 struct mbuf *n; 498 499 n = m_copy(m, 0, M_COPYALL); 500 up = intoudpcb(last); 501 if (up->u_tun_func == NULL) { 502 if (n != NULL) 503 udp_append(last, 504 ip, n, 505 iphlen + 506 sizeof(struct udphdr), 507 &udp_in); 508 } else { 509 /* 510 * Engage the tunneling protocol we 511 * will have to leave the info_lock 512 * up, since we are hunting through 513 * multiple UDP's. 514 */ 515 516 (*up->u_tun_func)(n, iphlen, last); 517 } 518 INP_RUNLOCK(last); 519 } 520 last = inp; 521 /* 522 * Don't look for additional matches if this one does 523 * not have either the SO_REUSEPORT or SO_REUSEADDR 524 * socket options set. This heuristic avoids 525 * searching through all pcbs in the common case of a 526 * non-shared port. It assumes that an application 527 * will never clear these options after setting them. 528 */ 529 if ((last->inp_socket->so_options & 530 (SO_REUSEPORT|SO_REUSEADDR)) == 0) 531 break; 532 } 533 534 if (last == NULL) { 535 /* 536 * No matching pcb found; discard datagram. (No need 537 * to send an ICMP Port Unreachable for a broadcast 538 * or multicast datgram.) 539 */ 540 UDPSTAT_INC(udps_noportbcast); 541 goto badheadlocked; 542 } 543 up = intoudpcb(last); 544 if (up->u_tun_func == NULL) { 545 udp_append(last, ip, m, iphlen + sizeof(struct udphdr), 546 &udp_in); 547 } else { 548 /* 549 * Engage the tunneling protocol. 550 */ 551 (*up->u_tun_func)(m, iphlen, last); 552 } 553 INP_RUNLOCK(last); 554 INP_INFO_RUNLOCK(&V_udbinfo); 555 return; 556 } 557 558 /* 559 * Locate pcb for datagram. 560 */ 561 inp = in_pcblookup_hash(&V_udbinfo, ip->ip_src, uh->uh_sport, 562 ip->ip_dst, uh->uh_dport, 1, ifp); 563 if (inp == NULL) { 564 if (udp_log_in_vain) { 565 char buf[4*sizeof "123"]; 566 567 strcpy(buf, inet_ntoa(ip->ip_dst)); 568 log(LOG_INFO, 569 "Connection attempt to UDP %s:%d from %s:%d\n", 570 buf, ntohs(uh->uh_dport), inet_ntoa(ip->ip_src), 571 ntohs(uh->uh_sport)); 572 } 573 UDPSTAT_INC(udps_noport); 574 if (m->m_flags & (M_BCAST | M_MCAST)) { 575 UDPSTAT_INC(udps_noportbcast); 576 goto badheadlocked; 577 } 578 if (V_udp_blackhole) 579 goto badheadlocked; 580 if (badport_bandlim(BANDLIM_ICMP_UNREACH) < 0) 581 goto badheadlocked; 582 *ip = save_ip; 583 ip->ip_len += iphlen; 584 icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_PORT, 0, 0); 585 INP_INFO_RUNLOCK(&V_udbinfo); 586 return; 587 } 588 589 /* 590 * Check the minimum TTL for socket. 591 */ 592 INP_RLOCK(inp); 593 INP_INFO_RUNLOCK(&V_udbinfo); 594 if (inp->inp_ip_minttl && inp->inp_ip_minttl > ip->ip_ttl) { 595 INP_RUNLOCK(inp); 596 goto badunlocked; 597 } 598 up = intoudpcb(inp); 599 if (up->u_tun_func == NULL) { 600 udp_append(inp, ip, m, iphlen + sizeof(struct udphdr), &udp_in); 601 } else { 602 /* 603 * Engage the tunneling protocol. 604 */ 605 606 (*up->u_tun_func)(m, iphlen, inp); 607 } 608 INP_RUNLOCK(inp); 609 return; 610 611 badheadlocked: 612 if (inp) 613 INP_RUNLOCK(inp); 614 INP_INFO_RUNLOCK(&V_udbinfo); 615 badunlocked: 616 m_freem(m); 617 } 618 619 /* 620 * Notify a udp user of an asynchronous error; just wake up so that they can 621 * collect error status. 622 */ 623 struct inpcb * 624 udp_notify(struct inpcb *inp, int errno) 625 { 626 627 /* 628 * While udp_ctlinput() always calls udp_notify() with a read lock 629 * when invoking it directly, in_pcbnotifyall() currently uses write 630 * locks due to sharing code with TCP. For now, accept either a read 631 * or a write lock, but a read lock is sufficient. 632 */ 633 INP_LOCK_ASSERT(inp); 634 635 inp->inp_socket->so_error = errno; 636 sorwakeup(inp->inp_socket); 637 sowwakeup(inp->inp_socket); 638 return (inp); 639 } 640 641 void 642 udp_ctlinput(int cmd, struct sockaddr *sa, void *vip) 643 { 644 INIT_VNET_INET(curvnet); 645 struct ip *ip = vip; 646 struct udphdr *uh; 647 struct in_addr faddr; 648 struct inpcb *inp; 649 650 faddr = ((struct sockaddr_in *)sa)->sin_addr; 651 if (sa->sa_family != AF_INET || faddr.s_addr == INADDR_ANY) 652 return; 653 654 /* 655 * Redirects don't need to be handled up here. 656 */ 657 if (PRC_IS_REDIRECT(cmd)) 658 return; 659 660 /* 661 * Hostdead is ugly because it goes linearly through all PCBs. 662 * 663 * XXX: We never get this from ICMP, otherwise it makes an excellent 664 * DoS attack on machines with many connections. 665 */ 666 if (cmd == PRC_HOSTDEAD) 667 ip = NULL; 668 else if ((unsigned)cmd >= PRC_NCMDS || inetctlerrmap[cmd] == 0) 669 return; 670 if (ip != NULL) { 671 uh = (struct udphdr *)((caddr_t)ip + (ip->ip_hl << 2)); 672 INP_INFO_RLOCK(&V_udbinfo); 673 inp = in_pcblookup_hash(&V_udbinfo, faddr, uh->uh_dport, 674 ip->ip_src, uh->uh_sport, 0, NULL); 675 if (inp != NULL) { 676 INP_RLOCK(inp); 677 if (inp->inp_socket != NULL) { 678 udp_notify(inp, inetctlerrmap[cmd]); 679 } 680 INP_RUNLOCK(inp); 681 } 682 INP_INFO_RUNLOCK(&V_udbinfo); 683 } else 684 in_pcbnotifyall(&V_udbinfo, faddr, inetctlerrmap[cmd], 685 udp_notify); 686 } 687 688 static int 689 udp_pcblist(SYSCTL_HANDLER_ARGS) 690 { 691 INIT_VNET_INET(curvnet); 692 int error, i, n; 693 struct inpcb *inp, **inp_list; 694 inp_gen_t gencnt; 695 struct xinpgen xig; 696 697 /* 698 * The process of preparing the PCB list is too time-consuming and 699 * resource-intensive to repeat twice on every request. 700 */ 701 if (req->oldptr == 0) { 702 n = V_udbinfo.ipi_count; 703 req->oldidx = 2 * (sizeof xig) 704 + (n + n/8) * sizeof(struct xinpcb); 705 return (0); 706 } 707 708 if (req->newptr != 0) 709 return (EPERM); 710 711 /* 712 * OK, now we're committed to doing something. 713 */ 714 INP_INFO_RLOCK(&V_udbinfo); 715 gencnt = V_udbinfo.ipi_gencnt; 716 n = V_udbinfo.ipi_count; 717 INP_INFO_RUNLOCK(&V_udbinfo); 718 719 error = sysctl_wire_old_buffer(req, 2 * (sizeof xig) 720 + n * sizeof(struct xinpcb)); 721 if (error != 0) 722 return (error); 723 724 xig.xig_len = sizeof xig; 725 xig.xig_count = n; 726 xig.xig_gen = gencnt; 727 xig.xig_sogen = so_gencnt; 728 error = SYSCTL_OUT(req, &xig, sizeof xig); 729 if (error) 730 return (error); 731 732 inp_list = malloc(n * sizeof *inp_list, M_TEMP, M_WAITOK); 733 if (inp_list == 0) 734 return (ENOMEM); 735 736 INP_INFO_RLOCK(&V_udbinfo); 737 for (inp = LIST_FIRST(V_udbinfo.ipi_listhead), i = 0; inp && i < n; 738 inp = LIST_NEXT(inp, inp_list)) { 739 INP_RLOCK(inp); 740 if (inp->inp_gencnt <= gencnt && 741 cr_canseeinpcb(req->td->td_ucred, inp) == 0) 742 inp_list[i++] = inp; 743 INP_RUNLOCK(inp); 744 } 745 INP_INFO_RUNLOCK(&V_udbinfo); 746 n = i; 747 748 error = 0; 749 for (i = 0; i < n; i++) { 750 inp = inp_list[i]; 751 INP_RLOCK(inp); 752 if (inp->inp_gencnt <= gencnt) { 753 struct xinpcb xi; 754 bzero(&xi, sizeof(xi)); 755 xi.xi_len = sizeof xi; 756 /* XXX should avoid extra copy */ 757 bcopy(inp, &xi.xi_inp, sizeof *inp); 758 if (inp->inp_socket) 759 sotoxsocket(inp->inp_socket, &xi.xi_socket); 760 xi.xi_inp.inp_gencnt = inp->inp_gencnt; 761 INP_RUNLOCK(inp); 762 error = SYSCTL_OUT(req, &xi, sizeof xi); 763 } else 764 INP_RUNLOCK(inp); 765 } 766 if (!error) { 767 /* 768 * Give the user an updated idea of our state. If the 769 * generation differs from what we told her before, she knows 770 * that something happened while we were processing this 771 * request, and it might be necessary to retry. 772 */ 773 INP_INFO_RLOCK(&V_udbinfo); 774 xig.xig_gen = V_udbinfo.ipi_gencnt; 775 xig.xig_sogen = so_gencnt; 776 xig.xig_count = V_udbinfo.ipi_count; 777 INP_INFO_RUNLOCK(&V_udbinfo); 778 error = SYSCTL_OUT(req, &xig, sizeof xig); 779 } 780 free(inp_list, M_TEMP); 781 return (error); 782 } 783 784 SYSCTL_PROC(_net_inet_udp, UDPCTL_PCBLIST, pcblist, CTLFLAG_RD, 0, 0, 785 udp_pcblist, "S,xinpcb", "List of active UDP sockets"); 786 787 static int 788 udp_getcred(SYSCTL_HANDLER_ARGS) 789 { 790 INIT_VNET_INET(curvnet); 791 struct xucred xuc; 792 struct sockaddr_in addrs[2]; 793 struct inpcb *inp; 794 int error; 795 796 error = priv_check(req->td, PRIV_NETINET_GETCRED); 797 if (error) 798 return (error); 799 error = SYSCTL_IN(req, addrs, sizeof(addrs)); 800 if (error) 801 return (error); 802 INP_INFO_RLOCK(&V_udbinfo); 803 inp = in_pcblookup_hash(&V_udbinfo, addrs[1].sin_addr, addrs[1].sin_port, 804 addrs[0].sin_addr, addrs[0].sin_port, 1, NULL); 805 if (inp != NULL) { 806 INP_RLOCK(inp); 807 INP_INFO_RUNLOCK(&V_udbinfo); 808 if (inp->inp_socket == NULL) 809 error = ENOENT; 810 if (error == 0) 811 error = cr_canseeinpcb(req->td->td_ucred, inp); 812 if (error == 0) 813 cru2x(inp->inp_cred, &xuc); 814 INP_RUNLOCK(inp); 815 } else { 816 INP_INFO_RUNLOCK(&V_udbinfo); 817 error = ENOENT; 818 } 819 if (error == 0) 820 error = SYSCTL_OUT(req, &xuc, sizeof(struct xucred)); 821 return (error); 822 } 823 824 SYSCTL_PROC(_net_inet_udp, OID_AUTO, getcred, 825 CTLTYPE_OPAQUE|CTLFLAG_RW|CTLFLAG_PRISON, 0, 0, 826 udp_getcred, "S,xucred", "Get the xucred of a UDP connection"); 827 828 static int 829 udp_output(struct inpcb *inp, struct mbuf *m, struct sockaddr *addr, 830 struct mbuf *control, struct thread *td) 831 { 832 INIT_VNET_INET(inp->inp_vnet); 833 struct udpiphdr *ui; 834 int len = m->m_pkthdr.len; 835 struct in_addr faddr, laddr; 836 struct cmsghdr *cm; 837 struct sockaddr_in *sin, src; 838 int error = 0; 839 int ipflags; 840 u_short fport, lport; 841 int unlock_udbinfo; 842 843 /* 844 * udp_output() may need to temporarily bind or connect the current 845 * inpcb. As such, we don't know up front whether we will need the 846 * pcbinfo lock or not. Do any work to decide what is needed up 847 * front before acquiring any locks. 848 */ 849 if (len + sizeof(struct udpiphdr) > IP_MAXPACKET) { 850 if (control) 851 m_freem(control); 852 m_freem(m); 853 return (EMSGSIZE); 854 } 855 856 src.sin_family = 0; 857 if (control != NULL) { 858 /* 859 * XXX: Currently, we assume all the optional information is 860 * stored in a single mbuf. 861 */ 862 if (control->m_next) { 863 m_freem(control); 864 m_freem(m); 865 return (EINVAL); 866 } 867 for (; control->m_len > 0; 868 control->m_data += CMSG_ALIGN(cm->cmsg_len), 869 control->m_len -= CMSG_ALIGN(cm->cmsg_len)) { 870 cm = mtod(control, struct cmsghdr *); 871 if (control->m_len < sizeof(*cm) || cm->cmsg_len == 0 872 || cm->cmsg_len > control->m_len) { 873 error = EINVAL; 874 break; 875 } 876 if (cm->cmsg_level != IPPROTO_IP) 877 continue; 878 879 switch (cm->cmsg_type) { 880 case IP_SENDSRCADDR: 881 if (cm->cmsg_len != 882 CMSG_LEN(sizeof(struct in_addr))) { 883 error = EINVAL; 884 break; 885 } 886 bzero(&src, sizeof(src)); 887 src.sin_family = AF_INET; 888 src.sin_len = sizeof(src); 889 src.sin_port = inp->inp_lport; 890 src.sin_addr = 891 *(struct in_addr *)CMSG_DATA(cm); 892 break; 893 894 default: 895 error = ENOPROTOOPT; 896 break; 897 } 898 if (error) 899 break; 900 } 901 m_freem(control); 902 } 903 if (error) { 904 m_freem(m); 905 return (error); 906 } 907 908 /* 909 * Depending on whether or not the application has bound or connected 910 * the socket, we may have to do varying levels of work. The optimal 911 * case is for a connected UDP socket, as a global lock isn't 912 * required at all. 913 * 914 * In order to decide which we need, we require stability of the 915 * inpcb binding, which we ensure by acquiring a read lock on the 916 * inpcb. This doesn't strictly follow the lock order, so we play 917 * the trylock and retry game; note that we may end up with more 918 * conservative locks than required the second time around, so later 919 * assertions have to accept that. Further analysis of the number of 920 * misses under contention is required. 921 */ 922 sin = (struct sockaddr_in *)addr; 923 INP_RLOCK(inp); 924 if (sin != NULL && 925 (inp->inp_laddr.s_addr == INADDR_ANY && inp->inp_lport == 0)) { 926 INP_RUNLOCK(inp); 927 INP_INFO_WLOCK(&V_udbinfo); 928 INP_WLOCK(inp); 929 unlock_udbinfo = 2; 930 } else if ((sin != NULL && ( 931 (sin->sin_addr.s_addr == INADDR_ANY) || 932 (sin->sin_addr.s_addr == INADDR_BROADCAST) || 933 (inp->inp_laddr.s_addr == INADDR_ANY) || 934 (inp->inp_lport == 0))) || 935 (src.sin_family == AF_INET)) { 936 if (!INP_INFO_TRY_RLOCK(&V_udbinfo)) { 937 INP_RUNLOCK(inp); 938 INP_INFO_RLOCK(&V_udbinfo); 939 INP_RLOCK(inp); 940 } 941 unlock_udbinfo = 1; 942 } else 943 unlock_udbinfo = 0; 944 945 /* 946 * If the IP_SENDSRCADDR control message was specified, override the 947 * source address for this datagram. Its use is invalidated if the 948 * address thus specified is incomplete or clobbers other inpcbs. 949 */ 950 laddr = inp->inp_laddr; 951 lport = inp->inp_lport; 952 if (src.sin_family == AF_INET) { 953 INP_INFO_LOCK_ASSERT(&V_udbinfo); 954 if ((lport == 0) || 955 (laddr.s_addr == INADDR_ANY && 956 src.sin_addr.s_addr == INADDR_ANY)) { 957 error = EINVAL; 958 goto release; 959 } 960 error = in_pcbbind_setup(inp, (struct sockaddr *)&src, 961 &laddr.s_addr, &lport, td->td_ucred); 962 if (error) 963 goto release; 964 } 965 966 /* 967 * If a UDP socket has been connected, then a local address/port will 968 * have been selected and bound. 969 * 970 * If a UDP socket has not been connected to, then an explicit 971 * destination address must be used, in which case a local 972 * address/port may not have been selected and bound. 973 */ 974 if (sin != NULL) { 975 INP_LOCK_ASSERT(inp); 976 if (inp->inp_faddr.s_addr != INADDR_ANY) { 977 error = EISCONN; 978 goto release; 979 } 980 981 /* 982 * Jail may rewrite the destination address, so let it do 983 * that before we use it. 984 */ 985 error = prison_remote_ip4(td->td_ucred, &sin->sin_addr); 986 if (error) 987 goto release; 988 989 /* 990 * If a local address or port hasn't yet been selected, or if 991 * the destination address needs to be rewritten due to using 992 * a special INADDR_ constant, invoke in_pcbconnect_setup() 993 * to do the heavy lifting. Once a port is selected, we 994 * commit the binding back to the socket; we also commit the 995 * binding of the address if in jail. 996 * 997 * If we already have a valid binding and we're not 998 * requesting a destination address rewrite, use a fast path. 999 */ 1000 if (inp->inp_laddr.s_addr == INADDR_ANY || 1001 inp->inp_lport == 0 || 1002 sin->sin_addr.s_addr == INADDR_ANY || 1003 sin->sin_addr.s_addr == INADDR_BROADCAST) { 1004 INP_INFO_LOCK_ASSERT(&V_udbinfo); 1005 error = in_pcbconnect_setup(inp, addr, &laddr.s_addr, 1006 &lport, &faddr.s_addr, &fport, NULL, 1007 td->td_ucred); 1008 if (error) 1009 goto release; 1010 1011 /* 1012 * XXXRW: Why not commit the port if the address is 1013 * !INADDR_ANY? 1014 */ 1015 /* Commit the local port if newly assigned. */ 1016 if (inp->inp_laddr.s_addr == INADDR_ANY && 1017 inp->inp_lport == 0) { 1018 INP_INFO_WLOCK_ASSERT(&V_udbinfo); 1019 INP_WLOCK_ASSERT(inp); 1020 /* 1021 * Remember addr if jailed, to prevent 1022 * rebinding. 1023 */ 1024 if (prison_flag(td->td_ucred, PR_IP4)) 1025 inp->inp_laddr = laddr; 1026 inp->inp_lport = lport; 1027 if (in_pcbinshash(inp) != 0) { 1028 inp->inp_lport = 0; 1029 error = EAGAIN; 1030 goto release; 1031 } 1032 inp->inp_flags |= INP_ANONPORT; 1033 } 1034 } else { 1035 faddr = sin->sin_addr; 1036 fport = sin->sin_port; 1037 } 1038 } else { 1039 INP_LOCK_ASSERT(inp); 1040 faddr = inp->inp_faddr; 1041 fport = inp->inp_fport; 1042 if (faddr.s_addr == INADDR_ANY) { 1043 error = ENOTCONN; 1044 goto release; 1045 } 1046 } 1047 1048 /* 1049 * Calculate data length and get a mbuf for UDP, IP, and possible 1050 * link-layer headers. Immediate slide the data pointer back forward 1051 * since we won't use that space at this layer. 1052 */ 1053 M_PREPEND(m, sizeof(struct udpiphdr) + max_linkhdr, M_DONTWAIT); 1054 if (m == NULL) { 1055 error = ENOBUFS; 1056 goto release; 1057 } 1058 m->m_data += max_linkhdr; 1059 m->m_len -= max_linkhdr; 1060 m->m_pkthdr.len -= max_linkhdr; 1061 1062 /* 1063 * Fill in mbuf with extended UDP header and addresses and length put 1064 * into network format. 1065 */ 1066 ui = mtod(m, struct udpiphdr *); 1067 bzero(ui->ui_x1, sizeof(ui->ui_x1)); /* XXX still needed? */ 1068 ui->ui_pr = IPPROTO_UDP; 1069 ui->ui_src = laddr; 1070 ui->ui_dst = faddr; 1071 ui->ui_sport = lport; 1072 ui->ui_dport = fport; 1073 ui->ui_ulen = htons((u_short)len + sizeof(struct udphdr)); 1074 1075 /* 1076 * Set the Don't Fragment bit in the IP header. 1077 */ 1078 if (inp->inp_flags & INP_DONTFRAG) { 1079 struct ip *ip; 1080 1081 ip = (struct ip *)&ui->ui_i; 1082 ip->ip_off |= IP_DF; 1083 } 1084 1085 ipflags = 0; 1086 if (inp->inp_socket->so_options & SO_DONTROUTE) 1087 ipflags |= IP_ROUTETOIF; 1088 if (inp->inp_socket->so_options & SO_BROADCAST) 1089 ipflags |= IP_ALLOWBROADCAST; 1090 if (inp->inp_flags & INP_ONESBCAST) 1091 ipflags |= IP_SENDONES; 1092 1093 #ifdef MAC 1094 mac_inpcb_create_mbuf(inp, m); 1095 #endif 1096 1097 /* 1098 * Set up checksum and output datagram. 1099 */ 1100 if (udp_cksum) { 1101 if (inp->inp_flags & INP_ONESBCAST) 1102 faddr.s_addr = INADDR_BROADCAST; 1103 ui->ui_sum = in_pseudo(ui->ui_src.s_addr, faddr.s_addr, 1104 htons((u_short)len + sizeof(struct udphdr) + IPPROTO_UDP)); 1105 m->m_pkthdr.csum_flags = CSUM_UDP; 1106 m->m_pkthdr.csum_data = offsetof(struct udphdr, uh_sum); 1107 } else 1108 ui->ui_sum = 0; 1109 ((struct ip *)ui)->ip_len = sizeof (struct udpiphdr) + len; 1110 ((struct ip *)ui)->ip_ttl = inp->inp_ip_ttl; /* XXX */ 1111 ((struct ip *)ui)->ip_tos = inp->inp_ip_tos; /* XXX */ 1112 UDPSTAT_INC(udps_opackets); 1113 1114 if (unlock_udbinfo == 2) 1115 INP_INFO_WUNLOCK(&V_udbinfo); 1116 else if (unlock_udbinfo == 1) 1117 INP_INFO_RUNLOCK(&V_udbinfo); 1118 error = ip_output(m, inp->inp_options, NULL, ipflags, 1119 inp->inp_moptions, inp); 1120 if (unlock_udbinfo == 2) 1121 INP_WUNLOCK(inp); 1122 else 1123 INP_RUNLOCK(inp); 1124 return (error); 1125 1126 release: 1127 if (unlock_udbinfo == 2) { 1128 INP_WUNLOCK(inp); 1129 INP_INFO_WUNLOCK(&V_udbinfo); 1130 } else if (unlock_udbinfo == 1) { 1131 INP_RUNLOCK(inp); 1132 INP_INFO_RUNLOCK(&V_udbinfo); 1133 } else 1134 INP_RUNLOCK(inp); 1135 m_freem(m); 1136 return (error); 1137 } 1138 1139 static void 1140 udp_abort(struct socket *so) 1141 { 1142 INIT_VNET_INET(so->so_vnet); 1143 struct inpcb *inp; 1144 1145 inp = sotoinpcb(so); 1146 KASSERT(inp != NULL, ("udp_abort: inp == NULL")); 1147 INP_INFO_WLOCK(&V_udbinfo); 1148 INP_WLOCK(inp); 1149 if (inp->inp_faddr.s_addr != INADDR_ANY) { 1150 in_pcbdisconnect(inp); 1151 inp->inp_laddr.s_addr = INADDR_ANY; 1152 soisdisconnected(so); 1153 } 1154 INP_WUNLOCK(inp); 1155 INP_INFO_WUNLOCK(&V_udbinfo); 1156 } 1157 1158 static int 1159 udp_attach(struct socket *so, int proto, struct thread *td) 1160 { 1161 INIT_VNET_INET(so->so_vnet); 1162 struct inpcb *inp; 1163 int error; 1164 1165 inp = sotoinpcb(so); 1166 KASSERT(inp == NULL, ("udp_attach: inp != NULL")); 1167 error = soreserve(so, udp_sendspace, udp_recvspace); 1168 if (error) 1169 return (error); 1170 INP_INFO_WLOCK(&V_udbinfo); 1171 error = in_pcballoc(so, &V_udbinfo); 1172 if (error) { 1173 INP_INFO_WUNLOCK(&V_udbinfo); 1174 return (error); 1175 } 1176 1177 inp = (struct inpcb *)so->so_pcb; 1178 inp->inp_vflag |= INP_IPV4; 1179 inp->inp_ip_ttl = V_ip_defttl; 1180 1181 error = udp_newudpcb(inp); 1182 if (error) { 1183 in_pcbdetach(inp); 1184 in_pcbfree(inp); 1185 INP_INFO_WUNLOCK(&V_udbinfo); 1186 return (error); 1187 } 1188 1189 INP_WUNLOCK(inp); 1190 INP_INFO_WUNLOCK(&V_udbinfo); 1191 return (0); 1192 } 1193 1194 int 1195 udp_set_kernel_tunneling(struct socket *so, udp_tun_func_t f) 1196 { 1197 struct inpcb *inp; 1198 struct udpcb *up; 1199 1200 KASSERT(so->so_type == SOCK_DGRAM, ("udp_set_kernel_tunneling: !dgram")); 1201 KASSERT(so->so_pcb != NULL, ("udp_set_kernel_tunneling: NULL inp")); 1202 if (so->so_type != SOCK_DGRAM) { 1203 /* Not UDP socket... sorry! */ 1204 return (ENOTSUP); 1205 } 1206 inp = (struct inpcb *)so->so_pcb; 1207 if (inp == NULL) { 1208 /* NULL INP? */ 1209 return (EINVAL); 1210 } 1211 INP_WLOCK(inp); 1212 up = intoudpcb(inp); 1213 if (up->u_tun_func != NULL) { 1214 INP_WUNLOCK(inp); 1215 return (EBUSY); 1216 } 1217 up->u_tun_func = f; 1218 INP_WUNLOCK(inp); 1219 return (0); 1220 } 1221 1222 static int 1223 udp_bind(struct socket *so, struct sockaddr *nam, struct thread *td) 1224 { 1225 INIT_VNET_INET(so->so_vnet); 1226 struct inpcb *inp; 1227 int error; 1228 1229 inp = sotoinpcb(so); 1230 KASSERT(inp != NULL, ("udp_bind: inp == NULL")); 1231 INP_INFO_WLOCK(&V_udbinfo); 1232 INP_WLOCK(inp); 1233 error = in_pcbbind(inp, nam, td->td_ucred); 1234 INP_WUNLOCK(inp); 1235 INP_INFO_WUNLOCK(&V_udbinfo); 1236 return (error); 1237 } 1238 1239 static void 1240 udp_close(struct socket *so) 1241 { 1242 INIT_VNET_INET(so->so_vnet); 1243 struct inpcb *inp; 1244 1245 inp = sotoinpcb(so); 1246 KASSERT(inp != NULL, ("udp_close: inp == NULL")); 1247 INP_INFO_WLOCK(&V_udbinfo); 1248 INP_WLOCK(inp); 1249 if (inp->inp_faddr.s_addr != INADDR_ANY) { 1250 in_pcbdisconnect(inp); 1251 inp->inp_laddr.s_addr = INADDR_ANY; 1252 soisdisconnected(so); 1253 } 1254 INP_WUNLOCK(inp); 1255 INP_INFO_WUNLOCK(&V_udbinfo); 1256 } 1257 1258 static int 1259 udp_connect(struct socket *so, struct sockaddr *nam, struct thread *td) 1260 { 1261 INIT_VNET_INET(so->so_vnet); 1262 struct inpcb *inp; 1263 int error; 1264 struct sockaddr_in *sin; 1265 1266 inp = sotoinpcb(so); 1267 KASSERT(inp != NULL, ("udp_connect: inp == NULL")); 1268 INP_INFO_WLOCK(&V_udbinfo); 1269 INP_WLOCK(inp); 1270 if (inp->inp_faddr.s_addr != INADDR_ANY) { 1271 INP_WUNLOCK(inp); 1272 INP_INFO_WUNLOCK(&V_udbinfo); 1273 return (EISCONN); 1274 } 1275 sin = (struct sockaddr_in *)nam; 1276 error = prison_remote_ip4(td->td_ucred, &sin->sin_addr); 1277 if (error != 0) { 1278 INP_WUNLOCK(inp); 1279 INP_INFO_WUNLOCK(&V_udbinfo); 1280 return (error); 1281 } 1282 error = in_pcbconnect(inp, nam, td->td_ucred); 1283 if (error == 0) 1284 soisconnected(so); 1285 INP_WUNLOCK(inp); 1286 INP_INFO_WUNLOCK(&V_udbinfo); 1287 return (error); 1288 } 1289 1290 static void 1291 udp_detach(struct socket *so) 1292 { 1293 INIT_VNET_INET(so->so_vnet); 1294 struct inpcb *inp; 1295 struct udpcb *up; 1296 1297 inp = sotoinpcb(so); 1298 KASSERT(inp != NULL, ("udp_detach: inp == NULL")); 1299 KASSERT(inp->inp_faddr.s_addr == INADDR_ANY, 1300 ("udp_detach: not disconnected")); 1301 INP_INFO_WLOCK(&V_udbinfo); 1302 INP_WLOCK(inp); 1303 up = intoudpcb(inp); 1304 KASSERT(up != NULL, ("%s: up == NULL", __func__)); 1305 inp->inp_ppcb = NULL; 1306 in_pcbdetach(inp); 1307 in_pcbfree(inp); 1308 INP_INFO_WUNLOCK(&V_udbinfo); 1309 udp_discardcb(up); 1310 } 1311 1312 static int 1313 udp_disconnect(struct socket *so) 1314 { 1315 INIT_VNET_INET(so->so_vnet); 1316 struct inpcb *inp; 1317 1318 inp = sotoinpcb(so); 1319 KASSERT(inp != NULL, ("udp_disconnect: inp == NULL")); 1320 INP_INFO_WLOCK(&V_udbinfo); 1321 INP_WLOCK(inp); 1322 if (inp->inp_faddr.s_addr == INADDR_ANY) { 1323 INP_WUNLOCK(inp); 1324 INP_INFO_WUNLOCK(&V_udbinfo); 1325 return (ENOTCONN); 1326 } 1327 1328 in_pcbdisconnect(inp); 1329 inp->inp_laddr.s_addr = INADDR_ANY; 1330 SOCK_LOCK(so); 1331 so->so_state &= ~SS_ISCONNECTED; /* XXX */ 1332 SOCK_UNLOCK(so); 1333 INP_WUNLOCK(inp); 1334 INP_INFO_WUNLOCK(&V_udbinfo); 1335 return (0); 1336 } 1337 1338 static int 1339 udp_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr, 1340 struct mbuf *control, struct thread *td) 1341 { 1342 struct inpcb *inp; 1343 1344 inp = sotoinpcb(so); 1345 KASSERT(inp != NULL, ("udp_send: inp == NULL")); 1346 return (udp_output(inp, m, addr, control, td)); 1347 } 1348 1349 int 1350 udp_shutdown(struct socket *so) 1351 { 1352 struct inpcb *inp; 1353 1354 inp = sotoinpcb(so); 1355 KASSERT(inp != NULL, ("udp_shutdown: inp == NULL")); 1356 INP_WLOCK(inp); 1357 socantsendmore(so); 1358 INP_WUNLOCK(inp); 1359 return (0); 1360 } 1361 1362 struct pr_usrreqs udp_usrreqs = { 1363 .pru_abort = udp_abort, 1364 .pru_attach = udp_attach, 1365 .pru_bind = udp_bind, 1366 .pru_connect = udp_connect, 1367 .pru_control = in_control, 1368 .pru_detach = udp_detach, 1369 .pru_disconnect = udp_disconnect, 1370 .pru_peeraddr = in_getpeeraddr, 1371 .pru_send = udp_send, 1372 .pru_soreceive = soreceive_dgram, 1373 .pru_sosend = sosend_dgram, 1374 .pru_shutdown = udp_shutdown, 1375 .pru_sockaddr = in_getsockaddr, 1376 .pru_sosetlabel = in_pcbsosetlabel, 1377 .pru_close = udp_close, 1378 }; 1379