Skip to content

Commit

Permalink
matcher: ip: add support for inverse IPv4 addr matcher in bfcli
Browse files Browse the repository at this point in the history
Allow to specific an inverse match for an IPv4 address in bfcli:
192.168.1.1 will match the exact IP, while !192.168.1.1 will match
anything but this exact IP.
  • Loading branch information
qdeslandes committed Aug 22, 2024
1 parent 8cd308d commit f2ea86f
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 4 deletions.
2 changes: 1 addition & 1 deletion src/cli/lexer.l
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ ip\.proto { BEGIN(STATE_MATCHER_IPPROTO); yylval.sval = strdup(yytext); re
ip\.saddr { BEGIN(STATE_MATCHER_IPADDR); yylval.sval = strdup(yytext); return MATCHER_TYPE; }
ip\.daddr { BEGIN(STATE_MATCHER_IPADDR); yylval.sval = strdup(yytext); return MATCHER_TYPE; }
<STATE_MATCHER_IPADDR>{
[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}(\/[0-9]+)? {
(\!)?[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}(\/[0-9]+)? {
yylval.sval = strdup(yytext);
return MATCHER_IPADDR;
}
Expand Down
17 changes: 14 additions & 3 deletions src/cli/parser.y
Original file line number Diff line number Diff line change
Expand Up @@ -230,9 +230,19 @@ matcher : matcher_type MATCHER_IPPROTO
{
_cleanup_bf_matcher_ struct bf_matcher *matcher = NULL;
struct bf_matcher_ip_addr addr;
char *ip = $2;
char *mask;
bool inv = false;
int r;

// If the payload starts with '!', it's an inverse match,
// and the IP starts at the next character.
if (*$2 == '!') {
inv = true;
++ip;
}

// If '/' is found, parse the mask, otherwise use /32.
mask = strchr($2, '/');
if (mask) {
*mask = '\0';
Expand All @@ -249,15 +259,16 @@ matcher : matcher_type MATCHER_IPPROTO
addr.mask = (uint32_t)~0;
}

r = inet_pton(AF_INET, $2, &addr.addr);
// Convert the IPv4 from string to uint32_t.
r = inet_pton(AF_INET, ip, &addr.addr);
if (r != 1) {
yyerror(chains, "failed to parse IPv4 adddress: %s\n", $2);
yyerror(chains, "failed to parse IPv4 adddress: %s\n", ip);
YYABORT;
}

free($2);

if (bf_matcher_new(&matcher, $1, BF_MATCHER_EQ, &addr, sizeof(addr))) {
if (bf_matcher_new(&matcher, $1, inv ? BF_MATCHER_NE : BF_MATCHER_EQ, &addr, sizeof(addr))) {
yyerror(chains, "failed to create a new matcher\n");
YYABORT;
}
Expand Down

0 comments on commit f2ea86f

Please sign in to comment.