Blame


1 fa325e9b 2020-01-10 cross /*
2 17b19538 2008-07-24 rsc * IEEE 802.11.
3 17b19538 2008-07-24 rsc */
4 17b19538 2008-07-24 rsc
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"
10 17b19538 2008-07-24 rsc
11 17b19538 2008-07-24 rsc enum
12 17b19538 2008-07-24 rsc {
13 17b19538 2008-07-24 rsc Tmgmt = 0,
14 17b19538 2008-07-24 rsc Tctl,
15 17b19538 2008-07-24 rsc Tdata,
16 17b19538 2008-07-24 rsc
17 17b19538 2008-07-24 rsc CtlPoll = 0xA,
18 17b19538 2008-07-24 rsc CtlRts,
19 17b19538 2008-07-24 rsc CtlCts,
20 17b19538 2008-07-24 rsc CtlAck,
21 17b19538 2008-07-24 rsc CtlCfEnd,
22 17b19538 2008-07-24 rsc CtlCfEndAck,
23 17b19538 2008-07-24 rsc
24 17b19538 2008-07-24 rsc Data = 0,
25 17b19538 2008-07-24 rsc DataCfAck,
26 17b19538 2008-07-24 rsc DataCfPoll,
27 17b19538 2008-07-24 rsc DataCfAckPoll,
28 17b19538 2008-07-24 rsc Nodata,
29 17b19538 2008-07-24 rsc NodataCfAck,
30 17b19538 2008-07-24 rsc NodataCfPoll,
31 17b19538 2008-07-24 rsc NodataCfAckPoll,
32 fa325e9b 2020-01-10 cross
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,
41 fa325e9b 2020-01-10 cross
42 17b19538 2008-07-24 rsc ProtoNone = 0,
43 17b19538 2008-07-24 rsc ProtoLlc,
44 17b19538 2008-07-24 rsc };
45 17b19538 2008-07-24 rsc
46 17b19538 2008-07-24 rsc static Mux p_mux[] =
47 17b19538 2008-07-24 rsc {
48 17b19538 2008-07-24 rsc { "llc", ProtoLlc },
49 17b19538 2008-07-24 rsc { 0 }
50 17b19538 2008-07-24 rsc };
51 17b19538 2008-07-24 rsc
52 17b19538 2008-07-24 rsc typedef struct Hdr Hdr;
53 17b19538 2008-07-24 rsc struct Hdr
54 17b19538 2008-07-24 rsc {
55 17b19538 2008-07-24 rsc uchar vers;
56 17b19538 2008-07-24 rsc uchar type;
57 17b19538 2008-07-24 rsc uchar subtype;
58 17b19538 2008-07-24 rsc uchar flags;
59 17b19538 2008-07-24 rsc ushort dur;
60 17b19538 2008-07-24 rsc uchar aid;
61 17b19538 2008-07-24 rsc uchar ra[6];
62 17b19538 2008-07-24 rsc uchar ta[6];
63 17b19538 2008-07-24 rsc uchar bssid[6];
64 17b19538 2008-07-24 rsc uchar sa[6];
65 17b19538 2008-07-24 rsc uchar da[6];
66 17b19538 2008-07-24 rsc ushort seq;
67 17b19538 2008-07-24 rsc int proto;
68 17b19538 2008-07-24 rsc int hdrlen;
69 17b19538 2008-07-24 rsc };
70 17b19538 2008-07-24 rsc
71 17b19538 2008-07-24 rsc static int
72 17b19538 2008-07-24 rsc unpackhdr(uchar *p, uchar *ep, Hdr *h)
73 17b19538 2008-07-24 rsc {
74 17b19538 2008-07-24 rsc if(p+2 > ep)
75 17b19538 2008-07-24 rsc return -1;
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;
79 17b19538 2008-07-24 rsc return -1;
80 17b19538 2008-07-24 rsc }
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;
85 17b19538 2008-07-24 rsc
86 17b19538 2008-07-24 rsc if(h->vers != 0)
87 17b19538 2008-07-24 rsc return 0;
88 fa325e9b 2020-01-10 cross
89 17b19538 2008-07-24 rsc switch(h->type){
90 17b19538 2008-07-24 rsc case Tmgmt:
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)
93 17b19538 2008-07-24 rsc return -1;
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);
100 17b19538 2008-07-24 rsc break;
101 fa325e9b 2020-01-10 cross
102 17b19538 2008-07-24 rsc case Tctl:
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)
107 17b19538 2008-07-24 rsc return -1;
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);
112 17b19538 2008-07-24 rsc break;
113 fa325e9b 2020-01-10 cross
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)
117 17b19538 2008-07-24 rsc return -1;
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);
122 17b19538 2008-07-24 rsc break;
123 fa325e9b 2020-01-10 cross
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)
128 17b19538 2008-07-24 rsc return -1;
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);
132 17b19538 2008-07-24 rsc break;
133 fa325e9b 2020-01-10 cross
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)
138 17b19538 2008-07-24 rsc return -1;
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);
143 17b19538 2008-07-24 rsc break;
144 17b19538 2008-07-24 rsc }
145 17b19538 2008-07-24 rsc break;
146 fa325e9b 2020-01-10 cross
147 17b19538 2008-07-24 rsc case Tdata:
148 17b19538 2008-07-24 rsc if(p+24 > ep)
149 17b19538 2008-07-24 rsc return -1;
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?
153 17b19538 2008-07-24 rsc
154 17b19538 2008-07-24 rsc switch(h->flags&(FlagFromds|FlagTods)){
155 17b19538 2008-07-24 rsc case 0:
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);
159 17b19538 2008-07-24 rsc break;
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);
164 17b19538 2008-07-24 rsc break;
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);
169 17b19538 2008-07-24 rsc break;
170 17b19538 2008-07-24 rsc case FlagFromds|FlagTods:
171 17b19538 2008-07-24 rsc if(p+30 > ep)
172 17b19538 2008-07-24 rsc return -1;
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
178 17b19538 2008-07-24 rsc break;
179 17b19538 2008-07-24 rsc }
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;
184 17b19538 2008-07-24 rsc break;
185 17b19538 2008-07-24 rsc }
186 fa325e9b 2020-01-10 cross return 0;
187 17b19538 2008-07-24 rsc }
188 17b19538 2008-07-24 rsc
189 17b19538 2008-07-24 rsc enum
190 17b19538 2008-07-24 rsc {
191 17b19538 2008-07-24 rsc Os,
192 17b19538 2008-07-24 rsc Od,
193 17b19538 2008-07-24 rsc Ot,
194 17b19538 2008-07-24 rsc Or,
195 17b19538 2008-07-24 rsc Obssid,
196 17b19538 2008-07-24 rsc Oa,
197 17b19538 2008-07-24 rsc Opr,
198 17b19538 2008-07-24 rsc };
199 17b19538 2008-07-24 rsc
200 17b19538 2008-07-24 rsc static Field p_fields[] =
201 17b19538 2008-07-24 rsc {
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" },
209 17b19538 2008-07-24 rsc { 0 }
210 17b19538 2008-07-24 rsc };
211 17b19538 2008-07-24 rsc
212 17b19538 2008-07-24 rsc static void
213 17b19538 2008-07-24 rsc p_compile(Filter *f)
214 17b19538 2008-07-24 rsc {
215 17b19538 2008-07-24 rsc Mux *m;
216 17b19538 2008-07-24 rsc
217 17b19538 2008-07-24 rsc if(f->op == '='){
218 17b19538 2008-07-24 rsc compile_cmp(p80211.name, f, p_fields);
219 17b19538 2008-07-24 rsc return;
220 17b19538 2008-07-24 rsc }
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;
225 17b19538 2008-07-24 rsc return;
226 17b19538 2008-07-24 rsc }
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;
231 17b19538 2008-07-24 rsc return;
232 17b19538 2008-07-24 rsc }
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;
237 17b19538 2008-07-24 rsc return;
238 17b19538 2008-07-24 rsc }
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;
244 17b19538 2008-07-24 rsc return;
245 17b19538 2008-07-24 rsc }
246 17b19538 2008-07-24 rsc }
247 17b19538 2008-07-24 rsc sysfatal("unknown 802.11 field or protocol: %s", f->s);
248 17b19538 2008-07-24 rsc }
249 17b19538 2008-07-24 rsc
250 17b19538 2008-07-24 rsc static int
251 17b19538 2008-07-24 rsc p_filter(Filter *f, Msg *m)
252 17b19538 2008-07-24 rsc {
253 17b19538 2008-07-24 rsc Hdr h;
254 17b19538 2008-07-24 rsc
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)
257 17b19538 2008-07-24 rsc return 0;
258 17b19538 2008-07-24 rsc m->ps += h.hdrlen;
259 17b19538 2008-07-24 rsc
260 17b19538 2008-07-24 rsc switch(f->subop){
261 17b19538 2008-07-24 rsc case Os:
262 17b19538 2008-07-24 rsc return memcmp(h.sa, f->a, 6) == 0;
263 17b19538 2008-07-24 rsc case Od:
264 17b19538 2008-07-24 rsc return memcmp(h.da, f->a, 6) == 0;
265 17b19538 2008-07-24 rsc case Ot:
266 17b19538 2008-07-24 rsc return memcmp(h.ta, f->a, 6) == 0;
267 17b19538 2008-07-24 rsc case Or:
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;
271 17b19538 2008-07-24 rsc case Oa:
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;
277 17b19538 2008-07-24 rsc case Opr:
278 17b19538 2008-07-24 rsc return h.proto == f->ulv;
279 17b19538 2008-07-24 rsc }
280 17b19538 2008-07-24 rsc return 0;
281 17b19538 2008-07-24 rsc }
282 17b19538 2008-07-24 rsc
283 17b19538 2008-07-24 rsc static int
284 17b19538 2008-07-24 rsc p_seprint(Msg *m)
285 17b19538 2008-07-24 rsc {
286 17b19538 2008-07-24 rsc Hdr h;
287 fa325e9b 2020-01-10 cross
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)
290 17b19538 2008-07-24 rsc return -1;
291 17b19538 2008-07-24 rsc
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){
295 17b19538 2008-07-24 rsc case Tmgmt:
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);
298 17b19538 2008-07-24 rsc break;
299 17b19538 2008-07-24 rsc case Tctl:
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);
304 17b19538 2008-07-24 rsc break;
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);
308 17b19538 2008-07-24 rsc break;
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);
312 17b19538 2008-07-24 rsc break;
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);
316 17b19538 2008-07-24 rsc break;
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);
320 17b19538 2008-07-24 rsc break;
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);
324 17b19538 2008-07-24 rsc break;
325 17b19538 2008-07-24 rsc default:
326 17b19538 2008-07-24 rsc m->p = seprint(m->p, m->e, "ctl %.*H", m->ps, h.hdrlen);
327 17b19538 2008-07-24 rsc break;
328 17b19538 2008-07-24 rsc }
329 17b19538 2008-07-24 rsc break;
330 17b19538 2008-07-24 rsc case Tdata:
331 17b19538 2008-07-24 rsc switch(h.flags&(FlagFromds|FlagTods)){
332 17b19538 2008-07-24 rsc case 0:
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);
335 17b19538 2008-07-24 rsc break;
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);
339 17b19538 2008-07-24 rsc break;
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);
343 17b19538 2008-07-24 rsc break;
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);
347 17b19538 2008-07-24 rsc break;
348 17b19538 2008-07-24 rsc }
349 17b19538 2008-07-24 rsc if(!(h.flags&FlagWep))
350 17b19538 2008-07-24 rsc m->pr = &llc;
351 17b19538 2008-07-24 rsc break;
352 17b19538 2008-07-24 rsc }
353 17b19538 2008-07-24 rsc m->ps += h.hdrlen;
354 17b19538 2008-07-24 rsc return 0;
355 17b19538 2008-07-24 rsc }
356 17b19538 2008-07-24 rsc
357 17b19538 2008-07-24 rsc Proto p80211 =
358 17b19538 2008-07-24 rsc {
359 17b19538 2008-07-24 rsc "802.11",
360 17b19538 2008-07-24 rsc p_compile,
361 17b19538 2008-07-24 rsc p_filter,
362 17b19538 2008-07-24 rsc p_seprint,
363 17b19538 2008-07-24 rsc p_mux,
364 17b19538 2008-07-24 rsc nil,
365 17b19538 2008-07-24 rsc nil,
366 17b19538 2008-07-24 rsc defaultframer
367 17b19538 2008-07-24 rsc };