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