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