From 12c8cc32f0c15823120fc0f9edda99e233bc8221 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Valverde?= Date: Wed, 6 Apr 2022 09:29:45 +0100 Subject: [PATCH] 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. --- epan/dfilter/scanner.l | 20 +++++----- test/suite_dfilter/group_bytes_ipv6.py | 55 ++++++++++++++++++++++++++ 2 files changed, 65 insertions(+), 10 deletions(-) diff --git a/epan/dfilter/scanner.l b/epan/dfilter/scanner.l index 1deb02c5e5..c8838a7219 100644 --- a/epan/dfilter/scanner.l +++ b/epan/dfilter/scanner.l @@ -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); } diff --git a/test/suite_dfilter/group_bytes_ipv6.py b/test/suite_dfilter/group_bytes_ipv6.py index fd3b007294..0ad1fa6c30 100644 --- a/test/suite_dfilter/group_bytes_ipv6.py +++ b/test/suite_dfilter/group_bytes_ipv6.py @@ -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)