diff --git a/bpf_filter.c b/bpf_filter.c index 1a8ae8c843..ebfd23dd3d 100644 --- a/bpf_filter.c +++ b/bpf_filter.c @@ -82,7 +82,8 @@ enum { * * Thanks to Ani Sinha for providing initial implementation */ -#if defined(SKF_AD_VLAN_TAG_PRESENT) +/* Npcap does not provide auxiliary data */ +#if defined(SKF_AD_VLAN_TAG_PRESENT) && !defined(NPCAP_AD_VLAN_TAG_PRESENT) u_int pcapint_filter_with_aux_data(const struct bpf_insn *pc, const u_char *p, u_int wirelen, u_int buflen, const struct pcap_bpf_aux_data *aux_data) @@ -142,7 +143,7 @@ pcapint_filter_with_aux_data(const struct bpf_insn *pc, const u_char *p, DIAG_OFF_DEFAULT_ONLY_SWITCH switch (pc->k) { -#if defined(SKF_AD_VLAN_TAG_PRESENT) +#if defined(SKF_AD_VLAN_TAG_PRESENT) && !defined(NPCAP_AD_VLAN_TAG_PRESENT) case SKF_AD_OFF + SKF_AD_VLAN_TAG: if (!aux_data) return 0; diff --git a/bpf_image.c b/bpf_image.c index c23d1313a7..17e296999f 100644 --- a/bpf_image.c +++ b/bpf_image.c @@ -48,11 +48,18 @@ #include "os-proto.h" #endif -#ifdef SKF_AD_OFF +#if defined(SKF_AD_OFF) || defined(NPCAP_AD_OFF) /* - * Symbolic names for offsets that refer to the special Linux BPF locations. + * Symbolic names for special offsets that refer to platform-specific BPF extensions. */ -static const char *offsets[SKF_AD_MAX] = { +#ifdef NPCAP_AD_MAX +#define BPFEXT_AD_OFF NPCAP_AD_OFF +#define BPFEXT_AD_MAX NPCAP_AD_MAX +#else +#define BPFEXT_AD_OFF SKF_AD_OFF +#define BPFEXT_AD_MAX SKF_AD_MAX +#endif +static const char *offsets[BPFEXT_AD_MAX] = { #ifdef SKF_AD_PROTOCOL [SKF_AD_PROTOCOL] = "proto", #endif @@ -86,10 +93,14 @@ static const char *offsets[SKF_AD_MAX] = { #ifdef SKF_AD_ALU_XOR_X [SKF_AD_ALU_XOR_X] = "xor_x", #endif -#ifdef SKF_AD_VLAN_TAG +#ifdef NPCAP_AD_VLAN_TAG + [NPCAP_AD_VLAN_TAG] = "vlan_tci", +#elif defined(SKF_AD_VLAN_TAG) [SKF_AD_VLAN_TAG] = "vlan_tci", #endif -#ifdef SKF_AD_VLAN_TAG_PRESENT +#ifdef NPCAP_AD_VLAN_TAG_PRESENT + [NPCAP_AD_VLAN_TAG_PRESENT] = "vlanp", +#elif defined(SKF_AD_VLAN_TAG_PRESENT) [SKF_AD_VLAN_TAG_PRESENT] = "vlanp", #endif #ifdef SKF_AD_PAY_OFFSET @@ -107,16 +118,16 @@ static const char *offsets[SKF_AD_MAX] = { static void bpf_print_abs_load_operand(char *buf, size_t bufsize, const struct bpf_insn *p) { -#ifdef SKF_AD_OFF +#ifdef BPFEXT_AD_OFF const char *sym; /* * It's an absolute load. * Is the offset a special Linux offset that we know about? */ - if (p->k >= (bpf_u_int32)SKF_AD_OFF && - p->k < (bpf_u_int32)(SKF_AD_OFF + SKF_AD_MAX) && - (sym = offsets[p->k - (bpf_u_int32)SKF_AD_OFF]) != NULL) { + if (p->k >= (bpf_u_int32)BPFEXT_AD_OFF && + p->k < (bpf_u_int32)(BPFEXT_AD_OFF + BPFEXT_AD_MAX) && + (sym = offsets[p->k - (bpf_u_int32)BPFEXT_AD_OFF]) != NULL) { /* * Yes. Print the offset symbolically. */ diff --git a/gencode.c b/gencode.c index b2e092f475..ab5b96f419 100644 --- a/gencode.c +++ b/gencode.c @@ -9222,6 +9222,13 @@ gen_vlan_no_bpf_extensions(compiler_state_t *cstate, bpf_u_int32 vlan_num, return b0; } +/* Npcap defines these constants in a way that is compatible with Linux, as + * long as no assumptions are made about the value or ordering. */ +#if defined(NPCAP_AD_OFF) && !defined(SKF_AD_OFF) +#define SKF_AD_OFF NPCAP_AD_OFF +#define SKF_AD_VLAN_TAG NPCAP_AD_VLAN_TAG +#define SKF_AD_VLAN_TAG_PRESENT NPCAP_AD_VLAN_TAG_PRESENT +#endif #if defined(SKF_AD_VLAN_TAG_PRESENT) /* add v to variable part of off */ static void @@ -9418,7 +9425,7 @@ gen_vlan(compiler_state_t *cstate, bpf_u_int32 vlan_num, int has_vlan_tag) * * This requires special treatment. */ -#if defined(SKF_AD_VLAN_TAG_PRESENT) +#if defined(SKF_AD_VLAN_TAG_PRESENT) || defined(NPCAP_AD_VLAN_TAG_PRESENT) /* Verify that this is the outer part of the packet and * not encapsulated somehow. */ if (cstate->vlan_stack_depth == 0 && !cstate->off_linkhdr.is_variable && diff --git a/pcap-npf.c b/pcap-npf.c index 4feee30cfd..dc7d03e5d4 100644 --- a/pcap-npf.c +++ b/pcap-npf.c @@ -1090,13 +1090,18 @@ pcap_activate_npf(pcap_t *p) } #endif /* HAVE_PACKET_GET_TIMESTAMP_MODES */ -#if defined(HAVE_PACKET_GET_INFO) && defined(NPF_GETINFO_BPFEXT) && defined(SKF_AD_VLAN_TAG_PRESENT) +/* Npcap SDK 1.15 defined SKF_AD_* constants; later versions prefer NPCAP_AD_* */ +#if !defined(NPCAP_AD_VLAN_TAG_PRESENT) && defined(SKF_AD_VLAN_TAG_PRESENT) +#define NPCAP_AD_VLAN_TAG_PRESENT SKF_AD_VLAN_TAG_PRESENT +#endif + +#if defined(HAVE_PACKET_GET_INFO) && defined(NPF_GETINFO_BPFEXT) && defined(NPCAP_AD_VLAN_TAG_PRESENT) /* Can we generate special code for VLAN checks? */ oid_data_arg->Oid = NPF_GETINFO_BPFEXT; oid_data_arg->Length = sizeof(ULONG); if (PacketGetInfo(pw->adapter, oid_data_arg)) { - if (*((ULONG *)oid_data_arg->Data) >= SKF_AD_VLAN_TAG_PRESENT) { + if (*((ULONG *)oid_data_arg->Data) >= NPCAP_AD_VLAN_TAG_PRESENT) { /* Yes, we can. Request that we do so. */ p->bpf_codegen_flags |= BPF_SPECIAL_VLAN_HANDLING; }