tradiotap.c - plan9port - [fork] Plan 9 from user space
 (HTM) git clone git://src.adamsgaard.dk/plan9port
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
       tradiotap.c (1693B)
       ---
            1 /*
            2  * Radio tap as exported by BSD and Linux.
            3  * The wireless ethernet devices return this format on Linux
            4  * when running in monitor mode.
            5  *
            6  * TODO: Automatically determine whether the ethernet
            7  * device is radio or ether, so that -h is not needed.
            8  */
            9 
           10 #include <u.h>
           11 #include <libc.h>
           12 #include <ip.h>
           13 #include "dat.h"
           14 #include "protos.h"
           15 
           16 static Mux p_mux[] =
           17 {
           18         { "802.11", 0 },
           19         { 0 }
           20 };
           21 
           22 typedef struct Hdr Hdr;
           23 struct Hdr
           24 {
           25         uchar vers;
           26         uchar pad;
           27         ushort        len;
           28         ulong        present;
           29 };
           30 
           31 static int
           32 unpackhdr(uchar *p, uchar *ep, Hdr *h)
           33 {
           34         if(p+sizeof(Hdr) > ep)
           35                 return -1;
           36         h->vers = p[0];
           37         h->pad = p[1];
           38         h->len = LittleS(p+2);
           39         h->present = LittleL(p+4);
           40         // can be more present fields if 0x80000000 is set in each along the chain.
           41         if(p+h->len > ep)
           42                 return -1;
           43         return 0;
           44 }
           45 
           46 enum
           47 {
           48         Ot,
           49 };
           50 
           51 static Field p_fields[] =
           52 {
           53         { 0 }
           54 };
           55 
           56 static void
           57 p_compile(Filter *f)
           58 {
           59         Mux *m;
           60 
           61         if(f->op == '='){
           62                 compile_cmp(radiotap.name, f, p_fields);
           63                 return;
           64         }
           65         for(m = p_mux; m->name != nil; m++){
           66                 if(strcmp(f->s, m->name) == 0){
           67                         f->pr = m->pr;
           68                         f->ulv = m->val;
           69                         f->subop = Ot;
           70                         return;
           71                 }
           72         }
           73         sysfatal("unknown radiotap field or protocol: %s", f->s);
           74 }
           75 
           76 static int
           77 p_filter(Filter *f, Msg *m)
           78 {
           79         Hdr h;
           80 
           81         memset(&h, 0, sizeof h);
           82         if(unpackhdr(m->ps, m->pe, &h) < 0)
           83                 return 0;
           84         m->ps += h.len;
           85         switch(f->subop){
           86         case Ot:
           87                 return 1;
           88         }
           89         return 0;
           90 }
           91 
           92 static int
           93 p_seprint(Msg *m)
           94 {
           95         Hdr h;
           96 
           97         memset(&h, 0, sizeof h);
           98         if(unpackhdr(m->ps, m->pe, &h) < 0)
           99                 return -1;
          100 
          101         m->p = seprint(m->p, m->e, "%.*H", h.len, m->ps);
          102         m->ps += h.len;
          103         m->pr = &p80211;
          104         return 0;
          105 }
          106 
          107 Proto radiotap =
          108 {
          109         "radiotap",
          110         p_compile,
          111         p_filter,
          112         p_seprint,
          113         p_mux,
          114         nil,
          115         nil,
          116         defaultframer
          117 };