]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/tcpdump/print-802_11.c
Merge commit 'acb089b983171667467adc66f56a723b609ed22e' into kbsd/vis
[FreeBSD/FreeBSD.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 /* \summary: IEEE 802.11 printer */
24
25 #ifdef HAVE_CONFIG_H
26 #include <config.h>
27 #endif
28
29 #include "netdissect-stdinc.h"
30
31 #include <string.h>
32
33 #include "netdissect.h"
34 #include "addrtoname.h"
35
36 #include "extract.h"
37
38 #include "cpack.h"
39
40
41 /* Lengths of 802.11 header components. */
42 #define IEEE802_11_FC_LEN               2
43 #define IEEE802_11_DUR_LEN              2
44 #define IEEE802_11_DA_LEN               6
45 #define IEEE802_11_SA_LEN               6
46 #define IEEE802_11_BSSID_LEN            6
47 #define IEEE802_11_RA_LEN               6
48 #define IEEE802_11_TA_LEN               6
49 #define IEEE802_11_ADDR1_LEN            6
50 #define IEEE802_11_SEQ_LEN              2
51 #define IEEE802_11_CTL_LEN              2
52 #define IEEE802_11_CARRIED_FC_LEN       2
53 #define IEEE802_11_HT_CONTROL_LEN       4
54 #define IEEE802_11_IV_LEN               3
55 #define IEEE802_11_KID_LEN              1
56
57 /* Frame check sequence length. */
58 #define IEEE802_11_FCS_LEN              4
59
60 /* Lengths of beacon components. */
61 #define IEEE802_11_TSTAMP_LEN           8
62 #define IEEE802_11_BCNINT_LEN           2
63 #define IEEE802_11_CAPINFO_LEN          2
64 #define IEEE802_11_LISTENINT_LEN        2
65
66 #define IEEE802_11_AID_LEN              2
67 #define IEEE802_11_STATUS_LEN           2
68 #define IEEE802_11_REASON_LEN           2
69
70 /* Length of previous AP in reassocation frame */
71 #define IEEE802_11_AP_LEN               6
72
73 #define T_MGMT 0x0  /* management */
74 #define T_CTRL 0x1  /* control */
75 #define T_DATA 0x2 /* data */
76 #define T_RESV 0x3  /* reserved */
77
78 #define ST_ASSOC_REQUEST        0x0
79 #define ST_ASSOC_RESPONSE       0x1
80 #define ST_REASSOC_REQUEST      0x2
81 #define ST_REASSOC_RESPONSE     0x3
82 #define ST_PROBE_REQUEST        0x4
83 #define ST_PROBE_RESPONSE       0x5
84 /* RESERVED                     0x6  */
85 /* RESERVED                     0x7  */
86 #define ST_BEACON               0x8
87 #define ST_ATIM                 0x9
88 #define ST_DISASSOC             0xA
89 #define ST_AUTH                 0xB
90 #define ST_DEAUTH               0xC
91 #define ST_ACTION               0xD
92 /* RESERVED                     0xE  */
93 /* RESERVED                     0xF  */
94
95 static const struct tok st_str[] = {
96         { ST_ASSOC_REQUEST,    "Assoc Request"    },
97         { ST_ASSOC_RESPONSE,   "Assoc Response"   },
98         { ST_REASSOC_REQUEST,  "ReAssoc Request"  },
99         { ST_REASSOC_RESPONSE, "ReAssoc Response" },
100         { ST_PROBE_REQUEST,    "Probe Request"    },
101         { ST_PROBE_RESPONSE,   "Probe Response"   },
102         { ST_BEACON,           "Beacon"           },
103         { ST_ATIM,             "ATIM"             },
104         { ST_DISASSOC,         "Disassociation"   },
105         { ST_AUTH,             "Authentication"   },
106         { ST_DEAUTH,           "DeAuthentication" },
107         { ST_ACTION,           "Action"           },
108         { 0, NULL }
109 };
110
111 #define CTRL_CONTROL_WRAPPER    0x7
112 #define CTRL_BAR        0x8
113 #define CTRL_BA         0x9
114 #define CTRL_PS_POLL    0xA
115 #define CTRL_RTS        0xB
116 #define CTRL_CTS        0xC
117 #define CTRL_ACK        0xD
118 #define CTRL_CF_END     0xE
119 #define CTRL_END_ACK    0xF
120
121 static const struct tok ctrl_str[] = {
122         { CTRL_CONTROL_WRAPPER, "Control Wrapper" },
123         { CTRL_BAR,             "BAR"             },
124         { CTRL_BA,              "BA"              },
125         { CTRL_PS_POLL,         "Power Save-Poll" },
126         { CTRL_RTS,             "Request-To-Send" },
127         { CTRL_CTS,             "Clear-To-Send"   },
128         { CTRL_ACK,             "Acknowledgment"  },
129         { CTRL_CF_END,          "CF-End"          },
130         { CTRL_END_ACK,         "CF-End+CF-Ack"   },
131         { 0, NULL }
132 };
133
134 #define DATA_DATA                       0x0
135 #define DATA_DATA_CF_ACK                0x1
136 #define DATA_DATA_CF_POLL               0x2
137 #define DATA_DATA_CF_ACK_POLL           0x3
138 #define DATA_NODATA                     0x4
139 #define DATA_NODATA_CF_ACK              0x5
140 #define DATA_NODATA_CF_POLL             0x6
141 #define DATA_NODATA_CF_ACK_POLL         0x7
142
143 #define DATA_QOS_DATA                   0x8
144 #define DATA_QOS_DATA_CF_ACK            0x9
145 #define DATA_QOS_DATA_CF_POLL           0xA
146 #define DATA_QOS_DATA_CF_ACK_POLL       0xB
147 #define DATA_QOS_NODATA                 0xC
148 #define DATA_QOS_CF_POLL_NODATA         0xE
149 #define DATA_QOS_CF_ACK_POLL_NODATA     0xF
150
151 /*
152  * The subtype field of a data frame is, in effect, composed of 4 flag
153  * bits - CF-Ack, CF-Poll, Null (means the frame doesn't actually have
154  * any data), and QoS.
155  */
156 #define DATA_FRAME_IS_CF_ACK(x)         ((x) & 0x01)
157 #define DATA_FRAME_IS_CF_POLL(x)        ((x) & 0x02)
158 #define DATA_FRAME_IS_NULL(x)           ((x) & 0x04)
159 #define DATA_FRAME_IS_QOS(x)            ((x) & 0x08)
160
161 /*
162  * Bits in the frame control field.
163  */
164 #define FC_VERSION(fc)          ((fc) & 0x3)
165 #define FC_TYPE(fc)             (((fc) >> 2) & 0x3)
166 #define FC_SUBTYPE(fc)          (((fc) >> 4) & 0xF)
167 #define FC_TO_DS(fc)            ((fc) & 0x0100)
168 #define FC_FROM_DS(fc)          ((fc) & 0x0200)
169 #define FC_MORE_FLAG(fc)        ((fc) & 0x0400)
170 #define FC_RETRY(fc)            ((fc) & 0x0800)
171 #define FC_POWER_MGMT(fc)       ((fc) & 0x1000)
172 #define FC_MORE_DATA(fc)        ((fc) & 0x2000)
173 #define FC_PROTECTED(fc)        ((fc) & 0x4000)
174 #define FC_ORDER(fc)            ((fc) & 0x8000)
175
176 struct mgmt_header_t {
177         nd_uint16_t     fc;
178         nd_uint16_t     duration;
179         nd_mac_addr     da;
180         nd_mac_addr     sa;
181         nd_mac_addr     bssid;
182         nd_uint16_t     seq_ctrl;
183 };
184
185 #define MGMT_HDRLEN     (IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+\
186                          IEEE802_11_DA_LEN+IEEE802_11_SA_LEN+\
187                          IEEE802_11_BSSID_LEN+IEEE802_11_SEQ_LEN)
188
189 #define CAPABILITY_ESS(cap)     ((cap) & 0x0001)
190 #define CAPABILITY_IBSS(cap)    ((cap) & 0x0002)
191 #define CAPABILITY_CFP(cap)     ((cap) & 0x0004)
192 #define CAPABILITY_CFP_REQ(cap) ((cap) & 0x0008)
193 #define CAPABILITY_PRIVACY(cap) ((cap) & 0x0010)
194
195 struct ssid_t {
196         uint8_t         element_id;
197         uint8_t         length;
198         u_char          ssid[33];  /* 32 + 1 for null */
199 };
200
201 struct rates_t {
202         uint8_t         element_id;
203         uint8_t         length;
204         uint8_t         rate[16];
205 };
206
207 struct challenge_t {
208         uint8_t         element_id;
209         uint8_t         length;
210         uint8_t         text[254]; /* 1-253 + 1 for null */
211 };
212
213 struct fh_t {
214         uint8_t         element_id;
215         uint8_t         length;
216         uint16_t        dwell_time;
217         uint8_t         hop_set;
218         uint8_t hop_pattern;
219         uint8_t         hop_index;
220 };
221
222 struct ds_t {
223         uint8_t         element_id;
224         uint8_t         length;
225         uint8_t         channel;
226 };
227
228 struct cf_t {
229         uint8_t         element_id;
230         uint8_t         length;
231         uint8_t         count;
232         uint8_t         period;
233         uint16_t        max_duration;
234         uint16_t        dur_remaining;
235 };
236
237 struct tim_t {
238         uint8_t         element_id;
239         uint8_t         length;
240         uint8_t         count;
241         uint8_t         period;
242         uint8_t         bitmap_control;
243         uint8_t         bitmap[251];
244 };
245
246 #define E_SSID          0
247 #define E_RATES 1
248 #define E_FH            2
249 #define E_DS            3
250 #define E_CF            4
251 #define E_TIM           5
252 #define E_IBSS          6
253 /* reserved             7 */
254 /* reserved             8 */
255 /* reserved             9 */
256 /* reserved             10 */
257 /* reserved             11 */
258 /* reserved             12 */
259 /* reserved             13 */
260 /* reserved             14 */
261 /* reserved             15 */
262 /* reserved             16 */
263
264 #define E_CHALLENGE     16
265 /* reserved             17 */
266 /* reserved             18 */
267 /* reserved             19 */
268 /* reserved             16 */
269 /* reserved             16 */
270
271
272 struct mgmt_body_t {
273         uint8_t         timestamp[IEEE802_11_TSTAMP_LEN];
274         uint16_t        beacon_interval;
275         uint16_t        listen_interval;
276         uint16_t        status_code;
277         uint16_t        aid;
278         u_char          ap[IEEE802_11_AP_LEN];
279         uint16_t        reason_code;
280         uint16_t        auth_alg;
281         uint16_t        auth_trans_seq_num;
282         int             challenge_present;
283         struct challenge_t  challenge;
284         uint16_t        capability_info;
285         int             ssid_present;
286         struct ssid_t   ssid;
287         int             rates_present;
288         struct rates_t  rates;
289         int             ds_present;
290         struct ds_t     ds;
291         int             cf_present;
292         struct cf_t     cf;
293         int             fh_present;
294         struct fh_t     fh;
295         int             tim_present;
296         struct tim_t    tim;
297 };
298
299 struct ctrl_control_wrapper_hdr_t {
300         nd_uint16_t     fc;
301         nd_uint16_t     duration;
302         nd_mac_addr     addr1;
303         nd_uint16_t     carried_fc[IEEE802_11_CARRIED_FC_LEN];
304         nd_uint16_t     ht_control[IEEE802_11_HT_CONTROL_LEN];
305 };
306
307 #define CTRL_CONTROL_WRAPPER_HDRLEN     (IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+\
308                                          IEEE802_11_ADDR1_LEN+\
309                                          IEEE802_11_CARRIED_FC_LEN+\
310                                          IEEE802_11_HT_CONTROL_LEN)
311
312 struct ctrl_rts_hdr_t {
313         nd_uint16_t     fc;
314         nd_uint16_t     duration;
315         nd_mac_addr     ra;
316         nd_mac_addr     ta;
317 };
318
319 #define CTRL_RTS_HDRLEN (IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+\
320                          IEEE802_11_RA_LEN+IEEE802_11_TA_LEN)
321
322 struct ctrl_cts_hdr_t {
323         nd_uint16_t     fc;
324         nd_uint16_t     duration;
325         nd_mac_addr     ra;
326 };
327
328 #define CTRL_CTS_HDRLEN (IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+IEEE802_11_RA_LEN)
329
330 struct ctrl_ack_hdr_t {
331         nd_uint16_t     fc;
332         nd_uint16_t     duration;
333         nd_mac_addr     ra;
334 };
335
336 #define CTRL_ACK_HDRLEN (IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+IEEE802_11_RA_LEN)
337
338 struct ctrl_ps_poll_hdr_t {
339         nd_uint16_t     fc;
340         nd_uint16_t     aid;
341         nd_mac_addr     bssid;
342         nd_mac_addr     ta;
343 };
344
345 #define CTRL_PS_POLL_HDRLEN     (IEEE802_11_FC_LEN+IEEE802_11_AID_LEN+\
346                                  IEEE802_11_BSSID_LEN+IEEE802_11_TA_LEN)
347
348 struct ctrl_end_hdr_t {
349         nd_uint16_t     fc;
350         nd_uint16_t     duration;
351         nd_mac_addr     ra;
352         nd_mac_addr     bssid;
353 };
354
355 #define CTRL_END_HDRLEN (IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+\
356                          IEEE802_11_RA_LEN+IEEE802_11_BSSID_LEN)
357
358 struct ctrl_end_ack_hdr_t {
359         nd_uint16_t     fc;
360         nd_uint16_t     duration;
361         nd_mac_addr     ra;
362         nd_mac_addr     bssid;
363 };
364
365 #define CTRL_END_ACK_HDRLEN     (IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+\
366                                  IEEE802_11_RA_LEN+IEEE802_11_BSSID_LEN)
367
368 struct ctrl_ba_hdr_t {
369         nd_uint16_t     fc;
370         nd_uint16_t     duration;
371         nd_mac_addr     ra;
372 };
373
374 #define CTRL_BA_HDRLEN  (IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+IEEE802_11_RA_LEN)
375
376 struct ctrl_bar_hdr_t {
377         nd_uint16_t     fc;
378         nd_uint16_t     dur;
379         nd_mac_addr     ra;
380         nd_mac_addr     ta;
381         nd_uint16_t     ctl;
382         nd_uint16_t     seq;
383 };
384
385 #define CTRL_BAR_HDRLEN         (IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+\
386                                  IEEE802_11_RA_LEN+IEEE802_11_TA_LEN+\
387                                  IEEE802_11_CTL_LEN+IEEE802_11_SEQ_LEN)
388
389 struct meshcntl_t {
390         nd_uint8_t      flags;
391         nd_uint8_t      ttl;
392         nd_uint32_t     seq;
393         nd_mac_addr     addr4;
394         nd_mac_addr     addr5;
395         nd_mac_addr     addr6;
396 };
397
398 #define IV_IV(iv)       ((iv) & 0xFFFFFF)
399 #define IV_PAD(iv)      (((iv) >> 24) & 0x3F)
400 #define IV_KEYID(iv)    (((iv) >> 30) & 0x03)
401
402 #define PRINT_SSID(p) \
403         if (p.ssid_present) { \
404                 ND_PRINT(" ("); \
405                 fn_print_str(ndo, p.ssid.ssid); \
406                 ND_PRINT(")"); \
407         }
408
409 #define PRINT_RATE(_sep, _r, _suf) \
410         ND_PRINT("%s%2.1f%s", _sep, (.5 * ((_r) & 0x7f)), _suf)
411 #define PRINT_RATES(p) \
412         if (p.rates_present) { \
413                 int z; \
414                 const char *sep = " ["; \
415                 for (z = 0; z < p.rates.length ; z++) { \
416                         PRINT_RATE(sep, p.rates.rate[z], \
417                                 (p.rates.rate[z] & 0x80 ? "*" : "")); \
418                         sep = " "; \
419                 } \
420                 if (p.rates.length != 0) \
421                         ND_PRINT(" Mbit]"); \
422         }
423
424 #define PRINT_DS_CHANNEL(p) \
425         if (p.ds_present) \
426                 ND_PRINT(" CH: %u", p.ds.channel); \
427         ND_PRINT("%s", \
428             CAPABILITY_PRIVACY(p.capability_info) ? ", PRIVACY" : "");
429
430 #define MAX_MCS_INDEX   76
431
432 /*
433  * Indices are:
434  *
435  *      the MCS index (0-76);
436  *
437  *      0 for 20 MHz, 1 for 40 MHz;
438  *
439  *      0 for a long guard interval, 1 for a short guard interval.
440  */
441 static const float ieee80211_float_htrates[MAX_MCS_INDEX+1][2][2] = {
442         /* MCS  0  */
443         {       /* 20 Mhz */ {    6.5f,         /* SGI */    7.2f, },
444                 /* 40 Mhz */ {   13.5f,         /* SGI */   15.0f, },
445         },
446
447         /* MCS  1  */
448         {       /* 20 Mhz */ {   13.0f,         /* SGI */   14.4f, },
449                 /* 40 Mhz */ {   27.0f,         /* SGI */   30.0f, },
450         },
451
452         /* MCS  2  */
453         {       /* 20 Mhz */ {   19.5f,         /* SGI */   21.7f, },
454                 /* 40 Mhz */ {   40.5f,         /* SGI */   45.0f, },
455         },
456
457         /* MCS  3  */
458         {       /* 20 Mhz */ {   26.0f,         /* SGI */   28.9f, },
459                 /* 40 Mhz */ {   54.0f,         /* SGI */   60.0f, },
460         },
461
462         /* MCS  4  */
463         {       /* 20 Mhz */ {   39.0f,         /* SGI */   43.3f, },
464                 /* 40 Mhz */ {   81.0f,         /* SGI */   90.0f, },
465         },
466
467         /* MCS  5  */
468         {       /* 20 Mhz */ {   52.0f,         /* SGI */   57.8f, },
469                 /* 40 Mhz */ {  108.0f,         /* SGI */  120.0f, },
470         },
471
472         /* MCS  6  */
473         {       /* 20 Mhz */ {   58.5f,         /* SGI */   65.0f, },
474                 /* 40 Mhz */ {  121.5f,         /* SGI */  135.0f, },
475         },
476
477         /* MCS  7  */
478         {       /* 20 Mhz */ {   65.0f,         /* SGI */   72.2f, },
479                 /* 40 Mhz */ {   135.0f,        /* SGI */  150.0f, },
480         },
481
482         /* MCS  8  */
483         {       /* 20 Mhz */ {   13.0f,         /* SGI */   14.4f, },
484                 /* 40 Mhz */ {   27.0f,         /* SGI */   30.0f, },
485         },
486
487         /* MCS  9  */
488         {       /* 20 Mhz */ {   26.0f,         /* SGI */   28.9f, },
489                 /* 40 Mhz */ {   54.0f,         /* SGI */   60.0f, },
490         },
491
492         /* MCS 10  */
493         {       /* 20 Mhz */ {   39.0f,         /* SGI */   43.3f, },
494                 /* 40 Mhz */ {   81.0f,         /* SGI */   90.0f, },
495         },
496
497         /* MCS 11  */
498         {       /* 20 Mhz */ {   52.0f,         /* SGI */   57.8f, },
499                 /* 40 Mhz */ {  108.0f,         /* SGI */  120.0f, },
500         },
501
502         /* MCS 12  */
503         {       /* 20 Mhz */ {   78.0f,         /* SGI */   86.7f, },
504                 /* 40 Mhz */ {  162.0f,         /* SGI */  180.0f, },
505         },
506
507         /* MCS 13  */
508         {       /* 20 Mhz */ {  104.0f,         /* SGI */  115.6f, },
509                 /* 40 Mhz */ {  216.0f,         /* SGI */  240.0f, },
510         },
511
512         /* MCS 14  */
513         {       /* 20 Mhz */ {  117.0f,         /* SGI */  130.0f, },
514                 /* 40 Mhz */ {  243.0f,         /* SGI */  270.0f, },
515         },
516
517         /* MCS 15  */
518         {       /* 20 Mhz */ {  130.0f,         /* SGI */  144.4f, },
519                 /* 40 Mhz */ {  270.0f,         /* SGI */  300.0f, },
520         },
521
522         /* MCS 16  */
523         {       /* 20 Mhz */ {   19.5f,         /* SGI */   21.7f, },
524                 /* 40 Mhz */ {   40.5f,         /* SGI */   45.0f, },
525         },
526
527         /* MCS 17  */
528         {       /* 20 Mhz */ {   39.0f,         /* SGI */   43.3f, },
529                 /* 40 Mhz */ {   81.0f,         /* SGI */   90.0f, },
530         },
531
532         /* MCS 18  */
533         {       /* 20 Mhz */ {   58.5f,         /* SGI */   65.0f, },
534                 /* 40 Mhz */ {  121.5f,         /* SGI */  135.0f, },
535         },
536
537         /* MCS 19  */
538         {       /* 20 Mhz */ {   78.0f,         /* SGI */   86.7f, },
539                 /* 40 Mhz */ {  162.0f,         /* SGI */  180.0f, },
540         },
541
542         /* MCS 20  */
543         {       /* 20 Mhz */ {  117.0f,         /* SGI */  130.0f, },
544                 /* 40 Mhz */ {  243.0f,         /* SGI */  270.0f, },
545         },
546
547         /* MCS 21  */
548         {       /* 20 Mhz */ {  156.0f,         /* SGI */  173.3f, },
549                 /* 40 Mhz */ {  324.0f,         /* SGI */  360.0f, },
550         },
551
552         /* MCS 22  */
553         {       /* 20 Mhz */ {  175.5f,         /* SGI */  195.0f, },
554                 /* 40 Mhz */ {  364.5f,         /* SGI */  405.0f, },
555         },
556
557         /* MCS 23  */
558         {       /* 20 Mhz */ {  195.0f,         /* SGI */  216.7f, },
559                 /* 40 Mhz */ {  405.0f,         /* SGI */  450.0f, },
560         },
561
562         /* MCS 24  */
563         {       /* 20 Mhz */ {   26.0f,         /* SGI */   28.9f, },
564                 /* 40 Mhz */ {   54.0f,         /* SGI */   60.0f, },
565         },
566
567         /* MCS 25  */
568         {       /* 20 Mhz */ {   52.0f,         /* SGI */   57.8f, },
569                 /* 40 Mhz */ {  108.0f,         /* SGI */  120.0f, },
570         },
571
572         /* MCS 26  */
573         {       /* 20 Mhz */ {   78.0f,         /* SGI */   86.7f, },
574                 /* 40 Mhz */ {  162.0f,         /* SGI */  180.0f, },
575         },
576
577         /* MCS 27  */
578         {       /* 20 Mhz */ {  104.0f,         /* SGI */  115.6f, },
579                 /* 40 Mhz */ {  216.0f,         /* SGI */  240.0f, },
580         },
581
582         /* MCS 28  */
583         {       /* 20 Mhz */ {  156.0f,         /* SGI */  173.3f, },
584                 /* 40 Mhz */ {  324.0f,         /* SGI */  360.0f, },
585         },
586
587         /* MCS 29  */
588         {       /* 20 Mhz */ {  208.0f,         /* SGI */  231.1f, },
589                 /* 40 Mhz */ {  432.0f,         /* SGI */  480.0f, },
590         },
591
592         /* MCS 30  */
593         {       /* 20 Mhz */ {  234.0f,         /* SGI */  260.0f, },
594                 /* 40 Mhz */ {  486.0f,         /* SGI */  540.0f, },
595         },
596
597         /* MCS 31  */
598         {       /* 20 Mhz */ {  260.0f,         /* SGI */  288.9f, },
599                 /* 40 Mhz */ {  540.0f,         /* SGI */  600.0f, },
600         },
601
602         /* MCS 32  */
603         {       /* 20 Mhz */ {    0.0f,         /* SGI */    0.0f, }, /* not valid */
604                 /* 40 Mhz */ {    6.0f,         /* SGI */    6.7f, },
605         },
606
607         /* MCS 33  */
608         {       /* 20 Mhz */ {   39.0f,         /* SGI */   43.3f, },
609                 /* 40 Mhz */ {   81.0f,         /* SGI */   90.0f, },
610         },
611
612         /* MCS 34  */
613         {       /* 20 Mhz */ {   52.0f,         /* SGI */   57.8f, },
614                 /* 40 Mhz */ {  108.0f,         /* SGI */  120.0f, },
615         },
616
617         /* MCS 35  */
618         {       /* 20 Mhz */ {   65.0f,         /* SGI */   72.2f, },
619                 /* 40 Mhz */ {  135.0f,         /* SGI */  150.0f, },
620         },
621
622         /* MCS 36  */
623         {       /* 20 Mhz */ {   58.5f,         /* SGI */   65.0f, },
624                 /* 40 Mhz */ {  121.5f,         /* SGI */  135.0f, },
625         },
626
627         /* MCS 37  */
628         {       /* 20 Mhz */ {   78.0f,         /* SGI */   86.7f, },
629                 /* 40 Mhz */ {  162.0f,         /* SGI */  180.0f, },
630         },
631
632         /* MCS 38  */
633         {       /* 20 Mhz */ {   97.5f,         /* SGI */  108.3f, },
634                 /* 40 Mhz */ {  202.5f,         /* SGI */  225.0f, },
635         },
636
637         /* MCS 39  */
638         {       /* 20 Mhz */ {   52.0f,         /* SGI */   57.8f, },
639                 /* 40 Mhz */ {  108.0f,         /* SGI */  120.0f, },
640         },
641
642         /* MCS 40  */
643         {       /* 20 Mhz */ {   65.0f,         /* SGI */   72.2f, },
644                 /* 40 Mhz */ {  135.0f,         /* SGI */  150.0f, },
645         },
646
647         /* MCS 41  */
648         {       /* 20 Mhz */ {   65.0f,         /* SGI */   72.2f, },
649                 /* 40 Mhz */ {  135.0f,         /* SGI */  150.0f, },
650         },
651
652         /* MCS 42  */
653         {       /* 20 Mhz */ {   78.0f,         /* SGI */   86.7f, },
654                 /* 40 Mhz */ {  162.0f,         /* SGI */  180.0f, },
655         },
656
657         /* MCS 43  */
658         {       /* 20 Mhz */ {   91.0f,         /* SGI */  101.1f, },
659                 /* 40 Mhz */ {  189.0f,         /* SGI */  210.0f, },
660         },
661
662         /* MCS 44  */
663         {       /* 20 Mhz */ {   91.0f,         /* SGI */  101.1f, },
664                 /* 40 Mhz */ {  189.0f,         /* SGI */  210.0f, },
665         },
666
667         /* MCS 45  */
668         {       /* 20 Mhz */ {  104.0f,         /* SGI */  115.6f, },
669                 /* 40 Mhz */ {  216.0f,         /* SGI */  240.0f, },
670         },
671
672         /* MCS 46  */
673         {       /* 20 Mhz */ {   78.0f,         /* SGI */   86.7f, },
674                 /* 40 Mhz */ {  162.0f,         /* SGI */  180.0f, },
675         },
676
677         /* MCS 47  */
678         {       /* 20 Mhz */ {   97.5f,         /* SGI */  108.3f, },
679                 /* 40 Mhz */ {  202.5f,         /* SGI */  225.0f, },
680         },
681
682         /* MCS 48  */
683         {       /* 20 Mhz */ {   97.5f,         /* SGI */  108.3f, },
684                 /* 40 Mhz */ {  202.5f,         /* SGI */  225.0f, },
685         },
686
687         /* MCS 49  */
688         {       /* 20 Mhz */ {  117.0f,         /* SGI */  130.0f, },
689                 /* 40 Mhz */ {  243.0f,         /* SGI */  270.0f, },
690         },
691
692         /* MCS 50  */
693         {       /* 20 Mhz */ {  136.5f,         /* SGI */  151.7f, },
694                 /* 40 Mhz */ {  283.5f,         /* SGI */  315.0f, },
695         },
696
697         /* MCS 51  */
698         {       /* 20 Mhz */ {  136.5f,         /* SGI */  151.7f, },
699                 /* 40 Mhz */ {  283.5f,         /* SGI */  315.0f, },
700         },
701
702         /* MCS 52  */
703         {       /* 20 Mhz */ {  156.0f,         /* SGI */  173.3f, },
704                 /* 40 Mhz */ {  324.0f,         /* SGI */  360.0f, },
705         },
706
707         /* MCS 53  */
708         {       /* 20 Mhz */ {   65.0f,         /* SGI */   72.2f, },
709                 /* 40 Mhz */ {  135.0f,         /* SGI */  150.0f, },
710         },
711
712         /* MCS 54  */
713         {       /* 20 Mhz */ {   78.0f,         /* SGI */   86.7f, },
714                 /* 40 Mhz */ {  162.0f,         /* SGI */  180.0f, },
715         },
716
717         /* MCS 55  */
718         {       /* 20 Mhz */ {   91.0f,         /* SGI */  101.1f, },
719                 /* 40 Mhz */ {  189.0f,         /* SGI */  210.0f, },
720         },
721
722         /* MCS 56  */
723         {       /* 20 Mhz */ {   78.0f,         /* SGI */   86.7f, },
724                 /* 40 Mhz */ {  162.0f,         /* SGI */  180.0f, },
725         },
726
727         /* MCS 57  */
728         {       /* 20 Mhz */ {   91.0f,         /* SGI */  101.1f, },
729                 /* 40 Mhz */ {  189.0f,         /* SGI */  210.0f, },
730         },
731
732         /* MCS 58  */
733         {       /* 20 Mhz */ {  104.0f,         /* SGI */  115.6f, },
734                 /* 40 Mhz */ {  216.0f,         /* SGI */  240.0f, },
735         },
736
737         /* MCS 59  */
738         {       /* 20 Mhz */ {  117.0f,         /* SGI */  130.0f, },
739                 /* 40 Mhz */ {  243.0f,         /* SGI */  270.0f, },
740         },
741
742         /* MCS 60  */
743         {       /* 20 Mhz */ {  104.0f,         /* SGI */  115.6f, },
744                 /* 40 Mhz */ {  216.0f,         /* SGI */  240.0f, },
745         },
746
747         /* MCS 61  */
748         {       /* 20 Mhz */ {  117.0f,         /* SGI */  130.0f, },
749                 /* 40 Mhz */ {  243.0f,         /* SGI */  270.0f, },
750         },
751
752         /* MCS 62  */
753         {       /* 20 Mhz */ {  130.0f,         /* SGI */  144.4f, },
754                 /* 40 Mhz */ {  270.0f,         /* SGI */  300.0f, },
755         },
756
757         /* MCS 63  */
758         {       /* 20 Mhz */ {  130.0f,         /* SGI */  144.4f, },
759                 /* 40 Mhz */ {  270.0f,         /* SGI */  300.0f, },
760         },
761
762         /* MCS 64  */
763         {       /* 20 Mhz */ {  143.0f,         /* SGI */  158.9f, },
764                 /* 40 Mhz */ {  297.0f,         /* SGI */  330.0f, },
765         },
766
767         /* MCS 65  */
768         {       /* 20 Mhz */ {   97.5f,         /* SGI */  108.3f, },
769                 /* 40 Mhz */ {  202.5f,         /* SGI */  225.0f, },
770         },
771
772         /* MCS 66  */
773         {       /* 20 Mhz */ {  117.0f,         /* SGI */  130.0f, },
774                 /* 40 Mhz */ {  243.0f,         /* SGI */  270.0f, },
775         },
776
777         /* MCS 67  */
778         {       /* 20 Mhz */ {  136.5f,         /* SGI */  151.7f, },
779                 /* 40 Mhz */ {  283.5f,         /* SGI */  315.0f, },
780         },
781
782         /* MCS 68  */
783         {       /* 20 Mhz */ {  117.0f,         /* SGI */  130.0f, },
784                 /* 40 Mhz */ {  243.0f,         /* SGI */  270.0f, },
785         },
786
787         /* MCS 69  */
788         {       /* 20 Mhz */ {  136.5f,         /* SGI */  151.7f, },
789                 /* 40 Mhz */ {  283.5f,         /* SGI */  315.0f, },
790         },
791
792         /* MCS 70  */
793         {       /* 20 Mhz */ {  156.0f,         /* SGI */  173.3f, },
794                 /* 40 Mhz */ {  324.0f,         /* SGI */  360.0f, },
795         },
796
797         /* MCS 71  */
798         {       /* 20 Mhz */ {  175.5f,         /* SGI */  195.0f, },
799                 /* 40 Mhz */ {  364.5f,         /* SGI */  405.0f, },
800         },
801
802         /* MCS 72  */
803         {       /* 20 Mhz */ {  156.0f,         /* SGI */  173.3f, },
804                 /* 40 Mhz */ {  324.0f,         /* SGI */  360.0f, },
805         },
806
807         /* MCS 73  */
808         {       /* 20 Mhz */ {  175.5f,         /* SGI */  195.0f, },
809                 /* 40 Mhz */ {  364.5f,         /* SGI */  405.0f, },
810         },
811
812         /* MCS 74  */
813         {       /* 20 Mhz */ {  195.0f,         /* SGI */  216.7f, },
814                 /* 40 Mhz */ {  405.0f,         /* SGI */  450.0f, },
815         },
816
817         /* MCS 75  */
818         {       /* 20 Mhz */ {  195.0f,         /* SGI */  216.7f, },
819                 /* 40 Mhz */ {  405.0f,         /* SGI */  450.0f, },
820         },
821
822         /* MCS 76  */
823         {       /* 20 Mhz */ {  214.5f,         /* SGI */  238.3f, },
824                 /* 40 Mhz */ {  445.5f,         /* SGI */  495.0f, },
825         },
826 };
827
828 static const char *auth_alg_text[]={"Open System","Shared Key","EAP"};
829 #define NUM_AUTH_ALGS   (sizeof(auth_alg_text) / sizeof(auth_alg_text[0]))
830
831 static const char *status_text[] = {
832         "Successful",                                           /*  0 */
833         "Unspecified failure",                                  /*  1 */
834         "TDLS wakeup schedule rejected but alternative schedule "
835           "provided",                                   /*  2 */
836         "TDLS wakeup schedule rejected",/*  3 */
837         "Reserved",                                             /*  4 */
838         "Security disabled",                    /*  5 */
839         "Unacceptable lifetime",                /*  6 */
840         "Not in same BSS",                              /*  7 */
841         "Reserved",                                             /*  8 */
842         "Reserved",                                             /*  9 */
843         "Cannot Support all requested capabilities in the Capability "
844           "Information field",                                  /* 10 */
845         "Reassociation denied due to inability to confirm that association "
846           "exists",                                             /* 11 */
847         "Association denied due to reason outside the scope of this "
848           "standard",                                           /* 12 */
849         "Responding STA does not support the specified authentication "
850           "algorithm",                                          /* 13 */
851         "Received an Authentication frame with authentication transaction "
852           "sequence number out of expected sequence",           /* 14 */
853         "Authentication rejected because of challenge failure", /* 15 */
854         "Authentication rejected due to timeout waiting for next frame in "
855           "sequence",                                           /* 16 */
856         "Association denied because AP is unable to handle "
857           "additional associated STAs",                         /* 17 */
858         "Association denied due to requesting STA not supporting "
859           "all of the data rates in the BSSBasicRateSet parameter, "
860           "the Basic HT-MCS Set field of the HT Operation "
861           "parameter, or the Basic VHT-MCS and NSS Set field in "
862           "the VHT Operation parameter",        /* 18 */
863         "Association denied due to requesting STA not supporting "
864           "the short preamble option",                          /* 19 */
865         "Reserved",                                     /* 20 */
866         "Reserved",                                     /* 21 */
867         "Association request rejected because Spectrum Management "
868           "capability is required",                             /* 22 */
869         "Association request rejected because the information in the "
870           "Power Capability element is unacceptable",           /* 23 */
871         "Association request rejected because the information in the "
872           "Supported Channels element is unacceptable",         /* 24 */
873         "Association denied due to requesting STA not supporting "
874           "the Short Slot Time option",                         /* 25 */
875         "Reserved",                             /* 26 */
876         "Association denied because the requested STA does not support HT "
877           "features",                                           /* 27 */
878         "R0KH unreachable",                                     /* 28 */
879         "Association denied because the requesting STA does not "
880           "support the phased coexistence operation (PCO) "
881           "transition time required by the AP",         /* 29 */
882         "Association request rejected temporarily; try again "
883           "later",                                                      /* 30 */
884         "Robust management frame policy violation",     /* 31 */
885         "Unspecified, QoS-related failure",                     /* 32 */
886         "Association denied because QoS AP or PCP has "
887           "insufficient bandwidth to handle another QoS "
888           "STA",                                                                        /* 33 */
889         "Association denied due to excessive frame loss rates and/or "
890           "poor conditions on current operating channel",       /* 34 */
891         "Association (with QoS BSS) denied because the requesting STA "
892           "does not support the QoS facility",                  /* 35 */
893         "Reserved",                                                                     /* 36 */
894         "The request has been declined",                        /* 37 */
895         "The request has not been successful as one or more parameters "
896           "have invalid values",                                /* 38 */
897         "The allocation or TS has not been created because the request "
898           "cannot be honored; however, a suggested TSPEC/DMG TSPEC is "
899           "provided so that the initiating STA can attempt to set "
900           "another allocation or TS with the suggested changes to the "
901           "TSPEC/DMG TSPEC",                                    /* 39 */
902         "Invalid element, i.e., an element defined in this standard "
903           "for which the content does not meet the specifications in "
904           "Clause 9",                                                           /* 40 */
905         "Invalid group cipher",                                         /* 41 */
906         "Invalid pairwise cipher",                                      /* 42 */
907         "Invalid AKMP",                                                         /* 43 */
908         "Unsupported RSNE version",                                     /* 44 */
909         "Invalid RSNE capabilities",                            /* 45 */
910         "Cipher suite rejected because of security policy",             /* 46 */
911         "The TS or allocation has not been created; however, the "
912           "HC or PCP might be capable of creating a TS or "
913           "allocation, in response to a request, after the time "
914           "indicated in the TS Delay element",          /* 47 */
915         "Direct Link is not allowed in the BSS by policy",      /* 48 */
916         "The Destination STA is not present within this BSS",   /* 49 */
917         "The Destination STA is not a QoS STA",         /* 50 */
918
919         "Association denied because the listen interval is "
920           "too large",                                                          /* 51 */
921         "Invalid FT Action frame count",                        /* 52 */
922         "Invalid pairwise master key identifier (PMKID)", /* 53 */
923         "Invalid MDE",                                                          /* 54 */
924         "Invalid FTE",                                                          /* 55 */
925         "Requested TCLAS processing is not supported by the AP "
926           "or PCP",                                                                     /* 56 */
927         "The AP or PCP has insufficient TCLAS processing "
928           "resources to satisfy the request",           /* 57 */
929         "The TS has not been created because the request "
930           "cannot be honored; however, the HC or PCP suggests "
931           "that the STA transition to a different BSS to set up "
932           "the TS",                                                                     /* 58 */
933         "GAS Advertisement Protocol not supported",     /* 59 */
934         "No outstanding GAS request",                           /* 60 */
935         "GAS Response not received from the Advertisement "
936           "Server",                                                                     /* 61 */
937         "STA timed out waiting for GAS Query Response", /* 62 */
938         "LARGE GAS Response is larger than query response "
939           "length limit",                                                       /* 63 */
940         "Request refused because home network does not support "
941           "request",                                                            /* 64 */
942         "Advertisement Server in the network is not currently "
943           "reachable",                                                          /* 65 */
944         "Reserved",                                                                     /* 66 */
945         "Request refused due to permissions received via SSPN "
946           "interface",                                                          /* 67 */
947         "Request refused because the AP or PCP does not "
948           "support unauthenticated access",                     /* 68 */
949         "Reserved",                                                                     /* 69 */
950         "Reserved",                                                                     /* 70 */
951         "Reserved",                                                                     /* 71 */
952         "Invalid contents of RSNE",                             /* 72 */
953         "U-APSD coexistence is not supported",          /* 73 */
954         "Requested U-APSD coexistence mode is not supported", /* 74 */
955         "Requested Interval/Duration value cannot be "
956           "supported with U-APSD coexistence",          /* 75 */
957         "Authentication is rejected because an Anti-Clogging "
958           "Token is required",                                          /* 76 */
959         "Authentication is rejected because the offered "
960           "finite cyclic group is not supported",       /* 77 */
961         "The TBTT adjustment request has not been successful "
962           "because the STA could not find an alternative TBTT", /* 78 */
963         "Transmission failure",                                         /* 79 */
964         "Requested TCLAS Not Supported",                        /* 80 */
965         "TCLAS Resources Exhausted",                            /* 81 */
966         "Rejected with Suggested BSS transition",       /* 82 */
967         "Reject with recommended schedule",                     /* 83 */
968         "Reject because no wakeup schedule specified", /* 84 */
969         "Success, the destination STA is in power save mode", /* 85 */
970         "FST pending, in process of admitting FST session", /* 86 */
971         "Performing FST now",                                           /* 87 */
972         "FST pending, gap(s) in block ack window",      /* 88 */
973         "Reject because of U-PID setting",                      /* 89 */
974         "Reserved",                                                                     /* 90 */
975         "Reserved",                                                                     /* 91 */
976         "(Re)Association refused for some external reason", /* 92 */
977         "(Re)Association refused because of memory limits "
978           "at the AP",                                                          /* 93 */
979         "(Re)Association refused because emergency services "
980           "are not supported at the AP",                        /* 94 */
981         "GAS query response not yet received",          /* 95 */
982         "Reject since the request is for transition to a "
983           "frequency band subject to DSE procedures and "
984           "FST Initiator is a dependent STA",           /* 96 */
985         "Requested TCLAS processing has been terminated by "
986           "the AP",                                                                     /* 97 */
987         "The TS schedule conflicts with an existing "
988           "schedule; an alternative schedule is provided", /* 98 */
989         "The association has been denied; however, one or "
990           "more Multi-band elements are included that can "
991           "be used by the receiving STA to join the BSS", /* 99 */
992         "The request failed due to a reservation conflict", /* 100 */
993         "The request failed due to exceeded MAF limit", /* 101 */
994         "The request failed due to exceeded MCCA track "
995           "limit",                                                                      /* 102 */
996         "Association denied because the information in the"
997           "Spectrum Management field is unacceptable", /* 103 */
998         "Association denied because the requesting STA "
999           "does not support VHT features",                      /* 104 */
1000         "Enablement denied",                                            /* 105 */
1001         "Enablement denied due to restriction from an "
1002           "authorized GDB",                                                     /* 106 */
1003         "Authorization deenabled",                                      /* 107 */
1004 };
1005 #define NUM_STATUSES    (sizeof(status_text) / sizeof(status_text[0]))
1006
1007 static const char *reason_text[] = {
1008         "Reserved",                                             /* 0 */
1009         "Unspecified reason",                                   /* 1 */
1010         "Previous authentication no longer valid",              /* 2 */
1011         "Deauthenticated because sending STA is leaving (or has left) "
1012           "IBSS or ESS",                                        /* 3 */
1013         "Disassociated due to inactivity",                      /* 4 */
1014         "Disassociated because AP is unable to handle all currently "
1015           " associated STAs",                           /* 5 */
1016         "Class 2 frame received from nonauthenticated STA", /* 6 */
1017         "Class 3 frame received from nonassociated STA",        /* 7 */
1018         "Disassociated because sending STA is leaving "
1019           "(or has left) BSS",                                  /* 8 */
1020         "STA requesting (re)association is not authenticated with "
1021           "responding STA",                                     /* 9 */
1022         "Disassociated because the information in the Power Capability "
1023           "element is unacceptable",                            /* 10 */
1024         "Disassociated because the information in the Supported Channels "
1025           "element is unacceptable",                            /* 11 */
1026         "Disassociated due to BSS transition management",       /* 12 */
1027         "Invalid element, i.e., an element defined in this standard for "
1028           "which the content does not meet the specifications "
1029           "in Clause 9",                                                /* 13 */
1030         "Message integrity code (MIC) failure", /* 14 */
1031         "4-Way Handshake timeout",                              /* 15 */
1032         "Group key handshake timeout",                  /* 16 */
1033         "Information element in 4-Way Handshake different from (Re)Association"
1034           "Request/Probe Response/Beacon frame",        /* 17 */
1035         "Invalid group cipher",                                 /* 18 */
1036         "Invalid pairwise cipher",                              /* 19 */
1037         "Invalid AKMP",                                                 /* 20 */
1038         "Unsupported RSNE version",                             /* 21 */
1039         "Invalid RSNE capabilities",                            /* 22 */
1040         "IEEE 802.1X authentication failed",                    /* 23 */
1041         "Cipher suite rejected because of the security policy",         /* 24 */
1042         "TDLS direct-link teardown due to TDLS peer STA "
1043           "unreachable via the TDLS direct link",                               /* 25 */
1044         "TDLS direct-link teardown for unspecified reason",             /* 26 */
1045         "Disassociated because session terminated by SSP request",/* 27 */
1046         "Disassociated because of lack of SSP roaming agreement",/* 28 */
1047         "Requested service rejected because of SSP cipher suite or "
1048           "AKM requirement",                                            /* 29 */
1049         "Requested service not authorized in this location",    /* 30 */
1050         "TS deleted because QoS AP lacks sufficient bandwidth for this "
1051           "QoS STA due to a change in BSS service characteristics or "
1052           "operational mode (e.g. an HT BSS change from 40 MHz channel "
1053           "to 20 MHz channel)",                                 /* 31 */
1054         "Disassociated for unspecified, QoS-related reason",    /* 32 */
1055         "Disassociated because QoS AP lacks sufficient bandwidth for this "
1056           "QoS STA",                                            /* 33 */
1057         "Disassociated because of excessive number of frames that need to be "
1058           "acknowledged, but are not acknowledged due to AP transmissions "
1059           "and/or poor channel conditions",                     /* 34 */
1060         "Disassociated because STA is transmitting outside the limits "
1061           "of its TXOPs",                                       /* 35 */
1062         "Requested from peer STA as the STA is leaving the BSS "
1063           "(or resetting)",                                     /* 36 */
1064         "Requested from peer STA as it does not want to use the "
1065           "mechanism",                                          /* 37 */
1066         "Requested from peer STA as the STA received frames using the "
1067           "mechanism for which a set up is required",           /* 38 */
1068         "Requested from peer STA due to time out",              /* 39 */
1069         "Reserved",                                             /* 40 */
1070         "Reserved",                                             /* 41 */
1071         "Reserved",                                             /* 42 */
1072         "Reserved",                                             /* 43 */
1073         "Reserved",                                             /* 44 */
1074         "Peer STA does not support the requested cipher suite", /* 45 */
1075         "In a DLS Teardown frame: The teardown was initiated by the "
1076           "DLS peer. In a Disassociation frame: Disassociated because "
1077           "authorized access limit reached",                                    /* 46 */
1078         "In a DLS Teardown frame: The teardown was initiated by the "
1079           "AP. In a Disassociation frame: Disassociated due to external "
1080           "service requirements",                                                               /* 47 */
1081         "Invalid FT Action frame count",                                                /* 48 */
1082         "Invalid pairwise master key identifier (PMKID)",               /* 49 */
1083         "Invalid MDE",                                                                                  /* 50 */
1084         "Invalid FTE",                                                                                  /* 51 */
1085         "Mesh peering canceled for unknown reasons",                    /* 52 */
1086         "The mesh STA has reached the supported maximum number of "
1087           "peer mesh STAs",                                                                             /* 53 */
1088         "The received information violates the Mesh Configuration "
1089           "policy configured in the mesh STA profile",                  /* 54 */
1090         "The mesh STA has received a Mesh Peering Close frame "
1091           "requesting to close the mesh peering",                               /* 55 */
1092         "The mesh STA has resent dot11MeshMaxRetries Mesh "
1093           "Peering Open frames, without receiving a Mesh Peering "
1094           "Confirm frame",                                                                              /* 56 */
1095         "The confirmTimer for the mesh peering instance times out",     /* 57 */
1096         "The mesh STA fails to unwrap the GTK or the values in the "
1097           "wrapped contents do not match",                                              /* 58 */
1098         "The mesh STA receives inconsistent information about the "
1099           "mesh parameters between mesh peering Management frames",     /* 59 */
1100         "The mesh STA fails the authenticated mesh peering exchange "
1101           "because due to failure in selecting either the pairwise "
1102           "ciphersuite or group ciphersuite",                                   /* 60 */
1103         "The mesh STA does not have proxy information for this "
1104           "external destination",                                                               /* 61 */
1105         "The mesh STA does not have forwarding information for this "
1106           "destination",                                                                                /* 62 */
1107         "The mesh STA determines that the link to the next hop of an "
1108           "active path in its forwarding information is no longer "
1109           "usable",                                                                                             /* 63 */
1110         "The Deauthentication frame was sent because the MAC "
1111           "address of the STA already exists in the mesh BSS",  /* 64 */
1112         "The mesh STA performs channel switch to meet regulatory "
1113           "requirements",                                                                               /* 65 */
1114         "The mesh STA performs channel switching with unspecified "
1115           "reason",                                                                                             /* 66 */
1116 };
1117 #define NUM_REASONS     (sizeof(reason_text) / sizeof(reason_text[0]))
1118
1119 static int
1120 wep_print(netdissect_options *ndo,
1121           const u_char *p)
1122 {
1123         uint32_t iv;
1124
1125         ND_TCHECK_LEN(p, IEEE802_11_IV_LEN + IEEE802_11_KID_LEN);
1126         iv = GET_LE_U_4(p);
1127
1128         ND_PRINT(" IV:%3x Pad %x KeyID %x", IV_IV(iv), IV_PAD(iv),
1129             IV_KEYID(iv));
1130
1131         return 1;
1132 trunc:
1133         return 0;
1134 }
1135
1136 static int
1137 parse_elements(netdissect_options *ndo,
1138                struct mgmt_body_t *pbody, const u_char *p, int offset,
1139                u_int length)
1140 {
1141         u_int elementlen;
1142         struct ssid_t ssid;
1143         struct challenge_t challenge;
1144         struct rates_t rates;
1145         struct ds_t ds;
1146         struct cf_t cf;
1147         struct tim_t tim;
1148
1149         /*
1150          * We haven't seen any elements yet.
1151          */
1152         pbody->challenge_present = 0;
1153         pbody->ssid_present = 0;
1154         pbody->rates_present = 0;
1155         pbody->ds_present = 0;
1156         pbody->cf_present = 0;
1157         pbody->tim_present = 0;
1158
1159         while (length != 0) {
1160                 /* Make sure we at least have the element ID and length. */
1161                 ND_TCHECK_2(p + offset);
1162                 if (length < 2)
1163                         goto trunc;
1164                 elementlen = GET_U_1(p + offset + 1);
1165
1166                 /* Make sure we have the entire element. */
1167                 ND_TCHECK_LEN(p + offset + 2, elementlen);
1168                 if (length < elementlen + 2)
1169                         goto trunc;
1170
1171                 switch (GET_U_1(p + offset)) {
1172                 case E_SSID:
1173                         memcpy(&ssid, p + offset, 2);
1174                         offset += 2;
1175                         length -= 2;
1176                         if (ssid.length != 0) {
1177                                 if (ssid.length > sizeof(ssid.ssid) - 1)
1178                                         return 0;
1179                                 memcpy(&ssid.ssid, p + offset, ssid.length);
1180                                 offset += ssid.length;
1181                                 length -= ssid.length;
1182                         }
1183                         ssid.ssid[ssid.length] = '\0';
1184                         /*
1185                          * Present and not truncated.
1186                          *
1187                          * If we haven't already seen an SSID IE,
1188                          * copy this one, otherwise ignore this one,
1189                          * so we later report the first one we saw.
1190                          */
1191                         if (!pbody->ssid_present) {
1192                                 pbody->ssid = ssid;
1193                                 pbody->ssid_present = 1;
1194                         }
1195                         break;
1196                 case E_CHALLENGE:
1197                         memcpy(&challenge, p + offset, 2);
1198                         offset += 2;
1199                         length -= 2;
1200                         if (challenge.length != 0) {
1201                                 if (challenge.length >
1202                                     sizeof(challenge.text) - 1)
1203                                         return 0;
1204                                 memcpy(&challenge.text, p + offset,
1205                                     challenge.length);
1206                                 offset += challenge.length;
1207                                 length -= challenge.length;
1208                         }
1209                         challenge.text[challenge.length] = '\0';
1210                         /*
1211                          * Present and not truncated.
1212                          *
1213                          * If we haven't already seen a challenge IE,
1214                          * copy this one, otherwise ignore this one,
1215                          * so we later report the first one we saw.
1216                          */
1217                         if (!pbody->challenge_present) {
1218                                 pbody->challenge = challenge;
1219                                 pbody->challenge_present = 1;
1220                         }
1221                         break;
1222                 case E_RATES:
1223                         memcpy(&rates, p + offset, 2);
1224                         offset += 2;
1225                         length -= 2;
1226                         if (rates.length != 0) {
1227                                 if (rates.length > sizeof(rates.rate))
1228                                         return 0;
1229                                 memcpy(&rates.rate, p + offset, rates.length);
1230                                 offset += rates.length;
1231                                 length -= rates.length;
1232                         }
1233                         /*
1234                          * Present and not truncated.
1235                          *
1236                          * If we haven't already seen a rates IE,
1237                          * copy this one if it's not zero-length,
1238                          * otherwise ignore this one, so we later
1239                          * report the first one we saw.
1240                          *
1241                          * We ignore zero-length rates IEs as some
1242                          * devices seem to put a zero-length rates
1243                          * IE, followed by an SSID IE, followed by
1244                          * a non-zero-length rates IE into frames,
1245                          * even though IEEE Std 802.11-2007 doesn't
1246                          * seem to indicate that a zero-length rates
1247                          * IE is valid.
1248                          */
1249                         if (!pbody->rates_present && rates.length != 0) {
1250                                 pbody->rates = rates;
1251                                 pbody->rates_present = 1;
1252                         }
1253                         break;
1254                 case E_DS:
1255                         memcpy(&ds, p + offset, 2);
1256                         offset += 2;
1257                         length -= 2;
1258                         if (ds.length != 1) {
1259                                 offset += ds.length;
1260                                 length -= ds.length;
1261                                 break;
1262                         }
1263                         ds.channel = GET_U_1(p + offset);
1264                         offset += 1;
1265                         length -= 1;
1266                         /*
1267                          * Present and not truncated.
1268                          *
1269                          * If we haven't already seen a DS IE,
1270                          * copy this one, otherwise ignore this one,
1271                          * so we later report the first one we saw.
1272                          */
1273                         if (!pbody->ds_present) {
1274                                 pbody->ds = ds;
1275                                 pbody->ds_present = 1;
1276                         }
1277                         break;
1278                 case E_CF:
1279                         memcpy(&cf, p + offset, 2);
1280                         offset += 2;
1281                         length -= 2;
1282                         if (cf.length != 6) {
1283                                 offset += cf.length;
1284                                 length -= cf.length;
1285                                 break;
1286                         }
1287                         cf.count = GET_U_1(p + offset);
1288                         offset += 1;
1289                         length -= 1;
1290                         cf.period = GET_U_1(p + offset);
1291                         offset += 1;
1292                         length -= 1;
1293                         cf.max_duration = GET_LE_U_2(p + offset);
1294                         offset += 2;
1295                         length -= 2;
1296                         cf.dur_remaining = GET_LE_U_2(p + offset);
1297                         offset += 2;
1298                         length -= 2;
1299                         /*
1300                          * Present and not truncated.
1301                          *
1302                          * If we haven't already seen a CF IE,
1303                          * copy this one, otherwise ignore this one,
1304                          * so we later report the first one we saw.
1305                          */
1306                         if (!pbody->cf_present) {
1307                                 pbody->cf = cf;
1308                                 pbody->cf_present = 1;
1309                         }
1310                         break;
1311                 case E_TIM:
1312                         memcpy(&tim, p + offset, 2);
1313                         offset += 2;
1314                         length -= 2;
1315                         if (tim.length <= 3U) {
1316                                 offset += tim.length;
1317                                 length -= tim.length;
1318                                 break;
1319                         }
1320                         if (tim.length - 3U > sizeof(tim.bitmap))
1321                                 return 0;
1322                         tim.count = GET_U_1(p + offset);
1323                         offset += 1;
1324                         length -= 1;
1325                         tim.period = GET_U_1(p + offset);
1326                         offset += 1;
1327                         length -= 1;
1328                         tim.bitmap_control = GET_U_1(p + offset);
1329                         offset += 1;
1330                         length -= 1;
1331                         memcpy(tim.bitmap, p + offset, tim.length - 3);
1332                         offset += tim.length - 3;
1333                         length -= tim.length - 3;
1334                         /*
1335                          * Present and not truncated.
1336                          *
1337                          * If we haven't already seen a TIM IE,
1338                          * copy this one, otherwise ignore this one,
1339                          * so we later report the first one we saw.
1340                          */
1341                         if (!pbody->tim_present) {
1342                                 pbody->tim = tim;
1343                                 pbody->tim_present = 1;
1344                         }
1345                         break;
1346                 default:
1347 #if 0
1348                         ND_PRINT("(1) unhandled element_id (%u)  ",
1349                             GET_U_1(p + offset));
1350 #endif
1351                         offset += 2 + elementlen;
1352                         length -= 2 + elementlen;
1353                         break;
1354                 }
1355         }
1356
1357         /* No problems found. */
1358         return 1;
1359 trunc:
1360         return 0;
1361 }
1362
1363 /*********************************************************************************
1364  * Print Handle functions for the management frame types
1365  *********************************************************************************/
1366
1367 static int
1368 handle_beacon(netdissect_options *ndo,
1369               const u_char *p, u_int length)
1370 {
1371         struct mgmt_body_t pbody;
1372         int offset = 0;
1373         int ret;
1374
1375         memset(&pbody, 0, sizeof(pbody));
1376
1377         ND_TCHECK_LEN(p, IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN +
1378                       IEEE802_11_CAPINFO_LEN);
1379         if (length < IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN +
1380             IEEE802_11_CAPINFO_LEN)
1381                 goto trunc;
1382         memcpy(&pbody.timestamp, p, IEEE802_11_TSTAMP_LEN);
1383         offset += IEEE802_11_TSTAMP_LEN;
1384         length -= IEEE802_11_TSTAMP_LEN;
1385         pbody.beacon_interval = GET_LE_U_2(p + offset);
1386         offset += IEEE802_11_BCNINT_LEN;
1387         length -= IEEE802_11_BCNINT_LEN;
1388         pbody.capability_info = GET_LE_U_2(p + offset);
1389         offset += IEEE802_11_CAPINFO_LEN;
1390         length -= IEEE802_11_CAPINFO_LEN;
1391
1392         ret = parse_elements(ndo, &pbody, p, offset, length);
1393
1394         PRINT_SSID(pbody);
1395         PRINT_RATES(pbody);
1396         ND_PRINT(" %s",
1397             CAPABILITY_ESS(pbody.capability_info) ? "ESS" : "IBSS");
1398         PRINT_DS_CHANNEL(pbody);
1399
1400         return ret;
1401 trunc:
1402         return 0;
1403 }
1404
1405 static int
1406 handle_assoc_request(netdissect_options *ndo,
1407                      const u_char *p, u_int length)
1408 {
1409         struct mgmt_body_t pbody;
1410         int offset = 0;
1411         int ret;
1412
1413         memset(&pbody, 0, sizeof(pbody));
1414
1415         ND_TCHECK_LEN(p, IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN);
1416         if (length < IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN)
1417                 goto trunc;
1418         pbody.capability_info = GET_LE_U_2(p);
1419         offset += IEEE802_11_CAPINFO_LEN;
1420         length -= IEEE802_11_CAPINFO_LEN;
1421         pbody.listen_interval = GET_LE_U_2(p + offset);
1422         offset += IEEE802_11_LISTENINT_LEN;
1423         length -= IEEE802_11_LISTENINT_LEN;
1424
1425         ret = parse_elements(ndo, &pbody, p, offset, length);
1426
1427         PRINT_SSID(pbody);
1428         PRINT_RATES(pbody);
1429         return ret;
1430 trunc:
1431         return 0;
1432 }
1433
1434 static int
1435 handle_assoc_response(netdissect_options *ndo,
1436                       const u_char *p, u_int length)
1437 {
1438         struct mgmt_body_t pbody;
1439         int offset = 0;
1440         int ret;
1441
1442         memset(&pbody, 0, sizeof(pbody));
1443
1444         ND_TCHECK_LEN(p, IEEE802_11_CAPINFO_LEN + IEEE802_11_STATUS_LEN +
1445                       IEEE802_11_AID_LEN);
1446         if (length < IEEE802_11_CAPINFO_LEN + IEEE802_11_STATUS_LEN +
1447             IEEE802_11_AID_LEN)
1448                 goto trunc;
1449         pbody.capability_info = GET_LE_U_2(p);
1450         offset += IEEE802_11_CAPINFO_LEN;
1451         length -= IEEE802_11_CAPINFO_LEN;
1452         pbody.status_code = GET_LE_U_2(p + offset);
1453         offset += IEEE802_11_STATUS_LEN;
1454         length -= IEEE802_11_STATUS_LEN;
1455         pbody.aid = GET_LE_U_2(p + offset);
1456         offset += IEEE802_11_AID_LEN;
1457         length -= IEEE802_11_AID_LEN;
1458
1459         ret = parse_elements(ndo, &pbody, p, offset, length);
1460
1461         ND_PRINT(" AID(%x) :%s: %s", ((uint16_t)(pbody.aid << 2 )) >> 2 ,
1462             CAPABILITY_PRIVACY(pbody.capability_info) ? " PRIVACY " : "",
1463             (pbody.status_code < NUM_STATUSES
1464                 ? status_text[pbody.status_code]
1465                 : "n/a"));
1466
1467         return ret;
1468 trunc:
1469         return 0;
1470 }
1471
1472 static int
1473 handle_reassoc_request(netdissect_options *ndo,
1474                        const u_char *p, u_int length)
1475 {
1476         struct mgmt_body_t pbody;
1477         int offset = 0;
1478         int ret;
1479
1480         memset(&pbody, 0, sizeof(pbody));
1481
1482         ND_TCHECK_LEN(p, IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN +
1483                       IEEE802_11_AP_LEN);
1484         if (length < IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN +
1485             IEEE802_11_AP_LEN)
1486                 goto trunc;
1487         pbody.capability_info = GET_LE_U_2(p);
1488         offset += IEEE802_11_CAPINFO_LEN;
1489         length -= IEEE802_11_CAPINFO_LEN;
1490         pbody.listen_interval = GET_LE_U_2(p + offset);
1491         offset += IEEE802_11_LISTENINT_LEN;
1492         length -= IEEE802_11_LISTENINT_LEN;
1493         memcpy(&pbody.ap, p+offset, IEEE802_11_AP_LEN);
1494         offset += IEEE802_11_AP_LEN;
1495         length -= IEEE802_11_AP_LEN;
1496
1497         ret = parse_elements(ndo, &pbody, p, offset, length);
1498
1499         PRINT_SSID(pbody);
1500         ND_PRINT(" AP : %s", etheraddr_string(ndo,  pbody.ap ));
1501
1502         return ret;
1503 trunc:
1504         return 0;
1505 }
1506
1507 static int
1508 handle_reassoc_response(netdissect_options *ndo,
1509                         const u_char *p, u_int length)
1510 {
1511         /* Same as a Association Response */
1512         return handle_assoc_response(ndo, p, length);
1513 }
1514
1515 static int
1516 handle_probe_request(netdissect_options *ndo,
1517                      const u_char *p, u_int length)
1518 {
1519         struct mgmt_body_t  pbody;
1520         int offset = 0;
1521         int ret;
1522
1523         memset(&pbody, 0, sizeof(pbody));
1524
1525         ret = parse_elements(ndo, &pbody, p, offset, length);
1526
1527         PRINT_SSID(pbody);
1528         PRINT_RATES(pbody);
1529
1530         return ret;
1531 }
1532
1533 static int
1534 handle_probe_response(netdissect_options *ndo,
1535                       const u_char *p, u_int length)
1536 {
1537         struct mgmt_body_t  pbody;
1538         int offset = 0;
1539         int ret;
1540
1541         memset(&pbody, 0, sizeof(pbody));
1542
1543         ND_TCHECK_LEN(p, IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN +
1544                       IEEE802_11_CAPINFO_LEN);
1545         if (length < IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN +
1546             IEEE802_11_CAPINFO_LEN)
1547                 goto trunc;
1548         memcpy(&pbody.timestamp, p, IEEE802_11_TSTAMP_LEN);
1549         offset += IEEE802_11_TSTAMP_LEN;
1550         length -= IEEE802_11_TSTAMP_LEN;
1551         pbody.beacon_interval = GET_LE_U_2(p + offset);
1552         offset += IEEE802_11_BCNINT_LEN;
1553         length -= IEEE802_11_BCNINT_LEN;
1554         pbody.capability_info = GET_LE_U_2(p + offset);
1555         offset += IEEE802_11_CAPINFO_LEN;
1556         length -= IEEE802_11_CAPINFO_LEN;
1557
1558         ret = parse_elements(ndo, &pbody, p, offset, length);
1559
1560         PRINT_SSID(pbody);
1561         PRINT_RATES(pbody);
1562         PRINT_DS_CHANNEL(pbody);
1563
1564         return ret;
1565 trunc:
1566         return 0;
1567 }
1568
1569 static int
1570 handle_atim(void)
1571 {
1572         /* the frame body for ATIM is null. */
1573         return 1;
1574 }
1575
1576 static int
1577 handle_disassoc(netdissect_options *ndo,
1578                 const u_char *p, u_int length)
1579 {
1580         struct mgmt_body_t  pbody;
1581
1582         memset(&pbody, 0, sizeof(pbody));
1583
1584         ND_TCHECK_LEN(p, IEEE802_11_REASON_LEN);
1585         if (length < IEEE802_11_REASON_LEN)
1586                 goto trunc;
1587         pbody.reason_code = GET_LE_U_2(p);
1588
1589         ND_PRINT(": %s",
1590             (pbody.reason_code < NUM_REASONS)
1591                 ? reason_text[pbody.reason_code]
1592                 : "Reserved");
1593
1594         return 1;
1595 trunc:
1596         return 0;
1597 }
1598
1599 static int
1600 handle_auth(netdissect_options *ndo,
1601             const u_char *p, u_int length)
1602 {
1603         struct mgmt_body_t  pbody;
1604         int offset = 0;
1605         int ret;
1606
1607         memset(&pbody, 0, sizeof(pbody));
1608
1609         ND_TCHECK_6(p);
1610         if (length < 6)
1611                 goto trunc;
1612         pbody.auth_alg = GET_LE_U_2(p);
1613         offset += 2;
1614         length -= 2;
1615         pbody.auth_trans_seq_num = GET_LE_U_2(p + offset);
1616         offset += 2;
1617         length -= 2;
1618         pbody.status_code = GET_LE_U_2(p + offset);
1619         offset += 2;
1620         length -= 2;
1621
1622         ret = parse_elements(ndo, &pbody, p, offset, length);
1623
1624         if ((pbody.auth_alg == 1) &&
1625             ((pbody.auth_trans_seq_num == 2) ||
1626              (pbody.auth_trans_seq_num == 3))) {
1627                 ND_PRINT(" (%s)-%x [Challenge Text] %s",
1628                     (pbody.auth_alg < NUM_AUTH_ALGS)
1629                         ? auth_alg_text[pbody.auth_alg]
1630                         : "Reserved",
1631                     pbody.auth_trans_seq_num,
1632                     ((pbody.auth_trans_seq_num % 2)
1633                         ? ((pbody.status_code < NUM_STATUSES)
1634                                ? status_text[pbody.status_code]
1635                                : "n/a") : ""));
1636                 return ret;
1637         }
1638         ND_PRINT(" (%s)-%x: %s",
1639             (pbody.auth_alg < NUM_AUTH_ALGS)
1640                 ? auth_alg_text[pbody.auth_alg]
1641                 : "Reserved",
1642             pbody.auth_trans_seq_num,
1643             (pbody.auth_trans_seq_num % 2)
1644                 ? ((pbody.status_code < NUM_STATUSES)
1645                     ? status_text[pbody.status_code]
1646                     : "n/a")
1647                 : "");
1648
1649         return ret;
1650 trunc:
1651         return 0;
1652 }
1653
1654 static int
1655 handle_deauth(netdissect_options *ndo,
1656               const uint8_t *src, const u_char *p, u_int length)
1657 {
1658         struct mgmt_body_t  pbody;
1659         const char *reason = NULL;
1660
1661         memset(&pbody, 0, sizeof(pbody));
1662
1663         ND_TCHECK_LEN(p, IEEE802_11_REASON_LEN);
1664         if (length < IEEE802_11_REASON_LEN)
1665                 goto trunc;
1666         pbody.reason_code = GET_LE_U_2(p);
1667
1668         reason = (pbody.reason_code < NUM_REASONS)
1669                         ? reason_text[pbody.reason_code]
1670                         : "Reserved";
1671
1672         if (ndo->ndo_eflag) {
1673                 ND_PRINT(": %s", reason);
1674         } else {
1675                 ND_PRINT(" (%s): %s", GET_ETHERADDR_STRING(src), reason);
1676         }
1677         return 1;
1678 trunc:
1679         return 0;
1680 }
1681
1682 #define PRINT_HT_ACTION(v) (\
1683         (v) == 0 ? ND_PRINT("TxChWidth"): \
1684         (v) == 1 ? ND_PRINT("MIMOPwrSave"): \
1685                    ND_PRINT("Act#%u", (v)))
1686 #define PRINT_BA_ACTION(v) (\
1687         (v) == 0 ? ND_PRINT("ADDBA Request"): \
1688         (v) == 1 ? ND_PRINT("ADDBA Response"): \
1689         (v) == 2 ? ND_PRINT("DELBA"): \
1690                    ND_PRINT("Act#%u", (v)))
1691 #define PRINT_MESHLINK_ACTION(v) (\
1692         (v) == 0 ? ND_PRINT("Request"): \
1693         (v) == 1 ? ND_PRINT("Report"): \
1694                    ND_PRINT("Act#%u", (v)))
1695 #define PRINT_MESHPEERING_ACTION(v) (\
1696         (v) == 0 ? ND_PRINT("Open"): \
1697         (v) == 1 ? ND_PRINT("Confirm"): \
1698         (v) == 2 ? ND_PRINT("Close"): \
1699                    ND_PRINT("Act#%u", (v)))
1700 #define PRINT_MESHPATH_ACTION(v) (\
1701         (v) == 0 ? ND_PRINT("Request"): \
1702         (v) == 1 ? ND_PRINT("Report"): \
1703         (v) == 2 ? ND_PRINT("Error"): \
1704         (v) == 3 ? ND_PRINT("RootAnnouncement"): \
1705                    ND_PRINT("Act#%u", (v)))
1706
1707 #define PRINT_MESH_ACTION(v) (\
1708         (v) == 0 ? ND_PRINT("MeshLink"): \
1709         (v) == 1 ? ND_PRINT("HWMP"): \
1710         (v) == 2 ? ND_PRINT("Gate Announcement"): \
1711         (v) == 3 ? ND_PRINT("Congestion Control"): \
1712         (v) == 4 ? ND_PRINT("MCCA Setup Request"): \
1713         (v) == 5 ? ND_PRINT("MCCA Setup Reply"): \
1714         (v) == 6 ? ND_PRINT("MCCA Advertisement Request"): \
1715         (v) == 7 ? ND_PRINT("MCCA Advertisement"): \
1716         (v) == 8 ? ND_PRINT("MCCA Teardown"): \
1717         (v) == 9 ? ND_PRINT("TBTT Adjustment Request"): \
1718         (v) == 10 ? ND_PRINT("TBTT Adjustment Response"): \
1719                    ND_PRINT("Act#%u", (v)))
1720 #define PRINT_MULTIHOP_ACTION(v) (\
1721         (v) == 0 ? ND_PRINT("Proxy Update"): \
1722         (v) == 1 ? ND_PRINT("Proxy Update Confirmation"): \
1723                    ND_PRINT("Act#%u", (v)))
1724 #define PRINT_SELFPROT_ACTION(v) (\
1725         (v) == 1 ? ND_PRINT("Peering Open"): \
1726         (v) == 2 ? ND_PRINT("Peering Confirm"): \
1727         (v) == 3 ? ND_PRINT("Peering Close"): \
1728         (v) == 4 ? ND_PRINT("Group Key Inform"): \
1729         (v) == 5 ? ND_PRINT("Group Key Acknowledge"): \
1730                    ND_PRINT("Act#%u", (v)))
1731
1732 static int
1733 handle_action(netdissect_options *ndo,
1734               const uint8_t *src, const u_char *p, u_int length)
1735 {
1736         ND_TCHECK_2(p);
1737         if (length < 2)
1738                 goto trunc;
1739         if (ndo->ndo_eflag) {
1740                 ND_PRINT(": ");
1741         } else {
1742                 ND_PRINT(" (%s): ", GET_ETHERADDR_STRING(src));
1743         }
1744         switch (GET_U_1(p)) {
1745         case 0: ND_PRINT("Spectrum Management Act#%u", GET_U_1(p + 1)); break;
1746         case 1: ND_PRINT("QoS Act#%u", GET_U_1(p + 1)); break;
1747         case 2: ND_PRINT("DLS Act#%u", GET_U_1(p + 1)); break;
1748         case 3: ND_PRINT("BA "); PRINT_BA_ACTION(GET_U_1(p + 1)); break;
1749         case 7: ND_PRINT("HT "); PRINT_HT_ACTION(GET_U_1(p + 1)); break;
1750         case 13: ND_PRINT("MeshAction "); PRINT_MESH_ACTION(GET_U_1(p + 1)); break;
1751         case 14:
1752                 ND_PRINT("MultiohopAction ");
1753                 PRINT_MULTIHOP_ACTION(GET_U_1(p + 1)); break;
1754         case 15:
1755                 ND_PRINT("SelfprotectAction ");
1756                 PRINT_SELFPROT_ACTION(GET_U_1(p + 1)); break;
1757         case 127: ND_PRINT("Vendor Act#%u", GET_U_1(p + 1)); break;
1758         default:
1759                 ND_PRINT("Reserved(%u) Act#%u", GET_U_1(p), GET_U_1(p + 1));
1760                 break;
1761         }
1762         return 1;
1763 trunc:
1764         return 0;
1765 }
1766
1767
1768 /*********************************************************************************
1769  * Print Body funcs
1770  *********************************************************************************/
1771
1772
1773 static int
1774 mgmt_body_print(netdissect_options *ndo,
1775                 uint16_t fc, const uint8_t *src, const u_char *p, u_int length)
1776 {
1777         ND_PRINT("%s", tok2str(st_str, "Unhandled Management subtype(%x)", FC_SUBTYPE(fc)));
1778
1779         /* There may be a problem w/ AP not having this bit set */
1780         if (FC_PROTECTED(fc))
1781                 return wep_print(ndo, p);
1782         switch (FC_SUBTYPE(fc)) {
1783         case ST_ASSOC_REQUEST:
1784                 return handle_assoc_request(ndo, p, length);
1785         case ST_ASSOC_RESPONSE:
1786                 return handle_assoc_response(ndo, p, length);
1787         case ST_REASSOC_REQUEST:
1788                 return handle_reassoc_request(ndo, p, length);
1789         case ST_REASSOC_RESPONSE:
1790                 return handle_reassoc_response(ndo, p, length);
1791         case ST_PROBE_REQUEST:
1792                 return handle_probe_request(ndo, p, length);
1793         case ST_PROBE_RESPONSE:
1794                 return handle_probe_response(ndo, p, length);
1795         case ST_BEACON:
1796                 return handle_beacon(ndo, p, length);
1797         case ST_ATIM:
1798                 return handle_atim();
1799         case ST_DISASSOC:
1800                 return handle_disassoc(ndo, p, length);
1801         case ST_AUTH:
1802                 return handle_auth(ndo, p, length);
1803         case ST_DEAUTH:
1804                 return handle_deauth(ndo, src, p, length);
1805         case ST_ACTION:
1806                 return handle_action(ndo, src, p, length);
1807         default:
1808                 return 1;
1809         }
1810 }
1811
1812
1813 /*********************************************************************************
1814  * Handles printing all the control frame types
1815  *********************************************************************************/
1816
1817 static int
1818 ctrl_body_print(netdissect_options *ndo,
1819                 uint16_t fc, const u_char *p)
1820 {
1821         ND_PRINT("%s", tok2str(ctrl_str, "Unknown Ctrl Subtype", FC_SUBTYPE(fc)));
1822         switch (FC_SUBTYPE(fc)) {
1823         case CTRL_CONTROL_WRAPPER:
1824                 /* XXX - requires special handling */
1825                 break;
1826         case CTRL_BAR:
1827                 ND_TCHECK_LEN(p, CTRL_BAR_HDRLEN);
1828                 if (!ndo->ndo_eflag)
1829                         ND_PRINT(" RA:%s TA:%s CTL(%x) SEQ(%u) ",
1830                             GET_ETHERADDR_STRING(((const struct ctrl_bar_hdr_t *)p)->ra),
1831                             GET_ETHERADDR_STRING(((const struct ctrl_bar_hdr_t *)p)->ta),
1832                             GET_LE_U_2(((const struct ctrl_bar_hdr_t *)p)->ctl),
1833                             GET_LE_U_2(((const struct ctrl_bar_hdr_t *)p)->seq));
1834                 break;
1835         case CTRL_BA:
1836                 ND_TCHECK_LEN(p, CTRL_BA_HDRLEN);
1837                 if (!ndo->ndo_eflag)
1838                         ND_PRINT(" RA:%s ",
1839                             GET_ETHERADDR_STRING(((const struct ctrl_ba_hdr_t *)p)->ra));
1840                 break;
1841         case CTRL_PS_POLL:
1842                 ND_TCHECK_LEN(p, CTRL_PS_POLL_HDRLEN);
1843                 ND_PRINT(" AID(%x)",
1844                     GET_LE_U_2(((const struct ctrl_ps_poll_hdr_t *)p)->aid));
1845                 break;
1846         case CTRL_RTS:
1847                 ND_TCHECK_LEN(p, CTRL_RTS_HDRLEN);
1848                 if (!ndo->ndo_eflag)
1849                         ND_PRINT(" TA:%s ",
1850                             GET_ETHERADDR_STRING(((const struct ctrl_rts_hdr_t *)p)->ta));
1851                 break;
1852         case CTRL_CTS:
1853                 ND_TCHECK_LEN(p, CTRL_CTS_HDRLEN);
1854                 if (!ndo->ndo_eflag)
1855                         ND_PRINT(" RA:%s ",
1856                             GET_ETHERADDR_STRING(((const struct ctrl_cts_hdr_t *)p)->ra));
1857                 break;
1858         case CTRL_ACK:
1859                 ND_TCHECK_LEN(p, CTRL_ACK_HDRLEN);
1860                 if (!ndo->ndo_eflag)
1861                         ND_PRINT(" RA:%s ",
1862                             GET_ETHERADDR_STRING(((const struct ctrl_ack_hdr_t *)p)->ra));
1863                 break;
1864         case CTRL_CF_END:
1865                 ND_TCHECK_LEN(p, CTRL_END_HDRLEN);
1866                 if (!ndo->ndo_eflag)
1867                         ND_PRINT(" RA:%s ",
1868                             GET_ETHERADDR_STRING(((const struct ctrl_end_hdr_t *)p)->ra));
1869                 break;
1870         case CTRL_END_ACK:
1871                 ND_TCHECK_LEN(p, CTRL_END_ACK_HDRLEN);
1872                 if (!ndo->ndo_eflag)
1873                         ND_PRINT(" RA:%s ",
1874                             GET_ETHERADDR_STRING(((const struct ctrl_end_ack_hdr_t *)p)->ra));
1875                 break;
1876         }
1877         return 1;
1878 trunc:
1879         return 0;
1880 }
1881
1882 /*
1883  *  Data Frame - Address field contents
1884  *
1885  *  To Ds  | From DS | Addr 1 | Addr 2 | Addr 3 | Addr 4
1886  *    0    |  0      |  DA    | SA     | BSSID  | n/a
1887  *    0    |  1      |  DA    | BSSID  | SA     | n/a
1888  *    1    |  0      |  BSSID | SA     | DA     | n/a
1889  *    1    |  1      |  RA    | TA     | DA     | SA
1890  */
1891
1892 /*
1893  * Function to get source and destination MAC addresses for a data frame.
1894  */
1895 static void
1896 get_data_src_dst_mac(uint16_t fc, const u_char *p, const uint8_t **srcp,
1897                      const uint8_t **dstp)
1898 {
1899 #define ADDR1  (p + 4)
1900 #define ADDR2  (p + 10)
1901 #define ADDR3  (p + 16)
1902 #define ADDR4  (p + 24)
1903
1904         if (!FC_TO_DS(fc)) {
1905                 if (!FC_FROM_DS(fc)) {
1906                         /* not To DS and not From DS */
1907                         *srcp = ADDR2;
1908                         *dstp = ADDR1;
1909                 } else {
1910                         /* not To DS and From DS */
1911                         *srcp = ADDR3;
1912                         *dstp = ADDR1;
1913                 }
1914         } else {
1915                 if (!FC_FROM_DS(fc)) {
1916                         /* To DS and not From DS */
1917                         *srcp = ADDR2;
1918                         *dstp = ADDR3;
1919                 } else {
1920                         /* To DS and From DS */
1921                         *srcp = ADDR4;
1922                         *dstp = ADDR3;
1923                 }
1924         }
1925
1926 #undef ADDR1
1927 #undef ADDR2
1928 #undef ADDR3
1929 #undef ADDR4
1930 }
1931
1932 static void
1933 get_mgmt_src_dst_mac(const u_char *p, const uint8_t **srcp, const uint8_t **dstp)
1934 {
1935         const struct mgmt_header_t *hp = (const struct mgmt_header_t *) p;
1936
1937         if (srcp != NULL)
1938                 *srcp = hp->sa;
1939         if (dstp != NULL)
1940                 *dstp = hp->da;
1941 }
1942
1943 /*
1944  * Print Header funcs
1945  */
1946
1947 static void
1948 data_header_print(netdissect_options *ndo, uint16_t fc, const u_char *p)
1949 {
1950         u_int subtype = FC_SUBTYPE(fc);
1951
1952         if (DATA_FRAME_IS_CF_ACK(subtype) || DATA_FRAME_IS_CF_POLL(subtype) ||
1953             DATA_FRAME_IS_QOS(subtype)) {
1954                 ND_PRINT("CF ");
1955                 if (DATA_FRAME_IS_CF_ACK(subtype)) {
1956                         if (DATA_FRAME_IS_CF_POLL(subtype))
1957                                 ND_PRINT("Ack/Poll");
1958                         else
1959                                 ND_PRINT("Ack");
1960                 } else {
1961                         if (DATA_FRAME_IS_CF_POLL(subtype))
1962                                 ND_PRINT("Poll");
1963                 }
1964                 if (DATA_FRAME_IS_QOS(subtype))
1965                         ND_PRINT("+QoS");
1966                 ND_PRINT(" ");
1967         }
1968
1969 #define ADDR1  (p + 4)
1970 #define ADDR2  (p + 10)
1971 #define ADDR3  (p + 16)
1972 #define ADDR4  (p + 24)
1973
1974         if (!FC_TO_DS(fc) && !FC_FROM_DS(fc)) {
1975                 ND_PRINT("DA:%s SA:%s BSSID:%s ",
1976                     GET_ETHERADDR_STRING(ADDR1), GET_ETHERADDR_STRING(ADDR2),
1977                     GET_ETHERADDR_STRING(ADDR3));
1978         } else if (!FC_TO_DS(fc) && FC_FROM_DS(fc)) {
1979                 ND_PRINT("DA:%s BSSID:%s SA:%s ",
1980                     GET_ETHERADDR_STRING(ADDR1), GET_ETHERADDR_STRING(ADDR2),
1981                     GET_ETHERADDR_STRING(ADDR3));
1982         } else if (FC_TO_DS(fc) && !FC_FROM_DS(fc)) {
1983                 ND_PRINT("BSSID:%s SA:%s DA:%s ",
1984                     GET_ETHERADDR_STRING(ADDR1), GET_ETHERADDR_STRING(ADDR2),
1985                     GET_ETHERADDR_STRING(ADDR3));
1986         } else if (FC_TO_DS(fc) && FC_FROM_DS(fc)) {
1987                 ND_PRINT("RA:%s TA:%s DA:%s SA:%s ",
1988                     GET_ETHERADDR_STRING(ADDR1), GET_ETHERADDR_STRING(ADDR2),
1989                     GET_ETHERADDR_STRING(ADDR3), GET_ETHERADDR_STRING(ADDR4));
1990         }
1991
1992 #undef ADDR1
1993 #undef ADDR2
1994 #undef ADDR3
1995 #undef ADDR4
1996 }
1997
1998 static void
1999 mgmt_header_print(netdissect_options *ndo, const u_char *p)
2000 {
2001         const struct mgmt_header_t *hp = (const struct mgmt_header_t *) p;
2002
2003         ND_PRINT("BSSID:%s DA:%s SA:%s ",
2004             GET_ETHERADDR_STRING((hp)->bssid), GET_ETHERADDR_STRING((hp)->da),
2005             GET_ETHERADDR_STRING((hp)->sa));
2006 }
2007
2008 static void
2009 ctrl_header_print(netdissect_options *ndo, uint16_t fc, const u_char *p)
2010 {
2011         switch (FC_SUBTYPE(fc)) {
2012         case CTRL_BAR:
2013                 ND_PRINT(" RA:%s TA:%s CTL(%x) SEQ(%u) ",
2014                     GET_ETHERADDR_STRING(((const struct ctrl_bar_hdr_t *)p)->ra),
2015                     GET_ETHERADDR_STRING(((const struct ctrl_bar_hdr_t *)p)->ta),
2016                     GET_LE_U_2(((const struct ctrl_bar_hdr_t *)p)->ctl),
2017                     GET_LE_U_2(((const struct ctrl_bar_hdr_t *)p)->seq));
2018                 break;
2019         case CTRL_BA:
2020                 ND_PRINT("RA:%s ",
2021                     GET_ETHERADDR_STRING(((const struct ctrl_ba_hdr_t *)p)->ra));
2022                 break;
2023         case CTRL_PS_POLL:
2024                 ND_PRINT("BSSID:%s TA:%s ",
2025                     GET_ETHERADDR_STRING(((const struct ctrl_ps_poll_hdr_t *)p)->bssid),
2026                     GET_ETHERADDR_STRING(((const struct ctrl_ps_poll_hdr_t *)p)->ta));
2027                 break;
2028         case CTRL_RTS:
2029                 ND_PRINT("RA:%s TA:%s ",
2030                     GET_ETHERADDR_STRING(((const struct ctrl_rts_hdr_t *)p)->ra),
2031                     GET_ETHERADDR_STRING(((const struct ctrl_rts_hdr_t *)p)->ta));
2032                 break;
2033         case CTRL_CTS:
2034                 ND_PRINT("RA:%s ",
2035                     GET_ETHERADDR_STRING(((const struct ctrl_cts_hdr_t *)p)->ra));
2036                 break;
2037         case CTRL_ACK:
2038                 ND_PRINT("RA:%s ",
2039                     GET_ETHERADDR_STRING(((const struct ctrl_ack_hdr_t *)p)->ra));
2040                 break;
2041         case CTRL_CF_END:
2042                 ND_PRINT("RA:%s BSSID:%s ",
2043                     GET_ETHERADDR_STRING(((const struct ctrl_end_hdr_t *)p)->ra),
2044                     GET_ETHERADDR_STRING(((const struct ctrl_end_hdr_t *)p)->bssid));
2045                 break;
2046         case CTRL_END_ACK:
2047                 ND_PRINT("RA:%s BSSID:%s ",
2048                     GET_ETHERADDR_STRING(((const struct ctrl_end_ack_hdr_t *)p)->ra),
2049                     GET_ETHERADDR_STRING(((const struct ctrl_end_ack_hdr_t *)p)->bssid));
2050                 break;
2051         default:
2052                 /* We shouldn't get here - we should already have quit */
2053                 break;
2054         }
2055 }
2056
2057 static int
2058 extract_header_length(netdissect_options *ndo,
2059                       uint16_t fc)
2060 {
2061         int len;
2062
2063         switch (FC_TYPE(fc)) {
2064         case T_MGMT:
2065                 return MGMT_HDRLEN;
2066         case T_CTRL:
2067                 switch (FC_SUBTYPE(fc)) {
2068                 case CTRL_CONTROL_WRAPPER:
2069                         return CTRL_CONTROL_WRAPPER_HDRLEN;
2070                 case CTRL_BAR:
2071                         return CTRL_BAR_HDRLEN;
2072                 case CTRL_BA:
2073                         return CTRL_BA_HDRLEN;
2074                 case CTRL_PS_POLL:
2075                         return CTRL_PS_POLL_HDRLEN;
2076                 case CTRL_RTS:
2077                         return CTRL_RTS_HDRLEN;
2078                 case CTRL_CTS:
2079                         return CTRL_CTS_HDRLEN;
2080                 case CTRL_ACK:
2081                         return CTRL_ACK_HDRLEN;
2082                 case CTRL_CF_END:
2083                         return CTRL_END_HDRLEN;
2084                 case CTRL_END_ACK:
2085                         return CTRL_END_ACK_HDRLEN;
2086                 default:
2087                         ND_PRINT("unknown 802.11 ctrl frame subtype (%u)", FC_SUBTYPE(fc));
2088                         return 0;
2089                 }
2090         case T_DATA:
2091                 len = (FC_TO_DS(fc) && FC_FROM_DS(fc)) ? 30 : 24;
2092                 if (DATA_FRAME_IS_QOS(FC_SUBTYPE(fc)))
2093                         len += 2;
2094                 return len;
2095         default:
2096                 ND_PRINT("unknown 802.11 frame type (%u)", FC_TYPE(fc));
2097                 return 0;
2098         }
2099 }
2100
2101 static int
2102 extract_mesh_header_length(netdissect_options *ndo, const u_char *p)
2103 {
2104         return (GET_U_1(p) &~ 3) ? 0 : 6*(1 + (GET_U_1(p) & 3));
2105 }
2106
2107 /*
2108  * Print the 802.11 MAC header.
2109  */
2110 static void
2111 ieee_802_11_hdr_print(netdissect_options *ndo,
2112                       uint16_t fc, const u_char *p, u_int hdrlen,
2113                       u_int meshdrlen)
2114 {
2115         if (ndo->ndo_vflag) {
2116                 if (FC_MORE_DATA(fc))
2117                         ND_PRINT("More Data ");
2118                 if (FC_MORE_FLAG(fc))
2119                         ND_PRINT("More Fragments ");
2120                 if (FC_POWER_MGMT(fc))
2121                         ND_PRINT("Pwr Mgmt ");
2122                 if (FC_RETRY(fc))
2123                         ND_PRINT("Retry ");
2124                 if (FC_ORDER(fc))
2125                         ND_PRINT("Strictly Ordered ");
2126                 if (FC_PROTECTED(fc))
2127                         ND_PRINT("Protected ");
2128                 if (FC_TYPE(fc) != T_CTRL || FC_SUBTYPE(fc) != CTRL_PS_POLL)
2129                         ND_PRINT("%uus ",
2130                             GET_LE_U_2(((const struct mgmt_header_t *)p)->duration));
2131         }
2132         if (meshdrlen != 0) {
2133                 const struct meshcntl_t *mc =
2134                     (const struct meshcntl_t *)(p + hdrlen - meshdrlen);
2135                 u_int ae = GET_U_1(mc->flags) & 3;
2136
2137                 ND_PRINT("MeshData (AE %u TTL %u seq %u", ae,
2138                     GET_U_1(mc->ttl), GET_LE_U_4(mc->seq));
2139                 if (ae > 0)
2140                         ND_PRINT(" A4:%s", GET_ETHERADDR_STRING(mc->addr4));
2141                 if (ae > 1)
2142                         ND_PRINT(" A5:%s", GET_ETHERADDR_STRING(mc->addr5));
2143                 if (ae > 2)
2144                         ND_PRINT(" A6:%s", GET_ETHERADDR_STRING(mc->addr6));
2145                 ND_PRINT(") ");
2146         }
2147
2148         switch (FC_TYPE(fc)) {
2149         case T_MGMT:
2150                 mgmt_header_print(ndo, p);
2151                 break;
2152         case T_CTRL:
2153                 ctrl_header_print(ndo, fc, p);
2154                 break;
2155         case T_DATA:
2156                 data_header_print(ndo, fc, p);
2157                 break;
2158         default:
2159                 break;
2160         }
2161 }
2162
2163 static u_int
2164 ieee802_11_print(netdissect_options *ndo,
2165                  const u_char *p, u_int length, u_int orig_caplen, int pad,
2166                  u_int fcslen)
2167 {
2168         uint16_t fc;
2169         u_int caplen, hdrlen, meshdrlen;
2170         struct lladdr_info src, dst;
2171         int llc_hdrlen;
2172
2173         ndo->ndo_protocol = "802.11";
2174         caplen = orig_caplen;
2175         /* Remove FCS, if present */
2176         if (length < fcslen) {
2177                 nd_print_trunc(ndo);
2178                 return caplen;
2179         }
2180         length -= fcslen;
2181         if (caplen > length) {
2182                 /* Amount of FCS in actual packet data, if any */
2183                 fcslen = caplen - length;
2184                 caplen -= fcslen;
2185                 ndo->ndo_snapend -= fcslen;
2186         }
2187
2188         if (caplen < IEEE802_11_FC_LEN) {
2189                 nd_print_trunc(ndo);
2190                 return orig_caplen;
2191         }
2192
2193         fc = GET_LE_U_2(p);
2194         hdrlen = extract_header_length(ndo, fc);
2195         if (hdrlen == 0) {
2196                 /* Unknown frame type or control frame subtype; quit. */
2197                 return (0);
2198         }
2199         if (pad)
2200                 hdrlen = roundup2(hdrlen, 4);
2201         if (ndo->ndo_Hflag && FC_TYPE(fc) == T_DATA &&
2202             DATA_FRAME_IS_QOS(FC_SUBTYPE(fc))) {
2203                 if(!ND_TTEST_1(p + hdrlen)) {
2204                         nd_print_trunc(ndo);
2205                         return hdrlen;
2206                 }
2207                 meshdrlen = extract_mesh_header_length(ndo, p + hdrlen);
2208                 hdrlen += meshdrlen;
2209         } else
2210                 meshdrlen = 0;
2211
2212         if (caplen < hdrlen) {
2213                 nd_print_trunc(ndo);
2214                 return hdrlen;
2215         }
2216
2217         if (ndo->ndo_eflag)
2218                 ieee_802_11_hdr_print(ndo, fc, p, hdrlen, meshdrlen);
2219
2220         /*
2221          * Go past the 802.11 header.
2222          */
2223         length -= hdrlen;
2224         caplen -= hdrlen;
2225         p += hdrlen;
2226
2227         src.addr_string = etheraddr_string;
2228         dst.addr_string = etheraddr_string;
2229         switch (FC_TYPE(fc)) {
2230         case T_MGMT:
2231                 get_mgmt_src_dst_mac(p - hdrlen, &src.addr, &dst.addr);
2232                 if (!mgmt_body_print(ndo, fc, src.addr, p, length)) {
2233                         nd_print_trunc(ndo);
2234                         return hdrlen;
2235                 }
2236                 break;
2237         case T_CTRL:
2238                 if (!ctrl_body_print(ndo, fc, p - hdrlen)) {
2239                         nd_print_trunc(ndo);
2240                         return hdrlen;
2241                 }
2242                 break;
2243         case T_DATA:
2244                 if (DATA_FRAME_IS_NULL(FC_SUBTYPE(fc)))
2245                         return hdrlen;  /* no-data frame */
2246                 /* There may be a problem w/ AP not having this bit set */
2247                 if (FC_PROTECTED(fc)) {
2248                         ND_PRINT("Data");
2249                         if (!wep_print(ndo, p)) {
2250                                 nd_print_trunc(ndo);
2251                                 return hdrlen;
2252                         }
2253                 } else {
2254                         get_data_src_dst_mac(fc, p - hdrlen, &src.addr, &dst.addr);
2255                         llc_hdrlen = llc_print(ndo, p, length, caplen, &src, &dst);
2256                         if (llc_hdrlen < 0) {
2257                                 /*
2258                                  * Some kinds of LLC packet we cannot
2259                                  * handle intelligently
2260                                  */
2261                                 if (!ndo->ndo_suppress_default_print)
2262                                         ND_DEFAULTPRINT(p, caplen);
2263                                 llc_hdrlen = -llc_hdrlen;
2264                         }
2265                         hdrlen += llc_hdrlen;
2266                 }
2267                 break;
2268         default:
2269                 /* We shouldn't get here - we should already have quit */
2270                 break;
2271         }
2272
2273         return hdrlen;
2274 }
2275
2276 /*
2277  * This is the top level routine of the printer.  'p' points
2278  * to the 802.11 header of the packet, 'h->ts' is the timestamp,
2279  * 'h->len' is the length of the packet off the wire, and 'h->caplen'
2280  * is the number of bytes actually captured.
2281  */
2282 void
2283 ieee802_11_if_print(netdissect_options *ndo,
2284                     const struct pcap_pkthdr *h, const u_char *p)
2285 {
2286         ndo->ndo_protocol = "802.11";
2287         ndo->ndo_ll_hdr_len += ieee802_11_print(ndo, p, h->len, h->caplen, 0, 0);
2288 }
2289
2290
2291 /* $FreeBSD: projects/clang400-import/contrib/tcpdump/print-802_11.c 276788 2015-01-07 19:55:18Z delphij $ */
2292 /* NetBSD: ieee802_11_radio.h,v 1.2 2006/02/26 03:04:03 dyoung Exp  */
2293
2294 /*-
2295  * Copyright (c) 2003, 2004 David Young.  All rights reserved.
2296  *
2297  * Redistribution and use in source and binary forms, with or without
2298  * modification, are permitted provided that the following conditions
2299  * are met:
2300  * 1. Redistributions of source code must retain the above copyright
2301  *    notice, this list of conditions and the following disclaimer.
2302  * 2. Redistributions in binary form must reproduce the above copyright
2303  *    notice, this list of conditions and the following disclaimer in the
2304  *    documentation and/or other materials provided with the distribution.
2305  * 3. The name of David Young may not be used to endorse or promote
2306  *    products derived from this software without specific prior
2307  *    written permission.
2308  *
2309  * THIS SOFTWARE IS PROVIDED BY DAVID YOUNG ``AS IS'' AND ANY
2310  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
2311  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
2312  * PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL DAVID
2313  * YOUNG BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
2314  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
2315  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2316  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
2317  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
2318  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2319  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
2320  * OF SUCH DAMAGE.
2321  */
2322
2323 /* A generic radio capture format is desirable. It must be
2324  * rigidly defined (e.g., units for fields should be given),
2325  * and easily extensible.
2326  *
2327  * The following is an extensible radio capture format. It is
2328  * based on a bitmap indicating which fields are present.
2329  *
2330  * I am trying to describe precisely what the application programmer
2331  * should expect in the following, and for that reason I tell the
2332  * units and origin of each measurement (where it applies), or else I
2333  * use sufficiently weaselly language ("is a monotonically nondecreasing
2334  * function of...") that I cannot set false expectations for lawyerly
2335  * readers.
2336  */
2337
2338 /*
2339  * The radio capture header precedes the 802.11 header.
2340  *
2341  * Note well: all radiotap fields are little-endian.
2342  */
2343 struct ieee80211_radiotap_header {
2344         nd_uint8_t      it_version;     /* Version 0. Only increases
2345                                          * for drastic changes,
2346                                          * introduction of compatible
2347                                          * new fields does not count.
2348                                          */
2349         nd_uint8_t      it_pad;
2350         nd_uint16_t     it_len;         /* length of the whole
2351                                          * header in bytes, including
2352                                          * it_version, it_pad,
2353                                          * it_len, and data fields.
2354                                          */
2355         nd_uint32_t     it_present;     /* A bitmap telling which
2356                                          * fields are present. Set bit 31
2357                                          * (0x80000000) to extend the
2358                                          * bitmap by another 32 bits.
2359                                          * Additional extensions are made
2360                                          * by setting bit 31.
2361                                          */
2362 };
2363
2364 /* Name                                 Data type       Units
2365  * ----                                 ---------       -----
2366  *
2367  * IEEE80211_RADIOTAP_TSFT              uint64_t       microseconds
2368  *
2369  *      Value in microseconds of the MAC's 64-bit 802.11 Time
2370  *      Synchronization Function timer when the first bit of the
2371  *      MPDU arrived at the MAC. For received frames, only.
2372  *
2373  * IEEE80211_RADIOTAP_CHANNEL           2 x uint16_t   MHz, bitmap
2374  *
2375  *      Tx/Rx frequency in MHz, followed by flags (see below).
2376  *      Note that IEEE80211_RADIOTAP_XCHANNEL must be used to
2377  *      represent an HT channel as there is not enough room in
2378  *      the flags word.
2379  *
2380  * IEEE80211_RADIOTAP_FHSS              uint16_t       see below
2381  *
2382  *      For frequency-hopping radios, the hop set (first byte)
2383  *      and pattern (second byte).
2384  *
2385  * IEEE80211_RADIOTAP_RATE              uint8_t        500kb/s or index
2386  *
2387  *      Tx/Rx data rate.  If bit 0x80 is set then it represents an
2388  *      an MCS index and not an IEEE rate.
2389  *
2390  * IEEE80211_RADIOTAP_DBM_ANTSIGNAL     int8_t         decibels from
2391  *                                                     one milliwatt (dBm)
2392  *
2393  *      RF signal power at the antenna, decibel difference from
2394  *      one milliwatt.
2395  *
2396  * IEEE80211_RADIOTAP_DBM_ANTNOISE      int8_t         decibels from
2397  *                                                     one milliwatt (dBm)
2398  *
2399  *      RF noise power at the antenna, decibel difference from one
2400  *      milliwatt.
2401  *
2402  * IEEE80211_RADIOTAP_DB_ANTSIGNAL      uint8_t        decibel (dB)
2403  *
2404  *      RF signal power at the antenna, decibel difference from an
2405  *      arbitrary, fixed reference.
2406  *
2407  * IEEE80211_RADIOTAP_DB_ANTNOISE       uint8_t        decibel (dB)
2408  *
2409  *      RF noise power at the antenna, decibel difference from an
2410  *      arbitrary, fixed reference point.
2411  *
2412  * IEEE80211_RADIOTAP_LOCK_QUALITY      uint16_t       unitless
2413  *
2414  *      Quality of Barker code lock. Unitless. Monotonically
2415  *      nondecreasing with "better" lock strength. Called "Signal
2416  *      Quality" in datasheets.  (Is there a standard way to measure
2417  *      this?)
2418  *
2419  * IEEE80211_RADIOTAP_TX_ATTENUATION    uint16_t       unitless
2420  *
2421  *      Transmit power expressed as unitless distance from max
2422  *      power set at factory calibration.  0 is max power.
2423  *      Monotonically nondecreasing with lower power levels.
2424  *
2425  * IEEE80211_RADIOTAP_DB_TX_ATTENUATION uint16_t       decibels (dB)
2426  *
2427  *      Transmit power expressed as decibel distance from max power
2428  *      set at factory calibration.  0 is max power.  Monotonically
2429  *      nondecreasing with lower power levels.
2430  *
2431  * IEEE80211_RADIOTAP_DBM_TX_POWER      int8_t         decibels from
2432  *                                                     one milliwatt (dBm)
2433  *
2434  *      Transmit power expressed as dBm (decibels from a 1 milliwatt
2435  *      reference). This is the absolute power level measured at
2436  *      the antenna port.
2437  *
2438  * IEEE80211_RADIOTAP_FLAGS             uint8_t        bitmap
2439  *
2440  *      Properties of transmitted and received frames. See flags
2441  *      defined below.
2442  *
2443  * IEEE80211_RADIOTAP_ANTENNA           uint8_t        antenna index
2444  *
2445  *      Unitless indication of the Rx/Tx antenna for this packet.
2446  *      The first antenna is antenna 0.
2447  *
2448  * IEEE80211_RADIOTAP_RX_FLAGS          uint16_t       bitmap
2449  *
2450  *     Properties of received frames. See flags defined below.
2451  *
2452  * IEEE80211_RADIOTAP_XCHANNEL          uint32_t       bitmap
2453  *                                      uint16_t       MHz
2454  *                                      uint8_t        channel number
2455  *                                      uint8_t        .5 dBm
2456  *
2457  *      Extended channel specification: flags (see below) followed by
2458  *      frequency in MHz, the corresponding IEEE channel number, and
2459  *      finally the maximum regulatory transmit power cap in .5 dBm
2460  *      units.  This property supersedes IEEE80211_RADIOTAP_CHANNEL
2461  *      and only one of the two should be present.
2462  *
2463  * IEEE80211_RADIOTAP_MCS               uint8_t        known
2464  *                                      uint8_t        flags
2465  *                                      uint8_t        mcs
2466  *
2467  *      Bitset indicating which fields have known values, followed
2468  *      by bitset of flag values, followed by the MCS rate index as
2469  *      in IEEE 802.11n.
2470  *
2471  *
2472  * IEEE80211_RADIOTAP_AMPDU_STATUS      u32, u16, u8, u8        unitless
2473  *
2474  *      Contains the AMPDU information for the subframe.
2475  *
2476  * IEEE80211_RADIOTAP_VHT       u16, u8, u8, u8[4], u8, u8, u16
2477  *
2478  *      Contains VHT information about this frame.
2479  *
2480  * IEEE80211_RADIOTAP_VENDOR_NAMESPACE
2481  *                                      uint8_t  OUI[3]
2482  *                                      uint8_t        subspace
2483  *                                      uint16_t       length
2484  *
2485  *     The Vendor Namespace Field contains three sub-fields. The first
2486  *     sub-field is 3 bytes long. It contains the vendor's IEEE 802
2487  *     Organizationally Unique Identifier (OUI). The fourth byte is a
2488  *     vendor-specific "namespace selector."
2489  *
2490  */
2491 enum ieee80211_radiotap_type {
2492         IEEE80211_RADIOTAP_TSFT = 0,
2493         IEEE80211_RADIOTAP_FLAGS = 1,
2494         IEEE80211_RADIOTAP_RATE = 2,
2495         IEEE80211_RADIOTAP_CHANNEL = 3,
2496         IEEE80211_RADIOTAP_FHSS = 4,
2497         IEEE80211_RADIOTAP_DBM_ANTSIGNAL = 5,
2498         IEEE80211_RADIOTAP_DBM_ANTNOISE = 6,
2499         IEEE80211_RADIOTAP_LOCK_QUALITY = 7,
2500         IEEE80211_RADIOTAP_TX_ATTENUATION = 8,
2501         IEEE80211_RADIOTAP_DB_TX_ATTENUATION = 9,
2502         IEEE80211_RADIOTAP_DBM_TX_POWER = 10,
2503         IEEE80211_RADIOTAP_ANTENNA = 11,
2504         IEEE80211_RADIOTAP_DB_ANTSIGNAL = 12,
2505         IEEE80211_RADIOTAP_DB_ANTNOISE = 13,
2506         IEEE80211_RADIOTAP_RX_FLAGS = 14,
2507         /* NB: gap for netbsd definitions */
2508         IEEE80211_RADIOTAP_XCHANNEL = 18,
2509         IEEE80211_RADIOTAP_MCS = 19,
2510         IEEE80211_RADIOTAP_AMPDU_STATUS = 20,
2511         IEEE80211_RADIOTAP_VHT = 21,
2512         IEEE80211_RADIOTAP_NAMESPACE = 29,
2513         IEEE80211_RADIOTAP_VENDOR_NAMESPACE = 30,
2514         IEEE80211_RADIOTAP_EXT = 31
2515 };
2516
2517 /* channel attributes */
2518 #define IEEE80211_CHAN_TURBO    0x00010 /* Turbo channel */
2519 #define IEEE80211_CHAN_CCK      0x00020 /* CCK channel */
2520 #define IEEE80211_CHAN_OFDM     0x00040 /* OFDM channel */
2521 #define IEEE80211_CHAN_2GHZ     0x00080 /* 2 GHz spectrum channel. */
2522 #define IEEE80211_CHAN_5GHZ     0x00100 /* 5 GHz spectrum channel */
2523 #define IEEE80211_CHAN_PASSIVE  0x00200 /* Only passive scan allowed */
2524 #define IEEE80211_CHAN_DYN      0x00400 /* Dynamic CCK-OFDM channel */
2525 #define IEEE80211_CHAN_GFSK     0x00800 /* GFSK channel (FHSS PHY) */
2526 #define IEEE80211_CHAN_GSM      0x01000 /* 900 MHz spectrum channel */
2527 #define IEEE80211_CHAN_STURBO   0x02000 /* 11a static turbo channel only */
2528 #define IEEE80211_CHAN_HALF     0x04000 /* Half rate channel */
2529 #define IEEE80211_CHAN_QUARTER  0x08000 /* Quarter rate channel */
2530 #define IEEE80211_CHAN_HT20     0x10000 /* HT 20 channel */
2531 #define IEEE80211_CHAN_HT40U    0x20000 /* HT 40 channel w/ ext above */
2532 #define IEEE80211_CHAN_HT40D    0x40000 /* HT 40 channel w/ ext below */
2533
2534 /* Useful combinations of channel characteristics, borrowed from Ethereal */
2535 #define IEEE80211_CHAN_A \
2536         (IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM)
2537 #define IEEE80211_CHAN_B \
2538         (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_CCK)
2539 #define IEEE80211_CHAN_G \
2540         (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_DYN)
2541 #define IEEE80211_CHAN_TA \
2542         (IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM | IEEE80211_CHAN_TURBO)
2543 #define IEEE80211_CHAN_TG \
2544         (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_DYN  | IEEE80211_CHAN_TURBO)
2545
2546
2547 /* For IEEE80211_RADIOTAP_FLAGS */
2548 #define IEEE80211_RADIOTAP_F_CFP        0x01    /* sent/received
2549                                                  * during CFP
2550                                                  */
2551 #define IEEE80211_RADIOTAP_F_SHORTPRE   0x02    /* sent/received
2552                                                  * with short
2553                                                  * preamble
2554                                                  */
2555 #define IEEE80211_RADIOTAP_F_WEP        0x04    /* sent/received
2556                                                  * with WEP encryption
2557                                                  */
2558 #define IEEE80211_RADIOTAP_F_FRAG       0x08    /* sent/received
2559                                                  * with fragmentation
2560                                                  */
2561 #define IEEE80211_RADIOTAP_F_FCS        0x10    /* frame includes FCS */
2562 #define IEEE80211_RADIOTAP_F_DATAPAD    0x20    /* frame has padding between
2563                                                  * 802.11 header and payload
2564                                                  * (to 32-bit boundary)
2565                                                  */
2566 #define IEEE80211_RADIOTAP_F_BADFCS     0x40    /* does not pass FCS check */
2567
2568 /* For IEEE80211_RADIOTAP_RX_FLAGS */
2569 #define IEEE80211_RADIOTAP_F_RX_BADFCS  0x0001  /* frame failed crc check */
2570 #define IEEE80211_RADIOTAP_F_RX_PLCP_CRC        0x0002  /* frame failed PLCP CRC check */
2571
2572 /* For IEEE80211_RADIOTAP_MCS known */
2573 #define IEEE80211_RADIOTAP_MCS_BANDWIDTH_KNOWN          0x01
2574 #define IEEE80211_RADIOTAP_MCS_MCS_INDEX_KNOWN          0x02    /* MCS index field */
2575 #define IEEE80211_RADIOTAP_MCS_GUARD_INTERVAL_KNOWN     0x04
2576 #define IEEE80211_RADIOTAP_MCS_HT_FORMAT_KNOWN          0x08
2577 #define IEEE80211_RADIOTAP_MCS_FEC_TYPE_KNOWN           0x10
2578 #define IEEE80211_RADIOTAP_MCS_STBC_KNOWN               0x20
2579 #define IEEE80211_RADIOTAP_MCS_NESS_KNOWN               0x40
2580 #define IEEE80211_RADIOTAP_MCS_NESS_BIT_1               0x80
2581
2582 /* For IEEE80211_RADIOTAP_MCS flags */
2583 #define IEEE80211_RADIOTAP_MCS_BANDWIDTH_MASK   0x03
2584 #define IEEE80211_RADIOTAP_MCS_BANDWIDTH_20     0
2585 #define IEEE80211_RADIOTAP_MCS_BANDWIDTH_40     1
2586 #define IEEE80211_RADIOTAP_MCS_BANDWIDTH_20L    2
2587 #define IEEE80211_RADIOTAP_MCS_BANDWIDTH_20U    3
2588 #define IEEE80211_RADIOTAP_MCS_SHORT_GI         0x04 /* short guard interval */
2589 #define IEEE80211_RADIOTAP_MCS_HT_GREENFIELD    0x08
2590 #define IEEE80211_RADIOTAP_MCS_FEC_LDPC         0x10
2591 #define IEEE80211_RADIOTAP_MCS_STBC_MASK        0x60
2592 #define         IEEE80211_RADIOTAP_MCS_STBC_1   1
2593 #define         IEEE80211_RADIOTAP_MCS_STBC_2   2
2594 #define         IEEE80211_RADIOTAP_MCS_STBC_3   3
2595 #define IEEE80211_RADIOTAP_MCS_STBC_SHIFT       5
2596 #define IEEE80211_RADIOTAP_MCS_NESS_BIT_0       0x80
2597
2598 /* For IEEE80211_RADIOTAP_AMPDU_STATUS */
2599 #define IEEE80211_RADIOTAP_AMPDU_REPORT_ZEROLEN         0x0001
2600 #define IEEE80211_RADIOTAP_AMPDU_IS_ZEROLEN             0x0002
2601 #define IEEE80211_RADIOTAP_AMPDU_LAST_KNOWN             0x0004
2602 #define IEEE80211_RADIOTAP_AMPDU_IS_LAST                0x0008
2603 #define IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_ERR          0x0010
2604 #define IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_KNOWN        0x0020
2605
2606 /* For IEEE80211_RADIOTAP_VHT known */
2607 #define IEEE80211_RADIOTAP_VHT_STBC_KNOWN                       0x0001
2608 #define IEEE80211_RADIOTAP_VHT_TXOP_PS_NA_KNOWN                 0x0002
2609 #define IEEE80211_RADIOTAP_VHT_GUARD_INTERVAL_KNOWN             0x0004
2610 #define IEEE80211_RADIOTAP_VHT_SGI_NSYM_DIS_KNOWN               0x0008
2611 #define IEEE80211_RADIOTAP_VHT_LDPC_EXTRA_OFDM_SYM_KNOWN        0x0010
2612 #define IEEE80211_RADIOTAP_VHT_BEAMFORMED_KNOWN                 0x0020
2613 #define IEEE80211_RADIOTAP_VHT_BANDWIDTH_KNOWN                  0x0040
2614 #define IEEE80211_RADIOTAP_VHT_GROUP_ID_KNOWN                   0x0080
2615 #define IEEE80211_RADIOTAP_VHT_PARTIAL_AID_KNOWN                0x0100
2616
2617 /* For IEEE80211_RADIOTAP_VHT flags */
2618 #define IEEE80211_RADIOTAP_VHT_STBC                     0x01
2619 #define IEEE80211_RADIOTAP_VHT_TXOP_PS_NA               0x02
2620 #define IEEE80211_RADIOTAP_VHT_SHORT_GI                 0x04
2621 #define IEEE80211_RADIOTAP_VHT_SGI_NSYM_M10_9           0x08
2622 #define IEEE80211_RADIOTAP_VHT_LDPC_EXTRA_OFDM_SYM      0x10
2623 #define IEEE80211_RADIOTAP_VHT_BEAMFORMED               0x20
2624
2625 #define IEEE80211_RADIOTAP_VHT_BANDWIDTH_MASK   0x1f
2626
2627 #define IEEE80211_RADIOTAP_VHT_NSS_MASK         0x0f
2628 #define IEEE80211_RADIOTAP_VHT_MCS_MASK         0xf0
2629 #define IEEE80211_RADIOTAP_VHT_MCS_SHIFT        4
2630
2631 #define IEEE80211_RADIOTAP_CODING_LDPC_USERn                    0x01
2632
2633 #define IEEE80211_CHAN_FHSS \
2634         (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_GFSK)
2635 #define IEEE80211_CHAN_A \
2636         (IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM)
2637 #define IEEE80211_CHAN_B \
2638         (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_CCK)
2639 #define IEEE80211_CHAN_PUREG \
2640         (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_OFDM)
2641 #define IEEE80211_CHAN_G \
2642         (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_DYN)
2643
2644 #define IS_CHAN_FHSS(flags) \
2645         ((flags & IEEE80211_CHAN_FHSS) == IEEE80211_CHAN_FHSS)
2646 #define IS_CHAN_A(flags) \
2647         ((flags & IEEE80211_CHAN_A) == IEEE80211_CHAN_A)
2648 #define IS_CHAN_B(flags) \
2649         ((flags & IEEE80211_CHAN_B) == IEEE80211_CHAN_B)
2650 #define IS_CHAN_PUREG(flags) \
2651         ((flags & IEEE80211_CHAN_PUREG) == IEEE80211_CHAN_PUREG)
2652 #define IS_CHAN_G(flags) \
2653         ((flags & IEEE80211_CHAN_G) == IEEE80211_CHAN_G)
2654 #define IS_CHAN_ANYG(flags) \
2655         (IS_CHAN_PUREG(flags) || IS_CHAN_G(flags))
2656
2657 static void
2658 print_chaninfo(netdissect_options *ndo,
2659                uint16_t freq, uint32_t flags, uint32_t presentflags)
2660 {
2661         ND_PRINT("%u MHz", freq);
2662         if (presentflags & (1 << IEEE80211_RADIOTAP_MCS)) {
2663                 /*
2664                  * We have the MCS field, so this is 11n, regardless
2665                  * of what the channel flags say.
2666                  */
2667                 ND_PRINT(" 11n");
2668         } else {
2669                 if (IS_CHAN_FHSS(flags))
2670                         ND_PRINT(" FHSS");
2671                 if (IS_CHAN_A(flags)) {
2672                         if (flags & IEEE80211_CHAN_HALF)
2673                                 ND_PRINT(" 11a/10Mhz");
2674                         else if (flags & IEEE80211_CHAN_QUARTER)
2675                                 ND_PRINT(" 11a/5Mhz");
2676                         else
2677                                 ND_PRINT(" 11a");
2678                 }
2679                 if (IS_CHAN_ANYG(flags)) {
2680                         if (flags & IEEE80211_CHAN_HALF)
2681                                 ND_PRINT(" 11g/10Mhz");
2682                         else if (flags & IEEE80211_CHAN_QUARTER)
2683                                 ND_PRINT(" 11g/5Mhz");
2684                         else
2685                                 ND_PRINT(" 11g");
2686                 } else if (IS_CHAN_B(flags))
2687                         ND_PRINT(" 11b");
2688                 if (flags & IEEE80211_CHAN_TURBO)
2689                         ND_PRINT(" Turbo");
2690         }
2691         /*
2692          * These apply to 11n.
2693          */
2694         if (flags & IEEE80211_CHAN_HT20)
2695                 ND_PRINT(" ht/20");
2696         else if (flags & IEEE80211_CHAN_HT40D)
2697                 ND_PRINT(" ht/40-");
2698         else if (flags & IEEE80211_CHAN_HT40U)
2699                 ND_PRINT(" ht/40+");
2700         ND_PRINT(" ");
2701 }
2702
2703 static int
2704 print_radiotap_field(netdissect_options *ndo,
2705                      struct cpack_state *s, uint32_t bit, uint8_t *flagsp,
2706                      uint32_t presentflags)
2707 {
2708         u_int i;
2709         int rc;
2710
2711         switch (bit) {
2712
2713         case IEEE80211_RADIOTAP_TSFT: {
2714                 uint64_t tsft;
2715
2716                 rc = nd_cpack_uint64(ndo, s, &tsft);
2717                 if (rc != 0)
2718                         goto trunc;
2719                 ND_PRINT("%" PRIu64 "us tsft ", tsft);
2720                 break;
2721                 }
2722
2723         case IEEE80211_RADIOTAP_FLAGS: {
2724                 uint8_t flagsval;
2725
2726                 rc = nd_cpack_uint8(ndo, s, &flagsval);
2727                 if (rc != 0)
2728                         goto trunc;
2729                 *flagsp = flagsval;
2730                 if (flagsval & IEEE80211_RADIOTAP_F_CFP)
2731                         ND_PRINT("cfp ");
2732                 if (flagsval & IEEE80211_RADIOTAP_F_SHORTPRE)
2733                         ND_PRINT("short preamble ");
2734                 if (flagsval & IEEE80211_RADIOTAP_F_WEP)
2735                         ND_PRINT("wep ");
2736                 if (flagsval & IEEE80211_RADIOTAP_F_FRAG)
2737                         ND_PRINT("fragmented ");
2738                 if (flagsval & IEEE80211_RADIOTAP_F_BADFCS)
2739                         ND_PRINT("bad-fcs ");
2740                 break;
2741                 }
2742
2743         case IEEE80211_RADIOTAP_RATE: {
2744                 uint8_t rate;
2745
2746                 rc = nd_cpack_uint8(ndo, s, &rate);
2747                 if (rc != 0)
2748                         goto trunc;
2749                 /*
2750                  * XXX On FreeBSD rate & 0x80 means we have an MCS. On
2751                  * Linux and AirPcap it does not.  (What about
2752                  * macOS, NetBSD, OpenBSD, and DragonFly BSD?)
2753                  *
2754                  * This is an issue either for proprietary extensions
2755                  * to 11a or 11g, which do exist, or for 11n
2756                  * implementations that stuff a rate value into
2757                  * this field, which also appear to exist.
2758                  *
2759                  * We currently handle that by assuming that
2760                  * if the 0x80 bit is set *and* the remaining
2761                  * bits have a value between 0 and 15 it's
2762                  * an MCS value, otherwise it's a rate.  If
2763                  * there are cases where systems that use
2764                  * "0x80 + MCS index" for MCS indices > 15,
2765                  * or stuff a rate value here between 64 and
2766                  * 71.5 Mb/s in here, we'll need a preference
2767                  * setting.  Such rates do exist, e.g. 11n
2768                  * MCS 7 at 20 MHz with a long guard interval.
2769                  */
2770                 if (rate >= 0x80 && rate <= 0x8f) {
2771                         /*
2772                          * XXX - we don't know the channel width
2773                          * or guard interval length, so we can't
2774                          * convert this to a data rate.
2775                          *
2776                          * If you want us to show a data rate,
2777                          * use the MCS field, not the Rate field;
2778                          * the MCS field includes not only the
2779                          * MCS index, it also includes bandwidth
2780                          * and guard interval information.
2781                          *
2782                          * XXX - can we get the channel width
2783                          * from XChannel and the guard interval
2784                          * information from Flags, at least on
2785                          * FreeBSD?
2786                          */
2787                         ND_PRINT("MCS %u ", rate & 0x7f);
2788                 } else
2789                         ND_PRINT("%2.1f Mb/s ", .5 * rate);
2790                 break;
2791                 }
2792
2793         case IEEE80211_RADIOTAP_CHANNEL: {
2794                 uint16_t frequency;
2795                 uint16_t flags;
2796
2797                 rc = nd_cpack_uint16(ndo, s, &frequency);
2798                 if (rc != 0)
2799                         goto trunc;
2800                 rc = nd_cpack_uint16(ndo, s, &flags);
2801                 if (rc != 0)
2802                         goto trunc;
2803                 /*
2804                  * If CHANNEL and XCHANNEL are both present, skip
2805                  * CHANNEL.
2806                  */
2807                 if (presentflags & (1 << IEEE80211_RADIOTAP_XCHANNEL))
2808                         break;
2809                 print_chaninfo(ndo, frequency, flags, presentflags);
2810                 break;
2811                 }
2812
2813         case IEEE80211_RADIOTAP_FHSS: {
2814                 uint8_t hopset;
2815                 uint8_t hoppat;
2816
2817                 rc = nd_cpack_uint8(ndo, s, &hopset);
2818                 if (rc != 0)
2819                         goto trunc;
2820                 rc = nd_cpack_uint8(ndo, s, &hoppat);
2821                 if (rc != 0)
2822                         goto trunc;
2823                 ND_PRINT("fhset %u fhpat %u ", hopset, hoppat);
2824                 break;
2825                 }
2826
2827         case IEEE80211_RADIOTAP_DBM_ANTSIGNAL: {
2828                 int8_t dbm_antsignal;
2829
2830                 rc = nd_cpack_int8(ndo, s, &dbm_antsignal);
2831                 if (rc != 0)
2832                         goto trunc;
2833                 ND_PRINT("%ddBm signal ", dbm_antsignal);
2834                 break;
2835                 }
2836
2837         case IEEE80211_RADIOTAP_DBM_ANTNOISE: {
2838                 int8_t dbm_antnoise;
2839
2840                 rc = nd_cpack_int8(ndo, s, &dbm_antnoise);
2841                 if (rc != 0)
2842                         goto trunc;
2843                 ND_PRINT("%ddBm noise ", dbm_antnoise);
2844                 break;
2845                 }
2846
2847         case IEEE80211_RADIOTAP_LOCK_QUALITY: {
2848                 uint16_t lock_quality;
2849
2850                 rc = nd_cpack_uint16(ndo, s, &lock_quality);
2851                 if (rc != 0)
2852                         goto trunc;
2853                 ND_PRINT("%u sq ", lock_quality);
2854                 break;
2855                 }
2856
2857         case IEEE80211_RADIOTAP_TX_ATTENUATION: {
2858                 int16_t tx_attenuation;
2859
2860                 rc = nd_cpack_int16(ndo, s, &tx_attenuation);
2861                 if (rc != 0)
2862                         goto trunc;
2863                 ND_PRINT("%d tx power ", -tx_attenuation);
2864                 break;
2865                 }
2866
2867         case IEEE80211_RADIOTAP_DB_TX_ATTENUATION: {
2868                 int8_t db_tx_attenuation;
2869
2870                 rc = nd_cpack_int8(ndo, s, &db_tx_attenuation);
2871                 if (rc != 0)
2872                         goto trunc;
2873                 ND_PRINT("%ddB tx attenuation ", -db_tx_attenuation);
2874                 break;
2875                 }
2876
2877         case IEEE80211_RADIOTAP_DBM_TX_POWER: {
2878                 int8_t dbm_tx_power;
2879
2880                 rc = nd_cpack_int8(ndo, s, &dbm_tx_power);
2881                 if (rc != 0)
2882                         goto trunc;
2883                 ND_PRINT("%ddBm tx power ", dbm_tx_power);
2884                 break;
2885                 }
2886
2887         case IEEE80211_RADIOTAP_ANTENNA: {
2888                 uint8_t antenna;
2889
2890                 rc = nd_cpack_uint8(ndo, s, &antenna);
2891                 if (rc != 0)
2892                         goto trunc;
2893                 ND_PRINT("antenna %u ", antenna);
2894                 break;
2895                 }
2896
2897         case IEEE80211_RADIOTAP_DB_ANTSIGNAL: {
2898                 uint8_t db_antsignal;
2899
2900                 rc = nd_cpack_uint8(ndo, s, &db_antsignal);
2901                 if (rc != 0)
2902                         goto trunc;
2903                 ND_PRINT("%udB signal ", db_antsignal);
2904                 break;
2905                 }
2906
2907         case IEEE80211_RADIOTAP_DB_ANTNOISE: {
2908                 uint8_t db_antnoise;
2909
2910                 rc = nd_cpack_uint8(ndo, s, &db_antnoise);
2911                 if (rc != 0)
2912                         goto trunc;
2913                 ND_PRINT("%udB noise ", db_antnoise);
2914                 break;
2915                 }
2916
2917         case IEEE80211_RADIOTAP_RX_FLAGS: {
2918                 uint16_t rx_flags;
2919
2920                 rc = nd_cpack_uint16(ndo, s, &rx_flags);
2921                 if (rc != 0)
2922                         goto trunc;
2923                 /* Do nothing for now */
2924                 break;
2925                 }
2926
2927         case IEEE80211_RADIOTAP_XCHANNEL: {
2928                 uint32_t flags;
2929                 uint16_t frequency;
2930                 uint8_t channel;
2931                 uint8_t maxpower;
2932
2933                 rc = nd_cpack_uint32(ndo, s, &flags);
2934                 if (rc != 0)
2935                         goto trunc;
2936                 rc = nd_cpack_uint16(ndo, s, &frequency);
2937                 if (rc != 0)
2938                         goto trunc;
2939                 rc = nd_cpack_uint8(ndo, s, &channel);
2940                 if (rc != 0)
2941                         goto trunc;
2942                 rc = nd_cpack_uint8(ndo, s, &maxpower);
2943                 if (rc != 0)
2944                         goto trunc;
2945                 print_chaninfo(ndo, frequency, flags, presentflags);
2946                 break;
2947                 }
2948
2949         case IEEE80211_RADIOTAP_MCS: {
2950                 uint8_t known;
2951                 uint8_t flags;
2952                 uint8_t mcs_index;
2953                 static const char *ht_bandwidth[4] = {
2954                         "20 MHz",
2955                         "40 MHz",
2956                         "20 MHz (L)",
2957                         "20 MHz (U)"
2958                 };
2959                 float htrate;
2960
2961                 rc = nd_cpack_uint8(ndo, s, &known);
2962                 if (rc != 0)
2963                         goto trunc;
2964                 rc = nd_cpack_uint8(ndo, s, &flags);
2965                 if (rc != 0)
2966                         goto trunc;
2967                 rc = nd_cpack_uint8(ndo, s, &mcs_index);
2968                 if (rc != 0)
2969                         goto trunc;
2970                 if (known & IEEE80211_RADIOTAP_MCS_MCS_INDEX_KNOWN) {
2971                         /*
2972                          * We know the MCS index.
2973                          */
2974                         if (mcs_index <= MAX_MCS_INDEX) {
2975                                 /*
2976                                  * And it's in-range.
2977                                  */
2978                                 if (known & (IEEE80211_RADIOTAP_MCS_BANDWIDTH_KNOWN|IEEE80211_RADIOTAP_MCS_GUARD_INTERVAL_KNOWN)) {
2979                                         /*
2980                                          * And we know both the bandwidth and
2981                                          * the guard interval, so we can look
2982                                          * up the rate.
2983                                          */
2984                                         htrate =
2985                                                 ieee80211_float_htrates
2986                                                         [mcs_index]
2987                                                         [((flags & IEEE80211_RADIOTAP_MCS_BANDWIDTH_MASK) == IEEE80211_RADIOTAP_MCS_BANDWIDTH_40 ? 1 : 0)]
2988                                                         [((flags & IEEE80211_RADIOTAP_MCS_SHORT_GI) ? 1 : 0)];
2989                                 } else {
2990                                         /*
2991                                          * We don't know both the bandwidth
2992                                          * and the guard interval, so we can
2993                                          * only report the MCS index.
2994                                          */
2995                                         htrate = 0.0;
2996                                 }
2997                         } else {
2998                                 /*
2999                                  * The MCS value is out of range.
3000                                  */
3001                                 htrate = 0.0;
3002                         }
3003                         if (htrate != 0.0) {
3004                                 /*
3005                                  * We have the rate.
3006                                  * Print it.
3007                                  */
3008                                 ND_PRINT("%.1f Mb/s MCS %u ", htrate, mcs_index);
3009                         } else {
3010                                 /*
3011                                  * We at least have the MCS index.
3012                                  * Print it.
3013                                  */
3014                                 ND_PRINT("MCS %u ", mcs_index);
3015                         }
3016                 }
3017                 if (known & IEEE80211_RADIOTAP_MCS_BANDWIDTH_KNOWN) {
3018                         ND_PRINT("%s ",
3019                                 ht_bandwidth[flags & IEEE80211_RADIOTAP_MCS_BANDWIDTH_MASK]);
3020                 }
3021                 if (known & IEEE80211_RADIOTAP_MCS_GUARD_INTERVAL_KNOWN) {
3022                         ND_PRINT("%s GI ",
3023                                 (flags & IEEE80211_RADIOTAP_MCS_SHORT_GI) ?
3024                                 "short" : "long");
3025                 }
3026                 if (known & IEEE80211_RADIOTAP_MCS_HT_FORMAT_KNOWN) {
3027                         ND_PRINT("%s ",
3028                                 (flags & IEEE80211_RADIOTAP_MCS_HT_GREENFIELD) ?
3029                                 "greenfield" : "mixed");
3030                 }
3031                 if (known & IEEE80211_RADIOTAP_MCS_FEC_TYPE_KNOWN) {
3032                         ND_PRINT("%s FEC ",
3033                                 (flags & IEEE80211_RADIOTAP_MCS_FEC_LDPC) ?
3034                                 "LDPC" : "BCC");
3035                 }
3036                 if (known & IEEE80211_RADIOTAP_MCS_STBC_KNOWN) {
3037                         ND_PRINT("RX-STBC%u ",
3038                                 (flags & IEEE80211_RADIOTAP_MCS_STBC_MASK) >> IEEE80211_RADIOTAP_MCS_STBC_SHIFT);
3039                 }
3040                 break;
3041                 }
3042
3043         case IEEE80211_RADIOTAP_AMPDU_STATUS: {
3044                 uint32_t reference_num;
3045                 uint16_t flags;
3046                 uint8_t delim_crc;
3047                 uint8_t reserved;
3048
3049                 rc = nd_cpack_uint32(ndo, s, &reference_num);
3050                 if (rc != 0)
3051                         goto trunc;
3052                 rc = nd_cpack_uint16(ndo, s, &flags);
3053                 if (rc != 0)
3054                         goto trunc;
3055                 rc = nd_cpack_uint8(ndo, s, &delim_crc);
3056                 if (rc != 0)
3057                         goto trunc;
3058                 rc = nd_cpack_uint8(ndo, s, &reserved);
3059                 if (rc != 0)
3060                         goto trunc;
3061                 /* Do nothing for now */
3062                 break;
3063                 }
3064
3065         case IEEE80211_RADIOTAP_VHT: {
3066                 uint16_t known;
3067                 uint8_t flags;
3068                 uint8_t bandwidth;
3069                 uint8_t mcs_nss[4];
3070                 uint8_t coding;
3071                 uint8_t group_id;
3072                 uint16_t partial_aid;
3073                 static const char *vht_bandwidth[32] = {
3074                         "20 MHz",
3075                         "40 MHz",
3076                         "20 MHz (L)",
3077                         "20 MHz (U)",
3078                         "80 MHz",
3079                         "80 MHz (L)",
3080                         "80 MHz (U)",
3081                         "80 MHz (LL)",
3082                         "80 MHz (LU)",
3083                         "80 MHz (UL)",
3084                         "80 MHz (UU)",
3085                         "160 MHz",
3086                         "160 MHz (L)",
3087                         "160 MHz (U)",
3088                         "160 MHz (LL)",
3089                         "160 MHz (LU)",
3090                         "160 MHz (UL)",
3091                         "160 MHz (UU)",
3092                         "160 MHz (LLL)",
3093                         "160 MHz (LLU)",
3094                         "160 MHz (LUL)",
3095                         "160 MHz (UUU)",
3096                         "160 MHz (ULL)",
3097                         "160 MHz (ULU)",
3098                         "160 MHz (UUL)",
3099                         "160 MHz (UUU)",
3100                         "unknown (26)",
3101                         "unknown (27)",
3102                         "unknown (28)",
3103                         "unknown (29)",
3104                         "unknown (30)",
3105                         "unknown (31)"
3106                 };
3107
3108                 rc = nd_cpack_uint16(ndo, s, &known);
3109                 if (rc != 0)
3110                         goto trunc;
3111                 rc = nd_cpack_uint8(ndo, s, &flags);
3112                 if (rc != 0)
3113                         goto trunc;
3114                 rc = nd_cpack_uint8(ndo, s, &bandwidth);
3115                 if (rc != 0)
3116                         goto trunc;
3117                 for (i = 0; i < 4; i++) {
3118                         rc = nd_cpack_uint8(ndo, s, &mcs_nss[i]);
3119                         if (rc != 0)
3120                                 goto trunc;
3121                 }
3122                 rc = nd_cpack_uint8(ndo, s, &coding);
3123                 if (rc != 0)
3124                         goto trunc;
3125                 rc = nd_cpack_uint8(ndo, s, &group_id);
3126                 if (rc != 0)
3127                         goto trunc;
3128                 rc = nd_cpack_uint16(ndo, s, &partial_aid);
3129                 if (rc != 0)
3130                         goto trunc;
3131                 for (i = 0; i < 4; i++) {
3132                         u_int nss, mcs;
3133                         nss = mcs_nss[i] & IEEE80211_RADIOTAP_VHT_NSS_MASK;
3134                         mcs = (mcs_nss[i] & IEEE80211_RADIOTAP_VHT_MCS_MASK) >> IEEE80211_RADIOTAP_VHT_MCS_SHIFT;
3135
3136                         if (nss == 0)
3137                                 continue;
3138
3139                         ND_PRINT("User %u MCS %u ", i, mcs);
3140                         ND_PRINT("%s FEC ",
3141                                 (coding & (IEEE80211_RADIOTAP_CODING_LDPC_USERn << i)) ?
3142                                 "LDPC" : "BCC");
3143                 }
3144                 if (known & IEEE80211_RADIOTAP_VHT_BANDWIDTH_KNOWN) {
3145                         ND_PRINT("%s ",
3146                                 vht_bandwidth[bandwidth & IEEE80211_RADIOTAP_VHT_BANDWIDTH_MASK]);
3147                 }
3148                 if (known & IEEE80211_RADIOTAP_VHT_GUARD_INTERVAL_KNOWN) {
3149                         ND_PRINT("%s GI ",
3150                                 (flags & IEEE80211_RADIOTAP_VHT_SHORT_GI) ?
3151                                 "short" : "long");
3152                 }
3153                 break;
3154                 }
3155
3156         default:
3157                 /* this bit indicates a field whose
3158                  * size we do not know, so we cannot
3159                  * proceed.  Just print the bit number.
3160                  */
3161                 ND_PRINT("[bit %u] ", bit);
3162                 return -1;
3163         }
3164
3165         return 0;
3166
3167 trunc:
3168         nd_print_trunc(ndo);
3169         return rc;
3170 }
3171
3172
3173 static int
3174 print_in_radiotap_namespace(netdissect_options *ndo,
3175                             struct cpack_state *s, uint8_t *flags,
3176                             uint32_t presentflags, int bit0)
3177 {
3178 #define BITNO_32(x) (((x) >> 16) ? 16 + BITNO_16((x) >> 16) : BITNO_16((x)))
3179 #define BITNO_16(x) (((x) >> 8) ? 8 + BITNO_8((x) >> 8) : BITNO_8((x)))
3180 #define BITNO_8(x) (((x) >> 4) ? 4 + BITNO_4((x) >> 4) : BITNO_4((x)))
3181 #define BITNO_4(x) (((x) >> 2) ? 2 + BITNO_2((x) >> 2) : BITNO_2((x)))
3182 #define BITNO_2(x) (((x) & 2) ? 1 : 0)
3183         uint32_t present, next_present;
3184         int bitno;
3185         enum ieee80211_radiotap_type bit;
3186         int rc;
3187
3188         for (present = presentflags; present; present = next_present) {
3189                 /*
3190                  * Clear the least significant bit that is set.
3191                  */
3192                 next_present = present & (present - 1);
3193
3194                 /*
3195                  * Get the bit number, within this presence word,
3196                  * of the remaining least significant bit that
3197                  * is set.
3198                  */
3199                 bitno = BITNO_32(present ^ next_present);
3200
3201                 /*
3202                  * Stop if this is one of the "same meaning
3203                  * in all presence flags" bits.
3204                  */
3205                 if (bitno >= IEEE80211_RADIOTAP_NAMESPACE)
3206                         break;
3207
3208                 /*
3209                  * Get the radiotap bit number of that bit.
3210                  */
3211                 bit = (enum ieee80211_radiotap_type)(bit0 + bitno);
3212
3213                 rc = print_radiotap_field(ndo, s, bit, flags, presentflags);
3214                 if (rc != 0)
3215                         return rc;
3216         }
3217
3218         return 0;
3219 }
3220
3221 u_int
3222 ieee802_11_radio_print(netdissect_options *ndo,
3223                        const u_char *p, u_int length, u_int caplen)
3224 {
3225 #define BIT(n)  (1U << n)
3226 #define IS_EXTENDED(__p)        \
3227             (GET_LE_U_4(__p) & BIT(IEEE80211_RADIOTAP_EXT)) != 0
3228
3229         struct cpack_state cpacker;
3230         const struct ieee80211_radiotap_header *hdr;
3231         uint32_t presentflags;
3232         const nd_uint32_t *presentp, *last_presentp;
3233         int vendor_namespace;
3234         uint8_t vendor_oui[3];
3235         uint8_t vendor_subnamespace;
3236         uint16_t skip_length;
3237         int bit0;
3238         u_int len;
3239         uint8_t flags;
3240         int pad;
3241         u_int fcslen;
3242
3243         ndo->ndo_protocol = "802.11_radio";
3244         if (caplen < sizeof(*hdr)) {
3245                 nd_print_trunc(ndo);
3246                 return caplen;
3247         }
3248
3249         hdr = (const struct ieee80211_radiotap_header *)p;
3250
3251         len = GET_LE_U_2(hdr->it_len);
3252         if (len < sizeof(*hdr)) {
3253                 /*
3254                  * The length is the length of the entire header, so
3255                  * it must be as large as the fixed-length part of
3256                  * the header.
3257                  */
3258                 nd_print_trunc(ndo);
3259                 return caplen;
3260         }
3261
3262         /*
3263          * If we don't have the entire radiotap header, just give up.
3264          */
3265         if (caplen < len) {
3266                 nd_print_trunc(ndo);
3267                 return caplen;
3268         }
3269         nd_cpack_init(&cpacker, (const uint8_t *)hdr, len); /* align against header start */
3270         nd_cpack_advance(&cpacker, sizeof(*hdr)); /* includes the 1st bitmap */
3271         for (last_presentp = &hdr->it_present;
3272              (const u_char*)(last_presentp + 1) <= p + len &&
3273              IS_EXTENDED(last_presentp);
3274              last_presentp++)
3275           nd_cpack_advance(&cpacker, sizeof(hdr->it_present)); /* more bitmaps */
3276
3277         /* are there more bitmap extensions than bytes in header? */
3278         if ((const u_char*)(last_presentp + 1) > p + len) {
3279                 nd_print_trunc(ndo);
3280                 return caplen;
3281         }
3282
3283         /*
3284          * Start out at the beginning of the default radiotap namespace.
3285          */
3286         bit0 = 0;
3287         vendor_namespace = 0;
3288         memset(vendor_oui, 0, 3);
3289         vendor_subnamespace = 0;
3290         skip_length = 0;
3291         /* Assume no flags */
3292         flags = 0;
3293         /* Assume no Atheros padding between 802.11 header and body */
3294         pad = 0;
3295         /* Assume no FCS at end of frame */
3296         fcslen = 0;
3297         for (presentp = &hdr->it_present; presentp <= last_presentp;
3298             presentp++) {
3299                 presentflags = GET_LE_U_4(presentp);
3300
3301                 /*
3302                  * If this is a vendor namespace, we don't handle it.
3303                  */
3304                 if (vendor_namespace) {
3305                         /*
3306                          * Skip past the stuff we don't understand.
3307                          * If we add support for any vendor namespaces,
3308                          * it'd be added here; use vendor_oui and
3309                          * vendor_subnamespace to interpret the fields.
3310                          */
3311                         if (nd_cpack_advance(&cpacker, skip_length) != 0) {
3312                                 /*
3313                                  * Ran out of space in the packet.
3314                                  */
3315                                 break;
3316                         }
3317
3318                         /*
3319                          * We've skipped it all; nothing more to
3320                          * skip.
3321                          */
3322                         skip_length = 0;
3323                 } else {
3324                         if (print_in_radiotap_namespace(ndo, &cpacker,
3325                             &flags, presentflags, bit0) != 0) {
3326                                 /*
3327                                  * Fatal error - can't process anything
3328                                  * more in the radiotap header.
3329                                  */
3330                                 break;
3331                         }
3332                 }
3333
3334                 /*
3335                  * Handle the namespace switch bits; we've already handled
3336                  * the extension bit in all but the last word above.
3337                  */
3338                 switch (presentflags &
3339                     (BIT(IEEE80211_RADIOTAP_NAMESPACE)|BIT(IEEE80211_RADIOTAP_VENDOR_NAMESPACE))) {
3340
3341                 case 0:
3342                         /*
3343                          * We're not changing namespaces.
3344                          * advance to the next 32 bits in the current
3345                          * namespace.
3346                          */
3347                         bit0 += 32;
3348                         break;
3349
3350                 case BIT(IEEE80211_RADIOTAP_NAMESPACE):
3351                         /*
3352                          * We're switching to the radiotap namespace.
3353                          * Reset the presence-bitmap index to 0, and
3354                          * reset the namespace to the default radiotap
3355                          * namespace.
3356                          */
3357                         bit0 = 0;
3358                         vendor_namespace = 0;
3359                         memset(vendor_oui, 0, 3);
3360                         vendor_subnamespace = 0;
3361                         skip_length = 0;
3362                         break;
3363
3364                 case BIT(IEEE80211_RADIOTAP_VENDOR_NAMESPACE):
3365                         /*
3366                          * We're switching to a vendor namespace.
3367                          * Reset the presence-bitmap index to 0,
3368                          * note that we're in a vendor namespace,
3369                          * and fetch the fields of the Vendor Namespace
3370                          * item.
3371                          */
3372                         bit0 = 0;
3373                         vendor_namespace = 1;
3374                         if ((nd_cpack_align_and_reserve(&cpacker, 2)) == NULL) {
3375                                 nd_print_trunc(ndo);
3376                                 break;
3377                         }
3378                         if (nd_cpack_uint8(ndo, &cpacker, &vendor_oui[0]) != 0) {
3379                                 nd_print_trunc(ndo);
3380                                 break;
3381                         }
3382                         if (nd_cpack_uint8(ndo, &cpacker, &vendor_oui[1]) != 0) {
3383                                 nd_print_trunc(ndo);
3384                                 break;
3385                         }
3386                         if (nd_cpack_uint8(ndo, &cpacker, &vendor_oui[2]) != 0) {
3387                                 nd_print_trunc(ndo);
3388                                 break;
3389                         }
3390                         if (nd_cpack_uint8(ndo, &cpacker, &vendor_subnamespace) != 0) {
3391                                 nd_print_trunc(ndo);
3392                                 break;
3393                         }
3394                         if (nd_cpack_uint16(ndo, &cpacker, &skip_length) != 0) {
3395                                 nd_print_trunc(ndo);
3396                                 break;
3397                         }
3398                         break;
3399
3400                 default:
3401                         /*
3402                          * Illegal combination.  The behavior in this
3403                          * case is undefined by the radiotap spec; we
3404                          * just ignore both bits.
3405                          */
3406                         break;
3407                 }
3408         }
3409
3410         if (flags & IEEE80211_RADIOTAP_F_DATAPAD)
3411                 pad = 1;        /* Atheros padding */
3412         if (flags & IEEE80211_RADIOTAP_F_FCS)
3413                 fcslen = 4;     /* FCS at end of packet */
3414         return len + ieee802_11_print(ndo, p + len, length - len, caplen - len, pad,
3415             fcslen);
3416 #undef BITNO_32
3417 #undef BITNO_16
3418 #undef BITNO_8
3419 #undef BITNO_4
3420 #undef BITNO_2
3421 #undef BIT
3422 }
3423
3424 static u_int
3425 ieee802_11_radio_avs_print(netdissect_options *ndo,
3426                            const u_char *p, u_int length, u_int caplen)
3427 {
3428         uint32_t caphdr_len;
3429
3430         ndo->ndo_protocol = "802.11_radio_avs";
3431         if (caplen < 8) {
3432                 nd_print_trunc(ndo);
3433                 return caplen;
3434         }
3435
3436         caphdr_len = GET_BE_U_4(p + 4);
3437         if (caphdr_len < 8) {
3438                 /*
3439                  * Yow!  The capture header length is claimed not
3440                  * to be large enough to include even the version
3441                  * cookie or capture header length!
3442                  */
3443                 nd_print_trunc(ndo);
3444                 return caplen;
3445         }
3446
3447         if (caplen < caphdr_len) {
3448                 nd_print_trunc(ndo);
3449                 return caplen;
3450         }
3451
3452         return caphdr_len + ieee802_11_print(ndo, p + caphdr_len,
3453             length - caphdr_len, caplen - caphdr_len, 0, 0);
3454 }
3455
3456 #define PRISM_HDR_LEN           144
3457
3458 #define WLANCAP_MAGIC_COOKIE_BASE 0x80211000
3459 #define WLANCAP_MAGIC_COOKIE_V1 0x80211001
3460 #define WLANCAP_MAGIC_COOKIE_V2 0x80211002
3461
3462 /*
3463  * For DLT_PRISM_HEADER; like DLT_IEEE802_11, but with an extra header,
3464  * containing information such as radio information, which we
3465  * currently ignore.
3466  *
3467  * If, however, the packet begins with WLANCAP_MAGIC_COOKIE_V1 or
3468  * WLANCAP_MAGIC_COOKIE_V2, it's really DLT_IEEE802_11_RADIO_AVS
3469  * (currently, on Linux, there's no ARPHRD_ type for
3470  * DLT_IEEE802_11_RADIO_AVS, as there is a ARPHRD_IEEE80211_PRISM
3471  * for DLT_PRISM_HEADER, so ARPHRD_IEEE80211_PRISM is used for
3472  * the AVS header, and the first 4 bytes of the header are used to
3473  * indicate whether it's a Prism header or an AVS header).
3474  */
3475 void
3476 prism_if_print(netdissect_options *ndo,
3477                const struct pcap_pkthdr *h, const u_char *p)
3478 {
3479         u_int caplen = h->caplen;
3480         u_int length = h->len;
3481         uint32_t msgcode;
3482
3483         ndo->ndo_protocol = "prism";
3484         if (caplen < 4) {
3485                 nd_print_trunc(ndo);
3486                 ndo->ndo_ll_hdr_len += caplen;
3487                 return;
3488         }
3489
3490         msgcode = GET_BE_U_4(p);
3491         if (msgcode == WLANCAP_MAGIC_COOKIE_V1 ||
3492             msgcode == WLANCAP_MAGIC_COOKIE_V2) {
3493                 ndo->ndo_ll_hdr_len += ieee802_11_radio_avs_print(ndo, p, length, caplen);
3494                 return;
3495         }
3496
3497         if (caplen < PRISM_HDR_LEN) {
3498                 nd_print_trunc(ndo);
3499                 ndo->ndo_ll_hdr_len += caplen;
3500                 return;
3501         }
3502
3503         p += PRISM_HDR_LEN;
3504         length -= PRISM_HDR_LEN;
3505         caplen -= PRISM_HDR_LEN;
3506         ndo->ndo_ll_hdr_len += PRISM_HDR_LEN;
3507         ndo->ndo_ll_hdr_len += ieee802_11_print(ndo, p, length, caplen, 0, 0);
3508 }
3509
3510 /*
3511  * For DLT_IEEE802_11_RADIO; like DLT_IEEE802_11, but with an extra
3512  * header, containing information such as radio information.
3513  */
3514 void
3515 ieee802_11_radio_if_print(netdissect_options *ndo,
3516                           const struct pcap_pkthdr *h, const u_char *p)
3517 {
3518         ndo->ndo_protocol = "802.11_radio";
3519         ndo->ndo_ll_hdr_len += ieee802_11_radio_print(ndo, p, h->len, h->caplen);
3520 }
3521
3522 /*
3523  * For DLT_IEEE802_11_RADIO_AVS; like DLT_IEEE802_11, but with an
3524  * extra header, containing information such as radio information,
3525  * which we currently ignore.
3526  */
3527 void
3528 ieee802_11_radio_avs_if_print(netdissect_options *ndo,
3529                               const struct pcap_pkthdr *h, const u_char *p)
3530 {
3531         ndo->ndo_protocol = "802.11_radio_avs";
3532         ndo->ndo_ll_hdr_len += ieee802_11_radio_avs_print(ndo, p, h->len, h->caplen);
3533 }