Initial commit
[profile/ivi/tcpdump.git] / print-802_11.c
1 /*
2  * Copyright (c) 2001
3  *      Fortress Technologies, Inc.  All rights reserved.
4  *      Charlie Lenahan (clenahan@fortresstech.com)
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that: (1) source code distributions
8  * retain the above copyright notice and this paragraph in its entirety, (2)
9  * distributions including binary code include the above copyright notice and
10  * this paragraph in its entirety in the documentation or other materials
11  * provided with the distribution, and (3) all advertising materials mentioning
12  * features or use of this software display the following acknowledgement:
13  * ``This product includes software developed by the University of California,
14  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
15  * the University nor the names of its contributors may be used to endorse
16  * or promote products derived from this software without specific prior
17  * written permission.
18  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
19  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
20  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
21  */
22
23 #ifndef lint
24 static const char rcsid[] _U_ =
25     "@(#) $Header: /tcpdump/master/tcpdump/print-802_11.c,v 1.49 2007-12-29 23:25:02 guy Exp $ (LBL)";
26 #endif
27
28 #ifdef HAVE_CONFIG_H
29 #include "config.h"
30 #endif
31
32 #include <tcpdump-stdinc.h>
33
34 #include <stdio.h>
35 #include <pcap.h>
36 #include <string.h>
37
38 #include "interface.h"
39 #include "addrtoname.h"
40 #include "ethertype.h"
41
42 #include "extract.h"
43
44 #include "cpack.h"
45
46 #include "ieee802_11.h"
47 #include "ieee802_11_radio.h"
48
49 #define PRINT_SSID(p) \
50         if (p.ssid_present) { \
51                 printf(" ("); \
52                 fn_print(p.ssid.ssid, NULL); \
53                 printf(")"); \
54         }
55
56 #define PRINT_RATE(_sep, _r, _suf) \
57         printf("%s%2.1f%s", _sep, (.5 * ((_r) & 0x7f)), _suf)
58 #define PRINT_RATES(p) \
59         if (p.rates_present) { \
60                 int z; \
61                 const char *sep = " ["; \
62                 for (z = 0; z < p.rates.length ; z++) { \
63                         PRINT_RATE(sep, p.rates.rate[z], \
64                                 (p.rates.rate[z] & 0x80 ? "*" : "")); \
65                         sep = " "; \
66                 } \
67                 if (p.rates.length != 0) \
68                         printf(" Mbit]"); \
69         }
70
71 #define PRINT_DS_CHANNEL(p) \
72         if (p.ds_present) \
73                 printf(" CH: %u", p.ds.channel); \
74         printf("%s", \
75             CAPABILITY_PRIVACY(p.capability_info) ? ", PRIVACY" : "" );
76
77 static const int ieee80211_htrates[16] = {
78         13,             /* IFM_IEEE80211_MCS0 */
79         26,             /* IFM_IEEE80211_MCS1 */
80         39,             /* IFM_IEEE80211_MCS2 */
81         52,             /* IFM_IEEE80211_MCS3 */
82         78,             /* IFM_IEEE80211_MCS4 */
83         104,            /* IFM_IEEE80211_MCS5 */
84         117,            /* IFM_IEEE80211_MCS6 */
85         130,            /* IFM_IEEE80211_MCS7 */
86         26,             /* IFM_IEEE80211_MCS8 */
87         52,             /* IFM_IEEE80211_MCS9 */
88         78,             /* IFM_IEEE80211_MCS10 */
89         104,            /* IFM_IEEE80211_MCS11 */
90         156,            /* IFM_IEEE80211_MCS12 */
91         208,            /* IFM_IEEE80211_MCS13 */
92         234,            /* IFM_IEEE80211_MCS14 */
93         260,            /* IFM_IEEE80211_MCS15 */
94 };
95 #define PRINT_HT_RATE(_sep, _r, _suf) \
96         printf("%s%.1f%s", _sep, (.5 * ieee80211_htrates[(_r) & 0xf]), _suf)
97
98 static const char *auth_alg_text[]={"Open System","Shared Key","EAP"};
99 #define NUM_AUTH_ALGS   (sizeof auth_alg_text / sizeof auth_alg_text[0])
100
101 static const char *status_text[] = {
102         "Succesful",                                            /*  0 */
103         "Unspecified failure",                                  /*  1 */
104         "Reserved",                                             /*  2 */
105         "Reserved",                                             /*  3 */
106         "Reserved",                                             /*  4 */
107         "Reserved",                                             /*  5 */
108         "Reserved",                                             /*  6 */
109         "Reserved",                                             /*  7 */
110         "Reserved",                                             /*  8 */
111         "Reserved",                                             /*  9 */
112         "Cannot Support all requested capabilities in the Capability "
113           "Information field",                                  /* 10 */
114         "Reassociation denied due to inability to confirm that association "
115           "exists",                                             /* 11 */
116         "Association denied due to reason outside the scope of the "
117           "standard",                                           /* 12 */
118         "Responding station does not support the specified authentication "
119           "algorithm ",                                         /* 13 */
120         "Received an Authentication frame with authentication transaction "
121           "sequence number out of expected sequence",           /* 14 */
122         "Authentication rejected because of challenge failure", /* 15 */
123         "Authentication rejected due to timeout waiting for next frame in "
124           "sequence",                                           /* 16 */
125         "Association denied because AP is unable to handle additional"
126           "associated stations",                                /* 17 */
127         "Association denied due to requesting station not supporting all of "
128           "the data rates in BSSBasicRateSet parameter",        /* 18 */
129         "Association denied due to requesting station not supporting "
130           "short preamble operation",                           /* 19 */
131         "Association denied due to requesting station not supporting "
132           "PBCC encoding",                                      /* 20 */
133         "Association denied due to requesting station not supporting "
134           "channel agility",                                    /* 21 */
135         "Association request rejected because Spectrum Management "
136           "capability is required",                             /* 22 */
137         "Association request rejected because the information in the "
138           "Power Capability element is unacceptable",           /* 23 */
139         "Association request rejected because the information in the "
140           "Supported Channels element is unacceptable",         /* 24 */
141         "Association denied due to requesting station not supporting "
142           "short slot operation",                               /* 25 */
143         "Association denied due to requesting station not supporting "
144           "DSSS-OFDM operation",                                /* 26 */
145         "Association denied because the requested STA does not support HT "
146           "features",                                           /* 27 */
147         "Reserved",                                             /* 28 */
148         "Association denied because the requested STA does not support "
149           "the PCO transition time required by the AP",         /* 29 */
150         "Reserved",                                             /* 30 */
151         "Reserved",                                             /* 31 */
152         "Unspecified, QoS-related failure",                     /* 32 */
153         "Association denied due to QAP having insufficient bandwidth "
154           "to handle another QSTA",                             /* 33 */
155         "Association denied due to excessive frame loss rates and/or "
156           "poor conditions on current operating channel",       /* 34 */
157         "Association (with QBSS) denied due to requesting station not "
158           "supporting the QoS facility",                        /* 35 */
159         "Association denied due to requesting station not supporting "
160           "Block Ack",                                          /* 36 */
161         "The request has been declined",                        /* 37 */
162         "The request has not been successful as one or more parameters "
163           "have invalid values",                                /* 38 */
164         "The TS has not been created because the request cannot be honored. "
165           "However, a suggested TSPEC is provided so that the initiating QSTA"
166           "may attempt to set another TS with the suggested changes to the "
167           "TSPEC",                                              /* 39 */
168         "Invalid Information Element",                          /* 40 */
169         "Group Cipher is not valid",                            /* 41 */
170         "Pairwise Cipher is not valid",                         /* 42 */
171         "AKMP is not valid",                                    /* 43 */
172         "Unsupported RSN IE version",                           /* 44 */
173         "Invalid RSN IE Capabilities",                          /* 45 */
174         "Cipher suite is rejected per security policy",         /* 46 */
175         "The TS has not been created. However, the HC may be capable of "
176           "creating a TS, in response to a request, after the time indicated "
177           "in the TS Delay element",                            /* 47 */
178         "Direct Link is not allowed in the BSS by policy",      /* 48 */
179         "Destination STA is not present within this QBSS.",     /* 49 */
180         "The Destination STA is not a QSTA.",                   /* 50 */
181
182 };
183 #define NUM_STATUSES    (sizeof status_text / sizeof status_text[0])
184
185 static const char *reason_text[] = {
186         "Reserved",                                             /* 0 */
187         "Unspecified reason",                                   /* 1 */
188         "Previous authentication no longer valid",              /* 2 */
189         "Deauthenticated because sending station is leaving (or has left) "
190           "IBSS or ESS",                                        /* 3 */
191         "Disassociated due to inactivity",                      /* 4 */
192         "Disassociated because AP is unable to handle all currently "
193           " associated stations",                               /* 5 */
194         "Class 2 frame received from nonauthenticated station", /* 6 */
195         "Class 3 frame received from nonassociated station",    /* 7 */
196         "Disassociated because sending station is leaving "
197           "(or has left) BSS",                                  /* 8 */
198         "Station requesting (re)association is not authenticated with "
199           "responding station",                                 /* 9 */
200         "Disassociated because the information in the Power Capability "
201           "element is unacceptable",                            /* 10 */
202         "Disassociated because the information in the SupportedChannels "
203           "element is unacceptable",                            /* 11 */
204         "Invalid Information Element",                          /* 12 */
205         "Reserved",                                             /* 13 */
206         "Michael MIC failure",                                  /* 14 */
207         "4-Way Handshake timeout",                              /* 15 */
208         "Group key update timeout",                             /* 16 */
209         "Information element in 4-Way Handshake different from (Re)Association"
210           "Request/Probe Response/Beacon",                      /* 17 */
211         "Group Cipher is not valid",                            /* 18 */
212         "AKMP is not valid",                                    /* 20 */
213         "Unsupported RSN IE version",                           /* 21 */
214         "Invalid RSN IE Capabilities",                          /* 22 */
215         "IEEE 802.1X Authentication failed",                    /* 23 */
216         "Cipher suite is rejected per security policy",         /* 24 */
217         "Reserved",                                             /* 25 */
218         "Reserved",                                             /* 26 */
219         "Reserved",                                             /* 27 */
220         "Reserved",                                             /* 28 */
221         "Reserved",                                             /* 29 */
222         "Reserved",                                             /* 30 */
223         "TS deleted because QoS AP lacks sufficient bandwidth for this "
224           "QoS STA due to a change in BSS service characteristics or "
225           "operational mode (e.g. an HT BSS change from 40 MHz channel "
226           "to 20 MHz channel)",                                 /* 31 */
227         "Disassociated for unspecified, QoS-related reason",    /* 32 */
228         "Disassociated because QoS AP lacks sufficient bandwidth for this "
229           "QoS STA",                                            /* 33 */
230         "Disassociated because of excessive number of frames that need to be "
231           "acknowledged, but are not acknowledged for AP transmissions "
232           "and/or poor channel conditions",                     /* 34 */
233         "Disassociated because STA is transmitting outside the limits "
234           "of its TXOPs",                                       /* 35 */
235         "Requested from peer STA as the STA is leaving the BSS "
236           "(or resetting)",                                     /* 36 */
237         "Requested from peer STA as it does not want to use the "
238           "mechanism",                                          /* 37 */
239         "Requested from peer STA as the STA received frames using the "
240           "mechanism for which a set up is required",           /* 38 */
241         "Requested from peer STA due to time out",              /* 39 */
242         "Reserved",                                             /* 40 */
243         "Reserved",                                             /* 41 */
244         "Reserved",                                             /* 42 */
245         "Reserved",                                             /* 43 */
246         "Reserved",                                             /* 44 */
247         "Peer STA does not support the requested cipher suite", /* 45 */
248         "Association denied due to requesting STA not supporting HT "
249           "features",                                           /* 46 */
250 };
251 #define NUM_REASONS     (sizeof reason_text / sizeof reason_text[0])
252
253 static int
254 wep_print(const u_char *p)
255 {
256         u_int32_t iv;
257
258         if (!TTEST2(*p, IEEE802_11_IV_LEN + IEEE802_11_KID_LEN))
259                 return 0;
260         iv = EXTRACT_LE_32BITS(p);
261
262         printf("Data IV:%3x Pad %x KeyID %x", IV_IV(iv), IV_PAD(iv),
263             IV_KEYID(iv));
264
265         return 1;
266 }
267
268 static int
269 parse_elements(struct mgmt_body_t *pbody, const u_char *p, int offset,
270     u_int length)
271 {
272         struct ssid_t ssid;
273         struct challenge_t challenge;
274         struct rates_t rates;
275         struct ds_t ds;
276         struct cf_t cf;
277         struct tim_t tim;
278
279         /*
280          * We haven't seen any elements yet.
281          */
282         pbody->challenge_present = 0;
283         pbody->ssid_present = 0;
284         pbody->rates_present = 0;
285         pbody->ds_present = 0;
286         pbody->cf_present = 0;
287         pbody->tim_present = 0;
288
289         while (length != 0) {
290                 if (!TTEST2(*(p + offset), 1))
291                         return 0;
292                 if (length < 1)
293                         return 0;
294                 switch (*(p + offset)) {
295                 case E_SSID:
296                         if (!TTEST2(*(p + offset), 2))
297                                 return 0;
298                         if (length < 2)
299                                 return 0;
300                         memcpy(&ssid, p + offset, 2);
301                         offset += 2;
302                         length -= 2;
303                         if (ssid.length != 0) {
304                                 if (ssid.length > sizeof(ssid.ssid) - 1)
305                                         return 0;
306                                 if (!TTEST2(*(p + offset), ssid.length))
307                                         return 0;
308                                 if (length < ssid.length)
309                                         return 0;
310                                 memcpy(&ssid.ssid, p + offset, ssid.length);
311                                 offset += ssid.length;
312                                 length -= ssid.length;
313                         }
314                         ssid.ssid[ssid.length] = '\0';
315                         /*
316                          * Present and not truncated.
317                          *
318                          * If we haven't already seen an SSID IE,
319                          * copy this one, otherwise ignore this one,
320                          * so we later report the first one we saw.
321                          */
322                         if (!pbody->ssid_present) {
323                                 pbody->ssid = ssid;
324                                 pbody->ssid_present = 1;
325                         }
326                         break;
327                 case E_CHALLENGE:
328                         if (!TTEST2(*(p + offset), 2))
329                                 return 0;
330                         if (length < 2)
331                                 return 0;
332                         memcpy(&challenge, p + offset, 2);
333                         offset += 2;
334                         length -= 2;
335                         if (challenge.length != 0) {
336                                 if (challenge.length >
337                                     sizeof(challenge.text) - 1)
338                                         return 0;
339                                 if (!TTEST2(*(p + offset), challenge.length))
340                                         return 0;
341                                 if (length < challenge.length)
342                                         return 0;
343                                 memcpy(&challenge.text, p + offset,
344                                     challenge.length);
345                                 offset += challenge.length;
346                                 length -= challenge.length;
347                         }
348                         challenge.text[challenge.length] = '\0';
349                         /*
350                          * Present and not truncated.
351                          *
352                          * If we haven't already seen a challenge IE,
353                          * copy this one, otherwise ignore this one,
354                          * so we later report the first one we saw.
355                          */
356                         if (!pbody->challenge_present) {
357                                 pbody->challenge = challenge;
358                                 pbody->challenge_present = 1;
359                         }
360                         break;
361                 case E_RATES:
362                         if (!TTEST2(*(p + offset), 2))
363                                 return 0;
364                         if (length < 2)
365                                 return 0;
366                         memcpy(&rates, p + offset, 2);
367                         offset += 2;
368                         length -= 2;
369                         if (rates.length != 0) {
370                                 if (rates.length > sizeof rates.rate)
371                                         return 0;
372                                 if (!TTEST2(*(p + offset), rates.length))
373                                         return 0;
374                                 if (length < rates.length)
375                                         return 0;
376                                 memcpy(&rates.rate, p + offset, rates.length);
377                                 offset += rates.length;
378                                 length -= rates.length;
379                         }
380                         /*
381                          * Present and not truncated.
382                          *
383                          * If we haven't already seen a rates IE,
384                          * copy this one if it's not zero-length,
385                          * otherwise ignore this one, so we later
386                          * report the first one we saw.
387                          *
388                          * We ignore zero-length rates IEs as some
389                          * devices seem to put a zero-length rates
390                          * IE, followed by an SSID IE, followed by
391                          * a non-zero-length rates IE into frames,
392                          * even though IEEE Std 802.11-2007 doesn't
393                          * seem to indicate that a zero-length rates
394                          * IE is valid.
395                          */
396                         if (!pbody->rates_present && rates.length != 0) {
397                                 pbody->rates = rates;
398                                 pbody->rates_present = 1;
399                         }
400                         break;
401                 case E_DS:
402                         if (!TTEST2(*(p + offset), 3))
403                                 return 0;
404                         if (length < 3)
405                                 return 0;
406                         memcpy(&ds, p + offset, 3);
407                         offset += 3;
408                         length -= 3;
409                         /*
410                          * Present and not truncated.
411                          *
412                          * If we haven't already seen a DS IE,
413                          * copy this one, otherwise ignore this one,
414                          * so we later report the first one we saw.
415                          */
416                         if (!pbody->ds_present) {
417                                 pbody->ds = ds;
418                                 pbody->ds_present = 1;
419                         }
420                         break;
421                 case E_CF:
422                         if (!TTEST2(*(p + offset), 8))
423                                 return 0;
424                         if (length < 8)
425                                 return 0;
426                         memcpy(&cf, p + offset, 8);
427                         offset += 8;
428                         length -= 8;
429                         /*
430                          * Present and not truncated.
431                          *
432                          * If we haven't already seen a CF IE,
433                          * copy this one, otherwise ignore this one,
434                          * so we later report the first one we saw.
435                          */
436                         if (!pbody->cf_present) {
437                                 pbody->cf = cf;
438                                 pbody->cf_present = 1;
439                         }
440                         break;
441                 case E_TIM:
442                         if (!TTEST2(*(p + offset), 2))
443                                 return 0;
444                         if (length < 2)
445                                 return 0;
446                         memcpy(&tim, p + offset, 2);
447                         offset += 2;
448                         length -= 2;
449                         if (!TTEST2(*(p + offset), 3))
450                                 return 0;
451                         if (length < 3)
452                                 return 0;
453                         memcpy(&tim.count, p + offset, 3);
454                         offset += 3;
455                         length -= 3;
456
457                         if (tim.length <= 3)
458                                 break;
459                         if (tim.length - 3 > (int)sizeof tim.bitmap)
460                                 return 0;
461                         if (!TTEST2(*(p + offset), tim.length - 3))
462                                 return 0;
463                         if (length < (u_int)(tim.length - 3))
464                                 return 0;
465                         memcpy(tim.bitmap, p + (tim.length - 3),
466                             (tim.length - 3));
467                         offset += tim.length - 3;
468                         length -= tim.length - 3;
469                         /*
470                          * Present and not truncated.
471                          *
472                          * If we haven't already seen a TIM IE,
473                          * copy this one, otherwise ignore this one,
474                          * so we later report the first one we saw.
475                          */
476                         if (!pbody->tim_present) {
477                                 pbody->tim = tim;
478                                 pbody->tim_present = 1;
479                         }
480                         break;
481                 default:
482 #if 0
483                         printf("(1) unhandled element_id (%d)  ",
484                             *(p + offset));
485 #endif
486                         if (!TTEST2(*(p + offset), 2))
487                                 return 0;
488                         if (length < 2)
489                                 return 0;
490                         if (!TTEST2(*(p + offset + 2), *(p + offset + 1)))
491                                 return 0;
492                         if (length < (u_int)(*(p + offset + 1) + 2))
493                                 return 0;
494                         offset += *(p + offset + 1) + 2;
495                         length -= *(p + offset + 1) + 2;
496                         break;
497                 }
498         }
499
500         /* No problems found. */
501         return 1;
502 }
503
504 /*********************************************************************************
505  * Print Handle functions for the management frame types
506  *********************************************************************************/
507
508 static int
509 handle_beacon(const u_char *p, u_int length)
510 {
511         struct mgmt_body_t pbody;
512         int offset = 0;
513         int ret;
514
515         memset(&pbody, 0, sizeof(pbody));
516
517         if (!TTEST2(*p, IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN +
518             IEEE802_11_CAPINFO_LEN))
519                 return 0;
520         if (length < IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN +
521             IEEE802_11_CAPINFO_LEN)
522                 return 0;
523         memcpy(&pbody.timestamp, p, IEEE802_11_TSTAMP_LEN);
524         offset += IEEE802_11_TSTAMP_LEN;
525         length -= IEEE802_11_TSTAMP_LEN;
526         pbody.beacon_interval = EXTRACT_LE_16BITS(p+offset);
527         offset += IEEE802_11_BCNINT_LEN;
528         length -= IEEE802_11_BCNINT_LEN;
529         pbody.capability_info = EXTRACT_LE_16BITS(p+offset);
530         offset += IEEE802_11_CAPINFO_LEN;
531         length -= IEEE802_11_CAPINFO_LEN;
532
533         ret = parse_elements(&pbody, p, offset, length);
534
535         PRINT_SSID(pbody);
536         PRINT_RATES(pbody);
537         printf(" %s",
538             CAPABILITY_ESS(pbody.capability_info) ? "ESS" : "IBSS");
539         PRINT_DS_CHANNEL(pbody);
540
541         return ret;
542 }
543
544 static int
545 handle_assoc_request(const u_char *p, u_int length)
546 {
547         struct mgmt_body_t pbody;
548         int offset = 0;
549         int ret;
550
551         memset(&pbody, 0, sizeof(pbody));
552
553         if (!TTEST2(*p, IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN))
554                 return 0;
555         if (length < IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN)
556                 return 0;
557         pbody.capability_info = EXTRACT_LE_16BITS(p);
558         offset += IEEE802_11_CAPINFO_LEN;
559         length -= IEEE802_11_CAPINFO_LEN;
560         pbody.listen_interval = EXTRACT_LE_16BITS(p+offset);
561         offset += IEEE802_11_LISTENINT_LEN;
562         length -= IEEE802_11_LISTENINT_LEN;
563
564         ret = parse_elements(&pbody, p, offset, length);
565
566         PRINT_SSID(pbody);
567         PRINT_RATES(pbody);
568         return ret;
569 }
570
571 static int
572 handle_assoc_response(const u_char *p, u_int length)
573 {
574         struct mgmt_body_t pbody;
575         int offset = 0;
576         int ret;
577
578         memset(&pbody, 0, sizeof(pbody));
579
580         if (!TTEST2(*p, IEEE802_11_CAPINFO_LEN + IEEE802_11_STATUS_LEN +
581             IEEE802_11_AID_LEN))
582                 return 0;
583         if (length < IEEE802_11_CAPINFO_LEN + IEEE802_11_STATUS_LEN +
584             IEEE802_11_AID_LEN)
585                 return 0;
586         pbody.capability_info = EXTRACT_LE_16BITS(p);
587         offset += IEEE802_11_CAPINFO_LEN;
588         length -= IEEE802_11_CAPINFO_LEN;
589         pbody.status_code = EXTRACT_LE_16BITS(p+offset);
590         offset += IEEE802_11_STATUS_LEN;
591         length -= IEEE802_11_STATUS_LEN;
592         pbody.aid = EXTRACT_LE_16BITS(p+offset);
593         offset += IEEE802_11_AID_LEN;
594         length -= IEEE802_11_AID_LEN;
595
596         ret = parse_elements(&pbody, p, offset, length);
597
598         printf(" AID(%x) :%s: %s", ((u_int16_t)(pbody.aid << 2 )) >> 2 ,
599             CAPABILITY_PRIVACY(pbody.capability_info) ? " PRIVACY " : "",
600             (pbody.status_code < NUM_STATUSES
601                 ? status_text[pbody.status_code]
602                 : "n/a"));
603
604         return ret;
605 }
606
607 static int
608 handle_reassoc_request(const u_char *p, u_int length)
609 {
610         struct mgmt_body_t pbody;
611         int offset = 0;
612         int ret;
613
614         memset(&pbody, 0, sizeof(pbody));
615
616         if (!TTEST2(*p, IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN +
617             IEEE802_11_AP_LEN))
618                 return 0;
619         if (length < IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN +
620             IEEE802_11_AP_LEN)
621                 return 0;
622         pbody.capability_info = EXTRACT_LE_16BITS(p);
623         offset += IEEE802_11_CAPINFO_LEN;
624         length -= IEEE802_11_CAPINFO_LEN;
625         pbody.listen_interval = EXTRACT_LE_16BITS(p+offset);
626         offset += IEEE802_11_LISTENINT_LEN;
627         length -= IEEE802_11_LISTENINT_LEN;
628         memcpy(&pbody.ap, p+offset, IEEE802_11_AP_LEN);
629         offset += IEEE802_11_AP_LEN;
630         length -= IEEE802_11_AP_LEN;
631
632         ret = parse_elements(&pbody, p, offset, length);
633
634         PRINT_SSID(pbody);
635         printf(" AP : %s", etheraddr_string( pbody.ap ));
636
637         return ret;
638 }
639
640 static int
641 handle_reassoc_response(const u_char *p, u_int length)
642 {
643         /* Same as a Association Reponse */
644         return handle_assoc_response(p, length);
645 }
646
647 static int
648 handle_probe_request(const u_char *p, u_int length)
649 {
650         struct mgmt_body_t  pbody;
651         int offset = 0;
652         int ret;
653
654         memset(&pbody, 0, sizeof(pbody));
655
656         ret = parse_elements(&pbody, p, offset, length);
657
658         PRINT_SSID(pbody);
659         PRINT_RATES(pbody);
660
661         return ret;
662 }
663
664 static int
665 handle_probe_response(const u_char *p, u_int length)
666 {
667         struct mgmt_body_t  pbody;
668         int offset = 0;
669         int ret;
670
671         memset(&pbody, 0, sizeof(pbody));
672
673         if (!TTEST2(*p, IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN +
674             IEEE802_11_CAPINFO_LEN))
675                 return 0;
676         if (length < IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN +
677             IEEE802_11_CAPINFO_LEN)
678                 return 0;
679         memcpy(&pbody.timestamp, p, IEEE802_11_TSTAMP_LEN);
680         offset += IEEE802_11_TSTAMP_LEN;
681         length -= IEEE802_11_TSTAMP_LEN;
682         pbody.beacon_interval = EXTRACT_LE_16BITS(p+offset);
683         offset += IEEE802_11_BCNINT_LEN;
684         length -= IEEE802_11_BCNINT_LEN;
685         pbody.capability_info = EXTRACT_LE_16BITS(p+offset);
686         offset += IEEE802_11_CAPINFO_LEN;
687         length -= IEEE802_11_CAPINFO_LEN;
688
689         ret = parse_elements(&pbody, p, offset, length);
690
691         PRINT_SSID(pbody);
692         PRINT_RATES(pbody);
693         PRINT_DS_CHANNEL(pbody);
694
695         return ret;
696 }
697
698 static int
699 handle_atim(void)
700 {
701         /* the frame body for ATIM is null. */
702         return 1;
703 }
704
705 static int
706 handle_disassoc(const u_char *p, u_int length)
707 {
708         struct mgmt_body_t  pbody;
709
710         memset(&pbody, 0, sizeof(pbody));
711
712         if (!TTEST2(*p, IEEE802_11_REASON_LEN))
713                 return 0;
714         if (length < IEEE802_11_REASON_LEN)
715                 return 0;
716         pbody.reason_code = EXTRACT_LE_16BITS(p);
717
718         printf(": %s",
719             (pbody.reason_code < NUM_REASONS)
720                 ? reason_text[pbody.reason_code]
721                 : "Reserved" );
722
723         return 1;
724 }
725
726 static int
727 handle_auth(const u_char *p, u_int length)
728 {
729         struct mgmt_body_t  pbody;
730         int offset = 0;
731         int ret;
732
733         memset(&pbody, 0, sizeof(pbody));
734
735         if (!TTEST2(*p, 6))
736                 return 0;
737         if (length < 6)
738                 return 0;
739         pbody.auth_alg = EXTRACT_LE_16BITS(p);
740         offset += 2;
741         length -= 2;
742         pbody.auth_trans_seq_num = EXTRACT_LE_16BITS(p + offset);
743         offset += 2;
744         length -= 2;
745         pbody.status_code = EXTRACT_LE_16BITS(p + offset);
746         offset += 2;
747         length -= 2;
748
749         ret = parse_elements(&pbody, p, offset, length);
750
751         if ((pbody.auth_alg == 1) &&
752             ((pbody.auth_trans_seq_num == 2) ||
753              (pbody.auth_trans_seq_num == 3))) {
754                 printf(" (%s)-%x [Challenge Text] %s",
755                     (pbody.auth_alg < NUM_AUTH_ALGS)
756                         ? auth_alg_text[pbody.auth_alg]
757                         : "Reserved",
758                     pbody.auth_trans_seq_num,
759                     ((pbody.auth_trans_seq_num % 2)
760                         ? ((pbody.status_code < NUM_STATUSES)
761                                ? status_text[pbody.status_code]
762                                : "n/a") : ""));
763                 return ret;
764         }
765         printf(" (%s)-%x: %s",
766             (pbody.auth_alg < NUM_AUTH_ALGS)
767                 ? auth_alg_text[pbody.auth_alg]
768                 : "Reserved",
769             pbody.auth_trans_seq_num,
770             (pbody.auth_trans_seq_num % 2)
771                 ? ((pbody.status_code < NUM_STATUSES)
772                     ? status_text[pbody.status_code]
773                     : "n/a")
774                 : "");
775
776         return ret;
777 }
778
779 static int
780 handle_deauth(const struct mgmt_header_t *pmh, const u_char *p, u_int length)
781 {
782         struct mgmt_body_t  pbody;
783         int offset = 0;
784         const char *reason = NULL;
785
786         memset(&pbody, 0, sizeof(pbody));
787
788         if (!TTEST2(*p, IEEE802_11_REASON_LEN))
789                 return 0;
790         if (length < IEEE802_11_REASON_LEN)
791                 return 0;
792         pbody.reason_code = EXTRACT_LE_16BITS(p);
793         offset += IEEE802_11_REASON_LEN;
794         length -= IEEE802_11_REASON_LEN;
795
796         reason = (pbody.reason_code < NUM_REASONS)
797                         ? reason_text[pbody.reason_code]
798                         : "Reserved";
799
800         if (eflag) {
801                 printf(": %s", reason);
802         } else {
803                 printf(" (%s): %s", etheraddr_string(pmh->sa), reason);
804         }
805         return 1;
806 }
807
808 #define PRINT_HT_ACTION(v) (\
809         (v) == 0 ? printf("TxChWidth") : \
810         (v) == 1 ? printf("MIMOPwrSave") : \
811                    printf("Act#%d", (v)) \
812 )
813 #define PRINT_BA_ACTION(v) (\
814         (v) == 0 ? printf("ADDBA Request") : \
815         (v) == 1 ? printf("ADDBA Response") : \
816         (v) == 2 ? printf("DELBA") : \
817                    printf("Act#%d", (v)) \
818 )
819 #define PRINT_MESHLINK_ACTION(v) (\
820         (v) == 0 ? printf("Request") : \
821         (v) == 1 ? printf("Report") : \
822                    printf("Act#%d", (v)) \
823 )
824 #define PRINT_MESHPEERING_ACTION(v) (\
825         (v) == 0 ? printf("Open") : \
826         (v) == 1 ? printf("Confirm") : \
827         (v) == 2 ? printf("Close") : \
828                    printf("Act#%d", (v)) \
829 )
830 #define PRINT_MESHPATH_ACTION(v) (\
831         (v) == 0 ? printf("Request") : \
832         (v) == 1 ? printf("Report") : \
833         (v) == 2 ? printf("Error") : \
834         (v) == 3 ? printf("RootAnnouncement") : \
835                    printf("Act#%d", (v)) \
836 )
837
838 static int
839 handle_action(const struct mgmt_header_t *pmh, const u_char *p, u_int length)
840 {
841         if (!TTEST2(*p, 2))
842                 return 0;
843         if (length < 2)
844                 return 0;
845         if (eflag) {
846                 printf(": ");
847         } else {
848                 printf(" (%s): ", etheraddr_string(pmh->sa));
849         }
850         switch (p[0]) {
851         case 0: printf("Spectrum Management Act#%d", p[1]); break;
852         case 1: printf("QoS Act#%d", p[1]); break;
853         case 2: printf("DLS Act#%d", p[1]); break;
854         case 3: printf("BA "); PRINT_BA_ACTION(p[1]); break;
855         case 7: printf("HT "); PRINT_HT_ACTION(p[1]); break;
856         case 13: printf("MeshLMetric "); PRINT_MESHLINK_ACTION(p[1]); break;
857         case 15: printf("Interwork Act#%d", p[1]); break;
858         case 16: printf("Resource Act#%d", p[1]); break;
859         case 17: printf("Proxy Act#%d", p[1]); break;
860         case 30: printf("MeshPeering "); PRINT_MESHPEERING_ACTION(p[1]); break;
861         case 32: printf("MeshPath "); PRINT_MESHPATH_ACTION(p[1]); break;
862         case 127: printf("Vendor Act#%d", p[1]); break;
863         default:
864                 printf("Reserved(%d) Act#%d", p[0], p[1]);
865                 break;
866         }
867         return 1;
868 }
869
870
871 /*********************************************************************************
872  * Print Body funcs
873  *********************************************************************************/
874
875
876 static int
877 mgmt_body_print(u_int16_t fc, const struct mgmt_header_t *pmh,
878     const u_char *p, u_int length)
879 {
880         switch (FC_SUBTYPE(fc)) {
881         case ST_ASSOC_REQUEST:
882                 printf("Assoc Request");
883                 return handle_assoc_request(p, length);
884         case ST_ASSOC_RESPONSE:
885                 printf("Assoc Response");
886                 return handle_assoc_response(p, length);
887         case ST_REASSOC_REQUEST:
888                 printf("ReAssoc Request");
889                 return handle_reassoc_request(p, length);
890         case ST_REASSOC_RESPONSE:
891                 printf("ReAssoc Response");
892                 return handle_reassoc_response(p, length);
893         case ST_PROBE_REQUEST:
894                 printf("Probe Request");
895                 return handle_probe_request(p, length);
896         case ST_PROBE_RESPONSE:
897                 printf("Probe Response");
898                 return handle_probe_response(p, length);
899         case ST_BEACON:
900                 printf("Beacon");
901                 return handle_beacon(p, length);
902         case ST_ATIM:
903                 printf("ATIM");
904                 return handle_atim();
905         case ST_DISASSOC:
906                 printf("Disassociation");
907                 return handle_disassoc(p, length);
908         case ST_AUTH:
909                 printf("Authentication");
910                 if (!TTEST2(*p, 3))
911                         return 0;
912                 if ((p[0] == 0 ) && (p[1] == 0) && (p[2] == 0)) {
913                         printf("Authentication (Shared-Key)-3 ");
914                         return wep_print(p);
915                 }
916                 return handle_auth(p, length);
917         case ST_DEAUTH:
918                 printf("DeAuthentication");
919                 return handle_deauth(pmh, p, length);
920                 break;
921         case ST_ACTION:
922                 printf("Action");
923                 return handle_action(pmh, p, length);
924                 break;
925         default:
926                 printf("Unhandled Management subtype(%x)",
927                     FC_SUBTYPE(fc));
928                 return 1;
929         }
930 }
931
932
933 /*********************************************************************************
934  * Handles printing all the control frame types
935  *********************************************************************************/
936
937 static int
938 ctrl_body_print(u_int16_t fc, const u_char *p)
939 {
940         switch (FC_SUBTYPE(fc)) {
941         case CTRL_CONTROL_WRAPPER:
942                 printf("Control Wrapper");
943                 /* XXX - requires special handling */
944                 break;
945         case CTRL_BAR:
946                 printf("BAR");
947                 if (!TTEST2(*p, CTRL_BAR_HDRLEN))
948                         return 0;
949                 if (!eflag)
950                         printf(" RA:%s TA:%s CTL(%x) SEQ(%u) ",
951                             etheraddr_string(((const struct ctrl_bar_t *)p)->ra),
952                             etheraddr_string(((const struct ctrl_bar_t *)p)->ta),
953                             EXTRACT_LE_16BITS(&(((const struct ctrl_bar_t *)p)->ctl)),
954                             EXTRACT_LE_16BITS(&(((const struct ctrl_bar_t *)p)->seq)));
955                 break;
956         case CTRL_BA:
957                 printf("BA");
958                 if (!TTEST2(*p, CTRL_BA_HDRLEN))
959                         return 0;
960                 if (!eflag)
961                         printf(" RA:%s ",
962                             etheraddr_string(((const struct ctrl_ba_t *)p)->ra));
963                 break;
964         case CTRL_PS_POLL:
965                 printf("Power Save-Poll");
966                 if (!TTEST2(*p, CTRL_PS_POLL_HDRLEN))
967                         return 0;
968                 printf(" AID(%x)",
969                     EXTRACT_LE_16BITS(&(((const struct ctrl_ps_poll_t *)p)->aid)));
970                 break;
971         case CTRL_RTS:
972                 printf("Request-To-Send");
973                 if (!TTEST2(*p, CTRL_RTS_HDRLEN))
974                         return 0;
975                 if (!eflag)
976                         printf(" TA:%s ",
977                             etheraddr_string(((const struct ctrl_rts_t *)p)->ta));
978                 break;
979         case CTRL_CTS:
980                 printf("Clear-To-Send");
981                 if (!TTEST2(*p, CTRL_CTS_HDRLEN))
982                         return 0;
983                 if (!eflag)
984                         printf(" RA:%s ",
985                             etheraddr_string(((const struct ctrl_cts_t *)p)->ra));
986                 break;
987         case CTRL_ACK:
988                 printf("Acknowledgment");
989                 if (!TTEST2(*p, CTRL_ACK_HDRLEN))
990                         return 0;
991                 if (!eflag)
992                         printf(" RA:%s ",
993                             etheraddr_string(((const struct ctrl_ack_t *)p)->ra));
994                 break;
995         case CTRL_CF_END:
996                 printf("CF-End");
997                 if (!TTEST2(*p, CTRL_END_HDRLEN))
998                         return 0;
999                 if (!eflag)
1000                         printf(" RA:%s ",
1001                             etheraddr_string(((const struct ctrl_end_t *)p)->ra));
1002                 break;
1003         case CTRL_END_ACK:
1004                 printf("CF-End+CF-Ack");
1005                 if (!TTEST2(*p, CTRL_END_ACK_HDRLEN))
1006                         return 0;
1007                 if (!eflag)
1008                         printf(" RA:%s ",
1009                             etheraddr_string(((const struct ctrl_end_ack_t *)p)->ra));
1010                 break;
1011         default:
1012                 printf("Unknown Ctrl Subtype");
1013         }
1014         return 1;
1015 }
1016
1017 /*
1018  * Print Header funcs
1019  */
1020
1021 /*
1022  *  Data Frame - Address field contents
1023  *
1024  *  To Ds  | From DS | Addr 1 | Addr 2 | Addr 3 | Addr 4
1025  *    0    |  0      |  DA    | SA     | BSSID  | n/a
1026  *    0    |  1      |  DA    | BSSID  | SA     | n/a
1027  *    1    |  0      |  BSSID | SA     | DA     | n/a
1028  *    1    |  1      |  RA    | TA     | DA     | SA
1029  */
1030
1031 static void
1032 data_header_print(u_int16_t fc, const u_char *p, const u_int8_t **srcp,
1033     const u_int8_t **dstp)
1034 {
1035         u_int subtype = FC_SUBTYPE(fc);
1036
1037         if (DATA_FRAME_IS_CF_ACK(subtype) || DATA_FRAME_IS_CF_POLL(subtype) ||
1038             DATA_FRAME_IS_QOS(subtype)) {
1039                 printf("CF ");
1040                 if (DATA_FRAME_IS_CF_ACK(subtype)) {
1041                         if (DATA_FRAME_IS_CF_POLL(subtype))
1042                                 printf("Ack/Poll");
1043                         else
1044                                 printf("Ack");
1045                 } else {
1046                         if (DATA_FRAME_IS_CF_POLL(subtype))
1047                                 printf("Poll");
1048                 }
1049                 if (DATA_FRAME_IS_QOS(subtype))
1050                         printf("+QoS");
1051                 printf(" ");
1052         }
1053
1054 #define ADDR1  (p + 4)
1055 #define ADDR2  (p + 10)
1056 #define ADDR3  (p + 16)
1057 #define ADDR4  (p + 24)
1058
1059         if (!FC_TO_DS(fc) && !FC_FROM_DS(fc)) {
1060                 if (srcp != NULL)
1061                         *srcp = ADDR2;
1062                 if (dstp != NULL)
1063                         *dstp = ADDR1;
1064                 if (!eflag)
1065                         return;
1066                 printf("DA:%s SA:%s BSSID:%s ",
1067                     etheraddr_string(ADDR1), etheraddr_string(ADDR2),
1068                     etheraddr_string(ADDR3));
1069         } else if (!FC_TO_DS(fc) && FC_FROM_DS(fc)) {
1070                 if (srcp != NULL)
1071                         *srcp = ADDR3;
1072                 if (dstp != NULL)
1073                         *dstp = ADDR1;
1074                 if (!eflag)
1075                         return;
1076                 printf("DA:%s BSSID:%s SA:%s ",
1077                     etheraddr_string(ADDR1), etheraddr_string(ADDR2),
1078                     etheraddr_string(ADDR3));
1079         } else if (FC_TO_DS(fc) && !FC_FROM_DS(fc)) {
1080                 if (srcp != NULL)
1081                         *srcp = ADDR2;
1082                 if (dstp != NULL)
1083                         *dstp = ADDR3;
1084                 if (!eflag)
1085                         return;
1086                 printf("BSSID:%s SA:%s DA:%s ",
1087                     etheraddr_string(ADDR1), etheraddr_string(ADDR2),
1088                     etheraddr_string(ADDR3));
1089         } else if (FC_TO_DS(fc) && FC_FROM_DS(fc)) {
1090                 if (srcp != NULL)
1091                         *srcp = ADDR4;
1092                 if (dstp != NULL)
1093                         *dstp = ADDR3;
1094                 if (!eflag)
1095                         return;
1096                 printf("RA:%s TA:%s DA:%s SA:%s ",
1097                     etheraddr_string(ADDR1), etheraddr_string(ADDR2),
1098                     etheraddr_string(ADDR3), etheraddr_string(ADDR4));
1099         }
1100
1101 #undef ADDR1
1102 #undef ADDR2
1103 #undef ADDR3
1104 #undef ADDR4
1105 }
1106
1107 static void
1108 mgmt_header_print(const u_char *p, const u_int8_t **srcp,
1109     const u_int8_t **dstp)
1110 {
1111         const struct mgmt_header_t *hp = (const struct mgmt_header_t *) p;
1112
1113         if (srcp != NULL)
1114                 *srcp = hp->sa;
1115         if (dstp != NULL)
1116                 *dstp = hp->da;
1117         if (!eflag)
1118                 return;
1119
1120         printf("BSSID:%s DA:%s SA:%s ",
1121             etheraddr_string((hp)->bssid), etheraddr_string((hp)->da),
1122             etheraddr_string((hp)->sa));
1123 }
1124
1125 static void
1126 ctrl_header_print(u_int16_t fc, const u_char *p, const u_int8_t **srcp,
1127     const u_int8_t **dstp)
1128 {
1129         if (srcp != NULL)
1130                 *srcp = NULL;
1131         if (dstp != NULL)
1132                 *dstp = NULL;
1133         if (!eflag)
1134                 return;
1135
1136         switch (FC_SUBTYPE(fc)) {
1137         case CTRL_BAR:
1138                 printf(" RA:%s TA:%s CTL(%x) SEQ(%u) ",
1139                     etheraddr_string(((const struct ctrl_bar_t *)p)->ra),
1140                     etheraddr_string(((const struct ctrl_bar_t *)p)->ta),
1141                     EXTRACT_LE_16BITS(&(((const struct ctrl_bar_t *)p)->ctl)),
1142                     EXTRACT_LE_16BITS(&(((const struct ctrl_bar_t *)p)->seq)));
1143                 break;
1144         case CTRL_BA:
1145                 printf("RA:%s ",
1146                     etheraddr_string(((const struct ctrl_ba_t *)p)->ra));
1147                 break;
1148         case CTRL_PS_POLL:
1149                 printf("BSSID:%s TA:%s ",
1150                     etheraddr_string(((const struct ctrl_ps_poll_t *)p)->bssid),
1151                     etheraddr_string(((const struct ctrl_ps_poll_t *)p)->ta));
1152                 break;
1153         case CTRL_RTS:
1154                 printf("RA:%s TA:%s ",
1155                     etheraddr_string(((const struct ctrl_rts_t *)p)->ra),
1156                     etheraddr_string(((const struct ctrl_rts_t *)p)->ta));
1157                 break;
1158         case CTRL_CTS:
1159                 printf("RA:%s ",
1160                     etheraddr_string(((const struct ctrl_cts_t *)p)->ra));
1161                 break;
1162         case CTRL_ACK:
1163                 printf("RA:%s ",
1164                     etheraddr_string(((const struct ctrl_ack_t *)p)->ra));
1165                 break;
1166         case CTRL_CF_END:
1167                 printf("RA:%s BSSID:%s ",
1168                     etheraddr_string(((const struct ctrl_end_t *)p)->ra),
1169                     etheraddr_string(((const struct ctrl_end_t *)p)->bssid));
1170                 break;
1171         case CTRL_END_ACK:
1172                 printf("RA:%s BSSID:%s ",
1173                     etheraddr_string(((const struct ctrl_end_ack_t *)p)->ra),
1174                     etheraddr_string(((const struct ctrl_end_ack_t *)p)->bssid));
1175                 break;
1176         default:
1177                 printf("(H) Unknown Ctrl Subtype");
1178                 break;
1179         }
1180 }
1181
1182 static int
1183 extract_header_length(u_int16_t fc)
1184 {
1185         int len;
1186
1187         switch (FC_TYPE(fc)) {
1188         case T_MGMT:
1189                 return MGMT_HDRLEN;
1190         case T_CTRL:
1191                 switch (FC_SUBTYPE(fc)) {
1192                 case CTRL_BAR:
1193                         return CTRL_BAR_HDRLEN;
1194                 case CTRL_PS_POLL:
1195                         return CTRL_PS_POLL_HDRLEN;
1196                 case CTRL_RTS:
1197                         return CTRL_RTS_HDRLEN;
1198                 case CTRL_CTS:
1199                         return CTRL_CTS_HDRLEN;
1200                 case CTRL_ACK:
1201                         return CTRL_ACK_HDRLEN;
1202                 case CTRL_CF_END:
1203                         return CTRL_END_HDRLEN;
1204                 case CTRL_END_ACK:
1205                         return CTRL_END_ACK_HDRLEN;
1206                 default:
1207                         return 0;
1208                 }
1209         case T_DATA:
1210                 len = (FC_TO_DS(fc) && FC_FROM_DS(fc)) ? 30 : 24;
1211                 if (DATA_FRAME_IS_QOS(FC_SUBTYPE(fc)))
1212                         len += 2;
1213                 return len;
1214         default:
1215                 printf("unknown IEEE802.11 frame type (%d)", FC_TYPE(fc));
1216                 return 0;
1217         }
1218 }
1219
1220 static int
1221 extract_mesh_header_length(const u_char *p)
1222 {
1223         return (p[0] &~ 3) ? 0 : 6*(1 + (p[0] & 3));
1224 }
1225
1226 /*
1227  * Print the 802.11 MAC header if eflag is set, and set "*srcp" and "*dstp"
1228  * to point to the source and destination MAC addresses in any case if
1229  * "srcp" and "dstp" aren't null.
1230  */
1231 static void
1232 ieee_802_11_hdr_print(u_int16_t fc, const u_char *p, u_int hdrlen,
1233     u_int meshdrlen, const u_int8_t **srcp, const u_int8_t **dstp)
1234 {
1235         if (vflag) {
1236                 if (FC_MORE_DATA(fc))
1237                         printf("More Data ");
1238                 if (FC_MORE_FLAG(fc))
1239                         printf("More Fragments ");
1240                 if (FC_POWER_MGMT(fc))
1241                         printf("Pwr Mgmt ");
1242                 if (FC_RETRY(fc))
1243                         printf("Retry ");
1244                 if (FC_ORDER(fc))
1245                         printf("Strictly Ordered ");
1246                 if (FC_WEP(fc))
1247                         printf("WEP Encrypted ");
1248                 if (FC_TYPE(fc) != T_CTRL || FC_SUBTYPE(fc) != CTRL_PS_POLL)
1249                         printf("%dus ",
1250                             EXTRACT_LE_16BITS(
1251                                 &((const struct mgmt_header_t *)p)->duration));
1252         }
1253         if (meshdrlen != 0) {
1254                 const struct meshcntl_t *mc =
1255                     (const struct meshcntl_t *)&p[hdrlen - meshdrlen];
1256                 int ae = mc->flags & 3;
1257
1258                 printf("MeshData (AE %d TTL %u seq %u", ae, mc->ttl,
1259                     EXTRACT_LE_32BITS(mc->seq));
1260                 if (ae > 0)
1261                         printf(" A4:%s", etheraddr_string(mc->addr4));
1262                 if (ae > 1)
1263                         printf(" A5:%s", etheraddr_string(mc->addr5));
1264                 if (ae > 2)
1265                         printf(" A6:%s", etheraddr_string(mc->addr6));
1266                 printf(") ");
1267         }
1268
1269         switch (FC_TYPE(fc)) {
1270         case T_MGMT:
1271                 mgmt_header_print(p, srcp, dstp);
1272                 break;
1273         case T_CTRL:
1274                 ctrl_header_print(fc, p, srcp, dstp);
1275                 break;
1276         case T_DATA:
1277                 data_header_print(fc, p, srcp, dstp);
1278                 break;
1279         default:
1280                 printf("(header) unknown IEEE802.11 frame type (%d)",
1281                     FC_TYPE(fc));
1282                 *srcp = NULL;
1283                 *dstp = NULL;
1284                 break;
1285         }
1286 }
1287
1288 #ifndef roundup2
1289 #define roundup2(x, y)  (((x)+((y)-1))&(~((y)-1))) /* if y is powers of two */
1290 #endif
1291
1292 static u_int
1293 ieee802_11_print(const u_char *p, u_int length, u_int orig_caplen, int pad,
1294     u_int fcslen)
1295 {
1296         u_int16_t fc;
1297         u_int caplen, hdrlen, meshdrlen;
1298         const u_int8_t *src, *dst;
1299         u_short extracted_ethertype;
1300
1301         caplen = orig_caplen;
1302         /* Remove FCS, if present */
1303         if (length < fcslen) {
1304                 printf("[|802.11]");
1305                 return caplen;
1306         }
1307         length -= fcslen;
1308         if (caplen > length) {
1309                 /* Amount of FCS in actual packet data, if any */
1310                 fcslen = caplen - length;
1311                 caplen -= fcslen;
1312                 snapend -= fcslen;
1313         }
1314
1315         if (caplen < IEEE802_11_FC_LEN) {
1316                 printf("[|802.11]");
1317                 return orig_caplen;
1318         }
1319
1320         fc = EXTRACT_LE_16BITS(p);
1321         hdrlen = extract_header_length(fc);
1322         if (pad)
1323                 hdrlen = roundup2(hdrlen, 4);
1324         if (FC_TYPE(fc) == T_DATA && DATA_FRAME_IS_QOS(FC_SUBTYPE(fc))) {
1325                 meshdrlen = extract_mesh_header_length(p+hdrlen);
1326                 hdrlen += meshdrlen;
1327         } else
1328                 meshdrlen = 0;
1329
1330
1331         if (caplen < hdrlen) {
1332                 printf("[|802.11]");
1333                 return hdrlen;
1334         }
1335
1336         ieee_802_11_hdr_print(fc, p, hdrlen, meshdrlen, &src, &dst);
1337
1338         /*
1339          * Go past the 802.11 header.
1340          */
1341         length -= hdrlen;
1342         caplen -= hdrlen;
1343         p += hdrlen;
1344
1345         switch (FC_TYPE(fc)) {
1346         case T_MGMT:
1347                 if (!mgmt_body_print(fc,
1348                     (const struct mgmt_header_t *)(p - hdrlen), p, length)) {
1349                         printf("[|802.11]");
1350                         return hdrlen;
1351                 }
1352                 break;
1353         case T_CTRL:
1354                 if (!ctrl_body_print(fc, p - hdrlen)) {
1355                         printf("[|802.11]");
1356                         return hdrlen;
1357                 }
1358                 break;
1359         case T_DATA:
1360                 if (DATA_FRAME_IS_NULL(FC_SUBTYPE(fc)))
1361                         return hdrlen;  /* no-data frame */
1362                 /* There may be a problem w/ AP not having this bit set */
1363                 if (FC_WEP(fc)) {
1364                         if (!wep_print(p)) {
1365                                 printf("[|802.11]");
1366                                 return hdrlen;
1367                         }
1368                 } else if (llc_print(p, length, caplen, dst, src,
1369                     &extracted_ethertype) == 0) {
1370                         /*
1371                          * Some kinds of LLC packet we cannot
1372                          * handle intelligently
1373                          */
1374                         if (!eflag)
1375                                 ieee_802_11_hdr_print(fc, p - hdrlen, hdrlen,
1376                                     meshdrlen, NULL, NULL);
1377                         if (extracted_ethertype)
1378                                 printf("(LLC %s) ",
1379                                     etherproto_string(
1380                                         htons(extracted_ethertype)));
1381                         if (!suppress_default_print)
1382                                 default_print(p, caplen);
1383                 }
1384                 break;
1385         default:
1386                 printf("unknown 802.11 frame type (%d)", FC_TYPE(fc));
1387                 break;
1388         }
1389
1390         return hdrlen;
1391 }
1392
1393 /*
1394  * This is the top level routine of the printer.  'p' points
1395  * to the 802.11 header of the packet, 'h->ts' is the timestamp,
1396  * 'h->len' is the length of the packet off the wire, and 'h->caplen'
1397  * is the number of bytes actually captured.
1398  */
1399 u_int
1400 ieee802_11_if_print(const struct pcap_pkthdr *h, const u_char *p)
1401 {
1402         return ieee802_11_print(p, h->len, h->caplen, 0, 0);
1403 }
1404
1405 #define IEEE80211_CHAN_FHSS \
1406         (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_GFSK)
1407 #define IEEE80211_CHAN_A \
1408         (IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM)
1409 #define IEEE80211_CHAN_B \
1410         (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_CCK)
1411 #define IEEE80211_CHAN_PUREG \
1412         (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_OFDM)
1413 #define IEEE80211_CHAN_G \
1414         (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_DYN)
1415
1416 #define IS_CHAN_FHSS(flags) \
1417         ((flags & IEEE80211_CHAN_FHSS) == IEEE80211_CHAN_FHSS)
1418 #define IS_CHAN_A(flags) \
1419         ((flags & IEEE80211_CHAN_A) == IEEE80211_CHAN_A)
1420 #define IS_CHAN_B(flags) \
1421         ((flags & IEEE80211_CHAN_B) == IEEE80211_CHAN_B)
1422 #define IS_CHAN_PUREG(flags) \
1423         ((flags & IEEE80211_CHAN_PUREG) == IEEE80211_CHAN_PUREG)
1424 #define IS_CHAN_G(flags) \
1425         ((flags & IEEE80211_CHAN_G) == IEEE80211_CHAN_G)
1426 #define IS_CHAN_ANYG(flags) \
1427         (IS_CHAN_PUREG(flags) || IS_CHAN_G(flags))
1428
1429 static void
1430 print_chaninfo(int freq, int flags)
1431 {
1432         printf("%u MHz", freq);
1433         if (IS_CHAN_FHSS(flags))
1434                 printf(" FHSS");
1435         if (IS_CHAN_A(flags)) {
1436                 if (flags & IEEE80211_CHAN_HALF)
1437                         printf(" 11a/10Mhz");
1438                 else if (flags & IEEE80211_CHAN_QUARTER)
1439                         printf(" 11a/5Mhz");
1440                 else
1441                         printf(" 11a");
1442         }
1443         if (IS_CHAN_ANYG(flags)) {
1444                 if (flags & IEEE80211_CHAN_HALF)
1445                         printf(" 11g/10Mhz");
1446                 else if (flags & IEEE80211_CHAN_QUARTER)
1447                         printf(" 11g/5Mhz");
1448                 else
1449                         printf(" 11g");
1450         } else if (IS_CHAN_B(flags))
1451                 printf(" 11b");
1452         if (flags & IEEE80211_CHAN_TURBO)
1453                 printf(" Turbo");
1454         if (flags & IEEE80211_CHAN_HT20)
1455                 printf(" ht/20");
1456         else if (flags & IEEE80211_CHAN_HT40D)
1457                 printf(" ht/40-");
1458         else if (flags & IEEE80211_CHAN_HT40U)
1459                 printf(" ht/40+");
1460         printf(" ");
1461 }
1462
1463 static int
1464 print_radiotap_field(struct cpack_state *s, u_int32_t bit, u_int8_t *flags)
1465 {
1466         union {
1467                 int8_t          i8;
1468                 u_int8_t        u8;
1469                 int16_t         i16;
1470                 u_int16_t       u16;
1471                 u_int32_t       u32;
1472                 u_int64_t       u64;
1473         } u, u2, u3, u4;
1474         int rc;
1475
1476         switch (bit) {
1477         case IEEE80211_RADIOTAP_FLAGS:
1478                 rc = cpack_uint8(s, &u.u8);
1479                 *flags = u.u8;
1480                 break;
1481         case IEEE80211_RADIOTAP_RATE:
1482         case IEEE80211_RADIOTAP_DB_ANTSIGNAL:
1483         case IEEE80211_RADIOTAP_DB_ANTNOISE:
1484         case IEEE80211_RADIOTAP_ANTENNA:
1485                 rc = cpack_uint8(s, &u.u8);
1486                 break;
1487         case IEEE80211_RADIOTAP_DBM_ANTSIGNAL:
1488         case IEEE80211_RADIOTAP_DBM_ANTNOISE:
1489                 rc = cpack_int8(s, &u.i8);
1490                 break;
1491         case IEEE80211_RADIOTAP_CHANNEL:
1492                 rc = cpack_uint16(s, &u.u16);
1493                 if (rc != 0)
1494                         break;
1495                 rc = cpack_uint16(s, &u2.u16);
1496                 break;
1497         case IEEE80211_RADIOTAP_FHSS:
1498         case IEEE80211_RADIOTAP_LOCK_QUALITY:
1499         case IEEE80211_RADIOTAP_TX_ATTENUATION:
1500                 rc = cpack_uint16(s, &u.u16);
1501                 break;
1502         case IEEE80211_RADIOTAP_DB_TX_ATTENUATION:
1503                 rc = cpack_uint8(s, &u.u8);
1504                 break;
1505         case IEEE80211_RADIOTAP_DBM_TX_POWER:
1506                 rc = cpack_int8(s, &u.i8);
1507                 break;
1508         case IEEE80211_RADIOTAP_TSFT:
1509                 rc = cpack_uint64(s, &u.u64);
1510                 break;
1511         case IEEE80211_RADIOTAP_XCHANNEL:
1512                 rc = cpack_uint32(s, &u.u32);
1513                 if (rc != 0)
1514                         break;
1515                 rc = cpack_uint16(s, &u2.u16);
1516                 if (rc != 0)
1517                         break;
1518                 rc = cpack_uint8(s, &u3.u8);
1519                 if (rc != 0)
1520                         break;
1521                 rc = cpack_uint8(s, &u4.u8);
1522                 break;
1523         default:
1524                 /* this bit indicates a field whose
1525                  * size we do not know, so we cannot
1526                  * proceed.  Just print the bit number.
1527                  */
1528                 printf("[bit %u] ", bit);
1529                 return -1;
1530         }
1531
1532         if (rc != 0) {
1533                 printf("[|802.11]");
1534                 return rc;
1535         }
1536
1537         switch (bit) {
1538         case IEEE80211_RADIOTAP_CHANNEL:
1539                 print_chaninfo(u.u16, u2.u16);
1540                 break;
1541         case IEEE80211_RADIOTAP_FHSS:
1542                 printf("fhset %d fhpat %d ", u.u16 & 0xff, (u.u16 >> 8) & 0xff);
1543                 break;
1544         case IEEE80211_RADIOTAP_RATE:
1545                 if (u.u8 & 0x80)
1546                         PRINT_HT_RATE("", u.u8, " Mb/s ");
1547                 else
1548                         PRINT_RATE("", u.u8, " Mb/s ");
1549                 break;
1550         case IEEE80211_RADIOTAP_DBM_ANTSIGNAL:
1551                 printf("%ddB signal ", u.i8);
1552                 break;
1553         case IEEE80211_RADIOTAP_DBM_ANTNOISE:
1554                 printf("%ddB noise ", u.i8);
1555                 break;
1556         case IEEE80211_RADIOTAP_DB_ANTSIGNAL:
1557                 printf("%ddB signal ", u.u8);
1558                 break;
1559         case IEEE80211_RADIOTAP_DB_ANTNOISE:
1560                 printf("%ddB noise ", u.u8);
1561                 break;
1562         case IEEE80211_RADIOTAP_LOCK_QUALITY:
1563                 printf("%u sq ", u.u16);
1564                 break;
1565         case IEEE80211_RADIOTAP_TX_ATTENUATION:
1566                 printf("%d tx power ", -(int)u.u16);
1567                 break;
1568         case IEEE80211_RADIOTAP_DB_TX_ATTENUATION:
1569                 printf("%ddB tx power ", -(int)u.u8);
1570                 break;
1571         case IEEE80211_RADIOTAP_DBM_TX_POWER:
1572                 printf("%ddBm tx power ", u.i8);
1573                 break;
1574         case IEEE80211_RADIOTAP_FLAGS:
1575                 if (u.u8 & IEEE80211_RADIOTAP_F_CFP)
1576                         printf("cfp ");
1577                 if (u.u8 & IEEE80211_RADIOTAP_F_SHORTPRE)
1578                         printf("short preamble ");
1579                 if (u.u8 & IEEE80211_RADIOTAP_F_WEP)
1580                         printf("wep ");
1581                 if (u.u8 & IEEE80211_RADIOTAP_F_FRAG)
1582                         printf("fragmented ");
1583                 if (u.u8 & IEEE80211_RADIOTAP_F_BADFCS)
1584                         printf("bad-fcs ");
1585                 break;
1586         case IEEE80211_RADIOTAP_ANTENNA:
1587                 printf("antenna %d ", u.u8);
1588                 break;
1589         case IEEE80211_RADIOTAP_TSFT:
1590                 printf("%" PRIu64 "us tsft ", u.u64);
1591                 break;
1592         case IEEE80211_RADIOTAP_XCHANNEL:
1593                 print_chaninfo(u2.u16, u.u32);
1594                 break;
1595         }
1596         return 0;
1597 }
1598
1599 static u_int
1600 ieee802_11_radio_print(const u_char *p, u_int length, u_int caplen)
1601 {
1602 #define BITNO_32(x) (((x) >> 16) ? 16 + BITNO_16((x) >> 16) : BITNO_16((x)))
1603 #define BITNO_16(x) (((x) >> 8) ? 8 + BITNO_8((x) >> 8) : BITNO_8((x)))
1604 #define BITNO_8(x) (((x) >> 4) ? 4 + BITNO_4((x) >> 4) : BITNO_4((x)))
1605 #define BITNO_4(x) (((x) >> 2) ? 2 + BITNO_2((x) >> 2) : BITNO_2((x)))
1606 #define BITNO_2(x) (((x) & 2) ? 1 : 0)
1607 #define BIT(n)  (1U << n)
1608 #define IS_EXTENDED(__p)        \
1609             (EXTRACT_LE_32BITS(__p) & BIT(IEEE80211_RADIOTAP_EXT)) != 0
1610
1611         struct cpack_state cpacker;
1612         struct ieee80211_radiotap_header *hdr;
1613         u_int32_t present, next_present;
1614         u_int32_t *presentp, *last_presentp;
1615         enum ieee80211_radiotap_type bit;
1616         int bit0;
1617         const u_char *iter;
1618         u_int len;
1619         u_int8_t flags;
1620         int pad;
1621         u_int fcslen;
1622
1623         if (caplen < sizeof(*hdr)) {
1624                 printf("[|802.11]");
1625                 return caplen;
1626         }
1627
1628         hdr = (struct ieee80211_radiotap_header *)p;
1629
1630         len = EXTRACT_LE_16BITS(&hdr->it_len);
1631
1632         if (caplen < len) {
1633                 printf("[|802.11]");
1634                 return caplen;
1635         }
1636         for (last_presentp = &hdr->it_present;
1637              IS_EXTENDED(last_presentp) &&
1638              (u_char*)(last_presentp + 1) <= p + len;
1639              last_presentp++);
1640
1641         /* are there more bitmap extensions than bytes in header? */
1642         if (IS_EXTENDED(last_presentp)) {
1643                 printf("[|802.11]");
1644                 return caplen;
1645         }
1646
1647         iter = (u_char*)(last_presentp + 1);
1648
1649         if (cpack_init(&cpacker, (u_int8_t*)iter, len - (iter - p)) != 0) {
1650                 /* XXX */
1651                 printf("[|802.11]");
1652                 return caplen;
1653         }
1654
1655         /* Assume no flags */
1656         flags = 0;
1657         /* Assume no Atheros padding between 802.11 header and body */
1658         pad = 0;
1659         /* Assume no FCS at end of frame */
1660         fcslen = 0;
1661         for (bit0 = 0, presentp = &hdr->it_present; presentp <= last_presentp;
1662              presentp++, bit0 += 32) {
1663                 for (present = EXTRACT_LE_32BITS(presentp); present;
1664                      present = next_present) {
1665                         /* clear the least significant bit that is set */
1666                         next_present = present & (present - 1);
1667
1668                         /* extract the least significant bit that is set */
1669                         bit = (enum ieee80211_radiotap_type)
1670                             (bit0 + BITNO_32(present ^ next_present));
1671
1672                         if (print_radiotap_field(&cpacker, bit, &flags) != 0)
1673                                 goto out;
1674                 }
1675         }
1676
1677         if (flags & IEEE80211_RADIOTAP_F_DATAPAD)
1678                 pad = 1;        /* Atheros padding */
1679         if (flags & IEEE80211_RADIOTAP_F_FCS)
1680                 fcslen = 4;     /* FCS at end of packet */
1681 out:
1682         return len + ieee802_11_print(p + len, length - len, caplen - len, pad,
1683             fcslen);
1684 #undef BITNO_32
1685 #undef BITNO_16
1686 #undef BITNO_8
1687 #undef BITNO_4
1688 #undef BITNO_2
1689 #undef BIT
1690 }
1691
1692 static u_int
1693 ieee802_11_avs_radio_print(const u_char *p, u_int length, u_int caplen)
1694 {
1695         u_int32_t caphdr_len;
1696
1697         if (caplen < 8) {
1698                 printf("[|802.11]");
1699                 return caplen;
1700         }
1701
1702         caphdr_len = EXTRACT_32BITS(p + 4);
1703         if (caphdr_len < 8) {
1704                 /*
1705                  * Yow!  The capture header length is claimed not
1706                  * to be large enough to include even the version
1707                  * cookie or capture header length!
1708                  */
1709                 printf("[|802.11]");
1710                 return caplen;
1711         }
1712
1713         if (caplen < caphdr_len) {
1714                 printf("[|802.11]");
1715                 return caplen;
1716         }
1717
1718         return caphdr_len + ieee802_11_print(p + caphdr_len,
1719             length - caphdr_len, caplen - caphdr_len, 0, 0);
1720 }
1721
1722 #define PRISM_HDR_LEN           144
1723
1724 #define WLANCAP_MAGIC_COOKIE_BASE 0x80211000
1725 #define WLANCAP_MAGIC_COOKIE_V1 0x80211001
1726 #define WLANCAP_MAGIC_COOKIE_V2 0x80211002
1727
1728 /*
1729  * For DLT_PRISM_HEADER; like DLT_IEEE802_11, but with an extra header,
1730  * containing information such as radio information, which we
1731  * currently ignore.
1732  *
1733  * If, however, the packet begins with WLANCAP_MAGIC_COOKIE_V1 or
1734  * WLANCAP_MAGIC_COOKIE_V2, it's really DLT_IEEE802_11_RADIO_AVS
1735  * (currently, on Linux, there's no ARPHRD_ type for
1736  * DLT_IEEE802_11_RADIO_AVS, as there is a ARPHRD_IEEE80211_PRISM
1737  * for DLT_PRISM_HEADER, so ARPHRD_IEEE80211_PRISM is used for
1738  * the AVS header, and the first 4 bytes of the header are used to
1739  * indicate whether it's a Prism header or an AVS header).
1740  */
1741 u_int
1742 prism_if_print(const struct pcap_pkthdr *h, const u_char *p)
1743 {
1744         u_int caplen = h->caplen;
1745         u_int length = h->len;
1746         u_int32_t msgcode;
1747
1748         if (caplen < 4) {
1749                 printf("[|802.11]");
1750                 return caplen;
1751         }
1752
1753         msgcode = EXTRACT_32BITS(p);
1754         if (msgcode == WLANCAP_MAGIC_COOKIE_V1 ||
1755             msgcode == WLANCAP_MAGIC_COOKIE_V2)
1756                 return ieee802_11_avs_radio_print(p, length, caplen);
1757
1758         if (caplen < PRISM_HDR_LEN) {
1759                 printf("[|802.11]");
1760                 return caplen;
1761         }
1762
1763         return PRISM_HDR_LEN + ieee802_11_print(p + PRISM_HDR_LEN,
1764             length - PRISM_HDR_LEN, caplen - PRISM_HDR_LEN, 0, 0);
1765 }
1766
1767 /*
1768  * For DLT_IEEE802_11_RADIO; like DLT_IEEE802_11, but with an extra
1769  * header, containing information such as radio information.
1770  */
1771 u_int
1772 ieee802_11_radio_if_print(const struct pcap_pkthdr *h, const u_char *p)
1773 {
1774         return ieee802_11_radio_print(p, h->len, h->caplen);
1775 }
1776
1777 /*
1778  * For DLT_IEEE802_11_RADIO_AVS; like DLT_IEEE802_11, but with an
1779  * extra header, containing information such as radio information,
1780  * which we currently ignore.
1781  */
1782 u_int
1783 ieee802_11_radio_avs_if_print(const struct pcap_pkthdr *h, const u_char *p)
1784 {
1785         return ieee802_11_avs_radio_print(p, h->len, h->caplen);
1786 }