#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
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);
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;
};
struct in_endpoints {
u_int16_t ie_fport;
u_int16_t ie_lport;
union in_dependaddr ie_dependfaddr;
union in_dependaddr ie_dependladdr;
#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;
u_char il_jailed;
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;
int il_inpcnt;
struct inpcb *il_inp[];
};
LIST_HEAD(inp_localgrphead, inp_localgroup);
struct in_conninfo {
u_int8_t inc_flags;
u_int8_t inc_len;
u_int16_t inc_pad;
struct in_endpoints inc_ie;
union {
struct route inc4_route;
struct route_in6 inc6_route;
} inc_dependroute;
};
#define inc_isipv6 inc_flags
#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
struct icmp6_filter;
struct inpcbportinfo;
struct inpcb {
LIST_ENTRY(inpcb) inp_hash;
LIST_ENTRY(inpcb) inp_list;
u_int32_t inp_flow;
int inp_lgrpindex;
struct in_conninfo inp_inc;
void *inp_ppcb;
struct inpcbinfo *inp_pcbinfo;
struct socket *inp_socket;
int inp_flags;
uint16_t inp_hashval;
uint16_t inp_pad;
void *inp_unused1;
u_char inp_af;
u_char inp_ip_ttl;
u_char inp_ip_p;
u_char inp_ip_minttl;
struct {
u_char inp4_ip_tos;
struct mbuf *inp4_options;
struct ip_moptions *inp4_moptions;
} 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 {
struct mbuf *inp6_options;
struct ip6_pktopts *inp6_outputopts;
struct ip6_moptions *inp6_moptions;
struct icmp6_filter *inp6_icmp6filt;
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;
inp_gen_t inp_gencnt;
#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
#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
#define in6p_socket inp_socket
#define in6p_lport inp_lport
#define in6p_fport inp_fport
#define in6p_ppcb inp_ppcb
void *inp_pf_sk;
};
#ifdef _SYS_SOCKETVAR_H_
struct xinpcb {
size_t xi_len;
struct inpcb xi_inp;
struct xsocket xi_socket;
u_quad_t xi_alignment_hack;
};
#endif
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 {
struct lwkt_token *infotoken;
struct inpcbhead *hashbase;
u_long hashmask;
int portinfo_cnt;
struct inpcbportinfo *portinfo;
struct inpcbport *portsave;
struct inpcontainerhead *wildcardhashbase;
u_long wildcardhashmask;
struct inp_localgrphead *localgrphashbase;
u_long localgrphashmask;
struct inpcbhead pcblisthead;
size_t ipi_size;
u_int ipi_count;
int cpu;
u_quad_t ipi_gencnt;
} __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))
#define INP_RECVOPTS 0x01
#define INP_RECVRETOPTS 0x02
#define INP_RECVDSTADDR 0x04
#define INP_HDRINCL 0x08
#define INP_HIGHPORT 0x10
#define INP_LOWPORT 0x20
#define INP_ANONPORT 0x40
#define INP_RECVIF 0x80
#define INP_MTUDISC 0x100
#define INP_WILDCARD 0x400
#define INP_FLAG_PROTO2 0x800
#define INP_CONNECTED 0x1000
#define INP_FLAG_PROTO1 0x2000
#define INP_PLACEMARKER 0x4000
#define INP_HASH 0x8000
#define IN6P_PKTINFO 0x010000
#define IN6P_HOPLIMIT 0x020000
#define IN6P_HOPOPTS 0x040000
#define IN6P_DSTOPTS 0x080000
#define IN6P_RTHDR 0x100000
#define IN6P_RTHDRDSTOPTS 0x200000
#define IN6P_AUTOFLOWLABEL 0x800000
#define IN6P_TCLASS 0x400000
#define IN6P_RFC2292 0x40000000
#define IN6P_MTU 0x80000000
#define INP_RECVTOS 0x10000000
#define INP_ONLIST 0x20000000
#define INP_RECVTTL 0x80000000
#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)
#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
#define INPLOOKUP_WILDCARD 1
#define sotoinpcb(so) ((struct inpcb *)(so)->so_pcb)
#define sotoin6pcb(so) sotoinpcb(so)
#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)))
#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
#define ASSERT_PCBINFO_TOKEN_HELD(pcbinfo)
#endif
#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
#define ASSERT_INP_NOTINHASH(inp)
#endif
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
#endif