- Split dissect_wendor_specific_ie into
[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  * Ethereal - Network traffic analyzer
9  * By Gerald Combs <gerald@ethereal.com>
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
46 #ifdef HAVE_CONFIG_H
47 # include "config.h"
48 #endif
49
50 #include <stdio.h>
51 #include <stdlib.h>
52
53 #ifdef NEED_SNPRINTF_H
54 # include "snprintf.h"
55 #endif
56
57 #include <string.h>
58 #include <glib.h>
59 #include <epan/bitswap.h>
60 #include <epan/proto.h>
61 #include <epan/packet.h>
62 #include <epan/addr_resolv.h>
63 #include <epan/strutil.h>
64 #include <epan/prefs.h>
65 #include <epan/reassemble.h>
66 #include "packet-ipx.h"
67 #include "packet-llc.h"
68 #include "packet-ieee80211.h"
69 #include <epan/etypes.h>
70 #include <epan/crc32.h>
71 #include <epan/tap.h>
72 #include <epan/emem.h>
73
74 #include <ctype.h>
75 #include "isprint.h"
76
77 /* Defragment fragmented 802.11 datagrams */
78 static gboolean wlan_defragment = TRUE;
79
80 /* Check for the presence of the 802.11 FCS */
81 static gboolean wlan_check_fcs = FALSE;
82
83 /* Ignore the WEP bit; assume packet is decrypted */
84 static gboolean wlan_ignore_wep = FALSE;
85
86 /* Tables for reassembly of fragments. */
87 static GHashTable *wlan_fragment_table = NULL;
88 static GHashTable *wlan_reassembled_table = NULL;
89
90 /* Stuff for the WEP decoder */
91 static gint num_wepkeys = 0;
92 static guint8 **wep_keys = NULL;
93 static int *wep_keylens = NULL;
94 static void init_wepkeys(void);
95 static int wep_decrypt(guint8 *buf, guint32 len, int key_override);
96 static tvbuff_t *try_decrypt_wep(tvbuff_t *tvb, guint32 offset, guint32 len);
97 static int weak_iv(guchar *iv);
98 #define SSWAP(a,b) {guint8 tmp = s[a]; s[a] = s[b]; s[b] = tmp;}
99
100 /* #define USE_ENV */
101 /* When this is set, an unlimited number of WEP keys can be set in the
102    environment:
103
104    ETHEREAL_WEPKEYNUM=##
105    ETHEREAL_WEPKEY1=aa:bb:cc:dd:...
106    ETHEREAL_WEPKEY2=aa:bab:cc:dd:ee:...
107
108    ... you get the idea.
109
110    otherwise you're limited to specifying four keys in the preference system.
111  */
112
113 #ifndef USE_ENV
114 static const char *wep_keystr[] = {NULL, NULL, NULL, NULL};
115 #endif
116
117 /* ************************************************************************* */
118 /*                          Miscellaneous Constants                          */
119 /* ************************************************************************* */
120 #define SHORT_STR 256
121
122 /* ************************************************************************* */
123 /*  Define some very useful macros that are used to analyze frame types etc. */
124 /* ************************************************************************* */
125 #define COMPOSE_FRAME_TYPE(x) (((x & 0x0C)<< 2)+((x & 0xF0) >> 4))      /* Create key to (sub)type */
126 #define COOK_PROT_VERSION(x)  ((x) & 0x3)
127 #define COOK_FRAME_TYPE(x)    (((x) & 0xC) >> 2)
128 #define COOK_FRAME_SUBTYPE(x) (((x) & 0xF0) >> 4)
129 #define COOK_ADDR_SELECTOR(x) ((x) & 0x300)
130 #define COOK_ASSOC_ID(x)      ((x) & 0x3FFF)
131 #define COOK_FRAGMENT_NUMBER(x) ((x) & 0x000F)
132 #define COOK_SEQUENCE_NUMBER(x) (((x) & 0xFFF0) >> 4)
133 #define COOK_QOS_PRIORITY(x)    ((x) & 0x0007)
134 #define COOK_QOS_ACK_POLICY(x)  (((x) & 0x0060) >> 5)
135 #define COOK_FLAGS(x)           (((x) & 0xFF00) >> 8)
136 #define COOK_DS_STATUS(x)       ((x) & 0x3)
137 #define COOK_WEP_KEY(x)       (((x) & 0xC0) >> 6)
138 #define COOK_QOS_TID(x)            ((x) & 0x000F)
139 #define COOK_QOS_EOSP(x)           (((x) & 0x0010) >> 4) /* end of service period */
140 #define COOK_QOS_FIELD_CONTENT(x)  (((x) & 0xFF00) >> 8)
141 #define COOK_PS_BUF_STATE(x)       (((x) & 0x02) >> 1)
142 #define COOK_PS_BUF_AC(x)          (((x) & 0x0C) >> 2)
143 #define COOK_PS_BUF_LOAD(x)        (((x) & 0xF0) >> 4)
144
145 #define KEY_EXTIV               0x20
146 #define EXTIV_LEN               8
147
148 #define FLAG_TO_DS              0x01
149 #define FLAG_FROM_DS            0x02
150 #define FLAG_MORE_FRAGMENTS     0x04
151 #define FLAG_RETRY              0x08
152 #define FLAG_POWER_MGT          0x10
153 #define FLAG_MORE_DATA          0x20
154 #define FLAG_PROTECTED          0x40
155 #define FLAG_ORDER              0x80
156 #define FLAG_DATA_NULL          0x24
157 #define FLAG_DATA_QOS           0x28
158 #define FLAG_EOSP               0x08
159 #define FLAG_DATA_CF_POLL       0x22
160
161 #define IS_TO_DS(x)            ((x) & FLAG_TO_DS)
162 #define IS_FROM_DS(x)          ((x) & FLAG_FROM_DS)
163 #define HAVE_FRAGMENTS(x)      ((x) & FLAG_MORE_FRAGMENTS)
164 #define IS_RETRY(x)            ((x) & FLAG_RETRY)
165 #define POWER_MGT_STATUS(x)    ((x) & FLAG_POWER_MGT)
166 #define HAS_MORE_DATA(x)       ((x) & FLAG_MORE_DATA)
167 #define IS_PROTECTED(x)              (!wlan_ignore_wep && ((x) & FLAG_PROTECTED))
168 #define IS_STRICTLY_ORDERED(x) ((x) & FLAG_ORDER)
169 #define IS_DATA_NULL(x)        (((x) & 0xf4) == FLAG_DATA_NULL)
170 #define IS_DATA_QOS(x)         (((x) & 0xf8) == FLAG_DATA_QOS)
171 #define IS_DATA_CF_POLL(x)     (((x) & 0xf2) == FLAG_DATA_CF_POLL)
172
173 #define MGT_RESERVED_RANGE(x)  (((x>=0x06)&&(x<=0x07))||((x>=0x0E)&&(x<=0x0F)))
174 #define CTRL_RESERVED_RANGE(x) ((x>=0x10)&&(x<=0x17))
175 #define DATA_RESERVED_RANGE(x) (x==0x2D)
176 #define SPEC_RESERVED_RANGE(x) ((x>=0x30)&&(x<=0x3f))
177
178
179 /* ************************************************************************* */
180 /*              Constants used to identify cooked frame types                */
181 /* ************************************************************************* */
182 #define MGT_FRAME            0x00       /* Frame type is management */
183 #define CONTROL_FRAME        0x01       /* Frame type is control */
184 #define DATA_FRAME           0x02       /* Frame type is Data */
185
186 #define DATA_SHORT_HDR_LEN     24
187 #define DATA_LONG_HDR_LEN      30
188 #define MGT_FRAME_HDR_LEN      24       /* Length of Managment frame-headers */
189
190 #define MGT_ASSOC_REQ        0x00       /* Management - association request        */
191 #define MGT_ASSOC_RESP       0x01       /* Management - association response       */
192 #define MGT_REASSOC_REQ      0x02       /* Management - reassociation request      */
193 #define MGT_REASSOC_RESP     0x03       /* Management - reassociation response     */
194 #define MGT_PROBE_REQ        0x04       /* Management - Probe request              */
195 #define MGT_PROBE_RESP       0x05       /* Management - Probe response             */
196 #define MGT_BEACON           0x08       /* Management - Beacon frame               */
197 #define MGT_ATIM             0x09       /* Management - ATIM                       */
198 #define MGT_DISASS           0x0A       /* Management - Disassociation             */
199 #define MGT_AUTHENTICATION   0x0B       /* Management - Authentication             */
200 #define MGT_DEAUTHENTICATION 0x0C       /* Management - Deauthentication           */
201 #define MGT_ACTION           0x0D       /* Management - Action */
202
203 #define CTRL_BLOCK_ACK_REQ   0x18       /* Control - Block ack Request              */
204 #define CTRL_BLOCK_ACK       0x19       /* Control - Block ack                      */
205
206 #define CTRL_PS_POLL         0x1A       /* Control - power-save poll               */
207 #define CTRL_RTS             0x1B       /* Control - request to send               */
208 #define CTRL_CTS             0x1C       /* Control - clear to send                 */
209 #define CTRL_ACKNOWLEDGEMENT 0x1D       /* Control - acknowledgement               */
210 #define CTRL_CFP_END         0x1E       /* Control - contention-free period end    */
211 #define CTRL_CFP_ENDACK      0x1F       /* Control - contention-free period end/ack */
212
213 #define DATA                 0x20       /* Data - Data                             */
214 #define DATA_CF_ACK          0x21       /* Data - Data + CF acknowledge            */
215 #define DATA_CF_POLL         FLAG_DATA_CF_POLL  /* Data - Data + CF poll                   */
216 #define DATA_CF_ACK_POLL     0x23       /* Data - Data + CF acknowledge + CF poll  */
217 #define DATA_NULL_FUNCTION   FLAG_DATA_NULL     /* Data - Null function (no data)          */
218 #define DATA_CF_ACK_NOD      0x25       /* Data - CF ack (no data)                 */
219 #define DATA_CF_POLL_NOD     0x26       /* Data - CF poll (No data)         */
220 #define DATA_CF_ACK_POLL_NOD 0x27       /* Data - CF ack + CF poll (no data)       */
221 #define DATA_QOS_DATA        FLAG_DATA_QOS      /* Data - QoS Data                         */
222
223
224 #define DATA_QOS_DATA_CF_ACK        0x29        /* Data - QoS Data + CF-Ack               */
225 #define DATA_QOS_DATA_CF_POLL       0x2A        /* Data - QoS Data + CF-Poll              */
226 #define DATA_QOS_DATA_CF_ACK_POLL   0x2B        /* Data - QoS Data + CF-Ack + CF-poll     */
227 #define DATA_QOS_NULL               0x2C        /* Data - QoS Null                        */
228 #define DATA_QOS_CF_POLL_NOD        0x2E        /* Data - QoS CF-poll (No Data)           */
229 #define DATA_QOS_CF_ACK_POLL_NOD    0x2F        /* Data - QoS CF-Ack + CF-poll (No Data)  */
230
231 #define DATA_ADDR_T1         0
232 #define DATA_ADDR_T2         (FLAG_FROM_DS << 8)
233 #define DATA_ADDR_T3         (FLAG_TO_DS << 8)
234 #define DATA_ADDR_T4         ((FLAG_TO_DS|FLAG_FROM_DS) << 8)
235
236
237 /* ************************************************************************* */
238 /*          Macros used to extract information about fixed fields            */
239 /* ************************************************************************* */
240 #define ESS_SET(x) ((x) & 0x0001)
241 #define IBSS_SET(x) ((x) & 0x0002)
242
243
244
245 /* ************************************************************************* */
246 /*        Logical field codes (dissector's encoding of fixed fields)         */
247 /* ************************************************************************* */
248 #define FIELD_TIMESTAMP       0x01      /* 64-bit timestamp                       */
249 #define FIELD_BEACON_INTERVAL 0x02      /* 16-bit beacon interval                 */
250 #define FIELD_CAP_INFO        0x03      /* Add capability information tree        */
251 #define FIELD_AUTH_ALG        0x04      /* Authentication algorithm used          */
252 #define FIELD_AUTH_TRANS_SEQ  0x05      /* Authentication sequence number         */
253 #define FIELD_CURRENT_AP_ADDR 0x06
254 #define FIELD_LISTEN_IVAL     0x07
255 #define FIELD_REASON_CODE     0x08
256 #define FIELD_ASSOC_ID        0x09
257 #define FIELD_STATUS_CODE     0x0A
258 #define FIELD_CATEGORY_CODE   0x0B      /* Management action category */
259 #define FIELD_ACTION_CODE     0x0C      /* Management action code */
260 #define FIELD_DIALOG_TOKEN    0x0D      /* Management action dialog token */
261 #define FIELD_WME_ACTION_CODE   0x0E    /* Management notification action code */
262 #define FIELD_WME_DIALOG_TOKEN  0x0F    /* Management notification dialog token */
263 #define FIELD_WME_STATUS_CODE   0x10    /* Management notification setup response status code */
264
265 /* ************************************************************************* */
266 /*        Logical field codes (IEEE 802.11 encoding of tags)                 */
267 /* ************************************************************************* */
268 #define TAG_SSID                 0x00
269 #define TAG_SUPP_RATES           0x01
270 #define TAG_FH_PARAMETER         0x02
271 #define TAG_DS_PARAMETER         0x03
272 #define TAG_CF_PARAMETER         0x04
273 #define TAG_TIM                  0x05
274 #define TAG_IBSS_PARAMETER       0x06
275 #define TAG_COUNTRY_INFO         0x07
276 #define TAG_FH_HOPPING_PARAMETER 0x08
277 #define TAG_FH_HOPPING_TABLE     0x09
278 #define TAG_REQUEST              0x0A
279 #define TAG_QBSS_LOAD            0x0B
280 #define TAG_EDCA_PARAM_SET       0x0C
281 #define TAG_TRAF_SPEC            0x0D
282 #define TAG_TRAF_CLASS           0x0E
283 #define TAG_SCHEDULE             0x0F
284 #define TAG_CHALLENGE_TEXT       0x10
285 #define TAG_POWER_CONSTRAINT     0x20
286 #define TAG_POWER_CAPABILITY     0x21
287 #define TAG_TPC_REQUEST          0x22
288 #define TAG_TPC_REPORT           0x23
289 #define TAG_SUPPORTED_CHANNELS   0x24
290 #define TAG_CHANNEL_SWITCH_ANN   0x25
291 #define TAG_MEASURE_REQ          0x26
292 #define TAG_MEASURE_REP          0x27
293 #define TAG_QUIET                0x28
294 #define TAG_IBSS_DFS             0x29
295 #define TAG_ERP_INFO             0x2A
296 #define TAG_TS_DELAY             0x2B
297 #define TAG_TCLAS_PROCESS        0x2C
298 #define TAG_QOS_CAPABILITY       0x2E
299 #define TAG_ERP_INFO_OLD         0x2F   /* IEEE Std 802.11g/D4.0 */
300 #define TAG_RSN_IE               0x30
301 #define TAG_EXT_SUPP_RATES       0x32
302 #define TAG_AGERE_PROPRIETARY    0x80
303 #define TAG_CISCO_UNKNOWN_1      0x85   /* Cisco Compatible eXtensions? */
304 #define TAG_CISCO_UNKNOWN_2      0x88   /* Cisco Compatible eXtensions? */
305 #define TAG_VENDOR_SPECIFIC_IE   0xDD
306 #define TAG_SYMBOL_PROPRIETARY   0xAD
307
308 #define WPA_OUI "\x00\x50\xF2"
309 #define RSN_OUI "\x00\x0F\xAC"
310 #define WME_OUI "\x00\x50\xF2"
311
312 #define PMKID_LEN 16
313
314 /* ************************************************************************* */
315 /*                         Frame types, and their names                      */
316 /* ************************************************************************* */
317 static const value_string frame_type_subtype_vals[] = {
318         {MGT_ASSOC_REQ,        "Association Request"},
319         {MGT_ASSOC_RESP,       "Association Response"},
320         {MGT_REASSOC_REQ,      "Reassociation Request"},
321         {MGT_REASSOC_RESP,     "Reassociation Response"},
322         {MGT_PROBE_REQ,        "Probe Request"},
323         {MGT_PROBE_RESP,       "Probe Response"},
324         {MGT_BEACON,           "Beacon frame"},
325         {MGT_ATIM,             "ATIM"},
326         {MGT_DISASS,           "Dissassociate"},
327         {MGT_AUTHENTICATION,   "Authentication"},
328         {MGT_DEAUTHENTICATION, "Deauthentication"},
329         {MGT_ACTION,           "Action"},
330         {CTRL_PS_POLL,         "Power-Save poll"},
331         {CTRL_RTS,             "Request-to-send"},
332         {CTRL_CTS,             "Clear-to-send"},
333         {CTRL_ACKNOWLEDGEMENT, "Acknowledgement"},
334         {CTRL_CFP_END,         "CF-End (Control-frame)"},
335         {CTRL_CFP_ENDACK,      "CF-End + CF-Ack (Control-frame)"},
336         {DATA,                 "Data"},
337         {DATA_CF_ACK,          "Data + CF-Acknowledgement"},
338         {DATA_CF_POLL,         "Data + CF-Poll"},
339         {DATA_CF_ACK_POLL,     "Data + CF-Acknowledgement/Poll"},
340         {DATA_NULL_FUNCTION,   "Null function (No data)"},
341         {DATA_CF_ACK_NOD,      "Data + Acknowledgement (No data)"},
342         {DATA_CF_POLL_NOD,     "Data + CF-Poll (No data)"},
343         {DATA_CF_ACK_POLL_NOD, "Data + CF-Acknowledgement/Poll (No data)"},
344         {DATA_QOS_DATA,        "QoS Data"},
345         {DATA_QOS_NULL,        "QoS Null (No data)"},
346         {DATA_QOS_DATA_CF_ACK,  "802.11 Q0S Data + CF-Ack"},
347         {DATA_QOS_DATA_CF_POLL, "802.11 QoS Data + CF-Poll"},
348         {DATA_QOS_DATA_CF_ACK_POLL,     "802.11 Q0S Data + CF-Ack/Poll"},
349         {DATA_QOS_CF_POLL_NOD,  "802.11 QoS CF-poll (No Data)"},
350         {DATA_QOS_CF_ACK_POLL_NOD,  "802.11 QoS CF-Ack + CF-poll (No Data)"},
351         {CTRL_BLOCK_ACK_REQ,    "802.11 Block Ack Req"},
352         {CTRL_BLOCK_ACK,        "802.11 Block Ack"},
353         {0,                    NULL}
354 };
355
356 /* ************************************************************************* */
357 /*                             802.1D Tag Names                              */
358 /* ************************************************************************* */
359 static const char *qos_tags[8] = {
360         "Best Effort",
361         "Background",
362         "Spare",
363         "Excellent Effort",
364         "Controlled Load",
365         "Video",
366         "Voice",
367         "Network Control"
368 };
369
370 /* ************************************************************************* */
371 /*                 WME Access Category Names (by 802.1D Tag)                 */
372 /* ************************************************************************* */
373 static const char *qos_acs[8] = {
374         "Best Effort",
375         "Background",
376         "Background",
377         "Video",
378         "Video",
379         "Video",
380         "Voice",
381         "Voice"
382 };
383
384 /* ************************************************************************* */
385 /*                   WME Access Category Names (by WME ACI)                  */
386 /* ************************************************************************* */
387 static const char *wme_acs[4] = {
388         "Best Effort",
389         "Background",
390         "Video",
391         "Voice",
392 };
393
394
395 #define CAT_SPECTRUM_MGMT       0
396 #define CAT_QOS                 1
397 #define CAT_DLS                 2
398 #define CAT_BLOCK_ACK           3
399 #define CAT_MGMT_NOTIFICATION   17
400
401 #define SM_ACTION_MEASUREMENT_REQUEST   0
402 #define SM_ACTION_MEASUREMENT_REPORT    1
403 #define SM_ACTION_TPC_REQUEST           2
404 #define SM_ACTION_TPC_REPORT            3
405 #define SM_ACTION_CHAN_SWITCH_ANNC      4
406
407 static int proto_wlan = -1;
408 static packet_info * g_pinfo;
409
410 /* ************************************************************************* */
411 /*                Header field info values for radio information             */
412 /* ************************************************************************* */
413 static int hf_data_rate = -1;
414 static int hf_channel = -1;
415 static int hf_signal_strength = -1;
416
417 /* ************************************************************************* */
418 /*                Header field info values for FC-field                      */
419 /* ************************************************************************* */
420 static int hf_fc_field = -1;
421 static int hf_fc_proto_version = -1;
422 static int hf_fc_frame_type = -1;
423 static int hf_fc_frame_subtype = -1;
424 static int hf_fc_frame_type_subtype = -1;
425
426 static int hf_fc_flags = -1;
427 static int hf_fc_to_ds = -1;
428 static int hf_fc_from_ds = -1;
429 static int hf_fc_data_ds = -1;
430
431 static int hf_fc_more_frag = -1;
432 static int hf_fc_retry = -1;
433 static int hf_fc_pwr_mgt = -1;
434 static int hf_fc_more_data = -1;
435 static int hf_fc_protected = -1;
436 static int hf_fc_order = -1;
437
438
439 /* ************************************************************************* */
440 /*                   Header values for Duration/ID field                     */
441 /* ************************************************************************* */
442 static int hf_did_duration = -1;
443 static int hf_assoc_id = -1;
444
445
446 /* ************************************************************************* */
447 /*         Header values for different address-fields (all 4 of them)        */
448 /* ************************************************************************* */
449 static int hf_addr_da = -1;     /* Destination address subfield */
450 static int hf_addr_sa = -1;     /* Source address subfield */
451 static int hf_addr_ra = -1;     /* Receiver address subfield */
452 static int hf_addr_ta = -1;     /* Transmitter address subfield */
453 static int hf_addr_bssid = -1;  /* address is bssid */
454
455 static int hf_addr = -1;        /* Source or destination address subfield */
456
457
458 /* ************************************************************************* */
459 /*                Header values for QoS control field                        */
460 /* ************************************************************************* */
461 static int hf_qos_priority = -1;
462 static int hf_qos_ack_policy = -1;
463 static int hf_qos_eosp = -1;
464 static int hf_qos_field_content = -1;
465 /*static int hf_qos_txop_limit = -1;*/
466 static int hf_qos_buf_state = -1;
467 static int hf_qos_buf_ac = -1;
468 static int hf_qos_buf_load = -1;
469 /*static int hf_qos_txop_dur_req = -1;
470 static int hf_qos_queue_size = -1;*/
471
472 /* ************************************************************************* */
473 /*                Header values for sequence number field                    */
474 /* ************************************************************************* */
475 static int hf_frag_number = -1;
476 static int hf_seq_number = -1;
477
478 /* ************************************************************************* */
479 /*                   Header values for Frame Check field                     */
480 /* ************************************************************************* */
481 static int hf_fcs = -1;
482
483 /* ************************************************************************* */
484 /*                   Header values for reassembly                            */
485 /* ************************************************************************* */
486 static int hf_fragments = -1;
487 static int hf_fragment = -1;
488 static int hf_fragment_overlap = -1;
489 static int hf_fragment_overlap_conflict = -1;
490 static int hf_fragment_multiple_tails = -1;
491 static int hf_fragment_too_long_fragment = -1;
492 static int hf_fragment_error = -1;
493 static int hf_reassembled_in = -1;
494
495
496 static int proto_wlan_mgt = -1;
497 /* ************************************************************************* */
498 /*                      Fixed fields found in mgt frames                     */
499 /* ************************************************************************* */
500 static int ff_auth_alg = -1;    /* Authentication algorithm field            */
501 static int ff_auth_seq = -1;    /* Authentication transaction sequence       */
502 static int ff_current_ap = -1;  /* Current AP MAC address                    */
503 static int ff_listen_ival = -1; /* Listen interval fixed field               */
504 static int ff_timestamp = -1;   /* 64 bit timestamp                          */
505 static int ff_beacon_interval = -1;     /* 16 bit Beacon interval            */
506 static int ff_assoc_id = -1;    /* 16 bit AID field                          */
507 static int ff_reason = -1;      /* 16 bit reason code                        */
508 static int ff_status_code = -1; /* Status code                               */
509 static int ff_category_code = -1;       /* 8 bit Category code */
510 static int ff_action_code = -1;         /* 8 bit Action code */
511 static int ff_dialog_token = -1;        /* 8 bit Dialog token */
512 static int ff_wme_action_code = -1;     /* Management notification action code */
513 static int ff_wme_status_code = -1;     /* Management notification setup response status code */
514
515 /* ************************************************************************* */
516 /*            Flags found in the capability field (fixed field)              */
517 /* ************************************************************************* */
518 static int ff_capture = -1;
519 static int ff_cf_ess = -1;
520 static int ff_cf_ibss = -1;
521 static int ff_cf_sta_poll = -1; /* CF pollable status for a STA            */
522 static int ff_cf_ap_poll = -1;  /* CF pollable status for an AP            */
523 static int ff_cf_privacy = -1;
524 static int ff_cf_preamble = -1;
525 static int ff_cf_pbcc = -1;
526 static int ff_cf_agility = -1;
527 static int ff_short_slot_time = -1;
528 static int ff_dsss_ofdm = -1;
529 static int ff_cf_spec_man = -1;
530 static int ff_cf_apsd = -1;
531 static int ff_cf_del_blk_ack = -1;
532 static int ff_cf_imm_blk_ack = -1;
533
534 /* ************************************************************************* */
535 /*                       Tagged value format fields                          */
536 /* ************************************************************************* */
537 static int tag_number = -1;
538 static int tag_length = -1;
539 static int tag_interpretation = -1;
540 static int tag_oui = -1;
541
542 static int tim_length = -1;
543 static int tim_dtim_count = -1;
544 static int tim_dtim_period = -1;
545 static int tim_bmapctl = -1;
546
547
548 static int hf_fixed_parameters = -1;    /* Protocol payload for management frames */
549 static int hf_tagged_parameters = -1;   /* Fixed payload item */
550 static int hf_wep_iv = -1;
551 static int hf_wep_iv_weak = -1;
552 static int hf_tkip_extiv = -1;
553 static int hf_ccmp_extiv = -1;
554 static int hf_wep_key = -1;
555 static int hf_wep_icv = -1;
556
557
558 static int rsn_cap = -1;
559 static int rsn_cap_preauth = -1;
560 static int rsn_cap_no_pairwise = -1;
561 static int rsn_cap_ptksa_replay_counter = -1;
562 static int rsn_cap_gtksa_replay_counter = -1;
563
564 /* ************************************************************************* */
565 /*                               Protocol trees                              */
566 /* ************************************************************************* */
567 static gint ett_80211 = -1;
568 static gint ett_proto_flags = -1;
569 static gint ett_cap_tree = -1;
570 static gint ett_fc_tree = -1;
571 static gint ett_fragments = -1;
572 static gint ett_fragment = -1;
573
574 static gint ett_80211_mgt = -1;
575 static gint ett_fixed_parameters = -1;
576 static gint ett_tagged_parameters = -1;
577 static gint ett_qos_parameters = -1;
578 static gint ett_qos_ps_buf_state = -1;
579 static gint ett_wep_parameters = -1;
580
581 static gint ett_rsn_cap_tree = -1;
582
583 static gint ett_80211_mgt_ie = -1;
584
585 static const fragment_items frag_items = {
586         &ett_fragment,
587         &ett_fragments,
588         &hf_fragments,
589         &hf_fragment,
590         &hf_fragment_overlap,
591         &hf_fragment_overlap_conflict,
592         &hf_fragment_multiple_tails,
593         &hf_fragment_too_long_fragment,
594         &hf_fragment_error,
595         &hf_reassembled_in,
596         "fragments"
597 };
598
599 static dissector_handle_t llc_handle;
600 static dissector_handle_t ipx_handle;
601 static dissector_handle_t eth_withoutfcs_handle;
602 static dissector_handle_t data_handle;
603
604 static int wlan_tap = -1;
605
606 /* ************************************************************************* */
607 /*            Return the length of the current header (in bytes)             */
608 /* ************************************************************************* */
609 static int
610 find_header_length (guint16 fcf)
611 {
612   int len;
613
614   switch (COOK_FRAME_TYPE (fcf)) {
615
616   case MGT_FRAME:
617     return MGT_FRAME_HDR_LEN;
618
619   case CONTROL_FRAME:
620     switch (COMPOSE_FRAME_TYPE (fcf)) {
621
622     case CTRL_CTS:
623     case CTRL_ACKNOWLEDGEMENT:
624       return 10;
625
626     case CTRL_RTS:
627     case CTRL_PS_POLL:
628     case CTRL_CFP_END:
629     case CTRL_CFP_ENDACK:
630     case CTRL_BLOCK_ACK_REQ:
631     case CTRL_BLOCK_ACK:
632       return 16;
633     }
634     return 4;   /* XXX */
635
636   case DATA_FRAME:
637     len = (COOK_ADDR_SELECTOR(fcf) == DATA_ADDR_T4) ? DATA_LONG_HDR_LEN :
638                                                       DATA_SHORT_HDR_LEN;
639     if( IS_DATA_QOS(fcf))
640       return len + 2;
641     else
642       return len;
643
644   default:
645     return 4;   /* XXX */
646   }
647 }
648
649
650 /* ************************************************************************* */
651 /*          This is the capture function used to update packet counts        */
652 /* ************************************************************************* */
653 static void
654 capture_ieee80211_common (const guchar * pd, int offset, int len,
655                           packet_counts * ld, gboolean fixed_length_header)
656 {
657   guint16 fcf, hdr_length;
658
659   if (!BYTES_ARE_IN_FRAME(offset, len, 2)) {
660     ld->other++;
661     return;
662   }
663
664   fcf = pletohs (&pd[0]);
665
666   if (IS_PROTECTED(COOK_FLAGS(fcf)))
667     {
668       ld->other++;
669       return;
670     }
671
672   switch (COMPOSE_FRAME_TYPE (fcf))
673     {
674
675     case DATA:                  /* We got a data frame */
676     case DATA_CF_ACK:           /* Data with ACK */
677     case DATA_CF_POLL:
678     case DATA_CF_ACK_POLL:
679     case DATA_QOS_DATA:
680       if (fixed_length_header)
681         hdr_length = DATA_LONG_HDR_LEN;
682       else
683         hdr_length = find_header_length (fcf);
684       /* I guess some bridges take Netware Ethernet_802_3 frames,
685          which are 802.3 frames (with a length field rather than
686          a type field, but with no 802.2 header in the payload),
687          and just stick the payload into an 802.11 frame.  I've seen
688          captures that show frames of that sort.
689
690          This means we have to do the same check for Netware 802.3 -
691          or, if you will, "Netware 802.11" - that we do in the
692          Ethernet dissector, i.e. checking for 0xffff as the first
693          four bytes of the payload and, if we find it, treating it
694          as an IPX frame. */
695       if (!BYTES_ARE_IN_FRAME(offset+hdr_length, len, 2)) {
696         ld->other++;
697         return;
698       }
699       if (pd[offset+hdr_length] == 0xff && pd[offset+hdr_length+1] == 0xff) {
700         capture_ipx (ld);
701       }
702       else {
703         capture_llc (pd, offset + hdr_length, len, ld);
704       }
705       break;
706
707     default:
708       ld->other++;
709       break;
710     }
711 }
712
713 /*
714  * Handle 802.11 with a variable-length link-layer header.
715  */
716 void
717 capture_ieee80211 (const guchar * pd, int offset, int len, packet_counts * ld)
718 {
719   capture_ieee80211_common (pd, offset, len, ld, FALSE);
720 }
721
722 /*
723  * Handle 802.11 with a fixed-length link-layer header (padded to the
724  * maximum length).
725  */
726 void
727 capture_ieee80211_fixed (const guchar * pd, int offset, int len, packet_counts * ld)
728 {
729   capture_ieee80211_common (pd, offset, len, ld, TRUE);
730 }
731
732
733 /* ************************************************************************* */
734 /*          Add the subtree used to store the fixed parameters               */
735 /* ************************************************************************* */
736 static proto_tree *
737 get_fixed_parameter_tree (proto_tree * tree, tvbuff_t *tvb, int start, int size)
738 {
739   proto_item *fixed_fields;
740   fixed_fields =
741     proto_tree_add_uint_format (tree, hf_fixed_parameters, tvb, start,
742                                 size, size, "Fixed parameters (%d bytes)",
743                                 size);
744
745   return proto_item_add_subtree (fixed_fields, ett_fixed_parameters);
746 }
747
748
749 /* ************************************************************************* */
750 /*            Add the subtree used to store tagged parameters                */
751 /* ************************************************************************* */
752 static proto_tree *
753 get_tagged_parameter_tree (proto_tree * tree, tvbuff_t *tvb, int start, int size)
754 {
755   proto_item *tagged_fields;
756
757   tagged_fields = proto_tree_add_uint_format (tree, hf_tagged_parameters,
758                                               tvb,
759                                               start,
760                                               size,
761                                               size,
762                                               "Tagged parameters (%d bytes)",
763                                               size);
764
765   return proto_item_add_subtree (tagged_fields, ett_tagged_parameters);
766 }
767
768
769 /* ************************************************************************* */
770 /*              Dissect and add fixed mgmt fields to protocol tree           */
771 /* ************************************************************************* */
772 static void
773 add_fixed_field (proto_tree * tree, tvbuff_t * tvb, int offset, int lfcode)
774 {
775   const guint8 *dataptr;
776   char out_buff[SHORT_STR];
777   guint16 capability;
778   proto_item *cap_item;
779   static proto_tree *cap_tree;
780   double temp_double;
781
782   switch (lfcode)
783     {
784     case FIELD_TIMESTAMP:
785       dataptr = tvb_get_ptr (tvb, offset, 8);
786       memset (out_buff, 0, SHORT_STR);
787       g_snprintf (out_buff, SHORT_STR, "0x%02X%02X%02X%02X%02X%02X%02X%02X",
788                 dataptr[7],
789                 dataptr[6],
790                 dataptr[5],
791                 dataptr[4],
792                 dataptr[3],
793                 dataptr[2],
794                 dataptr[1],
795                 dataptr[0]);
796
797       proto_tree_add_string (tree, ff_timestamp, tvb, offset, 8, out_buff);
798       break;
799
800     case FIELD_BEACON_INTERVAL:
801       capability = tvb_get_letohs (tvb, offset);
802       temp_double = (double)capability;
803       temp_double = temp_double * 1024 / 1000000;
804       proto_tree_add_double_format (tree, ff_beacon_interval, tvb, offset, 2,
805                                     temp_double,"Beacon Interval: %f [Seconds]",
806                                     temp_double);
807       if (check_col (g_pinfo->cinfo, COL_INFO)) {
808           col_append_fstr(g_pinfo->cinfo, COL_INFO, ",BI=%d", capability);
809       }
810       break;
811
812
813     case FIELD_CAP_INFO:
814       capability = tvb_get_letohs (tvb, offset);
815
816       cap_item = proto_tree_add_uint_format (tree, ff_capture,
817                                              tvb, offset, 2,
818                                              capability,
819                                              "Capability Information: 0x%04X",
820                                              capability);
821       cap_tree = proto_item_add_subtree (cap_item, ett_cap_tree);
822       proto_tree_add_boolean (cap_tree, ff_cf_ess, tvb, offset, 2,
823                               capability);
824       proto_tree_add_boolean (cap_tree, ff_cf_ibss, tvb, offset, 2,
825                               capability);
826       if (ESS_SET (capability) != 0)    /* This is an AP */
827         proto_tree_add_uint (cap_tree, ff_cf_ap_poll, tvb, offset, 2,
828                              capability);
829
830       else                      /* This is a STA */
831         proto_tree_add_uint (cap_tree, ff_cf_sta_poll, tvb, offset, 2,
832                              capability);
833       proto_tree_add_boolean (cap_tree, ff_cf_privacy, tvb, offset, 2,
834                               capability);
835       proto_tree_add_boolean (cap_tree, ff_cf_preamble, tvb, offset, 2,
836                               capability);
837       proto_tree_add_boolean (cap_tree, ff_cf_pbcc, tvb, offset, 2,
838                               capability);
839       proto_tree_add_boolean (cap_tree, ff_cf_agility, tvb, offset, 2,
840                               capability);
841       proto_tree_add_boolean (cap_tree, ff_cf_spec_man, tvb, offset, 2,
842                               capability);
843       proto_tree_add_boolean (cap_tree, ff_short_slot_time, tvb, offset, 2,
844                               capability);
845       proto_tree_add_boolean (cap_tree, ff_cf_apsd, tvb, offset, 2,
846                               capability);
847       proto_tree_add_boolean (cap_tree, ff_dsss_ofdm, tvb, offset, 2,
848                               capability);
849       proto_tree_add_boolean (cap_tree, ff_cf_del_blk_ack, tvb, offset, 2,
850                               capability);
851       proto_tree_add_boolean (cap_tree, ff_cf_imm_blk_ack, tvb, offset, 2,
852                               capability);
853       break;
854
855     case FIELD_AUTH_ALG:
856       proto_tree_add_item (tree, ff_auth_alg, tvb, offset, 2, TRUE);
857       break;
858
859     case FIELD_AUTH_TRANS_SEQ:
860       proto_tree_add_item (tree, ff_auth_seq, tvb, offset, 2, TRUE);
861       break;
862
863     case FIELD_CURRENT_AP_ADDR:
864       proto_tree_add_item (tree, ff_current_ap, tvb, offset, 6, FALSE);
865       break;
866
867     case FIELD_LISTEN_IVAL:
868       proto_tree_add_item (tree, ff_listen_ival, tvb, offset, 2, TRUE);
869       break;
870
871     case FIELD_REASON_CODE:
872       proto_tree_add_item (tree, ff_reason, tvb, offset, 2, TRUE);
873       break;
874
875     case FIELD_ASSOC_ID:
876       proto_tree_add_uint(tree, ff_assoc_id, tvb, offset, 2,
877                           COOK_ASSOC_ID(tvb_get_letohs(tvb,offset)));
878       /* proto_tree_add_item (tree, ff_assoc_id, tvb, offset, 2, TRUE); */
879       break;
880
881     case FIELD_STATUS_CODE:
882       proto_tree_add_item (tree, ff_status_code, tvb, offset, 2, TRUE);
883       break;
884
885     case FIELD_CATEGORY_CODE:
886       proto_tree_add_item (tree, ff_category_code, tvb, offset, 1, TRUE);
887       break;
888
889     case FIELD_ACTION_CODE:
890       proto_tree_add_item (tree, ff_action_code, tvb, offset, 1, TRUE);
891       break;
892
893     case FIELD_DIALOG_TOKEN:
894       proto_tree_add_item (tree, ff_dialog_token, tvb, offset, 1, TRUE);
895       break;
896
897     case FIELD_WME_ACTION_CODE:
898       proto_tree_add_item (tree, ff_wme_action_code, tvb, offset, 1, TRUE);
899       break;
900
901     case FIELD_WME_STATUS_CODE:
902       proto_tree_add_item (tree, ff_wme_status_code, tvb, offset, 1, TRUE);
903       break;
904     }
905 }
906
907 static const char *wpa_cipher_str[] =
908 {
909   "NONE",
910   "WEP (40-bit)",
911   "TKIP",
912   "AES (OCB)",
913   "AES (CCM)",
914   "WEP (104-bit)",
915 };
916
917 static const char *
918 wpa_cipher_idx2str(guint idx)
919 {
920   if (idx < sizeof(wpa_cipher_str)/sizeof(wpa_cipher_str[0]))
921     return wpa_cipher_str[idx];
922   return "UNKNOWN";
923 }
924
925 static const char *wpa_keymgmt_str[] =
926 {
927   "NONE",
928   "WPA",
929   "PSK",
930 };
931
932 static const char *
933 wpa_keymgmt_idx2str(guint idx)
934 {
935   if (idx < sizeof(wpa_keymgmt_str)/sizeof(wpa_keymgmt_str[0]))
936     return wpa_keymgmt_str[idx];
937   return "UNKNOWN";
938 }
939
940 static void
941 dissect_vendor_ie_wpawme(proto_tree * ietree, proto_tree * tree, tvbuff_t * tvb,
942         int offset, guint32 tag_len, const guint8 *tag_val)
943 {
944       guint32 tag_val_off = 0;
945       char out_buff[SHORT_STR], *pos;
946       guint i;
947
948       /* Wi-Fi Protected Access (WPA) Information Element */
949       if (tag_val_off + 6 <= tag_len && !memcmp(tag_val, WPA_OUI"\x01", 4)) {
950         g_snprintf(out_buff, SHORT_STR, "WPA IE, type %u, version %u",
951                   tag_val[tag_val_off + 3], pletohs(&tag_val[tag_val_off + 4]));
952         proto_tree_add_string(tree, tag_interpretation, tvb, offset, 6, out_buff);
953         offset += 6;
954         tag_val_off += 6;
955         if (tag_val_off + 4 <= tag_len) {
956           /* multicast cipher suite */
957           if (!memcmp(&tag_val[tag_val_off], WPA_OUI, 3)) {
958             g_snprintf(out_buff, SHORT_STR, "Multicast cipher suite: %s",
959                       wpa_cipher_idx2str(tag_val[tag_val_off + 3]));
960             proto_tree_add_string(tree, tag_interpretation, tvb, offset, 4, out_buff);
961             offset += 4;
962             tag_val_off += 4;
963             /* unicast cipher suites */
964             if (tag_val_off + 2 <= tag_len) {
965               g_snprintf(out_buff, SHORT_STR, "# of unicast cipher suites: %u",
966                         pletohs(tag_val + tag_val_off));
967               proto_tree_add_string(tree, tag_interpretation, tvb, offset, 2, out_buff);
968               offset += 2;
969               tag_val_off += 2;
970               i = 1;
971               while (tag_val_off + 4 <= tag_len) {
972                 if (!memcmp(&tag_val[tag_val_off], WPA_OUI, 3)) {
973                   g_snprintf(out_buff, SHORT_STR, "Unicast cipher suite %u: %s",
974                             i, wpa_cipher_idx2str(tag_val[tag_val_off + 3]));
975                   proto_tree_add_string(tree, tag_interpretation, tvb, offset, 4, out_buff);
976                   offset += 4;
977                   tag_val_off += 4;
978                   i ++;
979                 }
980                 else
981                   break;
982               }
983               /* authenticated key management suites */
984               if (tag_val_off + 2 <= tag_len) {
985                 g_snprintf(out_buff, SHORT_STR, "# of auth key management suites: %u",
986                           pletohs(tag_val + tag_val_off));
987                 proto_tree_add_string(tree, tag_interpretation, tvb, offset, 2, out_buff);
988                 offset += 2;
989                 tag_val_off += 2;
990                 i = 1;
991                 while (tag_val_off + 4 <= tag_len) {
992                   if (!memcmp(&tag_val[tag_val_off], WPA_OUI, 3)) {
993                     g_snprintf(out_buff, SHORT_STR, "auth key management suite %u: %s",
994                               i, wpa_keymgmt_idx2str(tag_val[tag_val_off + 3]));
995                     proto_tree_add_string(tree, tag_interpretation, tvb, offset, 4, out_buff);
996                     offset += 4;
997                     tag_val_off += 4;
998                     i ++;
999                   }
1000                   else
1001                     break;
1002                 }
1003               }
1004             }
1005           }
1006         }
1007         if (tag_val_off < tag_len)
1008           proto_tree_add_string(tree, tag_interpretation, tvb,
1009                                  offset, tag_len - tag_val_off, "Not interpreted");
1010         proto_item_append_text(ietree, ": WPA");
1011       } else if (tag_val_off + 7 <= tag_len && !memcmp(tag_val, WME_OUI"\x02\x00", 5)) {
1012       /* Wireless Multimedia Enhancements (WME) Information Element */
1013         g_snprintf(out_buff, SHORT_STR, "WME IE: type %u, subtype %u, version %u, parameter set %u",
1014                  tag_val[tag_val_off + 3], tag_val[tag_val_off + 4], tag_val[tag_val_off + 5],
1015                  tag_val[tag_val_off + 6]);
1016         proto_tree_add_string(tree, tag_interpretation, tvb, offset, 7, out_buff);
1017         proto_item_append_text(ietree, ": WME");
1018       } else if (tag_val_off + 24 <= tag_len && !memcmp(tag_val, WME_OUI"\x02\x01", 5)) {
1019       /* Wireless Multimedia Enhancements (WME) Parameter Element */
1020         g_snprintf(out_buff, SHORT_STR, "WME PE: type %u, subtype %u, version %u, parameter set %u",
1021                  tag_val[tag_val_off + 3], tag_val[tag_val_off + 4], tag_val[tag_val_off + 5],
1022                  tag_val[tag_val_off + 6]);
1023         proto_tree_add_string(tree, tag_interpretation, tvb, offset, 7, out_buff);
1024         offset += 8;
1025         tag_val_off += 8;
1026         for (i = 0; i < 4; i++) {
1027           g_snprintf(out_buff, SHORT_STR, "WME AC Parameters: ACI %u (%s), Admission Control %sMandatory, AIFSN %u, ECWmin %u, ECWmax %u, TXOP %u",
1028                    (tag_val[tag_val_off] & 0x60) >> 5,
1029                    wme_acs[(tag_val[tag_val_off] & 0x60) >> 5],
1030                    (tag_val[tag_val_off] & 0x10) ? "" : "not ",
1031                    tag_val[tag_val_off] & 0x0f,
1032                    tag_val[tag_val_off + 1] & 0x0f,
1033                    (tag_val[tag_val_off + 1] & 0xf0) >> 4,
1034                    tvb_get_letohs(tvb, offset + 2));
1035           proto_tree_add_string(tree, tag_interpretation, tvb, offset, 4, out_buff);
1036           offset += 4;
1037           tag_val_off += 4;
1038         }
1039         proto_item_append_text(ietree, ": WME");
1040       } else if (tag_val_off + 56 <= tag_len && !memcmp(tag_val, WME_OUI"\x02\x02", 5)) {
1041       /* Wireless Multimedia Enhancements (WME) TSPEC Element */
1042         guint16 ts_info, msdu_size, surplus_bandwidth;
1043         const char *direction[] = { "Uplink", "Downlink", "Reserved", "Bi-directional" };
1044         const value_string fields[] = {
1045           {12, "Minimum Service Interval"},
1046           {16, "Maximum Service Interval"},
1047           {20, "Inactivity Interval"},
1048           {24, "Service Start Time"},
1049           {28, "Minimum Data Rate"},
1050           {32, "Mean Data Rate"},
1051           {36, "Maximum Burst Size"},
1052           {40, "Minimum PHY Rate"},
1053           {44, "Peak Data Rate"},
1054           {48, "Delay Bound"},
1055           {0, NULL}
1056         };
1057         const char *field;
1058
1059         g_snprintf(out_buff, SHORT_STR, "WME TSPEC: type %u, subtype %u, version %u",
1060                  tag_val[tag_val_off + 3], tag_val[tag_val_off + 4], tag_val[tag_val_off + 5]);
1061         proto_tree_add_string(tree, tag_interpretation, tvb, offset, 6, out_buff);
1062         offset += 6;
1063         tag_val_off += 6;
1064
1065         ts_info = tvb_get_letohs(tvb, offset);
1066         g_snprintf(out_buff, SHORT_STR, "WME TS Info: Priority %u (%s) (%s), Contention-based access %sset, %s",
1067                  (ts_info >> 11) & 0x7, qos_tags[(ts_info >> 11) & 0x7], qos_acs[(ts_info >> 11) & 0x7],
1068                  (ts_info & 0x0080) ? "" : "not ",
1069                  direction[(ts_info >> 5) & 0x3]);
1070         proto_tree_add_string(tree, tag_interpretation, tvb, offset, 2, out_buff);
1071         offset += 2;
1072         tag_val_off += 2;
1073
1074         msdu_size = tvb_get_letohs(tvb, offset);
1075         g_snprintf(out_buff, SHORT_STR, "WME TSPEC: %s MSDU Size %u",
1076                  (msdu_size & 0x8000) ? "Fixed" : "Nominal", msdu_size & 0x7fff);
1077         proto_tree_add_string(tree, tag_interpretation, tvb, offset, 2, out_buff);
1078         offset += 2;
1079         tag_val_off += 2;
1080
1081         g_snprintf(out_buff, SHORT_STR, "WME TSPEC: Maximum MSDU Size %u", tvb_get_letohs(tvb, offset));
1082         proto_tree_add_string(tree, tag_interpretation, tvb, offset, 2, out_buff);
1083         offset += 2;
1084         tag_val_off += 2;
1085
1086         while ((field = val_to_str(tag_val_off, fields, "Unknown"))) {
1087           g_snprintf(out_buff, SHORT_STR, "WME TSPEC: %s %u", field, tvb_get_letohl(tvb, offset));
1088           proto_tree_add_string(tree, tag_interpretation, tvb, offset, 4, out_buff);
1089           offset += 4;
1090           tag_val_off += 4;
1091           if (tag_val_off == 52)
1092             break;
1093         }
1094
1095         surplus_bandwidth = tvb_get_letohs(tvb, offset);
1096         g_snprintf(out_buff, SHORT_STR, "WME TSPEC: Surplus Bandwidth Allowance Factor %u.%u",
1097                  (surplus_bandwidth >> 13) & 0x7, (surplus_bandwidth & 0x1fff));
1098         offset += 2;
1099         tag_val_off += 2;
1100
1101         g_snprintf(out_buff, SHORT_STR, "WME TSPEC: Medium Time %u", tvb_get_letohs(tvb, offset));
1102         proto_tree_add_string(tree, tag_interpretation, tvb, offset, 2, out_buff);
1103         offset += 2;
1104         tag_val_off += 2;
1105         proto_item_append_text(ietree, ": WME");
1106       }
1107 }
1108
1109 static void
1110 dissect_vendor_ie_rsn(proto_tree * ietree, proto_tree * tree, tvbuff_t * tvb,
1111         int offset, guint32 tag_len, const guint8 *tag_val)
1112 {
1113         guint32 tag_val_off = 0;
1114         char out_buff[SHORT_STR], *pos;
1115         guint i;
1116
1117         if (tag_val_off + 4 <= tag_len && !memcmp(tag_val, RSN_OUI"\x04", 4)) {
1118                 /* IEEE 802.11i / Key Data Encapsulation / Data Type=4 - PMKID.
1119                  * This is only used within EAPOL-Key frame Key Data. */
1120                 pos = out_buff;
1121                 pos += snprintf(pos, out_buff + SHORT_STR - pos, "RSN PMKID: ");
1122         if (tag_len - 4 != PMKID_LEN) {
1123                 pos += snprintf(pos, out_buff + SHORT_STR - pos,
1124                           "(invalid PMKID len=%d, expected 16) ", tag_len - 4);
1125         }
1126         for (i = 0; i < tag_len - 4; i++) {
1127                 pos += snprintf(pos, out_buff + SHORT_STR - pos, "%02X",
1128                         tag_val[tag_val_off + 4 + i]);
1129         }
1130         proto_tree_add_string(tree, tag_interpretation, tvb, offset,
1131               tag_len, out_buff);
1132         }
1133         proto_item_append_text(ietree, ": RSN");
1134 }
1135
1136 static void
1137 dissect_rsn_ie(proto_tree * tree, tvbuff_t * tvb, int offset,
1138                guint32 tag_len, const guint8 *tag_val)
1139 {
1140   guint32 tag_val_off = 0;
1141   guint16 rsn_capab;
1142   char out_buff[SHORT_STR];
1143   int i, j, count;
1144   proto_item *cap_item;
1145   proto_tree *cap_tree;
1146
1147   if (tag_val_off + 2 > tag_len) {
1148     proto_tree_add_string(tree, tag_interpretation, tvb, offset, tag_len,
1149                           "Not interpreted");
1150     return;
1151   }
1152
1153   g_snprintf(out_buff, SHORT_STR, "RSN IE, version %u",
1154            pletohs(&tag_val[tag_val_off]));
1155   proto_tree_add_string(tree, tag_interpretation, tvb, offset, 2, out_buff);
1156
1157   offset += 2;
1158   tag_val_off += 2;
1159
1160   if (tag_val_off + 4 > tag_len)
1161     goto done;
1162
1163   /* multicast cipher suite */
1164   if (!memcmp(&tag_val[tag_val_off], RSN_OUI, 3)) {
1165     g_snprintf(out_buff, SHORT_STR, "Multicast cipher suite: %s",
1166              wpa_cipher_idx2str(tag_val[tag_val_off + 3]));
1167     proto_tree_add_string(tree, tag_interpretation, tvb, offset, 4, out_buff);
1168     offset += 4;
1169     tag_val_off += 4;
1170   }
1171
1172   if (tag_val_off + 2 > tag_len)
1173     goto done;
1174
1175   /* unicast cipher suites */
1176   count = pletohs(tag_val + tag_val_off);
1177   g_snprintf(out_buff, SHORT_STR, "# of unicast cipher suites: %u", count);
1178   proto_tree_add_string(tree, tag_interpretation, tvb, offset, 2, out_buff);
1179   offset += 2;
1180   tag_val_off += 2;
1181   i = 1;
1182   while (tag_val_off + 4 <= tag_len && i <= count) {
1183     if (memcmp(&tag_val[tag_val_off], RSN_OUI, 3) != 0)
1184       goto done;
1185     g_snprintf(out_buff, SHORT_STR, "Unicast cipher suite %u: %s",
1186              i, wpa_cipher_idx2str(tag_val[tag_val_off + 3]));
1187     proto_tree_add_string(tree, tag_interpretation, tvb, offset, 4, out_buff);
1188     offset += 4;
1189     tag_val_off += 4;
1190     i++;
1191   }
1192
1193   if (i <= count || tag_val_off + 2 > tag_len)
1194     goto done;
1195
1196   /* authenticated key management suites */
1197   count = pletohs(tag_val + tag_val_off);
1198   g_snprintf(out_buff, SHORT_STR, "# of auth key management suites: %u", count);
1199   proto_tree_add_string(tree, tag_interpretation, tvb, offset, 2, out_buff);
1200   offset += 2;
1201   tag_val_off += 2;
1202   i = 1;
1203   while (tag_val_off + 4 <= tag_len && i <= count) {
1204     if (memcmp(&tag_val[tag_val_off], RSN_OUI, 3) != 0)
1205       goto done;
1206     g_snprintf(out_buff, SHORT_STR, "auth key management suite %u: %s",
1207              i, wpa_keymgmt_idx2str(tag_val[tag_val_off + 3]));
1208     proto_tree_add_string(tree, tag_interpretation, tvb, offset, 4, out_buff);
1209     offset += 4;
1210     tag_val_off += 4;
1211     i++;
1212   }
1213
1214   if (i <= count || tag_val_off + 2 > tag_len)
1215     goto done;
1216
1217   rsn_capab = pletohs(&tag_val[tag_val_off]);
1218   g_snprintf(out_buff, SHORT_STR, "RSN Capabilities 0x%04x", rsn_capab);
1219   cap_item = proto_tree_add_uint_format(tree, rsn_cap, tvb,
1220                                         offset, 2, rsn_capab,
1221                                         "RSN Capabilities: 0x%04X", rsn_capab);
1222   cap_tree = proto_item_add_subtree(cap_item, ett_rsn_cap_tree);
1223   proto_tree_add_boolean(cap_tree, rsn_cap_preauth, tvb, offset, 2,
1224                          rsn_capab);
1225   proto_tree_add_boolean(cap_tree, rsn_cap_no_pairwise, tvb, offset, 2,
1226                          rsn_capab);
1227   proto_tree_add_uint(cap_tree, rsn_cap_ptksa_replay_counter, tvb, offset, 2,
1228                       rsn_capab);
1229   proto_tree_add_uint(cap_tree, rsn_cap_gtksa_replay_counter, tvb, offset, 2,
1230                       rsn_capab);
1231   offset += 2;
1232   tag_val_off += 2;
1233
1234   if (tag_val_off + 2 > tag_len)
1235     goto done;
1236
1237   count = pletohs(tag_val + tag_val_off);
1238   g_snprintf(out_buff, SHORT_STR, "# of PMKIDs: %u", count);
1239   proto_tree_add_string(tree, tag_interpretation, tvb, offset, 2, out_buff);
1240   offset += 2;
1241   tag_val_off += 2;
1242
1243   /* PMKID List (16 * n octets) */
1244   for (i = 0; i < count; i++) {
1245     char *pos;
1246     if (tag_val_off + PMKID_LEN > tag_len)
1247       goto done;
1248     pos = out_buff;
1249     pos += snprintf(pos, out_buff + SHORT_STR - pos, "PMKID %u: ", i);
1250     for (j = 0; j < PMKID_LEN; j++) {
1251       pos += snprintf(pos, out_buff + SHORT_STR - pos, "%02X",
1252                       tag_val[tag_val_off + j]);
1253     }
1254     proto_tree_add_string(tree, tag_interpretation, tvb, offset,
1255                           PMKID_LEN, out_buff);
1256     offset += PMKID_LEN;
1257     tag_val_off += PMKID_LEN;
1258   }
1259
1260  done:
1261   if (tag_val_off < tag_len)
1262     proto_tree_add_string(tree, tag_interpretation, tvb, offset,
1263                           tag_len - tag_val_off, "Not interpreted");
1264 }
1265
1266 /* ************************************************************************* */
1267 /*           Dissect and add tagged (optional) fields to proto tree          */
1268 /* ************************************************************************* */
1269
1270 static const value_string tag_num_vals[] = {
1271         { TAG_SSID,                 "SSID parameter set" },
1272         { TAG_SUPP_RATES,           "Supported Rates" },
1273         { TAG_FH_PARAMETER,         "FH Parameter set" },
1274         { TAG_DS_PARAMETER,         "DS Parameter set" },
1275         { TAG_CF_PARAMETER,         "CF Parameter set" },
1276         { TAG_TIM,                  "(TIM) Traffic Indication Map" },
1277         { TAG_IBSS_PARAMETER,       "IBSS Parameter set" },
1278         { TAG_COUNTRY_INFO,         "Country Information" },
1279         { TAG_FH_HOPPING_PARAMETER, "Hopping Pattern Parameters" },
1280         { TAG_CHALLENGE_TEXT,       "Challenge text" },
1281         { TAG_ERP_INFO,             "ERP Information" },
1282         { TAG_ERP_INFO_OLD,         "ERP Information" },
1283         { TAG_RSN_IE,               "RSN Information" },
1284         { TAG_EXT_SUPP_RATES,       "Extended Supported Rates" },
1285         { TAG_CISCO_UNKNOWN_1,      "Cisco Unknown 1 + Device Name" },
1286         { TAG_CISCO_UNKNOWN_2,      "Cisco Unknown 2" },
1287         { TAG_VENDOR_SPECIFIC_IE,   "Vendor Specific" },
1288         { TAG_SYMBOL_PROPRIETARY,   "Symbol Proprietary"},
1289         { TAG_AGERE_PROPRIETARY,    "Agere Proprietary"},
1290         { TAG_REQUEST,              "Request"},
1291         { TAG_QBSS_LOAD,            "QBSS Load Element"},
1292         { TAG_EDCA_PARAM_SET,       "EDCA Parameter Set"},
1293         { TAG_TRAF_SPEC,            "Traffic Specification"},
1294         { TAG_TRAF_CLASS,           "Traffic Classification"},
1295         { TAG_SCHEDULE,             "Schedule"},
1296         { TAG_TS_DELAY,             "TS Delay"},
1297         { TAG_TCLAS_PROCESS,        "TCLAS Processing"},
1298         { TAG_QOS_CAPABILITY,       "QoS Capability"},
1299         { TAG_POWER_CONSTRAINT,     "Power Constraint"},
1300         { TAG_POWER_CAPABILITY,     "Power Capability"},
1301         { TAG_TPC_REQUEST,          "TPC Request"},
1302         { TAG_TPC_REPORT,           "TPC Report"},
1303         { TAG_SUPPORTED_CHANNELS,   "Supported Channels"},
1304         { TAG_CHANNEL_SWITCH_ANN,   "Channel Switch Announcement"},
1305         { TAG_MEASURE_REQ,          "Measurement Request"},
1306         { TAG_MEASURE_REP,          "Measurement Report"},
1307         { TAG_QUIET,                "Quiet"},
1308         { TAG_IBSS_DFS,             "IBSS DFS"},
1309         { 0,                        NULL }
1310 };
1311
1312 static const value_string environment_vals[] = {
1313         { 0x20, "Any" },
1314         { 0x4f, "Outdoor" },
1315         { 0x49, "Indoor" },
1316         { 0,    NULL }
1317 };
1318
1319 static int beacon_padding = 0; /* beacon padding bug */
1320 static int
1321 add_tagged_field (packet_info * pinfo, proto_tree * tree, tvbuff_t * tvb, int offset)
1322 {
1323   guint32 oui;
1324   guint8 *tag_val;
1325   const guint8 *tag_data_ptr;
1326   guint32 tag_no, tag_len;
1327   unsigned int i;
1328   int n, ret;
1329   char out_buff[SHORT_STR];
1330   char print_buff[SHORT_STR];
1331   proto_tree * orig_tree=tree;
1332   proto_item *ti;
1333
1334   tag_no = tvb_get_guint8(tvb, offset);
1335   tag_len = tvb_get_guint8(tvb, offset + 1);
1336
1337   ti=proto_tree_add_text(orig_tree,tvb,offset,tag_len+2,"%s",
1338                          val_to_str(tag_no, tag_num_vals,
1339                          (tag_no >= 17 && tag_no <= 31) ?
1340                          "Reserved for challenge text" : "Reserved tag number" ));
1341   tree=proto_item_add_subtree(ti,ett_80211_mgt_ie);
1342
1343   proto_tree_add_uint_format (tree, tag_number, tvb, offset, 1, tag_no,
1344                               "Tag Number: %u (%s)",
1345                               tag_no,
1346                               val_to_str(tag_no, tag_num_vals,
1347                                          (tag_no >= 17 && tag_no <= 31) ?
1348                                          "Reserved for challenge text" :
1349                                          "Reserved tag number"));
1350   proto_tree_add_uint (tree, (tag_no==TAG_TIM ? tim_length : tag_length), tvb, offset + 1, 1, tag_len);
1351
1352   switch (tag_no)
1353     {
1354
1355     case TAG_SSID:
1356       if(beacon_padding == 0) /* padding bug */
1357       {
1358         char *ssid;
1359
1360         ssid = tvb_get_ephemeral_string(tvb, offset + 2, tag_len);
1361         proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
1362                                tag_len, ssid);
1363         if (check_col (pinfo->cinfo, COL_INFO)) {
1364           if (tag_len > 0) {
1365             col_append_fstr(pinfo->cinfo, COL_INFO, ", SSID: \"%s\"",
1366                             format_text(ssid, tag_len));
1367           } else {
1368             col_append_fstr(pinfo->cinfo, COL_INFO, ", SSID: Broadcast");
1369           }
1370         }
1371         if (tag_len > 0) {
1372           proto_item_append_text(ti, ": \"%s\"",
1373                                  format_text(ssid, tag_len));
1374         } else {
1375           proto_item_append_text(ti, ": Broadcast");
1376         }
1377         beacon_padding++; /* padding bug */
1378       }
1379       break;
1380
1381     case TAG_SUPP_RATES:
1382     case TAG_EXT_SUPP_RATES:
1383       tag_data_ptr = tvb_get_ptr (tvb, offset + 2, tag_len);
1384       for (i = 0, n = 0; i < tag_len && n < SHORT_STR; i++) {
1385         ret = snprintf (print_buff + n, SHORT_STR - n, "%2.1f%s ",
1386                         (tag_data_ptr[i] & 0x7F) * 0.5,
1387                         (tag_data_ptr[i] & 0x80) ? "(B)" : "");
1388         if (ret == -1 || ret >= SHORT_STR - n) {
1389           /* Some versions of snprintf return -1 if they'd truncate
1390              the output. Others return <buf_size> or greater.  */
1391           break;
1392         }
1393         n += ret;
1394       }
1395       g_snprintf (out_buff, SHORT_STR, "Supported rates: %s [Mbit/sec]", print_buff);
1396       out_buff[SHORT_STR-1] = '\0';
1397       proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
1398                              tag_len, out_buff);
1399       proto_item_append_text(ti, ": %s", print_buff);
1400       break;
1401
1402     case TAG_FH_PARAMETER:
1403       if (tag_len < 5)
1404       {
1405         proto_tree_add_text (tree, tvb, offset + 2, tag_len, "Tag length %u too short, must be >= 5",
1406                              tag_len);
1407         break;
1408       }
1409       g_snprintf (out_buff, SHORT_STR,
1410                 "Dwell time 0x%04X, Hop Set %2d, Hop Pattern %2d, Hop Index %2d",
1411                 tvb_get_letohs(tvb, offset + 2),
1412                 tvb_get_guint8(tvb, offset + 4),
1413                 tvb_get_guint8(tvb, offset + 5),
1414                 tvb_get_guint8(tvb, offset + 6));
1415       out_buff[SHORT_STR-1] = '\0';
1416       proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
1417                              tag_len, out_buff);
1418       break;
1419
1420     case TAG_DS_PARAMETER:
1421       if (tag_len < 1)
1422       {
1423         proto_tree_add_text (tree, tvb, offset + 2, tag_len, "Tag length %u too short, must be >= 1",
1424                              tag_len);
1425         break;
1426       }
1427       g_snprintf (out_buff, SHORT_STR, "Current Channel: %u",
1428                 tvb_get_guint8(tvb, offset + 2));
1429       out_buff[SHORT_STR-1] = '\0';
1430       proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
1431                              tag_len, out_buff);
1432       proto_item_append_text(ti, ": %s", out_buff);
1433       break;
1434
1435     case TAG_CF_PARAMETER:
1436       if (tag_len < 6)
1437       {
1438         proto_tree_add_text (tree, tvb, offset + 2, tag_len, "Tag length %u too short, must be >= 6",
1439                              tag_len);
1440         break;
1441       }
1442       g_snprintf (out_buff, SHORT_STR, "CFP count: %u",
1443                 tvb_get_guint8(tvb, offset + 2));
1444       out_buff[SHORT_STR-1] = '\0';
1445       proto_tree_add_string_format(tree, tag_interpretation, tvb, offset + 2,
1446                                    1, out_buff, "%s", out_buff);
1447       g_snprintf (out_buff, SHORT_STR, "CFP period: %u",
1448                 tvb_get_guint8(tvb, offset + 3));
1449       out_buff[SHORT_STR-1] = '\0';
1450       proto_tree_add_string_format(tree, tag_interpretation, tvb, offset + 3,
1451                                    1, out_buff, "%s", out_buff);
1452       g_snprintf (out_buff, SHORT_STR, "CFP max duration: %u",
1453                 tvb_get_letohs(tvb, offset + 4));
1454       out_buff[SHORT_STR-1] = '\0';
1455       proto_tree_add_string_format(tree, tag_interpretation, tvb, offset + 4,
1456                                    2, out_buff, "%s", out_buff);
1457       g_snprintf (out_buff, SHORT_STR, "CFP Remaining: %u",
1458                 tvb_get_letohs(tvb, offset + 6));
1459       out_buff[SHORT_STR-1] = '\0';
1460       proto_tree_add_string_format(tree, tag_interpretation, tvb, offset + 6,
1461                                    2, out_buff, "%s", out_buff);
1462       proto_item_append_text(ti, ": CFP count %u, CFP period %u, CFP max duration %u, "
1463                              "CFP Remaining %u",
1464                              tvb_get_guint8(tvb, offset + 2),
1465                              tvb_get_guint8(tvb, offset + 3),
1466                              tvb_get_letohs(tvb, offset + 4),
1467                              tvb_get_letohs(tvb, offset + 6));
1468       break;
1469
1470     case TAG_TIM:
1471       if (tag_len < 4)
1472       {
1473         proto_tree_add_text (tree, tvb, offset + 2, tag_len, "Tag length %u too short, must be >= 4",
1474                              tag_len);
1475         break;
1476       }
1477       {
1478         guint8 bmapctl;
1479         guint8 bmapoff;
1480         guint8 bmaplen;
1481         const guint8* bmap;
1482
1483         proto_tree_add_item(tree, tim_dtim_count, tvb,
1484                             offset + 2, 1, TRUE);
1485         proto_tree_add_item(tree, tim_dtim_period, tvb,
1486                             offset + 3, 1, TRUE);
1487         proto_item_append_text(ti, ": DTIM %u of %u bitmap",
1488                                tvb_get_guint8(tvb, offset + 2),
1489                                tvb_get_guint8(tvb, offset + 3));
1490
1491         bmapctl = tvb_get_guint8(tvb, offset + 4);
1492         bmapoff = bmapctl>>1;
1493         proto_tree_add_uint_format(tree, tim_bmapctl, tvb,
1494                             offset + 4, 1, bmapctl,
1495                             "Bitmap Control: 0x%02X (mcast:%u, bitmap offset %u)",
1496                             bmapctl, bmapctl&1, bmapoff);
1497
1498         bmaplen = tag_len - 3;
1499         bmap = tvb_get_ptr(tvb, offset + 5, bmaplen);
1500         if (bmaplen==1 && 0==bmap[0] && !(bmapctl&1)) {
1501           proto_item_append_text(ti, " empty");
1502         } else {
1503           if (bmapctl&1) {
1504             proto_item_append_text(ti, " mcast");
1505           }
1506         }
1507         if (bmaplen>1 || bmap[0]) {
1508           int len=snprintf (out_buff, SHORT_STR,
1509                             "Bitmap: traffic for AID's:");
1510           int i=0;
1511           for (i=0;i<bmaplen*8;i++) {
1512             if (bmap[i/8] & (1<<(i%8))) {
1513               int aid=i+bmapoff*8;
1514               len+=snprintf (out_buff+len, SHORT_STR-len," %u", aid);
1515               proto_item_append_text(ti, "  %u", aid);
1516               if (len>=SHORT_STR) {
1517                 break;
1518               }
1519             }
1520           }
1521           out_buff[SHORT_STR-1] = '\0';
1522           proto_tree_add_string_format (tree, tag_interpretation, tvb, offset + 5,
1523                bmaplen, out_buff, "%s", out_buff);
1524         }
1525       }
1526       break;
1527
1528     case TAG_IBSS_PARAMETER:
1529       if (tag_len < 2)
1530       {
1531         proto_tree_add_text (tree, tvb, offset + 2, tag_len, "Tag length %u too short, must be >= 2",
1532                              tag_len);
1533         break;
1534       }
1535       g_snprintf (out_buff, SHORT_STR, "ATIM window 0x%X",
1536                 tvb_get_letohs(tvb, offset + 2));
1537       out_buff[SHORT_STR-1] = '\0';
1538       proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
1539                              tag_len, out_buff);
1540       proto_item_append_text(ti, ": %s", out_buff);
1541       break;
1542
1543     case TAG_COUNTRY_INFO: /* IEEE 802.11d-2001 and IEEE 802.11j-2004 */
1544       {
1545         char ccode[2+1];
1546
1547         if (tag_len < 3)
1548         {
1549           proto_tree_add_text (tree, tvb, offset + 2, tag_len, "Tag length %u too short, must be >= 3",
1550                                tag_len);
1551           break;
1552         }
1553         tvb_memcpy(tvb, ccode, offset + 2, 2);
1554         ccode[2] = '\0';
1555         g_snprintf (out_buff, SHORT_STR, "Country Code: %s, %s Environment",
1556                  format_text(ccode, 2),
1557                  val_to_str(tvb_get_guint8(tvb, offset + 4), environment_vals,"Unknown (0x%02x)"));
1558         out_buff[SHORT_STR-1] = '\0';
1559         proto_item_append_text(ti, ": %s", out_buff);
1560         proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,3, out_buff);
1561
1562         for (i = 3; (i + 3) <= tag_len; i += 3)
1563         {
1564           guint8 val1, val2, val3;
1565           val1 = tvb_get_guint8(tvb, offset + 2 + i);
1566           val2 = tvb_get_guint8(tvb, offset + 3 + i);
1567           val3 = tvb_get_guint8(tvb, offset + 4 + i);
1568
1569           if (val1 <= 200) {  /* 802.11d */
1570             proto_tree_add_string_format(tree, tag_interpretation, tvb, offset + 2+i,3, out_buff,
1571                                        "  Start Channel: %u, Channels: %u, Max TX Power: %d dBm",
1572                                        val1, val2, (gint) val3);
1573           } else {  /* 802.11j */
1574             proto_tree_add_string_format(tree, tag_interpretation, tvb, offset + 2+i,3, out_buff,
1575                                        "  Reg Extension Id: %u, Regulatory Class: %u, Coverage Class: %u",
1576                                        val1, val2, val3);
1577           }
1578         }
1579       }
1580       break;
1581
1582     case TAG_FH_HOPPING_PARAMETER:
1583       if (tag_len < 2)
1584       {
1585         proto_tree_add_text (tree, tvb, offset + 2, tag_len, "Tag length %u too short, must be >= 2",
1586                              tag_len);
1587         break;
1588       }
1589       g_snprintf (out_buff, SHORT_STR, "Prime Radix: %u, Number of Channels: %u",
1590                 tvb_get_guint8(tvb, offset + 2),
1591                 tvb_get_guint8(tvb, offset + 3));
1592       out_buff[SHORT_STR-1] = '\0';
1593       proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2, tag_len, out_buff);
1594       proto_item_append_text(ti, ": %s", out_buff);
1595       break;
1596
1597     case TAG_CHALLENGE_TEXT:
1598       g_snprintf (out_buff, SHORT_STR, "Challenge text: %s",
1599                 tvb_bytes_to_str(tvb, offset + 2, tag_len));
1600       out_buff[SHORT_STR-1] = '\0';
1601       proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
1602                              tag_len, out_buff);
1603       break;
1604
1605     case TAG_ERP_INFO:
1606     case TAG_ERP_INFO_OLD:
1607       {
1608         guint8 erp_info;
1609
1610         if (tag_len < 1)
1611         {
1612           proto_tree_add_text (tree, tvb, offset + 2, tag_len, "Tag length %u too short, must be >= 1",
1613                                tag_len);
1614           break;
1615         }
1616         erp_info = tvb_get_guint8 (tvb, offset + 2);
1617         g_snprintf (print_buff, SHORT_STR, "%sNon-ERP STAs, %suse protection, %s preambles",
1618                   erp_info & 0x01 ? "" : "no ",
1619                   erp_info & 0x02 ? "" : "do not ",
1620                   erp_info & 0x04 ? "short or long": "long");
1621         print_buff[SHORT_STR-1] = '\0';
1622         g_snprintf (out_buff, SHORT_STR,
1623                   "ERP info: 0x%x (%s)",erp_info,print_buff);
1624         out_buff[SHORT_STR-1] = '\0';
1625         proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
1626                                tag_len, out_buff);
1627         proto_item_append_text(ti, ": %s", print_buff);
1628       }
1629       break;
1630
1631     case TAG_CISCO_UNKNOWN_1:
1632       /* The Name of the sending device starts at offset 10 and is up to
1633          15 or 16 bytes in length, \0 padded */
1634       if (tag_len < 26)
1635       {
1636         proto_tree_add_text (tree, tvb, offset + 2, tag_len, "Tag length %u too short, must be >= 26",
1637                              tag_len);
1638         break;
1639       }
1640       g_snprintf (out_buff, SHORT_STR, "%.16s",
1641                 tvb_format_stringzpad(tvb, offset + 12, 16));
1642       out_buff[SHORT_STR-1] = '\0';
1643       proto_tree_add_string_format (tree, tag_interpretation, tvb, offset + 2,
1644                              tag_len, "", "Tag interpretation: Unknown + Name: %s",
1645                              out_buff);
1646       if (check_col (pinfo->cinfo, COL_INFO)) {
1647           col_append_fstr(pinfo->cinfo, COL_INFO, ", Name: \"%s\"", out_buff);
1648       }
1649       break;
1650
1651     case TAG_VENDOR_SPECIFIC_IE:
1652       tvb_ensure_bytes_exist (tvb, offset + 2, tag_len);
1653       if (tag_len >= 3) {
1654                 oui = tvb_get_ntoh24(tvb, offset + 2);
1655                 tag_val = tvb_get_ptr(tvb, offset + 2, tag_len);
1656 #define WPAWME_OUI      0x0050F2
1657 #define RSNOUI_VAL      0x000FAC
1658                 switch (oui) {
1659                 case WPAWME_OUI:
1660                         dissect_vendor_ie_wpawme(ti, tree, tvb, offset + 2, tag_len, tag_val);
1661                         break;
1662                 case RSNOUI_VAL:
1663                         dissect_vendor_ie_rsn(ti, tree, tvb, offset + 2, tag_len, tag_val);
1664                         break;
1665                 default:
1666                         proto_tree_add_bytes_format (tree, tag_oui, tvb, offset + 2, 3,
1667                                 "", "Vendor: %s", get_manuf_name(tag_val));
1668                         proto_item_append_text(ti, ": %s", get_manuf_name(tag_val));
1669                         proto_tree_add_string (tree, tag_interpretation, tvb, offset + 5,
1670                                 tag_len - 3, "Not interpreted");
1671                         break;
1672                 }
1673
1674       }
1675       break;
1676
1677     case TAG_RSN_IE:
1678       dissect_rsn_ie(tree, tvb, offset + 2, tag_len,
1679                      tvb_get_ptr (tvb, offset + 2, tag_len));
1680       break;
1681
1682     default:
1683       tvb_ensure_bytes_exist (tvb, offset + 2, tag_len);
1684       proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
1685                              tag_len, "Not interpreted");
1686       proto_item_append_text(ti, ": Tag %u Len %u", tag_no, tag_len);
1687       break;
1688     }
1689
1690   return tag_len + 2;
1691 }
1692
1693 void
1694 ieee_80211_add_tagged_parameters (tvbuff_t * tvb, int offset, packet_info * pinfo,
1695         proto_tree * tree, int tagged_parameters_len)
1696 {
1697   int next_len;
1698
1699   beacon_padding = 0; /* this is for the beacon padding confused with ssid fix */
1700   while (tagged_parameters_len > 0) {
1701     if ((next_len=add_tagged_field (pinfo, tree, tvb, offset))==0)
1702       break;
1703     if (next_len > tagged_parameters_len) {
1704       /* XXX - flag this as an error? */
1705       next_len = tagged_parameters_len;
1706     }
1707     offset += next_len;
1708     tagged_parameters_len -= next_len;
1709   }
1710 }
1711
1712 /* ************************************************************************* */
1713 /*                     Dissect 802.11 management frame                       */
1714 /* ************************************************************************* */
1715 static void
1716 dissect_ieee80211_mgt (guint16 fcf, tvbuff_t * tvb, packet_info * pinfo,
1717         proto_tree * tree)
1718 {
1719       proto_item *ti = NULL;
1720       proto_tree *mgt_tree;
1721       proto_tree *fixed_tree;
1722       proto_tree *tagged_tree;
1723       int offset;
1724       int tagged_parameter_tree_len;
1725
1726       g_pinfo = pinfo;
1727
1728       CHECK_DISPLAY_AS_X(data_handle,proto_wlan_mgt, tvb, pinfo, tree);
1729
1730       ti = proto_tree_add_item (tree, proto_wlan_mgt, tvb, 0, -1, FALSE);
1731       mgt_tree = proto_item_add_subtree (ti, ett_80211_mgt);
1732
1733       switch (COMPOSE_FRAME_TYPE(fcf))
1734         {
1735
1736         case MGT_ASSOC_REQ:
1737           fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 4);
1738           add_fixed_field (fixed_tree, tvb, 0, FIELD_CAP_INFO);
1739           add_fixed_field (fixed_tree, tvb, 2, FIELD_LISTEN_IVAL);
1740           offset = 4;   /* Size of fixed fields */
1741
1742           tagged_parameter_tree_len =
1743               tvb_reported_length_remaining(tvb, offset);
1744           tagged_tree = get_tagged_parameter_tree (mgt_tree, tvb, offset,
1745                                                    tagged_parameter_tree_len);
1746           ieee_80211_add_tagged_parameters (tvb, offset, pinfo, tagged_tree,
1747               tagged_parameter_tree_len);
1748           break;
1749
1750
1751         case MGT_ASSOC_RESP:
1752           fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 6);
1753           add_fixed_field (fixed_tree, tvb, 0, FIELD_CAP_INFO);
1754           add_fixed_field (fixed_tree, tvb, 2, FIELD_STATUS_CODE);
1755           add_fixed_field (fixed_tree, tvb, 4, FIELD_ASSOC_ID);
1756           offset = 6;   /* Size of fixed fields */
1757
1758           tagged_parameter_tree_len =
1759               tvb_reported_length_remaining(tvb, offset);
1760           tagged_tree = get_tagged_parameter_tree (mgt_tree, tvb, offset,
1761                                                    tagged_parameter_tree_len);
1762           ieee_80211_add_tagged_parameters (tvb, offset, pinfo, tagged_tree,
1763               tagged_parameter_tree_len);
1764           break;
1765
1766
1767         case MGT_REASSOC_REQ:
1768           fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 10);
1769           add_fixed_field (fixed_tree, tvb, 0, FIELD_CAP_INFO);
1770           add_fixed_field (fixed_tree, tvb, 2, FIELD_LISTEN_IVAL);
1771           add_fixed_field (fixed_tree, tvb, 4, FIELD_CURRENT_AP_ADDR);
1772           offset = 10;  /* Size of fixed fields */
1773
1774           tagged_parameter_tree_len =
1775               tvb_reported_length_remaining(tvb, offset);
1776           tagged_tree = get_tagged_parameter_tree (mgt_tree, tvb, offset,
1777                                                    tagged_parameter_tree_len);
1778           ieee_80211_add_tagged_parameters (tvb, offset, pinfo, tagged_tree,
1779               tagged_parameter_tree_len);
1780           break;
1781
1782         case MGT_REASSOC_RESP:
1783           fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 6);
1784           add_fixed_field (fixed_tree, tvb, 0, FIELD_CAP_INFO);
1785           add_fixed_field (fixed_tree, tvb, 2, FIELD_STATUS_CODE);
1786           add_fixed_field (fixed_tree, tvb, 4, FIELD_ASSOC_ID);
1787           offset = 6;   /* Size of fixed fields */
1788
1789           tagged_parameter_tree_len =
1790               tvb_reported_length_remaining(tvb, offset);
1791           tagged_tree = get_tagged_parameter_tree (mgt_tree, tvb, offset,
1792                                                    tagged_parameter_tree_len);
1793           ieee_80211_add_tagged_parameters (tvb, offset, pinfo, tagged_tree,
1794               tagged_parameter_tree_len);
1795           break;
1796
1797
1798         case MGT_PROBE_REQ:
1799           offset = 0;
1800           tagged_parameter_tree_len =
1801               tvb_reported_length_remaining(tvb, offset);
1802           tagged_tree = get_tagged_parameter_tree (mgt_tree, tvb, offset,
1803                                                    tagged_parameter_tree_len);
1804           ieee_80211_add_tagged_parameters (tvb, offset, pinfo, tagged_tree,
1805               tagged_parameter_tree_len);
1806           break;
1807
1808
1809         case MGT_PROBE_RESP:
1810           fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 12);
1811           add_fixed_field (fixed_tree, tvb, 0, FIELD_TIMESTAMP);
1812           add_fixed_field (fixed_tree, tvb, 8, FIELD_BEACON_INTERVAL);
1813           add_fixed_field (fixed_tree, tvb, 10, FIELD_CAP_INFO);
1814           offset = 12;  /* Size of fixed fields */
1815
1816           tagged_parameter_tree_len =
1817               tvb_reported_length_remaining(tvb, offset);
1818           tagged_tree = get_tagged_parameter_tree (mgt_tree, tvb, offset,
1819                                                    tagged_parameter_tree_len);
1820           ieee_80211_add_tagged_parameters (tvb, offset, pinfo, tagged_tree,
1821               tagged_parameter_tree_len);
1822           break;
1823
1824
1825         case MGT_BEACON:                /* Dissect protocol payload fields  */
1826           fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 12);
1827           add_fixed_field (fixed_tree, tvb, 0, FIELD_TIMESTAMP);
1828           add_fixed_field (fixed_tree, tvb, 8, FIELD_BEACON_INTERVAL);
1829           add_fixed_field (fixed_tree, tvb, 10, FIELD_CAP_INFO);
1830           offset = 12;  /* Size of fixed fields */
1831
1832           tagged_parameter_tree_len =
1833               tvb_reported_length_remaining(tvb, offset);
1834           tagged_tree = get_tagged_parameter_tree (mgt_tree, tvb, offset,
1835                                                    tagged_parameter_tree_len);
1836           ieee_80211_add_tagged_parameters (tvb, offset, pinfo, tagged_tree,
1837               tagged_parameter_tree_len);
1838           break;
1839
1840
1841         case MGT_ATIM:
1842           break;
1843
1844
1845         case MGT_DISASS:
1846           fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 2);
1847           add_fixed_field (fixed_tree, tvb, 0, FIELD_REASON_CODE);
1848           break;
1849
1850
1851         case MGT_AUTHENTICATION:
1852           fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 6);
1853           add_fixed_field (fixed_tree, tvb, 0, FIELD_AUTH_ALG);
1854           add_fixed_field (fixed_tree, tvb, 2, FIELD_AUTH_TRANS_SEQ);
1855           add_fixed_field (fixed_tree, tvb, 4, FIELD_STATUS_CODE);
1856           offset = 6;   /* Size of fixed fields */
1857
1858           tagged_parameter_tree_len =
1859                   tvb_reported_length_remaining(tvb, offset);
1860           if (tagged_parameter_tree_len != 0)
1861             {
1862               tagged_tree = get_tagged_parameter_tree (mgt_tree,
1863                                                        tvb,
1864                                                        offset,
1865                                                        tagged_parameter_tree_len);
1866               ieee_80211_add_tagged_parameters (tvb, offset, pinfo, tagged_tree,
1867                 tagged_parameter_tree_len);
1868             }
1869           break;
1870
1871
1872         case MGT_DEAUTHENTICATION:
1873           fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 2);
1874           add_fixed_field (fixed_tree, tvb, 0, FIELD_REASON_CODE);
1875           break;
1876
1877
1878         case MGT_ACTION:
1879           switch (tvb_get_guint8(tvb, 0))
1880             {
1881
1882             case CAT_SPECTRUM_MGMT:
1883               switch (tvb_get_guint8(tvb, 1))
1884                 {
1885                 case SM_ACTION_MEASUREMENT_REQUEST:
1886                 case SM_ACTION_MEASUREMENT_REPORT:
1887                 case SM_ACTION_TPC_REQUEST:
1888                 case SM_ACTION_TPC_REPORT:
1889                   fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 3);
1890                   add_fixed_field (fixed_tree, tvb, 0, FIELD_CATEGORY_CODE);
1891                   add_fixed_field (fixed_tree, tvb, 1, FIELD_ACTION_CODE);
1892                   add_fixed_field (fixed_tree, tvb, 2, FIELD_DIALOG_TOKEN);
1893                   offset = 3;   /* Size of fixed fields */
1894                   break;
1895
1896                 case SM_ACTION_CHAN_SWITCH_ANNC:
1897                   fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 2);
1898                   add_fixed_field (fixed_tree, tvb, 0, FIELD_CATEGORY_CODE);
1899                   offset = 2;   /* Size of fixed fields */
1900                   break;
1901
1902                 default:
1903                   fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 2);
1904                   add_fixed_field (fixed_tree, tvb, 0, FIELD_CATEGORY_CODE);
1905                   offset = 2;   /* Size of fixed fields */
1906                   break;
1907                 }
1908               break;
1909
1910             case CAT_MGMT_NOTIFICATION: /* Management notification frame */
1911               fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 4);
1912               add_fixed_field (fixed_tree, tvb, 0, FIELD_CATEGORY_CODE);
1913               add_fixed_field (fixed_tree, tvb, 1, FIELD_WME_ACTION_CODE);
1914               add_fixed_field (fixed_tree, tvb, 2, FIELD_DIALOG_TOKEN);
1915               add_fixed_field (fixed_tree, tvb, 3, FIELD_WME_STATUS_CODE);
1916               offset = 4;       /* Size of fixed fields */
1917               break;
1918
1919             default:
1920               fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 1);
1921               add_fixed_field (fixed_tree, tvb, 0, FIELD_CATEGORY_CODE);
1922               offset = 1;       /* Size of fixed fields */
1923               break;
1924             }
1925
1926             tagged_parameter_tree_len =
1927               tvb_reported_length_remaining(tvb, offset);
1928             if (tagged_parameter_tree_len != 0)
1929               {
1930                 tagged_tree = get_tagged_parameter_tree (mgt_tree, tvb, offset,
1931                                                          tagged_parameter_tree_len);
1932                 ieee_80211_add_tagged_parameters (tvb, offset, pinfo, tagged_tree,
1933                                                   tagged_parameter_tree_len);
1934               }
1935           break;
1936         }
1937 }
1938
1939 static void
1940 set_src_addr_cols(packet_info *pinfo, const guint8 *addr, const char *type)
1941 {
1942   if (check_col(pinfo->cinfo, COL_RES_DL_SRC))
1943     col_add_fstr(pinfo->cinfo, COL_RES_DL_SRC, "%s (%s)",
1944                     get_ether_name(addr), type);
1945   if (check_col(pinfo->cinfo, COL_UNRES_DL_SRC))
1946     col_add_fstr(pinfo->cinfo, COL_UNRES_DL_SRC, "%s",
1947                      ether_to_str(addr));
1948 }
1949
1950 static void
1951 set_dst_addr_cols(packet_info *pinfo, const guint8 *addr, const char *type)
1952 {
1953   if (check_col(pinfo->cinfo, COL_RES_DL_DST))
1954     col_add_fstr(pinfo->cinfo, COL_RES_DL_DST, "%s (%s)",
1955                      get_ether_name(addr), type);
1956   if (check_col(pinfo->cinfo, COL_UNRES_DL_DST))
1957     col_add_fstr(pinfo->cinfo, COL_UNRES_DL_DST, "%s",
1958                      ether_to_str(addr));
1959 }
1960
1961 typedef enum {
1962     ENCAP_802_2,
1963     ENCAP_IPX,
1964     ENCAP_ETHERNET
1965 } encap_t;
1966
1967 /* ************************************************************************* */
1968 /*                          Dissect 802.11 frame                             */
1969 /* ************************************************************************* */
1970 static void
1971 dissect_ieee80211_common (tvbuff_t * tvb, packet_info * pinfo,
1972                           proto_tree * tree, gboolean fixed_length_header,
1973                           gboolean has_radio_information, gint fcs_len,
1974                           gboolean wlan_broken_fc)
1975 {
1976   guint16 fcf, flags, frame_type_subtype;
1977   guint16 seq_control;
1978   guint32 seq_number, frag_number;
1979   gboolean more_frags;
1980   const guint8 *src = NULL;
1981   const guint8 *dst = NULL;
1982   const guint8 *bssid = NULL;
1983   proto_item *ti = NULL;
1984   proto_item *flag_item;
1985   proto_item *fc_item;
1986   proto_tree *hdr_tree = NULL;
1987   proto_tree *flag_tree;
1988   proto_tree *fc_tree;
1989   guint16 hdr_len;
1990   gboolean has_fcs;
1991   gint len, reported_len, ivlen;
1992   gboolean save_fragmented;
1993   tvbuff_t *volatile next_tvb = NULL;
1994   guint32 addr_type;
1995   volatile encap_t encap_type;
1996   guint8 octet1, octet2;
1997   char out_buff[SHORT_STR];
1998   gint is_iv_bad;
1999   guchar iv_buff[4];
2000   wlan_hdr *volatile whdr;
2001   static wlan_hdr whdrs[4];
2002
2003   whdr= &whdrs[0];
2004
2005   if (check_col (pinfo->cinfo, COL_PROTOCOL))
2006     col_set_str (pinfo->cinfo, COL_PROTOCOL, "IEEE 802.11");
2007   if (check_col (pinfo->cinfo, COL_INFO))
2008     col_clear (pinfo->cinfo, COL_INFO);
2009
2010   /* Add the radio information, if present, to the column information */
2011   if (has_radio_information) {
2012     if (check_col(pinfo->cinfo, COL_TX_RATE)) {
2013         col_add_fstr(pinfo->cinfo, COL_TX_RATE, "%u.%u",
2014            pinfo->pseudo_header->ieee_802_11.data_rate / 2,
2015            pinfo->pseudo_header->ieee_802_11.data_rate & 1 ? 5 : 0);
2016     }
2017     if (check_col(pinfo->cinfo, COL_RSSI)) {
2018       /* XX - this is a percentage, not a dBm or normalized or raw RSSI */
2019       col_add_fstr(pinfo->cinfo, COL_RSSI, "%u",
2020            pinfo->pseudo_header->ieee_802_11.signal_level);
2021     }
2022   }
2023
2024   fcf = tvb_get_letohs (tvb, 0);
2025   if (wlan_broken_fc) {
2026     /* Swap bytes */
2027     fcf = ((fcf & 0xff) << 8) | (((fcf & 0xff00) >> 8) & 0xff);
2028   }
2029   if (fixed_length_header)
2030     hdr_len = DATA_LONG_HDR_LEN;
2031   else
2032     hdr_len = find_header_length (fcf);
2033   frame_type_subtype = COMPOSE_FRAME_TYPE(fcf);
2034
2035   if (check_col (pinfo->cinfo, COL_PROTOCOL))
2036       col_set_str (pinfo->cinfo, COL_PROTOCOL,
2037           val_to_str(frame_type_subtype, frame_type_subtype_vals,
2038               "Unrecognized (Reserved frame)"));
2039
2040   if (check_col (pinfo->cinfo, COL_INFO))
2041       col_set_str (pinfo->cinfo, COL_INFO,
2042           val_to_str(frame_type_subtype, frame_type_subtype_vals,
2043               "Unrecognized (Reserved frame)"));
2044
2045   flags = COOK_FLAGS (fcf);
2046   more_frags = HAVE_FRAGMENTS (flags);
2047
2048
2049   /* Add the radio information, if present, and the FC to the current tree */
2050   if (tree)
2051     {
2052       ti = proto_tree_add_protocol_format (tree, proto_wlan, tvb, 0, hdr_len,
2053                                            "IEEE 802.11");
2054       hdr_tree = proto_item_add_subtree (ti, ett_80211);
2055
2056       if (has_radio_information) {
2057         proto_tree_add_uint_format(hdr_tree, hf_data_rate,
2058                                    tvb, 0, 0,
2059                                    pinfo->pseudo_header->ieee_802_11.data_rate,
2060                                    "Data Rate: %u.%u Mb/s",
2061                                    pinfo->pseudo_header->ieee_802_11.data_rate / 2,
2062                                    pinfo->pseudo_header->ieee_802_11.data_rate & 1 ? 5 : 0);
2063
2064         proto_tree_add_uint(hdr_tree, hf_channel,
2065                             tvb, 0, 0,
2066                             pinfo->pseudo_header->ieee_802_11.channel);
2067
2068         proto_tree_add_uint_format(hdr_tree, hf_signal_strength,
2069                                    tvb, 0, 0,
2070                                    pinfo->pseudo_header->ieee_802_11.signal_level,
2071                                    "Signal Strength: %u%%",
2072                                    pinfo->pseudo_header->ieee_802_11.signal_level);
2073       }
2074
2075       proto_tree_add_uint (hdr_tree, hf_fc_frame_type_subtype,
2076                            tvb,
2077                            wlan_broken_fc?1:0, 1,
2078                            frame_type_subtype);
2079
2080       fc_item = proto_tree_add_uint_format (hdr_tree, hf_fc_field, tvb,
2081                                             0, 2,
2082                                             fcf,
2083                                             "Frame Control: 0x%04X (%s)",
2084                                             fcf, wlan_broken_fc?"Swapped":"Normal");
2085
2086       fc_tree = proto_item_add_subtree (fc_item, ett_fc_tree);
2087
2088
2089       proto_tree_add_uint (fc_tree, hf_fc_proto_version, tvb,
2090                            wlan_broken_fc?1:0, 1,
2091                            COOK_PROT_VERSION (fcf));
2092
2093       proto_tree_add_uint (fc_tree, hf_fc_frame_type, tvb,
2094                            wlan_broken_fc?1:0, 1,
2095                            COOK_FRAME_TYPE (fcf));
2096
2097       proto_tree_add_uint (fc_tree, hf_fc_frame_subtype,
2098                            tvb,
2099                            wlan_broken_fc?1:0, 1,
2100                            COOK_FRAME_SUBTYPE (fcf));
2101
2102       flag_item =
2103         proto_tree_add_uint_format (fc_tree, hf_fc_flags, tvb,
2104                                     wlan_broken_fc?0:1, 1,
2105                                     flags, "Flags: 0x%X", flags);
2106
2107       flag_tree = proto_item_add_subtree (flag_item, ett_proto_flags);
2108
2109       proto_tree_add_uint (flag_tree, hf_fc_data_ds, tvb,
2110                            wlan_broken_fc?0:1, 1,
2111                            COOK_DS_STATUS (flags));
2112       proto_tree_add_boolean_hidden (flag_tree, hf_fc_to_ds, tvb, 1, 1,
2113                                      flags);
2114       proto_tree_add_boolean_hidden (flag_tree, hf_fc_from_ds, tvb, 1, 1,
2115                                      flags);
2116
2117       proto_tree_add_boolean (flag_tree, hf_fc_more_frag, tvb,
2118                               wlan_broken_fc?0:1, 1,
2119                               flags);
2120
2121       proto_tree_add_boolean (flag_tree, hf_fc_retry, tvb,
2122                               wlan_broken_fc?0:1, 1, flags);
2123
2124       proto_tree_add_boolean (flag_tree, hf_fc_pwr_mgt, tvb,
2125                               wlan_broken_fc?0:1, 1, flags);
2126
2127       proto_tree_add_boolean (flag_tree, hf_fc_more_data, tvb,
2128                               wlan_broken_fc?0:1, 1,
2129                               flags);
2130
2131       proto_tree_add_boolean (flag_tree, hf_fc_protected, tvb,
2132                               wlan_broken_fc?0:1, 1, flags);
2133
2134       proto_tree_add_boolean (flag_tree, hf_fc_order, tvb,
2135                               wlan_broken_fc?0:1, 1, flags);
2136
2137       if (frame_type_subtype == CTRL_PS_POLL)
2138         proto_tree_add_uint(hdr_tree, hf_assoc_id,tvb,2,2,
2139                             COOK_ASSOC_ID(tvb_get_letohs(tvb,2)));
2140
2141       else
2142           proto_tree_add_uint (hdr_tree, hf_did_duration, tvb, 2, 2,
2143                                tvb_get_letohs (tvb, 2));
2144     }
2145
2146   /*
2147    * Decode the part of the frame header that isn't the same for all
2148    * frame types.
2149    */
2150   seq_control = 0;
2151   frag_number = 0;
2152   seq_number = 0;
2153
2154   switch (COOK_FRAME_TYPE (fcf))
2155     {
2156
2157     case MGT_FRAME:
2158       /*
2159        * All management frame types have the same header.
2160        */
2161       src = tvb_get_ptr (tvb, 10, 6);
2162       dst = tvb_get_ptr (tvb, 4, 6);
2163
2164       SET_ADDRESS(&pinfo->dl_src, AT_ETHER, 6, src);
2165       SET_ADDRESS(&pinfo->src, AT_ETHER, 6, src);
2166       SET_ADDRESS(&pinfo->dl_dst, AT_ETHER, 6, dst);
2167       SET_ADDRESS(&pinfo->dst, AT_ETHER, 6, dst);
2168
2169       /* for tap */
2170       SET_ADDRESS(&whdr->bssid, AT_ETHER, 6, tvb_get_ptr(tvb, 16,6));
2171       SET_ADDRESS(&whdr->src, AT_ETHER, 6, src);
2172       SET_ADDRESS(&whdr->dst, AT_ETHER, 6, dst);
2173       whdr->type = frame_type_subtype;
2174
2175       seq_control = tvb_get_letohs(tvb, 22);
2176       frag_number = COOK_FRAGMENT_NUMBER(seq_control);
2177       seq_number = COOK_SEQUENCE_NUMBER(seq_control);
2178
2179       if (check_col (pinfo->cinfo, COL_INFO))
2180       {
2181         col_append_fstr(pinfo->cinfo, COL_INFO,
2182           ",SN=%d", seq_number);
2183
2184         col_append_fstr(pinfo->cinfo, COL_INFO,
2185           ",FN=%d",frag_number);
2186       }
2187
2188       if (tree)
2189         {
2190           proto_tree_add_ether (hdr_tree, hf_addr_da, tvb, 4, 6, dst);
2191
2192           proto_tree_add_ether (hdr_tree, hf_addr_sa, tvb, 10, 6, src);
2193
2194           /* add items for wlan.addr filter */
2195           proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 4, 6, dst);
2196           proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 10, 6, src);
2197
2198           proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 16, 6,
2199                                 tvb_get_ptr (tvb, 16, 6));
2200
2201           proto_tree_add_uint (hdr_tree, hf_frag_number, tvb, 22, 2,
2202                                frag_number);
2203
2204           proto_tree_add_uint (hdr_tree, hf_seq_number, tvb, 22, 2,
2205                                seq_number);
2206         }
2207       break;
2208
2209     case CONTROL_FRAME:
2210       switch (frame_type_subtype)
2211         {
2212
2213         case CTRL_PS_POLL:
2214           src = tvb_get_ptr (tvb, 10, 6);
2215           dst = tvb_get_ptr (tvb, 4, 6);
2216
2217           set_src_addr_cols(pinfo, src, "BSSID");
2218           set_dst_addr_cols(pinfo, dst, "BSSID");
2219
2220           if (tree)
2221             {
2222               proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 4, 6, dst);
2223
2224               proto_tree_add_ether (hdr_tree, hf_addr_ta, tvb, 10, 6, src);
2225             }
2226           break;
2227
2228
2229         case CTRL_RTS:
2230           src = tvb_get_ptr (tvb, 10, 6);
2231           dst = tvb_get_ptr (tvb, 4, 6);
2232
2233           set_src_addr_cols(pinfo, src, "TA");
2234           set_dst_addr_cols(pinfo, dst, "RA");
2235
2236           if (tree)
2237             {
2238               proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6, dst);
2239
2240               proto_tree_add_ether (hdr_tree, hf_addr_ta, tvb, 10, 6, src);
2241             }
2242           break;
2243
2244
2245         case CTRL_CTS:
2246           dst = tvb_get_ptr (tvb, 4, 6);
2247
2248           set_dst_addr_cols(pinfo, dst, "RA");
2249
2250           if (tree)
2251             proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6, dst);
2252           break;
2253
2254
2255         case CTRL_ACKNOWLEDGEMENT:
2256           dst = tvb_get_ptr (tvb, 4, 6);
2257
2258           set_dst_addr_cols(pinfo, dst, "RA");
2259
2260           if (tree)
2261             proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6, dst);
2262           break;
2263
2264
2265         case CTRL_CFP_END:
2266           src = tvb_get_ptr (tvb, 10, 6);
2267           dst = tvb_get_ptr (tvb, 4, 6);
2268
2269           set_src_addr_cols(pinfo, src, "BSSID");
2270           set_dst_addr_cols(pinfo, dst, "RA");
2271
2272           if (tree)
2273             {
2274               proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6, dst);
2275               proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 10, 6, src);
2276             }
2277           break;
2278
2279
2280         case CTRL_CFP_ENDACK:
2281           src = tvb_get_ptr (tvb, 10, 6);
2282           dst = tvb_get_ptr (tvb, 4, 6);
2283
2284           set_src_addr_cols(pinfo, src, "BSSID");
2285           set_dst_addr_cols(pinfo, dst, "RA");
2286
2287           if (tree)
2288             {
2289               proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6, dst);
2290
2291               proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 10, 6, src);
2292             }
2293           break;
2294
2295         case CTRL_BLOCK_ACK_REQ:
2296           {
2297             src = tvb_get_ptr (tvb, 10, 6);
2298             dst = tvb_get_ptr (tvb, 4, 6);
2299
2300             set_src_addr_cols(pinfo, src, "TA");
2301             set_dst_addr_cols(pinfo, dst, "RA");
2302
2303             if (tree)
2304             {
2305               proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6, src);
2306
2307               proto_tree_add_ether (hdr_tree, hf_addr_ta, tvb, 10, 6, dst);
2308             }
2309           /* TODO BAR */
2310           break;
2311           }
2312
2313         case CTRL_BLOCK_ACK:
2314           {
2315             src = tvb_get_ptr (tvb, 10, 6);
2316             dst = tvb_get_ptr (tvb, 4, 6);
2317
2318             set_src_addr_cols(pinfo, src, "TA");
2319             set_dst_addr_cols(pinfo, dst, "RA");
2320
2321             if (tree)
2322             {
2323               proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6, src);
2324
2325               proto_tree_add_ether (hdr_tree, hf_addr_ta, tvb, 10, 6, dst);
2326             }
2327             /* TODO BAR Format */
2328             break;
2329           }
2330         }
2331       break;
2332
2333     case DATA_FRAME:
2334       addr_type = COOK_ADDR_SELECTOR (fcf);
2335
2336       /* In order to show src/dst address we must always do the following */
2337       switch (addr_type)
2338         {
2339
2340         case DATA_ADDR_T1:
2341           src = tvb_get_ptr (tvb, 10, 6);
2342           dst = tvb_get_ptr (tvb, 4, 6);
2343           bssid = tvb_get_ptr (tvb, 16, 6);
2344           break;
2345
2346
2347         case DATA_ADDR_T2:
2348           src = tvb_get_ptr (tvb, 16, 6);
2349           dst = tvb_get_ptr (tvb, 4, 6);
2350           bssid = tvb_get_ptr (tvb, 10, 6);
2351           break;
2352
2353
2354         case DATA_ADDR_T3:
2355           src = tvb_get_ptr (tvb, 10, 6);
2356           dst = tvb_get_ptr (tvb, 16, 6);
2357           bssid = tvb_get_ptr (tvb, 4, 6);
2358           break;
2359
2360
2361         case DATA_ADDR_T4:
2362           src = tvb_get_ptr (tvb, 24, 6);
2363           dst = tvb_get_ptr (tvb, 16, 6);
2364           bssid = tvb_get_ptr (tvb, 16, 6);
2365           break;
2366         }
2367
2368       SET_ADDRESS(&pinfo->dl_src, AT_ETHER, 6, src);
2369       SET_ADDRESS(&pinfo->src, AT_ETHER, 6, src);
2370       SET_ADDRESS(&pinfo->dl_dst, AT_ETHER, 6, dst);
2371       SET_ADDRESS(&pinfo->dst, AT_ETHER, 6, dst);
2372
2373       /* for tap */
2374
2375       SET_ADDRESS(&whdr->bssid, AT_ETHER, 6, bssid);
2376       SET_ADDRESS(&whdr->src, AT_ETHER, 6, src);
2377       SET_ADDRESS(&whdr->dst, AT_ETHER, 6, dst);
2378       whdr->type = frame_type_subtype;
2379
2380       seq_control = tvb_get_letohs(tvb, 22);
2381       frag_number = COOK_FRAGMENT_NUMBER(seq_control);
2382       seq_number = COOK_SEQUENCE_NUMBER(seq_control);
2383
2384       if (check_col (pinfo->cinfo, COL_INFO))
2385       {
2386         col_append_fstr(pinfo->cinfo, COL_INFO,
2387           ",SN=%d", seq_number);
2388
2389         col_append_fstr(pinfo->cinfo, COL_INFO,
2390           ",FN=%d",frag_number);
2391       }
2392
2393       /* Now if we have a tree we start adding stuff */
2394       if (tree)
2395         {
2396
2397
2398           switch (addr_type)
2399             {
2400
2401             case DATA_ADDR_T1:
2402               proto_tree_add_ether (hdr_tree, hf_addr_da, tvb, 4, 6, dst);
2403               proto_tree_add_ether (hdr_tree, hf_addr_sa, tvb, 10, 6, src);
2404               proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 16, 6,
2405                                     tvb_get_ptr (tvb, 16, 6));
2406               proto_tree_add_uint (hdr_tree, hf_frag_number, tvb, 22, 2,
2407                                    frag_number);
2408               proto_tree_add_uint (hdr_tree, hf_seq_number, tvb, 22, 2,
2409                                    seq_number);
2410
2411               /* add items for wlan.addr filter */
2412               proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 4, 6, dst);
2413               proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 10, 6, src);
2414               break;
2415
2416
2417             case DATA_ADDR_T2:
2418               proto_tree_add_ether (hdr_tree, hf_addr_da, tvb, 4, 6, dst);
2419               proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 10, 6,
2420                                     tvb_get_ptr (tvb, 10, 6));
2421               proto_tree_add_ether (hdr_tree, hf_addr_sa, tvb, 16, 6, src);
2422               proto_tree_add_uint (hdr_tree, hf_frag_number, tvb, 22, 2,
2423                                    frag_number);
2424               proto_tree_add_uint (hdr_tree, hf_seq_number, tvb, 22, 2,
2425                                    seq_number);
2426
2427               /* add items for wlan.addr filter */
2428               proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 4, 6, dst);
2429               proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 16, 6, src);
2430               break;
2431
2432
2433             case DATA_ADDR_T3:
2434               proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 4, 6,
2435                                     tvb_get_ptr (tvb, 4, 6));
2436               proto_tree_add_ether (hdr_tree, hf_addr_sa, tvb, 10, 6, src);
2437               proto_tree_add_ether (hdr_tree, hf_addr_da, tvb, 16, 6, dst);
2438
2439               proto_tree_add_uint (hdr_tree, hf_frag_number, tvb, 22, 2,
2440                                    frag_number);
2441               proto_tree_add_uint (hdr_tree, hf_seq_number, tvb, 22, 2,
2442                                    seq_number);
2443
2444               /* add items for wlan.addr filter */
2445               proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 10, 6, src);
2446               proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 16, 6, dst);
2447               break;
2448
2449
2450             case DATA_ADDR_T4:
2451               proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6,
2452                                     tvb_get_ptr (tvb, 4, 6));
2453               proto_tree_add_ether (hdr_tree, hf_addr_ta, tvb, 10, 6,
2454                                     tvb_get_ptr (tvb, 10, 6));
2455               proto_tree_add_ether (hdr_tree, hf_addr_da, tvb, 16, 6, dst);
2456               proto_tree_add_uint (hdr_tree, hf_frag_number, tvb, 22, 2,
2457                                    frag_number);
2458               proto_tree_add_uint (hdr_tree, hf_seq_number, tvb, 22, 2,
2459                                    seq_number);
2460               proto_tree_add_ether (hdr_tree, hf_addr_sa, tvb, 24, 6, src);
2461
2462               /* add items for wlan.addr filter */
2463               proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 16, 6, dst);
2464               proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 24, 6, src);
2465               break;
2466             }
2467
2468         }
2469       break;
2470     }
2471
2472   len = tvb_length_remaining(tvb, hdr_len);
2473   reported_len = tvb_reported_length_remaining(tvb, hdr_len);
2474
2475   switch (fcs_len)
2476     {
2477       case 0: /* Definitely has no FCS */
2478         has_fcs = FALSE;
2479         break;
2480
2481       case 4: /* Definitely has an FCS */
2482         has_fcs = TRUE;
2483         break;
2484
2485       default: /* Don't know - use "wlan_check_fcs" */
2486         has_fcs = wlan_check_fcs;
2487         break;
2488     }
2489   if (has_fcs)
2490     {
2491       /*
2492        * Well, this packet should, in theory, have an FCS.
2493        * Do we have the entire packet, and does it have enough data for
2494        * the FCS?
2495        */
2496       if (reported_len < 4)
2497         {
2498           /*
2499            * The packet is claimed not to even have enough data for a 4-byte
2500            * FCS.
2501            * Pretend it doesn't have an FCS.
2502            */
2503           ;
2504         }
2505       else if (len < reported_len)
2506         {
2507           /*
2508            * The packet is claimed to have enough data for a 4-byte FCS, but
2509            * we didn't capture all of the packet.
2510            * Slice off the 4-byte FCS from the reported length, and trim the
2511            * captured length so it's no more than the reported length; that
2512            * will slice off what of the FCS, if any, is in the captured
2513            * length.
2514            */
2515           reported_len -= 4;
2516           if (len > reported_len)
2517             len = reported_len;
2518         }
2519       else
2520         {
2521           /*
2522            * We have the entire packet, and it includes a 4-byte FCS.
2523            * Slice it off, and put it into the tree.
2524            */
2525           len -= 4;
2526           reported_len -= 4;
2527           if (tree)
2528             {
2529               guint32 fcs = crc32_802_tvb(tvb, hdr_len + len);
2530               guint32 sent_fcs = tvb_get_ntohl(tvb, hdr_len + len);
2531
2532               if (fcs == sent_fcs)
2533                 proto_tree_add_uint_format(hdr_tree, hf_fcs, tvb,
2534                         hdr_len + len, 4, sent_fcs,
2535                         "Frame check sequence: 0x%08x [correct]", sent_fcs);
2536               else
2537                 proto_tree_add_uint_format(hdr_tree, hf_fcs, tvb,
2538                         hdr_len + len, 4, sent_fcs,
2539                         "Frame check sequence: 0x%08x [incorrect, should be 0x%08x]",
2540                         sent_fcs, fcs);
2541             }
2542         }
2543     }
2544
2545
2546
2547   /*
2548    * Only management and data frames have a body, so we don't have
2549    * anything more to do for other types of frames.
2550    */
2551   switch (COOK_FRAME_TYPE (fcf))
2552     {
2553
2554     case MGT_FRAME:
2555       break;
2556
2557     case DATA_FRAME:
2558       {
2559         if (tree && IS_DATA_QOS(frame_type_subtype)) {
2560
2561           proto_item *qos_fields;
2562           proto_tree *qos_tree;
2563
2564           guint16 qos_control;
2565           guint16 qos_priority;
2566           guint16 qos_ack_policy;
2567           guint16 qos_eosp;
2568           guint16 qos_field_content;
2569
2570           qos_fields = proto_tree_add_text(hdr_tree, tvb, hdr_len - 2, 2,
2571               "QoS parameters");
2572           qos_tree = proto_item_add_subtree (qos_fields, ett_qos_parameters);
2573
2574           qos_control =       tvb_get_letohs(tvb, hdr_len - 2);
2575           qos_priority =      COOK_QOS_PRIORITY(qos_control);
2576           qos_ack_policy =    COOK_QOS_ACK_POLICY(qos_control);
2577           qos_eosp =          COOK_QOS_EOSP(qos_control);
2578           qos_field_content = COOK_QOS_FIELD_CONTENT( qos_control);
2579
2580           proto_tree_add_uint_format (qos_tree, hf_qos_priority, tvb,
2581               hdr_len - 2, 2, qos_priority,
2582               "Priority: %d (%s) (%s)",
2583               qos_priority, qos_tags[qos_priority], qos_acs[qos_priority]);
2584
2585           if(flags & FLAG_FROM_DS)      {
2586             proto_tree_add_boolean (qos_tree, hf_qos_eosp, tvb,
2587               hdr_len - 2, 1, qos_eosp);
2588
2589             if(IS_DATA_CF_POLL(frame_type_subtype)) {
2590               /* txop limit */
2591               proto_tree_add_uint_format (qos_tree, hf_qos_field_content, tvb,
2592                   hdr_len - 1, 1, qos_field_content, "TXOP Limit: %d ", qos_field_content);
2593
2594             }else {
2595               /* qap ps buffer state */
2596               proto_item *qos_ps_buf_state_fields;
2597               proto_tree *qos_ps_buf_state_tree;
2598               guint16 buf_state;
2599               guint16 buf_ac;
2600               guint16 buf_load;
2601
2602               buf_state = COOK_PS_BUF_STATE(qos_field_content);
2603               buf_ac    = COOK_PS_BUF_AC(qos_field_content);  /*access category */
2604               buf_load  = COOK_PS_BUF_LOAD(qos_field_content);
2605
2606               qos_ps_buf_state_fields = proto_tree_add_text(qos_tree, tvb, hdr_len - 1, 1,
2607               "QAP PS Buffer State: 0x%x", qos_field_content);
2608               qos_ps_buf_state_tree = proto_item_add_subtree (qos_ps_buf_state_fields, ett_qos_ps_buf_state);
2609
2610 /*      FIXME: hf_ values not defined
2611               proto_tree_add_boolean (qos_ps_buf_state_tree, hf_qos_buf_state, tvb,
2612                   1, 1, buf_state);
2613
2614               proto_tree_add_uint_format (qos_ps_buf_state_tree, hf_qos_buf_ac, tvb,
2615                   hdr_len - 1, 1, buf_ac, "Priority: %d (%s)",
2616                   buf_ac, wme_acs[buf_ac]);
2617
2618               proto_tree_add_uint_format (qos_ps_buf_state_tree, hf_qos_buf_load, tvb,
2619                   hdr_len - 1, 1, buf_load, "Buffered load: %d ", (buf_load * 4096));
2620 */
2621
2622             }
2623           } else  if(qos_eosp)  {
2624             /* txop limit requested */
2625             proto_tree_add_uint_format (qos_tree, hf_qos_field_content, tvb,
2626                   hdr_len - 1, 1, qos_field_content, "Queue Size: %d ", (qos_field_content * 254));
2627           } else  {
2628             /* queue size */
2629             proto_tree_add_uint_format (qos_tree, hf_qos_field_content, tvb,
2630                   hdr_len - 1, 1, qos_field_content, "TXOP Limit Requested: %d ", qos_field_content);
2631           }
2632
2633           proto_tree_add_uint (qos_tree, hf_qos_ack_policy, tvb, hdr_len - 2, 1,
2634               qos_ack_policy);
2635
2636         } /* end of qos control field */
2637
2638       /*
2639        * No-data frames don't have a body.
2640        */
2641       if( IS_DATA_NULL(frame_type_subtype))
2642         return;
2643
2644       break;
2645       }
2646
2647     case CONTROL_FRAME:
2648       return;
2649
2650     default:
2651       return;
2652     }
2653
2654   if (IS_PROTECTED(COOK_FLAGS(fcf))) {
2655     /*
2656      * It's a WEP-encrypted frame; dissect the WEP parameters and decrypt
2657      * the data, if we have a matching key.  Otherwise display it as data.
2658      */
2659     gboolean can_decrypt = FALSE;
2660     proto_tree *wep_tree = NULL;
2661     guint32 iv;
2662     guint8 key, keybyte;
2663
2664     keybyte = tvb_get_guint8(tvb, hdr_len + 3);
2665     key = COOK_WEP_KEY(keybyte);
2666     if ((keybyte & KEY_EXTIV) && (len >= EXTIV_LEN)) {
2667       /* Extended IV; this frame is likely encrypted with TKIP or CCMP */
2668       if (tree) {
2669         proto_item *extiv_fields;
2670
2671         extiv_fields = proto_tree_add_text(hdr_tree, tvb, hdr_len, 8,
2672                                            "TKIP/CCMP parameters");
2673         wep_tree = proto_item_add_subtree (extiv_fields, ett_wep_parameters);
2674         /* It is unknown whether this is a TKIP or CCMP encrypted packet, so
2675          * display both packet number alternatives unless the ExtIV can be
2676          * determined to be possible only with one of the encryption protocols.
2677          */
2678         if (tvb_get_guint8(tvb, hdr_len + 1) & 0x20) {
2679           g_snprintf(out_buff, SHORT_STR, "0x%08X%02X%02X",
2680                    tvb_get_letohl(tvb, hdr_len + 4),
2681                    tvb_get_guint8(tvb, hdr_len),
2682                    tvb_get_guint8(tvb, hdr_len + 2));
2683           proto_tree_add_string(wep_tree, hf_tkip_extiv, tvb, hdr_len,
2684                                 EXTIV_LEN, out_buff);
2685         }
2686         if (tvb_get_guint8(tvb, hdr_len + 2) == 0) {
2687           g_snprintf(out_buff, SHORT_STR, "0x%08X%02X%02X",
2688                    tvb_get_letohl(tvb, hdr_len + 4),
2689                    tvb_get_guint8(tvb, hdr_len + 1),
2690                    tvb_get_guint8(tvb, hdr_len));
2691           proto_tree_add_string(wep_tree, hf_ccmp_extiv, tvb, hdr_len,
2692                                 EXTIV_LEN, out_buff);
2693         }
2694         proto_tree_add_uint(wep_tree, hf_wep_key, tvb, hdr_len + 3, 1, key);
2695       }
2696
2697       /* Subtract out the length of the IV. */
2698       len -= EXTIV_LEN;
2699       reported_len -= EXTIV_LEN;
2700       ivlen = EXTIV_LEN;
2701       /* It is unknown whether this is TKIP or CCMP, so let's not even try to
2702        * parse TKIP Michael MIC+ICV or CCMP MIC. */
2703     } else {
2704       /* No Ext. IV - WEP packet */
2705       /*
2706        * XXX - pass the IV and key to "try_decrypt_wep()", and have it pass
2707        * them to "wep_decrypt()", rather than having "wep_decrypt()" extract
2708        * them itself.
2709        *
2710        * Also, just pass the data *following* the WEP parameters as the
2711        * buffer to decrypt.
2712        */
2713       iv = tvb_get_ntoh24(tvb, hdr_len);
2714       if (tree) {
2715         proto_item *wep_fields;
2716
2717         wep_fields = proto_tree_add_text(hdr_tree, tvb, hdr_len, 4,
2718                                          "WEP parameters");
2719
2720         wep_tree = proto_item_add_subtree (wep_fields, ett_wep_parameters);
2721         proto_tree_add_uint (wep_tree, hf_wep_iv, tvb, hdr_len, 3, iv);
2722         tvb_memcpy(tvb, iv_buff, hdr_len, 3);
2723         is_iv_bad = weak_iv(iv_buff);
2724         if (is_iv_bad != -1) {
2725                 proto_tree_add_boolean_format (wep_tree, hf_wep_iv_weak,
2726                                                tvb, 0, 0, TRUE,
2727                                                "Weak IV for key byte %d",
2728                                                is_iv_bad);
2729         }
2730       }
2731       if (tree)
2732         proto_tree_add_uint (wep_tree, hf_wep_key, tvb, hdr_len + 3, 1, key);
2733
2734       /* Subtract out the length of the IV. */
2735       len -= 4;
2736       reported_len -= 4;
2737       ivlen = 4;
2738
2739       /*
2740        * Well, this packet should, in theory, have an ICV.
2741        * Do we have the entire packet, and does it have enough data for
2742        * the ICV?
2743        */
2744       if (reported_len < 4) {
2745         /*
2746          * The packet is claimed not to even have enough data for a
2747          * 4-byte ICV.
2748          * Pretend it doesn't have an ICV.
2749          */
2750         ;
2751       } else if (len < reported_len) {
2752         /*
2753          * The packet is claimed to have enough data for a 4-byte ICV,
2754          * but we didn't capture all of the packet.
2755          * Slice off the 4-byte ICV from the reported length, and trim
2756          * the captured length so it's no more than the reported length;
2757          * that will slice off what of the ICV, if any, is in the
2758          * captured length.
2759          *
2760          */
2761         reported_len -= 4;
2762         if (len > reported_len)
2763           len = reported_len;
2764       } else {
2765         /*
2766          * We have the entire packet, and it includes a 4-byte ICV.
2767          * Slice it off, and put it into the tree.
2768          *
2769          * We only support decrypting if we have the the ICV.
2770          *
2771          * XXX - the ICV is encrypted; we're putting the encrypted
2772          * value, not the decrypted value, into the tree.
2773          */
2774         len -= 4;
2775         reported_len -= 4;
2776         can_decrypt = TRUE;
2777       }
2778     }
2779
2780     if (!can_decrypt || (next_tvb = try_decrypt_wep(tvb, hdr_len, reported_len + 8)) == NULL) {
2781       /*
2782        * WEP decode impossible or failed, treat payload as raw data
2783        * and don't attempt fragment reassembly or further dissection.
2784        */
2785       next_tvb = tvb_new_subset(tvb, hdr_len + ivlen, len, reported_len);
2786
2787       if (tree && can_decrypt)
2788         proto_tree_add_uint_format (wep_tree, hf_wep_icv, tvb,
2789                                     hdr_len + ivlen + len, 4,
2790                                     tvb_get_ntohl(tvb, hdr_len + ivlen + len),
2791                                     "WEP ICV: 0x%08x (not verified)",
2792                                     tvb_get_ntohl(tvb, hdr_len + ivlen + len));
2793
2794       if (pinfo->ethertype != ETHERTYPE_CENTRINO_PROMISC)
2795       {
2796         /* Some wireless drivers (such as Centrino) WEP payload already decrypted */
2797         call_dissector(data_handle, next_tvb, pinfo, tree);
2798         goto end_of_wlan;
2799       }
2800     } else {
2801
2802       if (tree)
2803         proto_tree_add_uint_format (wep_tree, hf_wep_icv, tvb,
2804                                     hdr_len + ivlen + len, 4,
2805                                     tvb_get_ntohl(tvb, hdr_len + ivlen + len),
2806                                     "WEP ICV: 0x%08x (correct)",
2807                                     tvb_get_ntohl(tvb, hdr_len + ivlen + len));
2808
2809       add_new_data_source(pinfo, next_tvb, "Decrypted WEP data");
2810     }
2811
2812     /*
2813      * WEP decryption successful!
2814      *
2815      * Use the tvbuff we got back from the decryption; the data starts at
2816      * the beginning.  The lengths are already correct for the decoded WEP
2817      * payload.
2818      */
2819     hdr_len = 0;
2820
2821   } else {
2822     /*
2823      * Not a WEP-encrypted frame; just use the data from the tvbuff
2824      * handed to us.
2825      *
2826      * The payload starts at "hdr_len" (i.e., just past the 802.11
2827      * MAC header), the length of data in the tvbuff following the
2828      * 802.11 header is "len", and the length of data in the packet
2829      * following the 802.11 header is "reported_len".
2830      */
2831     next_tvb = tvb;
2832   }
2833
2834   /*
2835    * Do defragmentation if "wlan_defragment" is true, and we have more
2836    * fragments or this isn't the first fragment.
2837    *
2838    * We have to do some special handling to catch frames that
2839    * have the "More Fragments" indicator not set but that
2840    * don't show up as reassembled and don't have any other
2841    * fragments present.  Some networking interfaces appear
2842    * to do reassembly even when you're capturing raw packets
2843    * *and* show the reassembled packet without the "More
2844    * Fragments" indicator set *but* with a non-zero fragment
2845    * number.
2846    *
2847    * "fragment_add_seq_802_11()" handles that; we want to call it
2848    * even if we have a short frame, so that it does those checks - if
2849    * the frame is short, it doesn't do reassembly on it.
2850    *
2851    * (This could get some false positives if we really *did* only
2852    * capture the last fragment of a fragmented packet, but that's
2853    * life.)
2854    */
2855   save_fragmented = pinfo->fragmented;
2856   if (wlan_defragment && (more_frags || frag_number != 0)) {
2857     fragment_data *fd_head;
2858
2859     /*
2860      * If we've already seen this frame, look it up in the
2861      * table of reassembled packets, otherwise add it to
2862      * whatever reassembly is in progress, if any, and see
2863      * if it's done.
2864      */
2865     fd_head = fragment_add_seq_802_11(next_tvb, hdr_len, pinfo, seq_number,
2866                                      wlan_fragment_table,
2867                                      wlan_reassembled_table,
2868                                      frag_number,
2869                                      reported_len,
2870                                      more_frags);
2871     next_tvb = process_reassembled_data(tvb, hdr_len, pinfo,
2872                                         "Reassembled 802.11", fd_head,
2873                                         &frag_items, NULL, hdr_tree);
2874   } else {
2875     /*
2876      * If this is the first fragment, dissect its contents, otherwise
2877      * just show it as a fragment.
2878      */
2879     if (frag_number != 0) {
2880       /* Not the first fragment - don't dissect it. */
2881       next_tvb = NULL;
2882     } else {
2883       /* First fragment, or not fragmented.  Dissect what we have here. */
2884
2885       /* Get a tvbuff for the payload. */
2886       next_tvb = tvb_new_subset (next_tvb, hdr_len, len, reported_len);
2887
2888       /*
2889        * If this is the first fragment, but not the only fragment,
2890        * tell the next protocol that.
2891        */
2892       if (more_frags)
2893         pinfo->fragmented = TRUE;
2894       else
2895         pinfo->fragmented = FALSE;
2896     }
2897   }
2898
2899   if (next_tvb == NULL) {
2900     /* Just show this as an incomplete fragment. */
2901     if (check_col(pinfo->cinfo, COL_INFO))
2902       col_set_str(pinfo->cinfo, COL_INFO, "Fragmented IEEE 802.11 frame");
2903     next_tvb = tvb_new_subset (tvb, hdr_len, len, reported_len);
2904     call_dissector(data_handle, next_tvb, pinfo, tree);
2905     pinfo->fragmented = save_fragmented;
2906     goto end_of_wlan;
2907   }
2908
2909   switch (COOK_FRAME_TYPE (fcf))
2910     {
2911
2912     case MGT_FRAME:
2913       dissect_ieee80211_mgt (fcf, next_tvb, pinfo, tree);
2914       break;
2915
2916
2917     case DATA_FRAME:
2918       /* I guess some bridges take Netware Ethernet_802_3 frames,
2919          which are 802.3 frames (with a length field rather than
2920          a type field, but with no 802.2 header in the payload),
2921          and just stick the payload into an 802.11 frame.  I've seen
2922          captures that show frames of that sort.
2923
2924          We also handle some odd form of encapsulation in which a
2925          complete Ethernet frame is encapsulated within an 802.11
2926          data frame, with no 802.2 header.  This has been seen
2927          from some hardware.
2928
2929          So, if the packet doesn't start with 0xaa 0xaa:
2930
2931            we first use the same scheme that linux-wlan-ng does to detect
2932            those encapsulated Ethernet frames, namely looking to see whether
2933            the frame either starts with 6 octets that match the destination
2934            address from the 802.11 header or has 6 octets that match the
2935            source address from the 802.11 header following the first 6 octets,
2936            and, if so, treat it as an encapsulated Ethernet frame;
2937
2938            otherwise, we use the same scheme that we use in the Ethernet
2939            dissector to recognize Netware 802.3 frames, namely checking
2940            whether the packet starts with 0xff 0xff and, if so, treat it
2941            as an encapsulated IPX frame. */
2942       encap_type = ENCAP_802_2;
2943       TRY {
2944         octet1 = tvb_get_guint8(next_tvb, 0);
2945         octet2 = tvb_get_guint8(next_tvb, 1);
2946         if (octet1 != 0xaa || octet2 != 0xaa) {
2947           src = tvb_get_ptr (next_tvb, 6, 6);
2948           dst = tvb_get_ptr (next_tvb, 0, 6);
2949           if (memcmp(src, pinfo->dl_src.data, 6) == 0 ||
2950               memcmp(dst, pinfo->dl_dst.data, 6) == 0)
2951             encap_type = ENCAP_ETHERNET;
2952           else if (octet1 == 0xff && octet2 == 0xff)
2953             encap_type = ENCAP_IPX;
2954         }
2955       }
2956       CATCH2(BoundsError, ReportedBoundsError) {
2957             ; /* do nothing */
2958
2959       }
2960       ENDTRY;
2961
2962       switch (encap_type) {
2963
2964       case ENCAP_802_2:
2965         call_dissector(llc_handle, next_tvb, pinfo, tree);
2966         break;
2967
2968       case ENCAP_ETHERNET:
2969         call_dissector(eth_withoutfcs_handle, next_tvb, pinfo, tree);
2970         break;
2971
2972       case ENCAP_IPX:
2973         call_dissector(ipx_handle, next_tvb, pinfo, tree);
2974         break;
2975       }
2976       break;
2977     }
2978   pinfo->fragmented = save_fragmented;
2979
2980   end_of_wlan:
2981   tap_queue_packet(wlan_tap, pinfo, whdr);
2982 }
2983
2984 /*
2985  * Dissect 802.11 with a variable-length link-layer header.
2986  */
2987 static void
2988 dissect_ieee80211 (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
2989 {
2990   dissect_ieee80211_common (tvb, pinfo, tree, FALSE, FALSE,
2991       pinfo->pseudo_header->ieee_802_11.fcs_len, FALSE);
2992 }
2993
2994 /*
2995  * Dissect 802.11 with a variable-length link-layer header and a pseudo-
2996  * header containing radio information.
2997  */
2998 static void
2999 dissect_ieee80211_radio (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
3000 {
3001   dissect_ieee80211_common (tvb, pinfo, tree, FALSE, TRUE,
3002      pinfo->pseudo_header->ieee_802_11.fcs_len, FALSE);
3003 }
3004
3005 /*
3006  * Dissect 802.11 with a variable-length link-layer header and a byte-swapped
3007  * control field (some hardware sends out LWAPP-encapsulated 802.11
3008  * packets with the control field byte swapped).
3009  */
3010 static void
3011 dissect_ieee80211_bsfc (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
3012 {
3013   dissect_ieee80211_common (tvb, pinfo, tree, FALSE, FALSE, 0, TRUE);
3014 }
3015
3016 /*
3017  * Dissect 802.11 with a fixed-length link-layer header (padded to the
3018  * maximum length).
3019  */
3020 static void
3021 dissect_ieee80211_fixed (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
3022 {
3023   dissect_ieee80211_common (tvb, pinfo, tree, TRUE, FALSE, 0, FALSE);
3024 }
3025
3026 static void
3027 wlan_defragment_init(void)
3028 {
3029   fragment_table_init(&wlan_fragment_table);
3030   reassembled_table_init(&wlan_reassembled_table);
3031 }
3032
3033 void
3034 proto_register_ieee80211 (void)
3035 {
3036   static const value_string frame_type[] = {
3037     {MGT_FRAME,     "Management frame"},
3038     {CONTROL_FRAME, "Control frame"},
3039     {DATA_FRAME,    "Data frame"},
3040     {0,             NULL}
3041   };
3042
3043   static const value_string tofrom_ds[] = {
3044     {0,                       "Not leaving DS or network is operating "
3045       "in AD-HOC mode (To DS: 0 From DS: 0)"},
3046     {FLAG_TO_DS,              "Frame from STA to DS via an AP (To DS: 1 "
3047       "From DS: 0)"},
3048     {FLAG_FROM_DS,            "Frame from DS to a STA via AP(To DS: 0 "
3049       "From DS: 1)"},
3050     {FLAG_TO_DS|FLAG_FROM_DS, "Frame part of WDS from one AP to another "
3051       "AP (To DS: 1 From DS: 1)"},
3052     {0, NULL}
3053   };
3054
3055   static const true_false_string tods_flag = {
3056     "Frame is entering DS",
3057     "Frame is not entering DS"
3058   };
3059
3060   static const true_false_string fromds_flag = {
3061     "Frame is exiting DS",
3062     "Frame is not exiting DS"
3063   };
3064
3065   static const true_false_string more_frags = {
3066     "More fragments follow",
3067     "This is the last fragment"
3068   };
3069
3070   static const true_false_string retry_flags = {
3071     "Frame is being retransmitted",
3072     "Frame is not being retransmitted"
3073   };
3074
3075   static const true_false_string pm_flags = {
3076     "STA will go to sleep",
3077     "STA will stay up"
3078   };
3079
3080   static const true_false_string md_flags = {
3081     "Data is buffered for STA at AP",
3082     "No data buffered"
3083   };
3084
3085   static const true_false_string protected_flags = {
3086     "Data is protected",
3087     "Data is not protected"
3088   };
3089
3090   static const true_false_string order_flags = {
3091     "Strictly ordered",
3092     "Not strictly ordered"
3093   };
3094
3095   static const true_false_string cf_ess_flags = {
3096     "Transmitter is an AP",
3097     "Transmitter is a STA"
3098   };
3099
3100
3101   static const true_false_string cf_privacy_flags = {
3102     "AP/STA can support WEP",
3103     "AP/STA cannot support WEP"
3104   };
3105
3106   static const true_false_string cf_preamble_flags = {
3107     "Short preamble allowed",
3108     "Short preamble not allowed"
3109   };
3110
3111   static const true_false_string cf_pbcc_flags = {
3112     "PBCC modulation allowed",
3113     "PBCC modulation not allowed"
3114   };
3115
3116   static const true_false_string cf_agility_flags = {
3117     "Channel agility in use",
3118     "Channel agility not in use"
3119   };
3120
3121   static const true_false_string short_slot_time_flags = {
3122     "Short slot time in use",
3123     "Short slot time not in use"
3124   };
3125
3126   static const true_false_string dsss_ofdm_flags = {
3127     "DSSS-OFDM modulation allowed",
3128     "DSSS-OFDM modulation not allowed"
3129   };
3130
3131   static const true_false_string cf_spec_man_flags = {
3132     "dot11SpectrumManagementRequired TRUE",
3133     "dot11SpectrumManagementRequired FALSE",
3134   };
3135
3136   static const true_false_string cf_apsd_flags = {
3137     "apsd implemented",
3138     "apsd not implemented",
3139   };
3140
3141   static const true_false_string cf_del_blk_ack_flags = {
3142     "delayed block ack implemented",
3143     "delayed block ack not implented",
3144   };
3145
3146   static const true_false_string cf_imm_blk_ack_flags = {
3147     "immediate block ack implemented",
3148     "immediate block ack not implented",
3149   };
3150   static const true_false_string cf_ibss_flags = {
3151     "Transmitter belongs to an IBSS",
3152     "Transmitter belongs to a BSS"
3153   };
3154
3155   static const true_false_string eosp_flag = {
3156     "End of service period",
3157     "Service period"
3158   };
3159
3160   static const value_string sta_cf_pollable[] = {
3161     {0x00, "Station is not CF-Pollable"},
3162     {0x02, "Station is CF-Pollable, "
3163      "not requesting to be placed on the  CF-polling list"},
3164     {0x01, "Station is CF-Pollable, "
3165      "requesting to be placed on the CF-polling list"},
3166     {0x03, "Station is CF-Pollable, requesting never to be polled"},
3167     {0x0200, "QSTA requesting association in QBSS"},
3168     {0, NULL}
3169   };
3170
3171   static const value_string ap_cf_pollable[] = {
3172     {0x00, "No point coordinator at AP"},
3173     {0x02, "Point coordinator at AP for delivery only (no polling)"},
3174     {0x01, "Point coordinator at AP for delivery and polling"},
3175     {0x03, "Reserved"},
3176     {0x0200, "QAP (HC) does not use CFP for delivery of unicast data type frames"},
3177     {0x0202, "QAP (HC) uses CFP for delivery, but does not send CF-Polls to non-QoS STAs"},
3178     {0x0201, "QAP (HC) uses CFP for delivery, and sends CF-Polls to non-QoS STAs"},
3179     {0x0203, "Reserved"},
3180     {0, NULL}
3181   };
3182
3183
3184   static const value_string auth_alg[] = {
3185     {0x00, "Open System"},
3186     {0x01, "Shared key"},
3187     {0x80, "Network EAP"},      /* Cisco proprietary? */
3188     {0, NULL}
3189   };
3190
3191   static const value_string reason_codes[] = {
3192     {0x00, "Reserved"},
3193     {0x01, "Unspecified reason"},
3194     {0x02, "Previous authentication no longer valid"},
3195     {0x03, "Deauthenticated because sending STA is leaving (has left) "
3196      "IBSS or ESS"},
3197     {0x04, "Disassociated due to inactivity"},
3198     {0x05, "Disassociated because AP is unable to handle all currently "
3199      "associated stations"},
3200     {0x06, "Class 2 frame received from nonauthenticated station"},
3201     {0x07, "Class 3 frame received from nonassociated station"},
3202     {0x08, "Disassociated because sending STA is leaving (has left) BSS"},
3203     {0x09, "Station requesting (re)association is not authenticated with "
3204       "responding station"},
3205     {0x0A, "Disassociated because the information in the Power Capability "
3206       "element is unacceptable"},
3207     {0x0B, "Disassociated because the information in the Supported"
3208       "Channels element is unacceptable"},
3209     {0x0D, "Invalid Information Element"},
3210     {0x0E, "Michael MIC failure"},
3211     {0x0F, "4-Way Handshake timeout"},
3212     {0x10, "Group key update timeout"},
3213     {0x11, "Information element in 4-Way Handshake different from "
3214      "(Re)Association Request/Probe Response/Beacon"},
3215     {0x12, "Group Cipher is not valid"},
3216     {0x13, "Pairwise Cipher is not valid"},
3217     {0x14, "AKMP is not valid"},
3218     {0x15, "Unsupported RSN IE version"},
3219     {0x16, "Invalid RSN IE Capabilities"},
3220     {0x17, "IEEE 802.1X Authentication failed"},
3221     {0x18, "Cipher suite is rejected per security policy"},
3222     {0x20, "Disassociated for unspecified, QoS-related reason"},
3223     {0x21, "Disassociated because QAP lacks sufficient bandwidth for this QSTA"},
3224     {0x22, "Disassociated because of excessive number of frames that need to be "
3225       "acknowledged, but are not acknowledged for AP transmissions and/or poor "
3226         "channel conditions"},
3227     {0x23, "Disassociated because QSTA is transmitting outside the limits of its TXOPs"},
3228     {0x24, "Requested from peer QSTA as the QSTA is leaving the QBSS (or resetting)"},
3229     {0x25, "Requested from peer QSTA as it does not want to use the mechanism"},
3230     {0x26, "Requested from peer QSTA as the QSTA received frames using the mechanism "
3231       "for which a set up is required"},
3232     {0x27, "Requested from peer QSTA due to time out"},
3233     {0x2D, "Peer QSTA does not support the requested cipher suite"},
3234     {0x00, NULL}
3235   };
3236
3237
3238   static const value_string status_codes[] = {
3239     {0x00, "Successful"},
3240     {0x01, "Unspecified failure"},
3241     {0x0A, "Cannot support all requested capabilities in the "
3242      "Capability information field"},
3243     {0x0B, "Reassociation denied due to inability to confirm that "
3244      "association exists"},
3245     {0x0C, "Association denied due to reason outside the scope of this "
3246      "standard"},
3247
3248     {0x0D, "Responding station does not support the specified authentication "
3249      "algorithm"},
3250     {0x0E, "Received an Authentication frame with authentication sequence "
3251      "transaction sequence number out of expected sequence"},
3252     {0x0F, "Authentication rejected because of challenge failure"},
3253     {0x10, "Authentication rejected due to timeout waiting for next "
3254      "frame in sequence"},
3255     {0x11, "Association denied because AP is unable to handle additional "
3256      "associated stations"},
3257     {0x12, "Association denied due to requesting station not supporting all "
3258      "of the datarates in the BSSBasicServiceSet Parameter"},
3259     {0x13, "Association denied due to requesting station not supporting "
3260      "short preamble operation"},
3261     {0x14, "Association denied due to requesting station not supporting "
3262      "PBCC encoding"},
3263     {0x15, "Association denied due to requesting station not supporting "
3264      "channel agility"},
3265     {0x16, "Association request rejected because Spectrum Management"
3266       "capability is required"},
3267     {0x17, "Association request rejected because the information in the"
3268       "Power Capability element is unacceptable"},
3269     {0x18, "Association request rejected because the information in the"
3270       "Supported Channels element is unacceptable"},
3271     {0x19, "Association denied due to requesting station not supporting "
3272      "short slot operation"},
3273     {0x1A, "Association denied due to requesting station not supporting "
3274      "DSSS-OFDM operation"},
3275     {0x20, "Unspecified, QoS-related failure"},
3276     {0x21, "Association denied due to QAP having insufficient bandwidth "
3277       "to handle another QSTA"},
3278     {0x22, "Association denied due to excessive frame loss rates and/or "
3279       "poor conditions on current operating channel"},
3280     {0x23, "Association (with QBSS) denied due to requesting station not "
3281       "supporting the QoS facility"},
3282     {0x24, "Association denied due to requesting station not supporting "
3283       "Block Ack"},
3284     {0x25, "The request has been declined."},
3285     {0x26, "The request has not been successful as one or more parameters "
3286       "have invalid values."},
3287     {0x27, "The TS has not been created because the request cannot be honored. "
3288       "However, a suggested TSPEC is provided so that the initiating QSTA may "
3289         "attempt to set another TS with the suggested changes to the TSPEC."},
3290     {0x28, "Invalid Information Element"},
3291     {0x29, "Group Cipher is not valid"},
3292     {0x2A, "Pairwise Cipher is not valid"},
3293     {0x2B, "AKMP is not valid"},
3294     {0x2C, "Unsupported RSN IE version"},
3295     {0x2D, "Invalid RSN IE Capabilities"},
3296     {0x2E, "Cipher suite is rejected per security policy"},
3297     {0x2F, "The TS has not been created. However, the HC may be capable of "
3298       "creating a TS, in response to a request, after the time indicated in the TS Delay element."},
3299     {0x30, "Direct Link is not allowed in the BSS by policy"},
3300     {0x31, "Destination STA is not present within this QBSS."},
3301     {0x32, "The Destination STA is not a QSTA."},
3302     {0x00, NULL}
3303   };
3304
3305   static const value_string category_codes[] = {
3306     {CAT_SPECTRUM_MGMT, "Spectrum Management"},
3307     {CAT_QOS, "QoS"},
3308     {CAT_DLS, "DLS"},
3309     {CAT_BLOCK_ACK, "Block Ack"},
3310     {CAT_MGMT_NOTIFICATION, "Management notification frame"},
3311     {0, NULL}
3312   };
3313
3314   static const value_string action_codes[] ={
3315     {SM_ACTION_MEASUREMENT_REQUEST, "Measurement Request"},
3316     {SM_ACTION_MEASUREMENT_REPORT, "Measurement Report"},
3317     {SM_ACTION_TPC_REQUEST, "TPC Request"},
3318     {SM_ACTION_TPC_REPORT, "TPC Report"},
3319     {SM_ACTION_CHAN_SWITCH_ANNC, "Channel Switch Announcement"},
3320     {0, NULL}
3321   };
3322
3323   static const value_string wme_action_codes[] = {
3324     {0x00, "Setup request"},
3325     {0x01, "Setup response"},
3326     {0x02, "Teardown"},
3327     {0x00, NULL}
3328   };
3329
3330   static const value_string wme_status_codes[] = {
3331     {0x00, "Admission accepted"},
3332     {0x01, "Invalid parameters"},
3333     {0x03, "Refused"},
3334     {0x00, NULL}
3335   };
3336
3337   static const value_string ack_policy[] = {
3338     {0x00, "Normal Ack"},
3339     {0x02, "No Ack"},
3340     {0x01, "No explicit Ack"},
3341     {0x03, "Block Ack"},
3342     {0x00, NULL}
3343   };
3344
3345   static hf_register_info hf[] = {
3346     {&hf_data_rate,
3347      {"Data Rate", "wlan.data_rate", FT_UINT8, BASE_DEC, NULL, 0,
3348       "Data rate (.5 Mb/s units)", HFILL }},
3349
3350     {&hf_channel,
3351      {"Channel", "wlan.channel", FT_UINT8, BASE_DEC, NULL, 0,
3352       "Radio channel", HFILL }},
3353
3354     {&hf_signal_strength,
3355      {"Signal Strength", "wlan.signal_strength", FT_UINT8, BASE_DEC, NULL, 0,
3356       "Signal strength (percentage)", HFILL }},
3357
3358     {&hf_fc_field,
3359      {"Frame Control Field", "wlan.fc", FT_UINT16, BASE_HEX, NULL, 0,
3360       "MAC Frame control", HFILL }},
3361
3362     {&hf_fc_proto_version,
3363      {"Version", "wlan.fc.version", FT_UINT8, BASE_DEC, NULL, 0,
3364       "MAC Protocol version", HFILL }}, /* 0 */
3365
3366     {&hf_fc_frame_type,
3367      {"Type", "wlan.fc.type", FT_UINT8, BASE_DEC, VALS(frame_type), 0,
3368       "Frame type", HFILL }},
3369
3370     {&hf_fc_frame_subtype,
3371      {"Subtype", "wlan.fc.subtype", FT_UINT8, BASE_DEC, NULL, 0,
3372       "Frame subtype", HFILL }},        /* 2 */
3373
3374     {&hf_fc_frame_type_subtype,
3375      {"Type/Subtype", "wlan.fc.type_subtype", FT_UINT16, BASE_DEC, VALS(frame_type_subtype_vals), 0,
3376       "Type and subtype combined", HFILL }},
3377
3378     {&hf_fc_flags,
3379      {"Protocol Flags", "wlan.flags", FT_UINT8, BASE_HEX, NULL, 0,
3380       "Protocol flags", HFILL }},
3381
3382     {&hf_fc_data_ds,
3383      {"DS status", "wlan.fc.ds", FT_UINT8, BASE_HEX, VALS (&tofrom_ds), 0,
3384       "Data-frame DS-traversal status", HFILL }},       /* 3 */
3385
3386     {&hf_fc_to_ds,
3387      {"To DS", "wlan.fc.tods", FT_BOOLEAN, 8, TFS (&tods_flag), FLAG_TO_DS,
3388       "To DS flag", HFILL }},           /* 4 */
3389
3390     {&hf_fc_from_ds,
3391      {"From DS", "wlan.fc.fromds", FT_BOOLEAN, 8, TFS (&fromds_flag), FLAG_FROM_DS,
3392       "From DS flag", HFILL }},         /* 5 */
3393
3394     {&hf_fc_more_frag,
3395      {"More Fragments", "wlan.fc.frag", FT_BOOLEAN, 8, TFS (&more_frags), FLAG_MORE_FRAGMENTS,
3396       "More Fragments flag", HFILL }},  /* 6 */
3397
3398     {&hf_fc_retry,
3399      {"Retry", "wlan.fc.retry", FT_BOOLEAN, 8, TFS (&retry_flags), FLAG_RETRY,
3400       "Retransmission flag", HFILL }},
3401
3402     {&hf_fc_pwr_mgt,
3403      {"PWR MGT", "wlan.fc.pwrmgt", FT_BOOLEAN, 8, TFS (&pm_flags), FLAG_POWER_MGT,
3404       "Power management status", HFILL }},
3405
3406     {&hf_fc_more_data,
3407      {"More Data", "wlan.fc.moredata", FT_BOOLEAN, 8, TFS (&md_flags), FLAG_MORE_DATA,
3408       "More data flag", HFILL }},
3409
3410     {&hf_fc_protected,
3411      {"Protected flag", "wlan.fc.protected", FT_BOOLEAN, 8, TFS (&protected_flags), FLAG_PROTECTED,
3412       "Protected flag", HFILL }},
3413
3414     {&hf_fc_order,
3415      {"Order flag", "wlan.fc.order", FT_BOOLEAN, 8, TFS (&order_flags), FLAG_ORDER,
3416       "Strictly ordered flag", HFILL }},
3417
3418     {&hf_assoc_id,
3419      {"Association ID","wlan.aid",FT_UINT16, BASE_DEC,NULL,0,
3420       "Association-ID field", HFILL }},
3421
3422     {&hf_did_duration,
3423      {"Duration", "wlan.duration", FT_UINT16, BASE_DEC, NULL, 0,
3424       "Duration field", HFILL }},
3425
3426     {&hf_addr_da,
3427      {"Destination address", "wlan.da", FT_ETHER, BASE_NONE, NULL, 0,
3428       "Destination Hardware Address", HFILL }},
3429
3430     {&hf_addr_sa,
3431      {"Source address", "wlan.sa", FT_ETHER, BASE_NONE, NULL, 0,
3432       "Source Hardware Address", HFILL }},
3433
3434     { &hf_addr,
3435       {"Source or Destination address", "wlan.addr", FT_ETHER, BASE_NONE, NULL, 0,
3436        "Source or Destination Hardware Address", HFILL }},
3437
3438     {&hf_addr_ra,
3439      {"Receiver address", "wlan.ra", FT_ETHER, BASE_NONE, NULL, 0,
3440       "Receiving Station Hardware Address", HFILL }},
3441
3442     {&hf_addr_ta,
3443      {"Transmitter address", "wlan.ta", FT_ETHER, BASE_NONE, NULL, 0,
3444       "Transmitting Station Hardware Address", HFILL }},
3445
3446     {&hf_addr_bssid,
3447      {"BSS Id", "wlan.bssid", FT_ETHER, BASE_NONE, NULL, 0,
3448       "Basic Service Set ID", HFILL }},
3449
3450     {&hf_frag_number,
3451      {"Fragment number", "wlan.frag", FT_UINT16, BASE_DEC, NULL, 0,
3452       "Fragment number", HFILL }},
3453
3454     {&hf_seq_number,
3455      {"Sequence number", "wlan.seq", FT_UINT16, BASE_DEC, NULL, 0,
3456       "Sequence number", HFILL }},
3457
3458     {&hf_qos_priority,
3459      {"Priority", "wlan.qos.priority", FT_UINT16, BASE_DEC, NULL, 0,
3460       "802.1D Tag", HFILL }},
3461
3462     {&hf_qos_eosp,
3463      {"EOSP", "wlan.qos.eosp", FT_BOOLEAN, 8, TFS (&eosp_flag), FLAG_EOSP,
3464       "EOSP Field", HFILL }},
3465
3466     {&hf_qos_ack_policy,
3467      {"Ack Policy", "wlan.qos.ack", FT_UINT16, BASE_HEX,  VALS (&ack_policy), 0,
3468       "Ack Policy", HFILL }},
3469
3470     {&hf_qos_field_content,
3471      {"Content", "wlan.qos.fc_content", FT_UINT16, BASE_DEC, NULL, 0,
3472       "Content1", HFILL }},
3473
3474 /*    {&hf_qos_buffer_state,
3475      {"QAP PS buffer State", "wlan.qos.ps_buf_state", FT_UINT16, BASE_DEC, NULL, 0,
3476       "QAP PS buffer State", HFILL }},
3477
3478     {&hf_qos_txop_dur_req,
3479      {"TXOP Duration Requested", "wlan.qos.txop_dur_req", FT_UINT16, BASE_DEC, NULL, 0,
3480       "TXOP Duration Requested", HFILL }},
3481
3482     {&hf_qos_queue_size,
3483      {"Queue Size", "wlan.qos.queue_size", FT_UINT16, BASE_DEC, NULL, 0,
3484       "Queue Size", HFILL }},*/
3485
3486     {&hf_fcs,
3487      {"Frame check sequence", "wlan.fcs", FT_UINT32, BASE_HEX,
3488       NULL, 0, "FCS", HFILL }},
3489
3490     {&hf_fragment_overlap,
3491       {"Fragment overlap", "wlan.fragment.overlap", FT_BOOLEAN, BASE_NONE,
3492        NULL, 0x0, "Fragment overlaps with other fragments", HFILL }},
3493
3494     {&hf_fragment_overlap_conflict,
3495       {"Conflicting data in fragment overlap", "wlan.fragment.overlap.conflict",
3496        FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3497        "Overlapping fragments contained conflicting data", HFILL }},
3498
3499     {&hf_fragment_multiple_tails,
3500       {"Multiple tail fragments found", "wlan.fragment.multipletails",
3501        FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3502        "Several tails were found when defragmenting the packet", HFILL }},
3503
3504     {&hf_fragment_too_long_fragment,
3505       {"Fragment too long", "wlan.fragment.toolongfragment",
3506        FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3507        "Fragment contained data past end of packet", HFILL }},
3508
3509     {&hf_fragment_error,
3510       {"Defragmentation error", "wlan.fragment.error",
3511        FT_FRAMENUM, BASE_NONE, NULL, 0x0,
3512        "Defragmentation error due to illegal fragments", HFILL }},
3513
3514     {&hf_fragment,
3515       {"802.11 Fragment", "wlan.fragment", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
3516        "802.11 Fragment", HFILL }},
3517
3518     {&hf_fragments,
3519       {"802.11 Fragments", "wlan.fragments", FT_NONE, BASE_NONE, NULL, 0x0,
3520        "802.11 Fragments", HFILL }},
3521
3522     {&hf_reassembled_in,
3523       {"Reassembled 802.11 in frame", "wlan.reassembled_in", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
3524        "This 802.11 packet is reassembled in this frame", HFILL }},
3525
3526     {&hf_wep_iv,
3527      {"Initialization Vector", "wlan.wep.iv", FT_UINT24, BASE_HEX, NULL, 0,
3528       "Initialization Vector", HFILL }},
3529
3530     {&hf_wep_iv_weak,
3531      {"Weak IV", "wlan.wep.weakiv", FT_BOOLEAN,BASE_NONE, NULL,0x0,
3532        "Weak IV",HFILL}},
3533
3534     {&hf_tkip_extiv,
3535      {"TKIP Ext. Initialization Vector", "wlan.tkip.extiv", FT_STRING,
3536       BASE_HEX, NULL, 0, "TKIP Extended Initialization Vector", HFILL }},
3537
3538     {&hf_ccmp_extiv,
3539      {"CCMP Ext. Initialization Vector", "wlan.ccmp.extiv", FT_STRING,
3540       BASE_HEX, NULL, 0, "CCMP Extended Initialization Vector", HFILL }},
3541
3542     {&hf_wep_key,
3543      {"Key Index", "wlan.wep.key", FT_UINT8, BASE_DEC, NULL, 0,
3544       "Key Index", HFILL }},
3545
3546     {&hf_wep_icv,
3547      {"WEP ICV", "wlan.wep.icv", FT_UINT32, BASE_HEX, NULL, 0,
3548       "WEP ICV", HFILL }},
3549   };
3550
3551   static const true_false_string rsn_preauth_flags = {
3552     "Transmitter supports pre-authentication",
3553     "Transmitter does not support pre-authentication"
3554   };
3555
3556   static const true_false_string rsn_no_pairwise_flags = {
3557     "Transmitter cannot support WEP default key 0 simultaneously with "
3558     "Pairwise key",
3559     "Transmitter can support WEP default key 0 simultaneously with "
3560     "Pairwise key"
3561   };
3562
3563   static const value_string rsn_cap_replay_counter[] = {
3564     {0x00, "1 replay counter per PTKSA/GTKSA/STAKeySA"},
3565     {0x01, "2 replay counters per PTKSA/GTKSA/STAKeySA"},
3566     {0x02, "4 replay counters per PTKSA/GTKSA/STAKeySA"},
3567     {0x03, "16 replay counters per PTKSA/GTKSA/STAKeySA"},
3568     {0, NULL}
3569   };
3570
3571   static hf_register_info ff[] = {
3572     {&ff_timestamp,
3573      {"Timestamp", "wlan_mgt.fixed.timestamp", FT_STRING, BASE_NONE,
3574       NULL, 0, "", HFILL }},
3575
3576     {&ff_auth_alg,
3577      {"Authentication Algorithm", "wlan_mgt.fixed.auth.alg",
3578       FT_UINT16, BASE_DEC, VALS (&auth_alg), 0, "", HFILL }},
3579
3580     {&ff_beacon_interval,
3581      {"Beacon Interval", "wlan_mgt.fixed.beacon", FT_DOUBLE, BASE_DEC, NULL, 0,
3582       "", HFILL }},
3583
3584     {&hf_fixed_parameters,
3585      {"Fixed parameters", "wlan_mgt.fixed.all", FT_UINT16, BASE_DEC, NULL, 0,
3586       "", HFILL }},
3587
3588     {&hf_tagged_parameters,
3589      {"Tagged parameters", "wlan_mgt.tagged.all", FT_UINT16, BASE_DEC, NULL, 0,
3590       "", HFILL }},
3591
3592     {&ff_capture,
3593      {"Capabilities", "wlan_mgt.fixed.capabilities", FT_UINT16, BASE_HEX, NULL, 0,
3594       "Capability information", HFILL }},
3595
3596     {&ff_cf_ess,
3597      {"ESS capabilities", "wlan_mgt.fixed.capabilities.ess",
3598       FT_BOOLEAN, 16, TFS (&cf_ess_flags), 0x0001, "ESS capabilities", HFILL }},
3599
3600     {&ff_cf_ibss,
3601      {"IBSS status", "wlan_mgt.fixed.capabilities.ibss",
3602       FT_BOOLEAN, 16, TFS (&cf_ibss_flags), 0x0002, "IBSS participation", HFILL }},
3603
3604     {&ff_cf_sta_poll,
3605      {"CFP participation capabilities", "wlan_mgt.fixed.capabilities.cfpoll.sta",
3606       FT_UINT16, BASE_HEX, VALS (&sta_cf_pollable), 0x020C,
3607       "CF-Poll capabilities for a STA", HFILL }},
3608
3609     {&ff_cf_ap_poll,
3610      {"CFP participation capabilities", "wlan_mgt.fixed.capabilities.cfpoll.ap",
3611       FT_UINT16, BASE_HEX, VALS (&ap_cf_pollable), 0x020C,
3612       "CF-Poll capabilities for an AP", HFILL }},
3613
3614     {&ff_cf_privacy,
3615      {"Privacy", "wlan_mgt.fixed.capabilities.privacy",
3616       FT_BOOLEAN, 16, TFS (&cf_privacy_flags), 0x0010, "WEP support", HFILL }},
3617
3618     {&ff_cf_preamble,
3619      {"Short Preamble", "wlan_mgt.fixed.capabilities.preamble",
3620       FT_BOOLEAN, 16, TFS (&cf_preamble_flags), 0x0020, "Short Preamble", HFILL }},
3621
3622     {&ff_cf_pbcc,
3623      {"PBCC", "wlan_mgt.fixed.capabilities.pbcc",
3624       FT_BOOLEAN, 16, TFS (&cf_pbcc_flags), 0x0040, "PBCC Modulation", HFILL }},
3625
3626     {&ff_cf_agility,
3627      {"Channel Agility", "wlan_mgt.fixed.capabilities.agility",
3628       FT_BOOLEAN, 16, TFS (&cf_agility_flags), 0x0080, "Channel Agility", HFILL }},
3629
3630     {&ff_cf_spec_man,
3631      {"Spectrum Management", "wlan_mgt.fixed.capabilities.spec_man",
3632       FT_BOOLEAN, 16, TFS (&cf_spec_man_flags), 0x0100, "Spectrum Management", HFILL }},
3633
3634     {&ff_short_slot_time,
3635      {"Short Slot Time", "wlan_mgt.fixed.capabilities.short_slot_time",
3636       FT_BOOLEAN, 16, TFS (&short_slot_time_flags), 0x0400, "Short Slot Time",
3637       HFILL }},
3638
3639     {&ff_cf_apsd,
3640      {"Automatic Power Save Delivery", "wlan_mgt.fixed.capabilities.apsd",
3641       FT_BOOLEAN, 16, TFS (&cf_apsd_flags), 0x0800, "Automatic Power Save "
3642         "Delivery", HFILL }},
3643
3644     {&ff_dsss_ofdm,
3645      {"DSSS-OFDM", "wlan_mgt.fixed.capabilities.dsss_ofdm",
3646       FT_BOOLEAN, 16, TFS (&dsss_ofdm_flags), 0x2000, "DSSS-OFDM Modulation",
3647       HFILL }},
3648
3649     {&ff_cf_del_blk_ack,
3650      {"Delayed Block Ack", "wlan_mgt.fixed.capabilities.del_blk_ack",
3651       FT_BOOLEAN, 16, TFS (&cf_del_blk_ack_flags), 0x4000, "Delayed Block "
3652         "Ack", HFILL }},
3653
3654     {&ff_cf_imm_blk_ack,
3655      {"Immediate Block Ack", "wlan_mgt.fixed.capabilities.imm_blk_ack",
3656       FT_BOOLEAN, 16, TFS (&cf_imm_blk_ack_flags), 0x8000, "Immediate Block "
3657         "Ack", HFILL }},
3658
3659     {&ff_auth_seq,
3660      {"Authentication SEQ", "wlan_mgt.fixed.auth_seq",
3661       FT_UINT16, BASE_HEX, NULL, 0, "Authentication sequence number", HFILL }},
3662
3663     {&ff_assoc_id,
3664      {"Association ID", "wlan_mgt.fixed.aid",
3665       FT_UINT16, BASE_HEX, NULL, 0, "Association ID", HFILL }},
3666
3667     {&ff_listen_ival,
3668      {"Listen Interval", "wlan_mgt.fixed.listen_ival",
3669       FT_UINT16, BASE_HEX, NULL, 0, "Listen Interval", HFILL }},
3670
3671     {&ff_current_ap,
3672      {"Current AP", "wlan_mgt.fixed.current_ap",
3673       FT_ETHER, BASE_NONE, NULL, 0, "MAC address of current AP", HFILL }},
3674
3675     {&ff_reason,
3676      {"Reason code", "wlan_mgt.fixed.reason_code",
3677       FT_UINT16, BASE_HEX, VALS (&reason_codes), 0,
3678       "Reason for unsolicited notification", HFILL }},
3679
3680     {&ff_status_code,
3681      {"Status code", "wlan_mgt.fixed.status_code",
3682       FT_UINT16, BASE_HEX, VALS (&status_codes), 0,
3683       "Status of requested event", HFILL }},
3684
3685     {&ff_category_code,
3686      {"Category code", "wlan_mgt.fixed.category_code",
3687       FT_UINT16, BASE_DEC, VALS (&category_codes), 0,
3688       "Management action category", HFILL }},
3689
3690     {&ff_action_code,
3691      {"Action code", "wlan_mgt.fixed.action_code",
3692       FT_UINT16, BASE_DEC, VALS (&action_codes), 0,
3693       "Management action code", HFILL }},
3694
3695     {&ff_dialog_token,
3696      {"Dialog token", "wlan_mgt.fixed.dialog_token",
3697       FT_UINT16, BASE_HEX, NULL, 0, "Management action dialog token", HFILL }},
3698
3699     {&ff_wme_action_code,
3700      {"Action code", "wlan_mgt.fixed.action_code",
3701       FT_UINT16, BASE_HEX, VALS (&wme_action_codes), 0,
3702       "Management notification action code", HFILL }},
3703
3704     {&ff_wme_status_code,
3705      {"Status code", "wlan_mgt.fixed.status_code",
3706       FT_UINT16, BASE_HEX, VALS (&wme_status_codes), 0,
3707       "Management notification setup response status code", HFILL }},
3708
3709     {&tag_number,
3710      {"Tag", "wlan_mgt.tag.number",
3711       FT_UINT8, BASE_DEC, VALS(tag_num_vals), 0,
3712       "Element ID", HFILL }},
3713
3714     {&tag_length,
3715      {"Tag length", "wlan_mgt.tag.length",
3716       FT_UINT8, BASE_DEC, NULL, 0, "Length of tag", HFILL }},
3717
3718     {&tag_interpretation,
3719      {"Tag interpretation", "wlan_mgt.tag.interpretation",
3720       FT_STRING, BASE_NONE, NULL, 0, "Interpretation of tag", HFILL }},
3721
3722     {&tag_oui,
3723      {"OUI", "wlan_mgt.tag.oui",
3724       FT_BYTES, BASE_NONE, NULL, 0, "OUI of vendor specific IE", HFILL }},
3725
3726     {&tim_length,
3727      {"TIM length", "wlan_mgt.tim.length",
3728       FT_UINT8, BASE_DEC, NULL, 0,
3729       "Traffic Indication Map length", HFILL }},
3730
3731     {&tim_dtim_count,
3732      {"DTIM count", "wlan_mgt.tim.dtim_count",
3733       FT_UINT8, BASE_DEC, NULL, 0,
3734       "DTIM count", HFILL }},
3735
3736     {&tim_dtim_period,
3737      {"DTIM period", "wlan_mgt.tim.dtim_period",
3738       FT_UINT8, BASE_DEC, NULL, 0,
3739       "DTIM period", HFILL }},
3740
3741     {&tim_bmapctl,
3742      {"Bitmap control", "wlan_mgt.tim.bmapctl",
3743       FT_UINT8, BASE_HEX, NULL, 0,
3744       "Bitmap control", HFILL }},
3745
3746     {&rsn_cap,
3747      {"RSN Capabilities", "wlan_mgt.rsn.capabilities", FT_UINT16, BASE_HEX,
3748       NULL, 0, "RSN Capability information", HFILL }},
3749
3750     {&rsn_cap_preauth,
3751      {"RSN Pre-Auth capabilities", "wlan_mgt.rsn.capabilities.preauth",
3752       FT_BOOLEAN, 16, TFS (&rsn_preauth_flags), 0x0001,
3753       "RSN Pre-Auth capabilities", HFILL }},
3754
3755     {&rsn_cap_no_pairwise,
3756      {"RSN No Pairwise capabilities", "wlan_mgt.rsn.capabilities.no_pairwise",
3757       FT_BOOLEAN, 16, TFS (&rsn_no_pairwise_flags), 0x0002,
3758       "RSN No Pairwise capabilities", HFILL }},
3759
3760     {&rsn_cap_ptksa_replay_counter,
3761      {"RSN PTKSA Replay Counter capabilities",
3762       "wlan_mgt.rsn.capabilities.ptksa_replay_counter",
3763       FT_UINT16, BASE_HEX, VALS (&rsn_cap_replay_counter), 0x000C,
3764       "RSN PTKSA Replay Counter capabilities", HFILL }},
3765
3766     {&rsn_cap_gtksa_replay_counter,
3767      {"RSN GTKSA Replay Counter capabilities",
3768       "wlan_mgt.rsn.capabilities.gtksa_replay_counter",
3769       FT_UINT16, BASE_HEX, VALS (&rsn_cap_replay_counter), 0x0030,
3770       "RSN GTKSA Replay Counter capabilities", HFILL }},
3771   };
3772
3773   static gint *tree_array[] = {
3774     &ett_80211,
3775     &ett_fc_tree,
3776     &ett_proto_flags,
3777     &ett_fragments,
3778     &ett_fragment,
3779     &ett_80211_mgt,
3780     &ett_fixed_parameters,
3781     &ett_tagged_parameters,
3782     &ett_qos_parameters,
3783     &ett_qos_ps_buf_state,
3784     &ett_wep_parameters,
3785     &ett_cap_tree,
3786     &ett_rsn_cap_tree,
3787     &ett_80211_mgt_ie,
3788   };
3789   module_t *wlan_module;
3790
3791   static const enum_val_t wep_keys_options[] = {
3792     {"0", "0", 0},
3793     {"1", "1", 1},
3794     {"2", "2", 2},
3795     {"3", "3", 3},
3796     {"4", "4", 4},
3797     {NULL, NULL, -1},
3798   };
3799
3800
3801   proto_wlan = proto_register_protocol ("IEEE 802.11 wireless LAN",
3802                                         "IEEE 802.11", "wlan");
3803   proto_register_field_array (proto_wlan, hf, array_length (hf));
3804   proto_wlan_mgt = proto_register_protocol ("IEEE 802.11 wireless LAN management frame",
3805                                         "802.11 MGT", "wlan_mgt");
3806   proto_register_field_array (proto_wlan_mgt, ff, array_length (ff));
3807   proto_register_subtree_array (tree_array, array_length (tree_array));
3808
3809   register_dissector("wlan", dissect_ieee80211, proto_wlan);
3810   register_dissector("wlan_fixed", dissect_ieee80211_fixed, proto_wlan);
3811   register_dissector("wlan_bsfc", dissect_ieee80211_bsfc, proto_wlan);
3812   register_init_routine(wlan_defragment_init);
3813
3814   wlan_tap = register_tap("wlan");
3815
3816   /* Register configuration options */
3817   wlan_module = prefs_register_protocol(proto_wlan, init_wepkeys);
3818   prefs_register_bool_preference(wlan_module, "defragment",
3819         "Reassemble fragmented 802.11 datagrams",
3820         "Whether fragmented 802.11 datagrams should be reassembled",
3821         &wlan_defragment);
3822
3823   prefs_register_bool_preference(wlan_module, "check_fcs",
3824                                  "Assume packets have FCS",
3825                                  "Some 802.11 cards include the FCS at the end of a packet, others do not.",
3826                                  &wlan_check_fcs);
3827
3828   prefs_register_bool_preference(wlan_module, "ignore_wep",
3829                                  "Ignore the WEP bit",
3830                                  "Some 802.11 cards leave the WEP bit set even though the packet is decrypted.",
3831                                  &wlan_ignore_wep);
3832
3833 #ifndef USE_ENV
3834   prefs_register_enum_preference(wlan_module, "wep_keys",
3835                                  "WEP key count",
3836                                  "How many WEP keys do we have to choose from? (0 to disable, up to 4)",
3837                                  &num_wepkeys, wep_keys_options, FALSE);
3838
3839   prefs_register_string_preference(wlan_module, "wep_key1",
3840                                    "WEP key #1",
3841                                    "First WEP key (A:B:C:D:E) [40bit], (A:B:C:D:E:F:G:H:I:J:K:L:M) [104bit], or whatever key length you're using",
3842                                    &wep_keystr[0]);
3843   prefs_register_string_preference(wlan_module, "wep_key2",
3844                                    "WEP key #2",
3845                                    "Second WEP key (A:B:C:D:E) [40bit], (A:B:C:D:E:F:G:H:I:J:K:L:M) [104bit], or whatever key length you're using",
3846                                    &wep_keystr[1]);
3847   prefs_register_string_preference(wlan_module, "wep_key3",
3848                                    "WEP key #3",
3849                                    "Third WEP key (A:B:C:D:E) [40bit], (A:B:C:D:E:F:G:H:I:J:K:L:M) [104bit], or whatever key length you're using",
3850                                    &wep_keystr[2]);
3851   prefs_register_string_preference(wlan_module, "wep_key4",
3852                                    "WEP key #4",
3853                                    "Fourth WEP key (A:B:C:D:E) [40bit] (A:B:C:D:E:F:G:H:I:J:K:L:M) [104bit], or whatever key length you're using",
3854                                    &wep_keystr[3]);
3855 #endif
3856 }
3857
3858 void
3859 proto_reg_handoff_ieee80211(void)
3860 {
3861   dissector_handle_t ieee80211_handle;
3862   dissector_handle_t ieee80211_radio_handle;
3863
3864   /*
3865    * Get handles for the LLC, IPX and Ethernet  dissectors.
3866    */
3867   llc_handle = find_dissector("llc");
3868   ipx_handle = find_dissector("ipx");
3869   eth_withoutfcs_handle = find_dissector("eth_withoutfcs");
3870   data_handle = find_dissector("data");
3871
3872   ieee80211_handle = find_dissector("wlan");
3873   dissector_add("wtap_encap", WTAP_ENCAP_IEEE_802_11, ieee80211_handle);
3874   ieee80211_radio_handle = create_dissector_handle(dissect_ieee80211_radio,
3875                                                    proto_wlan);
3876   dissector_add("wtap_encap", WTAP_ENCAP_IEEE_802_11_WITH_RADIO,
3877                 ieee80211_radio_handle);
3878   dissector_add("ethertype", ETHERTYPE_CENTRINO_PROMISC, ieee80211_handle);
3879 }
3880
3881 static tvbuff_t *try_decrypt_wep(tvbuff_t *tvb, guint32 offset, guint32 len) {
3882   const guint8 *enc_data;
3883   guint8 *tmp = NULL;
3884   int i;
3885   tvbuff_t *decr_tvb = NULL;
3886
3887   if (num_wepkeys < 1)
3888     return NULL;
3889
3890   enc_data = tvb_get_ptr(tvb, offset, len);
3891
3892   if ((tmp = g_malloc(len)) == NULL)
3893     return NULL;  /* krap! */
3894
3895   /* try once with the key index in the packet, then look through our list. */
3896   for (i = -1; i < num_wepkeys; i++) {
3897     /* copy the encrypted data over to the tmp buffer */
3898 #if 0
3899     printf("trying %d\n", i);
3900 #endif
3901     memcpy(tmp, enc_data, len);
3902     if (wep_decrypt(tmp, len, i) == 0) {
3903
3904       /* decrypt successful, let's set up a new data tvb. */
3905       decr_tvb = tvb_new_real_data(tmp, len-8, len-8);
3906       tvb_set_free_cb(decr_tvb, g_free);
3907       tvb_set_child_real_data_tvbuff(tvb, decr_tvb);
3908
3909       goto done;
3910     }
3911   }
3912
3913  done:
3914   if ((!decr_tvb) && (tmp))    g_free(tmp);
3915
3916 #if 0
3917   printf("de-wep %p\n", decr_tvb);
3918 #endif
3919
3920   return decr_tvb;
3921 }
3922
3923
3924 /* de-weps the block.  if successful, buf* will point to the data start. */
3925 static int wep_decrypt(guint8 *buf, guint32 len, int key_override) {
3926   guint32 i, j, k, crc, keylen;
3927   guint8 s[256], key[128], c_crc[4];
3928   guint8 keyidx, *dpos, *cpos;
3929
3930   /* Needs to be at least 8 bytes of payload */
3931   if (len < 8)
3932     return -1;
3933
3934   /* initialize the first bytes of the key from the IV */
3935   key[0] = buf[0];
3936   key[1] = buf[1];
3937   key[2] = buf[2];
3938   keyidx = COOK_WEP_KEY(buf[3]);
3939
3940   if (key_override >= 0)
3941     keyidx = key_override;
3942
3943   if (keyidx >= (guint)num_wepkeys)
3944     return -1;
3945
3946   keylen = wep_keylens[keyidx];
3947
3948   if (keylen == 0)
3949     return -1;
3950   if (wep_keys[keyidx] == NULL)
3951     return -1;
3952
3953   keylen+=3;  /* add in ICV bytes */
3954
3955   /* copy the rest of the key over from the designated key */
3956   memcpy(key+3, wep_keys[keyidx], wep_keylens[keyidx]);
3957
3958 #if 0
3959   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]);
3960 #endif
3961
3962   /* set up the RC4 state */
3963   for (i = 0; i < 256; i++)
3964     s[i] = i;
3965   j = 0;
3966   for (i = 0; i < 256; i++) {
3967     j = (j + s[i] + key[i % keylen]) & 0xff;
3968     SSWAP(i,j);
3969   }
3970
3971   /* Apply the RC4 to the data, update the CRC32 */
3972   cpos = buf+4;
3973   dpos = buf;
3974   crc = ~0;
3975   i = j = 0;
3976   for (k = 0; k < (len -8); k++) {
3977     i = (i+1) & 0xff;
3978     j = (j+s[i]) & 0xff;
3979     SSWAP(i,j);
3980 #if 0
3981     printf("%d -- %02x ", k, *dpos);
3982 #endif
3983     *dpos = *cpos++ ^ s[(s[i] + s[j]) & 0xff];
3984 #if 0
3985     printf("%02x\n", *dpos);
3986 #endif
3987     crc = crc32_ccitt_table[(crc ^ *dpos++) & 0xff] ^ (crc >> 8);
3988   }
3989   crc = ~crc;
3990
3991   /* now let's check the crc */
3992   c_crc[0] = crc;
3993   c_crc[1] = crc >> 8;
3994   c_crc[2] = crc >> 16;
3995   c_crc[3] = crc >> 24;
3996
3997   for (k = 0; k < 4; k++) {
3998     i = (i + 1) & 0xff;
3999     j = (j+s[i]) & 0xff;
4000     SSWAP(i,j);
4001 #if 0
4002     printf("-- %02x %02x\n", *dpos, c_crc[k]);
4003 #endif
4004     if ((*cpos++ ^ s[(s[i] + s[j]) & 0xff]) != c_crc[k])
4005       return -1; /* ICV mismatch */
4006   }
4007
4008   return 0;
4009 }
4010
4011 static void init_wepkeys(void) {
4012   const char *tmp;
4013   int i;
4014   GByteArray *bytes;
4015   gboolean res;
4016
4017 #ifdef USE_ENV
4018   guint8 *buf;
4019
4020   tmp = getenv("ETHEREAL_WEPKEYNUM");
4021   if (!tmp) {
4022     num_wepkeys = 0;
4023     return;
4024   }
4025   num_wepkeys = atoi(tmp);
4026 #else
4027   if (num_wepkeys > 4)
4028     num_wepkeys = 4;
4029 #endif
4030
4031   if (num_wepkeys < 1)
4032     return;
4033
4034   if (wep_keys)
4035     g_free(wep_keys);
4036
4037   if (wep_keylens)
4038     g_free(wep_keylens);
4039
4040   wep_keys = g_malloc(num_wepkeys * sizeof(guint8*));
4041   wep_keylens = g_malloc(num_wepkeys * sizeof(int));
4042   bytes = g_byte_array_new();
4043
4044   for (i = 0 ; i < num_wepkeys; i++) {
4045     wep_keys[i] = NULL;
4046     wep_keylens[i] = 0;
4047
4048 #ifdef USE_ENV
4049     buf=ep_alloc(128);
4050     g_snprintf(buf, 128, "ETHEREAL_WEPKEY%d", i+1);
4051     tmp = getenv(buf);
4052 #else
4053     tmp = wep_keystr[i];
4054 #endif
4055
4056     if (tmp) {
4057 #if 0
4058 #ifdef USE_ENV
4059       printf("%s -- %s\n", buf, tmp);
4060 #else
4061       printf("%d -- %s\n", i+1, tmp);
4062 #endif
4063 #endif
4064
4065       if (wep_keys[i]) {
4066         g_free(wep_keys[i]);
4067       }
4068
4069       res = hex_str_to_bytes(tmp, bytes, FALSE);
4070       if (res && bytes->len > 0) {
4071         if (bytes->len > 32) {
4072           bytes->len = 32;
4073         }
4074         wep_keys[i] = g_malloc(32 * sizeof(guint8));
4075         memset(wep_keys[i], 0, 32 * sizeof(guint8));
4076         memcpy(wep_keys[i], bytes->data, bytes->len * sizeof(guint8));
4077         wep_keylens[i] = bytes->len;
4078 #if 0
4079         printf("%d: %d bytes\n", i, bytes->len);
4080         printf("%d: %s\n", i, bytes_to_str(bytes->data, bytes->len));
4081 #endif
4082       } else {
4083 #if 0
4084         printf("res: %d  bytes->len: %d\n", res, bytes->len);
4085 #endif
4086         g_warning("Could not parse WEP key %d: %s", i + 1, tmp);
4087       }
4088     }
4089   }
4090   g_byte_array_free(bytes, TRUE);
4091 }
4092 /*
4093  * This code had been taken from AirSnort crack.c function classify()
4094  * Permission granted by snax <at> shmoo dot com
4095  * weak_iv - determine which key byte an iv is useful in resolving
4096  * parm     - p, pointer to the first byte of an IV
4097  * return   -  n - this IV is weak for byte n of a WEP key
4098  *            -1 - this IV is not weak for any key bytes
4099  *
4100  * This function tests for IVs that are known to satisfy the criteria
4101  * for a weak IV as specified in FMS section 7.1
4102  *
4103  */
4104 static int
4105 weak_iv(guchar *iv)
4106 {
4107         guchar sum, k;
4108
4109         if (iv[1] == 255 && iv[0] > 2 && iv[0] < 16) {
4110                 return iv[0] -3;
4111         }
4112
4113         sum = iv[0] + iv[1];
4114         if (sum == 1) {
4115                 if (iv[2] <= 0x0a) {
4116                         return iv[2] +2;
4117                 }
4118                 else if (iv[2] == 0xff){
4119                         return 0;
4120                 }
4121         }
4122         k = 0xfe - iv[2];
4123         if (sum == k  && (iv[2] >= 0xf2 && iv[2] <= 0xfe && iv[2] != 0xfd)){
4124                 return k;
4125         }
4126         return -1;
4127 }