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