dfilter: Fix parsing of some IPv6 compressed addresses

Fix parsing of some IPv6 addresses and add tests.

Also pass tokens as unparsed unless the user was specfic about
the semantic type. For example the IPv4 address 1.1.1.1 is also a
valid field, but 1.1.1.1/128 is not (because of the slash). However
choose not to enforce the distinction in the lexical scanner and pass
everything as unparsed unless the meaning is explicit in the syntax
with leading dot, colon, or between angle branckets.
This commit is contained in:
João Valverde 2022-04-06 09:29:45 +01:00
parent 411b3c1d78
commit 12c8cc32f0
2 changed files with 65 additions and 10 deletions

View File

@ -364,27 +364,27 @@ v6-cidr-prefix \/[[:digit:]]{1,3}
/* None of the patterns below can match ".." anywhere in the token string. */
{MacAddress}|{QuadMacAddress} {
/* MAC Address literal or unparsed if using dots. */
/* MAC Address literal. */
return set_lval_str(TOKEN_UNPARSED, yytext);
}
{IPv4address}{v4-cidr-prefix} {
/* IPv4 CIDR. */
return set_lval_str(TOKEN_LITERAL, yytext);
{IPv4address}{v4-cidr-prefix}? {
/* IPv4 with or without prefix. */
return set_lval_str(TOKEN_UNPARSED, yytext);
}
{IPv6address}{v6-cidr-prefix} {
/* IPv6 CIDR. */
return set_lval_str(TOKEN_LITERAL, yytext);
{IPv6address}{v6-cidr-prefix}? {
/* IPv6 with or without prefix. */
return set_lval_str(TOKEN_UNPARSED, yytext);
}
[[:xdigit:]]+:[[:xdigit:]:]* {
/* Bytes or address (IPv6, etc). */
return set_lval_str(TOKEN_LITERAL, yytext);
/* Bytes. */
return set_lval_str(TOKEN_UNPARSED, yytext);
}
"<"[^>=]+">" {
/* Literal in angle brackets. */
/* Literal in-between angle brackets (cannot be parsed as a protocol field). */
return set_lval_str(TOKEN_LITERAL, yytext);
}

View File

@ -105,4 +105,59 @@ class case_bytes_ipv6(unittest.TestCase):
def test_slice_4(self, checkDFilterCount):
dfilter = "ipv6.dst[15:1] == 00"
#
# Test some addresses are parsed correctly
#
def test_unspecified_1(self, checkDFilterCount):
dfilter = "ipv6.dst == ::"
checkDFilterCount(dfilter, 0)
def test_unspecified_2(self, checkDFilterCount):
dfilter = "ipv6.dst == ::/128"
checkDFilterCount(dfilter, 0)
def test_loopback_1(self, checkDFilterCount):
dfilter = "ipv6.dst == ::1"
checkDFilterCount(dfilter, 0)
def test_loopback_2(self, checkDFilterCount):
dfilter = "ipv6.dst == ::1/128"
checkDFilterCount(dfilter, 0)
def test_compress_1(self, checkDFilterCount):
dfilter = "ipv6.dst == ::2000"
checkDFilterCount(dfilter, 0)
def test_compress_2(self, checkDFilterCount):
dfilter = "ipv6.dst == ::2000/64"
checkDFilterCount(dfilter, 0)
def test_compress_3(self, checkDFilterCount):
dfilter = "ipv6.dst == ::1:2000"
checkDFilterCount(dfilter, 0)
def test_compress_4(self, checkDFilterCount):
dfilter = "ipv6.dst == 2000::"
checkDFilterCount(dfilter, 0)
def test_compress_5(self, checkDFilterCount):
dfilter = "ipv6.dst == 2000::/120"
checkDFilterCount(dfilter, 0)
def test_compress_6(self, checkDFilterCount):
dfilter = "ipv6.dst == 2000:1::"
checkDFilterCount(dfilter, 0)
def test_compress_7(self, checkDFilterCount):
dfilter = "ipv6.dst == 2000:1::2:0"
checkDFilterCount(dfilter, 0)
def test_mapped_ipv4_1(self, checkDFilterCount):
dfilter = "ipv6.dst == ::13.1.68.3"
checkDFilterCount(dfilter, 0)
def test_mapped_ipv4_2(self, checkDFilterCount):
dfilter = "ipv6.dst == ::FFFF:129.144.52.38"
checkDFilterCount(dfilter, 0)