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