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