xref: /netbsd-src/external/bsd/tcpdump/dist/print-802_11.c (revision ba65fde2d7fefa7d39838fa5fa855e62bd606b5e)
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
26 static 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: print-802_11.c,v 1.2 2010/12/05 05:11:30 christos Exp $");
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 
82 static 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 
103 static 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 
106 static 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 
190 static 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 
258 static int
259 wep_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 
273 static int
274 parse_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 
513 static int
514 handle_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 
549 static int
550 handle_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 
576 static int
577 handle_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 
612 static int
613 handle_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 
645 static int
646 handle_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 
652 static int
653 handle_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 
669 static int
670 handle_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 
703 static int
704 handle_atim(void)
705 {
706 	/* the frame body for ATIM is null. */
707 	return 1;
708 }
709 
710 static int
711 handle_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 
731 static int
732 handle_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 
784 static int
785 handle_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 
843 static int
844 handle_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 
881 static int
882 mgmt_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 
942 static int
943 ctrl_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 
1036 static void
1037 data_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 
1112 static void
1113 mgmt_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 
1130 static void
1131 ctrl_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 
1187 static int
1188 extract_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 
1225 static int
1226 extract_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  */
1236 static void
1237 ieee_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 
1297 static u_int
1298 ieee802_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  */
1404 u_int
1405 ieee802_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 
1434 static void
1435 print_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 
1468 static int
1469 print_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 
1604 static u_int
1605 ieee802_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 */
1686 out:
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 
1697 static u_int
1698 ieee802_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  */
1746 u_int
1747 prism_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  */
1776 u_int
1777 ieee802_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  */
1787 u_int
1788 ieee802_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