]> CyberLeo.Net >> Repos - FreeBSD/releng/7.2.git/blob - contrib/tcpdump/print-802_11.c
Create releng/7.2 from stable/7 in preparation for 7.2-RELEASE.
[FreeBSD/releng/7.2.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.31.2.15 2007/07/22 23:14:14 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 Information field",          /*  10  */
135         "Reassociation denied due to inability to confirm that association exists",       /*  11  */
136         "Association denied due to reason outside the scope of the standard",     /*  12  */
137         "Responding station does not support the specified authentication algorithm ",    /*  13  */
138         "Received an Authentication frame with authentication transaction " \
139                 "sequence number out of expected sequence",       /*  14  */
140         "Authentication rejected because of challenge failure",   /*  15 */
141         "Authentication rejected due to timeout waiting for next frame in sequence",      /*  16 */
142         "Association denied because AP is unable to handle additional associated stations",       /*  17 */
143         "Association denied due to requesting station not supporting all of the " \
144                 "data rates in BSSBasicRateSet parameter",        /*  18 */
145 };
146 #define NUM_STATUSES    (sizeof status_text / sizeof status_text[0])
147
148 static const char *reason_text[] = {
149         "Reserved", /* 0 */
150         "Unspecified reason", /* 1 */
151         "Previous authentication no longer valid",  /* 2 */
152         "Deauthenticated because sending station is leaving (or has left) IBSS or ESS", /* 3 */
153         "Disassociated due to inactivity", /* 4 */
154         "Disassociated because AP is unable to handle all currently associated stations", /* 5 */
155         "Class 2 frame received from nonauthenticated station", /* 6 */
156         "Class 3 frame received from nonassociated station", /* 7 */
157         "Disassociated because sending station is leaving (or has left) BSS", /* 8 */
158         "Station requesting (re)association is not authenticated with responding station", /* 9 */
159 };
160 #define NUM_REASONS     (sizeof reason_text / sizeof reason_text[0])
161
162 static int
163 wep_print(const u_char *p)
164 {
165         u_int32_t iv;
166
167         if (!TTEST2(*p, IEEE802_11_IV_LEN + IEEE802_11_KID_LEN))
168                 return 0;
169         iv = EXTRACT_LE_32BITS(p);
170
171         printf("Data IV:%3x Pad %x KeyID %x", IV_IV(iv), IV_PAD(iv),
172             IV_KEYID(iv));
173
174         return 1;
175 }
176
177 static void
178 parse_elements(struct mgmt_body_t *pbody, const u_char *p, int offset)
179 {
180         /*
181          * We haven't seen any elements yet.
182          */
183         pbody->challenge_status = NOT_PRESENT;
184         pbody->ssid_status = NOT_PRESENT;
185         pbody->rates_status = NOT_PRESENT;
186         pbody->ds_status = NOT_PRESENT;
187         pbody->cf_status = NOT_PRESENT;
188         pbody->tim_status = NOT_PRESENT;
189
190         for (;;) {
191                 if (!TTEST2(*(p + offset), 1))
192                         return;
193                 switch (*(p + offset)) {
194                 case E_SSID:
195                         /* Present, possibly truncated */
196                         pbody->ssid_status = TRUNCATED;
197                         if (!TTEST2(*(p + offset), 2))
198                                 return;
199                         memcpy(&pbody->ssid, p + offset, 2);
200                         offset += 2;
201                         if (pbody->ssid.length != 0) {
202                                 if (pbody->ssid.length >
203                                     sizeof(pbody->ssid.ssid) - 1)
204                                         return;
205                                 if (!TTEST2(*(p + offset), pbody->ssid.length))
206                                         return;
207                                 memcpy(&pbody->ssid.ssid, p + offset,
208                                     pbody->ssid.length);
209                                 offset += pbody->ssid.length;
210                         }
211                         pbody->ssid.ssid[pbody->ssid.length] = '\0';
212                         /* Present and not truncated */
213                         pbody->ssid_status = PRESENT;
214                         break;
215                 case E_CHALLENGE:
216                         /* Present, possibly truncated */
217                         pbody->challenge_status = TRUNCATED;
218                         if (!TTEST2(*(p + offset), 2))
219                                 return;
220                         memcpy(&pbody->challenge, p + offset, 2);
221                         offset += 2;
222                         if (pbody->challenge.length != 0) {
223                                 if (pbody->challenge.length >
224                                     sizeof(pbody->challenge.text) - 1)
225                                         return;
226                                 if (!TTEST2(*(p + offset), pbody->challenge.length))
227                                         return;
228                                 memcpy(&pbody->challenge.text, p + offset,
229                                     pbody->challenge.length);
230                                 offset += pbody->challenge.length;
231                         }
232                         pbody->challenge.text[pbody->challenge.length] = '\0';
233                         /* Present and not truncated */
234                         pbody->challenge_status = PRESENT;
235                         break;
236                 case E_RATES:
237                         /* Present, possibly truncated */
238                         pbody->rates_status = TRUNCATED;
239                         if (!TTEST2(*(p + offset), 2))
240                                 return;
241                         memcpy(&(pbody->rates), p + offset, 2);
242                         offset += 2;
243                         if (pbody->rates.length != 0) {
244                                 if (pbody->rates.length > sizeof pbody->rates.rate)
245                                         return;
246                                 if (!TTEST2(*(p + offset), pbody->rates.length))
247                                         return;
248                                 memcpy(&pbody->rates.rate, p + offset,
249                                     pbody->rates.length);
250                                 offset += pbody->rates.length;
251                         }
252                         /* Present and not truncated */
253                         pbody->rates_status = PRESENT;
254                         break;
255                 case E_DS:
256                         /* Present, possibly truncated */
257                         pbody->ds_status = TRUNCATED;
258                         if (!TTEST2(*(p + offset), 3))
259                                 return;
260                         memcpy(&pbody->ds, p + offset, 3);
261                         offset += 3;
262                         /* Present and not truncated */
263                         pbody->ds_status = PRESENT;
264                         break;
265                 case E_CF:
266                         /* Present, possibly truncated */
267                         pbody->cf_status = TRUNCATED;
268                         if (!TTEST2(*(p + offset), 8))
269                                 return;
270                         memcpy(&pbody->cf, p + offset, 8);
271                         offset += 8;
272                         /* Present and not truncated */
273                         pbody->cf_status = PRESENT;
274                         break;
275                 case E_TIM:
276                         /* Present, possibly truncated */
277                         pbody->tim_status = TRUNCATED;
278                         if (!TTEST2(*(p + offset), 2))
279                                 return;
280                         memcpy(&pbody->tim, p + offset, 2);
281                         offset += 2;
282                         if (!TTEST2(*(p + offset), 3))
283                                 return;
284                         memcpy(&pbody->tim.count, p + offset, 3);
285                         offset += 3;
286
287                         if (pbody->tim.length <= 3)
288                                 break;
289                         if (pbody->tim.length - 3 > sizeof pbody->tim.bitmap)
290                                 return;
291                         if (!TTEST2(*(p + offset), pbody->tim.length - 3))
292                                 return;
293                         memcpy(pbody->tim.bitmap, p + (pbody->tim.length - 3),
294                             (pbody->tim.length - 3));
295                         offset += pbody->tim.length - 3;
296                         /* Present and not truncated */
297                         pbody->tim_status = PRESENT;
298                         break;
299                 default:
300 #if 0
301                         printf("(1) unhandled element_id (%d)  ",
302                             *(p + offset) );
303 #endif
304                         if (!TTEST2(*(p + offset), 2))
305                                 return;
306                         if (!TTEST2(*(p + offset + 2), *(p + offset + 1)))
307                                 return;
308                         offset += *(p + offset + 1) + 2;
309                         break;
310                 }
311         }
312 }
313
314 /*********************************************************************************
315  * Print Handle functions for the management frame types
316  *********************************************************************************/
317
318 static int
319 handle_beacon(const u_char *p)
320 {
321         struct mgmt_body_t pbody;
322         int offset = 0;
323
324         memset(&pbody, 0, sizeof(pbody));
325
326         if (!TTEST2(*p, IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN +
327             IEEE802_11_CAPINFO_LEN))
328                 return 0;
329         memcpy(&pbody.timestamp, p, IEEE802_11_TSTAMP_LEN);
330         offset += IEEE802_11_TSTAMP_LEN;
331         pbody.beacon_interval = EXTRACT_LE_16BITS(p+offset);
332         offset += IEEE802_11_BCNINT_LEN;
333         pbody.capability_info = EXTRACT_LE_16BITS(p+offset);
334         offset += IEEE802_11_CAPINFO_LEN;
335
336         parse_elements(&pbody, p, offset);
337
338         PRINT_SSID(pbody);
339         PRINT_RATES(pbody);
340         printf(" %s",
341             CAPABILITY_ESS(pbody.capability_info) ? "ESS" : "IBSS");
342         PRINT_DS_CHANNEL(pbody);
343
344         return 1;
345 }
346
347 static int
348 handle_assoc_request(const u_char *p)
349 {
350         struct mgmt_body_t pbody;
351         int offset = 0;
352
353         memset(&pbody, 0, sizeof(pbody));
354
355         if (!TTEST2(*p, IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN))
356                 return 0;
357         pbody.capability_info = EXTRACT_LE_16BITS(p);
358         offset += IEEE802_11_CAPINFO_LEN;
359         pbody.listen_interval = EXTRACT_LE_16BITS(p+offset);
360         offset += IEEE802_11_LISTENINT_LEN;
361
362         parse_elements(&pbody, p, offset);
363
364         PRINT_SSID(pbody);
365         PRINT_RATES(pbody);
366         return 1;
367 }
368
369 static int
370 handle_assoc_response(const u_char *p)
371 {
372         struct mgmt_body_t pbody;
373         int offset = 0;
374
375         memset(&pbody, 0, sizeof(pbody));
376
377         if (!TTEST2(*p, IEEE802_11_CAPINFO_LEN + IEEE802_11_STATUS_LEN +
378             IEEE802_11_AID_LEN))
379                 return 0;
380         pbody.capability_info = EXTRACT_LE_16BITS(p);
381         offset += IEEE802_11_CAPINFO_LEN;
382         pbody.status_code = EXTRACT_LE_16BITS(p+offset);
383         offset += IEEE802_11_STATUS_LEN;
384         pbody.aid = EXTRACT_LE_16BITS(p+offset);
385         offset += IEEE802_11_AID_LEN;
386
387         parse_elements(&pbody, p, offset);
388
389         printf(" AID(%x) :%s: %s", ((u_int16_t)(pbody.aid << 2 )) >> 2 ,
390             CAPABILITY_PRIVACY(pbody.capability_info) ? " PRIVACY " : "",
391             (pbody.status_code < NUM_STATUSES
392                 ? status_text[pbody.status_code]
393                 : "n/a"));
394
395         return 1;
396 }
397
398 static int
399 handle_reassoc_request(const u_char *p)
400 {
401         struct mgmt_body_t pbody;
402         int offset = 0;
403
404         memset(&pbody, 0, sizeof(pbody));
405
406         if (!TTEST2(*p, IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN +
407             IEEE802_11_AP_LEN))
408                 return 0;
409         pbody.capability_info = EXTRACT_LE_16BITS(p);
410         offset += IEEE802_11_CAPINFO_LEN;
411         pbody.listen_interval = EXTRACT_LE_16BITS(p+offset);
412         offset += IEEE802_11_LISTENINT_LEN;
413         memcpy(&pbody.ap, p+offset, IEEE802_11_AP_LEN);
414         offset += IEEE802_11_AP_LEN;
415
416         parse_elements(&pbody, p, offset);
417
418         PRINT_SSID(pbody);
419         printf(" AP : %s", etheraddr_string( pbody.ap ));
420
421         return 1;
422 }
423
424 static int
425 handle_reassoc_response(const u_char *p)
426 {
427         /* Same as a Association Reponse */
428         return handle_assoc_response(p);
429 }
430
431 static int
432 handle_probe_request(const u_char *p)
433 {
434         struct mgmt_body_t  pbody;
435         int offset = 0;
436
437         memset(&pbody, 0, sizeof(pbody));
438
439         parse_elements(&pbody, p, offset);
440
441         PRINT_SSID(pbody);
442         PRINT_RATES(pbody);
443
444         return 1;
445 }
446
447 static int
448 handle_probe_response(const u_char *p)
449 {
450         struct mgmt_body_t  pbody;
451         int offset = 0;
452
453         memset(&pbody, 0, sizeof(pbody));
454
455         if (!TTEST2(*p, IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN +
456             IEEE802_11_CAPINFO_LEN))
457                 return 0;
458
459         memcpy(&pbody.timestamp, p, IEEE802_11_TSTAMP_LEN);
460         offset += IEEE802_11_TSTAMP_LEN;
461         pbody.beacon_interval = EXTRACT_LE_16BITS(p+offset);
462         offset += IEEE802_11_BCNINT_LEN;
463         pbody.capability_info = EXTRACT_LE_16BITS(p+offset);
464         offset += IEEE802_11_CAPINFO_LEN;
465
466         parse_elements(&pbody, p, offset);
467
468         PRINT_SSID(pbody);
469         PRINT_RATES(pbody);
470         PRINT_DS_CHANNEL(pbody);
471
472         return 1;
473 }
474
475 static int
476 handle_atim(void)
477 {
478         /* the frame body for ATIM is null. */
479         return 1;
480 }
481
482 static int
483 handle_disassoc(const u_char *p)
484 {
485         struct mgmt_body_t  pbody;
486
487         memset(&pbody, 0, sizeof(pbody));
488
489         if (!TTEST2(*p, IEEE802_11_REASON_LEN))
490                 return 0;
491         pbody.reason_code = EXTRACT_LE_16BITS(p);
492
493         printf(": %s",
494             (pbody.reason_code < NUM_REASONS)
495                 ? reason_text[pbody.reason_code]
496                 : "Reserved" );
497
498         return 1;
499 }
500
501 static int
502 handle_auth(const u_char *p)
503 {
504         struct mgmt_body_t  pbody;
505         int offset = 0;
506
507         memset(&pbody, 0, sizeof(pbody));
508
509         if (!TTEST2(*p, 6))
510                 return 0;
511         pbody.auth_alg = EXTRACT_LE_16BITS(p);
512         offset += 2;
513         pbody.auth_trans_seq_num = EXTRACT_LE_16BITS(p + offset);
514         offset += 2;
515         pbody.status_code = EXTRACT_LE_16BITS(p + offset);
516         offset += 2;
517
518         parse_elements(&pbody, p, offset);
519
520         if ((pbody.auth_alg == 1) &&
521             ((pbody.auth_trans_seq_num == 2) ||
522              (pbody.auth_trans_seq_num == 3))) {
523                 printf(" (%s)-%x [Challenge Text] %s",
524                     (pbody.auth_alg < NUM_AUTH_ALGS)
525                         ? auth_alg_text[pbody.auth_alg]
526                         : "Reserved",
527                     pbody.auth_trans_seq_num,
528                     ((pbody.auth_trans_seq_num % 2)
529                         ? ((pbody.status_code < NUM_STATUSES)
530                                ? status_text[pbody.status_code]
531                                : "n/a") : ""));
532                 return 1;
533         }
534         printf(" (%s)-%x: %s",
535             (pbody.auth_alg < NUM_AUTH_ALGS)
536                 ? auth_alg_text[pbody.auth_alg]
537                 : "Reserved",
538             pbody.auth_trans_seq_num,
539             (pbody.auth_trans_seq_num % 2)
540                 ? ((pbody.status_code < NUM_STATUSES)
541                     ? status_text[pbody.status_code]
542                     : "n/a")
543                 : "");
544
545         return 1;
546 }
547
548 static int
549 handle_deauth(const struct mgmt_header_t *pmh, const u_char *p)
550 {
551         struct mgmt_body_t  pbody;
552         int offset = 0;
553         const char *reason = NULL;
554
555         memset(&pbody, 0, sizeof(pbody));
556
557         if (!TTEST2(*p, IEEE802_11_REASON_LEN))
558                 return 0;
559         pbody.reason_code = EXTRACT_LE_16BITS(p);
560         offset += IEEE802_11_REASON_LEN;
561
562         reason = (pbody.reason_code < NUM_REASONS)
563                         ? reason_text[pbody.reason_code]
564                         : "Reserved";
565
566         if (eflag) {
567                 printf(": %s", reason);
568         } else {
569                 printf(" (%s): %s", etheraddr_string(pmh->sa), reason);
570         }
571         return 1;
572 }
573
574
575 /*********************************************************************************
576  * Print Body funcs
577  *********************************************************************************/
578
579
580 static int
581 mgmt_body_print(u_int16_t fc, const struct mgmt_header_t *pmh,
582     const u_char *p)
583 {
584         switch (FC_SUBTYPE(fc)) {
585         case ST_ASSOC_REQUEST:
586                 printf("Assoc Request");
587                 return handle_assoc_request(p);
588         case ST_ASSOC_RESPONSE:
589                 printf("Assoc Response");
590                 return handle_assoc_response(p);
591         case ST_REASSOC_REQUEST:
592                 printf("ReAssoc Request");
593                 return handle_reassoc_request(p);
594         case ST_REASSOC_RESPONSE:
595                 printf("ReAssoc Response");
596                 return handle_reassoc_response(p);
597         case ST_PROBE_REQUEST:
598                 printf("Probe Request");
599                 return handle_probe_request(p);
600         case ST_PROBE_RESPONSE:
601                 printf("Probe Response");
602                 return handle_probe_response(p);
603         case ST_BEACON:
604                 printf("Beacon");
605                 return handle_beacon(p);
606         case ST_ATIM:
607                 printf("ATIM");
608                 return handle_atim();
609         case ST_DISASSOC:
610                 printf("Disassociation");
611                 return handle_disassoc(p);
612         case ST_AUTH:
613                 printf("Authentication");
614                 if (!TTEST2(*p, 3))
615                         return 0;
616                 if ((p[0] == 0 ) && (p[1] == 0) && (p[2] == 0)) {
617                         printf("Authentication (Shared-Key)-3 ");
618                         return wep_print(p);
619                 }
620                 return handle_auth(p);
621         case ST_DEAUTH:
622                 printf("DeAuthentication");
623                 return handle_deauth(pmh, p);
624                 break;
625         default:
626                 printf("Unhandled Management subtype(%x)",
627                     FC_SUBTYPE(fc));
628                 return 1;
629         }
630 }
631
632
633 /*********************************************************************************
634  * Handles printing all the control frame types
635  *********************************************************************************/
636
637 static int
638 ctrl_body_print(u_int16_t fc, const u_char *p)
639 {
640         switch (FC_SUBTYPE(fc)) {
641         case CTRL_BAR:
642                 printf("BAR");
643                 if (!TTEST2(*p, CTRL_BAR_HDRLEN))
644                         return 0;
645                 if (!eflag)
646                         printf(" RA:%s TA:%s CTL(%x) SEQ(%u) ",
647                             etheraddr_string(((const struct ctrl_bar_t *)p)->ra),
648                             etheraddr_string(((const struct ctrl_bar_t *)p)->ta),
649                             EXTRACT_LE_16BITS(&(((const struct ctrl_bar_t *)p)->ctl)),
650                             EXTRACT_LE_16BITS(&(((const struct ctrl_bar_t *)p)->seq)));
651                 break;
652         case CTRL_PS_POLL:
653                 printf("Power Save-Poll");
654                 if (!TTEST2(*p, CTRL_PS_POLL_HDRLEN))
655                         return 0;
656                 printf(" AID(%x)",
657                     EXTRACT_LE_16BITS(&(((const struct ctrl_ps_poll_t *)p)->aid)));
658                 break;
659         case CTRL_RTS:
660                 printf("Request-To-Send");
661                 if (!TTEST2(*p, CTRL_RTS_HDRLEN))
662                         return 0;
663                 if (!eflag)
664                         printf(" TA:%s ",
665                             etheraddr_string(((const struct ctrl_rts_t *)p)->ta));
666                 break;
667         case CTRL_CTS:
668                 printf("Clear-To-Send");
669                 if (!TTEST2(*p, CTRL_CTS_HDRLEN))
670                         return 0;
671                 if (!eflag)
672                         printf(" RA:%s ",
673                             etheraddr_string(((const struct ctrl_cts_t *)p)->ra));
674                 break;
675         case CTRL_ACK:
676                 printf("Acknowledgment");
677                 if (!TTEST2(*p, CTRL_ACK_HDRLEN))
678                         return 0;
679                 if (!eflag)
680                         printf(" RA:%s ",
681                             etheraddr_string(((const struct ctrl_ack_t *)p)->ra));
682                 break;
683         case CTRL_CF_END:
684                 printf("CF-End");
685                 if (!TTEST2(*p, CTRL_END_HDRLEN))
686                         return 0;
687                 if (!eflag)
688                         printf(" RA:%s ",
689                             etheraddr_string(((const struct ctrl_end_t *)p)->ra));
690                 break;
691         case CTRL_END_ACK:
692                 printf("CF-End+CF-Ack");
693                 if (!TTEST2(*p, CTRL_END_ACK_HDRLEN))
694                         return 0;
695                 if (!eflag)
696                         printf(" RA:%s ",
697                             etheraddr_string(((const struct ctrl_end_ack_t *)p)->ra));
698                 break;
699         default:
700                 printf("Unknown Ctrl Subtype");
701         }
702         return 1;
703 }
704
705 /*
706  * Print Header funcs
707  */
708
709 /*
710  *  Data Frame - Address field contents
711  *
712  *  To Ds  | From DS | Addr 1 | Addr 2 | Addr 3 | Addr 4
713  *    0    |  0      |  DA    | SA     | BSSID  | n/a
714  *    0    |  1      |  DA    | BSSID  | SA     | n/a
715  *    1    |  0      |  BSSID | SA     | DA     | n/a
716  *    1    |  1      |  RA    | TA     | DA     | SA
717  */
718
719 static void
720 data_header_print(u_int16_t fc, const u_char *p, const u_int8_t **srcp,
721     const u_int8_t **dstp)
722 {
723         u_int subtype = FC_SUBTYPE(fc);
724
725         if (DATA_FRAME_IS_CF_ACK(subtype) || DATA_FRAME_IS_CF_POLL(subtype) ||
726             DATA_FRAME_IS_QOS(subtype)) {
727                 printf("CF ");
728                 if (DATA_FRAME_IS_CF_ACK(subtype)) {
729                         if (DATA_FRAME_IS_CF_POLL(subtype))
730                                 printf("Ack/Poll");
731                         else
732                                 printf("Ack");
733                 } else {
734                         if (DATA_FRAME_IS_CF_POLL(subtype))
735                                 printf("Poll");
736                 }
737                 if (DATA_FRAME_IS_QOS(subtype))
738                         printf("+QoS");
739                 printf(" ");
740         }
741
742 #define ADDR1  (p + 4)
743 #define ADDR2  (p + 10)
744 #define ADDR3  (p + 16)
745 #define ADDR4  (p + 24)
746
747         if (!FC_TO_DS(fc) && !FC_FROM_DS(fc)) {
748                 if (srcp != NULL)
749                         *srcp = ADDR2;
750                 if (dstp != NULL)
751                         *dstp = ADDR1;
752                 if (!eflag)
753                         return;
754                 printf("DA:%s SA:%s BSSID:%s ",
755                     etheraddr_string(ADDR1), etheraddr_string(ADDR2),
756                     etheraddr_string(ADDR3));
757         } else if (!FC_TO_DS(fc) && FC_FROM_DS(fc)) {
758                 if (srcp != NULL)
759                         *srcp = ADDR3;
760                 if (dstp != NULL)
761                         *dstp = ADDR1;
762                 if (!eflag)
763                         return;
764                 printf("DA:%s BSSID:%s SA:%s ",
765                     etheraddr_string(ADDR1), etheraddr_string(ADDR2),
766                     etheraddr_string(ADDR3));
767         } else if (FC_TO_DS(fc) && !FC_FROM_DS(fc)) {
768                 if (srcp != NULL)
769                         *srcp = ADDR2;
770                 if (dstp != NULL)
771                         *dstp = ADDR3;
772                 if (!eflag)
773                         return;
774                 printf("BSSID:%s SA:%s DA:%s ",
775                     etheraddr_string(ADDR1), etheraddr_string(ADDR2),
776                     etheraddr_string(ADDR3));
777         } else if (FC_TO_DS(fc) && FC_FROM_DS(fc)) {
778                 if (srcp != NULL)
779                         *srcp = ADDR4;
780                 if (dstp != NULL)
781                         *dstp = ADDR3;
782                 if (!eflag)
783                         return;
784                 printf("RA:%s TA:%s DA:%s SA:%s ",
785                     etheraddr_string(ADDR1), etheraddr_string(ADDR2),
786                     etheraddr_string(ADDR3), etheraddr_string(ADDR4));
787         }
788
789 #undef ADDR1
790 #undef ADDR2
791 #undef ADDR3
792 #undef ADDR4
793 }
794
795 static void
796 mgmt_header_print(const u_char *p, const u_int8_t **srcp,
797     const u_int8_t **dstp)
798 {
799         const struct mgmt_header_t *hp = (const struct mgmt_header_t *) p;
800
801         if (srcp != NULL)
802                 *srcp = hp->sa;
803         if (dstp != NULL)
804                 *dstp = hp->da;
805         if (!eflag)
806                 return;
807
808         printf("BSSID:%s DA:%s SA:%s ",
809             etheraddr_string((hp)->bssid), etheraddr_string((hp)->da),
810             etheraddr_string((hp)->sa));
811 }
812
813 static void
814 ctrl_header_print(u_int16_t fc, const u_char *p, const u_int8_t **srcp,
815     const u_int8_t **dstp)
816 {
817         if (srcp != NULL)
818                 *srcp = NULL;
819         if (dstp != NULL)
820                 *dstp = NULL;
821         if (!eflag)
822                 return;
823
824         switch (FC_SUBTYPE(fc)) {
825         case CTRL_BAR:
826                 printf(" RA:%s TA:%s CTL(%x) SEQ(%u) ",
827                     etheraddr_string(((const struct ctrl_bar_t *)p)->ra),
828                     etheraddr_string(((const struct ctrl_bar_t *)p)->ta),
829                     EXTRACT_LE_16BITS(&(((const struct ctrl_bar_t *)p)->ctl)),
830                     EXTRACT_LE_16BITS(&(((const struct ctrl_bar_t *)p)->seq)));
831                 break;
832         case CTRL_PS_POLL:
833                 printf("BSSID:%s TA:%s ",
834                     etheraddr_string(((const struct ctrl_ps_poll_t *)p)->bssid),
835                     etheraddr_string(((const struct ctrl_ps_poll_t *)p)->ta));
836                 break;
837         case CTRL_RTS:
838                 printf("RA:%s TA:%s ",
839                     etheraddr_string(((const struct ctrl_rts_t *)p)->ra),
840                     etheraddr_string(((const struct ctrl_rts_t *)p)->ta));
841                 break;
842         case CTRL_CTS:
843                 printf("RA:%s ",
844                     etheraddr_string(((const struct ctrl_cts_t *)p)->ra));
845                 break;
846         case CTRL_ACK:
847                 printf("RA:%s ",
848                     etheraddr_string(((const struct ctrl_ack_t *)p)->ra));
849                 break;
850         case CTRL_CF_END:
851                 printf("RA:%s BSSID:%s ",
852                     etheraddr_string(((const struct ctrl_end_t *)p)->ra),
853                     etheraddr_string(((const struct ctrl_end_t *)p)->bssid));
854                 break;
855         case CTRL_END_ACK:
856                 printf("RA:%s BSSID:%s ",
857                     etheraddr_string(((const struct ctrl_end_ack_t *)p)->ra),
858                     etheraddr_string(((const struct ctrl_end_ack_t *)p)->bssid));
859                 break;
860         default:
861                 printf("(H) Unknown Ctrl Subtype");
862                 break;
863         }
864 }
865
866 static int
867 extract_header_length(u_int16_t fc)
868 {
869         int len;
870
871         switch (FC_TYPE(fc)) {
872         case T_MGMT:
873                 return MGMT_HDRLEN;
874         case T_CTRL:
875                 switch (FC_SUBTYPE(fc)) {
876                 case CTRL_BAR:
877                         return CTRL_BAR_HDRLEN;
878                 case CTRL_PS_POLL:
879                         return CTRL_PS_POLL_HDRLEN;
880                 case CTRL_RTS:
881                         return CTRL_RTS_HDRLEN;
882                 case CTRL_CTS:
883                         return CTRL_CTS_HDRLEN;
884                 case CTRL_ACK:
885                         return CTRL_ACK_HDRLEN;
886                 case CTRL_CF_END:
887                         return CTRL_END_HDRLEN;
888                 case CTRL_END_ACK:
889                         return CTRL_END_ACK_HDRLEN;
890                 default:
891                         return 0;
892                 }
893         case T_DATA:
894                 len = (FC_TO_DS(fc) && FC_FROM_DS(fc)) ? 30 : 24;
895                 if (DATA_FRAME_IS_QOS(FC_SUBTYPE(fc)))
896                         len += 2;
897                 return len;
898         default:
899                 printf("unknown IEEE802.11 frame type (%d)", FC_TYPE(fc));
900                 return 0;
901         }
902 }
903
904 /*
905  * Print the 802.11 MAC header if eflag is set, and set "*srcp" and "*dstp"
906  * to point to the source and destination MAC addresses in any case if
907  * "srcp" and "dstp" aren't null.
908  */
909 static inline void
910 ieee_802_11_hdr_print(u_int16_t fc, const u_char *p, const u_int8_t **srcp,
911     const u_int8_t **dstp)
912 {
913         if (vflag) {
914                 if (FC_MORE_DATA(fc))
915                         printf("More Data ");
916                 if (FC_MORE_FLAG(fc))
917                         printf("More Fragments ");
918                 if (FC_POWER_MGMT(fc))
919                         printf("Pwr Mgmt ");
920                 if (FC_RETRY(fc))
921                         printf("Retry ");
922                 if (FC_ORDER(fc))
923                         printf("Strictly Ordered ");
924                 if (FC_WEP(fc))
925                         printf("WEP Encrypted ");
926                 if (FC_TYPE(fc) != T_CTRL || FC_SUBTYPE(fc) != CTRL_PS_POLL)
927                         printf("%dus ",
928                             EXTRACT_LE_16BITS(
929                                 &((const struct mgmt_header_t *)p)->duration));
930         }
931
932         switch (FC_TYPE(fc)) {
933         case T_MGMT:
934                 mgmt_header_print(p, srcp, dstp);
935                 break;
936         case T_CTRL:
937                 ctrl_header_print(fc, p, srcp, dstp);
938                 break;
939         case T_DATA:
940                 data_header_print(fc, p, srcp, dstp);
941                 break;
942         default:
943                 printf("(header) unknown IEEE802.11 frame type (%d)",
944                     FC_TYPE(fc));
945                 *srcp = NULL;
946                 *dstp = NULL;
947                 break;
948         }
949 }
950
951 #ifndef roundup2
952 #define roundup2(x, y)  (((x)+((y)-1))&(~((y)-1))) /* if y is powers of two */
953 #endif
954
955 static u_int
956 ieee802_11_print(const u_char *p, u_int length, u_int caplen, int pad)
957 {
958         u_int16_t fc;
959         u_int hdrlen;
960         const u_int8_t *src, *dst;
961         u_short extracted_ethertype;
962
963         if (caplen < IEEE802_11_FC_LEN) {
964                 printf("[|802.11]");
965                 return caplen;
966         }
967
968         fc = EXTRACT_LE_16BITS(p);
969         hdrlen = extract_header_length(fc);
970         if (pad)
971                 hdrlen = roundup2(hdrlen, 4);
972
973         if (caplen < hdrlen) {
974                 printf("[|802.11]");
975                 return hdrlen;
976         }
977
978         ieee_802_11_hdr_print(fc, p, &src, &dst);
979
980         /*
981          * Go past the 802.11 header.
982          */
983         length -= hdrlen;
984         caplen -= hdrlen;
985         p += hdrlen;
986
987         switch (FC_TYPE(fc)) {
988         case T_MGMT:
989                 if (!mgmt_body_print(fc,
990                     (const struct mgmt_header_t *)(p - hdrlen), p)) {
991                         printf("[|802.11]");
992                         return hdrlen;
993                 }
994                 break;
995         case T_CTRL:
996                 if (!ctrl_body_print(fc, p - hdrlen)) {
997                         printf("[|802.11]");
998                         return hdrlen;
999                 }
1000                 break;
1001         case T_DATA:
1002                 if (DATA_FRAME_IS_NULL(FC_SUBTYPE(fc)))
1003                         return hdrlen;  /* no-data frame */
1004                 /* There may be a problem w/ AP not having this bit set */
1005                 if (FC_WEP(fc)) {
1006                         if (!wep_print(p)) {
1007                                 printf("[|802.11]");
1008                                 return hdrlen;
1009                         }
1010                 } else if (llc_print(p, length, caplen, dst, src,
1011                     &extracted_ethertype) == 0) {
1012                         /*
1013                          * Some kinds of LLC packet we cannot
1014                          * handle intelligently
1015                          */
1016                         if (!eflag)
1017                                 ieee_802_11_hdr_print(fc, p - hdrlen, NULL,
1018                                     NULL);
1019                         if (extracted_ethertype)
1020                                 printf("(LLC %s) ",
1021                                     etherproto_string(
1022                                         htons(extracted_ethertype)));
1023                         if (!suppress_default_print)
1024                                 default_print(p, caplen);
1025                 }
1026                 break;
1027         default:
1028                 printf("unknown 802.11 frame type (%d)", FC_TYPE(fc));
1029                 break;
1030         }
1031
1032         return hdrlen;
1033 }
1034
1035 /*
1036  * This is the top level routine of the printer.  'p' points
1037  * to the 802.11 header of the packet, 'h->ts' is the timestamp,
1038  * 'h->len' is the length of the packet off the wire, and 'h->caplen'
1039  * is the number of bytes actually captured.
1040  */
1041 u_int
1042 ieee802_11_if_print(const struct pcap_pkthdr *h, const u_char *p)
1043 {
1044         return ieee802_11_print(p, h->len, h->caplen, 0);
1045 }
1046
1047 #define IEEE80211_CHAN_FHSS \
1048         (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_GFSK)
1049 #define IEEE80211_CHAN_A \
1050         (IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM)
1051 #define IEEE80211_CHAN_B \
1052         (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_CCK)
1053 #define IEEE80211_CHAN_PUREG \
1054         (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_OFDM)
1055 #define IEEE80211_CHAN_G \
1056         (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_DYN)
1057
1058 #define IS_CHAN_FHSS(flags) \
1059         ((flags & IEEE80211_CHAN_FHSS) == IEEE80211_CHAN_FHSS)
1060 #define IS_CHAN_A(flags) \
1061         ((flags & IEEE80211_CHAN_A) == IEEE80211_CHAN_A)
1062 #define IS_CHAN_B(flags) \
1063         ((flags & IEEE80211_CHAN_B) == IEEE80211_CHAN_B)
1064 #define IS_CHAN_PUREG(flags) \
1065         ((flags & IEEE80211_CHAN_PUREG) == IEEE80211_CHAN_PUREG)
1066 #define IS_CHAN_G(flags) \
1067         ((flags & IEEE80211_CHAN_G) == IEEE80211_CHAN_G)
1068 #define IS_CHAN_ANYG(flags) \
1069         (IS_CHAN_PUREG(flags) || IS_CHAN_G(flags))
1070
1071 static void
1072 print_chaninfo(int freq, int flags)
1073 {
1074         printf("%u MHz", freq);
1075         if (IS_CHAN_FHSS(flags))
1076                 printf(" FHSS");
1077         if (IS_CHAN_A(flags)) {
1078                 if (flags & IEEE80211_CHAN_HALF)
1079                         printf(" 11a/10Mhz");
1080                 else if (flags & IEEE80211_CHAN_QUARTER)
1081                         printf(" 11a/5Mhz");
1082                 else
1083                         printf(" 11a");
1084         }
1085         if (IS_CHAN_ANYG(flags)) {
1086                 if (flags & IEEE80211_CHAN_HALF)
1087                         printf(" 11g/10Mhz");
1088                 else if (flags & IEEE80211_CHAN_QUARTER)
1089                         printf(" 11g/5Mhz");
1090                 else
1091                         printf(" 11g");
1092         } else if (IS_CHAN_B(flags))
1093                 printf(" 11b");
1094         if (flags & IEEE80211_CHAN_TURBO)
1095                 printf(" Turbo");
1096         if (flags & IEEE80211_CHAN_HT20)
1097                 printf(" ht/20");
1098         else if (flags & IEEE80211_CHAN_HT40D)
1099                 printf(" ht/40-");
1100         else if (flags & IEEE80211_CHAN_HT40U)
1101                 printf(" ht/40+");
1102         printf(" ");
1103 }
1104
1105 static int
1106 print_radiotap_field(struct cpack_state *s, u_int32_t bit, int *pad)
1107 {
1108         union {
1109                 int8_t          i8;
1110                 u_int8_t        u8;
1111                 int16_t         i16;
1112                 u_int16_t       u16;
1113                 u_int32_t       u32;
1114                 u_int64_t       u64;
1115         } u, u2, u3, u4;
1116         int rc;
1117
1118         switch (bit) {
1119         case IEEE80211_RADIOTAP_FLAGS:
1120                 rc = cpack_uint8(s, &u.u8);
1121                 if (u.u8 & IEEE80211_RADIOTAP_F_DATAPAD)
1122                         *pad = 1;
1123                 break;
1124         case IEEE80211_RADIOTAP_RATE:
1125         case IEEE80211_RADIOTAP_DB_ANTSIGNAL:
1126         case IEEE80211_RADIOTAP_DB_ANTNOISE:
1127         case IEEE80211_RADIOTAP_ANTENNA:
1128                 rc = cpack_uint8(s, &u.u8);
1129                 break;
1130         case IEEE80211_RADIOTAP_DBM_ANTSIGNAL:
1131         case IEEE80211_RADIOTAP_DBM_ANTNOISE:
1132                 rc = cpack_int8(s, &u.i8);
1133                 break;
1134         case IEEE80211_RADIOTAP_CHANNEL:
1135                 rc = cpack_uint16(s, &u.u16);
1136                 if (rc != 0)
1137                         break;
1138                 rc = cpack_uint16(s, &u2.u16);
1139                 break;
1140         case IEEE80211_RADIOTAP_FHSS:
1141         case IEEE80211_RADIOTAP_LOCK_QUALITY:
1142         case IEEE80211_RADIOTAP_TX_ATTENUATION:
1143                 rc = cpack_uint16(s, &u.u16);
1144                 break;
1145         case IEEE80211_RADIOTAP_DB_TX_ATTENUATION:
1146                 rc = cpack_uint8(s, &u.u8);
1147                 break;
1148         case IEEE80211_RADIOTAP_DBM_TX_POWER:
1149                 rc = cpack_int8(s, &u.i8);
1150                 break;
1151         case IEEE80211_RADIOTAP_TSFT:
1152                 rc = cpack_uint64(s, &u.u64);
1153                 break;
1154         case IEEE80211_RADIOTAP_XCHANNEL:
1155                 rc = cpack_uint32(s, &u.u32);
1156                 if (rc != 0)
1157                         break;
1158                 rc = cpack_uint16(s, &u2.u16);
1159                 if (rc != 0)
1160                         break;
1161                 rc = cpack_uint8(s, &u3.u8);
1162                 if (rc != 0)
1163                         break;
1164                 rc = cpack_uint8(s, &u4.u8);
1165                 break;
1166         default:
1167                 /* this bit indicates a field whose
1168                  * size we do not know, so we cannot
1169                  * proceed.
1170                  */
1171                 printf("[0x%08x] ", bit);
1172                 return -1;
1173         }
1174
1175         if (rc != 0) {
1176                 printf("[|802.11]");
1177                 return rc;
1178         }
1179
1180         switch (bit) {
1181         case IEEE80211_RADIOTAP_CHANNEL:
1182                 print_chaninfo(u.u16, u2.u16);
1183                 break;
1184         case IEEE80211_RADIOTAP_FHSS:
1185                 printf("fhset %d fhpat %d ", u.u16 & 0xff, (u.u16 >> 8) & 0xff);
1186                 break;
1187         case IEEE80211_RADIOTAP_RATE:
1188                 if (u.u8 & 0x80)
1189                         PRINT_HT_RATE("", u.u8, " Mb/s ");
1190                 else
1191                         PRINT_RATE("", u.u8, " Mb/s ");
1192                 break;
1193         case IEEE80211_RADIOTAP_DBM_ANTSIGNAL:
1194                 printf("%ddB signal ", u.i8);
1195                 break;
1196         case IEEE80211_RADIOTAP_DBM_ANTNOISE:
1197                 printf("%ddB noise ", u.i8);
1198                 break;
1199         case IEEE80211_RADIOTAP_DB_ANTSIGNAL:
1200                 printf("%ddB signal ", u.u8);
1201                 break;
1202         case IEEE80211_RADIOTAP_DB_ANTNOISE:
1203                 printf("%ddB noise ", u.u8);
1204                 break;
1205         case IEEE80211_RADIOTAP_LOCK_QUALITY:
1206                 printf("%u sq ", u.u16);
1207                 break;
1208         case IEEE80211_RADIOTAP_TX_ATTENUATION:
1209                 printf("%d tx power ", -(int)u.u16);
1210                 break;
1211         case IEEE80211_RADIOTAP_DB_TX_ATTENUATION:
1212                 printf("%ddB tx power ", -(int)u.u8);
1213                 break;
1214         case IEEE80211_RADIOTAP_DBM_TX_POWER:
1215                 printf("%ddBm tx power ", u.i8);
1216                 break;
1217         case IEEE80211_RADIOTAP_FLAGS:
1218                 if (u.u8 & IEEE80211_RADIOTAP_F_CFP)
1219                         printf("cfp ");
1220                 if (u.u8 & IEEE80211_RADIOTAP_F_SHORTPRE)
1221                         printf("short preamble ");
1222                 if (u.u8 & IEEE80211_RADIOTAP_F_WEP)
1223                         printf("wep ");
1224                 if (u.u8 & IEEE80211_RADIOTAP_F_FRAG)
1225                         printf("fragmented ");
1226                 if (u.u8 & IEEE80211_RADIOTAP_F_BADFCS)
1227                         printf("bad-fcs ");
1228                 break;
1229         case IEEE80211_RADIOTAP_ANTENNA:
1230                 printf("antenna %d ", u.u8);
1231                 break;
1232         case IEEE80211_RADIOTAP_TSFT:
1233                 printf("%" PRIu64 "us tsft ", u.u64);
1234                 break;
1235         case IEEE80211_RADIOTAP_XCHANNEL:
1236                 print_chaninfo(u2.u16, u.u32);
1237                 break;
1238         }
1239         return 0;
1240 }
1241
1242 static u_int
1243 ieee802_11_radio_print(const u_char *p, u_int length, u_int caplen)
1244 {
1245 #define BITNO_32(x) (((x) >> 16) ? 16 + BITNO_16((x) >> 16) : BITNO_16((x)))
1246 #define BITNO_16(x) (((x) >> 8) ? 8 + BITNO_8((x) >> 8) : BITNO_8((x)))
1247 #define BITNO_8(x) (((x) >> 4) ? 4 + BITNO_4((x) >> 4) : BITNO_4((x)))
1248 #define BITNO_4(x) (((x) >> 2) ? 2 + BITNO_2((x) >> 2) : BITNO_2((x)))
1249 #define BITNO_2(x) (((x) & 2) ? 1 : 0)
1250 #define BIT(n)  (1 << n)
1251 #define IS_EXTENDED(__p)        \
1252             (EXTRACT_LE_32BITS(__p) & BIT(IEEE80211_RADIOTAP_EXT)) != 0
1253
1254         struct cpack_state cpacker;
1255         struct ieee80211_radiotap_header *hdr;
1256         u_int32_t present, next_present;
1257         u_int32_t *presentp, *last_presentp;
1258         enum ieee80211_radiotap_type bit;
1259         int bit0;
1260         const u_char *iter;
1261         u_int len;
1262         int pad;
1263
1264         if (caplen < sizeof(*hdr)) {
1265                 printf("[|802.11]");
1266                 return caplen;
1267         }
1268
1269         hdr = (struct ieee80211_radiotap_header *)p;
1270
1271         len = EXTRACT_LE_16BITS(&hdr->it_len);
1272
1273         if (caplen < len) {
1274                 printf("[|802.11]");
1275                 return caplen;
1276         }
1277         for (last_presentp = &hdr->it_present;
1278              IS_EXTENDED(last_presentp) &&
1279              (u_char*)(last_presentp + 1) <= p + len;
1280              last_presentp++);
1281
1282         /* are there more bitmap extensions than bytes in header? */
1283         if (IS_EXTENDED(last_presentp)) {
1284                 printf("[|802.11]");
1285                 return caplen;
1286         }
1287
1288         iter = (u_char*)(last_presentp + 1);
1289
1290         if (cpack_init(&cpacker, (u_int8_t*)iter, len - (iter - p)) != 0) {
1291                 /* XXX */
1292                 printf("[|802.11]");
1293                 return caplen;
1294         }
1295
1296         /* Assume no Atheros padding between 802.11 header and body */
1297         pad = 0;
1298         for (bit0 = 0, presentp = &hdr->it_present; presentp <= last_presentp;
1299              presentp++, bit0 += 32) {
1300                 for (present = EXTRACT_LE_32BITS(presentp); present;
1301                      present = next_present) {
1302                         /* clear the least significant bit that is set */
1303                         next_present = present & (present - 1);
1304
1305                         /* extract the least significant bit that is set */
1306                         bit = (enum ieee80211_radiotap_type)
1307                             (bit0 + BITNO_32(present ^ next_present));
1308
1309                         if (print_radiotap_field(&cpacker, bit, &pad) != 0)
1310                                 goto out;
1311                 }
1312         }
1313 out:
1314         return len + ieee802_11_print(p + len, length - len, caplen - len, pad);
1315 #undef BITNO_32
1316 #undef BITNO_16
1317 #undef BITNO_8
1318 #undef BITNO_4
1319 #undef BITNO_2
1320 #undef BIT
1321 }
1322
1323 static u_int
1324 ieee802_11_avs_radio_print(const u_char *p, u_int length, u_int caplen)
1325 {
1326         u_int32_t caphdr_len;
1327
1328         caphdr_len = EXTRACT_32BITS(p + 4);
1329         if (caphdr_len < 8) {
1330                 /*
1331                  * Yow!  The capture header length is claimed not
1332                  * to be large enough to include even the version
1333                  * cookie or capture header length!
1334                  */
1335                 printf("[|802.11]");
1336                 return caplen;
1337         }
1338
1339         if (caplen < caphdr_len) {
1340                 printf("[|802.11]");
1341                 return caplen;
1342         }
1343
1344         return caphdr_len + ieee802_11_print(p + caphdr_len,
1345             length - caphdr_len, caplen - caphdr_len, 0);
1346 }
1347
1348 #define PRISM_HDR_LEN           144
1349
1350 #define WLANCAP_MAGIC_COOKIE_V1 0x80211001
1351
1352 /*
1353  * For DLT_PRISM_HEADER; like DLT_IEEE802_11, but with an extra header,
1354  * containing information such as radio information, which we
1355  * currently ignore.
1356  *
1357  * If, however, the packet begins with WLANCAP_MAGIC_COOKIE_V1, it's
1358  * really DLT_IEEE802_11_RADIO (currently, on Linux, there's no
1359  * ARPHRD_ type for DLT_IEEE802_11_RADIO, as there is a
1360  * ARPHRD_IEEE80211_PRISM for DLT_PRISM_HEADER, so
1361  * ARPHRD_IEEE80211_PRISM is used for DLT_IEEE802_11_RADIO, and
1362  * the first 4 bytes of the header are used to indicate which it is).
1363  */
1364 u_int
1365 prism_if_print(const struct pcap_pkthdr *h, const u_char *p)
1366 {
1367         u_int caplen = h->caplen;
1368         u_int length = h->len;
1369
1370         if (caplen < 4) {
1371                 printf("[|802.11]");
1372                 return caplen;
1373         }
1374
1375         if (EXTRACT_32BITS(p) == WLANCAP_MAGIC_COOKIE_V1)
1376                 return ieee802_11_avs_radio_print(p, length, caplen);
1377
1378         if (caplen < PRISM_HDR_LEN) {
1379                 printf("[|802.11]");
1380                 return caplen;
1381         }
1382
1383         return PRISM_HDR_LEN + ieee802_11_print(p + PRISM_HDR_LEN,
1384             length - PRISM_HDR_LEN, caplen - PRISM_HDR_LEN, 0);
1385 }
1386
1387 /*
1388  * For DLT_IEEE802_11_RADIO; like DLT_IEEE802_11, but with an extra
1389  * header, containing information such as radio information, which we
1390  * currently ignore.
1391  */
1392 u_int
1393 ieee802_11_radio_if_print(const struct pcap_pkthdr *h, const u_char *p)
1394 {
1395         u_int caplen = h->caplen;
1396         u_int length = h->len;
1397
1398         if (caplen < 8) {
1399                 printf("[|802.11]");
1400                 return caplen;
1401         }
1402
1403         return ieee802_11_radio_print(p, length, caplen);
1404 }