Skip to content

WIP/RFC: add support for manual link layer offset changes #1477

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

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
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
8 changes: 8 additions & 0 deletions gencode.c
Original file line number Diff line number Diff line change
Expand Up @@ -10712,3 +10712,11 @@ gen_atmmulti_abbrev(compiler_state_t *cstate, int type)
}
return b1;
}

struct block *gen_offset_adjustment(compiler_state_t *cstate, int n) {
struct block *b = new_block(cstate, BPF_JMP|BPF_JA);
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I couldn't think of a better way of generating a "noop" block. I tried BPF_ALU|BPF_ADD|BPF_K with a value of 0, but the optimizer turned it into an unimplemented operator with an operand of 0xffff.

This is an odd ball in pcap-filter syntax, since it doesn't "check" for anything; it's an "always true" term that controls parsing rather than checking anything. But without returning a block something like offset+6 and host 192.0.2.68 would never work, since and assumes a block on both sides (as best I can tell). Returning NULL or nothing doesn't really work.

b->s.k = 0; // Jump by 0 bytes, effectively a no-op
cstate->off_linkpl.constant_part += n;
cstate->off_linktype.constant_part += n;
return b;
}
2 changes: 2 additions & 0 deletions gencode.h
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,8 @@ struct block *gen_pf_action(compiler_state_t *, int);
struct block *gen_p80211_type(compiler_state_t *, bpf_u_int32, bpf_u_int32);
struct block *gen_p80211_fcdir(compiler_state_t *, bpf_u_int32);

struct block *gen_offset_adjustment(compiler_state_t*, int);

/*
* Representation of a program as a tree of blocks, plus current mark.
* A block is marked if only if its mark equals the current mark.
Expand Down
5 changes: 5 additions & 0 deletions grammar.y.in
Original file line number Diff line number Diff line change
Expand Up @@ -401,12 +401,14 @@ DIAG_OFF_BISON_BYACC
%token RADIO
%token FISU LSSU MSU HFISU HLSSU HMSU
%token SIO OPC DPC SLS HSIO HOPC HDPC HSLS
%token OFFSET OFFSET_PLUS OFFSET_MINUS
%token LEX_ERROR

%type <s> ID EID AID
%type <s> HID HID6
%type <h> NUM
%type <i> action reason type subtype type_subtype dir
%type <h> OFFSET_PLUS OFFSET_MINUS

%left OR AND
%nonassoc '!'
Expand Down Expand Up @@ -689,6 +691,8 @@ other: pqual TK_BROADCAST { CHECK_PTR_VAL(($$ = gen_broadcast(cstate, $1))); }
| GENEVE { CHECK_PTR_VAL(($$ = gen_geneve(cstate, 0, 0))); }
| VXLAN pnum { CHECK_PTR_VAL(($$ = gen_vxlan(cstate, $2, 1))); }
| VXLAN { CHECK_PTR_VAL(($$ = gen_vxlan(cstate, 0, 0))); }
| OFFSET OFFSET_PLUS { CHECK_PTR_VAL(($$ = gen_offset_adjustment(cstate, $2))); }
| OFFSET OFFSET_MINUS { CHECK_PTR_VAL(($$ = gen_offset_adjustment(cstate, -$2))); }
| pfvar { $$ = $1; }
| pqual p80211 { $$ = $2; }
| pllc { $$ = $1; }
Expand Down Expand Up @@ -942,4 +946,5 @@ mtp3fieldvalue: NUM {
mtp3listvalue: mtp3fieldvalue
| mtp3listvalue or mtp3fieldvalue { gen_or($1.b, $3.b); $$ = $3; }
;

%%
5 changes: 5 additions & 0 deletions scanner.l
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,11 @@ tcp-ack { yylval->h = 0x10; return NUM; }
tcp-urg { yylval->h = 0x20; return NUM; }
tcp-ece { yylval->h = 0x40; return NUM; }
tcp-cwr { yylval->h = 0x80; return NUM; }

offset { return OFFSET; }
\+[0-9]+ { stou(yytext+1, yylval, yyextra); return OFFSET_PLUS; }
-[0-9]+ { stou(yytext+1, yylval, yyextra); return OFFSET_MINUS; }

[A-Za-z0-9]([-_.A-Za-z0-9]*[.A-Za-z0-9])? {
yylval->s = sdup(yyextra, (char *)yytext); return ID; }
"\\"[^ !()\n\t]+ { yylval->s = sdup(yyextra, (char *)yytext + 1); return ID; }
Expand Down