]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/tcpdump/print-802_11.c
Merge llvm, clang, lld, lldb, compiler-rt and libc++ r304460, and update
[FreeBSD/FreeBSD.git] / contrib / tcpdump / print-802_11.c
1 /*
2  * Copyright (c) 2001
3  *      Fortress Technologies, Inc.  All rights reserved.
4  *      Charlie Lenahan (clenahan@fortresstech.com)
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that: (1) source code distributions
8  * retain the above copyright notice and this paragraph in its entirety, (2)
9  * distributions including binary code include the above copyright notice and
10  * this paragraph in its entirety in the documentation or other materials
11  * provided with the distribution, and (3) all advertising materials mentioning
12  * features or use of this software display the following acknowledgement:
13  * ``This product includes software developed by the University of California,
14  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
15  * the University nor the names of its contributors may be used to endorse
16  * or promote products derived from this software without specific prior
17  * written permission.
18  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
19  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
20  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
21  */
22
23 /* \summary: IEEE 802.11 printer */
24
25 #ifdef HAVE_CONFIG_H
26 #include "config.h"
27 #endif
28
29 #include <netdissect-stdinc.h>
30
31 #include <string.h>
32
33 #include "netdissect.h"
34 #include "addrtoname.h"
35
36 #include "extract.h"
37
38 #include "cpack.h"
39
40
41 /* Lengths of 802.11 header components. */
42 #define IEEE802_11_FC_LEN               2
43 #define IEEE802_11_DUR_LEN              2
44 #define IEEE802_11_DA_LEN               6
45 #define IEEE802_11_SA_LEN               6
46 #define IEEE802_11_BSSID_LEN            6
47 #define IEEE802_11_RA_LEN               6
48 #define IEEE802_11_TA_LEN               6
49 #define IEEE802_11_ADDR1_LEN            6
50 #define IEEE802_11_SEQ_LEN              2
51 #define IEEE802_11_CTL_LEN              2
52 #define IEEE802_11_CARRIED_FC_LEN       2
53 #define IEEE802_11_HT_CONTROL_LEN       4
54 #define IEEE802_11_IV_LEN               3
55 #define IEEE802_11_KID_LEN              1
56
57 /* Frame check sequence length. */
58 #define IEEE802_11_FCS_LEN              4
59
60 /* Lengths of beacon components. */
61 #define IEEE802_11_TSTAMP_LEN           8
62 #define IEEE802_11_BCNINT_LEN           2
63 #define IEEE802_11_CAPINFO_LEN          2
64 #define IEEE802_11_LISTENINT_LEN        2
65
66 #define IEEE802_11_AID_LEN              2
67 #define IEEE802_11_STATUS_LEN           2
68 #define IEEE802_11_REASON_LEN           2
69
70 /* Length of previous AP in reassocation frame */
71 #define IEEE802_11_AP_LEN               6
72
73 #define T_MGMT 0x0  /* management */
74 #define T_CTRL 0x1  /* control */
75 #define T_DATA 0x2 /* data */
76 #define T_RESV 0x3  /* reserved */
77
78 #define ST_ASSOC_REQUEST        0x0
79 #define ST_ASSOC_RESPONSE       0x1
80 #define ST_REASSOC_REQUEST      0x2
81 #define ST_REASSOC_RESPONSE     0x3
82 #define ST_PROBE_REQUEST        0x4
83 #define ST_PROBE_RESPONSE       0x5
84 /* RESERVED                     0x6  */
85 /* RESERVED                     0x7  */
86 #define ST_BEACON               0x8
87 #define ST_ATIM                 0x9
88 #define ST_DISASSOC             0xA
89 #define ST_AUTH                 0xB
90 #define ST_DEAUTH               0xC
91 #define ST_ACTION               0xD
92 /* RESERVED                     0xE  */
93 /* RESERVED                     0xF  */
94
95 static const struct tok st_str[] = {
96         { ST_ASSOC_REQUEST,    "Assoc Request"    },
97         { ST_ASSOC_RESPONSE,   "Assoc Response"   },
98         { ST_REASSOC_REQUEST,  "ReAssoc Request"  },
99         { ST_REASSOC_RESPONSE, "ReAssoc Response" },
100         { ST_PROBE_REQUEST,    "Probe Request"    },
101         { ST_PROBE_RESPONSE,   "Probe Response"   },
102         { ST_BEACON,           "Beacon"           },
103         { ST_ATIM,             "ATIM"             },
104         { ST_DISASSOC,         "Disassociation"   },
105         { ST_AUTH,             "Authentication"   },
106         { ST_DEAUTH,           "DeAuthentication" },
107         { ST_ACTION,           "Action"           },
108         { 0, NULL }
109 };
110
111 #define CTRL_CONTROL_WRAPPER    0x7
112 #define CTRL_BAR        0x8
113 #define CTRL_BA         0x9
114 #define CTRL_PS_POLL    0xA
115 #define CTRL_RTS        0xB
116 #define CTRL_CTS        0xC
117 #define CTRL_ACK        0xD
118 #define CTRL_CF_END     0xE
119 #define CTRL_END_ACK    0xF
120
121 static const struct tok ctrl_str[] = {
122         { CTRL_CONTROL_WRAPPER, "Control Wrapper" },
123         { CTRL_BAR,             "BAR"             },
124         { CTRL_BA,              "BA"              },
125         { CTRL_PS_POLL,         "Power Save-Poll" },
126         { CTRL_RTS,             "Request-To-Send" },
127         { CTRL_CTS,             "Clear-To-Send"   },
128         { CTRL_ACK,             "Acknowledgment"  },
129         { CTRL_CF_END,          "CF-End"          },
130         { CTRL_END_ACK,         "CF-End+CF-Ack"   },
131         { 0, NULL }
132 };
133
134 #define DATA_DATA                       0x0
135 #define DATA_DATA_CF_ACK                0x1
136 #define DATA_DATA_CF_POLL               0x2
137 #define DATA_DATA_CF_ACK_POLL           0x3
138 #define DATA_NODATA                     0x4
139 #define DATA_NODATA_CF_ACK              0x5
140 #define DATA_NODATA_CF_POLL             0x6
141 #define DATA_NODATA_CF_ACK_POLL         0x7
142
143 #define DATA_QOS_DATA                   0x8
144 #define DATA_QOS_DATA_CF_ACK            0x9
145 #define DATA_QOS_DATA_CF_POLL           0xA
146 #define DATA_QOS_DATA_CF_ACK_POLL       0xB
147 #define DATA_QOS_NODATA                 0xC
148 #define DATA_QOS_CF_POLL_NODATA         0xE
149 #define DATA_QOS_CF_ACK_POLL_NODATA     0xF
150
151 /*
152  * The subtype field of a data frame is, in effect, composed of 4 flag
153  * bits - CF-Ack, CF-Poll, Null (means the frame doesn't actually have
154  * any data), and QoS.
155  */
156 #define DATA_FRAME_IS_CF_ACK(x)         ((x) & 0x01)
157 #define DATA_FRAME_IS_CF_POLL(x)        ((x) & 0x02)
158 #define DATA_FRAME_IS_NULL(x)           ((x) & 0x04)
159 #define DATA_FRAME_IS_QOS(x)            ((x) & 0x08)
160
161 /*
162  * Bits in the frame control field.
163  */
164 #define FC_VERSION(fc)          ((fc) & 0x3)
165 #define FC_TYPE(fc)             (((fc) >> 2) & 0x3)
166 #define FC_SUBTYPE(fc)          (((fc) >> 4) & 0xF)
167 #define FC_TO_DS(fc)            ((fc) & 0x0100)
168 #define FC_FROM_DS(fc)          ((fc) & 0x0200)
169 #define FC_MORE_FLAG(fc)        ((fc) & 0x0400)
170 #define FC_RETRY(fc)            ((fc) & 0x0800)
171 #define FC_POWER_MGMT(fc)       ((fc) & 0x1000)
172 #define FC_MORE_DATA(fc)        ((fc) & 0x2000)
173 #define FC_PROTECTED(fc)        ((fc) & 0x4000)
174 #define FC_ORDER(fc)            ((fc) & 0x8000)
175
176 struct mgmt_header_t {
177         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                                 if (!ND_TTEST2(*(p + offset), ssid.length))
1043                                         return 0;
1044                                 if (length < ssid.length)
1045                                         return 0;
1046                                 memcpy(&ssid.ssid, p + offset, ssid.length);
1047                                 offset += ssid.length;
1048                                 length -= ssid.length;
1049                         }
1050                         ssid.ssid[ssid.length] = '\0';
1051                         /*
1052                          * Present and not truncated.
1053                          *
1054                          * If we haven't already seen an SSID IE,
1055                          * copy this one, otherwise ignore this one,
1056                          * so we later report the first one we saw.
1057                          */
1058                         if (!pbody->ssid_present) {
1059                                 pbody->ssid = ssid;
1060                                 pbody->ssid_present = 1;
1061                         }
1062                         break;
1063                 case E_CHALLENGE:
1064                         memcpy(&challenge, p + offset, 2);
1065                         offset += 2;
1066                         length -= 2;
1067                         if (challenge.length != 0) {
1068                                 if (challenge.length >
1069                                     sizeof(challenge.text) - 1)
1070                                         return 0;
1071                                 if (!ND_TTEST2(*(p + offset), challenge.length))
1072                                         return 0;
1073                                 if (length < challenge.length)
1074                                         return 0;
1075                                 memcpy(&challenge.text, p + offset,
1076                                     challenge.length);
1077                                 offset += challenge.length;
1078                                 length -= challenge.length;
1079                         }
1080                         challenge.text[challenge.length] = '\0';
1081                         /*
1082                          * Present and not truncated.
1083                          *
1084                          * If we haven't already seen a challenge IE,
1085                          * copy this one, otherwise ignore this one,
1086                          * so we later report the first one we saw.
1087                          */
1088                         if (!pbody->challenge_present) {
1089                                 pbody->challenge = challenge;
1090                                 pbody->challenge_present = 1;
1091                         }
1092                         break;
1093                 case E_RATES:
1094                         memcpy(&rates, p + offset, 2);
1095                         offset += 2;
1096                         length -= 2;
1097                         if (rates.length != 0) {
1098                                 if (rates.length > sizeof rates.rate)
1099                                         return 0;
1100                                 if (!ND_TTEST2(*(p + offset), rates.length))
1101                                         return 0;
1102                                 if (length < rates.length)
1103                                         return 0;
1104                                 memcpy(&rates.rate, p + offset, rates.length);
1105                                 offset += rates.length;
1106                                 length -= rates.length;
1107                         }
1108                         /*
1109                          * Present and not truncated.
1110                          *
1111                          * If we haven't already seen a rates IE,
1112                          * copy this one if it's not zero-length,
1113                          * otherwise ignore this one, so we later
1114                          * report the first one we saw.
1115                          *
1116                          * We ignore zero-length rates IEs as some
1117                          * devices seem to put a zero-length rates
1118                          * IE, followed by an SSID IE, followed by
1119                          * a non-zero-length rates IE into frames,
1120                          * even though IEEE Std 802.11-2007 doesn't
1121                          * seem to indicate that a zero-length rates
1122                          * IE is valid.
1123                          */
1124                         if (!pbody->rates_present && rates.length != 0) {
1125                                 pbody->rates = rates;
1126                                 pbody->rates_present = 1;
1127                         }
1128                         break;
1129                 case E_DS:
1130                         memcpy(&ds, p + offset, 2);
1131                         offset += 2;
1132                         length -= 2;
1133                         if (ds.length != 1) {
1134                                 offset += ds.length;
1135                                 length -= ds.length;
1136                                 break;
1137                         }
1138                         ds.channel = *(p + offset);
1139                         offset += 1;
1140                         length -= 1;
1141                         /*
1142                          * Present and not truncated.
1143                          *
1144                          * If we haven't already seen a DS IE,
1145                          * copy this one, otherwise ignore this one,
1146                          * so we later report the first one we saw.
1147                          */
1148                         if (!pbody->ds_present) {
1149                                 pbody->ds = ds;
1150                                 pbody->ds_present = 1;
1151                         }
1152                         break;
1153                 case E_CF:
1154                         memcpy(&cf, p + offset, 2);
1155                         offset += 2;
1156                         length -= 2;
1157                         if (cf.length != 6) {
1158                                 offset += cf.length;
1159                                 length -= cf.length;
1160                                 break;
1161                         }
1162                         memcpy(&cf.count, p + offset, 6);
1163                         offset += 6;
1164                         length -= 6;
1165                         /*
1166                          * Present and not truncated.
1167                          *
1168                          * If we haven't already seen a CF IE,
1169                          * copy this one, otherwise ignore this one,
1170                          * so we later report the first one we saw.
1171                          */
1172                         if (!pbody->cf_present) {
1173                                 pbody->cf = cf;
1174                                 pbody->cf_present = 1;
1175                         }
1176                         break;
1177                 case E_TIM:
1178                         memcpy(&tim, p + offset, 2);
1179                         offset += 2;
1180                         length -= 2;
1181                         if (tim.length <= 3) {
1182                                 offset += tim.length;
1183                                 length -= tim.length;
1184                                 break;
1185                         }
1186                         if (tim.length - 3 > (int)sizeof tim.bitmap)
1187                                 return 0;
1188                         memcpy(&tim.count, p + offset, 3);
1189                         offset += 3;
1190                         length -= 3;
1191
1192                         memcpy(tim.bitmap, p + (tim.length - 3),
1193                             (tim.length - 3));
1194                         offset += tim.length - 3;
1195                         length -= tim.length - 3;
1196                         /*
1197                          * Present and not truncated.
1198                          *
1199                          * If we haven't already seen a TIM IE,
1200                          * copy this one, otherwise ignore this one,
1201                          * so we later report the first one we saw.
1202                          */
1203                         if (!pbody->tim_present) {
1204                                 pbody->tim = tim;
1205                                 pbody->tim_present = 1;
1206                         }
1207                         break;
1208                 default:
1209 #if 0
1210                         ND_PRINT((ndo, "(1) unhandled element_id (%d)  ",
1211                             *(p + offset)));
1212 #endif
1213                         offset += 2 + elementlen;
1214                         length -= 2 + elementlen;
1215                         break;
1216                 }
1217         }
1218
1219         /* No problems found. */
1220         return 1;
1221 }
1222
1223 /*********************************************************************************
1224  * Print Handle functions for the management frame types
1225  *********************************************************************************/
1226
1227 static int
1228 handle_beacon(netdissect_options *ndo,
1229               const u_char *p, u_int length)
1230 {
1231         struct mgmt_body_t pbody;
1232         int offset = 0;
1233         int ret;
1234
1235         memset(&pbody, 0, sizeof(pbody));
1236
1237         if (!ND_TTEST2(*p, IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN +
1238             IEEE802_11_CAPINFO_LEN))
1239                 return 0;
1240         if (length < IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN +
1241             IEEE802_11_CAPINFO_LEN)
1242                 return 0;
1243         memcpy(&pbody.timestamp, p, IEEE802_11_TSTAMP_LEN);
1244         offset += IEEE802_11_TSTAMP_LEN;
1245         length -= IEEE802_11_TSTAMP_LEN;
1246         pbody.beacon_interval = EXTRACT_LE_16BITS(p+offset);
1247         offset += IEEE802_11_BCNINT_LEN;
1248         length -= IEEE802_11_BCNINT_LEN;
1249         pbody.capability_info = EXTRACT_LE_16BITS(p+offset);
1250         offset += IEEE802_11_CAPINFO_LEN;
1251         length -= IEEE802_11_CAPINFO_LEN;
1252
1253         ret = parse_elements(ndo, &pbody, p, offset, length);
1254
1255         PRINT_SSID(pbody);
1256         PRINT_RATES(pbody);
1257         ND_PRINT((ndo, " %s",
1258             CAPABILITY_ESS(pbody.capability_info) ? "ESS" : "IBSS"));
1259         PRINT_DS_CHANNEL(pbody);
1260
1261         return ret;
1262 }
1263
1264 static int
1265 handle_assoc_request(netdissect_options *ndo,
1266                      const u_char *p, u_int length)
1267 {
1268         struct mgmt_body_t pbody;
1269         int offset = 0;
1270         int ret;
1271
1272         memset(&pbody, 0, sizeof(pbody));
1273
1274         if (!ND_TTEST2(*p, IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN))
1275                 return 0;
1276         if (length < IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN)
1277                 return 0;
1278         pbody.capability_info = EXTRACT_LE_16BITS(p);
1279         offset += IEEE802_11_CAPINFO_LEN;
1280         length -= IEEE802_11_CAPINFO_LEN;
1281         pbody.listen_interval = EXTRACT_LE_16BITS(p+offset);
1282         offset += IEEE802_11_LISTENINT_LEN;
1283         length -= IEEE802_11_LISTENINT_LEN;
1284
1285         ret = parse_elements(ndo, &pbody, p, offset, length);
1286
1287         PRINT_SSID(pbody);
1288         PRINT_RATES(pbody);
1289         return ret;
1290 }
1291
1292 static int
1293 handle_assoc_response(netdissect_options *ndo,
1294                       const u_char *p, u_int length)
1295 {
1296         struct mgmt_body_t pbody;
1297         int offset = 0;
1298         int ret;
1299
1300         memset(&pbody, 0, sizeof(pbody));
1301
1302         if (!ND_TTEST2(*p, IEEE802_11_CAPINFO_LEN + IEEE802_11_STATUS_LEN +
1303             IEEE802_11_AID_LEN))
1304                 return 0;
1305         if (length < IEEE802_11_CAPINFO_LEN + IEEE802_11_STATUS_LEN +
1306             IEEE802_11_AID_LEN)
1307                 return 0;
1308         pbody.capability_info = EXTRACT_LE_16BITS(p);
1309         offset += IEEE802_11_CAPINFO_LEN;
1310         length -= IEEE802_11_CAPINFO_LEN;
1311         pbody.status_code = EXTRACT_LE_16BITS(p+offset);
1312         offset += IEEE802_11_STATUS_LEN;
1313         length -= IEEE802_11_STATUS_LEN;
1314         pbody.aid = EXTRACT_LE_16BITS(p+offset);
1315         offset += IEEE802_11_AID_LEN;
1316         length -= IEEE802_11_AID_LEN;
1317
1318         ret = parse_elements(ndo, &pbody, p, offset, length);
1319
1320         ND_PRINT((ndo, " AID(%x) :%s: %s", ((uint16_t)(pbody.aid << 2 )) >> 2 ,
1321             CAPABILITY_PRIVACY(pbody.capability_info) ? " PRIVACY " : "",
1322             (pbody.status_code < NUM_STATUSES
1323                 ? status_text[pbody.status_code]
1324                 : "n/a")));
1325
1326         return ret;
1327 }
1328
1329 static int
1330 handle_reassoc_request(netdissect_options *ndo,
1331                        const u_char *p, u_int length)
1332 {
1333         struct mgmt_body_t pbody;
1334         int offset = 0;
1335         int ret;
1336
1337         memset(&pbody, 0, sizeof(pbody));
1338
1339         if (!ND_TTEST2(*p, IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN +
1340             IEEE802_11_AP_LEN))
1341                 return 0;
1342         if (length < IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN +
1343             IEEE802_11_AP_LEN)
1344                 return 0;
1345         pbody.capability_info = EXTRACT_LE_16BITS(p);
1346         offset += IEEE802_11_CAPINFO_LEN;
1347         length -= IEEE802_11_CAPINFO_LEN;
1348         pbody.listen_interval = EXTRACT_LE_16BITS(p+offset);
1349         offset += IEEE802_11_LISTENINT_LEN;
1350         length -= IEEE802_11_LISTENINT_LEN;
1351         memcpy(&pbody.ap, p+offset, IEEE802_11_AP_LEN);
1352         offset += IEEE802_11_AP_LEN;
1353         length -= IEEE802_11_AP_LEN;
1354
1355         ret = parse_elements(ndo, &pbody, p, offset, length);
1356
1357         PRINT_SSID(pbody);
1358         ND_PRINT((ndo, " AP : %s", etheraddr_string(ndo,  pbody.ap )));
1359
1360         return ret;
1361 }
1362
1363 static int
1364 handle_reassoc_response(netdissect_options *ndo,
1365                         const u_char *p, u_int length)
1366 {
1367         /* Same as a Association Reponse */
1368         return handle_assoc_response(ndo, p, length);
1369 }
1370
1371 static int
1372 handle_probe_request(netdissect_options *ndo,
1373                      const u_char *p, u_int length)
1374 {
1375         struct mgmt_body_t  pbody;
1376         int offset = 0;
1377         int ret;
1378
1379         memset(&pbody, 0, sizeof(pbody));
1380
1381         ret = parse_elements(ndo, &pbody, p, offset, length);
1382
1383         PRINT_SSID(pbody);
1384         PRINT_RATES(pbody);
1385
1386         return ret;
1387 }
1388
1389 static int
1390 handle_probe_response(netdissect_options *ndo,
1391                       const u_char *p, u_int length)
1392 {
1393         struct mgmt_body_t  pbody;
1394         int offset = 0;
1395         int ret;
1396
1397         memset(&pbody, 0, sizeof(pbody));
1398
1399         if (!ND_TTEST2(*p, IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN +
1400             IEEE802_11_CAPINFO_LEN))
1401                 return 0;
1402         if (length < IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN +
1403             IEEE802_11_CAPINFO_LEN)
1404                 return 0;
1405         memcpy(&pbody.timestamp, p, IEEE802_11_TSTAMP_LEN);
1406         offset += IEEE802_11_TSTAMP_LEN;
1407         length -= IEEE802_11_TSTAMP_LEN;
1408         pbody.beacon_interval = EXTRACT_LE_16BITS(p+offset);
1409         offset += IEEE802_11_BCNINT_LEN;
1410         length -= IEEE802_11_BCNINT_LEN;
1411         pbody.capability_info = EXTRACT_LE_16BITS(p+offset);
1412         offset += IEEE802_11_CAPINFO_LEN;
1413         length -= IEEE802_11_CAPINFO_LEN;
1414
1415         ret = parse_elements(ndo, &pbody, p, offset, length);
1416
1417         PRINT_SSID(pbody);
1418         PRINT_RATES(pbody);
1419         PRINT_DS_CHANNEL(pbody);
1420
1421         return ret;
1422 }
1423
1424 static int
1425 handle_atim(void)
1426 {
1427         /* the frame body for ATIM is null. */
1428         return 1;
1429 }
1430
1431 static int
1432 handle_disassoc(netdissect_options *ndo,
1433                 const u_char *p, u_int length)
1434 {
1435         struct mgmt_body_t  pbody;
1436
1437         memset(&pbody, 0, sizeof(pbody));
1438
1439         if (!ND_TTEST2(*p, IEEE802_11_REASON_LEN))
1440                 return 0;
1441         if (length < IEEE802_11_REASON_LEN)
1442                 return 0;
1443         pbody.reason_code = EXTRACT_LE_16BITS(p);
1444
1445         ND_PRINT((ndo, ": %s",
1446             (pbody.reason_code < NUM_REASONS)
1447                 ? reason_text[pbody.reason_code]
1448                 : "Reserved"));
1449
1450         return 1;
1451 }
1452
1453 static int
1454 handle_auth(netdissect_options *ndo,
1455             const u_char *p, u_int length)
1456 {
1457         struct mgmt_body_t  pbody;
1458         int offset = 0;
1459         int ret;
1460
1461         memset(&pbody, 0, sizeof(pbody));
1462
1463         if (!ND_TTEST2(*p, 6))
1464                 return 0;
1465         if (length < 6)
1466                 return 0;
1467         pbody.auth_alg = EXTRACT_LE_16BITS(p);
1468         offset += 2;
1469         length -= 2;
1470         pbody.auth_trans_seq_num = EXTRACT_LE_16BITS(p + offset);
1471         offset += 2;
1472         length -= 2;
1473         pbody.status_code = EXTRACT_LE_16BITS(p + offset);
1474         offset += 2;
1475         length -= 2;
1476
1477         ret = parse_elements(ndo, &pbody, p, offset, length);
1478
1479         if ((pbody.auth_alg == 1) &&
1480             ((pbody.auth_trans_seq_num == 2) ||
1481              (pbody.auth_trans_seq_num == 3))) {
1482                 ND_PRINT((ndo, " (%s)-%x [Challenge Text] %s",
1483                     (pbody.auth_alg < NUM_AUTH_ALGS)
1484                         ? auth_alg_text[pbody.auth_alg]
1485                         : "Reserved",
1486                     pbody.auth_trans_seq_num,
1487                     ((pbody.auth_trans_seq_num % 2)
1488                         ? ((pbody.status_code < NUM_STATUSES)
1489                                ? status_text[pbody.status_code]
1490                                : "n/a") : "")));
1491                 return ret;
1492         }
1493         ND_PRINT((ndo, " (%s)-%x: %s",
1494             (pbody.auth_alg < NUM_AUTH_ALGS)
1495                 ? auth_alg_text[pbody.auth_alg]
1496                 : "Reserved",
1497             pbody.auth_trans_seq_num,
1498             (pbody.auth_trans_seq_num % 2)
1499                 ? ((pbody.status_code < NUM_STATUSES)
1500                     ? status_text[pbody.status_code]
1501                     : "n/a")
1502                 : ""));
1503
1504         return ret;
1505 }
1506
1507 static int
1508 handle_deauth(netdissect_options *ndo,
1509               const uint8_t *src, const u_char *p, u_int length)
1510 {
1511         struct mgmt_body_t  pbody;
1512         const char *reason = NULL;
1513
1514         memset(&pbody, 0, sizeof(pbody));
1515
1516         if (!ND_TTEST2(*p, IEEE802_11_REASON_LEN))
1517                 return 0;
1518         if (length < IEEE802_11_REASON_LEN)
1519                 return 0;
1520         pbody.reason_code = EXTRACT_LE_16BITS(p);
1521
1522         reason = (pbody.reason_code < NUM_REASONS)
1523                         ? reason_text[pbody.reason_code]
1524                         : "Reserved";
1525
1526         if (ndo->ndo_eflag) {
1527                 ND_PRINT((ndo, ": %s", reason));
1528         } else {
1529                 ND_PRINT((ndo, " (%s): %s", etheraddr_string(ndo, src), reason));
1530         }
1531         return 1;
1532 }
1533
1534 #define PRINT_HT_ACTION(v) (\
1535         (v) == 0 ? ND_PRINT((ndo, "TxChWidth")) : \
1536         (v) == 1 ? ND_PRINT((ndo, "MIMOPwrSave")) : \
1537                    ND_PRINT((ndo, "Act#%d", (v))) \
1538 )
1539 #define PRINT_BA_ACTION(v) (\
1540         (v) == 0 ? ND_PRINT((ndo, "ADDBA Request")) : \
1541         (v) == 1 ? ND_PRINT((ndo, "ADDBA Response")) : \
1542         (v) == 2 ? ND_PRINT((ndo, "DELBA")) : \
1543                    ND_PRINT((ndo, "Act#%d", (v))) \
1544 )
1545 #define PRINT_MESHLINK_ACTION(v) (\
1546         (v) == 0 ? ND_PRINT((ndo, "Request")) : \
1547         (v) == 1 ? ND_PRINT((ndo, "Report")) : \
1548                    ND_PRINT((ndo, "Act#%d", (v))) \
1549 )
1550 #define PRINT_MESHPEERING_ACTION(v) (\
1551         (v) == 0 ? ND_PRINT((ndo, "Open")) : \
1552         (v) == 1 ? ND_PRINT((ndo, "Confirm")) : \
1553         (v) == 2 ? ND_PRINT((ndo, "Close")) : \
1554                    ND_PRINT((ndo, "Act#%d", (v))) \
1555 )
1556 #define PRINT_MESHPATH_ACTION(v) (\
1557         (v) == 0 ? ND_PRINT((ndo, "Request")) : \
1558         (v) == 1 ? ND_PRINT((ndo, "Report")) : \
1559         (v) == 2 ? ND_PRINT((ndo, "Error")) : \
1560         (v) == 3 ? ND_PRINT((ndo, "RootAnnouncement")) : \
1561                    ND_PRINT((ndo, "Act#%d", (v))) \
1562 )
1563
1564 #define PRINT_MESH_ACTION(v) (\
1565         (v) == 0 ? ND_PRINT((ndo, "MeshLink")) : \
1566         (v) == 1 ? ND_PRINT((ndo, "HWMP")) : \
1567         (v) == 2 ? ND_PRINT((ndo, "Gate Announcement")) : \
1568         (v) == 3 ? ND_PRINT((ndo, "Congestion Control")) : \
1569         (v) == 4 ? ND_PRINT((ndo, "MCCA Setup Request")) : \
1570         (v) == 5 ? ND_PRINT((ndo, "MCCA Setup Reply")) : \
1571         (v) == 6 ? ND_PRINT((ndo, "MCCA Advertisement Request")) : \
1572         (v) == 7 ? ND_PRINT((ndo, "MCCA Advertisement")) : \
1573         (v) == 8 ? ND_PRINT((ndo, "MCCA Teardown")) : \
1574         (v) == 9 ? ND_PRINT((ndo, "TBTT Adjustment Request")) : \
1575         (v) == 10 ? ND_PRINT((ndo, "TBTT Adjustment Response")) : \
1576                    ND_PRINT((ndo, "Act#%d", (v))) \
1577 )
1578 #define PRINT_MULTIHOP_ACTION(v) (\
1579         (v) == 0 ? ND_PRINT((ndo, "Proxy Update")) : \
1580         (v) == 1 ? ND_PRINT((ndo, "Proxy Update Confirmation")) : \
1581                    ND_PRINT((ndo, "Act#%d", (v))) \
1582 )
1583 #define PRINT_SELFPROT_ACTION(v) (\
1584         (v) == 1 ? ND_PRINT((ndo, "Peering Open")) : \
1585         (v) == 2 ? ND_PRINT((ndo, "Peering Confirm")) : \
1586         (v) == 3 ? ND_PRINT((ndo, "Peering Close")) : \
1587         (v) == 4 ? ND_PRINT((ndo, "Group Key Inform")) : \
1588         (v) == 5 ? ND_PRINT((ndo, "Group Key Acknowledge")) : \
1589                    ND_PRINT((ndo, "Act#%d", (v))) \
1590 )
1591
1592 static int
1593 handle_action(netdissect_options *ndo,
1594               const uint8_t *src, const u_char *p, u_int length)
1595 {
1596         if (!ND_TTEST2(*p, 2))
1597                 return 0;
1598         if (length < 2)
1599                 return 0;
1600         if (ndo->ndo_eflag) {
1601                 ND_PRINT((ndo, ": "));
1602         } else {
1603                 ND_PRINT((ndo, " (%s): ", etheraddr_string(ndo, src)));
1604         }
1605         switch (p[0]) {
1606         case 0: ND_PRINT((ndo, "Spectrum Management Act#%d", p[1])); break;
1607         case 1: ND_PRINT((ndo, "QoS Act#%d", p[1])); break;
1608         case 2: ND_PRINT((ndo, "DLS Act#%d", p[1])); break;
1609         case 3: ND_PRINT((ndo, "BA ")); PRINT_BA_ACTION(p[1]); break;
1610         case 7: ND_PRINT((ndo, "HT ")); PRINT_HT_ACTION(p[1]); break;
1611         case 13: ND_PRINT((ndo, "MeshAction ")); PRINT_MESH_ACTION(p[1]); break;
1612         case 14:
1613                 ND_PRINT((ndo, "MultiohopAction "));
1614                 PRINT_MULTIHOP_ACTION(p[1]); break;
1615         case 15:
1616                 ND_PRINT((ndo, "SelfprotectAction "));
1617                 PRINT_SELFPROT_ACTION(p[1]); break;
1618         case 127: ND_PRINT((ndo, "Vendor Act#%d", p[1])); break;
1619         default:
1620                 ND_PRINT((ndo, "Reserved(%d) Act#%d", p[0], p[1]));
1621                 break;
1622         }
1623         return 1;
1624 }
1625
1626
1627 /*********************************************************************************
1628  * Print Body funcs
1629  *********************************************************************************/
1630
1631
1632 static int
1633 mgmt_body_print(netdissect_options *ndo,
1634                 uint16_t fc, const uint8_t *src, const u_char *p, u_int length)
1635 {
1636         ND_PRINT((ndo, "%s", tok2str(st_str, "Unhandled Management subtype(%x)", FC_SUBTYPE(fc))));
1637
1638         /* There may be a problem w/ AP not having this bit set */
1639         if (FC_PROTECTED(fc))
1640                 return wep_print(ndo, p);
1641         switch (FC_SUBTYPE(fc)) {
1642         case ST_ASSOC_REQUEST:
1643                 return handle_assoc_request(ndo, p, length);
1644         case ST_ASSOC_RESPONSE:
1645                 return handle_assoc_response(ndo, p, length);
1646         case ST_REASSOC_REQUEST:
1647                 return handle_reassoc_request(ndo, p, length);
1648         case ST_REASSOC_RESPONSE:
1649                 return handle_reassoc_response(ndo, p, length);
1650         case ST_PROBE_REQUEST:
1651                 return handle_probe_request(ndo, p, length);
1652         case ST_PROBE_RESPONSE:
1653                 return handle_probe_response(ndo, p, length);
1654         case ST_BEACON:
1655                 return handle_beacon(ndo, p, length);
1656         case ST_ATIM:
1657                 return handle_atim();
1658         case ST_DISASSOC:
1659                 return handle_disassoc(ndo, p, length);
1660         case ST_AUTH:
1661                 return handle_auth(ndo, p, length);
1662         case ST_DEAUTH:
1663                 return handle_deauth(ndo, src, p, length);
1664         case ST_ACTION:
1665                 return handle_action(ndo, src, p, length);
1666         default:
1667                 return 1;
1668         }
1669 }
1670
1671
1672 /*********************************************************************************
1673  * Handles printing all the control frame types
1674  *********************************************************************************/
1675
1676 static int
1677 ctrl_body_print(netdissect_options *ndo,
1678                 uint16_t fc, const u_char *p)
1679 {
1680         ND_PRINT((ndo, "%s", tok2str(ctrl_str, "Unknown Ctrl Subtype", FC_SUBTYPE(fc))));
1681         switch (FC_SUBTYPE(fc)) {
1682         case CTRL_CONTROL_WRAPPER:
1683                 /* XXX - requires special handling */
1684                 break;
1685         case CTRL_BAR:
1686                 if (!ND_TTEST2(*p, CTRL_BAR_HDRLEN))
1687                         return 0;
1688                 if (!ndo->ndo_eflag)
1689                         ND_PRINT((ndo, " RA:%s TA:%s CTL(%x) SEQ(%u) ",
1690                             etheraddr_string(ndo, ((const struct ctrl_bar_hdr_t *)p)->ra),
1691                             etheraddr_string(ndo, ((const struct ctrl_bar_hdr_t *)p)->ta),
1692                             EXTRACT_LE_16BITS(&(((const struct ctrl_bar_hdr_t *)p)->ctl)),
1693                             EXTRACT_LE_16BITS(&(((const struct ctrl_bar_hdr_t *)p)->seq))));
1694                 break;
1695         case CTRL_BA:
1696                 if (!ND_TTEST2(*p, CTRL_BA_HDRLEN))
1697                         return 0;
1698                 if (!ndo->ndo_eflag)
1699                         ND_PRINT((ndo, " RA:%s ",
1700                             etheraddr_string(ndo, ((const struct ctrl_ba_hdr_t *)p)->ra)));
1701                 break;
1702         case CTRL_PS_POLL:
1703                 if (!ND_TTEST2(*p, CTRL_PS_POLL_HDRLEN))
1704                         return 0;
1705                 ND_PRINT((ndo, " AID(%x)",
1706                     EXTRACT_LE_16BITS(&(((const struct ctrl_ps_poll_hdr_t *)p)->aid))));
1707                 break;
1708         case CTRL_RTS:
1709                 if (!ND_TTEST2(*p, CTRL_RTS_HDRLEN))
1710                         return 0;
1711                 if (!ndo->ndo_eflag)
1712                         ND_PRINT((ndo, " TA:%s ",
1713                             etheraddr_string(ndo, ((const struct ctrl_rts_hdr_t *)p)->ta)));
1714                 break;
1715         case CTRL_CTS:
1716                 if (!ND_TTEST2(*p, CTRL_CTS_HDRLEN))
1717                         return 0;
1718                 if (!ndo->ndo_eflag)
1719                         ND_PRINT((ndo, " RA:%s ",
1720                             etheraddr_string(ndo, ((const struct ctrl_cts_hdr_t *)p)->ra)));
1721                 break;
1722         case CTRL_ACK:
1723                 if (!ND_TTEST2(*p, CTRL_ACK_HDRLEN))
1724                         return 0;
1725                 if (!ndo->ndo_eflag)
1726                         ND_PRINT((ndo, " RA:%s ",
1727                             etheraddr_string(ndo, ((const struct ctrl_ack_hdr_t *)p)->ra)));
1728                 break;
1729         case CTRL_CF_END:
1730                 if (!ND_TTEST2(*p, CTRL_END_HDRLEN))
1731                         return 0;
1732                 if (!ndo->ndo_eflag)
1733                         ND_PRINT((ndo, " RA:%s ",
1734                             etheraddr_string(ndo, ((const struct ctrl_end_hdr_t *)p)->ra)));
1735                 break;
1736         case CTRL_END_ACK:
1737                 if (!ND_TTEST2(*p, CTRL_END_ACK_HDRLEN))
1738                         return 0;
1739                 if (!ndo->ndo_eflag)
1740                         ND_PRINT((ndo, " RA:%s ",
1741                             etheraddr_string(ndo, ((const struct ctrl_end_ack_hdr_t *)p)->ra)));
1742                 break;
1743         }
1744         return 1;
1745 }
1746
1747 /*
1748  *  Data Frame - Address field contents
1749  *
1750  *  To Ds  | From DS | Addr 1 | Addr 2 | Addr 3 | Addr 4
1751  *    0    |  0      |  DA    | SA     | BSSID  | n/a
1752  *    0    |  1      |  DA    | BSSID  | SA     | n/a
1753  *    1    |  0      |  BSSID | SA     | DA     | n/a
1754  *    1    |  1      |  RA    | TA     | DA     | SA
1755  */
1756
1757 /*
1758  * Function to get source and destination MAC addresses for a data frame.
1759  */
1760 static void
1761 get_data_src_dst_mac(uint16_t fc, const u_char *p, const uint8_t **srcp,
1762                      const uint8_t **dstp)
1763 {
1764 #define ADDR1  (p + 4)
1765 #define ADDR2  (p + 10)
1766 #define ADDR3  (p + 16)
1767 #define ADDR4  (p + 24)
1768
1769         if (!FC_TO_DS(fc)) {
1770                 if (!FC_FROM_DS(fc)) {
1771                         /* not To DS and not From DS */
1772                         *srcp = ADDR2;
1773                         *dstp = ADDR1;
1774                 } else {
1775                         /* not To DS and From DS */
1776                         *srcp = ADDR3;
1777                         *dstp = ADDR1;
1778                 }
1779         } else {
1780                 if (!FC_FROM_DS(fc)) {
1781                         /* From DS and not To DS */
1782                         *srcp = ADDR2;
1783                         *dstp = ADDR3;
1784                 } else {
1785                         /* To DS and From DS */
1786                         *srcp = ADDR4;
1787                         *dstp = ADDR3;
1788                 }
1789         }
1790
1791 #undef ADDR1
1792 #undef ADDR2
1793 #undef ADDR3
1794 #undef ADDR4
1795 }
1796
1797 static void
1798 get_mgmt_src_dst_mac(const u_char *p, const uint8_t **srcp, const uint8_t **dstp)
1799 {
1800         const struct mgmt_header_t *hp = (const struct mgmt_header_t *) p;
1801
1802         if (srcp != NULL)
1803                 *srcp = hp->sa;
1804         if (dstp != NULL)
1805                 *dstp = hp->da;
1806 }
1807
1808 /*
1809  * Print Header funcs
1810  */
1811
1812 static void
1813 data_header_print(netdissect_options *ndo, uint16_t fc, const u_char *p)
1814 {
1815         u_int subtype = FC_SUBTYPE(fc);
1816
1817         if (DATA_FRAME_IS_CF_ACK(subtype) || DATA_FRAME_IS_CF_POLL(subtype) ||
1818             DATA_FRAME_IS_QOS(subtype)) {
1819                 ND_PRINT((ndo, "CF "));
1820                 if (DATA_FRAME_IS_CF_ACK(subtype)) {
1821                         if (DATA_FRAME_IS_CF_POLL(subtype))
1822                                 ND_PRINT((ndo, "Ack/Poll"));
1823                         else
1824                                 ND_PRINT((ndo, "Ack"));
1825                 } else {
1826                         if (DATA_FRAME_IS_CF_POLL(subtype))
1827                                 ND_PRINT((ndo, "Poll"));
1828                 }
1829                 if (DATA_FRAME_IS_QOS(subtype))
1830                         ND_PRINT((ndo, "+QoS"));
1831                 ND_PRINT((ndo, " "));
1832         }
1833
1834 #define ADDR1  (p + 4)
1835 #define ADDR2  (p + 10)
1836 #define ADDR3  (p + 16)
1837 #define ADDR4  (p + 24)
1838
1839         if (!FC_TO_DS(fc) && !FC_FROM_DS(fc)) {
1840                 ND_PRINT((ndo, "DA:%s SA:%s BSSID:%s ",
1841                     etheraddr_string(ndo, ADDR1), etheraddr_string(ndo, ADDR2),
1842                     etheraddr_string(ndo, ADDR3)));
1843         } else if (!FC_TO_DS(fc) && FC_FROM_DS(fc)) {
1844                 ND_PRINT((ndo, "DA:%s BSSID:%s SA:%s ",
1845                     etheraddr_string(ndo, ADDR1), etheraddr_string(ndo, ADDR2),
1846                     etheraddr_string(ndo, ADDR3)));
1847         } else if (FC_TO_DS(fc) && !FC_FROM_DS(fc)) {
1848                 ND_PRINT((ndo, "BSSID:%s SA:%s DA:%s ",
1849                     etheraddr_string(ndo, ADDR1), etheraddr_string(ndo, ADDR2),
1850                     etheraddr_string(ndo, ADDR3)));
1851         } else if (FC_TO_DS(fc) && FC_FROM_DS(fc)) {
1852                 ND_PRINT((ndo, "RA:%s TA:%s DA:%s SA:%s ",
1853                     etheraddr_string(ndo, ADDR1), etheraddr_string(ndo, ADDR2),
1854                     etheraddr_string(ndo, ADDR3), etheraddr_string(ndo, ADDR4)));
1855         }
1856
1857 #undef ADDR1
1858 #undef ADDR2
1859 #undef ADDR3
1860 #undef ADDR4
1861 }
1862
1863 static void
1864 mgmt_header_print(netdissect_options *ndo, const u_char *p)
1865 {
1866         const struct mgmt_header_t *hp = (const struct mgmt_header_t *) p;
1867
1868         ND_PRINT((ndo, "BSSID:%s DA:%s SA:%s ",
1869             etheraddr_string(ndo, (hp)->bssid), etheraddr_string(ndo, (hp)->da),
1870             etheraddr_string(ndo, (hp)->sa)));
1871 }
1872
1873 static void
1874 ctrl_header_print(netdissect_options *ndo, uint16_t fc, const u_char *p)
1875 {
1876         switch (FC_SUBTYPE(fc)) {
1877         case CTRL_BAR:
1878                 ND_PRINT((ndo, " RA:%s TA:%s CTL(%x) SEQ(%u) ",
1879                     etheraddr_string(ndo, ((const struct ctrl_bar_hdr_t *)p)->ra),
1880                     etheraddr_string(ndo, ((const struct ctrl_bar_hdr_t *)p)->ta),
1881                     EXTRACT_LE_16BITS(&(((const struct ctrl_bar_hdr_t *)p)->ctl)),
1882                     EXTRACT_LE_16BITS(&(((const struct ctrl_bar_hdr_t *)p)->seq))));
1883                 break;
1884         case CTRL_BA:
1885                 ND_PRINT((ndo, "RA:%s ",
1886                     etheraddr_string(ndo, ((const struct ctrl_ba_hdr_t *)p)->ra)));
1887                 break;
1888         case CTRL_PS_POLL:
1889                 ND_PRINT((ndo, "BSSID:%s TA:%s ",
1890                     etheraddr_string(ndo, ((const struct ctrl_ps_poll_hdr_t *)p)->bssid),
1891                     etheraddr_string(ndo, ((const struct ctrl_ps_poll_hdr_t *)p)->ta)));
1892                 break;
1893         case CTRL_RTS:
1894                 ND_PRINT((ndo, "RA:%s TA:%s ",
1895                     etheraddr_string(ndo, ((const struct ctrl_rts_hdr_t *)p)->ra),
1896                     etheraddr_string(ndo, ((const struct ctrl_rts_hdr_t *)p)->ta)));
1897                 break;
1898         case CTRL_CTS:
1899                 ND_PRINT((ndo, "RA:%s ",
1900                     etheraddr_string(ndo, ((const struct ctrl_cts_hdr_t *)p)->ra)));
1901                 break;
1902         case CTRL_ACK:
1903                 ND_PRINT((ndo, "RA:%s ",
1904                     etheraddr_string(ndo, ((const struct ctrl_ack_hdr_t *)p)->ra)));
1905                 break;
1906         case CTRL_CF_END:
1907                 ND_PRINT((ndo, "RA:%s BSSID:%s ",
1908                     etheraddr_string(ndo, ((const struct ctrl_end_hdr_t *)p)->ra),
1909                     etheraddr_string(ndo, ((const struct ctrl_end_hdr_t *)p)->bssid)));
1910                 break;
1911         case CTRL_END_ACK:
1912                 ND_PRINT((ndo, "RA:%s BSSID:%s ",
1913                     etheraddr_string(ndo, ((const struct ctrl_end_ack_hdr_t *)p)->ra),
1914                     etheraddr_string(ndo, ((const struct ctrl_end_ack_hdr_t *)p)->bssid)));
1915                 break;
1916         default:
1917                 /* We shouldn't get here - we should already have quit */
1918                 break;
1919         }
1920 }
1921
1922 static int
1923 extract_header_length(netdissect_options *ndo,
1924                       uint16_t fc)
1925 {
1926         int len;
1927
1928         switch (FC_TYPE(fc)) {
1929         case T_MGMT:
1930                 return MGMT_HDRLEN;
1931         case T_CTRL:
1932                 switch (FC_SUBTYPE(fc)) {
1933                 case CTRL_CONTROL_WRAPPER:
1934                         return CTRL_CONTROL_WRAPPER_HDRLEN;
1935                 case CTRL_BAR:
1936                         return CTRL_BAR_HDRLEN;
1937                 case CTRL_BA:
1938                         return CTRL_BA_HDRLEN;
1939                 case CTRL_PS_POLL:
1940                         return CTRL_PS_POLL_HDRLEN;
1941                 case CTRL_RTS:
1942                         return CTRL_RTS_HDRLEN;
1943                 case CTRL_CTS:
1944                         return CTRL_CTS_HDRLEN;
1945                 case CTRL_ACK:
1946                         return CTRL_ACK_HDRLEN;
1947                 case CTRL_CF_END:
1948                         return CTRL_END_HDRLEN;
1949                 case CTRL_END_ACK:
1950                         return CTRL_END_ACK_HDRLEN;
1951                 default:
1952                         ND_PRINT((ndo, "unknown 802.11 ctrl frame subtype (%d)", FC_SUBTYPE(fc)));
1953                         return 0;
1954                 }
1955         case T_DATA:
1956                 len = (FC_TO_DS(fc) && FC_FROM_DS(fc)) ? 30 : 24;
1957                 if (DATA_FRAME_IS_QOS(FC_SUBTYPE(fc)))
1958                         len += 2;
1959                 return len;
1960         default:
1961                 ND_PRINT((ndo, "unknown 802.11 frame type (%d)", FC_TYPE(fc)));
1962                 return 0;
1963         }
1964 }
1965
1966 static int
1967 extract_mesh_header_length(const u_char *p)
1968 {
1969         return (p[0] &~ 3) ? 0 : 6*(1 + (p[0] & 3));
1970 }
1971
1972 /*
1973  * Print the 802.11 MAC header.
1974  */
1975 static void
1976 ieee_802_11_hdr_print(netdissect_options *ndo,
1977                       uint16_t fc, const u_char *p, u_int hdrlen,
1978                       u_int meshdrlen)
1979 {
1980         if (ndo->ndo_vflag) {
1981                 if (FC_MORE_DATA(fc))
1982                         ND_PRINT((ndo, "More Data "));
1983                 if (FC_MORE_FLAG(fc))
1984                         ND_PRINT((ndo, "More Fragments "));
1985                 if (FC_POWER_MGMT(fc))
1986                         ND_PRINT((ndo, "Pwr Mgmt "));
1987                 if (FC_RETRY(fc))
1988                         ND_PRINT((ndo, "Retry "));
1989                 if (FC_ORDER(fc))
1990                         ND_PRINT((ndo, "Strictly Ordered "));
1991                 if (FC_PROTECTED(fc))
1992                         ND_PRINT((ndo, "Protected "));
1993                 if (FC_TYPE(fc) != T_CTRL || FC_SUBTYPE(fc) != CTRL_PS_POLL)
1994                         ND_PRINT((ndo, "%dus ",
1995                             EXTRACT_LE_16BITS(
1996                                 &((const struct mgmt_header_t *)p)->duration)));
1997         }
1998         if (meshdrlen != 0) {
1999                 const struct meshcntl_t *mc =
2000                     (const struct meshcntl_t *)&p[hdrlen - meshdrlen];
2001                 int ae = mc->flags & 3;
2002
2003                 ND_PRINT((ndo, "MeshData (AE %d TTL %u seq %u", ae, mc->ttl,
2004                     EXTRACT_LE_32BITS(mc->seq)));
2005                 if (ae > 0)
2006                         ND_PRINT((ndo, " A4:%s", etheraddr_string(ndo, mc->addr4)));
2007                 if (ae > 1)
2008                         ND_PRINT((ndo, " A5:%s", etheraddr_string(ndo, mc->addr5)));
2009                 if (ae > 2)
2010                         ND_PRINT((ndo, " A6:%s", etheraddr_string(ndo, mc->addr6)));
2011                 ND_PRINT((ndo, ") "));
2012         }
2013
2014         switch (FC_TYPE(fc)) {
2015         case T_MGMT:
2016                 mgmt_header_print(ndo, p);
2017                 break;
2018         case T_CTRL:
2019                 ctrl_header_print(ndo, fc, p);
2020                 break;
2021         case T_DATA:
2022                 data_header_print(ndo, fc, p);
2023                 break;
2024         default:
2025                 break;
2026         }
2027 }
2028
2029 #ifndef roundup2
2030 #define roundup2(x, y)  (((x)+((y)-1))&(~((y)-1))) /* if y is powers of two */
2031 #endif
2032
2033 static const char tstr[] = "[|802.11]";
2034
2035 static u_int
2036 ieee802_11_print(netdissect_options *ndo,
2037                  const u_char *p, u_int length, u_int orig_caplen, int pad,
2038                  u_int fcslen)
2039 {
2040         uint16_t fc;
2041         u_int caplen, hdrlen, meshdrlen;
2042         struct lladdr_info src, dst;
2043         int llc_hdrlen;
2044
2045         caplen = orig_caplen;
2046         /* Remove FCS, if present */
2047         if (length < fcslen) {
2048                 ND_PRINT((ndo, "%s", tstr));
2049                 return caplen;
2050         }
2051         length -= fcslen;
2052         if (caplen > length) {
2053                 /* Amount of FCS in actual packet data, if any */
2054                 fcslen = caplen - length;
2055                 caplen -= fcslen;
2056                 ndo->ndo_snapend -= fcslen;
2057         }
2058
2059         if (caplen < IEEE802_11_FC_LEN) {
2060                 ND_PRINT((ndo, "%s", tstr));
2061                 return orig_caplen;
2062         }
2063
2064         fc = EXTRACT_LE_16BITS(p);
2065         hdrlen = extract_header_length(ndo, fc);
2066         if (hdrlen == 0) {
2067                 /* Unknown frame type or control frame subtype; quit. */
2068                 return (0);
2069         }
2070         if (pad)
2071                 hdrlen = roundup2(hdrlen, 4);
2072         if (ndo->ndo_Hflag && FC_TYPE(fc) == T_DATA &&
2073             DATA_FRAME_IS_QOS(FC_SUBTYPE(fc))) {
2074                 meshdrlen = extract_mesh_header_length(p+hdrlen);
2075                 hdrlen += meshdrlen;
2076         } else
2077                 meshdrlen = 0;
2078
2079         if (caplen < hdrlen) {
2080                 ND_PRINT((ndo, "%s", tstr));
2081                 return hdrlen;
2082         }
2083
2084         if (ndo->ndo_eflag)
2085                 ieee_802_11_hdr_print(ndo, fc, p, hdrlen, meshdrlen);
2086
2087         /*
2088          * Go past the 802.11 header.
2089          */
2090         length -= hdrlen;
2091         caplen -= hdrlen;
2092         p += hdrlen;
2093
2094         src.addr_string = etheraddr_string;
2095         dst.addr_string = etheraddr_string;
2096         switch (FC_TYPE(fc)) {
2097         case T_MGMT:
2098                 get_mgmt_src_dst_mac(p - hdrlen, &src.addr, &dst.addr);
2099                 if (!mgmt_body_print(ndo, fc, src.addr, p, length)) {
2100                         ND_PRINT((ndo, "%s", tstr));
2101                         return hdrlen;
2102                 }
2103                 break;
2104         case T_CTRL:
2105                 if (!ctrl_body_print(ndo, fc, p - hdrlen)) {
2106                         ND_PRINT((ndo, "%s", tstr));
2107                         return hdrlen;
2108                 }
2109                 break;
2110         case T_DATA:
2111                 if (DATA_FRAME_IS_NULL(FC_SUBTYPE(fc)))
2112                         return hdrlen;  /* no-data frame */
2113                 /* There may be a problem w/ AP not having this bit set */
2114                 if (FC_PROTECTED(fc)) {
2115                         ND_PRINT((ndo, "Data"));
2116                         if (!wep_print(ndo, p)) {
2117                                 ND_PRINT((ndo, "%s", tstr));
2118                                 return hdrlen;
2119                         }
2120                 } else {
2121                         get_data_src_dst_mac(fc, p - hdrlen, &src.addr, &dst.addr);
2122                         llc_hdrlen = llc_print(ndo, p, length, caplen, &src, &dst);
2123                         if (llc_hdrlen < 0) {
2124                                 /*
2125                                  * Some kinds of LLC packet we cannot
2126                                  * handle intelligently
2127                                  */
2128                                 if (!ndo->ndo_suppress_default_print)
2129                                         ND_DEFAULTPRINT(p, caplen);
2130                                 llc_hdrlen = -llc_hdrlen;
2131                         }
2132                         hdrlen += llc_hdrlen;
2133                 }
2134                 break;
2135         default:
2136                 /* We shouldn't get here - we should already have quit */
2137                 break;
2138         }
2139
2140         return hdrlen;
2141 }
2142
2143 /*
2144  * This is the top level routine of the printer.  'p' points
2145  * to the 802.11 header of the packet, 'h->ts' is the timestamp,
2146  * 'h->len' is the length of the packet off the wire, and 'h->caplen'
2147  * is the number of bytes actually captured.
2148  */
2149 u_int
2150 ieee802_11_if_print(netdissect_options *ndo,
2151                     const struct pcap_pkthdr *h, const u_char *p)
2152 {
2153         return ieee802_11_print(ndo, p, h->len, h->caplen, 0, 0);
2154 }
2155
2156
2157 /* $FreeBSD: projects/clang400-import/contrib/tcpdump/print-802_11.c 276788 2015-01-07 19:55:18Z delphij $ */
2158 /* NetBSD: ieee802_11_radio.h,v 1.2 2006/02/26 03:04:03 dyoung Exp  */
2159
2160 /*-
2161  * Copyright (c) 2003, 2004 David Young.  All rights reserved.
2162  *
2163  * Redistribution and use in source and binary forms, with or without
2164  * modification, are permitted provided that the following conditions
2165  * are met:
2166  * 1. Redistributions of source code must retain the above copyright
2167  *    notice, this list of conditions and the following disclaimer.
2168  * 2. Redistributions in binary form must reproduce the above copyright
2169  *    notice, this list of conditions and the following disclaimer in the
2170  *    documentation and/or other materials provided with the distribution.
2171  * 3. The name of David Young may not be used to endorse or promote
2172  *    products derived from this software without specific prior
2173  *    written permission.
2174  *
2175  * THIS SOFTWARE IS PROVIDED BY DAVID YOUNG ``AS IS'' AND ANY
2176  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
2177  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
2178  * PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL DAVID
2179  * YOUNG BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
2180  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
2181  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2182  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
2183  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
2184  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2185  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
2186  * OF SUCH DAMAGE.
2187  */
2188
2189 /* A generic radio capture format is desirable. It must be
2190  * rigidly defined (e.g., units for fields should be given),
2191  * and easily extensible.
2192  *
2193  * The following is an extensible radio capture format. It is
2194  * based on a bitmap indicating which fields are present.
2195  *
2196  * I am trying to describe precisely what the application programmer
2197  * should expect in the following, and for that reason I tell the
2198  * units and origin of each measurement (where it applies), or else I
2199  * use sufficiently weaselly language ("is a monotonically nondecreasing
2200  * function of...") that I cannot set false expectations for lawyerly
2201  * readers.
2202  */
2203
2204 /*
2205  * The radio capture header precedes the 802.11 header.
2206  *
2207  * Note well: all radiotap fields are little-endian.
2208  */
2209 struct ieee80211_radiotap_header {
2210         uint8_t         it_version;     /* Version 0. Only increases
2211                                          * for drastic changes,
2212                                          * introduction of compatible
2213                                          * new fields does not count.
2214                                          */
2215         uint8_t         it_pad;
2216         uint16_t        it_len;         /* length of the whole
2217                                          * header in bytes, including
2218                                          * it_version, it_pad,
2219                                          * it_len, and data fields.
2220                                          */
2221         uint32_t        it_present;     /* A bitmap telling which
2222                                          * fields are present. Set bit 31
2223                                          * (0x80000000) to extend the
2224                                          * bitmap by another 32 bits.
2225                                          * Additional extensions are made
2226                                          * by setting bit 31.
2227                                          */
2228 };
2229
2230 /* Name                                 Data type       Units
2231  * ----                                 ---------       -----
2232  *
2233  * IEEE80211_RADIOTAP_TSFT              uint64_t       microseconds
2234  *
2235  *      Value in microseconds of the MAC's 64-bit 802.11 Time
2236  *      Synchronization Function timer when the first bit of the
2237  *      MPDU arrived at the MAC. For received frames, only.
2238  *
2239  * IEEE80211_RADIOTAP_CHANNEL           2 x uint16_t   MHz, bitmap
2240  *
2241  *      Tx/Rx frequency in MHz, followed by flags (see below).
2242  *      Note that IEEE80211_RADIOTAP_XCHANNEL must be used to
2243  *      represent an HT channel as there is not enough room in
2244  *      the flags word.
2245  *
2246  * IEEE80211_RADIOTAP_FHSS              uint16_t       see below
2247  *
2248  *      For frequency-hopping radios, the hop set (first byte)
2249  *      and pattern (second byte).
2250  *
2251  * IEEE80211_RADIOTAP_RATE              uint8_t        500kb/s or index
2252  *
2253  *      Tx/Rx data rate.  If bit 0x80 is set then it represents an
2254  *      an MCS index and not an IEEE rate.
2255  *
2256  * IEEE80211_RADIOTAP_DBM_ANTSIGNAL     int8_t          decibels from
2257  *                                                      one milliwatt (dBm)
2258  *
2259  *      RF signal power at the antenna, decibel difference from
2260  *      one milliwatt.
2261  *
2262  * IEEE80211_RADIOTAP_DBM_ANTNOISE      int8_t          decibels from
2263  *                                                      one milliwatt (dBm)
2264  *
2265  *      RF noise power at the antenna, decibel difference from one
2266  *      milliwatt.
2267  *
2268  * IEEE80211_RADIOTAP_DB_ANTSIGNAL      uint8_t        decibel (dB)
2269  *
2270  *      RF signal power at the antenna, decibel difference from an
2271  *      arbitrary, fixed reference.
2272  *
2273  * IEEE80211_RADIOTAP_DB_ANTNOISE       uint8_t        decibel (dB)
2274  *
2275  *      RF noise power at the antenna, decibel difference from an
2276  *      arbitrary, fixed reference point.
2277  *
2278  * IEEE80211_RADIOTAP_LOCK_QUALITY      uint16_t       unitless
2279  *
2280  *      Quality of Barker code lock. Unitless. Monotonically
2281  *      nondecreasing with "better" lock strength. Called "Signal
2282  *      Quality" in datasheets.  (Is there a standard way to measure
2283  *      this?)
2284  *
2285  * IEEE80211_RADIOTAP_TX_ATTENUATION    uint16_t       unitless
2286  *
2287  *      Transmit power expressed as unitless distance from max
2288  *      power set at factory calibration.  0 is max power.
2289  *      Monotonically nondecreasing with lower power levels.
2290  *
2291  * IEEE80211_RADIOTAP_DB_TX_ATTENUATION uint16_t       decibels (dB)
2292  *
2293  *      Transmit power expressed as decibel distance from max power
2294  *      set at factory calibration.  0 is max power.  Monotonically
2295  *      nondecreasing with lower power levels.
2296  *
2297  * IEEE80211_RADIOTAP_DBM_TX_POWER      int8_t          decibels from
2298  *                                                      one milliwatt (dBm)
2299  *
2300  *      Transmit power expressed as dBm (decibels from a 1 milliwatt
2301  *      reference). This is the absolute power level measured at
2302  *      the antenna port.
2303  *
2304  * IEEE80211_RADIOTAP_FLAGS             uint8_t        bitmap
2305  *
2306  *      Properties of transmitted and received frames. See flags
2307  *      defined below.
2308  *
2309  * IEEE80211_RADIOTAP_ANTENNA           uint8_t        antenna index
2310  *
2311  *      Unitless indication of the Rx/Tx antenna for this packet.
2312  *      The first antenna is antenna 0.
2313  *
2314  * IEEE80211_RADIOTAP_RX_FLAGS          uint16_t       bitmap
2315  *
2316  *     Properties of received frames. See flags defined below.
2317  *
2318  * IEEE80211_RADIOTAP_XCHANNEL          uint32_t        bitmap
2319  *                                      uint16_t        MHz
2320  *                                      uint8_t         channel number
2321  *                                      uint8_t         .5 dBm
2322  *
2323  *      Extended channel specification: flags (see below) followed by
2324  *      frequency in MHz, the corresponding IEEE channel number, and
2325  *      finally the maximum regulatory transmit power cap in .5 dBm
2326  *      units.  This property supersedes IEEE80211_RADIOTAP_CHANNEL
2327  *      and only one of the two should be present.
2328  *
2329  * IEEE80211_RADIOTAP_MCS               uint8_t         known
2330  *                                      uint8_t         flags
2331  *                                      uint8_t         mcs
2332  *
2333  *      Bitset indicating which fields have known values, followed
2334  *      by bitset of flag values, followed by the MCS rate index as
2335  *      in IEEE 802.11n.
2336  *
2337  *
2338  * IEEE80211_RADIOTAP_AMPDU_STATUS      u32, u16, u8, u8        unitless
2339  *
2340  *      Contains the AMPDU information for the subframe.
2341  *
2342  * IEEE80211_RADIOTAP_VHT       u16, u8, u8, u8[4], u8, u8, u16
2343  *
2344  *      Contains VHT information about this frame.
2345  *
2346  * IEEE80211_RADIOTAP_VENDOR_NAMESPACE
2347  *                                      uint8_t  OUI[3]
2348  *                                   uint8_t  subspace
2349  *                                   uint16_t length
2350  *
2351  *     The Vendor Namespace Field contains three sub-fields. The first
2352  *     sub-field is 3 bytes long. It contains the vendor's IEEE 802
2353  *     Organizationally Unique Identifier (OUI). The fourth byte is a
2354  *     vendor-specific "namespace selector."
2355  *
2356  */
2357 enum ieee80211_radiotap_type {
2358         IEEE80211_RADIOTAP_TSFT = 0,
2359         IEEE80211_RADIOTAP_FLAGS = 1,
2360         IEEE80211_RADIOTAP_RATE = 2,
2361         IEEE80211_RADIOTAP_CHANNEL = 3,
2362         IEEE80211_RADIOTAP_FHSS = 4,
2363         IEEE80211_RADIOTAP_DBM_ANTSIGNAL = 5,
2364         IEEE80211_RADIOTAP_DBM_ANTNOISE = 6,
2365         IEEE80211_RADIOTAP_LOCK_QUALITY = 7,
2366         IEEE80211_RADIOTAP_TX_ATTENUATION = 8,
2367         IEEE80211_RADIOTAP_DB_TX_ATTENUATION = 9,
2368         IEEE80211_RADIOTAP_DBM_TX_POWER = 10,
2369         IEEE80211_RADIOTAP_ANTENNA = 11,
2370         IEEE80211_RADIOTAP_DB_ANTSIGNAL = 12,
2371         IEEE80211_RADIOTAP_DB_ANTNOISE = 13,
2372         IEEE80211_RADIOTAP_RX_FLAGS = 14,
2373         /* NB: gap for netbsd definitions */
2374         IEEE80211_RADIOTAP_XCHANNEL = 18,
2375         IEEE80211_RADIOTAP_MCS = 19,
2376         IEEE80211_RADIOTAP_AMPDU_STATUS = 20,
2377         IEEE80211_RADIOTAP_VHT = 21,
2378         IEEE80211_RADIOTAP_NAMESPACE = 29,
2379         IEEE80211_RADIOTAP_VENDOR_NAMESPACE = 30,
2380         IEEE80211_RADIOTAP_EXT = 31
2381 };
2382
2383 /* channel attributes */
2384 #define IEEE80211_CHAN_TURBO    0x00010 /* Turbo channel */
2385 #define IEEE80211_CHAN_CCK      0x00020 /* CCK channel */
2386 #define IEEE80211_CHAN_OFDM     0x00040 /* OFDM channel */
2387 #define IEEE80211_CHAN_2GHZ     0x00080 /* 2 GHz spectrum channel. */
2388 #define IEEE80211_CHAN_5GHZ     0x00100 /* 5 GHz spectrum channel */
2389 #define IEEE80211_CHAN_PASSIVE  0x00200 /* Only passive scan allowed */
2390 #define IEEE80211_CHAN_DYN      0x00400 /* Dynamic CCK-OFDM channel */
2391 #define IEEE80211_CHAN_GFSK     0x00800 /* GFSK channel (FHSS PHY) */
2392 #define IEEE80211_CHAN_GSM      0x01000 /* 900 MHz spectrum channel */
2393 #define IEEE80211_CHAN_STURBO   0x02000 /* 11a static turbo channel only */
2394 #define IEEE80211_CHAN_HALF     0x04000 /* Half rate channel */
2395 #define IEEE80211_CHAN_QUARTER  0x08000 /* Quarter rate channel */
2396 #define IEEE80211_CHAN_HT20     0x10000 /* HT 20 channel */
2397 #define IEEE80211_CHAN_HT40U    0x20000 /* HT 40 channel w/ ext above */
2398 #define IEEE80211_CHAN_HT40D    0x40000 /* HT 40 channel w/ ext below */
2399
2400 /* Useful combinations of channel characteristics, borrowed from Ethereal */
2401 #define IEEE80211_CHAN_A \
2402         (IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM)
2403 #define IEEE80211_CHAN_B \
2404         (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_CCK)
2405 #define IEEE80211_CHAN_G \
2406         (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_DYN)
2407 #define IEEE80211_CHAN_TA \
2408         (IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM | IEEE80211_CHAN_TURBO)
2409 #define IEEE80211_CHAN_TG \
2410         (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_DYN  | IEEE80211_CHAN_TURBO)
2411
2412
2413 /* For IEEE80211_RADIOTAP_FLAGS */
2414 #define IEEE80211_RADIOTAP_F_CFP        0x01    /* sent/received
2415                                                  * during CFP
2416                                                  */
2417 #define IEEE80211_RADIOTAP_F_SHORTPRE   0x02    /* sent/received
2418                                                  * with short
2419                                                  * preamble
2420                                                  */
2421 #define IEEE80211_RADIOTAP_F_WEP        0x04    /* sent/received
2422                                                  * with WEP encryption
2423                                                  */
2424 #define IEEE80211_RADIOTAP_F_FRAG       0x08    /* sent/received
2425                                                  * with fragmentation
2426                                                  */
2427 #define IEEE80211_RADIOTAP_F_FCS        0x10    /* frame includes FCS */
2428 #define IEEE80211_RADIOTAP_F_DATAPAD    0x20    /* frame has padding between
2429                                                  * 802.11 header and payload
2430                                                  * (to 32-bit boundary)
2431                                                  */
2432 #define IEEE80211_RADIOTAP_F_BADFCS     0x40    /* does not pass FCS check */
2433
2434 /* For IEEE80211_RADIOTAP_RX_FLAGS */
2435 #define IEEE80211_RADIOTAP_F_RX_BADFCS  0x0001  /* frame failed crc check */
2436 #define IEEE80211_RADIOTAP_F_RX_PLCP_CRC        0x0002  /* frame failed PLCP CRC check */
2437
2438 /* For IEEE80211_RADIOTAP_MCS known */
2439 #define IEEE80211_RADIOTAP_MCS_BANDWIDTH_KNOWN          0x01
2440 #define IEEE80211_RADIOTAP_MCS_MCS_INDEX_KNOWN          0x02    /* MCS index field */
2441 #define IEEE80211_RADIOTAP_MCS_GUARD_INTERVAL_KNOWN     0x04
2442 #define IEEE80211_RADIOTAP_MCS_HT_FORMAT_KNOWN          0x08
2443 #define IEEE80211_RADIOTAP_MCS_FEC_TYPE_KNOWN           0x10
2444 #define IEEE80211_RADIOTAP_MCS_STBC_KNOWN               0x20
2445 #define IEEE80211_RADIOTAP_MCS_NESS_KNOWN               0x40
2446 #define IEEE80211_RADIOTAP_MCS_NESS_BIT_1               0x80
2447
2448 /* For IEEE80211_RADIOTAP_MCS flags */
2449 #define IEEE80211_RADIOTAP_MCS_BANDWIDTH_MASK   0x03
2450 #define IEEE80211_RADIOTAP_MCS_BANDWIDTH_20     0
2451 #define IEEE80211_RADIOTAP_MCS_BANDWIDTH_40     1
2452 #define IEEE80211_RADIOTAP_MCS_BANDWIDTH_20L    2
2453 #define IEEE80211_RADIOTAP_MCS_BANDWIDTH_20U    3
2454 #define IEEE80211_RADIOTAP_MCS_SHORT_GI         0x04 /* short guard interval */
2455 #define IEEE80211_RADIOTAP_MCS_HT_GREENFIELD    0x08
2456 #define IEEE80211_RADIOTAP_MCS_FEC_LDPC         0x10
2457 #define IEEE80211_RADIOTAP_MCS_STBC_MASK        0x60
2458 #define         IEEE80211_RADIOTAP_MCS_STBC_1   1
2459 #define         IEEE80211_RADIOTAP_MCS_STBC_2   2
2460 #define         IEEE80211_RADIOTAP_MCS_STBC_3   3
2461 #define IEEE80211_RADIOTAP_MCS_STBC_SHIFT       5
2462 #define IEEE80211_RADIOTAP_MCS_NESS_BIT_0       0x80
2463
2464 /* For IEEE80211_RADIOTAP_AMPDU_STATUS */
2465 #define IEEE80211_RADIOTAP_AMPDU_REPORT_ZEROLEN         0x0001
2466 #define IEEE80211_RADIOTAP_AMPDU_IS_ZEROLEN             0x0002
2467 #define IEEE80211_RADIOTAP_AMPDU_LAST_KNOWN             0x0004
2468 #define IEEE80211_RADIOTAP_AMPDU_IS_LAST                0x0008
2469 #define IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_ERR          0x0010
2470 #define IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_KNOWN        0x0020
2471
2472 /* For IEEE80211_RADIOTAP_VHT known */
2473 #define IEEE80211_RADIOTAP_VHT_STBC_KNOWN                       0x0001
2474 #define IEEE80211_RADIOTAP_VHT_TXOP_PS_NA_KNOWN                 0x0002
2475 #define IEEE80211_RADIOTAP_VHT_GUARD_INTERVAL_KNOWN             0x0004
2476 #define IEEE80211_RADIOTAP_VHT_SGI_NSYM_DIS_KNOWN               0x0008
2477 #define IEEE80211_RADIOTAP_VHT_LDPC_EXTRA_OFDM_SYM_KNOWN        0x0010
2478 #define IEEE80211_RADIOTAP_VHT_BEAMFORMED_KNOWN                 0x0020
2479 #define IEEE80211_RADIOTAP_VHT_BANDWIDTH_KNOWN                  0x0040
2480 #define IEEE80211_RADIOTAP_VHT_GROUP_ID_KNOWN                   0x0080
2481 #define IEEE80211_RADIOTAP_VHT_PARTIAL_AID_KNOWN                0x0100
2482
2483 /* For IEEE80211_RADIOTAP_VHT flags */
2484 #define IEEE80211_RADIOTAP_VHT_STBC                     0x01
2485 #define IEEE80211_RADIOTAP_VHT_TXOP_PS_NA               0x02
2486 #define IEEE80211_RADIOTAP_VHT_SHORT_GI                 0x04
2487 #define IEEE80211_RADIOTAP_VHT_SGI_NSYM_M10_9           0x08
2488 #define IEEE80211_RADIOTAP_VHT_LDPC_EXTRA_OFDM_SYM      0x10
2489 #define IEEE80211_RADIOTAP_VHT_BEAMFORMED               0x20
2490
2491 #define IEEE80211_RADIOTAP_VHT_BANDWIDTH_MASK   0x1f
2492
2493 #define IEEE80211_RADIOTAP_VHT_NSS_MASK         0x0f
2494 #define IEEE80211_RADIOTAP_VHT_MCS_MASK         0xf0
2495 #define IEEE80211_RADIOTAP_VHT_MCS_SHIFT        4
2496
2497 #define IEEE80211_RADIOTAP_CODING_LDPC_USERn                    0x01
2498
2499 #define IEEE80211_CHAN_FHSS \
2500         (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_GFSK)
2501 #define IEEE80211_CHAN_A \
2502         (IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM)
2503 #define IEEE80211_CHAN_B \
2504         (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_CCK)
2505 #define IEEE80211_CHAN_PUREG \
2506         (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_OFDM)
2507 #define IEEE80211_CHAN_G \
2508         (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_DYN)
2509
2510 #define IS_CHAN_FHSS(flags) \
2511         ((flags & IEEE80211_CHAN_FHSS) == IEEE80211_CHAN_FHSS)
2512 #define IS_CHAN_A(flags) \
2513         ((flags & IEEE80211_CHAN_A) == IEEE80211_CHAN_A)
2514 #define IS_CHAN_B(flags) \
2515         ((flags & IEEE80211_CHAN_B) == IEEE80211_CHAN_B)
2516 #define IS_CHAN_PUREG(flags) \
2517         ((flags & IEEE80211_CHAN_PUREG) == IEEE80211_CHAN_PUREG)
2518 #define IS_CHAN_G(flags) \
2519         ((flags & IEEE80211_CHAN_G) == IEEE80211_CHAN_G)
2520 #define IS_CHAN_ANYG(flags) \
2521         (IS_CHAN_PUREG(flags) || IS_CHAN_G(flags))
2522
2523 static void
2524 print_chaninfo(netdissect_options *ndo,
2525                uint16_t freq, int flags, int presentflags)
2526 {
2527         ND_PRINT((ndo, "%u MHz", freq));
2528         if (presentflags & (1 << IEEE80211_RADIOTAP_MCS)) {
2529                 /*
2530                  * We have the MCS field, so this is 11n, regardless
2531                  * of what the channel flags say.
2532                  */
2533                 ND_PRINT((ndo, " 11n"));
2534         } else {
2535                 if (IS_CHAN_FHSS(flags))
2536                         ND_PRINT((ndo, " FHSS"));
2537                 if (IS_CHAN_A(flags)) {
2538                         if (flags & IEEE80211_CHAN_HALF)
2539                                 ND_PRINT((ndo, " 11a/10Mhz"));
2540                         else if (flags & IEEE80211_CHAN_QUARTER)
2541                                 ND_PRINT((ndo, " 11a/5Mhz"));
2542                         else
2543                                 ND_PRINT((ndo, " 11a"));
2544                 }
2545                 if (IS_CHAN_ANYG(flags)) {
2546                         if (flags & IEEE80211_CHAN_HALF)
2547                                 ND_PRINT((ndo, " 11g/10Mhz"));
2548                         else if (flags & IEEE80211_CHAN_QUARTER)
2549                                 ND_PRINT((ndo, " 11g/5Mhz"));
2550                         else
2551                                 ND_PRINT((ndo, " 11g"));
2552                 } else if (IS_CHAN_B(flags))
2553                         ND_PRINT((ndo, " 11b"));
2554                 if (flags & IEEE80211_CHAN_TURBO)
2555                         ND_PRINT((ndo, " Turbo"));
2556         }
2557         /*
2558          * These apply to 11n.
2559          */
2560         if (flags & IEEE80211_CHAN_HT20)
2561                 ND_PRINT((ndo, " ht/20"));
2562         else if (flags & IEEE80211_CHAN_HT40D)
2563                 ND_PRINT((ndo, " ht/40-"));
2564         else if (flags & IEEE80211_CHAN_HT40U)
2565                 ND_PRINT((ndo, " ht/40+"));
2566         ND_PRINT((ndo, " "));
2567 }
2568
2569 static int
2570 print_radiotap_field(netdissect_options *ndo,
2571                      struct cpack_state *s, uint32_t bit, uint8_t *flagsp,
2572                      uint32_t presentflags)
2573 {
2574         u_int i;
2575         int rc;
2576
2577         switch (bit) {
2578
2579         case IEEE80211_RADIOTAP_TSFT: {
2580                 uint64_t tsft;
2581
2582                 rc = cpack_uint64(s, &tsft);
2583                 if (rc != 0)
2584                         goto trunc;
2585                 ND_PRINT((ndo, "%" PRIu64 "us tsft ", tsft));
2586                 break;
2587                 }
2588
2589         case IEEE80211_RADIOTAP_FLAGS: {
2590                 uint8_t flagsval;
2591
2592                 rc = cpack_uint8(s, &flagsval);
2593                 if (rc != 0)
2594                         goto trunc;
2595                 *flagsp = flagsval;
2596                 if (flagsval & IEEE80211_RADIOTAP_F_CFP)
2597                         ND_PRINT((ndo, "cfp "));
2598                 if (flagsval & IEEE80211_RADIOTAP_F_SHORTPRE)
2599                         ND_PRINT((ndo, "short preamble "));
2600                 if (flagsval & IEEE80211_RADIOTAP_F_WEP)
2601                         ND_PRINT((ndo, "wep "));
2602                 if (flagsval & IEEE80211_RADIOTAP_F_FRAG)
2603                         ND_PRINT((ndo, "fragmented "));
2604                 if (flagsval & IEEE80211_RADIOTAP_F_BADFCS)
2605                         ND_PRINT((ndo, "bad-fcs "));
2606                 break;
2607                 }
2608
2609         case IEEE80211_RADIOTAP_RATE: {
2610                 uint8_t rate;
2611
2612                 rc = cpack_uint8(s, &rate);
2613                 if (rc != 0)
2614                         goto trunc;
2615                 /*
2616                  * XXX On FreeBSD rate & 0x80 means we have an MCS. On
2617                  * Linux and AirPcap it does not.  (What about
2618                  * Mac OS X, NetBSD, OpenBSD, and DragonFly BSD?)
2619                  *
2620                  * This is an issue either for proprietary extensions
2621                  * to 11a or 11g, which do exist, or for 11n
2622                  * implementations that stuff a rate value into
2623                  * this field, which also appear to exist.
2624                  *
2625                  * We currently handle that by assuming that
2626                  * if the 0x80 bit is set *and* the remaining
2627                  * bits have a value between 0 and 15 it's
2628                  * an MCS value, otherwise it's a rate.  If
2629                  * there are cases where systems that use
2630                  * "0x80 + MCS index" for MCS indices > 15,
2631                  * or stuff a rate value here between 64 and
2632                  * 71.5 Mb/s in here, we'll need a preference
2633                  * setting.  Such rates do exist, e.g. 11n
2634                  * MCS 7 at 20 MHz with a long guard interval.
2635                  */
2636                 if (rate >= 0x80 && rate <= 0x8f) {
2637                         /*
2638                          * XXX - we don't know the channel width
2639                          * or guard interval length, so we can't
2640                          * convert this to a data rate.
2641                          *
2642                          * If you want us to show a data rate,
2643                          * use the MCS field, not the Rate field;
2644                          * the MCS field includes not only the
2645                          * MCS index, it also includes bandwidth
2646                          * and guard interval information.
2647                          *
2648                          * XXX - can we get the channel width
2649                          * from XChannel and the guard interval
2650                          * information from Flags, at least on
2651                          * FreeBSD?
2652                          */
2653                         ND_PRINT((ndo, "MCS %u ", rate & 0x7f));
2654                 } else
2655                         ND_PRINT((ndo, "%2.1f Mb/s ", .5 * rate));
2656                 break;
2657                 }
2658
2659         case IEEE80211_RADIOTAP_CHANNEL: {
2660                 uint16_t frequency;
2661                 uint16_t flags;
2662
2663                 rc = cpack_uint16(s, &frequency);
2664                 if (rc != 0)
2665                         goto trunc;
2666                 rc = cpack_uint16(s, &flags);
2667                 if (rc != 0)
2668                         goto trunc;
2669                 /*
2670                  * If CHANNEL and XCHANNEL are both present, skip
2671                  * CHANNEL.
2672                  */
2673                 if (presentflags & (1 << IEEE80211_RADIOTAP_XCHANNEL))
2674                         break;
2675                 print_chaninfo(ndo, frequency, flags, presentflags);
2676                 break;
2677                 }
2678
2679         case IEEE80211_RADIOTAP_FHSS: {
2680                 uint8_t hopset;
2681                 uint8_t hoppat;
2682
2683                 rc = cpack_uint8(s, &hopset);
2684                 if (rc != 0)
2685                         goto trunc;
2686                 rc = cpack_uint8(s, &hoppat);
2687                 if (rc != 0)
2688                         goto trunc;
2689                 ND_PRINT((ndo, "fhset %d fhpat %d ", hopset, hoppat));
2690                 break;
2691                 }
2692
2693         case IEEE80211_RADIOTAP_DBM_ANTSIGNAL: {
2694                 int8_t dbm_antsignal;
2695
2696                 rc = cpack_int8(s, &dbm_antsignal);
2697                 if (rc != 0)
2698                         goto trunc;
2699                 ND_PRINT((ndo, "%ddBm signal ", dbm_antsignal));
2700                 break;
2701                 }
2702
2703         case IEEE80211_RADIOTAP_DBM_ANTNOISE: {
2704                 int8_t dbm_antnoise;
2705
2706                 rc = cpack_int8(s, &dbm_antnoise);
2707                 if (rc != 0)
2708                         goto trunc;
2709                 ND_PRINT((ndo, "%ddBm noise ", dbm_antnoise));
2710                 break;
2711                 }
2712
2713         case IEEE80211_RADIOTAP_LOCK_QUALITY: {
2714                 uint16_t lock_quality;
2715
2716                 rc = cpack_uint16(s, &lock_quality);
2717                 if (rc != 0)
2718                         goto trunc;
2719                 ND_PRINT((ndo, "%u sq ", lock_quality));
2720                 break;
2721                 }
2722
2723         case IEEE80211_RADIOTAP_TX_ATTENUATION: {
2724                 uint16_t tx_attenuation;
2725
2726                 rc = cpack_uint16(s, &tx_attenuation);
2727                 if (rc != 0)
2728                         goto trunc;
2729                 ND_PRINT((ndo, "%d tx power ", -(int)tx_attenuation));
2730                 break;
2731                 }
2732
2733         case IEEE80211_RADIOTAP_DB_TX_ATTENUATION: {
2734                 uint8_t db_tx_attenuation;
2735
2736                 rc = cpack_uint8(s, &db_tx_attenuation);
2737                 if (rc != 0)
2738                         goto trunc;
2739                 ND_PRINT((ndo, "%ddB tx attenuation ", -(int)db_tx_attenuation));
2740                 break;
2741                 }
2742
2743         case IEEE80211_RADIOTAP_DBM_TX_POWER: {
2744                 int8_t dbm_tx_power;
2745
2746                 rc = cpack_int8(s, &dbm_tx_power);
2747                 if (rc != 0)
2748                         goto trunc;
2749                 ND_PRINT((ndo, "%ddBm tx power ", dbm_tx_power));
2750                 break;
2751                 }
2752
2753         case IEEE80211_RADIOTAP_ANTENNA: {
2754                 uint8_t antenna;
2755
2756                 rc = cpack_uint8(s, &antenna);
2757                 if (rc != 0)
2758                         goto trunc;
2759                 ND_PRINT((ndo, "antenna %u ", antenna));
2760                 break;
2761                 }
2762
2763         case IEEE80211_RADIOTAP_DB_ANTSIGNAL: {
2764                 uint8_t db_antsignal;
2765
2766                 rc = cpack_uint8(s, &db_antsignal);
2767                 if (rc != 0)
2768                         goto trunc;
2769                 ND_PRINT((ndo, "%ddB signal ", db_antsignal));
2770                 break;
2771                 }
2772
2773         case IEEE80211_RADIOTAP_DB_ANTNOISE: {
2774                 uint8_t db_antnoise;
2775
2776                 rc = cpack_uint8(s, &db_antnoise);
2777                 if (rc != 0)
2778                         goto trunc;
2779                 ND_PRINT((ndo, "%ddB noise ", db_antnoise));
2780                 break;
2781                 }
2782
2783         case IEEE80211_RADIOTAP_RX_FLAGS: {
2784                 uint16_t rx_flags;
2785
2786                 rc = cpack_uint16(s, &rx_flags);
2787                 if (rc != 0)
2788                         goto trunc;
2789                 /* Do nothing for now */
2790                 break;
2791                 }
2792
2793         case IEEE80211_RADIOTAP_XCHANNEL: {
2794                 uint32_t flags;
2795                 uint16_t frequency;
2796                 uint8_t channel;
2797                 uint8_t maxpower;
2798
2799                 rc = cpack_uint32(s, &flags);
2800                 if (rc != 0)
2801                         goto trunc;
2802                 rc = cpack_uint16(s, &frequency);
2803                 if (rc != 0)
2804                         goto trunc;
2805                 rc = cpack_uint8(s, &channel);
2806                 if (rc != 0)
2807                         goto trunc;
2808                 rc = cpack_uint8(s, &maxpower);
2809                 if (rc != 0)
2810                         goto trunc;
2811                 print_chaninfo(ndo, frequency, flags, presentflags);
2812                 break;
2813                 }
2814
2815         case IEEE80211_RADIOTAP_MCS: {
2816                 uint8_t known;
2817                 uint8_t flags;
2818                 uint8_t mcs_index;
2819                 static const char *ht_bandwidth[4] = {
2820                         "20 MHz",
2821                         "40 MHz",
2822                         "20 MHz (L)",
2823                         "20 MHz (U)"
2824                 };
2825                 float htrate;
2826
2827                 rc = cpack_uint8(s, &known);
2828                 if (rc != 0)
2829                         goto trunc;
2830                 rc = cpack_uint8(s, &flags);
2831                 if (rc != 0)
2832                         goto trunc;
2833                 rc = cpack_uint8(s, &mcs_index);
2834                 if (rc != 0)
2835                         goto trunc;
2836                 if (known & IEEE80211_RADIOTAP_MCS_MCS_INDEX_KNOWN) {
2837                         /*
2838                          * We know the MCS index.
2839                          */
2840                         if (mcs_index <= MAX_MCS_INDEX) {
2841                                 /*
2842                                  * And it's in-range.
2843                                  */
2844                                 if (known & (IEEE80211_RADIOTAP_MCS_BANDWIDTH_KNOWN|IEEE80211_RADIOTAP_MCS_GUARD_INTERVAL_KNOWN)) {
2845                                         /*
2846                                          * And we know both the bandwidth and
2847                                          * the guard interval, so we can look
2848                                          * up the rate.
2849                                          */
2850                                         htrate =
2851                                                 ieee80211_float_htrates \
2852                                                         [mcs_index] \
2853                                                         [((flags & IEEE80211_RADIOTAP_MCS_BANDWIDTH_MASK) == IEEE80211_RADIOTAP_MCS_BANDWIDTH_40 ? 1 : 0)] \
2854                                                         [((flags & IEEE80211_RADIOTAP_MCS_SHORT_GI) ? 1 : 0)];
2855                                 } else {
2856                                         /*
2857                                          * We don't know both the bandwidth
2858                                          * and the guard interval, so we can
2859                                          * only report the MCS index.
2860                                          */
2861                                         htrate = 0.0;
2862                                 }
2863                         } else {
2864                                 /*
2865                                  * The MCS value is out of range.
2866                                  */
2867                                 htrate = 0.0;
2868                         }
2869                         if (htrate != 0.0) {
2870                                 /*
2871                                  * We have the rate.
2872                                  * Print it.
2873                                  */
2874                                 ND_PRINT((ndo, "%.1f Mb/s MCS %u ", htrate, mcs_index));
2875                         } else {
2876                                 /*
2877                                  * We at least have the MCS index.
2878                                  * Print it.
2879                                  */
2880                                 ND_PRINT((ndo, "MCS %u ", mcs_index));
2881                         }
2882                 }
2883                 if (known & IEEE80211_RADIOTAP_MCS_BANDWIDTH_KNOWN) {
2884                         ND_PRINT((ndo, "%s ",
2885                                 ht_bandwidth[flags & IEEE80211_RADIOTAP_MCS_BANDWIDTH_MASK]));
2886                 }
2887                 if (known & IEEE80211_RADIOTAP_MCS_GUARD_INTERVAL_KNOWN) {
2888                         ND_PRINT((ndo, "%s GI ",
2889                                 (flags & IEEE80211_RADIOTAP_MCS_SHORT_GI) ?
2890                                 "short" : "long"));
2891                 }
2892                 if (known & IEEE80211_RADIOTAP_MCS_HT_FORMAT_KNOWN) {
2893                         ND_PRINT((ndo, "%s ",
2894                                 (flags & IEEE80211_RADIOTAP_MCS_HT_GREENFIELD) ?
2895                                 "greenfield" : "mixed"));
2896                 }
2897                 if (known & IEEE80211_RADIOTAP_MCS_FEC_TYPE_KNOWN) {
2898                         ND_PRINT((ndo, "%s FEC ",
2899                                 (flags & IEEE80211_RADIOTAP_MCS_FEC_LDPC) ?
2900                                 "LDPC" : "BCC"));
2901                 }
2902                 if (known & IEEE80211_RADIOTAP_MCS_STBC_KNOWN) {
2903                         ND_PRINT((ndo, "RX-STBC%u ",
2904                                 (flags & IEEE80211_RADIOTAP_MCS_STBC_MASK) >> IEEE80211_RADIOTAP_MCS_STBC_SHIFT));
2905                 }
2906                 break;
2907                 }
2908
2909         case IEEE80211_RADIOTAP_AMPDU_STATUS: {
2910                 uint32_t reference_num;
2911                 uint16_t flags;
2912                 uint8_t delim_crc;
2913                 uint8_t reserved;
2914
2915                 rc = cpack_uint32(s, &reference_num);
2916                 if (rc != 0)
2917                         goto trunc;
2918                 rc = cpack_uint16(s, &flags);
2919                 if (rc != 0)
2920                         goto trunc;
2921                 rc = cpack_uint8(s, &delim_crc);
2922                 if (rc != 0)
2923                         goto trunc;
2924                 rc = cpack_uint8(s, &reserved);
2925                 if (rc != 0)
2926                         goto trunc;
2927                 /* Do nothing for now */
2928                 break;
2929                 }
2930
2931         case IEEE80211_RADIOTAP_VHT: {
2932                 uint16_t known;
2933                 uint8_t flags;
2934                 uint8_t bandwidth;
2935                 uint8_t mcs_nss[4];
2936                 uint8_t coding;
2937                 uint8_t group_id;
2938                 uint16_t partial_aid;
2939                 static const char *vht_bandwidth[32] = {
2940                         "20 MHz",
2941                         "40 MHz",
2942                         "20 MHz (L)",
2943                         "20 MHz (U)",
2944                         "80 MHz",
2945                         "80 MHz (L)",
2946                         "80 MHz (U)",
2947                         "80 MHz (LL)",
2948                         "80 MHz (LU)",
2949                         "80 MHz (UL)",
2950                         "80 MHz (UU)",
2951                         "160 MHz",
2952                         "160 MHz (L)",
2953                         "160 MHz (U)",
2954                         "160 MHz (LL)",
2955                         "160 MHz (LU)",
2956                         "160 MHz (UL)",
2957                         "160 MHz (UU)",
2958                         "160 MHz (LLL)",
2959                         "160 MHz (LLU)",
2960                         "160 MHz (LUL)",
2961                         "160 MHz (UUU)",
2962                         "160 MHz (ULL)",
2963                         "160 MHz (ULU)",
2964                         "160 MHz (UUL)",
2965                         "160 MHz (UUU)",
2966                         "unknown (26)",
2967                         "unknown (27)",
2968                         "unknown (28)",
2969                         "unknown (29)",
2970                         "unknown (30)",
2971                         "unknown (31)"
2972                 };
2973
2974                 rc = cpack_uint16(s, &known);
2975                 if (rc != 0)
2976                         goto trunc;
2977                 rc = cpack_uint8(s, &flags);
2978                 if (rc != 0)
2979                         goto trunc;
2980                 rc = cpack_uint8(s, &bandwidth);
2981                 if (rc != 0)
2982                         goto trunc;
2983                 for (i = 0; i < 4; i++) {
2984                         rc = cpack_uint8(s, &mcs_nss[i]);
2985                         if (rc != 0)
2986                                 goto trunc;
2987                 }
2988                 rc = cpack_uint8(s, &coding);
2989                 if (rc != 0)
2990                         goto trunc;
2991                 rc = cpack_uint8(s, &group_id);
2992                 if (rc != 0)
2993                         goto trunc;
2994                 rc = cpack_uint16(s, &partial_aid);
2995                 if (rc != 0)
2996                         goto trunc;
2997                 for (i = 0; i < 4; i++) {
2998                         u_int nss, mcs;
2999                         nss = mcs_nss[i] & IEEE80211_RADIOTAP_VHT_NSS_MASK;
3000                         mcs = (mcs_nss[i] & IEEE80211_RADIOTAP_VHT_MCS_MASK) >> IEEE80211_RADIOTAP_VHT_MCS_SHIFT;
3001
3002                         if (nss == 0)
3003                                 continue;
3004
3005                         ND_PRINT((ndo, "User %u MCS %u ", i, mcs));
3006                         ND_PRINT((ndo, "%s FEC ",
3007                                 (coding & (IEEE80211_RADIOTAP_CODING_LDPC_USERn << i)) ?
3008                                 "LDPC" : "BCC"));
3009                 }
3010                 if (known & IEEE80211_RADIOTAP_VHT_BANDWIDTH_KNOWN) {
3011                         ND_PRINT((ndo, "%s ",
3012                                 vht_bandwidth[bandwidth & IEEE80211_RADIOTAP_VHT_BANDWIDTH_MASK]));
3013                 }
3014                 if (known & IEEE80211_RADIOTAP_VHT_GUARD_INTERVAL_KNOWN) {
3015                         ND_PRINT((ndo, "%s GI ",
3016                                 (flags & IEEE80211_RADIOTAP_VHT_SHORT_GI) ?
3017                                 "short" : "long"));
3018                 }
3019                 break;
3020                 }
3021
3022         default:
3023                 /* this bit indicates a field whose
3024                  * size we do not know, so we cannot
3025                  * proceed.  Just print the bit number.
3026                  */
3027                 ND_PRINT((ndo, "[bit %u] ", bit));
3028                 return -1;
3029         }
3030
3031         return 0;
3032
3033 trunc:
3034         ND_PRINT((ndo, "%s", tstr));
3035         return rc;
3036 }
3037
3038
3039 static int
3040 print_in_radiotap_namespace(netdissect_options *ndo,
3041                             struct cpack_state *s, uint8_t *flags,
3042                             uint32_t presentflags, int bit0)
3043 {
3044 #define BITNO_32(x) (((x) >> 16) ? 16 + BITNO_16((x) >> 16) : BITNO_16((x)))
3045 #define BITNO_16(x) (((x) >> 8) ? 8 + BITNO_8((x) >> 8) : BITNO_8((x)))
3046 #define BITNO_8(x) (((x) >> 4) ? 4 + BITNO_4((x) >> 4) : BITNO_4((x)))
3047 #define BITNO_4(x) (((x) >> 2) ? 2 + BITNO_2((x) >> 2) : BITNO_2((x)))
3048 #define BITNO_2(x) (((x) & 2) ? 1 : 0)
3049         uint32_t present, next_present;
3050         int bitno;
3051         enum ieee80211_radiotap_type bit;
3052         int rc;
3053
3054         for (present = presentflags; present; present = next_present) {
3055                 /*
3056                  * Clear the least significant bit that is set.
3057                  */
3058                 next_present = present & (present - 1);
3059
3060                 /*
3061                  * Get the bit number, within this presence word,
3062                  * of the remaining least significant bit that
3063                  * is set.
3064                  */
3065                 bitno = BITNO_32(present ^ next_present);
3066
3067                 /*
3068                  * Stop if this is one of the "same meaning
3069                  * in all presence flags" bits.
3070                  */
3071                 if (bitno >= IEEE80211_RADIOTAP_NAMESPACE)
3072                         break;
3073
3074                 /*
3075                  * Get the radiotap bit number of that bit.
3076                  */
3077                 bit = (enum ieee80211_radiotap_type)(bit0 + bitno);
3078
3079                 rc = print_radiotap_field(ndo, s, bit, flags, presentflags);
3080                 if (rc != 0)
3081                         return rc;
3082         }
3083
3084         return 0;
3085 }
3086
3087 static u_int
3088 ieee802_11_radio_print(netdissect_options *ndo,
3089                        const u_char *p, u_int length, u_int caplen)
3090 {
3091 #define BIT(n)  (1U << n)
3092 #define IS_EXTENDED(__p)        \
3093             (EXTRACT_LE_32BITS(__p) & BIT(IEEE80211_RADIOTAP_EXT)) != 0
3094
3095         struct cpack_state cpacker;
3096         const struct ieee80211_radiotap_header *hdr;
3097         uint32_t presentflags;
3098         const uint32_t *presentp, *last_presentp;
3099         int vendor_namespace;
3100         uint8_t vendor_oui[3];
3101         uint8_t vendor_subnamespace;
3102         uint16_t skip_length;
3103         int bit0;
3104         u_int len;
3105         uint8_t flags;
3106         int pad;
3107         u_int fcslen;
3108
3109         if (caplen < sizeof(*hdr)) {
3110                 ND_PRINT((ndo, "%s", tstr));
3111                 return caplen;
3112         }
3113
3114         hdr = (const struct ieee80211_radiotap_header *)p;
3115
3116         len = EXTRACT_LE_16BITS(&hdr->it_len);
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 }