Import tcpdump-4.2.1.
[dragonfly.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         "Succesful",                                            /*  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 static int
1227 handle_action(const struct mgmt_header_t *pmh, const u_char *p, u_int length)
1228 {
1229         if (!TTEST2(*p, 2))
1230                 return 0;
1231         if (length < 2)
1232                 return 0;
1233         if (eflag) {
1234                 printf(": ");
1235         } else {
1236                 printf(" (%s): ", etheraddr_string(pmh->sa));
1237         }
1238         switch (p[0]) {
1239         case 0: printf("Spectrum Management Act#%d", p[1]); break;
1240         case 1: printf("QoS Act#%d", p[1]); break;
1241         case 2: printf("DLS Act#%d", p[1]); break;
1242         case 3: printf("BA "); PRINT_BA_ACTION(p[1]); break;
1243         case 7: printf("HT "); PRINT_HT_ACTION(p[1]); break;
1244         case 13: printf("MeshLMetric "); PRINT_MESHLINK_ACTION(p[1]); break;
1245         case 15: printf("Interwork Act#%d", p[1]); break;
1246         case 16: printf("Resource Act#%d", p[1]); break;
1247         case 17: printf("Proxy Act#%d", p[1]); break;
1248         case 30: printf("MeshPeering "); PRINT_MESHPEERING_ACTION(p[1]); break;
1249         case 32: printf("MeshPath "); PRINT_MESHPATH_ACTION(p[1]); break;
1250         case 127: printf("Vendor Act#%d", p[1]); break;
1251         default:
1252                 printf("Reserved(%d) Act#%d", p[0], p[1]);
1253                 break;
1254         }
1255         return 1;
1256 }
1257
1258
1259 /*********************************************************************************
1260  * Print Body funcs
1261  *********************************************************************************/
1262
1263
1264 static int
1265 mgmt_body_print(u_int16_t fc, const struct mgmt_header_t *pmh,
1266     const u_char *p, u_int length)
1267 {
1268         switch (FC_SUBTYPE(fc)) {
1269         case ST_ASSOC_REQUEST:
1270                 printf("Assoc Request");
1271                 return handle_assoc_request(p, length);
1272         case ST_ASSOC_RESPONSE:
1273                 printf("Assoc Response");
1274                 return handle_assoc_response(p, length);
1275         case ST_REASSOC_REQUEST:
1276                 printf("ReAssoc Request");
1277                 return handle_reassoc_request(p, length);
1278         case ST_REASSOC_RESPONSE:
1279                 printf("ReAssoc Response");
1280                 return handle_reassoc_response(p, length);
1281         case ST_PROBE_REQUEST:
1282                 printf("Probe Request");
1283                 return handle_probe_request(p, length);
1284         case ST_PROBE_RESPONSE:
1285                 printf("Probe Response");
1286                 return handle_probe_response(p, length);
1287         case ST_BEACON:
1288                 printf("Beacon");
1289                 return handle_beacon(p, length);
1290         case ST_ATIM:
1291                 printf("ATIM");
1292                 return handle_atim();
1293         case ST_DISASSOC:
1294                 printf("Disassociation");
1295                 return handle_disassoc(p, length);
1296         case ST_AUTH:
1297                 printf("Authentication");
1298                 if (!TTEST2(*p, 3))
1299                         return 0;
1300                 if ((p[0] == 0 ) && (p[1] == 0) && (p[2] == 0)) {
1301                         printf("Authentication (Shared-Key)-3 ");
1302                         return wep_print(p);
1303                 }
1304                 return handle_auth(p, length);
1305         case ST_DEAUTH:
1306                 printf("DeAuthentication");
1307                 return handle_deauth(pmh, p, length);
1308                 break;
1309         case ST_ACTION:
1310                 printf("Action");
1311                 return handle_action(pmh, p, length);
1312                 break;
1313         default:
1314                 printf("Unhandled Management subtype(%x)",
1315                     FC_SUBTYPE(fc));
1316                 return 1;
1317         }
1318 }
1319
1320
1321 /*********************************************************************************
1322  * Handles printing all the control frame types
1323  *********************************************************************************/
1324
1325 static int
1326 ctrl_body_print(u_int16_t fc, const u_char *p)
1327 {
1328         switch (FC_SUBTYPE(fc)) {
1329         case CTRL_CONTROL_WRAPPER:
1330                 printf("Control Wrapper");
1331                 /* XXX - requires special handling */
1332                 break;
1333         case CTRL_BAR:
1334                 printf("BAR");
1335                 if (!TTEST2(*p, CTRL_BAR_HDRLEN))
1336                         return 0;
1337                 if (!eflag)
1338                         printf(" RA:%s TA:%s CTL(%x) SEQ(%u) ",
1339                             etheraddr_string(((const struct ctrl_bar_t *)p)->ra),
1340                             etheraddr_string(((const struct ctrl_bar_t *)p)->ta),
1341                             EXTRACT_LE_16BITS(&(((const struct ctrl_bar_t *)p)->ctl)),
1342                             EXTRACT_LE_16BITS(&(((const struct ctrl_bar_t *)p)->seq)));
1343                 break;
1344         case CTRL_BA:
1345                 printf("BA");
1346                 if (!TTEST2(*p, CTRL_BA_HDRLEN))
1347                         return 0;
1348                 if (!eflag)
1349                         printf(" RA:%s ",
1350                             etheraddr_string(((const struct ctrl_ba_t *)p)->ra));
1351                 break;
1352         case CTRL_PS_POLL:
1353                 printf("Power Save-Poll");
1354                 if (!TTEST2(*p, CTRL_PS_POLL_HDRLEN))
1355                         return 0;
1356                 printf(" AID(%x)",
1357                     EXTRACT_LE_16BITS(&(((const struct ctrl_ps_poll_t *)p)->aid)));
1358                 break;
1359         case CTRL_RTS:
1360                 printf("Request-To-Send");
1361                 if (!TTEST2(*p, CTRL_RTS_HDRLEN))
1362                         return 0;
1363                 if (!eflag)
1364                         printf(" TA:%s ",
1365                             etheraddr_string(((const struct ctrl_rts_t *)p)->ta));
1366                 break;
1367         case CTRL_CTS:
1368                 printf("Clear-To-Send");
1369                 if (!TTEST2(*p, CTRL_CTS_HDRLEN))
1370                         return 0;
1371                 if (!eflag)
1372                         printf(" RA:%s ",
1373                             etheraddr_string(((const struct ctrl_cts_t *)p)->ra));
1374                 break;
1375         case CTRL_ACK:
1376                 printf("Acknowledgment");
1377                 if (!TTEST2(*p, CTRL_ACK_HDRLEN))
1378                         return 0;
1379                 if (!eflag)
1380                         printf(" RA:%s ",
1381                             etheraddr_string(((const struct ctrl_ack_t *)p)->ra));
1382                 break;
1383         case CTRL_CF_END:
1384                 printf("CF-End");
1385                 if (!TTEST2(*p, CTRL_END_HDRLEN))
1386                         return 0;
1387                 if (!eflag)
1388                         printf(" RA:%s ",
1389                             etheraddr_string(((const struct ctrl_end_t *)p)->ra));
1390                 break;
1391         case CTRL_END_ACK:
1392                 printf("CF-End+CF-Ack");
1393                 if (!TTEST2(*p, CTRL_END_ACK_HDRLEN))
1394                         return 0;
1395                 if (!eflag)
1396                         printf(" RA:%s ",
1397                             etheraddr_string(((const struct ctrl_end_ack_t *)p)->ra));
1398                 break;
1399         default:
1400                 printf("Unknown Ctrl Subtype");
1401         }
1402         return 1;
1403 }
1404
1405 /*
1406  * Print Header funcs
1407  */
1408
1409 /*
1410  *  Data Frame - Address field contents
1411  *
1412  *  To Ds  | From DS | Addr 1 | Addr 2 | Addr 3 | Addr 4
1413  *    0    |  0      |  DA    | SA     | BSSID  | n/a
1414  *    0    |  1      |  DA    | BSSID  | SA     | n/a
1415  *    1    |  0      |  BSSID | SA     | DA     | n/a
1416  *    1    |  1      |  RA    | TA     | DA     | SA
1417  */
1418
1419 static void
1420 data_header_print(u_int16_t fc, const u_char *p, const u_int8_t **srcp,
1421     const u_int8_t **dstp)
1422 {
1423         u_int subtype = FC_SUBTYPE(fc);
1424
1425         if (DATA_FRAME_IS_CF_ACK(subtype) || DATA_FRAME_IS_CF_POLL(subtype) ||
1426             DATA_FRAME_IS_QOS(subtype)) {
1427                 printf("CF ");
1428                 if (DATA_FRAME_IS_CF_ACK(subtype)) {
1429                         if (DATA_FRAME_IS_CF_POLL(subtype))
1430                                 printf("Ack/Poll");
1431                         else
1432                                 printf("Ack");
1433                 } else {
1434                         if (DATA_FRAME_IS_CF_POLL(subtype))
1435                                 printf("Poll");
1436                 }
1437                 if (DATA_FRAME_IS_QOS(subtype))
1438                         printf("+QoS");
1439                 printf(" ");
1440         }
1441
1442 #define ADDR1  (p + 4)
1443 #define ADDR2  (p + 10)
1444 #define ADDR3  (p + 16)
1445 #define ADDR4  (p + 24)
1446
1447         if (!FC_TO_DS(fc) && !FC_FROM_DS(fc)) {
1448                 if (srcp != NULL)
1449                         *srcp = ADDR2;
1450                 if (dstp != NULL)
1451                         *dstp = ADDR1;
1452                 if (!eflag)
1453                         return;
1454                 printf("DA:%s SA:%s BSSID:%s ",
1455                     etheraddr_string(ADDR1), etheraddr_string(ADDR2),
1456                     etheraddr_string(ADDR3));
1457         } else if (!FC_TO_DS(fc) && FC_FROM_DS(fc)) {
1458                 if (srcp != NULL)
1459                         *srcp = ADDR3;
1460                 if (dstp != NULL)
1461                         *dstp = ADDR1;
1462                 if (!eflag)
1463                         return;
1464                 printf("DA:%s BSSID:%s SA:%s ",
1465                     etheraddr_string(ADDR1), etheraddr_string(ADDR2),
1466                     etheraddr_string(ADDR3));
1467         } else if (FC_TO_DS(fc) && !FC_FROM_DS(fc)) {
1468                 if (srcp != NULL)
1469                         *srcp = ADDR2;
1470                 if (dstp != NULL)
1471                         *dstp = ADDR3;
1472                 if (!eflag)
1473                         return;
1474                 printf("BSSID:%s SA:%s DA:%s ",
1475                     etheraddr_string(ADDR1), etheraddr_string(ADDR2),
1476                     etheraddr_string(ADDR3));
1477         } else if (FC_TO_DS(fc) && FC_FROM_DS(fc)) {
1478                 if (srcp != NULL)
1479                         *srcp = ADDR4;
1480                 if (dstp != NULL)
1481                         *dstp = ADDR3;
1482                 if (!eflag)
1483                         return;
1484                 printf("RA:%s TA:%s DA:%s SA:%s ",
1485                     etheraddr_string(ADDR1), etheraddr_string(ADDR2),
1486                     etheraddr_string(ADDR3), etheraddr_string(ADDR4));
1487         }
1488
1489 #undef ADDR1
1490 #undef ADDR2
1491 #undef ADDR3
1492 #undef ADDR4
1493 }
1494
1495 static void
1496 mgmt_header_print(const u_char *p, const u_int8_t **srcp,
1497     const u_int8_t **dstp)
1498 {
1499         const struct mgmt_header_t *hp = (const struct mgmt_header_t *) p;
1500
1501         if (srcp != NULL)
1502                 *srcp = hp->sa;
1503         if (dstp != NULL)
1504                 *dstp = hp->da;
1505         if (!eflag)
1506                 return;
1507
1508         printf("BSSID:%s DA:%s SA:%s ",
1509             etheraddr_string((hp)->bssid), etheraddr_string((hp)->da),
1510             etheraddr_string((hp)->sa));
1511 }
1512
1513 static void
1514 ctrl_header_print(u_int16_t fc, const u_char *p, const u_int8_t **srcp,
1515     const u_int8_t **dstp)
1516 {
1517         if (srcp != NULL)
1518                 *srcp = NULL;
1519         if (dstp != NULL)
1520                 *dstp = NULL;
1521         if (!eflag)
1522                 return;
1523
1524         switch (FC_SUBTYPE(fc)) {
1525         case CTRL_BAR:
1526                 printf(" RA:%s TA:%s CTL(%x) SEQ(%u) ",
1527                     etheraddr_string(((const struct ctrl_bar_t *)p)->ra),
1528                     etheraddr_string(((const struct ctrl_bar_t *)p)->ta),
1529                     EXTRACT_LE_16BITS(&(((const struct ctrl_bar_t *)p)->ctl)),
1530                     EXTRACT_LE_16BITS(&(((const struct ctrl_bar_t *)p)->seq)));
1531                 break;
1532         case CTRL_BA:
1533                 printf("RA:%s ",
1534                     etheraddr_string(((const struct ctrl_ba_t *)p)->ra));
1535                 break;
1536         case CTRL_PS_POLL:
1537                 printf("BSSID:%s TA:%s ",
1538                     etheraddr_string(((const struct ctrl_ps_poll_t *)p)->bssid),
1539                     etheraddr_string(((const struct ctrl_ps_poll_t *)p)->ta));
1540                 break;
1541         case CTRL_RTS:
1542                 printf("RA:%s TA:%s ",
1543                     etheraddr_string(((const struct ctrl_rts_t *)p)->ra),
1544                     etheraddr_string(((const struct ctrl_rts_t *)p)->ta));
1545                 break;
1546         case CTRL_CTS:
1547                 printf("RA:%s ",
1548                     etheraddr_string(((const struct ctrl_cts_t *)p)->ra));
1549                 break;
1550         case CTRL_ACK:
1551                 printf("RA:%s ",
1552                     etheraddr_string(((const struct ctrl_ack_t *)p)->ra));
1553                 break;
1554         case CTRL_CF_END:
1555                 printf("RA:%s BSSID:%s ",
1556                     etheraddr_string(((const struct ctrl_end_t *)p)->ra),
1557                     etheraddr_string(((const struct ctrl_end_t *)p)->bssid));
1558                 break;
1559         case CTRL_END_ACK:
1560                 printf("RA:%s BSSID:%s ",
1561                     etheraddr_string(((const struct ctrl_end_ack_t *)p)->ra),
1562                     etheraddr_string(((const struct ctrl_end_ack_t *)p)->bssid));
1563                 break;
1564         default:
1565                 printf("(H) Unknown Ctrl Subtype");
1566                 break;
1567         }
1568 }
1569
1570 static int
1571 extract_header_length(u_int16_t fc)
1572 {
1573         int len;
1574
1575         switch (FC_TYPE(fc)) {
1576         case T_MGMT:
1577                 return MGMT_HDRLEN;
1578         case T_CTRL:
1579                 switch (FC_SUBTYPE(fc)) {
1580                 case CTRL_BAR:
1581                         return CTRL_BAR_HDRLEN;
1582                 case CTRL_PS_POLL:
1583                         return CTRL_PS_POLL_HDRLEN;
1584                 case CTRL_RTS:
1585                         return CTRL_RTS_HDRLEN;
1586                 case CTRL_CTS:
1587                         return CTRL_CTS_HDRLEN;
1588                 case CTRL_ACK:
1589                         return CTRL_ACK_HDRLEN;
1590                 case CTRL_CF_END:
1591                         return CTRL_END_HDRLEN;
1592                 case CTRL_END_ACK:
1593                         return CTRL_END_ACK_HDRLEN;
1594                 default:
1595                         return 0;
1596                 }
1597         case T_DATA:
1598                 len = (FC_TO_DS(fc) && FC_FROM_DS(fc)) ? 30 : 24;
1599                 if (DATA_FRAME_IS_QOS(FC_SUBTYPE(fc)))
1600                         len += 2;
1601                 return len;
1602         default:
1603                 printf("unknown IEEE802.11 frame type (%d)", FC_TYPE(fc));
1604                 return 0;
1605         }
1606 }
1607
1608 static int
1609 extract_mesh_header_length(const u_char *p)
1610 {
1611         return (p[0] &~ 3) ? 0 : 6*(1 + (p[0] & 3));
1612 }
1613
1614 /*
1615  * Print the 802.11 MAC header if eflag is set, and set "*srcp" and "*dstp"
1616  * to point to the source and destination MAC addresses in any case if
1617  * "srcp" and "dstp" aren't null.
1618  */
1619 static void
1620 ieee_802_11_hdr_print(u_int16_t fc, const u_char *p, u_int hdrlen,
1621     u_int meshdrlen, const u_int8_t **srcp, const u_int8_t **dstp)
1622 {
1623         if (vflag) {
1624                 if (FC_MORE_DATA(fc))
1625                         printf("More Data ");
1626                 if (FC_MORE_FLAG(fc))
1627                         printf("More Fragments ");
1628                 if (FC_POWER_MGMT(fc))
1629                         printf("Pwr Mgmt ");
1630                 if (FC_RETRY(fc))
1631                         printf("Retry ");
1632                 if (FC_ORDER(fc))
1633                         printf("Strictly Ordered ");
1634                 if (FC_WEP(fc))
1635                         printf("WEP Encrypted ");
1636                 if (FC_TYPE(fc) != T_CTRL || FC_SUBTYPE(fc) != CTRL_PS_POLL)
1637                         printf("%dus ",
1638                             EXTRACT_LE_16BITS(
1639                                 &((const struct mgmt_header_t *)p)->duration));
1640         }
1641         if (meshdrlen != 0) {
1642                 const struct meshcntl_t *mc =
1643                     (const struct meshcntl_t *)&p[hdrlen - meshdrlen];
1644                 int ae = mc->flags & 3;
1645
1646                 printf("MeshData (AE %d TTL %u seq %u", ae, mc->ttl,
1647                     EXTRACT_LE_32BITS(mc->seq));
1648                 if (ae > 0)
1649                         printf(" A4:%s", etheraddr_string(mc->addr4));
1650                 if (ae > 1)
1651                         printf(" A5:%s", etheraddr_string(mc->addr5));
1652                 if (ae > 2)
1653                         printf(" A6:%s", etheraddr_string(mc->addr6));
1654                 printf(") ");
1655         }
1656
1657         switch (FC_TYPE(fc)) {
1658         case T_MGMT:
1659                 mgmt_header_print(p, srcp, dstp);
1660                 break;
1661         case T_CTRL:
1662                 ctrl_header_print(fc, p, srcp, dstp);
1663                 break;
1664         case T_DATA:
1665                 data_header_print(fc, p, srcp, dstp);
1666                 break;
1667         default:
1668                 printf("(header) unknown IEEE802.11 frame type (%d)",
1669                     FC_TYPE(fc));
1670                 *srcp = NULL;
1671                 *dstp = NULL;
1672                 break;
1673         }
1674 }
1675
1676 #ifndef roundup2
1677 #define roundup2(x, y)  (((x)+((y)-1))&(~((y)-1))) /* if y is powers of two */
1678 #endif
1679
1680 static u_int
1681 ieee802_11_print(const u_char *p, u_int length, u_int orig_caplen, int pad,
1682     u_int fcslen)
1683 {
1684         u_int16_t fc;
1685         u_int caplen, hdrlen, meshdrlen;
1686         const u_int8_t *src, *dst;
1687         u_short extracted_ethertype;
1688
1689         caplen = orig_caplen;
1690         /* Remove FCS, if present */
1691         if (length < fcslen) {
1692                 printf("[|802.11]");
1693                 return caplen;
1694         }
1695         length -= fcslen;
1696         if (caplen > length) {
1697                 /* Amount of FCS in actual packet data, if any */
1698                 fcslen = caplen - length;
1699                 caplen -= fcslen;
1700                 snapend -= fcslen;
1701         }
1702
1703         if (caplen < IEEE802_11_FC_LEN) {
1704                 printf("[|802.11]");
1705                 return orig_caplen;
1706         }
1707
1708         fc = EXTRACT_LE_16BITS(p);
1709         hdrlen = extract_header_length(fc);
1710         if (pad)
1711                 hdrlen = roundup2(hdrlen, 4);
1712         if (Hflag && FC_TYPE(fc) == T_DATA &&
1713             DATA_FRAME_IS_QOS(FC_SUBTYPE(fc))) {
1714                 meshdrlen = extract_mesh_header_length(p+hdrlen);
1715                 hdrlen += meshdrlen;
1716         } else
1717                 meshdrlen = 0;
1718
1719
1720         if (caplen < hdrlen) {
1721                 printf("[|802.11]");
1722                 return hdrlen;
1723         }
1724
1725         ieee_802_11_hdr_print(fc, p, hdrlen, meshdrlen, &src, &dst);
1726
1727         /*
1728          * Go past the 802.11 header.
1729          */
1730         length -= hdrlen;
1731         caplen -= hdrlen;
1732         p += hdrlen;
1733
1734         switch (FC_TYPE(fc)) {
1735         case T_MGMT:
1736                 if (!mgmt_body_print(fc,
1737                     (const struct mgmt_header_t *)(p - hdrlen), p, length)) {
1738                         printf("[|802.11]");
1739                         return hdrlen;
1740                 }
1741                 break;
1742         case T_CTRL:
1743                 if (!ctrl_body_print(fc, p - hdrlen)) {
1744                         printf("[|802.11]");
1745                         return hdrlen;
1746                 }
1747                 break;
1748         case T_DATA:
1749                 if (DATA_FRAME_IS_NULL(FC_SUBTYPE(fc)))
1750                         return hdrlen;  /* no-data frame */
1751                 /* There may be a problem w/ AP not having this bit set */
1752                 if (FC_WEP(fc)) {
1753                         if (!wep_print(p)) {
1754                                 printf("[|802.11]");
1755                                 return hdrlen;
1756                         }
1757                 } else if (llc_print(p, length, caplen, dst, src,
1758                     &extracted_ethertype) == 0) {
1759                         /*
1760                          * Some kinds of LLC packet we cannot
1761                          * handle intelligently
1762                          */
1763                         if (!eflag)
1764                                 ieee_802_11_hdr_print(fc, p - hdrlen, hdrlen,
1765                                     meshdrlen, NULL, NULL);
1766                         if (extracted_ethertype)
1767                                 printf("(LLC %s) ",
1768                                     etherproto_string(
1769                                         htons(extracted_ethertype)));
1770                         if (!suppress_default_print)
1771                                 default_print(p, caplen);
1772                 }
1773                 break;
1774         default:
1775                 printf("unknown 802.11 frame type (%d)", FC_TYPE(fc));
1776                 break;
1777         }
1778
1779         return hdrlen;
1780 }
1781
1782 /*
1783  * This is the top level routine of the printer.  'p' points
1784  * to the 802.11 header of the packet, 'h->ts' is the timestamp,
1785  * 'h->len' is the length of the packet off the wire, and 'h->caplen'
1786  * is the number of bytes actually captured.
1787  */
1788 u_int
1789 ieee802_11_if_print(const struct pcap_pkthdr *h, const u_char *p)
1790 {
1791         return ieee802_11_print(p, h->len, h->caplen, 0, 0);
1792 }
1793
1794 #define IEEE80211_CHAN_FHSS \
1795         (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_GFSK)
1796 #define IEEE80211_CHAN_A \
1797         (IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM)
1798 #define IEEE80211_CHAN_B \
1799         (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_CCK)
1800 #define IEEE80211_CHAN_PUREG \
1801         (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_OFDM)
1802 #define IEEE80211_CHAN_G \
1803         (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_DYN)
1804
1805 #define IS_CHAN_FHSS(flags) \
1806         ((flags & IEEE80211_CHAN_FHSS) == IEEE80211_CHAN_FHSS)
1807 #define IS_CHAN_A(flags) \
1808         ((flags & IEEE80211_CHAN_A) == IEEE80211_CHAN_A)
1809 #define IS_CHAN_B(flags) \
1810         ((flags & IEEE80211_CHAN_B) == IEEE80211_CHAN_B)
1811 #define IS_CHAN_PUREG(flags) \
1812         ((flags & IEEE80211_CHAN_PUREG) == IEEE80211_CHAN_PUREG)
1813 #define IS_CHAN_G(flags) \
1814         ((flags & IEEE80211_CHAN_G) == IEEE80211_CHAN_G)
1815 #define IS_CHAN_ANYG(flags) \
1816         (IS_CHAN_PUREG(flags) || IS_CHAN_G(flags))
1817
1818 static void
1819 print_chaninfo(int freq, int flags)
1820 {
1821         printf("%u MHz", freq);
1822         if (IS_CHAN_FHSS(flags))
1823                 printf(" FHSS");
1824         if (IS_CHAN_A(flags)) {
1825                 if (flags & IEEE80211_CHAN_HALF)
1826                         printf(" 11a/10Mhz");
1827                 else if (flags & IEEE80211_CHAN_QUARTER)
1828                         printf(" 11a/5Mhz");
1829                 else
1830                         printf(" 11a");
1831         }
1832         if (IS_CHAN_ANYG(flags)) {
1833                 if (flags & IEEE80211_CHAN_HALF)
1834                         printf(" 11g/10Mhz");
1835                 else if (flags & IEEE80211_CHAN_QUARTER)
1836                         printf(" 11g/5Mhz");
1837                 else
1838                         printf(" 11g");
1839         } else if (IS_CHAN_B(flags))
1840                 printf(" 11b");
1841         if (flags & IEEE80211_CHAN_TURBO)
1842                 printf(" Turbo");
1843         if (flags & IEEE80211_CHAN_HT20)
1844                 printf(" ht/20");
1845         else if (flags & IEEE80211_CHAN_HT40D)
1846                 printf(" ht/40-");
1847         else if (flags & IEEE80211_CHAN_HT40U)
1848                 printf(" ht/40+");
1849         printf(" ");
1850 }
1851
1852 static int
1853 print_radiotap_field(struct cpack_state *s, u_int32_t bit, u_int8_t *flags,
1854                                                 struct radiotap_state *state, u_int32_t presentflags)
1855 {
1856         union {
1857                 int8_t          i8;
1858                 u_int8_t        u8;
1859                 int16_t         i16;
1860                 u_int16_t       u16;
1861                 u_int32_t       u32;
1862                 u_int64_t       u64;
1863         } u, u2, u3, u4;
1864         int rc;
1865
1866         switch (bit) {
1867         case IEEE80211_RADIOTAP_FLAGS:
1868                 rc = cpack_uint8(s, &u.u8);
1869                 if (rc != 0)
1870                         break;
1871                 *flags = u.u8;
1872                 break;
1873         case IEEE80211_RADIOTAP_RATE:
1874                 rc = cpack_uint8(s, &u.u8);
1875                 if (rc != 0)
1876                         break;
1877
1878                 /* Save state rate */
1879                 state->rate = u.u8;
1880                 break;
1881         case IEEE80211_RADIOTAP_DB_ANTSIGNAL:
1882         case IEEE80211_RADIOTAP_DB_ANTNOISE:
1883         case IEEE80211_RADIOTAP_ANTENNA:
1884                 rc = cpack_uint8(s, &u.u8);
1885                 break;
1886         case IEEE80211_RADIOTAP_DBM_ANTSIGNAL:
1887         case IEEE80211_RADIOTAP_DBM_ANTNOISE:
1888                 rc = cpack_int8(s, &u.i8);
1889                 break;
1890         case IEEE80211_RADIOTAP_CHANNEL:
1891                 rc = cpack_uint16(s, &u.u16);
1892                 if (rc != 0)
1893                         break;
1894                 rc = cpack_uint16(s, &u2.u16);
1895                 break;
1896         case IEEE80211_RADIOTAP_FHSS:
1897         case IEEE80211_RADIOTAP_LOCK_QUALITY:
1898         case IEEE80211_RADIOTAP_TX_ATTENUATION:
1899         case IEEE80211_RADIOTAP_RX_FLAGS:
1900                 rc = cpack_uint16(s, &u.u16);
1901                 break;
1902         case IEEE80211_RADIOTAP_DB_TX_ATTENUATION:
1903                 rc = cpack_uint8(s, &u.u8);
1904                 break;
1905         case IEEE80211_RADIOTAP_DBM_TX_POWER:
1906                 rc = cpack_int8(s, &u.i8);
1907                 break;
1908         case IEEE80211_RADIOTAP_TSFT:
1909                 rc = cpack_uint64(s, &u.u64);
1910                 break;
1911         case IEEE80211_RADIOTAP_XCHANNEL:
1912                 rc = cpack_uint32(s, &u.u32);
1913                 if (rc != 0)
1914                         break;
1915                 rc = cpack_uint16(s, &u2.u16);
1916                 if (rc != 0)
1917                         break;
1918                 rc = cpack_uint8(s, &u3.u8);
1919                 if (rc != 0)
1920                         break;
1921                 rc = cpack_uint8(s, &u4.u8);
1922                 break;
1923         case IEEE80211_RADIOTAP_MCS:
1924                 rc = cpack_uint8(s, &u.u8);
1925                 if (rc != 0)
1926                         break;
1927                 rc = cpack_uint8(s, &u2.u8);
1928                 if (rc != 0)
1929                         break;
1930                 rc = cpack_uint8(s, &u3.u8);
1931                 break;
1932         case IEEE80211_RADIOTAP_VENDOR_NAMESPACE: {
1933                 u_int8_t vns[3];
1934                 u_int16_t length;
1935                 u_int8_t subspace;
1936
1937                 if ((cpack_align_and_reserve(s, 2)) == NULL) {
1938                         rc = -1;
1939                         break;
1940                 }
1941
1942                 rc = cpack_uint8(s, &vns[0]);
1943                 if (rc != 0)
1944                         break;
1945                 rc = cpack_uint8(s, &vns[1]);
1946                 if (rc != 0)
1947                         break;
1948                 rc = cpack_uint8(s, &vns[2]);
1949                 if (rc != 0)
1950                         break;
1951                 rc = cpack_uint8(s, &subspace);
1952                 if (rc != 0)
1953                         break;
1954                 rc = cpack_uint16(s, &length);
1955                 if (rc != 0)
1956                         break;
1957
1958                 /* Skip up to length */
1959                 s->c_next += length;
1960                 break;
1961         }
1962         default:
1963                 /* this bit indicates a field whose
1964                  * size we do not know, so we cannot
1965                  * proceed.  Just print the bit number.
1966                  */
1967                 printf("[bit %u] ", bit);
1968                 return -1;
1969         }
1970
1971         if (rc != 0) {
1972                 printf("[|802.11]");
1973                 return rc;
1974         }
1975
1976         /* Preserve the state present flags */
1977         state->present = presentflags;
1978
1979         switch (bit) {
1980         case IEEE80211_RADIOTAP_CHANNEL:
1981                 /*
1982                  * If CHANNEL and XCHANNEL are both present, skip
1983                  * CHANNEL.
1984                  */
1985                 if (presentflags & (1 << IEEE80211_RADIOTAP_XCHANNEL))
1986                         break;
1987                 print_chaninfo(u.u16, u2.u16);
1988                 break;
1989         case IEEE80211_RADIOTAP_FHSS:
1990                 printf("fhset %d fhpat %d ", u.u16 & 0xff, (u.u16 >> 8) & 0xff);
1991                 break;
1992         case IEEE80211_RADIOTAP_RATE:
1993                 /*
1994                  * XXX On FreeBSD rate & 0x80 means we have an MCS. On
1995                  * Linux and AirPcap it does not.  (What about
1996                  * Mac OS X, NetBSD, OpenBSD, and DragonFly BSD?)
1997                  *
1998                  * This is an issue either for proprietary extensions
1999                  * to 11a or 11g, which do exist, or for 11n
2000                  * implementations that stuff a rate value into
2001                  * this field, which also appear to exist.
2002                  *
2003                  * We currently handle that by assuming that
2004                  * if the 0x80 bit is set *and* the remaining
2005                  * bits have a value between 0 and 15 it's
2006                  * an MCS value, otherwise it's a rate.  If
2007                  * there are cases where systems that use
2008                  * "0x80 + MCS index" for MCS indices > 15,
2009                  * or stuff a rate value here between 64 and
2010                  * 71.5 Mb/s in here, we'll need a preference
2011                  * setting.  Such rates do exist, e.g. 11n
2012                  * MCS 7 at 20 MHz with a long guard interval.
2013                  */
2014                 if (u.u8 >= 0x80 && u.u8 <= 0x8f) {
2015                         /*
2016                          * XXX - we don't know the channel width
2017                          * or guard interval length, so we can't
2018                          * convert this to a data rate.
2019                          *
2020                          * If you want us to show a data rate,
2021                          * use the MCS field, not the Rate field;
2022                          * the MCS field includes not only the
2023                          * MCS index, it also includes bandwidth
2024                          * and guard interval information.
2025                          *
2026                          * XXX - can we get the channel width
2027                          * from XChannel and the guard interval
2028                          * information from Flags, at least on
2029                          * FreeBSD?
2030                          */
2031                         printf("MCS %u ", u.u8 & 0x7f);
2032                 } else
2033                         printf("%2.1f Mb/s ", .5*u.u8);
2034                 break;
2035         case IEEE80211_RADIOTAP_DBM_ANTSIGNAL:
2036                 printf("%ddB signal ", u.i8);
2037                 break;
2038         case IEEE80211_RADIOTAP_DBM_ANTNOISE:
2039                 printf("%ddB noise ", u.i8);
2040                 break;
2041         case IEEE80211_RADIOTAP_DB_ANTSIGNAL:
2042                 printf("%ddB signal ", u.u8);
2043                 break;
2044         case IEEE80211_RADIOTAP_DB_ANTNOISE:
2045                 printf("%ddB noise ", u.u8);
2046                 break;
2047         case IEEE80211_RADIOTAP_LOCK_QUALITY:
2048                 printf("%u sq ", u.u16);
2049                 break;
2050         case IEEE80211_RADIOTAP_TX_ATTENUATION:
2051                 printf("%d tx power ", -(int)u.u16);
2052                 break;
2053         case IEEE80211_RADIOTAP_DB_TX_ATTENUATION:
2054                 printf("%ddB tx power ", -(int)u.u8);
2055                 break;
2056         case IEEE80211_RADIOTAP_DBM_TX_POWER:
2057                 printf("%ddBm tx power ", u.i8);
2058                 break;
2059         case IEEE80211_RADIOTAP_FLAGS:
2060                 if (u.u8 & IEEE80211_RADIOTAP_F_CFP)
2061                         printf("cfp ");
2062                 if (u.u8 & IEEE80211_RADIOTAP_F_SHORTPRE)
2063                         printf("short preamble ");
2064                 if (u.u8 & IEEE80211_RADIOTAP_F_WEP)
2065                         printf("wep ");
2066                 if (u.u8 & IEEE80211_RADIOTAP_F_FRAG)
2067                         printf("fragmented ");
2068                 if (u.u8 & IEEE80211_RADIOTAP_F_BADFCS)
2069                         printf("bad-fcs ");
2070                 break;
2071         case IEEE80211_RADIOTAP_ANTENNA:
2072                 printf("antenna %d ", u.u8);
2073                 break;
2074         case IEEE80211_RADIOTAP_TSFT:
2075                 printf("%" PRIu64 "us tsft ", u.u64);
2076                 break;
2077         case IEEE80211_RADIOTAP_RX_FLAGS:
2078                 /* Do nothing for now */
2079                 break;
2080         case IEEE80211_RADIOTAP_XCHANNEL:
2081                 print_chaninfo(u2.u16, u.u32);
2082                 break;
2083         case IEEE80211_RADIOTAP_MCS: {
2084                 static const char *bandwidth[4] = {
2085                         "20 MHz",
2086                         "40 MHz",
2087                         "20 MHz (L)",
2088                         "20 MHz (U)"
2089                 };
2090                 float htrate;
2091
2092                 if (u.u8 & IEEE80211_RADIOTAP_MCS_MCS_INDEX_KNOWN) {
2093                         /*
2094                          * We know the MCS index.
2095                          */
2096                         if (u3.u8 <= MAX_MCS_INDEX) {
2097                                 /*
2098                                  * And it's in-range.
2099                                  */
2100                                 if (u.u8 & (IEEE80211_RADIOTAP_MCS_BANDWIDTH_KNOWN|IEEE80211_RADIOTAP_MCS_GUARD_INTERVAL_KNOWN)) {
2101                                         /*
2102                                          * And we know both the bandwidth and
2103                                          * the guard interval, so we can look
2104                                          * up the rate.
2105                                          */
2106                                         htrate = 
2107                                                 ieee80211_float_htrates \
2108                                                         [u3.u8] \
2109                                                         [((u2.u8 & IEEE80211_RADIOTAP_MCS_BANDWIDTH_MASK) == IEEE80211_RADIOTAP_MCS_BANDWIDTH_40 ? 1 : 0)] \
2110                                                         [((u2.u8 & IEEE80211_RADIOTAP_MCS_SHORT_GI) ? 1 : 0)];
2111                                 } else {
2112                                         /*
2113                                          * We don't know both the bandwidth
2114                                          * and the guard interval, so we can
2115                                          * only report the MCS index.
2116                                          */
2117                                         htrate = 0.0;
2118                                 }
2119                         } else {
2120                                 /*
2121                                  * The MCS value is out of range.
2122                                  */
2123                                 htrate = 0.0;
2124                         }
2125                         if (htrate != 0.0) {
2126                                 /*
2127                                  * We have the rate.
2128                                  * Print it.
2129                                  */
2130                                 printf("%.1f Mb/s MCS %u ", htrate, u3.u8);
2131                         } else {
2132                                 /*
2133                                  * We at least have the MCS index.
2134                                  * Print it.
2135                                  */
2136                                 printf("MCS %u ", u3.u8);
2137                         }
2138                 }
2139                 if (u.u8 & IEEE80211_RADIOTAP_MCS_BANDWIDTH_KNOWN) {
2140                         printf("%s ",
2141                                 bandwidth[u2.u8 & IEEE80211_RADIOTAP_MCS_BANDWIDTH_MASK]);
2142                 }
2143                 if (u.u8 & IEEE80211_RADIOTAP_MCS_GUARD_INTERVAL_KNOWN) {
2144                         printf("%s GI ",
2145                                 (u2.u8 & IEEE80211_RADIOTAP_MCS_SHORT_GI) ?
2146                                 "short" : "lon");
2147                 }
2148                 if (u.u8 & IEEE80211_RADIOTAP_MCS_HT_FORMAT_KNOWN) {
2149                         printf("%s ",
2150                                 (u2.u8 & IEEE80211_RADIOTAP_MCS_HT_GREENFIELD) ?
2151                                 "greenfield" : "mixed");
2152                 }
2153                 if (u.u8 & IEEE80211_RADIOTAP_MCS_FEC_TYPE_KNOWN) {
2154                         printf("%s FEC ",
2155                                 (u2.u8 & IEEE80211_RADIOTAP_MCS_FEC_LDPC) ?
2156                                 "LDPC" : "BCC");
2157                 }
2158                 break;
2159                 }
2160         }
2161         return 0;
2162 }
2163
2164 static u_int
2165 ieee802_11_radio_print(const u_char *p, u_int length, u_int caplen)
2166 {
2167 #define BITNO_32(x) (((x) >> 16) ? 16 + BITNO_16((x) >> 16) : BITNO_16((x)))
2168 #define BITNO_16(x) (((x) >> 8) ? 8 + BITNO_8((x) >> 8) : BITNO_8((x)))
2169 #define BITNO_8(x) (((x) >> 4) ? 4 + BITNO_4((x) >> 4) : BITNO_4((x)))
2170 #define BITNO_4(x) (((x) >> 2) ? 2 + BITNO_2((x) >> 2) : BITNO_2((x)))
2171 #define BITNO_2(x) (((x) & 2) ? 1 : 0)
2172 #define BIT(n)  (1U << n)
2173 #define IS_EXTENDED(__p)        \
2174             (EXTRACT_LE_32BITS(__p) & BIT(IEEE80211_RADIOTAP_EXT)) != 0
2175
2176         struct cpack_state cpacker;
2177         struct ieee80211_radiotap_header *hdr;
2178         u_int32_t present, next_present;
2179         u_int32_t presentflags = 0;
2180         u_int32_t *presentp, *last_presentp;
2181         enum ieee80211_radiotap_type bit;
2182         int bit0;
2183         const u_char *iter;
2184         u_int len;
2185         u_int8_t flags;
2186         int pad;
2187         u_int fcslen;
2188         struct radiotap_state state;
2189
2190         if (caplen < sizeof(*hdr)) {
2191                 printf("[|802.11]");
2192                 return caplen;
2193         }
2194
2195         hdr = (struct ieee80211_radiotap_header *)p;
2196
2197         len = EXTRACT_LE_16BITS(&hdr->it_len);
2198
2199         if (caplen < len) {
2200                 printf("[|802.11]");
2201                 return caplen;
2202         }
2203         for (last_presentp = &hdr->it_present;
2204              IS_EXTENDED(last_presentp) &&
2205              (u_char*)(last_presentp + 1) <= p + len;
2206              last_presentp++);
2207
2208         /* are there more bitmap extensions than bytes in header? */
2209         if (IS_EXTENDED(last_presentp)) {
2210                 printf("[|802.11]");
2211                 return caplen;
2212         }
2213
2214         iter = (u_char*)(last_presentp + 1);
2215
2216         if (cpack_init(&cpacker, (u_int8_t*)iter, len - (iter - p)) != 0) {
2217                 /* XXX */
2218                 printf("[|802.11]");
2219                 return caplen;
2220         }
2221
2222         /* Assume no flags */
2223         flags = 0;
2224         /* Assume no Atheros padding between 802.11 header and body */
2225         pad = 0;
2226         /* Assume no FCS at end of frame */
2227         fcslen = 0;
2228         for (bit0 = 0, presentp = &hdr->it_present; presentp <= last_presentp;
2229              presentp++, bit0 += 32) {
2230                 presentflags = EXTRACT_LE_32BITS(presentp);
2231
2232                 /* Clear state. */
2233                 memset(&state, 0, sizeof(state));
2234
2235                 for (present = EXTRACT_LE_32BITS(presentp); present;
2236                      present = next_present) {
2237                         /* clear the least significant bit that is set */
2238                         next_present = present & (present - 1);
2239
2240                         /* extract the least significant bit that is set */
2241                         bit = (enum ieee80211_radiotap_type)
2242                             (bit0 + BITNO_32(present ^ next_present));
2243
2244                         if (print_radiotap_field(&cpacker, bit, &flags, &state, presentflags) != 0)
2245                                 goto out;
2246                 }
2247         }
2248
2249 out:
2250         if (flags & IEEE80211_RADIOTAP_F_DATAPAD)
2251                 pad = 1;        /* Atheros padding */
2252         if (flags & IEEE80211_RADIOTAP_F_FCS)
2253                 fcslen = 4;     /* FCS at end of packet */
2254         return len + ieee802_11_print(p + len, length - len, caplen - len, pad,
2255             fcslen);
2256 #undef BITNO_32
2257 #undef BITNO_16
2258 #undef BITNO_8
2259 #undef BITNO_4
2260 #undef BITNO_2
2261 #undef BIT
2262 }
2263
2264 static u_int
2265 ieee802_11_avs_radio_print(const u_char *p, u_int length, u_int caplen)
2266 {
2267         u_int32_t caphdr_len;
2268
2269         if (caplen < 8) {
2270                 printf("[|802.11]");
2271                 return caplen;
2272         }
2273
2274         caphdr_len = EXTRACT_32BITS(p + 4);
2275         if (caphdr_len < 8) {
2276                 /*
2277                  * Yow!  The capture header length is claimed not
2278                  * to be large enough to include even the version
2279                  * cookie or capture header length!
2280                  */
2281                 printf("[|802.11]");
2282                 return caplen;
2283         }
2284
2285         if (caplen < caphdr_len) {
2286                 printf("[|802.11]");
2287                 return caplen;
2288         }
2289
2290         return caphdr_len + ieee802_11_print(p + caphdr_len,
2291             length - caphdr_len, caplen - caphdr_len, 0, 0);
2292 }
2293
2294 #define PRISM_HDR_LEN           144
2295
2296 #define WLANCAP_MAGIC_COOKIE_BASE 0x80211000
2297 #define WLANCAP_MAGIC_COOKIE_V1 0x80211001
2298 #define WLANCAP_MAGIC_COOKIE_V2 0x80211002
2299
2300 /*
2301  * For DLT_PRISM_HEADER; like DLT_IEEE802_11, but with an extra header,
2302  * containing information such as radio information, which we
2303  * currently ignore.
2304  *
2305  * If, however, the packet begins with WLANCAP_MAGIC_COOKIE_V1 or
2306  * WLANCAP_MAGIC_COOKIE_V2, it's really DLT_IEEE802_11_RADIO_AVS
2307  * (currently, on Linux, there's no ARPHRD_ type for
2308  * DLT_IEEE802_11_RADIO_AVS, as there is a ARPHRD_IEEE80211_PRISM
2309  * for DLT_PRISM_HEADER, so ARPHRD_IEEE80211_PRISM is used for
2310  * the AVS header, and the first 4 bytes of the header are used to
2311  * indicate whether it's a Prism header or an AVS header).
2312  */
2313 u_int
2314 prism_if_print(const struct pcap_pkthdr *h, const u_char *p)
2315 {
2316         u_int caplen = h->caplen;
2317         u_int length = h->len;
2318         u_int32_t msgcode;
2319
2320         if (caplen < 4) {
2321                 printf("[|802.11]");
2322                 return caplen;
2323         }
2324
2325         msgcode = EXTRACT_32BITS(p);
2326         if (msgcode == WLANCAP_MAGIC_COOKIE_V1 ||
2327             msgcode == WLANCAP_MAGIC_COOKIE_V2)
2328                 return ieee802_11_avs_radio_print(p, length, caplen);
2329
2330         if (caplen < PRISM_HDR_LEN) {
2331                 printf("[|802.11]");
2332                 return caplen;
2333         }
2334
2335         return PRISM_HDR_LEN + ieee802_11_print(p + PRISM_HDR_LEN,
2336             length - PRISM_HDR_LEN, caplen - PRISM_HDR_LEN, 0, 0);
2337 }
2338
2339 /*
2340  * For DLT_IEEE802_11_RADIO; like DLT_IEEE802_11, but with an extra
2341  * header, containing information such as radio information.
2342  */
2343 u_int
2344 ieee802_11_radio_if_print(const struct pcap_pkthdr *h, const u_char *p)
2345 {
2346         return ieee802_11_radio_print(p, h->len, h->caplen);
2347 }
2348
2349 /*
2350  * For DLT_IEEE802_11_RADIO_AVS; like DLT_IEEE802_11, but with an
2351  * extra header, containing information such as radio information,
2352  * which we currently ignore.
2353  */
2354 u_int
2355 ieee802_11_radio_avs_if_print(const struct pcap_pkthdr *h, const u_char *p)
2356 {
2357         return ieee802_11_avs_radio_print(p, h->len, h->caplen);
2358 }