Skip to content

Commit 1a4f736

Browse files
author
Stefan Baranoff
committed
WIP/RFC: allow manual computed offset adjusment
Some keywords, like VLAN and MPLS, implicitly adjust offsets. New protocols not yet handled by pcap-filter may also require offset jumping, but are not part of the existing known protocol code. Allowing arbitrary offset adjustments by users supports overcoming long standing "vlan X or vlan Y" issues, albeit with awkward syntax, and for jumping over new protocols not yet handled explicitly, like VNTag. This second attempt switches from adjusting compile time static offsets to using the variable arguments already baked into the offset structs to allow use with nvarg to generate either fixed or dynamically computed jumps. There is no support for "set to X"; all actions are increment or decrement. There is also no support at this time for selecting which offsets to adjust. That can be added once the basic concept is flushed out and there's some agreement on if this is a desired feature, syntax, and implementation approach. Initially my thoughts for a next commit to support selecting offset are something like `off-linkhdr` or `off-nl` or `off-linkpl` for each type of offset that might be reasonable for an end user to want to adjust themseleves.
1 parent ec3f702 commit 1a4f736

File tree

4 files changed

+49
-15
lines changed

4 files changed

+49
-15
lines changed

Diff for: gencode.c

+45-6
Original file line numberDiff line numberDiff line change
@@ -10713,10 +10713,49 @@ gen_atmmulti_abbrev(compiler_state_t *cstate, int type)
1071310713
return b1;
1071410714
}
1071510715

10716-
struct block *gen_offset_adjustment(compiler_state_t *cstate, int n) {
10717-
struct block *b = new_block(cstate, BPF_JMP|BPF_JA);
10718-
b->s.k = 0; // Jump by 0 bytes, effectively a no-op
10719-
cstate->off_linkpl.constant_part += n;
10720-
cstate->off_linktype.constant_part += n;
10721-
return b;
10716+
struct block*
10717+
gen_offset(compiler_state_t *cstate, struct arth *a_arg)
10718+
{
10719+
struct arth *a = a_arg;
10720+
struct block *b;
10721+
struct slist *s, *s1;
10722+
bpf_abs_offset *offsets[2] = {&(cstate->off_linkpl), &(cstate->off_linktype)};
10723+
int i;
10724+
10725+
/*
10726+
* Catch errors reported by us and routines below us, and return NULL
10727+
* on an error.
10728+
*/
10729+
if (setjmp(cstate->top_ctx))
10730+
return (NULL);
10731+
10732+
s = NULL;
10733+
b = gen_true(cstate);
10734+
for (i = 0; i < 2; ++i) {
10735+
bpf_abs_offset *off = offsets[i];
10736+
// Make sure the offset being adjusted is variable
10737+
if (!off->is_variable)
10738+
off->is_variable = 1;
10739+
if (off->reg == -1)
10740+
off->reg = alloc_reg(cstate);
10741+
10742+
// Put the current offset into the accumulator
10743+
s = new_stmt(cstate, BPF_LD|BPF_MEM);
10744+
s->s.k = off->reg;
10745+
10746+
// Put the computed offset into the extra register
10747+
s1 = xfer_to_x(cstate, a);
10748+
sappend(s, s1);
10749+
10750+
// Add to the accumulator from the computed offset in the extra register
10751+
s1 = new_stmt(cstate, BPF_ALU|BPF_ADD|BPF_X);
10752+
sappend(s, s1);
10753+
10754+
s1 = new_stmt(cstate, BPF_ST);
10755+
s1->s.k = off->reg;
10756+
sappend(s, s1);
10757+
}
10758+
sappend(a->s, s);
10759+
b->stmts = a->s;
10760+
return b;
1072210761
}

Diff for: gencode.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -378,7 +378,7 @@ struct block *gen_pf_action(compiler_state_t *, int);
378378
struct block *gen_p80211_type(compiler_state_t *, bpf_u_int32, bpf_u_int32);
379379
struct block *gen_p80211_fcdir(compiler_state_t *, bpf_u_int32);
380380

381-
struct block *gen_offset_adjustment(compiler_state_t*, int);
381+
struct block *gen_offset(compiler_state_t *, struct arth *);
382382

383383
/*
384384
* Representation of a program as a tree of blocks, plus current mark.

Diff for: grammar.y.in

+2-5
Original file line numberDiff line numberDiff line change
@@ -401,14 +401,13 @@ DIAG_OFF_BISON_BYACC
401401
%token RADIO
402402
%token FISU LSSU MSU HFISU HLSSU HMSU
403403
%token SIO OPC DPC SLS HSIO HOPC HDPC HSLS
404-
%token OFFSET OFFSET_PLUS OFFSET_MINUS
404+
%token OFFSET
405405
%token LEX_ERROR
406406

407407
%type <s> ID EID AID
408408
%type <s> HID HID6
409409
%type <h> NUM
410410
%type <i> action reason type subtype type_subtype dir
411-
%type <h> OFFSET_PLUS OFFSET_MINUS
412411

413412
%left OR AND
414413
%nonassoc '!'
@@ -691,8 +690,7 @@ other: pqual TK_BROADCAST { CHECK_PTR_VAL(($$ = gen_broadcast(cstate, $1))); }
691690
| GENEVE { CHECK_PTR_VAL(($$ = gen_geneve(cstate, 0, 0))); }
692691
| VXLAN pnum { CHECK_PTR_VAL(($$ = gen_vxlan(cstate, $2, 1))); }
693692
| VXLAN { CHECK_PTR_VAL(($$ = gen_vxlan(cstate, 0, 0))); }
694-
| OFFSET OFFSET_PLUS { CHECK_PTR_VAL(($$ = gen_offset_adjustment(cstate, $2))); }
695-
| OFFSET OFFSET_MINUS { CHECK_PTR_VAL(($$ = gen_offset_adjustment(cstate, -$2))); }
693+
| OFFSET arth { CHECK_PTR_VAL(($$ = gen_offset(cstate, $2))); }
696694
| pfvar { $$ = $1; }
697695
| pqual p80211 { $$ = $2; }
698696
| pllc { $$ = $1; }
@@ -946,5 +944,4 @@ mtp3fieldvalue: NUM {
946944
mtp3listvalue: mtp3fieldvalue
947945
| mtp3listvalue or mtp3fieldvalue { gen_or($1.b, $3.b); $$ = $3; }
948946
;
949-
950947
%%

Diff for: scanner.l

+1-3
Original file line numberDiff line numberDiff line change
@@ -472,9 +472,7 @@ tcp-urg { yylval->h = 0x20; return NUM; }
472472
tcp-ece { yylval->h = 0x40; return NUM; }
473473
tcp-cwr { yylval->h = 0x80; return NUM; }
474474

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

479477
[A-Za-z0-9]([-_.A-Za-z0-9]*[.A-Za-z0-9])? {
480478
yylval->s = sdup(yyextra, (char *)yytext); return ID; }

0 commit comments

Comments
 (0)