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