1 /* 2 * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1995 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by the University of 16 * California, Berkeley and its contributors. 17 * 4. Neither the name of the University nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * 33 * @(#)udp_usrreq.c 8.6 (Berkeley) 5/23/95 34 * $FreeBSD$ 35 */ 36 37 #include "opt_ipsec.h" 38 #include "opt_inet6.h" 39 40 #include <sys/param.h> 41 #include <sys/systm.h> 42 #include <sys/domain.h> 43 #include <sys/jail.h> 44 #include <sys/kernel.h> 45 #include <sys/lock.h> 46 #include <sys/malloc.h> 47 #include <sys/mbuf.h> 48 #include <sys/proc.h> 49 #include <sys/protosw.h> 50 #include <sys/signalvar.h> 51 #include <sys/socket.h> 52 #include <sys/socketvar.h> 53 #include <sys/sx.h> 54 #include <sys/sysctl.h> 55 #include <sys/syslog.h> 56 57 #include <vm/uma.h> 58 59 #include <net/if.h> 60 #include <net/route.h> 61 62 #include <netinet/in.h> 63 #include <netinet/in_systm.h> 64 #include <netinet/in_pcb.h> 65 #include <netinet/in_var.h> 66 #include <netinet/ip.h> 67 #ifdef INET6 68 #include <netinet/ip6.h> 69 #endif 70 #include <netinet/ip_icmp.h> 71 #include <netinet/icmp_var.h> 72 #include <netinet/ip_var.h> 73 #ifdef INET6 74 #include <netinet6/ip6_var.h> 75 #endif 76 #include <netinet/udp.h> 77 #include <netinet/udp_var.h> 78 79 #ifdef IPSEC 80 #include <netinet6/ipsec.h> 81 #endif /*IPSEC*/ 82 83 #include <machine/in_cksum.h> 84 85 /* 86 * UDP protocol implementation. 87 * Per RFC 768, August, 1980. 88 */ 89 #ifndef COMPAT_42 90 static int udpcksum = 1; 91 #else 92 static int udpcksum = 0; /* XXX */ 93 #endif 94 SYSCTL_INT(_net_inet_udp, UDPCTL_CHECKSUM, checksum, CTLFLAG_RW, 95 &udpcksum, 0, ""); 96 97 int log_in_vain = 0; 98 SYSCTL_INT(_net_inet_udp, OID_AUTO, log_in_vain, CTLFLAG_RW, 99 &log_in_vain, 0, "Log all incoming UDP packets"); 100 101 static int blackhole = 0; 102 SYSCTL_INT(_net_inet_udp, OID_AUTO, blackhole, CTLFLAG_RW, 103 &blackhole, 0, "Do not send port unreachables for refused connects"); 104 105 struct inpcbhead udb; /* from udp_var.h */ 106 #define udb6 udb /* for KAME src sync over BSD*'s */ 107 struct inpcbinfo udbinfo; 108 109 #ifndef UDBHASHSIZE 110 #define UDBHASHSIZE 16 111 #endif 112 113 struct udpstat udpstat; /* from udp_var.h */ 114 SYSCTL_STRUCT(_net_inet_udp, UDPCTL_STATS, stats, CTLFLAG_RW, 115 &udpstat, udpstat, "UDP statistics (struct udpstat, netinet/udp_var.h)"); 116 117 static struct sockaddr_in udp_in = { sizeof(udp_in), AF_INET }; 118 #ifdef INET6 119 struct udp_in6 { 120 struct sockaddr_in6 uin6_sin; 121 u_char uin6_init_done : 1; 122 } udp_in6 = { 123 { sizeof(udp_in6.uin6_sin), AF_INET6 }, 124 0 125 }; 126 struct udp_ip6 { 127 struct ip6_hdr uip6_ip6; 128 u_char uip6_init_done : 1; 129 } udp_ip6; 130 #endif /* INET6 */ 131 132 static void udp_append(struct inpcb *last, struct ip *ip, struct mbuf *n, 133 int off); 134 #ifdef INET6 135 static void ip_2_ip6_hdr(struct ip6_hdr *ip6, struct ip *ip); 136 #endif 137 138 static int udp_detach(struct socket *so); 139 static int udp_output(struct inpcb *, struct mbuf *, struct sockaddr *, 140 struct mbuf *, struct thread *); 141 142 void 143 udp_init() 144 { 145 INP_INFO_LOCK_INIT(&udbinfo, "udp"); 146 LIST_INIT(&udb); 147 udbinfo.listhead = &udb; 148 udbinfo.hashbase = hashinit(UDBHASHSIZE, M_PCB, &udbinfo.hashmask); 149 udbinfo.porthashbase = hashinit(UDBHASHSIZE, M_PCB, 150 &udbinfo.porthashmask); 151 udbinfo.ipi_zone = uma_zcreate("udpcb", sizeof(struct inpcb), NULL, 152 NULL, NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_NOFREE); 153 uma_zone_set_max(udbinfo.ipi_zone, maxsockets); 154 } 155 156 void 157 udp_input(m, off) 158 register struct mbuf *m; 159 int off; 160 { 161 int iphlen = off; 162 register struct ip *ip; 163 register struct udphdr *uh; 164 register struct inpcb *inp; 165 struct mbuf *opts = 0; 166 int len; 167 struct ip save_ip; 168 struct sockaddr *append_sa; 169 170 udpstat.udps_ipackets++; 171 172 /* 173 * Strip IP options, if any; should skip this, 174 * make available to user, and use on returned packets, 175 * but we don't yet have a way to check the checksum 176 * with options still present. 177 */ 178 if (iphlen > sizeof (struct ip)) { 179 ip_stripoptions(m, (struct mbuf *)0); 180 iphlen = sizeof(struct ip); 181 } 182 183 /* 184 * Get IP and UDP header together in first mbuf. 185 */ 186 ip = mtod(m, struct ip *); 187 if (m->m_len < iphlen + sizeof(struct udphdr)) { 188 if ((m = m_pullup(m, iphlen + sizeof(struct udphdr))) == 0) { 189 udpstat.udps_hdrops++; 190 return; 191 } 192 ip = mtod(m, struct ip *); 193 } 194 uh = (struct udphdr *)((caddr_t)ip + iphlen); 195 196 /* destination port of 0 is illegal, based on RFC768. */ 197 if (uh->uh_dport == 0) 198 goto badunlocked; 199 200 /* 201 * Make mbuf data length reflect UDP length. 202 * If not enough data to reflect UDP length, drop. 203 */ 204 len = ntohs((u_short)uh->uh_ulen); 205 if (ip->ip_len != len) { 206 if (len > ip->ip_len || len < sizeof(struct udphdr)) { 207 udpstat.udps_badlen++; 208 goto badunlocked; 209 } 210 m_adj(m, len - ip->ip_len); 211 /* ip->ip_len = len; */ 212 } 213 /* 214 * Save a copy of the IP header in case we want restore it 215 * for sending an ICMP error message in response. 216 */ 217 if (!blackhole) 218 save_ip = *ip; 219 220 /* 221 * Checksum extended UDP header and data. 222 */ 223 if (uh->uh_sum) { 224 if (m->m_pkthdr.csum_flags & CSUM_DATA_VALID) { 225 if (m->m_pkthdr.csum_flags & CSUM_PSEUDO_HDR) 226 uh->uh_sum = m->m_pkthdr.csum_data; 227 else 228 uh->uh_sum = in_pseudo(ip->ip_src.s_addr, 229 ip->ip_dst.s_addr, htonl((u_short)len + 230 m->m_pkthdr.csum_data + IPPROTO_UDP)); 231 uh->uh_sum ^= 0xffff; 232 } else { 233 char b[9]; 234 bcopy(((struct ipovly *)ip)->ih_x1, b, 9); 235 bzero(((struct ipovly *)ip)->ih_x1, 9); 236 ((struct ipovly *)ip)->ih_len = uh->uh_ulen; 237 uh->uh_sum = in_cksum(m, len + sizeof (struct ip)); 238 bcopy(b, ((struct ipovly *)ip)->ih_x1, 9); 239 } 240 if (uh->uh_sum) { 241 udpstat.udps_badsum++; 242 m_freem(m); 243 return; 244 } 245 } else 246 udpstat.udps_nosum++; 247 248 INP_INFO_RLOCK(&udbinfo); 249 250 if (IN_MULTICAST(ntohl(ip->ip_dst.s_addr)) || 251 in_broadcast(ip->ip_dst, m->m_pkthdr.rcvif)) { 252 struct inpcb *last; 253 /* 254 * Deliver a multicast or broadcast datagram to *all* sockets 255 * for which the local and remote addresses and ports match 256 * those of the incoming datagram. This allows more than 257 * one process to receive multi/broadcasts on the same port. 258 * (This really ought to be done for unicast datagrams as 259 * well, but that would cause problems with existing 260 * applications that open both address-specific sockets and 261 * a wildcard socket listening to the same port -- they would 262 * end up receiving duplicates of every unicast datagram. 263 * Those applications open the multiple sockets to overcome an 264 * inadequacy of the UDP socket interface, but for backwards 265 * compatibility we avoid the problem here rather than 266 * fixing the interface. Maybe 4.5BSD will remedy this?) 267 */ 268 269 /* 270 * Construct sockaddr format source address. 271 */ 272 udp_in.sin_port = uh->uh_sport; 273 udp_in.sin_addr = ip->ip_src; 274 /* 275 * Locate pcb(s) for datagram. 276 * (Algorithm copied from raw_intr().) 277 */ 278 last = NULL; 279 #ifdef INET6 280 udp_in6.uin6_init_done = udp_ip6.uip6_init_done = 0; 281 #endif 282 LIST_FOREACH(inp, &udb, inp_list) { 283 INP_LOCK(inp); 284 if (inp->inp_lport != uh->uh_dport) { 285 docontinue: 286 INP_UNLOCK(inp); 287 continue; 288 } 289 #ifdef INET6 290 if ((inp->inp_vflag & INP_IPV4) == 0) 291 goto docontinue; 292 #endif 293 if (inp->inp_laddr.s_addr != INADDR_ANY) { 294 if (inp->inp_laddr.s_addr != ip->ip_dst.s_addr) 295 goto docontinue; 296 } 297 if (inp->inp_faddr.s_addr != INADDR_ANY) { 298 if (inp->inp_faddr.s_addr != 299 ip->ip_src.s_addr || 300 inp->inp_fport != uh->uh_sport) 301 goto docontinue; 302 } 303 304 if (last != NULL) { 305 struct mbuf *n; 306 307 #ifdef IPSEC 308 /* check AH/ESP integrity. */ 309 if (ipsec4_in_reject_so(m, last->inp_socket)) 310 ipsecstat.in_polvio++; 311 /* do not inject data to pcb */ 312 else 313 #endif /*IPSEC*/ 314 if ((n = m_copy(m, 0, M_COPYALL)) != NULL) 315 udp_append(last, ip, n, 316 iphlen + 317 sizeof(struct udphdr)); 318 INP_UNLOCK(last); 319 } 320 last = inp; 321 /* 322 * Don't look for additional matches if this one does 323 * not have either the SO_REUSEPORT or SO_REUSEADDR 324 * socket options set. This heuristic avoids searching 325 * through all pcbs in the common case of a non-shared 326 * port. It * assumes that an application will never 327 * clear these options after setting them. 328 */ 329 if ((last->inp_socket->so_options&(SO_REUSEPORT|SO_REUSEADDR)) == 0) 330 break; 331 } 332 333 if (last == NULL) { 334 /* 335 * No matching pcb found; discard datagram. 336 * (No need to send an ICMP Port Unreachable 337 * for a broadcast or multicast datgram.) 338 */ 339 udpstat.udps_noportbcast++; 340 goto badheadlocked; 341 } 342 #ifdef IPSEC 343 /* check AH/ESP integrity. */ 344 if (ipsec4_in_reject_so(m, last->inp_socket)) { 345 ipsecstat.in_polvio++; 346 goto badheadlocked; 347 } 348 #endif /*IPSEC*/ 349 INP_UNLOCK(last); 350 INP_INFO_RUNLOCK(&udbinfo); 351 udp_append(last, ip, m, iphlen + sizeof(struct udphdr)); 352 return; 353 } 354 /* 355 * Locate pcb for datagram. 356 */ 357 inp = in_pcblookup_hash(&udbinfo, ip->ip_src, uh->uh_sport, 358 ip->ip_dst, uh->uh_dport, 1, m->m_pkthdr.rcvif); 359 if (inp == NULL) { 360 if (log_in_vain) { 361 char buf[4*sizeof "123"]; 362 363 strcpy(buf, inet_ntoa(ip->ip_dst)); 364 log(LOG_INFO, 365 "Connection attempt to UDP %s:%d from %s:%d\n", 366 buf, ntohs(uh->uh_dport), inet_ntoa(ip->ip_src), 367 ntohs(uh->uh_sport)); 368 } 369 udpstat.udps_noport++; 370 if (m->m_flags & (M_BCAST | M_MCAST)) { 371 udpstat.udps_noportbcast++; 372 goto badheadlocked; 373 } 374 if (badport_bandlim(BANDLIM_ICMP_UNREACH) < 0) 375 goto badheadlocked; 376 if (blackhole) 377 goto badheadlocked; 378 *ip = save_ip; 379 ip->ip_len += iphlen; 380 icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_PORT, 0, 0); 381 INP_INFO_RUNLOCK(&udbinfo); 382 return; 383 } 384 INP_LOCK(inp); 385 INP_INFO_RUNLOCK(&udbinfo); 386 #ifdef IPSEC 387 if (ipsec4_in_reject_so(m, inp->inp_socket)) { 388 ipsecstat.in_polvio++; 389 goto bad; 390 } 391 #endif /*IPSEC*/ 392 393 /* 394 * Construct sockaddr format source address. 395 * Stuff source address and datagram in user buffer. 396 */ 397 udp_in.sin_port = uh->uh_sport; 398 udp_in.sin_addr = ip->ip_src; 399 if (inp->inp_flags & INP_CONTROLOPTS 400 || inp->inp_socket->so_options & SO_TIMESTAMP) { 401 #ifdef INET6 402 if (inp->inp_vflag & INP_IPV6) { 403 int savedflags; 404 405 ip_2_ip6_hdr(&udp_ip6.uip6_ip6, ip); 406 savedflags = inp->inp_flags; 407 inp->inp_flags &= ~INP_UNMAPPABLEOPTS; 408 ip6_savecontrol(inp, &opts, &udp_ip6.uip6_ip6, m); 409 inp->inp_flags = savedflags; 410 } else 411 #endif 412 ip_savecontrol(inp, &opts, ip, m); 413 } 414 m_adj(m, iphlen + sizeof(struct udphdr)); 415 #ifdef INET6 416 if (inp->inp_vflag & INP_IPV6) { 417 in6_sin_2_v4mapsin6(&udp_in, &udp_in6.uin6_sin); 418 append_sa = (struct sockaddr *)&udp_in6; 419 } else 420 #endif 421 append_sa = (struct sockaddr *)&udp_in; 422 if (sbappendaddr(&inp->inp_socket->so_rcv, append_sa, m, opts) == 0) { 423 udpstat.udps_fullsock++; 424 goto bad; 425 } 426 sorwakeup(inp->inp_socket); 427 INP_UNLOCK(inp); 428 return; 429 430 badheadlocked: 431 INP_INFO_RUNLOCK(&udbinfo); 432 bad: 433 if (inp) 434 INP_UNLOCK(inp); 435 badunlocked: 436 m_freem(m); 437 if (opts) 438 m_freem(opts); 439 return; 440 } 441 442 #ifdef INET6 443 static void 444 ip_2_ip6_hdr(ip6, ip) 445 struct ip6_hdr *ip6; 446 struct ip *ip; 447 { 448 bzero(ip6, sizeof(*ip6)); 449 450 ip6->ip6_vfc = IPV6_VERSION; 451 ip6->ip6_plen = ip->ip_len; 452 ip6->ip6_nxt = ip->ip_p; 453 ip6->ip6_hlim = ip->ip_ttl; 454 ip6->ip6_src.s6_addr32[2] = ip6->ip6_dst.s6_addr32[2] = 455 IPV6_ADDR_INT32_SMP; 456 ip6->ip6_src.s6_addr32[3] = ip->ip_src.s_addr; 457 ip6->ip6_dst.s6_addr32[3] = ip->ip_dst.s_addr; 458 } 459 #endif 460 461 /* 462 * subroutine of udp_input(), mainly for source code readability. 463 * caller must properly init udp_ip6 and udp_in6 beforehand. 464 */ 465 static void 466 udp_append(last, ip, n, off) 467 struct inpcb *last; 468 struct ip *ip; 469 struct mbuf *n; 470 int off; 471 { 472 struct sockaddr *append_sa; 473 struct mbuf *opts = 0; 474 475 if (last->inp_flags & INP_CONTROLOPTS || 476 last->inp_socket->so_options & SO_TIMESTAMP) { 477 #ifdef INET6 478 if (last->inp_vflag & INP_IPV6) { 479 int savedflags; 480 481 if (udp_ip6.uip6_init_done == 0) { 482 ip_2_ip6_hdr(&udp_ip6.uip6_ip6, ip); 483 udp_ip6.uip6_init_done = 1; 484 } 485 savedflags = last->inp_flags; 486 last->inp_flags &= ~INP_UNMAPPABLEOPTS; 487 ip6_savecontrol(last, &opts, &udp_ip6.uip6_ip6, n); 488 last->inp_flags = savedflags; 489 } else 490 #endif 491 ip_savecontrol(last, &opts, ip, n); 492 } 493 #ifdef INET6 494 if (last->inp_vflag & INP_IPV6) { 495 if (udp_in6.uin6_init_done == 0) { 496 in6_sin_2_v4mapsin6(&udp_in, &udp_in6.uin6_sin); 497 udp_in6.uin6_init_done = 1; 498 } 499 append_sa = (struct sockaddr *)&udp_in6.uin6_sin; 500 } else 501 #endif 502 append_sa = (struct sockaddr *)&udp_in; 503 m_adj(n, off); 504 if (sbappendaddr(&last->inp_socket->so_rcv, append_sa, n, opts) == 0) { 505 m_freem(n); 506 if (opts) 507 m_freem(opts); 508 udpstat.udps_fullsock++; 509 } else 510 sorwakeup(last->inp_socket); 511 } 512 513 /* 514 * Notify a udp user of an asynchronous error; 515 * just wake up so that he can collect error status. 516 */ 517 struct inpcb * 518 udp_notify(inp, errno) 519 register struct inpcb *inp; 520 int errno; 521 { 522 inp->inp_socket->so_error = errno; 523 sorwakeup(inp->inp_socket); 524 sowwakeup(inp->inp_socket); 525 return inp; 526 } 527 528 void 529 udp_ctlinput(cmd, sa, vip) 530 int cmd; 531 struct sockaddr *sa; 532 void *vip; 533 { 534 struct ip *ip = vip; 535 struct udphdr *uh; 536 struct inpcb *(*notify)(struct inpcb *, int) = udp_notify; 537 struct in_addr faddr; 538 struct inpcb *inp; 539 int s; 540 541 faddr = ((struct sockaddr_in *)sa)->sin_addr; 542 if (sa->sa_family != AF_INET || faddr.s_addr == INADDR_ANY) 543 return; 544 545 if (PRC_IS_REDIRECT(cmd)) { 546 ip = 0; 547 notify = in_rtchange; 548 } else if (cmd == PRC_HOSTDEAD) 549 ip = 0; 550 else if ((unsigned)cmd >= PRC_NCMDS || inetctlerrmap[cmd] == 0) 551 return; 552 if (ip) { 553 s = splnet(); 554 uh = (struct udphdr *)((caddr_t)ip + (ip->ip_hl << 2)); 555 INP_INFO_RLOCK(&udbinfo); 556 inp = in_pcblookup_hash(&udbinfo, faddr, uh->uh_dport, 557 ip->ip_src, uh->uh_sport, 0, NULL); 558 if (inp != NULL) { 559 INP_LOCK(inp); 560 if(inp->inp_socket != NULL) { 561 (*notify)(inp, inetctlerrmap[cmd]); 562 } 563 INP_UNLOCK(inp); 564 } 565 INP_INFO_RUNLOCK(&udbinfo); 566 splx(s); 567 } else 568 in_pcbnotifyall(&udbinfo, faddr, inetctlerrmap[cmd], notify); 569 } 570 571 static int 572 udp_pcblist(SYSCTL_HANDLER_ARGS) 573 { 574 int error, i, n, s; 575 struct inpcb *inp, **inp_list; 576 inp_gen_t gencnt; 577 struct xinpgen xig; 578 579 /* 580 * The process of preparing the TCB list is too time-consuming and 581 * resource-intensive to repeat twice on every request. 582 */ 583 if (req->oldptr == 0) { 584 n = udbinfo.ipi_count; 585 req->oldidx = 2 * (sizeof xig) 586 + (n + n/8) * sizeof(struct xinpcb); 587 return 0; 588 } 589 590 if (req->newptr != 0) 591 return EPERM; 592 593 /* 594 * OK, now we're committed to doing something. 595 */ 596 s = splnet(); 597 gencnt = udbinfo.ipi_gencnt; 598 n = udbinfo.ipi_count; 599 splx(s); 600 601 xig.xig_len = sizeof xig; 602 xig.xig_count = n; 603 xig.xig_gen = gencnt; 604 xig.xig_sogen = so_gencnt; 605 error = SYSCTL_OUT(req, &xig, sizeof xig); 606 if (error) 607 return error; 608 609 inp_list = malloc(n * sizeof *inp_list, M_TEMP, M_WAITOK); 610 if (inp_list == 0) 611 return ENOMEM; 612 613 s = splnet(); 614 INP_INFO_RLOCK(&udbinfo); 615 for (inp = LIST_FIRST(udbinfo.listhead), i = 0; inp && i < n; 616 inp = LIST_NEXT(inp, inp_list)) { 617 INP_LOCK(inp); 618 if (inp->inp_gencnt <= gencnt) { 619 if (cr_canseesocket(req->td->td_ucred, 620 inp->inp_socket)) 621 continue; 622 inp_list[i++] = inp; 623 } 624 INP_UNLOCK(inp); 625 } 626 INP_INFO_RUNLOCK(&udbinfo); 627 splx(s); 628 n = i; 629 630 error = 0; 631 for (i = 0; i < n; i++) { 632 inp = inp_list[i]; 633 INP_LOCK(inp); 634 if (inp->inp_gencnt <= gencnt) { 635 struct xinpcb xi; 636 xi.xi_len = sizeof xi; 637 /* XXX should avoid extra copy */ 638 bcopy(inp, &xi.xi_inp, sizeof *inp); 639 if (inp->inp_socket) 640 sotoxsocket(inp->inp_socket, &xi.xi_socket); 641 error = SYSCTL_OUT(req, &xi, sizeof xi); 642 } 643 INP_UNLOCK(inp); 644 } 645 if (!error) { 646 /* 647 * Give the user an updated idea of our state. 648 * If the generation differs from what we told 649 * her before, she knows that something happened 650 * while we were processing this request, and it 651 * might be necessary to retry. 652 */ 653 s = splnet(); 654 INP_INFO_RLOCK(&udbinfo); 655 xig.xig_gen = udbinfo.ipi_gencnt; 656 xig.xig_sogen = so_gencnt; 657 xig.xig_count = udbinfo.ipi_count; 658 INP_INFO_RUNLOCK(&udbinfo); 659 splx(s); 660 error = SYSCTL_OUT(req, &xig, sizeof xig); 661 } 662 free(inp_list, M_TEMP); 663 return error; 664 } 665 666 SYSCTL_PROC(_net_inet_udp, UDPCTL_PCBLIST, pcblist, CTLFLAG_RD, 0, 0, 667 udp_pcblist, "S,xinpcb", "List of active UDP sockets"); 668 669 static int 670 udp_getcred(SYSCTL_HANDLER_ARGS) 671 { 672 struct xucred xuc; 673 struct sockaddr_in addrs[2]; 674 struct inpcb *inp; 675 int error, s; 676 677 error = suser_cred(req->td->td_ucred, PRISON_ROOT); 678 if (error) 679 return (error); 680 error = SYSCTL_IN(req, addrs, sizeof(addrs)); 681 if (error) 682 return (error); 683 s = splnet(); 684 INP_INFO_RLOCK(&udbinfo); 685 inp = in_pcblookup_hash(&udbinfo, addrs[1].sin_addr, addrs[1].sin_port, 686 addrs[0].sin_addr, addrs[0].sin_port, 1, NULL); 687 if (inp == NULL || inp->inp_socket == NULL) { 688 error = ENOENT; 689 goto out; 690 } 691 error = cr_canseesocket(req->td->td_ucred, inp->inp_socket); 692 if (error) 693 goto out; 694 cru2x(inp->inp_socket->so_cred, &xuc); 695 error = SYSCTL_OUT(req, &xuc, sizeof(struct xucred)); 696 out: 697 INP_INFO_RUNLOCK(&udbinfo); 698 splx(s); 699 return (error); 700 } 701 702 SYSCTL_PROC(_net_inet_udp, OID_AUTO, getcred, 703 CTLTYPE_OPAQUE|CTLFLAG_RW|CTLFLAG_PRISON, 0, 0, 704 udp_getcred, "S,xucred", "Get the xucred of a UDP connection"); 705 706 static int 707 udp_output(inp, m, addr, control, td) 708 register struct inpcb *inp; 709 struct mbuf *m; 710 struct sockaddr *addr; 711 struct mbuf *control; 712 struct thread *td; 713 { 714 register struct udpiphdr *ui; 715 register int len = m->m_pkthdr.len; 716 struct in_addr laddr; 717 struct sockaddr_in *sin; 718 int s = 0, error = 0; 719 720 if (control) 721 m_freem(control); /* XXX */ 722 723 if (len + sizeof(struct udpiphdr) > IP_MAXPACKET) { 724 error = EMSGSIZE; 725 goto release; 726 } 727 728 if (addr) { 729 sin = (struct sockaddr_in *)addr; 730 if (td && jailed(td->td_ucred)) 731 prison_remote_ip(td->td_ucred, 0, &sin->sin_addr.s_addr); 732 laddr = inp->inp_laddr; 733 if (inp->inp_faddr.s_addr != INADDR_ANY) { 734 error = EISCONN; 735 goto release; 736 } 737 /* 738 * Must block input while temporarily connected. 739 */ 740 s = splnet(); 741 error = in_pcbconnect(inp, addr, td); 742 if (error) { 743 splx(s); 744 goto release; 745 } 746 } else { 747 if (inp->inp_faddr.s_addr == INADDR_ANY) { 748 error = ENOTCONN; 749 goto release; 750 } 751 } 752 /* 753 * Calculate data length and get a mbuf 754 * for UDP and IP headers. 755 */ 756 M_PREPEND(m, sizeof(struct udpiphdr), M_DONTWAIT); 757 if (m == 0) { 758 error = ENOBUFS; 759 if (addr) 760 splx(s); 761 goto release; 762 } 763 764 /* 765 * Fill in mbuf with extended UDP header 766 * and addresses and length put into network format. 767 */ 768 ui = mtod(m, struct udpiphdr *); 769 bzero(ui->ui_x1, sizeof(ui->ui_x1)); /* XXX still needed? */ 770 ui->ui_pr = IPPROTO_UDP; 771 ui->ui_src = inp->inp_laddr; 772 ui->ui_dst = inp->inp_faddr; 773 ui->ui_sport = inp->inp_lport; 774 ui->ui_dport = inp->inp_fport; 775 ui->ui_ulen = htons((u_short)len + sizeof(struct udphdr)); 776 777 /* 778 * Set up checksum and output datagram. 779 */ 780 if (udpcksum) { 781 ui->ui_sum = in_pseudo(ui->ui_src.s_addr, ui->ui_dst.s_addr, 782 htons((u_short)len + sizeof(struct udphdr) + IPPROTO_UDP)); 783 m->m_pkthdr.csum_flags = CSUM_UDP; 784 m->m_pkthdr.csum_data = offsetof(struct udphdr, uh_sum); 785 } else { 786 ui->ui_sum = 0; 787 } 788 ((struct ip *)ui)->ip_len = sizeof (struct udpiphdr) + len; 789 ((struct ip *)ui)->ip_ttl = inp->inp_ip_ttl; /* XXX */ 790 ((struct ip *)ui)->ip_tos = inp->inp_ip_tos; /* XXX */ 791 udpstat.udps_opackets++; 792 793 #ifdef IPSEC 794 if (ipsec_setsocket(m, inp->inp_socket) != 0) { 795 error = ENOBUFS; 796 goto release; 797 } 798 #endif /*IPSEC*/ 799 error = ip_output(m, inp->inp_options, &inp->inp_route, 800 (inp->inp_socket->so_options & (SO_DONTROUTE | SO_BROADCAST)), 801 inp->inp_moptions); 802 803 if (addr) { 804 in_pcbdisconnect(inp); 805 inp->inp_laddr = laddr; /* XXX rehash? */ 806 splx(s); 807 } 808 return (error); 809 810 release: 811 m_freem(m); 812 return (error); 813 } 814 815 u_long udp_sendspace = 9216; /* really max datagram size */ 816 /* 40 1K datagrams */ 817 SYSCTL_INT(_net_inet_udp, UDPCTL_MAXDGRAM, maxdgram, CTLFLAG_RW, 818 &udp_sendspace, 0, "Maximum outgoing UDP datagram size"); 819 820 u_long udp_recvspace = 40 * (1024 + 821 #ifdef INET6 822 sizeof(struct sockaddr_in6) 823 #else 824 sizeof(struct sockaddr_in) 825 #endif 826 ); 827 SYSCTL_INT(_net_inet_udp, UDPCTL_RECVSPACE, recvspace, CTLFLAG_RW, 828 &udp_recvspace, 0, "Maximum incoming UDP datagram size"); 829 830 static int 831 udp_abort(struct socket *so) 832 { 833 struct inpcb *inp; 834 int s; 835 836 INP_INFO_WLOCK(&udbinfo); 837 inp = sotoinpcb(so); 838 if (inp == 0) { 839 INP_INFO_WUNLOCK(&udbinfo); 840 return EINVAL; /* ??? possible? panic instead? */ 841 } 842 INP_LOCK(inp); 843 soisdisconnected(so); 844 s = splnet(); 845 in_pcbdetach(inp); 846 INP_INFO_WUNLOCK(&udbinfo); 847 splx(s); 848 return 0; 849 } 850 851 static int 852 udp_attach(struct socket *so, int proto, struct thread *td) 853 { 854 struct inpcb *inp; 855 int s, error; 856 857 INP_INFO_WLOCK(&udbinfo); 858 inp = sotoinpcb(so); 859 if (inp != 0) { 860 INP_INFO_WUNLOCK(&udbinfo); 861 return EINVAL; 862 } 863 error = soreserve(so, udp_sendspace, udp_recvspace); 864 if (error) { 865 INP_INFO_WUNLOCK(&udbinfo); 866 return error; 867 } 868 s = splnet(); 869 error = in_pcballoc(so, &udbinfo, td); 870 splx(s); 871 if (error) 872 return error; 873 874 inp = (struct inpcb *)so->so_pcb; 875 INP_LOCK(inp); 876 INP_INFO_WUNLOCK(&udbinfo); 877 inp->inp_vflag |= INP_IPV4; 878 inp->inp_ip_ttl = ip_defttl; 879 INP_UNLOCK(inp); 880 return 0; 881 } 882 883 static int 884 udp_bind(struct socket *so, struct sockaddr *nam, struct thread *td) 885 { 886 struct inpcb *inp; 887 int s, error; 888 889 INP_INFO_WLOCK(&udbinfo); 890 inp = sotoinpcb(so); 891 if (inp == 0) { 892 INP_INFO_WUNLOCK(&udbinfo); 893 return EINVAL; 894 } 895 INP_LOCK(inp); 896 s = splnet(); 897 error = in_pcbbind(inp, nam, td); 898 splx(s); 899 INP_UNLOCK(inp); 900 INP_INFO_WUNLOCK(&udbinfo); 901 return error; 902 } 903 904 static int 905 udp_connect(struct socket *so, struct sockaddr *nam, struct thread *td) 906 { 907 struct inpcb *inp; 908 int s, error; 909 struct sockaddr_in *sin; 910 911 INP_INFO_WLOCK(&udbinfo); 912 inp = sotoinpcb(so); 913 if (inp == 0) { 914 INP_INFO_WUNLOCK(&udbinfo); 915 return EINVAL; 916 } 917 INP_LOCK(inp); 918 if (inp->inp_faddr.s_addr != INADDR_ANY) { 919 INP_UNLOCK(inp); 920 INP_INFO_WUNLOCK(&udbinfo); 921 return EISCONN; 922 } 923 s = splnet(); 924 sin = (struct sockaddr_in *)nam; 925 if (td && jailed(td->td_ucred)) 926 prison_remote_ip(td->td_ucred, 0, &sin->sin_addr.s_addr); 927 error = in_pcbconnect(inp, nam, td); 928 splx(s); 929 if (error == 0) 930 soisconnected(so); 931 INP_UNLOCK(inp); 932 INP_INFO_WUNLOCK(&udbinfo); 933 return error; 934 } 935 936 static int 937 udp_detach(struct socket *so) 938 { 939 struct inpcb *inp; 940 int s; 941 942 INP_INFO_WLOCK(&udbinfo); 943 inp = sotoinpcb(so); 944 if (inp == 0) { 945 INP_INFO_WUNLOCK(&udbinfo); 946 return EINVAL; 947 } 948 INP_LOCK(inp); 949 s = splnet(); 950 in_pcbdetach(inp); 951 INP_INFO_WUNLOCK(&udbinfo); 952 splx(s); 953 return 0; 954 } 955 956 static int 957 udp_disconnect(struct socket *so) 958 { 959 struct inpcb *inp; 960 int s; 961 962 INP_INFO_WLOCK(&udbinfo); 963 inp = sotoinpcb(so); 964 if (inp == 0) { 965 INP_INFO_WUNLOCK(&udbinfo); 966 return EINVAL; 967 } 968 INP_LOCK(inp); 969 if (inp->inp_faddr.s_addr == INADDR_ANY) { 970 INP_INFO_WUNLOCK(&udbinfo); 971 INP_UNLOCK(inp); 972 return ENOTCONN; 973 } 974 975 s = splnet(); 976 in_pcbdisconnect(inp); 977 inp->inp_laddr.s_addr = INADDR_ANY; 978 INP_UNLOCK(inp); 979 INP_INFO_WUNLOCK(&udbinfo); 980 splx(s); 981 so->so_state &= ~SS_ISCONNECTED; /* XXX */ 982 return 0; 983 } 984 985 static int 986 udp_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr, 987 struct mbuf *control, struct thread *td) 988 { 989 struct inpcb *inp; 990 int ret; 991 992 INP_INFO_WLOCK(&udbinfo); 993 inp = sotoinpcb(so); 994 if (inp == 0) { 995 INP_INFO_WUNLOCK(&udbinfo); 996 m_freem(m); 997 return EINVAL; 998 } 999 INP_LOCK(inp); 1000 ret = udp_output(inp, m, addr, control, td); 1001 INP_UNLOCK(inp); 1002 INP_INFO_WUNLOCK(&udbinfo); 1003 return ret; 1004 } 1005 1006 int 1007 udp_shutdown(struct socket *so) 1008 { 1009 struct inpcb *inp; 1010 1011 INP_INFO_RLOCK(&udbinfo); 1012 inp = sotoinpcb(so); 1013 if (inp == 0) { 1014 INP_INFO_RUNLOCK(&udbinfo); 1015 return EINVAL; 1016 } 1017 INP_LOCK(inp); 1018 INP_INFO_RUNLOCK(&udbinfo); 1019 socantsendmore(so); 1020 INP_UNLOCK(inp); 1021 return 0; 1022 } 1023 1024 /* 1025 * This is the wrapper function for in_setsockaddr. We just pass down 1026 * the pcbinfo for in_setsockaddr to lock. We don't want to do the locking 1027 * here because in_setsockaddr will call malloc and might block. 1028 */ 1029 static int 1030 udp_sockaddr(struct socket *so, struct sockaddr **nam) 1031 { 1032 return (in_setsockaddr(so, nam, &udbinfo)); 1033 } 1034 1035 /* 1036 * This is the wrapper function for in_setpeeraddr. We just pass down 1037 * the pcbinfo for in_setpeeraddr to lock. 1038 */ 1039 static int 1040 udp_peeraddr(struct socket *so, struct sockaddr **nam) 1041 { 1042 return (in_setpeeraddr(so, nam, &udbinfo)); 1043 } 1044 1045 struct pr_usrreqs udp_usrreqs = { 1046 udp_abort, pru_accept_notsupp, udp_attach, udp_bind, udp_connect, 1047 pru_connect2_notsupp, in_control, udp_detach, udp_disconnect, 1048 pru_listen_notsupp, udp_peeraddr, pru_rcvd_notsupp, 1049 pru_rcvoob_notsupp, udp_send, pru_sense_null, udp_shutdown, 1050 udp_sockaddr, sosend, soreceive, sopoll 1051 }; 1052