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