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