Skip to content

Commit 0056b3a

Browse files
committed
pcap-filter(7): IPv4-mapped IPv6 is valid syntax.
Moreover, it is valid in all contexts of an IPv6 address, so move the definition to the place of first use ("host") and refer to inet_pton(3), which does the parsing. Later on just refer to the earlier definition. Add IPv4-mapped aliases to the existing IPv6 accept tests, and a few reject tests.
1 parent 5aeaf16 commit 0056b3a

File tree

2 files changed

+102
-11
lines changed

2 files changed

+102
-11
lines changed

pcap-filter.manmisc.in

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
1919
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
2020
.\"
21-
.TH PCAP-FILTER @MAN_MISC_INFO@ "9 October 2025"
21+
.TH PCAP-FILTER @MAN_MISC_INFO@ "18 October 2025"
2222
.SH NAME
2323
pcap-filter \- packet filter syntax
2424
.br
@@ -226,8 +226,14 @@ for Ethernet-like link-layer types is equivalent to
226226
.in -.5i
227227
.IP
228228
.I hostnameaddr
229-
may be either an address or a name. If it is a name, the name must resolve
230-
to at least one IPv4 address for
229+
may be either an address or a name. If it is an IPv6 address, it may use both
230+
the zero compression
231+
.RB ( :: )
232+
and the IPv4-mapped
233+
.RB ( x:x:x:x:x:x:d.d.d.d )
234+
notations as discussed in
235+
.BR inet_pton (3).
236+
If it is a name, the name must resolve to at least one IPv4 address for
231237
.BR "arp host" ,
232238
.B "ip host"
233239
and
@@ -326,7 +332,10 @@ dotted triple (e.g., 192.168.1), dotted pair (e.g, 172.16), or single
326332
number (e.g., 10); the netmask is 255.255.255.255 (/32) for a dotted quad
327333
(which means that it's really a host match), 255.255.255.0 (/24) for a dotted
328334
triple, 255.255.0.0 (/16) for a dotted pair, or 255.0.0.0 (/8) for a single number.
329-
An IPv6 network number must be written out fully; the netmask is
335+
.IP
336+
An IPv6 network number is an IPv6 address as discussed for the
337+
.B host
338+
primitive above; the implicit netmask is
330339
ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff (/128), so in this primitive IPv6
331340
"network" matches are really always host matches. For an actual IPv6 network
332341
match see the `\fBnet \fInetaddr\fR/\fIlen\fR' primitive below.
@@ -398,11 +407,9 @@ is the same as the above. For IPv6,
398407
.I len
399408
is an integer between 0 and 128 (both inclusive) and
400409
.I netaddr
401-
is an IPv6 address. For the latter zero compression notation
402-
.RB ( :: )
403-
is valid, but IPv4-mapped notation
404-
.RB ( x:x:x:x:x:x:d.d.d.d )
405-
is not. For both IPv4 and IPv6 the maximum value of
410+
is an IPv6 address as discussed for the
411+
.B host
412+
primitive above. For both IPv4 and IPv6 the maximum value of
406413
.I len
407414
is equivalent to a host match and the 0 value (which implies an all-zeroes
408415
value of

testprogs/TESTrun

Lines changed: 86 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11276,6 +11276,27 @@ my @accept_blocks = (
1127611276
'host ::1/128',
1127711277
'src or dst host ::1/128',
1127811278
'src or dst ::1/128',
11279+
# IPv4-mapped notation of everything above
11280+
'ip6 host ::0.0.0.1',
11281+
'ip6 src or dst host ::0.0.0.1',
11282+
'ip6 src or dst ::0.0.0.1',
11283+
'host ::0.0.0.1',
11284+
'src or dst host ::0.0.0.1',
11285+
'src or dst ::0.0.0.1',
11286+
'ip6 net ::0.0.0.1/128',
11287+
'ip6 src or dst net ::0.0.0.1/128',
11288+
'net ::0.0.0.1/128',
11289+
'src or dst net ::0.0.0.1/128',
11290+
'ip6 net ::0.0.0.1',
11291+
'ip6 src or dst net ::0.0.0.1',
11292+
'net ::0.0.0.1',
11293+
'src or dst net ::0.0.0.1',
11294+
'ip6 host ::0.0.0.1/128',
11295+
'ip6 src or dst host ::0.0.0.1/128',
11296+
'ip6 src or dst ::0.0.0.1/128',
11297+
'host ::0.0.0.1/128',
11298+
'src or dst host ::0.0.0.1/128',
11299+
'src or dst ::0.0.0.1/128',
1127911300
],
1128011301
opt => '
1128111302
(000) ldb [0]
@@ -11392,6 +11413,15 @@ my @accept_blocks = (
1139211413
'ip6 src fe80::1122:33ff:fe44:5566/128',
1139311414
'src host fe80::1122:33ff:fe44:5566/128',
1139411415
'src fe80::1122:33ff:fe44:5566/128',
11416+
# IPv4-mapped notation of everything above
11417+
'ip6 src host fe80::1122:33ff:254.68.85.102',
11418+
'ip6 src fe80::1122:33ff:254.68.85.102',
11419+
'src host fe80::1122:33ff:254.68.85.102',
11420+
'src fe80::1122:33ff:254.68.85.102',
11421+
'ip6 src host fe80::1122:33ff:254.68.85.102/128',
11422+
'ip6 src fe80::1122:33ff:254.68.85.102/128',
11423+
'src host fe80::1122:33ff:254.68.85.102/128',
11424+
'src fe80::1122:33ff:254.68.85.102/128',
1139511425
],
1139611426
opt => '
1139711427
(000) ldb [0]
@@ -11478,6 +11508,15 @@ my @accept_blocks = (
1147811508
'ip6 dst fe80::7788:99ff:feaa:bbcc/128',
1147911509
'dst host fe80::7788:99ff:feaa:bbcc/128',
1148011510
'dst fe80::7788:99ff:feaa:bbcc/128',
11511+
# IPv4-mapped notation of everything above
11512+
'ip6 dst host fe80::7788:99ff:254.170.187.204',
11513+
'ip6 dst fe80::7788:99ff:254.170.187.204',
11514+
'dst host fe80::7788:99ff:254.170.187.204',
11515+
'dst fe80::7788:99ff:254.170.187.204',
11516+
'ip6 dst host fe80::7788:99ff:254.170.187.204/128',
11517+
'ip6 dst fe80::7788:99ff:254.170.187.204/128',
11518+
'dst host fe80::7788:99ff:254.170.187.204/128',
11519+
'dst fe80::7788:99ff:254.170.187.204/128',
1148111520
],
1148211521
opt => '
1148311522
(000) ldb [0]
@@ -11559,6 +11598,11 @@ my @accept_blocks = (
1155911598
'net fe80::/10',
1156011599
'src or dst net fe80::/10',
1156111600
'ip6 src or dst net fe80::/10',
11601+
# IPv4-mapped notation of everything above
11602+
'ip6 net fe80::0.0.0.0/10',
11603+
'net fe80::0.0.0.0/10',
11604+
'src or dst net fe80::0.0.0.0/10',
11605+
'ip6 src or dst net fe80::0.0.0.0/10',
1156211606
],
1156311607
opt => '
1156411608
(000) ldb [0]
@@ -11580,6 +11624,9 @@ my @accept_blocks = (
1158011624
aliases => [
1158111625
'ip6 src net 2000::/3',
1158211626
'src net 2000::/3',
11627+
# IPv4-mapped notation of everything above
11628+
'ip6 src net 2000::0.0.0.0/3',
11629+
'src net 2000::0.0.0.0/3',
1158311630
],
1158411631
opt => '
1158511632
(000) ldb [0]
@@ -11595,7 +11642,11 @@ my @accept_blocks = (
1159511642
{
1159611643
name => 'ip6_dst_net_0',
1159711644
DLT => 'RAW',
11598-
aliases => ['ip6 dst net ::/0'],
11645+
aliases => [
11646+
'ip6 dst net ::/0',
11647+
# IPv4-mapped notation of everything above
11648+
'ip6 dst net ::0.0.0.0/0',
11649+
],
1159911650
unopt => '
1160011651
(000) ldb [0]
1160111652
(001) and #0xf0
@@ -11658,7 +11709,11 @@ my @accept_blocks = (
1165811709
{
1165911710
name => 'ip6_dst_net_120',
1166011711
DLT => 'RAW',
11661-
aliases => ['ip6 dst net ff11:2233:4455:6677:8899:aabb:ccdd:ee00/120'],
11712+
aliases => [
11713+
'ip6 dst net ff11:2233:4455:6677:8899:aabb:ccdd:ee00/120',
11714+
# IPv4-mapped notation of everything above
11715+
'ip6 dst net ff11:2233:4455:6677:8899:aabb:204.221.238.0/120',
11716+
],
1166211717
unopt => '
1166311718
(000) ldb [0]
1166411719
(001) and #0xf0
@@ -14212,6 +14267,11 @@ sub errstr_invhost_ipv4 {
1421214267
return sprintf ('invalid IPv4 address \'%s\'', shift);
1421314268
}
1421414269

14270+
# scanner.l
14271+
sub errstr_invhost_ipv6 {
14272+
return sprintf ('bogus IPv6 address %s', shift);
14273+
}
14274+
1421514275
# ERRSTR_UNKNOWN_MAC48HOST
1421614276
sub errstr_nomac48host {
1421714277
return sprintf ('unknown Ethernet-like host \'%s\'', shift);
@@ -14389,6 +14449,30 @@ my @reject_tests = (
1438914449
expr => 'ip6 host fe80:0:0:0:0:0:0:0:0',
1439014450
errstr => errstr_syntax,
1439114451
},
14452+
{
14453+
name => 'ip6_host_mapped_octet1',
14454+
DLT => 'RAW',
14455+
expr => 'ip6 host fe80::256.20.30.40',
14456+
errstr => errstr_invhost_ipv6 ('fe80::256.20.30.40'),
14457+
},
14458+
{
14459+
name => 'ip6_host_mapped_octet2',
14460+
DLT => 'RAW',
14461+
expr => 'ip6 host fe80::10.256.30.40',
14462+
errstr => errstr_invhost_ipv6 ('fe80::10.256.30.40'),
14463+
},
14464+
{
14465+
name => 'ip6_host_mapped_octet3',
14466+
DLT => 'RAW',
14467+
expr => 'ip6 host fe80::10.20.256.40',
14468+
errstr => errstr_invhost_ipv6 ('fe80::10.20.256.40'),
14469+
},
14470+
{
14471+
name => 'ip6_host_mapped_octet4',
14472+
DLT => 'RAW',
14473+
expr => 'ip6 host fe80::10.20.30.256',
14474+
errstr => errstr_invhost_ipv6 ('fe80::10.20.30.256'),
14475+
},
1439214476

1439314477
# This test has been flaky because it depends on an external effect (DNS
1439414478
# lookup), which sometimes times out. Let's disable it until there is a good

0 commit comments

Comments
 (0)