Hi,

tcpdump(8) does support named networks, but only using the following
revolting syntax:

   $ grep fourrev /etc/hosts                                      
  0.192.168.4 fourrev
   $ tcpdump net fourrev
   $ ping 192.168.4.1

Two aspects are wrong with that:

 1. The hosts(5) entry must have leading zero octets,
    which is unlikely to work with other programs using hosts(5)
    and exceedingly ugly besides.

 2. The number of leading zeros determines the prefixlen:
    1 zero -> /24, 2 zeros -> /16, 3 zeros -> /8
    But we really don't want classful networks in 2018...

Unfortunately, the grammer provides no other way to specify the
prefixlen on a named network; and of course, you cannot specify
the prefixlen in hosts(5) either.

So if we want to salvage the feature, we have to change the grammar
to allow (and require)

   $ grep fournet /etc/hosts  
  192.168.4.0 fournet
   $ tcpdump net fournet/24
   $ ping 192.168.4.1

Similarly, we could also support

   $ tcpdump net fournet mask 255.255.255.0

but i don't really see the point, so i do not include it in the
diff below.

Alternatively, we could just stop supporting hosts(5) after
the "net" keyword and always require specifying nets numerically.
I might even prefer that.  If that's what we want, tell me,
and i'll cook a simpler diff.

Thoughts?
  Ingo


Index: gencode.c
===================================================================
RCS file: /cvs/src/lib/libpcap/gencode.c,v
retrieving revision 1.49
diff -u -p -r1.49 gencode.c
--- gencode.c   3 Jun 2018 10:29:28 -0000       1.49
+++ gencode.c   5 Aug 2018 17:11:41 -0000
@@ -2254,15 +2254,16 @@ gen_proto(v, proto, dir)
 }
 
 struct block *
-gen_scode(name, q)
+gen_scode(name, masklen, q)
        const char *name;
+       int masklen;
        struct qual q;
 {
        int proto = q.proto;
        int dir = q.dir;
        int tproto;
        u_char *eaddr;
-       bpf_u_int32 mask, addr;
+       bpf_u_int32 addr;
 #ifndef INET6
        bpf_u_int32 **alist;
 #else
@@ -2275,19 +2276,20 @@ gen_scode(name, q)
        struct block *b, *tmp;
        int port, real_proto;
 
+       if (masklen != -1 && q.addr != Q_NET)
+               bpf_error("prefixlen only supported for networks: %s/%d",
+                   name, masklen);
+
        switch (q.addr) {
 
        case Q_NET:
+               if (masklen < 0)
+                       bpf_error("missing prefixlen for network '%s'", name);
                addr = pcap_nametonetaddr(name);
                if (addr == 0)
                        bpf_error("unknown network '%s'", name);
-               /* Left justify network addr and calculate its network mask */
-               mask = 0xffffffff;
-               while (addr && (addr & 0xff000000) == 0) {
-                       addr <<= 8;
-                       mask <<= 8;
-               }
-               return gen_host(addr, mask, proto, dir);
+               return gen_host(addr, 0xffffffff << (32 - masklen),
+                   proto, dir);
 
        case Q_DEFAULT:
        case Q_HOST:
Index: gencode.h
===================================================================
RCS file: /cvs/src/lib/libpcap/gencode.h,v
retrieving revision 1.18
diff -u -p -r1.18 gencode.h
--- gencode.h   3 Jun 2018 10:29:28 -0000       1.18
+++ gencode.h   5 Aug 2018 17:11:41 -0000
@@ -162,7 +162,7 @@ void gen_and(struct block *, struct bloc
 void gen_or(struct block *, struct block *);
 void gen_not(struct block *);
 
-struct block *gen_scode(const char *, struct qual);
+struct block *gen_scode(const char *, int, struct qual);
 struct block *gen_ecode(const u_char *, struct qual);
 struct block *gen_mcode(const char *, const char *, int, struct qual);
 #ifdef INET6
Index: grammar.y
===================================================================
RCS file: /cvs/src/lib/libpcap/grammar.y,v
retrieving revision 1.19
diff -u -p -r1.19 grammar.y
--- grammar.y   27 Oct 2009 23:59:30 -0000      1.19
+++ grammar.y   5 Aug 2018 17:11:42 -0000
@@ -154,7 +154,8 @@ id:   nid
                                                   $$.q = $<blk>0.q); }
        | paren pid ')'         { $$ = $2; }
        ;
-nid:     ID                    { $$.b = gen_scode($1, $$.q = $<blk>0.q); }
+nid:   ID '/' NUM              { $$.b = gen_scode($1, $3, $$.q = $<blk>0.q); }
+       | ID                    { $$.b = gen_scode($1, -1, $$.q = $<blk>0.q); }
        | HID '/' NUM           { $$.b = gen_mcode($1, NULL, $3,
                                    $$.q = $<blk>0.q); }
        | HID MASK HID          { $$.b = gen_mcode($1, $3, 0,

Reply via email to