1 /* $NetBSD: in_pcb.c,v 1.175 2017/02/13 04:05:58 ozaki-r Exp $ */ 2 3 /* 4 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. Neither the name of the project nor the names of its contributors 16 * may be used to endorse or promote products derived from this software 17 * without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 */ 31 32 /*- 33 * Copyright (c) 1998, 2011 The NetBSD Foundation, Inc. 34 * All rights reserved. 35 * 36 * This code is derived from software contributed to The NetBSD Foundation 37 * by Coyote Point Systems, Inc. 38 * This code is derived from software contributed to The NetBSD Foundation 39 * by Public Access Networks Corporation ("Panix"). It was developed under 40 * contract to Panix by Eric Haszlakiewicz and Thor Lancelot Simon. 41 * 42 * Redistribution and use in source and binary forms, with or without 43 * modification, are permitted provided that the following conditions 44 * are met: 45 * 1. Redistributions of source code must retain the above copyright 46 * notice, this list of conditions and the following disclaimer. 47 * 2. Redistributions in binary form must reproduce the above copyright 48 * notice, this list of conditions and the following disclaimer in the 49 * documentation and/or other materials provided with the distribution. 50 * 51 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 52 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 53 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 54 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 55 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 56 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 57 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 58 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 59 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 60 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 61 * POSSIBILITY OF SUCH DAMAGE. 62 */ 63 64 /* 65 * Copyright (c) 1982, 1986, 1991, 1993, 1995 66 * The Regents of the University of California. All rights reserved. 67 * 68 * Redistribution and use in source and binary forms, with or without 69 * modification, are permitted provided that the following conditions 70 * are met: 71 * 1. Redistributions of source code must retain the above copyright 72 * notice, this list of conditions and the following disclaimer. 73 * 2. Redistributions in binary form must reproduce the above copyright 74 * notice, this list of conditions and the following disclaimer in the 75 * documentation and/or other materials provided with the distribution. 76 * 3. Neither the name of the University nor the names of its contributors 77 * may be used to endorse or promote products derived from this software 78 * without specific prior written permission. 79 * 80 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 81 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 82 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 83 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 84 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 85 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 86 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 87 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 88 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 89 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 90 * SUCH DAMAGE. 91 * 92 * @(#)in_pcb.c 8.4 (Berkeley) 5/24/95 93 */ 94 95 #include <sys/cdefs.h> 96 __KERNEL_RCSID(0, "$NetBSD: in_pcb.c,v 1.175 2017/02/13 04:05:58 ozaki-r Exp $"); 97 98 #ifdef _KERNEL_OPT 99 #include "opt_inet.h" 100 #include "opt_ipsec.h" 101 #endif 102 103 #include <sys/param.h> 104 #include <sys/systm.h> 105 #include <sys/mbuf.h> 106 #include <sys/socket.h> 107 #include <sys/socketvar.h> 108 #include <sys/ioctl.h> 109 #include <sys/errno.h> 110 #include <sys/time.h> 111 #include <sys/once.h> 112 #include <sys/pool.h> 113 #include <sys/proc.h> 114 #include <sys/kauth.h> 115 #include <sys/uidinfo.h> 116 #include <sys/domain.h> 117 118 #include <net/if.h> 119 #include <net/route.h> 120 121 #include <netinet/in.h> 122 #include <netinet/in_systm.h> 123 #include <netinet/ip.h> 124 #include <netinet/in_pcb.h> 125 #include <netinet/in_var.h> 126 #include <netinet/ip_var.h> 127 #include <netinet/portalgo.h> 128 129 #ifdef INET6 130 #include <netinet/ip6.h> 131 #include <netinet6/ip6_var.h> 132 #include <netinet6/in6_pcb.h> 133 #endif 134 135 #ifdef IPSEC 136 #include <netipsec/ipsec.h> 137 #include <netipsec/key.h> 138 #endif /* IPSEC */ 139 140 #include <netinet/tcp_vtw.h> 141 142 struct in_addr zeroin_addr; 143 144 #define INPCBHASH_PORT(table, lport) \ 145 &(table)->inpt_porthashtbl[ntohs(lport) & (table)->inpt_porthash] 146 #define INPCBHASH_BIND(table, laddr, lport) \ 147 &(table)->inpt_bindhashtbl[ \ 148 ((ntohl((laddr).s_addr) + ntohs(lport))) & (table)->inpt_bindhash] 149 #define INPCBHASH_CONNECT(table, faddr, fport, laddr, lport) \ 150 &(table)->inpt_connecthashtbl[ \ 151 ((ntohl((faddr).s_addr) + ntohs(fport)) + \ 152 (ntohl((laddr).s_addr) + ntohs(lport))) & (table)->inpt_connecthash] 153 154 int anonportmin = IPPORT_ANONMIN; 155 int anonportmax = IPPORT_ANONMAX; 156 int lowportmin = IPPORT_RESERVEDMIN; 157 int lowportmax = IPPORT_RESERVEDMAX; 158 159 static struct pool inpcb_pool; 160 161 static int 162 inpcb_poolinit(void) 163 { 164 165 pool_init(&inpcb_pool, sizeof(struct inpcb), 0, 0, 0, "inpcbpl", NULL, 166 IPL_NET); 167 return 0; 168 } 169 170 void 171 in_pcbinit(struct inpcbtable *table, int bindhashsize, int connecthashsize) 172 { 173 static ONCE_DECL(control); 174 175 TAILQ_INIT(&table->inpt_queue); 176 table->inpt_porthashtbl = hashinit(bindhashsize, HASH_LIST, true, 177 &table->inpt_porthash); 178 table->inpt_bindhashtbl = hashinit(bindhashsize, HASH_LIST, true, 179 &table->inpt_bindhash); 180 table->inpt_connecthashtbl = hashinit(connecthashsize, HASH_LIST, true, 181 &table->inpt_connecthash); 182 table->inpt_lastlow = IPPORT_RESERVEDMAX; 183 table->inpt_lastport = (u_int16_t)anonportmax; 184 185 RUN_ONCE(&control, inpcb_poolinit); 186 } 187 188 int 189 in_pcballoc(struct socket *so, void *v) 190 { 191 struct inpcbtable *table = v; 192 struct inpcb *inp; 193 int s; 194 195 inp = pool_get(&inpcb_pool, PR_NOWAIT); 196 if (inp == NULL) 197 return (ENOBUFS); 198 memset(inp, 0, sizeof(*inp)); 199 inp->inp_af = AF_INET; 200 inp->inp_table = table; 201 inp->inp_socket = so; 202 inp->inp_errormtu = -1; 203 inp->inp_portalgo = PORTALGO_DEFAULT; 204 inp->inp_bindportonsend = false; 205 #if defined(IPSEC) 206 if (ipsec_enabled) { 207 int error = ipsec_init_pcbpolicy(so, &inp->inp_sp); 208 if (error != 0) { 209 pool_put(&inpcb_pool, inp); 210 return error; 211 } 212 } 213 #endif 214 so->so_pcb = inp; 215 s = splsoftnet(); 216 TAILQ_INSERT_HEAD(&table->inpt_queue, &inp->inp_head, inph_queue); 217 LIST_INSERT_HEAD(INPCBHASH_PORT(table, inp->inp_lport), &inp->inp_head, 218 inph_lhash); 219 in_pcbstate(inp, INP_ATTACHED); 220 splx(s); 221 return (0); 222 } 223 224 static int 225 in_pcbsetport(struct sockaddr_in *sin, struct inpcb *inp, kauth_cred_t cred) 226 { 227 struct inpcbtable *table = inp->inp_table; 228 struct socket *so = inp->inp_socket; 229 u_int16_t *lastport; 230 u_int16_t lport = 0; 231 enum kauth_network_req req; 232 int error; 233 234 if (inp->inp_flags & INP_LOWPORT) { 235 #ifndef IPNOPRIVPORTS 236 req = KAUTH_REQ_NETWORK_BIND_PRIVPORT; 237 #else 238 req = KAUTH_REQ_NETWORK_BIND_PORT; 239 #endif 240 241 lastport = &table->inpt_lastlow; 242 } else { 243 req = KAUTH_REQ_NETWORK_BIND_PORT; 244 245 lastport = &table->inpt_lastport; 246 } 247 248 /* XXX-kauth: KAUTH_REQ_NETWORK_BIND_AUTOASSIGN_{,PRIV}PORT */ 249 error = kauth_authorize_network(cred, KAUTH_NETWORK_BIND, req, so, sin, 250 NULL); 251 if (error) 252 return (EACCES); 253 254 /* 255 * Use RFC6056 randomized port selection 256 */ 257 error = portalgo_randport(&lport, &inp->inp_head, cred); 258 if (error) 259 return error; 260 261 inp->inp_flags |= INP_ANONPORT; 262 *lastport = lport; 263 lport = htons(lport); 264 inp->inp_lport = lport; 265 in_pcbstate(inp, INP_BOUND); 266 267 return (0); 268 } 269 270 static int 271 in_pcbbind_addr(struct inpcb *inp, struct sockaddr_in *sin, kauth_cred_t cred) 272 { 273 int error = EADDRNOTAVAIL; 274 struct ifaddr *ifa = NULL; 275 int s; 276 277 if (sin->sin_family != AF_INET) 278 return (EAFNOSUPPORT); 279 280 s = pserialize_read_enter(); 281 if (IN_MULTICAST(sin->sin_addr.s_addr)) { 282 /* Always succeed; port reuse handled in in_pcbbind_port(). */ 283 } else if (!in_nullhost(sin->sin_addr)) { 284 struct in_ifaddr *ia; 285 286 ia = in_get_ia(sin->sin_addr); 287 /* check for broadcast addresses */ 288 if (ia == NULL) { 289 ifa = ifa_ifwithaddr(sintosa(sin)); 290 if (ifa != NULL) 291 ia = ifatoia(ifa); 292 } 293 if (ia == NULL) 294 goto error; 295 if (ia->ia4_flags & IN_IFF_DUPLICATED) 296 goto error; 297 } 298 pserialize_read_exit(s); 299 300 inp->inp_laddr = sin->sin_addr; 301 302 return (0); 303 error: 304 pserialize_read_exit(s); 305 return error; 306 } 307 308 static int 309 in_pcbbind_port(struct inpcb *inp, struct sockaddr_in *sin, kauth_cred_t cred) 310 { 311 struct inpcbtable *table = inp->inp_table; 312 struct socket *so = inp->inp_socket; 313 int reuseport = (so->so_options & SO_REUSEPORT); 314 int wild = 0, error; 315 316 if (IN_MULTICAST(sin->sin_addr.s_addr)) { 317 /* 318 * Treat SO_REUSEADDR as SO_REUSEPORT for multicast; 319 * allow complete duplication of binding if 320 * SO_REUSEPORT is set, or if SO_REUSEADDR is set 321 * and a multicast address is bound on both 322 * new and duplicated sockets. 323 */ 324 if (so->so_options & (SO_REUSEADDR | SO_REUSEPORT)) 325 reuseport = SO_REUSEADDR|SO_REUSEPORT; 326 } 327 328 if (sin->sin_port == 0) { 329 error = in_pcbsetport(sin, inp, cred); 330 if (error) 331 return (error); 332 } else { 333 struct inpcb *t; 334 vestigial_inpcb_t vestige; 335 #ifdef INET6 336 struct in6pcb *t6; 337 struct in6_addr mapped; 338 #endif 339 enum kauth_network_req req; 340 341 if ((so->so_options & (SO_REUSEADDR|SO_REUSEPORT)) == 0) 342 wild = 1; 343 344 #ifndef IPNOPRIVPORTS 345 if (ntohs(sin->sin_port) < IPPORT_RESERVED) 346 req = KAUTH_REQ_NETWORK_BIND_PRIVPORT; 347 else 348 #endif /* !IPNOPRIVPORTS */ 349 req = KAUTH_REQ_NETWORK_BIND_PORT; 350 351 error = kauth_authorize_network(cred, KAUTH_NETWORK_BIND, req, 352 so, sin, NULL); 353 if (error) 354 return (EACCES); 355 356 #ifdef INET6 357 in6_in_2_v4mapin6(&sin->sin_addr, &mapped); 358 t6 = in6_pcblookup_port(table, &mapped, sin->sin_port, wild, &vestige); 359 if (t6 && (reuseport & t6->in6p_socket->so_options) == 0) 360 return (EADDRINUSE); 361 if (!t6 && vestige.valid) { 362 if (!!reuseport != !!vestige.reuse_port) { 363 return EADDRINUSE; 364 } 365 } 366 #endif 367 368 /* XXX-kauth */ 369 if (so->so_uidinfo->ui_uid && !IN_MULTICAST(sin->sin_addr.s_addr)) { 370 t = in_pcblookup_port(table, sin->sin_addr, sin->sin_port, 1, &vestige); 371 /* 372 * XXX: investigate ramifications of loosening this 373 * restriction so that as long as both ports have 374 * SO_REUSEPORT allow the bind 375 */ 376 if (t && 377 (!in_nullhost(sin->sin_addr) || 378 !in_nullhost(t->inp_laddr) || 379 (t->inp_socket->so_options & SO_REUSEPORT) == 0) 380 && (so->so_uidinfo->ui_uid != t->inp_socket->so_uidinfo->ui_uid)) { 381 return (EADDRINUSE); 382 } 383 if (!t && vestige.valid) { 384 if ((!in_nullhost(sin->sin_addr) 385 || !in_nullhost(vestige.laddr.v4) 386 || !vestige.reuse_port) 387 && so->so_uidinfo->ui_uid != vestige.uid) { 388 return EADDRINUSE; 389 } 390 } 391 } 392 t = in_pcblookup_port(table, sin->sin_addr, sin->sin_port, wild, &vestige); 393 if (t && (reuseport & t->inp_socket->so_options) == 0) 394 return (EADDRINUSE); 395 if (!t 396 && vestige.valid 397 && !(reuseport && vestige.reuse_port)) 398 return EADDRINUSE; 399 400 inp->inp_lport = sin->sin_port; 401 in_pcbstate(inp, INP_BOUND); 402 } 403 404 LIST_REMOVE(&inp->inp_head, inph_lhash); 405 LIST_INSERT_HEAD(INPCBHASH_PORT(table, inp->inp_lport), &inp->inp_head, 406 inph_lhash); 407 408 return (0); 409 } 410 411 int 412 in_pcbbind(void *v, struct sockaddr_in *sin, struct lwp *l) 413 { 414 struct inpcb *inp = v; 415 struct sockaddr_in lsin; 416 int error; 417 418 if (inp->inp_af != AF_INET) 419 return (EINVAL); 420 421 if (IN_ADDRLIST_READER_EMPTY()) 422 return (EADDRNOTAVAIL); 423 if (inp->inp_lport || !in_nullhost(inp->inp_laddr)) 424 return (EINVAL); 425 426 if (NULL != sin) { 427 if (sin->sin_len != sizeof(*sin)) 428 return (EINVAL); 429 } else { 430 lsin = *((const struct sockaddr_in *) 431 inp->inp_socket->so_proto->pr_domain->dom_sa_any); 432 sin = &lsin; 433 } 434 435 /* Bind address. */ 436 error = in_pcbbind_addr(inp, sin, l->l_cred); 437 if (error) 438 return (error); 439 440 /* Bind port. */ 441 error = in_pcbbind_port(inp, sin, l->l_cred); 442 if (error) { 443 inp->inp_laddr.s_addr = INADDR_ANY; 444 445 return (error); 446 } 447 448 return (0); 449 } 450 451 /* 452 * Connect from a socket to a specified address. 453 * Both address and port must be specified in argument sin. 454 * If don't have a local address for this socket yet, 455 * then pick one. 456 */ 457 int 458 in_pcbconnect(void *v, struct sockaddr_in *sin, struct lwp *l) 459 { 460 struct inpcb *inp = v; 461 vestigial_inpcb_t vestige; 462 int error; 463 struct in_addr laddr; 464 465 if (inp->inp_af != AF_INET) 466 return (EINVAL); 467 468 if (sin->sin_len != sizeof (*sin)) 469 return (EINVAL); 470 if (sin->sin_family != AF_INET) 471 return (EAFNOSUPPORT); 472 if (sin->sin_port == 0) 473 return (EADDRNOTAVAIL); 474 475 if (IN_MULTICAST(sin->sin_addr.s_addr) && 476 inp->inp_socket->so_type == SOCK_STREAM) 477 return EADDRNOTAVAIL; 478 479 if (!IN_ADDRLIST_READER_EMPTY()) { 480 /* 481 * If the destination address is INADDR_ANY, 482 * use any local address (likely loopback). 483 * If the supplied address is INADDR_BROADCAST, 484 * use the broadcast address of an interface 485 * which supports broadcast. (loopback does not) 486 */ 487 488 if (in_nullhost(sin->sin_addr)) { 489 /* XXX racy */ 490 sin->sin_addr = 491 IN_ADDRLIST_READER_FIRST()->ia_addr.sin_addr; 492 } else if (sin->sin_addr.s_addr == INADDR_BROADCAST) { 493 struct in_ifaddr *ia; 494 int s = pserialize_read_enter(); 495 IN_ADDRLIST_READER_FOREACH(ia) { 496 if (ia->ia_ifp->if_flags & IFF_BROADCAST) { 497 sin->sin_addr = 498 ia->ia_broadaddr.sin_addr; 499 break; 500 } 501 } 502 pserialize_read_exit(s); 503 } 504 } 505 /* 506 * If we haven't bound which network number to use as ours, 507 * we will use the number of the outgoing interface. 508 * This depends on having done a routing lookup, which 509 * we will probably have to do anyway, so we might 510 * as well do it now. On the other hand if we are 511 * sending to multiple destinations we may have already 512 * done the lookup, so see if we can use the route 513 * from before. In any case, we only 514 * chose a port number once, even if sending to multiple 515 * destinations. 516 */ 517 if (in_nullhost(inp->inp_laddr)) { 518 int xerror; 519 struct in_ifaddr *ia, *_ia; 520 int s; 521 struct psref psref; 522 int bound; 523 524 bound = curlwp_bind(); 525 ia = in_selectsrc(sin, &inp->inp_route, 526 inp->inp_socket->so_options, inp->inp_moptions, &xerror, 527 &psref); 528 if (ia == NULL) { 529 curlwp_bindx(bound); 530 if (xerror == 0) 531 xerror = EADDRNOTAVAIL; 532 return xerror; 533 } 534 s = pserialize_read_enter(); 535 _ia = in_get_ia(IA_SIN(ia)->sin_addr); 536 if (_ia == NULL) { 537 pserialize_read_exit(s); 538 ia4_release(ia, &psref); 539 curlwp_bindx(bound); 540 return (EADDRNOTAVAIL); 541 } 542 pserialize_read_exit(s); 543 laddr = IA_SIN(ia)->sin_addr; 544 ia4_release(ia, &psref); 545 curlwp_bindx(bound); 546 } else 547 laddr = inp->inp_laddr; 548 if (in_pcblookup_connect(inp->inp_table, sin->sin_addr, sin->sin_port, 549 laddr, inp->inp_lport, &vestige) != NULL || 550 vestige.valid) { 551 return (EADDRINUSE); 552 } 553 if (in_nullhost(inp->inp_laddr)) { 554 if (inp->inp_lport == 0) { 555 error = in_pcbbind(inp, NULL, l); 556 /* 557 * This used to ignore the return value 558 * completely, but we need to check for 559 * ephemeral port shortage. 560 * And attempts to request low ports if not root. 561 */ 562 if (error != 0) 563 return (error); 564 } 565 inp->inp_laddr = laddr; 566 } 567 inp->inp_faddr = sin->sin_addr; 568 inp->inp_fport = sin->sin_port; 569 570 /* Late bind, if needed */ 571 if (inp->inp_bindportonsend) { 572 struct sockaddr_in lsin = *((const struct sockaddr_in *) 573 inp->inp_socket->so_proto->pr_domain->dom_sa_any); 574 lsin.sin_addr = inp->inp_laddr; 575 lsin.sin_port = 0; 576 577 if ((error = in_pcbbind_port(inp, &lsin, l->l_cred)) != 0) 578 return error; 579 } 580 581 in_pcbstate(inp, INP_CONNECTED); 582 #if defined(IPSEC) 583 if (ipsec_enabled && inp->inp_socket->so_type == SOCK_STREAM) 584 ipsec_pcbconn(inp->inp_sp); 585 #endif 586 return (0); 587 } 588 589 void 590 in_pcbdisconnect(void *v) 591 { 592 struct inpcb *inp = v; 593 594 if (inp->inp_af != AF_INET) 595 return; 596 597 inp->inp_faddr = zeroin_addr; 598 inp->inp_fport = 0; 599 in_pcbstate(inp, INP_BOUND); 600 #if defined(IPSEC) 601 if (ipsec_enabled) 602 ipsec_pcbdisconn(inp->inp_sp); 603 #endif 604 if (inp->inp_socket->so_state & SS_NOFDREF) 605 in_pcbdetach(inp); 606 } 607 608 void 609 in_pcbdetach(void *v) 610 { 611 struct inpcb *inp = v; 612 struct socket *so = inp->inp_socket; 613 int s; 614 615 if (inp->inp_af != AF_INET) 616 return; 617 618 #if defined(IPSEC) 619 if (ipsec_enabled) 620 ipsec4_delete_pcbpolicy(inp); 621 #endif 622 so->so_pcb = NULL; 623 624 s = splsoftnet(); 625 in_pcbstate(inp, INP_ATTACHED); 626 LIST_REMOVE(&inp->inp_head, inph_lhash); 627 TAILQ_REMOVE(&inp->inp_table->inpt_queue, &inp->inp_head, inph_queue); 628 splx(s); 629 630 if (inp->inp_options) { 631 m_free(inp->inp_options); 632 } 633 rtcache_free(&inp->inp_route); 634 ip_freemoptions(inp->inp_moptions); 635 sofree(so); /* drops the socket's lock */ 636 637 pool_put(&inpcb_pool, inp); 638 mutex_enter(softnet_lock); /* reacquire the softnet_lock */ 639 } 640 641 void 642 in_setsockaddr(struct inpcb *inp, struct sockaddr_in *sin) 643 { 644 645 if (inp->inp_af != AF_INET) 646 return; 647 648 sockaddr_in_init(sin, &inp->inp_laddr, inp->inp_lport); 649 } 650 651 void 652 in_setpeeraddr(struct inpcb *inp, struct sockaddr_in *sin) 653 { 654 655 if (inp->inp_af != AF_INET) 656 return; 657 658 sockaddr_in_init(sin, &inp->inp_faddr, inp->inp_fport); 659 } 660 661 /* 662 * Pass some notification to all connections of a protocol 663 * associated with address dst. The local address and/or port numbers 664 * may be specified to limit the search. The "usual action" will be 665 * taken, depending on the ctlinput cmd. The caller must filter any 666 * cmds that are uninteresting (e.g., no error in the map). 667 * Call the protocol specific routine (if any) to report 668 * any errors for each matching socket. 669 * 670 * Must be called at splsoftnet. 671 */ 672 int 673 in_pcbnotify(struct inpcbtable *table, struct in_addr faddr, u_int fport_arg, 674 struct in_addr laddr, u_int lport_arg, int errno, 675 void (*notify)(struct inpcb *, int)) 676 { 677 struct inpcbhead *head; 678 struct inpcb *inp, *ninp; 679 u_int16_t fport = fport_arg, lport = lport_arg; 680 int nmatch; 681 682 if (in_nullhost(faddr) || notify == 0) 683 return (0); 684 685 nmatch = 0; 686 head = INPCBHASH_CONNECT(table, faddr, fport, laddr, lport); 687 for (inp = (struct inpcb *)LIST_FIRST(head); inp != NULL; inp = ninp) { 688 ninp = (struct inpcb *)LIST_NEXT(inp, inp_hash); 689 if (inp->inp_af != AF_INET) 690 continue; 691 if (in_hosteq(inp->inp_faddr, faddr) && 692 inp->inp_fport == fport && 693 inp->inp_lport == lport && 694 in_hosteq(inp->inp_laddr, laddr)) { 695 (*notify)(inp, errno); 696 nmatch++; 697 } 698 } 699 return (nmatch); 700 } 701 702 void 703 in_pcbnotifyall(struct inpcbtable *table, struct in_addr faddr, int errno, 704 void (*notify)(struct inpcb *, int)) 705 { 706 struct inpcb_hdr *inph, *ninph; 707 708 if (in_nullhost(faddr) || notify == 0) 709 return; 710 711 TAILQ_FOREACH_SAFE(inph, &table->inpt_queue, inph_queue, ninph) { 712 struct inpcb *inp = (struct inpcb *)inph; 713 if (inp->inp_af != AF_INET) 714 continue; 715 if (in_hosteq(inp->inp_faddr, faddr)) 716 (*notify)(inp, errno); 717 } 718 } 719 720 void 721 in_purgeifmcast(struct ip_moptions *imo, struct ifnet *ifp) 722 { 723 int i, gap; 724 725 KASSERT(ifp != NULL); 726 727 if (imo == NULL) 728 return; 729 730 /* 731 * Unselect the outgoing interface if it is being 732 * detached. 733 */ 734 if (imo->imo_multicast_if_index == ifp->if_index) 735 imo->imo_multicast_if_index = 0; 736 737 /* 738 * Drop multicast group membership if we joined 739 * through the interface being detached. 740 */ 741 for (i = 0, gap = 0; i < imo->imo_num_memberships; i++) { 742 if (imo->imo_membership[i]->inm_ifp == ifp) { 743 in_delmulti(imo->imo_membership[i]); 744 gap++; 745 } else if (gap != 0) 746 imo->imo_membership[i - gap] = imo->imo_membership[i]; 747 } 748 imo->imo_num_memberships -= gap; 749 } 750 751 void 752 in_pcbpurgeif0(struct inpcbtable *table, struct ifnet *ifp) 753 { 754 struct inpcb_hdr *inph, *ninph; 755 756 TAILQ_FOREACH_SAFE(inph, &table->inpt_queue, inph_queue, ninph) { 757 struct inpcb *inp = (struct inpcb *)inph; 758 if (inp->inp_af != AF_INET) 759 continue; 760 in_purgeifmcast(inp->inp_moptions, ifp); 761 } 762 } 763 764 void 765 in_pcbpurgeif(struct inpcbtable *table, struct ifnet *ifp) 766 { 767 struct rtentry *rt; 768 struct inpcb_hdr *inph, *ninph; 769 770 TAILQ_FOREACH_SAFE(inph, &table->inpt_queue, inph_queue, ninph) { 771 struct inpcb *inp = (struct inpcb *)inph; 772 if (inp->inp_af != AF_INET) 773 continue; 774 if ((rt = rtcache_validate(&inp->inp_route)) != NULL && 775 rt->rt_ifp == ifp) { 776 rtcache_unref(rt, &inp->inp_route); 777 in_rtchange(inp, 0); 778 } else 779 rtcache_unref(rt, &inp->inp_route); 780 } 781 } 782 783 /* 784 * Check for alternatives when higher level complains 785 * about service problems. For now, invalidate cached 786 * routing information. If the route was created dynamically 787 * (by a redirect), time to try a default gateway again. 788 */ 789 void 790 in_losing(struct inpcb *inp) 791 { 792 struct rtentry *rt; 793 struct rt_addrinfo info; 794 795 if (inp->inp_af != AF_INET) 796 return; 797 798 if ((rt = rtcache_validate(&inp->inp_route)) == NULL) 799 return; 800 801 memset(&info, 0, sizeof(info)); 802 info.rti_info[RTAX_DST] = rtcache_getdst(&inp->inp_route); 803 info.rti_info[RTAX_GATEWAY] = rt->rt_gateway; 804 info.rti_info[RTAX_NETMASK] = rt_mask(rt); 805 rt_missmsg(RTM_LOSING, &info, rt->rt_flags, 0); 806 if (rt->rt_flags & RTF_DYNAMIC) { 807 int error; 808 struct rtentry *nrt; 809 810 error = rtrequest(RTM_DELETE, rt_getkey(rt), 811 rt->rt_gateway, rt_mask(rt), rt->rt_flags, &nrt); 812 rtcache_unref(rt, &inp->inp_route); 813 if (error == 0) 814 rt_free(nrt); 815 } else 816 rtcache_unref(rt, &inp->inp_route); 817 /* 818 * A new route can be allocated 819 * the next time output is attempted. 820 */ 821 rtcache_free(&inp->inp_route); 822 } 823 824 /* 825 * After a routing change, flush old routing. A new route can be 826 * allocated the next time output is attempted. 827 */ 828 void 829 in_rtchange(struct inpcb *inp, int errno) 830 { 831 832 if (inp->inp_af != AF_INET) 833 return; 834 835 rtcache_free(&inp->inp_route); 836 837 /* XXX SHOULD NOTIFY HIGHER-LEVEL PROTOCOLS */ 838 } 839 840 struct inpcb * 841 in_pcblookup_port(struct inpcbtable *table, struct in_addr laddr, 842 u_int lport_arg, int lookup_wildcard, vestigial_inpcb_t *vp) 843 { 844 struct inpcbhead *head; 845 struct inpcb_hdr *inph; 846 struct inpcb *match = NULL; 847 int matchwild = 3; 848 int wildcard; 849 u_int16_t lport = lport_arg; 850 851 if (vp) 852 vp->valid = 0; 853 854 head = INPCBHASH_PORT(table, lport); 855 LIST_FOREACH(inph, head, inph_lhash) { 856 struct inpcb * const inp = (struct inpcb *)inph; 857 858 if (inp->inp_af != AF_INET) 859 continue; 860 if (inp->inp_lport != lport) 861 continue; 862 /* 863 * check if inp's faddr and laddr match with ours. 864 * our faddr is considered null. 865 * count the number of wildcard matches. (0 - 2) 866 * 867 * null null match 868 * A null wildcard match 869 * null B wildcard match 870 * A B non match 871 * A A match 872 */ 873 wildcard = 0; 874 if (!in_nullhost(inp->inp_faddr)) 875 wildcard++; 876 if (in_nullhost(inp->inp_laddr)) { 877 if (!in_nullhost(laddr)) 878 wildcard++; 879 } else { 880 if (in_nullhost(laddr)) 881 wildcard++; 882 else { 883 if (!in_hosteq(inp->inp_laddr, laddr)) 884 continue; 885 } 886 } 887 if (wildcard && !lookup_wildcard) 888 continue; 889 /* 890 * prefer an address with less wildcards. 891 */ 892 if (wildcard < matchwild) { 893 match = inp; 894 matchwild = wildcard; 895 if (matchwild == 0) 896 break; 897 } 898 } 899 if (match && matchwild == 0) 900 return match; 901 902 if (vp && table->vestige) { 903 void *state = (*table->vestige->init_ports4)(laddr, lport_arg, lookup_wildcard); 904 vestigial_inpcb_t better; 905 906 while (table->vestige 907 && (*table->vestige->next_port4)(state, vp)) { 908 909 if (vp->lport != lport) 910 continue; 911 wildcard = 0; 912 if (!in_nullhost(vp->faddr.v4)) 913 wildcard++; 914 if (in_nullhost(vp->laddr.v4)) { 915 if (!in_nullhost(laddr)) 916 wildcard++; 917 } else { 918 if (in_nullhost(laddr)) 919 wildcard++; 920 else { 921 if (!in_hosteq(vp->laddr.v4, laddr)) 922 continue; 923 } 924 } 925 if (wildcard && !lookup_wildcard) 926 continue; 927 if (wildcard < matchwild) { 928 better = *vp; 929 match = (void*)&better; 930 931 matchwild = wildcard; 932 if (matchwild == 0) 933 break; 934 } 935 } 936 937 if (match) { 938 if (match != (void*)&better) 939 return match; 940 else { 941 *vp = better; 942 return 0; 943 } 944 } 945 } 946 947 return (match); 948 } 949 950 #ifdef DIAGNOSTIC 951 int in_pcbnotifymiss = 0; 952 #endif 953 954 struct inpcb * 955 in_pcblookup_connect(struct inpcbtable *table, 956 struct in_addr faddr, u_int fport_arg, 957 struct in_addr laddr, u_int lport_arg, 958 vestigial_inpcb_t *vp) 959 { 960 struct inpcbhead *head; 961 struct inpcb_hdr *inph; 962 struct inpcb *inp; 963 u_int16_t fport = fport_arg, lport = lport_arg; 964 965 if (vp) 966 vp->valid = 0; 967 968 head = INPCBHASH_CONNECT(table, faddr, fport, laddr, lport); 969 LIST_FOREACH(inph, head, inph_hash) { 970 inp = (struct inpcb *)inph; 971 if (inp->inp_af != AF_INET) 972 continue; 973 974 if (in_hosteq(inp->inp_faddr, faddr) && 975 inp->inp_fport == fport && 976 inp->inp_lport == lport && 977 in_hosteq(inp->inp_laddr, laddr)) 978 goto out; 979 } 980 if (vp && table->vestige) { 981 if ((*table->vestige->lookup4)(faddr, fport_arg, 982 laddr, lport_arg, vp)) 983 return 0; 984 } 985 986 #ifdef DIAGNOSTIC 987 if (in_pcbnotifymiss) { 988 printf("in_pcblookup_connect: faddr=%08x fport=%d laddr=%08x lport=%d\n", 989 ntohl(faddr.s_addr), ntohs(fport), 990 ntohl(laddr.s_addr), ntohs(lport)); 991 } 992 #endif 993 return (0); 994 995 out: 996 /* Move this PCB to the head of hash chain. */ 997 inph = &inp->inp_head; 998 if (inph != LIST_FIRST(head)) { 999 LIST_REMOVE(inph, inph_hash); 1000 LIST_INSERT_HEAD(head, inph, inph_hash); 1001 } 1002 return (inp); 1003 } 1004 1005 struct inpcb * 1006 in_pcblookup_bind(struct inpcbtable *table, 1007 struct in_addr laddr, u_int lport_arg) 1008 { 1009 struct inpcbhead *head; 1010 struct inpcb_hdr *inph; 1011 struct inpcb *inp; 1012 u_int16_t lport = lport_arg; 1013 1014 head = INPCBHASH_BIND(table, laddr, lport); 1015 LIST_FOREACH(inph, head, inph_hash) { 1016 inp = (struct inpcb *)inph; 1017 if (inp->inp_af != AF_INET) 1018 continue; 1019 1020 if (inp->inp_lport == lport && 1021 in_hosteq(inp->inp_laddr, laddr)) 1022 goto out; 1023 } 1024 head = INPCBHASH_BIND(table, zeroin_addr, lport); 1025 LIST_FOREACH(inph, head, inph_hash) { 1026 inp = (struct inpcb *)inph; 1027 if (inp->inp_af != AF_INET) 1028 continue; 1029 1030 if (inp->inp_lport == lport && 1031 in_hosteq(inp->inp_laddr, zeroin_addr)) 1032 goto out; 1033 } 1034 #ifdef DIAGNOSTIC 1035 if (in_pcbnotifymiss) { 1036 printf("in_pcblookup_bind: laddr=%08x lport=%d\n", 1037 ntohl(laddr.s_addr), ntohs(lport)); 1038 } 1039 #endif 1040 return (0); 1041 1042 out: 1043 /* Move this PCB to the head of hash chain. */ 1044 inph = &inp->inp_head; 1045 if (inph != LIST_FIRST(head)) { 1046 LIST_REMOVE(inph, inph_hash); 1047 LIST_INSERT_HEAD(head, inph, inph_hash); 1048 } 1049 return (inp); 1050 } 1051 1052 void 1053 in_pcbstate(struct inpcb *inp, int state) 1054 { 1055 1056 if (inp->inp_af != AF_INET) 1057 return; 1058 1059 if (inp->inp_state > INP_ATTACHED) 1060 LIST_REMOVE(&inp->inp_head, inph_hash); 1061 1062 switch (state) { 1063 case INP_BOUND: 1064 LIST_INSERT_HEAD(INPCBHASH_BIND(inp->inp_table, 1065 inp->inp_laddr, inp->inp_lport), &inp->inp_head, 1066 inph_hash); 1067 break; 1068 case INP_CONNECTED: 1069 LIST_INSERT_HEAD(INPCBHASH_CONNECT(inp->inp_table, 1070 inp->inp_faddr, inp->inp_fport, 1071 inp->inp_laddr, inp->inp_lport), &inp->inp_head, 1072 inph_hash); 1073 break; 1074 } 1075 1076 inp->inp_state = state; 1077 } 1078 1079 struct rtentry * 1080 in_pcbrtentry(struct inpcb *inp) 1081 { 1082 struct route *ro; 1083 union { 1084 struct sockaddr dst; 1085 struct sockaddr_in dst4; 1086 } u; 1087 1088 if (inp->inp_af != AF_INET) 1089 return (NULL); 1090 1091 ro = &inp->inp_route; 1092 1093 sockaddr_in_init(&u.dst4, &inp->inp_faddr, 0); 1094 return rtcache_lookup(ro, &u.dst); 1095 } 1096 1097 void 1098 in_pcbrtentry_unref(struct rtentry *rt, struct inpcb *inp) 1099 { 1100 1101 rtcache_unref(rt, &inp->inp_route); 1102 } 1103