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