1 /* $OpenBSD: in_pcb.c,v 1.286 2024/01/19 02:24:07 bluhm Exp $ */ 2 /* $NetBSD: in_pcb.c,v 1.25 1996/02/13 23:41:53 christos Exp $ */ 3 4 /* 5 * Copyright (c) 1982, 1986, 1991, 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 "pf.h" 72 73 #include <sys/param.h> 74 #include <sys/systm.h> 75 #include <sys/mbuf.h> 76 #include <sys/protosw.h> 77 #include <sys/socket.h> 78 #include <sys/socketvar.h> 79 #include <sys/domain.h> 80 #include <sys/mount.h> 81 #include <sys/pool.h> 82 #include <sys/proc.h> 83 84 #include <net/if.h> 85 #include <net/if_var.h> 86 #include <net/pfvar.h> 87 #include <net/route.h> 88 89 #include <netinet/in.h> 90 #include <netinet/in_var.h> 91 #include <netinet/ip.h> 92 #include <netinet/ip_var.h> 93 #include <netinet/in_pcb.h> 94 #ifdef IPSEC 95 #include <netinet/ip_esp.h> 96 #endif /* IPSEC */ 97 98 #include "stoeplitz.h" 99 #if NSTOEPLITZ > 0 100 #include <net/toeplitz.h> 101 #endif 102 103 const struct in_addr zeroin_addr; 104 105 const union { 106 struct in_addr za_in; 107 struct in6_addr za_in6; 108 } zeroin46_addr; 109 110 /* 111 * These configure the range of local port addresses assigned to 112 * "unspecified" outgoing connections/packets/whatever. 113 */ 114 int ipport_firstauto = IPPORT_RESERVED; 115 int ipport_lastauto = IPPORT_USERRESERVED; 116 int ipport_hifirstauto = IPPORT_HIFIRSTAUTO; 117 int ipport_hilastauto = IPPORT_HILASTAUTO; 118 119 struct baddynamicports baddynamicports; 120 struct baddynamicports rootonlyports; 121 struct pool inpcb_pool; 122 123 void in_pcbhash_insert(struct inpcb *); 124 struct inpcb *in_pcbhash_lookup(struct inpcbtable *, uint64_t, u_int, 125 const struct in_addr *, u_short, const struct in_addr *, u_short); 126 int in_pcbresize(struct inpcbtable *, int); 127 128 #define INPCBHASH_LOADFACTOR(_x) (((_x) * 3) / 4) 129 130 uint64_t in_pcbhash(struct inpcbtable *, u_int, 131 const struct in_addr *, u_short, const struct in_addr *, u_short); 132 uint64_t in_pcblhash(struct inpcbtable *, u_int, u_short); 133 134 struct inpcb *in_pcblookup_lock(struct inpcbtable *, struct in_addr, u_int, 135 struct in_addr, u_int, u_int, int); 136 int in_pcbaddrisavail_lock(const struct inpcb *, struct sockaddr_in *, int, 137 struct proc *, int); 138 int in_pcbpickport(u_int16_t *, const void *, int, const struct inpcb *, 139 struct proc *); 140 141 /* 142 * in_pcb is used for inet and inet6. in6_pcb only contains special 143 * IPv6 cases. So the internet initializer is used for both domains. 144 */ 145 void 146 in_init(void) 147 { 148 pool_init(&inpcb_pool, sizeof(struct inpcb), 0, 149 IPL_SOFTNET, 0, "inpcb", NULL); 150 } 151 152 uint64_t 153 in_pcbhash(struct inpcbtable *table, u_int rdomain, 154 const struct in_addr *faddr, u_short fport, 155 const struct in_addr *laddr, u_short lport) 156 { 157 SIPHASH_CTX ctx; 158 u_int32_t nrdom = htonl(rdomain); 159 160 SipHash24_Init(&ctx, &table->inpt_key); 161 SipHash24_Update(&ctx, &nrdom, sizeof(nrdom)); 162 SipHash24_Update(&ctx, faddr, sizeof(*faddr)); 163 SipHash24_Update(&ctx, &fport, sizeof(fport)); 164 SipHash24_Update(&ctx, laddr, sizeof(*laddr)); 165 SipHash24_Update(&ctx, &lport, sizeof(lport)); 166 return SipHash24_End(&ctx); 167 } 168 169 uint64_t 170 in_pcblhash(struct inpcbtable *table, u_int rdomain, u_short lport) 171 { 172 SIPHASH_CTX ctx; 173 u_int32_t nrdom = htonl(rdomain); 174 175 SipHash24_Init(&ctx, &table->inpt_lkey); 176 SipHash24_Update(&ctx, &nrdom, sizeof(nrdom)); 177 SipHash24_Update(&ctx, &lport, sizeof(lport)); 178 return SipHash24_End(&ctx); 179 } 180 181 void 182 in_pcbinit(struct inpcbtable *table, int hashsize) 183 { 184 mtx_init(&table->inpt_mtx, IPL_SOFTNET); 185 rw_init(&table->inpt_notify, "inpnotify"); 186 TAILQ_INIT(&table->inpt_queue); 187 table->inpt_hashtbl = hashinit(hashsize, M_PCB, M_WAITOK, 188 &table->inpt_mask); 189 table->inpt_lhashtbl = hashinit(hashsize, M_PCB, M_WAITOK, 190 &table->inpt_lmask); 191 table->inpt_count = 0; 192 table->inpt_size = hashsize; 193 arc4random_buf(&table->inpt_key, sizeof(table->inpt_key)); 194 arc4random_buf(&table->inpt_lkey, sizeof(table->inpt_lkey)); 195 } 196 197 /* 198 * Check if the specified port is invalid for dynamic allocation. 199 */ 200 int 201 in_baddynamic(u_int16_t port, u_int16_t proto) 202 { 203 switch (proto) { 204 case IPPROTO_TCP: 205 return (DP_ISSET(baddynamicports.tcp, port)); 206 case IPPROTO_UDP: 207 #ifdef IPSEC 208 /* Cannot preset this as it is a sysctl */ 209 if (port == udpencap_port) 210 return (1); 211 #endif 212 return (DP_ISSET(baddynamicports.udp, port)); 213 default: 214 return (0); 215 } 216 } 217 218 int 219 in_rootonly(u_int16_t port, u_int16_t proto) 220 { 221 switch (proto) { 222 case IPPROTO_TCP: 223 return (port < IPPORT_RESERVED || 224 DP_ISSET(rootonlyports.tcp, port)); 225 case IPPROTO_UDP: 226 return (port < IPPORT_RESERVED || 227 DP_ISSET(rootonlyports.udp, port)); 228 default: 229 return (0); 230 } 231 } 232 233 int 234 in_pcballoc(struct socket *so, struct inpcbtable *table, int wait) 235 { 236 struct inpcb *inp; 237 238 inp = pool_get(&inpcb_pool, (wait == M_WAIT ? PR_WAITOK : PR_NOWAIT) | 239 PR_ZERO); 240 if (inp == NULL) 241 return (ENOBUFS); 242 inp->inp_table = table; 243 inp->inp_socket = so; 244 refcnt_init_trace(&inp->inp_refcnt, DT_REFCNT_IDX_INPCB); 245 mtx_init(&inp->inp_mtx, IPL_SOFTNET); 246 inp->inp_seclevel[SL_AUTH] = IPSEC_AUTH_LEVEL_DEFAULT; 247 inp->inp_seclevel[SL_ESP_TRANS] = IPSEC_ESP_TRANS_LEVEL_DEFAULT; 248 inp->inp_seclevel[SL_ESP_NETWORK] = IPSEC_ESP_NETWORK_LEVEL_DEFAULT; 249 inp->inp_seclevel[SL_IPCOMP] = IPSEC_IPCOMP_LEVEL_DEFAULT; 250 inp->inp_rtableid = curproc->p_p->ps_rtableid; 251 inp->inp_hops = -1; 252 #ifdef INET6 253 switch (so->so_proto->pr_domain->dom_family) { 254 case PF_INET6: 255 inp->inp_flags = INP_IPV6; 256 break; 257 case PF_INET: 258 /* inp->inp_flags is initialized to 0 */ 259 break; 260 default: 261 unhandled_af(so->so_proto->pr_domain->dom_family); 262 } 263 inp->inp_cksum6 = -1; 264 #endif /* INET6 */ 265 266 mtx_enter(&table->inpt_mtx); 267 if (table->inpt_count++ > INPCBHASH_LOADFACTOR(table->inpt_size)) 268 (void)in_pcbresize(table, table->inpt_size * 2); 269 TAILQ_INSERT_HEAD(&table->inpt_queue, inp, inp_queue); 270 in_pcbhash_insert(inp); 271 mtx_leave(&table->inpt_mtx); 272 273 so->so_pcb = inp; 274 275 return (0); 276 } 277 278 int 279 in_pcbbind_locked(struct inpcb *inp, struct mbuf *nam, struct proc *p) 280 { 281 struct socket *so = inp->inp_socket; 282 u_int16_t lport = 0; 283 int wild = 0; 284 const void *laddr = &zeroin46_addr; 285 int error; 286 287 if (inp->inp_lport) 288 return (EINVAL); 289 290 if ((so->so_options & (SO_REUSEADDR|SO_REUSEPORT)) == 0 && 291 ((so->so_proto->pr_flags & PR_CONNREQUIRED) == 0 || 292 (so->so_options & SO_ACCEPTCONN) == 0)) 293 wild = INPLOOKUP_WILDCARD; 294 295 #ifdef INET6 296 if (ISSET(inp->inp_flags, INP_IPV6)) { 297 if (!IN6_IS_ADDR_UNSPECIFIED(&inp->inp_laddr6)) 298 return (EINVAL); 299 wild |= INPLOOKUP_IPV6; 300 301 if (nam) { 302 struct sockaddr_in6 *sin6; 303 304 if ((error = in6_nam2sin6(nam, &sin6))) 305 return (error); 306 if ((error = in6_pcbaddrisavail_lock(inp, sin6, wild, 307 p, IN_PCBLOCK_HOLD))) 308 return (error); 309 laddr = &sin6->sin6_addr; 310 lport = sin6->sin6_port; 311 } 312 } else 313 #endif 314 { 315 if (inp->inp_laddr.s_addr != INADDR_ANY) 316 return (EINVAL); 317 318 if (nam) { 319 struct sockaddr_in *sin; 320 321 if ((error = in_nam2sin(nam, &sin))) 322 return (error); 323 if ((error = in_pcbaddrisavail_lock(inp, sin, wild, 324 p, IN_PCBLOCK_HOLD))) 325 return (error); 326 laddr = &sin->sin_addr; 327 lport = sin->sin_port; 328 } 329 } 330 331 if (lport == 0) { 332 if ((error = in_pcbpickport(&lport, laddr, wild, inp, p))) 333 return (error); 334 } else { 335 if (in_rootonly(ntohs(lport), so->so_proto->pr_protocol) && 336 suser(p) != 0) 337 return (EACCES); 338 } 339 if (nam) { 340 #ifdef INET6 341 if (ISSET(inp->inp_flags, INP_IPV6)) 342 inp->inp_laddr6 = *(struct in6_addr *)laddr; 343 else 344 #endif 345 inp->inp_laddr = *(struct in_addr *)laddr; 346 } 347 inp->inp_lport = lport; 348 in_pcbrehash(inp); 349 350 return (0); 351 } 352 353 int 354 in_pcbbind(struct inpcb *inp, struct mbuf *nam, struct proc *p) 355 { 356 struct inpcbtable *table = inp->inp_table; 357 int error; 358 359 /* keep lookup, modification, and rehash in sync */ 360 mtx_enter(&table->inpt_mtx); 361 error = in_pcbbind_locked(inp, nam, p); 362 mtx_leave(&table->inpt_mtx); 363 364 return error; 365 } 366 367 int 368 in_pcbaddrisavail_lock(const struct inpcb *inp, struct sockaddr_in *sin, 369 int wild, struct proc *p, int lock) 370 { 371 struct socket *so = inp->inp_socket; 372 struct inpcbtable *table = inp->inp_table; 373 u_int16_t lport = sin->sin_port; 374 int reuseport = (so->so_options & SO_REUSEPORT); 375 376 if (IN_MULTICAST(sin->sin_addr.s_addr)) { 377 /* 378 * Treat SO_REUSEADDR as SO_REUSEPORT for multicast; 379 * allow complete duplication of binding if 380 * SO_REUSEPORT is set, or if SO_REUSEADDR is set 381 * and a multicast address is bound on both 382 * new and duplicated sockets. 383 */ 384 if (so->so_options & (SO_REUSEADDR|SO_REUSEPORT)) 385 reuseport = SO_REUSEADDR|SO_REUSEPORT; 386 } else if (sin->sin_addr.s_addr != INADDR_ANY) { 387 /* 388 * we must check that we are binding to an address we 389 * own except when: 390 * - SO_BINDANY is set or 391 * - we are binding a UDP socket to 255.255.255.255 or 392 * - we are binding a UDP socket to one of our broadcast 393 * addresses 394 */ 395 if (!ISSET(so->so_options, SO_BINDANY) && 396 !(so->so_type == SOCK_DGRAM && 397 sin->sin_addr.s_addr == INADDR_BROADCAST) && 398 !(so->so_type == SOCK_DGRAM && 399 in_broadcast(sin->sin_addr, inp->inp_rtableid))) { 400 struct ifaddr *ia; 401 402 sin->sin_port = 0; 403 memset(sin->sin_zero, 0, sizeof(sin->sin_zero)); 404 ia = ifa_ifwithaddr(sintosa(sin), inp->inp_rtableid); 405 sin->sin_port = lport; 406 407 if (ia == NULL) 408 return (EADDRNOTAVAIL); 409 } 410 } 411 if (lport) { 412 struct inpcb *t; 413 int error = 0; 414 415 if (so->so_euid && !IN_MULTICAST(sin->sin_addr.s_addr)) { 416 t = in_pcblookup_local_lock(table, &sin->sin_addr, 417 lport, INPLOOKUP_WILDCARD, inp->inp_rtableid, lock); 418 if (t && (so->so_euid != t->inp_socket->so_euid)) 419 error = EADDRINUSE; 420 if (lock == IN_PCBLOCK_GRAB) 421 in_pcbunref(t); 422 if (error) 423 return (error); 424 } 425 t = in_pcblookup_local_lock(table, &sin->sin_addr, lport, 426 wild, inp->inp_rtableid, lock); 427 if (t && (reuseport & t->inp_socket->so_options) == 0) 428 error = EADDRINUSE; 429 if (lock == IN_PCBLOCK_GRAB) 430 in_pcbunref(t); 431 if (error) 432 return (error); 433 } 434 435 return (0); 436 } 437 438 int 439 in_pcbaddrisavail(const struct inpcb *inp, struct sockaddr_in *sin, 440 int wild, struct proc *p) 441 { 442 return in_pcbaddrisavail_lock(inp, sin, wild, p, IN_PCBLOCK_GRAB); 443 } 444 445 int 446 in_pcbpickport(u_int16_t *lport, const void *laddr, int wild, 447 const struct inpcb *inp, struct proc *p) 448 { 449 struct socket *so = inp->inp_socket; 450 struct inpcbtable *table = inp->inp_table; 451 struct inpcb *t; 452 u_int16_t first, last, lower, higher, candidate, localport; 453 int count; 454 455 MUTEX_ASSERT_LOCKED(&table->inpt_mtx); 456 457 if (inp->inp_flags & INP_HIGHPORT) { 458 first = ipport_hifirstauto; /* sysctl */ 459 last = ipport_hilastauto; 460 } else if (inp->inp_flags & INP_LOWPORT) { 461 if (suser(p)) 462 return (EACCES); 463 first = IPPORT_RESERVED-1; /* 1023 */ 464 last = 600; /* not IPPORT_RESERVED/2 */ 465 } else { 466 first = ipport_firstauto; /* sysctl */ 467 last = ipport_lastauto; 468 } 469 if (first < last) { 470 lower = first; 471 higher = last; 472 } else { 473 lower = last; 474 higher = first; 475 } 476 477 /* 478 * Simple check to ensure all ports are not used up causing 479 * a deadlock here. 480 */ 481 482 count = higher - lower; 483 candidate = lower + arc4random_uniform(count); 484 485 do { 486 do { 487 if (count-- < 0) /* completely used? */ 488 return (EADDRNOTAVAIL); 489 ++candidate; 490 if (candidate < lower || candidate > higher) 491 candidate = lower; 492 localport = htons(candidate); 493 } while (in_baddynamic(candidate, so->so_proto->pr_protocol)); 494 t = in_pcblookup_local_lock(table, laddr, localport, wild, 495 inp->inp_rtableid, IN_PCBLOCK_HOLD); 496 } while (t != NULL); 497 *lport = localport; 498 499 return (0); 500 } 501 502 /* 503 * Connect from a socket to a specified address. 504 * Both address and port must be specified in argument sin. 505 * If don't have a local address for this socket yet, 506 * then pick one. 507 */ 508 int 509 in_pcbconnect(struct inpcb *inp, struct mbuf *nam) 510 { 511 struct inpcbtable *table = inp->inp_table; 512 struct in_addr ina; 513 struct sockaddr_in *sin; 514 struct inpcb *t; 515 int error; 516 517 #ifdef INET6 518 if (ISSET(inp->inp_flags, INP_IPV6)) 519 return (in6_pcbconnect(inp, nam)); 520 #endif 521 522 if ((error = in_nam2sin(nam, &sin))) 523 return (error); 524 if (sin->sin_port == 0) 525 return (EADDRNOTAVAIL); 526 error = in_pcbselsrc(&ina, sin, inp); 527 if (error) 528 return (error); 529 530 /* keep lookup, modification, and rehash in sync */ 531 mtx_enter(&table->inpt_mtx); 532 533 t = in_pcblookup_lock(inp->inp_table, sin->sin_addr, sin->sin_port, 534 ina, inp->inp_lport, inp->inp_rtableid, IN_PCBLOCK_HOLD); 535 if (t != NULL) { 536 mtx_leave(&table->inpt_mtx); 537 return (EADDRINUSE); 538 } 539 540 KASSERT(inp->inp_laddr.s_addr == INADDR_ANY || inp->inp_lport); 541 542 if (inp->inp_laddr.s_addr == INADDR_ANY) { 543 if (inp->inp_lport == 0) { 544 error = in_pcbbind_locked(inp, NULL, curproc); 545 if (error) { 546 mtx_leave(&table->inpt_mtx); 547 return (error); 548 } 549 t = in_pcblookup_lock(inp->inp_table, sin->sin_addr, 550 sin->sin_port, ina, inp->inp_lport, 551 inp->inp_rtableid, IN_PCBLOCK_HOLD); 552 if (t != NULL) { 553 inp->inp_lport = 0; 554 mtx_leave(&table->inpt_mtx); 555 return (EADDRINUSE); 556 } 557 } 558 inp->inp_laddr = ina; 559 } 560 inp->inp_faddr = sin->sin_addr; 561 inp->inp_fport = sin->sin_port; 562 in_pcbrehash(inp); 563 564 mtx_leave(&table->inpt_mtx); 565 566 #if NSTOEPLITZ > 0 567 inp->inp_flowid = stoeplitz_ip4port(inp->inp_faddr.s_addr, 568 inp->inp_laddr.s_addr, inp->inp_fport, inp->inp_lport); 569 #endif 570 return (0); 571 } 572 573 void 574 in_pcbdisconnect(struct inpcb *inp) 575 { 576 #if NPF > 0 577 pf_remove_divert_state(inp); 578 pf_inp_unlink(inp); 579 #endif 580 inp->inp_flowid = 0; 581 if (inp->inp_socket->so_state & SS_NOFDREF) 582 in_pcbdetach(inp); 583 } 584 585 void 586 in_pcbdetach(struct inpcb *inp) 587 { 588 struct socket *so = inp->inp_socket; 589 struct inpcbtable *table = inp->inp_table; 590 591 so->so_pcb = NULL; 592 /* 593 * As long as the NET_LOCK() is the default lock for Internet 594 * sockets, do not release it to not introduce new sleeping 595 * points. 596 */ 597 sofree(so, 1); 598 m_freem(inp->inp_options); 599 if (inp->inp_route.ro_rt) { 600 rtfree(inp->inp_route.ro_rt); 601 inp->inp_route.ro_rt = NULL; 602 } 603 #ifdef INET6 604 if (ISSET(inp->inp_flags, INP_IPV6)) { 605 ip6_freepcbopts(inp->inp_outputopts6); 606 ip6_freemoptions(inp->inp_moptions6); 607 } else 608 #endif 609 ip_freemoptions(inp->inp_moptions); 610 611 #if NPF > 0 612 pf_remove_divert_state(inp); 613 pf_inp_unlink(inp); 614 #endif 615 mtx_enter(&table->inpt_mtx); 616 LIST_REMOVE(inp, inp_lhash); 617 LIST_REMOVE(inp, inp_hash); 618 TAILQ_REMOVE(&table->inpt_queue, inp, inp_queue); 619 table->inpt_count--; 620 mtx_leave(&table->inpt_mtx); 621 622 in_pcbunref(inp); 623 } 624 625 struct inpcb * 626 in_pcbref(struct inpcb *inp) 627 { 628 if (inp == NULL) 629 return NULL; 630 refcnt_take(&inp->inp_refcnt); 631 return inp; 632 } 633 634 void 635 in_pcbunref(struct inpcb *inp) 636 { 637 if (inp == NULL) 638 return; 639 if (refcnt_rele(&inp->inp_refcnt) == 0) 640 return; 641 KASSERT((LIST_NEXT(inp, inp_hash) == NULL) || 642 (LIST_NEXT(inp, inp_hash) == _Q_INVALID)); 643 KASSERT((LIST_NEXT(inp, inp_lhash) == NULL) || 644 (LIST_NEXT(inp, inp_lhash) == _Q_INVALID)); 645 KASSERT((TAILQ_NEXT(inp, inp_queue) == NULL) || 646 (TAILQ_NEXT(inp, inp_queue) == _Q_INVALID)); 647 pool_put(&inpcb_pool, inp); 648 } 649 650 void 651 in_setsockaddr(struct inpcb *inp, struct mbuf *nam) 652 { 653 struct sockaddr_in *sin; 654 655 #ifdef INET6 656 if (ISSET(inp->inp_flags, INP_IPV6)) { 657 in6_setsockaddr(inp, nam); 658 return; 659 } 660 #endif 661 662 nam->m_len = sizeof(*sin); 663 sin = mtod(nam, struct sockaddr_in *); 664 memset(sin, 0, sizeof(*sin)); 665 sin->sin_family = AF_INET; 666 sin->sin_len = sizeof(*sin); 667 sin->sin_port = inp->inp_lport; 668 sin->sin_addr = inp->inp_laddr; 669 } 670 671 void 672 in_setpeeraddr(struct inpcb *inp, struct mbuf *nam) 673 { 674 struct sockaddr_in *sin; 675 676 #ifdef INET6 677 if (ISSET(inp->inp_flags, INP_IPV6)) { 678 in6_setpeeraddr(inp, nam); 679 return; 680 } 681 #endif 682 683 nam->m_len = sizeof(*sin); 684 sin = mtod(nam, struct sockaddr_in *); 685 memset(sin, 0, sizeof(*sin)); 686 sin->sin_family = AF_INET; 687 sin->sin_len = sizeof(*sin); 688 sin->sin_port = inp->inp_fport; 689 sin->sin_addr = inp->inp_faddr; 690 } 691 692 int 693 in_sockaddr(struct socket *so, struct mbuf *nam) 694 { 695 struct inpcb *inp; 696 697 inp = sotoinpcb(so); 698 in_setsockaddr(inp, nam); 699 700 return (0); 701 } 702 703 int 704 in_peeraddr(struct socket *so, struct mbuf *nam) 705 { 706 struct inpcb *inp; 707 708 inp = sotoinpcb(so); 709 in_setpeeraddr(inp, nam); 710 711 return (0); 712 } 713 714 /* 715 * Pass some notification to all connections of a protocol 716 * associated with address dst. The "usual action" will be 717 * taken, depending on the ctlinput cmd. The caller must filter any 718 * cmds that are uninteresting (e.g., no error in the map). 719 * Call the protocol specific routine (if any) to report 720 * any errors for each matching socket. 721 */ 722 void 723 in_pcbnotifyall(struct inpcbtable *table, struct sockaddr *dst, u_int rtable, 724 int errno, void (*notify)(struct inpcb *, int)) 725 { 726 SIMPLEQ_HEAD(, inpcb) inpcblist; 727 struct inpcb *inp; 728 struct in_addr faddr; 729 u_int rdomain; 730 731 if (dst->sa_family != AF_INET) 732 return; 733 faddr = satosin(dst)->sin_addr; 734 if (faddr.s_addr == INADDR_ANY) 735 return; 736 if (notify == NULL) 737 return; 738 739 /* 740 * Use a temporary notify list protected by rwlock to run over 741 * selected PCB. This is necessary as the list of all PCB is 742 * protected by a mutex. Notify may call ip_output() eventually 743 * which may sleep as pf lock is a rwlock. Also the SRP 744 * implementation of the routing table might sleep. 745 * The same inp_notify list entry and inpt_notify rwlock are 746 * used for UDP multicast and raw IP delivery. 747 */ 748 SIMPLEQ_INIT(&inpcblist); 749 rdomain = rtable_l2(rtable); 750 rw_enter_write(&table->inpt_notify); 751 mtx_enter(&table->inpt_mtx); 752 TAILQ_FOREACH(inp, &table->inpt_queue, inp_queue) { 753 #ifdef INET6 754 if (ISSET(inp->inp_flags, INP_IPV6)) 755 continue; 756 #endif 757 if (inp->inp_faddr.s_addr != faddr.s_addr || 758 rtable_l2(inp->inp_rtableid) != rdomain) { 759 continue; 760 } 761 in_pcbref(inp); 762 SIMPLEQ_INSERT_TAIL(&inpcblist, inp, inp_notify); 763 } 764 mtx_leave(&table->inpt_mtx); 765 766 while ((inp = SIMPLEQ_FIRST(&inpcblist)) != NULL) { 767 SIMPLEQ_REMOVE_HEAD(&inpcblist, inp_notify); 768 (*notify)(inp, errno); 769 in_pcbunref(inp); 770 } 771 rw_exit_write(&table->inpt_notify); 772 } 773 774 /* 775 * Check for alternatives when higher level complains 776 * about service problems. For now, invalidate cached 777 * routing information. If the route was created dynamically 778 * (by a redirect), time to try a default gateway again. 779 */ 780 void 781 in_losing(struct inpcb *inp) 782 { 783 struct rtentry *rt = inp->inp_route.ro_rt; 784 785 if (rt) { 786 inp->inp_route.ro_rt = NULL; 787 788 if (rt->rt_flags & RTF_DYNAMIC) { 789 struct ifnet *ifp; 790 791 ifp = if_get(rt->rt_ifidx); 792 /* 793 * If the interface is gone, all its attached 794 * route entries have been removed from the table, 795 * so we're dealing with a stale cache and have 796 * nothing to do. 797 */ 798 if (ifp != NULL) 799 rtdeletemsg(rt, ifp, inp->inp_rtableid); 800 if_put(ifp); 801 } 802 /* 803 * A new route can be allocated 804 * the next time output is attempted. 805 * rtfree() needs to be called in anycase because the inp 806 * is still holding a reference to rt. 807 */ 808 rtfree(rt); 809 } 810 } 811 812 /* 813 * After a routing change, flush old routing 814 * and allocate a (hopefully) better one. 815 */ 816 void 817 in_rtchange(struct inpcb *inp, int errno) 818 { 819 if (inp->inp_route.ro_rt) { 820 rtfree(inp->inp_route.ro_rt); 821 inp->inp_route.ro_rt = NULL; 822 /* 823 * A new route can be allocated the next time 824 * output is attempted. 825 */ 826 } 827 } 828 829 struct inpcb * 830 in_pcblookup_local_lock(struct inpcbtable *table, const void *laddrp, 831 u_int lport_arg, int flags, u_int rtable, int lock) 832 { 833 struct inpcb *inp, *match = NULL; 834 int matchwild = 3, wildcard; 835 u_int16_t lport = lport_arg; 836 const struct in_addr laddr = *(const struct in_addr *)laddrp; 837 #ifdef INET6 838 const struct in6_addr *laddr6 = (const struct in6_addr *)laddrp; 839 #endif 840 struct inpcbhead *head; 841 uint64_t lhash; 842 u_int rdomain; 843 844 rdomain = rtable_l2(rtable); 845 lhash = in_pcblhash(table, rdomain, lport); 846 847 if (lock == IN_PCBLOCK_GRAB) { 848 mtx_enter(&table->inpt_mtx); 849 } else { 850 KASSERT(lock == IN_PCBLOCK_HOLD); 851 MUTEX_ASSERT_LOCKED(&table->inpt_mtx); 852 } 853 head = &table->inpt_lhashtbl[lhash & table->inpt_lmask]; 854 LIST_FOREACH(inp, head, inp_lhash) { 855 if (rtable_l2(inp->inp_rtableid) != rdomain) 856 continue; 857 if (inp->inp_lport != lport) 858 continue; 859 wildcard = 0; 860 #ifdef INET6 861 if (ISSET(flags, INPLOOKUP_IPV6)) { 862 if (!ISSET(inp->inp_flags, INP_IPV6)) 863 continue; 864 865 if (!IN6_IS_ADDR_UNSPECIFIED(&inp->inp_faddr6)) 866 wildcard++; 867 868 if (!IN6_ARE_ADDR_EQUAL(&inp->inp_laddr6, laddr6)) { 869 if (IN6_IS_ADDR_UNSPECIFIED(&inp->inp_laddr6) || 870 IN6_IS_ADDR_UNSPECIFIED(laddr6)) 871 wildcard++; 872 else 873 continue; 874 } 875 876 } else 877 #endif /* INET6 */ 878 { 879 #ifdef INET6 880 if (ISSET(inp->inp_flags, INP_IPV6)) 881 continue; 882 #endif /* INET6 */ 883 884 if (inp->inp_faddr.s_addr != INADDR_ANY) 885 wildcard++; 886 887 if (inp->inp_laddr.s_addr != laddr.s_addr) { 888 if (inp->inp_laddr.s_addr == INADDR_ANY || 889 laddr.s_addr == INADDR_ANY) 890 wildcard++; 891 else 892 continue; 893 } 894 895 } 896 if ((!wildcard || (flags & INPLOOKUP_WILDCARD)) && 897 wildcard < matchwild) { 898 match = inp; 899 if ((matchwild = wildcard) == 0) 900 break; 901 } 902 } 903 if (lock == IN_PCBLOCK_GRAB) { 904 in_pcbref(match); 905 mtx_leave(&table->inpt_mtx); 906 } 907 908 return (match); 909 } 910 911 struct rtentry * 912 in_pcbrtentry(struct inpcb *inp) 913 { 914 struct route *ro; 915 916 ro = &inp->inp_route; 917 918 /* check if route is still valid */ 919 if (!rtisvalid(ro->ro_rt)) { 920 rtfree(ro->ro_rt); 921 ro->ro_rt = NULL; 922 } 923 924 /* 925 * No route yet, so try to acquire one. 926 */ 927 if (ro->ro_rt == NULL) { 928 #ifdef INET6 929 memset(ro, 0, sizeof(struct route_in6)); 930 #else 931 memset(ro, 0, sizeof(struct route)); 932 #endif 933 934 #ifdef INET6 935 if (ISSET(inp->inp_flags, INP_IPV6)) { 936 if (IN6_IS_ADDR_UNSPECIFIED(&inp->inp_faddr6)) 937 return (NULL); 938 ro->ro_dst.sa_family = AF_INET6; 939 ro->ro_dst.sa_len = sizeof(struct sockaddr_in6); 940 satosin6(&ro->ro_dst)->sin6_addr = inp->inp_faddr6; 941 ro->ro_tableid = inp->inp_rtableid; 942 ro->ro_rt = rtalloc_mpath(&ro->ro_dst, 943 &inp->inp_laddr6.s6_addr32[0], ro->ro_tableid); 944 } else 945 #endif /* INET6 */ 946 { 947 if (inp->inp_faddr.s_addr == INADDR_ANY) 948 return (NULL); 949 ro->ro_dst.sa_family = AF_INET; 950 ro->ro_dst.sa_len = sizeof(struct sockaddr_in); 951 satosin(&ro->ro_dst)->sin_addr = inp->inp_faddr; 952 ro->ro_tableid = inp->inp_rtableid; 953 ro->ro_rt = rtalloc_mpath(&ro->ro_dst, 954 &inp->inp_laddr.s_addr, ro->ro_tableid); 955 } 956 } 957 return (ro->ro_rt); 958 } 959 960 /* 961 * Return an IPv4 address, which is the most appropriate for a given 962 * destination. 963 * If necessary, this function lookups the routing table and returns 964 * an entry to the caller for later use. 965 */ 966 int 967 in_pcbselsrc(struct in_addr *insrc, struct sockaddr_in *sin, 968 struct inpcb *inp) 969 { 970 struct ip_moptions *mopts = inp->inp_moptions; 971 struct route *ro = &inp->inp_route; 972 const struct in_addr *laddr = &inp->inp_laddr; 973 u_int rtableid = inp->inp_rtableid; 974 struct sockaddr *ip4_source = NULL; 975 976 struct sockaddr_in *sin2; 977 struct in_ifaddr *ia = NULL; 978 979 /* 980 * If the socket(if any) is already bound, use that bound address 981 * unless it is INADDR_ANY or INADDR_BROADCAST. 982 */ 983 if (laddr->s_addr != INADDR_ANY && 984 laddr->s_addr != INADDR_BROADCAST) { 985 *insrc = *laddr; 986 return (0); 987 } 988 989 /* 990 * If the destination address is multicast or limited 991 * broadcast (255.255.255.255) and an outgoing interface has 992 * been set as a multicast option, use the address of that 993 * interface as our source address. 994 */ 995 if ((IN_MULTICAST(sin->sin_addr.s_addr) || 996 sin->sin_addr.s_addr == INADDR_BROADCAST) && mopts != NULL) { 997 struct ifnet *ifp; 998 999 ifp = if_get(mopts->imo_ifidx); 1000 if (ifp != NULL) { 1001 if (ifp->if_rdomain == rtable_l2(rtableid)) 1002 IFP_TO_IA(ifp, ia); 1003 if (ia == NULL) { 1004 if_put(ifp); 1005 return (EADDRNOTAVAIL); 1006 } 1007 1008 *insrc = ia->ia_addr.sin_addr; 1009 if_put(ifp); 1010 return (0); 1011 } 1012 } 1013 1014 /* 1015 * If route is known or can be allocated now, 1016 * our src addr is taken from the i/f, else punt. 1017 */ 1018 if (!rtisvalid(ro->ro_rt) || (ro->ro_tableid != rtableid) || 1019 (satosin(&ro->ro_dst)->sin_addr.s_addr != sin->sin_addr.s_addr)) { 1020 rtfree(ro->ro_rt); 1021 ro->ro_rt = NULL; 1022 } 1023 if (ro->ro_rt == NULL) { 1024 /* No route yet, so try to acquire one */ 1025 ro->ro_dst.sa_family = AF_INET; 1026 ro->ro_dst.sa_len = sizeof(struct sockaddr_in); 1027 satosin(&ro->ro_dst)->sin_addr = sin->sin_addr; 1028 ro->ro_tableid = rtableid; 1029 ro->ro_rt = rtalloc_mpath(&ro->ro_dst, NULL, ro->ro_tableid); 1030 1031 /* 1032 * It is important to zero out the rest of the 1033 * struct sockaddr_in when mixing v6 & v4! 1034 */ 1035 sin2 = satosin(&ro->ro_dst); 1036 memset(sin2->sin_zero, 0, sizeof(sin2->sin_zero)); 1037 } 1038 1039 /* 1040 * If we found a route, use the address 1041 * corresponding to the outgoing interface. 1042 */ 1043 if (ro->ro_rt != NULL) 1044 ia = ifatoia(ro->ro_rt->rt_ifa); 1045 1046 /* 1047 * Use preferred source address if : 1048 * - destination is not onlink 1049 * - preferred source address is set 1050 * - output interface is UP 1051 */ 1052 if (ro->ro_rt && !(ro->ro_rt->rt_flags & RTF_LLINFO) && 1053 !(ro->ro_rt->rt_flags & RTF_HOST)) { 1054 ip4_source = rtable_getsource(rtableid, AF_INET); 1055 if (ip4_source != NULL) { 1056 struct ifaddr *ifa; 1057 if ((ifa = ifa_ifwithaddr(ip4_source, rtableid)) != 1058 NULL && ISSET(ifa->ifa_ifp->if_flags, IFF_UP)) { 1059 *insrc = satosin(ip4_source)->sin_addr; 1060 return (0); 1061 } 1062 } 1063 } 1064 1065 if (ia == NULL) 1066 return (EADDRNOTAVAIL); 1067 1068 *insrc = ia->ia_addr.sin_addr; 1069 return (0); 1070 } 1071 1072 void 1073 in_pcbrehash(struct inpcb *inp) 1074 { 1075 LIST_REMOVE(inp, inp_lhash); 1076 LIST_REMOVE(inp, inp_hash); 1077 in_pcbhash_insert(inp); 1078 } 1079 1080 void 1081 in_pcbhash_insert(struct inpcb *inp) 1082 { 1083 struct inpcbtable *table = inp->inp_table; 1084 struct inpcbhead *head; 1085 uint64_t hash, lhash; 1086 1087 MUTEX_ASSERT_LOCKED(&table->inpt_mtx); 1088 1089 lhash = in_pcblhash(table, inp->inp_rtableid, inp->inp_lport); 1090 head = &table->inpt_lhashtbl[lhash & table->inpt_lmask]; 1091 LIST_INSERT_HEAD(head, inp, inp_lhash); 1092 #ifdef INET6 1093 if (ISSET(inp->inp_flags, INP_IPV6)) 1094 hash = in6_pcbhash(table, rtable_l2(inp->inp_rtableid), 1095 &inp->inp_faddr6, inp->inp_fport, 1096 &inp->inp_laddr6, inp->inp_lport); 1097 else 1098 #endif /* INET6 */ 1099 hash = in_pcbhash(table, rtable_l2(inp->inp_rtableid), 1100 &inp->inp_faddr, inp->inp_fport, 1101 &inp->inp_laddr, inp->inp_lport); 1102 head = &table->inpt_hashtbl[hash & table->inpt_mask]; 1103 LIST_INSERT_HEAD(head, inp, inp_hash); 1104 } 1105 1106 struct inpcb * 1107 in_pcbhash_lookup(struct inpcbtable *table, uint64_t hash, u_int rdomain, 1108 const struct in_addr *faddr, u_short fport, 1109 const struct in_addr *laddr, u_short lport) 1110 { 1111 struct inpcbhead *head; 1112 struct inpcb *inp; 1113 1114 MUTEX_ASSERT_LOCKED(&table->inpt_mtx); 1115 1116 head = &table->inpt_hashtbl[hash & table->inpt_mask]; 1117 LIST_FOREACH(inp, head, inp_hash) { 1118 #ifdef INET6 1119 if (ISSET(inp->inp_flags, INP_IPV6)) 1120 continue; 1121 #endif 1122 if (inp->inp_fport == fport && inp->inp_lport == lport && 1123 inp->inp_faddr.s_addr == faddr->s_addr && 1124 inp->inp_laddr.s_addr == laddr->s_addr && 1125 rtable_l2(inp->inp_rtableid) == rdomain) { 1126 break; 1127 } 1128 } 1129 if (inp != NULL) { 1130 /* 1131 * Move this PCB to the head of hash chain so that 1132 * repeated accesses are quicker. This is analogous to 1133 * the historic single-entry PCB cache. 1134 */ 1135 if (inp != LIST_FIRST(head)) { 1136 LIST_REMOVE(inp, inp_hash); 1137 LIST_INSERT_HEAD(head, inp, inp_hash); 1138 } 1139 } 1140 return (inp); 1141 } 1142 1143 int 1144 in_pcbresize(struct inpcbtable *table, int hashsize) 1145 { 1146 u_long nmask, nlmask; 1147 int osize; 1148 void *nhashtbl, *nlhashtbl, *ohashtbl, *olhashtbl; 1149 struct inpcb *inp; 1150 1151 MUTEX_ASSERT_LOCKED(&table->inpt_mtx); 1152 1153 ohashtbl = table->inpt_hashtbl; 1154 olhashtbl = table->inpt_lhashtbl; 1155 osize = table->inpt_size; 1156 1157 nhashtbl = hashinit(hashsize, M_PCB, M_NOWAIT, &nmask); 1158 if (nhashtbl == NULL) 1159 return ENOBUFS; 1160 nlhashtbl = hashinit(hashsize, M_PCB, M_NOWAIT, &nlmask); 1161 if (nlhashtbl == NULL) { 1162 hashfree(nhashtbl, hashsize, M_PCB); 1163 return ENOBUFS; 1164 } 1165 table->inpt_hashtbl = nhashtbl; 1166 table->inpt_lhashtbl = nlhashtbl; 1167 table->inpt_mask = nmask; 1168 table->inpt_lmask = nlmask; 1169 table->inpt_size = hashsize; 1170 1171 TAILQ_FOREACH(inp, &table->inpt_queue, inp_queue) { 1172 LIST_REMOVE(inp, inp_lhash); 1173 LIST_REMOVE(inp, inp_hash); 1174 in_pcbhash_insert(inp); 1175 } 1176 hashfree(ohashtbl, osize, M_PCB); 1177 hashfree(olhashtbl, osize, M_PCB); 1178 1179 return (0); 1180 } 1181 1182 #ifdef DIAGNOSTIC 1183 int in_pcbnotifymiss = 0; 1184 #endif 1185 1186 /* 1187 * The in(6)_pcblookup functions are used to locate connected sockets 1188 * quickly: 1189 * faddr.fport <-> laddr.lport 1190 * No wildcard matching is done so that listening sockets are not found. 1191 * If the functions return NULL in(6)_pcblookup_listen can be used to 1192 * find a listening/bound socket that may accept the connection. 1193 * After those two lookups no other are necessary. 1194 */ 1195 struct inpcb * 1196 in_pcblookup_lock(struct inpcbtable *table, struct in_addr faddr, 1197 u_int fport, struct in_addr laddr, u_int lport, u_int rtable, int lock) 1198 { 1199 struct inpcb *inp; 1200 uint64_t hash; 1201 u_int rdomain; 1202 1203 rdomain = rtable_l2(rtable); 1204 hash = in_pcbhash(table, rdomain, &faddr, fport, &laddr, lport); 1205 1206 if (lock == IN_PCBLOCK_GRAB) { 1207 mtx_enter(&table->inpt_mtx); 1208 } else { 1209 KASSERT(lock == IN_PCBLOCK_HOLD); 1210 MUTEX_ASSERT_LOCKED(&table->inpt_mtx); 1211 } 1212 inp = in_pcbhash_lookup(table, hash, rdomain, 1213 &faddr, fport, &laddr, lport); 1214 if (lock == IN_PCBLOCK_GRAB) { 1215 in_pcbref(inp); 1216 mtx_leave(&table->inpt_mtx); 1217 } 1218 1219 #ifdef DIAGNOSTIC 1220 if (inp == NULL && in_pcbnotifymiss) { 1221 printf("%s: faddr=%08x fport=%d laddr=%08x lport=%d rdom=%u\n", 1222 __func__, ntohl(faddr.s_addr), ntohs(fport), 1223 ntohl(laddr.s_addr), ntohs(lport), rdomain); 1224 } 1225 #endif 1226 return (inp); 1227 } 1228 1229 struct inpcb * 1230 in_pcblookup(struct inpcbtable *table, struct in_addr faddr, 1231 u_int fport, struct in_addr laddr, u_int lport, u_int rtable) 1232 { 1233 return in_pcblookup_lock(table, faddr, fport, laddr, lport, rtable, 1234 IN_PCBLOCK_GRAB); 1235 } 1236 1237 /* 1238 * The in(6)_pcblookup_listen functions are used to locate listening 1239 * sockets quickly. This are sockets with unspecified foreign address 1240 * and port: 1241 * *.* <-> laddr.lport 1242 * *.* <-> *.lport 1243 */ 1244 struct inpcb * 1245 in_pcblookup_listen(struct inpcbtable *table, struct in_addr laddr, 1246 u_int lport_arg, struct mbuf *m, u_int rtable) 1247 { 1248 const struct in_addr *key1, *key2; 1249 struct inpcb *inp; 1250 uint64_t hash; 1251 u_int16_t lport = lport_arg; 1252 u_int rdomain; 1253 1254 key1 = &laddr; 1255 key2 = &zeroin_addr; 1256 #if NPF > 0 1257 if (m && m->m_pkthdr.pf.flags & PF_TAG_DIVERTED) { 1258 struct pf_divert *divert; 1259 1260 divert = pf_find_divert(m); 1261 KASSERT(divert != NULL); 1262 switch (divert->type) { 1263 case PF_DIVERT_TO: 1264 key1 = key2 = &divert->addr.v4; 1265 lport = divert->port; 1266 break; 1267 case PF_DIVERT_REPLY: 1268 return (NULL); 1269 default: 1270 panic("%s: unknown divert type %d, mbuf %p, divert %p", 1271 __func__, divert->type, m, divert); 1272 } 1273 } else if (m && m->m_pkthdr.pf.flags & PF_TAG_TRANSLATE_LOCALHOST) { 1274 /* 1275 * Redirected connections should not be treated the same 1276 * as connections directed to 127.0.0.0/8 since localhost 1277 * can only be accessed from the host itself. 1278 * For example portmap(8) grants more permissions for 1279 * connections to the socket bound to 127.0.0.1 than 1280 * to the * socket. 1281 */ 1282 key1 = &zeroin_addr; 1283 key2 = &laddr; 1284 } 1285 #endif 1286 1287 rdomain = rtable_l2(rtable); 1288 hash = in_pcbhash(table, rdomain, &zeroin_addr, 0, key1, lport); 1289 1290 mtx_enter(&table->inpt_mtx); 1291 inp = in_pcbhash_lookup(table, hash, rdomain, 1292 &zeroin_addr, 0, key1, lport); 1293 if (inp == NULL && key1->s_addr != key2->s_addr) { 1294 hash = in_pcbhash(table, rdomain, 1295 &zeroin_addr, 0, key2, lport); 1296 inp = in_pcbhash_lookup(table, hash, rdomain, 1297 &zeroin_addr, 0, key2, lport); 1298 } 1299 in_pcbref(inp); 1300 mtx_leave(&table->inpt_mtx); 1301 1302 #ifdef DIAGNOSTIC 1303 if (inp == NULL && in_pcbnotifymiss) { 1304 printf("%s: laddr=%08x lport=%d rdom=%u\n", 1305 __func__, ntohl(laddr.s_addr), ntohs(lport), rdomain); 1306 } 1307 #endif 1308 return (inp); 1309 } 1310 1311 int 1312 in_pcbset_rtableid(struct inpcb *inp, u_int rtableid) 1313 { 1314 struct inpcbtable *table = inp->inp_table; 1315 1316 /* table must exist */ 1317 if (!rtable_exists(rtableid)) 1318 return (EINVAL); 1319 1320 mtx_enter(&table->inpt_mtx); 1321 if (inp->inp_lport) { 1322 mtx_leave(&table->inpt_mtx); 1323 return (EBUSY); 1324 } 1325 inp->inp_rtableid = rtableid; 1326 in_pcbrehash(inp); 1327 mtx_leave(&table->inpt_mtx); 1328 1329 return (0); 1330 } 1331 1332 void 1333 in_pcbset_laddr(struct inpcb *inp, const struct sockaddr *sa, u_int rtableid) 1334 { 1335 struct inpcbtable *table = inp->inp_table; 1336 1337 mtx_enter(&table->inpt_mtx); 1338 inp->inp_rtableid = rtableid; 1339 #ifdef INET6 1340 if (ISSET(inp->inp_flags, INP_IPV6)) { 1341 const struct sockaddr_in6 *sin6; 1342 1343 KASSERT(sa->sa_family == AF_INET6); 1344 sin6 = satosin6_const(sa); 1345 inp->inp_lport = sin6->sin6_port; 1346 inp->inp_laddr6 = sin6->sin6_addr; 1347 } else 1348 #endif 1349 { 1350 const struct sockaddr_in *sin; 1351 1352 KASSERT(sa->sa_family == AF_INET); 1353 sin = satosin_const(sa); 1354 inp->inp_lport = sin->sin_port; 1355 inp->inp_laddr = sin->sin_addr; 1356 } 1357 in_pcbrehash(inp); 1358 mtx_leave(&table->inpt_mtx); 1359 } 1360 1361 void 1362 in_pcbunset_faddr(struct inpcb *inp) 1363 { 1364 struct inpcbtable *table = inp->inp_table; 1365 1366 mtx_enter(&table->inpt_mtx); 1367 #ifdef INET6 1368 if (ISSET(inp->inp_flags, INP_IPV6)) 1369 inp->inp_faddr6 = in6addr_any; 1370 else 1371 #endif 1372 inp->inp_faddr.s_addr = INADDR_ANY; 1373 inp->inp_fport = 0; 1374 in_pcbrehash(inp); 1375 mtx_leave(&table->inpt_mtx); 1376 } 1377 1378 void 1379 in_pcbunset_laddr(struct inpcb *inp) 1380 { 1381 struct inpcbtable *table = inp->inp_table; 1382 1383 mtx_enter(&table->inpt_mtx); 1384 #ifdef INET6 1385 if (ISSET(inp->inp_flags, INP_IPV6)) { 1386 inp->inp_faddr6 = in6addr_any; 1387 inp->inp_laddr6 = in6addr_any; 1388 } else 1389 #endif 1390 { 1391 inp->inp_faddr.s_addr = INADDR_ANY; 1392 inp->inp_laddr.s_addr = INADDR_ANY; 1393 } 1394 inp->inp_fport = 0; 1395 in_pcbrehash(inp); 1396 mtx_leave(&table->inpt_mtx); 1397 } 1398