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