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