]> The Tcpdump Group git mirrors - libpcap/commitdiff
Mind all-zeroes IPv4 netmask in gen_host().
authorDenis Ovsienko <[email protected]>
Fri, 28 Mar 2025 23:27:33 +0000 (23:27 +0000)
committerDenis Ovsienko <[email protected]>
Tue, 8 Apr 2025 10:38:16 +0000 (11:38 +0100)
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).

gencode.c
testprogs/TESTrun

index d36abbeb52d6197b48d64e83485b40ae98bd90cd..74780cdc085215e0e80baa9522d31d0c7b858f0f 100644 (file)
--- 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;
index d88367864d514a137ccd2b09eea0fe20075bc87c..12704fc151b71d209d99f616c1836229fabe8a95 100755 (executable)
@@ -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',