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 sysctl_wire_old_buffer(req, 2 * (sizeof xig) 602 + n * sizeof(struct xinpcb)); 603 604 xig.xig_len = sizeof xig; 605 xig.xig_count = n; 606 xig.xig_gen = gencnt; 607 xig.xig_sogen = so_gencnt; 608 error = SYSCTL_OUT(req, &xig, sizeof xig); 609 if (error) 610 return error; 611 612 inp_list = malloc(n * sizeof *inp_list, M_TEMP, M_WAITOK); 613 if (inp_list == 0) 614 return ENOMEM; 615 616 s = splnet(); 617 INP_INFO_RLOCK(&udbinfo); 618 for (inp = LIST_FIRST(udbinfo.listhead), i = 0; inp && i < n; 619 inp = LIST_NEXT(inp, inp_list)) { 620 INP_LOCK(inp); 621 if (inp->inp_gencnt <= gencnt && 622 cr_canseesocket(req->td->td_ucred, inp->inp_socket) == 0) 623 inp_list[i++] = inp; 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 out: 696 INP_INFO_RUNLOCK(&udbinfo); 697 splx(s); 698 if (error == 0) 699 error = SYSCTL_OUT(req, &xuc, sizeof(struct xucred)); 700 return (error); 701 } 702 703 SYSCTL_PROC(_net_inet_udp, OID_AUTO, getcred, 704 CTLTYPE_OPAQUE|CTLFLAG_RW|CTLFLAG_PRISON, 0, 0, 705 udp_getcred, "S,xucred", "Get the xucred of a UDP connection"); 706 707 static int 708 udp_output(inp, m, addr, control, td) 709 register struct inpcb *inp; 710 struct mbuf *m; 711 struct sockaddr *addr; 712 struct mbuf *control; 713 struct thread *td; 714 { 715 register struct udpiphdr *ui; 716 register int len = m->m_pkthdr.len; 717 struct in_addr laddr; 718 struct sockaddr_in *sin; 719 int s = 0, error = 0; 720 721 if (control) 722 m_freem(control); /* XXX */ 723 724 if (len + sizeof(struct udpiphdr) > IP_MAXPACKET) { 725 error = EMSGSIZE; 726 goto release; 727 } 728 729 if (addr) { 730 sin = (struct sockaddr_in *)addr; 731 if (td && jailed(td->td_ucred)) 732 prison_remote_ip(td->td_ucred, 0, &sin->sin_addr.s_addr); 733 laddr = inp->inp_laddr; 734 if (inp->inp_faddr.s_addr != INADDR_ANY) { 735 error = EISCONN; 736 goto release; 737 } 738 /* 739 * Must block input while temporarily connected. 740 */ 741 s = splnet(); 742 error = in_pcbconnect(inp, addr, td); 743 if (error) { 744 splx(s); 745 goto release; 746 } 747 } else { 748 if (inp->inp_faddr.s_addr == INADDR_ANY) { 749 error = ENOTCONN; 750 goto release; 751 } 752 } 753 /* 754 * Calculate data length and get a mbuf 755 * for UDP and IP headers. 756 */ 757 M_PREPEND(m, sizeof(struct udpiphdr), M_DONTWAIT); 758 if (m == 0) { 759 error = ENOBUFS; 760 if (addr) 761 splx(s); 762 goto release; 763 } 764 765 /* 766 * Fill in mbuf with extended UDP header 767 * and addresses and length put into network format. 768 */ 769 ui = mtod(m, struct udpiphdr *); 770 bzero(ui->ui_x1, sizeof(ui->ui_x1)); /* XXX still needed? */ 771 ui->ui_pr = IPPROTO_UDP; 772 ui->ui_src = inp->inp_laddr; 773 ui->ui_dst = inp->inp_faddr; 774 ui->ui_sport = inp->inp_lport; 775 ui->ui_dport = inp->inp_fport; 776 ui->ui_ulen = htons((u_short)len + sizeof(struct udphdr)); 777 778 /* 779 * Set up checksum and output datagram. 780 */ 781 if (udpcksum) { 782 ui->ui_sum = in_pseudo(ui->ui_src.s_addr, ui->ui_dst.s_addr, 783 htons((u_short)len + sizeof(struct udphdr) + IPPROTO_UDP)); 784 m->m_pkthdr.csum_flags = CSUM_UDP; 785 m->m_pkthdr.csum_data = offsetof(struct udphdr, uh_sum); 786 } else { 787 ui->ui_sum = 0; 788 } 789 ((struct ip *)ui)->ip_len = sizeof (struct udpiphdr) + len; 790 ((struct ip *)ui)->ip_ttl = inp->inp_ip_ttl; /* XXX */ 791 ((struct ip *)ui)->ip_tos = inp->inp_ip_tos; /* XXX */ 792 udpstat.udps_opackets++; 793 794 #ifdef IPSEC 795 if (ipsec_setsocket(m, inp->inp_socket) != 0) { 796 error = ENOBUFS; 797 goto release; 798 } 799 #endif /*IPSEC*/ 800 error = ip_output(m, inp->inp_options, &inp->inp_route, 801 (inp->inp_socket->so_options & (SO_DONTROUTE | SO_BROADCAST)), 802 inp->inp_moptions); 803 804 if (addr) { 805 in_pcbdisconnect(inp); 806 inp->inp_laddr = laddr; /* XXX rehash? */ 807 splx(s); 808 } 809 return (error); 810 811 release: 812 m_freem(m); 813 return (error); 814 } 815 816 u_long udp_sendspace = 9216; /* really max datagram size */ 817 /* 40 1K datagrams */ 818 SYSCTL_INT(_net_inet_udp, UDPCTL_MAXDGRAM, maxdgram, CTLFLAG_RW, 819 &udp_sendspace, 0, "Maximum outgoing UDP datagram size"); 820 821 u_long udp_recvspace = 40 * (1024 + 822 #ifdef INET6 823 sizeof(struct sockaddr_in6) 824 #else 825 sizeof(struct sockaddr_in) 826 #endif 827 ); 828 SYSCTL_INT(_net_inet_udp, UDPCTL_RECVSPACE, recvspace, CTLFLAG_RW, 829 &udp_recvspace, 0, "Maximum incoming UDP datagram size"); 830 831 static int 832 udp_abort(struct socket *so) 833 { 834 struct inpcb *inp; 835 int s; 836 837 INP_INFO_WLOCK(&udbinfo); 838 inp = sotoinpcb(so); 839 if (inp == 0) { 840 INP_INFO_WUNLOCK(&udbinfo); 841 return EINVAL; /* ??? possible? panic instead? */ 842 } 843 INP_LOCK(inp); 844 soisdisconnected(so); 845 s = splnet(); 846 in_pcbdetach(inp); 847 INP_INFO_WUNLOCK(&udbinfo); 848 splx(s); 849 return 0; 850 } 851 852 static int 853 udp_attach(struct socket *so, int proto, struct thread *td) 854 { 855 struct inpcb *inp; 856 int s, error; 857 858 INP_INFO_WLOCK(&udbinfo); 859 inp = sotoinpcb(so); 860 if (inp != 0) { 861 INP_INFO_WUNLOCK(&udbinfo); 862 return EINVAL; 863 } 864 error = soreserve(so, udp_sendspace, udp_recvspace); 865 if (error) { 866 INP_INFO_WUNLOCK(&udbinfo); 867 return error; 868 } 869 s = splnet(); 870 error = in_pcballoc(so, &udbinfo, td); 871 splx(s); 872 if (error) 873 return error; 874 875 inp = (struct inpcb *)so->so_pcb; 876 INP_LOCK(inp); 877 INP_INFO_WUNLOCK(&udbinfo); 878 inp->inp_vflag |= INP_IPV4; 879 inp->inp_ip_ttl = ip_defttl; 880 INP_UNLOCK(inp); 881 return 0; 882 } 883 884 static int 885 udp_bind(struct socket *so, struct sockaddr *nam, struct thread *td) 886 { 887 struct inpcb *inp; 888 int s, error; 889 890 INP_INFO_WLOCK(&udbinfo); 891 inp = sotoinpcb(so); 892 if (inp == 0) { 893 INP_INFO_WUNLOCK(&udbinfo); 894 return EINVAL; 895 } 896 INP_LOCK(inp); 897 s = splnet(); 898 error = in_pcbbind(inp, nam, td); 899 splx(s); 900 INP_UNLOCK(inp); 901 INP_INFO_WUNLOCK(&udbinfo); 902 return error; 903 } 904 905 static int 906 udp_connect(struct socket *so, struct sockaddr *nam, struct thread *td) 907 { 908 struct inpcb *inp; 909 int s, error; 910 struct sockaddr_in *sin; 911 912 INP_INFO_WLOCK(&udbinfo); 913 inp = sotoinpcb(so); 914 if (inp == 0) { 915 INP_INFO_WUNLOCK(&udbinfo); 916 return EINVAL; 917 } 918 INP_LOCK(inp); 919 if (inp->inp_faddr.s_addr != INADDR_ANY) { 920 INP_UNLOCK(inp); 921 INP_INFO_WUNLOCK(&udbinfo); 922 return EISCONN; 923 } 924 s = splnet(); 925 sin = (struct sockaddr_in *)nam; 926 if (td && jailed(td->td_ucred)) 927 prison_remote_ip(td->td_ucred, 0, &sin->sin_addr.s_addr); 928 error = in_pcbconnect(inp, nam, td); 929 splx(s); 930 if (error == 0) 931 soisconnected(so); 932 INP_UNLOCK(inp); 933 INP_INFO_WUNLOCK(&udbinfo); 934 return error; 935 } 936 937 static int 938 udp_detach(struct socket *so) 939 { 940 struct inpcb *inp; 941 int s; 942 943 INP_INFO_WLOCK(&udbinfo); 944 inp = sotoinpcb(so); 945 if (inp == 0) { 946 INP_INFO_WUNLOCK(&udbinfo); 947 return EINVAL; 948 } 949 INP_LOCK(inp); 950 s = splnet(); 951 in_pcbdetach(inp); 952 INP_INFO_WUNLOCK(&udbinfo); 953 splx(s); 954 return 0; 955 } 956 957 static int 958 udp_disconnect(struct socket *so) 959 { 960 struct inpcb *inp; 961 int s; 962 963 INP_INFO_WLOCK(&udbinfo); 964 inp = sotoinpcb(so); 965 if (inp == 0) { 966 INP_INFO_WUNLOCK(&udbinfo); 967 return EINVAL; 968 } 969 INP_LOCK(inp); 970 if (inp->inp_faddr.s_addr == INADDR_ANY) { 971 INP_INFO_WUNLOCK(&udbinfo); 972 INP_UNLOCK(inp); 973 return ENOTCONN; 974 } 975 976 s = splnet(); 977 in_pcbdisconnect(inp); 978 inp->inp_laddr.s_addr = INADDR_ANY; 979 INP_UNLOCK(inp); 980 INP_INFO_WUNLOCK(&udbinfo); 981 splx(s); 982 so->so_state &= ~SS_ISCONNECTED; /* XXX */ 983 return 0; 984 } 985 986 static int 987 udp_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr, 988 struct mbuf *control, struct thread *td) 989 { 990 struct inpcb *inp; 991 int ret; 992 993 INP_INFO_WLOCK(&udbinfo); 994 inp = sotoinpcb(so); 995 if (inp == 0) { 996 INP_INFO_WUNLOCK(&udbinfo); 997 m_freem(m); 998 return EINVAL; 999 } 1000 INP_LOCK(inp); 1001 ret = udp_output(inp, m, addr, control, td); 1002 INP_UNLOCK(inp); 1003 INP_INFO_WUNLOCK(&udbinfo); 1004 return ret; 1005 } 1006 1007 int 1008 udp_shutdown(struct socket *so) 1009 { 1010 struct inpcb *inp; 1011 1012 INP_INFO_RLOCK(&udbinfo); 1013 inp = sotoinpcb(so); 1014 if (inp == 0) { 1015 INP_INFO_RUNLOCK(&udbinfo); 1016 return EINVAL; 1017 } 1018 INP_LOCK(inp); 1019 INP_INFO_RUNLOCK(&udbinfo); 1020 socantsendmore(so); 1021 INP_UNLOCK(inp); 1022 return 0; 1023 } 1024 1025 /* 1026 * This is the wrapper function for in_setsockaddr. We just pass down 1027 * the pcbinfo for in_setsockaddr to lock. We don't want to do the locking 1028 * here because in_setsockaddr will call malloc and might block. 1029 */ 1030 static int 1031 udp_sockaddr(struct socket *so, struct sockaddr **nam) 1032 { 1033 return (in_setsockaddr(so, nam, &udbinfo)); 1034 } 1035 1036 /* 1037 * This is the wrapper function for in_setpeeraddr. We just pass down 1038 * the pcbinfo for in_setpeeraddr to lock. 1039 */ 1040 static int 1041 udp_peeraddr(struct socket *so, struct sockaddr **nam) 1042 { 1043 return (in_setpeeraddr(so, nam, &udbinfo)); 1044 } 1045 1046 struct pr_usrreqs udp_usrreqs = { 1047 udp_abort, pru_accept_notsupp, udp_attach, udp_bind, udp_connect, 1048 pru_connect2_notsupp, in_control, udp_detach, udp_disconnect, 1049 pru_listen_notsupp, udp_peeraddr, pru_rcvd_notsupp, 1050 pru_rcvoob_notsupp, udp_send, pru_sense_null, udp_shutdown, 1051 udp_sockaddr, sosend, soreceive, sopoll 1052 }; 1053