print-802_11.c revision 241235
1/*
2 * Copyright (c) 2001
3 *	Fortress Technologies, Inc.  All rights reserved.
4 *      Charlie Lenahan (clenahan@fortresstech.com)
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that: (1) source code distributions
8 * retain the above copyright notice and this paragraph in its entirety, (2)
9 * distributions including binary code include the above copyright notice and
10 * this paragraph in its entirety in the documentation or other materials
11 * provided with the distribution, and (3) all advertising materials mentioning
12 * features or use of this software display the following acknowledgement:
13 * ``This product includes software developed by the University of California,
14 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
15 * the University nor the names of its contributors may be used to endorse
16 * or promote products derived from this software without specific prior
17 * written permission.
18 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
19 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
20 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
21 */
22
23#ifndef lint
24static const char rcsid[] _U_ =
25    "@(#) $Header: /tcpdump/master/tcpdump/print-802_11.c,v 1.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/* Radiotap state */
50/*  This is used to save state when parsing/processing parameters */
51struct radiotap_state
52{
53	u_int32_t	present;
54
55	u_int8_t	rate;
56};
57
58#define PRINT_SSID(p) \
59	if (p.ssid_present) { \
60		printf(" ("); \
61		fn_print(p.ssid.ssid, NULL); \
62		printf(")"); \
63	}
64
65#define PRINT_RATE(_sep, _r, _suf) \
66	printf("%s%2.1f%s", _sep, (.5 * ((_r) & 0x7f)), _suf)
67#define PRINT_RATES(p) \
68	if (p.rates_present) { \
69		int z; \
70		const char *sep = " ["; \
71		for (z = 0; z < p.rates.length ; z++) { \
72			PRINT_RATE(sep, p.rates.rate[z], \
73				(p.rates.rate[z] & 0x80 ? "*" : "")); \
74			sep = " "; \
75		} \
76		if (p.rates.length != 0) \
77			printf(" Mbit]"); \
78	}
79
80#define PRINT_DS_CHANNEL(p) \
81	if (p.ds_present) \
82		printf(" CH: %u", p.ds.channel); \
83	printf("%s", \
84	    CAPABILITY_PRIVACY(p.capability_info) ? ", PRIVACY" : "" );
85
86#define MAX_MCS_INDEX	76
87
88/*
89 * Indices are:
90 *
91 *	the MCS index (0-76);
92 *
93 *	0 for 20 MHz, 1 for 40 MHz;
94 *
95 *	0 for a long guard interval, 1 for a short guard interval.
96 */
97static const float ieee80211_float_htrates[MAX_MCS_INDEX+1][2][2] = {
98	/* MCS  0  */
99	{	/* 20 Mhz */ {    6.5,		/* SGI */    7.2, },
100		/* 40 Mhz */ {   13.5,		/* SGI */   15.0, },
101	},
102
103	/* MCS  1  */
104	{	/* 20 Mhz */ {   13.0,		/* SGI */   14.4, },
105		/* 40 Mhz */ {   27.0,		/* SGI */   30.0, },
106	},
107
108	/* MCS  2  */
109	{	/* 20 Mhz */ {   19.5,		/* SGI */   21.7, },
110		/* 40 Mhz */ {   40.5,		/* SGI */   45.0, },
111	},
112
113	/* MCS  3  */
114	{	/* 20 Mhz */ {   26.0,		/* SGI */   28.9, },
115		/* 40 Mhz */ {   54.0,		/* SGI */   60.0, },
116	},
117
118	/* MCS  4  */
119	{	/* 20 Mhz */ {   39.0,		/* SGI */   43.3, },
120		/* 40 Mhz */ {   81.0,		/* SGI */   90.0, },
121	},
122
123	/* MCS  5  */
124	{	/* 20 Mhz */ {   52.0,		/* SGI */   57.8, },
125		/* 40 Mhz */ {  108.0,		/* SGI */  120.0, },
126	},
127
128	/* MCS  6  */
129	{	/* 20 Mhz */ {   58.5,		/* SGI */   65.0, },
130		/* 40 Mhz */ {  121.5,		/* SGI */  135.0, },
131	},
132
133	/* MCS  7  */
134	{	/* 20 Mhz */ {   65.0,		/* SGI */   72.2, },
135		/* 40 Mhz */ {   135.0,		/* SGI */  150.0, },
136	},
137
138	/* MCS  8  */
139	{	/* 20 Mhz */ {   13.0,		/* SGI */   14.4, },
140		/* 40 Mhz */ {   27.0,		/* SGI */   30.0, },
141	},
142
143	/* MCS  9  */
144	{	/* 20 Mhz */ {   26.0,		/* SGI */   28.9, },
145		/* 40 Mhz */ {   54.0,		/* SGI */   60.0, },
146	},
147
148	/* MCS 10  */
149	{	/* 20 Mhz */ {   39.0,		/* SGI */   43.3, },
150		/* 40 Mhz */ {   81.0,		/* SGI */   90.0, },
151	},
152
153	/* MCS 11  */
154	{	/* 20 Mhz */ {   52.0,		/* SGI */   57.8, },
155		/* 40 Mhz */ {  108.0,		/* SGI */  120.0, },
156	},
157
158	/* MCS 12  */
159	{	/* 20 Mhz */ {   78.0,		/* SGI */   86.7, },
160		/* 40 Mhz */ {  162.0,		/* SGI */  180.0, },
161	},
162
163	/* MCS 13  */
164	{	/* 20 Mhz */ {  104.0,		/* SGI */  115.6, },
165		/* 40 Mhz */ {  216.0,		/* SGI */  240.0, },
166	},
167
168	/* MCS 14  */
169	{	/* 20 Mhz */ {  117.0,		/* SGI */  130.0, },
170		/* 40 Mhz */ {  243.0,		/* SGI */  270.0, },
171	},
172
173	/* MCS 15  */
174	{	/* 20 Mhz */ {  130.0,		/* SGI */  144.4, },
175		/* 40 Mhz */ {  270.0,		/* SGI */  300.0, },
176	},
177
178	/* MCS 16  */
179	{	/* 20 Mhz */ {   19.5,		/* SGI */   21.7, },
180		/* 40 Mhz */ {   40.5,		/* SGI */   45.0, },
181	},
182
183	/* MCS 17  */
184	{	/* 20 Mhz */ {   39.0,		/* SGI */   43.3, },
185		/* 40 Mhz */ {   81.0,		/* SGI */   90.0, },
186	},
187
188	/* MCS 18  */
189	{	/* 20 Mhz */ {   58.5,		/* SGI */   65.0, },
190		/* 40 Mhz */ {  121.5,		/* SGI */  135.0, },
191	},
192
193	/* MCS 19  */
194	{	/* 20 Mhz */ {   78.0,		/* SGI */   86.7, },
195		/* 40 Mhz */ {  162.0,		/* SGI */  180.0, },
196	},
197
198	/* MCS 20  */
199	{	/* 20 Mhz */ {  117.0,		/* SGI */  130.0, },
200		/* 40 Mhz */ {  243.0,		/* SGI */  270.0, },
201	},
202
203	/* MCS 21  */
204	{	/* 20 Mhz */ {  156.0,		/* SGI */  173.3, },
205		/* 40 Mhz */ {  324.0,		/* SGI */  360.0, },
206	},
207
208	/* MCS 22  */
209	{	/* 20 Mhz */ {  175.5,		/* SGI */  195.0, },
210		/* 40 Mhz */ {  364.5,		/* SGI */  405.0, },
211	},
212
213	/* MCS 23  */
214	{	/* 20 Mhz */ {  195.0,		/* SGI */  216.7, },
215		/* 40 Mhz */ {  405.0,		/* SGI */  450.0, },
216	},
217
218	/* MCS 24  */
219	{	/* 20 Mhz */ {   26.0,		/* SGI */   28.9, },
220		/* 40 Mhz */ {   54.0,		/* SGI */   60.0, },
221	},
222
223	/* MCS 25  */
224	{	/* 20 Mhz */ {   52.0,		/* SGI */   57.8, },
225		/* 40 Mhz */ {  108.0,		/* SGI */  120.0, },
226	},
227
228	/* MCS 26  */
229	{	/* 20 Mhz */ {   78.0,		/* SGI */   86.7, },
230		/* 40 Mhz */ {  162.0,		/* SGI */  180.0, },
231	},
232
233	/* MCS 27  */
234	{	/* 20 Mhz */ {  104.0,		/* SGI */  115.6, },
235		/* 40 Mhz */ {  216.0,		/* SGI */  240.0, },
236	},
237
238	/* MCS 28  */
239	{	/* 20 Mhz */ {  156.0,		/* SGI */  173.3, },
240		/* 40 Mhz */ {  324.0,		/* SGI */  360.0, },
241	},
242
243	/* MCS 29  */
244	{	/* 20 Mhz */ {  208.0,		/* SGI */  231.1, },
245		/* 40 Mhz */ {  432.0,		/* SGI */  480.0, },
246	},
247
248	/* MCS 30  */
249	{	/* 20 Mhz */ {  234.0,		/* SGI */  260.0, },
250		/* 40 Mhz */ {  486.0,		/* SGI */  540.0, },
251	},
252
253	/* MCS 31  */
254	{	/* 20 Mhz */ {  260.0,		/* SGI */  288.9, },
255		/* 40 Mhz */ {  540.0,		/* SGI */  600.0, },
256	},
257
258	/* MCS 32  */
259	{	/* 20 Mhz */ {    0.0,		/* SGI */    0.0, }, /* not valid */
260		/* 40 Mhz */ {    6.0,		/* SGI */    6.7, },
261	},
262
263	/* MCS 33  */
264	{	/* 20 Mhz */ {   39.0,		/* SGI */   43.3, },
265		/* 40 Mhz */ {   81.0,		/* SGI */   90.0, },
266	},
267
268	/* MCS 34  */
269	{	/* 20 Mhz */ {   52.0,		/* SGI */   57.8, },
270		/* 40 Mhz */ {  108.0,		/* SGI */  120.0, },
271	},
272
273	/* MCS 35  */
274	{	/* 20 Mhz */ {   65.0,		/* SGI */   72.2, },
275		/* 40 Mhz */ {  135.0,		/* SGI */  150.0, },
276	},
277
278	/* MCS 36  */
279	{	/* 20 Mhz */ {   58.5,		/* SGI */   65.0, },
280		/* 40 Mhz */ {  121.5,		/* SGI */  135.0, },
281	},
282
283	/* MCS 37  */
284	{	/* 20 Mhz */ {   78.0,		/* SGI */   86.7, },
285		/* 40 Mhz */ {  162.0,		/* SGI */  180.0, },
286	},
287
288	/* MCS 38  */
289	{	/* 20 Mhz */ {   97.5,		/* SGI */  108.3, },
290		/* 40 Mhz */ {  202.5,		/* SGI */  225.0, },
291	},
292
293	/* MCS 39  */
294	{	/* 20 Mhz */ {   52.0,		/* SGI */   57.8, },
295		/* 40 Mhz */ {  108.0,		/* SGI */  120.0, },
296	},
297
298	/* MCS 40  */
299	{	/* 20 Mhz */ {   65.0,		/* SGI */   72.2, },
300		/* 40 Mhz */ {  135.0,		/* SGI */  150.0, },
301	},
302
303	/* MCS 41  */
304	{	/* 20 Mhz */ {   65.0,		/* SGI */   72.2, },
305		/* 40 Mhz */ {  135.0,		/* SGI */  150.0, },
306	},
307
308	/* MCS 42  */
309	{	/* 20 Mhz */ {   78.0,		/* SGI */   86.7, },
310		/* 40 Mhz */ {  162.0,		/* SGI */  180.0, },
311	},
312
313	/* MCS 43  */
314	{	/* 20 Mhz */ {   91.0,		/* SGI */  101.1, },
315		/* 40 Mhz */ {  189.0,		/* SGI */  210.0, },
316	},
317
318	/* MCS 44  */
319	{	/* 20 Mhz */ {   91.0,		/* SGI */  101.1, },
320		/* 40 Mhz */ {  189.0,		/* SGI */  210.0, },
321	},
322
323	/* MCS 45  */
324	{	/* 20 Mhz */ {  104.0,		/* SGI */  115.6, },
325		/* 40 Mhz */ {  216.0,		/* SGI */  240.0, },
326	},
327
328	/* MCS 46  */
329	{	/* 20 Mhz */ {   78.0,		/* SGI */   86.7, },
330		/* 40 Mhz */ {  162.0,		/* SGI */  180.0, },
331	},
332
333	/* MCS 47  */
334	{	/* 20 Mhz */ {   97.5,		/* SGI */  108.3, },
335		/* 40 Mhz */ {  202.5,		/* SGI */  225.0, },
336	},
337
338	/* MCS 48  */
339	{	/* 20 Mhz */ {   97.5,		/* SGI */  108.3, },
340		/* 40 Mhz */ {  202.5,		/* SGI */  225.0, },
341	},
342
343	/* MCS 49  */
344	{	/* 20 Mhz */ {  117.0,		/* SGI */  130.0, },
345		/* 40 Mhz */ {  243.0,		/* SGI */  270.0, },
346	},
347
348	/* MCS 50  */
349	{	/* 20 Mhz */ {  136.5,		/* SGI */  151.7, },
350		/* 40 Mhz */ {  283.5,		/* SGI */  315.0, },
351	},
352
353	/* MCS 51  */
354	{	/* 20 Mhz */ {  136.5,		/* SGI */  151.7, },
355		/* 40 Mhz */ {  283.5,		/* SGI */  315.0, },
356	},
357
358	/* MCS 52  */
359	{	/* 20 Mhz */ {  156.0,		/* SGI */  173.3, },
360		/* 40 Mhz */ {  324.0,		/* SGI */  360.0, },
361	},
362
363	/* MCS 53  */
364	{	/* 20 Mhz */ {   65.0,		/* SGI */   72.2, },
365		/* 40 Mhz */ {  135.0,		/* SGI */  150.0, },
366	},
367
368	/* MCS 54  */
369	{	/* 20 Mhz */ {   78.0,		/* SGI */   86.7, },
370		/* 40 Mhz */ {  162.0,		/* SGI */  180.0, },
371	},
372
373	/* MCS 55  */
374	{	/* 20 Mhz */ {   91.0,		/* SGI */  101.1, },
375		/* 40 Mhz */ {  189.0,		/* SGI */  210.0, },
376	},
377
378	/* MCS 56  */
379	{	/* 20 Mhz */ {   78.0,		/* SGI */   86.7, },
380		/* 40 Mhz */ {  162.0,		/* SGI */  180.0, },
381	},
382
383	/* MCS 57  */
384	{	/* 20 Mhz */ {   91.0,		/* SGI */  101.1, },
385		/* 40 Mhz */ {  189.0,		/* SGI */  210.0, },
386	},
387
388	/* MCS 58  */
389	{	/* 20 Mhz */ {  104.0,		/* SGI */  115.6, },
390		/* 40 Mhz */ {  216.0,		/* SGI */  240.0, },
391	},
392
393	/* MCS 59  */
394	{	/* 20 Mhz */ {  117.0,		/* SGI */  130.0, },
395		/* 40 Mhz */ {  243.0,		/* SGI */  270.0, },
396	},
397
398	/* MCS 60  */
399	{	/* 20 Mhz */ {  104.0,		/* SGI */  115.6, },
400		/* 40 Mhz */ {  216.0,		/* SGI */  240.0, },
401	},
402
403	/* MCS 61  */
404	{	/* 20 Mhz */ {  117.0,		/* SGI */  130.0, },
405		/* 40 Mhz */ {  243.0,		/* SGI */  270.0, },
406	},
407
408	/* MCS 62  */
409	{	/* 20 Mhz */ {  130.0,		/* SGI */  144.4, },
410		/* 40 Mhz */ {  270.0,		/* SGI */  300.0, },
411	},
412
413	/* MCS 63  */
414	{	/* 20 Mhz */ {  130.0,		/* SGI */  144.4, },
415		/* 40 Mhz */ {  270.0,		/* SGI */  300.0, },
416	},
417
418	/* MCS 64  */
419	{	/* 20 Mhz */ {  143.0,		/* SGI */  158.9, },
420		/* 40 Mhz */ {  297.0,		/* SGI */  330.0, },
421	},
422
423	/* MCS 65  */
424	{	/* 20 Mhz */ {   97.5,		/* SGI */  108.3, },
425		/* 40 Mhz */ {  202.5,		/* SGI */  225.0, },
426	},
427
428	/* MCS 66  */
429	{	/* 20 Mhz */ {  117.0,		/* SGI */  130.0, },
430		/* 40 Mhz */ {  243.0,		/* SGI */  270.0, },
431	},
432
433	/* MCS 67  */
434	{	/* 20 Mhz */ {  136.5,		/* SGI */  151.7, },
435		/* 40 Mhz */ {  283.5,		/* SGI */  315.0, },
436	},
437
438	/* MCS 68  */
439	{	/* 20 Mhz */ {  117.0,		/* SGI */  130.0, },
440		/* 40 Mhz */ {  243.0,		/* SGI */  270.0, },
441	},
442
443	/* MCS 69  */
444	{	/* 20 Mhz */ {  136.5,		/* SGI */  151.7, },
445		/* 40 Mhz */ {  283.5,		/* SGI */  315.0, },
446	},
447
448	/* MCS 70  */
449	{	/* 20 Mhz */ {  156.0,		/* SGI */  173.3, },
450		/* 40 Mhz */ {  324.0,		/* SGI */  360.0, },
451	},
452
453	/* MCS 71  */
454	{	/* 20 Mhz */ {  175.5,		/* SGI */  195.0, },
455		/* 40 Mhz */ {  364.5,		/* SGI */  405.0, },
456	},
457
458	/* MCS 72  */
459	{	/* 20 Mhz */ {  156.0,		/* SGI */  173.3, },
460		/* 40 Mhz */ {  324.0,		/* SGI */  360.0, },
461	},
462
463	/* MCS 73  */
464	{	/* 20 Mhz */ {  175.5,		/* SGI */  195.0, },
465		/* 40 Mhz */ {  364.5,		/* SGI */  405.0, },
466	},
467
468	/* MCS 74  */
469	{	/* 20 Mhz */ {  195.0,		/* SGI */  216.7, },
470		/* 40 Mhz */ {  405.0,		/* SGI */  450.0, },
471	},
472
473	/* MCS 75  */
474	{	/* 20 Mhz */ {  195.0,		/* SGI */  216.7, },
475		/* 40 Mhz */ {  405.0,		/* SGI */  450.0, },
476	},
477
478	/* MCS 76  */
479	{	/* 20 Mhz */ {  214.5,		/* SGI */  238.3, },
480		/* 40 Mhz */ {  445.5,		/* SGI */  495.0, },
481	},
482};
483
484static const char *auth_alg_text[]={"Open System","Shared Key","EAP"};
485#define NUM_AUTH_ALGS	(sizeof auth_alg_text / sizeof auth_alg_text[0])
486
487static const char *status_text[] = {
488	"Successful",						/*  0 */
489	"Unspecified failure",					/*  1 */
490	"Reserved",						/*  2 */
491	"Reserved",						/*  3 */
492	"Reserved",						/*  4 */
493	"Reserved",						/*  5 */
494	"Reserved",						/*  6 */
495	"Reserved",						/*  7 */
496	"Reserved",						/*  8 */
497	"Reserved",						/*  9 */
498	"Cannot Support all requested capabilities in the Capability "
499	  "Information field",	  				/* 10 */
500	"Reassociation denied due to inability to confirm that association "
501	  "exists",						/* 11 */
502	"Association denied due to reason outside the scope of the "
503	  "standard",						/* 12 */
504	"Responding station does not support the specified authentication "
505	  "algorithm ",						/* 13 */
506	"Received an Authentication frame with authentication transaction "
507	  "sequence number out of expected sequence",		/* 14 */
508	"Authentication rejected because of challenge failure",	/* 15 */
509	"Authentication rejected due to timeout waiting for next frame in "
510	  "sequence",	  					/* 16 */
511	"Association denied because AP is unable to handle additional"
512	  "associated stations",	  			/* 17 */
513	"Association denied due to requesting station not supporting all of "
514	  "the data rates in BSSBasicRateSet parameter",	/* 18 */
515	"Association denied due to requesting station not supporting "
516	  "short preamble operation",				/* 19 */
517	"Association denied due to requesting station not supporting "
518	  "PBCC encoding",					/* 20 */
519	"Association denied due to requesting station not supporting "
520	  "channel agility",					/* 21 */
521	"Association request rejected because Spectrum Management "
522	  "capability is required",				/* 22 */
523	"Association request rejected because the information in the "
524	  "Power Capability element is unacceptable",		/* 23 */
525	"Association request rejected because the information in the "
526	  "Supported Channels element is unacceptable",		/* 24 */
527	"Association denied due to requesting station not supporting "
528	  "short slot operation",				/* 25 */
529	"Association denied due to requesting station not supporting "
530	  "DSSS-OFDM operation",				/* 26 */
531	"Association denied because the requested STA does not support HT "
532	  "features",						/* 27 */
533	"Reserved",						/* 28 */
534	"Association denied because the requested STA does not support "
535	  "the PCO transition time required by the AP",		/* 29 */
536	"Reserved",						/* 30 */
537	"Reserved",						/* 31 */
538	"Unspecified, QoS-related failure",			/* 32 */
539	"Association denied due to QAP having insufficient bandwidth "
540	  "to handle another QSTA",				/* 33 */
541	"Association denied due to excessive frame loss rates and/or "
542	  "poor conditions on current operating channel",	/* 34 */
543	"Association (with QBSS) denied due to requesting station not "
544	  "supporting the QoS facility",			/* 35 */
545	"Association denied due to requesting station not supporting "
546	  "Block Ack",						/* 36 */
547	"The request has been declined",			/* 37 */
548	"The request has not been successful as one or more parameters "
549	  "have invalid values",				/* 38 */
550	"The TS has not been created because the request cannot be honored. "
551	  "However, a suggested TSPEC is provided so that the initiating QSTA"
552	  "may attempt to set another TS with the suggested changes to the "
553	  "TSPEC",						/* 39 */
554	"Invalid Information Element",				/* 40 */
555	"Group Cipher is not valid",				/* 41 */
556	"Pairwise Cipher is not valid",				/* 42 */
557	"AKMP is not valid",					/* 43 */
558	"Unsupported RSN IE version",				/* 44 */
559	"Invalid RSN IE Capabilities",				/* 45 */
560	"Cipher suite is rejected per security policy",		/* 46 */
561	"The TS has not been created. However, the HC may be capable of "
562	  "creating a TS, in response to a request, after the time indicated "
563	  "in the TS Delay element",				/* 47 */
564	"Direct Link is not allowed in the BSS by policy",	/* 48 */
565	"Destination STA is not present within this QBSS.",	/* 49 */
566	"The Destination STA is not a QSTA.",			/* 50 */
567
568};
569#define NUM_STATUSES	(sizeof status_text / sizeof status_text[0])
570
571static const char *reason_text[] = {
572	"Reserved",						/* 0 */
573	"Unspecified reason",					/* 1 */
574	"Previous authentication no longer valid",  		/* 2 */
575	"Deauthenticated because sending station is leaving (or has left) "
576	  "IBSS or ESS",					/* 3 */
577	"Disassociated due to inactivity",			/* 4 */
578	"Disassociated because AP is unable to handle all currently "
579	  " associated stations",				/* 5 */
580	"Class 2 frame received from nonauthenticated station", /* 6 */
581	"Class 3 frame received from nonassociated station",	/* 7 */
582	"Disassociated because sending station is leaving "
583	  "(or has left) BSS",					/* 8 */
584	"Station requesting (re)association is not authenticated with "
585	  "responding station",					/* 9 */
586	"Disassociated because the information in the Power Capability "
587	  "element is unacceptable",				/* 10 */
588	"Disassociated because the information in the SupportedChannels "
589	  "element is unacceptable",				/* 11 */
590	"Invalid Information Element",				/* 12 */
591	"Reserved",						/* 13 */
592	"Michael MIC failure",					/* 14 */
593	"4-Way Handshake timeout",				/* 15 */
594	"Group key update timeout",				/* 16 */
595	"Information element in 4-Way Handshake different from (Re)Association"
596	  "Request/Probe Response/Beacon",			/* 17 */
597	"Group Cipher is not valid",				/* 18 */
598	"AKMP is not valid",					/* 20 */
599	"Unsupported RSN IE version",				/* 21 */
600	"Invalid RSN IE Capabilities",				/* 22 */
601	"IEEE 802.1X Authentication failed",			/* 23 */
602	"Cipher suite is rejected per security policy",		/* 24 */
603	"Reserved",						/* 25 */
604	"Reserved",						/* 26 */
605	"Reserved",						/* 27 */
606	"Reserved",						/* 28 */
607	"Reserved",						/* 29 */
608	"Reserved",						/* 30 */
609	"TS deleted because QoS AP lacks sufficient bandwidth for this "
610	  "QoS STA due to a change in BSS service characteristics or "
611	  "operational mode (e.g. an HT BSS change from 40 MHz channel "
612	  "to 20 MHz channel)",					/* 31 */
613	"Disassociated for unspecified, QoS-related reason",	/* 32 */
614	"Disassociated because QoS AP lacks sufficient bandwidth for this "
615	  "QoS STA",						/* 33 */
616	"Disassociated because of excessive number of frames that need to be "
617          "acknowledged, but are not acknowledged for AP transmissions "
618	  "and/or poor channel conditions",			/* 34 */
619	"Disassociated because STA is transmitting outside the limits "
620	  "of its TXOPs",					/* 35 */
621	"Requested from peer STA as the STA is leaving the BSS "
622	  "(or resetting)",					/* 36 */
623	"Requested from peer STA as it does not want to use the "
624	  "mechanism",						/* 37 */
625	"Requested from peer STA as the STA received frames using the "
626	  "mechanism for which a set up is required",		/* 38 */
627	"Requested from peer STA due to time out",		/* 39 */
628	"Reserved",						/* 40 */
629	"Reserved",						/* 41 */
630	"Reserved",						/* 42 */
631	"Reserved",						/* 43 */
632	"Reserved",						/* 44 */
633	"Peer STA does not support the requested cipher suite",	/* 45 */
634	"Association denied due to requesting STA not supporting HT "
635	  "features",						/* 46 */
636};
637#define NUM_REASONS	(sizeof reason_text / sizeof reason_text[0])
638
639static int
640wep_print(const u_char *p)
641{
642	u_int32_t iv;
643
644	if (!TTEST2(*p, IEEE802_11_IV_LEN + IEEE802_11_KID_LEN))
645		return 0;
646	iv = EXTRACT_LE_32BITS(p);
647
648	printf("Data IV:%3x Pad %x KeyID %x", IV_IV(iv), IV_PAD(iv),
649	    IV_KEYID(iv));
650
651	return 1;
652}
653
654static int
655parse_elements(struct mgmt_body_t *pbody, const u_char *p, int offset,
656    u_int length)
657{
658	u_int elementlen;
659	struct ssid_t ssid;
660	struct challenge_t challenge;
661	struct rates_t rates;
662	struct ds_t ds;
663	struct cf_t cf;
664	struct tim_t tim;
665
666	/*
667	 * We haven't seen any elements yet.
668	 */
669	pbody->challenge_present = 0;
670	pbody->ssid_present = 0;
671	pbody->rates_present = 0;
672	pbody->ds_present = 0;
673	pbody->cf_present = 0;
674	pbody->tim_present = 0;
675
676	while (length != 0) {
677		if (!TTEST2(*(p + offset), 1))
678			return 0;
679		if (length < 1)
680			return 0;
681		switch (*(p + offset)) {
682		case E_SSID:
683			if (!TTEST2(*(p + offset), 2))
684				return 0;
685			if (length < 2)
686				return 0;
687			memcpy(&ssid, p + offset, 2);
688			offset += 2;
689			length -= 2;
690			if (ssid.length != 0) {
691				if (ssid.length > sizeof(ssid.ssid) - 1)
692					return 0;
693				if (!TTEST2(*(p + offset), ssid.length))
694					return 0;
695				if (length < ssid.length)
696					return 0;
697				memcpy(&ssid.ssid, p + offset, ssid.length);
698				offset += ssid.length;
699				length -= ssid.length;
700			}
701			ssid.ssid[ssid.length] = '\0';
702			/*
703			 * Present and not truncated.
704			 *
705			 * If we haven't already seen an SSID IE,
706			 * copy this one, otherwise ignore this one,
707			 * so we later report the first one we saw.
708			 */
709			if (!pbody->ssid_present) {
710				pbody->ssid = ssid;
711				pbody->ssid_present = 1;
712			}
713			break;
714		case E_CHALLENGE:
715			if (!TTEST2(*(p + offset), 2))
716				return 0;
717			if (length < 2)
718				return 0;
719			memcpy(&challenge, p + offset, 2);
720			offset += 2;
721			length -= 2;
722			if (challenge.length != 0) {
723				if (challenge.length >
724				    sizeof(challenge.text) - 1)
725					return 0;
726				if (!TTEST2(*(p + offset), challenge.length))
727					return 0;
728				if (length < challenge.length)
729					return 0;
730				memcpy(&challenge.text, p + offset,
731				    challenge.length);
732				offset += challenge.length;
733				length -= challenge.length;
734			}
735			challenge.text[challenge.length] = '\0';
736			/*
737			 * Present and not truncated.
738			 *
739			 * If we haven't already seen a challenge IE,
740			 * copy this one, otherwise ignore this one,
741			 * so we later report the first one we saw.
742			 */
743			if (!pbody->challenge_present) {
744				pbody->challenge = challenge;
745				pbody->challenge_present = 1;
746			}
747			break;
748		case E_RATES:
749			if (!TTEST2(*(p + offset), 2))
750				return 0;
751			if (length < 2)
752				return 0;
753			memcpy(&rates, p + offset, 2);
754			offset += 2;
755			length -= 2;
756			if (rates.length != 0) {
757				if (rates.length > sizeof rates.rate)
758					return 0;
759				if (!TTEST2(*(p + offset), rates.length))
760					return 0;
761				if (length < rates.length)
762					return 0;
763				memcpy(&rates.rate, p + offset, rates.length);
764				offset += rates.length;
765				length -= rates.length;
766			}
767			/*
768			 * Present and not truncated.
769			 *
770			 * If we haven't already seen a rates IE,
771			 * copy this one if it's not zero-length,
772			 * otherwise ignore this one, so we later
773			 * report the first one we saw.
774			 *
775			 * We ignore zero-length rates IEs as some
776			 * devices seem to put a zero-length rates
777			 * IE, followed by an SSID IE, followed by
778			 * a non-zero-length rates IE into frames,
779			 * even though IEEE Std 802.11-2007 doesn't
780			 * seem to indicate that a zero-length rates
781			 * IE is valid.
782			 */
783			if (!pbody->rates_present && rates.length != 0) {
784				pbody->rates = rates;
785				pbody->rates_present = 1;
786			}
787			break;
788		case E_DS:
789			if (!TTEST2(*(p + offset), 3))
790				return 0;
791			if (length < 3)
792				return 0;
793			memcpy(&ds, p + offset, 3);
794			offset += 3;
795			length -= 3;
796			/*
797			 * Present and not truncated.
798			 *
799			 * If we haven't already seen a DS IE,
800			 * copy this one, otherwise ignore this one,
801			 * so we later report the first one we saw.
802			 */
803			if (!pbody->ds_present) {
804				pbody->ds = ds;
805				pbody->ds_present = 1;
806			}
807			break;
808		case E_CF:
809			if (!TTEST2(*(p + offset), 8))
810				return 0;
811			if (length < 8)
812				return 0;
813			memcpy(&cf, p + offset, 8);
814			offset += 8;
815			length -= 8;
816			/*
817			 * Present and not truncated.
818			 *
819			 * If we haven't already seen a CF IE,
820			 * copy this one, otherwise ignore this one,
821			 * so we later report the first one we saw.
822			 */
823			if (!pbody->cf_present) {
824				pbody->cf = cf;
825				pbody->cf_present = 1;
826			}
827			break;
828		case E_TIM:
829			if (!TTEST2(*(p + offset), 2))
830				return 0;
831			if (length < 2)
832				return 0;
833			memcpy(&tim, p + offset, 2);
834			offset += 2;
835			length -= 2;
836			if (!TTEST2(*(p + offset), 3))
837				return 0;
838			if (length < 3)
839				return 0;
840			memcpy(&tim.count, p + offset, 3);
841			offset += 3;
842			length -= 3;
843
844			if (tim.length <= 3)
845				break;
846			if (tim.length - 3 > (int)sizeof tim.bitmap)
847				return 0;
848			if (!TTEST2(*(p + offset), tim.length - 3))
849				return 0;
850			if (length < (u_int)(tim.length - 3))
851				return 0;
852			memcpy(tim.bitmap, p + (tim.length - 3),
853			    (tim.length - 3));
854			offset += tim.length - 3;
855			length -= tim.length - 3;
856			/*
857			 * Present and not truncated.
858			 *
859			 * If we haven't already seen a TIM IE,
860			 * copy this one, otherwise ignore this one,
861			 * so we later report the first one we saw.
862			 */
863			if (!pbody->tim_present) {
864				pbody->tim = tim;
865				pbody->tim_present = 1;
866			}
867			break;
868		default:
869#if 0
870			printf("(1) unhandled element_id (%d)  ",
871			    *(p + offset));
872#endif
873			if (!TTEST2(*(p + offset), 2))
874				return 0;
875			if (length < 2)
876				return 0;
877			elementlen = *(p + offset + 1);
878			if (!TTEST2(*(p + offset + 2), elementlen))
879				return 0;
880			if (length < elementlen + 2)
881				return 0;
882			offset += elementlen + 2;
883			length -= elementlen + 2;
884			break;
885		}
886	}
887
888	/* No problems found. */
889	return 1;
890}
891
892/*********************************************************************************
893 * Print Handle functions for the management frame types
894 *********************************************************************************/
895
896static int
897handle_beacon(const u_char *p, u_int length)
898{
899	struct mgmt_body_t pbody;
900	int offset = 0;
901	int ret;
902
903	memset(&pbody, 0, sizeof(pbody));
904
905	if (!TTEST2(*p, IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN +
906	    IEEE802_11_CAPINFO_LEN))
907		return 0;
908	if (length < IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN +
909	    IEEE802_11_CAPINFO_LEN)
910		return 0;
911	memcpy(&pbody.timestamp, p, IEEE802_11_TSTAMP_LEN);
912	offset += IEEE802_11_TSTAMP_LEN;
913	length -= IEEE802_11_TSTAMP_LEN;
914	pbody.beacon_interval = EXTRACT_LE_16BITS(p+offset);
915	offset += IEEE802_11_BCNINT_LEN;
916	length -= IEEE802_11_BCNINT_LEN;
917	pbody.capability_info = EXTRACT_LE_16BITS(p+offset);
918	offset += IEEE802_11_CAPINFO_LEN;
919	length -= IEEE802_11_CAPINFO_LEN;
920
921	ret = parse_elements(&pbody, p, offset, length);
922
923	PRINT_SSID(pbody);
924	PRINT_RATES(pbody);
925	printf(" %s",
926	    CAPABILITY_ESS(pbody.capability_info) ? "ESS" : "IBSS");
927	PRINT_DS_CHANNEL(pbody);
928
929	return ret;
930}
931
932static int
933handle_assoc_request(const u_char *p, u_int length)
934{
935	struct mgmt_body_t pbody;
936	int offset = 0;
937	int ret;
938
939	memset(&pbody, 0, sizeof(pbody));
940
941	if (!TTEST2(*p, IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN))
942		return 0;
943	if (length < IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN)
944		return 0;
945	pbody.capability_info = EXTRACT_LE_16BITS(p);
946	offset += IEEE802_11_CAPINFO_LEN;
947	length -= IEEE802_11_CAPINFO_LEN;
948	pbody.listen_interval = EXTRACT_LE_16BITS(p+offset);
949	offset += IEEE802_11_LISTENINT_LEN;
950	length -= IEEE802_11_LISTENINT_LEN;
951
952	ret = parse_elements(&pbody, p, offset, length);
953
954	PRINT_SSID(pbody);
955	PRINT_RATES(pbody);
956	return ret;
957}
958
959static int
960handle_assoc_response(const u_char *p, u_int length)
961{
962	struct mgmt_body_t pbody;
963	int offset = 0;
964	int ret;
965
966	memset(&pbody, 0, sizeof(pbody));
967
968	if (!TTEST2(*p, IEEE802_11_CAPINFO_LEN + IEEE802_11_STATUS_LEN +
969	    IEEE802_11_AID_LEN))
970		return 0;
971	if (length < IEEE802_11_CAPINFO_LEN + IEEE802_11_STATUS_LEN +
972	    IEEE802_11_AID_LEN)
973		return 0;
974	pbody.capability_info = EXTRACT_LE_16BITS(p);
975	offset += IEEE802_11_CAPINFO_LEN;
976	length -= IEEE802_11_CAPINFO_LEN;
977	pbody.status_code = EXTRACT_LE_16BITS(p+offset);
978	offset += IEEE802_11_STATUS_LEN;
979	length -= IEEE802_11_STATUS_LEN;
980	pbody.aid = EXTRACT_LE_16BITS(p+offset);
981	offset += IEEE802_11_AID_LEN;
982	length -= IEEE802_11_AID_LEN;
983
984	ret = parse_elements(&pbody, p, offset, length);
985
986	printf(" AID(%x) :%s: %s", ((u_int16_t)(pbody.aid << 2 )) >> 2 ,
987	    CAPABILITY_PRIVACY(pbody.capability_info) ? " PRIVACY " : "",
988	    (pbody.status_code < NUM_STATUSES
989		? status_text[pbody.status_code]
990		: "n/a"));
991
992	return ret;
993}
994
995static int
996handle_reassoc_request(const u_char *p, u_int length)
997{
998	struct mgmt_body_t pbody;
999	int offset = 0;
1000	int ret;
1001
1002	memset(&pbody, 0, sizeof(pbody));
1003
1004	if (!TTEST2(*p, IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN +
1005	    IEEE802_11_AP_LEN))
1006		return 0;
1007	if (length < IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN +
1008	    IEEE802_11_AP_LEN)
1009		return 0;
1010	pbody.capability_info = EXTRACT_LE_16BITS(p);
1011	offset += IEEE802_11_CAPINFO_LEN;
1012	length -= IEEE802_11_CAPINFO_LEN;
1013	pbody.listen_interval = EXTRACT_LE_16BITS(p+offset);
1014	offset += IEEE802_11_LISTENINT_LEN;
1015	length -= IEEE802_11_LISTENINT_LEN;
1016	memcpy(&pbody.ap, p+offset, IEEE802_11_AP_LEN);
1017	offset += IEEE802_11_AP_LEN;
1018	length -= IEEE802_11_AP_LEN;
1019
1020	ret = parse_elements(&pbody, p, offset, length);
1021
1022	PRINT_SSID(pbody);
1023	printf(" AP : %s", etheraddr_string( pbody.ap ));
1024
1025	return ret;
1026}
1027
1028static int
1029handle_reassoc_response(const u_char *p, u_int length)
1030{
1031	/* Same as a Association Reponse */
1032	return handle_assoc_response(p, length);
1033}
1034
1035static int
1036handle_probe_request(const u_char *p, u_int length)
1037{
1038	struct mgmt_body_t  pbody;
1039	int offset = 0;
1040	int ret;
1041
1042	memset(&pbody, 0, sizeof(pbody));
1043
1044	ret = parse_elements(&pbody, p, offset, length);
1045
1046	PRINT_SSID(pbody);
1047	PRINT_RATES(pbody);
1048
1049	return ret;
1050}
1051
1052static int
1053handle_probe_response(const u_char *p, u_int length)
1054{
1055	struct mgmt_body_t  pbody;
1056	int offset = 0;
1057	int ret;
1058
1059	memset(&pbody, 0, sizeof(pbody));
1060
1061	if (!TTEST2(*p, IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN +
1062	    IEEE802_11_CAPINFO_LEN))
1063		return 0;
1064	if (length < IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN +
1065	    IEEE802_11_CAPINFO_LEN)
1066		return 0;
1067	memcpy(&pbody.timestamp, p, IEEE802_11_TSTAMP_LEN);
1068	offset += IEEE802_11_TSTAMP_LEN;
1069	length -= IEEE802_11_TSTAMP_LEN;
1070	pbody.beacon_interval = EXTRACT_LE_16BITS(p+offset);
1071	offset += IEEE802_11_BCNINT_LEN;
1072	length -= IEEE802_11_BCNINT_LEN;
1073	pbody.capability_info = EXTRACT_LE_16BITS(p+offset);
1074	offset += IEEE802_11_CAPINFO_LEN;
1075	length -= IEEE802_11_CAPINFO_LEN;
1076
1077	ret = parse_elements(&pbody, p, offset, length);
1078
1079	PRINT_SSID(pbody);
1080	PRINT_RATES(pbody);
1081	PRINT_DS_CHANNEL(pbody);
1082
1083	return ret;
1084}
1085
1086static int
1087handle_atim(void)
1088{
1089	/* the frame body for ATIM is null. */
1090	return 1;
1091}
1092
1093static int
1094handle_disassoc(const u_char *p, u_int length)
1095{
1096	struct mgmt_body_t  pbody;
1097
1098	memset(&pbody, 0, sizeof(pbody));
1099
1100	if (!TTEST2(*p, IEEE802_11_REASON_LEN))
1101		return 0;
1102	if (length < IEEE802_11_REASON_LEN)
1103		return 0;
1104	pbody.reason_code = EXTRACT_LE_16BITS(p);
1105
1106	printf(": %s",
1107	    (pbody.reason_code < NUM_REASONS)
1108		? reason_text[pbody.reason_code]
1109		: "Reserved" );
1110
1111	return 1;
1112}
1113
1114static int
1115handle_auth(const u_char *p, u_int length)
1116{
1117	struct mgmt_body_t  pbody;
1118	int offset = 0;
1119	int ret;
1120
1121	memset(&pbody, 0, sizeof(pbody));
1122
1123	if (!TTEST2(*p, 6))
1124		return 0;
1125	if (length < 6)
1126		return 0;
1127	pbody.auth_alg = EXTRACT_LE_16BITS(p);
1128	offset += 2;
1129	length -= 2;
1130	pbody.auth_trans_seq_num = EXTRACT_LE_16BITS(p + offset);
1131	offset += 2;
1132	length -= 2;
1133	pbody.status_code = EXTRACT_LE_16BITS(p + offset);
1134	offset += 2;
1135	length -= 2;
1136
1137	ret = parse_elements(&pbody, p, offset, length);
1138
1139	if ((pbody.auth_alg == 1) &&
1140	    ((pbody.auth_trans_seq_num == 2) ||
1141	     (pbody.auth_trans_seq_num == 3))) {
1142		printf(" (%s)-%x [Challenge Text] %s",
1143		    (pbody.auth_alg < NUM_AUTH_ALGS)
1144			? auth_alg_text[pbody.auth_alg]
1145			: "Reserved",
1146		    pbody.auth_trans_seq_num,
1147		    ((pbody.auth_trans_seq_num % 2)
1148		        ? ((pbody.status_code < NUM_STATUSES)
1149			       ? status_text[pbody.status_code]
1150			       : "n/a") : ""));
1151		return ret;
1152	}
1153	printf(" (%s)-%x: %s",
1154	    (pbody.auth_alg < NUM_AUTH_ALGS)
1155		? auth_alg_text[pbody.auth_alg]
1156		: "Reserved",
1157	    pbody.auth_trans_seq_num,
1158	    (pbody.auth_trans_seq_num % 2)
1159	        ? ((pbody.status_code < NUM_STATUSES)
1160		    ? status_text[pbody.status_code]
1161	            : "n/a")
1162	        : "");
1163
1164	return ret;
1165}
1166
1167static int
1168handle_deauth(const struct mgmt_header_t *pmh, const u_char *p, u_int length)
1169{
1170	struct mgmt_body_t  pbody;
1171	int offset = 0;
1172	const char *reason = NULL;
1173
1174	memset(&pbody, 0, sizeof(pbody));
1175
1176	if (!TTEST2(*p, IEEE802_11_REASON_LEN))
1177		return 0;
1178	if (length < IEEE802_11_REASON_LEN)
1179		return 0;
1180	pbody.reason_code = EXTRACT_LE_16BITS(p);
1181	offset += IEEE802_11_REASON_LEN;
1182	length -= IEEE802_11_REASON_LEN;
1183
1184	reason = (pbody.reason_code < NUM_REASONS)
1185			? reason_text[pbody.reason_code]
1186			: "Reserved";
1187
1188	if (eflag) {
1189		printf(": %s", reason);
1190	} else {
1191		printf(" (%s): %s", etheraddr_string(pmh->sa), reason);
1192	}
1193	return 1;
1194}
1195
1196#define	PRINT_HT_ACTION(v) (\
1197	(v) == 0 ? printf("TxChWidth") : \
1198	(v) == 1 ? printf("MIMOPwrSave") : \
1199		   printf("Act#%d", (v)) \
1200)
1201#define	PRINT_BA_ACTION(v) (\
1202	(v) == 0 ? printf("ADDBA Request") : \
1203	(v) == 1 ? printf("ADDBA Response") : \
1204	(v) == 2 ? printf("DELBA") : \
1205		   printf("Act#%d", (v)) \
1206)
1207#define	PRINT_MESHLINK_ACTION(v) (\
1208	(v) == 0 ? printf("Request") : \
1209	(v) == 1 ? printf("Report") : \
1210		   printf("Act#%d", (v)) \
1211)
1212#define	PRINT_MESHPEERING_ACTION(v) (\
1213	(v) == 0 ? printf("Open") : \
1214	(v) == 1 ? printf("Confirm") : \
1215	(v) == 2 ? printf("Close") : \
1216		   printf("Act#%d", (v)) \
1217)
1218#define	PRINT_MESHPATH_ACTION(v) (\
1219	(v) == 0 ? printf("Request") : \
1220	(v) == 1 ? printf("Report") : \
1221	(v) == 2 ? printf("Error") : \
1222	(v) == 3 ? printf("RootAnnouncement") : \
1223		   printf("Act#%d", (v)) \
1224)
1225
1226static int
1227handle_action(const struct mgmt_header_t *pmh, const u_char *p, u_int length)
1228{
1229	if (!TTEST2(*p, 2))
1230		return 0;
1231	if (length < 2)
1232		return 0;
1233	if (eflag) {
1234		printf(": ");
1235	} else {
1236		printf(" (%s): ", etheraddr_string(pmh->sa));
1237	}
1238	switch (p[0]) {
1239	case 0: printf("Spectrum Management Act#%d", p[1]); break;
1240	case 1: printf("QoS Act#%d", p[1]); break;
1241	case 2: printf("DLS Act#%d", p[1]); break;
1242	case 3: printf("BA "); PRINT_BA_ACTION(p[1]); break;
1243	case 7: printf("HT "); PRINT_HT_ACTION(p[1]); break;
1244	case 13: printf("MeshLMetric "); PRINT_MESHLINK_ACTION(p[1]); break;
1245	case 15: printf("Interwork Act#%d", p[1]); break;
1246	case 16: printf("Resource Act#%d", p[1]); break;
1247	case 17: printf("Proxy Act#%d", p[1]); break;
1248	case 30: printf("MeshPeering "); PRINT_MESHPEERING_ACTION(p[1]); break;
1249	case 32: printf("MeshPath "); PRINT_MESHPATH_ACTION(p[1]); break;
1250	case 127: printf("Vendor Act#%d", p[1]); break;
1251	default:
1252		printf("Reserved(%d) Act#%d", p[0], p[1]);
1253		break;
1254	}
1255	return 1;
1256}
1257
1258
1259/*********************************************************************************
1260 * Print Body funcs
1261 *********************************************************************************/
1262
1263
1264static int
1265mgmt_body_print(u_int16_t fc, const struct mgmt_header_t *pmh,
1266    const u_char *p, u_int length)
1267{
1268	switch (FC_SUBTYPE(fc)) {
1269	case ST_ASSOC_REQUEST:
1270		printf("Assoc Request");
1271		return handle_assoc_request(p, length);
1272	case ST_ASSOC_RESPONSE:
1273		printf("Assoc Response");
1274		return handle_assoc_response(p, length);
1275	case ST_REASSOC_REQUEST:
1276		printf("ReAssoc Request");
1277		return handle_reassoc_request(p, length);
1278	case ST_REASSOC_RESPONSE:
1279		printf("ReAssoc Response");
1280		return handle_reassoc_response(p, length);
1281	case ST_PROBE_REQUEST:
1282		printf("Probe Request");
1283		return handle_probe_request(p, length);
1284	case ST_PROBE_RESPONSE:
1285		printf("Probe Response");
1286		return handle_probe_response(p, length);
1287	case ST_BEACON:
1288		printf("Beacon");
1289		return handle_beacon(p, length);
1290	case ST_ATIM:
1291		printf("ATIM");
1292		return handle_atim();
1293	case ST_DISASSOC:
1294		printf("Disassociation");
1295		return handle_disassoc(p, length);
1296	case ST_AUTH:
1297		printf("Authentication");
1298		if (!TTEST2(*p, 3))
1299			return 0;
1300		if ((p[0] == 0 ) && (p[1] == 0) && (p[2] == 0)) {
1301			printf("Authentication (Shared-Key)-3 ");
1302			return wep_print(p);
1303		}
1304		return handle_auth(p, length);
1305	case ST_DEAUTH:
1306		printf("DeAuthentication");
1307		return handle_deauth(pmh, p, length);
1308		break;
1309	case ST_ACTION:
1310		printf("Action");
1311		return handle_action(pmh, p, length);
1312		break;
1313	default:
1314		printf("Unhandled Management subtype(%x)",
1315		    FC_SUBTYPE(fc));
1316		return 1;
1317	}
1318}
1319
1320
1321/*********************************************************************************
1322 * Handles printing all the control frame types
1323 *********************************************************************************/
1324
1325static int
1326ctrl_body_print(u_int16_t fc, const u_char *p)
1327{
1328	switch (FC_SUBTYPE(fc)) {
1329	case CTRL_CONTROL_WRAPPER:
1330		printf("Control Wrapper");
1331		/* XXX - requires special handling */
1332		break;
1333	case CTRL_BAR:
1334		printf("BAR");
1335		if (!TTEST2(*p, CTRL_BAR_HDRLEN))
1336			return 0;
1337		if (!eflag)
1338			printf(" RA:%s TA:%s CTL(%x) SEQ(%u) ",
1339			    etheraddr_string(((const struct ctrl_bar_t *)p)->ra),
1340			    etheraddr_string(((const struct ctrl_bar_t *)p)->ta),
1341			    EXTRACT_LE_16BITS(&(((const struct ctrl_bar_t *)p)->ctl)),
1342			    EXTRACT_LE_16BITS(&(((const struct ctrl_bar_t *)p)->seq)));
1343		break;
1344	case CTRL_BA:
1345		printf("BA");
1346		if (!TTEST2(*p, CTRL_BA_HDRLEN))
1347			return 0;
1348		if (!eflag)
1349			printf(" RA:%s ",
1350			    etheraddr_string(((const struct ctrl_ba_t *)p)->ra));
1351		break;
1352	case CTRL_PS_POLL:
1353		printf("Power Save-Poll");
1354		if (!TTEST2(*p, CTRL_PS_POLL_HDRLEN))
1355			return 0;
1356		printf(" AID(%x)",
1357		    EXTRACT_LE_16BITS(&(((const struct ctrl_ps_poll_t *)p)->aid)));
1358		break;
1359	case CTRL_RTS:
1360		printf("Request-To-Send");
1361		if (!TTEST2(*p, CTRL_RTS_HDRLEN))
1362			return 0;
1363		if (!eflag)
1364			printf(" TA:%s ",
1365			    etheraddr_string(((const struct ctrl_rts_t *)p)->ta));
1366		break;
1367	case CTRL_CTS:
1368		printf("Clear-To-Send");
1369		if (!TTEST2(*p, CTRL_CTS_HDRLEN))
1370			return 0;
1371		if (!eflag)
1372			printf(" RA:%s ",
1373			    etheraddr_string(((const struct ctrl_cts_t *)p)->ra));
1374		break;
1375	case CTRL_ACK:
1376		printf("Acknowledgment");
1377		if (!TTEST2(*p, CTRL_ACK_HDRLEN))
1378			return 0;
1379		if (!eflag)
1380			printf(" RA:%s ",
1381			    etheraddr_string(((const struct ctrl_ack_t *)p)->ra));
1382		break;
1383	case CTRL_CF_END:
1384		printf("CF-End");
1385		if (!TTEST2(*p, CTRL_END_HDRLEN))
1386			return 0;
1387		if (!eflag)
1388			printf(" RA:%s ",
1389			    etheraddr_string(((const struct ctrl_end_t *)p)->ra));
1390		break;
1391	case CTRL_END_ACK:
1392		printf("CF-End+CF-Ack");
1393		if (!TTEST2(*p, CTRL_END_ACK_HDRLEN))
1394			return 0;
1395		if (!eflag)
1396			printf(" RA:%s ",
1397			    etheraddr_string(((const struct ctrl_end_ack_t *)p)->ra));
1398		break;
1399	default:
1400		printf("Unknown Ctrl Subtype");
1401	}
1402	return 1;
1403}
1404
1405/*
1406 * Print Header funcs
1407 */
1408
1409/*
1410 *  Data Frame - Address field contents
1411 *
1412 *  To Ds  | From DS | Addr 1 | Addr 2 | Addr 3 | Addr 4
1413 *    0    |  0      |  DA    | SA     | BSSID  | n/a
1414 *    0    |  1      |  DA    | BSSID  | SA     | n/a
1415 *    1    |  0      |  BSSID | SA     | DA     | n/a
1416 *    1    |  1      |  RA    | TA     | DA     | SA
1417 */
1418
1419static void
1420data_header_print(u_int16_t fc, const u_char *p, const u_int8_t **srcp,
1421    const u_int8_t **dstp)
1422{
1423	u_int subtype = FC_SUBTYPE(fc);
1424
1425	if (DATA_FRAME_IS_CF_ACK(subtype) || DATA_FRAME_IS_CF_POLL(subtype) ||
1426	    DATA_FRAME_IS_QOS(subtype)) {
1427		printf("CF ");
1428		if (DATA_FRAME_IS_CF_ACK(subtype)) {
1429			if (DATA_FRAME_IS_CF_POLL(subtype))
1430				printf("Ack/Poll");
1431			else
1432				printf("Ack");
1433		} else {
1434			if (DATA_FRAME_IS_CF_POLL(subtype))
1435				printf("Poll");
1436		}
1437		if (DATA_FRAME_IS_QOS(subtype))
1438			printf("+QoS");
1439		printf(" ");
1440	}
1441
1442#define ADDR1  (p + 4)
1443#define ADDR2  (p + 10)
1444#define ADDR3  (p + 16)
1445#define ADDR4  (p + 24)
1446
1447	if (!FC_TO_DS(fc) && !FC_FROM_DS(fc)) {
1448		if (srcp != NULL)
1449			*srcp = ADDR2;
1450		if (dstp != NULL)
1451			*dstp = ADDR1;
1452		if (!eflag)
1453			return;
1454		printf("DA:%s SA:%s BSSID:%s ",
1455		    etheraddr_string(ADDR1), etheraddr_string(ADDR2),
1456		    etheraddr_string(ADDR3));
1457	} else if (!FC_TO_DS(fc) && FC_FROM_DS(fc)) {
1458		if (srcp != NULL)
1459			*srcp = ADDR3;
1460		if (dstp != NULL)
1461			*dstp = ADDR1;
1462		if (!eflag)
1463			return;
1464		printf("DA:%s BSSID:%s SA:%s ",
1465		    etheraddr_string(ADDR1), etheraddr_string(ADDR2),
1466		    etheraddr_string(ADDR3));
1467	} else if (FC_TO_DS(fc) && !FC_FROM_DS(fc)) {
1468		if (srcp != NULL)
1469			*srcp = ADDR2;
1470		if (dstp != NULL)
1471			*dstp = ADDR3;
1472		if (!eflag)
1473			return;
1474		printf("BSSID:%s SA:%s DA:%s ",
1475		    etheraddr_string(ADDR1), etheraddr_string(ADDR2),
1476		    etheraddr_string(ADDR3));
1477	} else if (FC_TO_DS(fc) && FC_FROM_DS(fc)) {
1478		if (srcp != NULL)
1479			*srcp = ADDR4;
1480		if (dstp != NULL)
1481			*dstp = ADDR3;
1482		if (!eflag)
1483			return;
1484		printf("RA:%s TA:%s DA:%s SA:%s ",
1485		    etheraddr_string(ADDR1), etheraddr_string(ADDR2),
1486		    etheraddr_string(ADDR3), etheraddr_string(ADDR4));
1487	}
1488
1489#undef ADDR1
1490#undef ADDR2
1491#undef ADDR3
1492#undef ADDR4
1493}
1494
1495static void
1496mgmt_header_print(const u_char *p, const u_int8_t **srcp,
1497    const u_int8_t **dstp)
1498{
1499	const struct mgmt_header_t *hp = (const struct mgmt_header_t *) p;
1500
1501	if (srcp != NULL)
1502		*srcp = hp->sa;
1503	if (dstp != NULL)
1504		*dstp = hp->da;
1505	if (!eflag)
1506		return;
1507
1508	printf("BSSID:%s DA:%s SA:%s ",
1509	    etheraddr_string((hp)->bssid), etheraddr_string((hp)->da),
1510	    etheraddr_string((hp)->sa));
1511}
1512
1513static void
1514ctrl_header_print(u_int16_t fc, const u_char *p, const u_int8_t **srcp,
1515    const u_int8_t **dstp)
1516{
1517	if (srcp != NULL)
1518		*srcp = NULL;
1519	if (dstp != NULL)
1520		*dstp = NULL;
1521	if (!eflag)
1522		return;
1523
1524	switch (FC_SUBTYPE(fc)) {
1525	case CTRL_BAR:
1526		printf(" RA:%s TA:%s CTL(%x) SEQ(%u) ",
1527		    etheraddr_string(((const struct ctrl_bar_t *)p)->ra),
1528		    etheraddr_string(((const struct ctrl_bar_t *)p)->ta),
1529		    EXTRACT_LE_16BITS(&(((const struct ctrl_bar_t *)p)->ctl)),
1530		    EXTRACT_LE_16BITS(&(((const struct ctrl_bar_t *)p)->seq)));
1531		break;
1532	case CTRL_BA:
1533		printf("RA:%s ",
1534		    etheraddr_string(((const struct ctrl_ba_t *)p)->ra));
1535		break;
1536	case CTRL_PS_POLL:
1537		printf("BSSID:%s TA:%s ",
1538		    etheraddr_string(((const struct ctrl_ps_poll_t *)p)->bssid),
1539		    etheraddr_string(((const struct ctrl_ps_poll_t *)p)->ta));
1540		break;
1541	case CTRL_RTS:
1542		printf("RA:%s TA:%s ",
1543		    etheraddr_string(((const struct ctrl_rts_t *)p)->ra),
1544		    etheraddr_string(((const struct ctrl_rts_t *)p)->ta));
1545		break;
1546	case CTRL_CTS:
1547		printf("RA:%s ",
1548		    etheraddr_string(((const struct ctrl_cts_t *)p)->ra));
1549		break;
1550	case CTRL_ACK:
1551		printf("RA:%s ",
1552		    etheraddr_string(((const struct ctrl_ack_t *)p)->ra));
1553		break;
1554	case CTRL_CF_END:
1555		printf("RA:%s BSSID:%s ",
1556		    etheraddr_string(((const struct ctrl_end_t *)p)->ra),
1557		    etheraddr_string(((const struct ctrl_end_t *)p)->bssid));
1558		break;
1559	case CTRL_END_ACK:
1560		printf("RA:%s BSSID:%s ",
1561		    etheraddr_string(((const struct ctrl_end_ack_t *)p)->ra),
1562		    etheraddr_string(((const struct ctrl_end_ack_t *)p)->bssid));
1563		break;
1564	default:
1565		printf("(H) Unknown Ctrl Subtype");
1566		break;
1567	}
1568}
1569
1570static int
1571extract_header_length(u_int16_t fc)
1572{
1573	int len;
1574
1575	switch (FC_TYPE(fc)) {
1576	case T_MGMT:
1577		return MGMT_HDRLEN;
1578	case T_CTRL:
1579		switch (FC_SUBTYPE(fc)) {
1580		case CTRL_BAR:
1581			return CTRL_BAR_HDRLEN;
1582		case CTRL_PS_POLL:
1583			return CTRL_PS_POLL_HDRLEN;
1584		case CTRL_RTS:
1585			return CTRL_RTS_HDRLEN;
1586		case CTRL_CTS:
1587			return CTRL_CTS_HDRLEN;
1588		case CTRL_ACK:
1589			return CTRL_ACK_HDRLEN;
1590		case CTRL_CF_END:
1591			return CTRL_END_HDRLEN;
1592		case CTRL_END_ACK:
1593			return CTRL_END_ACK_HDRLEN;
1594		default:
1595			return 0;
1596		}
1597	case T_DATA:
1598		len = (FC_TO_DS(fc) && FC_FROM_DS(fc)) ? 30 : 24;
1599		if (DATA_FRAME_IS_QOS(FC_SUBTYPE(fc)))
1600			len += 2;
1601		return len;
1602	default:
1603		printf("unknown IEEE802.11 frame type (%d)", FC_TYPE(fc));
1604		return 0;
1605	}
1606}
1607
1608static int
1609extract_mesh_header_length(const u_char *p)
1610{
1611	return (p[0] &~ 3) ? 0 : 6*(1 + (p[0] & 3));
1612}
1613
1614/*
1615 * Print the 802.11 MAC header if eflag is set, and set "*srcp" and "*dstp"
1616 * to point to the source and destination MAC addresses in any case if
1617 * "srcp" and "dstp" aren't null.
1618 */
1619static void
1620ieee_802_11_hdr_print(u_int16_t fc, const u_char *p, u_int hdrlen,
1621    u_int meshdrlen, const u_int8_t **srcp, const u_int8_t **dstp)
1622{
1623	if (vflag) {
1624		if (FC_MORE_DATA(fc))
1625			printf("More Data ");
1626		if (FC_MORE_FLAG(fc))
1627			printf("More Fragments ");
1628		if (FC_POWER_MGMT(fc))
1629			printf("Pwr Mgmt ");
1630		if (FC_RETRY(fc))
1631			printf("Retry ");
1632		if (FC_ORDER(fc))
1633			printf("Strictly Ordered ");
1634		if (FC_WEP(fc))
1635			printf("WEP Encrypted ");
1636		if (FC_TYPE(fc) != T_CTRL || FC_SUBTYPE(fc) != CTRL_PS_POLL)
1637			printf("%dus ",
1638			    EXTRACT_LE_16BITS(
1639			        &((const struct mgmt_header_t *)p)->duration));
1640	}
1641	if (meshdrlen != 0) {
1642		const struct meshcntl_t *mc =
1643		    (const struct meshcntl_t *)&p[hdrlen - meshdrlen];
1644		int ae = mc->flags & 3;
1645
1646		printf("MeshData (AE %d TTL %u seq %u", ae, mc->ttl,
1647		    EXTRACT_LE_32BITS(mc->seq));
1648		if (ae > 0)
1649			printf(" A4:%s", etheraddr_string(mc->addr4));
1650		if (ae > 1)
1651			printf(" A5:%s", etheraddr_string(mc->addr5));
1652		if (ae > 2)
1653			printf(" A6:%s", etheraddr_string(mc->addr6));
1654		printf(") ");
1655	}
1656
1657	switch (FC_TYPE(fc)) {
1658	case T_MGMT:
1659		mgmt_header_print(p, srcp, dstp);
1660		break;
1661	case T_CTRL:
1662		ctrl_header_print(fc, p, srcp, dstp);
1663		break;
1664	case T_DATA:
1665		data_header_print(fc, p, srcp, dstp);
1666		break;
1667	default:
1668		printf("(header) unknown IEEE802.11 frame type (%d)",
1669		    FC_TYPE(fc));
1670		*srcp = NULL;
1671		*dstp = NULL;
1672		break;
1673	}
1674}
1675
1676#ifndef roundup2
1677#define	roundup2(x, y)	(((x)+((y)-1))&(~((y)-1))) /* if y is powers of two */
1678#endif
1679
1680static u_int
1681ieee802_11_print(const u_char *p, u_int length, u_int orig_caplen, int pad,
1682    u_int fcslen)
1683{
1684	u_int16_t fc;
1685	u_int caplen, hdrlen, meshdrlen;
1686	const u_int8_t *src, *dst;
1687	u_short extracted_ethertype;
1688
1689	caplen = orig_caplen;
1690	/* Remove FCS, if present */
1691	if (length < fcslen) {
1692		printf("[|802.11]");
1693		return caplen;
1694	}
1695	length -= fcslen;
1696	if (caplen > length) {
1697		/* Amount of FCS in actual packet data, if any */
1698		fcslen = caplen - length;
1699		caplen -= fcslen;
1700		snapend -= fcslen;
1701	}
1702
1703	if (caplen < IEEE802_11_FC_LEN) {
1704		printf("[|802.11]");
1705		return orig_caplen;
1706	}
1707
1708	fc = EXTRACT_LE_16BITS(p);
1709	hdrlen = extract_header_length(fc);
1710	if (pad)
1711		hdrlen = roundup2(hdrlen, 4);
1712	if (Hflag && FC_TYPE(fc) == T_DATA &&
1713	    DATA_FRAME_IS_QOS(FC_SUBTYPE(fc))) {
1714		meshdrlen = extract_mesh_header_length(p+hdrlen);
1715		hdrlen += meshdrlen;
1716	} else
1717		meshdrlen = 0;
1718
1719
1720	if (caplen < hdrlen) {
1721		printf("[|802.11]");
1722		return hdrlen;
1723	}
1724
1725	ieee_802_11_hdr_print(fc, p, hdrlen, meshdrlen, &src, &dst);
1726
1727	/*
1728	 * Go past the 802.11 header.
1729	 */
1730	length -= hdrlen;
1731	caplen -= hdrlen;
1732	p += hdrlen;
1733
1734	switch (FC_TYPE(fc)) {
1735	case T_MGMT:
1736		if (!mgmt_body_print(fc,
1737		    (const struct mgmt_header_t *)(p - hdrlen), p, length)) {
1738			printf("[|802.11]");
1739			return hdrlen;
1740		}
1741		break;
1742	case T_CTRL:
1743		if (!ctrl_body_print(fc, p - hdrlen)) {
1744			printf("[|802.11]");
1745			return hdrlen;
1746		}
1747		break;
1748	case T_DATA:
1749		if (DATA_FRAME_IS_NULL(FC_SUBTYPE(fc)))
1750			return hdrlen;	/* no-data frame */
1751		/* There may be a problem w/ AP not having this bit set */
1752		if (FC_WEP(fc)) {
1753			if (!wep_print(p)) {
1754				printf("[|802.11]");
1755				return hdrlen;
1756			}
1757		} else if (llc_print(p, length, caplen, dst, src,
1758		    &extracted_ethertype) == 0) {
1759			/*
1760			 * Some kinds of LLC packet we cannot
1761			 * handle intelligently
1762			 */
1763			if (!eflag)
1764				ieee_802_11_hdr_print(fc, p - hdrlen, hdrlen,
1765				    meshdrlen, NULL, NULL);
1766			if (extracted_ethertype)
1767				printf("(LLC %s) ",
1768				    etherproto_string(
1769				        htons(extracted_ethertype)));
1770			if (!suppress_default_print)
1771				default_print(p, caplen);
1772		}
1773		break;
1774	default:
1775		printf("unknown 802.11 frame type (%d)", FC_TYPE(fc));
1776		break;
1777	}
1778
1779	return hdrlen;
1780}
1781
1782/*
1783 * This is the top level routine of the printer.  'p' points
1784 * to the 802.11 header of the packet, 'h->ts' is the timestamp,
1785 * 'h->len' is the length of the packet off the wire, and 'h->caplen'
1786 * is the number of bytes actually captured.
1787 */
1788u_int
1789ieee802_11_if_print(const struct pcap_pkthdr *h, const u_char *p)
1790{
1791	return ieee802_11_print(p, h->len, h->caplen, 0, 0);
1792}
1793
1794#define	IEEE80211_CHAN_FHSS \
1795	(IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_GFSK)
1796#define	IEEE80211_CHAN_A \
1797	(IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM)
1798#define	IEEE80211_CHAN_B \
1799	(IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_CCK)
1800#define	IEEE80211_CHAN_PUREG \
1801	(IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_OFDM)
1802#define	IEEE80211_CHAN_G \
1803	(IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_DYN)
1804
1805#define	IS_CHAN_FHSS(flags) \
1806	((flags & IEEE80211_CHAN_FHSS) == IEEE80211_CHAN_FHSS)
1807#define	IS_CHAN_A(flags) \
1808	((flags & IEEE80211_CHAN_A) == IEEE80211_CHAN_A)
1809#define	IS_CHAN_B(flags) \
1810	((flags & IEEE80211_CHAN_B) == IEEE80211_CHAN_B)
1811#define	IS_CHAN_PUREG(flags) \
1812	((flags & IEEE80211_CHAN_PUREG) == IEEE80211_CHAN_PUREG)
1813#define	IS_CHAN_G(flags) \
1814	((flags & IEEE80211_CHAN_G) == IEEE80211_CHAN_G)
1815#define	IS_CHAN_ANYG(flags) \
1816	(IS_CHAN_PUREG(flags) || IS_CHAN_G(flags))
1817
1818static void
1819print_chaninfo(int freq, int flags)
1820{
1821	printf("%u MHz", freq);
1822	if (IS_CHAN_FHSS(flags))
1823		printf(" FHSS");
1824	if (IS_CHAN_A(flags)) {
1825		if (flags & IEEE80211_CHAN_HALF)
1826			printf(" 11a/10Mhz");
1827		else if (flags & IEEE80211_CHAN_QUARTER)
1828			printf(" 11a/5Mhz");
1829		else
1830			printf(" 11a");
1831	}
1832	if (IS_CHAN_ANYG(flags)) {
1833		if (flags & IEEE80211_CHAN_HALF)
1834			printf(" 11g/10Mhz");
1835		else if (flags & IEEE80211_CHAN_QUARTER)
1836			printf(" 11g/5Mhz");
1837		else
1838			printf(" 11g");
1839	} else if (IS_CHAN_B(flags))
1840		printf(" 11b");
1841	if (flags & IEEE80211_CHAN_TURBO)
1842		printf(" Turbo");
1843	if (flags & IEEE80211_CHAN_HT20)
1844		printf(" ht/20");
1845	else if (flags & IEEE80211_CHAN_HT40D)
1846		printf(" ht/40-");
1847	else if (flags & IEEE80211_CHAN_HT40U)
1848		printf(" ht/40+");
1849	printf(" ");
1850}
1851
1852static int
1853print_radiotap_field(struct cpack_state *s, u_int32_t bit, u_int8_t *flags,
1854						struct radiotap_state *state, u_int32_t presentflags)
1855{
1856	union {
1857		int8_t		i8;
1858		u_int8_t	u8;
1859		int16_t		i16;
1860		u_int16_t	u16;
1861		u_int32_t	u32;
1862		u_int64_t	u64;
1863	} u, u2, u3, u4;
1864	int rc;
1865
1866	switch (bit) {
1867	case IEEE80211_RADIOTAP_FLAGS:
1868		rc = cpack_uint8(s, &u.u8);
1869		if (rc != 0)
1870			break;
1871		*flags = u.u8;
1872		break;
1873	case IEEE80211_RADIOTAP_RATE:
1874		rc = cpack_uint8(s, &u.u8);
1875		if (rc != 0)
1876			break;
1877
1878		/* Save state rate */
1879		state->rate = u.u8;
1880		break;
1881	case IEEE80211_RADIOTAP_DB_ANTSIGNAL:
1882	case IEEE80211_RADIOTAP_DB_ANTNOISE:
1883	case IEEE80211_RADIOTAP_ANTENNA:
1884		rc = cpack_uint8(s, &u.u8);
1885		break;
1886	case IEEE80211_RADIOTAP_DBM_ANTSIGNAL:
1887	case IEEE80211_RADIOTAP_DBM_ANTNOISE:
1888		rc = cpack_int8(s, &u.i8);
1889		break;
1890	case IEEE80211_RADIOTAP_CHANNEL:
1891		rc = cpack_uint16(s, &u.u16);
1892		if (rc != 0)
1893			break;
1894		rc = cpack_uint16(s, &u2.u16);
1895		break;
1896	case IEEE80211_RADIOTAP_FHSS:
1897	case IEEE80211_RADIOTAP_LOCK_QUALITY:
1898	case IEEE80211_RADIOTAP_TX_ATTENUATION:
1899	case IEEE80211_RADIOTAP_RX_FLAGS:
1900		rc = cpack_uint16(s, &u.u16);
1901		break;
1902	case IEEE80211_RADIOTAP_DB_TX_ATTENUATION:
1903		rc = cpack_uint8(s, &u.u8);
1904		break;
1905	case IEEE80211_RADIOTAP_DBM_TX_POWER:
1906		rc = cpack_int8(s, &u.i8);
1907		break;
1908	case IEEE80211_RADIOTAP_TSFT:
1909		rc = cpack_uint64(s, &u.u64);
1910		break;
1911	case IEEE80211_RADIOTAP_XCHANNEL:
1912		rc = cpack_uint32(s, &u.u32);
1913		if (rc != 0)
1914			break;
1915		rc = cpack_uint16(s, &u2.u16);
1916		if (rc != 0)
1917			break;
1918		rc = cpack_uint8(s, &u3.u8);
1919		if (rc != 0)
1920			break;
1921		rc = cpack_uint8(s, &u4.u8);
1922		break;
1923	case IEEE80211_RADIOTAP_MCS:
1924		rc = cpack_uint8(s, &u.u8);
1925		if (rc != 0)
1926			break;
1927		rc = cpack_uint8(s, &u2.u8);
1928		if (rc != 0)
1929			break;
1930		rc = cpack_uint8(s, &u3.u8);
1931		break;
1932	case IEEE80211_RADIOTAP_VENDOR_NAMESPACE: {
1933		u_int8_t vns[3];
1934		u_int16_t length;
1935		u_int8_t subspace;
1936
1937		if ((cpack_align_and_reserve(s, 2)) == NULL) {
1938			rc = -1;
1939			break;
1940		}
1941
1942		rc = cpack_uint8(s, &vns[0]);
1943		if (rc != 0)
1944			break;
1945		rc = cpack_uint8(s, &vns[1]);
1946		if (rc != 0)
1947			break;
1948		rc = cpack_uint8(s, &vns[2]);
1949		if (rc != 0)
1950			break;
1951		rc = cpack_uint8(s, &subspace);
1952		if (rc != 0)
1953			break;
1954		rc = cpack_uint16(s, &length);
1955		if (rc != 0)
1956			break;
1957
1958		/* Skip up to length */
1959		s->c_next += length;
1960		break;
1961	}
1962	default:
1963		/* this bit indicates a field whose
1964		 * size we do not know, so we cannot
1965		 * proceed.  Just print the bit number.
1966		 */
1967		printf("[bit %u] ", bit);
1968		return -1;
1969	}
1970
1971	if (rc != 0) {
1972		printf("[|802.11]");
1973		return rc;
1974	}
1975
1976	/* Preserve the state present flags */
1977	state->present = presentflags;
1978
1979	switch (bit) {
1980	case IEEE80211_RADIOTAP_CHANNEL:
1981		/*
1982		 * If CHANNEL and XCHANNEL are both present, skip
1983		 * CHANNEL.
1984		 */
1985		if (presentflags & (1 << IEEE80211_RADIOTAP_XCHANNEL))
1986			break;
1987		print_chaninfo(u.u16, u2.u16);
1988		break;
1989	case IEEE80211_RADIOTAP_FHSS:
1990		printf("fhset %d fhpat %d ", u.u16 & 0xff, (u.u16 >> 8) & 0xff);
1991		break;
1992	case IEEE80211_RADIOTAP_RATE:
1993		/*
1994		 * XXX On FreeBSD rate & 0x80 means we have an MCS. On
1995		 * Linux and AirPcap it does not.  (What about
1996		 * Mac OS X, NetBSD, OpenBSD, and DragonFly BSD?)
1997		 *
1998		 * This is an issue either for proprietary extensions
1999		 * to 11a or 11g, which do exist, or for 11n
2000		 * implementations that stuff a rate value into
2001		 * this field, which also appear to exist.
2002		 *
2003		 * We currently handle that by assuming that
2004		 * if the 0x80 bit is set *and* the remaining
2005		 * bits have a value between 0 and 15 it's
2006		 * an MCS value, otherwise it's a rate.  If
2007		 * there are cases where systems that use
2008		 * "0x80 + MCS index" for MCS indices > 15,
2009		 * or stuff a rate value here between 64 and
2010		 * 71.5 Mb/s in here, we'll need a preference
2011		 * setting.  Such rates do exist, e.g. 11n
2012		 * MCS 7 at 20 MHz with a long guard interval.
2013		 */
2014		if (u.u8 >= 0x80 && u.u8 <= 0x8f) {
2015			/*
2016			 * XXX - we don't know the channel width
2017			 * or guard interval length, so we can't
2018			 * convert this to a data rate.
2019			 *
2020			 * If you want us to show a data rate,
2021			 * use the MCS field, not the Rate field;
2022			 * the MCS field includes not only the
2023			 * MCS index, it also includes bandwidth
2024			 * and guard interval information.
2025			 *
2026			 * XXX - can we get the channel width
2027			 * from XChannel and the guard interval
2028			 * information from Flags, at least on
2029			 * FreeBSD?
2030			 */
2031			printf("MCS %u ", u.u8 & 0x7f);
2032		} else
2033			printf("%2.1f Mb/s ", .5*u.u8);
2034		break;
2035	case IEEE80211_RADIOTAP_DBM_ANTSIGNAL:
2036		printf("%ddB signal ", u.i8);
2037		break;
2038	case IEEE80211_RADIOTAP_DBM_ANTNOISE:
2039		printf("%ddB noise ", u.i8);
2040		break;
2041	case IEEE80211_RADIOTAP_DB_ANTSIGNAL:
2042		printf("%ddB signal ", u.u8);
2043		break;
2044	case IEEE80211_RADIOTAP_DB_ANTNOISE:
2045		printf("%ddB noise ", u.u8);
2046		break;
2047	case IEEE80211_RADIOTAP_LOCK_QUALITY:
2048		printf("%u sq ", u.u16);
2049		break;
2050	case IEEE80211_RADIOTAP_TX_ATTENUATION:
2051		printf("%d tx power ", -(int)u.u16);
2052		break;
2053	case IEEE80211_RADIOTAP_DB_TX_ATTENUATION:
2054		printf("%ddB tx power ", -(int)u.u8);
2055		break;
2056	case IEEE80211_RADIOTAP_DBM_TX_POWER:
2057		printf("%ddBm tx power ", u.i8);
2058		break;
2059	case IEEE80211_RADIOTAP_FLAGS:
2060		if (u.u8 & IEEE80211_RADIOTAP_F_CFP)
2061			printf("cfp ");
2062		if (u.u8 & IEEE80211_RADIOTAP_F_SHORTPRE)
2063			printf("short preamble ");
2064		if (u.u8 & IEEE80211_RADIOTAP_F_WEP)
2065			printf("wep ");
2066		if (u.u8 & IEEE80211_RADIOTAP_F_FRAG)
2067			printf("fragmented ");
2068		if (u.u8 & IEEE80211_RADIOTAP_F_BADFCS)
2069			printf("bad-fcs ");
2070		break;
2071	case IEEE80211_RADIOTAP_ANTENNA:
2072		printf("antenna %d ", u.u8);
2073		break;
2074	case IEEE80211_RADIOTAP_TSFT:
2075		printf("%" PRIu64 "us tsft ", u.u64);
2076		break;
2077	case IEEE80211_RADIOTAP_RX_FLAGS:
2078		/* Do nothing for now */
2079		break;
2080	case IEEE80211_RADIOTAP_XCHANNEL:
2081		print_chaninfo(u2.u16, u.u32);
2082		break;
2083	case IEEE80211_RADIOTAP_MCS: {
2084		static const char *bandwidth[4] = {
2085			"20 MHz",
2086			"40 MHz",
2087			"20 MHz (L)",
2088			"20 MHz (U)"
2089		};
2090		float htrate;
2091
2092		if (u.u8 & IEEE80211_RADIOTAP_MCS_MCS_INDEX_KNOWN) {
2093			/*
2094			 * We know the MCS index.
2095			 */
2096			if (u3.u8 <= MAX_MCS_INDEX) {
2097				/*
2098				 * And it's in-range.
2099				 */
2100				if (u.u8 & (IEEE80211_RADIOTAP_MCS_BANDWIDTH_KNOWN|IEEE80211_RADIOTAP_MCS_GUARD_INTERVAL_KNOWN)) {
2101					/*
2102					 * And we know both the bandwidth and
2103					 * the guard interval, so we can look
2104					 * up the rate.
2105					 */
2106					htrate =
2107						ieee80211_float_htrates \
2108							[u3.u8] \
2109							[((u2.u8 & IEEE80211_RADIOTAP_MCS_BANDWIDTH_MASK) == IEEE80211_RADIOTAP_MCS_BANDWIDTH_40 ? 1 : 0)] \
2110							[((u2.u8 & IEEE80211_RADIOTAP_MCS_SHORT_GI) ? 1 : 0)];
2111				} else {
2112					/*
2113					 * We don't know both the bandwidth
2114					 * and the guard interval, so we can
2115					 * only report the MCS index.
2116					 */
2117					htrate = 0.0;
2118				}
2119			} else {
2120				/*
2121				 * The MCS value is out of range.
2122				 */
2123				htrate = 0.0;
2124			}
2125			if (htrate != 0.0) {
2126				/*
2127				 * We have the rate.
2128				 * Print it.
2129				 */
2130				printf("%.1f Mb/s MCS %u ", htrate, u3.u8);
2131			} else {
2132				/*
2133				 * We at least have the MCS index.
2134				 * Print it.
2135				 */
2136				printf("MCS %u ", u3.u8);
2137			}
2138		}
2139		if (u.u8 & IEEE80211_RADIOTAP_MCS_BANDWIDTH_KNOWN) {
2140			printf("%s ",
2141				bandwidth[u2.u8 & IEEE80211_RADIOTAP_MCS_BANDWIDTH_MASK]);
2142		}
2143		if (u.u8 & IEEE80211_RADIOTAP_MCS_GUARD_INTERVAL_KNOWN) {
2144			printf("%s GI ",
2145				(u2.u8 & IEEE80211_RADIOTAP_MCS_SHORT_GI) ?
2146				"short" : "lon");
2147		}
2148		if (u.u8 & IEEE80211_RADIOTAP_MCS_HT_FORMAT_KNOWN) {
2149			printf("%s ",
2150				(u2.u8 & IEEE80211_RADIOTAP_MCS_HT_GREENFIELD) ?
2151				"greenfield" : "mixed");
2152		}
2153		if (u.u8 & IEEE80211_RADIOTAP_MCS_FEC_TYPE_KNOWN) {
2154			printf("%s FEC ",
2155				(u2.u8 & IEEE80211_RADIOTAP_MCS_FEC_LDPC) ?
2156				"LDPC" : "BCC");
2157		}
2158		break;
2159		}
2160	}
2161	return 0;
2162}
2163
2164static u_int
2165ieee802_11_radio_print(const u_char *p, u_int length, u_int caplen)
2166{
2167#define	BITNO_32(x) (((x) >> 16) ? 16 + BITNO_16((x) >> 16) : BITNO_16((x)))
2168#define	BITNO_16(x) (((x) >> 8) ? 8 + BITNO_8((x) >> 8) : BITNO_8((x)))
2169#define	BITNO_8(x) (((x) >> 4) ? 4 + BITNO_4((x) >> 4) : BITNO_4((x)))
2170#define	BITNO_4(x) (((x) >> 2) ? 2 + BITNO_2((x) >> 2) : BITNO_2((x)))
2171#define	BITNO_2(x) (((x) & 2) ? 1 : 0)
2172#define	BIT(n)	(1U << n)
2173#define	IS_EXTENDED(__p)	\
2174	    (EXTRACT_LE_32BITS(__p) & BIT(IEEE80211_RADIOTAP_EXT)) != 0
2175
2176	struct cpack_state cpacker;
2177	struct ieee80211_radiotap_header *hdr;
2178	u_int32_t present, next_present;
2179	u_int32_t presentflags = 0;
2180	u_int32_t *presentp, *last_presentp;
2181	enum ieee80211_radiotap_type bit;
2182	int bit0;
2183	const u_char *iter;
2184	u_int len;
2185	u_int8_t flags;
2186	int pad;
2187	u_int fcslen;
2188	struct radiotap_state state;
2189
2190	if (caplen < sizeof(*hdr)) {
2191		printf("[|802.11]");
2192		return caplen;
2193	}
2194
2195	hdr = (struct ieee80211_radiotap_header *)p;
2196
2197	len = EXTRACT_LE_16BITS(&hdr->it_len);
2198
2199	if (caplen < len) {
2200		printf("[|802.11]");
2201		return caplen;
2202	}
2203	for (last_presentp = &hdr->it_present;
2204	     IS_EXTENDED(last_presentp) &&
2205	     (u_char*)(last_presentp + 1) <= p + len;
2206	     last_presentp++);
2207
2208	/* are there more bitmap extensions than bytes in header? */
2209	if (IS_EXTENDED(last_presentp)) {
2210		printf("[|802.11]");
2211		return caplen;
2212	}
2213
2214	iter = (u_char*)(last_presentp + 1);
2215
2216	if (cpack_init(&cpacker, (u_int8_t*)iter, len - (iter - p)) != 0) {
2217		/* XXX */
2218		printf("[|802.11]");
2219		return caplen;
2220	}
2221
2222	/* Assume no flags */
2223	flags = 0;
2224	/* Assume no Atheros padding between 802.11 header and body */
2225	pad = 0;
2226	/* Assume no FCS at end of frame */
2227	fcslen = 0;
2228	for (bit0 = 0, presentp = &hdr->it_present; presentp <= last_presentp;
2229	     presentp++, bit0 += 32) {
2230		presentflags = EXTRACT_LE_32BITS(presentp);
2231
2232		/* Clear state. */
2233		memset(&state, 0, sizeof(state));
2234
2235		for (present = EXTRACT_LE_32BITS(presentp); present;
2236		     present = next_present) {
2237			/* clear the least significant bit that is set */
2238			next_present = present & (present - 1);
2239
2240			/* extract the least significant bit that is set */
2241			bit = (enum ieee80211_radiotap_type)
2242			    (bit0 + BITNO_32(present ^ next_present));
2243
2244			if (print_radiotap_field(&cpacker, bit, &flags, &state, presentflags) != 0)
2245				goto out;
2246		}
2247	}
2248
2249out:
2250	if (flags & IEEE80211_RADIOTAP_F_DATAPAD)
2251		pad = 1;	/* Atheros padding */
2252	if (flags & IEEE80211_RADIOTAP_F_FCS)
2253		fcslen = 4;	/* FCS at end of packet */
2254	return len + ieee802_11_print(p + len, length - len, caplen - len, pad,
2255	    fcslen);
2256#undef BITNO_32
2257#undef BITNO_16
2258#undef BITNO_8
2259#undef BITNO_4
2260#undef BITNO_2
2261#undef BIT
2262}
2263
2264static u_int
2265ieee802_11_avs_radio_print(const u_char *p, u_int length, u_int caplen)
2266{
2267	u_int32_t caphdr_len;
2268
2269	if (caplen < 8) {
2270		printf("[|802.11]");
2271		return caplen;
2272	}
2273
2274	caphdr_len = EXTRACT_32BITS(p + 4);
2275	if (caphdr_len < 8) {
2276		/*
2277		 * Yow!  The capture header length is claimed not
2278		 * to be large enough to include even the version
2279		 * cookie or capture header length!
2280		 */
2281		printf("[|802.11]");
2282		return caplen;
2283	}
2284
2285	if (caplen < caphdr_len) {
2286		printf("[|802.11]");
2287		return caplen;
2288	}
2289
2290	return caphdr_len + ieee802_11_print(p + caphdr_len,
2291	    length - caphdr_len, caplen - caphdr_len, 0, 0);
2292}
2293
2294#define PRISM_HDR_LEN		144
2295
2296#define WLANCAP_MAGIC_COOKIE_BASE 0x80211000
2297#define WLANCAP_MAGIC_COOKIE_V1	0x80211001
2298#define WLANCAP_MAGIC_COOKIE_V2	0x80211002
2299
2300/*
2301 * For DLT_PRISM_HEADER; like DLT_IEEE802_11, but with an extra header,
2302 * containing information such as radio information, which we
2303 * currently ignore.
2304 *
2305 * If, however, the packet begins with WLANCAP_MAGIC_COOKIE_V1 or
2306 * WLANCAP_MAGIC_COOKIE_V2, it's really DLT_IEEE802_11_RADIO_AVS
2307 * (currently, on Linux, there's no ARPHRD_ type for
2308 * DLT_IEEE802_11_RADIO_AVS, as there is a ARPHRD_IEEE80211_PRISM
2309 * for DLT_PRISM_HEADER, so ARPHRD_IEEE80211_PRISM is used for
2310 * the AVS header, and the first 4 bytes of the header are used to
2311 * indicate whether it's a Prism header or an AVS header).
2312 */
2313u_int
2314prism_if_print(const struct pcap_pkthdr *h, const u_char *p)
2315{
2316	u_int caplen = h->caplen;
2317	u_int length = h->len;
2318	u_int32_t msgcode;
2319
2320	if (caplen < 4) {
2321		printf("[|802.11]");
2322		return caplen;
2323	}
2324
2325	msgcode = EXTRACT_32BITS(p);
2326	if (msgcode == WLANCAP_MAGIC_COOKIE_V1 ||
2327	    msgcode == WLANCAP_MAGIC_COOKIE_V2)
2328		return ieee802_11_avs_radio_print(p, length, caplen);
2329
2330	if (caplen < PRISM_HDR_LEN) {
2331		printf("[|802.11]");
2332		return caplen;
2333	}
2334
2335	return PRISM_HDR_LEN + ieee802_11_print(p + PRISM_HDR_LEN,
2336	    length - PRISM_HDR_LEN, caplen - PRISM_HDR_LEN, 0, 0);
2337}
2338
2339/*
2340 * For DLT_IEEE802_11_RADIO; like DLT_IEEE802_11, but with an extra
2341 * header, containing information such as radio information.
2342 */
2343u_int
2344ieee802_11_radio_if_print(const struct pcap_pkthdr *h, const u_char *p)
2345{
2346	return ieee802_11_radio_print(p, h->len, h->caplen);
2347}
2348
2349/*
2350 * For DLT_IEEE802_11_RADIO_AVS; like DLT_IEEE802_11, but with an
2351 * extra header, containing information such as radio information,
2352 * which we currently ignore.
2353 */
2354u_int
2355ieee802_11_radio_avs_if_print(const struct pcap_pkthdr *h, const u_char *p)
2356{
2357	return ieee802_11_avs_radio_print(p, h->len, h->caplen);
2358}
2359