1 /* $OpenBSD: udp_usrreq.c,v 1.93 2003/12/02 23:16:29 markus Exp $ */ 2 /* $NetBSD: udp_usrreq.c,v 1.28 1996/03/16 23:54:03 christos Exp $ */ 3 4 /* 5 * Copyright (c) 1982, 1986, 1988, 1990, 1993 6 * The Regents of the University of California. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. Neither the name of the University nor the names of its contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 * 32 * @(#)COPYRIGHT 1.1 (NRL) 17 January 1995 33 * 34 * NRL grants permission for redistribution and use in source and binary 35 * forms, with or without modification, of the software and documentation 36 * created at NRL provided that the following conditions are met: 37 * 38 * 1. Redistributions of source code must retain the above copyright 39 * notice, this list of conditions and the following disclaimer. 40 * 2. Redistributions in binary form must reproduce the above copyright 41 * notice, this list of conditions and the following disclaimer in the 42 * documentation and/or other materials provided with the distribution. 43 * 3. All advertising materials mentioning features or use of this software 44 * must display the following acknowledgements: 45 * This product includes software developed by the University of 46 * California, Berkeley and its contributors. 47 * This product includes software developed at the Information 48 * Technology Division, US Naval Research Laboratory. 49 * 4. Neither the name of the NRL nor the names of its contributors 50 * may be used to endorse or promote products derived from this software 51 * without specific prior written permission. 52 * 53 * THE SOFTWARE PROVIDED BY NRL IS PROVIDED BY NRL AND CONTRIBUTORS ``AS 54 * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 55 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 56 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NRL OR 57 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 58 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 59 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 60 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 61 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 62 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 63 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 64 * 65 * The views and conclusions contained in the software and documentation 66 * are those of the authors and should not be interpreted as representing 67 * official policies, either expressed or implied, of the US Naval 68 * Research Laboratory (NRL). 69 */ 70 71 #include <sys/param.h> 72 #include <sys/systm.h> 73 #include <sys/mbuf.h> 74 #include <sys/protosw.h> 75 #include <sys/socket.h> 76 #include <sys/socketvar.h> 77 #include <sys/sysctl.h> 78 79 #include <net/if.h> 80 #include <net/route.h> 81 82 #include <netinet/in.h> 83 #include <netinet/in_systm.h> 84 #include <netinet/in_var.h> 85 #include <netinet/ip.h> 86 #include <netinet/in_pcb.h> 87 #include <netinet/ip_var.h> 88 #include <netinet/ip_icmp.h> 89 #include <netinet/udp.h> 90 #include <netinet/udp_var.h> 91 92 #ifdef IPSEC 93 #include <netinet/ip_ipsp.h> 94 #include <netinet/ip_esp.h> 95 #endif 96 97 #ifdef INET6 98 #ifndef INET 99 #include <netinet/in.h> 100 #endif 101 #include <netinet6/ip6protosw.h> 102 103 extern int ip6_defhlim; 104 #endif /* INET6 */ 105 106 /* 107 * UDP protocol implementation. 108 * Per RFC 768, August, 1980. 109 */ 110 int udpcksum = 1; 111 112 struct inpcbtable udbtable; 113 struct udpstat udpstat; 114 115 static void udp_detach(struct inpcb *); 116 static void udp_notify(struct inpcb *, int); 117 static struct mbuf *udp_saveopt(caddr_t, int, int); 118 119 #ifndef UDBHASHSIZE 120 #define UDBHASHSIZE 128 121 #endif 122 int udbhashsize = UDBHASHSIZE; 123 124 /* from in_pcb.c */ 125 extern struct baddynamicports baddynamicports; 126 127 void 128 udp_init() 129 { 130 in_pcbinit(&udbtable, udbhashsize); 131 } 132 133 #ifdef INET6 134 int 135 udp6_input(mp, offp, proto) 136 struct mbuf **mp; 137 int *offp, proto; 138 { 139 struct mbuf *m = *mp; 140 141 #if defined(NFAITH) && 0 < NFAITH 142 if (m->m_pkthdr.rcvif) { 143 if (m->m_pkthdr.rcvif->if_type == IFT_FAITH) { 144 /* XXX send icmp6 host/port unreach? */ 145 m_freem(m); 146 return IPPROTO_DONE; 147 } 148 } 149 #endif 150 151 udp_input(m, *offp, proto); 152 return IPPROTO_DONE; 153 } 154 #endif 155 156 void 157 udp_input(struct mbuf *m, ...) 158 { 159 register struct ip *ip; 160 register struct udphdr *uh; 161 register struct inpcb *inp; 162 struct mbuf *opts = 0; 163 struct ip save_ip; 164 int iphlen, len; 165 va_list ap; 166 u_int16_t savesum; 167 union { 168 struct sockaddr sa; 169 struct sockaddr_in sin; 170 #ifdef INET6 171 struct sockaddr_in6 sin6; 172 #endif /* INET6 */ 173 } srcsa, dstsa; 174 #ifdef INET6 175 struct ip6_hdr *ip6; 176 #endif /* INET6 */ 177 #ifdef IPSEC 178 struct m_tag *mtag; 179 struct tdb_ident *tdbi; 180 struct tdb *tdb; 181 int error, s; 182 #endif /* IPSEC */ 183 184 va_start(ap, m); 185 iphlen = va_arg(ap, int); 186 va_end(ap); 187 188 udpstat.udps_ipackets++; 189 190 switch (mtod(m, struct ip *)->ip_v) { 191 case 4: 192 ip = mtod(m, struct ip *); 193 #ifdef INET6 194 ip6 = NULL; 195 #endif /* INET6 */ 196 srcsa.sa.sa_family = AF_INET; 197 break; 198 #ifdef INET6 199 case 6: 200 ip = NULL; 201 ip6 = mtod(m, struct ip6_hdr *); 202 srcsa.sa.sa_family = AF_INET6; 203 break; 204 #endif /* INET6 */ 205 default: 206 goto bad; 207 } 208 209 IP6_EXTHDR_GET(uh, struct udphdr *, m, iphlen, sizeof(struct udphdr)); 210 if (!uh) { 211 udpstat.udps_hdrops++; 212 return; 213 } 214 215 /* Check for illegal destination port 0 */ 216 if (uh->uh_dport == 0) { 217 udpstat.udps_noport++; 218 goto bad; 219 } 220 221 /* 222 * Make mbuf data length reflect UDP length. 223 * If not enough data to reflect UDP length, drop. 224 */ 225 len = ntohs((u_int16_t)uh->uh_ulen); 226 if (ip) { 227 if (m->m_pkthdr.len - iphlen != len) { 228 if (len > (m->m_pkthdr.len - iphlen) || 229 len < sizeof(struct udphdr)) { 230 udpstat.udps_badlen++; 231 goto bad; 232 } 233 m_adj(m, len - (m->m_pkthdr.len - iphlen)); 234 } 235 } 236 #ifdef INET6 237 else if (ip6) { 238 /* jumbograms */ 239 if (len == 0 && m->m_pkthdr.len - iphlen > 0xffff) 240 len = m->m_pkthdr.len - iphlen; 241 if (len != m->m_pkthdr.len - iphlen) { 242 udpstat.udps_badlen++; 243 goto bad; 244 } 245 } 246 #endif 247 else /* shouldn't happen */ 248 goto bad; 249 250 /* 251 * Save a copy of the IP header in case we want restore it 252 * for sending an ICMP error message in response. 253 */ 254 if (ip) 255 save_ip = *ip; 256 257 /* 258 * Checksum extended UDP header and data. 259 * from W.R.Stevens: check incoming udp cksums even if 260 * udpcksum is not set. 261 */ 262 savesum = uh->uh_sum; 263 #ifdef INET6 264 if (ip6) { 265 /* Be proactive about malicious use of IPv4 mapped address */ 266 if (IN6_IS_ADDR_V4MAPPED(&ip6->ip6_src) || 267 IN6_IS_ADDR_V4MAPPED(&ip6->ip6_dst)) { 268 /* XXX stat */ 269 goto bad; 270 } 271 272 /* 273 * In IPv6, the UDP checksum is ALWAYS used. 274 */ 275 if ((uh->uh_sum = in6_cksum(m, IPPROTO_UDP, iphlen, len))) { 276 udpstat.udps_badsum++; 277 goto bad; 278 } 279 } else 280 #endif /* INET6 */ 281 if (uh->uh_sum) { 282 if ((m->m_pkthdr.csum & M_UDP_CSUM_IN_OK) == 0) { 283 if (m->m_pkthdr.csum & M_UDP_CSUM_IN_BAD) { 284 udpstat.udps_badsum++; 285 udpstat.udps_inhwcsum++; 286 m_freem(m); 287 return; 288 } 289 290 bzero(((struct ipovly *)ip)->ih_x1, 291 sizeof ((struct ipovly *)ip)->ih_x1); 292 ((struct ipovly *)ip)->ih_len = uh->uh_ulen; 293 294 if ((uh->uh_sum = in_cksum(m, len + 295 sizeof (struct ip))) != 0) { 296 udpstat.udps_badsum++; 297 m_freem(m); 298 return; 299 } 300 } else { 301 m->m_pkthdr.csum &= ~M_UDP_CSUM_IN_OK; 302 udpstat.udps_inhwcsum++; 303 } 304 } else 305 udpstat.udps_nosum++; 306 307 #ifdef IPSEC 308 if (udpencap_enable && udpencap_port && 309 uh->uh_dport == htons(udpencap_port)) { 310 u_int32_t spi; 311 int skip = iphlen + sizeof(struct udphdr); 312 313 if (m->m_pkthdr.len - skip < sizeof(u_int32_t)) { 314 /* packet too short */ 315 m_freem(m); 316 return; 317 } 318 m_copydata(m, skip, sizeof(u_int32_t), (caddr_t) &spi); 319 /* 320 * decapsulate if the SPI is not zero, otherwise pass 321 * to userland 322 */ 323 if (spi != 0) { 324 if ((m = m_pullup2(m, skip)) == NULL) { 325 udpstat.udps_hdrops++; 326 return; 327 } 328 329 /* remove the UDP header */ 330 bcopy(mtod(m, u_char *), 331 mtod(m, u_char *) + sizeof(struct udphdr), iphlen); 332 m_adj(m, sizeof(struct udphdr)); 333 skip -= sizeof(struct udphdr); 334 335 espstat.esps_udpencin++; 336 ipsec_common_input(m, skip, offsetof(struct ip, ip_p), 337 srcsa.sa.sa_family, IPPROTO_ESP, 1); 338 return; 339 } 340 } 341 #endif 342 343 switch (srcsa.sa.sa_family) { 344 case AF_INET: 345 bzero(&srcsa, sizeof(struct sockaddr_in)); 346 srcsa.sin.sin_len = sizeof(struct sockaddr_in); 347 srcsa.sin.sin_family = AF_INET; 348 srcsa.sin.sin_port = uh->uh_sport; 349 srcsa.sin.sin_addr = ip->ip_src; 350 351 bzero(&dstsa, sizeof(struct sockaddr_in)); 352 dstsa.sin.sin_len = sizeof(struct sockaddr_in); 353 dstsa.sin.sin_family = AF_INET; 354 dstsa.sin.sin_port = uh->uh_dport; 355 dstsa.sin.sin_addr = ip->ip_dst; 356 break; 357 #ifdef INET6 358 case AF_INET6: 359 bzero(&srcsa, sizeof(struct sockaddr_in6)); 360 srcsa.sin6.sin6_len = sizeof(struct sockaddr_in6); 361 srcsa.sin6.sin6_family = AF_INET6; 362 srcsa.sin6.sin6_port = uh->uh_sport; 363 #if 0 /*XXX inbound flowinfo */ 364 srcsa.sin6.sin6_flowinfo = htonl(0x0fffffff) & ip6->ip6_flow; 365 #endif 366 /* KAME hack: recover scopeid */ 367 (void)in6_recoverscope(&srcsa.sin6, &ip6->ip6_src, 368 m->m_pkthdr.rcvif); 369 370 bzero(&dstsa, sizeof(struct sockaddr_in6)); 371 dstsa.sin6.sin6_len = sizeof(struct sockaddr_in6); 372 dstsa.sin6.sin6_family = AF_INET6; 373 dstsa.sin6.sin6_port = uh->uh_dport; 374 /* KAME hack: recover scopeid */ 375 (void)in6_recoverscope(&dstsa.sin6, &ip6->ip6_dst, 376 m->m_pkthdr.rcvif); 377 break; 378 #endif /* INET6 */ 379 } 380 381 #ifdef INET6 382 if ((ip6 && IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) || 383 (ip && IN_MULTICAST(ip->ip_dst.s_addr)) || 384 (ip && in_broadcast(ip->ip_dst, m->m_pkthdr.rcvif))) { 385 #else /* INET6 */ 386 if (IN_MULTICAST(ip->ip_dst.s_addr) || 387 in_broadcast(ip->ip_dst, m->m_pkthdr.rcvif)) { 388 #endif /* INET6 */ 389 struct socket *last; 390 /* 391 * Deliver a multicast or broadcast datagram to *all* sockets 392 * for which the local and remote addresses and ports match 393 * those of the incoming datagram. This allows more than 394 * one process to receive multi/broadcasts on the same port. 395 * (This really ought to be done for unicast datagrams as 396 * well, but that would cause problems with existing 397 * applications that open both address-specific sockets and 398 * a wildcard socket listening to the same port -- they would 399 * end up receiving duplicates of every unicast datagram. 400 * Those applications open the multiple sockets to overcome an 401 * inadequacy of the UDP socket interface, but for backwards 402 * compatibility we avoid the problem here rather than 403 * fixing the interface. Maybe 4.5BSD will remedy this?) 404 */ 405 406 iphlen += sizeof(struct udphdr); 407 408 /* 409 * Locate pcb(s) for datagram. 410 * (Algorithm copied from raw_intr().) 411 */ 412 last = NULL; 413 for (inp = udbtable.inpt_queue.cqh_first; 414 inp != (struct inpcb *)&udbtable.inpt_queue; 415 inp = inp->inp_queue.cqe_next) { 416 #ifdef INET6 417 /* don't accept it if AF does not match */ 418 if (ip6 && !(inp->inp_flags & INP_IPV6)) 419 continue; 420 if (!ip6 && (inp->inp_flags & INP_IPV6)) 421 continue; 422 #endif 423 if (inp->inp_lport != uh->uh_dport) 424 continue; 425 #ifdef INET6 426 if (ip6) { 427 if (!IN6_IS_ADDR_UNSPECIFIED(&inp->inp_laddr6)) 428 if (!IN6_ARE_ADDR_EQUAL(&inp->inp_laddr6, 429 &ip6->ip6_dst)) 430 continue; 431 } else 432 #endif /* INET6 */ 433 if (inp->inp_laddr.s_addr != INADDR_ANY) { 434 if (inp->inp_laddr.s_addr != 435 ip->ip_dst.s_addr) 436 continue; 437 } 438 #ifdef INET6 439 if (ip6) { 440 if (!IN6_IS_ADDR_UNSPECIFIED(&inp->inp_faddr6)) 441 if (!IN6_ARE_ADDR_EQUAL(&inp->inp_faddr6, 442 &ip6->ip6_src) || 443 inp->inp_fport != uh->uh_sport) 444 continue; 445 } else 446 #endif /* INET6 */ 447 if (inp->inp_faddr.s_addr != INADDR_ANY) { 448 if (inp->inp_faddr.s_addr != 449 ip->ip_src.s_addr || 450 inp->inp_fport != uh->uh_sport) 451 continue; 452 } 453 454 if (last != NULL) { 455 struct mbuf *n; 456 457 if ((n = m_copy(m, 0, M_COPYALL)) != NULL) { 458 opts = NULL; 459 #ifdef INET6 460 if (ip6 && (inp->inp_flags & IN6P_CONTROLOPTS)) 461 ip6_savecontrol(inp, &opts, ip6, n); 462 #endif /* INET6 */ 463 m_adj(n, iphlen); 464 if (sbappendaddr(&last->so_rcv, 465 &srcsa.sa, n, opts) == 0) { 466 m_freem(n); 467 if (opts) 468 m_freem(opts); 469 udpstat.udps_fullsock++; 470 } else 471 sorwakeup(last); 472 opts = NULL; 473 } 474 } 475 last = inp->inp_socket; 476 /* 477 * Don't look for additional matches if this one does 478 * not have either the SO_REUSEPORT or SO_REUSEADDR 479 * socket options set. This heuristic avoids searching 480 * through all pcbs in the common case of a non-shared 481 * port. It * assumes that an application will never 482 * clear these options after setting them. 483 */ 484 if ((last->so_options&(SO_REUSEPORT|SO_REUSEADDR)) == 0) 485 break; 486 } 487 488 if (last == NULL) { 489 /* 490 * No matching pcb found; discard datagram. 491 * (No need to send an ICMP Port Unreachable 492 * for a broadcast or multicast datgram.) 493 */ 494 udpstat.udps_noportbcast++; 495 goto bad; 496 } 497 498 opts = NULL; 499 #ifdef INET6 500 if (ip6 && (inp->inp_flags & IN6P_CONTROLOPTS)) 501 ip6_savecontrol(inp, &opts, ip6, m); 502 #endif /* INET6 */ 503 m_adj(m, iphlen); 504 if (sbappendaddr(&last->so_rcv, 505 &srcsa.sa, m, opts) == 0) { 506 udpstat.udps_fullsock++; 507 goto bad; 508 } 509 sorwakeup(last); 510 return; 511 } 512 /* 513 * Locate pcb for datagram. 514 */ 515 #ifdef INET6 516 if (ip6) 517 inp = in6_pcbhashlookup(&udbtable, &ip6->ip6_src, uh->uh_sport, 518 &ip6->ip6_dst, uh->uh_dport); 519 else 520 #endif /* INET6 */ 521 inp = in_pcbhashlookup(&udbtable, ip->ip_src, uh->uh_sport, 522 ip->ip_dst, uh->uh_dport); 523 if (inp == 0) { 524 ++udpstat.udps_pcbhashmiss; 525 #ifdef INET6 526 if (ip6) { 527 inp = in6_pcblookup_listen(&udbtable, 528 &ip6->ip6_dst, uh->uh_dport); 529 } else 530 #endif /* INET6 */ 531 inp = in_pcblookup_listen(&udbtable, 532 ip->ip_dst, uh->uh_dport); 533 if (inp == 0) { 534 udpstat.udps_noport++; 535 if (m->m_flags & (M_BCAST | M_MCAST)) { 536 udpstat.udps_noportbcast++; 537 goto bad; 538 } 539 #ifdef INET6 540 if (ip6) { 541 icmp6_error(m, ICMP6_DST_UNREACH, 542 ICMP6_DST_UNREACH_NOPORT,0); 543 } else 544 #endif /* INET6 */ 545 { 546 *ip = save_ip; 547 uh->uh_sum = savesum; 548 icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_PORT, 549 0, 0); 550 } 551 return; 552 } 553 } 554 555 #ifdef IPSEC 556 mtag = m_tag_find(m, PACKET_TAG_IPSEC_IN_DONE, NULL); 557 s = splnet(); 558 if (mtag != NULL) { 559 tdbi = (struct tdb_ident *)(mtag + 1); 560 tdb = gettdb(tdbi->spi, &tdbi->dst, tdbi->proto); 561 } else 562 tdb = NULL; 563 ipsp_spd_lookup(m, srcsa.sa.sa_family, iphlen, &error, 564 IPSP_DIRECTION_IN, tdb, inp); 565 if (error) { 566 splx(s); 567 goto bad; 568 } 569 570 /* Latch SA only if the socket is connected */ 571 if (inp->inp_tdb_in != tdb && 572 (inp->inp_socket->so_state & SS_ISCONNECTED)) { 573 if (tdb) { 574 tdb_add_inp(tdb, inp, 1); 575 if (inp->inp_ipo == NULL) { 576 inp->inp_ipo = ipsec_add_policy(inp, 577 srcsa.sa.sa_family, IPSP_DIRECTION_OUT); 578 if (inp->inp_ipo == NULL) { 579 splx(s); 580 goto bad; 581 } 582 } 583 if (inp->inp_ipo->ipo_dstid == NULL && 584 tdb->tdb_srcid != NULL) { 585 inp->inp_ipo->ipo_dstid = tdb->tdb_srcid; 586 tdb->tdb_srcid->ref_count++; 587 } 588 if (inp->inp_ipsec_remotecred == NULL && 589 tdb->tdb_remote_cred != NULL) { 590 inp->inp_ipsec_remotecred = 591 tdb->tdb_remote_cred; 592 tdb->tdb_remote_cred->ref_count++; 593 } 594 if (inp->inp_ipsec_remoteauth == NULL && 595 tdb->tdb_remote_auth != NULL) { 596 inp->inp_ipsec_remoteauth = 597 tdb->tdb_remote_auth; 598 tdb->tdb_remote_auth->ref_count++; 599 } 600 } else { /* Just reset */ 601 TAILQ_REMOVE(&inp->inp_tdb_in->tdb_inp_in, inp, 602 inp_tdb_in_next); 603 inp->inp_tdb_in = NULL; 604 } 605 } 606 splx(s); 607 #endif /*IPSEC */ 608 609 opts = NULL; 610 #ifdef INET6 611 if (ip6 && (inp->inp_flags & IN6P_CONTROLOPTS)) 612 ip6_savecontrol(inp, &opts, ip6, m); 613 #endif /* INET6 */ 614 if (ip && (inp->inp_flags & INP_CONTROLOPTS)) { 615 struct mbuf **mp = &opts; 616 617 if (inp->inp_flags & INP_RECVDSTADDR) { 618 *mp = udp_saveopt((caddr_t) &ip->ip_dst, 619 sizeof(struct in_addr), IP_RECVDSTADDR); 620 if (*mp) 621 mp = &(*mp)->m_next; 622 } 623 #ifdef notyet 624 /* options were tossed above */ 625 if (inp->inp_flags & INP_RECVOPTS) { 626 *mp = udp_saveopt((caddr_t) opts_deleted_above, 627 sizeof(struct in_addr), IP_RECVOPTS); 628 if (*mp) 629 mp = &(*mp)->m_next; 630 } 631 /* ip_srcroute doesn't do what we want here, need to fix */ 632 if (inp->inp_flags & INP_RECVRETOPTS) { 633 *mp = udp_saveopt((caddr_t) ip_srcroute(), 634 sizeof(struct in_addr), IP_RECVRETOPTS); 635 if (*mp) 636 mp = &(*mp)->m_next; 637 } 638 #endif 639 } 640 iphlen += sizeof(struct udphdr); 641 m_adj(m, iphlen); 642 if (sbappendaddr(&inp->inp_socket->so_rcv, &srcsa.sa, m, opts) == 0) { 643 udpstat.udps_fullsock++; 644 goto bad; 645 } 646 sorwakeup(inp->inp_socket); 647 return; 648 bad: 649 m_freem(m); 650 if (opts) 651 m_freem(opts); 652 } 653 654 /* 655 * Create a "control" mbuf containing the specified data 656 * with the specified type for presentation with a datagram. 657 */ 658 struct mbuf * 659 udp_saveopt(p, size, type) 660 caddr_t p; 661 register int size; 662 int type; 663 { 664 register struct cmsghdr *cp; 665 struct mbuf *m; 666 667 if ((m = m_get(M_DONTWAIT, MT_CONTROL)) == NULL) 668 return ((struct mbuf *) NULL); 669 cp = (struct cmsghdr *) mtod(m, struct cmsghdr *); 670 bcopy(p, CMSG_DATA(cp), size); 671 size = CMSG_LEN(size); 672 m->m_len = size; 673 cp->cmsg_len = size; 674 cp->cmsg_level = IPPROTO_IP; 675 cp->cmsg_type = type; 676 return (m); 677 } 678 679 /* 680 * Notify a udp user of an asynchronous error; 681 * just wake up so that he can collect error status. 682 */ 683 static void 684 udp_notify(inp, errno) 685 register struct inpcb *inp; 686 int errno; 687 { 688 inp->inp_socket->so_error = errno; 689 sorwakeup(inp->inp_socket); 690 sowwakeup(inp->inp_socket); 691 } 692 693 #ifdef INET6 694 void 695 udp6_ctlinput(cmd, sa, d) 696 int cmd; 697 struct sockaddr *sa; 698 void *d; 699 { 700 struct udphdr uh; 701 struct sockaddr_in6 sa6; 702 register struct ip6_hdr *ip6; 703 struct mbuf *m; 704 int off; 705 void *cmdarg; 706 struct ip6ctlparam *ip6cp = NULL; 707 struct udp_portonly { 708 u_int16_t uh_sport; 709 u_int16_t uh_dport; 710 } *uhp; 711 void (*notify)(struct inpcb *, int) = udp_notify; 712 713 if (sa == NULL) 714 return; 715 if (sa->sa_family != AF_INET6 || 716 sa->sa_len != sizeof(struct sockaddr_in6)) 717 return; 718 719 if ((unsigned)cmd >= PRC_NCMDS) 720 return; 721 if (PRC_IS_REDIRECT(cmd)) 722 notify = in_rtchange, d = NULL; 723 else if (cmd == PRC_HOSTDEAD) 724 d = NULL; 725 else if (cmd == PRC_MSGSIZE) 726 ; /* special code is present, see below */ 727 else if (inet6ctlerrmap[cmd] == 0) 728 return; 729 730 /* if the parameter is from icmp6, decode it. */ 731 if (d != NULL) { 732 ip6cp = (struct ip6ctlparam *)d; 733 m = ip6cp->ip6c_m; 734 ip6 = ip6cp->ip6c_ip6; 735 off = ip6cp->ip6c_off; 736 cmdarg = ip6cp->ip6c_cmdarg; 737 } else { 738 m = NULL; 739 ip6 = NULL; 740 cmdarg = NULL; 741 /* XXX: translate addresses into internal form */ 742 sa6 = *(struct sockaddr_in6 *)sa; 743 #ifndef SCOPEDROUTING 744 if (in6_embedscope(&sa6.sin6_addr, &sa6, NULL, NULL)) { 745 /* should be impossible */ 746 return; 747 } 748 #endif 749 } 750 751 if (ip6cp && ip6cp->ip6c_finaldst) { 752 bzero(&sa6, sizeof(sa6)); 753 sa6.sin6_family = AF_INET6; 754 sa6.sin6_len = sizeof(sa6); 755 sa6.sin6_addr = *ip6cp->ip6c_finaldst; 756 /* XXX: assuming M is valid in this case */ 757 sa6.sin6_scope_id = in6_addr2scopeid(m->m_pkthdr.rcvif, 758 ip6cp->ip6c_finaldst); 759 #ifndef SCOPEDROUTING 760 if (in6_embedscope(ip6cp->ip6c_finaldst, &sa6, NULL, NULL)) { 761 /* should be impossible */ 762 return; 763 } 764 #endif 765 } else { 766 /* XXX: translate addresses into internal form */ 767 sa6 = *(struct sockaddr_in6 *)sa; 768 #ifndef SCOPEDROUTING 769 if (in6_embedscope(&sa6.sin6_addr, &sa6, NULL, NULL)) { 770 /* should be impossible */ 771 return; 772 } 773 #endif 774 } 775 776 if (ip6) { 777 /* 778 * XXX: We assume that when IPV6 is non NULL, 779 * M and OFF are valid. 780 */ 781 struct sockaddr_in6 sa6_src; 782 783 /* check if we can safely examine src and dst ports */ 784 if (m->m_pkthdr.len < off + sizeof(*uhp)) 785 return; 786 787 bzero(&uh, sizeof(uh)); 788 m_copydata(m, off, sizeof(*uhp), (caddr_t)&uh); 789 790 bzero(&sa6_src, sizeof(sa6_src)); 791 sa6_src.sin6_family = AF_INET6; 792 sa6_src.sin6_len = sizeof(sa6_src); 793 sa6_src.sin6_addr = ip6->ip6_src; 794 sa6_src.sin6_scope_id = in6_addr2scopeid(m->m_pkthdr.rcvif, 795 &ip6->ip6_src); 796 #ifndef SCOPEDROUTING 797 if (in6_embedscope(&sa6_src.sin6_addr, &sa6_src, NULL, NULL)) { 798 /* should be impossible */ 799 return; 800 } 801 #endif 802 803 if (cmd == PRC_MSGSIZE) { 804 int valid = 0; 805 806 /* 807 * Check to see if we have a valid UDP socket 808 * corresponding to the address in the ICMPv6 message 809 * payload. 810 */ 811 if (in6_pcbhashlookup(&udbtable, &sa6.sin6_addr, 812 uh.uh_dport, &sa6_src.sin6_addr, uh.uh_sport)) 813 valid = 1; 814 #if 0 815 /* 816 * As the use of sendto(2) is fairly popular, 817 * we may want to allow non-connected pcb too. 818 * But it could be too weak against attacks... 819 * We should at least check if the local address (= s) 820 * is really ours. 821 */ 822 else if (in6_pcblookup_listen(&udbtable, 823 &sa6_src.sin6_addr, uh.uh_sport)) 824 valid = 1; 825 #endif 826 827 /* 828 * Depending on the value of "valid" and routing table 829 * size (mtudisc_{hi,lo}wat), we will: 830 * - recalcurate the new MTU and create the 831 * corresponding routing entry, or 832 * - ignore the MTU change notification. 833 */ 834 icmp6_mtudisc_update((struct ip6ctlparam *)d, valid); 835 836 /* 837 * regardless of if we called icmp6_mtudisc_update(), 838 * we need to call in6_pcbnotify(), to notify path 839 * MTU change to the userland (2292bis-02), because 840 * some unconnected sockets may share the same 841 * destination and want to know the path MTU. 842 */ 843 } 844 845 (void) in6_pcbnotify(&udbtable, (struct sockaddr *)&sa6, 846 uh.uh_dport, (struct sockaddr *)&sa6_src, 847 uh.uh_sport, cmd, cmdarg, notify); 848 } else { 849 (void) in6_pcbnotify(&udbtable, (struct sockaddr *)&sa6, 0, 850 (struct sockaddr *)&sa6_any, 0, cmd, cmdarg, notify); 851 } 852 } 853 #endif 854 855 void * 856 udp_ctlinput(cmd, sa, v) 857 int cmd; 858 struct sockaddr *sa; 859 void *v; 860 { 861 register struct ip *ip = v; 862 register struct udphdr *uhp; 863 extern int inetctlerrmap[]; 864 void (*notify)(struct inpcb *, int) = udp_notify; 865 int errno; 866 867 if (sa == NULL) 868 return NULL; 869 if (sa->sa_family != AF_INET || 870 sa->sa_len != sizeof(struct sockaddr_in)) 871 return NULL; 872 873 if ((unsigned)cmd >= PRC_NCMDS) 874 return NULL; 875 errno = inetctlerrmap[cmd]; 876 if (PRC_IS_REDIRECT(cmd)) 877 notify = in_rtchange, ip = 0; 878 else if (cmd == PRC_HOSTDEAD) 879 ip = 0; 880 else if (errno == 0) 881 return NULL; 882 if (ip) { 883 uhp = (struct udphdr *)((caddr_t)ip + (ip->ip_hl << 2)); 884 in_pcbnotify(&udbtable, sa, uhp->uh_dport, ip->ip_src, 885 uhp->uh_sport, errno, notify); 886 } else 887 in_pcbnotifyall(&udbtable, sa, errno, notify); 888 return NULL; 889 } 890 891 int 892 udp_output(struct mbuf *m, ...) 893 { 894 register struct inpcb *inp; 895 struct mbuf *addr, *control; 896 register struct udpiphdr *ui; 897 register int len = m->m_pkthdr.len; 898 struct in_addr laddr; 899 int s = 0, error = 0; 900 va_list ap; 901 int pcbflags = 0; 902 903 va_start(ap, m); 904 inp = va_arg(ap, struct inpcb *); 905 addr = va_arg(ap, struct mbuf *); 906 control = va_arg(ap, struct mbuf *); 907 va_end(ap); 908 909 #ifdef DIAGNOSTIC 910 if ((inp->inp_flags & INP_IPV6) != 0) 911 panic("IPv6 inpcb to udp_output"); 912 #endif 913 914 /* 915 * Compute the packet length of the IP header, and 916 * punt if the length looks bogus. 917 */ 918 if ((len + sizeof(struct udpiphdr)) > IP_MAXPACKET) { 919 error = EMSGSIZE; 920 goto release; 921 } 922 923 if (addr) { 924 /* 925 * Save current PCB flags because they may change during 926 * temporary connection. 927 */ 928 pcbflags = inp->inp_flags; 929 930 laddr = inp->inp_laddr; 931 if (inp->inp_faddr.s_addr != INADDR_ANY) { 932 error = EISCONN; 933 goto release; 934 } 935 /* 936 * Must block input while temporarily connected. 937 */ 938 s = splsoftnet(); 939 error = in_pcbconnect(inp, addr); 940 if (error) { 941 splx(s); 942 goto release; 943 } 944 } else { 945 if (inp->inp_faddr.s_addr == INADDR_ANY) { 946 error = ENOTCONN; 947 goto release; 948 } 949 } 950 /* 951 * Calculate data length and get a mbuf 952 * for UDP and IP headers. 953 */ 954 M_PREPEND(m, sizeof(struct udpiphdr), M_DONTWAIT); 955 if (m == 0) { 956 error = ENOBUFS; 957 goto bail; 958 } 959 960 /* 961 * Fill in mbuf with extended UDP header 962 * and addresses and length put into network format. 963 */ 964 ui = mtod(m, struct udpiphdr *); 965 bzero(ui->ui_x1, sizeof ui->ui_x1); 966 ui->ui_pr = IPPROTO_UDP; 967 ui->ui_len = htons((u_int16_t)len + sizeof (struct udphdr)); 968 ui->ui_src = inp->inp_laddr; 969 ui->ui_dst = inp->inp_faddr; 970 ui->ui_sport = inp->inp_lport; 971 ui->ui_dport = inp->inp_fport; 972 ui->ui_ulen = ui->ui_len; 973 974 /* 975 * Compute the pseudo-header checksum; defer further checksumming 976 * until ip_output() or hardware (if it exists). 977 */ 978 if (udpcksum) { 979 m->m_pkthdr.csum |= M_UDPV4_CSUM_OUT; 980 ui->ui_sum = in_cksum_phdr(ui->ui_src.s_addr, 981 ui->ui_dst.s_addr, htons((u_int16_t)len + 982 sizeof (struct udphdr) + IPPROTO_UDP)); 983 } else 984 ui->ui_sum = 0; 985 ((struct ip *)ui)->ip_len = htons(sizeof (struct udpiphdr) + len); 986 ((struct ip *)ui)->ip_ttl = inp->inp_ip.ip_ttl; 987 ((struct ip *)ui)->ip_tos = inp->inp_ip.ip_tos; 988 989 udpstat.udps_opackets++; 990 error = ip_output(m, inp->inp_options, &inp->inp_route, 991 inp->inp_socket->so_options & (SO_DONTROUTE | SO_BROADCAST), 992 inp->inp_moptions, inp, (void *)NULL); 993 994 bail: 995 if (addr) { 996 in_pcbdisconnect(inp); 997 inp->inp_flags = pcbflags; 998 inp->inp_laddr = laddr; 999 splx(s); 1000 } 1001 if (control) 1002 m_freem(control); 1003 return (error); 1004 1005 release: 1006 m_freem(m); 1007 if (control) 1008 m_freem(control); 1009 return (error); 1010 } 1011 1012 u_int udp_sendspace = 9216; /* really max datagram size */ 1013 u_int udp_recvspace = 40 * (1024 + sizeof(struct sockaddr_in)); 1014 /* 40 1K datagrams */ 1015 1016 #ifdef INET6 1017 /*ARGSUSED*/ 1018 int 1019 udp6_usrreq(so, req, m, addr, control, p) 1020 struct socket *so; 1021 int req; 1022 struct mbuf *m, *addr, *control; 1023 struct proc *p; 1024 { 1025 1026 return udp_usrreq(so, req, m, addr, control); 1027 } 1028 #endif 1029 1030 /*ARGSUSED*/ 1031 int 1032 udp_usrreq(so, req, m, addr, control) 1033 struct socket *so; 1034 int req; 1035 struct mbuf *m, *addr, *control; 1036 { 1037 struct inpcb *inp = sotoinpcb(so); 1038 int error = 0; 1039 int s; 1040 1041 if (req == PRU_CONTROL) { 1042 #ifdef INET6 1043 if (inp->inp_flags & INP_IPV6) 1044 return (in6_control(so, (u_long)m, (caddr_t)addr, 1045 (struct ifnet *)control, 0)); 1046 else 1047 #endif /* INET6 */ 1048 return (in_control(so, (u_long)m, (caddr_t)addr, 1049 (struct ifnet *)control)); 1050 } 1051 if (inp == NULL && req != PRU_ATTACH) { 1052 error = EINVAL; 1053 goto release; 1054 } 1055 /* 1056 * Note: need to block udp_input while changing 1057 * the udp pcb queue and/or pcb addresses. 1058 */ 1059 switch (req) { 1060 1061 case PRU_ATTACH: 1062 if (inp != NULL) { 1063 error = EINVAL; 1064 break; 1065 } 1066 s = splsoftnet(); 1067 error = in_pcballoc(so, &udbtable); 1068 splx(s); 1069 if (error) 1070 break; 1071 error = soreserve(so, udp_sendspace, udp_recvspace); 1072 if (error) 1073 break; 1074 #ifdef INET6 1075 if (((struct inpcb *)so->so_pcb)->inp_flags & INP_IPV6) 1076 ((struct inpcb *) so->so_pcb)->inp_ipv6.ip6_hlim = 1077 ip6_defhlim; 1078 else 1079 #endif /* INET6 */ 1080 ((struct inpcb *) so->so_pcb)->inp_ip.ip_ttl = ip_defttl; 1081 break; 1082 1083 case PRU_DETACH: 1084 udp_detach(inp); 1085 break; 1086 1087 case PRU_BIND: 1088 s = splsoftnet(); 1089 #ifdef INET6 1090 if (inp->inp_flags & INP_IPV6) 1091 error = in6_pcbbind(inp, addr); 1092 else 1093 #endif 1094 error = in_pcbbind(inp, addr); 1095 splx(s); 1096 break; 1097 1098 case PRU_LISTEN: 1099 error = EOPNOTSUPP; 1100 break; 1101 1102 case PRU_CONNECT: 1103 #ifdef INET6 1104 if (inp->inp_flags & INP_IPV6) { 1105 if (!IN6_IS_ADDR_UNSPECIFIED(&inp->inp_faddr6)) { 1106 error = EISCONN; 1107 break; 1108 } 1109 s = splsoftnet(); 1110 error = in6_pcbconnect(inp, addr); 1111 splx(s); 1112 } else 1113 #endif /* INET6 */ 1114 { 1115 if (inp->inp_faddr.s_addr != INADDR_ANY) { 1116 error = EISCONN; 1117 break; 1118 } 1119 s = splsoftnet(); 1120 error = in_pcbconnect(inp, addr); 1121 splx(s); 1122 } 1123 1124 if (error == 0) 1125 soisconnected(so); 1126 break; 1127 1128 case PRU_CONNECT2: 1129 error = EOPNOTSUPP; 1130 break; 1131 1132 case PRU_ACCEPT: 1133 error = EOPNOTSUPP; 1134 break; 1135 1136 case PRU_DISCONNECT: 1137 #ifdef INET6 1138 if (inp->inp_flags & INP_IPV6) { 1139 if (IN6_IS_ADDR_UNSPECIFIED(&inp->inp_faddr6)) { 1140 error = ENOTCONN; 1141 break; 1142 } 1143 } else 1144 #endif /* INET6 */ 1145 { 1146 if (inp->inp_faddr.s_addr == INADDR_ANY) { 1147 error = ENOTCONN; 1148 break; 1149 } 1150 } 1151 1152 s = splsoftnet(); 1153 in_pcbdisconnect(inp); 1154 #ifdef INET6 1155 if (inp->inp_flags & INP_IPV6) 1156 inp->inp_laddr6 = in6addr_any; 1157 else 1158 #endif /* INET6 */ 1159 inp->inp_laddr.s_addr = INADDR_ANY; 1160 1161 splx(s); 1162 so->so_state &= ~SS_ISCONNECTED; /* XXX */ 1163 break; 1164 1165 case PRU_SHUTDOWN: 1166 socantsendmore(so); 1167 break; 1168 1169 case PRU_SEND: 1170 #ifdef INET6 1171 if (inp->inp_flags & INP_IPV6) 1172 return (udp6_output(inp, m, addr, control)); 1173 else 1174 return (udp_output(m, inp, addr, control)); 1175 #else 1176 return (udp_output(m, inp, addr, control)); 1177 #endif 1178 1179 case PRU_ABORT: 1180 soisdisconnected(so); 1181 udp_detach(inp); 1182 break; 1183 1184 case PRU_SOCKADDR: 1185 #ifdef INET6 1186 if (inp->inp_flags & INP_IPV6) 1187 in6_setsockaddr(inp, addr); 1188 else 1189 #endif /* INET6 */ 1190 in_setsockaddr(inp, addr); 1191 break; 1192 1193 case PRU_PEERADDR: 1194 #ifdef INET6 1195 if (inp->inp_flags & INP_IPV6) 1196 in6_setpeeraddr(inp, addr); 1197 else 1198 #endif /* INET6 */ 1199 in_setpeeraddr(inp, addr); 1200 break; 1201 1202 case PRU_SENSE: 1203 /* 1204 * stat: don't bother with a blocksize. 1205 */ 1206 /* 1207 * Perhaps Path MTU might be returned for a connected 1208 * UDP socket in this case. 1209 */ 1210 return (0); 1211 1212 case PRU_SENDOOB: 1213 case PRU_FASTTIMO: 1214 case PRU_SLOWTIMO: 1215 case PRU_PROTORCV: 1216 case PRU_PROTOSEND: 1217 error = EOPNOTSUPP; 1218 break; 1219 1220 case PRU_RCVD: 1221 case PRU_RCVOOB: 1222 return (EOPNOTSUPP); /* do not free mbuf's */ 1223 1224 default: 1225 panic("udp_usrreq"); 1226 } 1227 1228 release: 1229 if (control) { 1230 m_freem(control); 1231 } 1232 if (m) 1233 m_freem(m); 1234 return (error); 1235 } 1236 1237 static void 1238 udp_detach(inp) 1239 struct inpcb *inp; 1240 { 1241 int s = splsoftnet(); 1242 1243 in_pcbdetach(inp); 1244 splx(s); 1245 } 1246 1247 /* 1248 * Sysctl for udp variables. 1249 */ 1250 int 1251 udp_sysctl(name, namelen, oldp, oldlenp, newp, newlen) 1252 int *name; 1253 u_int namelen; 1254 void *oldp; 1255 size_t *oldlenp; 1256 void *newp; 1257 size_t newlen; 1258 { 1259 /* All sysctl names at this level are terminal. */ 1260 if (namelen != 1) 1261 return (ENOTDIR); 1262 1263 switch (name[0]) { 1264 case UDPCTL_CHECKSUM: 1265 return (sysctl_int(oldp, oldlenp, newp, newlen, &udpcksum)); 1266 case UDPCTL_BADDYNAMIC: 1267 return (sysctl_struct(oldp, oldlenp, newp, newlen, 1268 baddynamicports.udp, sizeof(baddynamicports.udp))); 1269 case UDPCTL_RECVSPACE: 1270 return (sysctl_int(oldp, oldlenp, newp, newlen,&udp_recvspace)); 1271 case UDPCTL_SENDSPACE: 1272 return (sysctl_int(oldp, oldlenp, newp, newlen,&udp_sendspace)); 1273 default: 1274 return (ENOPROTOOPT); 1275 } 1276 /* NOTREACHED */ 1277 } 1278