change the signature that asn2wrs generates for functions to marm all parameters...
[obnox/wireshark/wip.git] / epan / dissectors / packet-ieee80211.c
1 /* packet-ieee80211.c
2  * Routines for Wireless LAN (IEEE 802.11) dissection
3  * Copyright 2000, Axis Communications AB
4  * Inquiries/bugreports should be sent to Johan.Jorgensen@axis.com
5  *
6  * $Id$
7  *
8  * Wireshark - Network traffic analyzer
9  * By Gerald Combs <gerald@wireshark.org>
10  * Copyright 1998 Gerald Combs
11  *
12  * Copied from README.developer
13  *
14  * This program is free software; you can redistribute it and/or
15  * modify it under the terms of the GNU General Public License
16  * as published by the Free Software Foundation; either version 2
17  * of the License, or (at your option) any later version.
18  *
19  * This program is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU General Public License for more details.
23  *
24  * You should have received a copy of the GNU General Public License
25  * along with this program; if not, write to the Free Software
26  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
27  *
28  * Credits:
29  *
30  * The following people helped me by pointing out bugs etc. Thank you!
31  *
32  * Marco Molteni
33  * Lena-Marie Nilsson
34  * Magnus Hultman-Persson
35  */
36
37 /*
38  * 09/12/2003 - Added dissection of country information tag
39  *
40  * Ritchie<at>tipsybottle.com
41  *
42  * 03/22/2004 - Added dissection of RSN IE
43  * Jouni Malinen <jkmaline@cc.hut.fi>
44  *
45  * 10/24/2005 - Add dissection for 802.11e
46  * Zhu Yi <yi.zhu@intel.com>
47  */
48
49 #ifdef HAVE_CONFIG_H
50 # include "config.h"
51 #endif
52
53 #include <stdio.h>
54 #include <stdlib.h>
55
56 #include <string.h>
57 #include <glib.h>
58 #include <epan/bitswap.h>
59 #include <epan/proto.h>
60 #include <epan/packet.h>
61 #include <epan/addr_resolv.h>
62 #include <epan/strutil.h>
63 #include <epan/prefs.h>
64 #include <epan/reassemble.h>
65 #include "packet-ipx.h"
66 #include "packet-llc.h"
67 #include "packet-ieee80211.h"
68 #include <epan/etypes.h>
69 #include <epan/oui.h>
70 #include <epan/crc32.h>
71 #include <epan/tap.h>
72 #include <epan/emem.h>
73 #include <epan/crypt/wep-wpadefs.h>
74
75 #include <ctype.h>
76 #include "isprint.h"
77
78 #ifdef HAVE_AIRPCAP
79 #include <airpcap.h>
80 #include <airpcap_loader.h>
81 #else
82 /* XXX - This is probably a bit much */
83 #define MAX_ENCRYPTION_KEYS 64
84 #endif
85
86 #ifndef roundup2
87 #define roundup2(x, y)  (((x)+((y)-1))&(~((y)-1))) /* if y is powers of two */
88 #endif
89
90 /* Defragment fragmented 802.11 datagrams */
91 static gboolean wlan_defragment = TRUE;
92
93 /* Check for the presence of the 802.11 FCS */
94 static gboolean wlan_check_fcs = FALSE;
95
96 /* Ignore the WEP bit; assume packet is decrypted */
97 static gboolean wlan_ignore_wep = FALSE;
98
99 /* Tables for reassembly of fragments. */
100 static GHashTable *wlan_fragment_table = NULL;
101 static GHashTable *wlan_reassembled_table = NULL;
102
103 /* Stuff for the WEP decoder */
104
105 static gint num_wepkeys = 0;
106 static gboolean enable_decryption = FALSE;
107 static guint8 **wep_keys = NULL;
108 static int *wep_keylens = NULL;
109 static void init_wepkeys(void);
110 #ifndef HAVE_AIRPDCAP
111 static tvbuff_t *try_decrypt_wep(tvbuff_t *tvb, guint32 offset, guint32 len);
112 static int wep_decrypt(guint8 *buf, guint32 len, int key_override);
113 #else
114 /* Davide Schiera (2006-11-26): created function to decrypt WEP and WPA/WPA2    */
115 static tvbuff_t *try_decrypt(tvbuff_t *tvb, guint32 offset, guint32 len, guint8 *algorithm, guint32 *sec_header, guint32 *sec_trailer);
116 #endif
117 static int weak_iv(guchar *iv);
118 #define SSWAP(a,b) {guint8 tmp = s[a]; s[a] = s[b]; s[b] = tmp;}
119
120 /* #define USE_ENV */
121 /* When this is set, an unlimited number of WEP keys can be set in the
122    environment:
123
124    WIRESHARK_WEPKEYNUM=##
125    WIRESHARK_WEPKEY1=aa:bb:cc:dd:...
126    WIRESHARK_WEPKEY2=aa:bab:cc:dd:ee:...
127
128    ... you get the idea.
129
130    otherwise you're limited to specifying four keys in the preference system.
131  */
132
133 #ifndef USE_ENV
134 static char *wep_keystr[MAX_ENCRYPTION_KEYS];
135 #endif
136
137 /* ************************************************************************* */
138 /*                          Miscellaneous Constants                          */
139 /* ************************************************************************* */
140 #define SHORT_STR 256
141
142 /* ************************************************************************* */
143 /*  Define some very useful macros that are used to analyze frame types etc. */
144 /* ************************************************************************* */
145
146 /*
147  * Extract the protocol version from the frame control field
148  */
149 #define FCF_PROT_VERSION(x)  ((x) & 0x3)
150
151 /*
152  * Extract the frame type from the frame control field.
153  */
154 #define FCF_FRAME_TYPE(x)    (((x) & 0xC) >> 2)
155
156 /*
157  * Extract the frame subtype from the frame control field.
158  */
159 #define FCF_FRAME_SUBTYPE(x) (((x) & 0xF0) >> 4)
160
161 /*
162  * Convert the frame type and subtype from the frame control field into
163  * one of the MGT_, CTRL_, or DATA_ values.
164  */
165 #define COMPOSE_FRAME_TYPE(x) (((x & 0x0C)<< 2)+FCF_FRAME_SUBTYPE(x))   /* Create key to (sub)type */
166
167 /*
168  * The subtype field of a data frame is, in effect, composed of 4 flag
169  * bits - CF-Ack, CF-Poll, Null (means the frame doesn't actually have
170  * any data), and QoS.
171  */
172 #define DATA_FRAME_IS_CF_ACK(x)  ((x) & 0x01)
173 #define DATA_FRAME_IS_CF_POLL(x) ((x) & 0x02)
174 #define DATA_FRAME_IS_NULL(x)    ((x) & 0x04)
175 #define DATA_FRAME_IS_QOS(x)     ((x) & 0x08)
176
177 /*
178  * Extract the flags from the frame control field.
179  */
180 #define FCF_FLAGS(x)           (((x) & 0xFF00) >> 8)
181
182 /*
183  * Bits from the flags field.
184  */
185 #define FLAG_TO_DS              0x01
186 #define FLAG_FROM_DS            0x02
187 #define FLAG_MORE_FRAGMENTS     0x04
188 #define FLAG_RETRY              0x08
189 #define FLAG_POWER_MGT          0x10
190 #define FLAG_MORE_DATA          0x20
191 #define FLAG_PROTECTED          0x40
192 #define FLAG_ORDER              0x80
193
194 /*
195  * Test bits in the flags field.
196  */
197 #define IS_TO_DS(x)            ((x) & FLAG_TO_DS)
198 #define IS_FROM_DS(x)          ((x) & FLAG_FROM_DS)
199 #define HAVE_FRAGMENTS(x)      ((x) & FLAG_MORE_FRAGMENTS)
200 #define IS_RETRY(x)            ((x) & FLAG_RETRY)
201 #define POWER_MGT_STATUS(x)    ((x) & FLAG_POWER_MGT)
202 #define HAS_MORE_DATA(x)       ((x) & FLAG_MORE_DATA)
203 #define IS_PROTECTED(x)        (!wlan_ignore_wep && ((x) & FLAG_PROTECTED))
204 #define IS_STRICTLY_ORDERED(x) ((x) & FLAG_ORDER)
205
206 /*
207  * Extract subfields from the flags field.
208  */
209 #define FLAGS_DS_STATUS(x)          ((x) & (FLAG_FROM_DS|FLAG_TO_DS))
210
211 /*
212  * Extract an indication of the types of addresses in a data frame from
213  * the frame control field.
214  */
215 #define FCF_ADDR_SELECTOR(x) ((x) & ((FLAG_TO_DS|FLAG_FROM_DS) << 8))
216
217 #define DATA_ADDR_T1         0
218 #define DATA_ADDR_T2         (FLAG_FROM_DS << 8)
219 #define DATA_ADDR_T3         (FLAG_TO_DS << 8)
220 #define DATA_ADDR_T4         ((FLAG_TO_DS|FLAG_FROM_DS) << 8)
221
222 /*
223  * Extract the fragment number and sequence number from the sequence
224  * control field.
225  */
226 #define SEQCTL_FRAGMENT_NUMBER(x) ((x) & 0x000F)
227 #define SEQCTL_SEQUENCE_NUMBER(x) (((x) & 0xFFF0) >> 4)
228
229 /*
230  * Extract subfields from the QoS control field.
231  */
232 #define QOS_TID(x)            ((x) & 0x000F)
233 #define QOS_PRIORITY(x)       ((x) & 0x0007)
234 #define QOS_EOSP(x)           (((x) & 0x0010) >> 4) /* end of service period */
235 #define QOS_ACK_POLICY(x)     (((x) & 0x0060) >> 5)
236 #define QOS_FIELD_CONTENT(x)  (((x) & 0xFF00) >> 8)
237
238 #define QOS_FLAG_EOSP           0x08
239
240 /*
241  * Extract subfields from the result of QOS_FIELD_CONTENT().
242  */
243 #define QOS_PS_BUF_STATE(x)     (((x) & 0x02) >> 1)
244 #define QOS_PS_BUF_AC(x)        (((x) & 0x0C) >> 2)
245 #define QOS_PS_BUF_LOAD(x)      (((x) & 0xF0) >> 4)
246
247 /*
248  * Extract the association ID from the value in an association ID field.
249  */
250 #define ASSOC_ID(x)             ((x) & 0x3FFF)
251
252 /*
253  * Extract subfields from the key octet in WEP-encrypted frames.
254  */
255 #define KEY_OCTET_WEP_KEY(x)    (((x) & 0xC0) >> 6)
256
257 /*
258  * Extract subfields from TS Info field.
259  */
260 #define TSI_TYPE(x)             (((x) & 0x000001) >> 0)
261 #define TSI_TSID(x)             (((x) & 0x00001E) >> 1)
262 #define TSI_DIR(x)              (((x) & 0x000060) >> 5)
263 #define TSI_ACCESS(x)           (((x) & 0x000180) >> 7)
264 #define TSI_AGG(x)              (((x) & 0x000200) >> 9)
265 #define TSI_APSD(x)             (((x) & 0x000400) >> 10)
266 #define TSI_UP(x)               (((x) & 0x003800) >> 11)
267 #define TSI_ACK(x)              (((x) & 0x00C000) >> 14)
268 #define TSI_SCHED(x)            (((x) & 0x010000) >> 16)
269 #define TSI_RESERVED(x)         (((x) & 0xFE0000) >> 17)
270
271 #define KEY_EXTIV               0x20
272 #define EXTIV_LEN               8
273
274
275 /* ************************************************************************* */
276 /*              Constants used to identify cooked frame types                */
277 /* ************************************************************************* */
278 #define MGT_FRAME            0x00       /* Frame type is management */
279 #define CONTROL_FRAME        0x01       /* Frame type is control */
280 #define DATA_FRAME           0x02       /* Frame type is Data */
281
282 #define DATA_SHORT_HDR_LEN     24
283 #define DATA_LONG_HDR_LEN      30
284 #define MGT_FRAME_HDR_LEN      24       /* Length of Managment frame-headers */
285
286 /*
287  * COMPOSE_FRAME_TYPE() values for management frames.
288  */
289 #define MGT_ASSOC_REQ        0x00       /* association request        */
290 #define MGT_ASSOC_RESP       0x01       /* association response       */
291 #define MGT_REASSOC_REQ      0x02       /* reassociation request      */
292 #define MGT_REASSOC_RESP     0x03       /* reassociation response     */
293 #define MGT_PROBE_REQ        0x04       /* Probe request              */
294 #define MGT_PROBE_RESP       0x05       /* Probe response             */
295 #define MGT_BEACON           0x08       /* Beacon frame               */
296 #define MGT_ATIM             0x09       /* ATIM                       */
297 #define MGT_DISASS           0x0A       /* Disassociation             */
298 #define MGT_AUTHENTICATION   0x0B       /* Authentication             */
299 #define MGT_DEAUTHENTICATION 0x0C       /* Deauthentication           */
300 #define MGT_ACTION           0x0D       /* Action */
301
302 /*
303  * COMPOSE_FRAME_TYPE() values for control frames.
304  */
305 #define CTRL_BLOCK_ACK_REQ   0x18       /* Block ack Request                */
306 #define CTRL_BLOCK_ACK       0x19       /* Block ack                        */
307 #define CTRL_PS_POLL         0x1A       /* power-save poll               */
308 #define CTRL_RTS             0x1B       /* request to send               */
309 #define CTRL_CTS             0x1C       /* clear to send                 */
310 #define CTRL_ACKNOWLEDGEMENT 0x1D       /* acknowledgement               */
311 #define CTRL_CFP_END         0x1E       /* contention-free period end    */
312 #define CTRL_CFP_ENDACK      0x1F       /* contention-free period end/ack */
313
314 /*
315  * COMPOSE_FRAME_TYPE() values for data frames.
316  */
317 #define DATA                        0x20        /* Data                       */
318 #define DATA_CF_ACK                 0x21        /* Data + CF-Ack              */
319 #define DATA_CF_POLL                0x22        /* Data + CF-Poll             */
320 #define DATA_CF_ACK_POLL            0x23        /* Data + CF-Ack + CF-Poll    */
321 #define DATA_NULL_FUNCTION          0x24        /* Null function (no data)    */
322 #define DATA_CF_ACK_NOD             0x25        /* CF-Ack (no data)           */
323 #define DATA_CF_POLL_NOD            0x26        /* CF-Poll (No data)          */
324 #define DATA_CF_ACK_POLL_NOD        0x27        /* CF-Ack + CF-Poll (no data) */
325
326 #define DATA_QOS_DATA               0x28        /* QoS Data                   */
327 #define DATA_QOS_DATA_CF_ACK        0x29        /* QoS Data + CF-Ack          */
328 #define DATA_QOS_DATA_CF_POLL       0x2A        /* QoS Data + CF-Poll             */
329 #define DATA_QOS_DATA_CF_ACK_POLL   0x2B        /* QoS Data + CF-Ack + CF-Poll    */
330 #define DATA_QOS_NULL               0x2C        /* QoS Null                       */
331 #define DATA_QOS_CF_POLL_NOD        0x2E        /* QoS CF-Poll (No Data)                  */
332 #define DATA_QOS_CF_ACK_POLL_NOD    0x2F        /* QoS CF-Ack + CF-Poll (No Data) */
333
334
335 /* ************************************************************************* */
336 /*          Macros used to extract information about fixed fields            */
337 /* ************************************************************************* */
338 #define ESS_SET(x) ((x) & 0x0001)
339 #define IBSS_SET(x) ((x) & 0x0002)
340
341
342
343 /* ************************************************************************* */
344 /*        Logical field codes (dissector's encoding of fixed fields)         */
345 /* ************************************************************************* */
346 #define FIELD_TIMESTAMP       0x01      /* 64-bit timestamp                       */
347 #define FIELD_BEACON_INTERVAL 0x02      /* 16-bit beacon interval                 */
348 #define FIELD_CAP_INFO        0x03      /* Add capability information tree        */
349 #define FIELD_AUTH_ALG        0x04      /* Authentication algorithm used          */
350 #define FIELD_AUTH_TRANS_SEQ  0x05      /* Authentication sequence number         */
351 #define FIELD_CURRENT_AP_ADDR 0x06
352 #define FIELD_LISTEN_IVAL     0x07
353 #define FIELD_REASON_CODE     0x08
354 #define FIELD_ASSOC_ID        0x09
355 #define FIELD_STATUS_CODE     0x0A
356 #define FIELD_CATEGORY_CODE   0x0B      /* Management action category */
357 #define FIELD_ACTION_CODE     0x0C      /* Management action code */
358 #define FIELD_DIALOG_TOKEN    0x0D      /* Management action dialog token */
359 #define FIELD_WME_ACTION_CODE   0x0E    /* Management notification action code */
360 #define FIELD_WME_DIALOG_TOKEN  0x0F    /* Management notification dialog token */
361 #define FIELD_WME_STATUS_CODE   0x10    /* Management notification setup response status code */
362 #define FIELD_QOS_ACTION_CODE   0x11
363 #define FIELD_QOS_TS_INFO       0x12
364 #define FIELD_DLS_ACTION_CODE   0x13
365 #define FIELD_DST_MAC_ADDR      0X14    /* DLS destination MAC address */
366 #define FIELD_SRC_MAC_ADDR      0X15    /* DLS source MAC address */
367 #define FIELD_DLS_TIMEOUT       0X16    /* DLS timeout value */
368 #define FIELD_SCHEDULE_INFO     0X17    /* Schedule Info field */
369
370 /* ************************************************************************* */
371 /*        Logical field codes (IEEE 802.11 encoding of tags)                 */
372 /* ************************************************************************* */
373 #define TAG_SSID                 0x00
374 #define TAG_SUPP_RATES           0x01
375 #define TAG_FH_PARAMETER         0x02
376 #define TAG_DS_PARAMETER         0x03
377 #define TAG_CF_PARAMETER         0x04
378 #define TAG_TIM                  0x05
379 #define TAG_IBSS_PARAMETER       0x06
380 #define TAG_COUNTRY_INFO         0x07
381 #define TAG_FH_HOPPING_PARAMETER 0x08
382 #define TAG_FH_HOPPING_TABLE     0x09
383 #define TAG_REQUEST              0x0A
384 #define TAG_QBSS_LOAD            0x0B
385 #define TAG_EDCA_PARAM_SET       0x0C
386 #define TAG_TSPEC                0x0D
387 #define TAG_TCLAS                0x0E
388 #define TAG_SCHEDULE             0x0F
389 #define TAG_CHALLENGE_TEXT       0x10
390 #define TAG_POWER_CONSTRAINT     0x20
391 #define TAG_POWER_CAPABILITY     0x21
392 #define TAG_TPC_REQUEST          0x22
393 #define TAG_TPC_REPORT           0x23
394 #define TAG_SUPPORTED_CHANNELS   0x24
395 #define TAG_CHANNEL_SWITCH_ANN   0x25
396 #define TAG_MEASURE_REQ          0x26
397 #define TAG_MEASURE_REP          0x27
398 #define TAG_QUIET                0x28
399 #define TAG_IBSS_DFS             0x29
400 #define TAG_ERP_INFO             0x2A
401 #define TAG_TS_DELAY             0x2B
402 #define TAG_TCLAS_PROCESS        0x2C
403 #define TAG_HT_INFO               0x2D  /* IEEE Stc 802.11n/D1.0 */
404 #define TAG_QOS_CAPABILITY       0x2E
405 #define TAG_ERP_INFO_OLD         0x2F   /* IEEE Std 802.11g/D4.0 */
406 #define TAG_RSN_IE               0x30
407 #define TAG_EXT_SUPP_RATES       0x32
408 #define TAG_AGERE_PROPRIETARY    0x80
409 #define TAG_CISCO_UNKNOWN_1      0x85   /* Cisco Compatible eXtensions? */
410 #define TAG_CISCO_UNKNOWN_2      0x88   /* Cisco Compatible eXtensions? */
411 #define TAG_VENDOR_SPECIFIC_IE   0xDD
412 #define TAG_SYMBOL_PROPRIETARY   0xAD
413
414 #define WPA_OUI  (const guint8 *) "\x00\x50\xF2"
415 #define RSN_OUI (const guint8 *) "\x00\x0F\xAC"
416 #define WME_OUI (const guint8 *) "\x00\x50\xF2"
417 #define PRE_11N_OUI (const guint8 *) "\x00\x90\x4c" /* 802.11n pre 1 oui */
418
419 #define PMKID_LEN 16
420
421 /* ************************************************************************* */
422 /*                         Frame types, and their names                      */
423 /* ************************************************************************* */
424 static const value_string frame_type_subtype_vals[] = {
425         {MGT_ASSOC_REQ,        "Association Request"},
426         {MGT_ASSOC_RESP,       "Association Response"},
427         {MGT_REASSOC_REQ,      "Reassociation Request"},
428         {MGT_REASSOC_RESP,     "Reassociation Response"},
429         {MGT_PROBE_REQ,        "Probe Request"},
430         {MGT_PROBE_RESP,       "Probe Response"},
431         {MGT_BEACON,           "Beacon frame"},
432         {MGT_ATIM,             "ATIM"},
433         {MGT_DISASS,           "Dissassociate"},
434         {MGT_AUTHENTICATION,   "Authentication"},
435         {MGT_DEAUTHENTICATION, "Deauthentication"},
436         {MGT_ACTION,           "Action"},
437
438         {CTRL_BLOCK_ACK_REQ,   "802.11 Block Ack Req"},
439         {CTRL_BLOCK_ACK,       "802.11 Block Ack"},
440         {CTRL_PS_POLL,         "Power-Save poll"},
441         {CTRL_RTS,             "Request-to-send"},
442         {CTRL_CTS,             "Clear-to-send"},
443         {CTRL_ACKNOWLEDGEMENT, "Acknowledgement"},
444         {CTRL_CFP_END,         "CF-End (Control-frame)"},
445         {CTRL_CFP_ENDACK,      "CF-End + CF-Ack (Control-frame)"},
446
447         {DATA,                 "Data"},
448         {DATA_CF_ACK,          "Data + CF-Ack"},
449         {DATA_CF_POLL,         "Data + CF-Poll"},
450         {DATA_CF_ACK_POLL,     "Data + CF-Ack + CF-Poll"},
451         {DATA_NULL_FUNCTION,   "Null function (No data)"},
452         {DATA_CF_ACK_NOD,      "Acknowledgement (No data)"},
453         {DATA_CF_POLL_NOD,     "CF-Poll (No data)"},
454         {DATA_CF_ACK_POLL_NOD, "CF-Ack/Poll (No data)"},
455         {DATA_QOS_DATA,        "QoS Data"},
456         {DATA_QOS_DATA_CF_ACK,  "QoS Data + CF-Acknowledgment"},
457         {DATA_QOS_DATA_CF_POLL, "QoS Data + CF-Poll"},
458         {DATA_QOS_DATA_CF_ACK_POLL, "QoS Data + CF-Ack + CF-Poll"},
459         {DATA_QOS_NULL,        "QoS Null function (No data)"},
460         {DATA_QOS_CF_POLL_NOD,  "QoS CF-Poll (No Data)"},
461         {DATA_QOS_CF_ACK_POLL_NOD,  "QoS CF-Ack + CF-Poll (No data)"},
462         {0,                    NULL}
463 };
464
465 /* ************************************************************************* */
466 /*                             802.1D Tag Names                              */
467 /* ************************************************************************* */
468 static const char *qos_tags[8] = {
469         "Best Effort",
470         "Background",
471         "Spare",
472         "Excellent Effort",
473         "Controlled Load",
474         "Video",
475         "Voice",
476         "Network Control"
477 };
478
479 /* ************************************************************************* */
480 /*                 WME Access Category Names (by 802.1D Tag)                 */
481 /* ************************************************************************* */
482 static const char *qos_acs[8] = {
483         "Best Effort",
484         "Background",
485         "Background",
486         "Video",
487         "Video",
488         "Video",
489         "Voice",
490         "Voice"
491 };
492
493 /* ************************************************************************* */
494 /*                   WME Access Category Names (by WME ACI)                  */
495 /* ************************************************************************* */
496 static const char *wme_acs[4] = {
497         "Best Effort",
498         "Background",
499         "Video",
500         "Voice",
501 };
502
503
504 #define CAT_SPECTRUM_MGMT       0
505 #define CAT_QOS                 1
506 #define CAT_DLS                 2
507 #define CAT_BLOCK_ACK           3
508 #define CAT_MGMT_NOTIFICATION   17
509
510 #define SM_ACTION_MEASUREMENT_REQUEST   0
511 #define SM_ACTION_MEASUREMENT_REPORT    1
512 #define SM_ACTION_TPC_REQUEST           2
513 #define SM_ACTION_TPC_REPORT            3
514 #define SM_ACTION_CHAN_SWITCH_ANNC      4
515
516 #define SM_ACTION_ADDTS_REQUEST         0
517 #define SM_ACTION_ADDTS_RESPONSE        1
518 #define SM_ACTION_DELTS                 2
519 #define SM_ACTION_QOS_SCHEDULE          3
520
521 #define SM_ACTION_DLS_REQUEST           0
522 #define SM_ACTION_DLS_RESPONSE          1
523 #define SM_ACTION_DLS_TEARDOWN          2
524
525 static int proto_wlan = -1;
526 static packet_info * g_pinfo;
527
528 /* ************************************************************************* */
529 /*                Header field info values for radio information             */
530 /* ************************************************************************* */
531 static int hf_data_rate = -1;
532 static int hf_channel = -1;
533 static int hf_signal_strength = -1;
534
535 /* ************************************************************************* */
536 /*                Header field info values for FC-field                      */
537 /* ************************************************************************* */
538 static int hf_fc_field = -1;
539 static int hf_fc_proto_version = -1;
540 static int hf_fc_frame_type = -1;
541 static int hf_fc_frame_subtype = -1;
542 static int hf_fc_frame_type_subtype = -1;
543
544 static int hf_fc_flags = -1;
545 static int hf_fc_to_ds = -1;
546 static int hf_fc_from_ds = -1;
547 static int hf_fc_data_ds = -1;
548
549 static int hf_fc_more_frag = -1;
550 static int hf_fc_retry = -1;
551 static int hf_fc_pwr_mgt = -1;
552 static int hf_fc_more_data = -1;
553 static int hf_fc_protected = -1;
554 static int hf_fc_order = -1;
555
556
557 /* ************************************************************************* */
558 /*                   Header values for Duration/ID field                     */
559 /* ************************************************************************* */
560 static int hf_did_duration = -1;
561 static int hf_assoc_id = -1;
562
563
564 /* ************************************************************************* */
565 /*         Header values for different address-fields (all 4 of them)        */
566 /* ************************************************************************* */
567 static int hf_addr_da = -1;     /* Destination address subfield */
568 static int hf_addr_sa = -1;     /* Source address subfield */
569 static int hf_addr_ra = -1;     /* Receiver address subfield */
570 static int hf_addr_ta = -1;     /* Transmitter address subfield */
571 static int hf_addr_bssid = -1;  /* address is bssid */
572
573 static int hf_addr = -1;        /* Source or destination address subfield */
574
575
576 /* ************************************************************************* */
577 /*                Header values for QoS control field                        */
578 /* ************************************************************************* */
579 static int hf_qos_priority = -1;
580 static int hf_qos_ack_policy = -1;
581 static int hf_qos_eosp = -1;
582 static int hf_qos_field_content = -1;
583 /*static int hf_qos_txop_limit = -1;*/
584 /*      FIXME: hf_ values not defined
585 static int hf_qos_buf_state = -1;
586 static int hf_qos_buf_ac = -1;
587 static int hf_qos_buf_load = -1;
588 */
589 /*static int hf_qos_txop_dur_req = -1;
590 static int hf_qos_queue_size = -1;*/
591
592 /* ************************************************************************* */
593 /*                Header values for sequence number field                    */
594 /* ************************************************************************* */
595 static int hf_frag_number = -1;
596 static int hf_seq_number = -1;
597
598 /* ************************************************************************* */
599 /*                   Header values for Frame Check field                     */
600 /* ************************************************************************* */
601 static int hf_fcs = -1;
602 static int hf_fcs_good = -1;
603 static int hf_fcs_bad = -1;
604
605 /* ************************************************************************* */
606 /*                   Header values for reassembly                            */
607 /* ************************************************************************* */
608 static int hf_fragments = -1;
609 static int hf_fragment = -1;
610 static int hf_fragment_overlap = -1;
611 static int hf_fragment_overlap_conflict = -1;
612 static int hf_fragment_multiple_tails = -1;
613 static int hf_fragment_too_long_fragment = -1;
614 static int hf_fragment_error = -1;
615 static int hf_reassembled_in = -1;
616
617
618 static int proto_wlan_mgt = -1;
619 /* ************************************************************************* */
620 /*                      Fixed fields found in mgt frames                     */
621 /* ************************************************************************* */
622 static int ff_auth_alg = -1;    /* Authentication algorithm field            */
623 static int ff_auth_seq = -1;    /* Authentication transaction sequence       */
624 static int ff_current_ap = -1;  /* Current AP MAC address                    */
625 static int ff_listen_ival = -1; /* Listen interval fixed field               */
626 static int ff_timestamp = -1;   /* 64 bit timestamp                          */
627 static int ff_beacon_interval = -1;     /* 16 bit Beacon interval            */
628 static int ff_assoc_id = -1;    /* 16 bit AID field                          */
629 static int ff_reason = -1;      /* 16 bit reason code                        */
630 static int ff_status_code = -1; /* Status code                               */
631 static int ff_category_code = -1;       /* 8 bit Category code */
632 static int ff_action_code = -1;         /* 8 bit Action code */
633 static int ff_dialog_token = -1;        /* 8 bit Dialog token */
634 static int ff_wme_action_code = -1;     /* Management notification action code */
635 static int ff_wme_status_code = -1;     /* Management notification setup response status code */
636 static int ff_qos_action_code = -1;
637 static int ff_dls_action_code = -1;
638 static int ff_dst_mac_addr = -1;        /* DLS destination MAC addressi */
639 static int ff_src_mac_addr = -1;        /* DLS source MAC addressi */
640 static int ff_dls_timeout = -1;         /* DLS timeout value */
641
642 /* ************************************************************************* */
643 /*            Flags found in the capability field (fixed field)              */
644 /* ************************************************************************* */
645 static int ff_capture = -1;
646 static int ff_cf_ess = -1;
647 static int ff_cf_ibss = -1;
648 static int ff_cf_sta_poll = -1; /* CF pollable status for a STA            */
649 static int ff_cf_ap_poll = -1;  /* CF pollable status for an AP            */
650 static int ff_cf_privacy = -1;
651 static int ff_cf_preamble = -1;
652 static int ff_cf_pbcc = -1;
653 static int ff_cf_agility = -1;
654 static int ff_short_slot_time = -1;
655 static int ff_dsss_ofdm = -1;
656 static int ff_cf_spec_man = -1;
657 static int ff_cf_apsd = -1;
658 static int ff_cf_del_blk_ack = -1;
659 static int ff_cf_imm_blk_ack = -1;
660
661 /* ************************************************************************* */
662 /*                       Tagged value format fields                          */
663 /* ************************************************************************* */
664 static int tag_number = -1;
665 static int tag_length = -1;
666 static int tag_interpretation = -1;
667 static int tag_oui = -1;
668
669
670 static int tim_length = -1;
671 static int tim_dtim_count = -1;
672 static int tim_dtim_period = -1;
673 static int tim_bmapctl = -1;
674
675
676 static int hf_fixed_parameters = -1;    /* Protocol payload for management frames */
677 static int hf_tagged_parameters = -1;   /* Fixed payload item */
678 static int hf_wep_iv = -1;
679 static int hf_wep_iv_weak = -1;
680 static int hf_tkip_extiv = -1;
681 static int hf_ccmp_extiv = -1;
682 static int hf_wep_key = -1;
683 static int hf_wep_icv = -1;
684
685 static int ht_cap = -1;
686 static int ht_adv_coding = -1;
687 static int ht_chan_width = -1;
688 static int ht_mimo_pwsave = -1;
689 static int ht_green = -1;
690 static int ht_short20 = -1;
691 static int ht_short40 = -1;
692 static int ht_tx_stbc = -1;
693 static int ht_rx_stbc = -1;
694 static int ht_block_ack = -1;
695 static int ht_max_amsdu = -1;
696 static int ht_dsss_cck_40 = -1;
697 static int ht_psmp = -1;
698 static int ht_stbc = -1;
699 static int ht_l_sig = -1;
700
701 static int macparm = -1;
702 static int macparm_mpdu = -1;
703 static int macparm_mpdu_density = -1;
704
705 static int htex_cap = -1;
706 static int htex_pco = -1;
707 static int htex_transtime = -1;
708 static int htex_mcs = -1;
709
710 static int txbf = -1;
711 static int txbf_cap = -1;
712 static int txbf_rcv_ssc = -1;
713 static int txbf_tx_ssc = -1;
714 static int txbf_rcv_zlf = -1;
715 static int txbf_tx_zlf = -1;
716 static int txbf_impl_txbf = -1;
717 static int txbf_calib = -1;
718 static int txbf_expl_csi = -1;
719 static int txbf_expl_uncomp_sm = -1;
720 static int txbf_expl_bf_csi = -1;
721 static int txbf_expl_uncomp_sm_feed = -1;
722 static int txbf_expl_comp_sm_feed = -1;
723 static int txbf_csi_num_bf_ant = -1;
724 static int txbf_uncomp_sm_bf_ant = -1;
725 static int txbf_comp_sm_bf_ant = -1;
726
727 /* 802.11n 7.3.2.48 */
728 static int hta_control_channel = -1;
729 static int hta_cap = -1;
730 static int hta_ext_chan_offset = -1;
731 static int hta_rec_tx_width = -1;
732 static int hta_rifs_mode = -1;
733 static int hta_controlled_access = -1;
734 static int hta_service_interval = -1;
735 static int hta_operating_mode = -1;
736 static int hta_non_gf_devices = -1;
737 static int hta_basic_stbc_mcs = -1;
738 static int hta_dual_stbc_protection = -1;
739 static int hta_secondary_beacon = -1;
740 static int hta_lsig_txop_protection = -1;
741 static int hta_pco_active = -1;
742 static int hta_pco_phase = -1;
743
744
745 static int antsel = -1;
746 static int antsel_b0 = -1;
747 static int antsel_b1 = -1;
748 static int antsel_b2 = -1;
749 static int antsel_b3 = -1;
750 static int antsel_b4 = -1;
751 static int antsel_b5 = -1;
752 static int antsel_b6 = -1;
753
754 static int rsn_cap = -1;
755 static int rsn_cap_preauth = -1;
756 static int rsn_cap_no_pairwise = -1;
757 static int rsn_cap_ptksa_replay_counter = -1;
758 static int rsn_cap_gtksa_replay_counter = -1;
759
760 static int hf_aironet_ie_type = -1;
761 static int hf_aironet_ie_version = -1;
762 static int hf_aironet_ie_data = -1;
763 static int hf_aironet_ie_qos_unk1 = -1;
764 static int hf_aironet_ie_qos_paramset = -1;
765 static int hf_aironet_ie_qos_val = -1;
766
767 /*QBSS - Version 1,2,802.11e*/
768
769 static int hf_qbss2_cal = -1;
770 static int hf_qbss2_gl = -1;
771 static int hf_qbss_cu = -1;
772 static int hf_qbss2_cu = -1;
773 static int hf_qbss_scount = -1;
774 static int hf_qbss2_scount = -1;
775 static int hf_qbss_version = -1;
776 static int hf_qbss_adc = -1;
777
778 static int hf_ts_info = -1;
779 static int hf_tsinfo_type = -1;
780 static int hf_tsinfo_tsid = -1;
781 static int hf_tsinfo_dir = -1;
782 static int hf_tsinfo_access = -1;
783 static int hf_tsinfo_agg = -1;
784 static int hf_tsinfo_apsd = -1;
785 static int hf_tsinfo_up = -1;
786 static int hf_tsinfo_ack = -1;
787 static int hf_tsinfo_sched = -1;
788 static int tspec_nor_msdu = -1;
789 static int tspec_max_msdu = -1;
790 static int tspec_min_srv = -1;
791 static int tspec_max_srv = -1;
792 static int tspec_inact_int = -1;
793 static int tspec_susp_int = -1;
794 static int tspec_srv_start = -1;
795 static int tspec_min_data = -1;
796 static int tspec_mean_data = -1;
797 static int tspec_peak_data = -1;
798 static int tspec_burst_size = -1;
799 static int tspec_delay_bound = -1;
800 static int tspec_min_phy = -1;
801 static int tspec_surplus = -1;
802 static int tspec_medium = -1;
803 static int ts_delay = -1;
804 static int hf_class_type = -1;
805 static int hf_class_mask = -1;
806 static int hf_ether_type = -1;
807 static int hf_tclas_process = -1;
808 static int hf_sched_info = -1;
809 static int hf_sched_srv_start = -1;
810 static int hf_sched_srv_int = -1;
811 static int hf_sched_spec_int = -1;
812 static int cf_version = -1;
813 static int cf_ipv4_src = -1;
814 static int cf_ipv4_dst = -1;
815 static int cf_src_port = -1;
816 static int cf_dst_port = -1;
817 static int cf_dscp = -1;
818 static int cf_protocol = -1;
819 static int cf_ipv6_src = -1;
820 static int cf_ipv6_dst = -1;
821 static int cf_flow = -1;
822 static int cf_tag_type = -1;
823
824 /* ************************************************************************* */
825 /*                               Protocol trees                              */
826 /* ************************************************************************* */
827 static gint ett_80211 = -1;
828 static gint ett_proto_flags = -1;
829 static gint ett_cap_tree = -1;
830 static gint ett_fc_tree = -1;
831 static gint ett_fragments = -1;
832 static gint ett_fragment = -1;
833
834 static gint ett_80211_mgt = -1;
835 static gint ett_fixed_parameters = -1;
836 static gint ett_tagged_parameters = -1;
837 static gint ett_qos_parameters = -1;
838 static gint ett_qos_ps_buf_state = -1;
839 static gint ett_wep_parameters = -1;
840
841 static gint ett_rsn_cap_tree = -1;
842
843 static gint ett_ht_cap_tree = -1;
844 static gint ett_macparm_tree = -1;
845 static gint ett_htex_cap_tree = -1;
846 static gint ett_txbf_tree = -1;
847 static gint ett_antsel_tree = -1;
848 static gint ett_hta_cap_tree = -1;
849 static gint ett_hta_cap1_tree = -1;
850 static gint ett_hta_cap2_tree = -1;
851
852 static gint ett_80211_mgt_ie = -1;
853 static gint ett_tsinfo_tree = -1;
854 static gint ett_sched_tree = -1;
855
856 static gint ett_fcs = -1;
857
858 static const fragment_items frag_items = {
859         &ett_fragment,
860         &ett_fragments,
861         &hf_fragments,
862         &hf_fragment,
863         &hf_fragment_overlap,
864         &hf_fragment_overlap_conflict,
865         &hf_fragment_multiple_tails,
866         &hf_fragment_too_long_fragment,
867         &hf_fragment_error,
868         &hf_reassembled_in,
869         "fragments"
870 };
871
872 static dissector_handle_t llc_handle;
873 static dissector_handle_t ipx_handle;
874 static dissector_handle_t eth_withoutfcs_handle;
875 static dissector_handle_t data_handle;
876
877 static int wlan_tap = -1;
878
879 /*     Davide Schiera (2006-11-22): including AirPDcap project                */
880 #ifdef HAVE_AIRPDCAP
881 #include <epan/crypt/airpdcap_ws.h>
882 AIRPDCAP_CONTEXT airpdcap_ctx;
883 #else
884 int airpdcap_ctx;
885 #endif
886 /* Davide Schiera (2006-11-22) ---------------------------------------------- */
887
888
889 /* ************************************************************************* */
890 /*            Return the length of the current header (in bytes)             */
891 /* ************************************************************************* */
892 static int
893 find_header_length (guint16 fcf)
894 {
895   int len;
896
897   switch (FCF_FRAME_TYPE (fcf)) {
898
899   case MGT_FRAME:
900     return MGT_FRAME_HDR_LEN;
901
902   case CONTROL_FRAME:
903     switch (COMPOSE_FRAME_TYPE (fcf)) {
904
905     case CTRL_CTS:
906     case CTRL_ACKNOWLEDGEMENT:
907       return 10;
908
909     case CTRL_RTS:
910     case CTRL_PS_POLL:
911     case CTRL_CFP_END:
912     case CTRL_CFP_ENDACK:
913     case CTRL_BLOCK_ACK_REQ:
914     case CTRL_BLOCK_ACK:
915       return 16;
916     }
917     return 4;   /* XXX */
918
919   case DATA_FRAME:
920     len = (FCF_ADDR_SELECTOR(fcf) == DATA_ADDR_T4) ? DATA_LONG_HDR_LEN :
921                                                       DATA_SHORT_HDR_LEN;
922     if (DATA_FRAME_IS_QOS(COMPOSE_FRAME_TYPE(fcf)))
923       return len + 2;
924     else
925       return len;
926
927   default:
928     return 4;   /* XXX */
929   }
930 }
931
932
933 /* ************************************************************************* */
934 /*          This is the capture function used to update packet counts        */
935 /* ************************************************************************* */
936 static void
937 capture_ieee80211_common (const guchar * pd, int offset, int len,
938                           packet_counts * ld, gboolean fixed_length_header,
939                           gboolean datapad)
940 {
941   guint16 fcf, hdr_length;
942
943   if (!BYTES_ARE_IN_FRAME(offset, len, 2)) {
944     ld->other++;
945     return;
946   }
947
948   fcf = pletohs (&pd[offset]);
949
950   if (IS_PROTECTED(FCF_FLAGS(fcf)))
951     {
952       ld->other++;
953       return;
954     }
955
956   switch (COMPOSE_FRAME_TYPE (fcf))
957     {
958
959     case DATA:                  /* We got a data frame */
960     case DATA_CF_ACK:           /* Data with ACK */
961     case DATA_CF_POLL:
962     case DATA_CF_ACK_POLL:
963     case DATA_QOS_DATA:
964       if (fixed_length_header)
965         hdr_length = DATA_LONG_HDR_LEN;
966       else
967         hdr_length = find_header_length (fcf);
968       if (datapad)
969         hdr_length = roundup2(hdr_length, 4);
970       /* I guess some bridges take Netware Ethernet_802_3 frames,
971          which are 802.3 frames (with a length field rather than
972          a type field, but with no 802.2 header in the payload),
973          and just stick the payload into an 802.11 frame.  I've seen
974          captures that show frames of that sort.
975
976          This means we have to do the same check for Netware 802.3 -
977          or, if you will, "Netware 802.11" - that we do in the
978          Ethernet dissector, i.e. checking for 0xffff as the first
979          four bytes of the payload and, if we find it, treating it
980          as an IPX frame. */
981       if (!BYTES_ARE_IN_FRAME(offset+hdr_length, len, 2)) {
982         ld->other++;
983         return;
984       }
985       if (pd[offset+hdr_length] == 0xff && pd[offset+hdr_length+1] == 0xff) {
986         capture_ipx (ld);
987       }
988       else {
989         capture_llc (pd, offset + hdr_length, len, ld);
990       }
991       break;
992
993     default:
994       ld->other++;
995       break;
996     }
997 }
998
999 /*
1000  * Handle 802.11 with a variable-length link-layer header.
1001  */
1002 void
1003 capture_ieee80211 (const guchar * pd, int offset, int len, packet_counts * ld)
1004 {
1005   capture_ieee80211_common (pd, offset, len, ld, FALSE, FALSE);
1006 }
1007
1008 /*
1009  * Handle 802.11 with a variable-length link-layer header and data padding.
1010  */
1011 void
1012 capture_ieee80211_datapad (const guchar * pd, int offset, int len,
1013                            packet_counts * ld)
1014 {
1015   capture_ieee80211_common (pd, offset, len, ld, FALSE, TRUE);
1016 }
1017
1018 /*
1019  * Handle 802.11 with a fixed-length link-layer header (padded to the
1020  * maximum length).
1021  */
1022 void
1023 capture_ieee80211_fixed (const guchar * pd, int offset, int len, packet_counts * ld)
1024 {
1025   capture_ieee80211_common (pd, offset, len, ld, TRUE, FALSE);
1026 }
1027
1028
1029 /* ************************************************************************* */
1030 /*          Add the subtree used to store the fixed parameters               */
1031 /* ************************************************************************* */
1032 static proto_tree *
1033 get_fixed_parameter_tree (proto_tree * tree, tvbuff_t *tvb, int start, int size)
1034 {
1035   proto_item *fixed_fields;
1036   fixed_fields =
1037     proto_tree_add_uint_format (tree, hf_fixed_parameters, tvb, start,
1038                                 size, size, "Fixed parameters (%d bytes)",
1039                                 size);
1040
1041   return proto_item_add_subtree (fixed_fields, ett_fixed_parameters);
1042 }
1043
1044
1045 /* ************************************************************************* */
1046 /*            Add the subtree used to store tagged parameters                */
1047 /* ************************************************************************* */
1048 static proto_tree *
1049 get_tagged_parameter_tree (proto_tree * tree, tvbuff_t *tvb, int start, int size)
1050 {
1051   proto_item *tagged_fields;
1052
1053   tagged_fields = proto_tree_add_uint_format (tree, hf_tagged_parameters,
1054                                               tvb,
1055                                               start,
1056                                               size,
1057                                               size,
1058                                               "Tagged parameters (%d bytes)",
1059                                               size);
1060
1061   return proto_item_add_subtree (tagged_fields, ett_tagged_parameters);
1062 }
1063
1064
1065 /* ************************************************************************* */
1066 /*              Dissect and add fixed mgmt fields to protocol tree           */
1067 /* ************************************************************************* */
1068 static void
1069 add_fixed_field (proto_tree * tree, tvbuff_t * tvb, int offset, int lfcode)
1070 {
1071   const guint8 *dataptr;
1072   char out_buff[SHORT_STR];
1073   guint16 capability;
1074   proto_item *cap_item;
1075   static proto_tree *cap_tree;
1076   double temp_double;
1077
1078   switch (lfcode)
1079     {
1080     case FIELD_TIMESTAMP:
1081       dataptr = tvb_get_ptr (tvb, offset, 8);
1082       memset (out_buff, 0, SHORT_STR);
1083       g_snprintf (out_buff, SHORT_STR, "0x%02X%02X%02X%02X%02X%02X%02X%02X",
1084                 dataptr[7],
1085                 dataptr[6],
1086                 dataptr[5],
1087                 dataptr[4],
1088                 dataptr[3],
1089                 dataptr[2],
1090                 dataptr[1],
1091                 dataptr[0]);
1092
1093       proto_tree_add_string (tree, ff_timestamp, tvb, offset, 8, out_buff);
1094       break;
1095
1096     case FIELD_BEACON_INTERVAL:
1097       capability = tvb_get_letohs (tvb, offset);
1098       temp_double = (double)capability;
1099       temp_double = temp_double * 1024 / 1000000;
1100       proto_tree_add_double_format (tree, ff_beacon_interval, tvb, offset, 2,
1101                                     temp_double,"Beacon Interval: %f [Seconds]",
1102                                     temp_double);
1103       if (check_col (g_pinfo->cinfo, COL_INFO)) {
1104           col_append_fstr(g_pinfo->cinfo, COL_INFO, ",BI=%d", capability);
1105       }
1106       break;
1107
1108
1109     case FIELD_CAP_INFO:
1110       capability = tvb_get_letohs (tvb, offset);
1111
1112       cap_item = proto_tree_add_uint_format (tree, ff_capture,
1113                                              tvb, offset, 2,
1114                                              capability,
1115                                              "Capability Information: 0x%04X",
1116                                              capability);
1117       cap_tree = proto_item_add_subtree (cap_item, ett_cap_tree);
1118       proto_tree_add_boolean (cap_tree, ff_cf_ess, tvb, offset, 2,
1119                               capability);
1120       proto_tree_add_boolean (cap_tree, ff_cf_ibss, tvb, offset, 2,
1121                               capability);
1122       if (ESS_SET (capability) != 0)    /* This is an AP */
1123         proto_tree_add_uint (cap_tree, ff_cf_ap_poll, tvb, offset, 2,
1124                              capability);
1125
1126       else                      /* This is a STA */
1127         proto_tree_add_uint (cap_tree, ff_cf_sta_poll, tvb, offset, 2,
1128                              capability);
1129       proto_tree_add_boolean (cap_tree, ff_cf_privacy, tvb, offset, 2,
1130                               capability);
1131       proto_tree_add_boolean (cap_tree, ff_cf_preamble, tvb, offset, 2,
1132                               capability);
1133       proto_tree_add_boolean (cap_tree, ff_cf_pbcc, tvb, offset, 2,
1134                               capability);
1135       proto_tree_add_boolean (cap_tree, ff_cf_agility, tvb, offset, 2,
1136                               capability);
1137       proto_tree_add_boolean (cap_tree, ff_cf_spec_man, tvb, offset, 2,
1138                               capability);
1139       proto_tree_add_boolean (cap_tree, ff_short_slot_time, tvb, offset, 2,
1140                               capability);
1141       proto_tree_add_boolean (cap_tree, ff_cf_apsd, tvb, offset, 2,
1142                               capability);
1143       proto_tree_add_boolean (cap_tree, ff_dsss_ofdm, tvb, offset, 2,
1144                               capability);
1145       proto_tree_add_boolean (cap_tree, ff_cf_del_blk_ack, tvb, offset, 2,
1146                               capability);
1147       proto_tree_add_boolean (cap_tree, ff_cf_imm_blk_ack, tvb, offset, 2,
1148                               capability);
1149       break;
1150
1151     case FIELD_AUTH_ALG:
1152       proto_tree_add_item (tree, ff_auth_alg, tvb, offset, 2, TRUE);
1153       break;
1154
1155     case FIELD_AUTH_TRANS_SEQ:
1156       proto_tree_add_item (tree, ff_auth_seq, tvb, offset, 2, TRUE);
1157       break;
1158
1159     case FIELD_CURRENT_AP_ADDR:
1160       proto_tree_add_item (tree, ff_current_ap, tvb, offset, 6, FALSE);
1161       break;
1162
1163     case FIELD_LISTEN_IVAL:
1164       proto_tree_add_item (tree, ff_listen_ival, tvb, offset, 2, TRUE);
1165       break;
1166
1167     case FIELD_REASON_CODE:
1168       proto_tree_add_item (tree, ff_reason, tvb, offset, 2, TRUE);
1169       break;
1170
1171     case FIELD_ASSOC_ID:
1172       proto_tree_add_uint(tree, ff_assoc_id, tvb, offset, 2,
1173                           ASSOC_ID(tvb_get_letohs(tvb,offset)));
1174       /* proto_tree_add_item (tree, ff_assoc_id, tvb, offset, 2, TRUE); */
1175       break;
1176
1177     case FIELD_STATUS_CODE:
1178       proto_tree_add_item (tree, ff_status_code, tvb, offset, 2, TRUE);
1179       break;
1180
1181     case FIELD_CATEGORY_CODE:
1182       proto_tree_add_item (tree, ff_category_code, tvb, offset, 1, TRUE);
1183       break;
1184
1185     case FIELD_ACTION_CODE:
1186       proto_tree_add_item (tree, ff_action_code, tvb, offset, 1, TRUE);
1187       break;
1188
1189     case FIELD_DIALOG_TOKEN:
1190       proto_tree_add_item (tree, ff_dialog_token, tvb, offset, 1, TRUE);
1191       break;
1192
1193     case FIELD_WME_ACTION_CODE:
1194       proto_tree_add_item (tree, ff_wme_action_code, tvb, offset, 1, TRUE);
1195       break;
1196
1197     case FIELD_WME_STATUS_CODE:
1198       proto_tree_add_item (tree, ff_wme_status_code, tvb, offset, 1, TRUE);
1199       break;
1200
1201     case FIELD_QOS_ACTION_CODE:
1202       proto_tree_add_item (tree, ff_qos_action_code, tvb, offset, 1, TRUE);
1203       break;
1204
1205     case FIELD_QOS_TS_INFO:
1206       {
1207         proto_item *tsinfo_item;
1208         proto_tree *tsinfo_tree;
1209         guint32 tsi;
1210
1211         tsinfo_item = proto_tree_add_item(tree, hf_ts_info, tvb,
1212                                           offset, 3, TRUE);
1213         tsinfo_tree = proto_item_add_subtree(tsinfo_item, ett_tsinfo_tree);
1214         tsi = tvb_get_letoh24(tvb, offset);
1215         proto_tree_add_uint(tsinfo_tree, hf_tsinfo_type, tvb,
1216                             offset, 3, TSI_TYPE (tsi));
1217         if (TSI_TSID (tsi) < 8)
1218         {
1219           proto_tree_add_text(tsinfo_tree, tvb, offset, 3,
1220                               "TSID: %u (< 8 is invalid)", TSI_TSID (tsi));
1221         }
1222         else
1223         {
1224           proto_tree_add_uint(tsinfo_tree, hf_tsinfo_tsid, tvb,
1225                               offset, 3, TSI_TSID (tsi));
1226         }
1227         proto_tree_add_uint(tsinfo_tree, hf_tsinfo_dir, tvb,
1228                             offset, 3, TSI_DIR (tsi));
1229         proto_tree_add_uint(tsinfo_tree, hf_tsinfo_access, tvb,
1230                             offset, 3, TSI_ACCESS (tsi));
1231         proto_tree_add_uint(tsinfo_tree, hf_tsinfo_agg, tvb,
1232                             offset, 3, TSI_AGG (tsi));
1233         proto_tree_add_uint(tsinfo_tree, hf_tsinfo_apsd, tvb,
1234                             offset, 3, TSI_APSD (tsi));
1235         proto_tree_add_uint(tsinfo_tree, hf_tsinfo_up, tvb,
1236                             offset, 3, TSI_UP (tsi));
1237         proto_tree_add_uint(tsinfo_tree, hf_tsinfo_ack, tvb,
1238                             offset, 3, TSI_ACK (tsi));
1239         proto_tree_add_uint(tsinfo_tree, hf_tsinfo_sched, tvb,
1240                             offset, 3, TSI_SCHED (tsi));
1241       }
1242       break;
1243
1244     case FIELD_DLS_ACTION_CODE:
1245       proto_tree_add_item (tree, ff_dls_action_code, tvb, offset, 1, TRUE);
1246       break;
1247
1248     case FIELD_DST_MAC_ADDR:
1249       proto_tree_add_item (tree, ff_dst_mac_addr, tvb, offset, 6, TRUE);
1250       break;
1251
1252     case FIELD_SRC_MAC_ADDR:
1253       proto_tree_add_item (tree, ff_src_mac_addr, tvb, offset, 6, TRUE);
1254       break;
1255
1256     case FIELD_DLS_TIMEOUT:
1257       proto_tree_add_item (tree, ff_dls_timeout, tvb, offset, 2, TRUE);
1258       break;
1259
1260     case FIELD_SCHEDULE_INFO:
1261       {
1262         proto_item *sched_item;
1263         proto_tree *sched_tree;
1264         guint16 sched;
1265
1266         sched_item = proto_tree_add_item(tree, hf_sched_info,
1267                                          tvb, offset, 2, TRUE);
1268         sched_tree = proto_item_add_subtree(sched_item, ett_sched_tree);
1269         sched = tvb_get_letohs(tvb, offset);
1270         proto_tree_add_uint(sched_tree, hf_tsinfo_agg, tvb, offset,
1271                             2, sched & 0x0001);
1272         if (sched & 0x0001)
1273         {
1274           proto_tree_add_uint(sched_tree, hf_tsinfo_tsid, tvb, offset,
1275                               2, (sched & 0x001E) >> 1);
1276           proto_tree_add_uint(sched_tree, hf_tsinfo_dir, tvb, offset,
1277                               2, (sched & 0x0060) >> 5);
1278         }
1279       }
1280     break;
1281     }
1282 }
1283
1284 static const value_string wpa_cipher_vals[] =
1285 {
1286         {0, "NONE"},
1287         {1, "WEP (40-bit)"},
1288         {2, "TKIP"},
1289         {3, "AES (OCB)"},
1290         {4, "AES (CCM)"},
1291         {5, "WEP (104-bit)"},
1292         {0, NULL}
1293 };
1294
1295 static const value_string wpa_keymgmt_vals[] =
1296 {
1297         {0, "NONE"},
1298         {1, "WPA"},
1299         {2, "PSK"},
1300         {0, NULL}
1301 };
1302
1303 static void
1304 dissect_vendor_ie_wpawme(proto_tree * ietree, proto_tree * tree, tvbuff_t * tag_tvb)
1305 {
1306       gint tag_off = 0;
1307       gint tag_len = tvb_length_remaining(tag_tvb, 0);
1308       gchar out_buff[SHORT_STR];
1309       guint i, byte1, byte2;
1310
1311       /* Wi-Fi Protected Access (WPA) Information Element */
1312       if (tag_off + 6 <= tag_len && !tvb_memeql(tag_tvb, tag_off, WPA_OUI"\x01", 4)) {
1313         g_snprintf(out_buff, SHORT_STR, "WPA IE, type %u, version %u",
1314                 tvb_get_guint8(tag_tvb, tag_off + 3), tvb_get_letohs(tag_tvb, tag_off + 4));
1315         proto_tree_add_string(tree, tag_interpretation, tag_tvb, tag_off, 6, out_buff);
1316         tag_off += 6;
1317         if (tag_off + 4 <= tag_len) {
1318           /* multicast cipher suite */
1319           if (!tvb_memeql(tag_tvb, tag_off, WPA_OUI, 3)) {
1320             g_snprintf(out_buff, SHORT_STR, "Multicast cipher suite: %s",
1321                     val_to_str(tvb_get_guint8(tag_tvb, tag_off + 3), wpa_cipher_vals,
1322                             "UNKNOWN"));
1323             proto_tree_add_string(tree, tag_interpretation, tag_tvb, tag_off, 4,
1324                     out_buff);
1325             tag_off += 4;
1326             /* unicast cipher suites */
1327             if (tag_off + 2 <= tag_len) {
1328               g_snprintf(out_buff, SHORT_STR,
1329                       "# of unicast cipher suites: %u", tvb_get_letohs(tag_tvb, tag_off));
1330               proto_tree_add_string(tree, tag_interpretation, tag_tvb, tag_off, 2,
1331                       out_buff);
1332               tag_off += 2;
1333               i = 1;
1334               while (tag_off + 4 <= tag_len) {
1335                 if (!tvb_memeql(tag_tvb, tag_off, WPA_OUI, 3)) {
1336                   g_snprintf(out_buff, SHORT_STR,
1337                            "Unicast cipher suite %u: %s", i,
1338                            val_to_str(tvb_get_guint8(tag_tvb, tag_off + 3),
1339                                    wpa_cipher_vals, "UNKNOWN"));
1340                   proto_tree_add_string(tree, tag_interpretation, tag_tvb, tag_off, 4,
1341                           out_buff);
1342                   tag_off += 4;
1343                   i ++;
1344                 }
1345                 else
1346                   break;
1347               }
1348               /* authenticated key management suites */
1349               if (tag_off + 2 <= tag_len) {
1350                 g_snprintf(out_buff, SHORT_STR,
1351                         "# of auth key management suites: %u", tvb_get_letohs(tag_tvb, tag_off));
1352                 proto_tree_add_string(tree, tag_interpretation, tag_tvb, tag_off, 2,
1353                         out_buff);
1354                 tag_off += 2;
1355                 i = 1;
1356                 while (tag_off + 4 <= tag_len) {
1357                   if (!tvb_memeql(tag_tvb, tag_off, WPA_OUI, 3)) {
1358                     g_snprintf(out_buff, SHORT_STR,
1359                             "auth key management suite %u: %s", i,
1360                             val_to_str(tvb_get_guint8(tag_tvb, tag_off + 3),
1361                                     wpa_keymgmt_vals, "UNKNOWN"));
1362                     proto_tree_add_string(tree, tag_interpretation, tag_tvb, tag_off, 4,
1363                             out_buff);
1364                     tag_off += 4;
1365                     i ++;
1366                   }
1367                   else
1368                     break;
1369                 }
1370               }
1371             }
1372           }
1373         }
1374         if (tag_off < tag_len)
1375           proto_tree_add_string(tree, tag_interpretation, tag_tvb,
1376                                  tag_off, tag_len - tag_off, "Not interpreted");
1377         proto_item_append_text(ietree, ": WPA");
1378       } else if (tag_off + 7 <= tag_len && !tvb_memeql(tag_tvb, tag_off, WME_OUI"\x02\x00", 5)) {
1379       /* Wireless Multimedia Enhancements (WME) Information Element */
1380         g_snprintf(out_buff, SHORT_STR,
1381                 "WME IE: type %u, subtype %u, version %u, parameter set %u",
1382                 tvb_get_guint8(tag_tvb, tag_off+3), tvb_get_guint8(tag_tvb, tag_off+4),
1383                 tvb_get_guint8(tag_tvb, tag_off+5), tvb_get_guint8(tag_tvb, tag_off+6));
1384         proto_tree_add_string(tree, tag_interpretation, tag_tvb, tag_off, 7,
1385                 out_buff);
1386         proto_item_append_text(ietree, ": WME");
1387       } else if (tag_off + 24 <= tag_len && !tvb_memeql(tag_tvb, tag_off, WME_OUI"\x02\x01", 5)) {
1388       /* Wireless Multimedia Enhancements (WME) Parameter Element */
1389         g_snprintf(out_buff, SHORT_STR,
1390                 "WME PE: type %u, subtype %u, version %u, parameter set %u",
1391                 tvb_get_guint8(tag_tvb, tag_off+3), tvb_get_guint8(tag_tvb, tag_off+4),
1392                 tvb_get_guint8(tag_tvb, tag_off+5), tvb_get_guint8(tag_tvb, tag_off+6));
1393         proto_tree_add_string(tree, tag_interpretation, tag_tvb, tag_off, 7,
1394                 out_buff);
1395         tag_off += 8;
1396         for (i = 0; i < 4; i++) {
1397           byte1 = tvb_get_guint8(tag_tvb, tag_off);
1398           byte2 = tvb_get_guint8(tag_tvb, tag_off + 1);
1399           g_snprintf(out_buff, SHORT_STR,
1400                   "WME AC Parameters: ACI %u (%s), Admission Control %sMandatory, AIFSN %u, ECWmin %u, ECWmax %u, TXOP %u",
1401                    (byte1 & 0x60) >> 5, wme_acs[(byte1 & 0x60) >> 5],
1402                    (byte1 & 0x10) ? "" : "not ", byte1 & 0x0f,
1403                    byte2 & 0x0f, byte2 & 0xf0 >> 4,
1404                    tvb_get_letohs(tag_tvb, tag_off + 2));
1405           proto_tree_add_string(tree, tag_interpretation, tag_tvb, tag_off, 4,
1406                   out_buff);
1407           tag_off += 4;
1408         }
1409         proto_item_append_text(ietree, ": WME");
1410       } else if (tag_off + 56 <= tag_len && !tvb_memeql(tag_tvb, tag_off, WME_OUI"\x02\x02", 5)) {
1411       /* Wireless Multimedia Enhancements (WME) TSPEC Element */
1412         guint16 ts_info, msdu_size, surplus_bandwidth;
1413         const char *direction[] = { "Uplink", "Downlink", "Reserved", "Bi-directional" };
1414         const value_string fields[] = {
1415           {12, "Minimum Service Interval"},
1416           {16, "Maximum Service Interval"},
1417           {20, "Inactivity Interval"},
1418           {24, "Service Start Time"},
1419           {28, "Minimum Data Rate"},
1420           {32, "Mean Data Rate"},
1421           {36, "Maximum Burst Size"},
1422           {40, "Minimum PHY Rate"},
1423           {44, "Peak Data Rate"},
1424           {48, "Delay Bound"},
1425           {0, NULL}
1426         };
1427         const char *field;
1428
1429         g_snprintf(out_buff, SHORT_STR,
1430                 "WME TSPEC: type %u, subtype %u, version %u",
1431                 tvb_get_guint8(tag_tvb, tag_off+3), tvb_get_guint8(tag_tvb, tag_off+4),
1432                 tvb_get_guint8(tag_tvb, tag_off+5));
1433         proto_tree_add_string(tree, tag_interpretation, tag_tvb, tag_off, 6,
1434                 out_buff);
1435         tag_off += 6;
1436
1437         ts_info = tvb_get_letohs(tag_tvb, tag_off);
1438         byte1 = (ts_info >> 11) & 0x7;
1439         g_snprintf(out_buff, SHORT_STR,
1440                 "WME TS Info: Priority %u (%s) (%s), Contention-based access %sset, %s",
1441                  byte1, qos_tags[byte1], qos_acs[byte1],
1442                  (ts_info & 0x0080) ? "" : "not ",
1443                  direction[(ts_info >> 5) & 0x3]);
1444         proto_tree_add_string(tree, tag_interpretation, tag_tvb, tag_off, 2,
1445                 out_buff);
1446         tag_off += 2;
1447
1448         msdu_size = tvb_get_letohs(tag_tvb, tag_off);
1449         g_snprintf(out_buff, SHORT_STR,
1450                 "WME TSPEC: %s MSDU Size %u",
1451                 (msdu_size & 0x8000) ? "Fixed" : "Nominal", msdu_size & 0x7fff);
1452         proto_tree_add_string(tree, tag_interpretation, tag_tvb, tag_off, 2,
1453                 out_buff);
1454         tag_off += 2;
1455
1456         g_snprintf(out_buff, SHORT_STR,
1457                 "WME TSPEC: Maximum MSDU Size %u", tvb_get_letohs(tag_tvb, tag_off));
1458         proto_tree_add_string(tree, tag_interpretation, tag_tvb, tag_off, 2,
1459                 out_buff);
1460         tag_off += 2;
1461
1462         while ((field = val_to_str(tag_off, fields, "Unknown"))) {
1463           g_snprintf(out_buff, SHORT_STR,
1464                   "WME TSPEC: %s %u", field, tvb_get_letohl(tag_tvb, tag_off));
1465           proto_tree_add_string(tree, tag_interpretation, tag_tvb, tag_off, 4,
1466                   out_buff);
1467           tag_off += 4;
1468           if (tag_off == 52)
1469             break;
1470         }
1471
1472         surplus_bandwidth = tvb_get_letohs(tag_tvb, tag_off);
1473         g_snprintf(out_buff, SHORT_STR,
1474                 "WME TSPEC: Surplus Bandwidth Allowance Factor %u.%u",
1475                  (surplus_bandwidth >> 13) & 0x7, (surplus_bandwidth & 0x1fff));
1476         proto_tree_add_string(tree, tag_interpretation, tag_tvb, tag_off, 2,
1477                 out_buff);
1478         tag_off += 2;
1479
1480         g_snprintf(out_buff, SHORT_STR,
1481                 "WME TSPEC: Medium Time %u", tvb_get_letohs(tag_tvb, tag_off));
1482         proto_tree_add_string(tree, tag_interpretation, tag_tvb, tag_off, 2,
1483                 out_buff);
1484         tag_off += 2;
1485         proto_item_append_text(ietree, ": WME");
1486       }
1487 }
1488
1489 static void
1490 dissect_vendor_ie_rsn(proto_tree * ietree, proto_tree * tree, tvbuff_t * tag_tvb)
1491 {
1492         guint tag_off = 0;
1493         guint tag_len = tvb_length_remaining(tag_tvb, 0);
1494         guint pmkid_len = tag_len - 4;
1495         char out_buff[SHORT_STR], valid_str[SHORT_STR] = "";
1496
1497         if (tag_len >= 4 && !tvb_memeql(tag_tvb, tag_off, RSN_OUI"\x04", 4)) {
1498                 /* IEEE 802.11i / Key Data Encapsulation / Data Type=4 - PMKID.
1499                  * This is only used within EAPOL-Key frame Key Data. */
1500                 if (pmkid_len != PMKID_LEN) {
1501                         g_snprintf(valid_str, SHORT_STR,
1502                                 "(invalid PMKID len=%d, expected 16) ", pmkid_len);
1503                 }
1504                 g_snprintf(out_buff, SHORT_STR, "RSN PMKID: %s%s", valid_str,
1505                         tvb_bytes_to_str(tag_tvb, 4, pmkid_len));
1506                 proto_tree_add_string(tree, tag_interpretation, tag_tvb, 0,
1507                         tag_len, out_buff);
1508         }
1509         proto_item_append_text(ietree, ": RSN");
1510 }
1511
1512 typedef enum {
1513         AIRONET_IE_VERSION = 3,
1514         AIRONET_IE_QOS,
1515         AIRONET_IE_QBSS_V2 = 14
1516 } aironet_ie_type_t;
1517
1518 static const value_string aironet_ie_type_vals[] = {
1519         { AIRONET_IE_VERSION,   "CCX version"},
1520         { AIRONET_IE_QOS,       "Qos"},
1521         { AIRONET_IE_QBSS_V2,   "QBSS V2 - CCA"},
1522
1523         { 0,                    NULL }
1524 };
1525
1526 static void
1527 dissect_vendor_ie_aironet(proto_item * aironet_item, proto_tree * ietree,
1528         tvbuff_t * tvb, int offset, guint32 tag_len)
1529 {
1530         guint8  type;
1531         int i;
1532         gboolean dont_change = FALSE; /* Don't change the IE item text to default */
1533
1534         type = tvb_get_guint8(tvb, offset);
1535         proto_tree_add_item (ietree, hf_aironet_ie_type, tvb, offset, 1, TRUE);
1536         offset += 1;
1537
1538         switch (type) {
1539         case AIRONET_IE_VERSION:
1540                 proto_tree_add_item (ietree, hf_aironet_ie_version, tvb, offset, 1, TRUE);
1541                 proto_item_append_text(aironet_item, ": Aironet CCX version = %d",
1542                         tvb_get_guint8(tvb, offset));
1543                 dont_change = TRUE;
1544                 break;
1545         case AIRONET_IE_QOS:
1546                 proto_tree_add_item (ietree, hf_aironet_ie_qos_unk1, tvb, offset, 1, TRUE);
1547                 offset += 1;
1548                 proto_tree_add_item (ietree, hf_aironet_ie_qos_paramset, tvb, offset, 1, TRUE);
1549                 offset += 1;
1550
1551                 /* XXX: just copied over from WME. Maybe "Best Effort" and "Background"
1552                  *      need to be swapped. Also, the "TXOP" may be TXOP - or not.
1553                  */
1554                 for (i = 0; i < 4; i++) {
1555                         guint8 byte1, byte2;
1556                         guint16 txop;
1557                         byte1 = tvb_get_guint8(tvb, offset);
1558                         byte2 = tvb_get_guint8(tvb, offset + 1);
1559                         txop = tvb_get_letohs(tvb, offset + 2);
1560                         proto_tree_add_bytes_format(ietree, hf_aironet_ie_qos_val, tvb, offset, 4,
1561                                 tvb_get_ptr(tvb, offset, 4),
1562                                 "CCX QoS Parameters??: ACI %u (%s), Admission Control %sMandatory, AIFSN %u, ECWmin %u, ECWmax %u, TXOP %u",
1563                                 (byte1 & 0x60) >> 5, wme_acs[(byte1 & 0x60) >> 5],
1564                                 (byte1 & 0x10) ? "" : "not ", byte1 & 0x0f,
1565                                 byte2 & 0x0f, (byte2 & 0xf0) >> 4,
1566                                 txop);
1567                         offset += 4;
1568                 }
1569                 break;
1570         case AIRONET_IE_QBSS_V2:
1571                 /* Extract Values */
1572                 proto_tree_add_item (ietree, hf_qbss2_scount, tvb, offset, 2, TRUE);
1573                 proto_tree_add_item (ietree, hf_qbss2_cu, tvb, offset + 2, 1, FALSE);
1574                 proto_tree_add_item (ietree, hf_qbss2_cal, tvb, offset + 3, 1, FALSE);
1575                 proto_tree_add_item (ietree, hf_qbss2_gl, tvb, offset + 4, 1, FALSE);
1576                 break;
1577         default:
1578                 proto_tree_add_item(ietree, hf_aironet_ie_data, tvb, offset,
1579                         tag_len - 1, FALSE);
1580                 break;
1581         }
1582         if (!dont_change) {
1583                 proto_item_append_text(aironet_item, ": Aironet %s",
1584                         val_to_str(type, aironet_ie_type_vals, "Unknown"));
1585         }
1586 }
1587
1588 static void
1589 dissect_rsn_ie(proto_tree * tree, tvbuff_t * tag_tvb)
1590 {
1591   guint tag_off = 0;
1592   guint tag_len = tvb_length_remaining(tag_tvb, 0);
1593   guint16 rsn_capab;
1594   char out_buff[SHORT_STR];
1595   int i, count;
1596   proto_item *cap_item;
1597   proto_tree *cap_tree;
1598
1599   if (tag_off + 2 > tag_len) {
1600     proto_tree_add_string(tree, tag_interpretation, tag_tvb, tag_off, tag_len,
1601                           "Not interpreted");
1602     return;
1603   }
1604
1605   g_snprintf(out_buff, SHORT_STR, "RSN IE, version %u",
1606            tvb_get_letohs(tag_tvb, tag_off));
1607   proto_tree_add_string(tree, tag_interpretation, tag_tvb, tag_off, 2, out_buff);
1608
1609   tag_off += 2;
1610
1611   if (tag_off + 4 > tag_len)
1612     goto done;
1613
1614   /* multicast cipher suite */
1615   if (!tvb_memeql(tag_tvb, tag_off, RSN_OUI, 3)) {
1616     g_snprintf(out_buff, SHORT_STR, "Multicast cipher suite: %s",
1617              val_to_str(tvb_get_guint8(tag_tvb, tag_off + 3),
1618                      wpa_cipher_vals, "UNKNOWN"));
1619     proto_tree_add_string(tree, tag_interpretation, tag_tvb, tag_off, 4, out_buff);
1620     tag_off += 4;
1621   }
1622
1623   if (tag_off + 2 > tag_len)
1624     goto done;
1625
1626   /* unicast cipher suites */
1627   count = tvb_get_letohs(tag_tvb, tag_off);
1628   g_snprintf(out_buff, SHORT_STR, "# of unicast cipher suites: %u", count);
1629   proto_tree_add_string(tree, tag_interpretation, tag_tvb, tag_off, 2, out_buff);
1630   tag_off += 2;
1631   i = 1;
1632   while (tag_off + 4 <= tag_len && i <= count) {
1633     if (tvb_memeql(tag_tvb, tag_off, RSN_OUI, 3) != 0)
1634       goto done;
1635     g_snprintf(out_buff, SHORT_STR, "Unicast cipher suite %u: %s",
1636              i, val_to_str(tvb_get_guint8(tag_tvb, tag_off + 3),
1637                      wpa_cipher_vals, "UNKNOWN"));
1638     proto_tree_add_string(tree, tag_interpretation, tag_tvb, tag_off, 4, out_buff);
1639     tag_off += 4;
1640     i++;
1641   }
1642
1643   if (i <= count || tag_off + 2 > tag_len)
1644     goto done;
1645
1646   /* authenticated key management suites */
1647   count = tvb_get_letohs(tag_tvb, tag_off);
1648   g_snprintf(out_buff, SHORT_STR, "# of auth key management suites: %u", count);
1649   proto_tree_add_string(tree, tag_interpretation, tag_tvb, tag_off, 2, out_buff);
1650   tag_off += 2;
1651   i = 1;
1652   while (tag_off + 4 <= tag_len && i <= count) {
1653     if (tvb_memeql(tag_tvb, tag_off, RSN_OUI, 3) != 0)
1654       goto done;
1655     g_snprintf(out_buff, SHORT_STR, "auth key management suite %u: %s",
1656              i, val_to_str(tvb_get_guint8(tag_tvb, tag_off + 3),
1657                      wpa_keymgmt_vals, "UNKNOWN"));
1658     proto_tree_add_string(tree, tag_interpretation, tag_tvb, tag_off, 4, out_buff);
1659     tag_off += 4;
1660     i++;
1661   }
1662
1663   if (i <= count || tag_off + 2 > tag_len)
1664     goto done;
1665
1666   rsn_capab = tvb_get_letohs(tag_tvb, tag_off);
1667   g_snprintf(out_buff, SHORT_STR, "RSN Capabilities 0x%04x", rsn_capab);
1668   cap_item = proto_tree_add_uint_format(tree, rsn_cap, tag_tvb,
1669                                         tag_off, 2, rsn_capab,
1670                                         "RSN Capabilities: 0x%04X", rsn_capab);
1671   cap_tree = proto_item_add_subtree(cap_item, ett_rsn_cap_tree);
1672   proto_tree_add_boolean(cap_tree, rsn_cap_preauth, tag_tvb, tag_off, 2,
1673                          rsn_capab);
1674   proto_tree_add_boolean(cap_tree, rsn_cap_no_pairwise, tag_tvb, tag_off, 2,
1675                          rsn_capab);
1676   proto_tree_add_uint(cap_tree, rsn_cap_ptksa_replay_counter, tag_tvb, tag_off, 2,
1677                       rsn_capab);
1678   proto_tree_add_uint(cap_tree, rsn_cap_gtksa_replay_counter, tag_tvb, tag_off, 2,
1679                       rsn_capab);
1680   tag_off += 2;
1681
1682   if (tag_off + 2 > tag_len)
1683     goto done;
1684
1685   count = tvb_get_letohs(tag_tvb, tag_off);
1686   g_snprintf(out_buff, SHORT_STR, "# of PMKIDs: %u", count);
1687   proto_tree_add_string(tree, tag_interpretation, tag_tvb, tag_off, 2, out_buff);
1688   tag_off += 2;
1689
1690   /* PMKID List (16 * n octets) */
1691   for (i = 0; i < count; i++) {
1692     if (tag_off + PMKID_LEN > tag_len)
1693       break;
1694     g_snprintf(out_buff, SHORT_STR, "PMKID %u: %s", i,
1695         tvb_bytes_to_str(tag_tvb, tag_off, PMKID_LEN));
1696     proto_tree_add_string(tree, tag_interpretation, tag_tvb, tag_off,
1697                           PMKID_LEN, out_buff);
1698     tag_off += PMKID_LEN;
1699   }
1700
1701 done:
1702   if (tag_off < tag_len)
1703     proto_tree_add_string(tree, tag_interpretation, tag_tvb, tag_off,
1704                           tag_len - tag_off, "Not interpreted");
1705 }
1706
1707
1708 static void
1709 dissect_ht_ie(proto_tree * tree, tvbuff_t * tvb, int offset,
1710                guint32 tag_len)
1711 {
1712   proto_item *cap_item;
1713   proto_tree *cap_tree;
1714   guint16 capability;
1715   guint32 txbfcap;
1716   guint32 tag_val_off = 0;
1717
1718   if (tag_val_off + 2 > tag_len) {
1719     proto_tree_add_string(tree, tag_interpretation, tvb, offset, tag_len,
1720                           "Not interpreted");
1721     return;
1722   }
1723
1724   if (tag_len < 26) {
1725     proto_tree_add_string(tree, tag_interpretation, tvb, offset, tag_len,
1726               "HT Capabilities IE content length must be at least 26");
1727     return;
1728   }
1729
1730   /* 2 byte HT capabilities */
1731   capability = tvb_get_letohs (tvb, offset);
1732   cap_item = proto_tree_add_uint_format(tree, ht_cap, tvb,
1733                     offset, 2, capability,
1734                     "HT Capabilities: 0x%04X", capability);
1735   cap_tree = proto_item_add_subtree(cap_item, ett_ht_cap_tree);
1736   proto_tree_add_boolean(cap_tree, ht_adv_coding, tvb, offset, 2,
1737              capability);
1738   proto_tree_add_boolean(cap_tree, ht_chan_width, tvb, offset, 2,
1739              capability);
1740   proto_tree_add_uint(cap_tree, ht_mimo_pwsave, tvb, offset, 2,
1741              capability);
1742   proto_tree_add_boolean(cap_tree, ht_green, tvb, offset, 2,
1743              capability);
1744   proto_tree_add_boolean(cap_tree, ht_short20, tvb, offset, 2,
1745              capability);
1746   proto_tree_add_boolean(cap_tree, ht_short40, tvb, offset, 2,
1747              capability);
1748   proto_tree_add_boolean(cap_tree, ht_tx_stbc, tvb, offset, 2,
1749              capability);
1750   proto_tree_add_uint(cap_tree, ht_rx_stbc, tvb, offset, 2,
1751              capability);
1752   proto_tree_add_boolean(cap_tree, ht_block_ack, tvb, offset, 2,
1753              capability);
1754   proto_tree_add_boolean(cap_tree, ht_max_amsdu, tvb, offset, 2,
1755              capability);
1756   proto_tree_add_boolean(cap_tree, ht_dsss_cck_40, tvb, offset, 2,
1757              capability);
1758   proto_tree_add_boolean(cap_tree, ht_psmp, tvb, offset, 2,
1759              capability);
1760   proto_tree_add_boolean(cap_tree, ht_stbc, tvb, offset, 2,
1761              capability);
1762   proto_tree_add_boolean(cap_tree, ht_l_sig, tvb, offset, 2,
1763              capability);
1764
1765   offset += 2;
1766   tag_val_off += 2;
1767
1768   /* 1 byte HT MAC Parameters */
1769   capability = tvb_get_guint8 (tvb, offset);
1770   cap_item = proto_tree_add_uint_format(tree, macparm, tvb,
1771                     offset, 1, capability,
1772                     "MAC Parameters: 0x%02X", capability);
1773   cap_tree = proto_item_add_subtree(cap_item, ett_macparm_tree);
1774   proto_tree_add_uint(cap_tree, macparm_mpdu, tvb, offset, 1,
1775              capability);
1776   proto_tree_add_uint(cap_tree, macparm_mpdu_density, tvb, offset, 1,
1777              capability);
1778
1779   offset += 1;
1780   tag_val_off += 1;
1781
1782   /* 16 byte Supported MCS set */
1783   proto_tree_add_string(tree, tag_interpretation, tvb, offset,
1784             16, "Modulation Coding Streams (One bit per modulation)");
1785   offset += 16;
1786   tag_val_off += 16;
1787
1788   /* 2 byte extended HT capabilities */
1789   capability = tvb_get_letohs (tvb, offset);
1790   cap_item = proto_tree_add_uint_format(tree, htex_cap, tvb,
1791                     offset, 2, capability,
1792                     "HT Extended Capabilities: 0x%04X", capability);
1793   cap_tree = proto_item_add_subtree(cap_item, ett_htex_cap_tree);
1794   proto_tree_add_boolean(cap_tree, htex_pco, tvb, offset, 2,
1795              capability);
1796   proto_tree_add_uint(cap_tree, htex_transtime, tvb, offset, 2,
1797              capability);
1798   proto_tree_add_uint(cap_tree, htex_mcs, tvb, offset, 2,
1799              capability);
1800
1801   offset += 2;
1802   tag_val_off += 2;
1803
1804   /* 4 byte TxBF capabilities */
1805   txbfcap = tvb_get_letohl (tvb, offset);
1806   cap_item = proto_tree_add_uint_format(tree, txbf, tvb,
1807                     offset, 4, txbf,
1808                     "Transmit Beam Forming Capabilities: 0x%08X", txbfcap);
1809   cap_tree = proto_item_add_subtree(cap_item, ett_txbf_tree);
1810   proto_tree_add_boolean(cap_tree, txbf_cap, tvb, offset, 4,
1811              txbfcap);
1812   proto_tree_add_boolean(cap_tree, txbf_rcv_ssc, tvb, offset, 4,
1813              txbfcap);
1814   proto_tree_add_boolean(cap_tree, txbf_tx_ssc, tvb, offset, 4,
1815              txbfcap);
1816   proto_tree_add_boolean(cap_tree, txbf_rcv_zlf, tvb, offset, 4,
1817              txbfcap);
1818   proto_tree_add_boolean(cap_tree, txbf_tx_zlf, tvb, offset, 4,
1819              txbfcap);
1820   proto_tree_add_boolean(cap_tree, txbf_impl_txbf, tvb, offset, 4,
1821              txbfcap);
1822   proto_tree_add_uint(cap_tree, txbf_calib, tvb, offset, 4,
1823              txbfcap);
1824   proto_tree_add_boolean(cap_tree, txbf_expl_csi, tvb, offset, 4,
1825              txbfcap);
1826   proto_tree_add_boolean(cap_tree, txbf_expl_uncomp_sm, tvb, offset, 4,
1827              txbfcap);
1828   proto_tree_add_uint(cap_tree, txbf_expl_bf_csi, tvb, offset, 4,
1829              txbfcap);
1830   proto_tree_add_uint(cap_tree, txbf_expl_uncomp_sm_feed, tvb, offset, 4,
1831              txbfcap);
1832   proto_tree_add_uint(cap_tree, txbf_expl_comp_sm_feed, tvb, offset, 4,
1833              txbfcap);
1834   proto_tree_add_uint(cap_tree, txbf_csi_num_bf_ant, tvb, offset, 4,
1835              txbfcap);
1836   proto_tree_add_uint(cap_tree, txbf_uncomp_sm_bf_ant, tvb, offset, 4,
1837              txbfcap);
1838   proto_tree_add_uint(cap_tree, txbf_comp_sm_bf_ant, tvb, offset, 4,
1839              txbfcap);
1840
1841   offset += 4;
1842   tag_val_off += 4;
1843
1844   /* 1 byte AS capabilities */
1845   capability = tvb_get_guint8 (tvb, offset);
1846   cap_item = proto_tree_add_uint_format(tree, antsel, tvb,
1847                     offset, 1, capability,
1848                     "Antenna Selection: 0x%02X", capability);
1849   cap_tree = proto_item_add_subtree(cap_item, ett_antsel_tree);
1850   proto_tree_add_boolean(cap_tree, antsel_b0, tvb, offset, 1,
1851              capability);
1852   proto_tree_add_boolean(cap_tree, antsel_b1, tvb, offset, 1,
1853              capability);
1854   proto_tree_add_boolean(cap_tree, antsel_b2, tvb, offset, 1,
1855              capability);
1856   proto_tree_add_boolean(cap_tree, antsel_b3, tvb, offset, 1,
1857              capability);
1858   proto_tree_add_boolean(cap_tree, antsel_b4, tvb, offset, 1,
1859              capability);
1860   proto_tree_add_boolean(cap_tree, antsel_b5, tvb, offset, 1,
1861              capability);
1862   proto_tree_add_boolean(cap_tree, antsel_b6, tvb, offset, 1,
1863              capability);
1864
1865   offset += 1;
1866   tag_val_off += 1;
1867
1868   if (tag_val_off < tag_len)
1869     proto_tree_add_string(tree, tag_interpretation, tvb, offset,
1870                           tag_len - tag_val_off, "Not interpreted");
1871 }
1872
1873 static void
1874 dissect_hta_ie(proto_tree * tree, tvbuff_t * tvb, int offset,
1875                guint32 tag_len)
1876 {
1877   proto_item *cap_item;
1878   proto_tree *cap_tree;
1879   guint16 capability;
1880   guint32 tag_val_off = 0;
1881   gchar out_buff[SHORT_STR];
1882
1883   if (tag_val_off + 2 > tag_len) {
1884     proto_tree_add_string(tree, tag_interpretation, tvb, offset, tag_len,
1885                           "Not interpreted");
1886     return;
1887   }
1888
1889   if (tag_len < 22) {
1890     proto_tree_add_string(tree, tag_interpretation, tvb, offset, tag_len,
1891               "HT Additional Capabilities IE content length must be 22");
1892     return;
1893   }
1894
1895   g_snprintf(out_buff, SHORT_STR, "Control Channel %d",
1896              tvb_get_guint8(tvb, offset));
1897   proto_tree_add_string(tree, tag_interpretation, tvb, offset, 1, out_buff);
1898   offset += 1;
1899   tag_val_off += 1;
1900
1901   /* 1 byte HT additional capabilities */
1902   capability = tvb_get_guint8 (tvb, offset);
1903   cap_item = proto_tree_add_uint_format(tree, hta_cap, tvb,
1904                     offset, 1, capability,
1905                     "HT Additional Capabilities: 0x%04X", capability);
1906   cap_tree = proto_item_add_subtree(cap_item, ett_hta_cap_tree);
1907   proto_tree_add_uint(cap_tree, hta_ext_chan_offset, tvb, offset, 1,
1908              capability);
1909   proto_tree_add_boolean(cap_tree, hta_rec_tx_width, tvb, offset, 1,
1910              capability);
1911   proto_tree_add_boolean(cap_tree, hta_rifs_mode, tvb, offset, 1,
1912              capability);
1913   proto_tree_add_boolean(cap_tree, hta_controlled_access, tvb, offset, 1,
1914              capability);
1915   proto_tree_add_uint(cap_tree, hta_service_interval, tvb, offset, 1,
1916              capability);
1917   offset += 1;
1918   tag_val_off += 1;
1919
1920   /* 2 byte HT additional capabilities */
1921   capability = tvb_get_letohs (tvb, offset);
1922   cap_item = proto_tree_add_uint_format(tree, hta_cap, tvb,
1923                     offset, 2, capability,
1924                     "HT Additional Capabilities: 0x%04X", capability);
1925   cap_tree = proto_item_add_subtree(cap_item, ett_hta_cap1_tree);
1926   proto_tree_add_uint(cap_tree, hta_operating_mode, tvb, offset, 2,
1927              capability);
1928   proto_tree_add_boolean(cap_tree, hta_non_gf_devices, tvb, offset, 2,
1929              capability);
1930
1931   offset += 2;
1932   tag_val_off += 2;
1933
1934   /* 2 byte HT additional capabilities */
1935   capability = tvb_get_letohs (tvb, offset);
1936   cap_item = proto_tree_add_uint_format(tree, hta_cap, tvb,
1937                     offset, 2, capability,
1938                     "HT Additional Capabilities: 0x%04X", capability);
1939   cap_tree = proto_item_add_subtree(cap_item, ett_hta_cap2_tree);
1940   proto_tree_add_uint(cap_tree, hta_basic_stbc_mcs, tvb, offset, 2,
1941              capability);
1942   proto_tree_add_boolean(cap_tree, hta_dual_stbc_protection, tvb, offset, 2,
1943              capability);
1944   proto_tree_add_boolean(cap_tree, hta_secondary_beacon, tvb, offset, 2,
1945              capability);
1946   proto_tree_add_boolean(cap_tree, hta_lsig_txop_protection, tvb, offset, 2,
1947              capability);
1948   proto_tree_add_boolean(cap_tree, hta_pco_active, tvb, offset, 2,
1949              capability);
1950   proto_tree_add_boolean(cap_tree, hta_pco_phase, tvb, offset, 2,
1951              capability);
1952   offset += 2;
1953   tag_val_off += 2;
1954
1955   /* 16 byte Supported MCS set */
1956   proto_tree_add_string(tree, tag_interpretation, tvb, offset,
1957             16, "Modulation Coding Streams (One bit per modulation)");
1958   offset += 16;
1959   tag_val_off += 16;
1960
1961    if (tag_val_off < tag_len)
1962      proto_tree_add_string(tree, tag_interpretation, tvb, offset,
1963                tag_len - tag_val_off, "Not interpreted");
1964 }
1965
1966
1967 static void
1968 dissect_vendor_ie_ht(proto_tree * ietree, proto_tree * tree, tvbuff_t * tag_tvb)
1969 {
1970       gint tag_len = tvb_length_remaining(tag_tvb, 0);
1971       gchar out_buff[SHORT_STR];
1972
1973       g_snprintf(out_buff, SHORT_STR, "802.11n (Pre) OUI");
1974       proto_tree_add_string(tree, tag_interpretation, tag_tvb, 0, 3, out_buff);
1975       /* 802.11n OUI  Information Element */
1976       if (4 <= tag_len && !tvb_memeql(tag_tvb, 0, PRE_11N_OUI"\x33", 4)) {
1977         g_snprintf(out_buff, SHORT_STR, "802.11n (Pre) HT information");
1978         proto_tree_add_string(tree, tag_interpretation, tag_tvb, 3, 1, out_buff);
1979
1980         dissect_ht_ie(tree, tag_tvb, 4, tag_len - 4);
1981         proto_item_append_text(ietree, ": HT Capabilities (802.11n)");
1982       }
1983       else
1984       if (4 <= tag_len && !tvb_memeql(tag_tvb, 0, PRE_11N_OUI"\x34", 4)) {
1985         g_snprintf(out_buff, SHORT_STR, "HT additional information (802.11n)");
1986         proto_tree_add_string(tree, tag_interpretation, tag_tvb, 3, 1, out_buff);
1987
1988         dissect_hta_ie(tree, tag_tvb, 4, tag_len - 4);
1989         proto_item_append_text(ietree, ": HT Additional Capabilities (802.11n)");
1990       }
1991       else
1992       {
1993           g_snprintf(out_buff, SHORT_STR, "Unknown type");
1994           proto_tree_add_string(tree, tag_interpretation, tag_tvb, 3, 1, out_buff);
1995           proto_item_append_text(ietree, ": 802.11n (pre) Unknown type");
1996           proto_tree_add_string(tree, tag_interpretation, tag_tvb, 4,
1997                     tag_len - 4, "Not interpreted");
1998       }
1999 }
2000
2001
2002 /* ************************************************************************* */
2003 /*           Dissect and add tagged (optional) fields to proto tree          */
2004 /* ************************************************************************* */
2005
2006 static const value_string tag_num_vals[] = {
2007         { TAG_SSID,                 "SSID parameter set" },
2008         { TAG_SUPP_RATES,           "Supported Rates" },
2009         { TAG_FH_PARAMETER,         "FH Parameter set" },
2010         { TAG_DS_PARAMETER,         "DS Parameter set" },
2011         { TAG_CF_PARAMETER,         "CF Parameter set" },
2012         { TAG_TIM,                  "(TIM) Traffic Indication Map" },
2013         { TAG_IBSS_PARAMETER,       "IBSS Parameter set" },
2014         { TAG_COUNTRY_INFO,         "Country Information" },
2015         { TAG_FH_HOPPING_PARAMETER, "Hopping Pattern Parameters" },
2016         { TAG_CHALLENGE_TEXT,       "Challenge text" },
2017         { TAG_ERP_INFO,             "ERP Information" },
2018         { TAG_ERP_INFO_OLD,         "ERP Information" },
2019         { TAG_RSN_IE,               "RSN Information" },
2020         { TAG_EXT_SUPP_RATES,       "Extended Supported Rates" },
2021         { TAG_CISCO_UNKNOWN_1,      "Cisco Unknown 1 + Device Name" },
2022         { TAG_CISCO_UNKNOWN_2,      "Cisco Unknown 2" },
2023         { TAG_VENDOR_SPECIFIC_IE,   "Vendor Specific" },
2024         { TAG_SYMBOL_PROPRIETARY,   "Symbol Proprietary"},
2025         { TAG_AGERE_PROPRIETARY,    "Agere Proprietary"},
2026         { TAG_REQUEST,              "Request"},
2027         { TAG_QBSS_LOAD,            "QBSS Load Element"},
2028         { TAG_EDCA_PARAM_SET,       "EDCA Parameter Set"},
2029         { TAG_TSPEC,                "Traffic Specification"},
2030         { TAG_TCLAS,                "Traffic Classification"},
2031         { TAG_SCHEDULE,             "Schedule"},
2032         { TAG_TS_DELAY,             "TS Delay"},
2033         { TAG_TCLAS_PROCESS,        "TCLAS Processing"},
2034     { TAG_HT_INFO,       "HT Capabilities (802.11n)"},
2035         { TAG_QOS_CAPABILITY,       "QoS Capability"},
2036         { TAG_POWER_CONSTRAINT,     "Power Constraint"},
2037         { TAG_POWER_CAPABILITY,     "Power Capability"},
2038         { TAG_TPC_REQUEST,          "TPC Request"},
2039         { TAG_TPC_REPORT,           "TPC Report"},
2040         { TAG_SUPPORTED_CHANNELS,   "Supported Channels"},
2041         { TAG_CHANNEL_SWITCH_ANN,   "Channel Switch Announcement"},
2042         { TAG_MEASURE_REQ,          "Measurement Request"},
2043         { TAG_MEASURE_REP,          "Measurement Report"},
2044         { TAG_QUIET,                "Quiet"},
2045         { TAG_IBSS_DFS,             "IBSS DFS"},
2046         { 0,                        NULL }
2047 };
2048
2049 static const value_string environment_vals[] = {
2050         { 0x20, "Any" },
2051         { 0x4f, "Outdoor" },
2052         { 0x49, "Indoor" },
2053         { 0,    NULL }
2054 };
2055
2056 static int beacon_padding = 0; /* beacon padding bug */
2057 static int
2058 add_tagged_field (packet_info * pinfo, proto_tree * tree, tvbuff_t * tvb, int offset)
2059 {
2060   guint32 oui;
2061   tvbuff_t *tag_tvb;
2062   const guint8 *tag_data_ptr;
2063   guint32 tag_no, tag_len;
2064   unsigned int i;
2065   int n, ret;
2066   char out_buff[SHORT_STR];
2067   char print_buff[SHORT_STR];
2068   proto_tree * orig_tree=tree;
2069   proto_item *ti;
2070
2071   tag_no = tvb_get_guint8(tvb, offset);
2072   tag_len = tvb_get_guint8(tvb, offset + 1);
2073
2074   ti=proto_tree_add_text(orig_tree,tvb,offset,tag_len+2,"%s",
2075                          val_to_str(tag_no, tag_num_vals,
2076                          (tag_no >= 17 && tag_no <= 31) ?
2077                          "Reserved for challenge text" : "Reserved tag number" ));
2078   tree=proto_item_add_subtree(ti,ett_80211_mgt_ie);
2079
2080   proto_tree_add_uint_format (tree, tag_number, tvb, offset, 1, tag_no,
2081                               "Tag Number: %u (%s)",
2082                               tag_no,
2083                               val_to_str(tag_no, tag_num_vals,
2084                                          (tag_no >= 17 && tag_no <= 31) ?
2085                                          "Reserved for challenge text" :
2086                                          "Reserved tag number"));
2087   proto_tree_add_uint (tree, (tag_no==TAG_TIM ? tim_length : tag_length), tvb, offset + 1, 1, tag_len);
2088
2089   switch (tag_no)
2090     {
2091
2092     case TAG_SSID:
2093       if(beacon_padding == 0) /* padding bug */
2094       {
2095         guint8 *ssid; /* The SSID may consist of arbitrary bytes */
2096
2097         ssid = tvb_get_ephemeral_string(tvb, offset + 2, tag_len);
2098 #ifdef HAVE_AIRPDCAP
2099         AirPDcapSetLastSSID(&airpdcap_ctx, (CHAR *) ssid, tag_len);
2100 #endif
2101         proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
2102                                tag_len, (char *) ssid);
2103         if (check_col (pinfo->cinfo, COL_INFO)) {
2104           if (tag_len > 0) {
2105             col_append_fstr(pinfo->cinfo, COL_INFO, ", SSID: \"%s\"",
2106                             format_text(ssid, tag_len));
2107           } else {
2108             col_append_fstr(pinfo->cinfo, COL_INFO, ", SSID: Broadcast");
2109           }
2110         }
2111         if (tag_len > 0) {
2112           proto_item_append_text(ti, ": \"%s\"",
2113                                  format_text(ssid, tag_len));
2114         } else {
2115           proto_item_append_text(ti, ": Broadcast");
2116         }
2117         beacon_padding++; /* padding bug */
2118       }
2119       break;
2120
2121     case TAG_SUPP_RATES:
2122     case TAG_EXT_SUPP_RATES:
2123       if (tag_len < 1)
2124       {
2125         proto_tree_add_text (tree, tvb, offset + 2, tag_len,
2126                 "Tag length %u too short, must be > 0", tag_len);
2127         break;
2128       }
2129
2130       tag_data_ptr = tvb_get_ptr (tvb, offset + 2, tag_len);
2131       for (i = 0, n = 0; i < tag_len && n < SHORT_STR; i++) {
2132         ret = g_snprintf (print_buff + n, SHORT_STR - n, "%2.1f%s ",
2133                         (tag_data_ptr[i] & 0x7F) * 0.5,
2134                         (tag_data_ptr[i] & 0x80) ? "(B)" : "");
2135         if (ret == -1 || ret >= SHORT_STR - n) {
2136           /* Some versions of snprintf return -1 if they'd truncate
2137              the output. Others return <buf_size> or greater.  */
2138           break;
2139         }
2140         n += ret;
2141       }
2142       g_snprintf (out_buff, SHORT_STR, "Supported rates: %s [Mbit/sec]", print_buff);
2143       out_buff[SHORT_STR-1] = '\0';
2144       proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
2145                              tag_len, out_buff);
2146       proto_item_append_text(ti, ": %s", print_buff);
2147       break;
2148
2149     case TAG_FH_PARAMETER:
2150       if (tag_len < 5)
2151       {
2152         proto_tree_add_text (tree, tvb, offset + 2, tag_len, "Tag length %u too short, must be >= 5",
2153                              tag_len);
2154         break;
2155       }
2156       g_snprintf (out_buff, SHORT_STR,
2157                 "Dwell time 0x%04X, Hop Set %2d, Hop Pattern %2d, Hop Index %2d",
2158                 tvb_get_letohs(tvb, offset + 2),
2159                 tvb_get_guint8(tvb, offset + 4),
2160                 tvb_get_guint8(tvb, offset + 5),
2161                 tvb_get_guint8(tvb, offset + 6));
2162       out_buff[SHORT_STR-1] = '\0';
2163       proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
2164                              tag_len, out_buff);
2165       break;
2166
2167     case TAG_DS_PARAMETER:
2168       if (tag_len < 1)
2169       {
2170         proto_tree_add_text (tree, tvb, offset + 2, tag_len, "Tag length %u too short, must be >= 1",
2171                              tag_len);
2172         break;
2173       }
2174       g_snprintf (out_buff, SHORT_STR, "Current Channel: %u",
2175                 tvb_get_guint8(tvb, offset + 2));
2176       out_buff[SHORT_STR-1] = '\0';
2177       proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
2178                              tag_len, out_buff);
2179       proto_item_append_text(ti, ": %s", out_buff);
2180       break;
2181
2182     case TAG_CF_PARAMETER:
2183       if (tag_len < 6)
2184       {
2185         proto_tree_add_text (tree, tvb, offset + 2, tag_len, "Tag length %u too short, must be >= 6",
2186                              tag_len);
2187         break;
2188       }
2189       g_snprintf (out_buff, SHORT_STR, "CFP count: %u",
2190                 tvb_get_guint8(tvb, offset + 2));
2191       out_buff[SHORT_STR-1] = '\0';
2192       proto_tree_add_string_format(tree, tag_interpretation, tvb, offset + 2,
2193                                    1, out_buff, "%s", out_buff);
2194       g_snprintf (out_buff, SHORT_STR, "CFP period: %u",
2195                 tvb_get_guint8(tvb, offset + 3));
2196       out_buff[SHORT_STR-1] = '\0';
2197       proto_tree_add_string_format(tree, tag_interpretation, tvb, offset + 3,
2198                                    1, out_buff, "%s", out_buff);
2199       g_snprintf (out_buff, SHORT_STR, "CFP max duration: %u",
2200                 tvb_get_letohs(tvb, offset + 4));
2201       out_buff[SHORT_STR-1] = '\0';
2202       proto_tree_add_string_format(tree, tag_interpretation, tvb, offset + 4,
2203                                    2, out_buff, "%s", out_buff);
2204       g_snprintf (out_buff, SHORT_STR, "CFP Remaining: %u",
2205                 tvb_get_letohs(tvb, offset + 6));
2206       out_buff[SHORT_STR-1] = '\0';
2207       proto_tree_add_string_format(tree, tag_interpretation, tvb, offset + 6,
2208                                    2, out_buff, "%s", out_buff);
2209       proto_item_append_text(ti, ": CFP count %u, CFP period %u, CFP max duration %u, "
2210                              "CFP Remaining %u",
2211                              tvb_get_guint8(tvb, offset + 2),
2212                              tvb_get_guint8(tvb, offset + 3),
2213                              tvb_get_letohs(tvb, offset + 4),
2214                              tvb_get_letohs(tvb, offset + 6));
2215       break;
2216
2217     case TAG_TIM:
2218       if (tag_len < 4)
2219       {
2220         proto_tree_add_text (tree, tvb, offset + 2, tag_len, "Tag length %u too short, must be >= 4",
2221                              tag_len);
2222         break;
2223       }
2224       {
2225         guint8 bmapctl;
2226         guint8 bmapoff;
2227         guint8 bmaplen;
2228         const guint8* bmap;
2229
2230         proto_tree_add_item(tree, tim_dtim_count, tvb,
2231                             offset + 2, 1, TRUE);
2232         proto_tree_add_item(tree, tim_dtim_period, tvb,
2233                             offset + 3, 1, TRUE);
2234         proto_item_append_text(ti, ": DTIM %u of %u bitmap",
2235                                tvb_get_guint8(tvb, offset + 2),
2236                                tvb_get_guint8(tvb, offset + 3));
2237
2238         bmapctl = tvb_get_guint8(tvb, offset + 4);
2239         bmapoff = bmapctl>>1;
2240         proto_tree_add_uint_format(tree, tim_bmapctl, tvb,
2241                             offset + 4, 1, bmapctl,
2242                             "Bitmap Control: 0x%02X (mcast:%u, bitmap offset %u)",
2243                             bmapctl, bmapctl&1, bmapoff);
2244
2245         bmaplen = tag_len - 3;
2246         bmap = tvb_get_ptr(tvb, offset + 5, bmaplen);
2247         if (bmaplen==1 && 0==bmap[0] && !(bmapctl&1)) {
2248           proto_item_append_text(ti, " empty");
2249         } else {
2250           if (bmapctl&1) {
2251             proto_item_append_text(ti, " mcast");
2252           }
2253         }
2254         if (bmaplen>1 || bmap[0]) {
2255           int len=g_snprintf (out_buff, SHORT_STR,
2256                             "Bitmap: traffic for AID's:");
2257           int i=0;
2258           for (i=0;i<bmaplen*8;i++) {
2259             if (bmap[i/8] & (1<<(i%8))) {
2260               int aid=i+2*bmapoff*8;
2261               len+=g_snprintf (out_buff+len, SHORT_STR-len," %u", aid);
2262               proto_item_append_text(ti, " %u", aid);
2263               if (len>=SHORT_STR) {
2264                 break;
2265               }
2266             }
2267           }
2268           out_buff[SHORT_STR-1] = '\0';
2269           proto_tree_add_string_format (tree, tag_interpretation, tvb, offset + 5,
2270                bmaplen, out_buff, "%s", out_buff);
2271         }
2272       }
2273       break;
2274
2275     case TAG_IBSS_PARAMETER:
2276       if (tag_len < 2)
2277       {
2278         proto_tree_add_text (tree, tvb, offset + 2, tag_len, "Tag length %u too short, must be >= 2",
2279                              tag_len);
2280         break;
2281       }
2282       g_snprintf (out_buff, SHORT_STR, "ATIM window 0x%X",
2283                 tvb_get_letohs(tvb, offset + 2));
2284       out_buff[SHORT_STR-1] = '\0';
2285       proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
2286                              tag_len, out_buff);
2287       proto_item_append_text(ti, ": %s", out_buff);
2288       break;
2289
2290     case TAG_COUNTRY_INFO: /* IEEE 802.11d-2001 and IEEE 802.11j-2004 */
2291       {
2292         guint8 ccode[2+1];
2293
2294         if (tag_len < 3)
2295         {
2296           proto_tree_add_text (tree, tvb, offset + 2, tag_len, "Tag length %u too short, must be >= 3",
2297                                tag_len);
2298           break;
2299         }
2300         tvb_memcpy(tvb, ccode, offset + 2, 2);
2301         ccode[2] = '\0';
2302         g_snprintf (out_buff, SHORT_STR, "Country Code: %s, %s Environment",
2303                  format_text(ccode, 2),
2304                  val_to_str(tvb_get_guint8(tvb, offset + 4), environment_vals,"Unknown (0x%02x)"));
2305         out_buff[SHORT_STR-1] = '\0';
2306         proto_item_append_text(ti, ": %s", out_buff);
2307         proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,3, out_buff);
2308
2309         for (i = 3; (i + 3) <= tag_len; i += 3)
2310         {
2311           guint8 val1, val2, val3;
2312           val1 = tvb_get_guint8(tvb, offset + 2 + i);
2313           val2 = tvb_get_guint8(tvb, offset + 3 + i);
2314           val3 = tvb_get_guint8(tvb, offset + 4 + i);
2315
2316           if (val1 <= 200) {  /* 802.11d */
2317             proto_tree_add_string_format(tree, tag_interpretation, tvb, offset + 2+i,3, out_buff,
2318                                        "  Start Channel: %u, Channels: %u, Max TX Power: %d dBm",
2319                                        val1, val2, (gint) val3);
2320           } else {  /* 802.11j */
2321             proto_tree_add_string_format(tree, tag_interpretation, tvb, offset + 2+i,3, out_buff,
2322                                        "  Reg Extension Id: %u, Regulatory Class: %u, Coverage Class: %u",
2323                                        val1, val2, val3);
2324           }
2325         }
2326       }
2327       break;
2328
2329     case TAG_QBSS_LOAD:
2330       if (tag_len < 4 || tag_len >5)
2331       {
2332         proto_tree_add_text (tree, tvb, offset + 2, tag_len, "Wrong QBSS Tag Length %u", tag_len);
2333         break;
2334       }
2335
2336       if (tag_len == 4)
2337       {
2338         /* QBSS Version 1 */
2339         proto_tree_add_string (tree, tag_interpretation, tvb, offset + 1,
2340           tag_len, "Cisco QBSS Version 1 - non CCA");
2341
2342         /* Extract Values */
2343         proto_tree_add_uint (tree, hf_qbss_version, tvb, offset + 2, tag_len, 1);
2344         proto_tree_add_item (tree, hf_qbss_scount, tvb, offset + 2, 2, TRUE);
2345         proto_tree_add_item (tree, hf_qbss_cu, tvb, offset + 4, 1, FALSE);
2346         proto_tree_add_item (tree, hf_qbss_adc, tvb, offset + 5, 1, FALSE);
2347       }
2348       else if (tag_len == 5)
2349       {
2350          /* QBSS Version 2 */
2351          proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
2352            tag_len, "802.11e CCA Version");
2353
2354          /* Extract Values */
2355          proto_tree_add_uint (tree, hf_qbss_version, tvb, offset + 2, tag_len, 2);
2356          proto_tree_add_item (tree, hf_qbss_scount, tvb, offset + 2, 2, TRUE);
2357          proto_tree_add_item (tree, hf_qbss_cu, tvb, offset + 4, 1, FALSE);
2358          proto_tree_add_item (tree, hf_qbss_adc, tvb, offset + 5, 2, FALSE);
2359       }
2360       break;
2361
2362     case TAG_FH_HOPPING_PARAMETER:
2363       if (tag_len < 2)
2364       {
2365         proto_tree_add_text (tree, tvb, offset + 2, tag_len, "Tag length %u too short, must be >= 2",
2366                              tag_len);
2367         break;
2368       }
2369       g_snprintf (out_buff, SHORT_STR, "Prime Radix: %u, Number of Channels: %u",
2370                 tvb_get_guint8(tvb, offset + 2),
2371                 tvb_get_guint8(tvb, offset + 3));
2372       out_buff[SHORT_STR-1] = '\0';
2373       proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2, tag_len, out_buff);
2374       proto_item_append_text(ti, ": %s", out_buff);
2375       break;
2376
2377     case TAG_TSPEC:
2378       if (tag_len != 55)
2379       {
2380         proto_tree_add_text (tree, tvb, offset + 2, tag_len,
2381                 "TSPEC tag length %u != 55", tag_len);
2382         break;
2383       }
2384       add_fixed_field (tree, tvb, offset + 2, FIELD_QOS_TS_INFO);
2385       proto_tree_add_item(tree, tspec_nor_msdu, tvb, offset + 5, 2, TRUE);
2386       proto_tree_add_item(tree, tspec_max_msdu, tvb, offset + 7, 2, TRUE);
2387       proto_tree_add_item(tree, tspec_min_srv, tvb, offset + 9, 4, TRUE);
2388       proto_tree_add_item(tree, tspec_max_srv, tvb, offset + 13, 4, TRUE);
2389       proto_tree_add_item(tree, tspec_inact_int, tvb, offset + 17, 4, TRUE);
2390       proto_tree_add_item(tree, tspec_susp_int, tvb, offset + 21, 4, TRUE);
2391       proto_tree_add_item(tree, tspec_srv_start, tvb, offset + 25, 4, TRUE);
2392       proto_tree_add_item(tree, tspec_min_data, tvb, offset + 29, 4, TRUE);
2393       proto_tree_add_item(tree, tspec_mean_data, tvb, offset + 33, 4, TRUE);
2394       proto_tree_add_item(tree, tspec_peak_data, tvb, offset + 37, 4, TRUE);
2395       proto_tree_add_item(tree, tspec_burst_size, tvb, offset + 41, 4, TRUE);
2396       proto_tree_add_item(tree, tspec_delay_bound, tvb, offset + 45, 4, TRUE);
2397       proto_tree_add_item(tree, tspec_min_phy, tvb, offset + 49, 4, TRUE);
2398       proto_tree_add_item(tree, tspec_surplus, tvb, offset + 53, 2, TRUE);
2399       proto_tree_add_item(tree, tspec_medium, tvb, offset + 55, 2, TRUE);
2400       break;
2401
2402     case TAG_TS_DELAY:
2403       if (tag_len != 4)
2404       {
2405         proto_tree_add_text (tree, tvb, offset + 2, tag_len,
2406                 "TS_DELAY tag length %u != 4", tag_len);
2407         break;
2408       }
2409       proto_tree_add_item(tree, ts_delay, tvb, offset + 2, 4, TRUE);
2410       break;
2411
2412     case TAG_TCLAS:
2413       if (tag_len < 6)
2414       {
2415         proto_tree_add_text (tree, tvb, offset + 2, tag_len,
2416                 "TCLAS element is too small %u", tag_len);
2417         break;
2418       }
2419       {
2420         guint8 type;
2421         guint8 version;
2422
2423         type = tvb_get_guint8(tvb, offset + 2);
2424         proto_tree_add_item(tree, hf_tsinfo_up, tvb, offset + 2, 1, TRUE);
2425         proto_tree_add_item(tree, hf_class_type, tvb, offset + 3, 1, TRUE);
2426         proto_tree_add_item(tree, hf_class_mask, tvb, offset + 4, 1, TRUE);
2427         switch (type)
2428           {
2429             case 0:
2430               proto_tree_add_item(tree, ff_src_mac_addr, tvb, offset + 5,
2431                                   6, TRUE);
2432               proto_tree_add_item(tree, ff_dst_mac_addr, tvb, offset + 11,
2433                                   6, TRUE);
2434               proto_tree_add_item(tree, hf_ether_type, tvb, offset + 17,
2435                                   2, TRUE);
2436               break;
2437
2438             case 1:
2439               version = tvb_get_guint8(tvb, offset + 5);
2440               proto_tree_add_item(tree, cf_version, tvb, offset + 5, 1, TRUE);
2441               if (version == 4)
2442               {
2443                 proto_tree_add_item(tree, cf_ipv4_src, tvb, offset + 6,
2444                                     4, FALSE);
2445                 proto_tree_add_item(tree, cf_ipv4_dst, tvb, offset + 10,
2446                                     4, FALSE);
2447                 proto_tree_add_item(tree, cf_src_port, tvb, offset + 14,
2448                                     2, FALSE);
2449                 proto_tree_add_item(tree, cf_dst_port, tvb, offset + 16,
2450                                     2, FALSE);
2451                 proto_tree_add_item(tree, cf_dscp, tvb, offset + 18,
2452                                     1, FALSE);
2453                 proto_tree_add_item(tree, cf_protocol, tvb, offset + 19,
2454                                     1, FALSE);
2455               }
2456               else if (version == 6)
2457               {
2458                 proto_tree_add_item(tree, cf_ipv6_src, tvb, offset + 6,
2459                                     16, FALSE);
2460                 proto_tree_add_item(tree, cf_ipv6_dst, tvb, offset + 22,
2461                                     16, FALSE);
2462                 proto_tree_add_item(tree, cf_src_port, tvb, offset + 38,
2463                                     2, FALSE);
2464                 proto_tree_add_item(tree, cf_dst_port, tvb, offset + 40,
2465                                     2, FALSE);
2466                 proto_tree_add_item(tree, cf_flow, tvb, offset + 42,
2467                                     3, FALSE);
2468               }
2469               break;
2470
2471             case 2:
2472               proto_tree_add_item(tree, cf_tag_type, tvb, offset + 5,
2473                                   2, TRUE);
2474               break;
2475
2476             default:
2477               break;
2478           }
2479       }
2480       break;
2481
2482     case TAG_TCLAS_PROCESS:
2483       if (tag_len != 1)
2484       {
2485         proto_tree_add_text (tree, tvb, offset + 2, tag_len,
2486                 "TCLAS_PROCESS element length %u != 1", tag_len);
2487         break;
2488       }
2489       proto_tree_add_item(tree, hf_tclas_process, tvb, offset + 2, 1, TRUE);
2490       break;
2491
2492     case TAG_SCHEDULE:
2493       if (tag_len != 14)
2494       {
2495         proto_tree_add_text (tree, tvb, offset + 2, tag_len,
2496                 "TCLAS_PROCESS element length %u != 14", tag_len);
2497         break;
2498       }
2499       add_fixed_field (tree, tvb, offset + 2, FIELD_SCHEDULE_INFO);
2500       proto_tree_add_item(tree, hf_sched_srv_start, tvb, offset + 4, 4, TRUE);
2501       proto_tree_add_item(tree, hf_sched_srv_int, tvb, offset + 8, 4, TRUE);
2502       proto_tree_add_item(tree, hf_sched_spec_int, tvb, offset + 12, 2, TRUE);
2503       break;
2504
2505     case TAG_CHALLENGE_TEXT:
2506       g_snprintf (out_buff, SHORT_STR, "Challenge text: %s",
2507                 tvb_bytes_to_str(tvb, offset + 2, tag_len));
2508       out_buff[SHORT_STR-1] = '\0';
2509       proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
2510                              tag_len, out_buff);
2511       break;
2512
2513     case TAG_ERP_INFO:
2514     case TAG_ERP_INFO_OLD:
2515       {
2516         guint8 erp_info;
2517
2518         if (tag_len < 1)
2519         {
2520           proto_tree_add_text (tree, tvb, offset + 2, tag_len, "Tag length %u too short, must be >= 1",
2521                                tag_len);
2522           break;
2523         }
2524         erp_info = tvb_get_guint8 (tvb, offset + 2);
2525         g_snprintf (print_buff, SHORT_STR, "%sNon-ERP STAs, %suse protection, %s preambles",
2526                   erp_info & 0x01 ? "" : "no ",
2527                   erp_info & 0x02 ? "" : "do not ",
2528                   /* 802.11g, 7.3.2.13: 1 means "one or more ... STAs
2529                    * are not short preamble capable" */
2530                   erp_info & 0x04 ? "long": "short or long");
2531         print_buff[SHORT_STR-1] = '\0';
2532         g_snprintf (out_buff, SHORT_STR,
2533                   "ERP info: 0x%x (%s)",erp_info,print_buff);
2534         out_buff[SHORT_STR-1] = '\0';
2535         proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
2536                                tag_len, out_buff);
2537         proto_item_append_text(ti, ": %s", print_buff);
2538       }
2539       break;
2540
2541     case TAG_CISCO_UNKNOWN_1:
2542       /* The Name of the sending device starts at offset 10 and is up to
2543          15 or 16 bytes in length, \0 padded */
2544       if (tag_len < 26)
2545       {
2546         proto_tree_add_text (tree, tvb, offset + 2, tag_len, "Tag length %u too short, must be >= 26",
2547                              tag_len);
2548         break;
2549       }
2550       /* A cisco AP transmits the first 15 bytes of the AP name, probably
2551          followed by '\0' for ASCII termination */
2552       g_snprintf (out_buff, SHORT_STR, "%.16s",
2553                 tvb_format_stringzpad(tvb, offset + 12, 16));
2554       out_buff[SHORT_STR-1] = '\0';
2555       proto_tree_add_string_format (tree, tag_interpretation, tvb, offset + 2,
2556                              tag_len, "", "Tag interpretation: Unknown + Name: %s #Clients: %u",
2557                              out_buff,
2558                              /* Total number off associated clients and
2559                                 repeater access points */
2560                              tvb_get_guint8(tvb, offset + 28));
2561       if (check_col (pinfo->cinfo, COL_INFO)) {
2562           col_append_fstr(pinfo->cinfo, COL_INFO, ", Name: \"%s\"", out_buff);
2563       }
2564       break;
2565
2566     case TAG_VENDOR_SPECIFIC_IE:
2567       tvb_ensure_bytes_exist (tvb, offset + 2, tag_len);
2568       if (tag_len >= 3) {
2569                 oui = tvb_get_ntoh24(tvb, offset + 2);
2570                 tag_tvb = tvb_new_subset(tvb, offset + 2, tag_len, tag_len);
2571
2572 #define WPAWME_OUI      0x0050F2
2573 #define RSNOUI_VAL      0x000FAC
2574 #define PRE11N_OUI  0x00904c
2575
2576                 switch (oui) {
2577                 case WPAWME_OUI:
2578                         dissect_vendor_ie_wpawme(ti, tree, tag_tvb);
2579                         break;
2580                 case RSNOUI_VAL:
2581                         dissect_vendor_ie_rsn(ti, tree, tag_tvb);
2582                         break;
2583                 case OUI_CISCOWL:       /* Cisco Wireless (Aironet) */
2584                         dissect_vendor_ie_aironet(ti, tree, tvb, offset + 5, tag_len - 3);
2585                         break;
2586         case PRE11N_OUI:
2587             dissect_vendor_ie_ht(ti, tree, tag_tvb);
2588             break;
2589                 default:
2590                         tag_data_ptr = tvb_get_ptr(tag_tvb, 0, 3);
2591                         proto_tree_add_bytes_format (tree, tag_oui, tvb, offset + 2, 3,
2592                                 tag_data_ptr, "Vendor: %s", get_manuf_name(tag_data_ptr));
2593                         proto_item_append_text(ti, ": %s", get_manuf_name(tag_data_ptr));
2594                         proto_tree_add_string (tree, tag_interpretation, tvb, offset + 5,
2595                                 tag_len - 3, "Not interpreted");
2596                         break;
2597                 }
2598
2599       }
2600       break;
2601
2602     case TAG_RSN_IE:
2603       tag_tvb = tvb_new_subset(tvb, offset + 2, tag_len, tag_len);
2604       dissect_rsn_ie(tree, tag_tvb);
2605       break;
2606
2607   case TAG_HT_INFO:
2608     dissect_ht_ie(tree, tvb, offset + 2, tag_len);
2609     break;
2610
2611     default:
2612       tvb_ensure_bytes_exist (tvb, offset + 2, tag_len);
2613       proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
2614                              tag_len, "Not interpreted");
2615       proto_item_append_text(ti, ": Tag %u Len %u", tag_no, tag_len);
2616       break;
2617     }
2618
2619   return tag_len + 2;
2620 }
2621
2622 void
2623 ieee_80211_add_tagged_parameters (tvbuff_t * tvb, int offset, packet_info * pinfo,
2624         proto_tree * tree, int tagged_parameters_len)
2625 {
2626   int next_len;
2627
2628   beacon_padding = 0; /* this is for the beacon padding confused with ssid fix */
2629   while (tagged_parameters_len > 0) {
2630     if ((next_len=add_tagged_field (pinfo, tree, tvb, offset))==0)
2631       break;
2632     if (next_len > tagged_parameters_len) {
2633       /* XXX - flag this as an error? */
2634       next_len = tagged_parameters_len;
2635     }
2636     offset += next_len;
2637     tagged_parameters_len -= next_len;
2638   }
2639 }
2640
2641 /* ************************************************************************* */
2642 /*                     Dissect 802.11 management frame                       */
2643 /* ************************************************************************* */
2644 static void
2645 dissect_ieee80211_mgt (guint16 fcf, tvbuff_t * tvb, packet_info * pinfo,
2646         proto_tree * tree)
2647 {
2648       proto_item *ti = NULL;
2649       proto_tree *mgt_tree;
2650       proto_tree *fixed_tree;
2651       proto_tree *tagged_tree;
2652       int offset;
2653       int tagged_parameter_tree_len;
2654
2655       g_pinfo = pinfo;
2656
2657       CHECK_DISPLAY_AS_X(data_handle,proto_wlan_mgt, tvb, pinfo, tree);
2658
2659       ti = proto_tree_add_item (tree, proto_wlan_mgt, tvb, 0, -1, FALSE);
2660       mgt_tree = proto_item_add_subtree (ti, ett_80211_mgt);
2661
2662       switch (COMPOSE_FRAME_TYPE(fcf))
2663         {
2664
2665         case MGT_ASSOC_REQ:
2666           fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 4);
2667           add_fixed_field (fixed_tree, tvb, 0, FIELD_CAP_INFO);
2668           add_fixed_field (fixed_tree, tvb, 2, FIELD_LISTEN_IVAL);
2669           offset = 4;   /* Size of fixed fields */
2670
2671           tagged_parameter_tree_len =
2672               tvb_reported_length_remaining(tvb, offset);
2673           tagged_tree = get_tagged_parameter_tree (mgt_tree, tvb, offset,
2674                                                    tagged_parameter_tree_len);
2675           ieee_80211_add_tagged_parameters (tvb, offset, pinfo, tagged_tree,
2676               tagged_parameter_tree_len);
2677           break;
2678
2679
2680         case MGT_ASSOC_RESP:
2681           fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 6);
2682           add_fixed_field (fixed_tree, tvb, 0, FIELD_CAP_INFO);
2683           add_fixed_field (fixed_tree, tvb, 2, FIELD_STATUS_CODE);
2684           add_fixed_field (fixed_tree, tvb, 4, FIELD_ASSOC_ID);
2685           offset = 6;   /* Size of fixed fields */
2686
2687           tagged_parameter_tree_len =
2688               tvb_reported_length_remaining(tvb, offset);
2689           tagged_tree = get_tagged_parameter_tree (mgt_tree, tvb, offset,
2690                                                    tagged_parameter_tree_len);
2691           ieee_80211_add_tagged_parameters (tvb, offset, pinfo, tagged_tree,
2692               tagged_parameter_tree_len);
2693           break;
2694
2695
2696         case MGT_REASSOC_REQ:
2697           fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 10);
2698           add_fixed_field (fixed_tree, tvb, 0, FIELD_CAP_INFO);
2699           add_fixed_field (fixed_tree, tvb, 2, FIELD_LISTEN_IVAL);
2700           add_fixed_field (fixed_tree, tvb, 4, FIELD_CURRENT_AP_ADDR);
2701           offset = 10;  /* Size of fixed fields */
2702
2703           tagged_parameter_tree_len =
2704               tvb_reported_length_remaining(tvb, offset);
2705           tagged_tree = get_tagged_parameter_tree (mgt_tree, tvb, offset,
2706                                                    tagged_parameter_tree_len);
2707           ieee_80211_add_tagged_parameters (tvb, offset, pinfo, tagged_tree,
2708               tagged_parameter_tree_len);
2709           break;
2710
2711         case MGT_REASSOC_RESP:
2712           fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 6);
2713           add_fixed_field (fixed_tree, tvb, 0, FIELD_CAP_INFO);
2714           add_fixed_field (fixed_tree, tvb, 2, FIELD_STATUS_CODE);
2715           add_fixed_field (fixed_tree, tvb, 4, FIELD_ASSOC_ID);
2716           offset = 6;   /* Size of fixed fields */
2717
2718           tagged_parameter_tree_len =
2719               tvb_reported_length_remaining(tvb, offset);
2720           tagged_tree = get_tagged_parameter_tree (mgt_tree, tvb, offset,
2721                                                    tagged_parameter_tree_len);
2722           ieee_80211_add_tagged_parameters (tvb, offset, pinfo, tagged_tree,
2723               tagged_parameter_tree_len);
2724           break;
2725
2726
2727         case MGT_PROBE_REQ:
2728           offset = 0;
2729           tagged_parameter_tree_len =
2730               tvb_reported_length_remaining(tvb, offset);
2731           tagged_tree = get_tagged_parameter_tree (mgt_tree, tvb, offset,
2732                                                    tagged_parameter_tree_len);
2733           ieee_80211_add_tagged_parameters (tvb, offset, pinfo, tagged_tree,
2734               tagged_parameter_tree_len);
2735           break;
2736
2737
2738         case MGT_PROBE_RESP:
2739           fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 12);
2740           add_fixed_field (fixed_tree, tvb, 0, FIELD_TIMESTAMP);
2741           add_fixed_field (fixed_tree, tvb, 8, FIELD_BEACON_INTERVAL);
2742           add_fixed_field (fixed_tree, tvb, 10, FIELD_CAP_INFO);
2743           offset = 12;  /* Size of fixed fields */
2744
2745           tagged_parameter_tree_len =
2746               tvb_reported_length_remaining(tvb, offset);
2747           tagged_tree = get_tagged_parameter_tree (mgt_tree, tvb, offset,
2748                                                    tagged_parameter_tree_len);
2749           ieee_80211_add_tagged_parameters (tvb, offset, pinfo, tagged_tree,
2750               tagged_parameter_tree_len);
2751           break;
2752
2753
2754         case MGT_BEACON:                /* Dissect protocol payload fields  */
2755           fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 12);
2756           add_fixed_field (fixed_tree, tvb, 0, FIELD_TIMESTAMP);
2757           add_fixed_field (fixed_tree, tvb, 8, FIELD_BEACON_INTERVAL);
2758           add_fixed_field (fixed_tree, tvb, 10, FIELD_CAP_INFO);
2759           offset = 12;  /* Size of fixed fields */
2760
2761           tagged_parameter_tree_len =
2762               tvb_reported_length_remaining(tvb, offset);
2763           tagged_tree = get_tagged_parameter_tree (mgt_tree, tvb, offset,
2764                                                    tagged_parameter_tree_len);
2765           ieee_80211_add_tagged_parameters (tvb, offset, pinfo, tagged_tree,
2766               tagged_parameter_tree_len);
2767           break;
2768
2769
2770         case MGT_ATIM:
2771           break;
2772
2773
2774         case MGT_DISASS:
2775           fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 2);
2776           add_fixed_field (fixed_tree, tvb, 0, FIELD_REASON_CODE);
2777           break;
2778
2779
2780         case MGT_AUTHENTICATION:
2781           fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 6);
2782           add_fixed_field (fixed_tree, tvb, 0, FIELD_AUTH_ALG);
2783           add_fixed_field (fixed_tree, tvb, 2, FIELD_AUTH_TRANS_SEQ);
2784           add_fixed_field (fixed_tree, tvb, 4, FIELD_STATUS_CODE);
2785           offset = 6;   /* Size of fixed fields */
2786
2787           tagged_parameter_tree_len =
2788                   tvb_reported_length_remaining(tvb, offset);
2789           if (tagged_parameter_tree_len != 0)
2790             {
2791               tagged_tree = get_tagged_parameter_tree (mgt_tree,
2792                                                        tvb,
2793                                                        offset,
2794                                                        tagged_parameter_tree_len);
2795               ieee_80211_add_tagged_parameters (tvb, offset, pinfo, tagged_tree,
2796                 tagged_parameter_tree_len);
2797             }
2798           break;
2799
2800
2801         case MGT_DEAUTHENTICATION:
2802           fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 2);
2803           add_fixed_field (fixed_tree, tvb, 0, FIELD_REASON_CODE);
2804           break;
2805
2806
2807         case MGT_ACTION:
2808           switch (tvb_get_guint8(tvb, 0))
2809             {
2810
2811             case CAT_SPECTRUM_MGMT:
2812               switch (tvb_get_guint8(tvb, 1))
2813                 {
2814                 case SM_ACTION_MEASUREMENT_REQUEST:
2815                 case SM_ACTION_MEASUREMENT_REPORT:
2816                 case SM_ACTION_TPC_REQUEST:
2817                 case SM_ACTION_TPC_REPORT:
2818                   fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 3);
2819                   add_fixed_field (fixed_tree, tvb, 0, FIELD_CATEGORY_CODE);
2820                   add_fixed_field (fixed_tree, tvb, 1, FIELD_ACTION_CODE);
2821                   add_fixed_field (fixed_tree, tvb, 2, FIELD_DIALOG_TOKEN);
2822                   offset = 3;   /* Size of fixed fields */
2823                   break;
2824
2825                 case SM_ACTION_CHAN_SWITCH_ANNC:
2826                   fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 2);
2827                   add_fixed_field (fixed_tree, tvb, 0, FIELD_CATEGORY_CODE);
2828                   offset = 2;   /* Size of fixed fields */
2829                   break;
2830
2831                 default:
2832                   fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 2);
2833                   add_fixed_field (fixed_tree, tvb, 0, FIELD_CATEGORY_CODE);
2834                   offset = 2;   /* Size of fixed fields */
2835                   break;
2836                 }
2837               break;
2838
2839             case CAT_QOS:
2840               switch (tvb_get_guint8(tvb, 1))
2841                 {
2842                 case SM_ACTION_ADDTS_REQUEST:
2843                   fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 3);
2844                   add_fixed_field (fixed_tree, tvb, 0, FIELD_CATEGORY_CODE);
2845                   add_fixed_field (fixed_tree, tvb, 1, FIELD_QOS_ACTION_CODE);
2846                   add_fixed_field (fixed_tree, tvb, 2, FIELD_DIALOG_TOKEN);
2847                   offset = 3;
2848                   break;
2849
2850                 case SM_ACTION_ADDTS_RESPONSE:
2851                   fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 5);
2852                   add_fixed_field (fixed_tree, tvb, 0, FIELD_CATEGORY_CODE);
2853                   add_fixed_field (fixed_tree, tvb, 1, FIELD_QOS_ACTION_CODE);
2854                   add_fixed_field (fixed_tree, tvb, 2, FIELD_DIALOG_TOKEN);
2855                   add_fixed_field (fixed_tree, tvb, 3, FIELD_STATUS_CODE);
2856                   offset = 5;
2857                   break;
2858
2859                 case SM_ACTION_DELTS:
2860                   fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 7);
2861                   add_fixed_field (fixed_tree, tvb, 0, FIELD_CATEGORY_CODE);
2862                   add_fixed_field (fixed_tree, tvb, 1, FIELD_QOS_ACTION_CODE);
2863                   add_fixed_field (fixed_tree, tvb, 2, FIELD_QOS_TS_INFO);
2864                   add_fixed_field (fixed_tree, tvb, 5, FIELD_REASON_CODE);
2865                   offset = 7;
2866                   break;
2867
2868                 case SM_ACTION_QOS_SCHEDULE:
2869                   fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 2);
2870                   add_fixed_field (fixed_tree, tvb, 0, FIELD_CATEGORY_CODE);
2871                   add_fixed_field (fixed_tree, tvb, 1, FIELD_QOS_ACTION_CODE);
2872                   offset = 2;
2873                   break;
2874
2875                 default:
2876                   fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 2);
2877                   add_fixed_field (fixed_tree, tvb, 0, FIELD_CATEGORY_CODE);
2878                   offset = 2;   /* Size of fixed fields */
2879                   break;
2880                 }
2881               break;
2882
2883             case CAT_DLS:
2884               switch (tvb_get_guint8(tvb, 1))
2885                 {
2886                 case SM_ACTION_DLS_REQUEST:
2887                   fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 18);
2888                   add_fixed_field (fixed_tree, tvb, 0, FIELD_CATEGORY_CODE);
2889                   add_fixed_field (fixed_tree, tvb, 1, FIELD_DLS_ACTION_CODE);
2890                   add_fixed_field (fixed_tree, tvb, 2, FIELD_DST_MAC_ADDR);
2891                   add_fixed_field (fixed_tree, tvb, 8, FIELD_SRC_MAC_ADDR);
2892                   add_fixed_field (fixed_tree, tvb, 14, FIELD_CAP_INFO);
2893                   add_fixed_field (fixed_tree, tvb, 16, FIELD_DLS_TIMEOUT);
2894                   offset = 18;
2895                   break;
2896
2897                 case SM_ACTION_DLS_RESPONSE:
2898                   fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 16);
2899                   add_fixed_field (fixed_tree, tvb, 0, FIELD_CATEGORY_CODE);
2900                   add_fixed_field (fixed_tree, tvb, 1, FIELD_DLS_ACTION_CODE);
2901                   add_fixed_field (fixed_tree, tvb, 2, FIELD_STATUS_CODE);
2902                   add_fixed_field (fixed_tree, tvb, 4, FIELD_DST_MAC_ADDR);
2903                   add_fixed_field (fixed_tree, tvb, 10, FIELD_SRC_MAC_ADDR);
2904                   offset = 16;
2905                   if (!ff_status_code)
2906                     add_fixed_field (fixed_tree, tvb, 16, FIELD_CAP_INFO);
2907                   break;
2908
2909                 case SM_ACTION_DLS_TEARDOWN:
2910                   fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 18);
2911                   add_fixed_field (fixed_tree, tvb, 0, FIELD_CATEGORY_CODE);
2912                   add_fixed_field (fixed_tree, tvb, 1, FIELD_DLS_ACTION_CODE);
2913                   add_fixed_field (fixed_tree, tvb, 2, FIELD_DST_MAC_ADDR);
2914                   add_fixed_field (fixed_tree, tvb, 8, FIELD_SRC_MAC_ADDR);
2915                   add_fixed_field (fixed_tree, tvb, 14, FIELD_REASON_CODE);
2916                   offset = 16;
2917                   break;
2918
2919                 default:
2920                   fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 2);
2921                   add_fixed_field (fixed_tree, tvb, 0, FIELD_CATEGORY_CODE);
2922                   offset = 2;   /* Size of fixed fields */
2923                   break;
2924                 }
2925               break;
2926
2927             case CAT_MGMT_NOTIFICATION: /* Management notification frame */
2928               fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 4);
2929               add_fixed_field (fixed_tree, tvb, 0, FIELD_CATEGORY_CODE);
2930               add_fixed_field (fixed_tree, tvb, 1, FIELD_WME_ACTION_CODE);
2931               add_fixed_field (fixed_tree, tvb, 2, FIELD_DIALOG_TOKEN);
2932               add_fixed_field (fixed_tree, tvb, 3, FIELD_WME_STATUS_CODE);
2933               offset = 4;       /* Size of fixed fields */
2934               break;
2935
2936             default:
2937               fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 1);
2938               add_fixed_field (fixed_tree, tvb, 0, FIELD_CATEGORY_CODE);
2939               offset = 1;       /* Size of fixed fields */
2940               break;
2941             }
2942
2943             tagged_parameter_tree_len =
2944               tvb_reported_length_remaining(tvb, offset);
2945             if (tagged_parameter_tree_len != 0)
2946               {
2947                 tagged_tree = get_tagged_parameter_tree (mgt_tree, tvb, offset,
2948                                                          tagged_parameter_tree_len);
2949                 ieee_80211_add_tagged_parameters (tvb, offset, pinfo, tagged_tree,
2950                                                   tagged_parameter_tree_len);
2951               }
2952           break;
2953         }
2954 }
2955
2956 static void
2957 set_src_addr_cols(packet_info *pinfo, const guint8 *addr, const char *type)
2958 {
2959   if (check_col(pinfo->cinfo, COL_RES_DL_SRC))
2960     col_add_fstr(pinfo->cinfo, COL_RES_DL_SRC, "%s (%s)",
2961                     get_ether_name(addr), type);
2962   if (check_col(pinfo->cinfo, COL_UNRES_DL_SRC))
2963     col_add_fstr(pinfo->cinfo, COL_UNRES_DL_SRC, "%s",
2964                      ether_to_str(addr));
2965 }
2966
2967 static void
2968 set_dst_addr_cols(packet_info *pinfo, const guint8 *addr, const char *type)
2969 {
2970   if (check_col(pinfo->cinfo, COL_RES_DL_DST))
2971     col_add_fstr(pinfo->cinfo, COL_RES_DL_DST, "%s (%s)",
2972                      get_ether_name(addr), type);
2973   if (check_col(pinfo->cinfo, COL_UNRES_DL_DST))
2974     col_add_fstr(pinfo->cinfo, COL_UNRES_DL_DST, "%s",
2975                      ether_to_str(addr));
2976 }
2977
2978 static guint32
2979 crc32_802_tvb_padded(tvbuff_t *tvb, guint hdr_len, guint hdr_size, guint len)
2980 {
2981   guint32 c_crc;
2982
2983   c_crc = crc32_ccitt_tvb(tvb, hdr_len);
2984   c_crc = crc32_ccitt_seed(tvb_get_ptr(tvb, hdr_size, len), len, ~c_crc);
2985
2986   /* Byte reverse. */
2987   c_crc = ((unsigned char)(c_crc>>0)<<24) |
2988     ((unsigned char)(c_crc>>8)<<16) |
2989     ((unsigned char)(c_crc>>16)<<8) |
2990     ((unsigned char)(c_crc>>24)<<0);
2991
2992   return ( c_crc );
2993 }
2994
2995 typedef enum {
2996     ENCAP_802_2,
2997     ENCAP_IPX,
2998     ENCAP_ETHERNET
2999 } encap_t;
3000
3001 /* ************************************************************************* */
3002 /*                          Dissect 802.11 frame                             */
3003 /* ************************************************************************* */
3004 static void
3005 dissect_ieee80211_common (tvbuff_t * tvb, packet_info * pinfo,
3006                           proto_tree * tree, gboolean fixed_length_header,
3007                           gboolean has_radio_information, gint fcs_len,
3008                           gboolean wlan_broken_fc, gboolean datapad)
3009 {
3010   guint16 fcf, flags, frame_type_subtype;
3011   guint16 seq_control;
3012   guint32 seq_number, frag_number;
3013   gboolean more_frags;
3014   const guint8 *src = NULL;
3015   const guint8 *dst = NULL;
3016   const guint8 *bssid = NULL;
3017   proto_item *ti = NULL;
3018   proto_item *flag_item;
3019   proto_item *fc_item;
3020   proto_item *fcs_item;
3021   proto_tree *hdr_tree = NULL;
3022   proto_tree *flag_tree;
3023   proto_tree *fc_tree;
3024   proto_tree *fcs_tree;
3025   guint16 hdr_len, ohdr_len;
3026   gboolean has_fcs, fcs_good, fcs_bad;
3027   gint len, reported_len, ivlen;
3028   gboolean save_fragmented;
3029   tvbuff_t *volatile next_tvb = NULL;
3030   guint32 addr_type;
3031   volatile encap_t encap_type;
3032   guint8 octet1, octet2;
3033   char out_buff[SHORT_STR];
3034   gint is_iv_bad;
3035   guchar iv_buff[4];
3036   wlan_hdr *volatile whdr;
3037   static wlan_hdr whdrs[4];
3038
3039   whdr= &whdrs[0];
3040
3041   if (check_col (pinfo->cinfo, COL_PROTOCOL))
3042     col_set_str (pinfo->cinfo, COL_PROTOCOL, "IEEE 802.11");
3043   if (check_col (pinfo->cinfo, COL_INFO))
3044     col_clear (pinfo->cinfo, COL_INFO);
3045
3046   /* Add the radio information, if present, to the column information */
3047   if (has_radio_information) {
3048     if (check_col(pinfo->cinfo, COL_TX_RATE)) {
3049         col_add_fstr(pinfo->cinfo, COL_TX_RATE, "%u.%u",
3050            pinfo->pseudo_header->ieee_802_11.data_rate / 2,
3051            pinfo->pseudo_header->ieee_802_11.data_rate & 1 ? 5 : 0);
3052     }
3053     if (check_col(pinfo->cinfo, COL_RSSI)) {
3054       /* XX - this is a percentage, not a dBm or normalized or raw RSSI */
3055       col_add_fstr(pinfo->cinfo, COL_RSSI, "%u",
3056            pinfo->pseudo_header->ieee_802_11.signal_level);
3057     }
3058   }
3059
3060   fcf = tvb_get_letohs (tvb, 0);
3061   if (wlan_broken_fc) {
3062     /* Swap bytes */
3063     fcf = ((fcf & 0xff) << 8) | (((fcf & 0xff00) >> 8) & 0xff);
3064   }
3065   if (fixed_length_header)
3066     hdr_len = DATA_LONG_HDR_LEN;
3067   else
3068     hdr_len = find_header_length (fcf);
3069   ohdr_len = hdr_len;
3070   if (datapad)
3071     hdr_len = roundup2(hdr_len, 4);
3072   frame_type_subtype = COMPOSE_FRAME_TYPE(fcf);
3073
3074   if (check_col (pinfo->cinfo, COL_INFO))
3075       col_set_str (pinfo->cinfo, COL_INFO,
3076           val_to_str(frame_type_subtype, frame_type_subtype_vals,
3077               "Unrecognized (Reserved frame)"));
3078
3079   flags = FCF_FLAGS (fcf);
3080   more_frags = HAVE_FRAGMENTS (flags);
3081
3082
3083   /* Add the radio information, if present, and the FC to the current tree */
3084   if (tree)
3085     {
3086       ti = proto_tree_add_protocol_format (tree, proto_wlan, tvb, 0, hdr_len,
3087                                            "IEEE 802.11");
3088       hdr_tree = proto_item_add_subtree (ti, ett_80211);
3089
3090       if (has_radio_information) {
3091         proto_tree_add_uint_format(hdr_tree, hf_data_rate,
3092                                    tvb, 0, 0,
3093                                    pinfo->pseudo_header->ieee_802_11.data_rate,
3094                                    "Data Rate: %u.%u Mb/s",
3095                                    pinfo->pseudo_header->ieee_802_11.data_rate / 2,
3096                                    pinfo->pseudo_header->ieee_802_11.data_rate & 1 ? 5 : 0);
3097
3098         proto_tree_add_uint(hdr_tree, hf_channel,
3099                             tvb, 0, 0,
3100                             pinfo->pseudo_header->ieee_802_11.channel);
3101
3102         proto_tree_add_uint_format(hdr_tree, hf_signal_strength,
3103                                    tvb, 0, 0,
3104                                    pinfo->pseudo_header->ieee_802_11.signal_level,
3105                                    "Signal Strength: %u%%",
3106                                    pinfo->pseudo_header->ieee_802_11.signal_level);
3107       }
3108
3109       proto_tree_add_uint (hdr_tree, hf_fc_frame_type_subtype,
3110                            tvb,
3111                            wlan_broken_fc?1:0, 1,
3112                            frame_type_subtype);
3113
3114       fc_item = proto_tree_add_uint_format (hdr_tree, hf_fc_field, tvb,
3115                                             0, 2,
3116                                             fcf,
3117                                             "Frame Control: 0x%04X (%s)",
3118                                             fcf, wlan_broken_fc?"Swapped":"Normal");
3119
3120       fc_tree = proto_item_add_subtree (fc_item, ett_fc_tree);
3121
3122
3123       proto_tree_add_uint (fc_tree, hf_fc_proto_version, tvb,
3124                            wlan_broken_fc?1:0, 1,
3125                            FCF_PROT_VERSION (fcf));
3126
3127       proto_tree_add_uint (fc_tree, hf_fc_frame_type, tvb,
3128                            wlan_broken_fc?1:0, 1,
3129                            FCF_FRAME_TYPE (fcf));
3130
3131       proto_tree_add_uint (fc_tree, hf_fc_frame_subtype,
3132                            tvb,
3133                            wlan_broken_fc?1:0, 1,
3134                            FCF_FRAME_SUBTYPE (fcf));
3135
3136       flag_item =
3137         proto_tree_add_uint_format (fc_tree, hf_fc_flags, tvb,
3138                                     wlan_broken_fc?0:1, 1,
3139                                     flags, "Flags: 0x%X", flags);
3140
3141       flag_tree = proto_item_add_subtree (flag_item, ett_proto_flags);
3142
3143       proto_tree_add_uint (flag_tree, hf_fc_data_ds, tvb,
3144                            wlan_broken_fc?0:1, 1,
3145                            FLAGS_DS_STATUS (flags));
3146       proto_tree_add_boolean_hidden (flag_tree, hf_fc_to_ds, tvb, 1, 1,
3147                                      flags);
3148       proto_tree_add_boolean_hidden (flag_tree, hf_fc_from_ds, tvb, 1, 1,
3149                                      flags);
3150
3151       proto_tree_add_boolean (flag_tree, hf_fc_more_frag, tvb,
3152                               wlan_broken_fc?0:1, 1,
3153                               flags);
3154
3155       proto_tree_add_boolean (flag_tree, hf_fc_retry, tvb,
3156                               wlan_broken_fc?0:1, 1, flags);
3157
3158       proto_tree_add_boolean (flag_tree, hf_fc_pwr_mgt, tvb,
3159                               wlan_broken_fc?0:1, 1, flags);
3160
3161       proto_tree_add_boolean (flag_tree, hf_fc_more_data, tvb,
3162                               wlan_broken_fc?0:1, 1,
3163                               flags);
3164
3165       proto_tree_add_boolean (flag_tree, hf_fc_protected, tvb,
3166                               wlan_broken_fc?0:1, 1, flags);
3167
3168       proto_tree_add_boolean (flag_tree, hf_fc_order, tvb,
3169                               wlan_broken_fc?0:1, 1, flags);
3170
3171       if (frame_type_subtype == CTRL_PS_POLL)
3172         proto_tree_add_uint(hdr_tree, hf_assoc_id,tvb,2,2,
3173                             ASSOC_ID(tvb_get_letohs(tvb,2)));
3174
3175       else
3176           proto_tree_add_uint (hdr_tree, hf_did_duration, tvb, 2, 2,
3177                                tvb_get_letohs (tvb, 2));
3178     }
3179
3180   /*
3181    * Decode the part of the frame header that isn't the same for all
3182    * frame types.
3183    */
3184   seq_control = 0;
3185   frag_number = 0;
3186   seq_number = 0;
3187
3188   switch (FCF_FRAME_TYPE (fcf))
3189     {
3190
3191     case MGT_FRAME:
3192       /*
3193        * All management frame types have the same header.
3194        */
3195       src = tvb_get_ptr (tvb, 10, 6);
3196       dst = tvb_get_ptr (tvb, 4, 6);
3197
3198       SET_ADDRESS(&pinfo->dl_src, AT_ETHER, 6, src);
3199       SET_ADDRESS(&pinfo->src, AT_ETHER, 6, src);
3200       SET_ADDRESS(&pinfo->dl_dst, AT_ETHER, 6, dst);
3201       SET_ADDRESS(&pinfo->dst, AT_ETHER, 6, dst);
3202
3203       /* for tap */
3204       SET_ADDRESS(&whdr->bssid, AT_ETHER, 6, tvb_get_ptr(tvb, 16,6));
3205       SET_ADDRESS(&whdr->src, AT_ETHER, 6, src);
3206       SET_ADDRESS(&whdr->dst, AT_ETHER, 6, dst);
3207       whdr->type = frame_type_subtype;
3208
3209       seq_control = tvb_get_letohs(tvb, 22);
3210       frag_number = SEQCTL_FRAGMENT_NUMBER(seq_control);
3211       seq_number = SEQCTL_SEQUENCE_NUMBER(seq_control);
3212
3213       if (check_col (pinfo->cinfo, COL_INFO))
3214       {
3215         col_append_fstr(pinfo->cinfo, COL_INFO,
3216           ",SN=%d", seq_number);
3217
3218         col_append_fstr(pinfo->cinfo, COL_INFO,
3219           ",FN=%d",frag_number);
3220       }
3221
3222       if (tree)
3223         {
3224           proto_tree_add_ether (hdr_tree, hf_addr_da, tvb, 4, 6, dst);
3225
3226           proto_tree_add_ether (hdr_tree, hf_addr_sa, tvb, 10, 6, src);
3227
3228           /* add items for wlan.addr filter */
3229           proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 4, 6, dst);
3230           proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 10, 6, src);
3231
3232           proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 16, 6,
3233                                 tvb_get_ptr (tvb, 16, 6));
3234
3235           proto_tree_add_uint (hdr_tree, hf_frag_number, tvb, 22, 2,
3236                                frag_number);
3237
3238           proto_tree_add_uint (hdr_tree, hf_seq_number, tvb, 22, 2,
3239                                seq_number);
3240         }
3241       break;
3242
3243     case CONTROL_FRAME:
3244       switch (frame_type_subtype)
3245         {
3246
3247         case CTRL_PS_POLL:
3248           src = tvb_get_ptr (tvb, 10, 6);
3249           dst = tvb_get_ptr (tvb, 4, 6);
3250
3251           set_src_addr_cols(pinfo, src, "BSSID");
3252           set_dst_addr_cols(pinfo, dst, "BSSID");
3253
3254           if (tree)
3255             {
3256               proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 4, 6, dst);
3257
3258               proto_tree_add_ether (hdr_tree, hf_addr_ta, tvb, 10, 6, src);
3259             }
3260           break;
3261
3262
3263         case CTRL_RTS:
3264           src = tvb_get_ptr (tvb, 10, 6);
3265           dst = tvb_get_ptr (tvb, 4, 6);
3266
3267           set_src_addr_cols(pinfo, src, "TA");
3268           set_dst_addr_cols(pinfo, dst, "RA");
3269
3270           if (tree)
3271             {
3272               proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6, dst);
3273
3274               proto_tree_add_ether (hdr_tree, hf_addr_ta, tvb, 10, 6, src);
3275             }
3276           break;
3277
3278
3279         case CTRL_CTS:
3280           dst = tvb_get_ptr (tvb, 4, 6);
3281
3282           set_dst_addr_cols(pinfo, dst, "RA");
3283
3284           if (tree)
3285             proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6, dst);
3286           break;
3287
3288
3289         case CTRL_ACKNOWLEDGEMENT:
3290           dst = tvb_get_ptr (tvb, 4, 6);
3291
3292           set_dst_addr_cols(pinfo, dst, "RA");
3293
3294           if (tree)
3295             proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6, dst);
3296           break;
3297
3298
3299         case CTRL_CFP_END:
3300           src = tvb_get_ptr (tvb, 10, 6);
3301           dst = tvb_get_ptr (tvb, 4, 6);
3302
3303           set_src_addr_cols(pinfo, src, "BSSID");
3304           set_dst_addr_cols(pinfo, dst, "RA");
3305
3306           if (tree)
3307             {
3308               proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6, dst);
3309               proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 10, 6, src);
3310             }
3311           break;
3312
3313
3314         case CTRL_CFP_ENDACK:
3315           src = tvb_get_ptr (tvb, 10, 6);
3316           dst = tvb_get_ptr (tvb, 4, 6);
3317
3318           set_src_addr_cols(pinfo, src, "BSSID");
3319           set_dst_addr_cols(pinfo, dst, "RA");
3320
3321           if (tree)
3322             {
3323               proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6, dst);
3324
3325               proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 10, 6, src);
3326             }
3327           break;
3328
3329         case CTRL_BLOCK_ACK_REQ:
3330           {
3331             src = tvb_get_ptr (tvb, 10, 6);
3332             dst = tvb_get_ptr (tvb, 4, 6);
3333
3334             set_src_addr_cols(pinfo, src, "TA");
3335             set_dst_addr_cols(pinfo, dst, "RA");
3336
3337             if (tree)
3338             {
3339               proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6, src);
3340
3341               proto_tree_add_ether (hdr_tree, hf_addr_ta, tvb, 10, 6, dst);
3342             }
3343           /* TODO BAR */
3344           break;
3345           }
3346
3347         case CTRL_BLOCK_ACK:
3348           {
3349             src = tvb_get_ptr (tvb, 10, 6);
3350             dst = tvb_get_ptr (tvb, 4, 6);
3351
3352             set_src_addr_cols(pinfo, src, "TA");
3353             set_dst_addr_cols(pinfo, dst, "RA");
3354
3355             if (tree)
3356             {
3357               proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6, src);
3358
3359               proto_tree_add_ether (hdr_tree, hf_addr_ta, tvb, 10, 6, dst);
3360             }
3361             /* TODO BAR Format */
3362             break;
3363           }
3364         }
3365       break;
3366
3367     case DATA_FRAME:
3368       addr_type = FCF_ADDR_SELECTOR (fcf);
3369
3370       /* In order to show src/dst address we must always do the following */
3371       switch (addr_type)
3372         {
3373
3374         case DATA_ADDR_T1:
3375           src = tvb_get_ptr (tvb, 10, 6);
3376           dst = tvb_get_ptr (tvb, 4, 6);
3377           bssid = tvb_get_ptr (tvb, 16, 6);
3378           break;
3379
3380
3381         case DATA_ADDR_T2:
3382           src = tvb_get_ptr (tvb, 16, 6);
3383           dst = tvb_get_ptr (tvb, 4, 6);
3384           bssid = tvb_get_ptr (tvb, 10, 6);
3385           break;
3386
3387
3388         case DATA_ADDR_T3:
3389           src = tvb_get_ptr (tvb, 10, 6);
3390           dst = tvb_get_ptr (tvb, 16, 6);
3391           bssid = tvb_get_ptr (tvb, 4, 6);
3392           break;
3393
3394
3395         case DATA_ADDR_T4:
3396           src = tvb_get_ptr (tvb, 24, 6);
3397           dst = tvb_get_ptr (tvb, 16, 6);
3398           bssid = tvb_get_ptr (tvb, 16, 6);
3399           break;
3400         }
3401
3402       SET_ADDRESS(&pinfo->dl_src, AT_ETHER, 6, src);
3403       SET_ADDRESS(&pinfo->src, AT_ETHER, 6, src);
3404       SET_ADDRESS(&pinfo->dl_dst, AT_ETHER, 6, dst);
3405       SET_ADDRESS(&pinfo->dst, AT_ETHER, 6, dst);
3406
3407       /* for tap */
3408
3409       SET_ADDRESS(&whdr->bssid, AT_ETHER, 6, bssid);
3410       SET_ADDRESS(&whdr->src, AT_ETHER, 6, src);
3411       SET_ADDRESS(&whdr->dst, AT_ETHER, 6, dst);
3412       whdr->type = frame_type_subtype;
3413
3414       seq_control = tvb_get_letohs(tvb, 22);
3415       frag_number = SEQCTL_FRAGMENT_NUMBER(seq_control);
3416       seq_number = SEQCTL_SEQUENCE_NUMBER(seq_control);
3417
3418       if (check_col (pinfo->cinfo, COL_INFO))
3419       {
3420         col_append_fstr(pinfo->cinfo, COL_INFO,
3421           ",SN=%d", seq_number);
3422
3423         col_append_fstr(pinfo->cinfo, COL_INFO,
3424           ",FN=%d",frag_number);
3425       }
3426
3427       /* Now if we have a tree we start adding stuff */
3428       if (tree)
3429         {
3430
3431
3432           switch (addr_type)
3433             {
3434
3435             case DATA_ADDR_T1:
3436               proto_tree_add_ether (hdr_tree, hf_addr_da, tvb, 4, 6, dst);
3437               proto_tree_add_ether (hdr_tree, hf_addr_sa, tvb, 10, 6, src);
3438               proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 16, 6,
3439                                     tvb_get_ptr (tvb, 16, 6));
3440               proto_tree_add_uint (hdr_tree, hf_frag_number, tvb, 22, 2,
3441                                    frag_number);
3442               proto_tree_add_uint (hdr_tree, hf_seq_number, tvb, 22, 2,
3443                                    seq_number);
3444
3445               /* add items for wlan.addr filter */
3446               proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 4, 6, dst);
3447               proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 10, 6, src);
3448               break;
3449
3450
3451             case DATA_ADDR_T2:
3452               proto_tree_add_ether (hdr_tree, hf_addr_da, tvb, 4, 6, dst);
3453               proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 10, 6,
3454                                     tvb_get_ptr (tvb, 10, 6));
3455               proto_tree_add_ether (hdr_tree, hf_addr_sa, tvb, 16, 6, src);
3456               proto_tree_add_uint (hdr_tree, hf_frag_number, tvb, 22, 2,
3457                                    frag_number);
3458               proto_tree_add_uint (hdr_tree, hf_seq_number, tvb, 22, 2,
3459                                    seq_number);
3460
3461               /* add items for wlan.addr filter */
3462               proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 4, 6, dst);
3463               proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 16, 6, src);
3464               break;
3465
3466
3467             case DATA_ADDR_T3:
3468               proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 4, 6,
3469                                     tvb_get_ptr (tvb, 4, 6));
3470               proto_tree_add_ether (hdr_tree, hf_addr_sa, tvb, 10, 6, src);
3471               proto_tree_add_ether (hdr_tree, hf_addr_da, tvb, 16, 6, dst);
3472
3473               proto_tree_add_uint (hdr_tree, hf_frag_number, tvb, 22, 2,
3474                                    frag_number);
3475               proto_tree_add_uint (hdr_tree, hf_seq_number, tvb, 22, 2,
3476                                    seq_number);
3477
3478               /* add items for wlan.addr filter */
3479               proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 10, 6, src);
3480               proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 16, 6, dst);
3481               break;
3482
3483
3484             case DATA_ADDR_T4:
3485               proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6,
3486                                     tvb_get_ptr (tvb, 4, 6));
3487               proto_tree_add_ether (hdr_tree, hf_addr_ta, tvb, 10, 6,
3488                                     tvb_get_ptr (tvb, 10, 6));
3489               proto_tree_add_ether (hdr_tree, hf_addr_da, tvb, 16, 6, dst);
3490               proto_tree_add_uint (hdr_tree, hf_frag_number, tvb, 22, 2,
3491                                    frag_number);
3492               proto_tree_add_uint (hdr_tree, hf_seq_number, tvb, 22, 2,
3493                                    seq_number);
3494               proto_tree_add_ether (hdr_tree, hf_addr_sa, tvb, 24, 6, src);
3495
3496               /* add items for wlan.addr filter */
3497               proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 16, 6, dst);
3498               proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 24, 6, src);
3499               break;
3500             }
3501
3502         }
3503       break;
3504     }
3505
3506   len = tvb_length_remaining(tvb, hdr_len);
3507   reported_len = tvb_reported_length_remaining(tvb, hdr_len);
3508
3509   switch (fcs_len)
3510     {
3511       case 0: /* Definitely has no FCS */
3512         has_fcs = FALSE;
3513         break;
3514
3515       case 4: /* Definitely has an FCS */
3516         has_fcs = TRUE;
3517         break;
3518
3519       default: /* Don't know - use "wlan_check_fcs" */
3520         has_fcs = wlan_check_fcs;
3521         break;
3522     }
3523   if (has_fcs)
3524     {
3525       /*
3526        * Well, this packet should, in theory, have an FCS.
3527        * Do we have the entire packet, and does it have enough data for
3528        * the FCS?
3529        */
3530       if (reported_len < 4)
3531         {
3532           /*
3533            * The packet is claimed not to even have enough data for a 4-byte
3534            * FCS.
3535            * Pretend it doesn't have an FCS.
3536            */
3537           ;
3538         }
3539       else if (len < reported_len)
3540         {
3541           /*
3542            * The packet is claimed to have enough data for a 4-byte FCS, but
3543            * we didn't capture all of the packet.
3544            * Slice off the 4-byte FCS from the reported length, and trim the
3545            * captured length so it's no more than the reported length; that
3546            * will slice off what of the FCS, if any, is in the captured
3547            * length.
3548            */
3549           reported_len -= 4;
3550           if (len > reported_len)
3551             len = reported_len;
3552         }
3553       else
3554         {
3555           /*
3556            * We have the entire packet, and it includes a 4-byte FCS.
3557            * Slice it off, and put it into the tree.
3558            */
3559           len -= 4;
3560           reported_len -= 4;
3561           if (tree)
3562             {
3563               guint32 sent_fcs = tvb_get_ntohl(tvb, hdr_len + len);
3564               guint32 fcs;
3565
3566               if (datapad)
3567                 fcs = crc32_802_tvb_padded(tvb, ohdr_len, hdr_len, len);
3568               else
3569                 fcs = crc32_802_tvb(tvb, hdr_len + len);
3570               if (fcs == sent_fcs) {
3571                       fcs_good = TRUE;
3572                       fcs_bad = FALSE;
3573               } else {
3574                       fcs_good = FALSE;
3575                       fcs_bad = TRUE;
3576               }
3577
3578               if(fcs_good)
3579                 fcs_item = proto_tree_add_uint_format(hdr_tree, hf_fcs, tvb,
3580                         hdr_len + len, 4, sent_fcs,
3581                         "Frame check sequence: 0x%08x [correct]", sent_fcs);
3582               else
3583                 fcs_item = proto_tree_add_uint_format(hdr_tree, hf_fcs, tvb,
3584                         hdr_len + len, 4, sent_fcs,
3585                         "Frame check sequence: 0x%08x [incorrect, should be 0x%08x]",
3586                         sent_fcs, fcs);
3587
3588               fcs_tree = proto_item_add_subtree(fcs_item, ett_fcs);
3589
3590               fcs_item = proto_tree_add_boolean(fcs_tree,
3591                                                 hf_fcs_good, tvb,
3592                                                 hdr_len + len, 2,
3593                                                 fcs_good);
3594               PROTO_ITEM_SET_GENERATED(fcs_item);
3595
3596               fcs_item = proto_tree_add_boolean(fcs_tree,
3597                                                 hf_fcs_bad, tvb,
3598                                                 hdr_len + len, 2,
3599                                                 fcs_bad);
3600               PROTO_ITEM_SET_GENERATED(fcs_item);
3601             }
3602         }
3603     }
3604
3605
3606
3607   /*
3608    * Only management and data frames have a body, so we don't have
3609    * anything more to do for other types of frames.
3610    */
3611   switch (FCF_FRAME_TYPE (fcf))
3612     {
3613
3614     case MGT_FRAME:
3615       break;
3616
3617     case DATA_FRAME:
3618       if (tree && DATA_FRAME_IS_QOS(frame_type_subtype))
3619         {
3620
3621           proto_item *qos_fields;
3622           proto_tree *qos_tree;
3623
3624           guint16 qosoff;
3625           guint16 qos_control;
3626           guint16 qos_priority;
3627           guint16 qos_ack_policy;
3628           guint16 qos_eosp;
3629           guint16 qos_field_content;
3630
3631           /*
3632            * We calculate the offset to the QoS header data as
3633            * an offset relative to the end of the header.  But
3634            * when the header has been padded to align the data
3635            * this must be done relative to true header size, not
3636            * the padded/aligned value.  To simplify this work we
3637            * stash the original header size in ohdr_len instead
3638            * of recalculating it.
3639            */
3640           qosoff = ohdr_len - 2;
3641           qos_fields = proto_tree_add_text(hdr_tree, tvb, qosoff, 2,
3642               "QoS parameters");
3643           qos_tree = proto_item_add_subtree (qos_fields, ett_qos_parameters);
3644
3645           qos_control = tvb_get_letohs(tvb, qosoff + 0);
3646           qos_priority = QOS_PRIORITY(qos_control);
3647           qos_ack_policy = QOS_ACK_POLICY(qos_control);
3648           qos_eosp = QOS_EOSP(qos_control);
3649           qos_field_content = QOS_FIELD_CONTENT( qos_control);
3650
3651           proto_tree_add_uint_format (qos_tree, hf_qos_priority, tvb,
3652               qosoff, 2, qos_priority,
3653               "Priority: %d (%s) (%s)",
3654               qos_priority, qos_tags[qos_priority], qos_acs[qos_priority]);
3655
3656           if (flags & FLAG_FROM_DS) {
3657             proto_tree_add_boolean (qos_tree, hf_qos_eosp, tvb,
3658               qosoff, 1, qos_eosp);
3659
3660             if (DATA_FRAME_IS_CF_POLL(frame_type_subtype)) {
3661               /* txop limit */
3662               proto_tree_add_uint_format (qos_tree, hf_qos_field_content, tvb,
3663                   qosoff + 1, 1, qos_field_content, "TXOP Limit: %d ", qos_field_content);
3664
3665             } else {
3666               /* qap ps buffer state */
3667               proto_item *qos_ps_buf_state_fields;
3668               proto_tree *qos_ps_buf_state_tree;
3669               guint16 buf_state;
3670               guint16 buf_ac;
3671               guint16 buf_load;
3672
3673               buf_state = QOS_PS_BUF_STATE(qos_field_content);
3674               buf_ac = QOS_PS_BUF_AC(qos_field_content);  /*access category */
3675               buf_load = QOS_PS_BUF_LOAD(qos_field_content);
3676
3677               qos_ps_buf_state_fields = proto_tree_add_text(qos_tree, tvb, qosoff + 1, 1,
3678                 "QAP PS Buffer State: 0x%x", qos_field_content);
3679               qos_ps_buf_state_tree = proto_item_add_subtree (qos_ps_buf_state_fields, ett_qos_ps_buf_state);
3680
3681 /*      FIXME: hf_ values not defined
3682               proto_tree_add_boolean (qos_ps_buf_state_tree, hf_qos_buf_state, tvb,
3683                   1, 1, buf_state);
3684
3685               proto_tree_add_uint_format (qos_ps_buf_state_tree, hf_qos_buf_ac, tvb,
3686                   qosoff + 1, 1, buf_ac, "Priority: %d (%s)",
3687                   buf_ac, wme_acs[buf_ac]);
3688
3689               proto_tree_add_uint_format (qos_ps_buf_state_tree, hf_qos_buf_load, tvb,
3690                   qosoff + 1, 1, buf_load, "Buffered load: %d ", (buf_load * 4096));
3691 */
3692
3693             }
3694           } else if (qos_eosp)  {
3695             /* txop limit requested */
3696             proto_tree_add_uint_format (qos_tree, hf_qos_field_content, tvb,
3697                   qosoff + 1, 1, qos_field_content, "Queue Size: %d ", (qos_field_content * 254));
3698           } else {
3699             /* queue size */
3700             proto_tree_add_uint_format (qos_tree, hf_qos_field_content, tvb,
3701                   qosoff + 1, 1, qos_field_content, "TXOP Limit Requested: %d ", qos_field_content);
3702           }
3703
3704           proto_tree_add_uint (qos_tree, hf_qos_ack_policy, tvb, qosoff, 1,
3705               qos_ack_policy);
3706
3707         } /* end of qos control field */
3708
3709 #ifdef  HAVE_AIRPDCAP
3710         /*      Davide Schiera (2006-11-21): process handshake packet with AirPDcap             */
3711         /*              the processing will take care of 4-way handshake sessions for WPA               */
3712         /*              and WPA2 decryption                                                                                                                                     */
3713         if (enable_decryption && !pinfo->fd->flags.visited) {
3714           const guint8 *enc_data = tvb_get_ptr(tvb, 0, hdr_len+reported_len);
3715           AirPDcapPacketProcess(&airpdcap_ctx, enc_data, hdr_len+reported_len, NULL, 0, NULL, FALSE, FALSE, TRUE, FALSE);
3716         }
3717         /* Davide Schiera --------------------------------------------------------      */
3718 #endif
3719
3720       /*
3721        * No-data frames don't have a body.
3722        */
3723       if (DATA_FRAME_IS_NULL(frame_type_subtype))
3724         return;
3725
3726       break;
3727
3728     case CONTROL_FRAME:
3729       return;
3730
3731     default:
3732       return;
3733     }
3734
3735   if (IS_PROTECTED(FCF_FLAGS(fcf))) {
3736     /*
3737      * It's a WEP or WPA encrypted frame; dissect the protections parameters
3738      * and decrypt the data, if we have a matching key. Otherwise display it as data.
3739      */
3740
3741     gboolean can_decrypt = FALSE;
3742     proto_tree *wep_tree = NULL;
3743     guint32 iv;
3744     guint8 key, keybyte;
3745
3746     /* Davide Schiera (2006-11-27): define algorithms constants and macros      */
3747 #ifdef  HAVE_AIRPDCAP
3748 #define PROTECTION_ALG_TKIP     AIRPDCAP_KEY_TYPE_TKIP
3749 #define PROTECTION_ALG_CCMP     AIRPDCAP_KEY_TYPE_CCMP
3750 #define PROTECTION_ALG_WEP      AIRPDCAP_KEY_TYPE_WEP
3751 #define PROTECTION_ALG_RSNA     PROTECTION_ALG_CCMP | PROTECTION_ALG_TKIP
3752 #else
3753 #define PROTECTION_ALG_WEP      0
3754 #define PROTECTION_ALG_TKIP     1
3755 #define PROTECTION_ALG_CCMP     2
3756 #define PROTECTION_ALG_RSNA     PROTECTION_ALG_CCMP | PROTECTION_ALG_TKIP
3757 #endif
3758     guint8 algorithm=-1;
3759     /* Davide Schiera (2006-11-27): added macros to check the algorithm         */
3760     /*          used could be TKIP or CCMP                                                                                                              */
3761 #define IS_TKIP(tvb, hdr_len)   (tvb_get_guint8(tvb, hdr_len + 1) & 0x20)
3762 #define IS_CCMP(tvb, hdr_len)   (tvb_get_guint8(tvb, hdr_len + 2) == 0)
3763     /* Davide Schiera -----------------------------------------------------     */
3764
3765 #ifdef  HAVE_AIRPDCAP
3766     /* Davide Schiera (2006-11-21): recorded original lengths to pass them      */
3767     /*          to the packets process function                                                                                         */
3768     guint32 sec_header=0;
3769     guint32 sec_trailer=0;
3770
3771     next_tvb = try_decrypt(tvb, hdr_len, reported_len, &algorithm, &sec_header, &sec_trailer);
3772 #endif
3773     /* Davide Schiera -----------------------------------------------------     */
3774
3775     keybyte = tvb_get_guint8(tvb, hdr_len + 3);
3776     key = KEY_OCTET_WEP_KEY(keybyte);
3777     if ((keybyte & KEY_EXTIV) && (len >= EXTIV_LEN)) {
3778       /* Extended IV; this frame is likely encrypted with TKIP or CCMP */
3779
3780
3781       if (tree) {
3782         proto_item *extiv_fields;
3783
3784 #ifdef  HAVE_AIRPDCAP
3785         /* Davide Schiera (2006-11-27): differentiated CCMP and TKIP if */
3786         /*              it's possible                                                                                                                           */
3787         if (algorithm==PROTECTION_ALG_TKIP)
3788                 extiv_fields = proto_tree_add_text(hdr_tree, tvb, hdr_len, 8,
3789                 "TKIP parameters");
3790         else if (algorithm==PROTECTION_ALG_CCMP)
3791                 extiv_fields = proto_tree_add_text(hdr_tree, tvb, hdr_len, 8,
3792                 "CCMP parameters");
3793         else {
3794                 /* Davide Schiera --------------------------------------------  */
3795 #endif
3796           /* Davide Schiera (2006-11-27): differentiated CCMP and TKIP if*/
3797           /*            it's possible                                                                                                                   */
3798           if (IS_TKIP(tvb, hdr_len)) {
3799                   algorithm=PROTECTION_ALG_TKIP;
3800                   extiv_fields = proto_tree_add_text(hdr_tree, tvb, hdr_len, 8,
3801                           "TKIP parameters");
3802           } else if (IS_CCMP(tvb, hdr_len)) {
3803                   algorithm=PROTECTION_ALG_CCMP;
3804                   extiv_fields = proto_tree_add_text(hdr_tree, tvb, hdr_len, 8,
3805                           "CCMP parameters");
3806           } else
3807             extiv_fields = proto_tree_add_text(hdr_tree, tvb, hdr_len, 8,
3808                                            "TKIP/CCMP parameters");
3809 #ifdef  HAVE_AIRPDCAP
3810         }
3811 #endif
3812
3813         wep_tree = proto_item_add_subtree (extiv_fields, ett_wep_parameters);
3814
3815         if (algorithm==PROTECTION_ALG_TKIP) {
3816           g_snprintf(out_buff, SHORT_STR, "0x%08X%02X%02X",
3817                    tvb_get_letohl(tvb, hdr_len + 4),
3818                    tvb_get_guint8(tvb, hdr_len),
3819                    tvb_get_guint8(tvb, hdr_len + 2));
3820           proto_tree_add_string(wep_tree, hf_tkip_extiv, tvb, hdr_len,
3821                                 EXTIV_LEN, out_buff);
3822                                 } else if (algorithm==PROTECTION_ALG_CCMP) {
3823           g_snprintf(out_buff, SHORT_STR, "0x%08X%02X%02X",
3824                    tvb_get_letohl(tvb, hdr_len + 4),
3825                    tvb_get_guint8(tvb, hdr_len + 1),
3826                    tvb_get_guint8(tvb, hdr_len));
3827           proto_tree_add_string(wep_tree, hf_ccmp_extiv, tvb, hdr_len,
3828                                 EXTIV_LEN, out_buff);
3829         }
3830
3831         proto_tree_add_uint(wep_tree, hf_wep_key, tvb, hdr_len + 3, 1, key);
3832       }
3833
3834       /* Subtract out the length of the IV. */
3835       len -= EXTIV_LEN;
3836       reported_len -= EXTIV_LEN;
3837       ivlen = EXTIV_LEN;
3838       /* It is unknown whether this is TKIP or CCMP, so let's not even try to
3839        * parse TKIP Michael MIC+ICV or CCMP MIC. */
3840
3841 #ifdef  HAVE_AIRPDCAP
3842       /*        Davide Schiera (2006-11-21): enable TKIP and CCMP decryption                    */
3843       /*                checking for the trailer                                                                                                                */
3844       if (next_tvb!=NULL) {
3845         if (reported_len < sec_trailer) {
3846           /* There is no space for a trailer, ignore it and don't decrypt       */
3847           ;
3848         } else if (len < reported_len) {
3849           /* There is space for a trailer, but we haven't capture all the       */
3850           /* packet. Slice off the trailer, but don't try to decrypt                    */
3851           reported_len -= sec_trailer;
3852           if (len > reported_len)
3853                   len = reported_len;
3854         } else {
3855           /* Ok, we have a trailer and the whole packet. Decrypt it!                    */
3856           /* TODO: At the moment we won't add the trailer to the tree,          */
3857           /* so don't remove the trailer from the packet                                                        */
3858           len -= sec_trailer;
3859           reported_len -= sec_trailer;
3860           can_decrypt = TRUE;
3861         }
3862       }
3863       /* Davide Schiera --------------------------------------------------      */
3864 #endif
3865     } else {
3866       /* No Ext. IV - WEP packet */
3867       /*
3868        * XXX - pass the IV and key to "try_decrypt_wep()", and have it pass
3869        * them to "wep_decrypt()", rather than having "wep_decrypt()" extract
3870        * them itself.
3871        *
3872        * Also, just pass the data *following* the WEP parameters as the
3873        * buffer to decrypt.
3874        */
3875       iv = tvb_get_ntoh24(tvb, hdr_len);
3876       if (tree) {
3877         proto_item *wep_fields;
3878
3879         wep_fields = proto_tree_add_text(hdr_tree, tvb, hdr_len, 4,
3880                                          "WEP parameters");
3881
3882         wep_tree = proto_item_add_subtree (wep_fields, ett_wep_parameters);
3883         proto_tree_add_uint (wep_tree, hf_wep_iv, tvb, hdr_len, 3, iv);
3884         tvb_memcpy(tvb, iv_buff, hdr_len, 3);
3885         is_iv_bad = weak_iv(iv_buff);
3886         if (is_iv_bad != -1) {
3887                 proto_tree_add_boolean_format (wep_tree, hf_wep_iv_weak,
3888                                                tvb, 0, 0, TRUE,
3889                                                "Weak IV for key byte %d",
3890                                                is_iv_bad);
3891         }
3892       }
3893       if (tree)
3894         proto_tree_add_uint (wep_tree, hf_wep_key, tvb, hdr_len + 3, 1, key);
3895
3896       /* Subtract out the length of the IV. */
3897       len -= 4;
3898       reported_len -= 4;
3899       ivlen = 4;
3900
3901       /* Davide Schiera (2006-11-27): Even if the decryption was not */
3902       /* successful, set the algorithm                               */
3903       algorithm=PROTECTION_ALG_WEP;
3904
3905       /*
3906        * Well, this packet should, in theory, have an ICV.
3907        * Do we have the entire packet, and does it have enough data for
3908        * the ICV?
3909        */
3910       if (reported_len < 4) {
3911         /*
3912          * The packet is claimed not to even have enough data for a
3913          * 4-byte ICV.
3914          * Pretend it doesn't have an ICV.
3915          */
3916         ;
3917       } else if (len < reported_len) {
3918         /*
3919          * The packet is claimed to have enough data for a 4-byte ICV,
3920          * but we didn't capture all of the packet.
3921          * Slice off the 4-byte ICV from the reported length, and trim
3922          * the captured length so it's no more than the reported length;
3923          * that will slice off what of the ICV, if any, is in the
3924          * captured length.
3925          *
3926          */
3927         reported_len -= 4;
3928         if (len > reported_len)
3929           len = reported_len;
3930       } else {
3931         /*
3932          * We have the entire packet, and it includes a 4-byte ICV.
3933          * Slice it off, and put it into the tree.
3934          *
3935          * We only support decrypting if we have the the ICV.
3936          *
3937          * XXX - the ICV is encrypted; we're putting the encrypted
3938          * value, not the decrypted value, into the tree.
3939          */
3940         len -= 4;
3941         reported_len -= 4;
3942         can_decrypt = TRUE;
3943       }
3944     }
3945
3946 #ifndef HAVE_AIRPDCAP
3947     if (can_decrypt)
3948       next_tvb = try_decrypt_wep(tvb, hdr_len, reported_len + 8);
3949 #else
3950     /* Davide Schiera (2006-11-26): decrypted before parsing header and         */
3951     /*          protection header                                                                                                                                       */
3952 #endif
3953                 if (!can_decrypt || next_tvb == NULL) {
3954       /*
3955        * WEP decode impossible or failed, treat payload as raw data
3956        * and don't attempt fragment reassembly or further dissection.
3957        */
3958       next_tvb = tvb_new_subset(tvb, hdr_len + ivlen, len, reported_len);
3959
3960       if (tree) {
3961         /* Davide Schiera (2006-11-21): added WEP or WPA separation                     */
3962         if (algorithm==PROTECTION_ALG_WEP) {
3963           if (can_decrypt)
3964             proto_tree_add_uint_format (wep_tree, hf_wep_icv, tvb,
3965                                     hdr_len + ivlen + len, 4,
3966                                     tvb_get_ntohl(tvb, hdr_len + ivlen + len),
3967                                     "WEP ICV: 0x%08x (not verified)",
3968                                     tvb_get_ntohl(tvb, hdr_len + ivlen + len));
3969         } else if (algorithm==PROTECTION_ALG_CCMP) {
3970         } else if (algorithm==PROTECTION_ALG_TKIP) {
3971         }
3972         /* Davide Schiera (2006-11-21) ----------------------------------       */
3973
3974         if (pinfo->ethertype != ETHERTYPE_CENTRINO_PROMISC)
3975         {
3976           /* Some wireless drivers (such as Centrino) WEP payload already decrypted */
3977           call_dissector(data_handle, next_tvb, pinfo, tree);
3978           goto end_of_wlan;
3979         }
3980       }
3981     } else {
3982       /* Davide Schiera (2006-11-21): added WEP or WPA separation                               */
3983       if (algorithm==PROTECTION_ALG_WEP) {
3984         if (tree)
3985           proto_tree_add_uint_format (wep_tree, hf_wep_icv, tvb,
3986                                     hdr_len + ivlen + len, 4,
3987                                     tvb_get_ntohl(tvb, hdr_len + ivlen + len),
3988                                     "WEP ICV: 0x%08x (correct)",
3989                                     tvb_get_ntohl(tvb, hdr_len + ivlen + len));
3990
3991         add_new_data_source(pinfo, next_tvb, "Decrypted WEP data");
3992       } else if (algorithm==PROTECTION_ALG_CCMP) {
3993         add_new_data_source(pinfo, next_tvb, "Decrypted CCMP data");
3994       } else if (algorithm==PROTECTION_ALG_TKIP) {
3995         add_new_data_source(pinfo, next_tvb, "Decrypted TKIP data");
3996       }
3997       /* Davide Schiera (2006-11-21) -------------------------------------      */
3998       /* Davide Schiera (2006-11-27): undefine macros and definitions   */
3999 #undef  IS_TKIP
4000 #undef  IS_CCMP
4001 #undef  PROTECTION_ALG_CCMP
4002 #undef  PROTECTION_ALG_TKIP
4003 #undef  PROTECTION_ALG_WEP
4004       /* Davide Schiera --------------------------------------------------      */
4005     }
4006
4007     /*
4008      * WEP decryption successful!
4009      *
4010      * Use the tvbuff we got back from the decryption; the data starts at
4011      * the beginning.  The lengths are already correct for the decoded WEP
4012      * payload.
4013      */
4014     hdr_len = 0;
4015
4016   } else {
4017     /*
4018      * Not a WEP-encrypted frame; just use the data from the tvbuff
4019      * handed to us.
4020      *
4021      * The payload starts at "hdr_len" (i.e., just past the 802.11
4022      * MAC header), the length of data in the tvbuff following the
4023      * 802.11 header is "len", and the length of data in the packet
4024      * following the 802.11 header is "reported_len".
4025      */
4026     next_tvb = tvb;
4027   }
4028
4029   /*
4030    * Do defragmentation if "wlan_defragment" is true, and we have more
4031    * fragments or this isn't the first fragment.
4032    *
4033    * We have to do some special handling to catch frames that
4034    * have the "More Fragments" indicator not set but that
4035    * don't show up as reassembled and don't have any other
4036    * fragments present.  Some networking interfaces appear
4037    * to do reassembly even when you're capturing raw packets
4038    * *and* show the reassembled packet without the "More
4039    * Fragments" indicator set *but* with a non-zero fragment
4040    * number.
4041    *
4042    * "fragment_add_seq_802_11()" handles that; we want to call it
4043    * even if we have a short frame, so that it does those checks - if
4044    * the frame is short, it doesn't do reassembly on it.
4045    *
4046    * (This could get some false positives if we really *did* only
4047    * capture the last fragment of a fragmented packet, but that's
4048    * life.)
4049    */
4050   save_fragmented = pinfo->fragmented;
4051   if (wlan_defragment && (more_frags || frag_number != 0)) {
4052     fragment_data *fd_head;
4053
4054     /*
4055      * If we've already seen this frame, look it up in the
4056      * table of reassembled packets, otherwise add it to
4057      * whatever reassembly is in progress, if any, and see
4058      * if it's done.
4059      */
4060     fd_head = fragment_add_seq_802_11(next_tvb, hdr_len, pinfo, seq_number,
4061                                      wlan_fragment_table,
4062                                      wlan_reassembled_table,
4063                                      frag_number,
4064                                      reported_len,
4065                                      more_frags);
4066     next_tvb = process_reassembled_data(tvb, hdr_len, pinfo,
4067                                         "Reassembled 802.11", fd_head,
4068                                         &frag_items, NULL, hdr_tree);
4069   } else {
4070     /*
4071      * If this is the first fragment, dissect its contents, otherwise
4072      * just show it as a fragment.
4073      */
4074     if (frag_number != 0) {
4075       /* Not the first fragment - don't dissect it. */
4076       next_tvb = NULL;
4077     } else {
4078       /* First fragment, or not fragmented.  Dissect what we have here. */
4079
4080       /* Get a tvbuff for the payload. */
4081       next_tvb = tvb_new_subset (next_tvb, hdr_len, len, reported_len);
4082
4083       /*
4084        * If this is the first fragment, but not the only fragment,
4085        * tell the next protocol that.
4086        */
4087       if (more_frags)
4088         pinfo->fragmented = TRUE;
4089       else
4090         pinfo->fragmented = FALSE;
4091     }
4092   }
4093
4094   if (next_tvb == NULL) {
4095     /* Just show this as an incomplete fragment. */
4096     if (check_col(pinfo->cinfo, COL_INFO))
4097       col_set_str(pinfo->cinfo, COL_INFO, "Fragmented IEEE 802.11 frame");
4098     next_tvb = tvb_new_subset (tvb, hdr_len, len, reported_len);
4099     call_dissector(data_handle, next_tvb, pinfo, tree);
4100     pinfo->fragmented = save_fragmented;
4101     goto end_of_wlan;
4102   }
4103
4104   switch (FCF_FRAME_TYPE (fcf))
4105     {
4106
4107     case MGT_FRAME:
4108       dissect_ieee80211_mgt (fcf, next_tvb, pinfo, tree);
4109       break;
4110
4111
4112     case DATA_FRAME:
4113       /* I guess some bridges take Netware Ethernet_802_3 frames,
4114          which are 802.3 frames (with a length field rather than
4115          a type field, but with no 802.2 header in the payload),
4116          and just stick the payload into an 802.11 frame.  I've seen
4117          captures that show frames of that sort.
4118
4119          We also handle some odd form of encapsulation in which a
4120          complete Ethernet frame is encapsulated within an 802.11
4121          data frame, with no 802.2 header.  This has been seen
4122          from some hardware.
4123
4124          So, if the packet doesn't start with 0xaa 0xaa:
4125
4126            we first use the same scheme that linux-wlan-ng does to detect
4127            those encapsulated Ethernet frames, namely looking to see whether
4128            the frame either starts with 6 octets that match the destination
4129            address from the 802.11 header or has 6 octets that match the
4130            source address from the 802.11 header following the first 6 octets,
4131            and, if so, treat it as an encapsulated Ethernet frame;
4132
4133            otherwise, we use the same scheme that we use in the Ethernet
4134            dissector to recognize Netware 802.3 frames, namely checking
4135            whether the packet starts with 0xff 0xff and, if so, treat it
4136            as an encapsulated IPX frame. */
4137       encap_type = ENCAP_802_2;
4138       TRY {
4139         octet1 = tvb_get_guint8(next_tvb, 0);
4140         octet2 = tvb_get_guint8(next_tvb, 1);
4141         if (octet1 != 0xaa || octet2 != 0xaa) {
4142           src = tvb_get_ptr (next_tvb, 6, 6);
4143           dst = tvb_get_ptr (next_tvb, 0, 6);
4144           if (memcmp(src, pinfo->dl_src.data, 6) == 0 ||
4145               memcmp(dst, pinfo->dl_dst.data, 6) == 0)
4146             encap_type = ENCAP_ETHERNET;
4147           else if (octet1 == 0xff && octet2 == 0xff)
4148             encap_type = ENCAP_IPX;
4149         }
4150       }
4151       CATCH2(BoundsError, ReportedBoundsError) {
4152             ; /* do nothing */
4153
4154       }
4155       ENDTRY;
4156
4157       switch (encap_type) {
4158
4159       case ENCAP_802_2:
4160         call_dissector(llc_handle, next_tvb, pinfo, tree);
4161         break;
4162
4163       case ENCAP_ETHERNET:
4164         call_dissector(eth_withoutfcs_handle, next_tvb, pinfo, tree);
4165         break;
4166
4167       case ENCAP_IPX:
4168         call_dissector(ipx_handle, next_tvb, pinfo, tree);
4169         break;
4170       }
4171       break;
4172     }
4173   pinfo->fragmented = save_fragmented;
4174
4175   end_of_wlan:
4176   tap_queue_packet(wlan_tap, pinfo, whdr);
4177 }
4178
4179 /*
4180  * Dissect 802.11 with a variable-length link-layer header.
4181  */
4182 static void
4183 dissect_ieee80211 (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
4184 {
4185   dissect_ieee80211_common (tvb, pinfo, tree, FALSE, FALSE,
4186       pinfo->pseudo_header->ieee_802_11.fcs_len, FALSE, FALSE);
4187 }
4188
4189 /*
4190  * Dissect 802.11 with a variable-length link-layer header and data padding.
4191  */
4192 static void
4193 dissect_ieee80211_datapad (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
4194 {
4195   dissect_ieee80211_common (tvb, pinfo, tree, FALSE, FALSE,
4196       pinfo->pseudo_header->ieee_802_11.fcs_len, FALSE, TRUE);
4197 }
4198
4199 /*
4200  * Dissect 802.11 with a variable-length link-layer header and a pseudo-
4201  * header containing radio information.
4202  */
4203 static void
4204 dissect_ieee80211_radio (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
4205 {
4206   dissect_ieee80211_common (tvb, pinfo, tree, FALSE, TRUE,
4207      pinfo->pseudo_header->ieee_802_11.fcs_len, FALSE, FALSE);
4208 }
4209
4210 /*
4211  * Dissect 802.11 with a variable-length link-layer header and a byte-swapped
4212  * control field (some hardware sends out LWAPP-encapsulated 802.11
4213  * packets with the control field byte swapped).
4214  */
4215 static void
4216 dissect_ieee80211_bsfc (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
4217 {
4218   dissect_ieee80211_common (tvb, pinfo, tree, FALSE, FALSE, 0, TRUE, FALSE);
4219 }
4220
4221 /*
4222  * Dissect 802.11 with a fixed-length link-layer header (padded to the
4223  * maximum length).
4224  */
4225 static void
4226 dissect_ieee80211_fixed (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
4227 {
4228   dissect_ieee80211_common (tvb, pinfo, tree, TRUE, FALSE, 0, FALSE, FALSE);
4229 }
4230
4231 static void
4232 wlan_defragment_init(void)
4233 {
4234   fragment_table_init(&wlan_fragment_table);
4235   reassembled_table_init(&wlan_reassembled_table);
4236 }
4237
4238 void
4239 proto_register_ieee80211 (void)
4240 {
4241   int i;
4242   GString *key_name, *key_title, *key_desc;
4243
4244   static const value_string frame_type[] = {
4245     {MGT_FRAME,     "Management frame"},
4246     {CONTROL_FRAME, "Control frame"},
4247     {DATA_FRAME,    "Data frame"},
4248     {0,             NULL}
4249   };
4250
4251   static const value_string tofrom_ds[] = {
4252     {0,                       "Not leaving DS or network is operating "
4253       "in AD-HOC mode (To DS: 0 From DS: 0)"},
4254     {FLAG_TO_DS,              "Frame from STA to DS via an AP (To DS: 1 "
4255       "From DS: 0)"},
4256     {FLAG_FROM_DS,            "Frame from DS to a STA via AP(To DS: 0 "
4257       "From DS: 1)"},
4258     {FLAG_TO_DS|FLAG_FROM_DS, "Frame part of WDS from one AP to another "
4259       "AP (To DS: 1 From DS: 1)"},
4260     {0, NULL}
4261   };
4262
4263   static const true_false_string tods_flag = {
4264     "Frame is entering DS",
4265     "Frame is not entering DS"
4266   };
4267
4268   static const true_false_string fromds_flag = {
4269     "Frame is exiting DS",
4270     "Frame is not exiting DS"
4271   };
4272
4273   static const true_false_string more_frags = {
4274     "More fragments follow",
4275     "This is the last fragment"
4276   };
4277
4278   static const true_false_string retry_flags = {
4279     "Frame is being retransmitted",
4280     "Frame is not being retransmitted"
4281   };
4282
4283   static const true_false_string pm_flags = {
4284     "STA will go to sleep",
4285     "STA will stay up"
4286   };
4287
4288   static const true_false_string md_flags = {
4289     "Data is buffered for STA at AP",
4290     "No data buffered"
4291   };
4292
4293   static const true_false_string protected_flags = {
4294     "Data is protected",
4295     "Data is not protected"
4296   };
4297
4298   static const true_false_string order_flags = {
4299     "Strictly ordered",
4300     "Not strictly ordered"
4301   };
4302
4303   static const true_false_string cf_ess_flags = {
4304     "Transmitter is an AP",
4305     "Transmitter is a STA"
4306   };
4307
4308
4309   static const true_false_string cf_privacy_flags = {
4310     "AP/STA can support WEP",
4311     "AP/STA cannot support WEP"
4312   };
4313
4314   static const true_false_string cf_preamble_flags = {
4315     "Short preamble allowed",
4316     "Short preamble not allowed"
4317   };
4318
4319   static const true_false_string cf_pbcc_flags = {
4320     "PBCC modulation allowed",
4321     "PBCC modulation not allowed"
4322   };
4323
4324   static const true_false_string cf_agility_flags = {
4325     "Channel agility in use",
4326     "Channel agility not in use"
4327   };
4328
4329   static const true_false_string short_slot_time_flags = {
4330     "Short slot time in use",
4331     "Short slot time not in use"
4332   };
4333
4334   static const true_false_string dsss_ofdm_flags = {
4335     "DSSS-OFDM modulation allowed",
4336     "DSSS-OFDM modulation not allowed"
4337   };
4338
4339   static const true_false_string cf_spec_man_flags = {
4340     "dot11SpectrumManagementRequired TRUE",
4341     "dot11SpectrumManagementRequired FALSE",
4342   };
4343
4344   static const true_false_string cf_apsd_flags = {
4345     "apsd implemented",
4346     "apsd not implemented",
4347   };
4348
4349   static const true_false_string cf_del_blk_ack_flags = {
4350     "delayed block ack implemented",
4351     "delayed block ack not implented",
4352   };
4353
4354   static const true_false_string cf_imm_blk_ack_flags = {
4355     "immediate block ack implemented",
4356     "immediate block ack not implented",
4357   };
4358   static const true_false_string cf_ibss_flags = {
4359     "Transmitter belongs to an IBSS",
4360     "Transmitter belongs to a BSS"
4361   };
4362
4363   static const true_false_string eosp_flag = {
4364     "End of service period",
4365     "Service period"
4366   };
4367
4368   static const value_string sta_cf_pollable[] = {
4369     {0x00, "Station is not CF-Pollable"},
4370     {0x02, "Station is CF-Pollable, "
4371      "not requesting to be placed on the  CF-polling list"},
4372     {0x01, "Station is CF-Pollable, "
4373      "requesting to be placed on the CF-polling list"},
4374     {0x03, "Station is CF-Pollable, requesting never to be polled"},
4375     {0x0200, "QSTA requesting association in QBSS"},
4376     {0, NULL}
4377   };
4378
4379   static const value_string ap_cf_pollable[] = {
4380     {0x00, "No point coordinator at AP"},
4381     {0x02, "Point coordinator at AP for delivery only (no polling)"},
4382     {0x01, "Point coordinator at AP for delivery and polling"},
4383     {0x03, "Reserved"},
4384     {0x0200, "QAP (HC) does not use CFP for delivery of unicast data type frames"},
4385     {0x0202, "QAP (HC) uses CFP for delivery, but does not send CF-Polls to non-QoS STAs"},
4386     {0x0201, "QAP (HC) uses CFP for delivery, and sends CF-Polls to non-QoS STAs"},
4387     {0x0203, "Reserved"},
4388     {0, NULL}
4389   };
4390
4391
4392   static const value_string auth_alg[] = {
4393     {0x00, "Open System"},
4394     {0x01, "Shared key"},
4395     {0x80, "Network EAP"},      /* Cisco proprietary? */
4396     {0, NULL}
4397   };
4398
4399   static const value_string reason_codes[] = {
4400     {0x00, "Reserved"},
4401     {0x01, "Unspecified reason"},
4402     {0x02, "Previous authentication no longer valid"},
4403     {0x03, "Deauthenticated because sending STA is leaving (has left) "
4404      "IBSS or ESS"},
4405     {0x04, "Disassociated due to inactivity"},
4406     {0x05, "Disassociated because AP is unable to handle all currently "
4407      "associated stations"},
4408     {0x06, "Class 2 frame received from nonauthenticated station"},
4409     {0x07, "Class 3 frame received from nonassociated station"},
4410     {0x08, "Disassociated because sending STA is leaving (has left) BSS"},
4411     {0x09, "Station requesting (re)association is not authenticated with "
4412       "responding station"},
4413     {0x0A, "Disassociated because the information in the Power Capability "
4414       "element is unacceptable"},
4415     {0x0B, "Disassociated because the information in the Supported"
4416       "Channels element is unacceptable"},
4417     {0x0D, "Invalid Information Element"},
4418     {0x0E, "Michael MIC failure"},
4419     {0x0F, "4-Way Handshake timeout"},
4420     {0x10, "Group key update timeout"},
4421     {0x11, "Information element in 4-Way Handshake different from "
4422      "(Re)Association Request/Probe Response/Beacon"},
4423     {0x12, "Group Cipher is not valid"},
4424     {0x13, "Pairwise Cipher is not valid"},
4425     {0x14, "AKMP is not valid"},
4426     {0x15, "Unsupported RSN IE version"},
4427     {0x16, "Invalid RSN IE Capabilities"},
4428     {0x17, "IEEE 802.1X Authentication failed"},
4429     {0x18, "Cipher suite is rejected per security policy"},
4430     {0x20, "Disassociated for unspecified, QoS-related reason"},
4431     {0x21, "Disassociated because QAP lacks sufficient bandwidth for this QSTA"},
4432     {0x22, "Disassociated because of excessive number of frames that need to be "
4433       "acknowledged, but are not acknowledged for AP transmissions and/or poor "
4434         "channel conditions"},
4435     {0x23, "Disassociated because QSTA is transmitting outside the limits of its TXOPs"},
4436     {0x24, "Requested from peer QSTA as the QSTA is leaving the QBSS (or resetting)"},
4437     {0x25, "Requested from peer QSTA as it does not want to use the mechanism"},
4438     {0x26, "Requested from peer QSTA as the QSTA received frames using the mechanism "
4439       "for which a set up is required"},
4440     {0x27, "Requested from peer QSTA due to time out"},
4441     {0x2D, "Peer QSTA does not support the requested cipher suite"},
4442     {0x00, NULL}
4443   };
4444
4445
4446   static const value_string status_codes[] = {
4447     {0x00, "Successful"},
4448     {0x01, "Unspecified failure"},
4449     {0x0A, "Cannot support all requested capabilities in the "
4450      "Capability information field"},
4451     {0x0B, "Reassociation denied due to inability to confirm that "
4452      "association exists"},
4453     {0x0C, "Association denied due to reason outside the scope of this "
4454      "standard"},
4455
4456     {0x0D, "Responding station does not support the specified authentication "
4457      "algorithm"},
4458     {0x0E, "Received an Authentication frame with authentication sequence "
4459      "transaction sequence number out of expected sequence"},
4460     {0x0F, "Authentication rejected because of challenge failure"},
4461     {0x10, "Authentication rejected due to timeout waiting for next "
4462      "frame in sequence"},
4463     {0x11, "Association denied because AP is unable to handle additional "
4464      "associated stations"},
4465     {0x12, "Association denied due to requesting station not supporting all "
4466      "of the datarates in the BSSBasicServiceSet Parameter"},
4467     {0x13, "Association denied due to requesting station not supporting "
4468      "short preamble operation"},
4469     {0x14, "Association denied due to requesting station not supporting "
4470      "PBCC encoding"},
4471     {0x15, "Association denied due to requesting station not supporting "
4472      "channel agility"},
4473     {0x16, "Association request rejected because Spectrum Management"
4474       "capability is required"},
4475     {0x17, "Association request rejected because the information in the"
4476       "Power Capability element is unacceptable"},
4477     {0x18, "Association request rejected because the information in the"
4478       "Supported Channels element is unacceptable"},
4479     {0x19, "Association denied due to requesting station not supporting "
4480      "short slot operation"},
4481     {0x1A, "Association denied due to requesting station not supporting "
4482      "DSSS-OFDM operation"},
4483     {0x20, "Unspecified, QoS-related failure"},
4484     {0x21, "Association denied due to QAP having insufficient bandwidth "
4485       "to handle another QSTA"},
4486     {0x22, "Association denied due to excessive frame loss rates and/or "
4487       "poor conditions on current operating channel"},
4488     {0x23, "Association (with QBSS) denied due to requesting station not "
4489       "supporting the QoS facility"},
4490     {0x24, "Association denied due to requesting station not supporting "
4491       "Block Ack"},
4492     {0x25, "The request has been declined."},
4493     {0x26, "The request has not been successful as one or more parameters "
4494       "have invalid values."},
4495     {0x27, "The TS has not been created because the request cannot be honored. "
4496       "However, a suggested TSPEC is provided so that the initiating QSTA may "
4497         "attempt to set another TS with the suggested changes to the TSPEC."},
4498     {0x28, "Invalid Information Element"},
4499     {0x29, "Group Cipher is not valid"},
4500     {0x2A, "Pairwise Cipher is not valid"},
4501     {0x2B, "AKMP is not valid"},
4502     {0x2C, "Unsupported RSN IE version"},
4503     {0x2D, "Invalid RSN IE Capabilities"},
4504     {0x2E, "Cipher suite is rejected per security policy"},
4505     {0x2F, "The TS has not been created. However, the HC may be capable of "
4506       "creating a TS, in response to a request, after the time indicated in the TS Delay element."},
4507     {0x30, "Direct Link is not allowed in the BSS by policy"},
4508     {0x31, "Destination STA is not present within this QBSS."},
4509     {0x32, "The Destination STA is not a QSTA."},
4510     {0x00, NULL}
4511   };
4512
4513   static const value_string category_codes[] = {
4514     {CAT_SPECTRUM_MGMT, "Spectrum Management"},
4515     {CAT_QOS, "QoS"},
4516     {CAT_DLS, "DLS"},
4517     {CAT_BLOCK_ACK, "Block Ack"},
4518     {CAT_MGMT_NOTIFICATION, "Management notification frame"},
4519     {0, NULL}
4520   };
4521
4522   static const value_string action_codes[] ={
4523     {SM_ACTION_MEASUREMENT_REQUEST, "Measurement Request"},
4524     {SM_ACTION_MEASUREMENT_REPORT, "Measurement Report"},
4525     {SM_ACTION_TPC_REQUEST, "TPC Request"},
4526     {SM_ACTION_TPC_REPORT, "TPC Report"},
4527     {SM_ACTION_CHAN_SWITCH_ANNC, "Channel Switch Announcement"},
4528     {0, NULL}
4529   };
4530
4531   static const value_string wme_action_codes[] = {
4532     {0x00, "Setup request"},
4533     {0x01, "Setup response"},
4534     {0x02, "Teardown"},
4535     {0x00, NULL}
4536   };
4537
4538   static const value_string wme_status_codes[] = {
4539     {0x00, "Admission accepted"},
4540     {0x01, "Invalid parameters"},
4541     {0x03, "Refused"},
4542     {0x00, NULL}
4543   };
4544
4545   static const value_string ack_policy[] = {
4546     {0x00, "Normal Ack"},
4547     {0x01, "No Ack"},
4548     {0x02, "No explicit Ack"},
4549     {0x03, "Block Ack"},
4550     {0x00, NULL}
4551   };
4552
4553   static const value_string qos_action_codes[] = {
4554     {SM_ACTION_ADDTS_REQUEST, "ADDTS Request"},
4555     {SM_ACTION_ADDTS_RESPONSE, "ADDTS Response"},
4556     {SM_ACTION_DELTS, "DELTS"},
4557     {SM_ACTION_QOS_SCHEDULE, "Schedule"},
4558     {0, NULL}
4559   };
4560
4561   static const value_string dls_action_codes[] = {
4562     {SM_ACTION_DLS_REQUEST, "DLS Request"},
4563     {SM_ACTION_DLS_RESPONSE, "DLS Response"},
4564     {SM_ACTION_DLS_TEARDOWN, "DLS Teardown"},
4565     {0, NULL}
4566   };
4567
4568   static const value_string tsinfo_type[] = {
4569     {0x0, "Aperiodic or unspecified Traffic"},
4570     {0x1, "Periodic Traffic"},
4571     {0, NULL}
4572   };
4573
4574   static const value_string tsinfo_direction[] = {
4575     {0x00, "Uplink"},
4576     {0x01, "Downlink"},
4577     {0x02, "Direct link"},
4578     {0x03, "Bidirectional link"},
4579     {0, NULL}
4580   };
4581
4582   static const value_string tsinfo_access[] = {
4583     {0x00, "Reserved"},
4584     {0x01, "EDCA"},
4585     {0x02, "HCCA"},
4586     {0x03, "HEMM"},
4587     {0, NULL}
4588   };
4589
4590   static const value_string qos_up[] = {
4591     {0x00, "Best Effort"},
4592     {0x01, "Background"},
4593     {0x02, "Spare"},
4594     {0x03, "Excellent Effort"},
4595     {0x04, "Controlled Load"},
4596     {0x05, "Video"},
4597     {0x06, "Voice"},
4598     {0x07, "Network Control"},
4599     {0, NULL}
4600   };
4601
4602   static const value_string classifier_type[] = {
4603     {0x00, "Ethernet parameters"},
4604     {0x01, "TCP/UDP IP parameters"},
4605     {0x02, "IEEE 802.1D/Q parameters"},
4606     {0, NULL}
4607   };
4608
4609   static const value_string tclas_process[] = {
4610     {0x00, "Incoming MSDU's higher layer parameters have to match to the parameters in all associated TCLAS elements."},
4611     {0x01, "Incoming MSDU's higher layer parameters have to match to at least one of the associated TCLAS elements."},
4612     {0x02, "Incoming MSDU's that do not belong to any other TS are classified to the TS for which this TCLAS Processing element is used. In this case, there will not be any associated TCLAS elements."},
4613     {0, NULL}
4614   };
4615
4616   static hf_register_info hf[] = {
4617     {&hf_data_rate,
4618      {"Data Rate", "wlan.data_rate", FT_UINT8, BASE_DEC, NULL, 0,
4619       "Data rate (.5 Mb/s units)", HFILL }},
4620
4621     {&hf_channel,
4622      {"Channel", "wlan.channel", FT_UINT8, BASE_DEC, NULL, 0,
4623       "Radio channel", HFILL }},
4624
4625     {&hf_signal_strength,
4626      {"Signal Strength", "wlan.signal_strength", FT_UINT8, BASE_DEC, NULL, 0,
4627       "Signal strength (percentage)", HFILL }},
4628
4629     {&hf_fc_field,
4630      {"Frame Control Field", "wlan.fc", FT_UINT16, BASE_HEX, NULL, 0,
4631       "MAC Frame control", HFILL }},
4632
4633     {&hf_fc_proto_version,
4634      {"Version", "wlan.fc.version", FT_UINT8, BASE_DEC, NULL, 0,
4635       "MAC Protocol version", HFILL }}, /* 0 */
4636
4637     {&hf_fc_frame_type,
4638      {"Type", "wlan.fc.type", FT_UINT8, BASE_DEC, VALS(frame_type), 0,
4639       "Frame type", HFILL }},
4640
4641     {&hf_fc_frame_subtype,
4642      {"Subtype", "wlan.fc.subtype", FT_UINT8, BASE_DEC, NULL, 0,
4643       "Frame subtype", HFILL }},        /* 2 */
4644
4645     {&hf_fc_frame_type_subtype,
4646      {"Type/Subtype", "wlan.fc.type_subtype", FT_UINT16, BASE_DEC, VALS(frame_type_subtype_vals), 0,
4647       "Type and subtype combined", HFILL }},
4648
4649     {&hf_fc_flags,
4650      {"Protocol Flags", "wlan.flags", FT_UINT8, BASE_HEX, NULL, 0,
4651       "Protocol flags", HFILL }},
4652
4653     {&hf_fc_data_ds,
4654      {"DS status", "wlan.fc.ds", FT_UINT8, BASE_HEX, VALS (&tofrom_ds), 0,
4655       "Data-frame DS-traversal status", HFILL }},       /* 3 */
4656
4657     {&hf_fc_to_ds,
4658      {"To DS", "wlan.fc.tods", FT_BOOLEAN, 8, TFS (&tods_flag), FLAG_TO_DS,
4659       "To DS flag", HFILL }},           /* 4 */
4660
4661     {&hf_fc_from_ds,
4662      {"From DS", "wlan.fc.fromds", FT_BOOLEAN, 8, TFS (&fromds_flag), FLAG_FROM_DS,
4663       "From DS flag", HFILL }},         /* 5 */
4664
4665     {&hf_fc_more_frag,
4666      {"More Fragments", "wlan.fc.frag", FT_BOOLEAN, 8, TFS (&more_frags), FLAG_MORE_FRAGMENTS,
4667       "More Fragments flag", HFILL }},  /* 6 */
4668
4669     {&hf_fc_retry,
4670      {"Retry", "wlan.fc.retry", FT_BOOLEAN, 8, TFS (&retry_flags), FLAG_RETRY,
4671       "Retransmission flag", HFILL }},
4672
4673     {&hf_fc_pwr_mgt,
4674      {"PWR MGT", "wlan.fc.pwrmgt", FT_BOOLEAN, 8, TFS (&pm_flags), FLAG_POWER_MGT,
4675       "Power management status", HFILL }},
4676
4677     {&hf_fc_more_data,
4678      {"More Data", "wlan.fc.moredata", FT_BOOLEAN, 8, TFS (&md_flags), FLAG_MORE_DATA,
4679       "More data flag", HFILL }},
4680
4681     {&hf_fc_protected,
4682      {"Protected flag", "wlan.fc.protected", FT_BOOLEAN, 8, TFS (&protected_flags), FLAG_PROTECTED,
4683       "Protected flag", HFILL }},
4684
4685     {&hf_fc_order,
4686      {"Order flag", "wlan.fc.order", FT_BOOLEAN, 8, TFS (&order_flags), FLAG_ORDER,
4687       "Strictly ordered flag", HFILL }},
4688
4689     {&hf_assoc_id,
4690      {"Association ID","wlan.aid",FT_UINT16, BASE_DEC,NULL,0,
4691       "Association-ID field", HFILL }},
4692
4693     {&hf_did_duration,
4694      {"Duration", "wlan.duration", FT_UINT16, BASE_DEC, NULL, 0,
4695       "Duration field", HFILL }},
4696
4697     {&hf_addr_da,
4698      {"Destination address", "wlan.da", FT_ETHER, BASE_NONE, NULL, 0,
4699       "Destination Hardware Address", HFILL }},
4700
4701     {&hf_addr_sa,
4702      {"Source address", "wlan.sa", FT_ETHER, BASE_NONE, NULL, 0,
4703       "Source Hardware Address", HFILL }},
4704
4705     { &hf_addr,
4706       {"Source or Destination address", "wlan.addr", FT_ETHER, BASE_NONE, NULL, 0,
4707        "Source or Destination Hardware Address", HFILL }},
4708
4709     {&hf_addr_ra,
4710      {"Receiver address", "wlan.ra", FT_ETHER, BASE_NONE, NULL, 0,
4711       "Receiving Station Hardware Address", HFILL }},
4712
4713     {&hf_addr_ta,
4714      {"Transmitter address", "wlan.ta", FT_ETHER, BASE_NONE, NULL, 0,
4715       "Transmitting Station Hardware Address", HFILL }},
4716
4717     {&hf_addr_bssid,
4718      {"BSS Id", "wlan.bssid", FT_ETHER, BASE_NONE, NULL, 0,
4719       "Basic Service Set ID", HFILL }},
4720
4721     {&hf_frag_number,
4722      {"Fragment number", "wlan.frag", FT_UINT16, BASE_DEC, NULL, 0,
4723       "Fragment number", HFILL }},
4724
4725     {&hf_seq_number,
4726      {"Sequence number", "wlan.seq", FT_UINT16, BASE_DEC, NULL, 0,
4727       "Sequence number", HFILL }},
4728
4729     {&hf_qos_priority,
4730      {"Priority", "wlan.qos.priority", FT_UINT16, BASE_DEC, NULL, 0,
4731       "802.1D Tag", HFILL }},
4732
4733     {&hf_qos_eosp,
4734      {"EOSP", "wlan.qos.eosp", FT_BOOLEAN, 8, TFS (&eosp_flag), QOS_FLAG_EOSP,
4735       "EOSP Field", HFILL }},
4736
4737     {&hf_qos_ack_policy,
4738      {"Ack Policy", "wlan.qos.ack", FT_UINT16, BASE_HEX,  VALS (&ack_policy), 0,
4739       "Ack Policy", HFILL }},
4740
4741     {&hf_qos_field_content,
4742      {"Content", "wlan.qos.fc_content", FT_UINT16, BASE_DEC, NULL, 0,
4743       "Content1", HFILL }},
4744
4745 /*    {&hf_qos_buffer_state,
4746      {"QAP PS buffer State", "wlan.qos.ps_buf_state", FT_UINT16, BASE_DEC, NULL, 0,
4747       "QAP PS buffer State", HFILL }},
4748
4749     {&hf_qos_txop_dur_req,
4750      {"TXOP Duration Requested", "wlan.qos.txop_dur_req", FT_UINT16, BASE_DEC, NULL, 0,
4751       "TXOP Duration Requested", HFILL }},
4752
4753     {&hf_qos_queue_size,
4754      {"Queue Size", "wlan.qos.queue_size", FT_UINT16, BASE_DEC, NULL, 0,
4755       "Queue Size", HFILL }},*/
4756
4757     {&hf_fcs,
4758      {"Frame check sequence", "wlan.fcs", FT_UINT32, BASE_HEX,
4759       NULL, 0, "FCS", HFILL }},
4760
4761     {&hf_fcs_good,
4762      {"Good", "wlan.fcs_good", FT_BOOLEAN, BASE_NONE,
4763       NULL, 0, "True if the FCS is correct", HFILL }},
4764
4765     {&hf_fcs_bad,
4766      {"Bad", "wlan.fcs_bad", FT_BOOLEAN, BASE_NONE,
4767       NULL, 0, "True if the FCS is incorrect", HFILL }},
4768
4769     {&hf_fragment_overlap,
4770       {"Fragment overlap", "wlan.fragment.overlap", FT_BOOLEAN, BASE_NONE,
4771        NULL, 0x0, "Fragment overlaps with other fragments", HFILL }},
4772
4773     {&hf_fragment_overlap_conflict,
4774       {"Conflicting data in fragment overlap", "wlan.fragment.overlap.conflict",
4775        FT_BOOLEAN, BASE_NONE, NULL, 0x0,
4776        "Overlapping fragments contained conflicting data", HFILL }},
4777
4778     {&hf_fragment_multiple_tails,
4779       {"Multiple tail fragments found", "wlan.fragment.multipletails",
4780        FT_BOOLEAN, BASE_NONE, NULL, 0x0,
4781        "Several tails were found when defragmenting the packet", HFILL }},
4782
4783     {&hf_fragment_too_long_fragment,
4784       {"Fragment too long", "wlan.fragment.toolongfragment",
4785        FT_BOOLEAN, BASE_NONE, NULL, 0x0,
4786        "Fragment contained data past end of packet", HFILL }},
4787
4788     {&hf_fragment_error,
4789       {"Defragmentation error", "wlan.fragment.error",
4790        FT_FRAMENUM, BASE_NONE, NULL, 0x0,
4791        "Defragmentation error due to illegal fragments", HFILL }},
4792
4793     {&hf_fragment,
4794       {"802.11 Fragment", "wlan.fragment", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
4795        "802.11 Fragment", HFILL }},
4796
4797     {&hf_fragments,
4798       {"802.11 Fragments", "wlan.fragments", FT_NONE, BASE_NONE, NULL, 0x0,
4799        "802.11 Fragments", HFILL }},
4800
4801     {&hf_reassembled_in,
4802       {"Reassembled 802.11 in frame", "wlan.reassembled_in", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
4803        "This 802.11 packet is reassembled in this frame", HFILL }},
4804
4805     {&hf_wep_iv,
4806      {"Initialization Vector", "wlan.wep.iv", FT_UINT24, BASE_HEX, NULL, 0,
4807       "Initialization Vector", HFILL }},
4808
4809     {&hf_wep_iv_weak,
4810      {"Weak IV", "wlan.wep.weakiv", FT_BOOLEAN,BASE_NONE, NULL,0x0,
4811        "Weak IV",HFILL}},
4812
4813     {&hf_tkip_extiv,
4814      {"TKIP Ext. Initialization Vector", "wlan.tkip.extiv", FT_STRING,
4815       BASE_HEX, NULL, 0, "TKIP Extended Initialization Vector", HFILL }},
4816
4817     {&hf_ccmp_extiv,
4818      {"CCMP Ext. Initialization Vector", "wlan.ccmp.extiv", FT_STRING,
4819       BASE_HEX, NULL, 0, "CCMP Extended Initialization Vector", HFILL }},
4820
4821     {&hf_wep_key,
4822      {"Key Index", "wlan.wep.key", FT_UINT8, BASE_DEC, NULL, 0,
4823       "Key Index", HFILL }},
4824
4825     {&hf_wep_icv,
4826      {"WEP ICV", "wlan.wep.icv", FT_UINT32, BASE_HEX, NULL, 0,
4827       "WEP ICV", HFILL }},
4828   };
4829
4830   static const true_false_string rsn_preauth_flags = {
4831     "Transmitter supports pre-authentication",
4832     "Transmitter does not support pre-authentication"
4833   };
4834
4835   static const true_false_string rsn_no_pairwise_flags = {
4836     "Transmitter cannot support WEP default key 0 simultaneously with "
4837     "Pairwise key",
4838     "Transmitter can support WEP default key 0 simultaneously with "
4839     "Pairwise key"
4840   };
4841
4842   static const value_string rsn_cap_replay_counter[] = {
4843     {0x00, "1 replay counter per PTKSA/GTKSA/STAKeySA"},
4844     {0x01, "2 replay counters per PTKSA/GTKSA/STAKeySA"},
4845     {0x02, "4 replay counters per PTKSA/GTKSA/STAKeySA"},
4846     {0x03, "16 replay counters per PTKSA/GTKSA/STAKeySA"},
4847     {0, NULL}
4848   };
4849
4850   static const true_false_string ht_adv_coding_flag = {
4851       "Transmitter supports Advanced Coding",
4852       "Transmitter does not support Advanced Coding"
4853   };
4854
4855   static const true_false_string ht_chan_width_flag = {
4856       "Transmitter supports 20MHz and 40MHz operation",
4857       "Transmitter only supports 20MHz operation"
4858   };
4859
4860   static const value_string ht_mimo_pwsave_flag[] = {
4861     {0x00, "Static MIMO power save mode"},
4862     {0x02, "Dynamic MIMO power save mode"},
4863     {0x01, "Reserved"},
4864     {0x03, "MIMO enabled"},
4865     {0x00, NULL}
4866   };
4867
4868   static const true_false_string ht_green_flag = {
4869       "Transmitter is able to receive PPDUs with GF preamble",
4870       "Transmitter is not able to receive PPDUs with GF preamble"
4871   };
4872
4873   static const true_false_string ht_tf_flag = {
4874       "Supported",
4875       "Not Supported "
4876   };
4877
4878   static const value_string ht_rx_stbc_flag[] = {
4879     {0x00, "No Rx STBC support"},
4880     {0x01, "Rx support of one spatial stream"},
4881     {0x02, "Rx support of one and two spatial streams"},
4882     {0x03, "Rx support of one, two, and three spatial streams"},
4883     {0x00, NULL}
4884   };
4885
4886   static const true_false_string ht_block_ack_flag = {
4887       "Transmitter supports N-Delayed BlockAck",
4888       "Transmitter does not support N-Delayed BlockAck"
4889   };
4890
4891   static const true_false_string ht_max_amsdu_flag = {
4892       "7935 bytes",
4893       "3839 bytes"
4894   };
4895
4896   static const true_false_string ht_dss_cck_40_flag = {
4897       "Will/Can use DSSS/CCK rates",
4898       "Won't/Can't use of DSSS/CCK rates"
4899   };
4900
4901   static const true_false_string ht_psmp_flag = {
4902       "Will/Can support PSMP ",
4903       "Won't/Can't support PSMP "
4904   };
4905
4906   static const true_false_string ht_stbc_flag = {
4907       "Will/Can Support STBC Control Frames ",
4908       "Won't/Can't support STBC Control Frames "
4909   };
4910
4911   static const value_string macparm_mpdu_density_flags[] = {
4912     {0x00, "no restriction"},
4913     {0x01, "1/8 usec"},
4914     {0x02, "1/4 usec"},
4915     {0x03, "1/2 usec"},
4916     {0x04, "1 usec"},
4917     {0x05, "2 usec"},
4918     {0x06, "4 usec"},
4919     {0x07, "8 usec"},
4920     {0x00, NULL}
4921   };
4922
4923   static const value_string htex_transtime_flag[] = {
4924     {0x00, "Reserved"},
4925     {0x01, "400 usec"},
4926     {0x02, "1.5 msec"},
4927     {0x03, "5 msec"},
4928     {0x00, NULL}
4929   };
4930
4931   static const value_string htex_mcs_flag[] = {
4932     {0x00, "STA does not provide MCS feedback"},
4933     {0x01, "Reserved"},
4934     {0x02, "STA provides only unsolicited MCS feedback"},
4935     {0x03, "STA provides MRQ and unsolicited MCS feedback"},
4936     {0x00, NULL}
4937   };
4938
4939   static const value_string txbf_calib_flag[] = {
4940     {0x00, "incapable"},
4941     {0x01, "Limited involvement, cannot initiate"},
4942     {0x02, "Limited involvement, can initiate"},
4943     {0x03, "Fully capable"},
4944     {0x00, NULL}
4945   };
4946
4947   static const value_string txbf_feedback_flag[] = {
4948     {0x00, "incapable"},
4949     {0x01, "unsolicited feedback capable"},
4950     {0x02, "immediate feedback capable"},
4951     {0x03, "aggregated feedback capable"},
4952     {0x00, NULL}
4953   };
4954
4955   static const value_string txbf_antenna_flag[] = {
4956     {0x00, "1 TX antenna sounding"},
4957     {0x01, "2 TX antenna soundin"},
4958     {0x02, "3 TX antenna soundin"},
4959     {0x03, "4 TX antenna soundin"},
4960     {0x00, NULL}
4961   };
4962
4963   static const value_string hta_ext_chan_offset_flag[] = {
4964     {0x00, "No Extension Channel"},
4965     {0x01, "Extension Channel above control channel"},
4966     {0x02, "Undefined"},
4967     {0x03, "Extension Channel below control channel"},
4968     {0x00, NULL}
4969   };
4970
4971   static const true_false_string hta_rec_tx_width_flag = {
4972       "Any channel width enabled",
4973       "Use 20MHz channel (control)"
4974   };
4975
4976   static const true_false_string hta_rifs_mode_flag = {
4977       "Use of RIFS permitted",
4978       "Use of RIFS prohibited"
4979   };
4980
4981   static const true_false_string hta_controlled_access_flag = {
4982       "Not only PSMP",
4983       "PSMP only"
4984   };
4985
4986   static const value_string hta_service_interval_flag[] = {
4987     {0x00, "5ms"},
4988     {0x01, "10ms"},
4989     {0x02, "15ms"},
4990     {0x03, "20ms"},
4991     {0x04, "25ms"},
4992     {0x05, "30ms"},
4993     {0x06, "35ms"},
4994     {0x07, "40ms"},
4995     {0x00, NULL}
4996   };
4997
4998   static const value_string hta_operating_mode_flag[] = {
4999     {0x00, "Pure HT, no protection"},
5000     {0x01, "There may be non-HT devices (control & ext channel)"},
5001     {0x02, "No non-HT is associated, but at least 1 20MHz is. protect on"},
5002     {0x03, "Mixed: no non-HT is associated, protect on"},
5003     {0x00, NULL}
5004   };
5005
5006   static const true_false_string hta_non_gf_devices_flag = {
5007       "All HT devices associated are GF capable",
5008       "One or More HT devices are not GF capable"
5009   };
5010
5011   static const true_false_string hta_dual_stbc_protection_flag = {
5012       "Dual CTS protections is used",
5013       "Regular use of RTS/CTS"
5014   };
5015
5016   static const true_false_string hta_secondary_beacon_flag = {
5017       "Secondary Beacon",
5018       "Primary Beacon"
5019   };
5020
5021   static const true_false_string hta_lsig_txop_protection_flag = {
5022       "Full Support",
5023       "Not full support"
5024   };
5025
5026   static const true_false_string hta_pco_active_flag = {
5027       "PCO is activated in the BSS",
5028       "PCO is not activated in the BSS"
5029   };
5030
5031   static const true_false_string hta_pco_phase_flag = {
5032       "Switch to 20MHz phase/keep 20MHz",
5033       "Switch to 40MHz phase/keep 40MHz"
5034   };
5035
5036
5037
5038   static hf_register_info ff[] = {
5039     {&ff_timestamp,
5040      {"Timestamp", "wlan_mgt.fixed.timestamp", FT_STRING, BASE_NONE,
5041       NULL, 0, "", HFILL }},
5042
5043     {&ff_auth_alg,
5044      {"Authentication Algorithm", "wlan_mgt.fixed.auth.alg",
5045       FT_UINT16, BASE_DEC, VALS (&auth_alg), 0, "", HFILL }},
5046
5047     {&ff_beacon_interval,
5048      {"Beacon Interval", "wlan_mgt.fixed.beacon", FT_DOUBLE, BASE_DEC, NULL, 0,
5049       "", HFILL }},
5050
5051     {&hf_fixed_parameters,
5052      {"Fixed parameters", "wlan_mgt.fixed.all", FT_UINT16, BASE_DEC, NULL, 0,
5053       "", HFILL }},
5054
5055     {&hf_tagged_parameters,
5056      {"Tagged parameters", "wlan_mgt.tagged.all", FT_UINT16, BASE_DEC, NULL, 0,
5057       "", HFILL }},
5058
5059     {&ff_capture,
5060      {"Capabilities", "wlan_mgt.fixed.capabilities", FT_UINT16, BASE_HEX, NULL, 0,
5061       "Capability information", HFILL }},
5062
5063     {&ff_cf_ess,
5064      {"ESS capabilities", "wlan_mgt.fixed.capabilities.ess",
5065       FT_BOOLEAN, 16, TFS (&cf_ess_flags), 0x0001, "ESS capabilities", HFILL }},
5066
5067     {&ff_cf_ibss,
5068      {"IBSS status", "wlan_mgt.fixed.capabilities.ibss",
5069       FT_BOOLEAN, 16, TFS (&cf_ibss_flags), 0x0002, "IBSS participation", HFILL }},
5070
5071     {&ff_cf_sta_poll,
5072      {"CFP participation capabilities", "wlan_mgt.fixed.capabilities.cfpoll.sta",
5073       FT_UINT16, BASE_HEX, VALS (&sta_cf_pollable), 0x020C,
5074       "CF-Poll capabilities for a STA", HFILL }},
5075
5076     {&ff_cf_ap_poll,
5077      {"CFP participation capabilities", "wlan_mgt.fixed.capabilities.cfpoll.ap",
5078       FT_UINT16, BASE_HEX, VALS (&ap_cf_pollable), 0x020C,
5079       "CF-Poll capabilities for an AP", HFILL }},
5080
5081     {&ff_cf_privacy,
5082      {"Privacy", "wlan_mgt.fixed.capabilities.privacy",
5083       FT_BOOLEAN, 16, TFS (&cf_privacy_flags), 0x0010, "WEP support", HFILL }},
5084
5085     {&ff_cf_preamble,
5086      {"Short Preamble", "wlan_mgt.fixed.capabilities.preamble",
5087       FT_BOOLEAN, 16, TFS (&cf_preamble_flags), 0x0020, "Short Preamble", HFILL }},
5088
5089     {&ff_cf_pbcc,
5090      {"PBCC", "wlan_mgt.fixed.capabilities.pbcc",
5091       FT_BOOLEAN, 16, TFS (&cf_pbcc_flags), 0x0040, "PBCC Modulation", HFILL }},
5092
5093     {&ff_cf_agility,
5094      {"Channel Agility", "wlan_mgt.fixed.capabilities.agility",
5095       FT_BOOLEAN, 16, TFS (&cf_agility_flags), 0x0080, "Channel Agility", HFILL }},
5096
5097     {&ff_cf_spec_man,
5098      {"Spectrum Management", "wlan_mgt.fixed.capabilities.spec_man",
5099       FT_BOOLEAN, 16, TFS (&cf_spec_man_flags), 0x0100, "Spectrum Management", HFILL }},
5100
5101     {&ff_short_slot_time,
5102      {"Short Slot Time", "wlan_mgt.fixed.capabilities.short_slot_time",
5103       FT_BOOLEAN, 16, TFS (&short_slot_time_flags), 0x0400, "Short Slot Time",
5104       HFILL }},
5105
5106     {&ff_cf_apsd,
5107      {"Automatic Power Save Delivery", "wlan_mgt.fixed.capabilities.apsd",
5108       FT_BOOLEAN, 16, TFS (&cf_apsd_flags), 0x0800, "Automatic Power Save "
5109         "Delivery", HFILL }},
5110
5111     {&ff_dsss_ofdm,
5112      {"DSSS-OFDM", "wlan_mgt.fixed.capabilities.dsss_ofdm",
5113       FT_BOOLEAN, 16, TFS (&dsss_ofdm_flags), 0x2000, "DSSS-OFDM Modulation",
5114       HFILL }},
5115
5116     {&ff_cf_del_blk_ack,
5117      {"Delayed Block Ack", "wlan_mgt.fixed.capabilities.del_blk_ack",
5118       FT_BOOLEAN, 16, TFS (&cf_del_blk_ack_flags), 0x4000, "Delayed Block "
5119         "Ack", HFILL }},
5120
5121     {&ff_cf_imm_blk_ack,
5122      {"Immediate Block Ack", "wlan_mgt.fixed.capabilities.imm_blk_ack",
5123       FT_BOOLEAN, 16, TFS (&cf_imm_blk_ack_flags), 0x8000, "Immediate Block "
5124         "Ack", HFILL }},
5125
5126     {&ff_auth_seq,
5127      {"Authentication SEQ", "wlan_mgt.fixed.auth_seq",
5128       FT_UINT16, BASE_HEX, NULL, 0, "Authentication sequence number", HFILL }},
5129
5130     {&ff_assoc_id,
5131      {"Association ID", "wlan_mgt.fixed.aid",
5132       FT_UINT16, BASE_HEX, NULL, 0, "Association ID", HFILL }},
5133
5134     {&ff_listen_ival,
5135      {"Listen Interval", "wlan_mgt.fixed.listen_ival",
5136       FT_UINT16, BASE_HEX, NULL, 0, "Listen Interval", HFILL }},
5137
5138     {&ff_current_ap,
5139      {"Current AP", "wlan_mgt.fixed.current_ap",
5140       FT_ETHER, BASE_NONE, NULL, 0, "MAC address of current AP", HFILL }},
5141
5142     {&ff_reason,
5143      {"Reason code", "wlan_mgt.fixed.reason_code",
5144       FT_UINT16, BASE_HEX, VALS (&reason_codes), 0,
5145       "Reason for unsolicited notification", HFILL }},
5146
5147     {&ff_status_code,
5148      {"Status code", "wlan_mgt.fixed.status_code",
5149       FT_UINT16, BASE_HEX, VALS (&status_codes), 0,
5150       "Status of requested event", HFILL }},
5151
5152     {&ff_category_code,
5153      {"Category code", "wlan_mgt.fixed.category_code",
5154       FT_UINT16, BASE_DEC, VALS (&category_codes), 0,
5155       "Management action category", HFILL }},
5156
5157     {&ff_action_code,
5158      {"Action code", "wlan_mgt.fixed.action_code",
5159       FT_UINT16, BASE_DEC, VALS (&action_codes), 0,
5160       "Management action code", HFILL }},
5161
5162     {&ff_dialog_token,
5163      {"Dialog token", "wlan_mgt.fixed.dialog_token",
5164       FT_UINT16, BASE_HEX, NULL, 0, "Management action dialog token", HFILL }},
5165
5166     {&ff_wme_action_code,
5167      {"Action code", "wlan_mgt.fixed.action_code",
5168       FT_UINT16, BASE_HEX, VALS (&wme_action_codes), 0,
5169       "Management notification action code", HFILL }},
5170
5171     {&ff_wme_status_code,
5172      {"Status code", "wlan_mgt.fixed.status_code",
5173       FT_UINT16, BASE_HEX, VALS (&wme_status_codes), 0,
5174       "Management notification setup response status code", HFILL }},
5175
5176     {&ff_qos_action_code,
5177      {"Action code", "wlan_mgt.fixed.action_code",
5178       FT_UINT16, BASE_HEX, VALS (&qos_action_codes), 0,
5179       "QoS management action code", HFILL }},
5180
5181     {&ff_dls_action_code,
5182      {"Action code", "wlan_mgt.fixed.action_code",
5183       FT_UINT16, BASE_HEX, VALS (&dls_action_codes), 0,
5184       "DLS management action code", HFILL }},
5185
5186     {&ff_dst_mac_addr,
5187      {"Destination address", "wlan_mgt.fixed.dst_mac_addr",
5188       FT_ETHER, BASE_NONE, NULL, 0, "Destination MAC address", HFILL }},
5189
5190     {&ff_src_mac_addr,
5191      {"Source address", "wlan_mgt.fixed.src_mac_addr",
5192       FT_ETHER, BASE_NONE, NULL, 0, "Source MAC address", HFILL }},
5193
5194     {&ff_dls_timeout,
5195      {"DLS timeout", "wlan_mgt.fixed.dls_timeout",
5196       FT_UINT16, BASE_HEX, NULL, 0, "DLS timeout value", HFILL }},
5197
5198     {&tag_number,
5199      {"Tag", "wlan_mgt.tag.number",
5200       FT_UINT8, BASE_DEC, VALS(tag_num_vals), 0,
5201       "Element ID", HFILL }},
5202
5203     {&tag_length,
5204      {"Tag length", "wlan_mgt.tag.length",
5205       FT_UINT8, BASE_DEC, NULL, 0, "Length of tag", HFILL }},
5206
5207     {&tag_interpretation,
5208      {"Tag interpretation", "wlan_mgt.tag.interpretation",
5209       FT_STRING, BASE_NONE, NULL, 0, "Interpretation of tag", HFILL }},
5210
5211     {&tag_oui,
5212      {"OUI", "wlan_mgt.tag.oui",
5213       FT_BYTES, BASE_NONE, NULL, 0, "OUI of vendor specific IE", HFILL }},
5214
5215     {&tim_length,
5216      {"TIM length", "wlan_mgt.tim.length",
5217       FT_UINT8, BASE_DEC, NULL, 0,
5218       "Traffic Indication Map length", HFILL }},
5219
5220     {&tim_dtim_count,
5221      {"DTIM count", "wlan_mgt.tim.dtim_count",
5222       FT_UINT8, BASE_DEC, NULL, 0,
5223       "DTIM count", HFILL }},
5224
5225     {&tim_dtim_period,
5226      {"DTIM period", "wlan_mgt.tim.dtim_period",
5227       FT_UINT8, BASE_DEC, NULL, 0,
5228       "DTIM period", HFILL }},
5229
5230     {&tim_bmapctl,
5231      {"Bitmap control", "wlan_mgt.tim.bmapctl",
5232       FT_UINT8, BASE_HEX, NULL, 0,
5233       "Bitmap control", HFILL }},
5234
5235     {&rsn_cap,
5236      {"RSN Capabilities", "wlan_mgt.rsn.capabilities", FT_UINT16, BASE_HEX,
5237       NULL, 0, "RSN Capability information", HFILL }},
5238
5239     {&rsn_cap_preauth,
5240      {"RSN Pre-Auth capabilities", "wlan_mgt.rsn.capabilities.preauth",
5241       FT_BOOLEAN, 16, TFS (&rsn_preauth_flags), 0x0001,
5242       "RSN Pre-Auth capabilities", HFILL }},
5243
5244     {&rsn_cap_no_pairwise,
5245      {"RSN No Pairwise capabilities", "wlan_mgt.rsn.capabilities.no_pairwise",
5246       FT_BOOLEAN, 16, TFS (&rsn_no_pairwise_flags), 0x0002,
5247       "RSN No Pairwise capabilities", HFILL }},
5248
5249     {&rsn_cap_ptksa_replay_counter,
5250      {"RSN PTKSA Replay Counter capabilities",
5251       "wlan_mgt.rsn.capabilities.ptksa_replay_counter",
5252       FT_UINT16, BASE_HEX, VALS (&rsn_cap_replay_counter), 0x000C,
5253       "RSN PTKSA Replay Counter capabilities", HFILL }},
5254
5255     {&rsn_cap_gtksa_replay_counter,
5256      {"RSN GTKSA Replay Counter capabilities",
5257       "wlan_mgt.rsn.capabilities.gtksa_replay_counter",
5258       FT_UINT16, BASE_HEX, VALS (&rsn_cap_replay_counter), 0x0030,
5259       "RSN GTKSA Replay Counter capabilities", HFILL }},
5260
5261     {&ht_cap,
5262      {"HT Capabilities", "wlan_mgt.ht.capabilities", FT_UINT16, BASE_HEX,
5263       NULL, 0, "HT Capability information", HFILL }},
5264
5265     {&ht_adv_coding,
5266      {"HT Advanced coding capability", "wlan_mgt.ht.capabilities.advcoding",
5267       FT_BOOLEAN, 16, TFS (&ht_adv_coding_flag), 0x0001,
5268       "HT Advanced coding capability", HFILL }},
5269
5270     {&ht_chan_width,
5271      {"HT Support channel width", "wlan_mgt.ht.capabilities.width",
5272       FT_BOOLEAN, 16, TFS (&ht_chan_width_flag), 0x0002,
5273       "HT Support channel width", HFILL }},
5274
5275     {&ht_mimo_pwsave,
5276      {"HT MIMO Power Save", "wlan_mgt.ht.capabilities.mimo",
5277       FT_UINT16, BASE_HEX, VALS (&ht_mimo_pwsave_flag), 0x000c,
5278       "HT MIMO Power Save", HFILL }},
5279
5280     {&ht_green,
5281      {"HT Green Field", "wlan_mgt.ht.capabilities.green",
5282       FT_BOOLEAN, 16, TFS (&ht_green_flag), 0x0010,
5283       "HT Green Field", HFILL }},
5284
5285     {&ht_short20,
5286      {"HT Short GI for 20MHz", "wlan_mgt.ht.capabilities.short20",
5287       FT_BOOLEAN, 16, TFS (&ht_tf_flag), 0x0020,
5288       "HT Short GI for 20MHz", HFILL }},
5289
5290     {&ht_short40,
5291      {"HT Short GI for 40MHz", "wlan_mgt.ht.capabilities.short40",
5292       FT_BOOLEAN, 16, TFS (&ht_tf_flag), 0x0040,
5293       "HT Short GI for 40MHz", HFILL }},
5294
5295     {&ht_tx_stbc,
5296      {"HT Tx STBC", "wlan_mgt.ht.capabilities.txstbc",
5297       FT_BOOLEAN, 16, TFS (&ht_tf_flag), 0x0080,
5298       "HT Tx STBC", HFILL }},
5299
5300     {&ht_rx_stbc,
5301      {"HT Rx STBC", "wlan_mgt.ht.capabilities.rxstbc",
5302       FT_UINT16, BASE_HEX, VALS (&ht_rx_stbc_flag), 0x0300,
5303       "HT Tx STBC", HFILL }},
5304
5305     {&ht_block_ack,
5306      {"HT Delayed Block ACK", "wlan_mgt.ht.capabilities.blockack",
5307       FT_BOOLEAN, 16, TFS (&ht_block_ack_flag), 0x0400,
5308       "HT Delayed Block ACK", HFILL }},
5309
5310     {&ht_max_amsdu,
5311      {"HT Max A-MSDU length", "wlan_mgt.ht.capabilities.amsdu",
5312       FT_BOOLEAN, 16, TFS (&ht_max_amsdu_flag), 0x0800,
5313       "HT Max A-MSDU length", HFILL }},
5314
5315     {&ht_dsss_cck_40,
5316      {"HT DSSS/CCK mode in 40MHz", "wlan_mgt.ht.capabilities.",
5317       FT_BOOLEAN, 16, TFS (&ht_dss_cck_40_flag), 0x1000,
5318       "HT DSS/CCK mode in 40MHz", HFILL }},
5319
5320     {&ht_psmp,
5321      {"HT PSMP Support", "wlan_mgt.ht.capabilities.psmp",
5322       FT_BOOLEAN, 16, TFS (&ht_psmp_flag), 0x2000,
5323       "HT PSMP Support", HFILL }},
5324
5325     {&ht_stbc,
5326      {"HT STBC Control Frame", "wlan_mgt.ht.capabilities.stbc",
5327       FT_BOOLEAN, 16, TFS (&ht_stbc_flag), 0x4000,
5328       "HT STBC Control Frame", HFILL }},
5329
5330     {&ht_l_sig,
5331      {"HT L-SIG TXOP Protection", "wlan_mgt.ht.capabilities.lsig",
5332       FT_BOOLEAN, 16, TFS (&ht_tf_flag), 0x8000,
5333       "HT L-SIG TXOP Protection", HFILL }},
5334
5335     {&macparm,
5336      {"MAC Parameters", "wlan_mgt.ht.macparm", FT_UINT16, BASE_HEX,
5337       NULL, 0, "MAC Parameters", HFILL }},
5338
5339     {&macparm_mpdu,
5340      {"Max MPDUs", "wlan_mgt.ht.macparm.mpdu",
5341       FT_UINT16, BASE_HEX, 0 , 0x0003,
5342       "Max MPDUs", HFILL }},
5343
5344     {&macparm_mpdu_density,
5345      {"MPDU Density", "wlan_mgt.ht.macparm.mpdudensity",
5346       FT_UINT16, BASE_HEX, VALS (&macparm_mpdu_density_flags) , 0x001c,
5347       "MPDU Density", HFILL }},
5348
5349     {&htex_cap,
5350      {"HT Extended Capabilities", "wlan_mgt.htex.capabilities", FT_UINT16, BASE_HEX,
5351       NULL, 0, "HT Extended Capability information", HFILL }},
5352
5353     {&htex_pco,
5354      {"Transmitter supports PCO", "wlan_mgt.htex.capabilities.pco",
5355       FT_BOOLEAN, 16, TFS (&ht_tf_flag), 0x0001,
5356       "Transmitter supports PCO", HFILL }},
5357
5358     {&htex_transtime,
5359      {"Transition Time between 20MHz and 40MHz", "wlan_mgt.htex.capabilities.transtime",
5360       FT_UINT16, BASE_HEX, VALS (&htex_transtime_flag), 0x0006,
5361       "", HFILL }},
5362
5363     {&htex_mcs,
5364      {"MCS Feedback capability", "wlan_mgt.htex.capabilities.mcs",
5365       FT_UINT16, BASE_HEX, VALS (&htex_mcs_flag), 0x0200,
5366       "", HFILL }},
5367
5368     {&txbf,
5369      {"TxBF Transmit Beam Forming Capability", "wlan_mgt.txbf", FT_UINT16, BASE_HEX,
5370       NULL, 0, "", HFILL }},
5371
5372     {&txbf_cap,
5373      {"TxBF", "wlan_mgt.htex.capabilities.pco",
5374       FT_BOOLEAN, 16, TFS (&ht_tf_flag), 0x00000001,
5375       "", HFILL }},
5376
5377     {&txbf_rcv_ssc,
5378      {"Receive staggered sounding", "wlan_mgt.htex.capabilities.pco",
5379       FT_BOOLEAN, 16, TFS (&ht_tf_flag), 0x00000002,
5380       "", HFILL }},
5381
5382     {&txbf_tx_ssc,
5383      {"Transmit staggered sounding", "wlan_mgt.htex.capabilities.pco",
5384       FT_BOOLEAN, 16, TFS (&ht_tf_flag), 0x00000004,
5385       "", HFILL }},
5386
5387     {&txbf_rcv_zlf,
5388      {"Receive ZLF", "wlan_mgt.htex.capabilities.pco",
5389       FT_BOOLEAN, 16, TFS (&ht_tf_flag), 0x00000008,
5390       "", HFILL }},
5391
5392     {&txbf_tx_zlf,
5393      {"Transmit ZLF", "wlan_mgt.htex.capabilities.pco",
5394       FT_BOOLEAN, 16, TFS (&ht_tf_flag), 0x00000010,
5395       "", HFILL }},
5396
5397     {&txbf_impl_txbf,
5398      {"Implicit TxBF capable", "wlan_mgt.htex.capabilities.pco",
5399       FT_BOOLEAN, 16, TFS (&ht_tf_flag), 0x00000020,
5400       "", HFILL }},
5401
5402     {&txbf_calib,
5403      {"Calibration", "wlan_mgt.htex.capabilities.mcs",
5404       FT_UINT16, BASE_HEX, VALS (&txbf_calib_flag), 0x000000c0,
5405       "", HFILL }},
5406
5407     {&txbf_expl_csi,
5408      {"STA can apply TxBF using CSI explicit feedback", "wlan_mgt.htex.capabilities.pco",
5409       FT_BOOLEAN, 16, TFS (&ht_tf_flag), 0x00000100,
5410       "", HFILL }},
5411
5412     {&txbf_expl_uncomp_sm,
5413      {"STA can apply TxBF using uncompressed steering matrix feedback", "wlan_mgt.htex.capabilities.pco",
5414       FT_BOOLEAN, 16, TFS (&ht_tf_flag), 0x00000200,
5415       "", HFILL }},
5416
5417     {&txbf_expl_bf_csi,
5418      {"Receiver can return explicit CSI feedback", "wlan_mgt.htex.capabilities.mcs",
5419       FT_UINT16, BASE_HEX, VALS (&txbf_feedback_flag), 0x00000c00,
5420       "", HFILL }},
5421
5422     {&txbf_expl_uncomp_sm_feed,
5423      {"Receiver can return uncompressed Steering Matrix feedback", "wlan_mgt.htex.capabilities.mcs",
5424       FT_UINT16, BASE_HEX, VALS (&txbf_feedback_flag), 0x00003000,
5425       "", HFILL }},
5426
5427     {&txbf_expl_comp_sm_feed,
5428      {"STA can compress and use compressed Steering Matrix feedback ", "wlan_mgt.htex.capabilities.mcs",
5429       FT_UINT16, BASE_HEX, VALS (&txbf_feedback_flag), 0x0000c000,
5430       "", HFILL }},
5431
5432     {&txbf_csi_num_bf_ant,
5433      {"Max antennae STA can support when CSI feedback required", "wlan_mgt.htex.capabilities.mcs",
5434       FT_UINT16, BASE_HEX, VALS (&txbf_antenna_flag), 0x00030000,
5435       "", HFILL }},
5436
5437     {&txbf_uncomp_sm_bf_ant,
5438      {"Max antennae STA can support when uncompressed SM feedback required", "wlan_mgt.htex.capabilities.mcs",
5439       FT_UINT16, BASE_HEX, VALS (&txbf_antenna_flag), 0x000c0000,
5440       "", HFILL }},
5441
5442     {&txbf_comp_sm_bf_ant,
5443      {"Max antennae STA can support when compressed SM feedback required", "wlan_mgt.htex.capabilities.mcs",
5444       FT_UINT16, BASE_HEX, VALS (&txbf_antenna_flag), 0x00300000,
5445       "", HFILL }},
5446
5447     {&hta_cap,
5448      {"HT Additional Capabilities", "wlan_mgt.hta.capabilities", FT_UINT16, BASE_HEX,
5449       NULL, 0, "HT Additional Capability information", HFILL }},
5450
5451     {&hta_ext_chan_offset,
5452      {"Extension Channel Offset", "wlan_mgt.hta.capabilities.extchan",
5453       FT_UINT16, BASE_HEX, VALS (&hta_ext_chan_offset_flag), 0x0003,
5454       "", HFILL }},
5455
5456     {&hta_rec_tx_width,
5457      {"Reccomended Tx Channel Width", "wlan_mgt.hta.capabilities.rectxwidth",
5458       FT_BOOLEAN, 16, TFS (&hta_rec_tx_width_flag), 0x0004,
5459       "", HFILL }},
5460
5461     {&hta_rifs_mode,
5462      {"RIFS Mode", "wlan_mgt.hta.capabilities.rifsmode",
5463       FT_BOOLEAN, 16, TFS (&hta_rifs_mode_flag), 0x0008,
5464       "", HFILL }},
5465
5466     {&hta_controlled_access,
5467      {"Controlled Access Only", "wlan_mgt.hta.capabilities.controlledaccess",
5468       FT_BOOLEAN, 16, TFS (&hta_controlled_access_flag), 0x0010,
5469       "", HFILL }},
5470
5471     {&hta_service_interval,
5472      {"Service Interval Granularity", "wlan_mgt.hta.capabilities.serviceinterval",
5473       FT_UINT16, BASE_HEX, VALS (&hta_service_interval_flag), 0x00E0,
5474       "", HFILL }},
5475
5476     {&hta_operating_mode,
5477      {"Operating Mode", "wlan_mgt.hta.capabilities.operatingmode",
5478       FT_UINT16, BASE_HEX, VALS (&hta_operating_mode_flag), 0x0003,
5479       "", HFILL }},
5480
5481     {&hta_non_gf_devices,
5482      {"Non GF devices Present", "wlan_mgt.hta.capabilities.nongfdevices",
5483       FT_BOOLEAN, 16, TFS (&hta_non_gf_devices_flag), 0x0004,
5484       "", HFILL }},
5485
5486     {&hta_basic_stbc_mcs,
5487      {"Basic STB MCS", "wlan_mgt.hta.capabilities.",
5488       FT_UINT16, BASE_HEX, NULL , 0x007f,
5489       "", HFILL }},
5490
5491     {&hta_dual_stbc_protection,
5492      {"Dual CTS Protection", "wlan_mgt.hta.capabilities.",
5493       FT_BOOLEAN, 16, TFS (&hta_dual_stbc_protection_flag), 0x0080,
5494       "", HFILL }},
5495
5496     {&hta_secondary_beacon,
5497      {"Secondary Beacon", "wlan_mgt.hta.capabilities.",
5498       FT_BOOLEAN, 16, TFS (&hta_secondary_beacon_flag), 0x0100,
5499       "", HFILL }},
5500
5501     {&hta_lsig_txop_protection,
5502      {"L-SIG TXOP Protection Support", "wlan_mgt.hta.capabilities.",
5503       FT_BOOLEAN, 16, TFS (&hta_lsig_txop_protection_flag), 0x0200,
5504       "", HFILL }},
5505
5506     {&hta_pco_active,
5507      {"PCO Active", "wlan_mgt.hta.capabilities.",
5508       FT_BOOLEAN, 16, TFS (&hta_pco_active_flag), 0x0400,
5509       "", HFILL }},
5510
5511     {&hta_pco_phase,
5512      {"PCO Phase", "wlan_mgt.hta.capabilities.",
5513       FT_BOOLEAN, 16, TFS (&hta_pco_phase_flag), 0x0800,
5514       "", HFILL }},
5515
5516
5517
5518
5519     {&antsel,
5520      {"Antenna Selection Capability", "wlan_mgt.txbf", FT_UINT16, BASE_HEX,
5521       NULL, 0, "", HFILL }},
5522
5523     {&antsel_b0,
5524      {"Antenna Selection Capable", "wlan_mgt.htex.capabilities.pco",
5525       FT_BOOLEAN, 16, TFS (&ht_tf_flag), 0x001,
5526       "", HFILL }},
5527
5528     {&antsel_b1,
5529      {"TX selection based on explicit CSI feedback", "wlan_mgt.htex.capabilities.pco",
5530       FT_BOOLEAN, 16, TFS (&ht_tf_flag), 0x002,
5531       "", HFILL }},
5532
5533     {&antsel_b2,
5534      {"TX selection based on antenna indices feedback", "wlan_mgt.htex.capabilities.pco",
5535       FT_BOOLEAN, 16, TFS (&ht_tf_flag), 0x004,
5536       "", HFILL }},
5537
5538     {&antsel_b3,
5539      {"Compute CSI and feedback to support peer", "wlan_mgt.htex.capabilities.pco",
5540       FT_BOOLEAN, 16, TFS (&ht_tf_flag), 0x008,
5541       "", HFILL }},
5542
5543     {&antsel_b4,
5544      {"Conduct antenna indices computation to support peer", "wlan_mgt.htex.capabilities.pco",
5545       FT_BOOLEAN, 16, TFS (&ht_tf_flag), 0x010,
5546       "", HFILL }},
5547
5548     {&antsel_b5,
5549      {"RX antenna selection", "wlan_mgt.htex.capabilities.pco",
5550       FT_BOOLEAN, 16, TFS (&ht_tf_flag), 0x020,
5551       "", HFILL }},
5552
5553     {&antsel_b6,
5554      {"Tx Sounding PPDUs on request", "wlan_mgt.htex.capabilities.pco",
5555       FT_BOOLEAN, 16, TFS (&ht_tf_flag), 0x040,
5556       "", HFILL }},
5557
5558
5559     {&hf_aironet_ie_type,
5560      {"Aironet IE type", "wlan_mgt.aironet.type",
5561       FT_UINT8, BASE_DEC, VALS(aironet_ie_type_vals), 0, "", HFILL }},
5562
5563     {&hf_aironet_ie_version,
5564      {"Aironet IE CCX version?", "wlan_mgt.aironet.version",
5565       FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }},
5566
5567     { &hf_aironet_ie_data,
5568       { "Aironet IE data", "wlan_mgmt.aironet.data",
5569         FT_BYTES, BASE_NONE, NULL, 0x0, "", HFILL }},
5570
5571     {&hf_qbss_version,
5572      {"QBSS Version", "wlan_mgt.qbss.version",
5573       FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }},
5574
5575     {&hf_qbss_scount,
5576      {"Station Count", "wlan_mgt.qbss.scount",
5577       FT_UINT16, BASE_DEC, NULL, 0, "", HFILL }},
5578
5579     {&hf_qbss_cu,
5580      {"Channel Utilization", "wlan_mgt.qbss.cu",
5581        FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }},
5582
5583     {&hf_qbss_adc,
5584      {"Available Admission Capabilities", "wlan_mgt.qbss.adc",
5585      FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }},
5586
5587     {&hf_qbss2_cu,
5588      {"Channel Utilization", "wlan_mgt.qbss2.cu",
5589        FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }},
5590
5591     {&hf_qbss2_gl,
5592      {"G.711 CU Quantum", "wlan_mgt.qbss2.glimit",
5593       FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }},
5594
5595     {&hf_qbss2_cal,
5596      {"Call Admission Limit", "wlan_mgt.qbss2.cal",
5597       FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }},
5598
5599     {&hf_qbss2_scount,
5600      {"Station Count", "wlan_mgt.qbss2.scount",
5601       FT_UINT16, BASE_DEC, NULL, 0, "", HFILL }},
5602
5603     {&hf_aironet_ie_qos_unk1,
5604      {"Aironet IE QoS unknown1", "wlan_mgt.aironet.qos.unk1",
5605       FT_UINT8, BASE_HEX, NULL, 0, "", HFILL }},
5606
5607     {&hf_aironet_ie_qos_paramset,
5608      {"Aironet IE QoS paramset", "wlan_mgt.aironet.qos.paramset",
5609       FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }},
5610
5611     {&hf_aironet_ie_qos_val,
5612      {"Aironet IE QoS valueset", "wlan_mgt.aironet.qos.val",
5613       FT_BYTES, BASE_NONE, NULL, 0, "", HFILL }},
5614
5615     {&hf_ts_info,
5616      {"TS Info", "wlan_mgt.ts_info",
5617       FT_UINT24, BASE_HEX, NULL, 0, "TS Info field", HFILL }},
5618
5619     {&hf_tsinfo_type,
5620      {"Traffic Type", "wlan_mgt.ts_info.type", FT_UINT8, BASE_DEC,
5621       VALS (&tsinfo_type), 0, "TS Info Traffic Type", HFILL }},
5622
5623     {&hf_tsinfo_tsid,
5624      {"TSID", "wlan_mgt.ts_info.tsid",
5625       FT_UINT8, BASE_DEC, NULL, 0, "TS Info TSID", HFILL }},
5626
5627     {&hf_tsinfo_dir,
5628      {"Direction", "wlan_mgt.ts_info.dir", FT_UINT8, BASE_DEC,
5629       VALS (&tsinfo_direction), 0, "TS Info Direction", HFILL }},
5630
5631     {&hf_tsinfo_access,
5632      {"Access Policy", "wlan_mgt.ts_info.dir", FT_UINT8, BASE_DEC,
5633       VALS (&tsinfo_access), 0, "TS Info Access Policy", HFILL }},
5634
5635     {&hf_tsinfo_agg,
5636      {"Aggregation", "wlan_mgt.ts_info.agg", FT_UINT8, BASE_DEC,
5637       NULL, 0, "TS Info Access Policy", HFILL }},
5638
5639     {&hf_tsinfo_apsd,
5640      {"APSD", "wlan_mgt.ts_info.apsd", FT_UINT8, BASE_DEC,
5641       NULL, 0, "TS Info APSD", HFILL }},
5642
5643     {&hf_tsinfo_up,
5644      {"UP", "wlan_mgt.ts_info.up", FT_UINT8, BASE_DEC,
5645       VALS (&qos_up), 0, "TS Info User Priority", HFILL }},
5646
5647     {&hf_tsinfo_ack,
5648      {"Ack Policy", "wlan_mgt.ts_info.ack", FT_UINT8, BASE_DEC,
5649       VALS (&ack_policy), 0, "TS Info Ack Policy", HFILL }},
5650
5651     {&hf_tsinfo_sched,
5652      {"Schedule", "wlan_mgt.ts_info.sched", FT_UINT8, BASE_DEC,
5653       NULL, 0, "TS Info Schedule", HFILL }},
5654
5655     {&tspec_nor_msdu,
5656      {"Normal MSDU Size", "wlan_mgt.tspec.nor_msdu",
5657       FT_UINT16, BASE_DEC, NULL, 0, "Normal MSDU Size", HFILL }},
5658
5659     {&tspec_max_msdu,
5660      {"Maximum MSDU Size", "wlan_mgt.tspec.max_msdu",
5661       FT_UINT16, BASE_DEC, NULL, 0, "Maximum MSDU Size", HFILL }},
5662
5663     {&tspec_min_srv,
5664      {"Minimum Service Interval", "wlan_mgt.tspec.min_srv",
5665       FT_UINT32, BASE_DEC, NULL, 0, "Minimum Service Interval", HFILL }},
5666
5667     {&tspec_max_srv,
5668      {"Maximum Service Interval", "wlan_mgt.tspec.max_srv",
5669       FT_UINT32, BASE_DEC, NULL, 0, "Maximum Service Interval", HFILL }},
5670
5671     {&tspec_inact_int,
5672      {"Inactivity Interval", "wlan_mgt.tspec.inact_int",
5673       FT_UINT32, BASE_DEC, NULL, 0, "Inactivity Interval", HFILL }},
5674
5675     {&tspec_susp_int,
5676      {"Suspension Interval", "wlan_mgt.tspec.susp_int",
5677       FT_UINT32, BASE_DEC, NULL, 0, "Suspension Interval", HFILL }},
5678
5679     {&tspec_srv_start,
5680      {"Service Start Time", "wlan_mgt.tspec.srv_start",
5681       FT_UINT32, BASE_DEC, NULL, 0, "Service Start Time", HFILL }},
5682
5683     {&tspec_min_data,
5684      {"Minimum Data Rate", "wlan_mgt.tspec.min_data",
5685       FT_UINT32, BASE_DEC, NULL, 0, "Minimum Data Rate", HFILL }},
5686
5687     {&tspec_mean_data,
5688      {"Mean Data Rate", "wlan_mgt.tspec.mean_data",
5689       FT_UINT32, BASE_DEC, NULL, 0, "Mean Data Rate", HFILL }},
5690
5691     {&tspec_peak_data,
5692      {"Peak Data Rate", "wlan_mgt.tspec.peak_data",
5693       FT_UINT32, BASE_DEC, NULL, 0, "Peak Data Rate", HFILL }},
5694
5695     {&tspec_burst_size,
5696      {"Burst Size", "wlan_mgt.tspec.burst_size",
5697       FT_UINT32, BASE_DEC, NULL, 0, "Burst Size", HFILL }},
5698
5699     {&tspec_delay_bound,
5700      {"Delay Bound", "wlan_mgt.tspec.delay_bound",
5701       FT_UINT32, BASE_DEC, NULL, 0, "Delay Bound", HFILL }},
5702
5703     {&tspec_min_phy,
5704      {"Minimum PHY Rate", "wlan_mgt.tspec.min_phy",
5705       FT_UINT32, BASE_DEC, NULL, 0, "Minimum PHY Rate", HFILL }},
5706
5707     {&tspec_surplus,
5708      {"Surplus Bandwidth Allowance", "wlan_mgt.tspec.surplus",
5709       FT_UINT16, BASE_DEC, NULL, 0, "Surplus Bandwidth Allowance", HFILL }},
5710
5711     {&tspec_medium,
5712      {"Medium Time", "wlan_mgt.tspec.medium",
5713       FT_UINT16, BASE_DEC, NULL, 0, "Medium Time", HFILL }},
5714
5715     {&ts_delay,
5716      {"TS Delay", "wlan_mgt.ts_delay",
5717       FT_UINT32, BASE_DEC, NULL, 0, "TS Delay", HFILL }},
5718
5719     {&hf_class_type,
5720      {"Classifier Type", "wlan_mgt.tclas.class_type", FT_UINT8, BASE_DEC,
5721       VALS (classifier_type), 0, "Classifier Type", HFILL }},
5722
5723     {&hf_class_mask,
5724      {"Classifier Mask", "wlan_mgt.tclas.class_mask", FT_UINT8, BASE_HEX,
5725       NULL, 0, "Classifier Mask", HFILL }},
5726
5727     {&hf_ether_type,
5728      {"Type", "wlan_mgt.tclas.params.type", FT_UINT8, BASE_DEC,
5729       NULL, 0, "Classifier Parameters Ethernet Type", HFILL }},
5730
5731     {&hf_tclas_process,
5732      {"Processing", "wlan_mgt.tclas_proc.processing", FT_UINT8, BASE_DEC,
5733       VALS (tclas_process), 0, "TCLAS Porcessing", HFILL }},
5734
5735     {&hf_sched_info,
5736      {"Schedule Info", "wlan_mgt.sched.sched_info",
5737       FT_UINT16, BASE_HEX, NULL, 0, "Schedule Info field", HFILL }},
5738
5739     {&hf_sched_srv_start,
5740      {"Service Start Time", "wlan_mgt.sched.srv_start",
5741       FT_UINT32, BASE_HEX, NULL, 0, "Service Start Time", HFILL }},
5742
5743     {&hf_sched_srv_int,
5744      {"Service Interval", "wlan_mgt.sched.srv_int",
5745       FT_UINT32, BASE_HEX, NULL, 0, "Service Interval", HFILL }},
5746
5747     {&hf_sched_spec_int,
5748      {"Specification Interval", "wlan_mgt.sched.spec_int",
5749       FT_UINT16, BASE_HEX, NULL, 0, "Specification Interval", HFILL }},
5750
5751     {&cf_version,
5752      {"IP Version", "wlan_mgt.tclas.params.version",
5753       FT_UINT8, BASE_DEC, NULL, 0, "IP Version", HFILL }},
5754
5755     {&cf_ipv4_src,
5756      {"IPv4 Src Addr", "wlan_mgt.tclas.params.ipv4_src",
5757       FT_IPv4, BASE_NONE, NULL, 0, "IPv4 Src Addr", HFILL }},
5758
5759     {&cf_ipv4_dst,
5760      {"IPv4 Dst Addr", "wlan_mgt.tclas.params.ipv4_dst",
5761       FT_IPv4, BASE_NONE, NULL, 0, "IPv4 Dst Addr", HFILL }},
5762
5763     {&cf_src_port,
5764      {"Source Port", "wlan_mgt.tclas.params.src_port",
5765       FT_UINT16, BASE_DEC, NULL, 0, "Source Port", HFILL }},
5766
5767     {&cf_dst_port,
5768      {"Destination Port", "wlan_mgt.tclas.params.dst_port",
5769       FT_UINT16, BASE_DEC, NULL, 0, "Destination Port", HFILL }},
5770
5771     {&cf_dscp,
5772      {"DSCP", "wlan_mgt.tclas.params.dscp",
5773       FT_UINT8, BASE_HEX, NULL, 0, "IPv4 DSCP Field", HFILL }},
5774
5775     {&cf_protocol,
5776      {"Protocol", "wlan_mgt.tclas.params.protocol",
5777       FT_UINT8, BASE_HEX, NULL, 0, "IPv4 Protocol", HFILL }},
5778
5779     {&cf_ipv6_src,
5780      {"IPv6 Src Addr", "wlan_mgt.tclas.params.ipv6_src",
5781       FT_IPv6, BASE_NONE, NULL, 0, "IPv6 Src Addr", HFILL }},
5782
5783     {&cf_ipv6_dst,
5784      {"IPv6 Dst Addr", "wlan_mgt.tclas.params.ipv6_dst",
5785       FT_IPv6, BASE_NONE, NULL, 0, "IPv6 Dst Addr", HFILL }},
5786
5787     {&cf_flow,
5788      {"Flow Label", "wlan_mgt.tclas.params.flow",
5789       FT_UINT24, BASE_HEX, NULL, 0, "IPv6 Flow Label", HFILL }},
5790
5791     {&cf_tag_type,
5792      {"802.1Q Tag Type", "wlan_mgt.tclas.params.tag_type",
5793       FT_UINT16, BASE_HEX, NULL, 0, "802.1Q Tag Type", HFILL }},
5794
5795   };
5796
5797   static gint *tree_array[] = {
5798     &ett_80211,
5799     &ett_fc_tree,
5800     &ett_proto_flags,
5801     &ett_fragments,
5802     &ett_fragment,
5803     &ett_80211_mgt,
5804     &ett_fixed_parameters,
5805     &ett_tagged_parameters,
5806     &ett_qos_parameters,
5807     &ett_qos_ps_buf_state,
5808     &ett_wep_parameters,
5809     &ett_cap_tree,
5810     &ett_rsn_cap_tree,
5811     &ett_ht_cap_tree,
5812     &ett_macparm_tree,
5813     &ett_htex_cap_tree,
5814     &ett_txbf_tree,
5815     &ett_hta_cap_tree,
5816     &ett_hta_cap1_tree,
5817     &ett_hta_cap2_tree,
5818     &ett_antsel_tree,
5819     &ett_80211_mgt_ie,
5820     &ett_tsinfo_tree,
5821     &ett_sched_tree,
5822     &ett_fcs
5823   };
5824   module_t *wlan_module;
5825
5826
5827   proto_wlan = proto_register_protocol ("IEEE 802.11 wireless LAN",
5828                                         "IEEE 802.11", "wlan");
5829   proto_register_field_array (proto_wlan, hf, array_length (hf));
5830   proto_wlan_mgt = proto_register_protocol ("IEEE 802.11 wireless LAN management frame",
5831                                         "802.11 MGT", "wlan_mgt");
5832   proto_register_field_array (proto_wlan_mgt, ff, array_length (ff));
5833   proto_register_subtree_array (tree_array, array_length (tree_array));
5834
5835   register_dissector("wlan", dissect_ieee80211, proto_wlan);
5836   register_dissector("wlan_fixed", dissect_ieee80211_fixed, proto_wlan);
5837   register_dissector("wlan_bsfc", dissect_ieee80211_bsfc, proto_wlan);
5838   register_dissector("wlan_datapad", dissect_ieee80211_datapad, proto_wlan);
5839   register_dissector("wlan_radio", dissect_ieee80211_radio, proto_wlan);
5840   register_init_routine(wlan_defragment_init);
5841
5842   wlan_tap = register_tap("wlan");
5843
5844   /* Register configuration options */
5845   wlan_module = prefs_register_protocol(proto_wlan, init_wepkeys);
5846   prefs_register_bool_preference(wlan_module, "defragment",
5847         "Reassemble fragmented 802.11 datagrams",
5848         "Whether fragmented 802.11 datagrams should be reassembled",
5849         &wlan_defragment);
5850
5851   prefs_register_bool_preference(wlan_module, "check_fcs",
5852                                  "Assume packets have FCS",
5853                                  "Some 802.11 cards include the FCS at the end of a packet, others do not.",
5854                                  &wlan_check_fcs);
5855
5856         /* Davide Schiera (2006-11-26): changed "WEP bit" in "Protection bit"           */
5857         /*              (according to the document IEEE Std 802.11i-2004)                                                       */
5858   prefs_register_bool_preference(wlan_module, "ignore_wep",
5859                 "Ignore the Protection bit",
5860                 "Some 802.11 cards leave the Protection bit set even though the packet is decrypted.",
5861                                  &wlan_ignore_wep);
5862
5863 #ifndef USE_ENV
5864
5865   prefs_register_obsolete_preference(wlan_module, "wep_keys");
5866
5867 #ifdef HAVE_AIRPDCAP
5868   /* Davide Schiera (2006-11-26): added reference to WPA/WPA2 decryption                */
5869   prefs_register_bool_preference(wlan_module, "enable_decryption",
5870         "Enable decryption", "Enable WEP and WPA/WPA2 decryption",
5871         &enable_decryption);
5872 #else
5873   prefs_register_bool_preference(wlan_module, "enable_decryption",
5874         "Enable decryption", "Enable WEP decryption",
5875         &enable_decryption);
5876 #endif
5877
5878 #ifdef HAVE_AIRPDCAP
5879   prefs_register_static_text_preference(wlan_module, "info_decryption_key",
5880           "Key examples: 01:02:03:04:05 (40/64-bit WEP),\n"
5881           "010203040506070809101111213 (104/128-bit WEP),\n"
5882           "wpa-pwd:MyPassword[:MyAP] (WPA + plaintext password [+ SSID]),\n"
5883           "wpa-psk:0102030405...6061626364 (WPA + 256-bit key).  "
5884           "Invalid keys will be ignored.",
5885           "This is just a static text");
5886 #else
5887   prefs_register_static_text_preference(wlan_module, "info_decryption_key",
5888           "Key examples: 01:02:03:04:05 (40/64-bit WEP),\n"
5889           "010203040506070809101111213 (104/128-bit WEP)",
5890           "This is just a static text");
5891 #endif
5892
5893   for (i = 0; i < MAX_ENCRYPTION_KEYS; i++) {
5894     key_name = g_string_new("");
5895     key_title = g_string_new("");
5896     key_desc = g_string_new("");
5897     wep_keystr[i] = NULL;
5898     /* prefs_register_*_preference() expects unique strings, so
5899      * we build them using g_string_sprintf and just leave them
5900      * allocated. */
5901 #ifdef HAVE_AIRPDCAP
5902   g_string_sprintf(key_name, "wep_key%d", i + 1);
5903   g_string_sprintf(key_title, "Key #%d", i + 1);
5904   /* Davide Schiera (2006-11-26): modified keys input tooltip                                   */
5905   g_string_sprintf(key_desc,
5906         "Key #%d string can be:"
5907         "   <wep hexadecimal key>;"
5908         "   wep:<wep hexadecimal key>;"
5909         "   wpa-pwd:<passphrase>[:<ssid>];"
5910         "   wpa-psk:<wpa hexadecimal key>", i + 1);
5911 #else
5912     g_string_sprintf(key_name, "wep_key%d", i + 1);
5913     g_string_sprintf(key_title, "WEP key #%d", i + 1);
5914     g_string_sprintf(key_desc, "WEP key #%d bytes in hexadecimal (A:B:C:D:E) "
5915             "[40bit], (A:B:C:D:E:F:G:H:I:J:K:L:M) [104bit], or whatever key "
5916             "length you're using", i + 1);
5917 #endif
5918
5919     prefs_register_string_preference(wlan_module, key_name->str,
5920             key_title->str, key_desc->str, (const char **) &wep_keystr[i]);
5921
5922     g_string_free(key_name, FALSE);
5923     g_string_free(key_title, FALSE);
5924     g_string_free(key_desc, FALSE);
5925   }
5926 #endif
5927 }
5928
5929 void
5930 proto_reg_handoff_ieee80211(void)
5931 {
5932   dissector_handle_t ieee80211_handle;
5933   dissector_handle_t ieee80211_radio_handle;
5934
5935   /*
5936    * Get handles for the LLC, IPX and Ethernet  dissectors.
5937    */
5938   llc_handle = find_dissector("llc");
5939   ipx_handle = find_dissector("ipx");
5940   eth_withoutfcs_handle = find_dissector("eth_withoutfcs");
5941   data_handle = find_dissector("data");
5942
5943   ieee80211_handle = find_dissector("wlan");
5944   dissector_add("wtap_encap", WTAP_ENCAP_IEEE_802_11, ieee80211_handle);
5945   ieee80211_radio_handle = create_dissector_handle(dissect_ieee80211_radio,
5946                                                    proto_wlan);
5947   dissector_add("wtap_encap", WTAP_ENCAP_IEEE_802_11_WITH_RADIO,
5948                 ieee80211_radio_handle);
5949   dissector_add("ethertype", ETHERTYPE_CENTRINO_PROMISC, ieee80211_handle);
5950 }
5951
5952 #ifdef  HAVE_AIRPDCAP
5953 /*      Davide Schiera (2006-11-26): this function will try to decrypt with WEP or      */
5954 /*              WPA and return a tvb to the caller to add a new tab. It returns the             */
5955 /*              algorithm used for decryption (WEP, TKIP, CCMP) and the header and              */
5956 /*              trailer lengths.                                                                                                                                                        */
5957 static tvbuff_t *
5958 try_decrypt(tvbuff_t *tvb, guint32 offset, guint32 len, guint8 *algorithm, guint32 *sec_header, guint32 *sec_trailer) {
5959         const guint8 *enc_data;
5960         guint8 *tmp = NULL;
5961         tvbuff_t *decr_tvb = NULL;
5962         size_t dec_caplen;
5963         guchar dec_data[AIRPDCAP_MAX_CAPLEN];
5964         AIRPDCAP_KEY_ITEM used_key;
5965
5966         if (!enable_decryption)
5967                 return NULL;
5968
5969         /* get the entire packet                                                                                                                                        */
5970         enc_data = tvb_get_ptr(tvb, 0, len+offset);
5971
5972         /*      process packet with AirPDcap                                                                                                                    */
5973         if (AirPDcapPacketProcess(&airpdcap_ctx, enc_data, len+offset, dec_data, &dec_caplen, &used_key, FALSE, FALSE, FALSE, TRUE)==AIRPDCAP_RET_SUCCESS)
5974         {
5975                 *algorithm=used_key.KeyType;
5976                 switch (*algorithm) {
5977                         case AIRPDCAP_KEY_TYPE_WEP:
5978                                 *sec_header=AIRPDCAP_WEP_HEADER;
5979                                 *sec_trailer=AIRPDCAP_WEP_TRAILER;
5980                                 break;
5981                         case AIRPDCAP_KEY_TYPE_CCMP:
5982                                 *sec_header=AIRPDCAP_RSNA_HEADER;
5983                                 *sec_trailer=AIRPDCAP_CCMP_TRAILER;
5984                                 break;
5985                         case AIRPDCAP_KEY_TYPE_TKIP:
5986                                 *sec_header=AIRPDCAP_RSNA_HEADER;
5987                                 *sec_trailer=AIRPDCAP_TKIP_TRAILER;
5988                                 break;
5989                         default:
5990                                 return NULL;
5991                 }
5992
5993                 /* allocate buffer for decrypted payload                                                                                        */
5994                 if ((tmp = g_malloc(dec_caplen-offset)) == NULL)
5995                         return NULL;  /* krap! */
5996                 memcpy(tmp, dec_data+offset, dec_caplen-offset);
5997
5998                 len=dec_caplen-offset;
5999
6000                 /* decrypt successful, let's set up a new data tvb.                                                     */
6001                 decr_tvb = tvb_new_real_data(tmp, len, len);
6002                 tvb_set_free_cb(decr_tvb, g_free);
6003                 tvb_set_child_real_data_tvbuff(tvb, decr_tvb);
6004         } else
6005                 g_free(tmp);
6006
6007         return decr_tvb;
6008 }
6009 /*      Davide Schiera -----------------------------------------------------------      */
6010 #else
6011
6012 static tvbuff_t *try_decrypt_wep(tvbuff_t *tvb, guint32 offset, guint32 len) {
6013   const guint8 *enc_data;
6014   guint8 *tmp = NULL;
6015   int i;
6016   tvbuff_t *decr_tvb = NULL;
6017
6018   if (! enable_decryption)
6019     return NULL;
6020
6021   enc_data = tvb_get_ptr(tvb, offset, len);
6022
6023   if ((tmp = g_malloc(len)) == NULL)
6024     return NULL;  /* krap! */
6025
6026   /* try once with the key index in the packet, then look through our list. */
6027   for (i = 0; i < num_wepkeys; i++) {
6028     /* copy the encrypted data over to the tmp buffer */
6029 #if 0
6030     printf("trying %d\n", i);
6031 #endif
6032     memcpy(tmp, enc_data, len);
6033     if (wep_decrypt(tmp, len, i) == 0) {
6034
6035       /* decrypt successful, let's set up a new data tvb. */
6036       decr_tvb = tvb_new_real_data(tmp, len-8, len-8);
6037       tvb_set_free_cb(decr_tvb, g_free);
6038       tvb_set_child_real_data_tvbuff(tvb, decr_tvb);
6039
6040       break;
6041     }
6042   }
6043
6044   if ((!decr_tvb) && (tmp))    g_free(tmp);
6045
6046 #if 0
6047   printf("de-wep %p\n", decr_tvb);
6048 #endif
6049
6050   return decr_tvb;
6051 }
6052 #endif
6053
6054 #ifdef  HAVE_AIRPDCAP
6055 static
6056 void set_airpdcap_keys(void)
6057 {
6058         guint i = 0;
6059         AIRPDCAP_KEY_ITEM key;
6060         PAIRPDCAP_KEYS_COLLECTION keys;
6061         decryption_key_t* dk = NULL;
6062         GByteArray *bytes = NULL;
6063         gboolean res;
6064         gchar* tmpk = NULL;
6065
6066         keys=(PAIRPDCAP_KEYS_COLLECTION)g_malloc(sizeof(AIRPDCAP_KEYS_COLLECTION));
6067         keys->nKeys = 0;
6068
6069         for(i = 0; i < MAX_ENCRYPTION_KEYS; i++)
6070         {
6071                 tmpk = g_strdup(wep_keystr[i]);
6072
6073                 dk = parse_key_string(tmpk);
6074
6075                 if(dk != NULL)
6076                 {
6077                         if(dk->type == AIRPDCAP_KEY_TYPE_WEP)
6078                         {
6079                                 key.KeyType = AIRPDCAP_KEY_TYPE_WEP;
6080
6081                                 bytes = g_byte_array_new();
6082                                 res = hex_str_to_bytes(dk->key->str, bytes, FALSE);
6083
6084                                 if (dk->key->str && res && bytes->len > 0 && bytes->len <= AIRPDCAP_WEP_KEY_MAXLEN)
6085                                 {
6086                                         /*
6087                                          * WEP key is correct (well, the can be even or odd, so it is not
6088                                          * a real check, I think... is a check performed somewhere in the
6089                                          * AirPDcap function??? )
6090                                          */
6091                                         memcpy(key.KeyData.Wep.WepKey, bytes->data, bytes->len);
6092                                         key.KeyData.Wep.WepKeyLen = bytes->len;
6093                                         keys->Keys[keys->nKeys] = key;
6094                                         keys->nKeys++;
6095                                 }
6096                         }
6097                         else if(dk->type == AIRPDCAP_KEY_TYPE_WPA_PWD)
6098                         {
6099                                 key.KeyType = AIRPDCAP_KEY_TYPE_WPA_PWD;
6100
6101                                 /* XXX - This just lops the end if the key off if it's too long.
6102                                  *       Should we handle this more gracefully? */
6103                                 strncpy(key.UserPwd.Passphrase, dk->key->str, AIRPDCAP_WPA_PASSPHRASE_MAX_LEN);
6104
6105                                 key.UserPwd.SsidLen = 0;
6106                                 if(dk->ssid != NULL && dk->ssid->len <= AIRPDCAP_WPA_SSID_MAX_LEN)
6107                                 {
6108                                         memcpy(key.UserPwd.Ssid, dk->ssid->data, dk->ssid->len);
6109                                         key.UserPwd.SsidLen = dk->ssid->len;
6110                                 }
6111
6112                                 keys->Keys[keys->nKeys] = key;
6113                                 keys->nKeys++;
6114                         }
6115                         else if(dk->type == AIRPDCAP_KEY_TYPE_WPA_PMK)
6116                         {
6117                                 key.KeyType = AIRPDCAP_KEY_TYPE_WPA_PMK;
6118
6119                                 bytes = g_byte_array_new();
6120                                 res = hex_str_to_bytes(dk->key->str, bytes, FALSE);
6121
6122                                 /* XXX - Pass the correct array of bytes... */
6123                                 if (bytes-> len <= AIRPDCAP_WPA_PMK_LEN) {
6124                                         memcpy(key.KeyData.Wpa.Pmk, bytes->data, bytes->len);
6125
6126                                         keys->Keys[keys->nKeys] = key;
6127                                         keys->nKeys++;
6128                                 }
6129                         }
6130                 }
6131                 if(tmpk != NULL) g_free(tmpk);
6132         }
6133
6134         /* Now set the keys */
6135         AirPDcapSetKeys(&airpdcap_ctx,keys->Keys,keys->nKeys);
6136         g_free(keys);
6137         if (bytes)
6138                 g_byte_array_free(bytes, TRUE);
6139
6140 }
6141 #endif
6142
6143 #ifndef HAVE_AIRPDCAP
6144 /* de-weps the block.  if successful, buf* will point to the data start. */
6145 static int wep_decrypt(guint8 *buf, guint32 len, int keyidx) {
6146   guint32 i, j, k, crc, keylen;
6147   guint8 s[256], key[128], c_crc[4];
6148   guint8 *dpos, *cpos;
6149
6150   /* Needs to be at least 8 bytes of payload */
6151   if (len < 8)
6152     return -1;
6153
6154   /* initialize the first bytes of the key from the IV */
6155   key[0] = buf[0];
6156   key[1] = buf[1];
6157   key[2] = buf[2];
6158
6159   if (keyidx < 0 || keyidx >= num_wepkeys)
6160     return -1;
6161
6162   keylen = wep_keylens[keyidx];
6163
6164   if (keylen == 0)
6165     return -1;
6166   if (wep_keys[keyidx] == NULL)
6167     return -1;
6168
6169   keylen+=3;  /* add in ICV bytes */
6170
6171   /* copy the rest of the key over from the designated key */
6172   memcpy(key+3, wep_keys[keyidx], wep_keylens[keyidx]);
6173
6174 #if 0
6175   printf("%d: %02x %02x %02x (%d %d) %02x:%02x:%02x:%02x:%02x\n", len, key[0], key[1], key[2], keyidx, keylen, key[3], key[4], key[5], key[6], key[7]);
6176 #endif
6177
6178   /* set up the RC4 state */
6179   for (i = 0; i < 256; i++)
6180     s[i] = i;
6181   j = 0;
6182   for (i = 0; i < 256; i++) {
6183     j = (j + s[i] + key[i % keylen]) & 0xff;
6184     SSWAP(i,j);
6185   }
6186
6187   /* Apply the RC4 to the data, update the CRC32 */
6188   cpos = buf+4;
6189   dpos = buf;
6190   crc = ~0;
6191   i = j = 0;
6192   for (k = 0; k < (len -8); k++) {
6193     i = (i+1) & 0xff;
6194     j = (j+s[i]) & 0xff;
6195     SSWAP(i,j);
6196 #if 0
6197     printf("%d -- %02x ", k, *dpos);
6198 #endif
6199     *dpos = *cpos++ ^ s[(s[i] + s[j]) & 0xff];
6200 #if 0
6201     printf("%02x\n", *dpos);
6202 #endif
6203     crc = crc32_ccitt_table[(crc ^ *dpos++) & 0xff] ^ (crc >> 8);
6204   }
6205   crc = ~crc;
6206
6207   /* now let's check the crc */
6208   c_crc[0] = crc;
6209   c_crc[1] = crc >> 8;
6210   c_crc[2] = crc >> 16;
6211   c_crc[3] = crc >> 24;
6212
6213   for (k = 0; k < 4; k++) {
6214     i = (i + 1) & 0xff;
6215     j = (j+s[i]) & 0xff;
6216     SSWAP(i,j);
6217 #if 0
6218     printf("-- %02x %02x\n", *dpos, c_crc[k]);
6219 #endif
6220     if ((*cpos++ ^ s[(s[i] + s[j]) & 0xff]) != c_crc[k])
6221       return -1; /* ICV mismatch */
6222   }
6223
6224   return 0;
6225 }
6226 #endif
6227
6228 static void init_wepkeys(void) {
6229   const char *tmp;
6230   int i, keyidx;
6231   GByteArray *bytes;
6232   gboolean res;
6233
6234   if (wep_keys) {
6235     for (i = 0; i < num_wepkeys; i++)
6236       g_free(wep_keys[i]);
6237     g_free(wep_keys);
6238   }
6239
6240   if (wep_keylens)
6241     g_free(wep_keylens);
6242
6243 #ifdef USE_ENV
6244   guint8 *buf;
6245
6246   tmp = getenv("WIRESHARK_WEPKEYNUM");
6247   if (!tmp) {
6248     num_wepkeys = 0;
6249     return;
6250   }
6251   num_wepkeys = atoi(tmp);
6252
6253   if (num_wepkeys < 1)
6254     return;
6255 #endif
6256
6257   /* Figure out how many valid keys we have */
6258   bytes = g_byte_array_new();
6259   num_wepkeys = 0;
6260   for ( i = 0; i < MAX_ENCRYPTION_KEYS; i++) {
6261     res = hex_str_to_bytes(wep_keystr[i], bytes, FALSE);
6262     if (wep_keystr[i] && res && bytes-> len > 0) {
6263       num_wepkeys++;
6264     }
6265   }
6266
6267 #ifdef  HAVE_AIRPDCAP
6268         /*
6269         * XXX - AirPDcap - That God sends it to us beautiful (che dio ce la mandi bona)
6270         * The next lines will add a key to the AirPDcap context. The keystring will be added
6271         * to the old WEP array too, but we don't care, because the packets will come here
6272         * already decrypted... One of these days we will fix this too
6273         */
6274         set_airpdcap_keys();
6275
6276         /* END AirPDcap */
6277 #endif
6278
6279   wep_keys = g_malloc0(num_wepkeys * sizeof(guint8*));
6280   wep_keylens = g_malloc(num_wepkeys * sizeof(int));
6281
6282   for (i = 0, keyidx = 0; i < MAX_ENCRYPTION_KEYS && keyidx < num_wepkeys; i++) {
6283     wep_keys[keyidx] = NULL;
6284     wep_keylens[keyidx] = 0;
6285
6286 #ifdef USE_ENV
6287     buf=ep_alloc(128);
6288     g_snprintf(buf, 128, "WIRESHARK_WEPKEY%d", i+1);
6289     tmp = getenv(buf);
6290 #else
6291     tmp = wep_keystr[i];
6292 #endif
6293
6294     if (tmp) {
6295 #if 0
6296 #ifdef USE_ENV
6297       printf("%s -- %s\n", buf, tmp);
6298 #else
6299       printf("%d -- %s\n", i+1, tmp);
6300 #endif
6301 #endif
6302
6303       if (wep_keys[keyidx]) {
6304         g_free(wep_keys[keyidx]);
6305       }
6306
6307       res = hex_str_to_bytes(tmp, bytes, FALSE);
6308       if (tmp && res && bytes->len > 0) {
6309         if (bytes->len > 32) {
6310           bytes->len = 32;
6311         }
6312         wep_keys[keyidx] = g_malloc0(32 * sizeof(guint8));
6313         memcpy(wep_keys[keyidx], bytes->data, bytes->len * sizeof(guint8));
6314         wep_keylens[keyidx] = bytes->len;
6315         keyidx++;
6316 #if 0
6317         printf("%d: %d bytes\n", i, bytes->len);
6318         printf("%d: %s\n", i, bytes_to_str(bytes->data, bytes->len));
6319 #endif
6320       } else {
6321 #if 0
6322         printf("res: %d  bytes->len: %d\n", res, bytes->len);
6323 #endif
6324         g_warning("Could not parse WEP key %d: %s", i + 1, tmp);
6325       }
6326     }
6327   }
6328   g_byte_array_free(bytes, TRUE);
6329 }
6330 /*
6331  * This code had been taken from AirSnort crack.c function classify()
6332  * Permission granted by snax <at> shmoo dot com
6333  * weak_iv - determine which key byte an iv is useful in resolving
6334  * parm     - p, pointer to the first byte of an IV
6335  * return   -  n - this IV is weak for byte n of a WEP key
6336  *            -1 - this IV is not weak for any key bytes
6337  *
6338  * This function tests for IVs that are known to satisfy the criteria
6339  * for a weak IV as specified in FMS section 7.1
6340  *
6341  */
6342 static int
6343 weak_iv(guchar *iv)
6344 {
6345         guchar sum, k;
6346
6347         if (iv[1] == 255 && iv[0] > 2 && iv[0] < 16) {
6348                 return iv[0] -3;
6349         }
6350
6351         sum = iv[0] + iv[1];
6352         if (sum == 1) {
6353                 if (iv[2] <= 0x0a) {
6354                         return iv[2] +2;
6355                 }
6356                 else if (iv[2] == 0xff){
6357                         return 0;
6358                 }
6359         }
6360         k = 0xfe - iv[2];
6361         if (sum == k  && (iv[2] >= 0xf2 && iv[2] <= 0xfe && iv[2] != 0xfd)){
6362                 return k;
6363         }
6364         return -1;
6365 }