4 * Fortress Technologies, Inc. All rights reserved.
5 * Charlie Lenahan (clenahan@fortresstech.com)
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
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.
25 static const char rcsid[] _U_ =
26 "@(#) $Header: /tcpdump/master/tcpdump/print-802_11.c,v 1.31.2.5 2005/07/30 21:37:50 guy Exp $ (LBL)";
33 #include <tcpdump-stdinc.h>
39 #include "interface.h"
40 #include "addrtoname.h"
41 #include "ethertype.h"
47 #include "ieee802_11.h"
48 #include "ieee802_11_radio.h"
50 #define PRINT_RATE(_sep, _r, _suf) \
51 printf("%s%2.1f%s", _sep, (.5 * ((_r) & 0x7f)), _suf)
52 #define PRINT_RATES(p) \
55 const char *sep = " ["; \
56 for (z = 0; z < p.rates.length ; z++) { \
57 PRINT_RATE(sep, p.rates.rate[z], \
58 (p.rates.rate[z] & 0x80 ? "*" : "")); \
61 if (p.rates.length != 0) \
65 static const int ieee80211_htrates[16] = {
66 13, /* IFM_IEEE80211_MCS0 */
67 26, /* IFM_IEEE80211_MCS1 */
68 39, /* IFM_IEEE80211_MCS2 */
69 52, /* IFM_IEEE80211_MCS3 */
70 78, /* IFM_IEEE80211_MCS4 */
71 104, /* IFM_IEEE80211_MCS5 */
72 117, /* IFM_IEEE80211_MCS6 */
73 130, /* IFM_IEEE80211_MCS7 */
74 26, /* IFM_IEEE80211_MCS8 */
75 52, /* IFM_IEEE80211_MCS9 */
76 78, /* IFM_IEEE80211_MCS10 */
77 104, /* IFM_IEEE80211_MCS11 */
78 156, /* IFM_IEEE80211_MCS12 */
79 208, /* IFM_IEEE80211_MCS13 */
80 234, /* IFM_IEEE80211_MCS14 */
81 260, /* IFM_IEEE80211_MCS15 */
83 #define PRINT_HT_RATE(_sep, _r, _suf) \
84 printf("%s%.1f%s", _sep, (.5 * ieee80211_htrates[(_r) & 0xf]), _suf)
86 static const char *auth_alg_text[]={"Open System","Shared Key","EAP"};
87 #define NUM_AUTH_ALGS (sizeof auth_alg_text / sizeof auth_alg_text[0])
89 static const char *status_text[] = {
91 "Unspecified failure", /* 1 */
100 "Cannot Support all requested capabilities in the Capability Information field", /* 10 */
101 "Reassociation denied due to inability to confirm that association exists", /* 11 */
102 "Association denied due to reason outside the scope of the standard", /* 12 */
103 "Responding station does not support the specified authentication algorithm ", /* 13 */
104 "Received an Authentication frame with authentication transaction " \
105 "sequence number out of expected sequence", /* 14 */
106 "Authentication rejected because of challenge failure", /* 15 */
107 "Authentication rejected due to timeout waiting for next frame in sequence", /* 16 */
108 "Association denied because AP is unable to handle additional associated stations", /* 17 */
109 "Association denied due to requesting station not supporting all of the " \
110 "data rates in BSSBasicRateSet parameter", /* 18 */
112 #define NUM_STATUSES (sizeof status_text / sizeof status_text[0])
114 static const char *reason_text[] = {
116 "Unspecified reason", /* 1 */
117 "Previous authentication no longer valid", /* 2 */
118 "Deauthenticated because sending station is leaving (or has left) IBSS or ESS", /* 3 */
119 "Disassociated due to inactivity", /* 4 */
120 "Disassociated because AP is unable to handle all currently associated stations", /* 5 */
121 "Class 2 frame received from nonauthenticated station", /* 6 */
122 "Class 3 frame received from nonassociated station", /* 7 */
123 "Disassociated because sending station is leaving (or has left) BSS", /* 8 */
124 "Station requesting (re)association is not authenticated with responding station", /* 9 */
126 #define NUM_REASONS (sizeof reason_text / sizeof reason_text[0])
129 wep_print(const u_char *p)
133 if (!TTEST2(*p, IEEE802_11_IV_LEN + IEEE802_11_KID_LEN))
135 iv = EXTRACT_LE_32BITS(p);
137 printf("Data IV:%3x Pad %x KeyID %x", IV_IV(iv), IV_PAD(iv),
144 parse_elements(struct mgmt_body_t *pbody, const u_char *p, int offset)
147 if (!TTEST2(*(p + offset), 1))
149 switch (*(p + offset)) {
151 if (!TTEST2(*(p + offset), 2))
153 memcpy(&pbody->ssid, p + offset, 2);
155 if (pbody->ssid.length <= 0)
157 if (!TTEST2(*(p + offset), pbody->ssid.length))
159 memcpy(&pbody->ssid.ssid, p + offset,
161 offset += pbody->ssid.length;
162 pbody->ssid.ssid[pbody->ssid.length] = '\0';
165 if (!TTEST2(*(p + offset), 2))
167 memcpy(&pbody->challenge, p + offset, 2);
169 if (pbody->challenge.length <= 0)
171 if (!TTEST2(*(p + offset), pbody->challenge.length))
173 memcpy(&pbody->challenge.text, p + offset,
174 pbody->challenge.length);
175 offset += pbody->challenge.length;
176 pbody->challenge.text[pbody->challenge.length] = '\0';
179 if (!TTEST2(*(p + offset), 2))
181 memcpy(&(pbody->rates), p + offset, 2);
183 if (pbody->rates.length <= 0)
185 if (!TTEST2(*(p + offset), pbody->rates.length))
187 memcpy(&pbody->rates.rate, p + offset,
188 pbody->rates.length);
189 offset += pbody->rates.length;
192 if (!TTEST2(*(p + offset), 3))
194 memcpy(&pbody->ds, p + offset, 3);
198 if (!TTEST2(*(p + offset), 8))
200 memcpy(&pbody->cf, p + offset, 8);
204 if (!TTEST2(*(p + offset), 2))
206 memcpy(&pbody->tim, p + offset, 2);
208 if (!TTEST2(*(p + offset), 3))
210 memcpy(&pbody->tim.count, p + offset, 3);
213 if (pbody->tim.length <= 3)
215 if (!TTEST2(*(p + offset), pbody->tim.length - 3))
217 memcpy(pbody->tim.bitmap, p + (pbody->tim.length - 3),
218 (pbody->tim.length - 3));
219 offset += pbody->tim.length - 3;
223 printf("(1) unhandled element_id (%d) ",
226 offset += *(p + offset + 1) + 2;
233 /*********************************************************************************
234 * Print Handle functions for the management frame types
235 *********************************************************************************/
238 handle_beacon(const u_char *p)
240 struct mgmt_body_t pbody;
243 memset(&pbody, 0, sizeof(pbody));
245 if (!TTEST2(*p, IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN +
246 IEEE802_11_CAPINFO_LEN))
248 memcpy(&pbody.timestamp, p, 8);
249 offset += IEEE802_11_TSTAMP_LEN;
250 pbody.beacon_interval = EXTRACT_LE_16BITS(p+offset);
251 offset += IEEE802_11_BCNINT_LEN;
252 pbody.capability_info = EXTRACT_LE_16BITS(p+offset);
253 offset += IEEE802_11_CAPINFO_LEN;
255 if (!parse_elements(&pbody, p, offset))
259 fn_print(pbody.ssid.ssid, NULL);
262 printf(" %s CH: %u%s",
263 CAPABILITY_ESS(pbody.capability_info) ? "ESS" : "IBSS",
265 CAPABILITY_PRIVACY(pbody.capability_info) ? ", PRIVACY" : "" );
271 handle_assoc_request(const u_char *p)
273 struct mgmt_body_t pbody;
276 memset(&pbody, 0, sizeof(pbody));
278 if (!TTEST2(*p, IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN))
280 pbody.capability_info = EXTRACT_LE_16BITS(p);
281 offset += IEEE802_11_CAPINFO_LEN;
282 pbody.listen_interval = EXTRACT_LE_16BITS(p+offset);
283 offset += IEEE802_11_LISTENINT_LEN;
285 if (!parse_elements(&pbody, p, offset))
289 fn_print(pbody.ssid.ssid, NULL);
296 handle_assoc_response(const u_char *p)
298 struct mgmt_body_t pbody;
301 memset(&pbody, 0, sizeof(pbody));
303 if (!TTEST2(*p, IEEE802_11_CAPINFO_LEN + IEEE802_11_STATUS_LEN +
306 pbody.capability_info = EXTRACT_LE_16BITS(p);
307 offset += IEEE802_11_CAPINFO_LEN;
308 pbody.status_code = EXTRACT_LE_16BITS(p+offset);
309 offset += IEEE802_11_STATUS_LEN;
310 pbody.aid = EXTRACT_LE_16BITS(p+offset);
311 offset += IEEE802_11_AID_LEN;
313 if (!parse_elements(&pbody, p, offset))
316 printf(" AID(%x) :%s: %s", ((u_int16_t)(pbody.aid << 2 )) >> 2 ,
317 CAPABILITY_PRIVACY(pbody.capability_info) ? " PRIVACY " : "",
318 (pbody.status_code < NUM_STATUSES
319 ? status_text[pbody.status_code]
326 handle_reassoc_request(const u_char *p)
328 struct mgmt_body_t pbody;
331 memset(&pbody, 0, sizeof(pbody));
333 if (!TTEST2(*p, IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN +
336 pbody.capability_info = EXTRACT_LE_16BITS(p);
337 offset += IEEE802_11_CAPINFO_LEN;
338 pbody.listen_interval = EXTRACT_LE_16BITS(p+offset);
339 offset += IEEE802_11_LISTENINT_LEN;
340 memcpy(&pbody.ap, p+offset, IEEE802_11_AP_LEN);
341 offset += IEEE802_11_AP_LEN;
343 if (!parse_elements(&pbody, p, offset))
347 fn_print(pbody.ssid.ssid, NULL);
348 printf(") AP : %s", etheraddr_string( pbody.ap ));
354 handle_reassoc_response(const u_char *p)
356 /* Same as a Association Reponse */
357 return handle_assoc_response(p);
361 handle_probe_request(const u_char *p)
363 struct mgmt_body_t pbody;
366 memset(&pbody, 0, sizeof(pbody));
368 if (!parse_elements(&pbody, p, offset))
372 fn_print(pbody.ssid.ssid, NULL);
380 handle_probe_response(const u_char *p)
382 struct mgmt_body_t pbody;
385 memset(&pbody, 0, sizeof(pbody));
387 if (!TTEST2(*p, IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN +
388 IEEE802_11_CAPINFO_LEN))
391 memcpy(&pbody.timestamp, p, IEEE802_11_TSTAMP_LEN);
392 offset += IEEE802_11_TSTAMP_LEN;
393 pbody.beacon_interval = EXTRACT_LE_16BITS(p+offset);
394 offset += IEEE802_11_BCNINT_LEN;
395 pbody.capability_info = EXTRACT_LE_16BITS(p+offset);
396 offset += IEEE802_11_CAPINFO_LEN;
398 if (!parse_elements(&pbody, p, offset))
402 fn_print(pbody.ssid.ssid, NULL);
405 printf(" CH: %u%s", pbody.ds.channel,
406 CAPABILITY_PRIVACY(pbody.capability_info) ? ", PRIVACY" : "" );
414 /* the frame body for ATIM is null. */
419 handle_disassoc(const u_char *p)
421 struct mgmt_body_t pbody;
423 memset(&pbody, 0, sizeof(pbody));
425 if (!TTEST2(*p, IEEE802_11_REASON_LEN))
427 pbody.reason_code = EXTRACT_LE_16BITS(p);
430 (pbody.reason_code < NUM_REASONS)
431 ? reason_text[pbody.reason_code]
438 handle_auth(const u_char *p)
440 struct mgmt_body_t pbody;
443 memset(&pbody, 0, sizeof(pbody));
447 pbody.auth_alg = EXTRACT_LE_16BITS(p);
449 pbody.auth_trans_seq_num = EXTRACT_LE_16BITS(p + offset);
451 pbody.status_code = EXTRACT_LE_16BITS(p + offset);
454 if (!parse_elements(&pbody, p, offset))
457 if ((pbody.auth_alg == 1) &&
458 ((pbody.auth_trans_seq_num == 2) ||
459 (pbody.auth_trans_seq_num == 3))) {
460 printf(" (%s)-%x [Challenge Text] %s",
461 (pbody.auth_alg < NUM_AUTH_ALGS)
462 ? auth_alg_text[pbody.auth_alg]
464 pbody.auth_trans_seq_num,
465 ((pbody.auth_trans_seq_num % 2)
466 ? ((pbody.status_code < NUM_STATUSES)
467 ? status_text[pbody.status_code]
471 printf(" (%s)-%x: %s",
472 (pbody.auth_alg < NUM_AUTH_ALGS)
473 ? auth_alg_text[pbody.auth_alg]
475 pbody.auth_trans_seq_num,
476 (pbody.auth_trans_seq_num % 2)
477 ? ((pbody.status_code < NUM_STATUSES)
478 ? status_text[pbody.status_code]
486 handle_deauth(const struct mgmt_header_t *pmh, const u_char *p)
488 struct mgmt_body_t pbody;
490 const char *reason = NULL;
492 memset(&pbody, 0, sizeof(pbody));
494 if (!TTEST2(*p, IEEE802_11_REASON_LEN))
496 pbody.reason_code = EXTRACT_LE_16BITS(p);
497 offset += IEEE802_11_REASON_LEN;
499 reason = (pbody.reason_code < NUM_REASONS)
500 ? reason_text[pbody.reason_code]
504 printf(": %s", reason);
506 printf(" (%s): %s", etheraddr_string(pmh->sa), reason);
512 /*********************************************************************************
514 *********************************************************************************/
518 mgmt_body_print(u_int16_t fc, const struct mgmt_header_t *pmh,
521 switch (FC_SUBTYPE(fc)) {
522 case ST_ASSOC_REQUEST:
523 printf("Assoc Request");
524 return handle_assoc_request(p);
525 case ST_ASSOC_RESPONSE:
526 printf("Assoc Response");
527 return handle_assoc_response(p);
528 case ST_REASSOC_REQUEST:
529 printf("ReAssoc Request");
530 return handle_reassoc_request(p);
531 case ST_REASSOC_RESPONSE:
532 printf("ReAssoc Response");
533 return handle_reassoc_response(p);
534 case ST_PROBE_REQUEST:
535 printf("Probe Request");
536 return handle_probe_request(p);
537 case ST_PROBE_RESPONSE:
538 printf("Probe Response");
539 return handle_probe_response(p);
542 return handle_beacon(p);
545 return handle_atim();
547 printf("Disassociation");
548 return handle_disassoc(p);
550 printf("Authentication");
553 if ((p[0] == 0 ) && (p[1] == 0) && (p[2] == 0)) {
554 printf("Authentication (Shared-Key)-3 ");
557 return handle_auth(p);
559 printf("DeAuthentication");
560 return handle_deauth(pmh, p);
563 printf("Unhandled Management subtype(%x)",
570 /*********************************************************************************
571 * Handles printing all the control frame types
572 *********************************************************************************/
575 ctrl_body_print(u_int16_t fc, const u_char *p)
577 switch (FC_SUBTYPE(fc)) {
580 if (!TTEST2(*p, CTRL_BAR_HDRLEN))
583 printf(" RA:%s TA:%s CTL(%x) SEQ(%u) ",
584 etheraddr_string(((const struct ctrl_bar_t *)p)->ra),
585 etheraddr_string(((const struct ctrl_bar_t *)p)->ta),
586 EXTRACT_LE_16BITS(&(((const struct ctrl_bar_t *)p)->ctl)),
587 EXTRACT_LE_16BITS(&(((const struct ctrl_bar_t *)p)->seq)));
590 printf("Power Save-Poll");
591 if (!TTEST2(*p, CTRL_PS_POLL_HDRLEN))
594 EXTRACT_LE_16BITS(&(((const struct ctrl_ps_poll_t *)p)->aid)));
597 printf("Request-To-Send");
598 if (!TTEST2(*p, CTRL_RTS_HDRLEN))
602 etheraddr_string(((const struct ctrl_rts_t *)p)->ta));
605 printf("Clear-To-Send");
606 if (!TTEST2(*p, CTRL_CTS_HDRLEN))
610 etheraddr_string(((const struct ctrl_cts_t *)p)->ra));
613 printf("Acknowledgment");
614 if (!TTEST2(*p, CTRL_ACK_HDRLEN))
618 etheraddr_string(((const struct ctrl_ack_t *)p)->ra));
622 if (!TTEST2(*p, CTRL_END_HDRLEN))
626 etheraddr_string(((const struct ctrl_end_t *)p)->ra));
629 printf("CF-End+CF-Ack");
630 if (!TTEST2(*p, CTRL_END_ACK_HDRLEN))
634 etheraddr_string(((const struct ctrl_end_ack_t *)p)->ra));
637 printf("Unknown Ctrl Subtype");
647 * Data Frame - Address field contents
649 * To Ds | From DS | Addr 1 | Addr 2 | Addr 3 | Addr 4
650 * 0 | 0 | DA | SA | BSSID | n/a
651 * 0 | 1 | DA | BSSID | SA | n/a
652 * 1 | 0 | BSSID | SA | DA | n/a
653 * 1 | 1 | RA | TA | DA | SA
657 data_header_print(u_int16_t fc, const u_char *p, const u_int8_t **srcp,
658 const u_int8_t **dstp)
660 switch (FC_SUBTYPE(fc)) {
664 case DATA_DATA_CF_ACK:
665 case DATA_NODATA_CF_ACK:
668 case DATA_DATA_CF_POLL:
669 case DATA_NODATA_CF_POLL:
672 case DATA_DATA_CF_ACK_POLL:
673 case DATA_NODATA_CF_ACK_POLL:
674 printf("CF Ack/Poll ");
678 #define ADDR1 (p + 4)
679 #define ADDR2 (p + 10)
680 #define ADDR3 (p + 16)
681 #define ADDR4 (p + 24)
683 if (!FC_TO_DS(fc) && !FC_FROM_DS(fc)) {
690 printf("DA:%s SA:%s BSSID:%s ",
691 etheraddr_string(ADDR1), etheraddr_string(ADDR2),
692 etheraddr_string(ADDR3));
693 } else if (!FC_TO_DS(fc) && FC_FROM_DS(fc)) {
700 printf("DA:%s BSSID:%s SA:%s ",
701 etheraddr_string(ADDR1), etheraddr_string(ADDR2),
702 etheraddr_string(ADDR3));
703 } else if (FC_TO_DS(fc) && !FC_FROM_DS(fc)) {
710 printf("BSSID:%s SA:%s DA:%s ",
711 etheraddr_string(ADDR1), etheraddr_string(ADDR2),
712 etheraddr_string(ADDR3));
713 } else if (FC_TO_DS(fc) && FC_FROM_DS(fc)) {
720 printf("RA:%s TA:%s DA:%s SA:%s ",
721 etheraddr_string(ADDR1), etheraddr_string(ADDR2),
722 etheraddr_string(ADDR3), etheraddr_string(ADDR4));
732 mgmt_header_print(const u_char *p, const u_int8_t **srcp,
733 const u_int8_t **dstp)
735 const struct mgmt_header_t *hp = (const struct mgmt_header_t *) p;
744 printf("BSSID:%s DA:%s SA:%s ",
745 etheraddr_string((hp)->bssid), etheraddr_string((hp)->da),
746 etheraddr_string((hp)->sa));
750 ctrl_header_print(u_int16_t fc, const u_char *p, const u_int8_t **srcp,
751 const u_int8_t **dstp)
760 switch (FC_SUBTYPE(fc)) {
762 printf(" RA:%s TA:%s CTL(%x) SEQ(%u) ",
763 etheraddr_string(((const struct ctrl_bar_t *)p)->ra),
764 etheraddr_string(((const struct ctrl_bar_t *)p)->ta),
765 EXTRACT_LE_16BITS(&(((const struct ctrl_bar_t *)p)->ctl)),
766 EXTRACT_LE_16BITS(&(((const struct ctrl_bar_t *)p)->seq)));
769 printf("BSSID:%s TA:%s ",
770 etheraddr_string(((const struct ctrl_ps_poll_t *)p)->bssid),
771 etheraddr_string(((const struct ctrl_ps_poll_t *)p)->ta));
774 printf("RA:%s TA:%s ",
775 etheraddr_string(((const struct ctrl_rts_t *)p)->ra),
776 etheraddr_string(((const struct ctrl_rts_t *)p)->ta));
780 etheraddr_string(((const struct ctrl_cts_t *)p)->ra));
784 etheraddr_string(((const struct ctrl_ack_t *)p)->ra));
787 printf("RA:%s BSSID:%s ",
788 etheraddr_string(((const struct ctrl_end_t *)p)->ra),
789 etheraddr_string(((const struct ctrl_end_t *)p)->bssid));
792 printf("RA:%s BSSID:%s ",
793 etheraddr_string(((const struct ctrl_end_ack_t *)p)->ra),
794 etheraddr_string(((const struct ctrl_end_ack_t *)p)->bssid));
797 printf("(H) Unknown Ctrl Subtype");
803 extract_header_length(u_int16_t fc)
805 switch (FC_TYPE(fc)) {
809 switch (FC_SUBTYPE(fc)) {
811 return CTRL_BAR_HDRLEN;
813 return CTRL_PS_POLL_HDRLEN;
815 return CTRL_RTS_HDRLEN;
817 return CTRL_CTS_HDRLEN;
819 return CTRL_ACK_HDRLEN;
821 return CTRL_END_HDRLEN;
823 return CTRL_END_ACK_HDRLEN;
828 return (FC_TO_DS(fc) && FC_FROM_DS(fc)) ? 30 : 24;
830 printf("unknown IEEE802.11 frame type (%d)", FC_TYPE(fc));
836 * Print the 802.11 MAC header if eflag is set, and set "*srcp" and "*dstp"
837 * to point to the source and destination MAC addresses in any case if
838 * "srcp" and "dstp" aren't null.
841 ieee_802_11_hdr_print(u_int16_t fc, const u_char *p, const u_int8_t **srcp,
842 const u_int8_t **dstp)
845 if (FC_MORE_DATA(fc))
846 printf("More Data ");
847 if (FC_MORE_FLAG(fc))
848 printf("More Fragments ");
849 if (FC_POWER_MGMT(fc))
854 printf("Strictly Ordered ");
856 printf("WEP Encrypted ");
857 if (FC_TYPE(fc) != T_CTRL || FC_SUBTYPE(fc) != CTRL_PS_POLL)
860 &((const struct mgmt_header_t *)p)->duration));
863 switch (FC_TYPE(fc)) {
865 mgmt_header_print(p, srcp, dstp);
868 ctrl_header_print(fc, p, srcp, dstp);
871 data_header_print(fc, p, srcp, dstp);
874 printf("(header) unknown IEEE802.11 frame type (%d)",
883 ieee802_11_print(const u_char *p, u_int length, u_int caplen)
887 const u_int8_t *src, *dst;
888 u_short extracted_ethertype;
890 if (caplen < IEEE802_11_FC_LEN) {
895 fc = EXTRACT_LE_16BITS(p);
896 hdrlen = extract_header_length(fc);
898 if (caplen < hdrlen) {
903 ieee_802_11_hdr_print(fc, p, &src, &dst);
906 * Go past the 802.11 header.
912 switch (FC_TYPE(fc)) {
914 if (!mgmt_body_print(fc,
915 (const struct mgmt_header_t *)(p - hdrlen), p)) {
921 if (!ctrl_body_print(fc, p - hdrlen)) {
927 /* There may be a problem w/ AP not having this bit set */
933 } else if (llc_print(p, length, caplen, dst, src,
934 &extracted_ethertype) == 0) {
936 * Some kinds of LLC packet we cannot
937 * handle intelligently
940 ieee_802_11_hdr_print(fc, p - hdrlen, NULL,
942 if (extracted_ethertype)
945 htons(extracted_ethertype)));
946 if (!suppress_default_print)
947 default_print(p, caplen);
951 printf("unknown 802.11 frame type (%d)", FC_TYPE(fc));
959 * This is the top level routine of the printer. 'p' points
960 * to the 802.11 header of the packet, 'h->ts' is the timestamp,
961 * 'h->len' is the length of the packet off the wire, and 'h->caplen'
962 * is the number of bytes actually captured.
965 ieee802_11_if_print(const struct pcap_pkthdr *h, const u_char *p)
967 return ieee802_11_print(p, h->len, h->caplen);
970 #define IEEE80211_CHAN_FHSS \
971 (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_GFSK)
972 #define IEEE80211_CHAN_A \
973 (IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM)
974 #define IEEE80211_CHAN_B \
975 (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_CCK)
976 #define IEEE80211_CHAN_PUREG \
977 (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_OFDM)
978 #define IEEE80211_CHAN_G \
979 (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_DYN)
981 #define IS_CHAN_FHSS(flags) \
982 ((flags & IEEE80211_CHAN_FHSS) == IEEE80211_CHAN_FHSS)
983 #define IS_CHAN_A(flags) \
984 ((flags & IEEE80211_CHAN_A) == IEEE80211_CHAN_A)
985 #define IS_CHAN_B(flags) \
986 ((flags & IEEE80211_CHAN_B) == IEEE80211_CHAN_B)
987 #define IS_CHAN_PUREG(flags) \
988 ((flags & IEEE80211_CHAN_PUREG) == IEEE80211_CHAN_PUREG)
989 #define IS_CHAN_G(flags) \
990 ((flags & IEEE80211_CHAN_G) == IEEE80211_CHAN_G)
991 #define IS_CHAN_ANYG(flags) \
992 (IS_CHAN_PUREG(flags) || IS_CHAN_G(flags))
995 print_chaninfo(int freq, int flags)
997 printf("%u MHz", freq);
998 if (IS_CHAN_FHSS(flags))
1000 if (IS_CHAN_A(flags)) {
1001 if (flags & IEEE80211_CHAN_HALF)
1002 printf(" 11a/10Mhz");
1003 else if (flags & IEEE80211_CHAN_QUARTER)
1004 printf(" 11a/5Mhz");
1008 if (IS_CHAN_ANYG(flags)) {
1009 if (flags & IEEE80211_CHAN_HALF)
1010 printf(" 11g/10Mhz");
1011 else if (flags & IEEE80211_CHAN_QUARTER)
1012 printf(" 11g/5Mhz");
1015 } else if (IS_CHAN_B(flags))
1017 if (flags & IEEE80211_CHAN_TURBO)
1019 if (flags & IEEE80211_CHAN_HT20)
1021 else if (flags & IEEE80211_CHAN_HT40D)
1023 else if (flags & IEEE80211_CHAN_HT40U)
1029 print_radiotap_field(struct cpack_state *s, u_int32_t bit)
1042 case IEEE80211_RADIOTAP_FLAGS:
1043 case IEEE80211_RADIOTAP_RATE:
1044 case IEEE80211_RADIOTAP_DB_ANTSIGNAL:
1045 case IEEE80211_RADIOTAP_DB_ANTNOISE:
1046 case IEEE80211_RADIOTAP_ANTENNA:
1047 rc = cpack_uint8(s, &u.u8);
1049 case IEEE80211_RADIOTAP_DBM_ANTSIGNAL:
1050 case IEEE80211_RADIOTAP_DBM_ANTNOISE:
1051 rc = cpack_int8(s, &u.i8);
1053 case IEEE80211_RADIOTAP_CHANNEL:
1054 rc = cpack_uint16(s, &u.u16);
1057 rc = cpack_uint16(s, &u2.u16);
1059 case IEEE80211_RADIOTAP_FHSS:
1060 case IEEE80211_RADIOTAP_LOCK_QUALITY:
1061 case IEEE80211_RADIOTAP_TX_ATTENUATION:
1062 rc = cpack_uint16(s, &u.u16);
1064 case IEEE80211_RADIOTAP_DB_TX_ATTENUATION:
1065 rc = cpack_uint8(s, &u.u8);
1067 case IEEE80211_RADIOTAP_DBM_TX_POWER:
1068 rc = cpack_int8(s, &u.i8);
1070 case IEEE80211_RADIOTAP_TSFT:
1071 rc = cpack_uint64(s, &u.u64);
1073 case IEEE80211_RADIOTAP_XCHANNEL:
1074 rc = cpack_uint32(s, &u.u32);
1077 rc = cpack_uint16(s, &u2.u16);
1080 rc = cpack_uint8(s, &u3.u8);
1083 rc = cpack_uint8(s, &u4.u8);
1086 /* this bit indicates a field whose
1087 * size we do not know, so we cannot
1090 printf("[0x%08x] ", bit);
1095 printf("[|802.11]");
1100 case IEEE80211_RADIOTAP_CHANNEL:
1101 print_chaninfo(u.u16, u2.u16);
1103 case IEEE80211_RADIOTAP_FHSS:
1104 printf("fhset %d fhpat %d ", u.u16 & 0xff, (u.u16 >> 8) & 0xff);
1106 case IEEE80211_RADIOTAP_RATE:
1108 PRINT_RATE("", u.u8, " Mb/s ");
1110 PRINT_HT_RATE("", u.u8, " Mb/s ");
1112 case IEEE80211_RADIOTAP_DBM_ANTSIGNAL:
1113 printf("%ddB signal ", u.i8);
1115 case IEEE80211_RADIOTAP_DBM_ANTNOISE:
1116 printf("%ddB noise ", u.i8);
1118 case IEEE80211_RADIOTAP_DB_ANTSIGNAL:
1119 printf("%ddB signal ", u.u8);
1121 case IEEE80211_RADIOTAP_DB_ANTNOISE:
1122 printf("%ddB noise ", u.u8);
1124 case IEEE80211_RADIOTAP_LOCK_QUALITY:
1125 printf("%u sq ", u.u16);
1127 case IEEE80211_RADIOTAP_TX_ATTENUATION:
1128 printf("%d tx power ", -(int)u.u16);
1130 case IEEE80211_RADIOTAP_DB_TX_ATTENUATION:
1131 printf("%ddB tx power ", -(int)u.u8);
1133 case IEEE80211_RADIOTAP_DBM_TX_POWER:
1134 printf("%ddBm tx power ", u.i8);
1136 case IEEE80211_RADIOTAP_FLAGS:
1137 if (u.u8 & IEEE80211_RADIOTAP_F_CFP)
1139 if (u.u8 & IEEE80211_RADIOTAP_F_SHORTPRE)
1140 printf("short preamble ");
1141 if (u.u8 & IEEE80211_RADIOTAP_F_WEP)
1143 if (u.u8 & IEEE80211_RADIOTAP_F_FRAG)
1144 printf("fragmented ");
1146 if (u.u8 & IEEE80211_RADIOTAP_F_FCS)
1148 if (u.u8 & IEEE80211_RADIOTAP_F_DATAPAD)
1151 if (u.u8 & IEEE80211_RADIOTAP_F_BADFCS)
1154 case IEEE80211_RADIOTAP_ANTENNA:
1155 printf("antenna %d ", u.u8);
1157 case IEEE80211_RADIOTAP_TSFT:
1158 printf("%" PRIu64 "us tsft ", u.u64);
1160 case IEEE80211_RADIOTAP_XCHANNEL:
1161 print_chaninfo(u2.u16, u.u32);
1168 ieee802_11_radio_print(const u_char *p, u_int length, u_int caplen)
1170 #define BITNO_32(x) (((x) >> 16) ? 16 + BITNO_16((x) >> 16) : BITNO_16((x)))
1171 #define BITNO_16(x) (((x) >> 8) ? 8 + BITNO_8((x) >> 8) : BITNO_8((x)))
1172 #define BITNO_8(x) (((x) >> 4) ? 4 + BITNO_4((x) >> 4) : BITNO_4((x)))
1173 #define BITNO_4(x) (((x) >> 2) ? 2 + BITNO_2((x) >> 2) : BITNO_2((x)))
1174 #define BITNO_2(x) (((x) & 2) ? 1 : 0)
1175 #define BIT(n) (1 << n)
1176 #define IS_EXTENDED(__p) \
1177 (EXTRACT_LE_32BITS(__p) & BIT(IEEE80211_RADIOTAP_EXT)) != 0
1179 struct cpack_state cpacker;
1180 struct ieee80211_radiotap_header *hdr;
1181 u_int32_t present, next_present;
1182 u_int32_t *presentp, *last_presentp;
1183 enum ieee80211_radiotap_type bit;
1188 if (caplen < sizeof(*hdr)) {
1189 printf("[|802.11]");
1193 hdr = (struct ieee80211_radiotap_header *)p;
1195 len = EXTRACT_LE_16BITS(&hdr->it_len);
1198 printf("[|802.11]");
1201 for (last_presentp = &hdr->it_present;
1202 IS_EXTENDED(last_presentp) &&
1203 (u_char*)(last_presentp + 1) <= p + len;
1206 /* are there more bitmap extensions than bytes in header? */
1207 if (IS_EXTENDED(last_presentp)) {
1208 printf("[|802.11]");
1212 iter = (u_char*)(last_presentp + 1);
1214 if (cpack_init(&cpacker, (u_int8_t*)iter, len - (iter - p)) != 0) {
1216 printf("[|802.11]");
1220 for (bit0 = 0, presentp = &hdr->it_present; presentp <= last_presentp;
1221 presentp++, bit0 += 32) {
1222 for (present = EXTRACT_LE_32BITS(presentp); present;
1223 present = next_present) {
1224 /* clear the least significant bit that is set */
1225 next_present = present & (present - 1);
1227 /* extract the least significant bit that is set */
1228 bit = (enum ieee80211_radiotap_type)
1229 (bit0 + BITNO_32(present ^ next_present));
1231 if (print_radiotap_field(&cpacker, bit) != 0)
1236 return len + ieee802_11_print(p + len, length - len, caplen - len);
1246 ieee802_11_avs_radio_print(const u_char *p, u_int length, u_int caplen)
1248 u_int32_t caphdr_len;
1250 caphdr_len = EXTRACT_32BITS(p + 4);
1251 if (caphdr_len < 8) {
1253 * Yow! The capture header length is claimed not
1254 * to be large enough to include even the version
1255 * cookie or capture header length!
1257 printf("[|802.11]");
1261 if (caplen < caphdr_len) {
1262 printf("[|802.11]");
1266 return caphdr_len + ieee802_11_print(p + caphdr_len,
1267 length - caphdr_len, caplen - caphdr_len);
1270 #define PRISM_HDR_LEN 144
1272 #define WLANCAP_MAGIC_COOKIE_V1 0x80211001
1275 * For DLT_PRISM_HEADER; like DLT_IEEE802_11, but with an extra header,
1276 * containing information such as radio information, which we
1279 * If, however, the packet begins with WLANCAP_MAGIC_COOKIE_V1, it's
1280 * really DLT_IEEE802_11_RADIO (currently, on Linux, there's no
1281 * ARPHRD_ type for DLT_IEEE802_11_RADIO, as there is a
1282 * ARPHRD_IEEE80211_PRISM for DLT_PRISM_HEADER, so
1283 * ARPHRD_IEEE80211_PRISM is used for DLT_IEEE802_11_RADIO, and
1284 * the first 4 bytes of the header are used to indicate which it is).
1287 prism_if_print(const struct pcap_pkthdr *h, const u_char *p)
1289 u_int caplen = h->caplen;
1290 u_int length = h->len;
1293 printf("[|802.11]");
1297 if (EXTRACT_32BITS(p) == WLANCAP_MAGIC_COOKIE_V1)
1298 return ieee802_11_avs_radio_print(p, length, caplen);
1300 if (caplen < PRISM_HDR_LEN) {
1301 printf("[|802.11]");
1305 return PRISM_HDR_LEN + ieee802_11_print(p + PRISM_HDR_LEN,
1306 length - PRISM_HDR_LEN, caplen - PRISM_HDR_LEN);
1310 * For DLT_IEEE802_11_RADIO; like DLT_IEEE802_11, but with an extra
1311 * header, containing information such as radio information, which we
1315 ieee802_11_radio_if_print(const struct pcap_pkthdr *h, const u_char *p)
1317 u_int caplen = h->caplen;
1318 u_int length = h->len;
1321 printf("[|802.11]");
1325 return ieee802_11_radio_print(p, length, caplen);