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#include <sys/cdefs.h>
24#ifndef lint
25#if 0
26static const char rcsid[] _U_ =
27    "@(#) Header: /tcpdump/master/tcpdump/print-802_11.c,v 1.49 2007-12-29 23:25:02 guy Exp (LBL)";
28#else
29__RCSID("$NetBSD$");
30#endif
31#endif
32
33#ifdef HAVE_CONFIG_H
34#include "config.h"
35#endif
36
37#include <tcpdump-stdinc.h>
38
39#include <stdio.h>
40#include <pcap.h>
41#include <string.h>
42
43#include "interface.h"
44#include "addrtoname.h"
45#include "ethertype.h"
46
47#include "extract.h"
48
49#include "cpack.h"
50
51#include "ieee802_11.h"
52#include "ieee802_11_radio.h"
53
54#define PRINT_SSID(p) \
55	if (p.ssid_present) { \
56		printf(" ("); \
57		fn_print(p.ssid.ssid, NULL); \
58		printf(")"); \
59	}
60
61#define PRINT_RATE(_sep, _r, _suf) \
62	printf("%s%2.1f%s", _sep, (.5 * ((_r) & 0x7f)), _suf)
63#define PRINT_RATES(p) \
64	if (p.rates_present) { \
65		int z; \
66		const char *sep = " ["; \
67		for (z = 0; z < p.rates.length ; z++) { \
68			PRINT_RATE(sep, p.rates.rate[z], \
69				(p.rates.rate[z] & 0x80 ? "*" : "")); \
70			sep = " "; \
71		} \
72		if (p.rates.length != 0) \
73			printf(" Mbit]"); \
74	}
75
76#define PRINT_DS_CHANNEL(p) \
77	if (p.ds_present) \
78		printf(" CH: %u", p.ds.channel); \
79	printf("%s", \
80	    CAPABILITY_PRIVACY(p.capability_info) ? ", PRIVACY" : "" );
81
82static const int ieee80211_htrates[16] = {
83	13,		/* IFM_IEEE80211_MCS0 */
84	26,		/* IFM_IEEE80211_MCS1 */
85	39,		/* IFM_IEEE80211_MCS2 */
86	52,		/* IFM_IEEE80211_MCS3 */
87	78,		/* IFM_IEEE80211_MCS4 */
88	104,		/* IFM_IEEE80211_MCS5 */
89	117,		/* IFM_IEEE80211_MCS6 */
90	130,		/* IFM_IEEE80211_MCS7 */
91	26,		/* IFM_IEEE80211_MCS8 */
92	52,		/* IFM_IEEE80211_MCS9 */
93	78,		/* IFM_IEEE80211_MCS10 */
94	104,		/* IFM_IEEE80211_MCS11 */
95	156,		/* IFM_IEEE80211_MCS12 */
96	208,		/* IFM_IEEE80211_MCS13 */
97	234,		/* IFM_IEEE80211_MCS14 */
98	260,		/* IFM_IEEE80211_MCS15 */
99};
100#define PRINT_HT_RATE(_sep, _r, _suf) \
101	printf("%s%.1f%s", _sep, (.5 * ieee80211_htrates[(_r) & 0xf]), _suf)
102
103static const char *auth_alg_text[]={"Open System","Shared Key","EAP"};
104#define NUM_AUTH_ALGS	(sizeof auth_alg_text / sizeof auth_alg_text[0])
105
106static const char *status_text[] = {
107	"Succesful",						/*  0 */
108	"Unspecified failure",					/*  1 */
109	"Reserved",						/*  2 */
110	"Reserved",						/*  3 */
111	"Reserved",						/*  4 */
112	"Reserved",						/*  5 */
113	"Reserved",						/*  6 */
114	"Reserved",						/*  7 */
115	"Reserved",						/*  8 */
116	"Reserved",						/*  9 */
117	"Cannot Support all requested capabilities in the Capability "
118	  "Information field",	  				/* 10 */
119	"Reassociation denied due to inability to confirm that association "
120	  "exists",						/* 11 */
121	"Association denied due to reason outside the scope of the "
122	  "standard",						/* 12 */
123	"Responding station does not support the specified authentication "
124	  "algorithm ",						/* 13 */
125	"Received an Authentication frame with authentication transaction "
126	  "sequence number out of expected sequence",		/* 14 */
127	"Authentication rejected because of challenge failure",	/* 15 */
128	"Authentication rejected due to timeout waiting for next frame in "
129	  "sequence",	  					/* 16 */
130	"Association denied because AP is unable to handle additional"
131	  "associated stations",	  			/* 17 */
132	"Association denied due to requesting station not supporting all of "
133	  "the data rates in BSSBasicRateSet parameter",	/* 18 */
134	"Association denied due to requesting station not supporting "
135	  "short preamble operation",				/* 19 */
136	"Association denied due to requesting station not supporting "
137	  "PBCC encoding",					/* 20 */
138	"Association denied due to requesting station not supporting "
139	  "channel agility",					/* 21 */
140	"Association request rejected because Spectrum Management "
141	  "capability is required",				/* 22 */
142	"Association request rejected because the information in the "
143	  "Power Capability element is unacceptable",		/* 23 */
144	"Association request rejected because the information in the "
145	  "Supported Channels element is unacceptable",		/* 24 */
146	"Association denied due to requesting station not supporting "
147	  "short slot operation",				/* 25 */
148	"Association denied due to requesting station not supporting "
149	  "DSSS-OFDM operation",				/* 26 */
150	"Association denied because the requested STA does not support HT "
151	  "features",						/* 27 */
152	"Reserved",						/* 28 */
153	"Association denied because the requested STA does not support "
154	  "the PCO transition time required by the AP",		/* 29 */
155	"Reserved",						/* 30 */
156	"Reserved",						/* 31 */
157	"Unspecified, QoS-related failure",			/* 32 */
158	"Association denied due to QAP having insufficient bandwidth "
159	  "to handle another QSTA",				/* 33 */
160	"Association denied due to excessive frame loss rates and/or "
161	  "poor conditions on current operating channel",	/* 34 */
162	"Association (with QBSS) denied due to requesting station not "
163	  "supporting the QoS facility",			/* 35 */
164	"Association denied due to requesting station not supporting "
165	  "Block Ack",						/* 36 */
166	"The request has been declined",			/* 37 */
167	"The request has not been successful as one or more parameters "
168	  "have invalid values",				/* 38 */
169	"The TS has not been created because the request cannot be honored. "
170	  "However, a suggested TSPEC is provided so that the initiating QSTA"
171	  "may attempt to set another TS with the suggested changes to the "
172	  "TSPEC",						/* 39 */
173	"Invalid Information Element",				/* 40 */
174	"Group Cipher is not valid",				/* 41 */
175	"Pairwise Cipher is not valid",				/* 42 */
176	"AKMP is not valid",					/* 43 */
177	"Unsupported RSN IE version",				/* 44 */
178	"Invalid RSN IE Capabilities",				/* 45 */
179	"Cipher suite is rejected per security policy",		/* 46 */
180	"The TS has not been created. However, the HC may be capable of "
181	  "creating a TS, in response to a request, after the time indicated "
182	  "in the TS Delay element",				/* 47 */
183	"Direct Link is not allowed in the BSS by policy",	/* 48 */
184	"Destination STA is not present within this QBSS.",	/* 49 */
185	"The Destination STA is not a QSTA.",			/* 50 */
186
187};
188#define NUM_STATUSES	(sizeof status_text / sizeof status_text[0])
189
190static const char *reason_text[] = {
191	"Reserved",						/* 0 */
192	"Unspecified reason",					/* 1 */
193	"Previous authentication no longer valid",  		/* 2 */
194	"Deauthenticated because sending station is leaving (or has left) "
195	  "IBSS or ESS",					/* 3 */
196	"Disassociated due to inactivity",			/* 4 */
197	"Disassociated because AP is unable to handle all currently "
198	  " associated stations",				/* 5 */
199	"Class 2 frame received from nonauthenticated station", /* 6 */
200	"Class 3 frame received from nonassociated station",	/* 7 */
201	"Disassociated because sending station is leaving "
202	  "(or has left) BSS",					/* 8 */
203	"Station requesting (re)association is not authenticated with "
204	  "responding station",					/* 9 */
205	"Disassociated because the information in the Power Capability "
206	  "element is unacceptable",				/* 10 */
207	"Disassociated because the information in the SupportedChannels "
208	  "element is unacceptable",				/* 11 */
209	"Invalid Information Element",				/* 12 */
210	"Reserved",						/* 13 */
211	"Michael MIC failure",					/* 14 */
212	"4-Way Handshake timeout",				/* 15 */
213	"Group key update timeout",				/* 16 */
214	"Information element in 4-Way Handshake different from (Re)Association"
215	  "Request/Probe Response/Beacon",			/* 17 */
216	"Group Cipher is not valid",				/* 18 */
217	"AKMP is not valid",					/* 20 */
218	"Unsupported RSN IE version",				/* 21 */
219	"Invalid RSN IE Capabilities",				/* 22 */
220	"IEEE 802.1X Authentication failed",			/* 23 */
221	"Cipher suite is rejected per security policy",		/* 24 */
222	"Reserved",						/* 25 */
223	"Reserved",						/* 26 */
224	"Reserved",						/* 27 */
225	"Reserved",						/* 28 */
226	"Reserved",						/* 29 */
227	"Reserved",						/* 30 */
228	"TS deleted because QoS AP lacks sufficient bandwidth for this "
229	  "QoS STA due to a change in BSS service characteristics or "
230	  "operational mode (e.g. an HT BSS change from 40 MHz channel "
231	  "to 20 MHz channel)",					/* 31 */
232	"Disassociated for unspecified, QoS-related reason",	/* 32 */
233	"Disassociated because QoS AP lacks sufficient bandwidth for this "
234	  "QoS STA",						/* 33 */
235	"Disassociated because of excessive number of frames that need to be "
236          "acknowledged, but are not acknowledged for AP transmissions "
237	  "and/or poor channel conditions",			/* 34 */
238	"Disassociated because STA is transmitting outside the limits "
239	  "of its TXOPs",					/* 35 */
240	"Requested from peer STA as the STA is leaving the BSS "
241	  "(or resetting)",					/* 36 */
242	"Requested from peer STA as it does not want to use the "
243	  "mechanism",						/* 37 */
244	"Requested from peer STA as the STA received frames using the "
245	  "mechanism for which a set up is required",		/* 38 */
246	"Requested from peer STA due to time out",		/* 39 */
247	"Reserved",						/* 40 */
248	"Reserved",						/* 41 */
249	"Reserved",						/* 42 */
250	"Reserved",						/* 43 */
251	"Reserved",						/* 44 */
252	"Peer STA does not support the requested cipher suite",	/* 45 */
253	"Association denied due to requesting STA not supporting HT "
254	  "features",						/* 46 */
255};
256#define NUM_REASONS	(sizeof reason_text / sizeof reason_text[0])
257
258static int
259wep_print(const u_char *p)
260{
261	u_int32_t iv;
262
263	if (!TTEST2(*p, IEEE802_11_IV_LEN + IEEE802_11_KID_LEN))
264		return 0;
265	iv = EXTRACT_LE_32BITS(p);
266
267	printf("Data IV:%3x Pad %x KeyID %x", IV_IV(iv), IV_PAD(iv),
268	    IV_KEYID(iv));
269
270	return 1;
271}
272
273static int
274parse_elements(struct mgmt_body_t *pbody, const u_char *p, int offset,
275    u_int length)
276{
277	struct ssid_t ssid;
278	struct challenge_t challenge;
279	struct rates_t rates;
280	struct ds_t ds;
281	struct cf_t cf;
282	struct tim_t tim;
283
284	/*
285	 * We haven't seen any elements yet.
286	 */
287	pbody->challenge_present = 0;
288	pbody->ssid_present = 0;
289	pbody->rates_present = 0;
290	pbody->ds_present = 0;
291	pbody->cf_present = 0;
292	pbody->tim_present = 0;
293
294	while (length != 0) {
295		if (!TTEST2(*(p + offset), 1))
296			return 0;
297		if (length < 1)
298			return 0;
299		switch (*(p + offset)) {
300		case E_SSID:
301			if (!TTEST2(*(p + offset), 2))
302				return 0;
303			if (length < 2)
304				return 0;
305			memcpy(&ssid, p + offset, 2);
306			offset += 2;
307			length -= 2;
308			if (ssid.length != 0) {
309				if (ssid.length > sizeof(ssid.ssid) - 1)
310					return 0;
311				if (!TTEST2(*(p + offset), ssid.length))
312					return 0;
313				if (length < ssid.length)
314					return 0;
315				memcpy(&ssid.ssid, p + offset, ssid.length);
316				offset += ssid.length;
317				length -= ssid.length;
318			}
319			ssid.ssid[ssid.length] = '\0';
320			/*
321			 * Present and not truncated.
322			 *
323			 * If we haven't already seen an SSID IE,
324			 * copy this one, otherwise ignore this one,
325			 * so we later report the first one we saw.
326			 */
327			if (!pbody->ssid_present) {
328				pbody->ssid = ssid;
329				pbody->ssid_present = 1;
330			}
331			break;
332		case E_CHALLENGE:
333			if (!TTEST2(*(p + offset), 2))
334				return 0;
335			if (length < 2)
336				return 0;
337			memcpy(&challenge, p + offset, 2);
338			offset += 2;
339			length -= 2;
340			if (challenge.length != 0) {
341				if (challenge.length >
342				    sizeof(challenge.text) - 1)
343					return 0;
344				if (!TTEST2(*(p + offset), challenge.length))
345					return 0;
346				if (length < challenge.length)
347					return 0;
348				memcpy(&challenge.text, p + offset,
349				    challenge.length);
350				offset += challenge.length;
351				length -= challenge.length;
352			}
353			challenge.text[challenge.length] = '\0';
354			/*
355			 * Present and not truncated.
356			 *
357			 * If we haven't already seen a challenge IE,
358			 * copy this one, otherwise ignore this one,
359			 * so we later report the first one we saw.
360			 */
361			if (!pbody->challenge_present) {
362				pbody->challenge = challenge;
363				pbody->challenge_present = 1;
364			}
365			break;
366		case E_RATES:
367			if (!TTEST2(*(p + offset), 2))
368				return 0;
369			if (length < 2)
370				return 0;
371			memcpy(&rates, p + offset, 2);
372			offset += 2;
373			length -= 2;
374			if (rates.length != 0) {
375				if (rates.length > sizeof rates.rate)
376					return 0;
377				if (!TTEST2(*(p + offset), rates.length))
378					return 0;
379				if (length < rates.length)
380					return 0;
381				memcpy(&rates.rate, p + offset, rates.length);
382				offset += rates.length;
383				length -= rates.length;
384			}
385			/*
386			 * Present and not truncated.
387			 *
388			 * If we haven't already seen a rates IE,
389			 * copy this one if it's not zero-length,
390			 * otherwise ignore this one, so we later
391			 * report the first one we saw.
392			 *
393			 * We ignore zero-length rates IEs as some
394			 * devices seem to put a zero-length rates
395			 * IE, followed by an SSID IE, followed by
396			 * a non-zero-length rates IE into frames,
397			 * even though IEEE Std 802.11-2007 doesn't
398			 * seem to indicate that a zero-length rates
399			 * IE is valid.
400			 */
401			if (!pbody->rates_present && rates.length != 0) {
402				pbody->rates = rates;
403				pbody->rates_present = 1;
404			}
405			break;
406		case E_DS:
407			if (!TTEST2(*(p + offset), 3))
408				return 0;
409			if (length < 3)
410				return 0;
411			memcpy(&ds, p + offset, 3);
412			offset += 3;
413			length -= 3;
414			/*
415			 * Present and not truncated.
416			 *
417			 * If we haven't already seen a DS IE,
418			 * copy this one, otherwise ignore this one,
419			 * so we later report the first one we saw.
420			 */
421			if (!pbody->ds_present) {
422				pbody->ds = ds;
423				pbody->ds_present = 1;
424			}
425			break;
426		case E_CF:
427			if (!TTEST2(*(p + offset), 8))
428				return 0;
429			if (length < 8)
430				return 0;
431			memcpy(&cf, p + offset, 8);
432			offset += 8;
433			length -= 8;
434			/*
435			 * Present and not truncated.
436			 *
437			 * If we haven't already seen a CF IE,
438			 * copy this one, otherwise ignore this one,
439			 * so we later report the first one we saw.
440			 */
441			if (!pbody->cf_present) {
442				pbody->cf = cf;
443				pbody->cf_present = 1;
444			}
445			break;
446		case E_TIM:
447			if (!TTEST2(*(p + offset), 2))
448				return 0;
449			if (length < 2)
450				return 0;
451			memcpy(&tim, p + offset, 2);
452			offset += 2;
453			length -= 2;
454			if (!TTEST2(*(p + offset), 3))
455				return 0;
456			if (length < 3)
457				return 0;
458			memcpy(&tim.count, p + offset, 3);
459			offset += 3;
460			length -= 3;
461
462			if (tim.length <= 3)
463				break;
464			if (tim.length - 3 > (int)sizeof tim.bitmap)
465				return 0;
466			if (!TTEST2(*(p + offset), tim.length - 3))
467				return 0;
468			if (length < (u_int)(tim.length - 3))
469				return 0;
470			memcpy(tim.bitmap, p + (tim.length - 3),
471			    (tim.length - 3));
472			offset += tim.length - 3;
473			length -= tim.length - 3;
474			/*
475			 * Present and not truncated.
476			 *
477			 * If we haven't already seen a TIM IE,
478			 * copy this one, otherwise ignore this one,
479			 * so we later report the first one we saw.
480			 */
481			if (!pbody->tim_present) {
482				pbody->tim = tim;
483				pbody->tim_present = 1;
484			}
485			break;
486		default:
487#if 0
488			printf("(1) unhandled element_id (%d)  ",
489			    *(p + offset));
490#endif
491			if (!TTEST2(*(p + offset), 2))
492				return 0;
493			if (length < 2)
494				return 0;
495			if (!TTEST2(*(p + offset + 2), *(p + offset + 1)))
496				return 0;
497			if (length < (u_int)(*(p + offset + 1) + 2))
498				return 0;
499			offset += *(p + offset + 1) + 2;
500			length -= *(p + offset + 1) + 2;
501			break;
502		}
503	}
504
505	/* No problems found. */
506	return 1;
507}
508
509/*********************************************************************************
510 * Print Handle functions for the management frame types
511 *********************************************************************************/
512
513static int
514handle_beacon(const u_char *p, u_int length)
515{
516	struct mgmt_body_t pbody;
517	int offset = 0;
518	int ret;
519
520	memset(&pbody, 0, sizeof(pbody));
521
522	if (!TTEST2(*p, IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN +
523	    IEEE802_11_CAPINFO_LEN))
524		return 0;
525	if (length < IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN +
526	    IEEE802_11_CAPINFO_LEN)
527		return 0;
528	memcpy(&pbody.timestamp, p, IEEE802_11_TSTAMP_LEN);
529	offset += IEEE802_11_TSTAMP_LEN;
530	length -= IEEE802_11_TSTAMP_LEN;
531	pbody.beacon_interval = EXTRACT_LE_16BITS(p+offset);
532	offset += IEEE802_11_BCNINT_LEN;
533	length -= IEEE802_11_BCNINT_LEN;
534	pbody.capability_info = EXTRACT_LE_16BITS(p+offset);
535	offset += IEEE802_11_CAPINFO_LEN;
536	length -= IEEE802_11_CAPINFO_LEN;
537
538	ret = parse_elements(&pbody, p, offset, length);
539
540	PRINT_SSID(pbody);
541	PRINT_RATES(pbody);
542	printf(" %s",
543	    CAPABILITY_ESS(pbody.capability_info) ? "ESS" : "IBSS");
544	PRINT_DS_CHANNEL(pbody);
545
546	return ret;
547}
548
549static int
550handle_assoc_request(const u_char *p, u_int length)
551{
552	struct mgmt_body_t pbody;
553	int offset = 0;
554	int ret;
555
556	memset(&pbody, 0, sizeof(pbody));
557
558	if (!TTEST2(*p, IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN))
559		return 0;
560	if (length < IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN)
561		return 0;
562	pbody.capability_info = EXTRACT_LE_16BITS(p);
563	offset += IEEE802_11_CAPINFO_LEN;
564	length -= IEEE802_11_CAPINFO_LEN;
565	pbody.listen_interval = EXTRACT_LE_16BITS(p+offset);
566	offset += IEEE802_11_LISTENINT_LEN;
567	length -= IEEE802_11_LISTENINT_LEN;
568
569	ret = parse_elements(&pbody, p, offset, length);
570
571	PRINT_SSID(pbody);
572	PRINT_RATES(pbody);
573	return ret;
574}
575
576static int
577handle_assoc_response(const u_char *p, u_int length)
578{
579	struct mgmt_body_t pbody;
580	int offset = 0;
581	int ret;
582
583	memset(&pbody, 0, sizeof(pbody));
584
585	if (!TTEST2(*p, IEEE802_11_CAPINFO_LEN + IEEE802_11_STATUS_LEN +
586	    IEEE802_11_AID_LEN))
587		return 0;
588	if (length < IEEE802_11_CAPINFO_LEN + IEEE802_11_STATUS_LEN +
589	    IEEE802_11_AID_LEN)
590		return 0;
591	pbody.capability_info = EXTRACT_LE_16BITS(p);
592	offset += IEEE802_11_CAPINFO_LEN;
593	length -= IEEE802_11_CAPINFO_LEN;
594	pbody.status_code = EXTRACT_LE_16BITS(p+offset);
595	offset += IEEE802_11_STATUS_LEN;
596	length -= IEEE802_11_STATUS_LEN;
597	pbody.aid = EXTRACT_LE_16BITS(p+offset);
598	offset += IEEE802_11_AID_LEN;
599	length -= IEEE802_11_AID_LEN;
600
601	ret = parse_elements(&pbody, p, offset, length);
602
603	printf(" AID(%x) :%s: %s", ((u_int16_t)(pbody.aid << 2 )) >> 2 ,
604	    CAPABILITY_PRIVACY(pbody.capability_info) ? " PRIVACY " : "",
605	    (pbody.status_code < NUM_STATUSES
606		? status_text[pbody.status_code]
607		: "n/a"));
608
609	return ret;
610}
611
612static int
613handle_reassoc_request(const u_char *p, u_int length)
614{
615	struct mgmt_body_t pbody;
616	int offset = 0;
617	int ret;
618
619	memset(&pbody, 0, sizeof(pbody));
620
621	if (!TTEST2(*p, IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN +
622	    IEEE802_11_AP_LEN))
623		return 0;
624	if (length < IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN +
625	    IEEE802_11_AP_LEN)
626		return 0;
627	pbody.capability_info = EXTRACT_LE_16BITS(p);
628	offset += IEEE802_11_CAPINFO_LEN;
629	length -= IEEE802_11_CAPINFO_LEN;
630	pbody.listen_interval = EXTRACT_LE_16BITS(p+offset);
631	offset += IEEE802_11_LISTENINT_LEN;
632	length -= IEEE802_11_LISTENINT_LEN;
633	memcpy(&pbody.ap, p+offset, IEEE802_11_AP_LEN);
634	offset += IEEE802_11_AP_LEN;
635	length -= IEEE802_11_AP_LEN;
636
637	ret = parse_elements(&pbody, p, offset, length);
638
639	PRINT_SSID(pbody);
640	printf(" AP : %s", etheraddr_string( pbody.ap ));
641
642	return ret;
643}
644
645static int
646handle_reassoc_response(const u_char *p, u_int length)
647{
648	/* Same as a Association Reponse */
649	return handle_assoc_response(p, length);
650}
651
652static int
653handle_probe_request(const u_char *p, u_int length)
654{
655	struct mgmt_body_t  pbody;
656	int offset = 0;
657	int ret;
658
659	memset(&pbody, 0, sizeof(pbody));
660
661	ret = parse_elements(&pbody, p, offset, length);
662
663	PRINT_SSID(pbody);
664	PRINT_RATES(pbody);
665
666	return ret;
667}
668
669static int
670handle_probe_response(const u_char *p, u_int length)
671{
672	struct mgmt_body_t  pbody;
673	int offset = 0;
674	int ret;
675
676	memset(&pbody, 0, sizeof(pbody));
677
678	if (!TTEST2(*p, IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN +
679	    IEEE802_11_CAPINFO_LEN))
680		return 0;
681	if (length < IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN +
682	    IEEE802_11_CAPINFO_LEN)
683		return 0;
684	memcpy(&pbody.timestamp, p, IEEE802_11_TSTAMP_LEN);
685	offset += IEEE802_11_TSTAMP_LEN;
686	length -= IEEE802_11_TSTAMP_LEN;
687	pbody.beacon_interval = EXTRACT_LE_16BITS(p+offset);
688	offset += IEEE802_11_BCNINT_LEN;
689	length -= IEEE802_11_BCNINT_LEN;
690	pbody.capability_info = EXTRACT_LE_16BITS(p+offset);
691	offset += IEEE802_11_CAPINFO_LEN;
692	length -= IEEE802_11_CAPINFO_LEN;
693
694	ret = parse_elements(&pbody, p, offset, length);
695
696	PRINT_SSID(pbody);
697	PRINT_RATES(pbody);
698	PRINT_DS_CHANNEL(pbody);
699
700	return ret;
701}
702
703static int
704handle_atim(void)
705{
706	/* the frame body for ATIM is null. */
707	return 1;
708}
709
710static int
711handle_disassoc(const u_char *p, u_int length)
712{
713	struct mgmt_body_t  pbody;
714
715	memset(&pbody, 0, sizeof(pbody));
716
717	if (!TTEST2(*p, IEEE802_11_REASON_LEN))
718		return 0;
719	if (length < IEEE802_11_REASON_LEN)
720		return 0;
721	pbody.reason_code = EXTRACT_LE_16BITS(p);
722
723	printf(": %s",
724	    (pbody.reason_code < NUM_REASONS)
725		? reason_text[pbody.reason_code]
726		: "Reserved" );
727
728	return 1;
729}
730
731static int
732handle_auth(const u_char *p, u_int length)
733{
734	struct mgmt_body_t  pbody;
735	int offset = 0;
736	int ret;
737
738	memset(&pbody, 0, sizeof(pbody));
739
740	if (!TTEST2(*p, 6))
741		return 0;
742	if (length < 6)
743		return 0;
744	pbody.auth_alg = EXTRACT_LE_16BITS(p);
745	offset += 2;
746	length -= 2;
747	pbody.auth_trans_seq_num = EXTRACT_LE_16BITS(p + offset);
748	offset += 2;
749	length -= 2;
750	pbody.status_code = EXTRACT_LE_16BITS(p + offset);
751	offset += 2;
752	length -= 2;
753
754	ret = parse_elements(&pbody, p, offset, length);
755
756	if ((pbody.auth_alg == 1) &&
757	    ((pbody.auth_trans_seq_num == 2) ||
758	     (pbody.auth_trans_seq_num == 3))) {
759		printf(" (%s)-%x [Challenge Text] %s",
760		    (pbody.auth_alg < NUM_AUTH_ALGS)
761			? auth_alg_text[pbody.auth_alg]
762			: "Reserved",
763		    pbody.auth_trans_seq_num,
764		    ((pbody.auth_trans_seq_num % 2)
765		        ? ((pbody.status_code < NUM_STATUSES)
766			       ? status_text[pbody.status_code]
767			       : "n/a") : ""));
768		return ret;
769	}
770	printf(" (%s)-%x: %s",
771	    (pbody.auth_alg < NUM_AUTH_ALGS)
772		? auth_alg_text[pbody.auth_alg]
773		: "Reserved",
774	    pbody.auth_trans_seq_num,
775	    (pbody.auth_trans_seq_num % 2)
776	        ? ((pbody.status_code < NUM_STATUSES)
777		    ? status_text[pbody.status_code]
778	            : "n/a")
779	        : "");
780
781	return ret;
782}
783
784static int
785handle_deauth(const struct mgmt_header_t *pmh, const u_char *p, u_int length)
786{
787	struct mgmt_body_t  pbody;
788	int offset = 0;
789	const char *reason = NULL;
790
791	memset(&pbody, 0, sizeof(pbody));
792
793	if (!TTEST2(*p, IEEE802_11_REASON_LEN))
794		return 0;
795	if (length < IEEE802_11_REASON_LEN)
796		return 0;
797	pbody.reason_code = EXTRACT_LE_16BITS(p);
798	offset += IEEE802_11_REASON_LEN;
799	length -= IEEE802_11_REASON_LEN;
800
801	reason = (pbody.reason_code < NUM_REASONS)
802			? reason_text[pbody.reason_code]
803			: "Reserved";
804
805	if (eflag) {
806		printf(": %s", reason);
807	} else {
808		printf(" (%s): %s", etheraddr_string(pmh->sa), reason);
809	}
810	return 1;
811}
812
813#define	PRINT_HT_ACTION(v) (\
814	(v) == 0 ? printf("TxChWidth") : \
815	(v) == 1 ? printf("MIMOPwrSave") : \
816		   printf("Act#%d", (v)) \
817)
818#define	PRINT_BA_ACTION(v) (\
819	(v) == 0 ? printf("ADDBA Request") : \
820	(v) == 1 ? printf("ADDBA Response") : \
821	(v) == 2 ? printf("DELBA") : \
822		   printf("Act#%d", (v)) \
823)
824#define	PRINT_MESHLINK_ACTION(v) (\
825	(v) == 0 ? printf("Request") : \
826	(v) == 1 ? printf("Report") : \
827		   printf("Act#%d", (v)) \
828)
829#define	PRINT_MESHPEERING_ACTION(v) (\
830	(v) == 0 ? printf("Open") : \
831	(v) == 1 ? printf("Confirm") : \
832	(v) == 2 ? printf("Close") : \
833		   printf("Act#%d", (v)) \
834)
835#define	PRINT_MESHPATH_ACTION(v) (\
836	(v) == 0 ? printf("Request") : \
837	(v) == 1 ? printf("Report") : \
838	(v) == 2 ? printf("Error") : \
839	(v) == 3 ? printf("RootAnnouncement") : \
840		   printf("Act#%d", (v)) \
841)
842
843static int
844handle_action(const struct mgmt_header_t *pmh, const u_char *p, u_int length)
845{
846	if (!TTEST2(*p, 2))
847		return 0;
848	if (length < 2)
849		return 0;
850	if (eflag) {
851		printf(": ");
852	} else {
853		printf(" (%s): ", etheraddr_string(pmh->sa));
854	}
855	switch (p[0]) {
856	case 0: printf("Spectrum Management Act#%d", p[1]); break;
857	case 1: printf("QoS Act#%d", p[1]); break;
858	case 2: printf("DLS Act#%d", p[1]); break;
859	case 3: printf("BA "); PRINT_BA_ACTION(p[1]); break;
860	case 7: printf("HT "); PRINT_HT_ACTION(p[1]); break;
861	case 13: printf("MeshLMetric "); PRINT_MESHLINK_ACTION(p[1]); break;
862	case 15: printf("Interwork Act#%d", p[1]); break;
863	case 16: printf("Resource Act#%d", p[1]); break;
864	case 17: printf("Proxy Act#%d", p[1]); break;
865	case 30: printf("MeshPeering "); PRINT_MESHPEERING_ACTION(p[1]); break;
866	case 32: printf("MeshPath "); PRINT_MESHPATH_ACTION(p[1]); break;
867	case 127: printf("Vendor Act#%d", p[1]); break;
868	default:
869		printf("Reserved(%d) Act#%d", p[0], p[1]);
870		break;
871	}
872	return 1;
873}
874
875
876/*********************************************************************************
877 * Print Body funcs
878 *********************************************************************************/
879
880
881static int
882mgmt_body_print(u_int16_t fc, const struct mgmt_header_t *pmh,
883    const u_char *p, u_int length)
884{
885	switch (FC_SUBTYPE(fc)) {
886	case ST_ASSOC_REQUEST:
887		printf("Assoc Request");
888		return handle_assoc_request(p, length);
889	case ST_ASSOC_RESPONSE:
890		printf("Assoc Response");
891		return handle_assoc_response(p, length);
892	case ST_REASSOC_REQUEST:
893		printf("ReAssoc Request");
894		return handle_reassoc_request(p, length);
895	case ST_REASSOC_RESPONSE:
896		printf("ReAssoc Response");
897		return handle_reassoc_response(p, length);
898	case ST_PROBE_REQUEST:
899		printf("Probe Request");
900		return handle_probe_request(p, length);
901	case ST_PROBE_RESPONSE:
902		printf("Probe Response");
903		return handle_probe_response(p, length);
904	case ST_BEACON:
905		printf("Beacon");
906		return handle_beacon(p, length);
907	case ST_ATIM:
908		printf("ATIM");
909		return handle_atim();
910	case ST_DISASSOC:
911		printf("Disassociation");
912		return handle_disassoc(p, length);
913	case ST_AUTH:
914		printf("Authentication");
915		if (!TTEST2(*p, 3))
916			return 0;
917		if ((p[0] == 0 ) && (p[1] == 0) && (p[2] == 0)) {
918			printf("Authentication (Shared-Key)-3 ");
919			return wep_print(p);
920		}
921		return handle_auth(p, length);
922	case ST_DEAUTH:
923		printf("DeAuthentication");
924		return handle_deauth(pmh, p, length);
925		break;
926	case ST_ACTION:
927		printf("Action");
928		return handle_action(pmh, p, length);
929		break;
930	default:
931		printf("Unhandled Management subtype(%x)",
932		    FC_SUBTYPE(fc));
933		return 1;
934	}
935}
936
937
938/*********************************************************************************
939 * Handles printing all the control frame types
940 *********************************************************************************/
941
942static int
943ctrl_body_print(u_int16_t fc, const u_char *p)
944{
945	switch (FC_SUBTYPE(fc)) {
946	case CTRL_CONTROL_WRAPPER:
947		printf("Control Wrapper");
948		/* XXX - requires special handling */
949		break;
950	case CTRL_BAR:
951		printf("BAR");
952		if (!TTEST2(*p, CTRL_BAR_HDRLEN))
953			return 0;
954		if (!eflag)
955			printf(" RA:%s TA:%s CTL(%x) SEQ(%u) ",
956			    etheraddr_string(((const struct ctrl_bar_t *)p)->ra),
957			    etheraddr_string(((const struct ctrl_bar_t *)p)->ta),
958			    EXTRACT_LE_16BITS(&(((const struct ctrl_bar_t *)p)->ctl)),
959			    EXTRACT_LE_16BITS(&(((const struct ctrl_bar_t *)p)->seq)));
960		break;
961	case CTRL_BA:
962		printf("BA");
963		if (!TTEST2(*p, CTRL_BA_HDRLEN))
964			return 0;
965		if (!eflag)
966			printf(" RA:%s ",
967			    etheraddr_string(((const struct ctrl_ba_t *)p)->ra));
968		break;
969	case CTRL_PS_POLL:
970		printf("Power Save-Poll");
971		if (!TTEST2(*p, CTRL_PS_POLL_HDRLEN))
972			return 0;
973		printf(" AID(%x)",
974		    EXTRACT_LE_16BITS(&(((const struct ctrl_ps_poll_t *)p)->aid)));
975		break;
976	case CTRL_RTS:
977		printf("Request-To-Send");
978		if (!TTEST2(*p, CTRL_RTS_HDRLEN))
979			return 0;
980		if (!eflag)
981			printf(" TA:%s ",
982			    etheraddr_string(((const struct ctrl_rts_t *)p)->ta));
983		break;
984	case CTRL_CTS:
985		printf("Clear-To-Send");
986		if (!TTEST2(*p, CTRL_CTS_HDRLEN))
987			return 0;
988		if (!eflag)
989			printf(" RA:%s ",
990			    etheraddr_string(((const struct ctrl_cts_t *)p)->ra));
991		break;
992	case CTRL_ACK:
993		printf("Acknowledgment");
994		if (!TTEST2(*p, CTRL_ACK_HDRLEN))
995			return 0;
996		if (!eflag)
997			printf(" RA:%s ",
998			    etheraddr_string(((const struct ctrl_ack_t *)p)->ra));
999		break;
1000	case CTRL_CF_END:
1001		printf("CF-End");
1002		if (!TTEST2(*p, CTRL_END_HDRLEN))
1003			return 0;
1004		if (!eflag)
1005			printf(" RA:%s ",
1006			    etheraddr_string(((const struct ctrl_end_t *)p)->ra));
1007		break;
1008	case CTRL_END_ACK:
1009		printf("CF-End+CF-Ack");
1010		if (!TTEST2(*p, CTRL_END_ACK_HDRLEN))
1011			return 0;
1012		if (!eflag)
1013			printf(" RA:%s ",
1014			    etheraddr_string(((const struct ctrl_end_ack_t *)p)->ra));
1015		break;
1016	default:
1017		printf("Unknown Ctrl Subtype");
1018	}
1019	return 1;
1020}
1021
1022/*
1023 * Print Header funcs
1024 */
1025
1026/*
1027 *  Data Frame - Address field contents
1028 *
1029 *  To Ds  | From DS | Addr 1 | Addr 2 | Addr 3 | Addr 4
1030 *    0    |  0      |  DA    | SA     | BSSID  | n/a
1031 *    0    |  1      |  DA    | BSSID  | SA     | n/a
1032 *    1    |  0      |  BSSID | SA     | DA     | n/a
1033 *    1    |  1      |  RA    | TA     | DA     | SA
1034 */
1035
1036static void
1037data_header_print(u_int16_t fc, const u_char *p, const u_int8_t **srcp,
1038    const u_int8_t **dstp)
1039{
1040	u_int subtype = FC_SUBTYPE(fc);
1041
1042	if (DATA_FRAME_IS_CF_ACK(subtype) || DATA_FRAME_IS_CF_POLL(subtype) ||
1043	    DATA_FRAME_IS_QOS(subtype)) {
1044		printf("CF ");
1045		if (DATA_FRAME_IS_CF_ACK(subtype)) {
1046			if (DATA_FRAME_IS_CF_POLL(subtype))
1047				printf("Ack/Poll");
1048			else
1049				printf("Ack");
1050		} else {
1051			if (DATA_FRAME_IS_CF_POLL(subtype))
1052				printf("Poll");
1053		}
1054		if (DATA_FRAME_IS_QOS(subtype))
1055			printf("+QoS");
1056		printf(" ");
1057	}
1058
1059#define ADDR1  (p + 4)
1060#define ADDR2  (p + 10)
1061#define ADDR3  (p + 16)
1062#define ADDR4  (p + 24)
1063
1064	if (!FC_TO_DS(fc) && !FC_FROM_DS(fc)) {
1065		if (srcp != NULL)
1066			*srcp = ADDR2;
1067		if (dstp != NULL)
1068			*dstp = ADDR1;
1069		if (!eflag)
1070			return;
1071		printf("DA:%s SA:%s BSSID:%s ",
1072		    etheraddr_string(ADDR1), etheraddr_string(ADDR2),
1073		    etheraddr_string(ADDR3));
1074	} else if (!FC_TO_DS(fc) && FC_FROM_DS(fc)) {
1075		if (srcp != NULL)
1076			*srcp = ADDR3;
1077		if (dstp != NULL)
1078			*dstp = ADDR1;
1079		if (!eflag)
1080			return;
1081		printf("DA:%s BSSID:%s SA:%s ",
1082		    etheraddr_string(ADDR1), etheraddr_string(ADDR2),
1083		    etheraddr_string(ADDR3));
1084	} else if (FC_TO_DS(fc) && !FC_FROM_DS(fc)) {
1085		if (srcp != NULL)
1086			*srcp = ADDR2;
1087		if (dstp != NULL)
1088			*dstp = ADDR3;
1089		if (!eflag)
1090			return;
1091		printf("BSSID:%s SA:%s DA:%s ",
1092		    etheraddr_string(ADDR1), etheraddr_string(ADDR2),
1093		    etheraddr_string(ADDR3));
1094	} else if (FC_TO_DS(fc) && FC_FROM_DS(fc)) {
1095		if (srcp != NULL)
1096			*srcp = ADDR4;
1097		if (dstp != NULL)
1098			*dstp = ADDR3;
1099		if (!eflag)
1100			return;
1101		printf("RA:%s TA:%s DA:%s SA:%s ",
1102		    etheraddr_string(ADDR1), etheraddr_string(ADDR2),
1103		    etheraddr_string(ADDR3), etheraddr_string(ADDR4));
1104	}
1105
1106#undef ADDR1
1107#undef ADDR2
1108#undef ADDR3
1109#undef ADDR4
1110}
1111
1112static void
1113mgmt_header_print(const u_char *p, const u_int8_t **srcp,
1114    const u_int8_t **dstp)
1115{
1116	const struct mgmt_header_t *hp = (const struct mgmt_header_t *) p;
1117
1118	if (srcp != NULL)
1119		*srcp = hp->sa;
1120	if (dstp != NULL)
1121		*dstp = hp->da;
1122	if (!eflag)
1123		return;
1124
1125	printf("BSSID:%s DA:%s SA:%s ",
1126	    etheraddr_string((hp)->bssid), etheraddr_string((hp)->da),
1127	    etheraddr_string((hp)->sa));
1128}
1129
1130static void
1131ctrl_header_print(u_int16_t fc, const u_char *p, const u_int8_t **srcp,
1132    const u_int8_t **dstp)
1133{
1134	if (srcp != NULL)
1135		*srcp = NULL;
1136	if (dstp != NULL)
1137		*dstp = NULL;
1138	if (!eflag)
1139		return;
1140
1141	switch (FC_SUBTYPE(fc)) {
1142	case CTRL_BAR:
1143		printf(" RA:%s TA:%s CTL(%x) SEQ(%u) ",
1144		    etheraddr_string(((const struct ctrl_bar_t *)p)->ra),
1145		    etheraddr_string(((const struct ctrl_bar_t *)p)->ta),
1146		    EXTRACT_LE_16BITS(&(((const struct ctrl_bar_t *)p)->ctl)),
1147		    EXTRACT_LE_16BITS(&(((const struct ctrl_bar_t *)p)->seq)));
1148		break;
1149	case CTRL_BA:
1150		printf("RA:%s ",
1151		    etheraddr_string(((const struct ctrl_ba_t *)p)->ra));
1152		break;
1153	case CTRL_PS_POLL:
1154		printf("BSSID:%s TA:%s ",
1155		    etheraddr_string(((const struct ctrl_ps_poll_t *)p)->bssid),
1156		    etheraddr_string(((const struct ctrl_ps_poll_t *)p)->ta));
1157		break;
1158	case CTRL_RTS:
1159		printf("RA:%s TA:%s ",
1160		    etheraddr_string(((const struct ctrl_rts_t *)p)->ra),
1161		    etheraddr_string(((const struct ctrl_rts_t *)p)->ta));
1162		break;
1163	case CTRL_CTS:
1164		printf("RA:%s ",
1165		    etheraddr_string(((const struct ctrl_cts_t *)p)->ra));
1166		break;
1167	case CTRL_ACK:
1168		printf("RA:%s ",
1169		    etheraddr_string(((const struct ctrl_ack_t *)p)->ra));
1170		break;
1171	case CTRL_CF_END:
1172		printf("RA:%s BSSID:%s ",
1173		    etheraddr_string(((const struct ctrl_end_t *)p)->ra),
1174		    etheraddr_string(((const struct ctrl_end_t *)p)->bssid));
1175		break;
1176	case CTRL_END_ACK:
1177		printf("RA:%s BSSID:%s ",
1178		    etheraddr_string(((const struct ctrl_end_ack_t *)p)->ra),
1179		    etheraddr_string(((const struct ctrl_end_ack_t *)p)->bssid));
1180		break;
1181	default:
1182		printf("(H) Unknown Ctrl Subtype");
1183		break;
1184	}
1185}
1186
1187static int
1188extract_header_length(u_int16_t fc)
1189{
1190	int len;
1191
1192	switch (FC_TYPE(fc)) {
1193	case T_MGMT:
1194		return MGMT_HDRLEN;
1195	case T_CTRL:
1196		switch (FC_SUBTYPE(fc)) {
1197		case CTRL_BAR:
1198			return CTRL_BAR_HDRLEN;
1199		case CTRL_PS_POLL:
1200			return CTRL_PS_POLL_HDRLEN;
1201		case CTRL_RTS:
1202			return CTRL_RTS_HDRLEN;
1203		case CTRL_CTS:
1204			return CTRL_CTS_HDRLEN;
1205		case CTRL_ACK:
1206			return CTRL_ACK_HDRLEN;
1207		case CTRL_CF_END:
1208			return CTRL_END_HDRLEN;
1209		case CTRL_END_ACK:
1210			return CTRL_END_ACK_HDRLEN;
1211		default:
1212			return 0;
1213		}
1214	case T_DATA:
1215		len = (FC_TO_DS(fc) && FC_FROM_DS(fc)) ? 30 : 24;
1216		if (DATA_FRAME_IS_QOS(FC_SUBTYPE(fc)))
1217			len += 2;
1218		return len;
1219	default:
1220		printf("unknown IEEE802.11 frame type (%d)", FC_TYPE(fc));
1221		return 0;
1222	}
1223}
1224
1225static int
1226extract_mesh_header_length(const u_char *p)
1227{
1228	return (p[0] &~ 3) ? 0 : 6*(1 + (p[0] & 3));
1229}
1230
1231/*
1232 * Print the 802.11 MAC header if eflag is set, and set "*srcp" and "*dstp"
1233 * to point to the source and destination MAC addresses in any case if
1234 * "srcp" and "dstp" aren't null.
1235 */
1236static void
1237ieee_802_11_hdr_print(u_int16_t fc, const u_char *p, u_int hdrlen,
1238    u_int meshdrlen, const u_int8_t **srcp, const u_int8_t **dstp)
1239{
1240	if (vflag) {
1241		if (FC_MORE_DATA(fc))
1242			printf("More Data ");
1243		if (FC_MORE_FLAG(fc))
1244			printf("More Fragments ");
1245		if (FC_POWER_MGMT(fc))
1246			printf("Pwr Mgmt ");
1247		if (FC_RETRY(fc))
1248			printf("Retry ");
1249		if (FC_ORDER(fc))
1250			printf("Strictly Ordered ");
1251		if (FC_WEP(fc))
1252			printf("WEP Encrypted ");
1253		if (FC_TYPE(fc) != T_CTRL || FC_SUBTYPE(fc) != CTRL_PS_POLL)
1254			printf("%dus ",
1255			    EXTRACT_LE_16BITS(
1256			        &((const struct mgmt_header_t *)p)->duration));
1257	}
1258	if (meshdrlen != 0) {
1259		const struct meshcntl_t *mc =
1260		    (const struct meshcntl_t *)&p[hdrlen - meshdrlen];
1261		int ae = mc->flags & 3;
1262
1263		printf("MeshData (AE %d TTL %u seq %u", ae, mc->ttl,
1264		    EXTRACT_LE_32BITS(mc->seq));
1265		if (ae > 0)
1266			printf(" A4:%s", etheraddr_string(mc->addr4));
1267		if (ae > 1)
1268			printf(" A5:%s", etheraddr_string(mc->addr5));
1269		if (ae > 2)
1270			printf(" A6:%s", etheraddr_string(mc->addr6));
1271		printf(") ");
1272	}
1273
1274	switch (FC_TYPE(fc)) {
1275	case T_MGMT:
1276		mgmt_header_print(p, srcp, dstp);
1277		break;
1278	case T_CTRL:
1279		ctrl_header_print(fc, p, srcp, dstp);
1280		break;
1281	case T_DATA:
1282		data_header_print(fc, p, srcp, dstp);
1283		break;
1284	default:
1285		printf("(header) unknown IEEE802.11 frame type (%d)",
1286		    FC_TYPE(fc));
1287		*srcp = NULL;
1288		*dstp = NULL;
1289		break;
1290	}
1291}
1292
1293#ifndef roundup2
1294#define	roundup2(x, y)	(((x)+((y)-1))&(~((y)-1))) /* if y is powers of two */
1295#endif
1296
1297static u_int
1298ieee802_11_print(const u_char *p, u_int length, u_int orig_caplen, int pad,
1299    u_int fcslen)
1300{
1301	u_int16_t fc;
1302	u_int caplen, hdrlen, meshdrlen;
1303	const u_int8_t *src, *dst;
1304	u_short extracted_ethertype;
1305
1306	caplen = orig_caplen;
1307	/* Remove FCS, if present */
1308	if (length < fcslen) {
1309		printf("[|802.11]");
1310		return caplen;
1311	}
1312	length -= fcslen;
1313	if (caplen > length) {
1314		/* Amount of FCS in actual packet data, if any */
1315		fcslen = caplen - length;
1316		caplen -= fcslen;
1317		snapend -= fcslen;
1318	}
1319
1320	if (caplen < IEEE802_11_FC_LEN) {
1321		printf("[|802.11]");
1322		return orig_caplen;
1323	}
1324
1325	fc = EXTRACT_LE_16BITS(p);
1326	hdrlen = extract_header_length(fc);
1327	if (pad)
1328		hdrlen = roundup2(hdrlen, 4);
1329	if (FC_TYPE(fc) == T_DATA && DATA_FRAME_IS_QOS(FC_SUBTYPE(fc))) {
1330		meshdrlen = extract_mesh_header_length(p+hdrlen);
1331		hdrlen += meshdrlen;
1332	} else
1333		meshdrlen = 0;
1334
1335
1336	if (caplen < hdrlen) {
1337		printf("[|802.11]");
1338		return hdrlen;
1339	}
1340
1341	ieee_802_11_hdr_print(fc, p, hdrlen, meshdrlen, &src, &dst);
1342
1343	/*
1344	 * Go past the 802.11 header.
1345	 */
1346	length -= hdrlen;
1347	caplen -= hdrlen;
1348	p += hdrlen;
1349
1350	switch (FC_TYPE(fc)) {
1351	case T_MGMT:
1352		if (!mgmt_body_print(fc,
1353		    (const struct mgmt_header_t *)(p - hdrlen), p, length)) {
1354			printf("[|802.11]");
1355			return hdrlen;
1356		}
1357		break;
1358	case T_CTRL:
1359		if (!ctrl_body_print(fc, p - hdrlen)) {
1360			printf("[|802.11]");
1361			return hdrlen;
1362		}
1363		break;
1364	case T_DATA:
1365		if (DATA_FRAME_IS_NULL(FC_SUBTYPE(fc)))
1366			return hdrlen;	/* no-data frame */
1367		/* There may be a problem w/ AP not having this bit set */
1368		if (FC_WEP(fc)) {
1369			if (!wep_print(p)) {
1370				printf("[|802.11]");
1371				return hdrlen;
1372			}
1373		} else if (llc_print(p, length, caplen, dst, src,
1374		    &extracted_ethertype) == 0) {
1375			/*
1376			 * Some kinds of LLC packet we cannot
1377			 * handle intelligently
1378			 */
1379			if (!eflag)
1380				ieee_802_11_hdr_print(fc, p - hdrlen, hdrlen,
1381				    meshdrlen, NULL, NULL);
1382			if (extracted_ethertype)
1383				printf("(LLC %s) ",
1384				    etherproto_string(
1385				        htons(extracted_ethertype)));
1386			if (!suppress_default_print)
1387				default_print(p, caplen);
1388		}
1389		break;
1390	default:
1391		printf("unknown 802.11 frame type (%d)", FC_TYPE(fc));
1392		break;
1393	}
1394
1395	return hdrlen;
1396}
1397
1398/*
1399 * This is the top level routine of the printer.  'p' points
1400 * to the 802.11 header of the packet, 'h->ts' is the timestamp,
1401 * 'h->len' is the length of the packet off the wire, and 'h->caplen'
1402 * is the number of bytes actually captured.
1403 */
1404u_int
1405ieee802_11_if_print(const struct pcap_pkthdr *h, const u_char *p)
1406{
1407	return ieee802_11_print(p, h->len, h->caplen, 0, 0);
1408}
1409
1410#define	IEEE80211_CHAN_FHSS \
1411	(IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_GFSK)
1412#define	IEEE80211_CHAN_A \
1413	(IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM)
1414#define	IEEE80211_CHAN_B \
1415	(IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_CCK)
1416#define	IEEE80211_CHAN_PUREG \
1417	(IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_OFDM)
1418#define	IEEE80211_CHAN_G \
1419	(IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_DYN)
1420
1421#define	IS_CHAN_FHSS(flags) \
1422	((flags & IEEE80211_CHAN_FHSS) == IEEE80211_CHAN_FHSS)
1423#define	IS_CHAN_A(flags) \
1424	((flags & IEEE80211_CHAN_A) == IEEE80211_CHAN_A)
1425#define	IS_CHAN_B(flags) \
1426	((flags & IEEE80211_CHAN_B) == IEEE80211_CHAN_B)
1427#define	IS_CHAN_PUREG(flags) \
1428	((flags & IEEE80211_CHAN_PUREG) == IEEE80211_CHAN_PUREG)
1429#define	IS_CHAN_G(flags) \
1430	((flags & IEEE80211_CHAN_G) == IEEE80211_CHAN_G)
1431#define	IS_CHAN_ANYG(flags) \
1432	(IS_CHAN_PUREG(flags) || IS_CHAN_G(flags))
1433
1434static void
1435print_chaninfo(int freq, int flags)
1436{
1437	printf("%u MHz", freq);
1438	if (IS_CHAN_FHSS(flags))
1439		printf(" FHSS");
1440	if (IS_CHAN_A(flags)) {
1441		if (flags & IEEE80211_CHAN_HALF)
1442			printf(" 11a/10Mhz");
1443		else if (flags & IEEE80211_CHAN_QUARTER)
1444			printf(" 11a/5Mhz");
1445		else
1446			printf(" 11a");
1447	}
1448	if (IS_CHAN_ANYG(flags)) {
1449		if (flags & IEEE80211_CHAN_HALF)
1450			printf(" 11g/10Mhz");
1451		else if (flags & IEEE80211_CHAN_QUARTER)
1452			printf(" 11g/5Mhz");
1453		else
1454			printf(" 11g");
1455	} else if (IS_CHAN_B(flags))
1456		printf(" 11b");
1457	if (flags & IEEE80211_CHAN_TURBO)
1458		printf(" Turbo");
1459	if (flags & IEEE80211_CHAN_HT20)
1460		printf(" ht/20");
1461	else if (flags & IEEE80211_CHAN_HT40D)
1462		printf(" ht/40-");
1463	else if (flags & IEEE80211_CHAN_HT40U)
1464		printf(" ht/40+");
1465	printf(" ");
1466}
1467
1468static int
1469print_radiotap_field(struct cpack_state *s, u_int32_t bit, u_int8_t *flags)
1470{
1471	union {
1472		int8_t		i8;
1473		u_int8_t	u8;
1474		int16_t		i16;
1475		u_int16_t	u16;
1476		u_int32_t	u32;
1477		u_int64_t	u64;
1478	} u, u2, u3, u4;
1479	int rc;
1480
1481	switch (bit) {
1482	case IEEE80211_RADIOTAP_FLAGS:
1483		rc = cpack_uint8(s, &u.u8);
1484		*flags = u.u8;
1485		break;
1486	case IEEE80211_RADIOTAP_RATE:
1487	case IEEE80211_RADIOTAP_DB_ANTSIGNAL:
1488	case IEEE80211_RADIOTAP_DB_ANTNOISE:
1489	case IEEE80211_RADIOTAP_ANTENNA:
1490		rc = cpack_uint8(s, &u.u8);
1491		break;
1492	case IEEE80211_RADIOTAP_DBM_ANTSIGNAL:
1493	case IEEE80211_RADIOTAP_DBM_ANTNOISE:
1494		rc = cpack_int8(s, &u.i8);
1495		break;
1496	case IEEE80211_RADIOTAP_CHANNEL:
1497		rc = cpack_uint16(s, &u.u16);
1498		if (rc != 0)
1499			break;
1500		rc = cpack_uint16(s, &u2.u16);
1501		break;
1502	case IEEE80211_RADIOTAP_FHSS:
1503	case IEEE80211_RADIOTAP_LOCK_QUALITY:
1504	case IEEE80211_RADIOTAP_TX_ATTENUATION:
1505		rc = cpack_uint16(s, &u.u16);
1506		break;
1507	case IEEE80211_RADIOTAP_DB_TX_ATTENUATION:
1508		rc = cpack_uint8(s, &u.u8);
1509		break;
1510	case IEEE80211_RADIOTAP_DBM_TX_POWER:
1511		rc = cpack_int8(s, &u.i8);
1512		break;
1513	case IEEE80211_RADIOTAP_TSFT:
1514		rc = cpack_uint64(s, &u.u64);
1515		break;
1516	case IEEE80211_RADIOTAP_XCHANNEL:
1517		rc = cpack_uint32(s, &u.u32);
1518		if (rc != 0)
1519			break;
1520		rc = cpack_uint16(s, &u2.u16);
1521		if (rc != 0)
1522			break;
1523		rc = cpack_uint8(s, &u3.u8);
1524		if (rc != 0)
1525			break;
1526		rc = cpack_uint8(s, &u4.u8);
1527		break;
1528	default:
1529		/* this bit indicates a field whose
1530		 * size we do not know, so we cannot
1531		 * proceed.  Just print the bit number.
1532		 */
1533		printf("[bit %u] ", bit);
1534		return -1;
1535	}
1536
1537	if (rc != 0) {
1538		printf("[|802.11]");
1539		return rc;
1540	}
1541
1542	switch (bit) {
1543	case IEEE80211_RADIOTAP_CHANNEL:
1544		print_chaninfo(u.u16, u2.u16);
1545		break;
1546	case IEEE80211_RADIOTAP_FHSS:
1547		printf("fhset %d fhpat %d ", u.u16 & 0xff, (u.u16 >> 8) & 0xff);
1548		break;
1549	case IEEE80211_RADIOTAP_RATE:
1550		if (u.u8 & 0x80)
1551			PRINT_HT_RATE("", u.u8, " Mb/s ");
1552		else
1553			PRINT_RATE("", u.u8, " Mb/s ");
1554		break;
1555	case IEEE80211_RADIOTAP_DBM_ANTSIGNAL:
1556		printf("%ddB signal ", u.i8);
1557		break;
1558	case IEEE80211_RADIOTAP_DBM_ANTNOISE:
1559		printf("%ddB noise ", u.i8);
1560		break;
1561	case IEEE80211_RADIOTAP_DB_ANTSIGNAL:
1562		printf("%ddB signal ", u.u8);
1563		break;
1564	case IEEE80211_RADIOTAP_DB_ANTNOISE:
1565		printf("%ddB noise ", u.u8);
1566		break;
1567	case IEEE80211_RADIOTAP_LOCK_QUALITY:
1568		printf("%u sq ", u.u16);
1569		break;
1570	case IEEE80211_RADIOTAP_TX_ATTENUATION:
1571		printf("%d tx power ", -(int)u.u16);
1572		break;
1573	case IEEE80211_RADIOTAP_DB_TX_ATTENUATION:
1574		printf("%ddB tx power ", -(int)u.u8);
1575		break;
1576	case IEEE80211_RADIOTAP_DBM_TX_POWER:
1577		printf("%ddBm tx power ", u.i8);
1578		break;
1579	case IEEE80211_RADIOTAP_FLAGS:
1580		if (u.u8 & IEEE80211_RADIOTAP_F_CFP)
1581			printf("cfp ");
1582		if (u.u8 & IEEE80211_RADIOTAP_F_SHORTPRE)
1583			printf("short preamble ");
1584		if (u.u8 & IEEE80211_RADIOTAP_F_WEP)
1585			printf("wep ");
1586		if (u.u8 & IEEE80211_RADIOTAP_F_FRAG)
1587			printf("fragmented ");
1588		if (u.u8 & IEEE80211_RADIOTAP_F_BADFCS)
1589			printf("bad-fcs ");
1590		break;
1591	case IEEE80211_RADIOTAP_ANTENNA:
1592		printf("antenna %d ", u.u8);
1593		break;
1594	case IEEE80211_RADIOTAP_TSFT:
1595		printf("%" PRIu64 "us tsft ", u.u64);
1596		break;
1597	case IEEE80211_RADIOTAP_XCHANNEL:
1598		print_chaninfo(u2.u16, u.u32);
1599		break;
1600	}
1601	return 0;
1602}
1603
1604static u_int
1605ieee802_11_radio_print(const u_char *p, u_int length, u_int caplen)
1606{
1607#define	BITNO_32(x) (((x) >> 16) ? 16 + BITNO_16((x) >> 16) : BITNO_16((x)))
1608#define	BITNO_16(x) (((x) >> 8) ? 8 + BITNO_8((x) >> 8) : BITNO_8((x)))
1609#define	BITNO_8(x) (((x) >> 4) ? 4 + BITNO_4((x) >> 4) : BITNO_4((x)))
1610#define	BITNO_4(x) (((x) >> 2) ? 2 + BITNO_2((x) >> 2) : BITNO_2((x)))
1611#define	BITNO_2(x) (((x) & 2) ? 1 : 0)
1612#define	BIT(n)	(1U << n)
1613#define	IS_EXTENDED(__p)	\
1614	    (EXTRACT_LE_32BITS(__p) & BIT(IEEE80211_RADIOTAP_EXT)) != 0
1615
1616	struct cpack_state cpacker;
1617	struct ieee80211_radiotap_header *hdr;
1618	u_int32_t present, next_present;
1619	u_int32_t *presentp, *last_presentp;
1620	enum ieee80211_radiotap_type bit;
1621	int bit0;
1622	const u_char *iter;
1623	u_int len;
1624	u_int8_t flags;
1625	int pad;
1626	u_int fcslen;
1627
1628	if (caplen < sizeof(*hdr)) {
1629		printf("[|802.11]");
1630		return caplen;
1631	}
1632
1633	hdr = (struct ieee80211_radiotap_header *)p;
1634
1635	len = EXTRACT_LE_16BITS(&hdr->it_len);
1636
1637	if (caplen < len) {
1638		printf("[|802.11]");
1639		return caplen;
1640	}
1641	for (last_presentp = &hdr->it_present;
1642	     IS_EXTENDED(last_presentp) &&
1643	     (u_char*)(last_presentp + 1) <= p + len;
1644	     last_presentp++);
1645
1646	/* are there more bitmap extensions than bytes in header? */
1647	if (IS_EXTENDED(last_presentp)) {
1648		printf("[|802.11]");
1649		return caplen;
1650	}
1651
1652	iter = (u_char*)(last_presentp + 1);
1653
1654	if (cpack_init(&cpacker, (u_int8_t*)iter, len - (iter - p)) != 0) {
1655		/* XXX */
1656		printf("[|802.11]");
1657		return caplen;
1658	}
1659
1660	/* Assume no flags */
1661	flags = 0;
1662	/* Assume no Atheros padding between 802.11 header and body */
1663	pad = 0;
1664	/* Assume no FCS at end of frame */
1665	fcslen = 0;
1666	for (bit0 = 0, presentp = &hdr->it_present; presentp <= last_presentp;
1667	     presentp++, bit0 += 32) {
1668		for (present = EXTRACT_LE_32BITS(presentp); present;
1669		     present = next_present) {
1670			/* clear the least significant bit that is set */
1671			next_present = present & (present - 1);
1672
1673			/* extract the least significant bit that is set */
1674			bit = (enum ieee80211_radiotap_type)
1675			    (bit0 + BITNO_32(present ^ next_present));
1676
1677			if (print_radiotap_field(&cpacker, bit, &flags) != 0)
1678				goto out;
1679		}
1680	}
1681
1682	if (flags & IEEE80211_RADIOTAP_F_DATAPAD)
1683		pad = 1;	/* Atheros padding */
1684	if (flags & IEEE80211_RADIOTAP_F_FCS)
1685		fcslen = 4;	/* FCS at end of packet */
1686out:
1687	return len + ieee802_11_print(p + len, length - len, caplen - len, pad,
1688	    fcslen);
1689#undef BITNO_32
1690#undef BITNO_16
1691#undef BITNO_8
1692#undef BITNO_4
1693#undef BITNO_2
1694#undef BIT
1695}
1696
1697static u_int
1698ieee802_11_avs_radio_print(const u_char *p, u_int length, u_int caplen)
1699{
1700	u_int32_t caphdr_len;
1701
1702	if (caplen < 8) {
1703		printf("[|802.11]");
1704		return caplen;
1705	}
1706
1707	caphdr_len = EXTRACT_32BITS(p + 4);
1708	if (caphdr_len < 8) {
1709		/*
1710		 * Yow!  The capture header length is claimed not
1711		 * to be large enough to include even the version
1712		 * cookie or capture header length!
1713		 */
1714		printf("[|802.11]");
1715		return caplen;
1716	}
1717
1718	if (caplen < caphdr_len) {
1719		printf("[|802.11]");
1720		return caplen;
1721	}
1722
1723	return caphdr_len + ieee802_11_print(p + caphdr_len,
1724	    length - caphdr_len, caplen - caphdr_len, 0, 0);
1725}
1726
1727#define PRISM_HDR_LEN		144
1728
1729#define WLANCAP_MAGIC_COOKIE_BASE 0x80211000
1730#define WLANCAP_MAGIC_COOKIE_V1	0x80211001
1731#define WLANCAP_MAGIC_COOKIE_V2	0x80211002
1732
1733/*
1734 * For DLT_PRISM_HEADER; like DLT_IEEE802_11, but with an extra header,
1735 * containing information such as radio information, which we
1736 * currently ignore.
1737 *
1738 * If, however, the packet begins with WLANCAP_MAGIC_COOKIE_V1 or
1739 * WLANCAP_MAGIC_COOKIE_V2, it's really DLT_IEEE802_11_RADIO_AVS
1740 * (currently, on Linux, there's no ARPHRD_ type for
1741 * DLT_IEEE802_11_RADIO_AVS, as there is a ARPHRD_IEEE80211_PRISM
1742 * for DLT_PRISM_HEADER, so ARPHRD_IEEE80211_PRISM is used for
1743 * the AVS header, and the first 4 bytes of the header are used to
1744 * indicate whether it's a Prism header or an AVS header).
1745 */
1746u_int
1747prism_if_print(const struct pcap_pkthdr *h, const u_char *p)
1748{
1749	u_int caplen = h->caplen;
1750	u_int length = h->len;
1751	u_int32_t msgcode;
1752
1753	if (caplen < 4) {
1754		printf("[|802.11]");
1755		return caplen;
1756	}
1757
1758	msgcode = EXTRACT_32BITS(p);
1759	if (msgcode == WLANCAP_MAGIC_COOKIE_V1 ||
1760	    msgcode == WLANCAP_MAGIC_COOKIE_V2)
1761		return ieee802_11_avs_radio_print(p, length, caplen);
1762
1763	if (caplen < PRISM_HDR_LEN) {
1764		printf("[|802.11]");
1765		return caplen;
1766	}
1767
1768	return PRISM_HDR_LEN + ieee802_11_print(p + PRISM_HDR_LEN,
1769	    length - PRISM_HDR_LEN, caplen - PRISM_HDR_LEN, 0, 0);
1770}
1771
1772/*
1773 * For DLT_IEEE802_11_RADIO; like DLT_IEEE802_11, but with an extra
1774 * header, containing information such as radio information.
1775 */
1776u_int
1777ieee802_11_radio_if_print(const struct pcap_pkthdr *h, const u_char *p)
1778{
1779	return ieee802_11_radio_print(p, h->len, h->caplen);
1780}
1781
1782/*
1783 * For DLT_IEEE802_11_RADIO_AVS; like DLT_IEEE802_11, but with an
1784 * extra header, containing information such as radio information,
1785 * which we currently ignore.
1786 */
1787u_int
1788ieee802_11_radio_avs_if_print(const struct pcap_pkthdr *h, const u_char *p)
1789{
1790	return ieee802_11_avs_radio_print(p, h->len, h->caplen);
1791}
1792