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.47.2.2 2007-12-29 23:25:28 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 switch (p.ssid_status) { \
55 fn_print(p.ssid.ssid, NULL); \
62 #define PRINT_RATE(_sep, _r, _suf) \
63 printf("%s%2.1f%s", _sep, (.5 * ((_r) & 0x7f)), _suf)
64 #define PRINT_RATES(p) \
65 switch (p.rates_status) { \
71 const char *sep = " ["; \
72 for (z = 0; z < p.rates.length ; z++) { \
73 PRINT_RATE(sep, p.rates.rate[z], \
74 (p.rates.rate[z] & 0x80 ? "*" : "")); \
77 if (p.rates.length != 0) \
85 #define PRINT_DS_CHANNEL(p) \
86 switch (p.ds_status) { \
90 printf(" CH: %u", p.ds.channel); \
96 CAPABILITY_PRIVACY(p.capability_info) ? ", PRIVACY" : "" );
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 Information field", /* 10 */
113 "Reassociation denied due to inability to confirm that association exists", /* 11 */
114 "Association denied due to reason outside the scope of the standard", /* 12 */
115 "Responding station does not support the specified authentication algorithm ", /* 13 */
116 "Received an Authentication frame with authentication transaction " \
117 "sequence number out of expected sequence", /* 14 */
118 "Authentication rejected because of challenge failure", /* 15 */
119 "Authentication rejected due to timeout waiting for next frame in sequence", /* 16 */
120 "Association denied because AP is unable to handle additional associated stations", /* 17 */
121 "Association denied due to requesting station not supporting all of the " \
122 "data rates in BSSBasicRateSet parameter", /* 18 */
124 #define NUM_STATUSES (sizeof status_text / sizeof status_text[0])
126 static const char *reason_text
[] = {
128 "Unspecified reason", /* 1 */
129 "Previous authentication no longer valid", /* 2 */
130 "Deauthenticated because sending station is leaving (or has left) IBSS or ESS", /* 3 */
131 "Disassociated due to inactivity", /* 4 */
132 "Disassociated because AP is unable to handle all currently associated stations", /* 5 */
133 "Class 2 frame received from nonauthenticated station", /* 6 */
134 "Class 3 frame received from nonassociated station", /* 7 */
135 "Disassociated because sending station is leaving (or has left) BSS", /* 8 */
136 "Station requesting (re)association is not authenticated with responding station", /* 9 */
138 #define NUM_REASONS (sizeof reason_text / sizeof reason_text[0])
141 wep_print(const u_char
*p
)
145 if (!TTEST2(*p
, IEEE802_11_IV_LEN
+ IEEE802_11_KID_LEN
))
147 iv
= EXTRACT_LE_32BITS(p
);
149 printf("Data IV:%3x Pad %x KeyID %x", IV_IV(iv
), IV_PAD(iv
),
156 parse_elements(struct mgmt_body_t
*pbody
, const u_char
*p
, int offset
)
159 * We haven't seen any elements yet.
161 pbody
->challenge_status
= NOT_PRESENT
;
162 pbody
->ssid_status
= NOT_PRESENT
;
163 pbody
->rates_status
= NOT_PRESENT
;
164 pbody
->ds_status
= NOT_PRESENT
;
165 pbody
->cf_status
= NOT_PRESENT
;
166 pbody
->tim_status
= NOT_PRESENT
;
169 if (!TTEST2(*(p
+ offset
), 1))
171 switch (*(p
+ offset
)) {
173 /* Present, possibly truncated */
174 pbody
->ssid_status
= TRUNCATED
;
175 if (!TTEST2(*(p
+ offset
), 2))
177 memcpy(&pbody
->ssid
, p
+ offset
, 2);
179 if (pbody
->ssid
.length
!= 0) {
180 if (pbody
->ssid
.length
>
181 sizeof(pbody
->ssid
.ssid
) - 1)
183 if (!TTEST2(*(p
+ offset
), pbody
->ssid
.length
))
185 memcpy(&pbody
->ssid
.ssid
, p
+ offset
,
187 offset
+= pbody
->ssid
.length
;
189 pbody
->ssid
.ssid
[pbody
->ssid
.length
] = '\0';
190 /* Present and not truncated */
191 pbody
->ssid_status
= PRESENT
;
194 /* Present, possibly truncated */
195 pbody
->challenge_status
= TRUNCATED
;
196 if (!TTEST2(*(p
+ offset
), 2))
198 memcpy(&pbody
->challenge
, p
+ offset
, 2);
200 if (pbody
->challenge
.length
!= 0) {
201 if (pbody
->challenge
.length
>
202 sizeof(pbody
->challenge
.text
) - 1)
204 if (!TTEST2(*(p
+ offset
), pbody
->challenge
.length
))
206 memcpy(&pbody
->challenge
.text
, p
+ offset
,
207 pbody
->challenge
.length
);
208 offset
+= pbody
->challenge
.length
;
210 pbody
->challenge
.text
[pbody
->challenge
.length
] = '\0';
211 /* Present and not truncated */
212 pbody
->challenge_status
= PRESENT
;
215 /* Present, possibly truncated */
216 pbody
->rates_status
= TRUNCATED
;
217 if (!TTEST2(*(p
+ offset
), 2))
219 memcpy(&(pbody
->rates
), p
+ offset
, 2);
221 if (pbody
->rates
.length
!= 0) {
222 if (pbody
->rates
.length
> sizeof pbody
->rates
.rate
)
224 if (!TTEST2(*(p
+ offset
), pbody
->rates
.length
))
226 memcpy(&pbody
->rates
.rate
, p
+ offset
,
227 pbody
->rates
.length
);
228 offset
+= pbody
->rates
.length
;
230 /* Present and not truncated */
231 pbody
->rates_status
= PRESENT
;
234 /* Present, possibly truncated */
235 pbody
->ds_status
= TRUNCATED
;
236 if (!TTEST2(*(p
+ offset
), 3))
238 memcpy(&pbody
->ds
, p
+ offset
, 3);
240 /* Present and not truncated */
241 pbody
->ds_status
= PRESENT
;
244 /* Present, possibly truncated */
245 pbody
->cf_status
= TRUNCATED
;
246 if (!TTEST2(*(p
+ offset
), 8))
248 memcpy(&pbody
->cf
, p
+ offset
, 8);
250 /* Present and not truncated */
251 pbody
->cf_status
= PRESENT
;
254 /* Present, possibly truncated */
255 pbody
->tim_status
= TRUNCATED
;
256 if (!TTEST2(*(p
+ offset
), 2))
258 memcpy(&pbody
->tim
, p
+ offset
, 2);
260 if (!TTEST2(*(p
+ offset
), 3))
262 memcpy(&pbody
->tim
.count
, p
+ offset
, 3);
265 if (pbody
->tim
.length
<= 3)
267 if (pbody
->tim
.length
- 3 > (int)sizeof pbody
->tim
.bitmap
)
269 if (!TTEST2(*(p
+ offset
), pbody
->tim
.length
- 3))
271 memcpy(pbody
->tim
.bitmap
, p
+ (pbody
->tim
.length
- 3),
272 (pbody
->tim
.length
- 3));
273 offset
+= pbody
->tim
.length
- 3;
274 /* Present and not truncated */
275 pbody
->tim_status
= PRESENT
;
279 printf("(1) unhandled element_id (%d) ",
282 if (!TTEST2(*(p
+ offset
), 2))
284 if (!TTEST2(*(p
+ offset
+ 2), *(p
+ offset
+ 1)))
286 offset
+= *(p
+ offset
+ 1) + 2;
292 /*********************************************************************************
293 * Print Handle functions for the management frame types
294 *********************************************************************************/
297 handle_beacon(const u_char
*p
)
299 struct mgmt_body_t pbody
;
302 memset(&pbody
, 0, sizeof(pbody
));
304 if (!TTEST2(*p
, IEEE802_11_TSTAMP_LEN
+ IEEE802_11_BCNINT_LEN
+
305 IEEE802_11_CAPINFO_LEN
))
307 memcpy(&pbody
.timestamp
, p
, IEEE802_11_TSTAMP_LEN
);
308 offset
+= IEEE802_11_TSTAMP_LEN
;
309 pbody
.beacon_interval
= EXTRACT_LE_16BITS(p
+offset
);
310 offset
+= IEEE802_11_BCNINT_LEN
;
311 pbody
.capability_info
= EXTRACT_LE_16BITS(p
+offset
);
312 offset
+= IEEE802_11_CAPINFO_LEN
;
314 parse_elements(&pbody
, p
, offset
);
319 CAPABILITY_ESS(pbody
.capability_info
) ? "ESS" : "IBSS");
320 PRINT_DS_CHANNEL(pbody
);
326 handle_assoc_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
))
335 pbody
.capability_info
= EXTRACT_LE_16BITS(p
);
336 offset
+= IEEE802_11_CAPINFO_LEN
;
337 pbody
.listen_interval
= EXTRACT_LE_16BITS(p
+offset
);
338 offset
+= IEEE802_11_LISTENINT_LEN
;
340 parse_elements(&pbody
, p
, offset
);
348 handle_assoc_response(const u_char
*p
)
350 struct mgmt_body_t pbody
;
353 memset(&pbody
, 0, sizeof(pbody
));
355 if (!TTEST2(*p
, IEEE802_11_CAPINFO_LEN
+ IEEE802_11_STATUS_LEN
+
358 pbody
.capability_info
= EXTRACT_LE_16BITS(p
);
359 offset
+= IEEE802_11_CAPINFO_LEN
;
360 pbody
.status_code
= EXTRACT_LE_16BITS(p
+offset
);
361 offset
+= IEEE802_11_STATUS_LEN
;
362 pbody
.aid
= EXTRACT_LE_16BITS(p
+offset
);
363 offset
+= IEEE802_11_AID_LEN
;
365 parse_elements(&pbody
, p
, offset
);
367 printf(" AID(%x) :%s: %s", ((u_int16_t
)(pbody
.aid
<< 2 )) >> 2 ,
368 CAPABILITY_PRIVACY(pbody
.capability_info
) ? " PRIVACY " : "",
369 (pbody
.status_code
< NUM_STATUSES
370 ? status_text
[pbody
.status_code
]
377 handle_reassoc_request(const u_char
*p
)
379 struct mgmt_body_t pbody
;
382 memset(&pbody
, 0, sizeof(pbody
));
384 if (!TTEST2(*p
, IEEE802_11_CAPINFO_LEN
+ IEEE802_11_LISTENINT_LEN
+
387 pbody
.capability_info
= EXTRACT_LE_16BITS(p
);
388 offset
+= IEEE802_11_CAPINFO_LEN
;
389 pbody
.listen_interval
= EXTRACT_LE_16BITS(p
+offset
);
390 offset
+= IEEE802_11_LISTENINT_LEN
;
391 memcpy(&pbody
.ap
, p
+offset
, IEEE802_11_AP_LEN
);
392 offset
+= IEEE802_11_AP_LEN
;
394 parse_elements(&pbody
, p
, offset
);
397 printf(" AP : %s", etheraddr_string( pbody
.ap
));
403 handle_reassoc_response(const u_char
*p
)
405 /* Same as a Association Reponse */
406 return handle_assoc_response(p
);
410 handle_probe_request(const u_char
*p
)
412 struct mgmt_body_t pbody
;
415 memset(&pbody
, 0, sizeof(pbody
));
417 parse_elements(&pbody
, p
, offset
);
426 handle_probe_response(const u_char
*p
)
428 struct mgmt_body_t pbody
;
431 memset(&pbody
, 0, sizeof(pbody
));
433 if (!TTEST2(*p
, IEEE802_11_TSTAMP_LEN
+ IEEE802_11_BCNINT_LEN
+
434 IEEE802_11_CAPINFO_LEN
))
437 memcpy(&pbody
.timestamp
, p
, IEEE802_11_TSTAMP_LEN
);
438 offset
+= IEEE802_11_TSTAMP_LEN
;
439 pbody
.beacon_interval
= EXTRACT_LE_16BITS(p
+offset
);
440 offset
+= IEEE802_11_BCNINT_LEN
;
441 pbody
.capability_info
= EXTRACT_LE_16BITS(p
+offset
);
442 offset
+= IEEE802_11_CAPINFO_LEN
;
444 parse_elements(&pbody
, p
, offset
);
448 PRINT_DS_CHANNEL(pbody
);
456 /* the frame body for ATIM is null. */
461 handle_disassoc(const u_char
*p
)
463 struct mgmt_body_t pbody
;
465 memset(&pbody
, 0, sizeof(pbody
));
467 if (!TTEST2(*p
, IEEE802_11_REASON_LEN
))
469 pbody
.reason_code
= EXTRACT_LE_16BITS(p
);
472 (pbody
.reason_code
< NUM_REASONS
)
473 ? reason_text
[pbody
.reason_code
]
480 handle_auth(const u_char
*p
)
482 struct mgmt_body_t pbody
;
485 memset(&pbody
, 0, sizeof(pbody
));
489 pbody
.auth_alg
= EXTRACT_LE_16BITS(p
);
491 pbody
.auth_trans_seq_num
= EXTRACT_LE_16BITS(p
+ offset
);
493 pbody
.status_code
= EXTRACT_LE_16BITS(p
+ offset
);
496 parse_elements(&pbody
, p
, offset
);
498 if ((pbody
.auth_alg
== 1) &&
499 ((pbody
.auth_trans_seq_num
== 2) ||
500 (pbody
.auth_trans_seq_num
== 3))) {
501 printf(" (%s)-%x [Challenge Text] %s",
502 (pbody
.auth_alg
< NUM_AUTH_ALGS
)
503 ? auth_alg_text
[pbody
.auth_alg
]
505 pbody
.auth_trans_seq_num
,
506 ((pbody
.auth_trans_seq_num
% 2)
507 ? ((pbody
.status_code
< NUM_STATUSES
)
508 ? status_text
[pbody
.status_code
]
512 printf(" (%s)-%x: %s",
513 (pbody
.auth_alg
< NUM_AUTH_ALGS
)
514 ? auth_alg_text
[pbody
.auth_alg
]
516 pbody
.auth_trans_seq_num
,
517 (pbody
.auth_trans_seq_num
% 2)
518 ? ((pbody
.status_code
< NUM_STATUSES
)
519 ? status_text
[pbody
.status_code
]
527 handle_deauth(const struct mgmt_header_t
*pmh
, const u_char
*p
)
529 struct mgmt_body_t pbody
;
531 const char *reason
= NULL
;
533 memset(&pbody
, 0, sizeof(pbody
));
535 if (!TTEST2(*p
, IEEE802_11_REASON_LEN
))
537 pbody
.reason_code
= EXTRACT_LE_16BITS(p
);
538 offset
+= IEEE802_11_REASON_LEN
;
540 reason
= (pbody
.reason_code
< NUM_REASONS
)
541 ? reason_text
[pbody
.reason_code
]
545 printf(": %s", reason
);
547 printf(" (%s): %s", etheraddr_string(pmh
->sa
), reason
);
553 /*********************************************************************************
555 *********************************************************************************/
559 mgmt_body_print(u_int16_t fc
, const struct mgmt_header_t
*pmh
,
562 switch (FC_SUBTYPE(fc
)) {
563 case ST_ASSOC_REQUEST
:
564 printf("Assoc Request");
565 return handle_assoc_request(p
);
566 case ST_ASSOC_RESPONSE
:
567 printf("Assoc Response");
568 return handle_assoc_response(p
);
569 case ST_REASSOC_REQUEST
:
570 printf("ReAssoc Request");
571 return handle_reassoc_request(p
);
572 case ST_REASSOC_RESPONSE
:
573 printf("ReAssoc Response");
574 return handle_reassoc_response(p
);
575 case ST_PROBE_REQUEST
:
576 printf("Probe Request");
577 return handle_probe_request(p
);
578 case ST_PROBE_RESPONSE
:
579 printf("Probe Response");
580 return handle_probe_response(p
);
583 return handle_beacon(p
);
586 return handle_atim();
588 printf("Disassociation");
589 return handle_disassoc(p
);
591 printf("Authentication");
594 if ((p
[0] == 0 ) && (p
[1] == 0) && (p
[2] == 0)) {
595 printf("Authentication (Shared-Key)-3 ");
598 return handle_auth(p
);
600 printf("DeAuthentication");
601 return handle_deauth(pmh
, p
);
604 printf("Unhandled Management subtype(%x)",
611 /*********************************************************************************
612 * Handles printing all the control frame types
613 *********************************************************************************/
616 ctrl_body_print(u_int16_t fc
, const u_char
*p
)
618 switch (FC_SUBTYPE(fc
)) {
620 printf("Power Save-Poll");
621 if (!TTEST2(*p
, CTRL_PS_POLL_HDRLEN
))
624 EXTRACT_LE_16BITS(&(((const struct ctrl_ps_poll_t
*)p
)->aid
)));
627 printf("Request-To-Send");
628 if (!TTEST2(*p
, CTRL_RTS_HDRLEN
))
632 etheraddr_string(((const struct ctrl_rts_t
*)p
)->ta
));
635 printf("Clear-To-Send");
636 if (!TTEST2(*p
, CTRL_CTS_HDRLEN
))
640 etheraddr_string(((const struct ctrl_cts_t
*)p
)->ra
));
643 printf("Acknowledgment");
644 if (!TTEST2(*p
, CTRL_ACK_HDRLEN
))
648 etheraddr_string(((const struct ctrl_ack_t
*)p
)->ra
));
652 if (!TTEST2(*p
, CTRL_END_HDRLEN
))
656 etheraddr_string(((const struct ctrl_end_t
*)p
)->ra
));
659 printf("CF-End+CF-Ack");
660 if (!TTEST2(*p
, CTRL_END_ACK_HDRLEN
))
664 etheraddr_string(((const struct ctrl_end_ack_t
*)p
)->ra
));
667 printf("Unknown Ctrl Subtype");
677 * Data Frame - Address field contents
679 * To Ds | From DS | Addr 1 | Addr 2 | Addr 3 | Addr 4
680 * 0 | 0 | DA | SA | BSSID | n/a
681 * 0 | 1 | DA | BSSID | SA | n/a
682 * 1 | 0 | BSSID | SA | DA | n/a
683 * 1 | 1 | RA | TA | DA | SA
687 data_header_print(u_int16_t fc
, const u_char
*p
, const u_int8_t
**srcp
,
688 const u_int8_t
**dstp
)
690 u_int subtype
= FC_SUBTYPE(fc
);
692 if (DATA_FRAME_IS_CF_ACK(subtype
) || DATA_FRAME_IS_CF_POLL(subtype
) ||
693 DATA_FRAME_IS_QOS(subtype
)) {
695 if (DATA_FRAME_IS_CF_ACK(subtype
)) {
696 if (DATA_FRAME_IS_CF_POLL(subtype
))
701 if (DATA_FRAME_IS_CF_POLL(subtype
))
704 if (DATA_FRAME_IS_QOS(subtype
))
709 #define ADDR1 (p + 4)
710 #define ADDR2 (p + 10)
711 #define ADDR3 (p + 16)
712 #define ADDR4 (p + 24)
714 if (!FC_TO_DS(fc
) && !FC_FROM_DS(fc
)) {
721 printf("DA:%s SA:%s BSSID:%s ",
722 etheraddr_string(ADDR1
), etheraddr_string(ADDR2
),
723 etheraddr_string(ADDR3
));
724 } else if (!FC_TO_DS(fc
) && FC_FROM_DS(fc
)) {
731 printf("DA:%s BSSID:%s SA:%s ",
732 etheraddr_string(ADDR1
), etheraddr_string(ADDR2
),
733 etheraddr_string(ADDR3
));
734 } else if (FC_TO_DS(fc
) && !FC_FROM_DS(fc
)) {
741 printf("BSSID:%s SA:%s DA:%s ",
742 etheraddr_string(ADDR1
), etheraddr_string(ADDR2
),
743 etheraddr_string(ADDR3
));
744 } else if (FC_TO_DS(fc
) && FC_FROM_DS(fc
)) {
751 printf("RA:%s TA:%s DA:%s SA:%s ",
752 etheraddr_string(ADDR1
), etheraddr_string(ADDR2
),
753 etheraddr_string(ADDR3
), etheraddr_string(ADDR4
));
763 mgmt_header_print(const u_char
*p
, const u_int8_t
**srcp
,
764 const u_int8_t
**dstp
)
766 const struct mgmt_header_t
*hp
= (const struct mgmt_header_t
*) p
;
775 printf("BSSID:%s DA:%s SA:%s ",
776 etheraddr_string((hp
)->bssid
), etheraddr_string((hp
)->da
),
777 etheraddr_string((hp
)->sa
));
781 ctrl_header_print(u_int16_t fc
, const u_char
*p
, const u_int8_t
**srcp
,
782 const u_int8_t
**dstp
)
791 switch (FC_SUBTYPE(fc
)) {
793 printf("BSSID:%s TA:%s ",
794 etheraddr_string(((const struct ctrl_ps_poll_t
*)p
)->bssid
),
795 etheraddr_string(((const struct ctrl_ps_poll_t
*)p
)->ta
));
798 printf("RA:%s TA:%s ",
799 etheraddr_string(((const struct ctrl_rts_t
*)p
)->ra
),
800 etheraddr_string(((const struct ctrl_rts_t
*)p
)->ta
));
804 etheraddr_string(((const struct ctrl_cts_t
*)p
)->ra
));
808 etheraddr_string(((const struct ctrl_ack_t
*)p
)->ra
));
811 printf("RA:%s BSSID:%s ",
812 etheraddr_string(((const struct ctrl_end_t
*)p
)->ra
),
813 etheraddr_string(((const struct ctrl_end_t
*)p
)->bssid
));
816 printf("RA:%s BSSID:%s ",
817 etheraddr_string(((const struct ctrl_end_ack_t
*)p
)->ra
),
818 etheraddr_string(((const struct ctrl_end_ack_t
*)p
)->bssid
));
821 printf("(H) Unknown Ctrl Subtype");
827 extract_header_length(u_int16_t fc
)
831 switch (FC_TYPE(fc
)) {
835 switch (FC_SUBTYPE(fc
)) {
837 return CTRL_PS_POLL_HDRLEN
;
839 return CTRL_RTS_HDRLEN
;
841 return CTRL_CTS_HDRLEN
;
843 return CTRL_ACK_HDRLEN
;
845 return CTRL_END_HDRLEN
;
847 return CTRL_END_ACK_HDRLEN
;
852 len
= (FC_TO_DS(fc
) && FC_FROM_DS(fc
)) ? 30 : 24;
853 if (DATA_FRAME_IS_QOS(FC_SUBTYPE(fc
)))
857 printf("unknown IEEE802.11 frame type (%d)", FC_TYPE(fc
));
863 * Print the 802.11 MAC header if eflag is set, and set "*srcp" and "*dstp"
864 * to point to the source and destination MAC addresses in any case if
865 * "srcp" and "dstp" aren't null.
868 ieee_802_11_hdr_print(u_int16_t fc
, const u_char
*p
, const u_int8_t
**srcp
,
869 const u_int8_t
**dstp
)
872 if (FC_MORE_DATA(fc
))
873 printf("More Data ");
874 if (FC_MORE_FLAG(fc
))
875 printf("More Fragments ");
876 if (FC_POWER_MGMT(fc
))
881 printf("Strictly Ordered ");
883 printf("WEP Encrypted ");
884 if (FC_TYPE(fc
) != T_CTRL
|| FC_SUBTYPE(fc
) != CTRL_PS_POLL
)
887 &((const struct mgmt_header_t
*)p
)->duration
));
890 switch (FC_TYPE(fc
)) {
892 mgmt_header_print(p
, srcp
, dstp
);
895 ctrl_header_print(fc
, p
, srcp
, dstp
);
898 data_header_print(fc
, p
, srcp
, dstp
);
901 printf("(header) unknown IEEE802.11 frame type (%d)",
910 #define roundup2(x, y) (((x)+((y)-1))&(~((y)-1))) /* if y is powers of two */
914 ieee802_11_print(const u_char
*p
, u_int length
, u_int caplen
, int pad
)
918 const u_int8_t
*src
, *dst
;
919 u_short extracted_ethertype
;
921 if (caplen
< IEEE802_11_FC_LEN
) {
926 fc
= EXTRACT_LE_16BITS(p
);
927 hdrlen
= extract_header_length(fc
);
929 hdrlen
= roundup2(hdrlen
, 4);
931 if (caplen
< hdrlen
) {
936 ieee_802_11_hdr_print(fc
, p
, &src
, &dst
);
939 * Go past the 802.11 header.
945 switch (FC_TYPE(fc
)) {
947 if (!mgmt_body_print(fc
,
948 (const struct mgmt_header_t
*)(p
- hdrlen
), p
)) {
954 if (!ctrl_body_print(fc
, p
- hdrlen
)) {
960 if (DATA_FRAME_IS_NULL(FC_SUBTYPE(fc
)))
961 return hdrlen
; /* no-data frame */
962 /* There may be a problem w/ AP not having this bit set */
968 } else if (llc_print(p
, length
, caplen
, dst
, src
,
969 &extracted_ethertype
) == 0) {
971 * Some kinds of LLC packet we cannot
972 * handle intelligently
975 ieee_802_11_hdr_print(fc
, p
- hdrlen
, NULL
,
977 if (extracted_ethertype
)
980 htons(extracted_ethertype
)));
981 if (!suppress_default_print
)
982 default_print(p
, caplen
);
986 printf("unknown 802.11 frame type (%d)", FC_TYPE(fc
));
994 * This is the top level routine of the printer. 'p' points
995 * to the 802.11 header of the packet, 'h->ts' is the timestamp,
996 * 'h->len' is the length of the packet off the wire, and 'h->caplen'
997 * is the number of bytes actually captured.
1000 ieee802_11_if_print(const struct pcap_pkthdr
*h
, const u_char
*p
)
1002 return ieee802_11_print(p
, h
->len
, h
->caplen
, 0);
1006 print_radiotap_field(struct cpack_state
*s
, u_int32_t bit
, int *pad
)
1019 case IEEE80211_RADIOTAP_FLAGS
:
1020 rc
= cpack_uint8(s
, &u
.u8
);
1021 if (u
.u8
& IEEE80211_RADIOTAP_F_DATAPAD
)
1024 case IEEE80211_RADIOTAP_RATE
:
1025 case IEEE80211_RADIOTAP_DB_ANTSIGNAL
:
1026 case IEEE80211_RADIOTAP_DB_ANTNOISE
:
1027 case IEEE80211_RADIOTAP_ANTENNA
:
1028 rc
= cpack_uint8(s
, &u
.u8
);
1030 case IEEE80211_RADIOTAP_DBM_ANTSIGNAL
:
1031 case IEEE80211_RADIOTAP_DBM_ANTNOISE
:
1032 rc
= cpack_int8(s
, &u
.i8
);
1034 case IEEE80211_RADIOTAP_CHANNEL
:
1035 rc
= cpack_uint16(s
, &u
.u16
);
1038 rc
= cpack_uint16(s
, &u2
.u16
);
1040 case IEEE80211_RADIOTAP_FHSS
:
1041 case IEEE80211_RADIOTAP_LOCK_QUALITY
:
1042 case IEEE80211_RADIOTAP_TX_ATTENUATION
:
1043 rc
= cpack_uint16(s
, &u
.u16
);
1045 case IEEE80211_RADIOTAP_DB_TX_ATTENUATION
:
1046 rc
= cpack_uint8(s
, &u
.u8
);
1048 case IEEE80211_RADIOTAP_DBM_TX_POWER
:
1049 rc
= cpack_int8(s
, &u
.i8
);
1051 case IEEE80211_RADIOTAP_TSFT
:
1052 rc
= cpack_uint64(s
, &u
.u64
);
1055 /* this bit indicates a field whose
1056 * size we do not know, so we cannot
1059 printf("[0x%08x] ", bit
);
1064 printf("[|802.11]");
1069 case IEEE80211_RADIOTAP_CHANNEL
:
1070 printf("%u MHz ", u
.u16
);
1072 printf("(0x%04x) ", u2
.u16
);
1074 case IEEE80211_RADIOTAP_FHSS
:
1075 printf("fhset %d fhpat %d ", u
.u16
& 0xff, (u
.u16
>> 8) & 0xff);
1077 case IEEE80211_RADIOTAP_RATE
:
1078 PRINT_RATE("", u
.u8
, " Mb/s ");
1080 case IEEE80211_RADIOTAP_DBM_ANTSIGNAL
:
1081 printf("%ddB signal ", u
.i8
);
1083 case IEEE80211_RADIOTAP_DBM_ANTNOISE
:
1084 printf("%ddB noise ", u
.i8
);
1086 case IEEE80211_RADIOTAP_DB_ANTSIGNAL
:
1087 printf("%ddB signal ", u
.u8
);
1089 case IEEE80211_RADIOTAP_DB_ANTNOISE
:
1090 printf("%ddB noise ", u
.u8
);
1092 case IEEE80211_RADIOTAP_LOCK_QUALITY
:
1093 printf("%u sq ", u
.u16
);
1095 case IEEE80211_RADIOTAP_TX_ATTENUATION
:
1096 printf("%d tx power ", -(int)u
.u16
);
1098 case IEEE80211_RADIOTAP_DB_TX_ATTENUATION
:
1099 printf("%ddB tx power ", -(int)u
.u8
);
1101 case IEEE80211_RADIOTAP_DBM_TX_POWER
:
1102 printf("%ddBm tx power ", u
.i8
);
1104 case IEEE80211_RADIOTAP_FLAGS
:
1105 if (u
.u8
& IEEE80211_RADIOTAP_F_CFP
)
1107 if (u
.u8
& IEEE80211_RADIOTAP_F_SHORTPRE
)
1108 printf("short preamble ");
1109 if (u
.u8
& IEEE80211_RADIOTAP_F_WEP
)
1111 if (u
.u8
& IEEE80211_RADIOTAP_F_FRAG
)
1112 printf("fragmented ");
1113 if (u
.u8
& IEEE80211_RADIOTAP_F_BADFCS
)
1116 case IEEE80211_RADIOTAP_ANTENNA
:
1117 printf("antenna %d ", u
.u8
);
1119 case IEEE80211_RADIOTAP_TSFT
:
1120 printf("%" PRIu64
"us tsft ", u
.u64
);
1127 ieee802_11_radio_print(const u_char
*p
, u_int length
, u_int caplen
)
1129 #define BITNO_32(x) (((x) >> 16) ? 16 + BITNO_16((x) >> 16) : BITNO_16((x)))
1130 #define BITNO_16(x) (((x) >> 8) ? 8 + BITNO_8((x) >> 8) : BITNO_8((x)))
1131 #define BITNO_8(x) (((x) >> 4) ? 4 + BITNO_4((x) >> 4) : BITNO_4((x)))
1132 #define BITNO_4(x) (((x) >> 2) ? 2 + BITNO_2((x) >> 2) : BITNO_2((x)))
1133 #define BITNO_2(x) (((x) & 2) ? 1 : 0)
1134 #define BIT(n) (1 << n)
1135 #define IS_EXTENDED(__p) \
1136 (EXTRACT_LE_32BITS(__p) & BIT(IEEE80211_RADIOTAP_EXT)) != 0
1138 struct cpack_state cpacker
;
1139 struct ieee80211_radiotap_header
*hdr
;
1140 u_int32_t present
, next_present
;
1141 u_int32_t
*presentp
, *last_presentp
;
1142 enum ieee80211_radiotap_type bit
;
1148 if (caplen
< sizeof(*hdr
)) {
1149 printf("[|802.11]");
1153 hdr
= (struct ieee80211_radiotap_header
*)p
;
1155 len
= EXTRACT_LE_16BITS(&hdr
->it_len
);
1158 printf("[|802.11]");
1161 for (last_presentp
= &hdr
->it_present
;
1162 IS_EXTENDED(last_presentp
) &&
1163 (u_char
*)(last_presentp
+ 1) <= p
+ len
;
1166 /* are there more bitmap extensions than bytes in header? */
1167 if (IS_EXTENDED(last_presentp
)) {
1168 printf("[|802.11]");
1172 iter
= (u_char
*)(last_presentp
+ 1);
1174 if (cpack_init(&cpacker
, (u_int8_t
*)iter
, len
- (iter
- p
)) != 0) {
1176 printf("[|802.11]");
1180 /* Assume no Atheros padding between 802.11 header and body */
1182 for (bit0
= 0, presentp
= &hdr
->it_present
; presentp
<= last_presentp
;
1183 presentp
++, bit0
+= 32) {
1184 for (present
= EXTRACT_LE_32BITS(presentp
); present
;
1185 present
= next_present
) {
1186 /* clear the least significant bit that is set */
1187 next_present
= present
& (present
- 1);
1189 /* extract the least significant bit that is set */
1190 bit
= (enum ieee80211_radiotap_type
)
1191 (bit0
+ BITNO_32(present
^ next_present
));
1193 if (print_radiotap_field(&cpacker
, bit
, &pad
) != 0)
1198 return len
+ ieee802_11_print(p
+ len
, length
- len
, caplen
- len
, pad
);
1208 ieee802_11_avs_radio_print(const u_char
*p
, u_int length
, u_int caplen
)
1210 u_int32_t caphdr_len
;
1213 printf("[|802.11]");
1217 caphdr_len
= EXTRACT_32BITS(p
+ 4);
1218 if (caphdr_len
< 8) {
1220 * Yow! The capture header length is claimed not
1221 * to be large enough to include even the version
1222 * cookie or capture header length!
1224 printf("[|802.11]");
1228 if (caplen
< caphdr_len
) {
1229 printf("[|802.11]");
1233 return caphdr_len
+ ieee802_11_print(p
+ caphdr_len
,
1234 length
- caphdr_len
, caplen
- caphdr_len
, 0);
1237 #define PRISM_HDR_LEN 144
1239 #define WLANCAP_MAGIC_COOKIE_BASE 0x80211000
1240 #define WLANCAP_MAGIC_COOKIE_V1 0x80211001
1241 #define WLANCAP_MAGIC_COOKIE_V2 0x80211002
1244 * For DLT_PRISM_HEADER; like DLT_IEEE802_11, but with an extra header,
1245 * containing information such as radio information, which we
1248 * If, however, the packet begins with WLANCAP_MAGIC_COOKIE_V1 or
1249 * WLANCAP_MAGIC_COOKIE_V2, it's really DLT_IEEE802_11_RADIO_AVS
1250 * (currently, on Linux, there's no ARPHRD_ type for
1251 * DLT_IEEE802_11_RADIO_AVS, as there is a ARPHRD_IEEE80211_PRISM
1252 * for DLT_PRISM_HEADER, so ARPHRD_IEEE80211_PRISM is used for
1253 * the AVS header, and the first 4 bytes of the header are used to
1254 * indicate whether it's a Prism header or an AVS header).
1257 prism_if_print(const struct pcap_pkthdr
*h
, const u_char
*p
)
1259 u_int caplen
= h
->caplen
;
1260 u_int length
= h
->len
;
1264 printf("[|802.11]");
1268 msgcode
= EXTRACT_32BITS(p
);
1269 if (msgcode
== WLANCAP_MAGIC_COOKIE_V1
||
1270 msgcode
== WLANCAP_MAGIC_COOKIE_V2
)
1271 return ieee802_11_avs_radio_print(p
, length
, caplen
);
1273 if (caplen
< PRISM_HDR_LEN
) {
1274 printf("[|802.11]");
1278 return PRISM_HDR_LEN
+ ieee802_11_print(p
+ PRISM_HDR_LEN
,
1279 length
- PRISM_HDR_LEN
, caplen
- PRISM_HDR_LEN
, 0);
1283 * For DLT_IEEE802_11_RADIO; like DLT_IEEE802_11, but with an extra
1284 * header, containing information such as radio information.
1287 ieee802_11_radio_if_print(const struct pcap_pkthdr
*h
, const u_char
*p
)
1289 return ieee802_11_radio_print(p
, h
->len
, h
->caplen
);
1293 * For DLT_IEEE802_11_RADIO_AVS; like DLT_IEEE802_11, but with an
1294 * extra header, containing information such as radio information,
1295 * which we currently ignore.
1298 ieee802_11_radio_avs_if_print(const struct pcap_pkthdr
*h
, const u_char
*p
)
1300 return ieee802_11_avs_radio_print(p
, h
->len
, h
->caplen
);