Fix "ip broadcast" netmask byte order with the -f flag.
Let's suppose the interface eth0 has one IPv4 address with a /24
netmask. Without -f tcpdump leaves the netmask variable set to 0, which
regardless of the host endianness causes "ip broadcast" to match
destination hosts 0.0.0.0 and 255.255.255.255:
# tcpdump -i eth0 -d 'ip broadcast'
(000) ldh [12]
(001) jeq #0x800 jt 2 jf 6
(002) ld [30]
(003) jeq #0x0 jt 5 jf 4
(004) jeq #0xffffffff jt 5 jf 6
(005) ret #262144
(006) ret #0
With -f tcpdump calls pcap_lookupnet(), which correctly sets the netmask
to 0xFFFFFF00 (in network byte order). Then pcap_compile() receives the
same value, but it expects it to be in host byte order, so on a
little-endian host the resulting filter program incorrectly tests for a
0x00FFFFFF netmask:
# tcpdump -i eth0 -f -d 'ip broadcast'
(000) ldh [12]
(001) jeq #0x800 jt 2 jf 7
(002) ld [30]
(003) jset #0xff000000 jt 4 jf 6
(004) and #0xff000000
(005) jeq #0xff000000 jt 6 jf 7
(006) ret #262144
(007) ret #0
Add two missing ntohl() wrappers to make it right:
# tcpdump -i eno1 -f -d 'ip broadcast'
(000) ldh [12]
(001) jeq #0x800 jt 2 jf 7
(002) ld [30]
(003) jset #0xff jt 4 jf 6
(004) and #0xff
(005) jeq #0xff jt 6 jf 7
(006) ret #262144
(007) ret #0
Audit the init_print() code path and do not change anything because
there the byte order is already correct. Add comments to spell the byte
order in every case and update the -f flag description in the man page.
See also libpcap commit
1e54958.