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