1 /* $NetBSD: in_pcb.c,v 1.36 1996/12/10 11:38:42 mycroft Exp $ */ 2 3 /* 4 * Copyright (c) 1982, 1986, 1991, 1993 5 * The Regents of the University of California. 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. All advertising materials mentioning features or use of this software 16 * must display the following acknowledgement: 17 * This product includes software developed by the University of 18 * California, Berkeley and its contributors. 19 * 4. Neither the name of the University nor the names of its contributors 20 * may be used to endorse or promote products derived from this software 21 * without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 * 35 * @(#)in_pcb.c 8.2 (Berkeley) 1/4/94 36 */ 37 38 #include <sys/param.h> 39 #include <sys/systm.h> 40 #include <sys/malloc.h> 41 #include <sys/mbuf.h> 42 #include <sys/protosw.h> 43 #include <sys/socket.h> 44 #include <sys/socketvar.h> 45 #include <sys/ioctl.h> 46 #include <sys/errno.h> 47 #include <sys/time.h> 48 #include <sys/proc.h> 49 50 #include <net/if.h> 51 #include <net/route.h> 52 53 #include <netinet/in.h> 54 #include <netinet/in_systm.h> 55 #include <netinet/ip.h> 56 #include <netinet/in_pcb.h> 57 #include <netinet/in_var.h> 58 #include <netinet/ip_var.h> 59 60 struct in_addr zeroin_addr; 61 62 #define INPCBHASH_BIND(table, laddr, lport) \ 63 &(table)->inpt_bindhashtbl[ \ 64 ((ntohl((laddr).s_addr) + ntohs(lport))) & (table)->inpt_bindhash] 65 #define INPCBHASH_CONNECT(table, faddr, fport, laddr, lport) \ 66 &(table)->inpt_connecthashtbl[ \ 67 ((ntohl((faddr).s_addr) + ntohs(fport)) + \ 68 (ntohl((laddr).s_addr) + ntohs(lport))) & (table)->inpt_connecthash] 69 70 struct inpcb * 71 in_pcblookup_port __P((struct inpcbtable *, 72 struct in_addr, u_int, int)); 73 74 void 75 in_pcbinit(table, bindhashsize, connecthashsize) 76 struct inpcbtable *table; 77 int bindhashsize, connecthashsize; 78 { 79 80 CIRCLEQ_INIT(&table->inpt_queue); 81 table->inpt_bindhashtbl = 82 hashinit(bindhashsize, M_PCB, &table->inpt_bindhash); 83 table->inpt_connecthashtbl = 84 hashinit(connecthashsize, M_PCB, &table->inpt_connecthash); 85 table->inpt_lastport = IPPORT_RESERVED; 86 } 87 88 int 89 in_pcballoc(so, v) 90 struct socket *so; 91 void *v; 92 { 93 struct inpcbtable *table = v; 94 register struct inpcb *inp; 95 int s; 96 97 MALLOC(inp, struct inpcb *, sizeof(*inp), M_PCB, M_WAITOK); 98 if (inp == NULL) 99 return (ENOBUFS); 100 bzero((caddr_t)inp, sizeof(*inp)); 101 inp->inp_table = table; 102 inp->inp_socket = so; 103 so->so_pcb = inp; 104 s = splnet(); 105 CIRCLEQ_INSERT_HEAD(&table->inpt_queue, inp, inp_queue); 106 in_pcbstate(inp, INP_ATTACHED); 107 splx(s); 108 return (0); 109 } 110 111 int 112 in_pcbbind(v, nam, p) 113 void *v; 114 struct mbuf *nam; 115 struct proc *p; 116 { 117 register struct inpcb *inp = v; 118 register struct socket *so = inp->inp_socket; 119 register struct inpcbtable *table = inp->inp_table; 120 register struct sockaddr_in *sin; 121 u_int16_t lport = 0; 122 int wild = 0, reuseport = (so->so_options & SO_REUSEPORT); 123 int error; 124 125 if (in_ifaddr.tqh_first == 0) 126 return (EADDRNOTAVAIL); 127 if (inp->inp_lport || !in_nullhost(inp->inp_laddr)) 128 return (EINVAL); 129 if ((so->so_options & (SO_REUSEADDR|SO_REUSEPORT)) == 0 && 130 ((so->so_proto->pr_flags & PR_CONNREQUIRED) == 0 || 131 (so->so_options & SO_ACCEPTCONN) == 0)) 132 wild = INPLOOKUP_WILDCARD; 133 if (nam == 0) 134 goto noname; 135 sin = mtod(nam, struct sockaddr_in *); 136 if (nam->m_len != sizeof (*sin)) 137 return (EINVAL); 138 #ifdef notdef 139 /* 140 * We should check the family, but old programs 141 * incorrectly fail to initialize it. 142 */ 143 if (sin->sin_family != AF_INET) 144 return (EAFNOSUPPORT); 145 #endif 146 lport = sin->sin_port; 147 if (IN_MULTICAST(sin->sin_addr.s_addr)) { 148 /* 149 * Treat SO_REUSEADDR as SO_REUSEPORT for multicast; 150 * allow complete duplication of binding if 151 * SO_REUSEPORT is set, or if SO_REUSEADDR is set 152 * and a multicast address is bound on both 153 * new and duplicated sockets. 154 */ 155 if (so->so_options & SO_REUSEADDR) 156 reuseport = SO_REUSEADDR|SO_REUSEPORT; 157 } else if (!in_nullhost(sin->sin_addr)) { 158 sin->sin_port = 0; /* yech... */ 159 if (ifa_ifwithaddr(sintosa(sin)) == 0) 160 return (EADDRNOTAVAIL); 161 } 162 if (lport) { 163 struct inpcb *t; 164 #ifndef IPNOPRIVPORTS 165 /* GROSS */ 166 if (ntohs(lport) < IPPORT_RESERVED && 167 (p == 0 || (error = suser(p->p_ucred, &p->p_acflag)))) 168 return (EACCES); 169 #endif 170 t = in_pcblookup_port(table, sin->sin_addr, lport, wild); 171 if (t && (reuseport & t->inp_socket->so_options) == 0) 172 return (EADDRINUSE); 173 } 174 inp->inp_laddr = sin->sin_addr; 175 noname: 176 if (lport == 0) { 177 for (lport = table->inpt_lastport + 1; 178 lport < IPPORT_USERRESERVED; lport++) 179 if (!in_pcblookup_port(table, inp->inp_laddr, 180 htons(lport), wild)) 181 goto found; 182 for (lport = IPPORT_RESERVED; 183 lport <= table->inpt_lastport; lport++) 184 if (!in_pcblookup_port(table, inp->inp_laddr, 185 htons(lport), wild)) 186 goto found; 187 return (EAGAIN); 188 found: 189 table->inpt_lastport = lport; 190 lport = htons(lport); 191 } 192 inp->inp_lport = lport; 193 in_pcbstate(inp, INP_BOUND); 194 return (0); 195 } 196 197 /* 198 * Connect from a socket to a specified address. 199 * Both address and port must be specified in argument sin. 200 * If don't have a local address for this socket yet, 201 * then pick one. 202 */ 203 int 204 in_pcbconnect(v, nam) 205 register void *v; 206 struct mbuf *nam; 207 { 208 register struct inpcb *inp = v; 209 struct in_ifaddr *ia; 210 struct sockaddr_in *ifaddr = NULL; 211 register struct sockaddr_in *sin = mtod(nam, struct sockaddr_in *); 212 213 if (nam->m_len != sizeof (*sin)) 214 return (EINVAL); 215 if (sin->sin_family != AF_INET) 216 return (EAFNOSUPPORT); 217 if (sin->sin_port == 0) 218 return (EADDRNOTAVAIL); 219 if (in_ifaddr.tqh_first != 0) { 220 /* 221 * If the destination address is INADDR_ANY, 222 * use the primary local address. 223 * If the supplied address is INADDR_BROADCAST, 224 * and the primary interface supports broadcast, 225 * choose the broadcast address for that interface. 226 */ 227 if (in_nullhost(sin->sin_addr)) 228 sin->sin_addr = in_ifaddr.tqh_first->ia_addr.sin_addr; 229 else if (sin->sin_addr.s_addr == INADDR_BROADCAST && 230 (in_ifaddr.tqh_first->ia_ifp->if_flags & IFF_BROADCAST)) 231 sin->sin_addr = in_ifaddr.tqh_first->ia_broadaddr.sin_addr; 232 } 233 /* 234 * If we haven't bound which network number to use as ours, 235 * we will use the number of the outgoing interface. 236 * This depends on having done a routing lookup, which 237 * we will probably have to do anyway, so we might 238 * as well do it now. On the other hand if we are 239 * sending to multiple destinations we may have already 240 * done the lookup, so see if we can use the route 241 * from before. In any case, we only 242 * chose a port number once, even if sending to multiple 243 * destinations. 244 */ 245 if (in_nullhost(inp->inp_laddr)) { 246 register struct route *ro; 247 248 ia = (struct in_ifaddr *)0; 249 /* 250 * If route is known or can be allocated now, 251 * our src addr is taken from the i/f, else punt. 252 */ 253 ro = &inp->inp_route; 254 if (ro->ro_rt && 255 (!in_hosteq(satosin(&ro->ro_dst)->sin_addr, 256 sin->sin_addr) || 257 inp->inp_socket->so_options & SO_DONTROUTE)) { 258 RTFREE(ro->ro_rt); 259 ro->ro_rt = (struct rtentry *)0; 260 } 261 if ((inp->inp_socket->so_options & SO_DONTROUTE) == 0 && /*XXX*/ 262 (ro->ro_rt == (struct rtentry *)0 || 263 ro->ro_rt->rt_ifp == (struct ifnet *)0)) { 264 /* No route yet, so try to acquire one */ 265 ro->ro_dst.sa_family = AF_INET; 266 ro->ro_dst.sa_len = sizeof(struct sockaddr_in); 267 satosin(&ro->ro_dst)->sin_addr = sin->sin_addr; 268 rtalloc(ro); 269 } 270 /* 271 * If we found a route, use the address 272 * corresponding to the outgoing interface 273 * unless it is the loopback (in case a route 274 * to our address on another net goes to loopback). 275 */ 276 if (ro->ro_rt && !(ro->ro_rt->rt_ifp->if_flags & IFF_LOOPBACK)) 277 ia = ifatoia(ro->ro_rt->rt_ifa); 278 if (ia == 0) { 279 u_int16_t fport = sin->sin_port; 280 281 sin->sin_port = 0; 282 ia = ifatoia(ifa_ifwithladdr(sintosa(sin))); 283 sin->sin_port = fport; 284 if (ia == 0) 285 ia = in_ifaddr.tqh_first; 286 if (ia == 0) 287 return (EADDRNOTAVAIL); 288 } 289 /* 290 * If the destination address is multicast and an outgoing 291 * interface has been set as a multicast option, use the 292 * address of that interface as our source address. 293 */ 294 if (IN_MULTICAST(sin->sin_addr.s_addr) && 295 inp->inp_moptions != NULL) { 296 struct ip_moptions *imo; 297 struct ifnet *ifp; 298 299 imo = inp->inp_moptions; 300 if (imo->imo_multicast_ifp != NULL) { 301 ifp = imo->imo_multicast_ifp; 302 for (ia = in_ifaddr.tqh_first; ia != 0; 303 ia = ia->ia_list.tqe_next) 304 if (ia->ia_ifp == ifp) 305 break; 306 if (ia == 0) 307 return (EADDRNOTAVAIL); 308 } 309 } 310 ifaddr = satosin(&ia->ia_addr); 311 } 312 if (in_pcblookup_connect(inp->inp_table, sin->sin_addr, sin->sin_port, 313 !in_nullhost(inp->inp_laddr) ? inp->inp_laddr : ifaddr->sin_addr, 314 inp->inp_lport) != 0) 315 return (EADDRINUSE); 316 if (in_nullhost(inp->inp_laddr)) { 317 if (inp->inp_lport == 0) 318 (void)in_pcbbind(inp, (struct mbuf *)0, 319 (struct proc *)0); 320 inp->inp_laddr = ifaddr->sin_addr; 321 } 322 inp->inp_faddr = sin->sin_addr; 323 inp->inp_fport = sin->sin_port; 324 in_pcbstate(inp, INP_CONNECTED); 325 return (0); 326 } 327 328 void 329 in_pcbdisconnect(v) 330 void *v; 331 { 332 struct inpcb *inp = v; 333 334 inp->inp_faddr = zeroin_addr; 335 inp->inp_fport = 0; 336 in_pcbstate(inp, INP_BOUND); 337 if (inp->inp_socket->so_state & SS_NOFDREF) 338 in_pcbdetach(inp); 339 } 340 341 void 342 in_pcbdetach(v) 343 void *v; 344 { 345 struct inpcb *inp = v; 346 struct socket *so = inp->inp_socket; 347 int s; 348 349 so->so_pcb = 0; 350 sofree(so); 351 if (inp->inp_options) 352 (void)m_free(inp->inp_options); 353 if (inp->inp_route.ro_rt) 354 rtfree(inp->inp_route.ro_rt); 355 ip_freemoptions(inp->inp_moptions); 356 s = splnet(); 357 in_pcbstate(inp, INP_ATTACHED); 358 CIRCLEQ_REMOVE(&inp->inp_table->inpt_queue, inp, inp_queue); 359 splx(s); 360 FREE(inp, M_PCB); 361 } 362 363 void 364 in_setsockaddr(inp, nam) 365 register struct inpcb *inp; 366 struct mbuf *nam; 367 { 368 register struct sockaddr_in *sin; 369 370 nam->m_len = sizeof (*sin); 371 sin = mtod(nam, struct sockaddr_in *); 372 bzero((caddr_t)sin, sizeof (*sin)); 373 sin->sin_family = AF_INET; 374 sin->sin_len = sizeof(*sin); 375 sin->sin_port = inp->inp_lport; 376 sin->sin_addr = inp->inp_laddr; 377 } 378 379 void 380 in_setpeeraddr(inp, nam) 381 struct inpcb *inp; 382 struct mbuf *nam; 383 { 384 register struct sockaddr_in *sin; 385 386 nam->m_len = sizeof (*sin); 387 sin = mtod(nam, struct sockaddr_in *); 388 bzero((caddr_t)sin, sizeof (*sin)); 389 sin->sin_family = AF_INET; 390 sin->sin_len = sizeof(*sin); 391 sin->sin_port = inp->inp_fport; 392 sin->sin_addr = inp->inp_faddr; 393 } 394 395 /* 396 * Pass some notification to all connections of a protocol 397 * associated with address dst. The local address and/or port numbers 398 * may be specified to limit the search. The "usual action" will be 399 * taken, depending on the ctlinput cmd. The caller must filter any 400 * cmds that are uninteresting (e.g., no error in the map). 401 * Call the protocol specific routine (if any) to report 402 * any errors for each matching socket. 403 * 404 * Must be called at splsoftnet. 405 */ 406 void 407 in_pcbnotify(table, faddr, fport_arg, laddr, lport_arg, errno, notify) 408 struct inpcbtable *table; 409 struct in_addr faddr, laddr; 410 u_int fport_arg, lport_arg; 411 int errno; 412 void (*notify) __P((struct inpcb *, int)); 413 { 414 struct inpcbhead *head; 415 register struct inpcb *inp, *ninp; 416 u_int16_t fport = fport_arg, lport = lport_arg; 417 418 if (in_nullhost(faddr) || notify == 0) 419 return; 420 421 head = INPCBHASH_CONNECT(table, faddr, fport, laddr, lport); 422 for (inp = head->lh_first; inp != NULL; inp = ninp) { 423 ninp = inp->inp_hash.le_next; 424 if (in_hosteq(inp->inp_faddr, faddr) && 425 inp->inp_fport == fport && 426 inp->inp_lport == lport && 427 in_hosteq(inp->inp_laddr, laddr)) 428 (*notify)(inp, errno); 429 } 430 } 431 432 void 433 in_pcbnotifyall(table, faddr, errno, notify) 434 struct inpcbtable *table; 435 struct in_addr faddr; 436 int errno; 437 void (*notify) __P((struct inpcb *, int)); 438 { 439 register struct inpcb *inp, *ninp; 440 441 if (in_nullhost(faddr) || notify == 0) 442 return; 443 444 for (inp = table->inpt_queue.cqh_first; 445 inp != (struct inpcb *)&table->inpt_queue; 446 inp = ninp) { 447 ninp = inp->inp_queue.cqe_next; 448 if (in_hosteq(inp->inp_faddr, faddr)) 449 (*notify)(inp, errno); 450 } 451 } 452 453 /* 454 * Check for alternatives when higher level complains 455 * about service problems. For now, invalidate cached 456 * routing information. If the route was created dynamically 457 * (by a redirect), time to try a default gateway again. 458 */ 459 void 460 in_losing(inp) 461 struct inpcb *inp; 462 { 463 register struct rtentry *rt; 464 struct rt_addrinfo info; 465 466 if ((rt = inp->inp_route.ro_rt)) { 467 inp->inp_route.ro_rt = 0; 468 bzero((caddr_t)&info, sizeof(info)); 469 info.rti_info[RTAX_DST] = &inp->inp_route.ro_dst; 470 info.rti_info[RTAX_GATEWAY] = rt->rt_gateway; 471 info.rti_info[RTAX_NETMASK] = rt_mask(rt); 472 rt_missmsg(RTM_LOSING, &info, rt->rt_flags, 0); 473 if (rt->rt_flags & RTF_DYNAMIC) 474 (void) rtrequest(RTM_DELETE, rt_key(rt), 475 rt->rt_gateway, rt_mask(rt), rt->rt_flags, 476 (struct rtentry **)0); 477 else 478 /* 479 * A new route can be allocated 480 * the next time output is attempted. 481 */ 482 rtfree(rt); 483 } 484 } 485 486 /* 487 * After a routing change, flush old routing 488 * and allocate a (hopefully) better one. 489 */ 490 void 491 in_rtchange(inp, errno) 492 register struct inpcb *inp; 493 int errno; 494 { 495 496 if (inp->inp_route.ro_rt) { 497 rtfree(inp->inp_route.ro_rt); 498 inp->inp_route.ro_rt = 0; 499 /* 500 * A new route can be allocated the next time 501 * output is attempted. 502 */ 503 } 504 /* SHOULD NOTIFY HIGHER-LEVEL PROTOCOLS */ 505 } 506 507 struct inpcb * 508 in_pcblookup_port(table, laddr, lport_arg, flags) 509 struct inpcbtable *table; 510 struct in_addr laddr; 511 u_int lport_arg; 512 int flags; 513 { 514 register struct inpcb *inp, *match = 0; 515 int matchwild = 3, wildcard; 516 u_int16_t lport = lport_arg; 517 518 for (inp = table->inpt_queue.cqh_first; 519 inp != (struct inpcb *)&table->inpt_queue; 520 inp = inp->inp_queue.cqe_next) { 521 if (inp->inp_lport != lport) 522 continue; 523 wildcard = 0; 524 if (!in_nullhost(inp->inp_faddr)) 525 wildcard++; 526 if (in_nullhost(inp->inp_laddr)) { 527 if (!in_nullhost(laddr)) 528 wildcard++; 529 } else { 530 if (in_nullhost(laddr)) 531 wildcard++; 532 else { 533 if (!in_hosteq(inp->inp_laddr, laddr)) 534 continue; 535 } 536 } 537 if (wildcard && (flags & INPLOOKUP_WILDCARD) == 0) 538 continue; 539 if (wildcard < matchwild) { 540 match = inp; 541 matchwild = wildcard; 542 if (matchwild == 0) 543 break; 544 } 545 } 546 return (match); 547 } 548 549 #ifdef DIAGNOSTIC 550 int in_pcbnotifymiss = 0; 551 #endif 552 553 struct inpcb * 554 in_pcblookup_connect(table, faddr, fport_arg, laddr, lport_arg) 555 struct inpcbtable *table; 556 struct in_addr faddr, laddr; 557 u_int fport_arg, lport_arg; 558 { 559 struct inpcbhead *head; 560 register struct inpcb *inp; 561 u_int16_t fport = fport_arg, lport = lport_arg; 562 563 head = INPCBHASH_CONNECT(table, faddr, fport, laddr, lport); 564 for (inp = head->lh_first; inp != NULL; inp = inp->inp_hash.le_next) { 565 if (in_hosteq(inp->inp_faddr, faddr) && 566 inp->inp_fport == fport && 567 inp->inp_lport == lport && 568 in_hosteq(inp->inp_laddr, laddr)) 569 goto out; 570 } 571 #ifdef DIAGNOSTIC 572 if (in_pcbnotifymiss) { 573 printf("in_pcblookup_connect: faddr=%08x fport=%d laddr=%08x lport=%d\n", 574 ntohl(faddr.s_addr), ntohs(fport), 575 ntohl(laddr.s_addr), ntohs(lport)); 576 } 577 #endif 578 return (0); 579 580 out: 581 /* Move this PCB to the head of hash chain. */ 582 if (inp != head->lh_first) { 583 LIST_REMOVE(inp, inp_hash); 584 LIST_INSERT_HEAD(head, inp, inp_hash); 585 } 586 return (inp); 587 } 588 589 struct inpcb * 590 in_pcblookup_bind(table, laddr, lport_arg) 591 struct inpcbtable *table; 592 struct in_addr laddr; 593 u_int lport_arg; 594 { 595 struct inpcbhead *head; 596 register struct inpcb *inp; 597 u_int16_t lport = lport_arg; 598 599 head = INPCBHASH_BIND(table, laddr, lport); 600 for (inp = head->lh_first; inp != NULL; inp = inp->inp_hash.le_next) { 601 if (inp->inp_lport == lport && 602 in_hosteq(inp->inp_laddr, laddr)) 603 goto out; 604 } 605 head = INPCBHASH_BIND(table, zeroin_addr, lport); 606 for (inp = head->lh_first; inp != NULL; inp = inp->inp_hash.le_next) { 607 if (inp->inp_lport == lport && 608 in_hosteq(inp->inp_laddr, zeroin_addr)) 609 goto out; 610 } 611 #ifdef DIAGNOSTIC 612 if (in_pcbnotifymiss) { 613 printf("in_pcblookup_bind: laddr=%08x lport=%d\n", 614 ntohl(laddr.s_addr), ntohs(lport)); 615 } 616 #endif 617 return (0); 618 619 out: 620 /* Move this PCB to the head of hash chain. */ 621 if (inp != head->lh_first) { 622 LIST_REMOVE(inp, inp_hash); 623 LIST_INSERT_HEAD(head, inp, inp_hash); 624 } 625 return (inp); 626 } 627 628 void 629 in_pcbstate(inp, state) 630 struct inpcb *inp; 631 int state; 632 { 633 634 if (inp->inp_state > INP_ATTACHED) 635 LIST_REMOVE(inp, inp_hash); 636 637 switch (state) { 638 case INP_BOUND: 639 LIST_INSERT_HEAD(INPCBHASH_BIND(inp->inp_table, 640 inp->inp_laddr, inp->inp_lport), inp, inp_hash); 641 break; 642 case INP_CONNECTED: 643 LIST_INSERT_HEAD(INPCBHASH_CONNECT(inp->inp_table, 644 inp->inp_faddr, inp->inp_fport, 645 inp->inp_laddr, inp->inp_lport), inp, inp_hash); 646 break; 647 } 648 649 inp->inp_state = state; 650 } 651