]> The Tcpdump Group git mirrors - tcpdump/blob - print-802_11.c
whitespace changes
[tcpdump] / print-802_11.c
1 /*
2 * Copyright (c) 2001
3 * Fortress Technologies, Inc. All rights reserved.
4 * Charlie Lenahan (clenahan@fortresstech.com)
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that: (1) source code distributions
8 * retain the above copyright notice and this paragraph in its entirety, (2)
9 * distributions including binary code include the above copyright notice and
10 * this paragraph in its entirety in the documentation or other materials
11 * provided with the distribution, and (3) all advertising materials mentioning
12 * features or use of this software display the following acknowledgement:
13 * ``This product includes software developed by the University of California,
14 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
15 * the University nor the names of its contributors may be used to endorse
16 * or promote products derived from this software without specific prior
17 * written permission.
18 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
19 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
20 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
21 */
22
23 #ifndef lint
24 static const char rcsid[] _U_ =
25 "@(#) $Header: /tcpdump/master/tcpdump/print-802_11.c,v 1.49 2007-12-29 23:25:02 guy Exp $ (LBL)";
26 #endif
27
28 #ifdef HAVE_CONFIG_H
29 #include "config.h"
30 #endif
31
32 #include <tcpdump-stdinc.h>
33
34 #include <stdio.h>
35 #include <pcap.h>
36 #include <string.h>
37
38 #include "interface.h"
39 #include "addrtoname.h"
40 #include "ethertype.h"
41
42 #include "extract.h"
43
44 #include "cpack.h"
45
46 #include "ieee802_11.h"
47 #include "ieee802_11_radio.h"
48
49 static const char tstr[] = "[|802.11]";
50
51 /* Radiotap state */
52 /* This is used to save state when parsing/processing parameters */
53 struct radiotap_state
54 {
55 u_int32_t present;
56
57 u_int8_t rate;
58 };
59
60 #define PRINT_SSID(p) \
61 if (p.ssid_present) { \
62 printf(" ("); \
63 fn_print(p.ssid.ssid, NULL); \
64 printf(")"); \
65 }
66
67 #define PRINT_RATE(_sep, _r, _suf) \
68 printf("%s%2.1f%s", _sep, (.5 * ((_r) & 0x7f)), _suf)
69 #define PRINT_RATES(p) \
70 if (p.rates_present) { \
71 int z; \
72 const char *sep = " ["; \
73 for (z = 0; z < p.rates.length ; z++) { \
74 PRINT_RATE(sep, p.rates.rate[z], \
75 (p.rates.rate[z] & 0x80 ? "*" : "")); \
76 sep = " "; \
77 } \
78 if (p.rates.length != 0) \
79 printf(" Mbit]"); \
80 }
81
82 #define PRINT_DS_CHANNEL(p) \
83 if (p.ds_present) \
84 printf(" CH: %u", p.ds.channel); \
85 printf("%s", \
86 CAPABILITY_PRIVACY(p.capability_info) ? ", PRIVACY" : "" );
87
88 #define MAX_MCS_INDEX 76
89
90 /*
91 * Indices are:
92 *
93 * the MCS index (0-76);
94 *
95 * 0 for 20 MHz, 1 for 40 MHz;
96 *
97 * 0 for a long guard interval, 1 for a short guard interval.
98 */
99 static const float ieee80211_float_htrates[MAX_MCS_INDEX+1][2][2] = {
100 /* MCS 0 */
101 { /* 20 Mhz */ { 6.5, /* SGI */ 7.2, },
102 /* 40 Mhz */ { 13.5, /* SGI */ 15.0, },
103 },
104
105 /* MCS 1 */
106 { /* 20 Mhz */ { 13.0, /* SGI */ 14.4, },
107 /* 40 Mhz */ { 27.0, /* SGI */ 30.0, },
108 },
109
110 /* MCS 2 */
111 { /* 20 Mhz */ { 19.5, /* SGI */ 21.7, },
112 /* 40 Mhz */ { 40.5, /* SGI */ 45.0, },
113 },
114
115 /* MCS 3 */
116 { /* 20 Mhz */ { 26.0, /* SGI */ 28.9, },
117 /* 40 Mhz */ { 54.0, /* SGI */ 60.0, },
118 },
119
120 /* MCS 4 */
121 { /* 20 Mhz */ { 39.0, /* SGI */ 43.3, },
122 /* 40 Mhz */ { 81.0, /* SGI */ 90.0, },
123 },
124
125 /* MCS 5 */
126 { /* 20 Mhz */ { 52.0, /* SGI */ 57.8, },
127 /* 40 Mhz */ { 108.0, /* SGI */ 120.0, },
128 },
129
130 /* MCS 6 */
131 { /* 20 Mhz */ { 58.5, /* SGI */ 65.0, },
132 /* 40 Mhz */ { 121.5, /* SGI */ 135.0, },
133 },
134
135 /* MCS 7 */
136 { /* 20 Mhz */ { 65.0, /* SGI */ 72.2, },
137 /* 40 Mhz */ { 135.0, /* SGI */ 150.0, },
138 },
139
140 /* MCS 8 */
141 { /* 20 Mhz */ { 13.0, /* SGI */ 14.4, },
142 /* 40 Mhz */ { 27.0, /* SGI */ 30.0, },
143 },
144
145 /* MCS 9 */
146 { /* 20 Mhz */ { 26.0, /* SGI */ 28.9, },
147 /* 40 Mhz */ { 54.0, /* SGI */ 60.0, },
148 },
149
150 /* MCS 10 */
151 { /* 20 Mhz */ { 39.0, /* SGI */ 43.3, },
152 /* 40 Mhz */ { 81.0, /* SGI */ 90.0, },
153 },
154
155 /* MCS 11 */
156 { /* 20 Mhz */ { 52.0, /* SGI */ 57.8, },
157 /* 40 Mhz */ { 108.0, /* SGI */ 120.0, },
158 },
159
160 /* MCS 12 */
161 { /* 20 Mhz */ { 78.0, /* SGI */ 86.7, },
162 /* 40 Mhz */ { 162.0, /* SGI */ 180.0, },
163 },
164
165 /* MCS 13 */
166 { /* 20 Mhz */ { 104.0, /* SGI */ 115.6, },
167 /* 40 Mhz */ { 216.0, /* SGI */ 240.0, },
168 },
169
170 /* MCS 14 */
171 { /* 20 Mhz */ { 117.0, /* SGI */ 130.0, },
172 /* 40 Mhz */ { 243.0, /* SGI */ 270.0, },
173 },
174
175 /* MCS 15 */
176 { /* 20 Mhz */ { 130.0, /* SGI */ 144.4, },
177 /* 40 Mhz */ { 270.0, /* SGI */ 300.0, },
178 },
179
180 /* MCS 16 */
181 { /* 20 Mhz */ { 19.5, /* SGI */ 21.7, },
182 /* 40 Mhz */ { 40.5, /* SGI */ 45.0, },
183 },
184
185 /* MCS 17 */
186 { /* 20 Mhz */ { 39.0, /* SGI */ 43.3, },
187 /* 40 Mhz */ { 81.0, /* SGI */ 90.0, },
188 },
189
190 /* MCS 18 */
191 { /* 20 Mhz */ { 58.5, /* SGI */ 65.0, },
192 /* 40 Mhz */ { 121.5, /* SGI */ 135.0, },
193 },
194
195 /* MCS 19 */
196 { /* 20 Mhz */ { 78.0, /* SGI */ 86.7, },
197 /* 40 Mhz */ { 162.0, /* SGI */ 180.0, },
198 },
199
200 /* MCS 20 */
201 { /* 20 Mhz */ { 117.0, /* SGI */ 130.0, },
202 /* 40 Mhz */ { 243.0, /* SGI */ 270.0, },
203 },
204
205 /* MCS 21 */
206 { /* 20 Mhz */ { 156.0, /* SGI */ 173.3, },
207 /* 40 Mhz */ { 324.0, /* SGI */ 360.0, },
208 },
209
210 /* MCS 22 */
211 { /* 20 Mhz */ { 175.5, /* SGI */ 195.0, },
212 /* 40 Mhz */ { 364.5, /* SGI */ 405.0, },
213 },
214
215 /* MCS 23 */
216 { /* 20 Mhz */ { 195.0, /* SGI */ 216.7, },
217 /* 40 Mhz */ { 405.0, /* SGI */ 450.0, },
218 },
219
220 /* MCS 24 */
221 { /* 20 Mhz */ { 26.0, /* SGI */ 28.9, },
222 /* 40 Mhz */ { 54.0, /* SGI */ 60.0, },
223 },
224
225 /* MCS 25 */
226 { /* 20 Mhz */ { 52.0, /* SGI */ 57.8, },
227 /* 40 Mhz */ { 108.0, /* SGI */ 120.0, },
228 },
229
230 /* MCS 26 */
231 { /* 20 Mhz */ { 78.0, /* SGI */ 86.7, },
232 /* 40 Mhz */ { 162.0, /* SGI */ 180.0, },
233 },
234
235 /* MCS 27 */
236 { /* 20 Mhz */ { 104.0, /* SGI */ 115.6, },
237 /* 40 Mhz */ { 216.0, /* SGI */ 240.0, },
238 },
239
240 /* MCS 28 */
241 { /* 20 Mhz */ { 156.0, /* SGI */ 173.3, },
242 /* 40 Mhz */ { 324.0, /* SGI */ 360.0, },
243 },
244
245 /* MCS 29 */
246 { /* 20 Mhz */ { 208.0, /* SGI */ 231.1, },
247 /* 40 Mhz */ { 432.0, /* SGI */ 480.0, },
248 },
249
250 /* MCS 30 */
251 { /* 20 Mhz */ { 234.0, /* SGI */ 260.0, },
252 /* 40 Mhz */ { 486.0, /* SGI */ 540.0, },
253 },
254
255 /* MCS 31 */
256 { /* 20 Mhz */ { 260.0, /* SGI */ 288.9, },
257 /* 40 Mhz */ { 540.0, /* SGI */ 600.0, },
258 },
259
260 /* MCS 32 */
261 { /* 20 Mhz */ { 0.0, /* SGI */ 0.0, }, /* not valid */
262 /* 40 Mhz */ { 6.0, /* SGI */ 6.7, },
263 },
264
265 /* MCS 33 */
266 { /* 20 Mhz */ { 39.0, /* SGI */ 43.3, },
267 /* 40 Mhz */ { 81.0, /* SGI */ 90.0, },
268 },
269
270 /* MCS 34 */
271 { /* 20 Mhz */ { 52.0, /* SGI */ 57.8, },
272 /* 40 Mhz */ { 108.0, /* SGI */ 120.0, },
273 },
274
275 /* MCS 35 */
276 { /* 20 Mhz */ { 65.0, /* SGI */ 72.2, },
277 /* 40 Mhz */ { 135.0, /* SGI */ 150.0, },
278 },
279
280 /* MCS 36 */
281 { /* 20 Mhz */ { 58.5, /* SGI */ 65.0, },
282 /* 40 Mhz */ { 121.5, /* SGI */ 135.0, },
283 },
284
285 /* MCS 37 */
286 { /* 20 Mhz */ { 78.0, /* SGI */ 86.7, },
287 /* 40 Mhz */ { 162.0, /* SGI */ 180.0, },
288 },
289
290 /* MCS 38 */
291 { /* 20 Mhz */ { 97.5, /* SGI */ 108.3, },
292 /* 40 Mhz */ { 202.5, /* SGI */ 225.0, },
293 },
294
295 /* MCS 39 */
296 { /* 20 Mhz */ { 52.0, /* SGI */ 57.8, },
297 /* 40 Mhz */ { 108.0, /* SGI */ 120.0, },
298 },
299
300 /* MCS 40 */
301 { /* 20 Mhz */ { 65.0, /* SGI */ 72.2, },
302 /* 40 Mhz */ { 135.0, /* SGI */ 150.0, },
303 },
304
305 /* MCS 41 */
306 { /* 20 Mhz */ { 65.0, /* SGI */ 72.2, },
307 /* 40 Mhz */ { 135.0, /* SGI */ 150.0, },
308 },
309
310 /* MCS 42 */
311 { /* 20 Mhz */ { 78.0, /* SGI */ 86.7, },
312 /* 40 Mhz */ { 162.0, /* SGI */ 180.0, },
313 },
314
315 /* MCS 43 */
316 { /* 20 Mhz */ { 91.0, /* SGI */ 101.1, },
317 /* 40 Mhz */ { 189.0, /* SGI */ 210.0, },
318 },
319
320 /* MCS 44 */
321 { /* 20 Mhz */ { 91.0, /* SGI */ 101.1, },
322 /* 40 Mhz */ { 189.0, /* SGI */ 210.0, },
323 },
324
325 /* MCS 45 */
326 { /* 20 Mhz */ { 104.0, /* SGI */ 115.6, },
327 /* 40 Mhz */ { 216.0, /* SGI */ 240.0, },
328 },
329
330 /* MCS 46 */
331 { /* 20 Mhz */ { 78.0, /* SGI */ 86.7, },
332 /* 40 Mhz */ { 162.0, /* SGI */ 180.0, },
333 },
334
335 /* MCS 47 */
336 { /* 20 Mhz */ { 97.5, /* SGI */ 108.3, },
337 /* 40 Mhz */ { 202.5, /* SGI */ 225.0, },
338 },
339
340 /* MCS 48 */
341 { /* 20 Mhz */ { 97.5, /* SGI */ 108.3, },
342 /* 40 Mhz */ { 202.5, /* SGI */ 225.0, },
343 },
344
345 /* MCS 49 */
346 { /* 20 Mhz */ { 117.0, /* SGI */ 130.0, },
347 /* 40 Mhz */ { 243.0, /* SGI */ 270.0, },
348 },
349
350 /* MCS 50 */
351 { /* 20 Mhz */ { 136.5, /* SGI */ 151.7, },
352 /* 40 Mhz */ { 283.5, /* SGI */ 315.0, },
353 },
354
355 /* MCS 51 */
356 { /* 20 Mhz */ { 136.5, /* SGI */ 151.7, },
357 /* 40 Mhz */ { 283.5, /* SGI */ 315.0, },
358 },
359
360 /* MCS 52 */
361 { /* 20 Mhz */ { 156.0, /* SGI */ 173.3, },
362 /* 40 Mhz */ { 324.0, /* SGI */ 360.0, },
363 },
364
365 /* MCS 53 */
366 { /* 20 Mhz */ { 65.0, /* SGI */ 72.2, },
367 /* 40 Mhz */ { 135.0, /* SGI */ 150.0, },
368 },
369
370 /* MCS 54 */
371 { /* 20 Mhz */ { 78.0, /* SGI */ 86.7, },
372 /* 40 Mhz */ { 162.0, /* SGI */ 180.0, },
373 },
374
375 /* MCS 55 */
376 { /* 20 Mhz */ { 91.0, /* SGI */ 101.1, },
377 /* 40 Mhz */ { 189.0, /* SGI */ 210.0, },
378 },
379
380 /* MCS 56 */
381 { /* 20 Mhz */ { 78.0, /* SGI */ 86.7, },
382 /* 40 Mhz */ { 162.0, /* SGI */ 180.0, },
383 },
384
385 /* MCS 57 */
386 { /* 20 Mhz */ { 91.0, /* SGI */ 101.1, },
387 /* 40 Mhz */ { 189.0, /* SGI */ 210.0, },
388 },
389
390 /* MCS 58 */
391 { /* 20 Mhz */ { 104.0, /* SGI */ 115.6, },
392 /* 40 Mhz */ { 216.0, /* SGI */ 240.0, },
393 },
394
395 /* MCS 59 */
396 { /* 20 Mhz */ { 117.0, /* SGI */ 130.0, },
397 /* 40 Mhz */ { 243.0, /* SGI */ 270.0, },
398 },
399
400 /* MCS 60 */
401 { /* 20 Mhz */ { 104.0, /* SGI */ 115.6, },
402 /* 40 Mhz */ { 216.0, /* SGI */ 240.0, },
403 },
404
405 /* MCS 61 */
406 { /* 20 Mhz */ { 117.0, /* SGI */ 130.0, },
407 /* 40 Mhz */ { 243.0, /* SGI */ 270.0, },
408 },
409
410 /* MCS 62 */
411 { /* 20 Mhz */ { 130.0, /* SGI */ 144.4, },
412 /* 40 Mhz */ { 270.0, /* SGI */ 300.0, },
413 },
414
415 /* MCS 63 */
416 { /* 20 Mhz */ { 130.0, /* SGI */ 144.4, },
417 /* 40 Mhz */ { 270.0, /* SGI */ 300.0, },
418 },
419
420 /* MCS 64 */
421 { /* 20 Mhz */ { 143.0, /* SGI */ 158.9, },
422 /* 40 Mhz */ { 297.0, /* SGI */ 330.0, },
423 },
424
425 /* MCS 65 */
426 { /* 20 Mhz */ { 97.5, /* SGI */ 108.3, },
427 /* 40 Mhz */ { 202.5, /* SGI */ 225.0, },
428 },
429
430 /* MCS 66 */
431 { /* 20 Mhz */ { 117.0, /* SGI */ 130.0, },
432 /* 40 Mhz */ { 243.0, /* SGI */ 270.0, },
433 },
434
435 /* MCS 67 */
436 { /* 20 Mhz */ { 136.5, /* SGI */ 151.7, },
437 /* 40 Mhz */ { 283.5, /* SGI */ 315.0, },
438 },
439
440 /* MCS 68 */
441 { /* 20 Mhz */ { 117.0, /* SGI */ 130.0, },
442 /* 40 Mhz */ { 243.0, /* SGI */ 270.0, },
443 },
444
445 /* MCS 69 */
446 { /* 20 Mhz */ { 136.5, /* SGI */ 151.7, },
447 /* 40 Mhz */ { 283.5, /* SGI */ 315.0, },
448 },
449
450 /* MCS 70 */
451 { /* 20 Mhz */ { 156.0, /* SGI */ 173.3, },
452 /* 40 Mhz */ { 324.0, /* SGI */ 360.0, },
453 },
454
455 /* MCS 71 */
456 { /* 20 Mhz */ { 175.5, /* SGI */ 195.0, },
457 /* 40 Mhz */ { 364.5, /* SGI */ 405.0, },
458 },
459
460 /* MCS 72 */
461 { /* 20 Mhz */ { 156.0, /* SGI */ 173.3, },
462 /* 40 Mhz */ { 324.0, /* SGI */ 360.0, },
463 },
464
465 /* MCS 73 */
466 { /* 20 Mhz */ { 175.5, /* SGI */ 195.0, },
467 /* 40 Mhz */ { 364.5, /* SGI */ 405.0, },
468 },
469
470 /* MCS 74 */
471 { /* 20 Mhz */ { 195.0, /* SGI */ 216.7, },
472 /* 40 Mhz */ { 405.0, /* SGI */ 450.0, },
473 },
474
475 /* MCS 75 */
476 { /* 20 Mhz */ { 195.0, /* SGI */ 216.7, },
477 /* 40 Mhz */ { 405.0, /* SGI */ 450.0, },
478 },
479
480 /* MCS 76 */
481 { /* 20 Mhz */ { 214.5, /* SGI */ 238.3, },
482 /* 40 Mhz */ { 445.5, /* SGI */ 495.0, },
483 },
484 };
485
486 static const char *auth_alg_text[]={"Open System","Shared Key","EAP"};
487 #define NUM_AUTH_ALGS (sizeof auth_alg_text / sizeof auth_alg_text[0])
488
489 static const char *status_text[] = {
490 "Successful", /* 0 */
491 "Unspecified failure", /* 1 */
492 "Reserved", /* 2 */
493 "Reserved", /* 3 */
494 "Reserved", /* 4 */
495 "Reserved", /* 5 */
496 "Reserved", /* 6 */
497 "Reserved", /* 7 */
498 "Reserved", /* 8 */
499 "Reserved", /* 9 */
500 "Cannot Support all requested capabilities in the Capability "
501 "Information field", /* 10 */
502 "Reassociation denied due to inability to confirm that association "
503 "exists", /* 11 */
504 "Association denied due to reason outside the scope of the "
505 "standard", /* 12 */
506 "Responding station does not support the specified authentication "
507 "algorithm ", /* 13 */
508 "Received an Authentication frame with authentication transaction "
509 "sequence number out of expected sequence", /* 14 */
510 "Authentication rejected because of challenge failure", /* 15 */
511 "Authentication rejected due to timeout waiting for next frame in "
512 "sequence", /* 16 */
513 "Association denied because AP is unable to handle additional"
514 "associated stations", /* 17 */
515 "Association denied due to requesting station not supporting all of "
516 "the data rates in BSSBasicRateSet parameter", /* 18 */
517 "Association denied due to requesting station not supporting "
518 "short preamble operation", /* 19 */
519 "Association denied due to requesting station not supporting "
520 "PBCC encoding", /* 20 */
521 "Association denied due to requesting station not supporting "
522 "channel agility", /* 21 */
523 "Association request rejected because Spectrum Management "
524 "capability is required", /* 22 */
525 "Association request rejected because the information in the "
526 "Power Capability element is unacceptable", /* 23 */
527 "Association request rejected because the information in the "
528 "Supported Channels element is unacceptable", /* 24 */
529 "Association denied due to requesting station not supporting "
530 "short slot operation", /* 25 */
531 "Association denied due to requesting station not supporting "
532 "DSSS-OFDM operation", /* 26 */
533 "Association denied because the requested STA does not support HT "
534 "features", /* 27 */
535 "Reserved", /* 28 */
536 "Association denied because the requested STA does not support "
537 "the PCO transition time required by the AP", /* 29 */
538 "Reserved", /* 30 */
539 "Reserved", /* 31 */
540 "Unspecified, QoS-related failure", /* 32 */
541 "Association denied due to QAP having insufficient bandwidth "
542 "to handle another QSTA", /* 33 */
543 "Association denied due to excessive frame loss rates and/or "
544 "poor conditions on current operating channel", /* 34 */
545 "Association (with QBSS) denied due to requesting station not "
546 "supporting the QoS facility", /* 35 */
547 "Association denied due to requesting station not supporting "
548 "Block Ack", /* 36 */
549 "The request has been declined", /* 37 */
550 "The request has not been successful as one or more parameters "
551 "have invalid values", /* 38 */
552 "The TS has not been created because the request cannot be honored. "
553 "However, a suggested TSPEC is provided so that the initiating QSTA"
554 "may attempt to set another TS with the suggested changes to the "
555 "TSPEC", /* 39 */
556 "Invalid Information Element", /* 40 */
557 "Group Cipher is not valid", /* 41 */
558 "Pairwise Cipher is not valid", /* 42 */
559 "AKMP is not valid", /* 43 */
560 "Unsupported RSN IE version", /* 44 */
561 "Invalid RSN IE Capabilities", /* 45 */
562 "Cipher suite is rejected per security policy", /* 46 */
563 "The TS has not been created. However, the HC may be capable of "
564 "creating a TS, in response to a request, after the time indicated "
565 "in the TS Delay element", /* 47 */
566 "Direct Link is not allowed in the BSS by policy", /* 48 */
567 "Destination STA is not present within this QBSS.", /* 49 */
568 "The Destination STA is not a QSTA.", /* 50 */
569
570 };
571 #define NUM_STATUSES (sizeof status_text / sizeof status_text[0])
572
573 static const char *reason_text[] = {
574 "Reserved", /* 0 */
575 "Unspecified reason", /* 1 */
576 "Previous authentication no longer valid", /* 2 */
577 "Deauthenticated because sending station is leaving (or has left) "
578 "IBSS or ESS", /* 3 */
579 "Disassociated due to inactivity", /* 4 */
580 "Disassociated because AP is unable to handle all currently "
581 " associated stations", /* 5 */
582 "Class 2 frame received from nonauthenticated station", /* 6 */
583 "Class 3 frame received from nonassociated station", /* 7 */
584 "Disassociated because sending station is leaving "
585 "(or has left) BSS", /* 8 */
586 "Station requesting (re)association is not authenticated with "
587 "responding station", /* 9 */
588 "Disassociated because the information in the Power Capability "
589 "element is unacceptable", /* 10 */
590 "Disassociated because the information in the SupportedChannels "
591 "element is unacceptable", /* 11 */
592 "Invalid Information Element", /* 12 */
593 "Reserved", /* 13 */
594 "Michael MIC failure", /* 14 */
595 "4-Way Handshake timeout", /* 15 */
596 "Group key update timeout", /* 16 */
597 "Information element in 4-Way Handshake different from (Re)Association"
598 "Request/Probe Response/Beacon", /* 17 */
599 "Group Cipher is not valid", /* 18 */
600 "AKMP is not valid", /* 20 */
601 "Unsupported RSN IE version", /* 21 */
602 "Invalid RSN IE Capabilities", /* 22 */
603 "IEEE 802.1X Authentication failed", /* 23 */
604 "Cipher suite is rejected per security policy", /* 24 */
605 "Reserved", /* 25 */
606 "Reserved", /* 26 */
607 "Reserved", /* 27 */
608 "Reserved", /* 28 */
609 "Reserved", /* 29 */
610 "Reserved", /* 30 */
611 "TS deleted because QoS AP lacks sufficient bandwidth for this "
612 "QoS STA due to a change in BSS service characteristics or "
613 "operational mode (e.g. an HT BSS change from 40 MHz channel "
614 "to 20 MHz channel)", /* 31 */
615 "Disassociated for unspecified, QoS-related reason", /* 32 */
616 "Disassociated because QoS AP lacks sufficient bandwidth for this "
617 "QoS STA", /* 33 */
618 "Disassociated because of excessive number of frames that need to be "
619 "acknowledged, but are not acknowledged for AP transmissions "
620 "and/or poor channel conditions", /* 34 */
621 "Disassociated because STA is transmitting outside the limits "
622 "of its TXOPs", /* 35 */
623 "Requested from peer STA as the STA is leaving the BSS "
624 "(or resetting)", /* 36 */
625 "Requested from peer STA as it does not want to use the "
626 "mechanism", /* 37 */
627 "Requested from peer STA as the STA received frames using the "
628 "mechanism for which a set up is required", /* 38 */
629 "Requested from peer STA due to time out", /* 39 */
630 "Reserved", /* 40 */
631 "Reserved", /* 41 */
632 "Reserved", /* 42 */
633 "Reserved", /* 43 */
634 "Reserved", /* 44 */
635 "Peer STA does not support the requested cipher suite", /* 45 */
636 "Association denied due to requesting STA not supporting HT "
637 "features", /* 46 */
638 };
639 #define NUM_REASONS (sizeof reason_text / sizeof reason_text[0])
640
641 static int
642 wep_print(const u_char *p)
643 {
644 u_int32_t iv;
645
646 if (!TTEST2(*p, IEEE802_11_IV_LEN + IEEE802_11_KID_LEN))
647 return 0;
648 iv = EXTRACT_LE_32BITS(p);
649
650 printf("Data IV:%3x Pad %x KeyID %x", IV_IV(iv), IV_PAD(iv),
651 IV_KEYID(iv));
652
653 return 1;
654 }
655
656 static int
657 parse_elements(struct mgmt_body_t *pbody, const u_char *p, int offset,
658 u_int length)
659 {
660 u_int elementlen;
661 struct ssid_t ssid;
662 struct challenge_t challenge;
663 struct rates_t rates;
664 struct ds_t ds;
665 struct cf_t cf;
666 struct tim_t tim;
667
668 /*
669 * We haven't seen any elements yet.
670 */
671 pbody->challenge_present = 0;
672 pbody->ssid_present = 0;
673 pbody->rates_present = 0;
674 pbody->ds_present = 0;
675 pbody->cf_present = 0;
676 pbody->tim_present = 0;
677
678 while (length != 0) {
679 if (!TTEST2(*(p + offset), 1))
680 return 0;
681 if (length < 1)
682 return 0;
683 switch (*(p + offset)) {
684 case E_SSID:
685 if (!TTEST2(*(p + offset), 2))
686 return 0;
687 if (length < 2)
688 return 0;
689 memcpy(&ssid, p + offset, 2);
690 offset += 2;
691 length -= 2;
692 if (ssid.length != 0) {
693 if (ssid.length > sizeof(ssid.ssid) - 1)
694 return 0;
695 if (!TTEST2(*(p + offset), ssid.length))
696 return 0;
697 if (length < ssid.length)
698 return 0;
699 memcpy(&ssid.ssid, p + offset, ssid.length);
700 offset += ssid.length;
701 length -= ssid.length;
702 }
703 ssid.ssid[ssid.length] = '\0';
704 /*
705 * Present and not truncated.
706 *
707 * If we haven't already seen an SSID IE,
708 * copy this one, otherwise ignore this one,
709 * so we later report the first one we saw.
710 */
711 if (!pbody->ssid_present) {
712 pbody->ssid = ssid;
713 pbody->ssid_present = 1;
714 }
715 break;
716 case E_CHALLENGE:
717 if (!TTEST2(*(p + offset), 2))
718 return 0;
719 if (length < 2)
720 return 0;
721 memcpy(&challenge, p + offset, 2);
722 offset += 2;
723 length -= 2;
724 if (challenge.length != 0) {
725 if (challenge.length >
726 sizeof(challenge.text) - 1)
727 return 0;
728 if (!TTEST2(*(p + offset), challenge.length))
729 return 0;
730 if (length < challenge.length)
731 return 0;
732 memcpy(&challenge.text, p + offset,
733 challenge.length);
734 offset += challenge.length;
735 length -= challenge.length;
736 }
737 challenge.text[challenge.length] = '\0';
738 /*
739 * Present and not truncated.
740 *
741 * If we haven't already seen a challenge IE,
742 * copy this one, otherwise ignore this one,
743 * so we later report the first one we saw.
744 */
745 if (!pbody->challenge_present) {
746 pbody->challenge = challenge;
747 pbody->challenge_present = 1;
748 }
749 break;
750 case E_RATES:
751 if (!TTEST2(*(p + offset), 2))
752 return 0;
753 if (length < 2)
754 return 0;
755 memcpy(&rates, p + offset, 2);
756 offset += 2;
757 length -= 2;
758 if (rates.length != 0) {
759 if (rates.length > sizeof rates.rate)
760 return 0;
761 if (!TTEST2(*(p + offset), rates.length))
762 return 0;
763 if (length < rates.length)
764 return 0;
765 memcpy(&rates.rate, p + offset, rates.length);
766 offset += rates.length;
767 length -= rates.length;
768 }
769 /*
770 * Present and not truncated.
771 *
772 * If we haven't already seen a rates IE,
773 * copy this one if it's not zero-length,
774 * otherwise ignore this one, so we later
775 * report the first one we saw.
776 *
777 * We ignore zero-length rates IEs as some
778 * devices seem to put a zero-length rates
779 * IE, followed by an SSID IE, followed by
780 * a non-zero-length rates IE into frames,
781 * even though IEEE Std 802.11-2007 doesn't
782 * seem to indicate that a zero-length rates
783 * IE is valid.
784 */
785 if (!pbody->rates_present && rates.length != 0) {
786 pbody->rates = rates;
787 pbody->rates_present = 1;
788 }
789 break;
790 case E_DS:
791 if (!TTEST2(*(p + offset), 3))
792 return 0;
793 if (length < 3)
794 return 0;
795 memcpy(&ds, p + offset, 3);
796 offset += 3;
797 length -= 3;
798 /*
799 * Present and not truncated.
800 *
801 * If we haven't already seen a DS IE,
802 * copy this one, otherwise ignore this one,
803 * so we later report the first one we saw.
804 */
805 if (!pbody->ds_present) {
806 pbody->ds = ds;
807 pbody->ds_present = 1;
808 }
809 break;
810 case E_CF:
811 if (!TTEST2(*(p + offset), 8))
812 return 0;
813 if (length < 8)
814 return 0;
815 memcpy(&cf, p + offset, 8);
816 offset += 8;
817 length -= 8;
818 /*
819 * Present and not truncated.
820 *
821 * If we haven't already seen a CF IE,
822 * copy this one, otherwise ignore this one,
823 * so we later report the first one we saw.
824 */
825 if (!pbody->cf_present) {
826 pbody->cf = cf;
827 pbody->cf_present = 1;
828 }
829 break;
830 case E_TIM:
831 if (!TTEST2(*(p + offset), 2))
832 return 0;
833 if (length < 2)
834 return 0;
835 memcpy(&tim, p + offset, 2);
836 offset += 2;
837 length -= 2;
838 if (!TTEST2(*(p + offset), 3))
839 return 0;
840 if (length < 3)
841 return 0;
842 memcpy(&tim.count, p + offset, 3);
843 offset += 3;
844 length -= 3;
845
846 if (tim.length <= 3)
847 break;
848 if (tim.length - 3 > (int)sizeof tim.bitmap)
849 return 0;
850 if (!TTEST2(*(p + offset), tim.length - 3))
851 return 0;
852 if (length < (u_int)(tim.length - 3))
853 return 0;
854 memcpy(tim.bitmap, p + (tim.length - 3),
855 (tim.length - 3));
856 offset += tim.length - 3;
857 length -= tim.length - 3;
858 /*
859 * Present and not truncated.
860 *
861 * If we haven't already seen a TIM IE,
862 * copy this one, otherwise ignore this one,
863 * so we later report the first one we saw.
864 */
865 if (!pbody->tim_present) {
866 pbody->tim = tim;
867 pbody->tim_present = 1;
868 }
869 break;
870 default:
871 #if 0
872 printf("(1) unhandled element_id (%d) ",
873 *(p + offset));
874 #endif
875 if (!TTEST2(*(p + offset), 2))
876 return 0;
877 if (length < 2)
878 return 0;
879 elementlen = *(p + offset + 1);
880 if (!TTEST2(*(p + offset + 2), elementlen))
881 return 0;
882 if (length < elementlen + 2)
883 return 0;
884 offset += elementlen + 2;
885 length -= elementlen + 2;
886 break;
887 }
888 }
889
890 /* No problems found. */
891 return 1;
892 }
893
894 /*********************************************************************************
895 * Print Handle functions for the management frame types
896 *********************************************************************************/
897
898 static int
899 handle_beacon(const u_char *p, u_int length)
900 {
901 struct mgmt_body_t pbody;
902 int offset = 0;
903 int ret;
904
905 memset(&pbody, 0, sizeof(pbody));
906
907 if (!TTEST2(*p, IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN +
908 IEEE802_11_CAPINFO_LEN))
909 return 0;
910 if (length < IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN +
911 IEEE802_11_CAPINFO_LEN)
912 return 0;
913 memcpy(&pbody.timestamp, p, IEEE802_11_TSTAMP_LEN);
914 offset += IEEE802_11_TSTAMP_LEN;
915 length -= IEEE802_11_TSTAMP_LEN;
916 pbody.beacon_interval = EXTRACT_LE_16BITS(p+offset);
917 offset += IEEE802_11_BCNINT_LEN;
918 length -= IEEE802_11_BCNINT_LEN;
919 pbody.capability_info = EXTRACT_LE_16BITS(p+offset);
920 offset += IEEE802_11_CAPINFO_LEN;
921 length -= IEEE802_11_CAPINFO_LEN;
922
923 ret = parse_elements(&pbody, p, offset, length);
924
925 PRINT_SSID(pbody);
926 PRINT_RATES(pbody);
927 printf(" %s",
928 CAPABILITY_ESS(pbody.capability_info) ? "ESS" : "IBSS");
929 PRINT_DS_CHANNEL(pbody);
930
931 return ret;
932 }
933
934 static int
935 handle_assoc_request(const u_char *p, u_int length)
936 {
937 struct mgmt_body_t pbody;
938 int offset = 0;
939 int ret;
940
941 memset(&pbody, 0, sizeof(pbody));
942
943 if (!TTEST2(*p, IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN))
944 return 0;
945 if (length < IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN)
946 return 0;
947 pbody.capability_info = EXTRACT_LE_16BITS(p);
948 offset += IEEE802_11_CAPINFO_LEN;
949 length -= IEEE802_11_CAPINFO_LEN;
950 pbody.listen_interval = EXTRACT_LE_16BITS(p+offset);
951 offset += IEEE802_11_LISTENINT_LEN;
952 length -= IEEE802_11_LISTENINT_LEN;
953
954 ret = parse_elements(&pbody, p, offset, length);
955
956 PRINT_SSID(pbody);
957 PRINT_RATES(pbody);
958 return ret;
959 }
960
961 static int
962 handle_assoc_response(const u_char *p, u_int length)
963 {
964 struct mgmt_body_t pbody;
965 int offset = 0;
966 int ret;
967
968 memset(&pbody, 0, sizeof(pbody));
969
970 if (!TTEST2(*p, IEEE802_11_CAPINFO_LEN + IEEE802_11_STATUS_LEN +
971 IEEE802_11_AID_LEN))
972 return 0;
973 if (length < IEEE802_11_CAPINFO_LEN + IEEE802_11_STATUS_LEN +
974 IEEE802_11_AID_LEN)
975 return 0;
976 pbody.capability_info = EXTRACT_LE_16BITS(p);
977 offset += IEEE802_11_CAPINFO_LEN;
978 length -= IEEE802_11_CAPINFO_LEN;
979 pbody.status_code = EXTRACT_LE_16BITS(p+offset);
980 offset += IEEE802_11_STATUS_LEN;
981 length -= IEEE802_11_STATUS_LEN;
982 pbody.aid = EXTRACT_LE_16BITS(p+offset);
983 offset += IEEE802_11_AID_LEN;
984 length -= IEEE802_11_AID_LEN;
985
986 ret = parse_elements(&pbody, p, offset, length);
987
988 printf(" AID(%x) :%s: %s", ((u_int16_t)(pbody.aid << 2 )) >> 2 ,
989 CAPABILITY_PRIVACY(pbody.capability_info) ? " PRIVACY " : "",
990 (pbody.status_code < NUM_STATUSES
991 ? status_text[pbody.status_code]
992 : "n/a"));
993
994 return ret;
995 }
996
997 static int
998 handle_reassoc_request(const u_char *p, u_int length)
999 {
1000 struct mgmt_body_t pbody;
1001 int offset = 0;
1002 int ret;
1003
1004 memset(&pbody, 0, sizeof(pbody));
1005
1006 if (!TTEST2(*p, IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN +
1007 IEEE802_11_AP_LEN))
1008 return 0;
1009 if (length < IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN +
1010 IEEE802_11_AP_LEN)
1011 return 0;
1012 pbody.capability_info = EXTRACT_LE_16BITS(p);
1013 offset += IEEE802_11_CAPINFO_LEN;
1014 length -= IEEE802_11_CAPINFO_LEN;
1015 pbody.listen_interval = EXTRACT_LE_16BITS(p+offset);
1016 offset += IEEE802_11_LISTENINT_LEN;
1017 length -= IEEE802_11_LISTENINT_LEN;
1018 memcpy(&pbody.ap, p+offset, IEEE802_11_AP_LEN);
1019 offset += IEEE802_11_AP_LEN;
1020 length -= IEEE802_11_AP_LEN;
1021
1022 ret = parse_elements(&pbody, p, offset, length);
1023
1024 PRINT_SSID(pbody);
1025 printf(" AP : %s", etheraddr_string( pbody.ap ));
1026
1027 return ret;
1028 }
1029
1030 static int
1031 handle_reassoc_response(const u_char *p, u_int length)
1032 {
1033 /* Same as a Association Reponse */
1034 return handle_assoc_response(p, length);
1035 }
1036
1037 static int
1038 handle_probe_request(const u_char *p, u_int length)
1039 {
1040 struct mgmt_body_t pbody;
1041 int offset = 0;
1042 int ret;
1043
1044 memset(&pbody, 0, sizeof(pbody));
1045
1046 ret = parse_elements(&pbody, p, offset, length);
1047
1048 PRINT_SSID(pbody);
1049 PRINT_RATES(pbody);
1050
1051 return ret;
1052 }
1053
1054 static int
1055 handle_probe_response(const u_char *p, u_int length)
1056 {
1057 struct mgmt_body_t pbody;
1058 int offset = 0;
1059 int ret;
1060
1061 memset(&pbody, 0, sizeof(pbody));
1062
1063 if (!TTEST2(*p, IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN +
1064 IEEE802_11_CAPINFO_LEN))
1065 return 0;
1066 if (length < IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN +
1067 IEEE802_11_CAPINFO_LEN)
1068 return 0;
1069 memcpy(&pbody.timestamp, p, IEEE802_11_TSTAMP_LEN);
1070 offset += IEEE802_11_TSTAMP_LEN;
1071 length -= IEEE802_11_TSTAMP_LEN;
1072 pbody.beacon_interval = EXTRACT_LE_16BITS(p+offset);
1073 offset += IEEE802_11_BCNINT_LEN;
1074 length -= IEEE802_11_BCNINT_LEN;
1075 pbody.capability_info = EXTRACT_LE_16BITS(p+offset);
1076 offset += IEEE802_11_CAPINFO_LEN;
1077 length -= IEEE802_11_CAPINFO_LEN;
1078
1079 ret = parse_elements(&pbody, p, offset, length);
1080
1081 PRINT_SSID(pbody);
1082 PRINT_RATES(pbody);
1083 PRINT_DS_CHANNEL(pbody);
1084
1085 return ret;
1086 }
1087
1088 static int
1089 handle_atim(void)
1090 {
1091 /* the frame body for ATIM is null. */
1092 return 1;
1093 }
1094
1095 static int
1096 handle_disassoc(const u_char *p, u_int length)
1097 {
1098 struct mgmt_body_t pbody;
1099
1100 memset(&pbody, 0, sizeof(pbody));
1101
1102 if (!TTEST2(*p, IEEE802_11_REASON_LEN))
1103 return 0;
1104 if (length < IEEE802_11_REASON_LEN)
1105 return 0;
1106 pbody.reason_code = EXTRACT_LE_16BITS(p);
1107
1108 printf(": %s",
1109 (pbody.reason_code < NUM_REASONS)
1110 ? reason_text[pbody.reason_code]
1111 : "Reserved" );
1112
1113 return 1;
1114 }
1115
1116 static int
1117 handle_auth(const u_char *p, u_int length)
1118 {
1119 struct mgmt_body_t pbody;
1120 int offset = 0;
1121 int ret;
1122
1123 memset(&pbody, 0, sizeof(pbody));
1124
1125 if (!TTEST2(*p, 6))
1126 return 0;
1127 if (length < 6)
1128 return 0;
1129 pbody.auth_alg = EXTRACT_LE_16BITS(p);
1130 offset += 2;
1131 length -= 2;
1132 pbody.auth_trans_seq_num = EXTRACT_LE_16BITS(p + offset);
1133 offset += 2;
1134 length -= 2;
1135 pbody.status_code = EXTRACT_LE_16BITS(p + offset);
1136 offset += 2;
1137 length -= 2;
1138
1139 ret = parse_elements(&pbody, p, offset, length);
1140
1141 if ((pbody.auth_alg == 1) &&
1142 ((pbody.auth_trans_seq_num == 2) ||
1143 (pbody.auth_trans_seq_num == 3))) {
1144 printf(" (%s)-%x [Challenge Text] %s",
1145 (pbody.auth_alg < NUM_AUTH_ALGS)
1146 ? auth_alg_text[pbody.auth_alg]
1147 : "Reserved",
1148 pbody.auth_trans_seq_num,
1149 ((pbody.auth_trans_seq_num % 2)
1150 ? ((pbody.status_code < NUM_STATUSES)
1151 ? status_text[pbody.status_code]
1152 : "n/a") : ""));
1153 return ret;
1154 }
1155 printf(" (%s)-%x: %s",
1156 (pbody.auth_alg < NUM_AUTH_ALGS)
1157 ? auth_alg_text[pbody.auth_alg]
1158 : "Reserved",
1159 pbody.auth_trans_seq_num,
1160 (pbody.auth_trans_seq_num % 2)
1161 ? ((pbody.status_code < NUM_STATUSES)
1162 ? status_text[pbody.status_code]
1163 : "n/a")
1164 : "");
1165
1166 return ret;
1167 }
1168
1169 static int
1170 handle_deauth(const struct mgmt_header_t *pmh, const u_char *p, u_int length)
1171 {
1172 struct mgmt_body_t pbody;
1173 int offset = 0;
1174 const char *reason = NULL;
1175
1176 memset(&pbody, 0, sizeof(pbody));
1177
1178 if (!TTEST2(*p, IEEE802_11_REASON_LEN))
1179 return 0;
1180 if (length < IEEE802_11_REASON_LEN)
1181 return 0;
1182 pbody.reason_code = EXTRACT_LE_16BITS(p);
1183 offset += IEEE802_11_REASON_LEN;
1184 length -= IEEE802_11_REASON_LEN;
1185
1186 reason = (pbody.reason_code < NUM_REASONS)
1187 ? reason_text[pbody.reason_code]
1188 : "Reserved";
1189
1190 if (eflag) {
1191 printf(": %s", reason);
1192 } else {
1193 printf(" (%s): %s", etheraddr_string(pmh->sa), reason);
1194 }
1195 return 1;
1196 }
1197
1198 #define PRINT_HT_ACTION(v) (\
1199 (v) == 0 ? printf("TxChWidth") : \
1200 (v) == 1 ? printf("MIMOPwrSave") : \
1201 printf("Act#%d", (v)) \
1202 )
1203 #define PRINT_BA_ACTION(v) (\
1204 (v) == 0 ? printf("ADDBA Request") : \
1205 (v) == 1 ? printf("ADDBA Response") : \
1206 (v) == 2 ? printf("DELBA") : \
1207 printf("Act#%d", (v)) \
1208 )
1209 #define PRINT_MESHLINK_ACTION(v) (\
1210 (v) == 0 ? printf("Request") : \
1211 (v) == 1 ? printf("Report") : \
1212 printf("Act#%d", (v)) \
1213 )
1214 #define PRINT_MESHPEERING_ACTION(v) (\
1215 (v) == 0 ? printf("Open") : \
1216 (v) == 1 ? printf("Confirm") : \
1217 (v) == 2 ? printf("Close") : \
1218 printf("Act#%d", (v)) \
1219 )
1220 #define PRINT_MESHPATH_ACTION(v) (\
1221 (v) == 0 ? printf("Request") : \
1222 (v) == 1 ? printf("Report") : \
1223 (v) == 2 ? printf("Error") : \
1224 (v) == 3 ? printf("RootAnnouncement") : \
1225 printf("Act#%d", (v)) \
1226 )
1227
1228 #define PRINT_MESH_ACTION(v) (\
1229 (v) == 0 ? printf("MeshLink") : \
1230 (v) == 1 ? printf("HWMP") : \
1231 (v) == 2 ? printf("Gate Announcement") : \
1232 (v) == 3 ? printf("Congestion Control") : \
1233 (v) == 4 ? printf("MCCA Setup Request") : \
1234 (v) == 5 ? printf("MCCA Setup Reply") : \
1235 (v) == 6 ? printf("MCCA Advertisement Request") : \
1236 (v) == 7 ? printf("MCCA Advertisement") : \
1237 (v) == 8 ? printf("MCCA Teardown") : \
1238 (v) == 9 ? printf("TBTT Adjustment Request") : \
1239 (v) == 10 ? printf("TBTT Adjustment Response") : \
1240 printf("Act#%d", (v)) \
1241 )
1242 #define PRINT_MULTIHOP_ACTION(v) (\
1243 (v) == 0 ? printf("Proxy Update") : \
1244 (v) == 1 ? printf("Proxy Update Confirmation") : \
1245 printf("Act#%d", (v)) \
1246 )
1247 #define PRINT_SELFPROT_ACTION(v) (\
1248 (v) == 1 ? printf("Peering Open") : \
1249 (v) == 2 ? printf("Peering Confirm") : \
1250 (v) == 3 ? printf("Peering Close") : \
1251 (v) == 4 ? printf("Group Key Inform") : \
1252 (v) == 5 ? printf("Group Key Acknowledge") : \
1253 printf("Act#%d", (v)) \
1254 )
1255
1256 static int
1257 handle_action(const struct mgmt_header_t *pmh, const u_char *p, u_int length)
1258 {
1259 if (!TTEST2(*p, 2))
1260 return 0;
1261 if (length < 2)
1262 return 0;
1263 if (eflag) {
1264 printf(": ");
1265 } else {
1266 printf(" (%s): ", etheraddr_string(pmh->sa));
1267 }
1268 switch (p[0]) {
1269 case 0: printf("Spectrum Management Act#%d", p[1]); break;
1270 case 1: printf("QoS Act#%d", p[1]); break;
1271 case 2: printf("DLS Act#%d", p[1]); break;
1272 case 3: printf("BA "); PRINT_BA_ACTION(p[1]); break;
1273 case 7: printf("HT "); PRINT_HT_ACTION(p[1]); break;
1274 case 13: printf("MeshAction "); PRINT_MESH_ACTION(p[1]); break;
1275 case 14:
1276 printf("MultiohopAction ");
1277 PRINT_MULTIHOP_ACTION(p[1]); break;
1278 case 15:
1279 printf("SelfprotectAction ");
1280 PRINT_SELFPROT_ACTION(p[1]); break;
1281 case 127: printf("Vendor Act#%d", p[1]); break;
1282 default:
1283 printf("Reserved(%d) Act#%d", p[0], p[1]);
1284 break;
1285 }
1286 return 1;
1287 }
1288
1289
1290 /*********************************************************************************
1291 * Print Body funcs
1292 *********************************************************************************/
1293
1294
1295 static int
1296 mgmt_body_print(u_int16_t fc, const struct mgmt_header_t *pmh,
1297 const u_char *p, u_int length)
1298 {
1299 switch (FC_SUBTYPE(fc)) {
1300 case ST_ASSOC_REQUEST:
1301 printf("Assoc Request");
1302 return handle_assoc_request(p, length);
1303 case ST_ASSOC_RESPONSE:
1304 printf("Assoc Response");
1305 return handle_assoc_response(p, length);
1306 case ST_REASSOC_REQUEST:
1307 printf("ReAssoc Request");
1308 return handle_reassoc_request(p, length);
1309 case ST_REASSOC_RESPONSE:
1310 printf("ReAssoc Response");
1311 return handle_reassoc_response(p, length);
1312 case ST_PROBE_REQUEST:
1313 printf("Probe Request");
1314 return handle_probe_request(p, length);
1315 case ST_PROBE_RESPONSE:
1316 printf("Probe Response");
1317 return handle_probe_response(p, length);
1318 case ST_BEACON:
1319 printf("Beacon");
1320 return handle_beacon(p, length);
1321 case ST_ATIM:
1322 printf("ATIM");
1323 return handle_atim();
1324 case ST_DISASSOC:
1325 printf("Disassociation");
1326 return handle_disassoc(p, length);
1327 case ST_AUTH:
1328 printf("Authentication");
1329 if (!TTEST2(*p, 3))
1330 return 0;
1331 if ((p[0] == 0 ) && (p[1] == 0) && (p[2] == 0)) {
1332 printf("Authentication (Shared-Key)-3 ");
1333 return wep_print(p);
1334 }
1335 return handle_auth(p, length);
1336 case ST_DEAUTH:
1337 printf("DeAuthentication");
1338 return handle_deauth(pmh, p, length);
1339 break;
1340 case ST_ACTION:
1341 printf("Action");
1342 return handle_action(pmh, p, length);
1343 break;
1344 default:
1345 printf("Unhandled Management subtype(%x)",
1346 FC_SUBTYPE(fc));
1347 return 1;
1348 }
1349 }
1350
1351
1352 /*********************************************************************************
1353 * Handles printing all the control frame types
1354 *********************************************************************************/
1355
1356 static int
1357 ctrl_body_print(u_int16_t fc, const u_char *p)
1358 {
1359 switch (FC_SUBTYPE(fc)) {
1360 case CTRL_CONTROL_WRAPPER:
1361 printf("Control Wrapper");
1362 /* XXX - requires special handling */
1363 break;
1364 case CTRL_BAR:
1365 printf("BAR");
1366 if (!TTEST2(*p, CTRL_BAR_HDRLEN))
1367 return 0;
1368 if (!eflag)
1369 printf(" RA:%s TA:%s CTL(%x) SEQ(%u) ",
1370 etheraddr_string(((const struct ctrl_bar_t *)p)->ra),
1371 etheraddr_string(((const struct ctrl_bar_t *)p)->ta),
1372 EXTRACT_LE_16BITS(&(((const struct ctrl_bar_t *)p)->ctl)),
1373 EXTRACT_LE_16BITS(&(((const struct ctrl_bar_t *)p)->seq)));
1374 break;
1375 case CTRL_BA:
1376 printf("BA");
1377 if (!TTEST2(*p, CTRL_BA_HDRLEN))
1378 return 0;
1379 if (!eflag)
1380 printf(" RA:%s ",
1381 etheraddr_string(((const struct ctrl_ba_t *)p)->ra));
1382 break;
1383 case CTRL_PS_POLL:
1384 printf("Power Save-Poll");
1385 if (!TTEST2(*p, CTRL_PS_POLL_HDRLEN))
1386 return 0;
1387 printf(" AID(%x)",
1388 EXTRACT_LE_16BITS(&(((const struct ctrl_ps_poll_t *)p)->aid)));
1389 break;
1390 case CTRL_RTS:
1391 printf("Request-To-Send");
1392 if (!TTEST2(*p, CTRL_RTS_HDRLEN))
1393 return 0;
1394 if (!eflag)
1395 printf(" TA:%s ",
1396 etheraddr_string(((const struct ctrl_rts_t *)p)->ta));
1397 break;
1398 case CTRL_CTS:
1399 printf("Clear-To-Send");
1400 if (!TTEST2(*p, CTRL_CTS_HDRLEN))
1401 return 0;
1402 if (!eflag)
1403 printf(" RA:%s ",
1404 etheraddr_string(((const struct ctrl_cts_t *)p)->ra));
1405 break;
1406 case CTRL_ACK:
1407 printf("Acknowledgment");
1408 if (!TTEST2(*p, CTRL_ACK_HDRLEN))
1409 return 0;
1410 if (!eflag)
1411 printf(" RA:%s ",
1412 etheraddr_string(((const struct ctrl_ack_t *)p)->ra));
1413 break;
1414 case CTRL_CF_END:
1415 printf("CF-End");
1416 if (!TTEST2(*p, CTRL_END_HDRLEN))
1417 return 0;
1418 if (!eflag)
1419 printf(" RA:%s ",
1420 etheraddr_string(((const struct ctrl_end_t *)p)->ra));
1421 break;
1422 case CTRL_END_ACK:
1423 printf("CF-End+CF-Ack");
1424 if (!TTEST2(*p, CTRL_END_ACK_HDRLEN))
1425 return 0;
1426 if (!eflag)
1427 printf(" RA:%s ",
1428 etheraddr_string(((const struct ctrl_end_ack_t *)p)->ra));
1429 break;
1430 default:
1431 printf("Unknown Ctrl Subtype");
1432 }
1433 return 1;
1434 }
1435
1436 /*
1437 * Print Header funcs
1438 */
1439
1440 /*
1441 * Data Frame - Address field contents
1442 *
1443 * To Ds | From DS | Addr 1 | Addr 2 | Addr 3 | Addr 4
1444 * 0 | 0 | DA | SA | BSSID | n/a
1445 * 0 | 1 | DA | BSSID | SA | n/a
1446 * 1 | 0 | BSSID | SA | DA | n/a
1447 * 1 | 1 | RA | TA | DA | SA
1448 */
1449
1450 static void
1451 data_header_print(u_int16_t fc, const u_char *p, const u_int8_t **srcp,
1452 const u_int8_t **dstp)
1453 {
1454 u_int subtype = FC_SUBTYPE(fc);
1455
1456 if (DATA_FRAME_IS_CF_ACK(subtype) || DATA_FRAME_IS_CF_POLL(subtype) ||
1457 DATA_FRAME_IS_QOS(subtype)) {
1458 printf("CF ");
1459 if (DATA_FRAME_IS_CF_ACK(subtype)) {
1460 if (DATA_FRAME_IS_CF_POLL(subtype))
1461 printf("Ack/Poll");
1462 else
1463 printf("Ack");
1464 } else {
1465 if (DATA_FRAME_IS_CF_POLL(subtype))
1466 printf("Poll");
1467 }
1468 if (DATA_FRAME_IS_QOS(subtype))
1469 printf("+QoS");
1470 printf(" ");
1471 }
1472
1473 #define ADDR1 (p + 4)
1474 #define ADDR2 (p + 10)
1475 #define ADDR3 (p + 16)
1476 #define ADDR4 (p + 24)
1477
1478 if (!FC_TO_DS(fc) && !FC_FROM_DS(fc)) {
1479 if (srcp != NULL)
1480 *srcp = ADDR2;
1481 if (dstp != NULL)
1482 *dstp = ADDR1;
1483 if (!eflag)
1484 return;
1485 printf("DA:%s SA:%s BSSID:%s ",
1486 etheraddr_string(ADDR1), etheraddr_string(ADDR2),
1487 etheraddr_string(ADDR3));
1488 } else if (!FC_TO_DS(fc) && FC_FROM_DS(fc)) {
1489 if (srcp != NULL)
1490 *srcp = ADDR3;
1491 if (dstp != NULL)
1492 *dstp = ADDR1;
1493 if (!eflag)
1494 return;
1495 printf("DA:%s BSSID:%s SA:%s ",
1496 etheraddr_string(ADDR1), etheraddr_string(ADDR2),
1497 etheraddr_string(ADDR3));
1498 } else if (FC_TO_DS(fc) && !FC_FROM_DS(fc)) {
1499 if (srcp != NULL)
1500 *srcp = ADDR2;
1501 if (dstp != NULL)
1502 *dstp = ADDR3;
1503 if (!eflag)
1504 return;
1505 printf("BSSID:%s SA:%s DA:%s ",
1506 etheraddr_string(ADDR1), etheraddr_string(ADDR2),
1507 etheraddr_string(ADDR3));
1508 } else if (FC_TO_DS(fc) && FC_FROM_DS(fc)) {
1509 if (srcp != NULL)
1510 *srcp = ADDR4;
1511 if (dstp != NULL)
1512 *dstp = ADDR3;
1513 if (!eflag)
1514 return;
1515 printf("RA:%s TA:%s DA:%s SA:%s ",
1516 etheraddr_string(ADDR1), etheraddr_string(ADDR2),
1517 etheraddr_string(ADDR3), etheraddr_string(ADDR4));
1518 }
1519
1520 #undef ADDR1
1521 #undef ADDR2
1522 #undef ADDR3
1523 #undef ADDR4
1524 }
1525
1526 static void
1527 mgmt_header_print(const u_char *p, const u_int8_t **srcp,
1528 const u_int8_t **dstp)
1529 {
1530 const struct mgmt_header_t *hp = (const struct mgmt_header_t *) p;
1531
1532 if (srcp != NULL)
1533 *srcp = hp->sa;
1534 if (dstp != NULL)
1535 *dstp = hp->da;
1536 if (!eflag)
1537 return;
1538
1539 printf("BSSID:%s DA:%s SA:%s ",
1540 etheraddr_string((hp)->bssid), etheraddr_string((hp)->da),
1541 etheraddr_string((hp)->sa));
1542 }
1543
1544 static void
1545 ctrl_header_print(u_int16_t fc, const u_char *p, const u_int8_t **srcp,
1546 const u_int8_t **dstp)
1547 {
1548 if (srcp != NULL)
1549 *srcp = NULL;
1550 if (dstp != NULL)
1551 *dstp = NULL;
1552 if (!eflag)
1553 return;
1554
1555 switch (FC_SUBTYPE(fc)) {
1556 case CTRL_BAR:
1557 printf(" RA:%s TA:%s CTL(%x) SEQ(%u) ",
1558 etheraddr_string(((const struct ctrl_bar_t *)p)->ra),
1559 etheraddr_string(((const struct ctrl_bar_t *)p)->ta),
1560 EXTRACT_LE_16BITS(&(((const struct ctrl_bar_t *)p)->ctl)),
1561 EXTRACT_LE_16BITS(&(((const struct ctrl_bar_t *)p)->seq)));
1562 break;
1563 case CTRL_BA:
1564 printf("RA:%s ",
1565 etheraddr_string(((const struct ctrl_ba_t *)p)->ra));
1566 break;
1567 case CTRL_PS_POLL:
1568 printf("BSSID:%s TA:%s ",
1569 etheraddr_string(((const struct ctrl_ps_poll_t *)p)->bssid),
1570 etheraddr_string(((const struct ctrl_ps_poll_t *)p)->ta));
1571 break;
1572 case CTRL_RTS:
1573 printf("RA:%s TA:%s ",
1574 etheraddr_string(((const struct ctrl_rts_t *)p)->ra),
1575 etheraddr_string(((const struct ctrl_rts_t *)p)->ta));
1576 break;
1577 case CTRL_CTS:
1578 printf("RA:%s ",
1579 etheraddr_string(((const struct ctrl_cts_t *)p)->ra));
1580 break;
1581 case CTRL_ACK:
1582 printf("RA:%s ",
1583 etheraddr_string(((const struct ctrl_ack_t *)p)->ra));
1584 break;
1585 case CTRL_CF_END:
1586 printf("RA:%s BSSID:%s ",
1587 etheraddr_string(((const struct ctrl_end_t *)p)->ra),
1588 etheraddr_string(((const struct ctrl_end_t *)p)->bssid));
1589 break;
1590 case CTRL_END_ACK:
1591 printf("RA:%s BSSID:%s ",
1592 etheraddr_string(((const struct ctrl_end_ack_t *)p)->ra),
1593 etheraddr_string(((const struct ctrl_end_ack_t *)p)->bssid));
1594 break;
1595 default:
1596 printf("(H) Unknown Ctrl Subtype");
1597 break;
1598 }
1599 }
1600
1601 static int
1602 extract_header_length(u_int16_t fc)
1603 {
1604 int len;
1605
1606 switch (FC_TYPE(fc)) {
1607 case T_MGMT:
1608 return MGMT_HDRLEN;
1609 case T_CTRL:
1610 switch (FC_SUBTYPE(fc)) {
1611 case CTRL_BAR:
1612 return CTRL_BAR_HDRLEN;
1613 case CTRL_PS_POLL:
1614 return CTRL_PS_POLL_HDRLEN;
1615 case CTRL_RTS:
1616 return CTRL_RTS_HDRLEN;
1617 case CTRL_CTS:
1618 return CTRL_CTS_HDRLEN;
1619 case CTRL_ACK:
1620 return CTRL_ACK_HDRLEN;
1621 case CTRL_CF_END:
1622 return CTRL_END_HDRLEN;
1623 case CTRL_END_ACK:
1624 return CTRL_END_ACK_HDRLEN;
1625 default:
1626 return 0;
1627 }
1628 case T_DATA:
1629 len = (FC_TO_DS(fc) && FC_FROM_DS(fc)) ? 30 : 24;
1630 if (DATA_FRAME_IS_QOS(FC_SUBTYPE(fc)))
1631 len += 2;
1632 return len;
1633 default:
1634 printf("unknown IEEE802.11 frame type (%d)", FC_TYPE(fc));
1635 return 0;
1636 }
1637 }
1638
1639 static int
1640 extract_mesh_header_length(const u_char *p)
1641 {
1642 return (p[0] &~ 3) ? 0 : 6*(1 + (p[0] & 3));
1643 }
1644
1645 /*
1646 * Print the 802.11 MAC header if eflag is set, and set "*srcp" and "*dstp"
1647 * to point to the source and destination MAC addresses in any case if
1648 * "srcp" and "dstp" aren't null.
1649 */
1650 static void
1651 ieee_802_11_hdr_print(u_int16_t fc, const u_char *p, u_int hdrlen,
1652 u_int meshdrlen, const u_int8_t **srcp, const u_int8_t **dstp)
1653 {
1654 if (vflag) {
1655 if (FC_MORE_DATA(fc))
1656 printf("More Data ");
1657 if (FC_MORE_FLAG(fc))
1658 printf("More Fragments ");
1659 if (FC_POWER_MGMT(fc))
1660 printf("Pwr Mgmt ");
1661 if (FC_RETRY(fc))
1662 printf("Retry ");
1663 if (FC_ORDER(fc))
1664 printf("Strictly Ordered ");
1665 if (FC_WEP(fc))
1666 printf("WEP Encrypted ");
1667 if (FC_TYPE(fc) != T_CTRL || FC_SUBTYPE(fc) != CTRL_PS_POLL)
1668 printf("%dus ",
1669 EXTRACT_LE_16BITS(
1670 &((const struct mgmt_header_t *)p)->duration));
1671 }
1672 if (meshdrlen != 0) {
1673 const struct meshcntl_t *mc =
1674 (const struct meshcntl_t *)&p[hdrlen - meshdrlen];
1675 int ae = mc->flags & 3;
1676
1677 printf("MeshData (AE %d TTL %u seq %u", ae, mc->ttl,
1678 EXTRACT_LE_32BITS(mc->seq));
1679 if (ae > 0)
1680 printf(" A4:%s", etheraddr_string(mc->addr4));
1681 if (ae > 1)
1682 printf(" A5:%s", etheraddr_string(mc->addr5));
1683 if (ae > 2)
1684 printf(" A6:%s", etheraddr_string(mc->addr6));
1685 printf(") ");
1686 }
1687
1688 switch (FC_TYPE(fc)) {
1689 case T_MGMT:
1690 mgmt_header_print(p, srcp, dstp);
1691 break;
1692 case T_CTRL:
1693 ctrl_header_print(fc, p, srcp, dstp);
1694 break;
1695 case T_DATA:
1696 data_header_print(fc, p, srcp, dstp);
1697 break;
1698 default:
1699 printf("(header) unknown IEEE802.11 frame type (%d)",
1700 FC_TYPE(fc));
1701 *srcp = NULL;
1702 *dstp = NULL;
1703 break;
1704 }
1705 }
1706
1707 #ifndef roundup2
1708 #define roundup2(x, y) (((x)+((y)-1))&(~((y)-1))) /* if y is powers of two */
1709 #endif
1710
1711 static u_int
1712 ieee802_11_print(const u_char *p, u_int length, u_int orig_caplen, int pad,
1713 u_int fcslen)
1714 {
1715 u_int16_t fc;
1716 u_int caplen, hdrlen, meshdrlen;
1717 const u_int8_t *src, *dst;
1718 u_short extracted_ethertype;
1719
1720 caplen = orig_caplen;
1721 /* Remove FCS, if present */
1722 if (length < fcslen) {
1723 printf("%s", tstr);
1724 return caplen;
1725 }
1726 length -= fcslen;
1727 if (caplen > length) {
1728 /* Amount of FCS in actual packet data, if any */
1729 fcslen = caplen - length;
1730 caplen -= fcslen;
1731 snapend -= fcslen;
1732 }
1733
1734 if (caplen < IEEE802_11_FC_LEN) {
1735 printf("%s", tstr);
1736 return orig_caplen;
1737 }
1738
1739 fc = EXTRACT_LE_16BITS(p);
1740 hdrlen = extract_header_length(fc);
1741 if (pad)
1742 hdrlen = roundup2(hdrlen, 4);
1743 if (Hflag && FC_TYPE(fc) == T_DATA &&
1744 DATA_FRAME_IS_QOS(FC_SUBTYPE(fc))) {
1745 meshdrlen = extract_mesh_header_length(p+hdrlen);
1746 hdrlen += meshdrlen;
1747 } else
1748 meshdrlen = 0;
1749
1750
1751 if (caplen < hdrlen) {
1752 printf("%s", tstr);
1753 return hdrlen;
1754 }
1755
1756 ieee_802_11_hdr_print(fc, p, hdrlen, meshdrlen, &src, &dst);
1757
1758 /*
1759 * Go past the 802.11 header.
1760 */
1761 length -= hdrlen;
1762 caplen -= hdrlen;
1763 p += hdrlen;
1764
1765 switch (FC_TYPE(fc)) {
1766 case T_MGMT:
1767 if (!mgmt_body_print(fc,
1768 (const struct mgmt_header_t *)(p - hdrlen), p, length)) {
1769 printf("%s", tstr);
1770 return hdrlen;
1771 }
1772 break;
1773 case T_CTRL:
1774 if (!ctrl_body_print(fc, p - hdrlen)) {
1775 printf("%s", tstr);
1776 return hdrlen;
1777 }
1778 break;
1779 case T_DATA:
1780 if (DATA_FRAME_IS_NULL(FC_SUBTYPE(fc)))
1781 return hdrlen; /* no-data frame */
1782 /* There may be a problem w/ AP not having this bit set */
1783 if (FC_WEP(fc)) {
1784 if (!wep_print(p)) {
1785 printf("%s", tstr);
1786 return hdrlen;
1787 }
1788 } else if (llc_print(p, length, caplen, dst, src,
1789 &extracted_ethertype) == 0) {
1790 /*
1791 * Some kinds of LLC packet we cannot
1792 * handle intelligently
1793 */
1794 if (!eflag)
1795 ieee_802_11_hdr_print(fc, p - hdrlen, hdrlen,
1796 meshdrlen, NULL, NULL);
1797 if (extracted_ethertype)
1798 printf("(LLC %s) ",
1799 etherproto_string(
1800 htons(extracted_ethertype)));
1801 if (!suppress_default_print)
1802 default_print(p, caplen);
1803 }
1804 break;
1805 default:
1806 printf("unknown 802.11 frame type (%d)", FC_TYPE(fc));
1807 break;
1808 }
1809
1810 return hdrlen;
1811 }
1812
1813 /*
1814 * This is the top level routine of the printer. 'p' points
1815 * to the 802.11 header of the packet, 'h->ts' is the timestamp,
1816 * 'h->len' is the length of the packet off the wire, and 'h->caplen'
1817 * is the number of bytes actually captured.
1818 */
1819 u_int
1820 ieee802_11_if_print(const struct pcap_pkthdr *h, const u_char *p)
1821 {
1822 return ieee802_11_print(p, h->len, h->caplen, 0, 0);
1823 }
1824
1825 #define IEEE80211_CHAN_FHSS \
1826 (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_GFSK)
1827 #define IEEE80211_CHAN_A \
1828 (IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM)
1829 #define IEEE80211_CHAN_B \
1830 (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_CCK)
1831 #define IEEE80211_CHAN_PUREG \
1832 (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_OFDM)
1833 #define IEEE80211_CHAN_G \
1834 (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_DYN)
1835
1836 #define IS_CHAN_FHSS(flags) \
1837 ((flags & IEEE80211_CHAN_FHSS) == IEEE80211_CHAN_FHSS)
1838 #define IS_CHAN_A(flags) \
1839 ((flags & IEEE80211_CHAN_A) == IEEE80211_CHAN_A)
1840 #define IS_CHAN_B(flags) \
1841 ((flags & IEEE80211_CHAN_B) == IEEE80211_CHAN_B)
1842 #define IS_CHAN_PUREG(flags) \
1843 ((flags & IEEE80211_CHAN_PUREG) == IEEE80211_CHAN_PUREG)
1844 #define IS_CHAN_G(flags) \
1845 ((flags & IEEE80211_CHAN_G) == IEEE80211_CHAN_G)
1846 #define IS_CHAN_ANYG(flags) \
1847 (IS_CHAN_PUREG(flags) || IS_CHAN_G(flags))
1848
1849 static void
1850 print_chaninfo(int freq, int flags)
1851 {
1852 printf("%u MHz", freq);
1853 if (IS_CHAN_FHSS(flags))
1854 printf(" FHSS");
1855 if (IS_CHAN_A(flags)) {
1856 if (flags & IEEE80211_CHAN_HALF)
1857 printf(" 11a/10Mhz");
1858 else if (flags & IEEE80211_CHAN_QUARTER)
1859 printf(" 11a/5Mhz");
1860 else
1861 printf(" 11a");
1862 }
1863 if (IS_CHAN_ANYG(flags)) {
1864 if (flags & IEEE80211_CHAN_HALF)
1865 printf(" 11g/10Mhz");
1866 else if (flags & IEEE80211_CHAN_QUARTER)
1867 printf(" 11g/5Mhz");
1868 else
1869 printf(" 11g");
1870 } else if (IS_CHAN_B(flags))
1871 printf(" 11b");
1872 if (flags & IEEE80211_CHAN_TURBO)
1873 printf(" Turbo");
1874 if (flags & IEEE80211_CHAN_HT20)
1875 printf(" ht/20");
1876 else if (flags & IEEE80211_CHAN_HT40D)
1877 printf(" ht/40-");
1878 else if (flags & IEEE80211_CHAN_HT40U)
1879 printf(" ht/40+");
1880 printf(" ");
1881 }
1882
1883 static int
1884 print_radiotap_field(struct cpack_state *s, u_int32_t bit, u_int8_t *flags,
1885 struct radiotap_state *state, u_int32_t presentflags)
1886 {
1887 union {
1888 int8_t i8;
1889 u_int8_t u8;
1890 int16_t i16;
1891 u_int16_t u16;
1892 u_int32_t u32;
1893 u_int64_t u64;
1894 } u, u2, u3, u4;
1895 int rc;
1896
1897 switch (bit) {
1898 case IEEE80211_RADIOTAP_FLAGS:
1899 rc = cpack_uint8(s, &u.u8);
1900 if (rc != 0)
1901 break;
1902 *flags = u.u8;
1903 break;
1904 case IEEE80211_RADIOTAP_RATE:
1905 rc = cpack_uint8(s, &u.u8);
1906 if (rc != 0)
1907 break;
1908
1909 /* Save state rate */
1910 state->rate = u.u8;
1911 break;
1912 case IEEE80211_RADIOTAP_DB_ANTSIGNAL:
1913 case IEEE80211_RADIOTAP_DB_ANTNOISE:
1914 case IEEE80211_RADIOTAP_ANTENNA:
1915 rc = cpack_uint8(s, &u.u8);
1916 break;
1917 case IEEE80211_RADIOTAP_DBM_ANTSIGNAL:
1918 case IEEE80211_RADIOTAP_DBM_ANTNOISE:
1919 rc = cpack_int8(s, &u.i8);
1920 break;
1921 case IEEE80211_RADIOTAP_CHANNEL:
1922 rc = cpack_uint16(s, &u.u16);
1923 if (rc != 0)
1924 break;
1925 rc = cpack_uint16(s, &u2.u16);
1926 break;
1927 case IEEE80211_RADIOTAP_FHSS:
1928 case IEEE80211_RADIOTAP_LOCK_QUALITY:
1929 case IEEE80211_RADIOTAP_TX_ATTENUATION:
1930 case IEEE80211_RADIOTAP_RX_FLAGS:
1931 rc = cpack_uint16(s, &u.u16);
1932 break;
1933 case IEEE80211_RADIOTAP_DB_TX_ATTENUATION:
1934 rc = cpack_uint8(s, &u.u8);
1935 break;
1936 case IEEE80211_RADIOTAP_DBM_TX_POWER:
1937 rc = cpack_int8(s, &u.i8);
1938 break;
1939 case IEEE80211_RADIOTAP_TSFT:
1940 rc = cpack_uint64(s, &u.u64);
1941 break;
1942 case IEEE80211_RADIOTAP_XCHANNEL:
1943 rc = cpack_uint32(s, &u.u32);
1944 if (rc != 0)
1945 break;
1946 rc = cpack_uint16(s, &u2.u16);
1947 if (rc != 0)
1948 break;
1949 rc = cpack_uint8(s, &u3.u8);
1950 if (rc != 0)
1951 break;
1952 rc = cpack_uint8(s, &u4.u8);
1953 break;
1954 case IEEE80211_RADIOTAP_MCS:
1955 rc = cpack_uint8(s, &u.u8);
1956 if (rc != 0)
1957 break;
1958 rc = cpack_uint8(s, &u2.u8);
1959 if (rc != 0)
1960 break;
1961 rc = cpack_uint8(s, &u3.u8);
1962 break;
1963 case IEEE80211_RADIOTAP_VENDOR_NAMESPACE: {
1964 u_int8_t vns[3];
1965 u_int16_t length;
1966 u_int8_t subspace;
1967
1968 if ((cpack_align_and_reserve(s, 2)) == NULL) {
1969 rc = -1;
1970 break;
1971 }
1972
1973 rc = cpack_uint8(s, &vns[0]);
1974 if (rc != 0)
1975 break;
1976 rc = cpack_uint8(s, &vns[1]);
1977 if (rc != 0)
1978 break;
1979 rc = cpack_uint8(s, &vns[2]);
1980 if (rc != 0)
1981 break;
1982 rc = cpack_uint8(s, &subspace);
1983 if (rc != 0)
1984 break;
1985 rc = cpack_uint16(s, &length);
1986 if (rc != 0)
1987 break;
1988
1989 /* Skip up to length */
1990 s->c_next += length;
1991 break;
1992 }
1993 default:
1994 /* this bit indicates a field whose
1995 * size we do not know, so we cannot
1996 * proceed. Just print the bit number.
1997 */
1998 printf("[bit %u] ", bit);
1999 return -1;
2000 }
2001
2002 if (rc != 0) {
2003 printf("%s", tstr);
2004 return rc;
2005 }
2006
2007 /* Preserve the state present flags */
2008 state->present = presentflags;
2009
2010 switch (bit) {
2011 case IEEE80211_RADIOTAP_CHANNEL:
2012 /*
2013 * If CHANNEL and XCHANNEL are both present, skip
2014 * CHANNEL.
2015 */
2016 if (presentflags & (1 << IEEE80211_RADIOTAP_XCHANNEL))
2017 break;
2018 print_chaninfo(u.u16, u2.u16);
2019 break;
2020 case IEEE80211_RADIOTAP_FHSS:
2021 printf("fhset %d fhpat %d ", u.u16 & 0xff, (u.u16 >> 8) & 0xff);
2022 break;
2023 case IEEE80211_RADIOTAP_RATE:
2024 /*
2025 * XXX On FreeBSD rate & 0x80 means we have an MCS. On
2026 * Linux and AirPcap it does not. (What about
2027 * Mac OS X, NetBSD, OpenBSD, and DragonFly BSD?)
2028 *
2029 * This is an issue either for proprietary extensions
2030 * to 11a or 11g, which do exist, or for 11n
2031 * implementations that stuff a rate value into
2032 * this field, which also appear to exist.
2033 *
2034 * We currently handle that by assuming that
2035 * if the 0x80 bit is set *and* the remaining
2036 * bits have a value between 0 and 15 it's
2037 * an MCS value, otherwise it's a rate. If
2038 * there are cases where systems that use
2039 * "0x80 + MCS index" for MCS indices > 15,
2040 * or stuff a rate value here between 64 and
2041 * 71.5 Mb/s in here, we'll need a preference
2042 * setting. Such rates do exist, e.g. 11n
2043 * MCS 7 at 20 MHz with a long guard interval.
2044 */
2045 if (u.u8 >= 0x80 && u.u8 <= 0x8f) {
2046 /*
2047 * XXX - we don't know the channel width
2048 * or guard interval length, so we can't
2049 * convert this to a data rate.
2050 *
2051 * If you want us to show a data rate,
2052 * use the MCS field, not the Rate field;
2053 * the MCS field includes not only the
2054 * MCS index, it also includes bandwidth
2055 * and guard interval information.
2056 *
2057 * XXX - can we get the channel width
2058 * from XChannel and the guard interval
2059 * information from Flags, at least on
2060 * FreeBSD?
2061 */
2062 printf("MCS %u ", u.u8 & 0x7f);
2063 } else
2064 printf("%2.1f Mb/s ", .5*u.u8);
2065 break;
2066 case IEEE80211_RADIOTAP_DBM_ANTSIGNAL:
2067 printf("%ddB signal ", u.i8);
2068 break;
2069 case IEEE80211_RADIOTAP_DBM_ANTNOISE:
2070 printf("%ddB noise ", u.i8);
2071 break;
2072 case IEEE80211_RADIOTAP_DB_ANTSIGNAL:
2073 printf("%ddB signal ", u.u8);
2074 break;
2075 case IEEE80211_RADIOTAP_DB_ANTNOISE:
2076 printf("%ddB noise ", u.u8);
2077 break;
2078 case IEEE80211_RADIOTAP_LOCK_QUALITY:
2079 printf("%u sq ", u.u16);
2080 break;
2081 case IEEE80211_RADIOTAP_TX_ATTENUATION:
2082 printf("%d tx power ", -(int)u.u16);
2083 break;
2084 case IEEE80211_RADIOTAP_DB_TX_ATTENUATION:
2085 printf("%ddB tx power ", -(int)u.u8);
2086 break;
2087 case IEEE80211_RADIOTAP_DBM_TX_POWER:
2088 printf("%ddBm tx power ", u.i8);
2089 break;
2090 case IEEE80211_RADIOTAP_FLAGS:
2091 if (u.u8 & IEEE80211_RADIOTAP_F_CFP)
2092 printf("cfp ");
2093 if (u.u8 & IEEE80211_RADIOTAP_F_SHORTPRE)
2094 printf("short preamble ");
2095 if (u.u8 & IEEE80211_RADIOTAP_F_WEP)
2096 printf("wep ");
2097 if (u.u8 & IEEE80211_RADIOTAP_F_FRAG)
2098 printf("fragmented ");
2099 if (u.u8 & IEEE80211_RADIOTAP_F_BADFCS)
2100 printf("bad-fcs ");
2101 break;
2102 case IEEE80211_RADIOTAP_ANTENNA:
2103 printf("antenna %d ", u.u8);
2104 break;
2105 case IEEE80211_RADIOTAP_TSFT:
2106 printf("%" PRIu64 "us tsft ", u.u64);
2107 break;
2108 case IEEE80211_RADIOTAP_RX_FLAGS:
2109 /* Do nothing for now */
2110 break;
2111 case IEEE80211_RADIOTAP_XCHANNEL:
2112 print_chaninfo(u2.u16, u.u32);
2113 break;
2114 case IEEE80211_RADIOTAP_MCS: {
2115 static const char *bandwidth[4] = {
2116 "20 MHz",
2117 "40 MHz",
2118 "20 MHz (L)",
2119 "20 MHz (U)"
2120 };
2121 float htrate;
2122
2123 if (u.u8 & IEEE80211_RADIOTAP_MCS_MCS_INDEX_KNOWN) {
2124 /*
2125 * We know the MCS index.
2126 */
2127 if (u3.u8 <= MAX_MCS_INDEX) {
2128 /*
2129 * And it's in-range.
2130 */
2131 if (u.u8 & (IEEE80211_RADIOTAP_MCS_BANDWIDTH_KNOWN|IEEE80211_RADIOTAP_MCS_GUARD_INTERVAL_KNOWN)) {
2132 /*
2133 * And we know both the bandwidth and
2134 * the guard interval, so we can look
2135 * up the rate.
2136 */
2137 htrate =
2138 ieee80211_float_htrates \
2139 [u3.u8] \
2140 [((u2.u8 & IEEE80211_RADIOTAP_MCS_BANDWIDTH_MASK) == IEEE80211_RADIOTAP_MCS_BANDWIDTH_40 ? 1 : 0)] \
2141 [((u2.u8 & IEEE80211_RADIOTAP_MCS_SHORT_GI) ? 1 : 0)];
2142 } else {
2143 /*
2144 * We don't know both the bandwidth
2145 * and the guard interval, so we can
2146 * only report the MCS index.
2147 */
2148 htrate = 0.0;
2149 }
2150 } else {
2151 /*
2152 * The MCS value is out of range.
2153 */
2154 htrate = 0.0;
2155 }
2156 if (htrate != 0.0) {
2157 /*
2158 * We have the rate.
2159 * Print it.
2160 */
2161 printf("%.1f Mb/s MCS %u ", htrate, u3.u8);
2162 } else {
2163 /*
2164 * We at least have the MCS index.
2165 * Print it.
2166 */
2167 printf("MCS %u ", u3.u8);
2168 }
2169 }
2170 if (u.u8 & IEEE80211_RADIOTAP_MCS_BANDWIDTH_KNOWN) {
2171 printf("%s ",
2172 bandwidth[u2.u8 & IEEE80211_RADIOTAP_MCS_BANDWIDTH_MASK]);
2173 }
2174 if (u.u8 & IEEE80211_RADIOTAP_MCS_GUARD_INTERVAL_KNOWN) {
2175 printf("%s GI ",
2176 (u2.u8 & IEEE80211_RADIOTAP_MCS_SHORT_GI) ?
2177 "short" : "lon");
2178 }
2179 if (u.u8 & IEEE80211_RADIOTAP_MCS_HT_FORMAT_KNOWN) {
2180 printf("%s ",
2181 (u2.u8 & IEEE80211_RADIOTAP_MCS_HT_GREENFIELD) ?
2182 "greenfield" : "mixed");
2183 }
2184 if (u.u8 & IEEE80211_RADIOTAP_MCS_FEC_TYPE_KNOWN) {
2185 printf("%s FEC ",
2186 (u2.u8 & IEEE80211_RADIOTAP_MCS_FEC_LDPC) ?
2187 "LDPC" : "BCC");
2188 }
2189 if (u.u8 & IEEE80211_RADIOTAP_MCS_STBC_KNOWN) {
2190 printf("RX-STBC%u ",
2191 (u2.u8 & IEEE80211_RADIOTAP_MCS_STBC_MASK) >> IEEE80211_RADIOTAP_MCS_STBC_SHIFT);
2192 }
2193
2194 break;
2195 }
2196 }
2197 return 0;
2198 }
2199
2200 static u_int
2201 ieee802_11_radio_print(const u_char *p, u_int length, u_int caplen)
2202 {
2203 #define BITNO_32(x) (((x) >> 16) ? 16 + BITNO_16((x) >> 16) : BITNO_16((x)))
2204 #define BITNO_16(x) (((x) >> 8) ? 8 + BITNO_8((x) >> 8) : BITNO_8((x)))
2205 #define BITNO_8(x) (((x) >> 4) ? 4 + BITNO_4((x) >> 4) : BITNO_4((x)))
2206 #define BITNO_4(x) (((x) >> 2) ? 2 + BITNO_2((x) >> 2) : BITNO_2((x)))
2207 #define BITNO_2(x) (((x) & 2) ? 1 : 0)
2208 #define BIT(n) (1U << n)
2209 #define IS_EXTENDED(__p) \
2210 (EXTRACT_LE_32BITS(__p) & BIT(IEEE80211_RADIOTAP_EXT)) != 0
2211
2212 struct cpack_state cpacker;
2213 struct ieee80211_radiotap_header *hdr;
2214 u_int32_t present, next_present;
2215 u_int32_t presentflags = 0;
2216 u_int32_t *presentp, *last_presentp;
2217 enum ieee80211_radiotap_type bit;
2218 int bit0;
2219 u_int len;
2220 u_int8_t flags;
2221 int pad;
2222 u_int fcslen;
2223 struct radiotap_state state;
2224
2225 if (caplen < sizeof(*hdr)) {
2226 printf("%s", tstr);
2227 return caplen;
2228 }
2229
2230 hdr = (struct ieee80211_radiotap_header *)p;
2231
2232 len = EXTRACT_LE_16BITS(&hdr->it_len);
2233
2234 if (caplen < len) {
2235 printf("%s", tstr);
2236 return caplen;
2237 }
2238 cpack_init(&cpacker, (u_int8_t *)hdr, len); /* align against header start */
2239 cpack_advance(&cpacker, sizeof(*hdr)); /* includes the 1st bitmap */
2240 for (last_presentp = &hdr->it_present;
2241 IS_EXTENDED(last_presentp) &&
2242 (u_char*)(last_presentp + 1) <= p + len;
2243 last_presentp++)
2244 cpack_advance(&cpacker, sizeof(hdr->it_present)); /* more bitmaps */
2245
2246 /* are there more bitmap extensions than bytes in header? */
2247 if (IS_EXTENDED(last_presentp)) {
2248 printf("%s", tstr);
2249 return caplen;
2250 }
2251
2252 /* Assume no flags */
2253 flags = 0;
2254 /* Assume no Atheros padding between 802.11 header and body */
2255 pad = 0;
2256 /* Assume no FCS at end of frame */
2257 fcslen = 0;
2258 for (bit0 = 0, presentp = &hdr->it_present; presentp <= last_presentp;
2259 presentp++, bit0 += 32) {
2260 presentflags = EXTRACT_LE_32BITS(presentp);
2261
2262 /* Clear state. */
2263 memset(&state, 0, sizeof(state));
2264
2265 for (present = EXTRACT_LE_32BITS(presentp); present;
2266 present = next_present) {
2267 /* clear the least significant bit that is set */
2268 next_present = present & (present - 1);
2269
2270 /* extract the least significant bit that is set */
2271 bit = (enum ieee80211_radiotap_type)
2272 (bit0 + BITNO_32(present ^ next_present));
2273
2274 if (print_radiotap_field(&cpacker, bit, &flags, &state, presentflags) != 0)
2275 goto out;
2276 }
2277 }
2278
2279 out:
2280 if (flags & IEEE80211_RADIOTAP_F_DATAPAD)
2281 pad = 1; /* Atheros padding */
2282 if (flags & IEEE80211_RADIOTAP_F_FCS)
2283 fcslen = 4; /* FCS at end of packet */
2284 return len + ieee802_11_print(p + len, length - len, caplen - len, pad,
2285 fcslen);
2286 #undef BITNO_32
2287 #undef BITNO_16
2288 #undef BITNO_8
2289 #undef BITNO_4
2290 #undef BITNO_2
2291 #undef BIT
2292 }
2293
2294 static u_int
2295 ieee802_11_avs_radio_print(const u_char *p, u_int length, u_int caplen)
2296 {
2297 u_int32_t caphdr_len;
2298
2299 if (caplen < 8) {
2300 printf("%s", tstr);
2301 return caplen;
2302 }
2303
2304 caphdr_len = EXTRACT_32BITS(p + 4);
2305 if (caphdr_len < 8) {
2306 /*
2307 * Yow! The capture header length is claimed not
2308 * to be large enough to include even the version
2309 * cookie or capture header length!
2310 */
2311 printf("%s", tstr);
2312 return caplen;
2313 }
2314
2315 if (caplen < caphdr_len) {
2316 printf("%s", tstr);
2317 return caplen;
2318 }
2319
2320 return caphdr_len + ieee802_11_print(p + caphdr_len,
2321 length - caphdr_len, caplen - caphdr_len, 0, 0);
2322 }
2323
2324 #define PRISM_HDR_LEN 144
2325
2326 #define WLANCAP_MAGIC_COOKIE_BASE 0x80211000
2327 #define WLANCAP_MAGIC_COOKIE_V1 0x80211001
2328 #define WLANCAP_MAGIC_COOKIE_V2 0x80211002
2329
2330 /*
2331 * For DLT_PRISM_HEADER; like DLT_IEEE802_11, but with an extra header,
2332 * containing information such as radio information, which we
2333 * currently ignore.
2334 *
2335 * If, however, the packet begins with WLANCAP_MAGIC_COOKIE_V1 or
2336 * WLANCAP_MAGIC_COOKIE_V2, it's really DLT_IEEE802_11_RADIO_AVS
2337 * (currently, on Linux, there's no ARPHRD_ type for
2338 * DLT_IEEE802_11_RADIO_AVS, as there is a ARPHRD_IEEE80211_PRISM
2339 * for DLT_PRISM_HEADER, so ARPHRD_IEEE80211_PRISM is used for
2340 * the AVS header, and the first 4 bytes of the header are used to
2341 * indicate whether it's a Prism header or an AVS header).
2342 */
2343 u_int
2344 prism_if_print(const struct pcap_pkthdr *h, const u_char *p)
2345 {
2346 u_int caplen = h->caplen;
2347 u_int length = h->len;
2348 u_int32_t msgcode;
2349
2350 if (caplen < 4) {
2351 printf("%s", tstr);
2352 return caplen;
2353 }
2354
2355 msgcode = EXTRACT_32BITS(p);
2356 if (msgcode == WLANCAP_MAGIC_COOKIE_V1 ||
2357 msgcode == WLANCAP_MAGIC_COOKIE_V2)
2358 return ieee802_11_avs_radio_print(p, length, caplen);
2359
2360 if (caplen < PRISM_HDR_LEN) {
2361 printf("%s", tstr);
2362 return caplen;
2363 }
2364
2365 return PRISM_HDR_LEN + ieee802_11_print(p + PRISM_HDR_LEN,
2366 length - PRISM_HDR_LEN, caplen - PRISM_HDR_LEN, 0, 0);
2367 }
2368
2369 /*
2370 * For DLT_IEEE802_11_RADIO; like DLT_IEEE802_11, but with an extra
2371 * header, containing information such as radio information.
2372 */
2373 u_int
2374 ieee802_11_radio_if_print(const struct pcap_pkthdr *h, const u_char *p)
2375 {
2376 return ieee802_11_radio_print(p, h->len, h->caplen);
2377 }
2378
2379 /*
2380 * For DLT_IEEE802_11_RADIO_AVS; like DLT_IEEE802_11, but with an
2381 * extra header, containing information such as radio information,
2382 * which we currently ignore.
2383 */
2384 u_int
2385 ieee802_11_radio_avs_if_print(const struct pcap_pkthdr *h, const u_char *p)
2386 {
2387 return ieee802_11_avs_radio_print(p, h->len, h->caplen);
2388 }