tradiotap.c - plan9port - [fork] Plan 9 from user space | |
git clone git://src.adamsgaard.dk/plan9port | |
Log | |
Files | |
Refs | |
README | |
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… | |
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 }; |