3 * Fortress Technologies, Inc. All rights reserved.
4 * Charlie Lenahan (clenahan@fortresstech.com)
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that: (1) source code distributions
8 * retain the above copyright notice and this paragraph in its entirety, (2)
9 * distributions including binary code include the above copyright notice and
10 * this paragraph in its entirety in the documentation or other materials
11 * provided with the distribution, and (3) all advertising materials mentioning
12 * features or use of this software display the following acknowledgement:
13 * ``This product includes software developed by the University of California,
14 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
15 * the University nor the names of its contributors may be used to endorse
16 * or promote products derived from this software without specific prior
18 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
19 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
20 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
24 static const char rcsid[] _U_ =
25 "@(#) $Header: /tcpdump/master/tcpdump/print-802_11.c,v 1.49 2007-12-29 23:25:02 guy Exp $ (LBL)";
32 #include <tcpdump-stdinc.h>
38 #include "interface.h"
39 #include "addrtoname.h"
40 #include "ethertype.h"
46 #include "ieee802_11.h"
47 #include "ieee802_11_radio.h"
49 #define PRINT_SSID(p) \
50 if (p.ssid_present) { \
52 fn_print(p.ssid.ssid, NULL); \
56 #define PRINT_RATE(_sep, _r, _suf) \
57 printf("%s%2.1f%s", _sep, (.5 * ((_r) & 0x7f)), _suf)
58 #define PRINT_RATES(p) \
59 if (p.rates_present) { \
61 const char *sep = " ["; \
62 for (z = 0; z < p.rates.length ; z++) { \
63 PRINT_RATE(sep, p.rates.rate[z], \
64 (p.rates.rate[z] & 0x80 ? "*" : "")); \
67 if (p.rates.length != 0) \
71 #define PRINT_DS_CHANNEL(p) \
73 printf(" CH: %u", p.ds.channel); \
75 CAPABILITY_PRIVACY(p.capability_info) ? ", PRIVACY" : "" );
77 static const int ieee80211_htrates[16] = {
78 13, /* IFM_IEEE80211_MCS0 */
79 26, /* IFM_IEEE80211_MCS1 */
80 39, /* IFM_IEEE80211_MCS2 */
81 52, /* IFM_IEEE80211_MCS3 */
82 78, /* IFM_IEEE80211_MCS4 */
83 104, /* IFM_IEEE80211_MCS5 */
84 117, /* IFM_IEEE80211_MCS6 */
85 130, /* IFM_IEEE80211_MCS7 */
86 26, /* IFM_IEEE80211_MCS8 */
87 52, /* IFM_IEEE80211_MCS9 */
88 78, /* IFM_IEEE80211_MCS10 */
89 104, /* IFM_IEEE80211_MCS11 */
90 156, /* IFM_IEEE80211_MCS12 */
91 208, /* IFM_IEEE80211_MCS13 */
92 234, /* IFM_IEEE80211_MCS14 */
93 260, /* IFM_IEEE80211_MCS15 */
95 #define PRINT_HT_RATE(_sep, _r, _suf) \
96 printf("%s%.1f%s", _sep, (.5 * ieee80211_htrates[(_r) & 0xf]), _suf)
98 static const char *auth_alg_text[]={"Open System","Shared Key","EAP"};
99 #define NUM_AUTH_ALGS (sizeof auth_alg_text / sizeof auth_alg_text[0])
101 static const char *status_text[] = {
103 "Unspecified failure", /* 1 */
112 "Cannot Support all requested capabilities in the Capability "
113 "Information field", /* 10 */
114 "Reassociation denied due to inability to confirm that association "
116 "Association denied due to reason outside the scope of the "
118 "Responding station does not support the specified authentication "
119 "algorithm ", /* 13 */
120 "Received an Authentication frame with authentication transaction "
121 "sequence number out of expected sequence", /* 14 */
122 "Authentication rejected because of challenge failure", /* 15 */
123 "Authentication rejected due to timeout waiting for next frame in "
125 "Association denied because AP is unable to handle additional"
126 "associated stations", /* 17 */
127 "Association denied due to requesting station not supporting all of "
128 "the data rates in BSSBasicRateSet parameter", /* 18 */
129 "Association denied due to requesting station not supporting "
130 "short preamble operation", /* 19 */
131 "Association denied due to requesting station not supporting "
132 "PBCC encoding", /* 20 */
133 "Association denied due to requesting station not supporting "
134 "channel agility", /* 21 */
135 "Association request rejected because Spectrum Management "
136 "capability is required", /* 22 */
137 "Association request rejected because the information in the "
138 "Power Capability element is unacceptable", /* 23 */
139 "Association request rejected because the information in the "
140 "Supported Channels element is unacceptable", /* 24 */
141 "Association denied due to requesting station not supporting "
142 "short slot operation", /* 25 */
143 "Association denied due to requesting station not supporting "
144 "DSSS-OFDM operation", /* 26 */
145 "Association denied because the requested STA does not support HT "
148 "Association denied because the requested STA does not support "
149 "the PCO transition time required by the AP", /* 29 */
152 "Unspecified, QoS-related failure", /* 32 */
153 "Association denied due to QAP having insufficient bandwidth "
154 "to handle another QSTA", /* 33 */
155 "Association denied due to excessive frame loss rates and/or "
156 "poor conditions on current operating channel", /* 34 */
157 "Association (with QBSS) denied due to requesting station not "
158 "supporting the QoS facility", /* 35 */
159 "Association denied due to requesting station not supporting "
160 "Block Ack", /* 36 */
161 "The request has been declined", /* 37 */
162 "The request has not been successful as one or more parameters "
163 "have invalid values", /* 38 */
164 "The TS has not been created because the request cannot be honored. "
165 "However, a suggested TSPEC is provided so that the initiating QSTA"
166 "may attempt to set another TS with the suggested changes to the "
168 "Invalid Information Element", /* 40 */
169 "Group Cipher is not valid", /* 41 */
170 "Pairwise Cipher is not valid", /* 42 */
171 "AKMP is not valid", /* 43 */
172 "Unsupported RSN IE version", /* 44 */
173 "Invalid RSN IE Capabilities", /* 45 */
174 "Cipher suite is rejected per security policy", /* 46 */
175 "The TS has not been created. However, the HC may be capable of "
176 "creating a TS, in response to a request, after the time indicated "
177 "in the TS Delay element", /* 47 */
178 "Direct Link is not allowed in the BSS by policy", /* 48 */
179 "Destination STA is not present within this QBSS.", /* 49 */
180 "The Destination STA is not a QSTA.", /* 50 */
183 #define NUM_STATUSES (sizeof status_text / sizeof status_text[0])
185 static const char *reason_text[] = {
187 "Unspecified reason", /* 1 */
188 "Previous authentication no longer valid", /* 2 */
189 "Deauthenticated because sending station is leaving (or has left) "
190 "IBSS or ESS", /* 3 */
191 "Disassociated due to inactivity", /* 4 */
192 "Disassociated because AP is unable to handle all currently "
193 " associated stations", /* 5 */
194 "Class 2 frame received from nonauthenticated station", /* 6 */
195 "Class 3 frame received from nonassociated station", /* 7 */
196 "Disassociated because sending station is leaving "
197 "(or has left) BSS", /* 8 */
198 "Station requesting (re)association is not authenticated with "
199 "responding station", /* 9 */
200 "Disassociated because the information in the Power Capability "
201 "element is unacceptable", /* 10 */
202 "Disassociated because the information in the SupportedChannels "
203 "element is unacceptable", /* 11 */
204 "Invalid Information Element", /* 12 */
206 "Michael MIC failure", /* 14 */
207 "4-Way Handshake timeout", /* 15 */
208 "Group key update timeout", /* 16 */
209 "Information element in 4-Way Handshake different from (Re)Association"
210 "Request/Probe Response/Beacon", /* 17 */
211 "Group Cipher is not valid", /* 18 */
212 "AKMP is not valid", /* 20 */
213 "Unsupported RSN IE version", /* 21 */
214 "Invalid RSN IE Capabilities", /* 22 */
215 "IEEE 802.1X Authentication failed", /* 23 */
216 "Cipher suite is rejected per security policy", /* 24 */
223 "TS deleted because QoS AP lacks sufficient bandwidth for this "
224 "QoS STA due to a change in BSS service characteristics or "
225 "operational mode (e.g. an HT BSS change from 40 MHz channel "
226 "to 20 MHz channel)", /* 31 */
227 "Disassociated for unspecified, QoS-related reason", /* 32 */
228 "Disassociated because QoS AP lacks sufficient bandwidth for this "
230 "Disassociated because of excessive number of frames that need to be "
231 "acknowledged, but are not acknowledged for AP transmissions "
232 "and/or poor channel conditions", /* 34 */
233 "Disassociated because STA is transmitting outside the limits "
234 "of its TXOPs", /* 35 */
235 "Requested from peer STA as the STA is leaving the BSS "
236 "(or resetting)", /* 36 */
237 "Requested from peer STA as it does not want to use the "
238 "mechanism", /* 37 */
239 "Requested from peer STA as the STA received frames using the "
240 "mechanism for which a set up is required", /* 38 */
241 "Requested from peer STA due to time out", /* 39 */
247 "Peer STA does not support the requested cipher suite", /* 45 */
248 "Association denied due to requesting STA not supporting HT "
251 #define NUM_REASONS (sizeof reason_text / sizeof reason_text[0])
254 wep_print(const u_char *p)
258 if (!TTEST2(*p, IEEE802_11_IV_LEN + IEEE802_11_KID_LEN))
260 iv = EXTRACT_LE_32BITS(p);
262 printf("Data IV:%3x Pad %x KeyID %x", IV_IV(iv), IV_PAD(iv),
269 parse_elements(struct mgmt_body_t *pbody, const u_char *p, int offset,
273 struct challenge_t challenge;
274 struct rates_t rates;
280 * We haven't seen any elements yet.
282 pbody->challenge_present = 0;
283 pbody->ssid_present = 0;
284 pbody->rates_present = 0;
285 pbody->ds_present = 0;
286 pbody->cf_present = 0;
287 pbody->tim_present = 0;
289 while (length != 0) {
290 if (!TTEST2(*(p + offset), 1))
294 switch (*(p + offset)) {
296 if (!TTEST2(*(p + offset), 2))
300 memcpy(&ssid, p + offset, 2);
303 if (ssid.length != 0) {
304 if (ssid.length > sizeof(ssid.ssid) - 1)
306 if (!TTEST2(*(p + offset), ssid.length))
308 if (length < ssid.length)
310 memcpy(&ssid.ssid, p + offset, ssid.length);
311 offset += ssid.length;
312 length -= ssid.length;
314 ssid.ssid[ssid.length] = '\0';
316 * Present and not truncated.
318 * If we haven't already seen an SSID IE,
319 * copy this one, otherwise ignore this one,
320 * so we later report the first one we saw.
322 if (!pbody->ssid_present) {
324 pbody->ssid_present = 1;
328 if (!TTEST2(*(p + offset), 2))
332 memcpy(&challenge, p + offset, 2);
335 if (challenge.length != 0) {
336 if (challenge.length >
337 sizeof(challenge.text) - 1)
339 if (!TTEST2(*(p + offset), challenge.length))
341 if (length < challenge.length)
343 memcpy(&challenge.text, p + offset,
345 offset += challenge.length;
346 length -= challenge.length;
348 challenge.text[challenge.length] = '\0';
350 * Present and not truncated.
352 * If we haven't already seen a challenge IE,
353 * copy this one, otherwise ignore this one,
354 * so we later report the first one we saw.
356 if (!pbody->challenge_present) {
357 pbody->challenge = challenge;
358 pbody->challenge_present = 1;
362 if (!TTEST2(*(p + offset), 2))
366 memcpy(&rates, p + offset, 2);
369 if (rates.length != 0) {
370 if (rates.length > sizeof rates.rate)
372 if (!TTEST2(*(p + offset), rates.length))
374 if (length < rates.length)
376 memcpy(&rates.rate, p + offset, rates.length);
377 offset += rates.length;
378 length -= rates.length;
381 * Present and not truncated.
383 * If we haven't already seen a rates IE,
384 * copy this one if it's not zero-length,
385 * otherwise ignore this one, so we later
386 * report the first one we saw.
388 * We ignore zero-length rates IEs as some
389 * devices seem to put a zero-length rates
390 * IE, followed by an SSID IE, followed by
391 * a non-zero-length rates IE into frames,
392 * even though IEEE Std 802.11-2007 doesn't
393 * seem to indicate that a zero-length rates
396 if (!pbody->rates_present && rates.length != 0) {
397 pbody->rates = rates;
398 pbody->rates_present = 1;
402 if (!TTEST2(*(p + offset), 3))
406 memcpy(&ds, p + offset, 3);
410 * Present and not truncated.
412 * If we haven't already seen a DS IE,
413 * copy this one, otherwise ignore this one,
414 * so we later report the first one we saw.
416 if (!pbody->ds_present) {
418 pbody->ds_present = 1;
422 if (!TTEST2(*(p + offset), 8))
426 memcpy(&cf, p + offset, 8);
430 * Present and not truncated.
432 * If we haven't already seen a CF IE,
433 * copy this one, otherwise ignore this one,
434 * so we later report the first one we saw.
436 if (!pbody->cf_present) {
438 pbody->cf_present = 1;
442 if (!TTEST2(*(p + offset), 2))
446 memcpy(&tim, p + offset, 2);
449 if (!TTEST2(*(p + offset), 3))
453 memcpy(&tim.count, p + offset, 3);
459 if (tim.length - 3 > (int)sizeof tim.bitmap)
461 if (!TTEST2(*(p + offset), tim.length - 3))
463 if (length < (u_int)(tim.length - 3))
465 memcpy(tim.bitmap, p + (tim.length - 3),
467 offset += tim.length - 3;
468 length -= tim.length - 3;
470 * Present and not truncated.
472 * If we haven't already seen a TIM IE,
473 * copy this one, otherwise ignore this one,
474 * so we later report the first one we saw.
476 if (!pbody->tim_present) {
478 pbody->tim_present = 1;
483 printf("(1) unhandled element_id (%d) ",
486 if (!TTEST2(*(p + offset), 2))
490 if (!TTEST2(*(p + offset + 2), *(p + offset + 1)))
492 if (length < (u_int)(*(p + offset + 1) + 2))
494 offset += *(p + offset + 1) + 2;
495 length -= *(p + offset + 1) + 2;
500 /* No problems found. */
504 /*********************************************************************************
505 * Print Handle functions for the management frame types
506 *********************************************************************************/
509 handle_beacon(const u_char *p, u_int length)
511 struct mgmt_body_t pbody;
515 memset(&pbody, 0, sizeof(pbody));
517 if (!TTEST2(*p, IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN +
518 IEEE802_11_CAPINFO_LEN))
520 if (length < IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN +
521 IEEE802_11_CAPINFO_LEN)
523 memcpy(&pbody.timestamp, p, IEEE802_11_TSTAMP_LEN);
524 offset += IEEE802_11_TSTAMP_LEN;
525 length -= IEEE802_11_TSTAMP_LEN;
526 pbody.beacon_interval = EXTRACT_LE_16BITS(p+offset);
527 offset += IEEE802_11_BCNINT_LEN;
528 length -= IEEE802_11_BCNINT_LEN;
529 pbody.capability_info = EXTRACT_LE_16BITS(p+offset);
530 offset += IEEE802_11_CAPINFO_LEN;
531 length -= IEEE802_11_CAPINFO_LEN;
533 ret = parse_elements(&pbody, p, offset, length);
538 CAPABILITY_ESS(pbody.capability_info) ? "ESS" : "IBSS");
539 PRINT_DS_CHANNEL(pbody);
545 handle_assoc_request(const u_char *p, u_int length)
547 struct mgmt_body_t pbody;
551 memset(&pbody, 0, sizeof(pbody));
553 if (!TTEST2(*p, IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN))
555 if (length < IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN)
557 pbody.capability_info = EXTRACT_LE_16BITS(p);
558 offset += IEEE802_11_CAPINFO_LEN;
559 length -= IEEE802_11_CAPINFO_LEN;
560 pbody.listen_interval = EXTRACT_LE_16BITS(p+offset);
561 offset += IEEE802_11_LISTENINT_LEN;
562 length -= IEEE802_11_LISTENINT_LEN;
564 ret = parse_elements(&pbody, p, offset, length);
572 handle_assoc_response(const u_char *p, u_int length)
574 struct mgmt_body_t pbody;
578 memset(&pbody, 0, sizeof(pbody));
580 if (!TTEST2(*p, IEEE802_11_CAPINFO_LEN + IEEE802_11_STATUS_LEN +
583 if (length < IEEE802_11_CAPINFO_LEN + IEEE802_11_STATUS_LEN +
586 pbody.capability_info = EXTRACT_LE_16BITS(p);
587 offset += IEEE802_11_CAPINFO_LEN;
588 length -= IEEE802_11_CAPINFO_LEN;
589 pbody.status_code = EXTRACT_LE_16BITS(p+offset);
590 offset += IEEE802_11_STATUS_LEN;
591 length -= IEEE802_11_STATUS_LEN;
592 pbody.aid = EXTRACT_LE_16BITS(p+offset);
593 offset += IEEE802_11_AID_LEN;
594 length -= IEEE802_11_AID_LEN;
596 ret = parse_elements(&pbody, p, offset, length);
598 printf(" AID(%x) :%s: %s", ((u_int16_t)(pbody.aid << 2 )) >> 2 ,
599 CAPABILITY_PRIVACY(pbody.capability_info) ? " PRIVACY " : "",
600 (pbody.status_code < NUM_STATUSES
601 ? status_text[pbody.status_code]
608 handle_reassoc_request(const u_char *p, u_int length)
610 struct mgmt_body_t pbody;
614 memset(&pbody, 0, sizeof(pbody));
616 if (!TTEST2(*p, IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN +
619 if (length < IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN +
622 pbody.capability_info = EXTRACT_LE_16BITS(p);
623 offset += IEEE802_11_CAPINFO_LEN;
624 length -= IEEE802_11_CAPINFO_LEN;
625 pbody.listen_interval = EXTRACT_LE_16BITS(p+offset);
626 offset += IEEE802_11_LISTENINT_LEN;
627 length -= IEEE802_11_LISTENINT_LEN;
628 memcpy(&pbody.ap, p+offset, IEEE802_11_AP_LEN);
629 offset += IEEE802_11_AP_LEN;
630 length -= IEEE802_11_AP_LEN;
632 ret = parse_elements(&pbody, p, offset, length);
635 printf(" AP : %s", etheraddr_string( pbody.ap ));
641 handle_reassoc_response(const u_char *p, u_int length)
643 /* Same as a Association Reponse */
644 return handle_assoc_response(p, length);
648 handle_probe_request(const u_char *p, u_int length)
650 struct mgmt_body_t pbody;
654 memset(&pbody, 0, sizeof(pbody));
656 ret = parse_elements(&pbody, p, offset, length);
665 handle_probe_response(const u_char *p, u_int length)
667 struct mgmt_body_t pbody;
671 memset(&pbody, 0, sizeof(pbody));
673 if (!TTEST2(*p, IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN +
674 IEEE802_11_CAPINFO_LEN))
676 if (length < IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN +
677 IEEE802_11_CAPINFO_LEN)
679 memcpy(&pbody.timestamp, p, IEEE802_11_TSTAMP_LEN);
680 offset += IEEE802_11_TSTAMP_LEN;
681 length -= IEEE802_11_TSTAMP_LEN;
682 pbody.beacon_interval = EXTRACT_LE_16BITS(p+offset);
683 offset += IEEE802_11_BCNINT_LEN;
684 length -= IEEE802_11_BCNINT_LEN;
685 pbody.capability_info = EXTRACT_LE_16BITS(p+offset);
686 offset += IEEE802_11_CAPINFO_LEN;
687 length -= IEEE802_11_CAPINFO_LEN;
689 ret = parse_elements(&pbody, p, offset, length);
693 PRINT_DS_CHANNEL(pbody);
701 /* the frame body for ATIM is null. */
706 handle_disassoc(const u_char *p, u_int length)
708 struct mgmt_body_t pbody;
710 memset(&pbody, 0, sizeof(pbody));
712 if (!TTEST2(*p, IEEE802_11_REASON_LEN))
714 if (length < IEEE802_11_REASON_LEN)
716 pbody.reason_code = EXTRACT_LE_16BITS(p);
719 (pbody.reason_code < NUM_REASONS)
720 ? reason_text[pbody.reason_code]
727 handle_auth(const u_char *p, u_int length)
729 struct mgmt_body_t pbody;
733 memset(&pbody, 0, sizeof(pbody));
739 pbody.auth_alg = EXTRACT_LE_16BITS(p);
742 pbody.auth_trans_seq_num = EXTRACT_LE_16BITS(p + offset);
745 pbody.status_code = EXTRACT_LE_16BITS(p + offset);
749 ret = parse_elements(&pbody, p, offset, length);
751 if ((pbody.auth_alg == 1) &&
752 ((pbody.auth_trans_seq_num == 2) ||
753 (pbody.auth_trans_seq_num == 3))) {
754 printf(" (%s)-%x [Challenge Text] %s",
755 (pbody.auth_alg < NUM_AUTH_ALGS)
756 ? auth_alg_text[pbody.auth_alg]
758 pbody.auth_trans_seq_num,
759 ((pbody.auth_trans_seq_num % 2)
760 ? ((pbody.status_code < NUM_STATUSES)
761 ? status_text[pbody.status_code]
765 printf(" (%s)-%x: %s",
766 (pbody.auth_alg < NUM_AUTH_ALGS)
767 ? auth_alg_text[pbody.auth_alg]
769 pbody.auth_trans_seq_num,
770 (pbody.auth_trans_seq_num % 2)
771 ? ((pbody.status_code < NUM_STATUSES)
772 ? status_text[pbody.status_code]
780 handle_deauth(const struct mgmt_header_t *pmh, const u_char *p, u_int length)
782 struct mgmt_body_t pbody;
784 const char *reason = NULL;
786 memset(&pbody, 0, sizeof(pbody));
788 if (!TTEST2(*p, IEEE802_11_REASON_LEN))
790 if (length < IEEE802_11_REASON_LEN)
792 pbody.reason_code = EXTRACT_LE_16BITS(p);
793 offset += IEEE802_11_REASON_LEN;
794 length -= IEEE802_11_REASON_LEN;
796 reason = (pbody.reason_code < NUM_REASONS)
797 ? reason_text[pbody.reason_code]
801 printf(": %s", reason);
803 printf(" (%s): %s", etheraddr_string(pmh->sa), reason);
808 #define PRINT_HT_ACTION(v) (\
809 (v) == 0 ? printf("TxChWidth") : \
810 (v) == 1 ? printf("MIMOPwrSave") : \
811 printf("Act#%d", (v)) \
813 #define PRINT_BA_ACTION(v) (\
814 (v) == 0 ? printf("ADDBA Request") : \
815 (v) == 1 ? printf("ADDBA Response") : \
816 (v) == 2 ? printf("DELBA") : \
817 printf("Act#%d", (v)) \
819 #define PRINT_MESHLINK_ACTION(v) (\
820 (v) == 0 ? printf("Request") : \
821 (v) == 1 ? printf("Report") : \
822 printf("Act#%d", (v)) \
824 #define PRINT_MESHPEERING_ACTION(v) (\
825 (v) == 0 ? printf("Open") : \
826 (v) == 1 ? printf("Confirm") : \
827 (v) == 2 ? printf("Close") : \
828 printf("Act#%d", (v)) \
830 #define PRINT_MESHPATH_ACTION(v) (\
831 (v) == 0 ? printf("Request") : \
832 (v) == 1 ? printf("Report") : \
833 (v) == 2 ? printf("Error") : \
834 (v) == 3 ? printf("RootAnnouncement") : \
835 printf("Act#%d", (v)) \
839 handle_action(const struct mgmt_header_t *pmh, const u_char *p, u_int length)
848 printf(" (%s): ", etheraddr_string(pmh->sa));
851 case 0: printf("Spectrum Management Act#%d", p[1]); break;
852 case 1: printf("QoS Act#%d", p[1]); break;
853 case 2: printf("DLS Act#%d", p[1]); break;
854 case 3: printf("BA "); PRINT_BA_ACTION(p[1]); break;
855 case 7: printf("HT "); PRINT_HT_ACTION(p[1]); break;
856 case 13: printf("MeshLMetric "); PRINT_MESHLINK_ACTION(p[1]); break;
857 case 15: printf("Interwork Act#%d", p[1]); break;
858 case 16: printf("Resource Act#%d", p[1]); break;
859 case 17: printf("Proxy Act#%d", p[1]); break;
860 case 30: printf("MeshPeering "); PRINT_MESHPEERING_ACTION(p[1]); break;
861 case 32: printf("MeshPath "); PRINT_MESHPATH_ACTION(p[1]); break;
862 case 127: printf("Vendor Act#%d", p[1]); break;
864 printf("Reserved(%d) Act#%d", p[0], p[1]);
871 /*********************************************************************************
873 *********************************************************************************/
877 mgmt_body_print(u_int16_t fc, const struct mgmt_header_t *pmh,
878 const u_char *p, u_int length)
880 switch (FC_SUBTYPE(fc)) {
881 case ST_ASSOC_REQUEST:
882 printf("Assoc Request");
883 return handle_assoc_request(p, length);
884 case ST_ASSOC_RESPONSE:
885 printf("Assoc Response");
886 return handle_assoc_response(p, length);
887 case ST_REASSOC_REQUEST:
888 printf("ReAssoc Request");
889 return handle_reassoc_request(p, length);
890 case ST_REASSOC_RESPONSE:
891 printf("ReAssoc Response");
892 return handle_reassoc_response(p, length);
893 case ST_PROBE_REQUEST:
894 printf("Probe Request");
895 return handle_probe_request(p, length);
896 case ST_PROBE_RESPONSE:
897 printf("Probe Response");
898 return handle_probe_response(p, length);
901 return handle_beacon(p, length);
904 return handle_atim();
906 printf("Disassociation");
907 return handle_disassoc(p, length);
909 printf("Authentication");
912 if ((p[0] == 0 ) && (p[1] == 0) && (p[2] == 0)) {
913 printf("Authentication (Shared-Key)-3 ");
916 return handle_auth(p, length);
918 printf("DeAuthentication");
919 return handle_deauth(pmh, p, length);
923 return handle_action(pmh, p, length);
926 printf("Unhandled Management subtype(%x)",
933 /*********************************************************************************
934 * Handles printing all the control frame types
935 *********************************************************************************/
938 ctrl_body_print(u_int16_t fc, const u_char *p)
940 switch (FC_SUBTYPE(fc)) {
941 case CTRL_CONTROL_WRAPPER:
942 printf("Control Wrapper");
943 /* XXX - requires special handling */
947 if (!TTEST2(*p, CTRL_BAR_HDRLEN))
950 printf(" RA:%s TA:%s CTL(%x) SEQ(%u) ",
951 etheraddr_string(((const struct ctrl_bar_t *)p)->ra),
952 etheraddr_string(((const struct ctrl_bar_t *)p)->ta),
953 EXTRACT_LE_16BITS(&(((const struct ctrl_bar_t *)p)->ctl)),
954 EXTRACT_LE_16BITS(&(((const struct ctrl_bar_t *)p)->seq)));
958 if (!TTEST2(*p, CTRL_BA_HDRLEN))
962 etheraddr_string(((const struct ctrl_ba_t *)p)->ra));
965 printf("Power Save-Poll");
966 if (!TTEST2(*p, CTRL_PS_POLL_HDRLEN))
969 EXTRACT_LE_16BITS(&(((const struct ctrl_ps_poll_t *)p)->aid)));
972 printf("Request-To-Send");
973 if (!TTEST2(*p, CTRL_RTS_HDRLEN))
977 etheraddr_string(((const struct ctrl_rts_t *)p)->ta));
980 printf("Clear-To-Send");
981 if (!TTEST2(*p, CTRL_CTS_HDRLEN))
985 etheraddr_string(((const struct ctrl_cts_t *)p)->ra));
988 printf("Acknowledgment");
989 if (!TTEST2(*p, CTRL_ACK_HDRLEN))
993 etheraddr_string(((const struct ctrl_ack_t *)p)->ra));
997 if (!TTEST2(*p, CTRL_END_HDRLEN))
1001 etheraddr_string(((const struct ctrl_end_t *)p)->ra));
1004 printf("CF-End+CF-Ack");
1005 if (!TTEST2(*p, CTRL_END_ACK_HDRLEN))
1009 etheraddr_string(((const struct ctrl_end_ack_t *)p)->ra));
1012 printf("Unknown Ctrl Subtype");
1018 * Print Header funcs
1022 * Data Frame - Address field contents
1024 * To Ds | From DS | Addr 1 | Addr 2 | Addr 3 | Addr 4
1025 * 0 | 0 | DA | SA | BSSID | n/a
1026 * 0 | 1 | DA | BSSID | SA | n/a
1027 * 1 | 0 | BSSID | SA | DA | n/a
1028 * 1 | 1 | RA | TA | DA | SA
1032 data_header_print(u_int16_t fc, const u_char *p, const u_int8_t **srcp,
1033 const u_int8_t **dstp)
1035 u_int subtype = FC_SUBTYPE(fc);
1037 if (DATA_FRAME_IS_CF_ACK(subtype) || DATA_FRAME_IS_CF_POLL(subtype) ||
1038 DATA_FRAME_IS_QOS(subtype)) {
1040 if (DATA_FRAME_IS_CF_ACK(subtype)) {
1041 if (DATA_FRAME_IS_CF_POLL(subtype))
1046 if (DATA_FRAME_IS_CF_POLL(subtype))
1049 if (DATA_FRAME_IS_QOS(subtype))
1054 #define ADDR1 (p + 4)
1055 #define ADDR2 (p + 10)
1056 #define ADDR3 (p + 16)
1057 #define ADDR4 (p + 24)
1059 if (!FC_TO_DS(fc) && !FC_FROM_DS(fc)) {
1066 printf("DA:%s SA:%s BSSID:%s ",
1067 etheraddr_string(ADDR1), etheraddr_string(ADDR2),
1068 etheraddr_string(ADDR3));
1069 } else if (!FC_TO_DS(fc) && FC_FROM_DS(fc)) {
1076 printf("DA:%s BSSID:%s SA:%s ",
1077 etheraddr_string(ADDR1), etheraddr_string(ADDR2),
1078 etheraddr_string(ADDR3));
1079 } else if (FC_TO_DS(fc) && !FC_FROM_DS(fc)) {
1086 printf("BSSID:%s SA:%s DA:%s ",
1087 etheraddr_string(ADDR1), etheraddr_string(ADDR2),
1088 etheraddr_string(ADDR3));
1089 } else if (FC_TO_DS(fc) && FC_FROM_DS(fc)) {
1096 printf("RA:%s TA:%s DA:%s SA:%s ",
1097 etheraddr_string(ADDR1), etheraddr_string(ADDR2),
1098 etheraddr_string(ADDR3), etheraddr_string(ADDR4));
1108 mgmt_header_print(const u_char *p, const u_int8_t **srcp,
1109 const u_int8_t **dstp)
1111 const struct mgmt_header_t *hp = (const struct mgmt_header_t *) p;
1120 printf("BSSID:%s DA:%s SA:%s ",
1121 etheraddr_string((hp)->bssid), etheraddr_string((hp)->da),
1122 etheraddr_string((hp)->sa));
1126 ctrl_header_print(u_int16_t fc, const u_char *p, const u_int8_t **srcp,
1127 const u_int8_t **dstp)
1136 switch (FC_SUBTYPE(fc)) {
1138 printf(" RA:%s TA:%s CTL(%x) SEQ(%u) ",
1139 etheraddr_string(((const struct ctrl_bar_t *)p)->ra),
1140 etheraddr_string(((const struct ctrl_bar_t *)p)->ta),
1141 EXTRACT_LE_16BITS(&(((const struct ctrl_bar_t *)p)->ctl)),
1142 EXTRACT_LE_16BITS(&(((const struct ctrl_bar_t *)p)->seq)));
1146 etheraddr_string(((const struct ctrl_ba_t *)p)->ra));
1149 printf("BSSID:%s TA:%s ",
1150 etheraddr_string(((const struct ctrl_ps_poll_t *)p)->bssid),
1151 etheraddr_string(((const struct ctrl_ps_poll_t *)p)->ta));
1154 printf("RA:%s TA:%s ",
1155 etheraddr_string(((const struct ctrl_rts_t *)p)->ra),
1156 etheraddr_string(((const struct ctrl_rts_t *)p)->ta));
1160 etheraddr_string(((const struct ctrl_cts_t *)p)->ra));
1164 etheraddr_string(((const struct ctrl_ack_t *)p)->ra));
1167 printf("RA:%s BSSID:%s ",
1168 etheraddr_string(((const struct ctrl_end_t *)p)->ra),
1169 etheraddr_string(((const struct ctrl_end_t *)p)->bssid));
1172 printf("RA:%s BSSID:%s ",
1173 etheraddr_string(((const struct ctrl_end_ack_t *)p)->ra),
1174 etheraddr_string(((const struct ctrl_end_ack_t *)p)->bssid));
1177 printf("(H) Unknown Ctrl Subtype");
1183 extract_header_length(u_int16_t fc)
1187 switch (FC_TYPE(fc)) {
1191 switch (FC_SUBTYPE(fc)) {
1193 return CTRL_BAR_HDRLEN;
1195 return CTRL_PS_POLL_HDRLEN;
1197 return CTRL_RTS_HDRLEN;
1199 return CTRL_CTS_HDRLEN;
1201 return CTRL_ACK_HDRLEN;
1203 return CTRL_END_HDRLEN;
1205 return CTRL_END_ACK_HDRLEN;
1210 len = (FC_TO_DS(fc) && FC_FROM_DS(fc)) ? 30 : 24;
1211 if (DATA_FRAME_IS_QOS(FC_SUBTYPE(fc)))
1215 printf("unknown IEEE802.11 frame type (%d)", FC_TYPE(fc));
1221 extract_mesh_header_length(const u_char *p)
1223 return (p[0] &~ 3) ? 0 : 6*(1 + (p[0] & 3));
1227 * Print the 802.11 MAC header if eflag is set, and set "*srcp" and "*dstp"
1228 * to point to the source and destination MAC addresses in any case if
1229 * "srcp" and "dstp" aren't null.
1232 ieee_802_11_hdr_print(u_int16_t fc, const u_char *p, u_int hdrlen,
1233 u_int meshdrlen, const u_int8_t **srcp, const u_int8_t **dstp)
1236 if (FC_MORE_DATA(fc))
1237 printf("More Data ");
1238 if (FC_MORE_FLAG(fc))
1239 printf("More Fragments ");
1240 if (FC_POWER_MGMT(fc))
1241 printf("Pwr Mgmt ");
1245 printf("Strictly Ordered ");
1247 printf("WEP Encrypted ");
1248 if (FC_TYPE(fc) != T_CTRL || FC_SUBTYPE(fc) != CTRL_PS_POLL)
1251 &((const struct mgmt_header_t *)p)->duration));
1253 if (meshdrlen != 0) {
1254 const struct meshcntl_t *mc =
1255 (const struct meshcntl_t *)&p[hdrlen - meshdrlen];
1256 int ae = mc->flags & 3;
1258 printf("MeshData (AE %d TTL %u seq %u", ae, mc->ttl,
1259 EXTRACT_LE_32BITS(mc->seq));
1261 printf(" A4:%s", etheraddr_string(mc->addr4));
1263 printf(" A5:%s", etheraddr_string(mc->addr5));
1265 printf(" A6:%s", etheraddr_string(mc->addr6));
1269 switch (FC_TYPE(fc)) {
1271 mgmt_header_print(p, srcp, dstp);
1274 ctrl_header_print(fc, p, srcp, dstp);
1277 data_header_print(fc, p, srcp, dstp);
1280 printf("(header) unknown IEEE802.11 frame type (%d)",
1289 #define roundup2(x, y) (((x)+((y)-1))&(~((y)-1))) /* if y is powers of two */
1293 ieee802_11_print(const u_char *p, u_int length, u_int orig_caplen, int pad,
1297 u_int caplen, hdrlen, meshdrlen;
1298 const u_int8_t *src, *dst;
1299 u_short extracted_ethertype;
1301 caplen = orig_caplen;
1302 /* Remove FCS, if present */
1303 if (length < fcslen) {
1304 printf("[|802.11]");
1308 if (caplen > length) {
1309 /* Amount of FCS in actual packet data, if any */
1310 fcslen = caplen - length;
1315 if (caplen < IEEE802_11_FC_LEN) {
1316 printf("[|802.11]");
1320 fc = EXTRACT_LE_16BITS(p);
1321 hdrlen = extract_header_length(fc);
1323 hdrlen = roundup2(hdrlen, 4);
1324 if (FC_TYPE(fc) == T_DATA && DATA_FRAME_IS_QOS(FC_SUBTYPE(fc))) {
1325 meshdrlen = extract_mesh_header_length(p+hdrlen);
1326 hdrlen += meshdrlen;
1331 if (caplen < hdrlen) {
1332 printf("[|802.11]");
1336 ieee_802_11_hdr_print(fc, p, hdrlen, meshdrlen, &src, &dst);
1339 * Go past the 802.11 header.
1345 switch (FC_TYPE(fc)) {
1347 if (!mgmt_body_print(fc,
1348 (const struct mgmt_header_t *)(p - hdrlen), p, length)) {
1349 printf("[|802.11]");
1354 if (!ctrl_body_print(fc, p - hdrlen)) {
1355 printf("[|802.11]");
1360 if (DATA_FRAME_IS_NULL(FC_SUBTYPE(fc)))
1361 return hdrlen; /* no-data frame */
1362 /* There may be a problem w/ AP not having this bit set */
1364 if (!wep_print(p)) {
1365 printf("[|802.11]");
1368 } else if (llc_print(p, length, caplen, dst, src,
1369 &extracted_ethertype) == 0) {
1371 * Some kinds of LLC packet we cannot
1372 * handle intelligently
1375 ieee_802_11_hdr_print(fc, p - hdrlen, hdrlen,
1376 meshdrlen, NULL, NULL);
1377 if (extracted_ethertype)
1380 htons(extracted_ethertype)));
1381 if (!suppress_default_print)
1382 default_print(p, caplen);
1386 printf("unknown 802.11 frame type (%d)", FC_TYPE(fc));
1394 * This is the top level routine of the printer. 'p' points
1395 * to the 802.11 header of the packet, 'h->ts' is the timestamp,
1396 * 'h->len' is the length of the packet off the wire, and 'h->caplen'
1397 * is the number of bytes actually captured.
1400 ieee802_11_if_print(const struct pcap_pkthdr *h, const u_char *p)
1402 return ieee802_11_print(p, h->len, h->caplen, 0, 0);
1405 #define IEEE80211_CHAN_FHSS \
1406 (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_GFSK)
1407 #define IEEE80211_CHAN_A \
1408 (IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM)
1409 #define IEEE80211_CHAN_B \
1410 (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_CCK)
1411 #define IEEE80211_CHAN_PUREG \
1412 (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_OFDM)
1413 #define IEEE80211_CHAN_G \
1414 (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_DYN)
1416 #define IS_CHAN_FHSS(flags) \
1417 ((flags & IEEE80211_CHAN_FHSS) == IEEE80211_CHAN_FHSS)
1418 #define IS_CHAN_A(flags) \
1419 ((flags & IEEE80211_CHAN_A) == IEEE80211_CHAN_A)
1420 #define IS_CHAN_B(flags) \
1421 ((flags & IEEE80211_CHAN_B) == IEEE80211_CHAN_B)
1422 #define IS_CHAN_PUREG(flags) \
1423 ((flags & IEEE80211_CHAN_PUREG) == IEEE80211_CHAN_PUREG)
1424 #define IS_CHAN_G(flags) \
1425 ((flags & IEEE80211_CHAN_G) == IEEE80211_CHAN_G)
1426 #define IS_CHAN_ANYG(flags) \
1427 (IS_CHAN_PUREG(flags) || IS_CHAN_G(flags))
1430 print_chaninfo(int freq, int flags)
1432 printf("%u MHz", freq);
1433 if (IS_CHAN_FHSS(flags))
1435 if (IS_CHAN_A(flags)) {
1436 if (flags & IEEE80211_CHAN_HALF)
1437 printf(" 11a/10Mhz");
1438 else if (flags & IEEE80211_CHAN_QUARTER)
1439 printf(" 11a/5Mhz");
1443 if (IS_CHAN_ANYG(flags)) {
1444 if (flags & IEEE80211_CHAN_HALF)
1445 printf(" 11g/10Mhz");
1446 else if (flags & IEEE80211_CHAN_QUARTER)
1447 printf(" 11g/5Mhz");
1450 } else if (IS_CHAN_B(flags))
1452 if (flags & IEEE80211_CHAN_TURBO)
1454 if (flags & IEEE80211_CHAN_HT20)
1456 else if (flags & IEEE80211_CHAN_HT40D)
1458 else if (flags & IEEE80211_CHAN_HT40U)
1464 print_radiotap_field(struct cpack_state *s, u_int32_t bit, u_int8_t *flags)
1477 case IEEE80211_RADIOTAP_FLAGS:
1478 rc = cpack_uint8(s, &u.u8);
1481 case IEEE80211_RADIOTAP_RATE:
1482 case IEEE80211_RADIOTAP_DB_ANTSIGNAL:
1483 case IEEE80211_RADIOTAP_DB_ANTNOISE:
1484 case IEEE80211_RADIOTAP_ANTENNA:
1485 rc = cpack_uint8(s, &u.u8);
1487 case IEEE80211_RADIOTAP_DBM_ANTSIGNAL:
1488 case IEEE80211_RADIOTAP_DBM_ANTNOISE:
1489 rc = cpack_int8(s, &u.i8);
1491 case IEEE80211_RADIOTAP_CHANNEL:
1492 rc = cpack_uint16(s, &u.u16);
1495 rc = cpack_uint16(s, &u2.u16);
1497 case IEEE80211_RADIOTAP_FHSS:
1498 case IEEE80211_RADIOTAP_LOCK_QUALITY:
1499 case IEEE80211_RADIOTAP_TX_ATTENUATION:
1500 rc = cpack_uint16(s, &u.u16);
1502 case IEEE80211_RADIOTAP_DB_TX_ATTENUATION:
1503 rc = cpack_uint8(s, &u.u8);
1505 case IEEE80211_RADIOTAP_DBM_TX_POWER:
1506 rc = cpack_int8(s, &u.i8);
1508 case IEEE80211_RADIOTAP_TSFT:
1509 rc = cpack_uint64(s, &u.u64);
1511 case IEEE80211_RADIOTAP_XCHANNEL:
1512 rc = cpack_uint32(s, &u.u32);
1515 rc = cpack_uint16(s, &u2.u16);
1518 rc = cpack_uint8(s, &u3.u8);
1521 rc = cpack_uint8(s, &u4.u8);
1524 /* this bit indicates a field whose
1525 * size we do not know, so we cannot
1526 * proceed. Just print the bit number.
1528 printf("[bit %u] ", bit);
1533 printf("[|802.11]");
1538 case IEEE80211_RADIOTAP_CHANNEL:
1539 print_chaninfo(u.u16, u2.u16);
1541 case IEEE80211_RADIOTAP_FHSS:
1542 printf("fhset %d fhpat %d ", u.u16 & 0xff, (u.u16 >> 8) & 0xff);
1544 case IEEE80211_RADIOTAP_RATE:
1546 PRINT_HT_RATE("", u.u8, " Mb/s ");
1548 PRINT_RATE("", u.u8, " Mb/s ");
1550 case IEEE80211_RADIOTAP_DBM_ANTSIGNAL:
1551 printf("%ddB signal ", u.i8);
1553 case IEEE80211_RADIOTAP_DBM_ANTNOISE:
1554 printf("%ddB noise ", u.i8);
1556 case IEEE80211_RADIOTAP_DB_ANTSIGNAL:
1557 printf("%ddB signal ", u.u8);
1559 case IEEE80211_RADIOTAP_DB_ANTNOISE:
1560 printf("%ddB noise ", u.u8);
1562 case IEEE80211_RADIOTAP_LOCK_QUALITY:
1563 printf("%u sq ", u.u16);
1565 case IEEE80211_RADIOTAP_TX_ATTENUATION:
1566 printf("%d tx power ", -(int)u.u16);
1568 case IEEE80211_RADIOTAP_DB_TX_ATTENUATION:
1569 printf("%ddB tx power ", -(int)u.u8);
1571 case IEEE80211_RADIOTAP_DBM_TX_POWER:
1572 printf("%ddBm tx power ", u.i8);
1574 case IEEE80211_RADIOTAP_FLAGS:
1575 if (u.u8 & IEEE80211_RADIOTAP_F_CFP)
1577 if (u.u8 & IEEE80211_RADIOTAP_F_SHORTPRE)
1578 printf("short preamble ");
1579 if (u.u8 & IEEE80211_RADIOTAP_F_WEP)
1581 if (u.u8 & IEEE80211_RADIOTAP_F_FRAG)
1582 printf("fragmented ");
1583 if (u.u8 & IEEE80211_RADIOTAP_F_BADFCS)
1586 case IEEE80211_RADIOTAP_ANTENNA:
1587 printf("antenna %d ", u.u8);
1589 case IEEE80211_RADIOTAP_TSFT:
1590 printf("%" PRIu64 "us tsft ", u.u64);
1592 case IEEE80211_RADIOTAP_XCHANNEL:
1593 print_chaninfo(u2.u16, u.u32);
1600 ieee802_11_radio_print(const u_char *p, u_int length, u_int caplen)
1602 #define BITNO_32(x) (((x) >> 16) ? 16 + BITNO_16((x) >> 16) : BITNO_16((x)))
1603 #define BITNO_16(x) (((x) >> 8) ? 8 + BITNO_8((x) >> 8) : BITNO_8((x)))
1604 #define BITNO_8(x) (((x) >> 4) ? 4 + BITNO_4((x) >> 4) : BITNO_4((x)))
1605 #define BITNO_4(x) (((x) >> 2) ? 2 + BITNO_2((x) >> 2) : BITNO_2((x)))
1606 #define BITNO_2(x) (((x) & 2) ? 1 : 0)
1607 #define BIT(n) (1U << n)
1608 #define IS_EXTENDED(__p) \
1609 (EXTRACT_LE_32BITS(__p) & BIT(IEEE80211_RADIOTAP_EXT)) != 0
1611 struct cpack_state cpacker;
1612 struct ieee80211_radiotap_header *hdr;
1613 u_int32_t present, next_present;
1614 u_int32_t *presentp, *last_presentp;
1615 enum ieee80211_radiotap_type bit;
1623 if (caplen < sizeof(*hdr)) {
1624 printf("[|802.11]");
1628 hdr = (struct ieee80211_radiotap_header *)p;
1630 len = EXTRACT_LE_16BITS(&hdr->it_len);
1633 printf("[|802.11]");
1636 for (last_presentp = &hdr->it_present;
1637 IS_EXTENDED(last_presentp) &&
1638 (u_char*)(last_presentp + 1) <= p + len;
1641 /* are there more bitmap extensions than bytes in header? */
1642 if (IS_EXTENDED(last_presentp)) {
1643 printf("[|802.11]");
1647 iter = (u_char*)(last_presentp + 1);
1649 if (cpack_init(&cpacker, (u_int8_t*)iter, len - (iter - p)) != 0) {
1651 printf("[|802.11]");
1655 /* Assume no flags */
1657 /* Assume no Atheros padding between 802.11 header and body */
1659 /* Assume no FCS at end of frame */
1661 for (bit0 = 0, presentp = &hdr->it_present; presentp <= last_presentp;
1662 presentp++, bit0 += 32) {
1663 for (present = EXTRACT_LE_32BITS(presentp); present;
1664 present = next_present) {
1665 /* clear the least significant bit that is set */
1666 next_present = present & (present - 1);
1668 /* extract the least significant bit that is set */
1669 bit = (enum ieee80211_radiotap_type)
1670 (bit0 + BITNO_32(present ^ next_present));
1672 if (print_radiotap_field(&cpacker, bit, &flags) != 0)
1677 if (flags & IEEE80211_RADIOTAP_F_DATAPAD)
1678 pad = 1; /* Atheros padding */
1679 if (flags & IEEE80211_RADIOTAP_F_FCS)
1680 fcslen = 4; /* FCS at end of packet */
1682 return len + ieee802_11_print(p + len, length - len, caplen - len, pad,
1693 ieee802_11_avs_radio_print(const u_char *p, u_int length, u_int caplen)
1695 u_int32_t caphdr_len;
1698 printf("[|802.11]");
1702 caphdr_len = EXTRACT_32BITS(p + 4);
1703 if (caphdr_len < 8) {
1705 * Yow! The capture header length is claimed not
1706 * to be large enough to include even the version
1707 * cookie or capture header length!
1709 printf("[|802.11]");
1713 if (caplen < caphdr_len) {
1714 printf("[|802.11]");
1718 return caphdr_len + ieee802_11_print(p + caphdr_len,
1719 length - caphdr_len, caplen - caphdr_len, 0, 0);
1722 #define PRISM_HDR_LEN 144
1724 #define WLANCAP_MAGIC_COOKIE_BASE 0x80211000
1725 #define WLANCAP_MAGIC_COOKIE_V1 0x80211001
1726 #define WLANCAP_MAGIC_COOKIE_V2 0x80211002
1729 * For DLT_PRISM_HEADER; like DLT_IEEE802_11, but with an extra header,
1730 * containing information such as radio information, which we
1733 * If, however, the packet begins with WLANCAP_MAGIC_COOKIE_V1 or
1734 * WLANCAP_MAGIC_COOKIE_V2, it's really DLT_IEEE802_11_RADIO_AVS
1735 * (currently, on Linux, there's no ARPHRD_ type for
1736 * DLT_IEEE802_11_RADIO_AVS, as there is a ARPHRD_IEEE80211_PRISM
1737 * for DLT_PRISM_HEADER, so ARPHRD_IEEE80211_PRISM is used for
1738 * the AVS header, and the first 4 bytes of the header are used to
1739 * indicate whether it's a Prism header or an AVS header).
1742 prism_if_print(const struct pcap_pkthdr *h, const u_char *p)
1744 u_int caplen = h->caplen;
1745 u_int length = h->len;
1749 printf("[|802.11]");
1753 msgcode = EXTRACT_32BITS(p);
1754 if (msgcode == WLANCAP_MAGIC_COOKIE_V1 ||
1755 msgcode == WLANCAP_MAGIC_COOKIE_V2)
1756 return ieee802_11_avs_radio_print(p, length, caplen);
1758 if (caplen < PRISM_HDR_LEN) {
1759 printf("[|802.11]");
1763 return PRISM_HDR_LEN + ieee802_11_print(p + PRISM_HDR_LEN,
1764 length - PRISM_HDR_LEN, caplen - PRISM_HDR_LEN, 0, 0);
1768 * For DLT_IEEE802_11_RADIO; like DLT_IEEE802_11, but with an extra
1769 * header, containing information such as radio information.
1772 ieee802_11_radio_if_print(const struct pcap_pkthdr *h, const u_char *p)
1774 return ieee802_11_radio_print(p, h->len, h->caplen);
1778 * For DLT_IEEE802_11_RADIO_AVS; like DLT_IEEE802_11, but with an
1779 * extra header, containing information such as radio information,
1780 * which we currently ignore.
1783 ieee802_11_radio_avs_if_print(const struct pcap_pkthdr *h, const u_char *p)
1785 return ieee802_11_avs_radio_print(p, h->len, h->caplen);