source: rtems-libbsd/freebsd/sys/netinet/in_pcb.c @ 11b7f58

4.1155-freebsd-126-freebsd-12freebsd-9.3
Last change on this file since 11b7f58 was 11b7f58, checked in by Sebastian Huber <sebastian.huber@…>, on 10/24/13 at 12:46:25

Fix errno conflict

Newlib defines errno as

#define errno (*errno())

In case this is expanded in a function parameter, e.g.

void f(int errno) { ... }

then we have a function pointer parameter instead of the integer scalar.

  • Property mode set to 100644
File size: 49.9 KB
Line 
1#include <machine/rtems-bsd-config.h>
2
3/*-
4 * Copyright (c) 1982, 1986, 1991, 1993, 1995
5 *      The Regents of the University of California.
6 * Copyright (c) 2007-2009 Robert N. M. Watson
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 *    notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 *    notice, this list of conditions and the following disclaimer in the
16 *    documentation and/or other materials provided with the distribution.
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 */
35
36#ifdef __rtems__
37#include <errno.h>
38#undef errno
39#endif /* __rtems__ */
40#include <sys/cdefs.h>
41__FBSDID("$FreeBSD$");
42
43#include <rtems/bsd/local/opt_ddb.h>
44#include <rtems/bsd/local/opt_ipsec.h>
45#include <rtems/bsd/local/opt_inet6.h>
46
47#include <rtems/bsd/sys/param.h>
48#include <sys/systm.h>
49#include <sys/malloc.h>
50#include <sys/mbuf.h>
51#include <sys/domain.h>
52#include <sys/protosw.h>
53#include <sys/socket.h>
54#include <sys/socketvar.h>
55#include <sys/priv.h>
56#include <sys/proc.h>
57#include <sys/jail.h>
58#include <sys/kernel.h>
59#include <sys/sysctl.h>
60
61#ifdef DDB
62#include <ddb/ddb.h>
63#endif
64
65#include <vm/uma.h>
66
67#include <net/if.h>
68#include <net/if_types.h>
69#include <net/route.h>
70#include <net/vnet.h>
71
72#include <netinet/in.h>
73#include <netinet/in_pcb.h>
74#include <netinet/in_var.h>
75#include <netinet/ip_var.h>
76#include <netinet/tcp_var.h>
77#include <netinet/udp.h>
78#include <netinet/udp_var.h>
79#ifdef INET6
80#include <netinet/ip6.h>
81#include <netinet6/ip6_var.h>
82#endif /* INET6 */
83
84
85#ifdef IPSEC
86#include <netipsec/ipsec.h>
87#include <netipsec/key.h>
88#endif /* IPSEC */
89
90#include <security/mac/mac_framework.h>
91
92/*
93 * These configure the range of local port addresses assigned to
94 * "unspecified" outgoing connections/packets/whatever.
95 */
96VNET_DEFINE(int, ipport_lowfirstauto) = IPPORT_RESERVED - 1;    /* 1023 */
97VNET_DEFINE(int, ipport_lowlastauto) = IPPORT_RESERVEDSTART;    /* 600 */
98VNET_DEFINE(int, ipport_firstauto) = IPPORT_EPHEMERALFIRST;     /* 10000 */
99VNET_DEFINE(int, ipport_lastauto) = IPPORT_EPHEMERALLAST;       /* 65535 */
100VNET_DEFINE(int, ipport_hifirstauto) = IPPORT_HIFIRSTAUTO;      /* 49152 */
101VNET_DEFINE(int, ipport_hilastauto) = IPPORT_HILASTAUTO;        /* 65535 */
102
103/*
104 * Reserved ports accessible only to root. There are significant
105 * security considerations that must be accounted for when changing these,
106 * but the security benefits can be great. Please be careful.
107 */
108VNET_DEFINE(int, ipport_reservedhigh) = IPPORT_RESERVED - 1;    /* 1023 */
109VNET_DEFINE(int, ipport_reservedlow);
110
111/* Variables dealing with random ephemeral port allocation. */
112VNET_DEFINE(int, ipport_randomized) = 1;        /* user controlled via sysctl */
113VNET_DEFINE(int, ipport_randomcps) = 10;        /* user controlled via sysctl */
114VNET_DEFINE(int, ipport_randomtime) = 45;       /* user controlled via sysctl */
115VNET_DEFINE(int, ipport_stoprandom);            /* toggled by ipport_tick */
116VNET_DEFINE(int, ipport_tcpallocs);
117static VNET_DEFINE(int, ipport_tcplastcount);
118
119#define V_ipport_tcplastcount           VNET(ipport_tcplastcount)
120
121#define RANGECHK(var, min, max) \
122        if ((var) < (min)) { (var) = (min); } \
123        else if ((var) > (max)) { (var) = (max); }
124
125static void     in_pcbremlists(struct inpcb *inp);
126
127static int
128sysctl_net_ipport_check(SYSCTL_HANDLER_ARGS)
129{
130        int error;
131
132#ifdef VIMAGE
133        error = vnet_sysctl_handle_int(oidp, arg1, arg2, req);
134#else
135        error = sysctl_handle_int(oidp, arg1, arg2, req);
136#endif
137        if (error == 0) {
138                RANGECHK(V_ipport_lowfirstauto, 1, IPPORT_RESERVED - 1);
139                RANGECHK(V_ipport_lowlastauto, 1, IPPORT_RESERVED - 1);
140                RANGECHK(V_ipport_firstauto, IPPORT_RESERVED, IPPORT_MAX);
141                RANGECHK(V_ipport_lastauto, IPPORT_RESERVED, IPPORT_MAX);
142                RANGECHK(V_ipport_hifirstauto, IPPORT_RESERVED, IPPORT_MAX);
143                RANGECHK(V_ipport_hilastauto, IPPORT_RESERVED, IPPORT_MAX);
144        }
145        return (error);
146}
147
148#undef RANGECHK
149
150SYSCTL_NODE(_net_inet_ip, IPPROTO_IP, portrange, CTLFLAG_RW, 0, "IP Ports");
151
152SYSCTL_VNET_PROC(_net_inet_ip_portrange, OID_AUTO, lowfirst,
153        CTLTYPE_INT|CTLFLAG_RW, &VNET_NAME(ipport_lowfirstauto), 0,
154        &sysctl_net_ipport_check, "I", "");
155SYSCTL_VNET_PROC(_net_inet_ip_portrange, OID_AUTO, lowlast,
156        CTLTYPE_INT|CTLFLAG_RW, &VNET_NAME(ipport_lowlastauto), 0,
157        &sysctl_net_ipport_check, "I", "");
158SYSCTL_VNET_PROC(_net_inet_ip_portrange, OID_AUTO, first,
159        CTLTYPE_INT|CTLFLAG_RW, &VNET_NAME(ipport_firstauto), 0,
160        &sysctl_net_ipport_check, "I", "");
161SYSCTL_VNET_PROC(_net_inet_ip_portrange, OID_AUTO, last,
162        CTLTYPE_INT|CTLFLAG_RW, &VNET_NAME(ipport_lastauto), 0,
163        &sysctl_net_ipport_check, "I", "");
164SYSCTL_VNET_PROC(_net_inet_ip_portrange, OID_AUTO, hifirst,
165        CTLTYPE_INT|CTLFLAG_RW, &VNET_NAME(ipport_hifirstauto), 0,
166        &sysctl_net_ipport_check, "I", "");
167SYSCTL_VNET_PROC(_net_inet_ip_portrange, OID_AUTO, hilast,
168        CTLTYPE_INT|CTLFLAG_RW, &VNET_NAME(ipport_hilastauto), 0,
169        &sysctl_net_ipport_check, "I", "");
170SYSCTL_VNET_INT(_net_inet_ip_portrange, OID_AUTO, reservedhigh,
171        CTLFLAG_RW|CTLFLAG_SECURE, &VNET_NAME(ipport_reservedhigh), 0, "");
172SYSCTL_VNET_INT(_net_inet_ip_portrange, OID_AUTO, reservedlow,
173        CTLFLAG_RW|CTLFLAG_SECURE, &VNET_NAME(ipport_reservedlow), 0, "");
174SYSCTL_VNET_INT(_net_inet_ip_portrange, OID_AUTO, randomized, CTLFLAG_RW,
175        &VNET_NAME(ipport_randomized), 0, "Enable random port allocation");
176SYSCTL_VNET_INT(_net_inet_ip_portrange, OID_AUTO, randomcps, CTLFLAG_RW,
177        &VNET_NAME(ipport_randomcps), 0, "Maximum number of random port "
178        "allocations before switching to a sequental one");
179SYSCTL_VNET_INT(_net_inet_ip_portrange, OID_AUTO, randomtime, CTLFLAG_RW,
180        &VNET_NAME(ipport_randomtime), 0,
181        "Minimum time to keep sequental port "
182        "allocation before switching to a random one");
183
184/*
185 * in_pcb.c: manage the Protocol Control Blocks.
186 *
187 * NOTE: It is assumed that most of these functions will be called with
188 * the pcbinfo lock held, and often, the inpcb lock held, as these utility
189 * functions often modify hash chains or addresses in pcbs.
190 */
191
192/*
193 * Allocate a PCB and associate it with the socket.
194 * On success return with the PCB locked.
195 */
196int
197in_pcballoc(struct socket *so, struct inpcbinfo *pcbinfo)
198{
199        struct inpcb *inp;
200        int error;
201
202        INP_INFO_WLOCK_ASSERT(pcbinfo);
203        error = 0;
204        inp = uma_zalloc(pcbinfo->ipi_zone, M_NOWAIT);
205        if (inp == NULL)
206                return (ENOBUFS);
207        bzero(inp, inp_zero_size);
208        inp->inp_pcbinfo = pcbinfo;
209        inp->inp_socket = so;
210        inp->inp_cred = crhold(so->so_cred);
211        inp->inp_inc.inc_fibnum = so->so_fibnum;
212#ifdef MAC
213        error = mac_inpcb_init(inp, M_NOWAIT);
214        if (error != 0)
215                goto out;
216        mac_inpcb_create(so, inp);
217#endif
218#ifdef IPSEC
219        error = ipsec_init_policy(so, &inp->inp_sp);
220        if (error != 0) {
221#ifdef MAC
222                mac_inpcb_destroy(inp);
223#endif
224                goto out;
225        }
226#endif /*IPSEC*/
227#ifdef INET6
228        if (INP_SOCKAF(so) == AF_INET6) {
229                inp->inp_vflag |= INP_IPV6PROTO;
230                if (V_ip6_v6only)
231                        inp->inp_flags |= IN6P_IPV6_V6ONLY;
232        }
233#endif
234        LIST_INSERT_HEAD(pcbinfo->ipi_listhead, inp, inp_list);
235        pcbinfo->ipi_count++;
236        so->so_pcb = (caddr_t)inp;
237#ifdef INET6
238        if (V_ip6_auto_flowlabel)
239                inp->inp_flags |= IN6P_AUTOFLOWLABEL;
240#endif
241        INP_WLOCK(inp);
242        inp->inp_gencnt = ++pcbinfo->ipi_gencnt;
243        inp->inp_refcount = 1;  /* Reference from the inpcbinfo */
244#if defined(IPSEC) || defined(MAC)
245out:
246        if (error != 0) {
247                crfree(inp->inp_cred);
248                uma_zfree(pcbinfo->ipi_zone, inp);
249        }
250#endif
251        return (error);
252}
253
254int
255in_pcbbind(struct inpcb *inp, struct sockaddr *nam, struct ucred *cred)
256{
257        int anonport, error;
258
259        INP_INFO_WLOCK_ASSERT(inp->inp_pcbinfo);
260        INP_WLOCK_ASSERT(inp);
261
262        if (inp->inp_lport != 0 || inp->inp_laddr.s_addr != INADDR_ANY)
263                return (EINVAL);
264        anonport = inp->inp_lport == 0 && (nam == NULL ||
265            ((struct sockaddr_in *)nam)->sin_port == 0);
266        error = in_pcbbind_setup(inp, nam, &inp->inp_laddr.s_addr,
267            &inp->inp_lport, cred);
268        if (error)
269                return (error);
270        if (in_pcbinshash(inp) != 0) {
271                inp->inp_laddr.s_addr = INADDR_ANY;
272                inp->inp_lport = 0;
273                return (EAGAIN);
274        }
275        if (anonport)
276                inp->inp_flags |= INP_ANONPORT;
277        return (0);
278}
279
280/*
281 * Set up a bind operation on a PCB, performing port allocation
282 * as required, but do not actually modify the PCB. Callers can
283 * either complete the bind by setting inp_laddr/inp_lport and
284 * calling in_pcbinshash(), or they can just use the resulting
285 * port and address to authorise the sending of a once-off packet.
286 *
287 * On error, the values of *laddrp and *lportp are not changed.
288 */
289int
290in_pcbbind_setup(struct inpcb *inp, struct sockaddr *nam, in_addr_t *laddrp,
291    u_short *lportp, struct ucred *cred)
292{
293        struct socket *so = inp->inp_socket;
294        unsigned short *lastport;
295        struct sockaddr_in *sin;
296        struct inpcbinfo *pcbinfo = inp->inp_pcbinfo;
297        struct in_addr laddr;
298        u_short lport = 0;
299        int wild = 0, reuseport = (so->so_options & SO_REUSEPORT);
300        int error;
301        int dorandom;
302
303        /*
304         * Because no actual state changes occur here, a global write lock on
305         * the pcbinfo isn't required.
306         */
307        INP_INFO_LOCK_ASSERT(pcbinfo);
308        INP_LOCK_ASSERT(inp);
309
310        if (TAILQ_EMPTY(&V_in_ifaddrhead)) /* XXX broken! */
311                return (EADDRNOTAVAIL);
312        laddr.s_addr = *laddrp;
313        if (nam != NULL && laddr.s_addr != INADDR_ANY)
314                return (EINVAL);
315        if ((so->so_options & (SO_REUSEADDR|SO_REUSEPORT)) == 0)
316                wild = INPLOOKUP_WILDCARD;
317        if (nam == NULL) {
318                if ((error = prison_local_ip4(cred, &laddr)) != 0)
319                        return (error);
320        } else {
321                sin = (struct sockaddr_in *)nam;
322                if (nam->sa_len != sizeof (*sin))
323                        return (EINVAL);
324#ifdef notdef
325                /*
326                 * We should check the family, but old programs
327                 * incorrectly fail to initialize it.
328                 */
329                if (sin->sin_family != AF_INET)
330                        return (EAFNOSUPPORT);
331#endif
332                error = prison_local_ip4(cred, &sin->sin_addr);
333                if (error)
334                        return (error);
335                if (sin->sin_port != *lportp) {
336                        /* Don't allow the port to change. */
337                        if (*lportp != 0)
338                                return (EINVAL);
339                        lport = sin->sin_port;
340                }
341                /* NB: lport is left as 0 if the port isn't being changed. */
342                if (IN_MULTICAST(ntohl(sin->sin_addr.s_addr))) {
343                        /*
344                         * Treat SO_REUSEADDR as SO_REUSEPORT for multicast;
345                         * allow complete duplication of binding if
346                         * SO_REUSEPORT is set, or if SO_REUSEADDR is set
347                         * and a multicast address is bound on both
348                         * new and duplicated sockets.
349                         */
350                        if (so->so_options & SO_REUSEADDR)
351                                reuseport = SO_REUSEADDR|SO_REUSEPORT;
352                } else if (sin->sin_addr.s_addr != INADDR_ANY) {
353                        sin->sin_port = 0;              /* yech... */
354                        bzero(&sin->sin_zero, sizeof(sin->sin_zero));
355                        /*
356                         * Is the address a local IP address?
357                         * If INP_BINDANY is set, then the socket may be bound
358                         * to any endpoint address, local or not.
359                         */
360                        if ((inp->inp_flags & INP_BINDANY) == 0 &&
361                            ifa_ifwithaddr_check((struct sockaddr *)sin) == 0)
362                                return (EADDRNOTAVAIL);
363                }
364                laddr = sin->sin_addr;
365                if (lport) {
366                        struct inpcb *t;
367                        struct tcptw *tw;
368
369                        /* GROSS */
370                        if (ntohs(lport) <= V_ipport_reservedhigh &&
371                            ntohs(lport) >= V_ipport_reservedlow &&
372                            priv_check_cred(cred, PRIV_NETINET_RESERVEDPORT,
373                            0))
374                                return (EACCES);
375                        if (!IN_MULTICAST(ntohl(sin->sin_addr.s_addr)) &&
376                            priv_check_cred(inp->inp_cred,
377                            PRIV_NETINET_REUSEPORT, 0) != 0) {
378                                t = in_pcblookup_local(pcbinfo, sin->sin_addr,
379                                    lport, INPLOOKUP_WILDCARD, cred);
380        /*
381         * XXX
382         * This entire block sorely needs a rewrite.
383         */
384                                if (t &&
385                                    ((t->inp_flags & INP_TIMEWAIT) == 0) &&
386                                    (so->so_type != SOCK_STREAM ||
387                                     ntohl(t->inp_faddr.s_addr) == INADDR_ANY) &&
388                                    (ntohl(sin->sin_addr.s_addr) != INADDR_ANY ||
389                                     ntohl(t->inp_laddr.s_addr) != INADDR_ANY ||
390                                     (t->inp_socket->so_options &
391                                         SO_REUSEPORT) == 0) &&
392#ifndef __rtems__
393                                    (inp->inp_cred->cr_uid !=
394                                     t->inp_cred->cr_uid))
395#else /* __rtems__ */
396                                    0)
397#endif /* __rtems__ */
398                                        return (EADDRINUSE);
399                        }
400                        t = in_pcblookup_local(pcbinfo, sin->sin_addr,
401                            lport, wild, cred);
402                        if (t && (t->inp_flags & INP_TIMEWAIT)) {
403                                /*
404                                 * XXXRW: If an incpb has had its timewait
405                                 * state recycled, we treat the address as
406                                 * being in use (for now).  This is better
407                                 * than a panic, but not desirable.
408                                 */
409                                tw = intotw(inp);
410                                if (tw == NULL ||
411                                    (reuseport & tw->tw_so_options) == 0)
412                                        return (EADDRINUSE);
413                        } else if (t &&
414                            (reuseport & t->inp_socket->so_options) == 0) {
415#ifdef INET6
416                                if (ntohl(sin->sin_addr.s_addr) !=
417                                    INADDR_ANY ||
418                                    ntohl(t->inp_laddr.s_addr) !=
419                                    INADDR_ANY ||
420                                    INP_SOCKAF(so) ==
421                                    INP_SOCKAF(t->inp_socket))
422#endif
423                                return (EADDRINUSE);
424                        }
425                }
426        }
427        if (*lportp != 0)
428                lport = *lportp;
429        if (lport == 0) {
430                u_short first, last, aux;
431                int count;
432
433                if (inp->inp_flags & INP_HIGHPORT) {
434                        first = V_ipport_hifirstauto;   /* sysctl */
435                        last  = V_ipport_hilastauto;
436                        lastport = &pcbinfo->ipi_lasthi;
437                } else if (inp->inp_flags & INP_LOWPORT) {
438                        error = priv_check_cred(cred,
439                            PRIV_NETINET_RESERVEDPORT, 0);
440                        if (error)
441                                return error;
442                        first = V_ipport_lowfirstauto;  /* 1023 */
443                        last  = V_ipport_lowlastauto;   /* 600 */
444                        lastport = &pcbinfo->ipi_lastlow;
445                } else {
446                        first = V_ipport_firstauto;     /* sysctl */
447                        last  = V_ipport_lastauto;
448                        lastport = &pcbinfo->ipi_lastport;
449                }
450                /*
451                 * For UDP, use random port allocation as long as the user
452                 * allows it.  For TCP (and as of yet unknown) connections,
453                 * use random port allocation only if the user allows it AND
454                 * ipport_tick() allows it.
455                 */
456                if (V_ipport_randomized &&
457                        (!V_ipport_stoprandom || pcbinfo == &V_udbinfo))
458                        dorandom = 1;
459                else
460                        dorandom = 0;
461                /*
462                 * It makes no sense to do random port allocation if
463                 * we have the only port available.
464                 */
465                if (first == last)
466                        dorandom = 0;
467                /* Make sure to not include UDP packets in the count. */
468                if (pcbinfo != &V_udbinfo)
469                        V_ipport_tcpallocs++;
470                /*
471                 * Instead of having two loops further down counting up or down
472                 * make sure that first is always <= last and go with only one
473                 * code path implementing all logic.
474                 */
475                if (first > last) {
476                        aux = first;
477                        first = last;
478                        last = aux;
479                }
480
481                if (dorandom)
482                        *lastport = first +
483                                    (arc4random() % (last - first));
484
485                count = last - first;
486
487                do {
488                        if (count-- < 0)        /* completely used? */
489                                return (EADDRNOTAVAIL);
490                        ++*lastport;
491                        if (*lastport < first || *lastport > last)
492                                *lastport = first;
493                        lport = htons(*lastport);
494                } while (in_pcblookup_local(pcbinfo, laddr,
495                    lport, wild, cred));
496        }
497        *laddrp = laddr.s_addr;
498        *lportp = lport;
499        return (0);
500}
501
502/*
503 * Connect from a socket to a specified address.
504 * Both address and port must be specified in argument sin.
505 * If don't have a local address for this socket yet,
506 * then pick one.
507 */
508int
509in_pcbconnect(struct inpcb *inp, struct sockaddr *nam, struct ucred *cred)
510{
511        u_short lport, fport;
512        in_addr_t laddr, faddr;
513        int anonport, error;
514
515        INP_INFO_WLOCK_ASSERT(inp->inp_pcbinfo);
516        INP_WLOCK_ASSERT(inp);
517
518        lport = inp->inp_lport;
519        laddr = inp->inp_laddr.s_addr;
520        anonport = (lport == 0);
521        error = in_pcbconnect_setup(inp, nam, &laddr, &lport, &faddr, &fport,
522            NULL, cred);
523        if (error)
524                return (error);
525
526        /* Do the initial binding of the local address if required. */
527        if (inp->inp_laddr.s_addr == INADDR_ANY && inp->inp_lport == 0) {
528                inp->inp_lport = lport;
529                inp->inp_laddr.s_addr = laddr;
530                if (in_pcbinshash(inp) != 0) {
531                        inp->inp_laddr.s_addr = INADDR_ANY;
532                        inp->inp_lport = 0;
533                        return (EAGAIN);
534                }
535        }
536
537        /* Commit the remaining changes. */
538        inp->inp_lport = lport;
539        inp->inp_laddr.s_addr = laddr;
540        inp->inp_faddr.s_addr = faddr;
541        inp->inp_fport = fport;
542        in_pcbrehash(inp);
543
544        if (anonport)
545                inp->inp_flags |= INP_ANONPORT;
546        return (0);
547}
548
549/*
550 * Do proper source address selection on an unbound socket in case
551 * of connect. Take jails into account as well.
552 */
553static int
554in_pcbladdr(struct inpcb *inp, struct in_addr *faddr, struct in_addr *laddr,
555    struct ucred *cred)
556{
557        struct ifaddr *ifa;
558        struct sockaddr *sa;
559        struct sockaddr_in *sin;
560        struct route sro;
561        int error;
562
563        KASSERT(laddr != NULL, ("%s: laddr NULL", __func__));
564
565        /*
566         * Bypass source address selection and use the primary jail IP
567         * if requested.
568         */
569        if (cred != NULL && !prison_saddrsel_ip4(cred, laddr))
570                return (0);
571
572        error = 0;
573        bzero(&sro, sizeof(sro));
574
575        sin = (struct sockaddr_in *)&sro.ro_dst;
576        sin->sin_family = AF_INET;
577        sin->sin_len = sizeof(struct sockaddr_in);
578        sin->sin_addr.s_addr = faddr->s_addr;
579
580        /*
581         * If route is known our src addr is taken from the i/f,
582         * else punt.
583         *
584         * Find out route to destination.
585         */
586        if ((inp->inp_socket->so_options & SO_DONTROUTE) == 0)
587                in_rtalloc_ign(&sro, 0, inp->inp_inc.inc_fibnum);
588
589        /*
590         * If we found a route, use the address corresponding to
591         * the outgoing interface.
592         *
593         * Otherwise assume faddr is reachable on a directly connected
594         * network and try to find a corresponding interface to take
595         * the source address from.
596         */
597        if (sro.ro_rt == NULL || sro.ro_rt->rt_ifp == NULL) {
598                struct in_ifaddr *ia;
599                struct ifnet *ifp;
600
601                ia = ifatoia(ifa_ifwithdstaddr((struct sockaddr *)sin));
602                if (ia == NULL)
603                        ia = ifatoia(ifa_ifwithnet((struct sockaddr *)sin, 0));
604                if (ia == NULL) {
605                        error = ENETUNREACH;
606                        goto done;
607                }
608
609                if (cred == NULL || !prison_flag(cred, PR_IP4)) {
610                        laddr->s_addr = ia->ia_addr.sin_addr.s_addr;
611                        ifa_free(&ia->ia_ifa);
612                        goto done;
613                }
614
615                ifp = ia->ia_ifp;
616                ifa_free(&ia->ia_ifa);
617                ia = NULL;
618                IF_ADDR_LOCK(ifp);
619                TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
620
621                        sa = ifa->ifa_addr;
622                        if (sa->sa_family != AF_INET)
623                                continue;
624                        sin = (struct sockaddr_in *)sa;
625                        if (prison_check_ip4(cred, &sin->sin_addr) == 0) {
626                                ia = (struct in_ifaddr *)ifa;
627                                break;
628                        }
629                }
630                if (ia != NULL) {
631                        laddr->s_addr = ia->ia_addr.sin_addr.s_addr;
632                        IF_ADDR_UNLOCK(ifp);
633                        goto done;
634                }
635                IF_ADDR_UNLOCK(ifp);
636
637                /* 3. As a last resort return the 'default' jail address. */
638                error = prison_get_ip4(cred, laddr);
639                goto done;
640        }
641
642        /*
643         * If the outgoing interface on the route found is not
644         * a loopback interface, use the address from that interface.
645         * In case of jails do those three steps:
646         * 1. check if the interface address belongs to the jail. If so use it.
647         * 2. check if we have any address on the outgoing interface
648         *    belonging to this jail. If so use it.
649         * 3. as a last resort return the 'default' jail address.
650         */
651        if ((sro.ro_rt->rt_ifp->if_flags & IFF_LOOPBACK) == 0) {
652                struct in_ifaddr *ia;
653                struct ifnet *ifp;
654
655                /* If not jailed, use the default returned. */
656                if (cred == NULL || !prison_flag(cred, PR_IP4)) {
657                        ia = (struct in_ifaddr *)sro.ro_rt->rt_ifa;
658                        laddr->s_addr = ia->ia_addr.sin_addr.s_addr;
659                        goto done;
660                }
661
662                /* Jailed. */
663                /* 1. Check if the iface address belongs to the jail. */
664                sin = (struct sockaddr_in *)sro.ro_rt->rt_ifa->ifa_addr;
665                if (prison_check_ip4(cred, &sin->sin_addr) == 0) {
666                        ia = (struct in_ifaddr *)sro.ro_rt->rt_ifa;
667                        laddr->s_addr = ia->ia_addr.sin_addr.s_addr;
668                        goto done;
669                }
670
671                /*
672                 * 2. Check if we have any address on the outgoing interface
673                 *    belonging to this jail.
674                 */
675                ia = NULL;
676                ifp = sro.ro_rt->rt_ifp;
677                IF_ADDR_LOCK(ifp);
678                TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
679                        sa = ifa->ifa_addr;
680                        if (sa->sa_family != AF_INET)
681                                continue;
682                        sin = (struct sockaddr_in *)sa;
683                        if (prison_check_ip4(cred, &sin->sin_addr) == 0) {
684                                ia = (struct in_ifaddr *)ifa;
685                                break;
686                        }
687                }
688                if (ia != NULL) {
689                        laddr->s_addr = ia->ia_addr.sin_addr.s_addr;
690                        IF_ADDR_UNLOCK(ifp);
691                        goto done;
692                }
693                IF_ADDR_UNLOCK(ifp);
694
695                /* 3. As a last resort return the 'default' jail address. */
696                error = prison_get_ip4(cred, laddr);
697                goto done;
698        }
699
700        /*
701         * The outgoing interface is marked with 'loopback net', so a route
702         * to ourselves is here.
703         * Try to find the interface of the destination address and then
704         * take the address from there. That interface is not necessarily
705         * a loopback interface.
706         * In case of jails, check that it is an address of the jail
707         * and if we cannot find, fall back to the 'default' jail address.
708         */
709        if ((sro.ro_rt->rt_ifp->if_flags & IFF_LOOPBACK) != 0) {
710                struct sockaddr_in sain;
711                struct in_ifaddr *ia;
712
713                bzero(&sain, sizeof(struct sockaddr_in));
714                sain.sin_family = AF_INET;
715                sain.sin_len = sizeof(struct sockaddr_in);
716                sain.sin_addr.s_addr = faddr->s_addr;
717
718                ia = ifatoia(ifa_ifwithdstaddr(sintosa(&sain)));
719                if (ia == NULL)
720                        ia = ifatoia(ifa_ifwithnet(sintosa(&sain), 0));
721                if (ia == NULL)
722                        ia = ifatoia(ifa_ifwithaddr(sintosa(&sain)));
723
724                if (cred == NULL || !prison_flag(cred, PR_IP4)) {
725                        if (ia == NULL) {
726                                error = ENETUNREACH;
727                                goto done;
728                        }
729                        laddr->s_addr = ia->ia_addr.sin_addr.s_addr;
730                        ifa_free(&ia->ia_ifa);
731                        goto done;
732                }
733
734                /* Jailed. */
735                if (ia != NULL) {
736                        struct ifnet *ifp;
737
738                        ifp = ia->ia_ifp;
739                        ifa_free(&ia->ia_ifa);
740                        ia = NULL;
741                        IF_ADDR_LOCK(ifp);
742                        TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
743
744                                sa = ifa->ifa_addr;
745                                if (sa->sa_family != AF_INET)
746                                        continue;
747                                sin = (struct sockaddr_in *)sa;
748                                if (prison_check_ip4(cred,
749                                    &sin->sin_addr) == 0) {
750                                        ia = (struct in_ifaddr *)ifa;
751                                        break;
752                                }
753                        }
754                        if (ia != NULL) {
755                                laddr->s_addr = ia->ia_addr.sin_addr.s_addr;
756                                IF_ADDR_UNLOCK(ifp);
757                                goto done;
758                        }
759                        IF_ADDR_UNLOCK(ifp);
760                }
761
762                /* 3. As a last resort return the 'default' jail address. */
763                error = prison_get_ip4(cred, laddr);
764                goto done;
765        }
766
767done:
768        if (sro.ro_rt != NULL)
769                RTFREE(sro.ro_rt);
770        return (error);
771}
772
773/*
774 * Set up for a connect from a socket to the specified address.
775 * On entry, *laddrp and *lportp should contain the current local
776 * address and port for the PCB; these are updated to the values
777 * that should be placed in inp_laddr and inp_lport to complete
778 * the connect.
779 *
780 * On success, *faddrp and *fportp will be set to the remote address
781 * and port. These are not updated in the error case.
782 *
783 * If the operation fails because the connection already exists,
784 * *oinpp will be set to the PCB of that connection so that the
785 * caller can decide to override it. In all other cases, *oinpp
786 * is set to NULL.
787 */
788int
789in_pcbconnect_setup(struct inpcb *inp, struct sockaddr *nam,
790    in_addr_t *laddrp, u_short *lportp, in_addr_t *faddrp, u_short *fportp,
791    struct inpcb **oinpp, struct ucred *cred)
792{
793        struct sockaddr_in *sin = (struct sockaddr_in *)nam;
794        struct in_ifaddr *ia;
795        struct inpcb *oinp;
796        struct in_addr laddr, faddr;
797        u_short lport, fport;
798        int error;
799
800        /*
801         * Because a global state change doesn't actually occur here, a read
802         * lock is sufficient.
803         */
804        INP_INFO_LOCK_ASSERT(inp->inp_pcbinfo);
805        INP_LOCK_ASSERT(inp);
806
807        if (oinpp != NULL)
808                *oinpp = NULL;
809        if (nam->sa_len != sizeof (*sin))
810                return (EINVAL);
811        if (sin->sin_family != AF_INET)
812                return (EAFNOSUPPORT);
813        if (sin->sin_port == 0)
814                return (EADDRNOTAVAIL);
815        laddr.s_addr = *laddrp;
816        lport = *lportp;
817        faddr = sin->sin_addr;
818        fport = sin->sin_port;
819
820        if (!TAILQ_EMPTY(&V_in_ifaddrhead)) {
821                /*
822                 * If the destination address is INADDR_ANY,
823                 * use the primary local address.
824                 * If the supplied address is INADDR_BROADCAST,
825                 * and the primary interface supports broadcast,
826                 * choose the broadcast address for that interface.
827                 */
828                if (faddr.s_addr == INADDR_ANY) {
829                        IN_IFADDR_RLOCK();
830                        faddr =
831                            IA_SIN(TAILQ_FIRST(&V_in_ifaddrhead))->sin_addr;
832                        IN_IFADDR_RUNLOCK();
833                        if (cred != NULL &&
834                            (error = prison_get_ip4(cred, &faddr)) != 0)
835                                return (error);
836                } else if (faddr.s_addr == (u_long)INADDR_BROADCAST) {
837                        IN_IFADDR_RLOCK();
838                        if (TAILQ_FIRST(&V_in_ifaddrhead)->ia_ifp->if_flags &
839                            IFF_BROADCAST)
840                                faddr = satosin(&TAILQ_FIRST(
841                                    &V_in_ifaddrhead)->ia_broadaddr)->sin_addr;
842                        IN_IFADDR_RUNLOCK();
843                }
844        }
845        if (laddr.s_addr == INADDR_ANY) {
846                error = in_pcbladdr(inp, &faddr, &laddr, cred);
847                /*
848                 * If the destination address is multicast and an outgoing
849                 * interface has been set as a multicast option, prefer the
850                 * address of that interface as our source address.
851                 */
852                if (IN_MULTICAST(ntohl(faddr.s_addr)) &&
853                    inp->inp_moptions != NULL) {
854                        struct ip_moptions *imo;
855                        struct ifnet *ifp;
856
857                        imo = inp->inp_moptions;
858                        if (imo->imo_multicast_ifp != NULL) {
859                                ifp = imo->imo_multicast_ifp;
860                                IN_IFADDR_RLOCK();
861                                TAILQ_FOREACH(ia, &V_in_ifaddrhead, ia_link)
862                                        if (ia->ia_ifp == ifp)
863                                                break;
864                                if (ia == NULL) {
865                                        IN_IFADDR_RUNLOCK();
866                                        error = EADDRNOTAVAIL;
867                                } else {
868                                        laddr = ia->ia_addr.sin_addr;
869                                        IN_IFADDR_RUNLOCK();
870                                        error = 0;
871                                }
872                        }
873                }
874                if (error)
875                        return (error);
876        }
877        oinp = in_pcblookup_hash(inp->inp_pcbinfo, faddr, fport, laddr, lport,
878            0, NULL);
879        if (oinp != NULL) {
880                if (oinpp != NULL)
881                        *oinpp = oinp;
882                return (EADDRINUSE);
883        }
884        if (lport == 0) {
885                error = in_pcbbind_setup(inp, NULL, &laddr.s_addr, &lport,
886                    cred);
887                if (error)
888                        return (error);
889        }
890        *laddrp = laddr.s_addr;
891        *lportp = lport;
892        *faddrp = faddr.s_addr;
893        *fportp = fport;
894        return (0);
895}
896
897void
898in_pcbdisconnect(struct inpcb *inp)
899{
900
901        INP_INFO_WLOCK_ASSERT(inp->inp_pcbinfo);
902        INP_WLOCK_ASSERT(inp);
903
904        inp->inp_faddr.s_addr = INADDR_ANY;
905        inp->inp_fport = 0;
906        in_pcbrehash(inp);
907}
908
909/*
910 * in_pcbdetach() is responsibe for disassociating a socket from an inpcb.
911 * For most protocols, this will be invoked immediately prior to calling
912 * in_pcbfree().  However, with TCP the inpcb may significantly outlive the
913 * socket, in which case in_pcbfree() is deferred.
914 */
915void
916in_pcbdetach(struct inpcb *inp)
917{
918
919        KASSERT(inp->inp_socket != NULL, ("%s: inp_socket == NULL", __func__));
920
921        inp->inp_socket->so_pcb = NULL;
922        inp->inp_socket = NULL;
923}
924
925/*
926 * in_pcbfree_internal() frees an inpcb that has been detached from its
927 * socket, and whose reference count has reached 0.  It will also remove the
928 * inpcb from any global lists it might remain on.
929 */
930static void
931in_pcbfree_internal(struct inpcb *inp)
932{
933        struct inpcbinfo *ipi = inp->inp_pcbinfo;
934
935        KASSERT(inp->inp_socket == NULL, ("%s: inp_socket != NULL", __func__));
936        KASSERT(inp->inp_refcount == 0, ("%s: refcount !0", __func__));
937
938        INP_INFO_WLOCK_ASSERT(ipi);
939        INP_WLOCK_ASSERT(inp);
940
941#ifdef IPSEC
942        if (inp->inp_sp != NULL)
943                ipsec_delete_pcbpolicy(inp);
944#endif /* IPSEC */
945        inp->inp_gencnt = ++ipi->ipi_gencnt;
946        in_pcbremlists(inp);
947#ifdef INET6
948        if (inp->inp_vflag & INP_IPV6PROTO) {
949                ip6_freepcbopts(inp->in6p_outputopts);
950                if (inp->in6p_moptions != NULL)
951                        ip6_freemoptions(inp->in6p_moptions);
952        }
953#endif
954        if (inp->inp_options)
955                (void)m_free(inp->inp_options);
956        if (inp->inp_moptions != NULL)
957                inp_freemoptions(inp->inp_moptions);
958        inp->inp_vflag = 0;
959        crfree(inp->inp_cred);
960
961#ifdef MAC
962        mac_inpcb_destroy(inp);
963#endif
964        INP_WUNLOCK(inp);
965        uma_zfree(ipi->ipi_zone, inp);
966}
967
968/*
969 * in_pcbref() bumps the reference count on an inpcb in order to maintain
970 * stability of an inpcb pointer despite the inpcb lock being released.  This
971 * is used in TCP when the inpcbinfo lock needs to be acquired or upgraded,
972 * but where the inpcb lock is already held.
973 *
974 * While the inpcb will not be freed, releasing the inpcb lock means that the
975 * connection's state may change, so the caller should be careful to
976 * revalidate any cached state on reacquiring the lock.  Drop the reference
977 * using in_pcbrele().
978 */
979void
980in_pcbref(struct inpcb *inp)
981{
982
983        INP_WLOCK_ASSERT(inp);
984
985        KASSERT(inp->inp_refcount > 0, ("%s: refcount 0", __func__));
986
987        inp->inp_refcount++;
988}
989
990/*
991 * Drop a refcount on an inpcb elevated using in_pcbref(); because a call to
992 * in_pcbfree() may have been made between in_pcbref() and in_pcbrele(), we
993 * return a flag indicating whether or not the inpcb remains valid.  If it is
994 * valid, we return with the inpcb lock held.
995 */
996int
997in_pcbrele(struct inpcb *inp)
998{
999#ifdef INVARIANTS
1000        struct inpcbinfo *ipi = inp->inp_pcbinfo;
1001#endif
1002
1003        KASSERT(inp->inp_refcount > 0, ("%s: refcount 0", __func__));
1004
1005        INP_INFO_WLOCK_ASSERT(ipi);
1006        INP_WLOCK_ASSERT(inp);
1007
1008        inp->inp_refcount--;
1009        if (inp->inp_refcount > 0)
1010                return (0);
1011        in_pcbfree_internal(inp);
1012        return (1);
1013}
1014
1015/*
1016 * Unconditionally schedule an inpcb to be freed by decrementing its
1017 * reference count, which should occur only after the inpcb has been detached
1018 * from its socket.  If another thread holds a temporary reference (acquired
1019 * using in_pcbref()) then the free is deferred until that reference is
1020 * released using in_pcbrele(), but the inpcb is still unlocked.
1021 */
1022void
1023in_pcbfree(struct inpcb *inp)
1024{
1025#ifdef INVARIANTS
1026        struct inpcbinfo *ipi = inp->inp_pcbinfo;
1027#endif
1028
1029        KASSERT(inp->inp_socket == NULL, ("%s: inp_socket != NULL",
1030            __func__));
1031
1032        INP_INFO_WLOCK_ASSERT(ipi);
1033        INP_WLOCK_ASSERT(inp);
1034
1035        if (!in_pcbrele(inp))
1036                INP_WUNLOCK(inp);
1037}
1038
1039/*
1040 * in_pcbdrop() removes an inpcb from hashed lists, releasing its address and
1041 * port reservation, and preventing it from being returned by inpcb lookups.
1042 *
1043 * It is used by TCP to mark an inpcb as unused and avoid future packet
1044 * delivery or event notification when a socket remains open but TCP has
1045 * closed.  This might occur as a result of a shutdown()-initiated TCP close
1046 * or a RST on the wire, and allows the port binding to be reused while still
1047 * maintaining the invariant that so_pcb always points to a valid inpcb until
1048 * in_pcbdetach().
1049 *
1050 * XXXRW: An inp_lport of 0 is used to indicate that the inpcb is not on hash
1051 * lists, but can lead to confusing netstat output, as open sockets with
1052 * closed TCP connections will no longer appear to have their bound port
1053 * number.  An explicit flag would be better, as it would allow us to leave
1054 * the port number intact after the connection is dropped.
1055 *
1056 * XXXRW: Possibly in_pcbdrop() should also prevent future notifications by
1057 * in_pcbnotifyall() and in_pcbpurgeif0()?
1058 */
1059void
1060in_pcbdrop(struct inpcb *inp)
1061{
1062
1063        INP_INFO_WLOCK_ASSERT(inp->inp_pcbinfo);
1064        INP_WLOCK_ASSERT(inp);
1065
1066        inp->inp_flags |= INP_DROPPED;
1067        if (inp->inp_flags & INP_INHASHLIST) {
1068                struct inpcbport *phd = inp->inp_phd;
1069
1070                LIST_REMOVE(inp, inp_hash);
1071                LIST_REMOVE(inp, inp_portlist);
1072                if (LIST_FIRST(&phd->phd_pcblist) == NULL) {
1073                        LIST_REMOVE(phd, phd_hash);
1074                        free(phd, M_PCB);
1075                }
1076                inp->inp_flags &= ~INP_INHASHLIST;
1077        }
1078}
1079
1080/*
1081 * Common routines to return the socket addresses associated with inpcbs.
1082 */
1083struct sockaddr *
1084in_sockaddr(in_port_t port, struct in_addr *addr_p)
1085{
1086        struct sockaddr_in *sin;
1087
1088        sin = malloc(sizeof *sin, M_SONAME,
1089                M_WAITOK | M_ZERO);
1090        sin->sin_family = AF_INET;
1091        sin->sin_len = sizeof(*sin);
1092        sin->sin_addr = *addr_p;
1093        sin->sin_port = port;
1094
1095        return (struct sockaddr *)sin;
1096}
1097
1098int
1099in_getsockaddr(struct socket *so, struct sockaddr **nam)
1100{
1101        struct inpcb *inp;
1102        struct in_addr addr;
1103        in_port_t port;
1104
1105        inp = sotoinpcb(so);
1106        KASSERT(inp != NULL, ("in_getsockaddr: inp == NULL"));
1107
1108        INP_RLOCK(inp);
1109        port = inp->inp_lport;
1110        addr = inp->inp_laddr;
1111        INP_RUNLOCK(inp);
1112
1113        *nam = in_sockaddr(port, &addr);
1114        return 0;
1115}
1116
1117int
1118in_getpeeraddr(struct socket *so, struct sockaddr **nam)
1119{
1120        struct inpcb *inp;
1121        struct in_addr addr;
1122        in_port_t port;
1123
1124        inp = sotoinpcb(so);
1125        KASSERT(inp != NULL, ("in_getpeeraddr: inp == NULL"));
1126
1127        INP_RLOCK(inp);
1128        port = inp->inp_fport;
1129        addr = inp->inp_faddr;
1130        INP_RUNLOCK(inp);
1131
1132        *nam = in_sockaddr(port, &addr);
1133        return 0;
1134}
1135
1136void  in_pcbnotifyall(struct inpcbinfo *pcbinfo, struct in_addr faddr, int errno,
1137    struct inpcb *(*notify)(struct inpcb *, int))
1138{
1139        struct inpcb *inp, *inp_temp;
1140
1141        INP_INFO_WLOCK(pcbinfo);
1142        LIST_FOREACH_SAFE(inp, pcbinfo->ipi_listhead, inp_list, inp_temp) {
1143                INP_WLOCK(inp);
1144#ifdef INET6
1145                if ((inp->inp_vflag & INP_IPV4) == 0) {
1146                        INP_WUNLOCK(inp);
1147                        continue;
1148                }
1149#endif
1150                if (inp->inp_faddr.s_addr != faddr.s_addr ||
1151                    inp->inp_socket == NULL) {
1152                        INP_WUNLOCK(inp);
1153                        continue;
1154                }
1155                if ((*notify)(inp, errno))
1156                        INP_WUNLOCK(inp);
1157        }
1158        INP_INFO_WUNLOCK(pcbinfo);
1159}
1160
1161void
1162in_pcbpurgeif0(struct inpcbinfo *pcbinfo, struct ifnet *ifp)
1163{
1164        struct inpcb *inp;
1165        struct ip_moptions *imo;
1166        int i, gap;
1167
1168        INP_INFO_RLOCK(pcbinfo);
1169        LIST_FOREACH(inp, pcbinfo->ipi_listhead, inp_list) {
1170                INP_WLOCK(inp);
1171                imo = inp->inp_moptions;
1172                if ((inp->inp_vflag & INP_IPV4) &&
1173                    imo != NULL) {
1174                        /*
1175                         * Unselect the outgoing interface if it is being
1176                         * detached.
1177                         */
1178                        if (imo->imo_multicast_ifp == ifp)
1179                                imo->imo_multicast_ifp = NULL;
1180
1181                        /*
1182                         * Drop multicast group membership if we joined
1183                         * through the interface being detached.
1184                         */
1185                        for (i = 0, gap = 0; i < imo->imo_num_memberships;
1186                            i++) {
1187                                if (imo->imo_membership[i]->inm_ifp == ifp) {
1188                                        in_delmulti(imo->imo_membership[i]);
1189                                        gap++;
1190                                } else if (gap != 0)
1191                                        imo->imo_membership[i - gap] =
1192                                            imo->imo_membership[i];
1193                        }
1194                        imo->imo_num_memberships -= gap;
1195                }
1196                INP_WUNLOCK(inp);
1197        }
1198        INP_INFO_RUNLOCK(pcbinfo);
1199}
1200
1201/*
1202 * Lookup a PCB based on the local address and port.
1203 */
1204#define INP_LOOKUP_MAPPED_PCB_COST      3
1205struct inpcb *
1206in_pcblookup_local(struct inpcbinfo *pcbinfo, struct in_addr laddr,
1207    u_short lport, int wild_okay, struct ucred *cred)
1208{
1209        struct inpcb *inp;
1210#ifdef INET6
1211        int matchwild = 3 + INP_LOOKUP_MAPPED_PCB_COST;
1212#else
1213        int matchwild = 3;
1214#endif
1215        int wildcard;
1216
1217        INP_INFO_LOCK_ASSERT(pcbinfo);
1218
1219        if (!wild_okay) {
1220                struct inpcbhead *head;
1221                /*
1222                 * Look for an unconnected (wildcard foreign addr) PCB that
1223                 * matches the local address and port we're looking for.
1224                 */
1225                head = &pcbinfo->ipi_hashbase[INP_PCBHASH(INADDR_ANY, lport,
1226                    0, pcbinfo->ipi_hashmask)];
1227                LIST_FOREACH(inp, head, inp_hash) {
1228#ifdef INET6
1229                        /* XXX inp locking */
1230                        if ((inp->inp_vflag & INP_IPV4) == 0)
1231                                continue;
1232#endif
1233                        if (inp->inp_faddr.s_addr == INADDR_ANY &&
1234                            inp->inp_laddr.s_addr == laddr.s_addr &&
1235                            inp->inp_lport == lport) {
1236                                /*
1237                                 * Found?
1238                                 */
1239                                if (cred == NULL ||
1240                                    prison_equal_ip4(cred->cr_prison,
1241                                        inp->inp_cred->cr_prison))
1242                                        return (inp);
1243                        }
1244                }
1245                /*
1246                 * Not found.
1247                 */
1248                return (NULL);
1249        } else {
1250                struct inpcbporthead *porthash;
1251                struct inpcbport *phd;
1252                struct inpcb *match = NULL;
1253                /*
1254                 * Best fit PCB lookup.
1255                 *
1256                 * First see if this local port is in use by looking on the
1257                 * port hash list.
1258                 */
1259                porthash = &pcbinfo->ipi_porthashbase[INP_PCBPORTHASH(lport,
1260                    pcbinfo->ipi_porthashmask)];
1261                LIST_FOREACH(phd, porthash, phd_hash) {
1262                        if (phd->phd_port == lport)
1263                                break;
1264                }
1265                if (phd != NULL) {
1266                        /*
1267                         * Port is in use by one or more PCBs. Look for best
1268                         * fit.
1269                         */
1270                        LIST_FOREACH(inp, &phd->phd_pcblist, inp_portlist) {
1271                                wildcard = 0;
1272                                if (cred != NULL &&
1273                                    !prison_equal_ip4(inp->inp_cred->cr_prison,
1274                                        cred->cr_prison))
1275                                        continue;
1276#ifdef INET6
1277                                /* XXX inp locking */
1278                                if ((inp->inp_vflag & INP_IPV4) == 0)
1279                                        continue;
1280                                /*
1281                                 * We never select the PCB that has
1282                                 * INP_IPV6 flag and is bound to :: if
1283                                 * we have another PCB which is bound
1284                                 * to 0.0.0.0.  If a PCB has the
1285                                 * INP_IPV6 flag, then we set its cost
1286                                 * higher than IPv4 only PCBs.
1287                                 *
1288                                 * Note that the case only happens
1289                                 * when a socket is bound to ::, under
1290                                 * the condition that the use of the
1291                                 * mapped address is allowed.
1292                                 */
1293                                if ((inp->inp_vflag & INP_IPV6) != 0)
1294                                        wildcard += INP_LOOKUP_MAPPED_PCB_COST;
1295#endif
1296                                if (inp->inp_faddr.s_addr != INADDR_ANY)
1297                                        wildcard++;
1298                                if (inp->inp_laddr.s_addr != INADDR_ANY) {
1299                                        if (laddr.s_addr == INADDR_ANY)
1300                                                wildcard++;
1301                                        else if (inp->inp_laddr.s_addr != laddr.s_addr)
1302                                                continue;
1303                                } else {
1304                                        if (laddr.s_addr != INADDR_ANY)
1305                                                wildcard++;
1306                                }
1307                                if (wildcard < matchwild) {
1308                                        match = inp;
1309                                        matchwild = wildcard;
1310                                        if (matchwild == 0)
1311                                                break;
1312                                }
1313                        }
1314                }
1315                return (match);
1316        }
1317}
1318#undef INP_LOOKUP_MAPPED_PCB_COST
1319
1320/*
1321 * Lookup PCB in hash list.
1322 */
1323struct inpcb *
1324in_pcblookup_hash(struct inpcbinfo *pcbinfo, struct in_addr faddr,
1325    u_int fport_arg, struct in_addr laddr, u_int lport_arg, int wildcard,
1326    struct ifnet *ifp)
1327{
1328        struct inpcbhead *head;
1329        struct inpcb *inp, *tmpinp;
1330        u_short fport = fport_arg, lport = lport_arg;
1331
1332        INP_INFO_LOCK_ASSERT(pcbinfo);
1333
1334        /*
1335         * First look for an exact match.
1336         */
1337        tmpinp = NULL;
1338        head = &pcbinfo->ipi_hashbase[INP_PCBHASH(faddr.s_addr, lport, fport,
1339            pcbinfo->ipi_hashmask)];
1340        LIST_FOREACH(inp, head, inp_hash) {
1341#ifdef INET6
1342                /* XXX inp locking */
1343                if ((inp->inp_vflag & INP_IPV4) == 0)
1344                        continue;
1345#endif
1346                if (inp->inp_faddr.s_addr == faddr.s_addr &&
1347                    inp->inp_laddr.s_addr == laddr.s_addr &&
1348                    inp->inp_fport == fport &&
1349                    inp->inp_lport == lport) {
1350                        /*
1351                         * XXX We should be able to directly return
1352                         * the inp here, without any checks.
1353                         * Well unless both bound with SO_REUSEPORT?
1354                         */
1355                        if (prison_flag(inp->inp_cred, PR_IP4))
1356                                return (inp);
1357                        if (tmpinp == NULL)
1358                                tmpinp = inp;
1359                }
1360        }
1361        if (tmpinp != NULL)
1362                return (tmpinp);
1363
1364        /*
1365         * Then look for a wildcard match, if requested.
1366         */
1367        if (wildcard == INPLOOKUP_WILDCARD) {
1368                struct inpcb *local_wild = NULL, *local_exact = NULL;
1369#ifdef INET6
1370                struct inpcb *local_wild_mapped = NULL;
1371#endif
1372                struct inpcb *jail_wild = NULL;
1373                int injail;
1374
1375                /*
1376                 * Order of socket selection - we always prefer jails.
1377                 *      1. jailed, non-wild.
1378                 *      2. jailed, wild.
1379                 *      3. non-jailed, non-wild.
1380                 *      4. non-jailed, wild.
1381                 */
1382
1383                head = &pcbinfo->ipi_hashbase[INP_PCBHASH(INADDR_ANY, lport,
1384                    0, pcbinfo->ipi_hashmask)];
1385                LIST_FOREACH(inp, head, inp_hash) {
1386#ifdef INET6
1387                        /* XXX inp locking */
1388                        if ((inp->inp_vflag & INP_IPV4) == 0)
1389                                continue;
1390#endif
1391                        if (inp->inp_faddr.s_addr != INADDR_ANY ||
1392                            inp->inp_lport != lport)
1393                                continue;
1394
1395                        /* XXX inp locking */
1396                        if (ifp && ifp->if_type == IFT_FAITH &&
1397                            (inp->inp_flags & INP_FAITH) == 0)
1398                                continue;
1399
1400                        injail = prison_flag(inp->inp_cred, PR_IP4);
1401                        if (injail) {
1402                                if (prison_check_ip4(inp->inp_cred,
1403                                    &laddr) != 0)
1404                                        continue;
1405                        } else {
1406                                if (local_exact != NULL)
1407                                        continue;
1408                        }
1409
1410                        if (inp->inp_laddr.s_addr == laddr.s_addr) {
1411                                if (injail)
1412                                        return (inp);
1413                                else
1414                                        local_exact = inp;
1415                        } else if (inp->inp_laddr.s_addr == INADDR_ANY) {
1416#ifdef INET6
1417                                /* XXX inp locking, NULL check */
1418                                if (inp->inp_vflag & INP_IPV6PROTO)
1419                                        local_wild_mapped = inp;
1420                                else
1421#endif /* INET6 */
1422                                        if (injail)
1423                                                jail_wild = inp;
1424                                        else
1425                                                local_wild = inp;
1426                        }
1427                } /* LIST_FOREACH */
1428                if (jail_wild != NULL)
1429                        return (jail_wild);
1430                if (local_exact != NULL)
1431                        return (local_exact);
1432                if (local_wild != NULL)
1433                        return (local_wild);
1434#ifdef INET6
1435                if (local_wild_mapped != NULL)
1436                        return (local_wild_mapped);
1437#endif /* defined(INET6) */
1438        } /* if (wildcard == INPLOOKUP_WILDCARD) */
1439
1440        return (NULL);
1441}
1442
1443/*
1444 * Insert PCB onto various hash lists.
1445 */
1446int
1447in_pcbinshash(struct inpcb *inp)
1448{
1449        struct inpcbhead *pcbhash;
1450        struct inpcbporthead *pcbporthash;
1451        struct inpcbinfo *pcbinfo = inp->inp_pcbinfo;
1452        struct inpcbport *phd;
1453        u_int32_t hashkey_faddr;
1454
1455        INP_INFO_WLOCK_ASSERT(pcbinfo);
1456        INP_WLOCK_ASSERT(inp);
1457        KASSERT((inp->inp_flags & INP_INHASHLIST) == 0,
1458            ("in_pcbinshash: INP_INHASHLIST"));
1459
1460#ifdef INET6
1461        if (inp->inp_vflag & INP_IPV6)
1462                hashkey_faddr = inp->in6p_faddr.s6_addr32[3] /* XXX */;
1463        else
1464#endif /* INET6 */
1465        hashkey_faddr = inp->inp_faddr.s_addr;
1466
1467        pcbhash = &pcbinfo->ipi_hashbase[INP_PCBHASH(hashkey_faddr,
1468                 inp->inp_lport, inp->inp_fport, pcbinfo->ipi_hashmask)];
1469
1470        pcbporthash = &pcbinfo->ipi_porthashbase[
1471            INP_PCBPORTHASH(inp->inp_lport, pcbinfo->ipi_porthashmask)];
1472
1473        /*
1474         * Go through port list and look for a head for this lport.
1475         */
1476        LIST_FOREACH(phd, pcbporthash, phd_hash) {
1477                if (phd->phd_port == inp->inp_lport)
1478                        break;
1479        }
1480        /*
1481         * If none exists, malloc one and tack it on.
1482         */
1483        if (phd == NULL) {
1484                phd = malloc(sizeof(struct inpcbport), M_PCB, M_NOWAIT);
1485                if (phd == NULL) {
1486                        return (ENOBUFS); /* XXX */
1487                }
1488                phd->phd_port = inp->inp_lport;
1489                LIST_INIT(&phd->phd_pcblist);
1490                LIST_INSERT_HEAD(pcbporthash, phd, phd_hash);
1491        }
1492        inp->inp_phd = phd;
1493        LIST_INSERT_HEAD(&phd->phd_pcblist, inp, inp_portlist);
1494        LIST_INSERT_HEAD(pcbhash, inp, inp_hash);
1495        inp->inp_flags |= INP_INHASHLIST;
1496        return (0);
1497}
1498
1499/*
1500 * Move PCB to the proper hash bucket when { faddr, fport } have  been
1501 * changed. NOTE: This does not handle the case of the lport changing (the
1502 * hashed port list would have to be updated as well), so the lport must
1503 * not change after in_pcbinshash() has been called.
1504 */
1505void
1506in_pcbrehash(struct inpcb *inp)
1507{
1508        struct inpcbinfo *pcbinfo = inp->inp_pcbinfo;
1509        struct inpcbhead *head;
1510        u_int32_t hashkey_faddr;
1511
1512        INP_INFO_WLOCK_ASSERT(pcbinfo);
1513        INP_WLOCK_ASSERT(inp);
1514        KASSERT(inp->inp_flags & INP_INHASHLIST,
1515            ("in_pcbrehash: !INP_INHASHLIST"));
1516
1517#ifdef INET6
1518        if (inp->inp_vflag & INP_IPV6)
1519                hashkey_faddr = inp->in6p_faddr.s6_addr32[3] /* XXX */;
1520        else
1521#endif /* INET6 */
1522        hashkey_faddr = inp->inp_faddr.s_addr;
1523
1524        head = &pcbinfo->ipi_hashbase[INP_PCBHASH(hashkey_faddr,
1525                inp->inp_lport, inp->inp_fport, pcbinfo->ipi_hashmask)];
1526
1527        LIST_REMOVE(inp, inp_hash);
1528        LIST_INSERT_HEAD(head, inp, inp_hash);
1529}
1530
1531/*
1532 * Remove PCB from various lists.
1533 */
1534static void
1535in_pcbremlists(struct inpcb *inp)
1536{
1537        struct inpcbinfo *pcbinfo = inp->inp_pcbinfo;
1538
1539        INP_INFO_WLOCK_ASSERT(pcbinfo);
1540        INP_WLOCK_ASSERT(inp);
1541
1542        inp->inp_gencnt = ++pcbinfo->ipi_gencnt;
1543        if (inp->inp_flags & INP_INHASHLIST) {
1544                struct inpcbport *phd = inp->inp_phd;
1545
1546                LIST_REMOVE(inp, inp_hash);
1547                LIST_REMOVE(inp, inp_portlist);
1548                if (LIST_FIRST(&phd->phd_pcblist) == NULL) {
1549                        LIST_REMOVE(phd, phd_hash);
1550                        free(phd, M_PCB);
1551                }
1552                inp->inp_flags &= ~INP_INHASHLIST;
1553        }
1554        LIST_REMOVE(inp, inp_list);
1555        pcbinfo->ipi_count--;
1556}
1557
1558/*
1559 * A set label operation has occurred at the socket layer, propagate the
1560 * label change into the in_pcb for the socket.
1561 */
1562void
1563in_pcbsosetlabel(struct socket *so)
1564{
1565#ifdef MAC
1566        struct inpcb *inp;
1567
1568        inp = sotoinpcb(so);
1569        KASSERT(inp != NULL, ("in_pcbsosetlabel: so->so_pcb == NULL"));
1570
1571        INP_WLOCK(inp);
1572        SOCK_LOCK(so);
1573        mac_inpcb_sosetlabel(so, inp);
1574        SOCK_UNLOCK(so);
1575        INP_WUNLOCK(inp);
1576#endif
1577}
1578
1579/*
1580 * ipport_tick runs once per second, determining if random port allocation
1581 * should be continued.  If more than ipport_randomcps ports have been
1582 * allocated in the last second, then we return to sequential port
1583 * allocation. We return to random allocation only once we drop below
1584 * ipport_randomcps for at least ipport_randomtime seconds.
1585 */
1586void
1587ipport_tick(void *xtp)
1588{
1589        VNET_ITERATOR_DECL(vnet_iter);
1590
1591        VNET_LIST_RLOCK_NOSLEEP();
1592        VNET_FOREACH(vnet_iter) {
1593                CURVNET_SET(vnet_iter); /* XXX appease INVARIANTS here */
1594                if (V_ipport_tcpallocs <=
1595                    V_ipport_tcplastcount + V_ipport_randomcps) {
1596                        if (V_ipport_stoprandom > 0)
1597                                V_ipport_stoprandom--;
1598                } else
1599                        V_ipport_stoprandom = V_ipport_randomtime;
1600                V_ipport_tcplastcount = V_ipport_tcpallocs;
1601                CURVNET_RESTORE();
1602        }
1603        VNET_LIST_RUNLOCK_NOSLEEP();
1604        callout_reset(&ipport_tick_callout, hz, ipport_tick, NULL);
1605}
1606
1607void
1608inp_wlock(struct inpcb *inp)
1609{
1610
1611        INP_WLOCK(inp);
1612}
1613
1614void
1615inp_wunlock(struct inpcb *inp)
1616{
1617
1618        INP_WUNLOCK(inp);
1619}
1620
1621void
1622inp_rlock(struct inpcb *inp)
1623{
1624
1625        INP_RLOCK(inp);
1626}
1627
1628void
1629inp_runlock(struct inpcb *inp)
1630{
1631
1632        INP_RUNLOCK(inp);
1633}
1634
1635#ifdef INVARIANTS
1636void
1637inp_lock_assert(struct inpcb *inp)
1638{
1639
1640        INP_WLOCK_ASSERT(inp);
1641}
1642
1643void
1644inp_unlock_assert(struct inpcb *inp)
1645{
1646
1647        INP_UNLOCK_ASSERT(inp);
1648}
1649#endif
1650
1651void
1652inp_apply_all(void (*func)(struct inpcb *, void *), void *arg)
1653{
1654        struct inpcb *inp;
1655
1656        INP_INFO_RLOCK(&V_tcbinfo);
1657        LIST_FOREACH(inp, V_tcbinfo.ipi_listhead, inp_list) {
1658                INP_WLOCK(inp);
1659                func(inp, arg);
1660                INP_WUNLOCK(inp);
1661        }
1662        INP_INFO_RUNLOCK(&V_tcbinfo);
1663}
1664
1665struct socket *
1666inp_inpcbtosocket(struct inpcb *inp)
1667{
1668
1669        INP_WLOCK_ASSERT(inp);
1670        return (inp->inp_socket);
1671}
1672
1673struct tcpcb *
1674inp_inpcbtotcpcb(struct inpcb *inp)
1675{
1676
1677        INP_WLOCK_ASSERT(inp);
1678        return ((struct tcpcb *)inp->inp_ppcb);
1679}
1680
1681int
1682inp_ip_tos_get(const struct inpcb *inp)
1683{
1684
1685        return (inp->inp_ip_tos);
1686}
1687
1688void
1689inp_ip_tos_set(struct inpcb *inp, int val)
1690{
1691
1692        inp->inp_ip_tos = val;
1693}
1694
1695void
1696inp_4tuple_get(struct inpcb *inp, uint32_t *laddr, uint16_t *lp,
1697    uint32_t *faddr, uint16_t *fp)
1698{
1699
1700        INP_LOCK_ASSERT(inp);
1701        *laddr = inp->inp_laddr.s_addr;
1702        *faddr = inp->inp_faddr.s_addr;
1703        *lp = inp->inp_lport;
1704        *fp = inp->inp_fport;
1705}
1706
1707struct inpcb *
1708so_sotoinpcb(struct socket *so)
1709{
1710
1711        return (sotoinpcb(so));
1712}
1713
1714struct tcpcb *
1715so_sototcpcb(struct socket *so)
1716{
1717
1718        return (sototcpcb(so));
1719}
1720
1721#ifdef DDB
1722static void
1723db_print_indent(int indent)
1724{
1725        int i;
1726
1727        for (i = 0; i < indent; i++)
1728                db_printf(" ");
1729}
1730
1731static void
1732db_print_inconninfo(struct in_conninfo *inc, const char *name, int indent)
1733{
1734        char faddr_str[48], laddr_str[48];
1735
1736        db_print_indent(indent);
1737        db_printf("%s at %p\n", name, inc);
1738
1739        indent += 2;
1740
1741#ifdef INET6
1742        if (inc->inc_flags & INC_ISIPV6) {
1743                /* IPv6. */
1744                ip6_sprintf(laddr_str, &inc->inc6_laddr);
1745                ip6_sprintf(faddr_str, &inc->inc6_faddr);
1746        } else {
1747#endif
1748                /* IPv4. */
1749                inet_ntoa_r(inc->inc_laddr, laddr_str);
1750                inet_ntoa_r(inc->inc_faddr, faddr_str);
1751#ifdef INET6
1752        }
1753#endif
1754        db_print_indent(indent);
1755        db_printf("inc_laddr %s   inc_lport %u\n", laddr_str,
1756            ntohs(inc->inc_lport));
1757        db_print_indent(indent);
1758        db_printf("inc_faddr %s   inc_fport %u\n", faddr_str,
1759            ntohs(inc->inc_fport));
1760}
1761
1762static void
1763db_print_inpflags(int inp_flags)
1764{
1765        int comma;
1766
1767        comma = 0;
1768        if (inp_flags & INP_RECVOPTS) {
1769                db_printf("%sINP_RECVOPTS", comma ? ", " : "");
1770                comma = 1;
1771        }
1772        if (inp_flags & INP_RECVRETOPTS) {
1773                db_printf("%sINP_RECVRETOPTS", comma ? ", " : "");
1774                comma = 1;
1775        }
1776        if (inp_flags & INP_RECVDSTADDR) {
1777                db_printf("%sINP_RECVDSTADDR", comma ? ", " : "");
1778                comma = 1;
1779        }
1780        if (inp_flags & INP_HDRINCL) {
1781                db_printf("%sINP_HDRINCL", comma ? ", " : "");
1782                comma = 1;
1783        }
1784        if (inp_flags & INP_HIGHPORT) {
1785                db_printf("%sINP_HIGHPORT", comma ? ", " : "");
1786                comma = 1;
1787        }
1788        if (inp_flags & INP_LOWPORT) {
1789                db_printf("%sINP_LOWPORT", comma ? ", " : "");
1790                comma = 1;
1791        }
1792        if (inp_flags & INP_ANONPORT) {
1793                db_printf("%sINP_ANONPORT", comma ? ", " : "");
1794                comma = 1;
1795        }
1796        if (inp_flags & INP_RECVIF) {
1797                db_printf("%sINP_RECVIF", comma ? ", " : "");
1798                comma = 1;
1799        }
1800        if (inp_flags & INP_MTUDISC) {
1801                db_printf("%sINP_MTUDISC", comma ? ", " : "");
1802                comma = 1;
1803        }
1804        if (inp_flags & INP_FAITH) {
1805                db_printf("%sINP_FAITH", comma ? ", " : "");
1806                comma = 1;
1807        }
1808        if (inp_flags & INP_RECVTTL) {
1809                db_printf("%sINP_RECVTTL", comma ? ", " : "");
1810                comma = 1;
1811        }
1812        if (inp_flags & INP_DONTFRAG) {
1813                db_printf("%sINP_DONTFRAG", comma ? ", " : "");
1814                comma = 1;
1815        }
1816        if (inp_flags & IN6P_IPV6_V6ONLY) {
1817                db_printf("%sIN6P_IPV6_V6ONLY", comma ? ", " : "");
1818                comma = 1;
1819        }
1820        if (inp_flags & IN6P_PKTINFO) {
1821                db_printf("%sIN6P_PKTINFO", comma ? ", " : "");
1822                comma = 1;
1823        }
1824        if (inp_flags & IN6P_HOPLIMIT) {
1825                db_printf("%sIN6P_HOPLIMIT", comma ? ", " : "");
1826                comma = 1;
1827        }
1828        if (inp_flags & IN6P_HOPOPTS) {
1829                db_printf("%sIN6P_HOPOPTS", comma ? ", " : "");
1830                comma = 1;
1831        }
1832        if (inp_flags & IN6P_DSTOPTS) {
1833                db_printf("%sIN6P_DSTOPTS", comma ? ", " : "");
1834                comma = 1;
1835        }
1836        if (inp_flags & IN6P_RTHDR) {
1837                db_printf("%sIN6P_RTHDR", comma ? ", " : "");
1838                comma = 1;
1839        }
1840        if (inp_flags & IN6P_RTHDRDSTOPTS) {
1841                db_printf("%sIN6P_RTHDRDSTOPTS", comma ? ", " : "");
1842                comma = 1;
1843        }
1844        if (inp_flags & IN6P_TCLASS) {
1845                db_printf("%sIN6P_TCLASS", comma ? ", " : "");
1846                comma = 1;
1847        }
1848        if (inp_flags & IN6P_AUTOFLOWLABEL) {
1849                db_printf("%sIN6P_AUTOFLOWLABEL", comma ? ", " : "");
1850                comma = 1;
1851        }
1852        if (inp_flags & INP_TIMEWAIT) {
1853                db_printf("%sINP_TIMEWAIT", comma ? ", " : "");
1854                comma  = 1;
1855        }
1856        if (inp_flags & INP_ONESBCAST) {
1857                db_printf("%sINP_ONESBCAST", comma ? ", " : "");
1858                comma  = 1;
1859        }
1860        if (inp_flags & INP_DROPPED) {
1861                db_printf("%sINP_DROPPED", comma ? ", " : "");
1862                comma  = 1;
1863        }
1864        if (inp_flags & INP_SOCKREF) {
1865                db_printf("%sINP_SOCKREF", comma ? ", " : "");
1866                comma  = 1;
1867        }
1868        if (inp_flags & IN6P_RFC2292) {
1869                db_printf("%sIN6P_RFC2292", comma ? ", " : "");
1870                comma = 1;
1871        }
1872        if (inp_flags & IN6P_MTU) {
1873                db_printf("IN6P_MTU%s", comma ? ", " : "");
1874                comma = 1;
1875        }
1876}
1877
1878static void
1879db_print_inpvflag(u_char inp_vflag)
1880{
1881        int comma;
1882
1883        comma = 0;
1884        if (inp_vflag & INP_IPV4) {
1885                db_printf("%sINP_IPV4", comma ? ", " : "");
1886                comma  = 1;
1887        }
1888        if (inp_vflag & INP_IPV6) {
1889                db_printf("%sINP_IPV6", comma ? ", " : "");
1890                comma  = 1;
1891        }
1892        if (inp_vflag & INP_IPV6PROTO) {
1893                db_printf("%sINP_IPV6PROTO", comma ? ", " : "");
1894                comma  = 1;
1895        }
1896}
1897
1898static void
1899db_print_inpcb(struct inpcb *inp, const char *name, int indent)
1900{
1901
1902        db_print_indent(indent);
1903        db_printf("%s at %p\n", name, inp);
1904
1905        indent += 2;
1906
1907        db_print_indent(indent);
1908        db_printf("inp_flow: 0x%x\n", inp->inp_flow);
1909
1910        db_print_inconninfo(&inp->inp_inc, "inp_conninfo", indent);
1911
1912        db_print_indent(indent);
1913        db_printf("inp_ppcb: %p   inp_pcbinfo: %p   inp_socket: %p\n",
1914            inp->inp_ppcb, inp->inp_pcbinfo, inp->inp_socket);
1915
1916        db_print_indent(indent);
1917        db_printf("inp_label: %p   inp_flags: 0x%x (",
1918           inp->inp_label, inp->inp_flags);
1919        db_print_inpflags(inp->inp_flags);
1920        db_printf(")\n");
1921
1922        db_print_indent(indent);
1923        db_printf("inp_sp: %p   inp_vflag: 0x%x (", inp->inp_sp,
1924            inp->inp_vflag);
1925        db_print_inpvflag(inp->inp_vflag);
1926        db_printf(")\n");
1927
1928        db_print_indent(indent);
1929        db_printf("inp_ip_ttl: %d   inp_ip_p: %d   inp_ip_minttl: %d\n",
1930            inp->inp_ip_ttl, inp->inp_ip_p, inp->inp_ip_minttl);
1931
1932        db_print_indent(indent);
1933#ifdef INET6
1934        if (inp->inp_vflag & INP_IPV6) {
1935                db_printf("in6p_options: %p   in6p_outputopts: %p   "
1936                    "in6p_moptions: %p\n", inp->in6p_options,
1937                    inp->in6p_outputopts, inp->in6p_moptions);
1938                db_printf("in6p_icmp6filt: %p   in6p_cksum %d   "
1939                    "in6p_hops %u\n", inp->in6p_icmp6filt, inp->in6p_cksum,
1940                    inp->in6p_hops);
1941        } else
1942#endif
1943        {
1944                db_printf("inp_ip_tos: %d   inp_ip_options: %p   "
1945                    "inp_ip_moptions: %p\n", inp->inp_ip_tos,
1946                    inp->inp_options, inp->inp_moptions);
1947        }
1948
1949        db_print_indent(indent);
1950        db_printf("inp_phd: %p   inp_gencnt: %ju\n", inp->inp_phd,
1951            (uintmax_t)inp->inp_gencnt);
1952}
1953
1954DB_SHOW_COMMAND(inpcb, db_show_inpcb)
1955{
1956        struct inpcb *inp;
1957
1958        if (!have_addr) {
1959                db_printf("usage: show inpcb <addr>\n");
1960                return;
1961        }
1962        inp = (struct inpcb *)addr;
1963
1964        db_print_inpcb(inp, "inpcb", 0);
1965}
1966#endif
Note: See TracBrowser for help on using the repository browser.