1 /* 2 * Copyright (c) 1982, 1986, 1991, 1993, 1995 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by the University of 16 * California, Berkeley and its contributors. 17 * 4. Neither the name of the University nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * 33 * @(#)in_pcb.c 8.4 (Berkeley) 5/24/95 34 * $FreeBSD$ 35 */ 36 37 #include <sys/param.h> 38 #include <sys/systm.h> 39 #include <sys/malloc.h> 40 #include <sys/mbuf.h> 41 #include <sys/protosw.h> 42 #include <sys/socket.h> 43 #include <sys/socketvar.h> 44 #include <sys/proc.h> 45 #include <sys/jail.h> 46 #include <sys/kernel.h> 47 #include <sys/sysctl.h> 48 49 #include <machine/limits.h> 50 51 #include <vm/vm_zone.h> 52 53 #include <net/if.h> 54 #include <net/route.h> 55 56 #include <netinet/in.h> 57 #include <netinet/in_pcb.h> 58 #include <netinet/in_var.h> 59 #include <netinet/ip_var.h> 60 61 struct in_addr zeroin_addr; 62 63 static void in_rtchange __P((struct inpcb *, int)); 64 65 /* 66 * These configure the range of local port addresses assigned to 67 * "unspecified" outgoing connections/packets/whatever. 68 */ 69 static int ipport_lowfirstauto = IPPORT_RESERVED - 1; /* 1023 */ 70 static int ipport_lowlastauto = IPPORT_RESERVEDSTART; /* 600 */ 71 static int ipport_firstauto = IPPORT_RESERVED; /* 1024 */ 72 static int ipport_lastauto = IPPORT_USERRESERVED; /* 5000 */ 73 static int ipport_hifirstauto = IPPORT_HIFIRSTAUTO; /* 49152 */ 74 static int ipport_hilastauto = IPPORT_HILASTAUTO; /* 65535 */ 75 76 #define RANGECHK(var, min, max) \ 77 if ((var) < (min)) { (var) = (min); } \ 78 else if ((var) > (max)) { (var) = (max); } 79 80 static int 81 sysctl_net_ipport_check SYSCTL_HANDLER_ARGS 82 { 83 int error = sysctl_handle_int(oidp, 84 oidp->oid_arg1, oidp->oid_arg2, req); 85 if (!error) { 86 RANGECHK(ipport_lowfirstauto, 1, IPPORT_RESERVED - 1); 87 RANGECHK(ipport_lowlastauto, 1, IPPORT_RESERVED - 1); 88 RANGECHK(ipport_firstauto, IPPORT_RESERVED, USHRT_MAX); 89 RANGECHK(ipport_lastauto, IPPORT_RESERVED, USHRT_MAX); 90 RANGECHK(ipport_hifirstauto, IPPORT_RESERVED, USHRT_MAX); 91 RANGECHK(ipport_hilastauto, IPPORT_RESERVED, USHRT_MAX); 92 } 93 return error; 94 } 95 96 #undef RANGECHK 97 98 SYSCTL_NODE(_net_inet_ip, IPPROTO_IP, portrange, CTLFLAG_RW, 0, "IP Ports"); 99 100 SYSCTL_PROC(_net_inet_ip_portrange, OID_AUTO, lowfirst, CTLTYPE_INT|CTLFLAG_RW, 101 &ipport_lowfirstauto, 0, &sysctl_net_ipport_check, "I", ""); 102 SYSCTL_PROC(_net_inet_ip_portrange, OID_AUTO, lowlast, CTLTYPE_INT|CTLFLAG_RW, 103 &ipport_lowlastauto, 0, &sysctl_net_ipport_check, "I", ""); 104 SYSCTL_PROC(_net_inet_ip_portrange, OID_AUTO, first, CTLTYPE_INT|CTLFLAG_RW, 105 &ipport_firstauto, 0, &sysctl_net_ipport_check, "I", ""); 106 SYSCTL_PROC(_net_inet_ip_portrange, OID_AUTO, last, CTLTYPE_INT|CTLFLAG_RW, 107 &ipport_lastauto, 0, &sysctl_net_ipport_check, "I", ""); 108 SYSCTL_PROC(_net_inet_ip_portrange, OID_AUTO, hifirst, CTLTYPE_INT|CTLFLAG_RW, 109 &ipport_hifirstauto, 0, &sysctl_net_ipport_check, "I", ""); 110 SYSCTL_PROC(_net_inet_ip_portrange, OID_AUTO, hilast, CTLTYPE_INT|CTLFLAG_RW, 111 &ipport_hilastauto, 0, &sysctl_net_ipport_check, "I", ""); 112 113 /* 114 * in_pcb.c: manage the Protocol Control Blocks. 115 * 116 * NOTE: It is assumed that most of these functions will be called at 117 * splnet(). XXX - There are, unfortunately, a few exceptions to this 118 * rule that should be fixed. 119 */ 120 121 /* 122 * Allocate a PCB and associate it with the socket. 123 */ 124 int 125 in_pcballoc(so, pcbinfo, p) 126 struct socket *so; 127 struct inpcbinfo *pcbinfo; 128 struct proc *p; 129 { 130 register struct inpcb *inp; 131 132 inp = zalloci(pcbinfo->ipi_zone); 133 if (inp == NULL) 134 return (ENOBUFS); 135 bzero((caddr_t)inp, sizeof(*inp)); 136 inp->inp_gencnt = ++pcbinfo->ipi_gencnt; 137 inp->inp_pcbinfo = pcbinfo; 138 inp->inp_socket = so; 139 LIST_INSERT_HEAD(pcbinfo->listhead, inp, inp_list); 140 pcbinfo->ipi_count++; 141 so->so_pcb = (caddr_t)inp; 142 return (0); 143 } 144 145 int 146 in_pcbbind(inp, nam, p) 147 register struct inpcb *inp; 148 struct sockaddr *nam; 149 struct proc *p; 150 { 151 register struct socket *so = inp->inp_socket; 152 unsigned short *lastport; 153 struct sockaddr_in *sin; 154 struct inpcbinfo *pcbinfo = inp->inp_pcbinfo; 155 u_short lport = 0; 156 int wild = 0, reuseport = (so->so_options & SO_REUSEPORT); 157 int error, prison = 0; 158 159 if (TAILQ_EMPTY(&in_ifaddrhead)) /* XXX broken! */ 160 return (EADDRNOTAVAIL); 161 if (inp->inp_lport || inp->inp_laddr.s_addr != INADDR_ANY) 162 return (EINVAL); 163 if ((so->so_options & (SO_REUSEADDR|SO_REUSEPORT)) == 0) 164 wild = 1; 165 if (nam) { 166 sin = (struct sockaddr_in *)nam; 167 if (nam->sa_len != sizeof (*sin)) 168 return (EINVAL); 169 #ifdef notdef 170 /* 171 * We should check the family, but old programs 172 * incorrectly fail to initialize it. 173 */ 174 if (sin->sin_family != AF_INET) 175 return (EAFNOSUPPORT); 176 #endif 177 if (prison_ip(p, 0, &sin->sin_addr.s_addr)) 178 return(EINVAL); 179 lport = sin->sin_port; 180 if (IN_MULTICAST(ntohl(sin->sin_addr.s_addr))) { 181 /* 182 * Treat SO_REUSEADDR as SO_REUSEPORT for multicast; 183 * allow complete duplication of binding if 184 * SO_REUSEPORT is set, or if SO_REUSEADDR is set 185 * and a multicast address is bound on both 186 * new and duplicated sockets. 187 */ 188 if (so->so_options & SO_REUSEADDR) 189 reuseport = SO_REUSEADDR|SO_REUSEPORT; 190 } else if (sin->sin_addr.s_addr != INADDR_ANY) { 191 sin->sin_port = 0; /* yech... */ 192 if (ifa_ifwithaddr((struct sockaddr *)sin) == 0) 193 return (EADDRNOTAVAIL); 194 } 195 if (lport) { 196 struct inpcb *t; 197 198 /* GROSS */ 199 if (ntohs(lport) < IPPORT_RESERVED && p && 200 suser_xxx(0, p, PRISON_ROOT)) 201 return (EACCES); 202 if (p && p->p_prison) 203 prison = 1; 204 if (so->so_cred->cr_uid != 0 && 205 !IN_MULTICAST(ntohl(sin->sin_addr.s_addr))) { 206 t = in_pcblookup_local(inp->inp_pcbinfo, 207 sin->sin_addr, lport, 208 prison ? 0 : INPLOOKUP_WILDCARD); 209 if (t && 210 (ntohl(sin->sin_addr.s_addr) != INADDR_ANY || 211 ntohl(t->inp_laddr.s_addr) != INADDR_ANY || 212 (t->inp_socket->so_options & 213 SO_REUSEPORT) == 0) && 214 (so->so_cred->cr_uid != 215 t->inp_socket->so_cred->cr_uid)) 216 return (EADDRINUSE); 217 } 218 t = in_pcblookup_local(pcbinfo, sin->sin_addr, 219 lport, prison ? 0 : wild); 220 if (t && (reuseport & t->inp_socket->so_options) == 0) 221 return (EADDRINUSE); 222 } 223 inp->inp_laddr = sin->sin_addr; 224 } 225 if (lport == 0) { 226 ushort first, last; 227 int count; 228 229 if (prison_ip(p, 0, &inp->inp_laddr.s_addr )) 230 return (EINVAL); 231 inp->inp_flags |= INP_ANONPORT; 232 233 if (inp->inp_flags & INP_HIGHPORT) { 234 first = ipport_hifirstauto; /* sysctl */ 235 last = ipport_hilastauto; 236 lastport = &pcbinfo->lasthi; 237 } else if (inp->inp_flags & INP_LOWPORT) { 238 if (p && (error = suser_xxx(0, p, PRISON_ROOT))) 239 return error; 240 first = ipport_lowfirstauto; /* 1023 */ 241 last = ipport_lowlastauto; /* 600 */ 242 lastport = &pcbinfo->lastlow; 243 } else { 244 first = ipport_firstauto; /* sysctl */ 245 last = ipport_lastauto; 246 lastport = &pcbinfo->lastport; 247 } 248 /* 249 * Simple check to ensure all ports are not used up causing 250 * a deadlock here. 251 * 252 * We split the two cases (up and down) so that the direction 253 * is not being tested on each round of the loop. 254 */ 255 if (first > last) { 256 /* 257 * counting down 258 */ 259 count = first - last; 260 261 do { 262 if (count-- < 0) { /* completely used? */ 263 /* 264 * Undo any address bind that may have 265 * occurred above. 266 */ 267 inp->inp_laddr.s_addr = INADDR_ANY; 268 return (EAGAIN); 269 } 270 --*lastport; 271 if (*lastport > first || *lastport < last) 272 *lastport = first; 273 lport = htons(*lastport); 274 } while (in_pcblookup_local(pcbinfo, 275 inp->inp_laddr, lport, wild)); 276 } else { 277 /* 278 * counting up 279 */ 280 count = last - first; 281 282 do { 283 if (count-- < 0) { /* completely used? */ 284 /* 285 * Undo any address bind that may have 286 * occurred above. 287 */ 288 inp->inp_laddr.s_addr = INADDR_ANY; 289 return (EAGAIN); 290 } 291 ++*lastport; 292 if (*lastport < first || *lastport > last) 293 *lastport = first; 294 lport = htons(*lastport); 295 } while (in_pcblookup_local(pcbinfo, 296 inp->inp_laddr, lport, wild)); 297 } 298 } 299 inp->inp_lport = lport; 300 if (in_pcbinshash(inp) != 0) { 301 inp->inp_laddr.s_addr = INADDR_ANY; 302 inp->inp_lport = 0; 303 return (EAGAIN); 304 } 305 return (0); 306 } 307 308 /* 309 * Transform old in_pcbconnect() into an inner subroutine for new 310 * in_pcbconnect(): Do some validity-checking on the remote 311 * address (in mbuf 'nam') and then determine local host address 312 * (i.e., which interface) to use to access that remote host. 313 * 314 * This preserves definition of in_pcbconnect(), while supporting a 315 * slightly different version for T/TCP. (This is more than 316 * a bit of a kludge, but cleaning up the internal interfaces would 317 * have forced minor changes in every protocol). 318 */ 319 320 int 321 in_pcbladdr(inp, nam, plocal_sin) 322 register struct inpcb *inp; 323 struct sockaddr *nam; 324 struct sockaddr_in **plocal_sin; 325 { 326 struct in_ifaddr *ia; 327 register struct sockaddr_in *sin = (struct sockaddr_in *)nam; 328 329 if (nam->sa_len != sizeof (*sin)) 330 return (EINVAL); 331 if (sin->sin_family != AF_INET) 332 return (EAFNOSUPPORT); 333 if (sin->sin_port == 0) 334 return (EADDRNOTAVAIL); 335 if (!TAILQ_EMPTY(&in_ifaddrhead)) { 336 /* 337 * If the destination address is INADDR_ANY, 338 * use the primary local address. 339 * If the supplied address is INADDR_BROADCAST, 340 * and the primary interface supports broadcast, 341 * choose the broadcast address for that interface. 342 */ 343 #define satosin(sa) ((struct sockaddr_in *)(sa)) 344 #define sintosa(sin) ((struct sockaddr *)(sin)) 345 #define ifatoia(ifa) ((struct in_ifaddr *)(ifa)) 346 if (sin->sin_addr.s_addr == INADDR_ANY) 347 sin->sin_addr = IA_SIN(in_ifaddrhead.tqh_first)->sin_addr; 348 else if (sin->sin_addr.s_addr == (u_long)INADDR_BROADCAST && 349 (in_ifaddrhead.tqh_first->ia_ifp->if_flags & IFF_BROADCAST)) 350 sin->sin_addr = satosin(&in_ifaddrhead.tqh_first->ia_broadaddr)->sin_addr; 351 } 352 if (inp->inp_laddr.s_addr == INADDR_ANY) { 353 register struct route *ro; 354 355 ia = (struct in_ifaddr *)0; 356 /* 357 * If route is known or can be allocated now, 358 * our src addr is taken from the i/f, else punt. 359 */ 360 ro = &inp->inp_route; 361 if (ro->ro_rt && 362 (satosin(&ro->ro_dst)->sin_addr.s_addr != 363 sin->sin_addr.s_addr || 364 inp->inp_socket->so_options & SO_DONTROUTE)) { 365 RTFREE(ro->ro_rt); 366 ro->ro_rt = (struct rtentry *)0; 367 } 368 if ((inp->inp_socket->so_options & SO_DONTROUTE) == 0 && /*XXX*/ 369 (ro->ro_rt == (struct rtentry *)0 || 370 ro->ro_rt->rt_ifp == (struct ifnet *)0)) { 371 /* No route yet, so try to acquire one */ 372 ro->ro_dst.sa_family = AF_INET; 373 ro->ro_dst.sa_len = sizeof(struct sockaddr_in); 374 ((struct sockaddr_in *) &ro->ro_dst)->sin_addr = 375 sin->sin_addr; 376 rtalloc(ro); 377 } 378 /* 379 * If we found a route, use the address 380 * corresponding to the outgoing interface 381 * unless it is the loopback (in case a route 382 * to our address on another net goes to loopback). 383 */ 384 if (ro->ro_rt && !(ro->ro_rt->rt_ifp->if_flags & IFF_LOOPBACK)) 385 ia = ifatoia(ro->ro_rt->rt_ifa); 386 if (ia == 0) { 387 u_short fport = sin->sin_port; 388 389 sin->sin_port = 0; 390 ia = ifatoia(ifa_ifwithdstaddr(sintosa(sin))); 391 if (ia == 0) 392 ia = ifatoia(ifa_ifwithnet(sintosa(sin))); 393 sin->sin_port = fport; 394 if (ia == 0) 395 ia = in_ifaddrhead.tqh_first; 396 if (ia == 0) 397 return (EADDRNOTAVAIL); 398 } 399 /* 400 * If the destination address is multicast and an outgoing 401 * interface has been set as a multicast option, use the 402 * address of that interface as our source address. 403 */ 404 if (IN_MULTICAST(ntohl(sin->sin_addr.s_addr)) && 405 inp->inp_moptions != NULL) { 406 struct ip_moptions *imo; 407 struct ifnet *ifp; 408 409 imo = inp->inp_moptions; 410 if (imo->imo_multicast_ifp != NULL) { 411 ifp = imo->imo_multicast_ifp; 412 for (ia = in_ifaddrhead.tqh_first; ia; 413 ia = ia->ia_link.tqe_next) 414 if (ia->ia_ifp == ifp) 415 break; 416 if (ia == 0) 417 return (EADDRNOTAVAIL); 418 } 419 } 420 /* 421 * Don't do pcblookup call here; return interface in plocal_sin 422 * and exit to caller, that will do the lookup. 423 */ 424 *plocal_sin = &ia->ia_addr; 425 426 } 427 return(0); 428 } 429 430 /* 431 * Outer subroutine: 432 * Connect from a socket to a specified address. 433 * Both address and port must be specified in argument sin. 434 * If don't have a local address for this socket yet, 435 * then pick one. 436 */ 437 int 438 in_pcbconnect(inp, nam, p) 439 register struct inpcb *inp; 440 struct sockaddr *nam; 441 struct proc *p; 442 { 443 struct sockaddr_in *ifaddr; 444 register struct sockaddr_in *sin = (struct sockaddr_in *)nam; 445 int error; 446 447 /* 448 * Call inner routine, to assign local interface address. 449 */ 450 if ((error = in_pcbladdr(inp, nam, &ifaddr)) != 0) 451 return(error); 452 453 if (in_pcblookup_hash(inp->inp_pcbinfo, sin->sin_addr, sin->sin_port, 454 inp->inp_laddr.s_addr ? inp->inp_laddr : ifaddr->sin_addr, 455 inp->inp_lport, 0) != NULL) { 456 return (EADDRINUSE); 457 } 458 if (inp->inp_laddr.s_addr == INADDR_ANY) { 459 if (inp->inp_lport == 0) { 460 error = in_pcbbind(inp, (struct sockaddr *)0, p); 461 if (error) 462 return (error); 463 } 464 inp->inp_laddr = ifaddr->sin_addr; 465 } 466 inp->inp_faddr = sin->sin_addr; 467 inp->inp_fport = sin->sin_port; 468 in_pcbrehash(inp); 469 return (0); 470 } 471 472 void 473 in_pcbdisconnect(inp) 474 struct inpcb *inp; 475 { 476 477 inp->inp_faddr.s_addr = INADDR_ANY; 478 inp->inp_fport = 0; 479 in_pcbrehash(inp); 480 if (inp->inp_socket->so_state & SS_NOFDREF) 481 in_pcbdetach(inp); 482 } 483 484 void 485 in_pcbdetach(inp) 486 struct inpcb *inp; 487 { 488 struct socket *so = inp->inp_socket; 489 struct inpcbinfo *ipi = inp->inp_pcbinfo; 490 491 inp->inp_gencnt = ++ipi->ipi_gencnt; 492 in_pcbremlists(inp); 493 so->so_pcb = 0; 494 sofree(so); 495 if (inp->inp_options) 496 (void)m_free(inp->inp_options); 497 if (inp->inp_route.ro_rt) 498 rtfree(inp->inp_route.ro_rt); 499 ip_freemoptions(inp->inp_moptions); 500 zfreei(ipi->ipi_zone, inp); 501 } 502 503 /* 504 * The calling convention of in_setsockaddr() and in_setpeeraddr() was 505 * modified to match the pru_sockaddr() and pru_peeraddr() entry points 506 * in struct pr_usrreqs, so that protocols can just reference then directly 507 * without the need for a wrapper function. The socket must have a valid 508 * (i.e., non-nil) PCB, but it should be impossible to get an invalid one 509 * except through a kernel programming error, so it is acceptable to panic 510 * (or in this case trap) if the PCB is invalid. (Actually, we don't trap 511 * because there actually /is/ a programming error somewhere... XXX) 512 */ 513 int 514 in_setsockaddr(so, nam) 515 struct socket *so; 516 struct sockaddr **nam; 517 { 518 int s; 519 register struct inpcb *inp; 520 register struct sockaddr_in *sin; 521 522 /* 523 * Do the malloc first in case it blocks. 524 */ 525 MALLOC(sin, struct sockaddr_in *, sizeof *sin, M_SONAME, M_WAITOK); 526 bzero(sin, sizeof *sin); 527 sin->sin_family = AF_INET; 528 sin->sin_len = sizeof(*sin); 529 530 s = splnet(); 531 inp = sotoinpcb(so); 532 if (!inp) { 533 splx(s); 534 free(sin, M_SONAME); 535 return EINVAL; 536 } 537 sin->sin_port = inp->inp_lport; 538 sin->sin_addr = inp->inp_laddr; 539 splx(s); 540 541 *nam = (struct sockaddr *)sin; 542 return 0; 543 } 544 545 int 546 in_setpeeraddr(so, nam) 547 struct socket *so; 548 struct sockaddr **nam; 549 { 550 int s; 551 struct inpcb *inp; 552 register struct sockaddr_in *sin; 553 554 /* 555 * Do the malloc first in case it blocks. 556 */ 557 MALLOC(sin, struct sockaddr_in *, sizeof *sin, M_SONAME, M_WAITOK); 558 bzero((caddr_t)sin, sizeof (*sin)); 559 sin->sin_family = AF_INET; 560 sin->sin_len = sizeof(*sin); 561 562 s = splnet(); 563 inp = sotoinpcb(so); 564 if (!inp) { 565 splx(s); 566 free(sin, M_SONAME); 567 return EINVAL; 568 } 569 sin->sin_port = inp->inp_fport; 570 sin->sin_addr = inp->inp_faddr; 571 splx(s); 572 573 *nam = (struct sockaddr *)sin; 574 return 0; 575 } 576 577 /* 578 * Pass some notification to all connections of a protocol 579 * associated with address dst. The local address and/or port numbers 580 * may be specified to limit the search. The "usual action" will be 581 * taken, depending on the ctlinput cmd. The caller must filter any 582 * cmds that are uninteresting (e.g., no error in the map). 583 * Call the protocol specific routine (if any) to report 584 * any errors for each matching socket. 585 */ 586 void 587 in_pcbnotify(head, dst, fport_arg, laddr, lport_arg, cmd, notify) 588 struct inpcbhead *head; 589 struct sockaddr *dst; 590 u_int fport_arg, lport_arg; 591 struct in_addr laddr; 592 int cmd; 593 void (*notify) __P((struct inpcb *, int)); 594 { 595 register struct inpcb *inp, *oinp; 596 struct in_addr faddr; 597 u_short fport = fport_arg, lport = lport_arg; 598 int errno, s; 599 600 if ((unsigned)cmd > PRC_NCMDS || dst->sa_family != AF_INET) 601 return; 602 faddr = ((struct sockaddr_in *)dst)->sin_addr; 603 if (faddr.s_addr == INADDR_ANY) 604 return; 605 606 /* 607 * Redirects go to all references to the destination, 608 * and use in_rtchange to invalidate the route cache. 609 * Dead host indications: notify all references to the destination. 610 * Otherwise, if we have knowledge of the local port and address, 611 * deliver only to that socket. 612 */ 613 if (PRC_IS_REDIRECT(cmd) || cmd == PRC_HOSTDEAD) { 614 fport = 0; 615 lport = 0; 616 laddr.s_addr = 0; 617 if (cmd != PRC_HOSTDEAD) 618 notify = in_rtchange; 619 } 620 errno = inetctlerrmap[cmd]; 621 s = splnet(); 622 for (inp = head->lh_first; inp != NULL;) { 623 if (inp->inp_faddr.s_addr != faddr.s_addr || 624 inp->inp_socket == 0 || 625 (lport && inp->inp_lport != lport) || 626 (laddr.s_addr && inp->inp_laddr.s_addr != laddr.s_addr) || 627 (fport && inp->inp_fport != fport)) { 628 inp = inp->inp_list.le_next; 629 continue; 630 } 631 oinp = inp; 632 inp = inp->inp_list.le_next; 633 if (notify) 634 (*notify)(oinp, errno); 635 } 636 splx(s); 637 } 638 639 /* 640 * Check for alternatives when higher level complains 641 * about service problems. For now, invalidate cached 642 * routing information. If the route was created dynamically 643 * (by a redirect), time to try a default gateway again. 644 */ 645 void 646 in_losing(inp) 647 struct inpcb *inp; 648 { 649 register struct rtentry *rt; 650 struct rt_addrinfo info; 651 652 if ((rt = inp->inp_route.ro_rt)) { 653 inp->inp_route.ro_rt = 0; 654 bzero((caddr_t)&info, sizeof(info)); 655 info.rti_info[RTAX_DST] = 656 (struct sockaddr *)&inp->inp_route.ro_dst; 657 info.rti_info[RTAX_GATEWAY] = rt->rt_gateway; 658 info.rti_info[RTAX_NETMASK] = rt_mask(rt); 659 rt_missmsg(RTM_LOSING, &info, rt->rt_flags, 0); 660 if (rt->rt_flags & RTF_DYNAMIC) 661 (void) rtrequest(RTM_DELETE, rt_key(rt), 662 rt->rt_gateway, rt_mask(rt), rt->rt_flags, 663 (struct rtentry **)0); 664 else 665 /* 666 * A new route can be allocated 667 * the next time output is attempted. 668 */ 669 rtfree(rt); 670 } 671 } 672 673 /* 674 * After a routing change, flush old routing 675 * and allocate a (hopefully) better one. 676 */ 677 static void 678 in_rtchange(inp, errno) 679 register struct inpcb *inp; 680 int errno; 681 { 682 if (inp->inp_route.ro_rt) { 683 rtfree(inp->inp_route.ro_rt); 684 inp->inp_route.ro_rt = 0; 685 /* 686 * A new route can be allocated the next time 687 * output is attempted. 688 */ 689 } 690 } 691 692 /* 693 * Lookup a PCB based on the local address and port. 694 */ 695 struct inpcb * 696 in_pcblookup_local(pcbinfo, laddr, lport_arg, wild_okay) 697 struct inpcbinfo *pcbinfo; 698 struct in_addr laddr; 699 u_int lport_arg; 700 int wild_okay; 701 { 702 register struct inpcb *inp; 703 int matchwild = 3, wildcard; 704 u_short lport = lport_arg; 705 706 if (!wild_okay) { 707 struct inpcbhead *head; 708 /* 709 * Look for an unconnected (wildcard foreign addr) PCB that 710 * matches the local address and port we're looking for. 711 */ 712 head = &pcbinfo->hashbase[INP_PCBHASH(INADDR_ANY, lport, 0, pcbinfo->hashmask)]; 713 for (inp = head->lh_first; inp != NULL; inp = inp->inp_hash.le_next) { 714 if (inp->inp_faddr.s_addr == INADDR_ANY && 715 inp->inp_laddr.s_addr == laddr.s_addr && 716 inp->inp_lport == lport) { 717 /* 718 * Found. 719 */ 720 return (inp); 721 } 722 } 723 /* 724 * Not found. 725 */ 726 return (NULL); 727 } else { 728 struct inpcbporthead *porthash; 729 struct inpcbport *phd; 730 struct inpcb *match = NULL; 731 /* 732 * Best fit PCB lookup. 733 * 734 * First see if this local port is in use by looking on the 735 * port hash list. 736 */ 737 porthash = &pcbinfo->porthashbase[INP_PCBPORTHASH(lport, 738 pcbinfo->porthashmask)]; 739 for (phd = porthash->lh_first; phd != NULL; phd = phd->phd_hash.le_next) { 740 if (phd->phd_port == lport) 741 break; 742 } 743 if (phd != NULL) { 744 /* 745 * Port is in use by one or more PCBs. Look for best 746 * fit. 747 */ 748 for (inp = phd->phd_pcblist.lh_first; inp != NULL; 749 inp = inp->inp_portlist.le_next) { 750 wildcard = 0; 751 if (inp->inp_faddr.s_addr != INADDR_ANY) 752 wildcard++; 753 if (inp->inp_laddr.s_addr != INADDR_ANY) { 754 if (laddr.s_addr == INADDR_ANY) 755 wildcard++; 756 else if (inp->inp_laddr.s_addr != laddr.s_addr) 757 continue; 758 } else { 759 if (laddr.s_addr != INADDR_ANY) 760 wildcard++; 761 } 762 if (wildcard < matchwild) { 763 match = inp; 764 matchwild = wildcard; 765 if (matchwild == 0) { 766 break; 767 } 768 } 769 } 770 } 771 return (match); 772 } 773 } 774 775 /* 776 * Lookup PCB in hash list. 777 */ 778 struct inpcb * 779 in_pcblookup_hash(pcbinfo, faddr, fport_arg, laddr, lport_arg, wildcard) 780 struct inpcbinfo *pcbinfo; 781 struct in_addr faddr, laddr; 782 u_int fport_arg, lport_arg; 783 int wildcard; 784 { 785 struct inpcbhead *head; 786 register struct inpcb *inp; 787 u_short fport = fport_arg, lport = lport_arg; 788 789 /* 790 * First look for an exact match. 791 */ 792 head = &pcbinfo->hashbase[INP_PCBHASH(faddr.s_addr, lport, fport, pcbinfo->hashmask)]; 793 for (inp = head->lh_first; inp != NULL; inp = inp->inp_hash.le_next) { 794 if (inp->inp_faddr.s_addr == faddr.s_addr && 795 inp->inp_laddr.s_addr == laddr.s_addr && 796 inp->inp_fport == fport && 797 inp->inp_lport == lport) { 798 /* 799 * Found. 800 */ 801 return (inp); 802 } 803 } 804 if (wildcard) { 805 struct inpcb *local_wild = NULL; 806 807 head = &pcbinfo->hashbase[INP_PCBHASH(INADDR_ANY, lport, 0, pcbinfo->hashmask)]; 808 for (inp = head->lh_first; inp != NULL; inp = inp->inp_hash.le_next) { 809 if (inp->inp_faddr.s_addr == INADDR_ANY && 810 inp->inp_lport == lport) { 811 if (inp->inp_laddr.s_addr == laddr.s_addr) 812 return (inp); 813 else if (inp->inp_laddr.s_addr == INADDR_ANY) 814 local_wild = inp; 815 } 816 } 817 return (local_wild); 818 } 819 820 /* 821 * Not found. 822 */ 823 return (NULL); 824 } 825 826 /* 827 * Insert PCB onto various hash lists. 828 */ 829 int 830 in_pcbinshash(inp) 831 struct inpcb *inp; 832 { 833 struct inpcbhead *pcbhash; 834 struct inpcbporthead *pcbporthash; 835 struct inpcbinfo *pcbinfo = inp->inp_pcbinfo; 836 struct inpcbport *phd; 837 838 pcbhash = &pcbinfo->hashbase[INP_PCBHASH(inp->inp_faddr.s_addr, 839 inp->inp_lport, inp->inp_fport, pcbinfo->hashmask)]; 840 841 pcbporthash = &pcbinfo->porthashbase[INP_PCBPORTHASH(inp->inp_lport, 842 pcbinfo->porthashmask)]; 843 844 /* 845 * Go through port list and look for a head for this lport. 846 */ 847 for (phd = pcbporthash->lh_first; phd != NULL; phd = phd->phd_hash.le_next) { 848 if (phd->phd_port == inp->inp_lport) 849 break; 850 } 851 /* 852 * If none exists, malloc one and tack it on. 853 */ 854 if (phd == NULL) { 855 MALLOC(phd, struct inpcbport *, sizeof(struct inpcbport), M_PCB, M_NOWAIT); 856 if (phd == NULL) { 857 return (ENOBUFS); /* XXX */ 858 } 859 phd->phd_port = inp->inp_lport; 860 LIST_INIT(&phd->phd_pcblist); 861 LIST_INSERT_HEAD(pcbporthash, phd, phd_hash); 862 } 863 inp->inp_phd = phd; 864 LIST_INSERT_HEAD(&phd->phd_pcblist, inp, inp_portlist); 865 LIST_INSERT_HEAD(pcbhash, inp, inp_hash); 866 return (0); 867 } 868 869 /* 870 * Move PCB to the proper hash bucket when { faddr, fport } have been 871 * changed. NOTE: This does not handle the case of the lport changing (the 872 * hashed port list would have to be updated as well), so the lport must 873 * not change after in_pcbinshash() has been called. 874 */ 875 void 876 in_pcbrehash(inp) 877 struct inpcb *inp; 878 { 879 struct inpcbhead *head; 880 881 head = &inp->inp_pcbinfo->hashbase[INP_PCBHASH(inp->inp_faddr.s_addr, 882 inp->inp_lport, inp->inp_fport, inp->inp_pcbinfo->hashmask)]; 883 884 LIST_REMOVE(inp, inp_hash); 885 LIST_INSERT_HEAD(head, inp, inp_hash); 886 } 887 888 /* 889 * Remove PCB from various lists. 890 */ 891 void 892 in_pcbremlists(inp) 893 struct inpcb *inp; 894 { 895 inp->inp_gencnt = ++inp->inp_pcbinfo->ipi_gencnt; 896 if (inp->inp_lport) { 897 struct inpcbport *phd = inp->inp_phd; 898 899 LIST_REMOVE(inp, inp_hash); 900 LIST_REMOVE(inp, inp_portlist); 901 if (phd->phd_pcblist.lh_first == NULL) { 902 LIST_REMOVE(phd, phd_hash); 903 free(phd, M_PCB); 904 } 905 } 906 LIST_REMOVE(inp, inp_list); 907 inp->inp_pcbinfo->ipi_count--; 908 } 909 910 int 911 prison_xinpcb(struct proc *p, struct inpcb *inp) 912 { 913 if (!p->p_prison) 914 return (0); 915 if (ntohl(inp->inp_laddr.s_addr) == p->p_prison->pr_ip) 916 return (0); 917 return (1); 918 } 919