Home | History | Annotate | Download | only in tcpdump
      1 /*
      2  * Copyright (c) 2001
      3  *	Fortress Technologies, Inc.  All rights reserved.
      4  *      Charlie Lenahan (clenahan (at) fortresstech.com)
      5  *
      6  * Redistribution and use in source and binary forms, with or without
      7  * modification, are permitted provided that: (1) source code distributions
      8  * retain the above copyright notice and this paragraph in its entirety, (2)
      9  * distributions including binary code include the above copyright notice and
     10  * this paragraph in its entirety in the documentation or other materials
     11  * provided with the distribution, and (3) all advertising materials mentioning
     12  * features or use of this software display the following acknowledgement:
     13  * ``This product includes software developed by the University of California,
     14  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
     15  * the University nor the names of its contributors may be used to endorse
     16  * or promote products derived from this software without specific prior
     17  * written permission.
     18  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
     19  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
     20  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
     21  */
     22 
     23 #ifndef lint
     24 static const char rcsid[] _U_ =
     25     "@(#) $Header: /tcpdump/master/tcpdump/print-802_11.c,v 1.49 2007-12-29 23:25:02 guy Exp $ (LBL)";
     26 #endif
     27 
     28 #ifdef HAVE_CONFIG_H
     29 #include "config.h"
     30 #endif
     31 
     32 #include <tcpdump-stdinc.h>
     33 
     34 #include <stdio.h>
     35 #include <pcap.h>
     36 #include <string.h>
     37 
     38 #include "interface.h"
     39 #include "addrtoname.h"
     40 #include "ethertype.h"
     41 
     42 #include "extract.h"
     43 
     44 #include "cpack.h"
     45 
     46 #include "ieee802_11.h"
     47 #include "ieee802_11_radio.h"
     48 
     49 /* Radiotap state */
     50 /*  This is used to save state when parsing/processing parameters */
     51 struct 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  */
     97 static 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 
    484 static 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 
    487 static 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 
    571 static 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 
    639 static int
    640 wep_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 
    654 static int
    655 parse_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 
    896 static int
    897 handle_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 
    932 static int
    933 handle_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 
    959 static int
    960 handle_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 
    995 static int
    996 handle_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 
   1028 static int
   1029 handle_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 
   1035 static int
   1036 handle_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 
   1052 static int
   1053 handle_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 
   1086 static int
   1087 handle_atim(void)
   1088 {
   1089 	/* the frame body for ATIM is null. */
   1090 	return 1;
   1091 }
   1092 
   1093 static int
   1094 handle_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 
   1114 static int
   1115 handle_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 
   1167 static int
   1168 handle_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 
   1254 static int
   1255 handle_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 
   1293 static int
   1294 mgmt_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 
   1354 static int
   1355 ctrl_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 
   1448 static void
   1449 data_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 
   1524 static void
   1525 mgmt_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 
   1542 static void
   1543 ctrl_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 
   1599 static int
   1600 extract_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 
   1637 static int
   1638 extract_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  */
   1648 static void
   1649 ieee_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 
   1709 static u_int
   1710 ieee802_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  */
   1817 u_int
   1818 ieee802_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 
   1847 static void
   1848 print_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 
   1881 static int
   1882 print_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 		if (u.u8 & IEEE80211_RADIOTAP_MCS_STBC_KNOWN) {
   2188 			printf("RX-STBC%u ",
   2189 				(u2.u8 & IEEE80211_RADIOTAP_MCS_STBC_MASK) >> IEEE80211_RADIOTAP_MCS_STBC_SHIFT);
   2190 		}
   2191 
   2192 		break;
   2193 		}
   2194 	}
   2195 	return 0;
   2196 }
   2197 
   2198 static u_int
   2199 ieee802_11_radio_print(const u_char *p, u_int length, u_int caplen)
   2200 {
   2201 #define	BITNO_32(x) (((x) >> 16) ? 16 + BITNO_16((x) >> 16) : BITNO_16((x)))
   2202 #define	BITNO_16(x) (((x) >> 8) ? 8 + BITNO_8((x) >> 8) : BITNO_8((x)))
   2203 #define	BITNO_8(x) (((x) >> 4) ? 4 + BITNO_4((x) >> 4) : BITNO_4((x)))
   2204 #define	BITNO_4(x) (((x) >> 2) ? 2 + BITNO_2((x) >> 2) : BITNO_2((x)))
   2205 #define	BITNO_2(x) (((x) & 2) ? 1 : 0)
   2206 #define	BIT(n)	(1U << n)
   2207 #define	IS_EXTENDED(__p)	\
   2208 	    (EXTRACT_LE_32BITS(__p) & BIT(IEEE80211_RADIOTAP_EXT)) != 0
   2209 
   2210 	struct cpack_state cpacker;
   2211 	struct ieee80211_radiotap_header *hdr;
   2212 	u_int32_t present, next_present;
   2213 	u_int32_t presentflags = 0;
   2214 	u_int32_t *presentp, *last_presentp;
   2215 	enum ieee80211_radiotap_type bit;
   2216 	int bit0;
   2217 	u_int len;
   2218 	u_int8_t flags;
   2219 	int pad;
   2220 	u_int fcslen;
   2221 	struct radiotap_state state;
   2222 
   2223 	if (caplen < sizeof(*hdr)) {
   2224 		printf("[|802.11]");
   2225 		return caplen;
   2226 	}
   2227 
   2228 	hdr = (struct ieee80211_radiotap_header *)p;
   2229 
   2230 	len = EXTRACT_LE_16BITS(&hdr->it_len);
   2231 
   2232 	if (caplen < len) {
   2233 		printf("[|802.11]");
   2234 		return caplen;
   2235 	}
   2236 	cpack_init(&cpacker, (u_int8_t *)hdr, len); /* align against header start */
   2237 	cpack_advance(&cpacker, sizeof(*hdr)); /* includes the 1st bitmap */
   2238 	for (last_presentp = &hdr->it_present;
   2239 	     IS_EXTENDED(last_presentp) &&
   2240 	     (u_char*)(last_presentp + 1) <= p + len;
   2241 	     last_presentp++)
   2242 	  cpack_advance(&cpacker, sizeof(hdr->it_present)); /* more bitmaps */
   2243 
   2244 	/* are there more bitmap extensions than bytes in header? */
   2245 	if (IS_EXTENDED(last_presentp)) {
   2246 		printf("[|802.11]");
   2247 		return caplen;
   2248 	}
   2249 
   2250 	/* Assume no flags */
   2251 	flags = 0;
   2252 	/* Assume no Atheros padding between 802.11 header and body */
   2253 	pad = 0;
   2254 	/* Assume no FCS at end of frame */
   2255 	fcslen = 0;
   2256 	for (bit0 = 0, presentp = &hdr->it_present; presentp <= last_presentp;
   2257 	     presentp++, bit0 += 32) {
   2258 		presentflags = EXTRACT_LE_32BITS(presentp);
   2259 
   2260 		/* Clear state. */
   2261 		memset(&state, 0, sizeof(state));
   2262 
   2263 		for (present = EXTRACT_LE_32BITS(presentp); present;
   2264 		     present = next_present) {
   2265 			/* clear the least significant bit that is set */
   2266 			next_present = present & (present - 1);
   2267 
   2268 			/* extract the least significant bit that is set */
   2269 			bit = (enum ieee80211_radiotap_type)
   2270 			    (bit0 + BITNO_32(present ^ next_present));
   2271 
   2272 			if (print_radiotap_field(&cpacker, bit, &flags, &state, presentflags) != 0)
   2273 				goto out;
   2274 		}
   2275 	}
   2276 
   2277 out:
   2278 	if (flags & IEEE80211_RADIOTAP_F_DATAPAD)
   2279 		pad = 1;	/* Atheros padding */
   2280 	if (flags & IEEE80211_RADIOTAP_F_FCS)
   2281 		fcslen = 4;	/* FCS at end of packet */
   2282 	return len + ieee802_11_print(p + len, length - len, caplen - len, pad,
   2283 	    fcslen);
   2284 #undef BITNO_32
   2285 #undef BITNO_16
   2286 #undef BITNO_8
   2287 #undef BITNO_4
   2288 #undef BITNO_2
   2289 #undef BIT
   2290 }
   2291 
   2292 static u_int
   2293 ieee802_11_avs_radio_print(const u_char *p, u_int length, u_int caplen)
   2294 {
   2295 	u_int32_t caphdr_len;
   2296 
   2297 	if (caplen < 8) {
   2298 		printf("[|802.11]");
   2299 		return caplen;
   2300 	}
   2301 
   2302 	caphdr_len = EXTRACT_32BITS(p + 4);
   2303 	if (caphdr_len < 8) {
   2304 		/*
   2305 		 * Yow!  The capture header length is claimed not
   2306 		 * to be large enough to include even the version
   2307 		 * cookie or capture header length!
   2308 		 */
   2309 		printf("[|802.11]");
   2310 		return caplen;
   2311 	}
   2312 
   2313 	if (caplen < caphdr_len) {
   2314 		printf("[|802.11]");
   2315 		return caplen;
   2316 	}
   2317 
   2318 	return caphdr_len + ieee802_11_print(p + caphdr_len,
   2319 	    length - caphdr_len, caplen - caphdr_len, 0, 0);
   2320 }
   2321 
   2322 #define PRISM_HDR_LEN		144
   2323 
   2324 #define WLANCAP_MAGIC_COOKIE_BASE 0x80211000
   2325 #define WLANCAP_MAGIC_COOKIE_V1	0x80211001
   2326 #define WLANCAP_MAGIC_COOKIE_V2	0x80211002
   2327 
   2328 /*
   2329  * For DLT_PRISM_HEADER; like DLT_IEEE802_11, but with an extra header,
   2330  * containing information such as radio information, which we
   2331  * currently ignore.
   2332  *
   2333  * If, however, the packet begins with WLANCAP_MAGIC_COOKIE_V1 or
   2334  * WLANCAP_MAGIC_COOKIE_V2, it's really DLT_IEEE802_11_RADIO_AVS
   2335  * (currently, on Linux, there's no ARPHRD_ type for
   2336  * DLT_IEEE802_11_RADIO_AVS, as there is a ARPHRD_IEEE80211_PRISM
   2337  * for DLT_PRISM_HEADER, so ARPHRD_IEEE80211_PRISM is used for
   2338  * the AVS header, and the first 4 bytes of the header are used to
   2339  * indicate whether it's a Prism header or an AVS header).
   2340  */
   2341 u_int
   2342 prism_if_print(const struct pcap_pkthdr *h, const u_char *p)
   2343 {
   2344 	u_int caplen = h->caplen;
   2345 	u_int length = h->len;
   2346 	u_int32_t msgcode;
   2347 
   2348 	if (caplen < 4) {
   2349 		printf("[|802.11]");
   2350 		return caplen;
   2351 	}
   2352 
   2353 	msgcode = EXTRACT_32BITS(p);
   2354 	if (msgcode == WLANCAP_MAGIC_COOKIE_V1 ||
   2355 	    msgcode == WLANCAP_MAGIC_COOKIE_V2)
   2356 		return ieee802_11_avs_radio_print(p, length, caplen);
   2357 
   2358 	if (caplen < PRISM_HDR_LEN) {
   2359 		printf("[|802.11]");
   2360 		return caplen;
   2361 	}
   2362 
   2363 	return PRISM_HDR_LEN + ieee802_11_print(p + PRISM_HDR_LEN,
   2364 	    length - PRISM_HDR_LEN, caplen - PRISM_HDR_LEN, 0, 0);
   2365 }
   2366 
   2367 /*
   2368  * For DLT_IEEE802_11_RADIO; like DLT_IEEE802_11, but with an extra
   2369  * header, containing information such as radio information.
   2370  */
   2371 u_int
   2372 ieee802_11_radio_if_print(const struct pcap_pkthdr *h, const u_char *p)
   2373 {
   2374 	return ieee802_11_radio_print(p, h->len, h->caplen);
   2375 }
   2376 
   2377 /*
   2378  * For DLT_IEEE802_11_RADIO_AVS; like DLT_IEEE802_11, but with an
   2379  * extra header, containing information such as radio information,
   2380  * which we currently ignore.
   2381  */
   2382 u_int
   2383 ieee802_11_radio_avs_if_print(const struct pcap_pkthdr *h, const u_char *p)
   2384 {
   2385 	return ieee802_11_avs_radio_print(p, h->len, h->caplen);
   2386 }
   2387