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
1226#define PRINT_MESH_ACTION(v) (\
1227	(v) == 0 ? printf("MeshLink") : \
1228	(v) == 1 ? printf("HWMP") : \
1229	(v) == 2 ? printf("Gate Announcement") : \
1230	(v) == 3 ? printf("Congestion Control") : \
1231	(v) == 4 ? printf("MCCA Setup Request") : \
1232	(v) == 5 ? printf("MCCA Setup Reply") : \
1233	(v) == 6 ? printf("MCCA Advertisement Request") : \
1234	(v) == 7 ? printf("MCCA Advertisement") : \
1235	(v) == 8 ? printf("MCCA Teardown") : \
1236	(v) == 9 ? printf("TBTT Adjustment Request") : \
1237	(v) == 10 ? printf("TBTT Adjustment Response") : \
1238		   printf("Act#%d", (v)) \
1239)
1240#define PRINT_MULTIHOP_ACTION(v) (\
1241	(v) == 0 ? printf("Proxy Update") : \
1242	(v) == 1 ? printf("Proxy Update Confirmation") : \
1243		   printf("Act#%d", (v)) \
1244)
1245#define PRINT_SELFPROT_ACTION(v) (\
1246	(v) == 1 ? printf("Peering Open") : \
1247	(v) == 2 ? printf("Peering Confirm") : \
1248	(v) == 3 ? printf("Peering Close") : \
1249	(v) == 4 ? printf("Group Key Inform") : \
1250	(v) == 5 ? printf("Group Key Acknowledge") : \
1251		   printf("Act#%d", (v)) \
1252)
1253
1254static int
1255handle_action(const struct mgmt_header_t *pmh, const u_char *p, u_int length)
1256{
1257	if (!TTEST2(*p, 2))
1258		return 0;
1259	if (length < 2)
1260		return 0;
1261	if (eflag) {
1262		printf(": ");
1263	} else {
1264		printf(" (%s): ", etheraddr_string(pmh->sa));
1265	}
1266	switch (p[0]) {
1267	case 0: printf("Spectrum Management Act#%d", p[1]); break;
1268	case 1: printf("QoS Act#%d", p[1]); break;
1269	case 2: printf("DLS Act#%d", p[1]); break;
1270	case 3: printf("BA "); PRINT_BA_ACTION(p[1]); break;
1271	case 7: printf("HT "); PRINT_HT_ACTION(p[1]); break;
1272	case 13: printf("MeshAction "); PRINT_MESH_ACTION(p[1]); break;
1273	case 14:
1274		printf("MultiohopAction ");
1275		PRINT_MULTIHOP_ACTION(p[1]); break;
1276	case 15:
1277		printf("SelfprotectAction ");
1278		PRINT_SELFPROT_ACTION(p[1]); break;
1279	case 127: printf("Vendor Act#%d", p[1]); break;
1280	default:
1281		printf("Reserved(%d) Act#%d", p[0], p[1]);
1282		break;
1283	}
1284	return 1;
1285}
1286
1287
1288/*********************************************************************************
1289 * Print Body funcs
1290 *********************************************************************************/
1291
1292
1293static int
1294mgmt_body_print(u_int16_t fc, const struct mgmt_header_t *pmh,
1295    const u_char *p, u_int length)
1296{
1297	switch (FC_SUBTYPE(fc)) {
1298	case ST_ASSOC_REQUEST:
1299		printf("Assoc Request");
1300		return handle_assoc_request(p, length);
1301	case ST_ASSOC_RESPONSE:
1302		printf("Assoc Response");
1303		return handle_assoc_response(p, length);
1304	case ST_REASSOC_REQUEST:
1305		printf("ReAssoc Request");
1306		return handle_reassoc_request(p, length);
1307	case ST_REASSOC_RESPONSE:
1308		printf("ReAssoc Response");
1309		return handle_reassoc_response(p, length);
1310	case ST_PROBE_REQUEST:
1311		printf("Probe Request");
1312		return handle_probe_request(p, length);
1313	case ST_PROBE_RESPONSE:
1314		printf("Probe Response");
1315		return handle_probe_response(p, length);
1316	case ST_BEACON:
1317		printf("Beacon");
1318		return handle_beacon(p, length);
1319	case ST_ATIM:
1320		printf("ATIM");
1321		return handle_atim();
1322	case ST_DISASSOC:
1323		printf("Disassociation");
1324		return handle_disassoc(p, length);
1325	case ST_AUTH:
1326		printf("Authentication");
1327		if (!TTEST2(*p, 3))
1328			return 0;
1329		if ((p[0] == 0 ) && (p[1] == 0) && (p[2] == 0)) {
1330			printf("Authentication (Shared-Key)-3 ");
1331			return wep_print(p);
1332		}
1333		return handle_auth(p, length);
1334	case ST_DEAUTH:
1335		printf("DeAuthentication");
1336		return handle_deauth(pmh, p, length);
1337		break;
1338	case ST_ACTION:
1339		printf("Action");
1340		return handle_action(pmh, p, length);
1341		break;
1342	default:
1343		printf("Unhandled Management subtype(%x)",
1344		    FC_SUBTYPE(fc));
1345		return 1;
1346	}
1347}
1348
1349
1350/*********************************************************************************
1351 * Handles printing all the control frame types
1352 *********************************************************************************/
1353
1354static int
1355ctrl_body_print(u_int16_t fc, const u_char *p)
1356{
1357	switch (FC_SUBTYPE(fc)) {
1358	case CTRL_CONTROL_WRAPPER:
1359		printf("Control Wrapper");
1360		/* XXX - requires special handling */
1361		break;
1362	case CTRL_BAR:
1363		printf("BAR");
1364		if (!TTEST2(*p, CTRL_BAR_HDRLEN))
1365			return 0;
1366		if (!eflag)
1367			printf(" RA:%s TA:%s CTL(%x) SEQ(%u) ",
1368			    etheraddr_string(((const struct ctrl_bar_t *)p)->ra),
1369			    etheraddr_string(((const struct ctrl_bar_t *)p)->ta),
1370			    EXTRACT_LE_16BITS(&(((const struct ctrl_bar_t *)p)->ctl)),
1371			    EXTRACT_LE_16BITS(&(((const struct ctrl_bar_t *)p)->seq)));
1372		break;
1373	case CTRL_BA:
1374		printf("BA");
1375		if (!TTEST2(*p, CTRL_BA_HDRLEN))
1376			return 0;
1377		if (!eflag)
1378			printf(" RA:%s ",
1379			    etheraddr_string(((const struct ctrl_ba_t *)p)->ra));
1380		break;
1381	case CTRL_PS_POLL:
1382		printf("Power Save-Poll");
1383		if (!TTEST2(*p, CTRL_PS_POLL_HDRLEN))
1384			return 0;
1385		printf(" AID(%x)",
1386		    EXTRACT_LE_16BITS(&(((const struct ctrl_ps_poll_t *)p)->aid)));
1387		break;
1388	case CTRL_RTS:
1389		printf("Request-To-Send");
1390		if (!TTEST2(*p, CTRL_RTS_HDRLEN))
1391			return 0;
1392		if (!eflag)
1393			printf(" TA:%s ",
1394			    etheraddr_string(((const struct ctrl_rts_t *)p)->ta));
1395		break;
1396	case CTRL_CTS:
1397		printf("Clear-To-Send");
1398		if (!TTEST2(*p, CTRL_CTS_HDRLEN))
1399			return 0;
1400		if (!eflag)
1401			printf(" RA:%s ",
1402			    etheraddr_string(((const struct ctrl_cts_t *)p)->ra));
1403		break;
1404	case CTRL_ACK:
1405		printf("Acknowledgment");
1406		if (!TTEST2(*p, CTRL_ACK_HDRLEN))
1407			return 0;
1408		if (!eflag)
1409			printf(" RA:%s ",
1410			    etheraddr_string(((const struct ctrl_ack_t *)p)->ra));
1411		break;
1412	case CTRL_CF_END:
1413		printf("CF-End");
1414		if (!TTEST2(*p, CTRL_END_HDRLEN))
1415			return 0;
1416		if (!eflag)
1417			printf(" RA:%s ",
1418			    etheraddr_string(((const struct ctrl_end_t *)p)->ra));
1419		break;
1420	case CTRL_END_ACK:
1421		printf("CF-End+CF-Ack");
1422		if (!TTEST2(*p, CTRL_END_ACK_HDRLEN))
1423			return 0;
1424		if (!eflag)
1425			printf(" RA:%s ",
1426			    etheraddr_string(((const struct ctrl_end_ack_t *)p)->ra));
1427		break;
1428	default:
1429		printf("Unknown Ctrl Subtype");
1430	}
1431	return 1;
1432}
1433
1434/*
1435 * Print Header funcs
1436 */
1437
1438/*
1439 *  Data Frame - Address field contents
1440 *
1441 *  To Ds  | From DS | Addr 1 | Addr 2 | Addr 3 | Addr 4
1442 *    0    |  0      |  DA    | SA     | BSSID  | n/a
1443 *    0    |  1      |  DA    | BSSID  | SA     | n/a
1444 *    1    |  0      |  BSSID | SA     | DA     | n/a
1445 *    1    |  1      |  RA    | TA     | DA     | SA
1446 */
1447
1448static void
1449data_header_print(u_int16_t fc, const u_char *p, const u_int8_t **srcp,
1450    const u_int8_t **dstp)
1451{
1452	u_int subtype = FC_SUBTYPE(fc);
1453
1454	if (DATA_FRAME_IS_CF_ACK(subtype) || DATA_FRAME_IS_CF_POLL(subtype) ||
1455	    DATA_FRAME_IS_QOS(subtype)) {
1456		printf("CF ");
1457		if (DATA_FRAME_IS_CF_ACK(subtype)) {
1458			if (DATA_FRAME_IS_CF_POLL(subtype))
1459				printf("Ack/Poll");
1460			else
1461				printf("Ack");
1462		} else {
1463			if (DATA_FRAME_IS_CF_POLL(subtype))
1464				printf("Poll");
1465		}
1466		if (DATA_FRAME_IS_QOS(subtype))
1467			printf("+QoS");
1468		printf(" ");
1469	}
1470
1471#define ADDR1  (p + 4)
1472#define ADDR2  (p + 10)
1473#define ADDR3  (p + 16)
1474#define ADDR4  (p + 24)
1475
1476	if (!FC_TO_DS(fc) && !FC_FROM_DS(fc)) {
1477		if (srcp != NULL)
1478			*srcp = ADDR2;
1479		if (dstp != NULL)
1480			*dstp = ADDR1;
1481		if (!eflag)
1482			return;
1483		printf("DA:%s SA:%s BSSID:%s ",
1484		    etheraddr_string(ADDR1), etheraddr_string(ADDR2),
1485		    etheraddr_string(ADDR3));
1486	} else if (!FC_TO_DS(fc) && FC_FROM_DS(fc)) {
1487		if (srcp != NULL)
1488			*srcp = ADDR3;
1489		if (dstp != NULL)
1490			*dstp = ADDR1;
1491		if (!eflag)
1492			return;
1493		printf("DA:%s BSSID:%s SA:%s ",
1494		    etheraddr_string(ADDR1), etheraddr_string(ADDR2),
1495		    etheraddr_string(ADDR3));
1496	} else if (FC_TO_DS(fc) && !FC_FROM_DS(fc)) {
1497		if (srcp != NULL)
1498			*srcp = ADDR2;
1499		if (dstp != NULL)
1500			*dstp = ADDR3;
1501		if (!eflag)
1502			return;
1503		printf("BSSID:%s SA:%s DA:%s ",
1504		    etheraddr_string(ADDR1), etheraddr_string(ADDR2),
1505		    etheraddr_string(ADDR3));
1506	} else if (FC_TO_DS(fc) && FC_FROM_DS(fc)) {
1507		if (srcp != NULL)
1508			*srcp = ADDR4;
1509		if (dstp != NULL)
1510			*dstp = ADDR3;
1511		if (!eflag)
1512			return;
1513		printf("RA:%s TA:%s DA:%s SA:%s ",
1514		    etheraddr_string(ADDR1), etheraddr_string(ADDR2),
1515		    etheraddr_string(ADDR3), etheraddr_string(ADDR4));
1516	}
1517
1518#undef ADDR1
1519#undef ADDR2
1520#undef ADDR3
1521#undef ADDR4
1522}
1523
1524static void
1525mgmt_header_print(const u_char *p, const u_int8_t **srcp,
1526    const u_int8_t **dstp)
1527{
1528	const struct mgmt_header_t *hp = (const struct mgmt_header_t *) p;
1529
1530	if (srcp != NULL)
1531		*srcp = hp->sa;
1532	if (dstp != NULL)
1533		*dstp = hp->da;
1534	if (!eflag)
1535		return;
1536
1537	printf("BSSID:%s DA:%s SA:%s ",
1538	    etheraddr_string((hp)->bssid), etheraddr_string((hp)->da),
1539	    etheraddr_string((hp)->sa));
1540}
1541
1542static void
1543ctrl_header_print(u_int16_t fc, const u_char *p, const u_int8_t **srcp,
1544    const u_int8_t **dstp)
1545{
1546	if (srcp != NULL)
1547		*srcp = NULL;
1548	if (dstp != NULL)
1549		*dstp = NULL;
1550	if (!eflag)
1551		return;
1552
1553	switch (FC_SUBTYPE(fc)) {
1554	case CTRL_BAR:
1555		printf(" RA:%s TA:%s CTL(%x) SEQ(%u) ",
1556		    etheraddr_string(((const struct ctrl_bar_t *)p)->ra),
1557		    etheraddr_string(((const struct ctrl_bar_t *)p)->ta),
1558		    EXTRACT_LE_16BITS(&(((const struct ctrl_bar_t *)p)->ctl)),
1559		    EXTRACT_LE_16BITS(&(((const struct ctrl_bar_t *)p)->seq)));
1560		break;
1561	case CTRL_BA:
1562		printf("RA:%s ",
1563		    etheraddr_string(((const struct ctrl_ba_t *)p)->ra));
1564		break;
1565	case CTRL_PS_POLL:
1566		printf("BSSID:%s TA:%s ",
1567		    etheraddr_string(((const struct ctrl_ps_poll_t *)p)->bssid),
1568		    etheraddr_string(((const struct ctrl_ps_poll_t *)p)->ta));
1569		break;
1570	case CTRL_RTS:
1571		printf("RA:%s TA:%s ",
1572		    etheraddr_string(((const struct ctrl_rts_t *)p)->ra),
1573		    etheraddr_string(((const struct ctrl_rts_t *)p)->ta));
1574		break;
1575	case CTRL_CTS:
1576		printf("RA:%s ",
1577		    etheraddr_string(((const struct ctrl_cts_t *)p)->ra));
1578		break;
1579	case CTRL_ACK:
1580		printf("RA:%s ",
1581		    etheraddr_string(((const struct ctrl_ack_t *)p)->ra));
1582		break;
1583	case CTRL_CF_END:
1584		printf("RA:%s BSSID:%s ",
1585		    etheraddr_string(((const struct ctrl_end_t *)p)->ra),
1586		    etheraddr_string(((const struct ctrl_end_t *)p)->bssid));
1587		break;
1588	case CTRL_END_ACK:
1589		printf("RA:%s BSSID:%s ",
1590		    etheraddr_string(((const struct ctrl_end_ack_t *)p)->ra),
1591		    etheraddr_string(((const struct ctrl_end_ack_t *)p)->bssid));
1592		break;
1593	default:
1594		printf("(H) Unknown Ctrl Subtype");
1595		break;
1596	}
1597}
1598
1599static int
1600extract_header_length(u_int16_t fc)
1601{
1602	int len;
1603
1604	switch (FC_TYPE(fc)) {
1605	case T_MGMT:
1606		return MGMT_HDRLEN;
1607	case T_CTRL:
1608		switch (FC_SUBTYPE(fc)) {
1609		case CTRL_BAR:
1610			return CTRL_BAR_HDRLEN;
1611		case CTRL_PS_POLL:
1612			return CTRL_PS_POLL_HDRLEN;
1613		case CTRL_RTS:
1614			return CTRL_RTS_HDRLEN;
1615		case CTRL_CTS:
1616			return CTRL_CTS_HDRLEN;
1617		case CTRL_ACK:
1618			return CTRL_ACK_HDRLEN;
1619		case CTRL_CF_END:
1620			return CTRL_END_HDRLEN;
1621		case CTRL_END_ACK:
1622			return CTRL_END_ACK_HDRLEN;
1623		default:
1624			return 0;
1625		}
1626	case T_DATA:
1627		len = (FC_TO_DS(fc) && FC_FROM_DS(fc)) ? 30 : 24;
1628		if (DATA_FRAME_IS_QOS(FC_SUBTYPE(fc)))
1629			len += 2;
1630		return len;
1631	default:
1632		printf("unknown IEEE802.11 frame type (%d)", FC_TYPE(fc));
1633		return 0;
1634	}
1635}
1636
1637static int
1638extract_mesh_header_length(const u_char *p)
1639{
1640	return (p[0] &~ 3) ? 0 : 6*(1 + (p[0] & 3));
1641}
1642
1643/*
1644 * Print the 802.11 MAC header if eflag is set, and set "*srcp" and "*dstp"
1645 * to point to the source and destination MAC addresses in any case if
1646 * "srcp" and "dstp" aren't null.
1647 */
1648static void
1649ieee_802_11_hdr_print(u_int16_t fc, const u_char *p, u_int hdrlen,
1650    u_int meshdrlen, const u_int8_t **srcp, const u_int8_t **dstp)
1651{
1652	if (vflag) {
1653		if (FC_MORE_DATA(fc))
1654			printf("More Data ");
1655		if (FC_MORE_FLAG(fc))
1656			printf("More Fragments ");
1657		if (FC_POWER_MGMT(fc))
1658			printf("Pwr Mgmt ");
1659		if (FC_RETRY(fc))
1660			printf("Retry ");
1661		if (FC_ORDER(fc))
1662			printf("Strictly Ordered ");
1663		if (FC_WEP(fc))
1664			printf("WEP Encrypted ");
1665		if (FC_TYPE(fc) != T_CTRL || FC_SUBTYPE(fc) != CTRL_PS_POLL)
1666			printf("%dus ",
1667			    EXTRACT_LE_16BITS(
1668			        &((const struct mgmt_header_t *)p)->duration));
1669	}
1670	if (meshdrlen != 0) {
1671		const struct meshcntl_t *mc =
1672		    (const struct meshcntl_t *)&p[hdrlen - meshdrlen];
1673		int ae = mc->flags & 3;
1674
1675		printf("MeshData (AE %d TTL %u seq %u", ae, mc->ttl,
1676		    EXTRACT_LE_32BITS(mc->seq));
1677		if (ae > 0)
1678			printf(" A4:%s", etheraddr_string(mc->addr4));
1679		if (ae > 1)
1680			printf(" A5:%s", etheraddr_string(mc->addr5));
1681		if (ae > 2)
1682			printf(" A6:%s", etheraddr_string(mc->addr6));
1683		printf(") ");
1684	}
1685
1686	switch (FC_TYPE(fc)) {
1687	case T_MGMT:
1688		mgmt_header_print(p, srcp, dstp);
1689		break;
1690	case T_CTRL:
1691		ctrl_header_print(fc, p, srcp, dstp);
1692		break;
1693	case T_DATA:
1694		data_header_print(fc, p, srcp, dstp);
1695		break;
1696	default:
1697		printf("(header) unknown IEEE802.11 frame type (%d)",
1698		    FC_TYPE(fc));
1699		*srcp = NULL;
1700		*dstp = NULL;
1701		break;
1702	}
1703}
1704
1705#ifndef roundup2
1706#define	roundup2(x, y)	(((x)+((y)-1))&(~((y)-1))) /* if y is powers of two */
1707#endif
1708
1709static u_int
1710ieee802_11_print(const u_char *p, u_int length, u_int orig_caplen, int pad,
1711    u_int fcslen)
1712{
1713	u_int16_t fc;
1714	u_int caplen, hdrlen, meshdrlen;
1715	const u_int8_t *src, *dst;
1716	u_short extracted_ethertype;
1717
1718	caplen = orig_caplen;
1719	/* Remove FCS, if present */
1720	if (length < fcslen) {
1721		printf("[|802.11]");
1722		return caplen;
1723	}
1724	length -= fcslen;
1725	if (caplen > length) {
1726		/* Amount of FCS in actual packet data, if any */
1727		fcslen = caplen - length;
1728		caplen -= fcslen;
1729		snapend -= fcslen;
1730	}
1731
1732	if (caplen < IEEE802_11_FC_LEN) {
1733		printf("[|802.11]");
1734		return orig_caplen;
1735	}
1736
1737	fc = EXTRACT_LE_16BITS(p);
1738	hdrlen = extract_header_length(fc);
1739	if (pad)
1740		hdrlen = roundup2(hdrlen, 4);
1741	if (Hflag && FC_TYPE(fc) == T_DATA &&
1742	    DATA_FRAME_IS_QOS(FC_SUBTYPE(fc))) {
1743		meshdrlen = extract_mesh_header_length(p+hdrlen);
1744		hdrlen += meshdrlen;
1745	} else
1746		meshdrlen = 0;
1747
1748
1749	if (caplen < hdrlen) {
1750		printf("[|802.11]");
1751		return hdrlen;
1752	}
1753
1754	ieee_802_11_hdr_print(fc, p, hdrlen, meshdrlen, &src, &dst);
1755
1756	/*
1757	 * Go past the 802.11 header.
1758	 */
1759	length -= hdrlen;
1760	caplen -= hdrlen;
1761	p += hdrlen;
1762
1763	switch (FC_TYPE(fc)) {
1764	case T_MGMT:
1765		if (!mgmt_body_print(fc,
1766		    (const struct mgmt_header_t *)(p - hdrlen), p, length)) {
1767			printf("[|802.11]");
1768			return hdrlen;
1769		}
1770		break;
1771	case T_CTRL:
1772		if (!ctrl_body_print(fc, p - hdrlen)) {
1773			printf("[|802.11]");
1774			return hdrlen;
1775		}
1776		break;
1777	case T_DATA:
1778		if (DATA_FRAME_IS_NULL(FC_SUBTYPE(fc)))
1779			return hdrlen;	/* no-data frame */
1780		/* There may be a problem w/ AP not having this bit set */
1781		if (FC_WEP(fc)) {
1782			if (!wep_print(p)) {
1783				printf("[|802.11]");
1784				return hdrlen;
1785			}
1786		} else if (llc_print(p, length, caplen, dst, src,
1787		    &extracted_ethertype) == 0) {
1788			/*
1789			 * Some kinds of LLC packet we cannot
1790			 * handle intelligently
1791			 */
1792			if (!eflag)
1793				ieee_802_11_hdr_print(fc, p - hdrlen, hdrlen,
1794				    meshdrlen, NULL, NULL);
1795			if (extracted_ethertype)
1796				printf("(LLC %s) ",
1797				    etherproto_string(
1798				        htons(extracted_ethertype)));
1799			if (!suppress_default_print)
1800				default_print(p, caplen);
1801		}
1802		break;
1803	default:
1804		printf("unknown 802.11 frame type (%d)", FC_TYPE(fc));
1805		break;
1806	}
1807
1808	return hdrlen;
1809}
1810
1811/*
1812 * This is the top level routine of the printer.  'p' points
1813 * to the 802.11 header of the packet, 'h->ts' is the timestamp,
1814 * 'h->len' is the length of the packet off the wire, and 'h->caplen'
1815 * is the number of bytes actually captured.
1816 */
1817u_int
1818ieee802_11_if_print(const struct pcap_pkthdr *h, const u_char *p)
1819{
1820	return ieee802_11_print(p, h->len, h->caplen, 0, 0);
1821}
1822
1823#define	IEEE80211_CHAN_FHSS \
1824	(IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_GFSK)
1825#define	IEEE80211_CHAN_A \
1826	(IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM)
1827#define	IEEE80211_CHAN_B \
1828	(IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_CCK)
1829#define	IEEE80211_CHAN_PUREG \
1830	(IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_OFDM)
1831#define	IEEE80211_CHAN_G \
1832	(IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_DYN)
1833
1834#define	IS_CHAN_FHSS(flags) \
1835	((flags & IEEE80211_CHAN_FHSS) == IEEE80211_CHAN_FHSS)
1836#define	IS_CHAN_A(flags) \
1837	((flags & IEEE80211_CHAN_A) == IEEE80211_CHAN_A)
1838#define	IS_CHAN_B(flags) \
1839	((flags & IEEE80211_CHAN_B) == IEEE80211_CHAN_B)
1840#define	IS_CHAN_PUREG(flags) \
1841	((flags & IEEE80211_CHAN_PUREG) == IEEE80211_CHAN_PUREG)
1842#define	IS_CHAN_G(flags) \
1843	((flags & IEEE80211_CHAN_G) == IEEE80211_CHAN_G)
1844#define	IS_CHAN_ANYG(flags) \
1845	(IS_CHAN_PUREG(flags) || IS_CHAN_G(flags))
1846
1847static void
1848print_chaninfo(int freq, int flags)
1849{
1850	printf("%u MHz", freq);
1851	if (IS_CHAN_FHSS(flags))
1852		printf(" FHSS");
1853	if (IS_CHAN_A(flags)) {
1854		if (flags & IEEE80211_CHAN_HALF)
1855			printf(" 11a/10Mhz");
1856		else if (flags & IEEE80211_CHAN_QUARTER)
1857			printf(" 11a/5Mhz");
1858		else
1859			printf(" 11a");
1860	}
1861	if (IS_CHAN_ANYG(flags)) {
1862		if (flags & IEEE80211_CHAN_HALF)
1863			printf(" 11g/10Mhz");
1864		else if (flags & IEEE80211_CHAN_QUARTER)
1865			printf(" 11g/5Mhz");
1866		else
1867			printf(" 11g");
1868	} else if (IS_CHAN_B(flags))
1869		printf(" 11b");
1870	if (flags & IEEE80211_CHAN_TURBO)
1871		printf(" Turbo");
1872	if (flags & IEEE80211_CHAN_HT20)
1873		printf(" ht/20");
1874	else if (flags & IEEE80211_CHAN_HT40D)
1875		printf(" ht/40-");
1876	else if (flags & IEEE80211_CHAN_HT40U)
1877		printf(" ht/40+");
1878	printf(" ");
1879}
1880
1881static int
1882print_radiotap_field(struct cpack_state *s, u_int32_t bit, u_int8_t *flags,
1883						struct radiotap_state *state, u_int32_t presentflags)
1884{
1885	union {
1886		int8_t		i8;
1887		u_int8_t	u8;
1888		int16_t		i16;
1889		u_int16_t	u16;
1890		u_int32_t	u32;
1891		u_int64_t	u64;
1892	} u, u2, u3, u4;
1893	int rc;
1894
1895	switch (bit) {
1896	case IEEE80211_RADIOTAP_FLAGS:
1897		rc = cpack_uint8(s, &u.u8);
1898		if (rc != 0)
1899			break;
1900		*flags = u.u8;
1901		break;
1902	case IEEE80211_RADIOTAP_RATE:
1903		rc = cpack_uint8(s, &u.u8);
1904		if (rc != 0)
1905			break;
1906
1907		/* Save state rate */
1908		state->rate = u.u8;
1909		break;
1910	case IEEE80211_RADIOTAP_DB_ANTSIGNAL:
1911	case IEEE80211_RADIOTAP_DB_ANTNOISE:
1912	case IEEE80211_RADIOTAP_ANTENNA:
1913		rc = cpack_uint8(s, &u.u8);
1914		break;
1915	case IEEE80211_RADIOTAP_DBM_ANTSIGNAL:
1916	case IEEE80211_RADIOTAP_DBM_ANTNOISE:
1917		rc = cpack_int8(s, &u.i8);
1918		break;
1919	case IEEE80211_RADIOTAP_CHANNEL:
1920		rc = cpack_uint16(s, &u.u16);
1921		if (rc != 0)
1922			break;
1923		rc = cpack_uint16(s, &u2.u16);
1924		break;
1925	case IEEE80211_RADIOTAP_FHSS:
1926	case IEEE80211_RADIOTAP_LOCK_QUALITY:
1927	case IEEE80211_RADIOTAP_TX_ATTENUATION:
1928	case IEEE80211_RADIOTAP_RX_FLAGS:
1929		rc = cpack_uint16(s, &u.u16);
1930		break;
1931	case IEEE80211_RADIOTAP_DB_TX_ATTENUATION:
1932		rc = cpack_uint8(s, &u.u8);
1933		break;
1934	case IEEE80211_RADIOTAP_DBM_TX_POWER:
1935		rc = cpack_int8(s, &u.i8);
1936		break;
1937	case IEEE80211_RADIOTAP_TSFT:
1938		rc = cpack_uint64(s, &u.u64);
1939		break;
1940	case IEEE80211_RADIOTAP_XCHANNEL:
1941		rc = cpack_uint32(s, &u.u32);
1942		if (rc != 0)
1943			break;
1944		rc = cpack_uint16(s, &u2.u16);
1945		if (rc != 0)
1946			break;
1947		rc = cpack_uint8(s, &u3.u8);
1948		if (rc != 0)
1949			break;
1950		rc = cpack_uint8(s, &u4.u8);
1951		break;
1952	case IEEE80211_RADIOTAP_MCS:
1953		rc = cpack_uint8(s, &u.u8);
1954		if (rc != 0)
1955			break;
1956		rc = cpack_uint8(s, &u2.u8);
1957		if (rc != 0)
1958			break;
1959		rc = cpack_uint8(s, &u3.u8);
1960		break;
1961	case IEEE80211_RADIOTAP_VENDOR_NAMESPACE: {
1962		u_int8_t vns[3];
1963		u_int16_t length;
1964		u_int8_t subspace;
1965
1966		if ((cpack_align_and_reserve(s, 2)) == NULL) {
1967			rc = -1;
1968			break;
1969		}
1970
1971		rc = cpack_uint8(s, &vns[0]);
1972		if (rc != 0)
1973			break;
1974		rc = cpack_uint8(s, &vns[1]);
1975		if (rc != 0)
1976			break;
1977		rc = cpack_uint8(s, &vns[2]);
1978		if (rc != 0)
1979			break;
1980		rc = cpack_uint8(s, &subspace);
1981		if (rc != 0)
1982			break;
1983		rc = cpack_uint16(s, &length);
1984		if (rc != 0)
1985			break;
1986
1987		/* Skip up to length */
1988		s->c_next += length;
1989		break;
1990	}
1991	default:
1992		/* this bit indicates a field whose
1993		 * size we do not know, so we cannot
1994		 * proceed.  Just print the bit number.
1995		 */
1996		printf("[bit %u] ", bit);
1997		return -1;
1998	}
1999
2000	if (rc != 0) {
2001		printf("[|802.11]");
2002		return rc;
2003	}
2004
2005	/* Preserve the state present flags */
2006	state->present = presentflags;
2007
2008	switch (bit) {
2009	case IEEE80211_RADIOTAP_CHANNEL:
2010		/*
2011		 * If CHANNEL and XCHANNEL are both present, skip
2012		 * CHANNEL.
2013		 */
2014		if (presentflags & (1 << IEEE80211_RADIOTAP_XCHANNEL))
2015			break;
2016		print_chaninfo(u.u16, u2.u16);
2017		break;
2018	case IEEE80211_RADIOTAP_FHSS:
2019		printf("fhset %d fhpat %d ", u.u16 & 0xff, (u.u16 >> 8) & 0xff);
2020		break;
2021	case IEEE80211_RADIOTAP_RATE:
2022		/*
2023		 * XXX On FreeBSD rate & 0x80 means we have an MCS. On
2024		 * Linux and AirPcap it does not.  (What about
2025		 * Mac OS X, NetBSD, OpenBSD, and DragonFly BSD?)
2026		 *
2027		 * This is an issue either for proprietary extensions
2028		 * to 11a or 11g, which do exist, or for 11n
2029		 * implementations that stuff a rate value into
2030		 * this field, which also appear to exist.
2031		 *
2032		 * We currently handle that by assuming that
2033		 * if the 0x80 bit is set *and* the remaining
2034		 * bits have a value between 0 and 15 it's
2035		 * an MCS value, otherwise it's a rate.  If
2036		 * there are cases where systems that use
2037		 * "0x80 + MCS index" for MCS indices > 15,
2038		 * or stuff a rate value here between 64 and
2039		 * 71.5 Mb/s in here, we'll need a preference
2040		 * setting.  Such rates do exist, e.g. 11n
2041		 * MCS 7 at 20 MHz with a long guard interval.
2042		 */
2043		if (u.u8 >= 0x80 && u.u8 <= 0x8f) {
2044			/*
2045			 * XXX - we don't know the channel width
2046			 * or guard interval length, so we can't
2047			 * convert this to a data rate.
2048			 *
2049			 * If you want us to show a data rate,
2050			 * use the MCS field, not the Rate field;
2051			 * the MCS field includes not only the
2052			 * MCS index, it also includes bandwidth
2053			 * and guard interval information.
2054			 *
2055			 * XXX - can we get the channel width
2056			 * from XChannel and the guard interval
2057			 * information from Flags, at least on
2058			 * FreeBSD?
2059			 */
2060			printf("MCS %u ", u.u8 & 0x7f);
2061		} else
2062			printf("%2.1f Mb/s ", .5*u.u8);
2063		break;
2064	case IEEE80211_RADIOTAP_DBM_ANTSIGNAL:
2065		printf("%ddB signal ", u.i8);
2066		break;
2067	case IEEE80211_RADIOTAP_DBM_ANTNOISE:
2068		printf("%ddB noise ", u.i8);
2069		break;
2070	case IEEE80211_RADIOTAP_DB_ANTSIGNAL:
2071		printf("%ddB signal ", u.u8);
2072		break;
2073	case IEEE80211_RADIOTAP_DB_ANTNOISE:
2074		printf("%ddB noise ", u.u8);
2075		break;
2076	case IEEE80211_RADIOTAP_LOCK_QUALITY:
2077		printf("%u sq ", u.u16);
2078		break;
2079	case IEEE80211_RADIOTAP_TX_ATTENUATION:
2080		printf("%d tx power ", -(int)u.u16);
2081		break;
2082	case IEEE80211_RADIOTAP_DB_TX_ATTENUATION:
2083		printf("%ddB tx power ", -(int)u.u8);
2084		break;
2085	case IEEE80211_RADIOTAP_DBM_TX_POWER:
2086		printf("%ddBm tx power ", u.i8);
2087		break;
2088	case IEEE80211_RADIOTAP_FLAGS:
2089		if (u.u8 & IEEE80211_RADIOTAP_F_CFP)
2090			printf("cfp ");
2091		if (u.u8 & IEEE80211_RADIOTAP_F_SHORTPRE)
2092			printf("short preamble ");
2093		if (u.u8 & IEEE80211_RADIOTAP_F_WEP)
2094			printf("wep ");
2095		if (u.u8 & IEEE80211_RADIOTAP_F_FRAG)
2096			printf("fragmented ");
2097		if (u.u8 & IEEE80211_RADIOTAP_F_BADFCS)
2098			printf("bad-fcs ");
2099		break;
2100	case IEEE80211_RADIOTAP_ANTENNA:
2101		printf("antenna %d ", u.u8);
2102		break;
2103	case IEEE80211_RADIOTAP_TSFT:
2104		printf("%" PRIu64 "us tsft ", u.u64);
2105		break;
2106	case IEEE80211_RADIOTAP_RX_FLAGS:
2107		/* Do nothing for now */
2108		break;
2109	case IEEE80211_RADIOTAP_XCHANNEL:
2110		print_chaninfo(u2.u16, u.u32);
2111		break;
2112	case IEEE80211_RADIOTAP_MCS: {
2113		static const char *bandwidth[4] = {
2114			"20 MHz",
2115			"40 MHz",
2116			"20 MHz (L)",
2117			"20 MHz (U)"
2118		};
2119		float htrate;
2120
2121		if (u.u8 & IEEE80211_RADIOTAP_MCS_MCS_INDEX_KNOWN) {
2122			/*
2123			 * We know the MCS index.
2124			 */
2125			if (u3.u8 <= MAX_MCS_INDEX) {
2126				/*
2127				 * And it's in-range.
2128				 */
2129				if (u.u8 & (IEEE80211_RADIOTAP_MCS_BANDWIDTH_KNOWN|IEEE80211_RADIOTAP_MCS_GUARD_INTERVAL_KNOWN)) {
2130					/*
2131					 * And we know both the bandwidth and
2132					 * the guard interval, so we can look
2133					 * up the rate.
2134					 */
2135					htrate =
2136						ieee80211_float_htrates \
2137							[u3.u8] \
2138							[((u2.u8 & IEEE80211_RADIOTAP_MCS_BANDWIDTH_MASK) == IEEE80211_RADIOTAP_MCS_BANDWIDTH_40 ? 1 : 0)] \
2139							[((u2.u8 & IEEE80211_RADIOTAP_MCS_SHORT_GI) ? 1 : 0)];
2140				} else {
2141					/*
2142					 * We don't know both the bandwidth
2143					 * and the guard interval, so we can
2144					 * only report the MCS index.
2145					 */
2146					htrate = 0.0;
2147				}
2148			} else {
2149				/*
2150				 * The MCS value is out of range.
2151				 */
2152				htrate = 0.0;
2153			}
2154			if (htrate != 0.0) {
2155				/*
2156				 * We have the rate.
2157				 * Print it.
2158				 */
2159				printf("%.1f Mb/s MCS %u ", htrate, u3.u8);
2160			} else {
2161				/*
2162				 * We at least have the MCS index.
2163				 * Print it.
2164				 */
2165				printf("MCS %u ", u3.u8);
2166			}
2167		}
2168		if (u.u8 & IEEE80211_RADIOTAP_MCS_BANDWIDTH_KNOWN) {
2169			printf("%s ",
2170				bandwidth[u2.u8 & IEEE80211_RADIOTAP_MCS_BANDWIDTH_MASK]);
2171		}
2172		if (u.u8 & IEEE80211_RADIOTAP_MCS_GUARD_INTERVAL_KNOWN) {
2173			printf("%s GI ",
2174				(u2.u8 & IEEE80211_RADIOTAP_MCS_SHORT_GI) ?
2175				"short" : "lon");
2176		}
2177		if (u.u8 & IEEE80211_RADIOTAP_MCS_HT_FORMAT_KNOWN) {
2178			printf("%s ",
2179				(u2.u8 & IEEE80211_RADIOTAP_MCS_HT_GREENFIELD) ?
2180				"greenfield" : "mixed");
2181		}
2182		if (u.u8 & IEEE80211_RADIOTAP_MCS_FEC_TYPE_KNOWN) {
2183			printf("%s FEC ",
2184				(u2.u8 & IEEE80211_RADIOTAP_MCS_FEC_LDPC) ?
2185				"LDPC" : "BCC");
2186		}
2187		break;
2188		}
2189	}
2190	return 0;
2191}
2192
2193static u_int
2194ieee802_11_radio_print(const u_char *p, u_int length, u_int caplen)
2195{
2196#define	BITNO_32(x) (((x) >> 16) ? 16 + BITNO_16((x) >> 16) : BITNO_16((x)))
2197#define	BITNO_16(x) (((x) >> 8) ? 8 + BITNO_8((x) >> 8) : BITNO_8((x)))
2198#define	BITNO_8(x) (((x) >> 4) ? 4 + BITNO_4((x) >> 4) : BITNO_4((x)))
2199#define	BITNO_4(x) (((x) >> 2) ? 2 + BITNO_2((x) >> 2) : BITNO_2((x)))
2200#define	BITNO_2(x) (((x) & 2) ? 1 : 0)
2201#define	BIT(n)	(1U << n)
2202#define	IS_EXTENDED(__p)	\
2203	    (EXTRACT_LE_32BITS(__p) & BIT(IEEE80211_RADIOTAP_EXT)) != 0
2204
2205	struct cpack_state cpacker;
2206	struct ieee80211_radiotap_header *hdr;
2207	u_int32_t present, next_present;
2208	u_int32_t presentflags = 0;
2209	u_int32_t *presentp, *last_presentp;
2210	enum ieee80211_radiotap_type bit;
2211	int bit0;
2212	const u_char *iter;
2213	u_int len;
2214	u_int8_t flags;
2215	int pad;
2216	u_int fcslen;
2217	struct radiotap_state state;
2218
2219	if (caplen < sizeof(*hdr)) {
2220		printf("[|802.11]");
2221		return caplen;
2222	}
2223
2224	hdr = (struct ieee80211_radiotap_header *)p;
2225
2226	len = EXTRACT_LE_16BITS(&hdr->it_len);
2227
2228	if (caplen < len) {
2229		printf("[|802.11]");
2230		return caplen;
2231	}
2232	for (last_presentp = &hdr->it_present;
2233	     IS_EXTENDED(last_presentp) &&
2234	     (u_char*)(last_presentp + 1) <= p + len;
2235	     last_presentp++);
2236
2237	/* are there more bitmap extensions than bytes in header? */
2238	if (IS_EXTENDED(last_presentp)) {
2239		printf("[|802.11]");
2240		return caplen;
2241	}
2242
2243	iter = (u_char*)(last_presentp + 1);
2244
2245	if (cpack_init(&cpacker, (u_int8_t*)iter, len - (iter - p)) != 0) {
2246		/* XXX */
2247		printf("[|802.11]");
2248		return caplen;
2249	}
2250
2251	/* Assume no flags */
2252	flags = 0;
2253	/* Assume no Atheros padding between 802.11 header and body */
2254	pad = 0;
2255	/* Assume no FCS at end of frame */
2256	fcslen = 0;
2257	for (bit0 = 0, presentp = &hdr->it_present; presentp <= last_presentp;
2258	     presentp++, bit0 += 32) {
2259		presentflags = EXTRACT_LE_32BITS(presentp);
2260
2261		/* Clear state. */
2262		memset(&state, 0, sizeof(state));
2263
2264		for (present = EXTRACT_LE_32BITS(presentp); present;
2265		     present = next_present) {
2266			/* clear the least significant bit that is set */
2267			next_present = present & (present - 1);
2268
2269			/* extract the least significant bit that is set */
2270			bit = (enum ieee80211_radiotap_type)
2271			    (bit0 + BITNO_32(present ^ next_present));
2272
2273			if (print_radiotap_field(&cpacker, bit, &flags, &state, presentflags) != 0)
2274				goto out;
2275		}
2276	}
2277
2278out:
2279	if (flags & IEEE80211_RADIOTAP_F_DATAPAD)
2280		pad = 1;	/* Atheros padding */
2281	if (flags & IEEE80211_RADIOTAP_F_FCS)
2282		fcslen = 4;	/* FCS at end of packet */
2283	return len + ieee802_11_print(p + len, length - len, caplen - len, pad,
2284	    fcslen);
2285#undef BITNO_32
2286#undef BITNO_16
2287#undef BITNO_8
2288#undef BITNO_4
2289#undef BITNO_2
2290#undef BIT
2291}
2292
2293static u_int
2294ieee802_11_avs_radio_print(const u_char *p, u_int length, u_int caplen)
2295{
2296	u_int32_t caphdr_len;
2297
2298	if (caplen < 8) {
2299		printf("[|802.11]");
2300		return caplen;
2301	}
2302
2303	caphdr_len = EXTRACT_32BITS(p + 4);
2304	if (caphdr_len < 8) {
2305		/*
2306		 * Yow!  The capture header length is claimed not
2307		 * to be large enough to include even the version
2308		 * cookie or capture header length!
2309		 */
2310		printf("[|802.11]");
2311		return caplen;
2312	}
2313
2314	if (caplen < caphdr_len) {
2315		printf("[|802.11]");
2316		return caplen;
2317	}
2318
2319	return caphdr_len + ieee802_11_print(p + caphdr_len,
2320	    length - caphdr_len, caplen - caphdr_len, 0, 0);
2321}
2322
2323#define PRISM_HDR_LEN		144
2324
2325#define WLANCAP_MAGIC_COOKIE_BASE 0x80211000
2326#define WLANCAP_MAGIC_COOKIE_V1	0x80211001
2327#define WLANCAP_MAGIC_COOKIE_V2	0x80211002
2328
2329/*
2330 * For DLT_PRISM_HEADER; like DLT_IEEE802_11, but with an extra header,
2331 * containing information such as radio information, which we
2332 * currently ignore.
2333 *
2334 * If, however, the packet begins with WLANCAP_MAGIC_COOKIE_V1 or
2335 * WLANCAP_MAGIC_COOKIE_V2, it's really DLT_IEEE802_11_RADIO_AVS
2336 * (currently, on Linux, there's no ARPHRD_ type for
2337 * DLT_IEEE802_11_RADIO_AVS, as there is a ARPHRD_IEEE80211_PRISM
2338 * for DLT_PRISM_HEADER, so ARPHRD_IEEE80211_PRISM is used for
2339 * the AVS header, and the first 4 bytes of the header are used to
2340 * indicate whether it's a Prism header or an AVS header).
2341 */
2342u_int
2343prism_if_print(const struct pcap_pkthdr *h, const u_char *p)
2344{
2345	u_int caplen = h->caplen;
2346	u_int length = h->len;
2347	u_int32_t msgcode;
2348
2349	if (caplen < 4) {
2350		printf("[|802.11]");
2351		return caplen;
2352	}
2353
2354	msgcode = EXTRACT_32BITS(p);
2355	if (msgcode == WLANCAP_MAGIC_COOKIE_V1 ||
2356	    msgcode == WLANCAP_MAGIC_COOKIE_V2)
2357		return ieee802_11_avs_radio_print(p, length, caplen);
2358
2359	if (caplen < PRISM_HDR_LEN) {
2360		printf("[|802.11]");
2361		return caplen;
2362	}
2363
2364	return PRISM_HDR_LEN + ieee802_11_print(p + PRISM_HDR_LEN,
2365	    length - PRISM_HDR_LEN, caplen - PRISM_HDR_LEN, 0, 0);
2366}
2367
2368/*
2369 * For DLT_IEEE802_11_RADIO; like DLT_IEEE802_11, but with an extra
2370 * header, containing information such as radio information.
2371 */
2372u_int
2373ieee802_11_radio_if_print(const struct pcap_pkthdr *h, const u_char *p)
2374{
2375	return ieee802_11_radio_print(p, h->len, h->caplen);
2376}
2377
2378/*
2379 * For DLT_IEEE802_11_RADIO_AVS; like DLT_IEEE802_11, but with an
2380 * extra header, containing information such as radio information,
2381 * which we currently ignore.
2382 */
2383u_int
2384ieee802_11_radio_avs_if_print(const struct pcap_pkthdr *h, const u_char *p)
2385{
2386	return ieee802_11_avs_radio_print(p, h->len, h->caplen);
2387}
2388