root/sys/netinet/in_pcb.h
/*
 * Copyright (c) 2004 Jeffrey M. Hsu.  All rights reserved.
 * Copyright (c) 2004 The DragonFly Project.  All rights reserved.
 *
 * This code is derived from software contributed to The DragonFly Project
 * by Jeffrey M. Hsu.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of The DragonFly Project nor the names of its
 *    contributors may be used to endorse or promote products derived
 *    from this software without specific, prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

/*
 * Copyright (c) 1982, 1986, 1990, 1993
 *      The Regents of the University of California.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 *      @(#)in_pcb.h    8.1 (Berkeley) 6/10/93
 * $FreeBSD: src/sys/netinet/in_pcb.h,v 1.32.2.7 2003/01/24 05:11:34 sam Exp $
 */

#ifndef _NETINET_IN_PCB_H_
#define _NETINET_IN_PCB_H_

#ifndef _SYS_QUEUE_H_
#include <sys/queue.h>
#endif
#ifndef _SYS_SYSCTL_H_
#include <sys/sysctl.h>
#endif
#ifndef _NETINET_IN_H_
#include <netinet/in.h>
#endif
#ifndef _NET_ROUTE_H_
#include <net/route.h>
#endif

#define in6pcb          inpcb   /* for KAME src sync over BSD*'s */

/*
 * Common structure pcb for internet protocol implementation.
 * Here are stored pointers to local and foreign host table
 * entries, local and foreign socket numbers, and pointers
 * up (to a socket structure) and down (to a protocol-specific)
 * control block.
 */
LIST_HEAD(inpcbhead, inpcb);
LIST_HEAD(inpcbporthead, inpcbport);
typedef u_quad_t        inp_gen_t;

struct inpcontainer {
        struct inpcb                    *ic_inp;
        LIST_ENTRY(inpcontainer)        ic_list;
};
LIST_HEAD(inpcontainerhead, inpcontainer);

/*
 * PCB with AF_INET6 null bind'ed laddr can receive AF_INET input packet.
 * So, AF_INET6 null laddr is also used as AF_INET null laddr,
 * by utilize following structure. (At last, same as INRIA)
 */
struct in_addr_4in6 {
        u_int32_t       ia46_pad32[3];
        struct  in_addr ia46_addr4;
};

union in_dependaddr {
        struct in_addr_4in6 id46_addr;
        struct in6_addr id6_addr;
};

/*
 * NOTE: ipv6 addrs should be 64-bit aligned, per RFC 2553.
 * in_conninfo has some extra padding to accomplish this.
 */
struct in_endpoints {
        u_int16_t       ie_fport;               /* foreign port */
        u_int16_t       ie_lport;               /* local port */
        /* protocol dependent part, local and foreign addr */
        union in_dependaddr ie_dependfaddr;     /* foreign host table entry */
        union in_dependaddr ie_dependladdr;     /* local host table entry */
#define ie_faddr        ie_dependfaddr.id46_addr.ia46_addr4
#define ie_laddr        ie_dependladdr.id46_addr.ia46_addr4
#define ie6_faddr       ie_dependfaddr.id6_addr
#define ie6_laddr       ie_dependladdr.id6_addr
};

struct inp_localgroup {
        LIST_ENTRY(inp_localgroup) il_list;
        uint16_t        il_lport;
        u_char          il_af;          /* AF_INET or AF_INET6 */
        u_char          il_jailed;      /* jailed lport, else not */
        uint32_t        il_pad2;
        union in_dependaddr il_dependladdr;
#define il_laddr        il_dependladdr.id46_addr.ia46_addr4
#define il6_laddr       il_dependladdr.id6_addr
        int             il_inpsiz;      /* size of il_inp[] */
        int             il_inpcnt;      /* # of elem in il_inp[] */
        struct inpcb    *il_inp[];
};
LIST_HEAD(inp_localgrphead, inp_localgroup);

/*
 * XXX
 * At some point struct route should possibly change to:
 *   struct rtentry *rt
 *   struct in_endpoints *ie;
 */
struct in_conninfo {
        u_int8_t        inc_flags;
        u_int8_t        inc_len;
        u_int16_t       inc_pad;        /* XXX alignment for in_endpoints */
        /* protocol dependent part; cached route */
        struct  in_endpoints inc_ie;
        union {
                /* placeholder for routing entry */
                struct  route inc4_route;
                struct  route_in6 inc6_route;
        } inc_dependroute;
};
#define inc_isipv6      inc_flags       /* temp compatibility */
#define inc_fport       inc_ie.ie_fport
#define inc_lport       inc_ie.ie_lport
#define inc_faddr       inc_ie.ie_faddr
#define inc_laddr       inc_ie.ie_laddr
#define inc_route       inc_dependroute.inc4_route
#define inc6_faddr      inc_ie.ie6_faddr
#define inc6_laddr      inc_ie.ie6_laddr
#define inc6_route      inc_dependroute.inc6_route

/*
 * NB: the zone allocator is type-stable EXCEPT FOR THE FIRST TWO LONGS
 * of the structure.  Therefore, it is important that the members in
 * that position not contain any information which is required to be
 * stable.
 */
struct  icmp6_filter;
struct  inpcbportinfo;

struct inpcb {
        LIST_ENTRY(inpcb) inp_hash; /* hash list */
        LIST_ENTRY(inpcb) inp_list; /* list for all PCBs of this proto */
        u_int32_t       inp_flow;
        int             inp_lgrpindex;  /* local group index */

        /* local and foreign ports, local and foreign addr */
        struct  in_conninfo inp_inc;

        void    *inp_ppcb;              /* pointer to per-protocol pcb */
        struct  inpcbinfo *inp_pcbinfo; /* PCB list info */
        struct  socket *inp_socket;     /* back pointer to socket */
                                        /* list for this PCB's local port */
        int             inp_flags;      /* generic IP/datagram flags */
        uint16_t        inp_hashval;    /* valid iff INP_HASH */
        uint16_t        inp_pad;        /* explicit padding */

        void    *inp_unused1;           /* was: for IPSEC */
        u_char  inp_af;                 /* AF_INET or AF_INET6 */
        u_char  inp_ip_ttl;             /* time to live proto */
        u_char  inp_ip_p;               /* protocol proto */
        u_char  inp_ip_minttl;          /* minimum TTL or drop */

        /* protocol dependent part; options */
        struct {
                u_char  inp4_ip_tos;            /* type of service proto */
                struct  mbuf *inp4_options;     /* IP options */
                struct  ip_moptions *inp4_moptions; /* IP multicast options */
        } inp_depend4;
#define inp_fport       inp_inc.inc_fport
#define inp_lport       inp_inc.inc_lport
#define inp_faddr       inp_inc.inc_faddr
#define inp_laddr       inp_inc.inc_laddr
#define inp_route       inp_inc.inc_route
#define inp_ip_tos      inp_depend4.inp4_ip_tos
#define inp_options     inp_depend4.inp4_options
#define inp_moptions    inp_depend4.inp4_moptions
        struct {
                /* IP options */
                struct  mbuf *inp6_options;
                /* IP6 options for outgoing packets */
                struct  ip6_pktopts *inp6_outputopts;
                /* IP multicast options */
                struct  ip6_moptions *inp6_moptions;
                /* ICMPv6 code type filter */
                struct  icmp6_filter *inp6_icmp6filt;
                /* IPV6_CHECKSUM setsockopt */
                int     inp6_cksum;
                u_short inp6_ifindex;
                short   inp6_hops;
                u_int8_t        inp6_hlim;
        } inp_depend6;
        LIST_ENTRY(inpcb) inp_portlist;
        struct  inpcbporthead *inp_porthash;
        struct  inpcbport *inp_phd;     /* head of this list */
        inp_gen_t       inp_gencnt;     /* generation count of this instance */
#define in6p_faddr      inp_inc.inc6_faddr
#define in6p_laddr      inp_inc.inc6_laddr
#define in6p_route      inp_inc.inc6_route
#define in6p_ip6_hlim   inp_depend6.inp6_hlim
#define in6p_hops       inp_depend6.inp6_hops   /* default hop limit */
#define in6p_ip6_nxt    inp_ip_p
#define in6p_flowinfo   inp_flow
#define in6p_af         inp_af
#define in6p_options    inp_depend6.inp6_options
#define in6p_outputopts inp_depend6.inp6_outputopts
#define in6p_moptions   inp_depend6.inp6_moptions
#define in6p_icmp6filt  inp_depend6.inp6_icmp6filt
#define in6p_cksum      inp_depend6.inp6_cksum
#define inp6_ifindex    inp_depend6.inp6_ifindex
#define in6p_flags      inp_flags  /* for KAME src sync over BSD*'s */
#define in6p_socket     inp_socket  /* for KAME src sync over BSD*'s */
#define in6p_lport      inp_lport  /* for KAME src sync over BSD*'s */
#define in6p_fport      inp_fport  /* for KAME src sync over BSD*'s */
#define in6p_ppcb       inp_ppcb  /* for KAME src sync over BSD*'s */

        void    *inp_pf_sk;
};
/*
 * The range of the generation count, as used in this implementation,
 * is 9e19.  We would have to create 300 billion connections per
 * second for this number to roll over in a year.  This seems sufficiently
 * unlikely that we simply don't concern ourselves with that possibility.
 */

/*
 * Interface exported to userland by various protocols which use
 * inpcbs.  Hack alert -- only define if struct xsocket is in scope.
 */
#ifdef _SYS_SOCKETVAR_H_
struct  xinpcb {
        size_t  xi_len;         /* length of this structure */
        struct  inpcb xi_inp;
        struct  xsocket xi_socket;
        u_quad_t        xi_alignment_hack;
};
#endif /* _SYS_SOCKETVAR_H_ */

struct inpcbport {
        LIST_ENTRY(inpcbport) phd_hash;
        struct inpcbhead phd_pcblist;
        u_short phd_port;
};

struct lwkt_token;

struct inpcbportinfo {
        struct  inpcbporthead *porthashbase;
        u_long  porthashcnt;
        u_short offset;
} __cachealign;

struct inpcbinfo {              /* XXX documentation, prefixes */
        struct  lwkt_token *infotoken;  /* if this inpcbinfo is shared */
        struct  inpcbhead *hashbase;
        u_long  hashmask;
        int     portinfo_cnt;
        struct  inpcbportinfo *portinfo;
        struct  inpcbport *portsave;    /* port allocation cache */
        struct  inpcontainerhead *wildcardhashbase;
        u_long  wildcardhashmask;
        struct  inp_localgrphead *localgrphashbase;
        u_long  localgrphashmask;
        struct  inpcbhead pcblisthead;  /* head of queue of active pcb's */
        size_t  ipi_size;       /* allocation size for pcbs */
        u_int   ipi_count;      /* number of pcbs in this list */
        int     cpu;            /* related protocol thread cpu */
        u_quad_t ipi_gencnt;    /* current generation count */
} __cachealign;


#define INP_PCBCONNHASH(faddr, fport, laddr, lport, mask)               \
    (((faddr) ^ ((faddr) >> 16) ^ (laddr) ^ ntohs((lport) ^ (fport))) & (mask))

#define INP_PCBPORTHASH(lport, cnt)             (ntohs(lport) % (cnt))

#define INP_PCBWILDCARDHASH(lport, mask)        (ntohs(lport) & (mask))

#define INP_PCBLOCALGRPHASH(lport, mask)        (ntohs(lport) & (mask))

/* flags in inp_flags: */
#define INP_RECVOPTS            0x01    /* receive incoming IP options */
#define INP_RECVRETOPTS         0x02    /* receive IP options for reply */
#define INP_RECVDSTADDR         0x04    /* receive IP dst address */
#define INP_HDRINCL             0x08    /* user supplies entire IP header */
#define INP_HIGHPORT            0x10    /* user wants "high" port binding */
#define INP_LOWPORT             0x20    /* user wants "low" port binding */
#define INP_ANONPORT            0x40    /* port chosen for user */
#define INP_RECVIF              0x80    /* receive incoming interface */
#define INP_MTUDISC             0x100   /* user can do MTU discovery */
/* 0x200 unused */
#define INP_WILDCARD            0x400   /* wildcard match */
#define INP_FLAG_PROTO2         0x800   /* protocol specific */
#define INP_CONNECTED           0x1000  /* exact match */
#define INP_FLAG_PROTO1         0x2000  /* protocol specific */
#define INP_PLACEMARKER         0x4000  /* skip this pcb, its a placemarker */
#define INP_HASH                0x8000  /* inp_hashval is valid */

#define IN6P_PKTINFO            0x010000 /* receive IP6 dst and I/F */
#define IN6P_HOPLIMIT           0x020000 /* receive hoplimit */
#define IN6P_HOPOPTS            0x040000 /* receive hop-by-hop options */
#define IN6P_DSTOPTS            0x080000 /* receive dst options after rthdr */
#define IN6P_RTHDR              0x100000 /* receive routing header */
#define IN6P_RTHDRDSTOPTS       0x200000 /* receive dstoptions before rthdr */
/* 0x400000 used: IN6P_TCLASS; see below */
#define IN6P_AUTOFLOWLABEL      0x800000 /* attach flowlabel automatically */
/* 
 * RFC3542 Definition 
 */
#define IN6P_TCLASS             0x400000 /* receive traffic class value */
#define IN6P_RFC2292            0x40000000 /* used RFC2292 API on the socket */
#define IN6P_MTU                0x80000000 /* receive path MTU */

#define INP_RECVTOS             0x10000000 /* receive incoming IP TOS */
#define INP_ONLIST              0x20000000 /* on pcblist */
#define INP_RECVTTL             0x80000000 /* receive incoming IP TTL */

#define INP_CONTROLOPTS         (INP_RECVOPTS|INP_RECVRETOPTS|INP_RECVDSTADDR|\
                                 INP_RECVIF|INP_RECVTTL|INP_RECVTOS|\
                                 IN6P_PKTINFO|IN6P_HOPLIMIT|IN6P_HOPOPTS|\
                                 IN6P_DSTOPTS|IN6P_RTHDR|IN6P_RTHDRDSTOPTS|\
                                 IN6P_TCLASS|IN6P_AUTOFLOWLABEL|IN6P_RFC2292|\
                                 IN6P_MTU)
                                 
#define INP_UNMAPPABLEOPTS      (IN6P_HOPOPTS|IN6P_DSTOPTS|IN6P_RTHDR|\
                                 IN6P_TCLASS|IN6P_AUTOFLOWLABEL)

 /* for KAME src sync over BSD*'s */
#define IN6P_HIGHPORT           INP_HIGHPORT
#define IN6P_LOWPORT            INP_LOWPORT
#define IN6P_ANONPORT           INP_ANONPORT
#define IN6P_RECVIF             INP_RECVIF
#define IN6P_MTUDISC            INP_MTUDISC
#define IN6P_CONTROLOPTS INP_CONTROLOPTS
        /*
         * socket AF version is {newer than,or include}
         * actual datagram AF version
         */

#define INPLOOKUP_WILDCARD      1
#define sotoinpcb(so)   ((struct inpcb *)(so)->so_pcb)
#define sotoin6pcb(so)  sotoinpcb(so) /* for KAME src sync over BSD*'s */

/* macros for handling bitmap of ports not to allocate dynamically */
#define DP_MAPBITS      (sizeof(u_int32_t) * NBBY)
#define DP_MAPSIZE      (howmany(65536, DP_MAPBITS))
#define DP_SET(m, p)    ((m)[(p) / DP_MAPBITS] |= (1 << ((p) % DP_MAPBITS)))
#define DP_CLR(m, p)    ((m)[(p) / DP_MAPBITS] &= ~(1 << ((p) % DP_MAPBITS)))
#define DP_ISSET(m, p)  ((m)[(p) / DP_MAPBITS] & (1 << ((p) % DP_MAPBITS)))

/* default values for baddynamicports [see ip_init()] */
#define DEFBADDYNAMICPORTS_TCP  { \
        587, 749, 750, 751, 871, 2049, \
        6000, 6001, 6002, 6003, 6004, 6005, 6006, 6007, 6008, 6009, 6010, \
        0 }
#define DEFBADDYNAMICPORTS_UDP  { 623, 664, 749, 750, 751, 2049, 0 }

struct baddynamicports {
        u_int32_t tcp[DP_MAPSIZE];
        u_int32_t udp[DP_MAPSIZE];
};


#define INP_SOCKAF(so) so->so_proto->pr_domain->dom_family
#define INP_CHECK_SOCKAF(so, af)        (INP_SOCKAF(so) == af)

#define INP_ISIPV6(inp)                 ((inp)->inp_af == AF_INET6)
#define INP_ISIPV4(inp)                 ((inp)->inp_af == AF_INET)

#ifdef _KERNEL

static __inline struct inpcbporthead *
in_pcbporthash_head(struct inpcbportinfo *portinfo, u_short lport)
{
        return &portinfo->porthashbase[
            INP_PCBPORTHASH(lport, portinfo->porthashcnt)];
}

#define GET_PORTHASH_TOKEN(porthashhead) \
do { \
        lwkt_getpooltoken((porthashhead)); \
} while (0)

#define REL_PORTHASH_TOKEN(porthashhead) \
do { \
        lwkt_relpooltoken((porthashhead)); \
} while (0)

#ifdef INVARIANTS
#define ASSERT_PORTHASH_TOKEN_HELD(pcbhashhead) \
        ASSERT_LWKT_TOKEN_HELD(lwkt_token_pool_lookup((pcbhashhead)))
#else
#define ASSERT_PORTHASH_TOKEN_HELD(pcbhashhead)
#endif

#define GET_PCBINFO_TOKEN(pcbinfo) \
do { \
        if ((pcbinfo)->infotoken) \
                lwkt_gettoken((pcbinfo)->infotoken); \
} while (0)

#define REL_PCBINFO_TOKEN(pcbinfo) \
do { \
        if ((pcbinfo)->infotoken) \
                lwkt_reltoken((pcbinfo)->infotoken); \
} while (0)

#ifdef INVARIANTS
#define ASSERT_PCBINFO_TOKEN_HELD(pcbinfo) \
do { \
        if ((pcbinfo)->infotoken) \
                ASSERT_LWKT_TOKEN_HELD((pcbinfo)->infotoken); \
} while (0)
#else   /* !INVARIANTS */
#define ASSERT_PCBINFO_TOKEN_HELD(pcbinfo)
#endif  /* INVARIANTS */

#ifdef INVARIANTS
#define ASSERT_INP_NOTINHASH(inp) \
do { \
        KASSERT(!((inp)->inp_flags & INP_CONNECTED), \
            ("already on connhash")); \
        KASSERT(!((inp)->inp_flags & INP_WILDCARD), \
            ("already on wildcardhash")); \
} while (0)
#else   /* !INVARIANTS */
#define ASSERT_INP_NOTINHASH(inp)
#endif  /* INVARIANTS */

extern int      ipport_lowfirstauto;
extern int      ipport_lowlastauto;
extern int      ipport_firstauto;
extern int      ipport_lastauto;
extern int      ipport_hifirstauto;
extern int      ipport_hilastauto;

union netmsg;
struct xinpcb;

typedef void    (*inp_notify_t)(struct inpcb *, int);

void    in_pcbportrange(u_short *, u_short *, u_short, u_short);
void    in_pcbpurgeif0 (struct inpcbinfo *, struct ifnet *);
void    in_losing (struct inpcb *);
void    in_rtchange (struct inpcb *, int);
void    in_pcbinfo_init (struct inpcbinfo *, int, boolean_t);
void    in_pcbportinfo_init (struct inpcbportinfo *, int, u_short);
void    in_pcbportinfo_set(struct inpcbinfo *, struct inpcbportinfo *, int);
int     in_pcballoc (struct socket *, struct inpcbinfo *);
void    in_pcbunlink (struct inpcb *, struct inpcbinfo *);
void    in_pcbunlink_flags (struct inpcb *, struct inpcbinfo *, int);
void    in_pcblink (struct inpcb *, struct inpcbinfo *);
void    in_pcblink_flags (struct inpcb *, struct inpcbinfo *, int);
void    in_pcbonlist (struct inpcb *);
void    in_pcbofflist (struct inpcb *);
int     in_pcbbind (struct inpcb *, struct sockaddr *, struct thread *);
int     in_pcbsrcaddr_check(const struct inpcb *, struct sockaddr_in *,
            struct in_addr *, struct thread *);
int     in_pcbbind_remote(struct inpcb *, const struct sockaddr *,
            struct thread *);
int     in_pcbconnect (struct inpcb *, struct sockaddr *, struct thread *);
void    in_pcbdetach (struct inpcb *);
void    in_pcbdisconnect (struct inpcb *);
void    in_pcbinswildcardhash(struct inpcb *inp);
void    in_pcbinswildcardhash_oncpu(struct inpcb *, struct inpcbinfo *);
void    in_pcbinsconnhash(struct inpcb *inp);
void    in_pcbinsporthash(struct inpcbporthead *, struct inpcb *);
void    in_pcbinsporthash_lport (struct inpcb *);
void    in_pcbremporthash (struct inpcb *);
int     in_pcbladdr (struct inpcb *, struct sockaddr *,
            struct sockaddr_in **, struct thread *);
int     in_pcbladdr_find (struct inpcb *, struct sockaddr *,
            struct sockaddr_in **, struct thread *, int);
struct inpcb *
        in_pcblookup_hash (struct inpcbinfo *,
                               struct in_addr, u_int, struct in_addr, u_int,
                               boolean_t, struct ifnet *);
struct inpcb *
        in_pcblookup_pkthash (struct inpcbinfo *,
                               struct in_addr, u_int, struct in_addr, u_int,
                               boolean_t, struct ifnet *, const struct mbuf *);
void    in_pcbnotifyall (struct inpcbinfo *, struct in_addr,
            int, inp_notify_t);
int     in_setpeeraddr (struct socket *so, struct sockaddr **nam);
void    in_setpeeraddr_dispatch(union netmsg *);
void    in_setsockaddr_dispatch(netmsg_t msg);
int     in_baddynamic(u_int16_t, u_int16_t);
void    in_pcbremwildcardhash(struct inpcb *inp);
void    in_pcbremwildcardhash_oncpu(struct inpcb *, struct inpcbinfo *);
void    in_pcbremconnhash(struct inpcb *inp);
void    in_pcbremlists (struct inpcb *inp);
int     prison_xinpcb (struct thread *p, struct inpcb *inp);
void    in_savefaddr (struct socket *so, const struct sockaddr *faddr);
struct inpcb *
        in_pcblocalgroup_last(const struct inpcbinfo *, const struct inpcb *);
void    in_pcbglobalinit(void);
void    in_pcbresetroute(struct inpcb *);

int     in_pcblist_range(SYSCTL_HANDLER_ARGS);
int     in_pcblist_ncpus(SYSCTL_HANDLER_ARGS);

struct inpcb *
        in_pcbmarker(void);
struct inpcontainer *
        in_pcbcontainer_marker(void);

#endif /* _KERNEL */

#endif /* !_NETINET_IN_PCB_H_ */