Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix "pppoes" filter for links with variable-length prefix to link header #835

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 20 additions & 29 deletions gencode.c
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ struct addrinfo {
{ \
(cs)->prevlinktype = (cs)->linktype; \
(cs)->off_prevlinkhdr = (cs)->off_linkhdr; \
(cs)->off_outermostlinkhdr = &((cs)->off_prevlinkhdr); \
(cs)->linktype = (new_linktype); \
(cs)->off_linkhdr.is_variable = (new_is_variable); \
(cs)->off_linkhdr.constant_part = (new_constant_part); \
Expand Down Expand Up @@ -302,10 +303,9 @@ struct _compiler_state {
bpf_abs_offset off_prevlinkhdr;

/*
* This is the equivalent information for the outermost layers'
* link-layer header.
* This is a pointer to either off_linkhdr of off_prevlinkhdr.
*/
bpf_abs_offset off_outermostlinkhdr;
bpf_abs_offset *off_outermostlinkhdr;

/*
* Absolute offset of the beginning of the link-layer payload.
Expand Down Expand Up @@ -1140,14 +1140,7 @@ init_linktype(compiler_state_t *cstate, pcap_t *p)
* We start out with only one link-layer header.
*/
cstate->outermostlinktype = pcap_datalink(p);
cstate->off_outermostlinkhdr.constant_part = 0;
cstate->off_outermostlinkhdr.is_variable = 0;
cstate->off_outermostlinkhdr.reg = -1;

cstate->prevlinktype = cstate->outermostlinktype;
cstate->off_prevlinkhdr.constant_part = 0;
cstate->off_prevlinkhdr.is_variable = 0;
cstate->off_prevlinkhdr.reg = -1;
cstate->off_outermostlinkhdr = &(cstate->off_linkhdr);

cstate->linktype = cstate->outermostlinktype;
cstate->off_linkhdr.constant_part = 0;
Expand Down Expand Up @@ -1721,7 +1714,6 @@ init_linktype(compiler_state_t *cstate, pcap_t *p)
break;
}

cstate->off_outermostlinkhdr = cstate->off_prevlinkhdr = cstate->off_linkhdr;
return (0);
}

Expand Down Expand Up @@ -2370,7 +2362,7 @@ gen_load_prism_llprefixlen(compiler_state_t *cstate)
* but no known software generates headers that aren't 144
* bytes long.
*/
if (cstate->off_linkhdr.reg != -1) {
if (cstate->off_outermostlinkhdr->reg != -1) {
/*
* Load the cookie.
*/
Expand Down Expand Up @@ -2432,7 +2424,7 @@ gen_load_prism_llprefixlen(compiler_state_t *cstate)
* loading the length of the AVS header.
*/
s2 = new_stmt(cstate, BPF_ST);
s2->s.k = cstate->off_linkhdr.reg;
s2->s.k = cstate->off_outermostlinkhdr->reg;
sappend(s1, s2);
sjcommon->s.jf = s2;

Expand All @@ -2459,7 +2451,7 @@ gen_load_avs_llprefixlen(compiler_state_t *cstate)
* generated uses that prefix, so we don't need to generate any
* code to load it.)
*/
if (cstate->off_linkhdr.reg != -1) {
if (cstate->off_outermostlinkhdr->reg != -1) {
/*
* The 4 bytes at an offset of 4 from the beginning of
* the AVS header are the length of the AVS header.
Expand All @@ -2473,7 +2465,7 @@ gen_load_avs_llprefixlen(compiler_state_t *cstate)
* it.
*/
s2 = new_stmt(cstate, BPF_ST);
s2->s.k = cstate->off_linkhdr.reg;
s2->s.k = cstate->off_outermostlinkhdr->reg;
sappend(s1, s2);

/*
Expand All @@ -2499,7 +2491,7 @@ gen_load_radiotap_llprefixlen(compiler_state_t *cstate)
* generated uses that prefix, so we don't need to generate any
* code to load it.)
*/
if (cstate->off_linkhdr.reg != -1) {
if (cstate->off_outermostlinkhdr->reg != -1) {
/*
* The 2 bytes at offsets of 2 and 3 from the beginning
* of the radiotap header are the length of the radiotap
Expand Down Expand Up @@ -2534,7 +2526,7 @@ gen_load_radiotap_llprefixlen(compiler_state_t *cstate)
* it.
*/
s2 = new_stmt(cstate, BPF_ST);
s2->s.k = cstate->off_linkhdr.reg;
s2->s.k = cstate->off_outermostlinkhdr->reg;
sappend(s1, s2);

/*
Expand Down Expand Up @@ -2567,7 +2559,7 @@ gen_load_ppi_llprefixlen(compiler_state_t *cstate)
* into the register assigned to hold that length, if one has
* been assigned.
*/
if (cstate->off_linkhdr.reg != -1) {
if (cstate->off_outermostlinkhdr->reg != -1) {
/*
* The 2 bytes at offsets of 2 and 3 from the beginning
* of the radiotap header are the length of the radiotap
Expand Down Expand Up @@ -2602,7 +2594,7 @@ gen_load_ppi_llprefixlen(compiler_state_t *cstate)
* it.
*/
s2 = new_stmt(cstate, BPF_ST);
s2->s.k = cstate->off_linkhdr.reg;
s2->s.k = cstate->off_outermostlinkhdr->reg;
sappend(s1, s2);

/*
Expand Down Expand Up @@ -2659,7 +2651,7 @@ gen_load_802_11_header_len(compiler_state_t *cstate, struct slist *s, struct sli
* header.
*
* Otherwise, the length of the prefix preceding the link-layer
* header is "off_outermostlinkhdr.constant_part".
* header is "off_outermostlinkhdr->constant_part".
*/
if (s == NULL) {
/*
Expand All @@ -2669,10 +2661,10 @@ gen_load_802_11_header_len(compiler_state_t *cstate, struct slist *s, struct sli
* Load the length of the fixed-length prefix preceding
* the link-layer header (if any) into the X register,
* and store it in the cstate->off_linkpl.reg register.
* That length is off_outermostlinkhdr.constant_part.
* That length is off_outermostlinkhdr->constant_part.
*/
s = new_stmt(cstate, BPF_LDX|BPF_IMM);
s->s.k = cstate->off_outermostlinkhdr.constant_part;
s->s.k = cstate->off_outermostlinkhdr->constant_part;
}

/*
Expand Down Expand Up @@ -2758,7 +2750,7 @@ gen_load_802_11_header_len(compiler_state_t *cstate, struct slist *s, struct sli
* annoying padding don't have multiple antennae and therefore
* do not generate radiotap headers with multiple presence words.
*/
if (cstate->linktype == DLT_IEEE802_11_RADIO) {
if (cstate->outermostlinktype == DLT_IEEE802_11_RADIO) {
/*
* Is the IEEE80211_RADIOTAP_FLAGS bit (0x0000002) set
* in the first presence flag word?
Expand Down Expand Up @@ -2872,9 +2864,9 @@ insert_compute_vloffsets(compiler_state_t *cstate, struct block *b)
* includes the variable part of the header. Therefore,
* if nobody else has allocated a register for the link
* header and we need it, do it now. */
if (cstate->off_linkpl.reg != -1 && cstate->off_linkhdr.is_variable &&
cstate->off_linkhdr.reg == -1)
cstate->off_linkhdr.reg = alloc_reg(cstate);
if (cstate->off_linkpl.reg != -1 && cstate->off_outermostlinkhdr->is_variable &&
cstate->off_outermostlinkhdr->reg == -1)
cstate->off_outermostlinkhdr->reg = alloc_reg(cstate);

/*
* For link-layer types that have a variable-length header
Expand Down Expand Up @@ -8956,8 +8948,7 @@ gen_vlan(compiler_state_t *cstate, bpf_u_int32 vlan_num, int has_vlan_tag)
/* 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 &&
cstate->off_linkhdr.constant_part ==
cstate->off_outermostlinkhdr.constant_part) {
cstate->off_outermostlinkhdr == &(cstate->off_linkhdr)) {
/*
* Do we need special VLAN handling?
*/
Expand Down