From: Denis Ovsienko Date: Fri, 28 Mar 2025 23:27:33 +0000 (+0000) Subject: Mind all-zeroes IPv4 netmask in gen_host(). X-Git-Url: https://git.tcpdump.org/libpcap/commitdiff_plain/8620df13397e5f6f1dc23202f28c365d3071ca59 Mind all-zeroes IPv4 netmask in gen_host(). When the IPv4 netmask is /0, gen_mcmp() returns an equivalent of either true or false. In the context of gen_host() it is clear when it is going to be true, so take a shortcut and return a block with fewer statements. Now for "ip dst net 0.0.0.0/0" the unoptimized and the optimized filter programs are the same (without the always-true comparison). --- diff --git a/gencode.c b/gencode.c index d36abbeb..74780cdc 100644 --- a/gencode.c +++ b/gencode.c @@ -5136,18 +5136,33 @@ gen_host(compiler_state_t *cstate, bpf_u_int32 addr, bpf_u_int32 mask, case Q_IP: b0 = gen_linktype(cstate, ETHERTYPE_IP); + /* + * Belt and braces: if other code works correctly, any host + * bits are clear and mask == 0 means addr == 0. In this case + * the call to gen_hostop() would produce an "always true" + * instruction block and ANDing it with the link type check + * would be a no-op. + */ + if (mask == 0 && addr == 0) + return b0; b1 = gen_hostop(cstate, addr, mask, dir, 12, 16); gen_and(b0, b1); return b1; case Q_RARP: b0 = gen_linktype(cstate, ETHERTYPE_REVARP); + // Same as for Q_IP above. + if (mask == 0 && addr == 0) + return b0; b1 = gen_hostop(cstate, addr, mask, dir, 14, 24); gen_and(b0, b1); return b1; case Q_ARP: b0 = gen_linktype(cstate, ETHERTYPE_ARP); + // Same as for Q_IP above. + if (mask == 0 && addr == 0) + return b0; b1 = gen_hostop(cstate, addr, mask, dir, 14, 24); gen_and(b0, b1); return b1; diff --git a/testprogs/TESTrun b/testprogs/TESTrun index d8836786..12704fc1 100755 --- a/testprogs/TESTrun +++ b/testprogs/TESTrun @@ -9181,22 +9181,13 @@ my @accept_blocks = ( DLT => 'RAW', snaplen => 2000, aliases => ['ip dst net 0.0.0.0/0'], - opt => ' + unopt => ' (000) ldb [0] (001) and #0xf0 (002) jeq #0x40 jt 3 jf 4 (003) ret #2000 (004) ret #0 ', - unopt => ' - (000) ldb [0] - (001) and #0xf0 - (002) jeq #0x40 jt 3 jf 6 - (003) ld #0x0 - (004) jeq #0x0 jt 5 jf 6 - (005) ret #2000 - (006) ret #0 - ', }, # ip_dst_net_addr_0 { name => 'ip_dst_net_addr_8',