Skip to content

WIP/RFC possible use of va_list in gencode.c #1520

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

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
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
121 changes: 78 additions & 43 deletions gencode.c
Original file line number Diff line number Diff line change
Expand Up @@ -640,6 +640,9 @@ static struct block *gen_set(compiler_state_t *, bpf_u_int32, struct slist *);
static struct block *gen_unset(compiler_state_t *, bpf_u_int32, struct slist *);
static struct block *gen_ncmp(compiler_state_t *, enum e_offrel, u_int,
u_int, bpf_u_int32, int, int, bpf_u_int32);
static struct block *gen_vncmp(compiler_state_t *, const enum e_offrel,
const u_int, const u_int, const bpf_u_int32, const int, const unsigned,
uint8_t, va_list);
static struct slist *gen_load_absoffsetrel(compiler_state_t *, bpf_abs_offset *,
u_int, u_int);
static struct slist *gen_load_a(compiler_state_t *, enum e_offrel, u_int,
Expand Down Expand Up @@ -713,7 +716,7 @@ static struct block *gen_encap_ll_check(compiler_state_t *cstate);
static struct block *gen_atmfield_code_internal(compiler_state_t *, int,
bpf_u_int32, int, int);
static struct block *gen_atmtype_llc(compiler_state_t *);
static struct block *gen_msg_abbrev(compiler_state_t *, const uint8_t);
static struct block *gen_msg_abbrev(compiler_state_t *, const uint8_t, ...);
static struct block *gen_atm_prototype(compiler_state_t *, const uint8_t);
static struct block *gen_atm_vpi(compiler_state_t *, const uint8_t);
static struct block *gen_atm_vci(compiler_state_t *, const uint16_t);
Expand Down Expand Up @@ -1391,11 +1394,34 @@ gen_not(struct block *b)
b->sense = !b->sense;
}

static struct block *
gen_ncmp_any(compiler_state_t *cstate, const enum e_offrel offrel,
const u_int offset, const u_int size, const bpf_u_int32 mask,
const int jtype, const unsigned reverse, const uint8_t nval, ...)
{
va_list ap;
va_start(ap, nval);
struct block *b = gen_vncmp(cstate, offrel, offset, size, mask, jtype, reverse, nval, ap);
va_end(ap);
return b;
}

static struct block *
gen_cmp_any(compiler_state_t *cstate, enum e_offrel offrel, u_int offset,
u_int size, const uint8_t nval, ...)
{
va_list ap;
va_start(ap, nval);
struct block *b = gen_vncmp(cstate, offrel, offset, size, 0xffffffff, BPF_JEQ, 0, nval, ap);
va_end(ap);
return b;
}

static struct block *
gen_cmp(compiler_state_t *cstate, enum e_offrel offrel, u_int offset,
u_int size, bpf_u_int32 v)
{
return gen_ncmp(cstate, offrel, offset, size, 0xffffffff, BPF_JEQ, 0, v);
return gen_cmp_any(cstate, offrel, offset, size, 1, v);
}

static struct block *
Expand Down Expand Up @@ -1530,6 +1556,7 @@ gen_ncmp(compiler_state_t *cstate, enum e_offrel offrel, u_int offset,
u_int size, bpf_u_int32 mask, int jtype, int reverse,
bpf_u_int32 v)
{
// return gen_ncmp_va(cstate, offrel, offset, size, mask, jtype, reverse, 1, v);
struct slist *s, *s2;
struct block *b;

Expand All @@ -1547,6 +1574,40 @@ gen_ncmp(compiler_state_t *cstate, enum e_offrel offrel, u_int offset,
return b;
}

// Test whether any of the specified values satisfies the condition.
static struct block *
gen_vncmp(compiler_state_t *cstate, const enum e_offrel offrel,
const u_int offset, const u_int size, const bpf_u_int32 mask,
const int jtype, const unsigned reverse, uint8_t nval, va_list ap)
{
struct slist *s = gen_load_a(cstate, offrel, offset, size);

if (mask != UINT32_MAX) {
struct slist *s2 = new_stmt(cstate, BPF_ALU|BPF_AND|BPF_K);
s2->s.k = mask;
sappend(s, s2);
}

if (! nval)
bpf_error(cstate, "Internal error in %s", __func__);

struct block *b = NULL;
while (nval--) {
bpf_u_int32 v = va_arg(ap, bpf_u_int32);
if (! b) {
b = gen_jmp(cstate, jtype, v, s);
} else {
struct block *tmp = gen_jmp(cstate, jtype, v, NULL);
gen_or(b, tmp);
b = tmp;
}
}

if (reverse)
gen_not(b);
return b;
}

static int
init_linktype(compiler_state_t *cstate, pcap_t *p)
{
Expand Down Expand Up @@ -3725,12 +3786,8 @@ gen_linktype(compiler_state_t *cstate, bpf_u_int32 ll_proto)
* Also check for Van Jacobson-compressed IP.
* XXX - do this for other forms of PPP?
*/
b0 = gen_cmp(cstate, OR_LINKTYPE, 0, BPF_H, PPP_IP);
b1 = gen_cmp(cstate, OR_LINKTYPE, 0, BPF_H, PPP_VJC);
gen_or(b0, b1);
b0 = gen_cmp(cstate, OR_LINKTYPE, 0, BPF_H, PPP_VJNC);
gen_or(b1, b0);
return b0;
return gen_cmp_any(cstate, OR_LINKTYPE, 0, BPF_H, 3,
PPP_IP, PPP_VJC, PPP_VJNC);

default:
return gen_cmp(cstate, OR_LINKTYPE, 0, BPF_H,
Expand Down Expand Up @@ -3847,20 +3904,12 @@ gen_linktype(compiler_state_t *cstate, bpf_u_int32 ll_proto)
ARCTYPE_INET6));

case ETHERTYPE_IP:
b0 = gen_cmp(cstate, OR_LINKTYPE, 0, BPF_B,
ARCTYPE_IP);
b1 = gen_cmp(cstate, OR_LINKTYPE, 0, BPF_B,
ARCTYPE_IP_OLD);
gen_or(b0, b1);
return (b1);
return gen_cmp_any(cstate, OR_LINKTYPE, 0, BPF_B,
2, ARCTYPE_IP, ARCTYPE_IP_OLD);

case ETHERTYPE_ARP:
b0 = gen_cmp(cstate, OR_LINKTYPE, 0, BPF_B,
ARCTYPE_ARP);
b1 = gen_cmp(cstate, OR_LINKTYPE, 0, BPF_B,
ARCTYPE_ARP_OLD);
gen_or(b0, b1);
return (b1);
return gen_cmp_any(cstate, OR_LINKTYPE, 0, BPF_B,
2, ARCTYPE_ARP, ARCTYPE_ARP_OLD);

case ETHERTYPE_REVARP:
return (gen_cmp(cstate, OR_LINKTYPE, 0, BPF_B,
Expand Down Expand Up @@ -9801,14 +9850,18 @@ gen_mtp3field_code(compiler_state_t *cstate, int mtp3field,
}

static struct block *
gen_msg_abbrev(compiler_state_t *cstate, const uint8_t type)
gen_msg_abbrev(compiler_state_t *cstate, const uint8_t nval, ...)
{
/*
* Q.2931 signalling protocol messages for handling virtual circuits
* establishment and teardown
*/
return gen_cmp(cstate, OR_LINKHDR, cstate->off_payload + MSG_TYPE_POS,
BPF_B, type);
va_list ap;
va_start(ap, nval);
struct block *b = gen_vncmp(cstate, OR_LINKHDR, cstate->off_payload + MSG_TYPE_POS,
BPF_B, 0xffffffff, BPF_JEQ, 0, nval, ap);
va_end(ap);
return b;
}

struct block *
Expand Down Expand Up @@ -9850,31 +9903,13 @@ gen_atmmulti_abbrev(compiler_state_t *cstate, int type)
* Get Q.2931 signalling messages for switched
* virtual connection
*/
b0 = gen_msg_abbrev(cstate, SETUP);
b1 = gen_msg_abbrev(cstate, CALL_PROCEED);
gen_or(b0, b1);
b0 = gen_msg_abbrev(cstate, CONNECT);
gen_or(b0, b1);
b0 = gen_msg_abbrev(cstate, CONNECT_ACK);
gen_or(b0, b1);
b0 = gen_msg_abbrev(cstate, RELEASE);
gen_or(b0, b1);
b0 = gen_msg_abbrev(cstate, RELEASE_DONE);
gen_or(b0, b1);
b1 = gen_msg_abbrev(cstate, 6, RELEASE_DONE, RELEASE, CONNECT_ACK, CONNECT, SETUP, CALL_PROCEED);
b0 = gen_atmtype_abbrev(cstate, A_SC);
gen_and(b0, b1);
return b1;

case A_METACONNECT:
b0 = gen_msg_abbrev(cstate, SETUP);
b1 = gen_msg_abbrev(cstate, CALL_PROCEED);
gen_or(b0, b1);
b0 = gen_msg_abbrev(cstate, CONNECT);
gen_or(b0, b1);
b0 = gen_msg_abbrev(cstate, RELEASE);
gen_or(b0, b1);
b0 = gen_msg_abbrev(cstate, RELEASE_DONE);
gen_or(b0, b1);
b1 = gen_msg_abbrev(cstate, 5, RELEASE_DONE, RELEASE, CONNECT, SETUP, CALL_PROCEED);
b0 = gen_atmtype_abbrev(cstate, A_METAC);
gen_and(b0, b1);
return b1;
Expand Down
16 changes: 13 additions & 3 deletions testprogs/TESTrun
Original file line number Diff line number Diff line change
Expand Up @@ -2444,7 +2444,7 @@ my @accept_blocks = (
name => 'atm_connectmsg',
DLT => 'SUNATM',
aliases => ['connectmsg'],
opt => '
unopt => '
(000) ldb [1]
(001) jeq #0x0 jt 2 jf 12
(002) ldh [2]
Expand All @@ -2464,7 +2464,7 @@ my @accept_blocks = (
name => 'atm_metaconnect',
DLT => 'SUNATM',
aliases => ['metaconnect'],
opt => '
unopt => '
(000) ldb [1]
(001) jeq #0x0 jt 2 jf 11
(002) ldh [2]
Expand Down Expand Up @@ -3920,7 +3920,7 @@ my @accept_blocks = (
name => 'link_proto_ip_PPP_BSDOS',
DLT => 'PPP_BSDOS',
aliases => ['link proto \ip'],
opt => '
unopt => '
(000) ldh [5]
(001) jeq #0x21 jt 4 jf 2
(002) jeq #0x2d jt 4 jf 3
Expand Down Expand Up @@ -5568,6 +5568,16 @@ my @accept_blocks = (
(004) ret #262144
(005) ret #0
',
unopt => '
(000) ldh [12]
(001) jeq #0x8100 jt 6 jf 2
(002) ldh [12]
(003) jeq #0x88a8 jt 6 jf 4
(004) ldh [12]
(005) jeq #0x9100 jt 6 jf 7
(006) ret #262144
(007) ret #0
',
}, # vlan_eth_nullary
{
name => 'vlan_eth_unary',
Expand Down