print-802_11.c revision 172686
1/* $FreeBSD: head/contrib/tcpdump/print-802_11.c 172686 2007-10-16 02:31:48Z mlaier $ */
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
25static 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
99static 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
120static 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
123static 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
148static 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
162static int
163wep_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
177static void
178parse_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
318static int
319handle_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
347static int
348handle_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
369static int
370handle_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
398static int
399handle_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
424static int
425handle_reassoc_response(const u_char *p)
426{
427	/* Same as a Association Reponse */
428	return handle_assoc_response(p);
429}
430
431static int
432handle_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
447static int
448handle_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
475static int
476handle_atim(void)
477{
478	/* the frame body for ATIM is null. */
479	return 1;
480}
481
482static int
483handle_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
501static int
502handle_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
548static int
549handle_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
580static int
581mgmt_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
637static int
638ctrl_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
719static void
720data_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
795static void
796mgmt_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
813static void
814ctrl_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
866static int
867extract_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 */
909static inline void
910ieee_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
955static u_int
956ieee802_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 */
1041u_int
1042ieee802_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
1071static void
1072print_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
1105static int
1106print_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
1242static u_int
1243ieee802_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	}
1313out:
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
1323static u_int
1324ieee802_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 */
1364u_int
1365prism_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 */
1392u_int
1393ieee802_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