Hello,
i wish to share (hoping it might be found of interest) a patch i've
written for personal use; it merges fine against the daily tarball of
09-06-2005 (yesterday). It aims to enhance the actual support for MPLS
label hierarchies in a BPF filter.

Actually it's not possible, for example, to match a label ignoring the
content of the upper ones. The patch allows to write an expression like
'mpls 1:100000 and mpls 3:1024' which checks whether the 2nd label has
value 100000 and the 4th has value 1024 (the top label is meant to be
0).

Though, i'm conscious of the following facts: a) the patch breaks the
actual filter syntax (not specifying the position of the label in the
stack is legal but matches everytime against the top label); b) it
breaks the strict bottom-up approach because it allows to jump behind
but still inside the MPLS stack (ie, 'mpls 3:1024 and mpls 1:100000' is
legal); c) it does not address the issue of supporting upper layers in
presence of MPLS in a BPF filter.

Cheers,
Paolo


diff -ur libpcap-2005.06.09/gencode.c libpcap-2005.06.09-paolo/gencode.c
--- libpcap-2005.06.09/gencode.c        2005-06-06 16:10:58.000000000 +0200
+++ libpcap-2005.06.09-paolo/gencode.c  2005-06-10 11:29:26.000000000 +0200
@@ -6221,10 +6221,15 @@
  * support for MPLS
  */
 struct block *
-gen_mpls(label_num)
+gen_mpls(stack_pos, label_num)
+       int stack_pos;
        int label_num;
 {
        struct  block   *b0;
+       int nl; 
+
+       if (orig_nl == -1) orig_nl = off_nl;
+       nl = orig_nl+(stack_pos*4)+4;
 
        /*
         * Change the offsets to point to the type and data fields within
@@ -6235,25 +6240,23 @@
         *
         * XXX - this is a bit of a kludge.  See comments in gen_vlan().
         */
-        orig_linktype = off_linktype;  /* save original values */
-        orig_nl = off_nl;
 
         switch (linktype) {
             
         case DLT_C_HDLC: /* fall through */
         case DLT_EN10MB:
-                off_nl_nosnap += 4;
-                off_nl += 4;
+                off_nl_nosnap = nl;
+                off_nl = nl;
                         
-                b0 = gen_cmp(OR_LINK, orig_linktype, BPF_H,
+                b0 = gen_cmp(OR_LINK, off_linktype, BPF_H,
                     (bpf_int32)ETHERTYPE_MPLS);
                 break;
 
         case DLT_PPP:
-                off_nl_nosnap += 4;
-                off_nl += 4;
+                off_nl_nosnap = nl;
+                off_nl = nl;
 
-                b0 = gen_cmp(OR_LINK, orig_linktype, BPF_H,
+                b0 = gen_cmp(OR_LINK, off_linktype, BPF_H,
                     (bpf_int32)PPP_MPLS_UCAST);
                 break;
 
@@ -6274,7 +6277,7 @@
                struct block *b1;
 
                label_num = label_num << 12; /* label is shifted 12 bits on the 
wire */
-               b1 = gen_mcmp(OR_LINK, orig_nl, BPF_W, (bpf_int32)label_num,
+               b1 = gen_mcmp(OR_LINK, orig_nl+(stack_pos*4), BPF_W, 
(bpf_int32)label_num,
                    0xfffff000); /* only compare the first 20 bits */
                gen_and(b0, b1);
                b0 = b1;
diff -ur libpcap-2005.06.09/gencode.h libpcap-2005.06.09-paolo/gencode.h
--- libpcap-2005.06.09/gencode.h        2005-05-02 23:13:08.000000000 +0200
+++ libpcap-2005.06.09-paolo/gencode.h  2005-06-10 11:15:29.000000000 +0200
@@ -280,7 +280,7 @@
 struct block *gen_inbound(int);
 
 struct block *gen_vlan(int);
-struct block *gen_mpls(int);
+struct block *gen_mpls(int, int);
 
 struct block *gen_atmfield_code(int atmfield, bpf_int32 jvalue, bpf_u_int32 
jtype, int reverse);
 struct block *gen_atmtype_abbrev(int type);
diff -ur libpcap-2005.06.09/grammar.y libpcap-2005.06.09-paolo/grammar.y
--- libpcap-2005.06.09/grammar.y        2005-05-02 23:13:09.000000000 +0200
+++ libpcap-2005.06.09-paolo/grammar.y  2005-06-10 11:15:29.000000000 +0200
@@ -325,8 +325,9 @@
        | OUTBOUND              { $$ = gen_inbound(1); }
        | VLAN pnum             { $$ = gen_vlan($2); }
        | VLAN                  { $$ = gen_vlan(-1); }
-       | MPLS pnum             { $$ = gen_mpls($2); }
-       | MPLS                  { $$ = gen_mpls(-1); }
+       | MPLS pnum             { $$ = gen_mpls(0, $2); }
+       | MPLS pnum ':' pnum    { $$ = gen_mpls($2, $4); }
+       | MPLS                  { $$ = gen_mpls(-1, -1); }
        | pfvar                 { $$ = $1; }
        ;
 
-
This is the tcpdump-workers list.
Visit https://lists.sandelman.ca/ to unsubscribe.

Reply via email to