On 13/05/11 12:52 AM, Darren Reed wrote:
On 12/05/11 04:27 AM, Guy Harris wrote:

On May 10, 2011, at 1:40 PM, Darren Reed wrote:

To pursue this a little further, experimenting has
determined that the best layout thus far would be
something similar to this:

bits field
00-07 version (1)
08-15 pad (0)
16-31 pre-mac payload length
32-63 dlt (DLT_*)
64-79 ethernet protocol number
80-95 pad (0)

What about packets for which there is no appropriate Ethernet protocol number value, such as:

various link control protocols for PPP;

management and control frames for 802.11 (and similar frames for older LAN technologies such as FDDI and Token Ring);

LAN frames with 802.2 headers with DSAPs for which there's no Ethernet protocol number;

LAN frames with 802.2+SNAP headers with an OUI other than 0x000000;

etc.?


An alternative would be like this:

bits  field values
----- ------------
00-07 version (1)
08-15 control field for bits 64-95
16-31 pre-mac payload length
32-63 dlt (DLT_*)
64-95 mac payload type

So, if bits 08-15 are 0, 64-79 are 0 and 80-95 are the ethernet protocol number.

...

I've adopted the comments directly above into the frame format being used.

The attached diffs represent the changes required to have libpcap properly work with this header. As yet I haven't seen a DLT assigned, so I've chosen one a fair distance off - 16384. At present the code generator assumes that bits 8-15 are 0 because thus far there is no other type of packet being generated.

Darren

diff -ur libpcap-clone/bpf_image.c libpcap/bpf_image.c
--- libpcap-clone/bpf_image.c   Fri Jun  3 20:41:14 2011
+++ libpcap/bpf_image.c Wed May 11 23:42:42 2011
@@ -130,6 +130,11 @@
                fmt = "4*([%d]&0xf)";
                break;
 
+       case BPF_LDX|BPF_MSHM|BPF_B:
+               op = "ldxbi";
+               fmt = "4*([[%d]]&0xf)";
+               break;
+
        case BPF_LD|BPF_MEM:
                op = "ld";
                fmt = "M[%d]";
diff -ur libpcap-clone/gencode.c libpcap/gencode.c
--- libpcap-clone/gencode.c     Fri Jun  3 20:41:14 2011
+++ libpcap/gencode.c   Fri Jun  3 19:47:06 2011
@@ -1608,6 +1608,14 @@
                off_nl = -1;
                off_nl_nosnap = -1;
                return;
+
+       case DLT_LINK:
+               off_linktype = 8;
+               off_macpl = 0;
+               off_macpl_is_variable = 1;
+               off_nl = 0;
+               off_nl_nosnap = 0;
+               return;
        }
        bpf_error("unknown data link type %d", linktype);
        /* NOTREACHED */
@@ -1776,7 +1784,10 @@
 {
        struct slist *s, *s2;
 
-       s = gen_off_macpl();
+       if (linktype != DLT_LINK)
+               s = gen_off_macpl();
+       else
+               s = NULL;
        if (s != NULL) {
                /*
                 * There's a variable-length prefix preceding the
@@ -1818,8 +1829,13 @@
                 * of off_mac_pl + off_nl from the beginning of the
                 * raw packet data.
                 */
-               s = new_stmt(BPF_LDX|BPF_MSH|BPF_B);
-               s->s.k = off_macpl + off_nl;
+               if (linktype == DLT_LINK) {
+                       s = new_stmt(BPF_LDX|BPF_MSHM|BPF_B);
+                       s->s.k = 2;
+               } else {
+                       s = new_stmt(BPF_LDX|BPF_MSH|BPF_B);
+                       s->s.k = off_macpl + off_nl;
+               }
        }
        return s;
 }
@@ -2437,6 +2453,39 @@
                return (NULL);
 }
 
+static struct slist *
+gen_load_link_ll_header_len()
+{
+       struct slist *s1, *s2;
+
+       if (reg_off_macpl == -1)
+               reg_off_macpl = alloc_reg();
+
+       /*
+        * Generate code to load the length of the link header into
+        * the register assigned to hold that length, if one has been
+        * assigned.  (If one hasn't been assigned, no code we've
+        * generated uses that prefix, so we don't need to generate any
+        * code to load it.)
+        */
+       if (reg_off_macpl != -1) {
+               s1 = new_stmt(BPF_LD|BPF_H|BPF_ABS);
+               s1->s.k = 2;
+               s2 = new_stmt(BPF_ST);
+               s2->s.k = reg_off_macpl;
+               sappend(s1, s2);
+
+               /*
+                * Now move it into the X register.
+                */
+               s2 = new_stmt(BPF_MISC|BPF_TAX);
+               sappend(s1, s2);
+
+               return (s1);
+       } else
+               return (NULL);
+}
+
 /* 
  * At the moment we treat PPI as normal Radiotap encoded
  * packets. The difference is in the function that generates
@@ -2775,6 +2824,11 @@
        case DLT_PPI:
                s = gen_load_802_11_header_len(s, b->stmts);
                break;
+
+       case DLT_LINK:
+               s = gen_load_link_ll_header_len();
+               break;
+
        }
 
        /*
@@ -5685,8 +5739,13 @@
                s[i]->s.k = off_macpl + off_nl + 9;
                i++;
                /* X = ip->ip_hl << 2 */
-               s[i] = new_stmt(BPF_LDX|BPF_MSH|BPF_B);
-               s[i]->s.k = off_macpl + off_nl;
+               if (linktype == DLT_LINK) {
+                       s[i] = new_stmt(BPF_LDX|BPF_MSHM|BPF_B);
+                       s[i]->s.k = 2;
+               } else {
+                       s[i] = new_stmt(BPF_LDX|BPF_MSH|BPF_B);
+                       s[i]->s.k = off_macpl + off_nl;
+               }
                i++;
                break;
 #ifdef INET6
diff -ur libpcap-clone/optimize.c libpcap/optimize.c
--- libpcap-clone/optimize.c    Fri Jun  3 20:41:15 2011
+++ libpcap/optimize.c  Wed May 11 23:36:55 2011
@@ -785,7 +785,8 @@
                         * following it (with 0 or more nops between the
                         * ldxms and addx).
                         */
-                       if (next->s.code != (BPF_LDX|BPF_MSH|BPF_B))
+                       if (next->s.code != (BPF_LDX|BPF_MSH|BPF_B) &&
+                           next->s.code != (BPF_LDX|BPF_MSHM|BPF_B))
                                add = next;
                        else
                                add = this_op(next->next);
@@ -1028,6 +1029,11 @@
        case BPF_LDX|BPF_MSH|BPF_B:
                v = F(s->code, s->k, 0L);
                vstore(s, &val[X_ATOM], v, alter);
+               break;
+
+       case BPF_LDX|BPF_MSHM|BPF_B:
+               v = F(s->code, s->k, 0L);
+               vstore(s, &val[X_ATOM], v, alter);
                break;
 
        case BPF_ALU|BPF_NEG:
diff -ur libpcap-clone/bpf/net/bpf_filter.c libpcap/bpf/net/bpf_filter.c
--- libpcap-clone/bpf/net/bpf_filter.c  Fri Jun  3 20:41:14 2011
+++ libpcap/bpf/net/bpf_filter.c        Fri Jun  3 19:47:06 2011
@@ -363,8 +363,26 @@
                        A = p[k];
                        continue;
 
+               case BPF_LDX|BPF_MSHM|BPF_B:
+                       k = pc->k;
+                       if (k >= buflen) {
+#if defined(KERNEL) || defined(_KERNEL)
+                               if (m == NULL)
+                                       return 0;
+                               n = m;
+                               MINDEX(len, n, k);
+                               k = mtod(n, u_char *)[k];
+#else
+                               return 0;
+#endif
+                       } else {
+                               k = p[k];
+                       }
+                       goto bpf_do_msh;
+
                case BPF_LDX|BPF_MSH|BPF_B:
                        k = pc->k;
+bpf_do_msh:
                        if (k >= buflen) {
 #if defined(KERNEL) || defined(_KERNEL)
                                if (m == NULL)
@@ -371,13 +389,13 @@
                                        return 0;
                                n = m;
                                MINDEX(len, n, k);
-                               X = (mtod(n, char *)[k] & 0xf) << 2;
+                               X = (mtod(n, u_char *)[k] & 0xf) << 2;
                                continue;
 #else
                                return 0;
 #endif
                        }
-                       X = (p[pc->k] & 0xf) << 2;
+                       X = (p[k] & 0xf) << 2;
                        continue;
 
                case BPF_LD|BPF_IMM:
@@ -575,6 +593,7 @@
                        case BPF_ABS:
                        case BPF_IND:
                        case BPF_MSH:
+                       case BPF_MSHM:
                                /*
                                 * There's no maximum packet data size
                                 * in userland.  The runtime packet length
diff -ur libpcap-clone/net/bpf_filter.c libpcap/net/bpf_filter.c
--- libpcap-clone/net/bpf_filter.c      Fri Jun  3 20:41:14 2011
+++ libpcap/net/bpf_filter.c    Fri Jun  3 19:47:06 2011
@@ -363,8 +363,26 @@
                        A = p[k];
                        continue;
 
+               case BPF_LDX|BPF_MSHM|BPF_B:
+                       k = pc->k;
+                       if (k >= buflen) {
+#if defined(KERNEL) || defined(_KERNEL)
+                               if (m == NULL)
+                                       return 0;
+                               n = m;
+                               MINDEX(len, n, k);
+                               k = mtod(n, u_char *)[k];
+#else
+                               return 0;
+#endif
+                       } else {
+                               k = p[k];
+                       }
+                       goto bpf_do_msh;
+
                case BPF_LDX|BPF_MSH|BPF_B:
                        k = pc->k;
+bpf_do_msh:
                        if (k >= buflen) {
 #if defined(KERNEL) || defined(_KERNEL)
                                if (m == NULL)
@@ -371,13 +389,13 @@
                                        return 0;
                                n = m;
                                MINDEX(len, n, k);
-                               X = (mtod(n, char *)[k] & 0xf) << 2;
+                               X = (mtod(n, u_char *)[k] & 0xf) << 2;
                                continue;
 #else
                                return 0;
 #endif
                        }
-                       X = (p[pc->k] & 0xf) << 2;
+                       X = (p[k] & 0xf) << 2;
                        continue;
 
                case BPF_LD|BPF_IMM:
@@ -575,6 +593,7 @@
                        case BPF_ABS:
                        case BPF_IND:
                        case BPF_MSH:
+                       case BPF_MSHM:
                                /*
                                 * There's no maximum packet data size
                                 * in userland.  The runtime packet length
diff -ur libpcap-clone/pcap/bpf.h libpcap/pcap/bpf.h
--- libpcap-clone/pcap/bpf.h    Fri Jun  3 20:41:15 2011
+++ libpcap/pcap/bpf.h  Fri Jun  3 19:47:07 2011
@@ -993,6 +993,8 @@
  */
 #define DLT_DBUS                       231
 
+#define        DLT_LINK                        16384
+
 /*
  * Juniper-private data link type, as per request from
  * Hannes Gredler <han...@juniper.net>.
@@ -1078,6 +1080,7 @@
 #define                BPF_MEM         0x60
 #define                BPF_LEN         0x80
 #define                BPF_MSH         0xa0
+#define                BPF_MSHM        0xe0
 
 /* alu/jmp fields */
 #define BPF_OP(code)   ((code) & 0xf0)
-
This is the tcpdump-workers list.
Visit https://cod.sandelman.ca/ to unsubscribe.

Reply via email to