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