#ifndef _NETINET_IN_PCB_H_
#define _NETINET_IN_PCB_H_
#include <sys/queue.h>
#include <sys/mutex.h>
#include <sys/rwlock.h>
#include <sys/refcnt.h>
#include <netinet/ip6.h>
#include <netinet/icmp6.h>
#include <netinet/ip_ipsp.h>
#include <crypto/siphash.h>
struct pf_state_key;
union inpaddru {
struct in_addr iau_addr;
struct in6_addr iau_addr6;
};
struct inpcb {
struct inpcbtable *inp_table;
TAILQ_ENTRY(inpcb) inp_queue;
LIST_ENTRY(inpcb) inp_hash;
LIST_ENTRY(inpcb) inp_lhash;
union inpaddru inp_faddru;
union inpaddru inp_laddru;
#define inp_faddr inp_faddru.iau_addr
#define inp_faddr6 inp_faddru.iau_addr6
#define inp_laddr inp_laddru.iau_addr
#define inp_laddr6 inp_laddru.iau_addr6
u_int16_t inp_fport;
u_int16_t inp_lport;
struct socket *inp_socket;
caddr_t inp_ppcb;
struct route inp_route;
struct refcnt inp_refcnt;
int inp_flags;
union {
struct ip hu_ip;
struct ip6_hdr hu_ipv6;
} inp_hu;
#define inp_ip inp_hu.hu_ip
#define inp_ipv6 inp_hu.hu_ipv6
union {
struct mbuf *inp_options;
struct ip6_pktopts *inp_outputopts6;
};
int inp_hops;
union {
struct ip_moptions *mou_mo;
struct ip6_moptions *mou_mo6;
} inp_mou;
#define inp_moptions inp_mou.mou_mo
#define inp_moptions6 inp_mou.mou_mo6
struct ipsec_level inp_seclevel;
u_char inp_ip_minttl;
#define inp_ip6_minhlim inp_ip_minttl
#define inp_flowinfo inp_hu.hu_ipv6.ip6_flow
int inp_cksum6;
struct icmp6_filter *inp_icmp6filt;
struct pf_state_key *inp_pf_sk;
struct mbuf *(*inp_upcall)(void *, struct mbuf *,
struct ip *, struct ip6_hdr *, void *, int, struct netstack *);
void *inp_upcall_arg;
u_int inp_rtableid;
int inp_pipex;
uint16_t inp_flowid;
};
LIST_HEAD(inpcbhead, inpcb);
struct inpcb_iterator {
struct inpcbtable *inp_table;
TAILQ_ENTRY(inpcb) inp_queue;
};
static inline int
in_pcb_is_iterator(struct inpcb *inp)
{
return (inp->inp_table == NULL ? 1 : 0);
}
struct inpcbtable {
struct mutex inpt_mtx;
TAILQ_HEAD(inpthead, inpcb) inpt_queue;
struct inpcbhead *inpt_hashtbl;
struct inpcbhead *inpt_lhashtbl;
SIPHASH_KEY inpt_key, inpt_lkey;
u_long inpt_mask, inpt_lmask;
int inpt_count, inpt_size;
};
#define INP_RECVOPTS 0x001
#define INP_RECVRETOPTS 0x002
#define INP_RECVDSTADDR 0x004
#define INP_RXDSTOPTS INP_RECVOPTS
#define INP_RXHOPOPTS INP_RECVRETOPTS
#define INP_RXINFO INP_RECVDSTADDR
#define INP_RXSRCRT 0x010
#define INP_HOPLIMIT 0x020
#define INP_HDRINCL 0x008
#define INP_HIGHPORT 0x010
#define INP_LOWPORT 0x020
#define INP_RECVIF 0x080
#define INP_RECVTTL 0x040
#define INP_RECVDSTPORT 0x200
#define INP_RECVRTABLE 0x400
#define INP_IPSECFLOWINFO 0x800
#define INP_CONTROLOPTS (INP_RECVOPTS|INP_RECVRETOPTS|INP_RECVDSTADDR| \
INP_RXSRCRT|INP_HOPLIMIT|INP_RECVIF|INP_RECVTTL|INP_RECVDSTPORT| \
INP_RECVRTABLE)
#define INP_IPV6 0x100
#define IN6P_HIGHPORT INP_HIGHPORT
#define IN6P_LOWPORT INP_LOWPORT
#define IN6P_RECVDSTPORT INP_RECVDSTPORT
#define IN6P_PKTINFO 0x010000
#define IN6P_HOPLIMIT 0x020000
#define IN6P_HOPOPTS 0x040000
#define IN6P_DSTOPTS 0x080000
#define IN6P_RTHDR 0x100000
#define IN6P_TCLASS 0x400000
#define IN6P_AUTOFLOWLABEL 0x800000
#define IN6P_ANONPORT 0x4000000
#define IN6P_RFC2292 0x40000000
#define IN6P_MTU 0x80000000
#define IN6P_MINMTU 0x20000000
#define IN6P_CONTROLOPTS (IN6P_PKTINFO|IN6P_HOPLIMIT|IN6P_HOPOPTS|\
IN6P_DSTOPTS|IN6P_RTHDR|\
IN6P_TCLASS|IN6P_AUTOFLOWLABEL|IN6P_RFC2292|\
IN6P_MTU|IN6P_RECVDSTPORT)
#define INPLOOKUP_WILDCARD 1
#define INPLOOKUP_SETLOCAL 2
#define INPLOOKUP_IPV6 4
#define sotoinpcb(so) ((struct inpcb *)(so)->so_pcb)
#define DP_MAPBITS (sizeof(u_int32_t) * NBBY)
#define DP_MAPSIZE (howmany(65536, DP_MAPBITS))
#define DP_SET(m, p) ((m)[(p) / DP_MAPBITS] |= (1U << ((p) % DP_MAPBITS)))
#define DP_CLR(m, p) ((m)[(p) / DP_MAPBITS] &= ~(1U << ((p) % DP_MAPBITS)))
#define DP_ISSET(m, p) ((m)[(p) / DP_MAPBITS] & (1U << ((p) % DP_MAPBITS)))
#define DEFBADDYNAMICPORTS_TCP { \
587, 749, 750, 751, 853, 871, 2049, \
6000, 6001, 6002, 6003, 6004, 6005, 6006, 6007, 6008, 6009, 6010, \
0 }
#define DEFBADDYNAMICPORTS_UDP { 623, 664, 749, 750, 751, 2049, \
3784, 3785, 7784, \
0 }
#define DEFROOTONLYPORTS_TCP { \
2049, \
0 }
#define DEFROOTONLYPORTS_UDP { \
2049, \
0 }
struct baddynamicports {
u_int32_t tcp[DP_MAPSIZE];
u_int32_t udp[DP_MAPSIZE];
};
#ifdef _KERNEL
#define IN_PCBLOCK_HOLD 1
#define IN_PCBLOCK_GRAB 2
extern struct inpcbtable rawcbtable, rawin6pcbtable;
extern struct baddynamicports baddynamicports;
extern struct baddynamicports rootonlyports;
extern int in_pcbnotifymiss;
void in_init(void);
void in_losing(struct inpcb *);
int in_pcballoc(struct socket *, struct inpcbtable *, int);
int in_pcbbind_locked(struct inpcb *, struct mbuf *, const void *,
struct proc *);
int in_pcbbind(struct inpcb *, struct mbuf *, struct proc *);
int in_pcbaddrisavail(const struct inpcb *, struct sockaddr_in *, int,
struct proc *);
int in_pcbconnect(struct inpcb *, struct mbuf *);
void in_pcbdetach(struct inpcb *);
struct socket *
in_pcbsolock(struct inpcb *);
void in_pcbsounlock(struct inpcb *, struct socket *);
struct inpcb *
in_pcbref(struct inpcb *);
void in_pcbunref(struct inpcb *);
void in_pcbdisconnect(struct inpcb *);
struct inpcb *
in_pcb_iterator(struct inpcbtable *, struct inpcb *,
struct inpcb_iterator *);
void in_pcb_iterator_abort(struct inpcbtable *, struct inpcb *,
struct inpcb_iterator *);
struct inpcb *
in_pcblookup(struct inpcbtable *, struct in_addr, u_int,
struct in_addr, u_int, u_int);
struct inpcb *
in_pcblookup_listen(struct inpcbtable *, struct in_addr, u_int,
struct mbuf *, u_int);
#ifdef INET6
uint64_t in6_pcbhash(struct inpcbtable *, u_int, const struct in6_addr *,
u_short, const struct in6_addr *, u_short);
struct inpcb *
in6_pcblookup(struct inpcbtable *, const struct in6_addr *,
u_int, const struct in6_addr *, u_int, u_int);
struct inpcb *
in6_pcblookup_listen(struct inpcbtable *, struct in6_addr *, u_int,
struct mbuf *, u_int);
int in6_pcbaddrisavail_lock(const struct inpcb *, struct sockaddr_in6 *,
int, struct proc *, int);
int in6_pcbaddrisavail(const struct inpcb *, struct sockaddr_in6 *, int,
struct proc *);
int in6_pcbconnect(struct inpcb *, struct mbuf *);
void in6_setsockaddr(struct inpcb *, struct mbuf *);
void in6_setpeeraddr(struct inpcb *, struct mbuf *);
int in6_sockaddr(struct socket *, struct mbuf *);
int in6_peeraddr(struct socket *, struct mbuf *);
#endif
void in_pcbinit(struct inpcbtable *, int);
struct inpcb *
in_pcblookup_local_lock(struct inpcbtable *, const void *, u_int, int,
u_int, int);
void in_pcbnotifyall(struct inpcbtable *, const struct sockaddr_in *,
u_int, int, void (*)(struct inpcb *, int));
void in_pcbrehash(struct inpcb *);
void in_pcbrtchange(struct inpcb *, int);
void in_setpeeraddr(struct inpcb *, struct mbuf *);
void in_setsockaddr(struct inpcb *, struct mbuf *);
int in_sockaddr(struct socket *, struct mbuf *);
int in_peeraddr(struct socket *, struct mbuf *);
int in_flowid(struct socket *);
int in_baddynamic(u_int16_t, u_int16_t);
int in_rootonly(u_int16_t, u_int16_t);
int in_pcbselsrc(struct in_addr *, const struct sockaddr_in *,
struct inpcb *);
struct rtentry *
in_pcbrtentry(struct inpcb *);
struct rtentry *
in6_pcbrtentry(struct inpcb *);
void in6_pcbnotify(struct inpcbtable *, const struct sockaddr_in6 *,
u_int, const struct sockaddr_in6 *, u_int, u_int, int, void *,
void (*)(struct inpcb *, int));
int in6_selecthlim(const struct inpcb *);
int in_pcbset_rtableid(struct inpcb *, u_int);
int in_pcbset_addr(struct inpcb *, const struct sockaddr *,
const struct sockaddr *, u_int);
int in6_pcbset_addr(struct inpcb *, const struct sockaddr_in6 *,
const struct sockaddr_in6 *, u_int);
void in_pcbunset_faddr(struct inpcb *);
void in_pcbunset_laddr(struct inpcb *);
#endif
#endif