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