2 17b19538 2008-07-24 rsc * IEEE 802.11.
5 17b19538 2008-07-24 rsc #include <u.h>
6 17b19538 2008-07-24 rsc #include <libc.h>
7 17b19538 2008-07-24 rsc #include <ip.h>
8 17b19538 2008-07-24 rsc #include "dat.h"
9 17b19538 2008-07-24 rsc #include "protos.h"
17 17b19538 2008-07-24 rsc CtlPoll = 0xA,
27 17b19538 2008-07-24 rsc DataCfAckPoll,
30 17b19538 2008-07-24 rsc NodataCfPoll,
31 17b19538 2008-07-24 rsc NodataCfAckPoll,
33 17b19538 2008-07-24 rsc FlagTods = 0x1,
34 17b19538 2008-07-24 rsc FlagFromds = 0x2,
35 17b19538 2008-07-24 rsc FlagMoreflag = 0x4,
36 17b19538 2008-07-24 rsc FlagRetry = 0x8,
37 17b19538 2008-07-24 rsc FlagPowerMgmt = 0x10,
38 17b19538 2008-07-24 rsc FlagMoreData = 0x20,
39 17b19538 2008-07-24 rsc FlagWep = 0x40,
40 17b19538 2008-07-24 rsc FlagOrder = 0x80,
42 17b19538 2008-07-24 rsc ProtoNone = 0,
46 17b19538 2008-07-24 rsc static Mux p_mux[] =
48 17b19538 2008-07-24 rsc { "llc", ProtoLlc },
52 17b19538 2008-07-24 rsc typedef struct Hdr Hdr;
57 17b19538 2008-07-24 rsc uchar subtype;
63 17b19538 2008-07-24 rsc uchar bssid[6];
72 17b19538 2008-07-24 rsc unpackhdr(uchar *p, uchar *ep, Hdr *h)
76 17b19538 2008-07-24 rsc h->vers = p[0]&3;
77 17b19538 2008-07-24 rsc if(h->vers != 0){
78 17b19538 2008-07-24 rsc h->hdrlen = 2;
81 17b19538 2008-07-24 rsc h->type = (p[0]>>2)&3;
82 17b19538 2008-07-24 rsc h->subtype = (p[0]>>4)&15;
83 17b19538 2008-07-24 rsc h->flags = p[1];
84 17b19538 2008-07-24 rsc h->hdrlen = 2;
86 17b19538 2008-07-24 rsc if(h->vers != 0)
89 17b19538 2008-07-24 rsc switch(h->type){
91 17b19538 2008-07-24 rsc // fc dur da sa bssid seq
92 17b19538 2008-07-24 rsc if(p+2+2+6+6+6+2 > ep)
94 17b19538 2008-07-24 rsc h->hdrlen = 24;
95 17b19538 2008-07-24 rsc h->dur = LittleS(p+2);
96 17b19538 2008-07-24 rsc memmove(h->da, p+4, 6);
97 17b19538 2008-07-24 rsc memmove(h->sa, p+10, 6);
98 17b19538 2008-07-24 rsc memmove(h->bssid, p+16, 6);
99 17b19538 2008-07-24 rsc h->seq = LittleS(p+22);
103 17b19538 2008-07-24 rsc switch(h->subtype){
104 17b19538 2008-07-24 rsc case CtlPoll:
105 17b19538 2008-07-24 rsc // fc aid bssid ta
106 17b19538 2008-07-24 rsc if(p+2+2+6+6 > ep)
108 17b19538 2008-07-24 rsc h->hdrlen = 16;
109 17b19538 2008-07-24 rsc h->aid = LittleS(p+2);
110 17b19538 2008-07-24 rsc memmove(h->bssid, p+4, 6);
111 17b19538 2008-07-24 rsc memmove(h->ta, p+10, 6);
114 17b19538 2008-07-24 rsc case CtlRts:
115 17b19538 2008-07-24 rsc // fc dur ra ta
116 17b19538 2008-07-24 rsc if(p+2+2+6+6 > ep)
118 17b19538 2008-07-24 rsc h->hdrlen = 16;
119 17b19538 2008-07-24 rsc h->dur = LittleS(p+2);
120 17b19538 2008-07-24 rsc memmove(h->ra, p+4, 6);
121 17b19538 2008-07-24 rsc memmove(h->ta, p+10, 6);
124 17b19538 2008-07-24 rsc case CtlCts:
125 17b19538 2008-07-24 rsc case CtlAck:
126 17b19538 2008-07-24 rsc // fc dur ra
127 17b19538 2008-07-24 rsc if(p+2+2+6 > ep)
129 17b19538 2008-07-24 rsc h->hdrlen = 10;
130 17b19538 2008-07-24 rsc h->dur = LittleS(p+2);
131 17b19538 2008-07-24 rsc memmove(h->ra, p+4, 6);
134 17b19538 2008-07-24 rsc case CtlCfEnd:
135 17b19538 2008-07-24 rsc case CtlCfEndAck:
136 17b19538 2008-07-24 rsc // fc dur ra bssid
137 17b19538 2008-07-24 rsc if(p+2+2+6+6 > ep)
139 17b19538 2008-07-24 rsc h->hdrlen = 16;
140 17b19538 2008-07-24 rsc h->dur = LittleS(p+2);
141 17b19538 2008-07-24 rsc memmove(h->ra, p+4, 6);
142 17b19538 2008-07-24 rsc memmove(h->bssid, p+10, 6);
148 17b19538 2008-07-24 rsc if(p+24 > ep)
150 17b19538 2008-07-24 rsc h->hdrlen = 24;
151 17b19538 2008-07-24 rsc h->dur = LittleS(p+2); // ??? maybe
152 17b19538 2008-07-24 rsc // Also, what is at p+22?
154 17b19538 2008-07-24 rsc switch(h->flags&(FlagFromds|FlagTods)){
156 17b19538 2008-07-24 rsc memmove(h->da, p+4, 6);
157 17b19538 2008-07-24 rsc memmove(h->sa, p+10, 6);
158 17b19538 2008-07-24 rsc memmove(h->bssid, p+16, 6);
160 17b19538 2008-07-24 rsc case FlagFromds:
161 17b19538 2008-07-24 rsc memmove(h->da, p+4, 6);
162 17b19538 2008-07-24 rsc memmove(h->bssid, p+10, 6);
163 17b19538 2008-07-24 rsc memmove(h->sa, p+16, 6);
165 17b19538 2008-07-24 rsc case FlagTods:
166 17b19538 2008-07-24 rsc memmove(h->bssid, p+4, 6);
167 17b19538 2008-07-24 rsc memmove(h->sa, p+10, 6);
168 17b19538 2008-07-24 rsc memmove(h->da, p+16, 6);
170 17b19538 2008-07-24 rsc case FlagFromds|FlagTods:
171 17b19538 2008-07-24 rsc if(p+30 > ep)
173 17b19538 2008-07-24 rsc h->hdrlen = 30;
174 17b19538 2008-07-24 rsc memmove(h->ra, p+4, 6);
175 17b19538 2008-07-24 rsc memmove(h->ta, p+10, 6);
176 17b19538 2008-07-24 rsc memmove(h->da, p+16, 6);
177 17b19538 2008-07-24 rsc memmove(h->sa, p+24, 6); // 24 sic
180 17b19538 2008-07-24 rsc p += h->hdrlen;
181 17b19538 2008-07-24 rsc h->proto = ProtoNone;
182 17b19538 2008-07-24 rsc if(!(h->flags&FlagWep))
183 17b19538 2008-07-24 rsc h->proto = ProtoLlc;
200 17b19538 2008-07-24 rsc static Field p_fields[] =
202 17b19538 2008-07-24 rsc { "s", Fether, Os, "source address" },
203 17b19538 2008-07-24 rsc { "d", Fether, Od, "destination address" },
204 17b19538 2008-07-24 rsc { "t", Fether, Ot, "transmit address" },
205 17b19538 2008-07-24 rsc { "r", Fether, Or, "receive address" },
206 17b19538 2008-07-24 rsc { "bssid", Fether, Obssid, "bssid address" },
207 17b19538 2008-07-24 rsc { "a", Fether, Oa, "any address" },
208 17b19538 2008-07-24 rsc { "sd", Fether, Oa, "source|destination address" },
213 17b19538 2008-07-24 rsc p_compile(Filter *f)
217 17b19538 2008-07-24 rsc if(f->op == '='){
218 17b19538 2008-07-24 rsc compile_cmp(p80211.name, f, p_fields);
221 17b19538 2008-07-24 rsc if(strcmp(f->s, "mgmt") == 0){
222 17b19538 2008-07-24 rsc f->pr = &p80211;
223 17b19538 2008-07-24 rsc f->ulv = Tmgmt;
224 17b19538 2008-07-24 rsc f->subop = Ot;
227 17b19538 2008-07-24 rsc if(strcmp(f->s, "ctl") == 0){
228 17b19538 2008-07-24 rsc f->pr = &p80211;
229 17b19538 2008-07-24 rsc f->ulv = Tctl;
230 17b19538 2008-07-24 rsc f->subop = Ot;
233 17b19538 2008-07-24 rsc if(strcmp(f->s, "data") == 0){
234 17b19538 2008-07-24 rsc f->pr = &p80211;
235 17b19538 2008-07-24 rsc f->ulv = Tdata;
236 17b19538 2008-07-24 rsc f->subop = Ot;
239 17b19538 2008-07-24 rsc for(m = p_mux; m->name != nil; m++){
240 17b19538 2008-07-24 rsc if(strcmp(f->s, m->name) == 0){
241 17b19538 2008-07-24 rsc f->pr = m->pr;
242 17b19538 2008-07-24 rsc f->ulv = m->val;
243 17b19538 2008-07-24 rsc f->subop = Opr;
247 17b19538 2008-07-24 rsc sysfatal("unknown 802.11 field or protocol: %s", f->s);
251 17b19538 2008-07-24 rsc p_filter(Filter *f, Msg *m)
255 17b19538 2008-07-24 rsc memset(&h, 0, sizeof h);
256 17b19538 2008-07-24 rsc if(unpackhdr(m->ps, m->pe, &h) < 0)
258 17b19538 2008-07-24 rsc m->ps += h.hdrlen;
260 17b19538 2008-07-24 rsc switch(f->subop){
262 17b19538 2008-07-24 rsc return memcmp(h.sa, f->a, 6) == 0;
264 17b19538 2008-07-24 rsc return memcmp(h.da, f->a, 6) == 0;
266 17b19538 2008-07-24 rsc return memcmp(h.ta, f->a, 6) == 0;
268 17b19538 2008-07-24 rsc return memcmp(h.ra, f->a, 6) == 0;
269 17b19538 2008-07-24 rsc case Obssid:
270 17b19538 2008-07-24 rsc return memcmp(h.bssid, f->a, 6) == 0;
272 17b19538 2008-07-24 rsc return memcmp(h.sa, f->a, 6) == 0
273 17b19538 2008-07-24 rsc || memcmp(h.da, f->a, 6) == 0
274 17b19538 2008-07-24 rsc || memcmp(h.ta, f->a, 6) == 0
275 17b19538 2008-07-24 rsc || memcmp(h.ra, f->a, 6) == 0
276 17b19538 2008-07-24 rsc || memcmp(h.bssid, f->a, 6) == 0;
278 17b19538 2008-07-24 rsc return h.proto == f->ulv;
284 17b19538 2008-07-24 rsc p_seprint(Msg *m)
288 17b19538 2008-07-24 rsc memset(&h, 0, sizeof h);
289 17b19538 2008-07-24 rsc if(unpackhdr(m->ps, m->pe, &h) < 0)
292 17b19538 2008-07-24 rsc m->pr = &dump;
293 17b19538 2008-07-24 rsc m->p = seprint(m->p, m->e, "fc=%02x flags=%02x ", m->ps[0], m->ps[1]);
294 17b19538 2008-07-24 rsc switch(h.type){
296 17b19538 2008-07-24 rsc m->p = seprint(m->p, m->e, "mgmt dur=%d d=%E s=%E bssid=%E seq=%d",
297 17b19538 2008-07-24 rsc h.dur, h.da, h.sa, h.bssid, h.seq);
300 17b19538 2008-07-24 rsc switch(h.subtype){
301 17b19538 2008-07-24 rsc case CtlPoll:
302 17b19538 2008-07-24 rsc m->p = seprint(m->p, m->e, "ctl poll aid=%d bssid=%E t=%E",
303 17b19538 2008-07-24 rsc h.aid, h.bssid, h.ta);
305 17b19538 2008-07-24 rsc case CtlRts:
306 17b19538 2008-07-24 rsc m->p = seprint(m->p, m->e, "ctl rts dur=%d r=%E t=%E",
307 17b19538 2008-07-24 rsc h.dur, h.ra, h.ta);
309 17b19538 2008-07-24 rsc case CtlCts:
310 17b19538 2008-07-24 rsc m->p = seprint(m->p, m->e, "ctl cts dur=%d r=%E",
311 17b19538 2008-07-24 rsc h.dur, h.ra);
313 17b19538 2008-07-24 rsc case CtlAck:
314 17b19538 2008-07-24 rsc m->p = seprint(m->p, m->e, "ctl ack dur=%d r=%E",
315 17b19538 2008-07-24 rsc h.dur, h.ra);
317 17b19538 2008-07-24 rsc case CtlCfEnd:
318 17b19538 2008-07-24 rsc m->p = seprint(m->p, m->e, "ctl cf end dur=%d r=%E bssid=%E",
319 17b19538 2008-07-24 rsc h.dur, h.ra, h.bssid);
321 17b19538 2008-07-24 rsc case CtlCfEndAck:
322 17b19538 2008-07-24 rsc m->p = seprint(m->p, m->e, "ctl cf end ack dur=%d r=%E bssid=%E",
323 17b19538 2008-07-24 rsc h.dur, h.ra, h.bssid);
326 17b19538 2008-07-24 rsc m->p = seprint(m->p, m->e, "ctl %.*H", m->ps, h.hdrlen);
331 17b19538 2008-07-24 rsc switch(h.flags&(FlagFromds|FlagTods)){
333 17b19538 2008-07-24 rsc m->p = seprint(m->p, m->e, "data d=%E s=%E bssid=%E",
334 17b19538 2008-07-24 rsc h.da, h.sa, h.bssid);
336 17b19538 2008-07-24 rsc case FlagFromds:
337 17b19538 2008-07-24 rsc m->p = seprint(m->p, m->e, "data fds d=%E bssid=%E s=%E",
338 17b19538 2008-07-24 rsc h.da, h.bssid, h.sa);
340 17b19538 2008-07-24 rsc case FlagTods:
341 17b19538 2008-07-24 rsc m->p = seprint(m->p, m->e, "data tds bssid=%E s=%E d=%E",
342 17b19538 2008-07-24 rsc h.bssid, h.sa, h.da);
344 17b19538 2008-07-24 rsc case FlagFromds|FlagTods:
345 17b19538 2008-07-24 rsc m->p = seprint(m->p, m->e, "data fds tds r=%E t=%E d=%E s=%E",
346 17b19538 2008-07-24 rsc h.ra, h.ta, h.da, h.sa);
349 17b19538 2008-07-24 rsc if(!(h.flags&FlagWep))
350 17b19538 2008-07-24 rsc m->pr = &llc;
353 17b19538 2008-07-24 rsc m->ps += h.hdrlen;
357 17b19538 2008-07-24 rsc Proto p80211 =
366 17b19538 2008-07-24 rsc defaultframer