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.22.2.6 2003/12/10 09:52:33 guy Exp $ (LBL)";
32 #include <tcpdump-stdinc.h>
38 #include "interface.h"
39 #include "addrtoname.h"
40 #include "ethertype.h"
44 #include "ieee802_11.h"
46 #define PRINT_RATES(p) \
49 const char *sep = " ["; \
50 for (z = 0; z < p.rates.length ; z++) { \
51 printf("%s%2.1f", sep, (.5 * (p.rates.rate[z] & 0x7f))); \
52 if (p.rates.rate[z] & 0x80) printf("*"); \
55 if (p.rates.length != 0) \
59 static const char *auth_alg_text[]={"Open System","Shared Key","EAP"};
60 static const char *subtype_text[]={
78 static const char *status_text[] = {
80 "Unspecified failure", /* 1 */
89 "Cannot Support all requested capabilities in the Capability Information field", /* 10 */
90 "Reassociation denied due to inability to confirm that association exists", /* 11 */
91 "Association denied due to reason outside the scope of the standard", /* 12 */
92 "Responding station does not support the specified authentication algorithm ", /* 13 */
93 "Received an Authentication frame with authentication transaction " \
94 "sequence number out of expected sequence", /* 14 */
95 "Authentication rejected because of challenge failure", /* 15 */
96 "Authentication rejected due to timeout waiting for next frame in sequence", /* 16 */
97 "Association denied because AP is unable to handle additional associated stations", /* 17 */
98 "Association denied due to requesting station not supporting all of the " \
99 "data rates in BSSBasicRateSet parameter", /* 18 */
103 static const char *reason_text[] = {
105 "Unspecified reason", /* 1 */
106 "Previous authentication no longer valid", /* 2 */
107 "Deauthenticated because sending station is leaving (or has left) IBSS or ESS", /* 3 */
108 "Disassociated due to inactivity", /* 4 */
109 "Disassociated because AP is unable to handle all currently associated stations", /* 5 */
110 "Class 2 frame receivedfrom nonauthenticated station", /* 6 */
111 "Class 3 frame received from nonassociated station", /* 7 */
112 "Disassociated because sending station is leaving (or has left) BSS", /* 8 */
113 "Station requesting (re)association is not authenticated with responding station", /* 9 */
118 wep_print(const u_char *p)
122 if (!TTEST2(*p, IEEE802_11_IV_LEN + IEEE802_11_KID_LEN))
124 iv = EXTRACT_LE_32BITS(p);
126 printf("Data IV:%3x Pad %x KeyID %x", IV_IV(iv), IV_PAD(iv),
133 parse_elements(struct mgmt_body_t *pbody, const u_char *p, int offset)
136 if (!TTEST2(*(p + offset), 1))
138 switch (*(p + offset)) {
140 if (!TTEST2(*(p + offset), 2))
142 memcpy(&pbody->ssid, p + offset, 2);
144 if (pbody->ssid.length <= 0)
146 if (!TTEST2(*(p + offset), pbody->ssid.length))
148 memcpy(&pbody->ssid.ssid, p + offset,
150 offset += pbody->ssid.length;
151 pbody->ssid.ssid[pbody->ssid.length] = '\0';
154 if (!TTEST2(*(p + offset), 2))
156 memcpy(&pbody->challenge, p + offset, 2);
158 if (pbody->challenge.length <= 0)
160 if (!TTEST2(*(p + offset), pbody->challenge.length))
162 memcpy(&pbody->challenge.text, p + offset,
163 pbody->challenge.length);
164 offset += pbody->challenge.length;
165 pbody->challenge.text[pbody->challenge.length] = '\0';
168 if (!TTEST2(*(p + offset), 2))
170 memcpy(&(pbody->rates), p + offset, 2);
172 if (pbody->rates.length <= 0)
174 if (!TTEST2(*(p + offset), pbody->rates.length))
176 memcpy(&pbody->rates.rate, p + offset,
177 pbody->rates.length);
178 offset += pbody->rates.length;
181 if (!TTEST2(*(p + offset), 3))
183 memcpy(&pbody->ds, p + offset, 3);
187 if (!TTEST2(*(p + offset), 8))
189 memcpy(&pbody->cf, p + offset, 8);
193 if (!TTEST2(*(p + offset), 2))
195 memcpy(&pbody->tim, p + offset, 2);
197 if (!TTEST2(*(p + offset), 3))
199 memcpy(&pbody->tim.count, p + offset, 3);
202 if (pbody->tim.length <= 3)
204 if (!TTEST2(*(p + offset), pbody->tim.length - 3))
206 memcpy(pbody->tim.bitmap, p + (pbody->tim.length - 3),
207 (pbody->tim.length - 3));
208 offset += pbody->tim.length - 3;
212 printf("(1) unhandled element_id (%d) ",
215 offset += *(p + offset + 1) + 2;
222 /*********************************************************************************
223 * Print Handle functions for the management frame types
224 *********************************************************************************/
227 handle_beacon(const u_char *p)
229 struct mgmt_body_t pbody;
232 memset(&pbody, 0, sizeof(pbody));
234 if (!TTEST2(*p, IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN +
235 IEEE802_11_CAPINFO_LEN))
237 memcpy(&pbody.timestamp, p, 8);
238 offset += IEEE802_11_TSTAMP_LEN;
239 pbody.beacon_interval = EXTRACT_LE_16BITS(p+offset);
240 offset += IEEE802_11_BCNINT_LEN;
241 pbody.capability_info = EXTRACT_LE_16BITS(p+offset);
242 offset += IEEE802_11_CAPINFO_LEN;
244 if (!parse_elements(&pbody, p, offset))
248 fn_print(pbody.ssid.ssid, NULL);
251 printf(" %s CH: %u%s",
252 CAPABILITY_ESS(pbody.capability_info) ? "ESS" : "IBSS",
254 CAPABILITY_PRIVACY(pbody.capability_info) ? ", PRIVACY" : "" );
260 handle_assoc_request(const u_char *p)
262 struct mgmt_body_t pbody;
265 memset(&pbody, 0, sizeof(pbody));
267 if (!TTEST2(*p, IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN))
269 pbody.capability_info = EXTRACT_LE_16BITS(p);
270 offset += IEEE802_11_CAPINFO_LEN;
271 pbody.listen_interval = EXTRACT_LE_16BITS(p+offset);
272 offset += IEEE802_11_LISTENINT_LEN;
274 if (!parse_elements(&pbody, p, offset))
278 fn_print(pbody.ssid.ssid, NULL);
285 handle_assoc_response(const u_char *p)
287 struct mgmt_body_t pbody;
290 memset(&pbody, 0, sizeof(pbody));
292 if (!TTEST2(*p, IEEE802_11_CAPINFO_LEN + IEEE802_11_STATUS_LEN +
295 pbody.capability_info = EXTRACT_LE_16BITS(p);
296 offset += IEEE802_11_CAPINFO_LEN;
297 pbody.status_code = EXTRACT_LE_16BITS(p+offset);
298 offset += IEEE802_11_STATUS_LEN;
299 pbody.aid = EXTRACT_LE_16BITS(p+offset);
300 offset += IEEE802_11_AID_LEN;
302 if (!parse_elements(&pbody, p, offset))
305 printf(" AID(%x) :%s: %s", ((u_int16_t)(pbody.aid << 2 )) >> 2 ,
306 CAPABILITY_PRIVACY(pbody.capability_info) ? " PRIVACY " : "",
307 (pbody.status_code < 19 ? status_text[pbody.status_code] : "n/a"));
313 handle_reassoc_request(const u_char *p)
315 struct mgmt_body_t pbody;
318 memset(&pbody, 0, sizeof(pbody));
320 if (!TTEST2(*p, IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN +
323 pbody.capability_info = EXTRACT_LE_16BITS(p);
324 offset += IEEE802_11_CAPINFO_LEN;
325 pbody.listen_interval = EXTRACT_LE_16BITS(p+offset);
326 offset += IEEE802_11_LISTENINT_LEN;
327 memcpy(&pbody.ap, p+offset, IEEE802_11_AP_LEN);
328 offset += IEEE802_11_AP_LEN;
330 if (!parse_elements(&pbody, p, offset))
334 fn_print(pbody.ssid.ssid, NULL);
335 printf(") AP : %s", etheraddr_string( pbody.ap ));
341 handle_reassoc_response(const u_char *p)
343 /* Same as a Association Reponse */
344 return handle_assoc_response(p);
348 handle_probe_request(const u_char *p)
350 struct mgmt_body_t pbody;
353 memset(&pbody, 0, sizeof(pbody));
355 if (!parse_elements(&pbody, p, offset))
359 fn_print(pbody.ssid.ssid, NULL);
367 handle_probe_response(const u_char *p)
369 struct mgmt_body_t pbody;
372 memset(&pbody, 0, sizeof(pbody));
374 if (!TTEST2(*p, IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN +
375 IEEE802_11_CAPINFO_LEN))
378 memcpy(&pbody.timestamp, p, IEEE802_11_TSTAMP_LEN);
379 offset += IEEE802_11_TSTAMP_LEN;
380 pbody.beacon_interval = EXTRACT_LE_16BITS(p+offset);
381 offset += IEEE802_11_BCNINT_LEN;
382 pbody.capability_info = EXTRACT_LE_16BITS(p+offset);
383 offset += IEEE802_11_CAPINFO_LEN;
385 if (!parse_elements(&pbody, p, offset))
389 fn_print(pbody.ssid.ssid, NULL);
392 printf(" CH: %u%s", pbody.ds.channel,
393 CAPABILITY_PRIVACY(pbody.capability_info) ? ", PRIVACY" : "" );
401 /* the frame body for ATIM is null. */
406 handle_disassoc(const u_char *p)
408 struct mgmt_body_t pbody;
410 memset(&pbody, 0, sizeof(pbody));
412 if (!TTEST2(*p, IEEE802_11_REASON_LEN))
414 pbody.reason_code = EXTRACT_LE_16BITS(p);
417 (pbody.reason_code < 10) ? reason_text[pbody.reason_code]
424 handle_auth(const u_char *p)
426 struct mgmt_body_t pbody;
429 memset(&pbody, 0, sizeof(pbody));
433 pbody.auth_alg = EXTRACT_LE_16BITS(p);
435 pbody.auth_trans_seq_num = EXTRACT_LE_16BITS(p + offset);
437 pbody.status_code = EXTRACT_LE_16BITS(p + offset);
440 if (!parse_elements(&pbody, p, offset))
443 if ((pbody.auth_alg == 1) &&
444 ((pbody.auth_trans_seq_num == 2) ||
445 (pbody.auth_trans_seq_num == 3))) {
446 printf(" (%s)-%x [Challenge Text] %s",
447 (pbody.auth_alg < 4) ? auth_alg_text[pbody.auth_alg]
449 pbody.auth_trans_seq_num,
450 ((pbody.auth_trans_seq_num % 2)
451 ? ((pbody.status_code < 19)
452 ? status_text[pbody.status_code]
456 printf(" (%s)-%x: %s",
457 (pbody.auth_alg < 4) ? auth_alg_text[pbody.auth_alg] : "Reserved",
458 pbody.auth_trans_seq_num,
459 (pbody.auth_trans_seq_num % 2)
460 ? ((pbody.status_code < 19) ? status_text[pbody.status_code]
468 handle_deauth(const struct mgmt_header_t *pmh, const u_char *p)
470 struct mgmt_body_t pbody;
472 const char *reason = NULL;
474 memset(&pbody, 0, sizeof(pbody));
476 if (!TTEST2(*p, IEEE802_11_REASON_LEN))
478 pbody.reason_code = EXTRACT_LE_16BITS(p);
479 offset += IEEE802_11_REASON_LEN;
481 reason = (pbody.reason_code < 10) ? reason_text[pbody.reason_code]
485 printf(": %s", reason);
487 printf(" (%s): %s", etheraddr_string(pmh->sa), reason);
493 /*********************************************************************************
495 *********************************************************************************/
499 mgmt_body_print(u_int16_t fc, const struct mgmt_header_t *pmh,
502 printf("%s", subtype_text[FC_SUBTYPE(fc)]);
504 switch (FC_SUBTYPE(fc)) {
505 case ST_ASSOC_REQUEST:
506 return handle_assoc_request(p);
507 case ST_ASSOC_RESPONSE:
508 return handle_assoc_response(p);
509 case ST_REASSOC_REQUEST:
510 return handle_reassoc_request(p);
511 case ST_REASSOC_RESPONSE:
512 return handle_reassoc_response(p);
513 case ST_PROBE_REQUEST:
514 return handle_probe_request(p);
515 case ST_PROBE_RESPONSE:
516 return handle_probe_response(p);
518 return handle_beacon(p);
520 return handle_atim();
522 return handle_disassoc(p);
526 if ((p[0] == 0 ) && (p[1] == 0) && (p[2] == 0)) {
527 printf("Authentication (Shared-Key)-3 ");
530 return handle_auth(p);
532 return handle_deauth(pmh, p);
535 printf("Unhandled Management subtype(%x)",
542 /*********************************************************************************
543 * Handles printing all the control frame types
544 *********************************************************************************/
547 ctrl_body_print(u_int16_t fc, const u_char *p)
549 switch (FC_SUBTYPE(fc)) {
551 printf("Power Save-Poll");
552 if (!TTEST2(*p, CTRL_PS_POLL_HDRLEN))
555 EXTRACT_LE_16BITS(&(((const struct ctrl_ps_poll_t *)p)->aid)));
558 printf("Request-To-Send");
559 if (!TTEST2(*p, CTRL_RTS_HDRLEN))
563 etheraddr_string(((const struct ctrl_rts_t *)p)->ta));
566 printf("Clear-To-Send");
567 if (!TTEST2(*p, CTRL_CTS_HDRLEN))
571 etheraddr_string(((const struct ctrl_cts_t *)p)->ra));
574 printf("Acknowledgment");
575 if (!TTEST2(*p, CTRL_ACK_HDRLEN))
579 etheraddr_string(((const struct ctrl_ack_t *)p)->ra));
583 if (!TTEST2(*p, CTRL_END_HDRLEN))
587 etheraddr_string(((const struct ctrl_end_t *)p)->ra));
590 printf("CF-End+CF-Ack");
591 if (!TTEST2(*p, CTRL_END_ACK_HDRLEN))
595 etheraddr_string(((const struct ctrl_end_ack_t *)p)->ra));
598 printf("Unknown Ctrl Subtype");
608 * Data Frame - Address field contents
610 * To Ds | From DS | Addr 1 | Addr 2 | Addr 3 | Addr 4
611 * 0 | 0 | DA | SA | BSSID | n/a
612 * 0 | 1 | DA | BSSID | SA | n/a
613 * 1 | 0 | BSSID | SA | DA | n/a
614 * 1 | 1 | RA | TA | DA | SA
618 data_header_print(u_int16_t fc, const u_char *p, const u_int8_t **srcp,
619 const u_int8_t **dstp)
621 switch (FC_SUBTYPE(fc)) {
625 case DATA_DATA_CF_ACK:
626 case DATA_NODATA_CF_ACK:
629 case DATA_DATA_CF_POLL:
630 case DATA_NODATA_CF_POLL:
633 case DATA_DATA_CF_ACK_POLL:
634 case DATA_NODATA_CF_ACK_POLL:
635 printf("CF Ack/Poll ");
639 #define ADDR1 (p + 4)
640 #define ADDR2 (p + 10)
641 #define ADDR3 (p + 16)
642 #define ADDR4 (p + 24)
644 if (!FC_TO_DS(fc) && !FC_FROM_DS(fc)) {
651 printf("DA:%s SA:%s BSSID:%s ",
652 etheraddr_string(ADDR1), etheraddr_string(ADDR2),
653 etheraddr_string(ADDR3));
654 } else if (!FC_TO_DS(fc) && FC_FROM_DS(fc)) {
661 printf("DA:%s BSSID:%s SA:%s ",
662 etheraddr_string(ADDR1), etheraddr_string(ADDR2),
663 etheraddr_string(ADDR3));
664 } else if (FC_TO_DS(fc) && !FC_FROM_DS(fc)) {
671 printf("BSSID:%s SA:%s DA:%s ",
672 etheraddr_string(ADDR1), etheraddr_string(ADDR2),
673 etheraddr_string(ADDR3));
674 } else if (FC_TO_DS(fc) && FC_FROM_DS(fc)) {
681 printf("RA:%s TA:%s DA:%s SA:%s ",
682 etheraddr_string(ADDR1), etheraddr_string(ADDR2),
683 etheraddr_string(ADDR3), etheraddr_string(ADDR4));
693 mgmt_header_print(const u_char *p, const u_int8_t **srcp,
694 const u_int8_t **dstp)
696 const struct mgmt_header_t *hp = (const struct mgmt_header_t *) p;
705 printf("BSSID:%s DA:%s SA:%s ",
706 etheraddr_string((hp)->bssid), etheraddr_string((hp)->da),
707 etheraddr_string((hp)->sa));
711 ctrl_header_print(u_int16_t fc, const u_char *p, const u_int8_t **srcp,
712 const u_int8_t **dstp)
721 switch (FC_SUBTYPE(fc)) {
723 printf("BSSID:%s TA:%s ",
724 etheraddr_string(((const struct ctrl_ps_poll_t *)p)->bssid),
725 etheraddr_string(((const struct ctrl_ps_poll_t *)p)->ta));
728 printf("RA:%s TA:%s ",
729 etheraddr_string(((const struct ctrl_rts_t *)p)->ra),
730 etheraddr_string(((const struct ctrl_rts_t *)p)->ta));
734 etheraddr_string(((const struct ctrl_cts_t *)p)->ra));
738 etheraddr_string(((const struct ctrl_ack_t *)p)->ra));
741 printf("RA:%s BSSID:%s ",
742 etheraddr_string(((const struct ctrl_end_t *)p)->ra),
743 etheraddr_string(((const struct ctrl_end_t *)p)->bssid));
746 printf("RA:%s BSSID:%s ",
747 etheraddr_string(((const struct ctrl_end_ack_t *)p)->ra),
748 etheraddr_string(((const struct ctrl_end_ack_t *)p)->bssid));
751 printf("(H) Unknown Ctrl Subtype");
757 extract_header_length(u_int16_t fc)
759 switch (FC_TYPE(fc)) {
763 switch (FC_SUBTYPE(fc)) {
765 return CTRL_PS_POLL_HDRLEN;
767 return CTRL_RTS_HDRLEN;
769 return CTRL_CTS_HDRLEN;
771 return CTRL_ACK_HDRLEN;
773 return CTRL_END_HDRLEN;
775 return CTRL_END_ACK_HDRLEN;
780 return (FC_TO_DS(fc) && FC_FROM_DS(fc)) ? 30 : 24;
782 printf("unknown IEEE802.11 frame type (%d)", FC_TYPE(fc));
788 * Print the 802.11 MAC header if eflag is set, and set "*srcp" and "*dstp"
789 * to point to the source and destination MAC addresses in any case if
790 * "srcp" and "dstp" aren't null.
793 ieee_802_11_hdr_print(u_int16_t fc, const u_char *p, const u_int8_t **srcp,
794 const u_int8_t **dstp)
797 if (FC_MORE_DATA(fc))
798 printf("More Data ");
799 if (FC_MORE_FLAG(fc))
800 printf("More Fragments ");
801 if (FC_POWER_MGMT(fc))
806 printf("Strictly Ordered ");
808 printf("WEP Encrypted ");
809 if (FC_TYPE(fc) != T_CTRL || FC_SUBTYPE(fc) != CTRL_PS_POLL)
812 &((const struct mgmt_header_t *)p)->duration));
815 switch (FC_TYPE(fc)) {
817 mgmt_header_print(p, srcp, dstp);
820 ctrl_header_print(fc, p, srcp, dstp);
823 data_header_print(fc, p, srcp, dstp);
826 printf("(header) unknown IEEE802.11 frame type (%d)",
835 ieee802_11_print(const u_char *p, u_int length, u_int caplen)
839 const u_int8_t *src, *dst;
840 u_short extracted_ethertype;
842 if (caplen < IEEE802_11_FC_LEN) {
847 fc = EXTRACT_LE_16BITS(p);
848 hdrlen = extract_header_length(fc);
850 if (caplen < hdrlen) {
855 ieee_802_11_hdr_print(fc, p, &src, &dst);
858 * Go past the 802.11 header.
864 switch (FC_TYPE(fc)) {
866 if (!mgmt_body_print(fc,
867 (const struct mgmt_header_t *)(p - hdrlen), p)) {
873 if (!ctrl_body_print(fc, p - hdrlen)) {
879 /* There may be a problem w/ AP not having this bit set */
885 } else if (llc_print(p, length, caplen, dst, src,
886 &extracted_ethertype) == 0) {
888 * Some kinds of LLC packet we cannot
889 * handle intelligently
892 ieee_802_11_hdr_print(fc, p - hdrlen, NULL,
894 if (extracted_ethertype)
897 htons(extracted_ethertype)));
898 if (!xflag && !qflag)
899 default_print(p, caplen);
903 printf("unknown 802.11 frame type (%d)", FC_TYPE(fc));
911 * This is the top level routine of the printer. 'p' points
912 * to the 802.11 header of the packet, 'h->ts' is the timestamp,
913 * 'h->length' is the length of the packet off the wire, and 'h->caplen'
914 * is the number of bytes actually captured.
917 ieee802_11_if_print(const struct pcap_pkthdr *h, const u_char *p)
919 return ieee802_11_print(p, h->len, h->caplen);
923 ieee802_11_radio_print(const u_char *p, u_int length, u_int caplen)
925 u_int32_t caphdr_len;
927 caphdr_len = EXTRACT_32BITS(p + 4);
928 if (caphdr_len < 8) {
930 * Yow! The capture header length is claimed not
931 * to be large enough to include even the version
932 * cookie or capture header length!
938 if (caplen < caphdr_len) {
943 return caphdr_len + ieee802_11_print(p + caphdr_len,
944 length - caphdr_len, caplen - caphdr_len);
947 #define PRISM_HDR_LEN 144
949 #define WLANCAP_MAGIC_COOKIE_V1 0x80211001
952 * For DLT_PRISM_HEADER; like DLT_IEEE802_11, but with an extra header,
953 * containing information such as radio information, which we
956 * If, however, the packet begins with WLANCAP_MAGIC_COOKIE_V1, it's
957 * really DLT_IEEE802_11_RADIO (currently, on Linux, there's no
958 * ARPHRD_ type for DLT_IEEE802_11_RADIO, as there is a
959 * ARPHRD_IEEE80211_PRISM for DLT_PRISM_HEADER, so
960 * ARPHRD_IEEE80211_PRISM is used for DLT_IEEE802_11_RADIO, and
961 * the first 4 bytes of the header are used to indicate which it is).
964 prism_if_print(const struct pcap_pkthdr *h, const u_char *p)
966 u_int caplen = h->caplen;
967 u_int length = h->len;
974 if (EXTRACT_32BITS(p) == WLANCAP_MAGIC_COOKIE_V1)
975 return ieee802_11_radio_print(p, length, caplen);
977 if (caplen < PRISM_HDR_LEN) {
982 return PRISM_HDR_LEN + ieee802_11_print(p + PRISM_HDR_LEN,
983 length - PRISM_HDR_LEN, caplen - PRISM_HDR_LEN);
987 * For DLT_IEEE802_11_RADIO; like DLT_IEEE802_11, but with an extra
988 * header, containing information such as radio information, which we
992 ieee802_11_radio_if_print(const struct pcap_pkthdr *h, const u_char *p)
994 u_int caplen = h->caplen;
995 u_int length = h->len;
1002 return ieee802_11_radio_print(p, length, caplen);