Here is an oddity I came across earlier.
pcap-filter(3PCAP) says:
dst net netnameaddr
True if the IPv4/v6 destination address of the
packet has a network number of netnameaddr.
Net may be either a name from the networks
database (/etc/networks, etc.) or a network
number. An IPv4 network number can be written
as a dotted quad (e.g., 192.168.1.0), dotted
triple (e.g., 192.168.1), dotted pair (e.g,
172.16), or single number (e.g., 10); the net‐
mask is 255.255.255.255 for a dotted quad
(which means that it's really a host match),
255.255.255.0 for a dotted triple, 255.255.0.0
for a dotted pair, or 255.0.0.0 for a single
number.
This holds exactly for the network primitive:
~> tcpdump -d -y EN10MB 'ip src net 10.20.30.40'
(000) ldh [12]
(001) jeq #0x800 jt 2jf 5
(002) ld [26]
(003) jeq #0xa141e28 jt 4jf 5
(004) ret #262144
(005) ret #0
~> tcpdump -d -y EN10MB 'ip src net 10.20.30'
(000) ldh [12]
(001) jeq #0x800 jt 2jf 6
(002) ld [26]
(003) and #0xff00
(004) jeq #0xa141e00 jt 5jf 6
(005) ret #262144
(006) ret #0
~> tcpdump -d -y EN10MB 'ip src net 10.20'
(000) ldh [12]
(001) jeq #0x800 jt 2jf 6
(002) ld [26]
(003) and #0x
(004) jeq #0xa14 jt 5jf 6
(005) ret #262144
(006) ret #0
~> tcpdump -d -y EN10MB 'ip src net 10'
(000) ldh [12]
(001) jeq #0x800 jt 2jf 6
(002) ld [26]
(003) and #0xff00
(004) jeq #0xa00 jt 5jf 6
(005) ret #262144
(006) ret #0
Now, if one tries the same with the host primitive (which does not
document the syntax of an IPv4 address), the first three variants work
the same, and the fourth (single number) instead of comparing the most
significant byte compares the entire address with 0x000A:
~> tcpdump -d -y EN10MB 'ip src host 10.20.30.40'
(000) ldh [12]
(001) jeq #0x800 jt 2jf 5
(002) ld [26]
(003) jeq #0xa141e28 jt 4jf 5
(004) ret #262144
(005) ret #0
~> tcpdump -d -y EN10MB 'ip src host 10.20.30'
(000) ldh [12]
(001) jeq #0x800 jt 2jf 6
(002) ld [26]
(003) and #0xff00
(004) jeq #0xa141e00 jt 5jf 6
(005) ret #262144
(006) ret #0
~> tcpdump -d -y EN10MB 'ip src host 10.20'
(000) ldh [12]
(001) jeq #0x800 jt 2jf 6
(002) ld [26]
(003) and #0x
(004) jeq #0xa14 jt 5jf 6
(005) ret #262144
(006) ret #0
~> tcpdump -d -y EN10MB 'ip src host 10'
(000) ldh [12]
(001) jeq #0x800 jt 2jf 5
(002) ld [26]
(003) jeq #0xa jt 4jf 5
(004) ret #262144
(005) ret #0
Seemingly, the only problem here is that the single number syntax should
work the same as it does for a network. But in fact it works exactly as
documented for `inet_aton()`:
a.b.c.d Each of the four numeric parts specifies a
byte of the address; the bytes are assigned
in left-to-right order to produce the bi‐
nary address.
a.b.c Parts a and b specify the first two bytes
of the binary address. Part c is inter‐
preted as a 16-bit value that defines the
rightmost two bytes of the binary address.
This notation is suitable for specifying
(outmoded) Class B network addresses.
a.b Part a specifies the first byte of the bi‐
nary address. Part b is interpreted as a
24-bit value that defines the rightmost
three bytes of the binary address. This
notation is suitable for specifying (out‐
moded) Class A network addresses.
a The value a is interpreted as a 32-bit
value that is stored directly into the bi‐
nary address without any byte rearrange‐
ment.
For example:
~> ping -n 0xa141e28
PING 0xa141e28 (10.20.30.40): 56 data bytes
~> ping -n 169090600
PING 169090600 (10.20.30.40): 56 data bytes
This way, the actual issues seem to be as follows:
* pcap-filter(3PCAP) does not specify the format of an IPv4 address
* "host N.N" works exactly as "net N.N"
* "host N.N.N" works exactly as "net N.N.N"
This way, to me it would make the most sense either to declare
inet_aton() IPv4 address format the nominal syntax (and to implement
that in the parser for N.N and N.N.N) or to declare N.N and N.N.N
invalid syntax and to return an appropriate error.
--
Denis Ovsienko