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