1 /* $NetBSD: in_pcb.c,v 1.172 2016/12/12 03:55:57 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.172 2016/12/12 03:55:57 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_DUPLICATED) 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 rtcache_unref(rt, &inp->inp_route); 782 in_rtchange(inp, 0); 783 } else 784 rtcache_unref(rt, &inp->inp_route); 785 } 786 } 787 788 /* 789 * Check for alternatives when higher level complains 790 * about service problems. For now, invalidate cached 791 * routing information. If the route was created dynamically 792 * (by a redirect), time to try a default gateway again. 793 */ 794 void 795 in_losing(struct inpcb *inp) 796 { 797 struct rtentry *rt; 798 struct rt_addrinfo info; 799 800 if (inp->inp_af != AF_INET) 801 return; 802 803 if ((rt = rtcache_validate(&inp->inp_route)) == NULL) 804 return; 805 806 memset(&info, 0, sizeof(info)); 807 info.rti_info[RTAX_DST] = rtcache_getdst(&inp->inp_route); 808 info.rti_info[RTAX_GATEWAY] = rt->rt_gateway; 809 info.rti_info[RTAX_NETMASK] = rt_mask(rt); 810 rt_missmsg(RTM_LOSING, &info, rt->rt_flags, 0); 811 if (rt->rt_flags & RTF_DYNAMIC) { 812 int error; 813 struct rtentry *nrt; 814 815 error = rtrequest(RTM_DELETE, rt_getkey(rt), 816 rt->rt_gateway, rt_mask(rt), rt->rt_flags, &nrt); 817 rtcache_unref(rt, &inp->inp_route); 818 if (error == 0) 819 rt_free(nrt); 820 } else 821 rtcache_unref(rt, &inp->inp_route); 822 /* 823 * A new route can be allocated 824 * the next time output is attempted. 825 */ 826 rtcache_free(&inp->inp_route); 827 } 828 829 /* 830 * After a routing change, flush old routing. A new route can be 831 * allocated the next time output is attempted. 832 */ 833 void 834 in_rtchange(struct inpcb *inp, int errno) 835 { 836 837 if (inp->inp_af != AF_INET) 838 return; 839 840 rtcache_free(&inp->inp_route); 841 842 /* XXX SHOULD NOTIFY HIGHER-LEVEL PROTOCOLS */ 843 } 844 845 struct inpcb * 846 in_pcblookup_port(struct inpcbtable *table, struct in_addr laddr, 847 u_int lport_arg, int lookup_wildcard, vestigial_inpcb_t *vp) 848 { 849 struct inpcbhead *head; 850 struct inpcb_hdr *inph; 851 struct inpcb *match = NULL; 852 int matchwild = 3; 853 int wildcard; 854 u_int16_t lport = lport_arg; 855 856 if (vp) 857 vp->valid = 0; 858 859 head = INPCBHASH_PORT(table, lport); 860 LIST_FOREACH(inph, head, inph_lhash) { 861 struct inpcb * const inp = (struct inpcb *)inph; 862 863 if (inp->inp_af != AF_INET) 864 continue; 865 if (inp->inp_lport != lport) 866 continue; 867 /* 868 * check if inp's faddr and laddr match with ours. 869 * our faddr is considered null. 870 * count the number of wildcard matches. (0 - 2) 871 * 872 * null null match 873 * A null wildcard match 874 * null B wildcard match 875 * A B non match 876 * A A match 877 */ 878 wildcard = 0; 879 if (!in_nullhost(inp->inp_faddr)) 880 wildcard++; 881 if (in_nullhost(inp->inp_laddr)) { 882 if (!in_nullhost(laddr)) 883 wildcard++; 884 } else { 885 if (in_nullhost(laddr)) 886 wildcard++; 887 else { 888 if (!in_hosteq(inp->inp_laddr, laddr)) 889 continue; 890 } 891 } 892 if (wildcard && !lookup_wildcard) 893 continue; 894 /* 895 * prefer an address with less wildcards. 896 */ 897 if (wildcard < matchwild) { 898 match = inp; 899 matchwild = wildcard; 900 if (matchwild == 0) 901 break; 902 } 903 } 904 if (match && matchwild == 0) 905 return match; 906 907 if (vp && table->vestige) { 908 void *state = (*table->vestige->init_ports4)(laddr, lport_arg, lookup_wildcard); 909 vestigial_inpcb_t better; 910 911 while (table->vestige 912 && (*table->vestige->next_port4)(state, vp)) { 913 914 if (vp->lport != lport) 915 continue; 916 wildcard = 0; 917 if (!in_nullhost(vp->faddr.v4)) 918 wildcard++; 919 if (in_nullhost(vp->laddr.v4)) { 920 if (!in_nullhost(laddr)) 921 wildcard++; 922 } else { 923 if (in_nullhost(laddr)) 924 wildcard++; 925 else { 926 if (!in_hosteq(vp->laddr.v4, laddr)) 927 continue; 928 } 929 } 930 if (wildcard && !lookup_wildcard) 931 continue; 932 if (wildcard < matchwild) { 933 better = *vp; 934 match = (void*)&better; 935 936 matchwild = wildcard; 937 if (matchwild == 0) 938 break; 939 } 940 } 941 942 if (match) { 943 if (match != (void*)&better) 944 return match; 945 else { 946 *vp = better; 947 return 0; 948 } 949 } 950 } 951 952 return (match); 953 } 954 955 #ifdef DIAGNOSTIC 956 int in_pcbnotifymiss = 0; 957 #endif 958 959 struct inpcb * 960 in_pcblookup_connect(struct inpcbtable *table, 961 struct in_addr faddr, u_int fport_arg, 962 struct in_addr laddr, u_int lport_arg, 963 vestigial_inpcb_t *vp) 964 { 965 struct inpcbhead *head; 966 struct inpcb_hdr *inph; 967 struct inpcb *inp; 968 u_int16_t fport = fport_arg, lport = lport_arg; 969 970 if (vp) 971 vp->valid = 0; 972 973 head = INPCBHASH_CONNECT(table, faddr, fport, laddr, lport); 974 LIST_FOREACH(inph, head, inph_hash) { 975 inp = (struct inpcb *)inph; 976 if (inp->inp_af != AF_INET) 977 continue; 978 979 if (in_hosteq(inp->inp_faddr, faddr) && 980 inp->inp_fport == fport && 981 inp->inp_lport == lport && 982 in_hosteq(inp->inp_laddr, laddr)) 983 goto out; 984 } 985 if (vp && table->vestige) { 986 if ((*table->vestige->lookup4)(faddr, fport_arg, 987 laddr, lport_arg, vp)) 988 return 0; 989 } 990 991 #ifdef DIAGNOSTIC 992 if (in_pcbnotifymiss) { 993 printf("in_pcblookup_connect: faddr=%08x fport=%d laddr=%08x lport=%d\n", 994 ntohl(faddr.s_addr), ntohs(fport), 995 ntohl(laddr.s_addr), ntohs(lport)); 996 } 997 #endif 998 return (0); 999 1000 out: 1001 /* Move this PCB to the head of hash chain. */ 1002 inph = &inp->inp_head; 1003 if (inph != LIST_FIRST(head)) { 1004 LIST_REMOVE(inph, inph_hash); 1005 LIST_INSERT_HEAD(head, inph, inph_hash); 1006 } 1007 return (inp); 1008 } 1009 1010 struct inpcb * 1011 in_pcblookup_bind(struct inpcbtable *table, 1012 struct in_addr laddr, u_int lport_arg) 1013 { 1014 struct inpcbhead *head; 1015 struct inpcb_hdr *inph; 1016 struct inpcb *inp; 1017 u_int16_t lport = lport_arg; 1018 1019 head = INPCBHASH_BIND(table, laddr, 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, laddr)) 1027 goto out; 1028 } 1029 head = INPCBHASH_BIND(table, zeroin_addr, lport); 1030 LIST_FOREACH(inph, head, inph_hash) { 1031 inp = (struct inpcb *)inph; 1032 if (inp->inp_af != AF_INET) 1033 continue; 1034 1035 if (inp->inp_lport == lport && 1036 in_hosteq(inp->inp_laddr, zeroin_addr)) 1037 goto out; 1038 } 1039 #ifdef DIAGNOSTIC 1040 if (in_pcbnotifymiss) { 1041 printf("in_pcblookup_bind: laddr=%08x lport=%d\n", 1042 ntohl(laddr.s_addr), ntohs(lport)); 1043 } 1044 #endif 1045 return (0); 1046 1047 out: 1048 /* Move this PCB to the head of hash chain. */ 1049 inph = &inp->inp_head; 1050 if (inph != LIST_FIRST(head)) { 1051 LIST_REMOVE(inph, inph_hash); 1052 LIST_INSERT_HEAD(head, inph, inph_hash); 1053 } 1054 return (inp); 1055 } 1056 1057 void 1058 in_pcbstate(struct inpcb *inp, int state) 1059 { 1060 1061 if (inp->inp_af != AF_INET) 1062 return; 1063 1064 if (inp->inp_state > INP_ATTACHED) 1065 LIST_REMOVE(&inp->inp_head, inph_hash); 1066 1067 switch (state) { 1068 case INP_BOUND: 1069 LIST_INSERT_HEAD(INPCBHASH_BIND(inp->inp_table, 1070 inp->inp_laddr, inp->inp_lport), &inp->inp_head, 1071 inph_hash); 1072 break; 1073 case INP_CONNECTED: 1074 LIST_INSERT_HEAD(INPCBHASH_CONNECT(inp->inp_table, 1075 inp->inp_faddr, inp->inp_fport, 1076 inp->inp_laddr, inp->inp_lport), &inp->inp_head, 1077 inph_hash); 1078 break; 1079 } 1080 1081 inp->inp_state = state; 1082 } 1083 1084 struct rtentry * 1085 in_pcbrtentry(struct inpcb *inp) 1086 { 1087 struct route *ro; 1088 union { 1089 struct sockaddr dst; 1090 struct sockaddr_in dst4; 1091 } u; 1092 1093 if (inp->inp_af != AF_INET) 1094 return (NULL); 1095 1096 ro = &inp->inp_route; 1097 1098 sockaddr_in_init(&u.dst4, &inp->inp_faddr, 0); 1099 return rtcache_lookup(ro, &u.dst); 1100 } 1101 1102 void 1103 in_pcbrtentry_unref(struct rtentry *rt, struct inpcb *inp) 1104 { 1105 1106 rtcache_unref(rt, &inp->inp_route); 1107 } 1108