#ifndef _NET_BPF_H_
#define _NET_BPF_H_
#include <sys/ioccom.h>
#include <sys/time.h>
#define BPF_RELEASE 199606
#define BPF_COP_EXTMEM_RELEASE 20140624
__BEGIN_DECLS
typedef int bpf_int32;
typedef u_int bpf_u_int32;
#define BPF_ALIGNMENT sizeof(long)
#define BPF_ALIGNMENT32 sizeof(int)
#define BPF_WORDALIGN(x) (((x)+(BPF_ALIGNMENT-1))&~(BPF_ALIGNMENT-1))
#define BPF_WORDALIGN32(x) (((x)+(BPF_ALIGNMENT32-1))&~(BPF_ALIGNMENT32-1))
#define BPF_MAXINSNS 512
#define BPF_DFLTBUFSIZE (1024*1024)
#define BPF_MAXBUFSIZE (1024*1024*16)
#define BPF_MINBUFSIZE 32
struct bpf_program {
u_int bf_len;
struct bpf_insn *bf_insns;
};
struct bpf_stat {
uint64_t bs_recv;
uint64_t bs_drop;
uint64_t bs_capt;
uint64_t bs_padding[13];
};
struct bpf_stat30 {
u_int bs_recv;
u_int bs_drop;
};
struct bpf_version {
u_short bv_major;
u_short bv_minor;
};
#define BPF_MAJOR_VERSION 1
#define BPF_MINOR_VERSION 1
#define BIOCGBLEN _IOR('B', 102, u_int)
#define BIOCSBLEN _IOWR('B', 102, u_int)
#define BIOCSETF _IOW('B', 103, struct bpf_program)
#define BIOCFLUSH _IO('B', 104)
#define BIOCPROMISC _IO('B', 105)
#define BIOCGDLT _IOR('B', 106, u_int)
#define BIOCGETIF _IOR('B', 107, struct ifreq)
#define BIOCSETIF _IOW('B', 108, struct ifreq)
#ifdef COMPAT_50
#include <compat/sys/time.h>
#define BIOCSORTIMEOUT _IOW('B', 109, struct timeval50)
#define BIOCGORTIMEOUT _IOR('B', 110, struct timeval50)
#endif
#define BIOCGSTATS _IOR('B', 111, struct bpf_stat)
#define BIOCGSTATS_30 _IOR('B', 111, struct bpf_stat30)
#define BIOCIMMEDIATE _IOW('B', 112, u_int)
#define BIOCVERSION _IOR('B', 113, struct bpf_version)
#define BIOCSTCPF _IOW('B', 114, struct bpf_program)
#define BIOCSUDPF _IOW('B', 115, struct bpf_program)
#define BIOCGHDRCMPLT _IOR('B', 116, u_int)
#define BIOCSHDRCMPLT _IOW('B', 117, u_int)
#define BIOCSDLT _IOW('B', 118, u_int)
#define BIOCGDLTLIST _IOWR('B', 119, struct bpf_dltlist)
#define BIOCGDIRECTION _IOR('B', 120, u_int)
#define BIOCSDIRECTION _IOW('B', 121, u_int)
#define BIOCSRTIMEOUT _IOW('B', 122, struct timeval)
#define BIOCGRTIMEOUT _IOR('B', 123, struct timeval)
#define BIOCGFEEDBACK _IOR('B', 124, u_int)
#define BIOCSFEEDBACK _IOW('B', 125, u_int)
#define BIOCFEEDBACK BIOCSFEEDBACK
#define BIOCLOCK _IO('B', 126)
#define BIOCSETWF _IOW('B', 127, struct bpf_program)
#define BIOCGSEESENT BIOCGDIRECTION
#define BIOCSSEESENT BIOCSDIRECTION
#define BPF_D_IN 0
#define BPF_D_INOUT 1
#define BPF_D_OUT 2
struct bpf_timeval {
long tv_sec;
long tv_usec;
};
struct bpf_timeval32 {
int32_t tv_sec;
int32_t tv_usec;
};
struct bpf_hdr {
struct bpf_timeval bh_tstamp;
uint32_t bh_caplen;
uint32_t bh_datalen;
uint16_t bh_hdrlen;
};
struct bpf_hdr32 {
struct bpf_timeval32 bh_tstamp;
uint32_t bh_caplen;
uint32_t bh_datalen;
uint16_t bh_hdrlen;
};
#ifdef _KERNEL
#if defined(__mips64)
#define SIZEOF_BPF_HDR sizeof(struct bpf_hdr)
#define SIZEOF_BPF_HDR32 18
#elif defined(__arm32__) || defined(__i386__) || defined(__m68k__) || \
defined(__mips__) || defined(__ns32k__) || defined(__vax__) || \
defined(__sh__) || (defined(__sparc__) && !defined(__sparc64__))
#define SIZEOF_BPF_HDR 18
#define SIZEOF_BPF_HDR32 18
#else
#define SIZEOF_BPF_HDR sizeof(struct bpf_hdr)
#define SIZEOF_BPF_HDR32 sizeof(struct bpf_hdr32)
#endif
#endif
#include <net/dlt.h>
#define BPF_CLASS(code) ((code) & 0x07)
#define BPF_LD 0x00
#define BPF_LDX 0x01
#define BPF_ST 0x02
#define BPF_STX 0x03
#define BPF_ALU 0x04
#define BPF_JMP 0x05
#define BPF_RET 0x06
#define BPF_MISC 0x07
#define BPF_SIZE(code) ((code) & 0x18)
#define BPF_W 0x00
#define BPF_H 0x08
#define BPF_B 0x10
#define BPF_MODE(code) ((code) & 0xe0)
#define BPF_IMM 0x00
#define BPF_ABS 0x20
#define BPF_IND 0x40
#define BPF_MEM 0x60
#define BPF_LEN 0x80
#define BPF_MSH 0xa0
#define BPF_OP(code) ((code) & 0xf0)
#define BPF_ADD 0x00
#define BPF_SUB 0x10
#define BPF_MUL 0x20
#define BPF_DIV 0x30
#define BPF_OR 0x40
#define BPF_AND 0x50
#define BPF_LSH 0x60
#define BPF_RSH 0x70
#define BPF_NEG 0x80
#define BPF_MOD 0x90
#define BPF_XOR 0xa0
#define BPF_JA 0x00
#define BPF_JEQ 0x10
#define BPF_JGT 0x20
#define BPF_JGE 0x30
#define BPF_JSET 0x40
#define BPF_SRC(code) ((code) & 0x08)
#define BPF_K 0x00
#define BPF_X 0x08
#define BPF_RVAL(code) ((code) & 0x18)
#define BPF_A 0x10
#define BPF_MISCOP(code) ((code) & 0xf8)
#define BPF_TAX 0x00
#define BPF_COP 0x20
#define BPF_COPX 0x40
#define BPF_TXA 0x80
struct bpf_insn {
uint16_t code;
u_char jt;
u_char jf;
uint32_t k;
};
struct bpf_aux_data {
u_short vlan_tag_present;
u_short vlan_tag;
};
#define BPF_STMT(code, k) { (uint16_t)(code), 0, 0, k }
#define BPF_JUMP(code, k, jt, jf) { (uint16_t)(code), jt, jf, k }
#define BPF_MEMWORDS 16
typedef uint32_t bpf_memword_init_t;
#define BPF_MEMWORD_INIT(k) (UINT32_C(1) << (k))
__CTASSERT(BPF_MEMWORDS + 2 <= sizeof(bpf_memword_init_t) * NBBY);
#ifdef _KERNEL
#define BPF_MAX_MEMWORDS 30
__CTASSERT(BPF_MAX_MEMWORDS >= BPF_MEMWORDS);
__CTASSERT(BPF_MAX_MEMWORDS + 2 <= sizeof(bpf_memword_init_t) * NBBY);
#endif
struct bpf_dltlist {
u_int bfl_len;
u_int *bfl_list;
};
struct bpf_ctx;
typedef struct bpf_ctx bpf_ctx_t;
typedef struct bpf_args {
const uint8_t * pkt;
size_t wirelen;
size_t buflen;
uint32_t * mem;
void * arg;
} bpf_args_t;
#if defined(_KERNEL) || defined(__BPF_PRIVATE)
typedef uint32_t (*bpf_copfunc_t)(const bpf_ctx_t *, bpf_args_t *, uint32_t);
struct bpf_ctx {
const bpf_copfunc_t * copfuncs;
size_t nfuncs;
size_t extwords;
bpf_memword_init_t preinited;
};
#endif
#ifdef _KERNEL
#include <net/bpfjit.h>
#include <net/if.h>
struct bpf_if;
struct bpf_ops {
void (*bpf_attach)(struct ifnet *, u_int, u_int, struct bpf_if **);
void (*bpf_detach)(struct ifnet *);
void (*bpf_change_type)(struct ifnet *, u_int, u_int);
void (*bpf_mtap)(struct bpf_if *, struct mbuf *, u_int);
void (*bpf_mtap2)(struct bpf_if *, void *, u_int, struct mbuf *,
u_int);
void (*bpf_mtap_af)(struct bpf_if *, uint32_t, struct mbuf *, u_int);
void (*bpf_mtap_sl_in)(struct bpf_if *, u_char *, struct mbuf **);
void (*bpf_mtap_sl_out)(struct bpf_if *, u_char *, struct mbuf *);
void (*bpf_mtap_softint_init)(struct ifnet *);
void (*bpf_mtap_softint)(struct ifnet *, struct mbuf *);
int (*bpf_register_track_event)(struct bpf_if **,
void (*)(struct bpf_if *, struct ifnet *, int, int));
int (*bpf_deregister_track_event)(struct bpf_if **,
void (*)(struct bpf_if *, struct ifnet *, int, int));
};
extern struct bpf_ops *bpf_ops;
static __inline void
bpf_attach(struct ifnet *_ifp, u_int _dlt, u_int _hdrlen)
{
bpf_ops->bpf_attach(_ifp, _dlt, _hdrlen, &_ifp->if_bpf);
}
static __inline void
bpf_attach2(struct ifnet *_ifp, u_int _dlt, u_int _hdrlen, struct bpf_if **_dp)
{
bpf_ops->bpf_attach(_ifp, _dlt, _hdrlen, _dp);
}
static __inline void
bpf_mtap(struct ifnet *_ifp, struct mbuf *_m, u_int _direction)
{
if (_ifp->if_bpf) {
if (_ifp->if_bpf_mtap) {
_ifp->if_bpf_mtap(_ifp->if_bpf, _m, _direction);
} else {
bpf_ops->bpf_mtap(_ifp->if_bpf, _m, _direction);
}
}
}
static __inline void
bpf_mtap2(struct bpf_if *_bpf, void *_data, u_int _dlen, struct mbuf *_m,
u_int _direction)
{
bpf_ops->bpf_mtap2(_bpf, _data, _dlen, _m, _direction);
}
static __inline void
bpf_mtap3(struct bpf_if *_bpf, struct mbuf *_m, u_int _direction)
{
if (_bpf)
bpf_ops->bpf_mtap(_bpf, _m, _direction);
}
static __inline void
bpf_mtap_af(struct ifnet *_ifp, uint32_t _af, struct mbuf *_m,
u_int _direction)
{
if (_ifp->if_bpf)
bpf_ops->bpf_mtap_af(_ifp->if_bpf, _af, _m, _direction);
}
static __inline void
bpf_change_type(struct ifnet *_ifp, u_int _dlt, u_int _hdrlen)
{
bpf_ops->bpf_change_type(_ifp, _dlt, _hdrlen);
}
static __inline bool
bpf_peers_present(struct bpf_if *dp)
{
return dp != NULL;
}
static __inline void
bpf_detach(struct ifnet *_ifp)
{
bpf_ops->bpf_detach(_ifp);
}
static __inline void
bpf_mtap_sl_in(struct ifnet *_ifp, u_char *_hdr, struct mbuf **_m)
{
bpf_ops->bpf_mtap_sl_in(_ifp->if_bpf, _hdr, _m);
}
static __inline void
bpf_mtap_sl_out(struct ifnet *_ifp, u_char *_hdr, struct mbuf *_m)
{
if (_ifp->if_bpf)
bpf_ops->bpf_mtap_sl_out(_ifp->if_bpf, _hdr, _m);
}
static __inline void
bpf_mtap_softint_init(struct ifnet *_ifp)
{
bpf_ops->bpf_mtap_softint_init(_ifp);
}
static __inline void
bpf_mtap_softint(struct ifnet *_ifp, struct mbuf *_m)
{
if (_ifp->if_bpf)
bpf_ops->bpf_mtap_softint(_ifp, _m);
}
static __inline int
bpf_register_track_event(struct bpf_if **_dp,
void (*_fun)(struct bpf_if *, struct ifnet *, int, int))
{
if (bpf_ops->bpf_register_track_event == NULL)
return ENXIO;
return bpf_ops->bpf_register_track_event(_dp, _fun);
}
static __inline int
bpf_deregister_track_event(struct bpf_if **_dp,
void (*_fun)(struct bpf_if *, struct ifnet *, int, int))
{
if (bpf_ops->bpf_deregister_track_event == NULL)
return ENXIO;
return bpf_ops->bpf_deregister_track_event(_dp, _fun);
}
void bpf_setops(void);
void bpf_ops_handover_enter(struct bpf_ops *);
void bpf_ops_handover_exit(void);
void bpfilterattach(int);
bpf_ctx_t *bpf_create(void);
void bpf_destroy(bpf_ctx_t *);
int bpf_set_cop(bpf_ctx_t *, const bpf_copfunc_t *, size_t);
int bpf_set_extmem(bpf_ctx_t *, size_t, bpf_memword_init_t);
u_int bpf_filter_ext(const bpf_ctx_t *, const struct bpf_insn *, bpf_args_t *);
int bpf_validate_ext(const bpf_ctx_t *, const struct bpf_insn *, int);
bpfjit_func_t bpf_jit_generate(bpf_ctx_t *, void *, size_t);
void bpf_jit_freecode(bpfjit_func_t);
#endif
int bpf_validate(const struct bpf_insn *, int);
u_int bpf_filter(const struct bpf_insn *, const u_char *, u_int, u_int);
u_int bpf_filter_with_aux_data(const struct bpf_insn *, const u_char *, u_int, u_int, const struct bpf_aux_data *);
#define BPF_TRACK_EVENT_ATTACH 1
#define BPF_TRACK_EVENT_DETACH 2
void bpf_dump(const struct bpf_program *, int);
char *bpf_image(const struct bpf_insn *, int);
__END_DECLS
#if 1
#define BIOCGSTATSOLD BIOCGSTATS_30
#define bpf_stat_old bpf_stat30
#endif
#endif