xref: /freebsd/sys/netinet/in_pcb.c (revision 8e6b01171e30297084bb0b4457c4183c2746aacc)
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  *	$Id: in_pcb.c,v 1.12 1995/05/30 08:09:28 rgrimes Exp $
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/ioctl.h>
45 #include <sys/errno.h>
46 #include <sys/time.h>
47 #include <sys/proc.h>
48 #include <sys/queue.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 int
63 in_pcballoc(so, pcbinfo)
64 	struct socket *so;
65 	struct inpcbinfo *pcbinfo;
66 {
67 	register struct inpcb *inp;
68 	int s;
69 
70 	MALLOC(inp, struct inpcb *, sizeof(*inp), M_PCB, M_NOWAIT);
71 	if (inp == NULL)
72 		return (ENOBUFS);
73 	bzero((caddr_t)inp, sizeof(*inp));
74 	inp->inp_pcbinfo = pcbinfo;
75 	inp->inp_socket = so;
76 	s = splnet();
77 	LIST_INSERT_HEAD(pcbinfo->listhead, inp, inp_list);
78 	in_pcbinshash(inp);
79 	splx(s);
80 	so->so_pcb = (caddr_t)inp;
81 	return (0);
82 }
83 
84 int
85 in_pcbbind(inp, nam)
86 	register struct inpcb *inp;
87 	struct mbuf *nam;
88 {
89 	register struct socket *so = inp->inp_socket;
90 	struct inpcbhead *head = inp->inp_pcbinfo->listhead;
91 	unsigned short *lastport = &inp->inp_pcbinfo->lastport;
92 	struct sockaddr_in *sin;
93 	struct proc *p = curproc;		/* XXX */
94 	u_short lport = 0;
95 	int wild = 0, reuseport = (so->so_options & SO_REUSEPORT);
96 	int error;
97 
98 	if (in_ifaddr == 0)
99 		return (EADDRNOTAVAIL);
100 	if (inp->inp_lport || inp->inp_laddr.s_addr != INADDR_ANY)
101 		return (EINVAL);
102 	if ((so->so_options & (SO_REUSEADDR|SO_REUSEPORT)) == 0 &&
103 	    ((so->so_proto->pr_flags & PR_CONNREQUIRED) == 0 ||
104 	     (so->so_options & SO_ACCEPTCONN) == 0))
105 		wild = INPLOOKUP_WILDCARD;
106 	if (nam) {
107 		sin = mtod(nam, struct sockaddr_in *);
108 		if (nam->m_len != sizeof (*sin))
109 			return (EINVAL);
110 #ifdef notdef
111 		/*
112 		 * We should check the family, but old programs
113 		 * incorrectly fail to initialize it.
114 		 */
115 		if (sin->sin_family != AF_INET)
116 			return (EAFNOSUPPORT);
117 #endif
118 		lport = sin->sin_port;
119 		if (IN_MULTICAST(ntohl(sin->sin_addr.s_addr))) {
120 			/*
121 			 * Treat SO_REUSEADDR as SO_REUSEPORT for multicast;
122 			 * allow complete duplication of binding if
123 			 * SO_REUSEPORT is set, or if SO_REUSEADDR is set
124 			 * and a multicast address is bound on both
125 			 * new and duplicated sockets.
126 			 */
127 			if (so->so_options & SO_REUSEADDR)
128 				reuseport = SO_REUSEADDR|SO_REUSEPORT;
129 		} else if (sin->sin_addr.s_addr != INADDR_ANY) {
130 			sin->sin_port = 0;		/* yech... */
131 			if (ifa_ifwithaddr((struct sockaddr *)sin) == 0)
132 				return (EADDRNOTAVAIL);
133 		}
134 		if (lport) {
135 			struct inpcb *t;
136 
137 			/* GROSS */
138 			if (ntohs(lport) < IPPORT_RESERVED &&
139 			    (error = suser(p->p_ucred, &p->p_acflag)))
140 				return (EACCES);
141 			t = in_pcblookup(head, zeroin_addr, 0,
142 			    sin->sin_addr, lport, wild);
143 			if (t && (reuseport & t->inp_socket->so_options) == 0)
144 				return (EADDRINUSE);
145 		}
146 		inp->inp_laddr = sin->sin_addr;
147 	}
148 	if (lport == 0)
149 		do {
150 			++*lastport;
151 			if (*lastport < IPPORT_RESERVED ||
152 			    *lastport > IPPORT_USERRESERVED)
153 				*lastport = IPPORT_RESERVED;
154 			lport = htons(*lastport);
155 		} while (in_pcblookup(head,
156 			    zeroin_addr, 0, inp->inp_laddr, lport, wild));
157 	inp->inp_lport = lport;
158 	in_pcbrehash(inp);
159 	return (0);
160 }
161 
162 /*
163  *   Transform old in_pcbconnect() into an inner subroutine for new
164  *   in_pcbconnect(): Do some validity-checking on the remote
165  *   address (in mbuf 'nam') and then determine local host address
166  *   (i.e., which interface) to use to access that remote host.
167  *
168  *   This preserves definition of in_pcbconnect(), while supporting a
169  *   slightly different version for T/TCP.  (This is more than
170  *   a bit of a kludge, but cleaning up the internal interfaces would
171  *   have forced minor changes in every protocol).
172  */
173 
174 int
175 in_pcbladdr(inp, nam, plocal_sin)
176 	register struct inpcb *inp;
177 	struct mbuf *nam;
178 	struct sockaddr_in **plocal_sin;
179 {
180 	struct in_ifaddr *ia;
181 	struct sockaddr_in *ifaddr = 0;
182 	register struct sockaddr_in *sin = mtod(nam, struct sockaddr_in *);
183 
184 	if (nam->m_len != sizeof (*sin))
185 		return (EINVAL);
186 	if (sin->sin_family != AF_INET)
187 		return (EAFNOSUPPORT);
188 	if (sin->sin_port == 0)
189 		return (EADDRNOTAVAIL);
190 	if (in_ifaddr) {
191 		/*
192 		 * If the destination address is INADDR_ANY,
193 		 * use the primary local address.
194 		 * If the supplied address is INADDR_BROADCAST,
195 		 * and the primary interface supports broadcast,
196 		 * choose the broadcast address for that interface.
197 		 */
198 #define	satosin(sa)	((struct sockaddr_in *)(sa))
199 #define sintosa(sin)	((struct sockaddr *)(sin))
200 #define ifatoia(ifa)	((struct in_ifaddr *)(ifa))
201 		if (sin->sin_addr.s_addr == INADDR_ANY)
202 		    sin->sin_addr = IA_SIN(in_ifaddr)->sin_addr;
203 		else if (sin->sin_addr.s_addr == (u_long)INADDR_BROADCAST &&
204 		  (in_ifaddr->ia_ifp->if_flags & IFF_BROADCAST))
205 		    sin->sin_addr = satosin(&in_ifaddr->ia_broadaddr)->sin_addr;
206 	}
207 	if (inp->inp_laddr.s_addr == INADDR_ANY) {
208 		register struct route *ro;
209 
210 		ia = (struct in_ifaddr *)0;
211 		/*
212 		 * If route is known or can be allocated now,
213 		 * our src addr is taken from the i/f, else punt.
214 		 */
215 		ro = &inp->inp_route;
216 		if (ro->ro_rt &&
217 		    (satosin(&ro->ro_dst)->sin_addr.s_addr !=
218 			sin->sin_addr.s_addr ||
219 		    inp->inp_socket->so_options & SO_DONTROUTE)) {
220 			RTFREE(ro->ro_rt);
221 			ro->ro_rt = (struct rtentry *)0;
222 		}
223 		if ((inp->inp_socket->so_options & SO_DONTROUTE) == 0 && /*XXX*/
224 		    (ro->ro_rt == (struct rtentry *)0 ||
225 		    ro->ro_rt->rt_ifp == (struct ifnet *)0)) {
226 			/* No route yet, so try to acquire one */
227 			ro->ro_dst.sa_family = AF_INET;
228 			ro->ro_dst.sa_len = sizeof(struct sockaddr_in);
229 			((struct sockaddr_in *) &ro->ro_dst)->sin_addr =
230 				sin->sin_addr;
231 			rtalloc(ro);
232 		}
233 		/*
234 		 * If we found a route, use the address
235 		 * corresponding to the outgoing interface
236 		 * unless it is the loopback (in case a route
237 		 * to our address on another net goes to loopback).
238 		 */
239 		if (ro->ro_rt && !(ro->ro_rt->rt_ifp->if_flags & IFF_LOOPBACK))
240 			ia = ifatoia(ro->ro_rt->rt_ifa);
241 		if (ia == 0) {
242 			u_short fport = sin->sin_port;
243 
244 			sin->sin_port = 0;
245 			ia = ifatoia(ifa_ifwithdstaddr(sintosa(sin)));
246 			if (ia == 0)
247 				ia = ifatoia(ifa_ifwithnet(sintosa(sin)));
248 			sin->sin_port = fport;
249 			if (ia == 0)
250 				ia = in_ifaddr;
251 			if (ia == 0)
252 				return (EADDRNOTAVAIL);
253 		}
254 		/*
255 		 * If the destination address is multicast and an outgoing
256 		 * interface has been set as a multicast option, use the
257 		 * address of that interface as our source address.
258 		 */
259 		if (IN_MULTICAST(ntohl(sin->sin_addr.s_addr)) &&
260 		    inp->inp_moptions != NULL) {
261 			struct ip_moptions *imo;
262 			struct ifnet *ifp;
263 
264 			imo = inp->inp_moptions;
265 			if (imo->imo_multicast_ifp != NULL) {
266 				ifp = imo->imo_multicast_ifp;
267 				for (ia = in_ifaddr; ia; ia = ia->ia_next)
268 					if (ia->ia_ifp == ifp)
269 						break;
270 				if (ia == 0)
271 					return (EADDRNOTAVAIL);
272 			}
273 		}
274 	/*
275 	 * Don't do pcblookup call here; return interface in plocal_sin
276 	 * and exit to caller, that will do the lookup.
277 	 */
278 		*plocal_sin = &ia->ia_addr;
279 
280 	}
281 	return(0);
282 }
283 
284 /*
285  * Outer subroutine:
286  * Connect from a socket to a specified address.
287  * Both address and port must be specified in argument sin.
288  * If don't have a local address for this socket yet,
289  * then pick one.
290  */
291 int
292 in_pcbconnect(inp, nam)
293 	register struct inpcb *inp;
294 	struct mbuf *nam;
295 {
296 	struct sockaddr_in *ifaddr;
297 	register struct sockaddr_in *sin = mtod(nam, struct sockaddr_in *);
298 	int error;
299 
300 	/*
301 	 *   Call inner routine, to assign local interface address.
302 	 */
303 	if (error = in_pcbladdr(inp, nam, &ifaddr))
304 		return(error);
305 
306 	if (in_pcblookuphash(inp->inp_pcbinfo, sin->sin_addr, sin->sin_port,
307 	    inp->inp_laddr.s_addr ? inp->inp_laddr : ifaddr->sin_addr,
308 	    inp->inp_lport) != NULL)
309 		return (EADDRINUSE);
310 	if (inp->inp_laddr.s_addr == INADDR_ANY) {
311 		if (inp->inp_lport == 0)
312 			(void)in_pcbbind(inp, (struct mbuf *)0);
313 		inp->inp_laddr = ifaddr->sin_addr;
314 	}
315 	inp->inp_faddr = sin->sin_addr;
316 	inp->inp_fport = sin->sin_port;
317 	in_pcbrehash(inp);
318 	return (0);
319 }
320 
321 void
322 in_pcbdisconnect(inp)
323 	struct inpcb *inp;
324 {
325 
326 	inp->inp_faddr.s_addr = INADDR_ANY;
327 	inp->inp_fport = 0;
328 	in_pcbrehash(inp);
329 	if (inp->inp_socket->so_state & SS_NOFDREF)
330 		in_pcbdetach(inp);
331 }
332 
333 void
334 in_pcbdetach(inp)
335 	struct inpcb *inp;
336 {
337 	struct socket *so = inp->inp_socket;
338 	int s;
339 
340 	so->so_pcb = 0;
341 	sofree(so);
342 	if (inp->inp_options)
343 		(void)m_free(inp->inp_options);
344 	if (inp->inp_route.ro_rt)
345 		rtfree(inp->inp_route.ro_rt);
346 	ip_freemoptions(inp->inp_moptions);
347 	s = splnet();
348 	LIST_REMOVE(inp, inp_hash);
349 	LIST_REMOVE(inp, inp_list);
350 	splx(s);
351 	FREE(inp, M_PCB);
352 }
353 
354 void
355 in_setsockaddr(inp, nam)
356 	register struct inpcb *inp;
357 	struct mbuf *nam;
358 {
359 	register struct sockaddr_in *sin;
360 
361 	nam->m_len = sizeof (*sin);
362 	sin = mtod(nam, struct sockaddr_in *);
363 	bzero((caddr_t)sin, sizeof (*sin));
364 	sin->sin_family = AF_INET;
365 	sin->sin_len = sizeof(*sin);
366 	sin->sin_port = inp->inp_lport;
367 	sin->sin_addr = inp->inp_laddr;
368 }
369 
370 void
371 in_setpeeraddr(inp, nam)
372 	struct inpcb *inp;
373 	struct mbuf *nam;
374 {
375 	register struct sockaddr_in *sin;
376 
377 	nam->m_len = sizeof (*sin);
378 	sin = mtod(nam, struct sockaddr_in *);
379 	bzero((caddr_t)sin, sizeof (*sin));
380 	sin->sin_family = AF_INET;
381 	sin->sin_len = sizeof(*sin);
382 	sin->sin_port = inp->inp_fport;
383 	sin->sin_addr = inp->inp_faddr;
384 }
385 
386 /*
387  * Pass some notification to all connections of a protocol
388  * associated with address dst.  The local address and/or port numbers
389  * may be specified to limit the search.  The "usual action" will be
390  * taken, depending on the ctlinput cmd.  The caller must filter any
391  * cmds that are uninteresting (e.g., no error in the map).
392  * Call the protocol specific routine (if any) to report
393  * any errors for each matching socket.
394  *
395  * Must be called at splnet.
396  */
397 void
398 in_pcbnotify(head, dst, fport_arg, laddr, lport_arg, cmd, notify)
399 	struct inpcbhead *head;
400 	struct sockaddr *dst;
401 	u_int fport_arg, lport_arg;
402 	struct in_addr laddr;
403 	int cmd;
404 	void (*notify) __P((struct inpcb *, int));
405 {
406 	register struct inpcb *inp, *oinp;
407 	struct in_addr faddr;
408 	u_short fport = fport_arg, lport = lport_arg;
409 	int errno, s;
410 
411 	if ((unsigned)cmd > PRC_NCMDS || dst->sa_family != AF_INET)
412 		return;
413 	faddr = ((struct sockaddr_in *)dst)->sin_addr;
414 	if (faddr.s_addr == INADDR_ANY)
415 		return;
416 
417 	/*
418 	 * Redirects go to all references to the destination,
419 	 * and use in_rtchange to invalidate the route cache.
420 	 * Dead host indications: notify all references to the destination.
421 	 * Otherwise, if we have knowledge of the local port and address,
422 	 * deliver only to that socket.
423 	 */
424 	if (PRC_IS_REDIRECT(cmd) || cmd == PRC_HOSTDEAD) {
425 		fport = 0;
426 		lport = 0;
427 		laddr.s_addr = 0;
428 		if (cmd != PRC_HOSTDEAD)
429 			notify = in_rtchange;
430 	}
431 	errno = inetctlerrmap[cmd];
432 	s = splnet();
433 	for (inp = head->lh_first; inp != NULL;) {
434 		if (inp->inp_faddr.s_addr != faddr.s_addr ||
435 		    inp->inp_socket == 0 ||
436 		    (lport && inp->inp_lport != lport) ||
437 		    (laddr.s_addr && inp->inp_laddr.s_addr != laddr.s_addr) ||
438 		    (fport && inp->inp_fport != fport)) {
439 			inp = inp->inp_list.le_next;
440 			continue;
441 		}
442 		oinp = inp;
443 		inp = inp->inp_list.le_next;
444 		if (notify)
445 			(*notify)(oinp, errno);
446 	}
447 	splx(s);
448 }
449 
450 /*
451  * Check for alternatives when higher level complains
452  * about service problems.  For now, invalidate cached
453  * routing information.  If the route was created dynamically
454  * (by a redirect), time to try a default gateway again.
455  */
456 void
457 in_losing(inp)
458 	struct inpcb *inp;
459 {
460 	register struct rtentry *rt;
461 	struct rt_addrinfo info;
462 
463 	if ((rt = inp->inp_route.ro_rt)) {
464 		inp->inp_route.ro_rt = 0;
465 		bzero((caddr_t)&info, sizeof(info));
466 		info.rti_info[RTAX_DST] =
467 			(struct sockaddr *)&inp->inp_route.ro_dst;
468 		info.rti_info[RTAX_GATEWAY] = rt->rt_gateway;
469 		info.rti_info[RTAX_NETMASK] = rt_mask(rt);
470 		rt_missmsg(RTM_LOSING, &info, rt->rt_flags, 0);
471 		if (rt->rt_flags & RTF_DYNAMIC)
472 			(void) rtrequest(RTM_DELETE, rt_key(rt),
473 				rt->rt_gateway, rt_mask(rt), rt->rt_flags,
474 				(struct rtentry **)0);
475 		else
476 		/*
477 		 * A new route can be allocated
478 		 * the next time output is attempted.
479 		 */
480 			rtfree(rt);
481 	}
482 }
483 
484 /*
485  * After a routing change, flush old routing
486  * and allocate a (hopefully) better one.
487  */
488 void
489 in_rtchange(inp, errno)
490 	register struct inpcb *inp;
491 	int errno;
492 {
493 	if (inp->inp_route.ro_rt) {
494 		rtfree(inp->inp_route.ro_rt);
495 		inp->inp_route.ro_rt = 0;
496 		/*
497 		 * A new route can be allocated the next time
498 		 * output is attempted.
499 		 */
500 	}
501 }
502 
503 struct inpcb *
504 in_pcblookup(head, faddr, fport_arg, laddr, lport_arg, flags)
505 	struct inpcbhead *head;
506 	struct in_addr faddr, laddr;
507 	u_int fport_arg, lport_arg;
508 	int flags;
509 {
510 	register struct inpcb *inp, *match = NULL;
511 	int matchwild = 3, wildcard;
512 	u_short fport = fport_arg, lport = lport_arg;
513 	int s;
514 
515 	s = splnet();
516 
517 	for (inp = head->lh_first; inp != NULL; inp = inp->inp_list.le_next) {
518 		if (inp->inp_lport != lport)
519 			continue;
520 		wildcard = 0;
521 		if (inp->inp_faddr.s_addr != INADDR_ANY) {
522 			if (faddr.s_addr == INADDR_ANY)
523 				wildcard++;
524 			else if (inp->inp_faddr.s_addr != faddr.s_addr ||
525 			    inp->inp_fport != fport)
526 				continue;
527 		} else {
528 			if (faddr.s_addr != INADDR_ANY)
529 				wildcard++;
530 		}
531 		if (inp->inp_laddr.s_addr != INADDR_ANY) {
532 			if (laddr.s_addr == INADDR_ANY)
533 				wildcard++;
534 			else if (inp->inp_laddr.s_addr != laddr.s_addr)
535 				continue;
536 		} else {
537 			if (laddr.s_addr != INADDR_ANY)
538 				wildcard++;
539 		}
540 		if (wildcard && (flags & INPLOOKUP_WILDCARD) == 0)
541 			continue;
542 		if (wildcard < matchwild) {
543 			match = inp;
544 			matchwild = wildcard;
545 			if (matchwild == 0) {
546 				break;
547 			}
548 		}
549 	}
550 	splx(s);
551 	return (match);
552 }
553 
554 /*
555  * Lookup PCB in hash list.
556  */
557 struct inpcb *
558 in_pcblookuphash(pcbinfo, faddr, fport_arg, laddr, lport_arg)
559 	struct inpcbinfo *pcbinfo;
560 	struct in_addr faddr, laddr;
561 	u_int fport_arg, lport_arg;
562 {
563 	struct inpcbhead *head;
564 	register struct inpcb *inp;
565 	u_short fport = fport_arg, lport = lport_arg;
566 	int s;
567 
568 	s = splnet();
569 	/*
570 	 * First look for an exact match.
571 	 */
572 	head = &pcbinfo->hashbase[(faddr.s_addr + lport + fport) % pcbinfo->hashsize];
573 
574 	for (inp = head->lh_first; inp != NULL; inp = inp->inp_hash.le_next) {
575 		if (inp->inp_faddr.s_addr != faddr.s_addr ||
576 		    inp->inp_fport != fport ||
577 		    inp->inp_lport != lport ||
578 		    inp->inp_laddr.s_addr != laddr.s_addr)
579 			continue;
580 		/*
581 		 * Move PCB to head of this hash chain so that it can be
582 		 * found more quickly in the future.
583 		 */
584 		if (inp != head->lh_first) {
585 			LIST_REMOVE(inp, inp_hash);
586 			LIST_INSERT_HEAD(head, inp, inp_hash);
587 		}
588 		break;
589 	}
590 	splx(s);
591 	return (inp);
592 }
593 
594 /*
595  * Insert PCB into hash chain. Must be called at splnet.
596  */
597 void
598 in_pcbinshash(inp)
599 	struct inpcb *inp;
600 {
601 	struct inpcbhead *head;
602 
603 	head = &inp->inp_pcbinfo->hashbase[(inp->inp_faddr.s_addr +
604 		inp->inp_lport + inp->inp_fport) % inp->inp_pcbinfo->hashsize];
605 
606 	LIST_INSERT_HEAD(head, inp, inp_hash);
607 }
608 
609 void
610 in_pcbrehash(inp)
611 	struct inpcb *inp;
612 {
613 	struct inpcbhead *head;
614 	int s;
615 
616 	s = splnet();
617 	LIST_REMOVE(inp, inp_hash);
618 
619 	head = &inp->inp_pcbinfo->hashbase[(inp->inp_faddr.s_addr +
620 		inp->inp_lport + inp->inp_fport) % inp->inp_pcbinfo->hashsize];
621 
622 	LIST_INSERT_HEAD(head, inp, inp_hash);
623 	splx(s);
624 }
625