Stephen Fisher:
[obnox/wireshark/wip.git] / epan / dissectors / packet-ieee80211.c
index 2dd6686e7ab8ff2f85e0da8e5782bbf4b47d98f7..18de9b6101ce7a37b8a7d3988e818ad7a98e757b 100644 (file)
@@ -5,8 +5,8 @@
  *
  * $Id$
  *
- * Ethereal - Network traffic analyzer
- * By Gerald Combs <gerald@ethereal.com>
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
  * Copyright 1998 Gerald Combs
  *
  * Copied from README.developer
 #include <stdio.h>
 #include <stdlib.h>
 
-#ifdef NEED_SNPRINTF_H
-# include "snprintf.h"
-#endif
-
 #include <string.h>
 #include <glib.h>
 #include <epan/bitswap.h>
 #include "packet-ipx.h"
 #include "packet-llc.h"
 #include "packet-ieee80211.h"
-#include "etypes.h"
+#include <epan/etypes.h>
+#include <epan/oui.h>
 #include <epan/crc32.h>
 #include <epan/tap.h>
+#include <epan/emem.h>
 
 #include <ctype.h>
 #include "isprint.h"
 
+#ifdef HAVE_AIRPCAP
+#include <airpcap.h>
+#else
+/* XXX - This is probably a bit much */
+#define MAX_ENCRYPTION_KEYS 64
+#endif
+
+#ifndef roundup2
+#define        roundup2(x, y)  (((x)+((y)-1))&(~((y)-1))) /* if y is powers of two */
+#endif
+
 /* Defragment fragmented 802.11 datagrams */
 static gboolean wlan_defragment = TRUE;
 
@@ -87,6 +96,11 @@ static GHashTable *wlan_fragment_table = NULL;
 static GHashTable *wlan_reassembled_table = NULL;
 
 /* Stuff for the WEP decoder */
+/* XXX - Instead of making the user specify the number of WEP keys manually,
+ * we may want to change the "WEP key count" option to a toggle that
+ * enables/disables WEP decryption, and automatically figure out how
+ * many keys we have by parsing the key list.
+ */
 static gint num_wepkeys = 0;
 static guint8 **wep_keys = NULL;
 static int *wep_keylens = NULL;
@@ -100,9 +114,9 @@ static int weak_iv(guchar *iv);
 /* When this is set, an unlimited number of WEP keys can be set in the
    environment:
 
-   ETHEREAL_WEPKEYNUM=##
-   ETHEREAL_WEPKEY1=aa:bb:cc:dd:...
-   ETHEREAL_WEPKEY2=aa:bab:cc:dd:ee:...
+   WIRESHARK_WEPKEYNUM=##
+   WIRESHARK_WEPKEY1=aa:bb:cc:dd:...
+   WIRESHARK_WEPKEY2=aa:bab:cc:dd:ee:...
 
    ... you get the idea.
 
@@ -110,7 +124,7 @@ static int weak_iv(guchar *iv);
  */
 
 #ifndef USE_ENV
-static char *wep_keystr[] = {NULL, NULL, NULL, NULL};
+static char *wep_keystr[MAX_ENCRYPTION_KEYS];
 #endif
 
 /* ************************************************************************* */
@@ -121,45 +135,120 @@ static char *wep_keystr[] = {NULL, NULL, NULL, NULL};
 /* ************************************************************************* */
 /*  Define some very useful macros that are used to analyze frame types etc. */
 /* ************************************************************************* */
-#define COMPOSE_FRAME_TYPE(x) (((x & 0x0C)<< 2)+((x & 0xF0) >> 4))     /* Create key to (sub)type */
-#define COOK_PROT_VERSION(x)  ((x) & 0x3)
-#define COOK_FRAME_TYPE(x)    (((x) & 0xC) >> 2)
-#define COOK_FRAME_SUBTYPE(x) (((x) & 0xF0) >> 4)
-#define COOK_ADDR_SELECTOR(x) ((x) & 0x300)
-#define COOK_ASSOC_ID(x)      ((x) & 0x3FFF)
-#define COOK_FRAGMENT_NUMBER(x) ((x) & 0x000F)
-#define COOK_SEQUENCE_NUMBER(x) (((x) & 0xFFF0) >> 4)
-#define COOK_QOS_PRIORITY(x)    ((x) & 0x0007)
-#define COOK_QOS_ACK_POLICY(x)  (((x) & 0x0060) >> 5)
-#define COOK_FLAGS(x)           (((x) & 0xFF00) >> 8)
-#define COOK_DS_STATUS(x)       ((x) & 0x3)
-#define COOK_WEP_KEY(x)       (((x) & 0xC0) >> 6)
 
-#define KEY_EXTIV              0x20
-#define EXTIV_LEN              8
+/*
+ * Extract the protocol version from the frame control field
+ */
+#define FCF_PROT_VERSION(x)  ((x) & 0x3)
+
+/*
+ * Extract the frame type from the frame control field.
+ */
+#define FCF_FRAME_TYPE(x)    (((x) & 0xC) >> 2)
 
+/*
+ * Extract the frame subtype from the frame control field.
+ */
+#define FCF_FRAME_SUBTYPE(x) (((x) & 0xF0) >> 4)
+
+/*
+ * Convert the frame type and subtype from the frame control field into
+ * one of the MGT_, CTRL_, or DATA_ values.
+ */
+#define COMPOSE_FRAME_TYPE(x) (((x & 0x0C)<< 2)+FCF_FRAME_SUBTYPE(x))  /* Create key to (sub)type */
+
+/*
+ * The subtype field of a data frame is, in effect, composed of 4 flag
+ * bits - CF-Ack, CF-Poll, Null (means the frame doesn't actually have
+ * any data), and QoS.
+ */
+#define DATA_FRAME_IS_CF_ACK(x)  ((x) & 0x01)
+#define DATA_FRAME_IS_CF_POLL(x) ((x) & 0x02)
+#define DATA_FRAME_IS_NULL(x)    ((x) & 0x04)
+#define DATA_FRAME_IS_QOS(x)     ((x) & 0x08)
+
+/*
+ * Extract the flags from the frame control field.
+ */
+#define FCF_FLAGS(x)           (((x) & 0xFF00) >> 8)
+
+/*
+ * Bits from the flags field.
+ */
 #define FLAG_TO_DS             0x01
 #define FLAG_FROM_DS           0x02
 #define FLAG_MORE_FRAGMENTS    0x04
 #define FLAG_RETRY             0x08
 #define FLAG_POWER_MGT         0x10
 #define FLAG_MORE_DATA         0x20
-#define FLAG_WEP               0x40
+#define FLAG_PROTECTED         0x40
 #define FLAG_ORDER             0x80
 
+/*
+ * Test bits in the flags field.
+ */
 #define IS_TO_DS(x)            ((x) & FLAG_TO_DS)
 #define IS_FROM_DS(x)          ((x) & FLAG_FROM_DS)
 #define HAVE_FRAGMENTS(x)      ((x) & FLAG_MORE_FRAGMENTS)
 #define IS_RETRY(x)            ((x) & FLAG_RETRY)
 #define POWER_MGT_STATUS(x)    ((x) & FLAG_POWER_MGT)
 #define HAS_MORE_DATA(x)       ((x) & FLAG_MORE_DATA)
-#define IS_WEP(x)              (!wlan_ignore_wep && ((x) & FLAG_WEP))
+#define IS_PROTECTED(x)        (!wlan_ignore_wep && ((x) & FLAG_PROTECTED))
 #define IS_STRICTLY_ORDERED(x) ((x) & FLAG_ORDER)
 
-#define MGT_RESERVED_RANGE(x)  (((x>=0x06)&&(x<=0x07))||((x>=0x0D)&&(x<=0x0F)))
-#define CTRL_RESERVED_RANGE(x) ((x>=0x10)&&(x<=0x19))
-#define DATA_RESERVED_RANGE(x) ((x>=0x28)&&(x<=0x2f))
-#define SPEC_RESERVED_RANGE(x) ((x>=0x30)&&(x<=0x3f))
+/*
+ * Extract subfields from the flags field.
+ */
+#define FLAGS_DS_STATUS(x)          ((x) & (FLAG_FROM_DS|FLAG_TO_DS))
+
+/*
+ * Extract an indication of the types of addresses in a data frame from
+ * the frame control field.
+ */
+#define FCF_ADDR_SELECTOR(x) ((x) & ((FLAG_TO_DS|FLAG_FROM_DS) << 8))
+
+#define DATA_ADDR_T1         0
+#define DATA_ADDR_T2         (FLAG_FROM_DS << 8)
+#define DATA_ADDR_T3         (FLAG_TO_DS << 8)
+#define DATA_ADDR_T4         ((FLAG_TO_DS|FLAG_FROM_DS) << 8)
+
+/*
+ * Extract the fragment number and sequence number from the sequence
+ * control field.
+ */
+#define SEQCTL_FRAGMENT_NUMBER(x) ((x) & 0x000F)
+#define SEQCTL_SEQUENCE_NUMBER(x) (((x) & 0xFFF0) >> 4)
+
+/*
+ * Extract subfields from the QoS control field.
+ */
+#define QOS_TID(x)           ((x) & 0x000F)
+#define QOS_PRIORITY(x)       ((x) & 0x0007)
+#define QOS_EOSP(x)          (((x) & 0x0010) >> 4) /* end of service period */
+#define QOS_ACK_POLICY(x)     (((x) & 0x0060) >> 5)
+#define QOS_FIELD_CONTENT(x)  (((x) & 0xFF00) >> 8)
+
+#define QOS_FLAG_EOSP          0x08
+
+/*
+ * Extract subfields from the result of QOS_FIELD_CONTENT().
+ */
+#define QOS_PS_BUF_STATE(x)    (((x) & 0x02) >> 1)
+#define QOS_PS_BUF_AC(x)       (((x) & 0x0C) >> 2)
+#define QOS_PS_BUF_LOAD(x)     (((x) & 0xF0) >> 4)
+
+/*
+ * Extract the association ID from the value in an association ID field.
+ */
+#define ASSOC_ID(x)             ((x) & 0x3FFF)
+
+/*
+ * Extract subfields from the key octet in WEP-encrypted frames.
+ */
+#define KEY_OCTET_WEP_KEY(x)    (((x) & 0xC0) >> 6)
+
+#define KEY_EXTIV              0x20
+#define EXTIV_LEN              8
 
 
 /* ************************************************************************* */
@@ -173,41 +262,53 @@ static char *wep_keystr[] = {NULL, NULL, NULL, NULL};
 #define DATA_LONG_HDR_LEN      30
 #define MGT_FRAME_HDR_LEN      24      /* Length of Managment frame-headers */
 
-#define MGT_ASSOC_REQ        0x00      /* Management - association request        */
-#define MGT_ASSOC_RESP       0x01      /* Management - association response       */
-#define MGT_REASSOC_REQ      0x02      /* Management - reassociation request      */
-#define MGT_REASSOC_RESP     0x03      /* Management - reassociation response     */
-#define MGT_PROBE_REQ        0x04      /* Management - Probe request              */
-#define MGT_PROBE_RESP       0x05      /* Management - Probe response             */
-#define MGT_BEACON           0x08      /* Management - Beacon frame               */
-#define MGT_ATIM             0x09      /* Management - ATIM                       */
-#define MGT_DISASS           0x0A      /* Management - Disassociation             */
-#define MGT_AUTHENTICATION   0x0B      /* Management - Authentication             */
-#define MGT_DEAUTHENTICATION 0x0C      /* Management - Deauthentication           */
-#define MGT_ACTION           0x0D      /* Management - Action */
-
-#define CTRL_PS_POLL         0x1A      /* Control - power-save poll               */
-#define CTRL_RTS             0x1B      /* Control - request to send               */
-#define CTRL_CTS             0x1C      /* Control - clear to send                 */
-#define CTRL_ACKNOWLEDGEMENT 0x1D      /* Control - acknowledgement               */
-#define CTRL_CFP_END         0x1E      /* Control - contention-free period end    */
-#define CTRL_CFP_ENDACK      0x1F      /* Control - contention-free period end/ack */
-
-#define DATA                 0x20      /* Data - Data                             */
-#define DATA_CF_ACK          0x21      /* Data - Data + CF acknowledge            */
-#define DATA_CF_POLL         0x22      /* Data - Data + CF poll                   */
-#define DATA_CF_ACK_POLL     0x23      /* Data - Data + CF acknowledge + CF poll  */
-#define DATA_NULL_FUNCTION   0x24      /* Data - Null function (no data)          */
-#define DATA_CF_ACK_NOD      0x25      /* Data - CF ack (no data)                 */
-#define DATA_CF_POLL_NOD     0x26       /* Data - Data + CF poll (No data)         */
-#define DATA_CF_ACK_POLL_NOD 0x27      /* Data - CF ack + CF poll (no data)       */
-#define DATA_QOS_DATA        0x28      /* Data - QoS Data                         */
-#define DATA_QOS_NULL        0x2c      /* Data - QoS Null                         */
+/*
+ * COMPOSE_FRAME_TYPE() values for management frames.
+ */
+#define MGT_ASSOC_REQ        0x00      /* association request        */
+#define MGT_ASSOC_RESP       0x01      /* association response       */
+#define MGT_REASSOC_REQ      0x02      /* reassociation request      */
+#define MGT_REASSOC_RESP     0x03      /* reassociation response     */
+#define MGT_PROBE_REQ        0x04      /* Probe request              */
+#define MGT_PROBE_RESP       0x05      /* Probe response             */
+#define MGT_BEACON           0x08      /* Beacon frame               */
+#define MGT_ATIM             0x09      /* ATIM                       */
+#define MGT_DISASS           0x0A      /* Disassociation             */
+#define MGT_AUTHENTICATION   0x0B      /* Authentication             */
+#define MGT_DEAUTHENTICATION 0x0C      /* Deauthentication           */
+#define MGT_ACTION           0x0D      /* Action */
 
-#define DATA_ADDR_T1         0
-#define DATA_ADDR_T2         (FLAG_FROM_DS << 8)
-#define DATA_ADDR_T3         (FLAG_TO_DS << 8)
-#define DATA_ADDR_T4         ((FLAG_TO_DS|FLAG_FROM_DS) << 8)
+/*
+ * COMPOSE_FRAME_TYPE() values for control frames.
+ */
+#define CTRL_BLOCK_ACK_REQ   0x18      /* Block ack Request                */
+#define CTRL_BLOCK_ACK      0x19       /* Block ack                        */
+#define CTRL_PS_POLL         0x1A      /* power-save poll               */
+#define CTRL_RTS             0x1B      /* request to send               */
+#define CTRL_CTS             0x1C      /* clear to send                 */
+#define CTRL_ACKNOWLEDGEMENT 0x1D      /* acknowledgement               */
+#define CTRL_CFP_END         0x1E      /* contention-free period end    */
+#define CTRL_CFP_ENDACK      0x1F      /* contention-free period end/ack */
+
+/*
+ * COMPOSE_FRAME_TYPE() values for data frames.
+ */
+#define DATA                        0x20       /* Data                       */
+#define DATA_CF_ACK                 0x21       /* Data + CF-Ack              */
+#define DATA_CF_POLL                0x22       /* Data + CF-Poll             */
+#define DATA_CF_ACK_POLL            0x23       /* Data + CF-Ack + CF-Poll    */
+#define DATA_NULL_FUNCTION          0x24       /* Null function (no data)    */
+#define DATA_CF_ACK_NOD             0x25       /* CF-Ack (no data)           */
+#define DATA_CF_POLL_NOD            0x26       /* CF-Poll (No data)          */
+#define DATA_CF_ACK_POLL_NOD        0x27       /* CF-Ack + CF-Poll (no data) */
+
+#define DATA_QOS_DATA               0x28       /* QoS Data                   */
+#define DATA_QOS_DATA_CF_ACK        0x29       /* QoS Data + CF-Ack          */
+#define DATA_QOS_DATA_CF_POLL       0x2A       /* QoS Data + CF-Poll             */
+#define DATA_QOS_DATA_CF_ACK_POLL   0x2B       /* QoS Data + CF-Ack + CF-Poll    */
+#define DATA_QOS_NULL              0x2C        /* QoS Null                       */
+#define DATA_QOS_CF_POLL_NOD       0x2E        /* QoS CF-Poll (No Data)                  */
+#define DATA_QOS_CF_ACK_POLL_NOD    0x2F       /* QoS CF-Ack + CF-Poll (No Data) */
 
 
 /* ************************************************************************* */
@@ -251,14 +352,35 @@ static char *wep_keystr[] = {NULL, NULL, NULL, NULL};
 #define TAG_COUNTRY_INFO         0x07
 #define TAG_FH_HOPPING_PARAMETER 0x08
 #define TAG_FH_HOPPING_TABLE     0x09
+#define TAG_REQUEST             0x0A
+#define TAG_QBSS_LOAD           0x0B
+#define TAG_EDCA_PARAM_SET      0x0C
+#define TAG_TRAF_SPEC           0x0D
+#define TAG_TRAF_CLASS          0x0E
+#define TAG_SCHEDULE            0x0F
 #define TAG_CHALLENGE_TEXT       0x10
+#define TAG_POWER_CONSTRAINT    0x20
+#define TAG_POWER_CAPABILITY    0x21
+#define TAG_TPC_REQUEST                 0x22
+#define TAG_TPC_REPORT          0x23
+#define TAG_SUPPORTED_CHANNELS  0x24
+#define TAG_CHANNEL_SWITCH_ANN  0x25
+#define TAG_MEASURE_REQ                 0x26
+#define TAG_MEASURE_REP                 0x27
+#define TAG_QUIET               0x28
+#define TAG_IBSS_DFS            0x29
 #define TAG_ERP_INFO             0x2A
+#define TAG_TS_DELAY            0x2B
+#define TAG_TCLAS_PROCESS       0x2C
+#define TAG_QOS_CAPABILITY      0x2E
 #define TAG_ERP_INFO_OLD         0x2F  /* IEEE Std 802.11g/D4.0 */
 #define TAG_RSN_IE               0x30
 #define TAG_EXT_SUPP_RATES       0x32
+#define TAG_AGERE_PROPRIETARY   0x80
 #define TAG_CISCO_UNKNOWN_1     0x85   /* Cisco Compatible eXtensions? */
 #define TAG_CISCO_UNKNOWN_2     0x88   /* Cisco Compatible eXtensions? */
 #define TAG_VENDOR_SPECIFIC_IE  0xDD
+#define TAG_SYMBOL_PROPRIETARY  0xAD
 
 #define WPA_OUI        "\x00\x50\xF2"
 #define RSN_OUI "\x00\x0F\xAC"
@@ -282,22 +404,31 @@ static const value_string frame_type_subtype_vals[] = {
        {MGT_AUTHENTICATION,   "Authentication"},
        {MGT_DEAUTHENTICATION, "Deauthentication"},
        {MGT_ACTION,           "Action"},
+
+       {CTRL_BLOCK_ACK_REQ,   "802.11 Block Ack Req"},
+       {CTRL_BLOCK_ACK,       "802.11 Block Ack"},
        {CTRL_PS_POLL,         "Power-Save poll"},
        {CTRL_RTS,             "Request-to-send"},
        {CTRL_CTS,             "Clear-to-send"},
        {CTRL_ACKNOWLEDGEMENT, "Acknowledgement"},
        {CTRL_CFP_END,         "CF-End (Control-frame)"},
        {CTRL_CFP_ENDACK,      "CF-End + CF-Ack (Control-frame)"},
+
        {DATA,                 "Data"},
-       {DATA_CF_ACK,          "Data + CF-Acknowledgement"},
+       {DATA_CF_ACK,          "Data + CF-Ack"},
        {DATA_CF_POLL,         "Data + CF-Poll"},
-       {DATA_CF_ACK_POLL,     "Data + CF-Acknowledgement/Poll"},
+       {DATA_CF_ACK_POLL,     "Data + CF-Ack + CF-Poll"},
        {DATA_NULL_FUNCTION,   "Null function (No data)"},
-       {DATA_CF_ACK_NOD,      "Data + Acknowledgement (No data)"},
-       {DATA_CF_POLL_NOD,     "Data + CF-Poll (No data)"},
-       {DATA_CF_ACK_POLL_NOD, "Data + CF-Acknowledgement/Poll (No data)"},
+       {DATA_CF_ACK_NOD,      "Acknowledgement (No data)"},
+       {DATA_CF_POLL_NOD,     "CF-Poll (No data)"},
+       {DATA_CF_ACK_POLL_NOD, "CF-Ack/Poll (No data)"},
        {DATA_QOS_DATA,        "QoS Data"},
-       {DATA_QOS_NULL,        "QoS Null (No data)"},
+       {DATA_QOS_DATA_CF_ACK,  "QoS Data + CF-Acknowledgment"},
+       {DATA_QOS_DATA_CF_POLL, "QoS Data + CF-Poll"},
+       {DATA_QOS_DATA_CF_ACK_POLL, "QoS Data + CF-Ack + CF-Poll"},
+       {DATA_QOS_NULL,        "QoS Null function (No data)"},
+       {DATA_QOS_CF_POLL_NOD,  "QoS CF-Poll (No Data)"},
+       {DATA_QOS_CF_ACK_POLL_NOD,  "QoS CF-Ack + CF-Poll (No data)"},
        {0,                    NULL}
 };
 
@@ -339,7 +470,21 @@ static const char *wme_acs[4] = {
        "Voice",
 };
 
+
+#define CAT_SPECTRUM_MGMT      0
+#define CAT_QOS                        1
+#define CAT_DLS                        2
+#define CAT_BLOCK_ACK          3
+#define CAT_MGMT_NOTIFICATION  17
+
+#define SM_ACTION_MEASUREMENT_REQUEST  0
+#define SM_ACTION_MEASUREMENT_REPORT   1
+#define SM_ACTION_TPC_REQUEST          2
+#define SM_ACTION_TPC_REPORT           3
+#define SM_ACTION_CHAN_SWITCH_ANNC     4
+
 static int proto_wlan = -1;
+static packet_info * g_pinfo;
 
 /* ************************************************************************* */
 /*                Header field info values for radio information             */
@@ -366,7 +511,7 @@ static int hf_fc_more_frag = -1;
 static int hf_fc_retry = -1;
 static int hf_fc_pwr_mgt = -1;
 static int hf_fc_more_data = -1;
-static int hf_fc_wep = -1;
+static int hf_fc_protected = -1;
 static int hf_fc_order = -1;
 
 
@@ -394,6 +539,16 @@ static int hf_addr = -1;   /* Source or destination address subfield */
 /* ************************************************************************* */
 static int hf_qos_priority = -1;
 static int hf_qos_ack_policy = -1;
+static int hf_qos_eosp = -1;
+static int hf_qos_field_content = -1;
+/*static int hf_qos_txop_limit = -1;*/
+/*     FIXME: hf_ values not defined
+static int hf_qos_buf_state = -1;
+static int hf_qos_buf_ac = -1;
+static int hf_qos_buf_load = -1;
+*/
+/*static int hf_qos_txop_dur_req = -1;
+static int hf_qos_queue_size = -1;*/
 
 /* ************************************************************************* */
 /*                Header values for sequence number field                    */
@@ -452,6 +607,10 @@ static int ff_cf_pbcc = -1;
 static int ff_cf_agility = -1;
 static int ff_short_slot_time = -1;
 static int ff_dsss_ofdm = -1;
+static int ff_cf_spec_man = -1;
+static int ff_cf_apsd = -1;
+static int ff_cf_del_blk_ack = -1;
+static int ff_cf_imm_blk_ack = -1;
 
 /* ************************************************************************* */
 /*                       Tagged value format fields                          */
@@ -459,6 +618,8 @@ static int ff_dsss_ofdm = -1;
 static int tag_number = -1;
 static int tag_length = -1;
 static int tag_interpretation = -1;
+static int tag_oui = -1;
+
 
 static int tim_length = -1;
 static int tim_dtim_count = -1;
@@ -482,6 +643,24 @@ static int rsn_cap_no_pairwise = -1;
 static int rsn_cap_ptksa_replay_counter = -1;
 static int rsn_cap_gtksa_replay_counter = -1;
 
+static int hf_aironet_ie_type = -1;
+static int hf_aironet_ie_version = -1;
+static int hf_aironet_ie_data = -1;
+static int hf_aironet_ie_qos_unk1 = -1;
+static int hf_aironet_ie_qos_paramset = -1;
+static int hf_aironet_ie_qos_val = -1;
+
+/*QBSS - Version 1,2,802.11e*/
+
+static int hf_qbss2_cal = -1;
+static int hf_qbss2_gl = -1;
+static int hf_qbss_cu = -1;
+static int hf_qbss2_cu = -1;
+static int hf_qbss_scount = -1;
+static int hf_qbss2_scount = -1;
+static int hf_qbss_version = -1;
+static int hf_qbss_adc = -1;
+
 /* ************************************************************************* */
 /*                               Protocol trees                              */
 /* ************************************************************************* */
@@ -496,6 +675,7 @@ static gint ett_80211_mgt = -1;
 static gint ett_fixed_parameters = -1;
 static gint ett_tagged_parameters = -1;
 static gint ett_qos_parameters = -1;
+static gint ett_qos_ps_buf_state = -1;
 static gint ett_wep_parameters = -1;
 
 static gint ett_rsn_cap_tree = -1;
@@ -531,7 +711,7 @@ find_header_length (guint16 fcf)
 {
   int len;
 
-  switch (COOK_FRAME_TYPE (fcf)) {
+  switch (FCF_FRAME_TYPE (fcf)) {
 
   case MGT_FRAME:
     return MGT_FRAME_HDR_LEN;
@@ -547,22 +727,20 @@ find_header_length (guint16 fcf)
     case CTRL_PS_POLL:
     case CTRL_CFP_END:
     case CTRL_CFP_ENDACK:
+    case CTRL_BLOCK_ACK_REQ:
+    case CTRL_BLOCK_ACK:
       return 16;
     }
     return 4;  /* XXX */
 
   case DATA_FRAME:
-    len = (COOK_ADDR_SELECTOR(fcf) == DATA_ADDR_T4) ? DATA_LONG_HDR_LEN :
+    len = (FCF_ADDR_SELECTOR(fcf) == DATA_ADDR_T4) ? DATA_LONG_HDR_LEN :
                                                      DATA_SHORT_HDR_LEN;
-    switch (COMPOSE_FRAME_TYPE (fcf)) {
-
-    case DATA_QOS_DATA:
-    case DATA_QOS_NULL:
+    if (DATA_FRAME_IS_QOS(COMPOSE_FRAME_TYPE(fcf)))
       return len + 2;
-
-    default:
+    else
       return len;
-    }
+
   default:
     return 4;  /* XXX */
   }
@@ -574,7 +752,8 @@ find_header_length (guint16 fcf)
 /* ************************************************************************* */
 static void
 capture_ieee80211_common (const guchar * pd, int offset, int len,
-                         packet_counts * ld, gboolean fixed_length_header)
+                         packet_counts * ld, gboolean fixed_length_header,
+                         gboolean datapad)
 {
   guint16 fcf, hdr_length;
 
@@ -583,9 +762,9 @@ capture_ieee80211_common (const guchar * pd, int offset, int len,
     return;
   }
 
-  fcf = pletohs (&pd[0]);
+  fcf = pletohs (&pd[offset]);
 
-  if (IS_WEP(COOK_FLAGS(fcf)))
+  if (IS_PROTECTED(FCF_FLAGS(fcf)))
     {
       ld->other++;
       return;
@@ -603,6 +782,8 @@ capture_ieee80211_common (const guchar * pd, int offset, int len,
         hdr_length = DATA_LONG_HDR_LEN;
       else
         hdr_length = find_header_length (fcf);
+      if (datapad)
+        hdr_length = roundup2(hdr_length, 4);
       /* I guess some bridges take Netware Ethernet_802_3 frames,
          which are 802.3 frames (with a length field rather than
          a type field, but with no 802.2 header in the payload),
@@ -638,7 +819,17 @@ capture_ieee80211_common (const guchar * pd, int offset, int len,
 void
 capture_ieee80211 (const guchar * pd, int offset, int len, packet_counts * ld)
 {
-  capture_ieee80211_common (pd, offset, len, ld, FALSE);
+  capture_ieee80211_common (pd, offset, len, ld, FALSE, FALSE);
+}
+
+/*
+ * Handle 802.11 with a variable-length link-layer header and data padding.
+ */
+void
+capture_ieee80211_datapad (const guchar * pd, int offset, int len,
+                           packet_counts * ld)
+{
+  capture_ieee80211_common (pd, offset, len, ld, FALSE, TRUE);
 }
 
 /*
@@ -648,7 +839,7 @@ capture_ieee80211 (const guchar * pd, int offset, int len, packet_counts * ld)
 void
 capture_ieee80211_fixed (const guchar * pd, int offset, int len, packet_counts * ld)
 {
-  capture_ieee80211_common (pd, offset, len, ld, TRUE);
+  capture_ieee80211_common (pd, offset, len, ld, TRUE, FALSE);
 }
 
 
@@ -706,7 +897,7 @@ add_fixed_field (proto_tree * tree, tvbuff_t * tvb, int offset, int lfcode)
     case FIELD_TIMESTAMP:
       dataptr = tvb_get_ptr (tvb, offset, 8);
       memset (out_buff, 0, SHORT_STR);
-      snprintf (out_buff, SHORT_STR, "0x%02X%02X%02X%02X%02X%02X%02X%02X",
+      g_snprintf (out_buff, SHORT_STR, "0x%02X%02X%02X%02X%02X%02X%02X%02X",
                dataptr[7],
                dataptr[6],
                dataptr[5],
@@ -720,11 +911,15 @@ add_fixed_field (proto_tree * tree, tvbuff_t * tvb, int offset, int lfcode)
       break;
 
     case FIELD_BEACON_INTERVAL:
-      temp_double = (double) tvb_get_letohs (tvb, offset);
+      capability = tvb_get_letohs (tvb, offset);
+      temp_double = (double)capability;
       temp_double = temp_double * 1024 / 1000000;
       proto_tree_add_double_format (tree, ff_beacon_interval, tvb, offset, 2,
                                    temp_double,"Beacon Interval: %f [Seconds]",
                                    temp_double);
+      if (check_col (g_pinfo->cinfo, COL_INFO)) {
+          col_append_fstr(g_pinfo->cinfo, COL_INFO, ",BI=%d", capability);
+      }
       break;
 
 
@@ -756,10 +951,18 @@ add_fixed_field (proto_tree * tree, tvbuff_t * tvb, int offset, int lfcode)
                              capability);
       proto_tree_add_boolean (cap_tree, ff_cf_agility, tvb, offset, 2,
                              capability);
+      proto_tree_add_boolean (cap_tree, ff_cf_spec_man, tvb, offset, 2,
+                             capability);
       proto_tree_add_boolean (cap_tree, ff_short_slot_time, tvb, offset, 2,
                              capability);
+      proto_tree_add_boolean (cap_tree, ff_cf_apsd, tvb, offset, 2,
+                             capability);
       proto_tree_add_boolean (cap_tree, ff_dsss_ofdm, tvb, offset, 2,
                              capability);
+      proto_tree_add_boolean (cap_tree, ff_cf_del_blk_ack, tvb, offset, 2,
+                             capability);
+      proto_tree_add_boolean (cap_tree, ff_cf_imm_blk_ack, tvb, offset, 2,
+                             capability);
       break;
 
     case FIELD_AUTH_ALG:
@@ -783,8 +986,8 @@ add_fixed_field (proto_tree * tree, tvbuff_t * tvb, int offset, int lfcode)
       break;
 
     case FIELD_ASSOC_ID:
-      proto_tree_add_uint(tree, ff_assoc_id, tvb, offset, 2, 
-                         COOK_ASSOC_ID(tvb_get_letohs(tvb,offset)));
+      proto_tree_add_uint(tree, ff_assoc_id, tvb, offset, 2,
+                         ASSOC_ID(tvb_get_letohs(tvb,offset)));
       /* proto_tree_add_item (tree, ff_assoc_id, tvb, offset, 2, TRUE); */
       break;
 
@@ -814,7 +1017,7 @@ add_fixed_field (proto_tree * tree, tvbuff_t * tvb, int offset, int lfcode)
     }
 }
 
-static char *wpa_cipher_str[] = 
+static const char *wpa_cipher_str[] =
 {
   "NONE",
   "WEP (40-bit)",
@@ -824,7 +1027,7 @@ static char *wpa_cipher_str[] =
   "WEP (104-bit)",
 };
 
-static char *
+static const char *
 wpa_cipher_idx2str(guint idx)
 {
   if (idx < sizeof(wpa_cipher_str)/sizeof(wpa_cipher_str[0]))
@@ -832,14 +1035,14 @@ wpa_cipher_idx2str(guint idx)
   return "UNKNOWN";
 }
 
-static char *wpa_keymgmt_str[] = 
+static const char *wpa_keymgmt_str[] =
 {
   "NONE",
   "WPA",
   "PSK",
 };
 
-static char *
+static const char *
 wpa_keymgmt_idx2str(guint idx)
 {
   if (idx < sizeof(wpa_keymgmt_str)/sizeof(wpa_keymgmt_str[0]))
@@ -847,17 +1050,17 @@ wpa_keymgmt_idx2str(guint idx)
   return "UNKNOWN";
 }
 
-static void 
-dissect_vendor_specific_ie(proto_tree * tree, tvbuff_t * tvb, int offset,
-               guint32 tag_len, const guint8 *tag_val)
+static void
+dissect_vendor_ie_wpawme(proto_tree * ietree, proto_tree * tree, tvbuff_t * tvb,
+       int offset, guint32 tag_len, const guint8 *tag_val)
 {
       guint32 tag_val_off = 0;
-      char out_buff[SHORT_STR], *pos;
+      char out_buff[SHORT_STR];
       guint i;
-       
+
       /* Wi-Fi Protected Access (WPA) Information Element */
       if (tag_val_off + 6 <= tag_len && !memcmp(tag_val, WPA_OUI"\x01", 4)) {
-        snprintf(out_buff, SHORT_STR, "WPA IE, type %u, version %u",
+        g_snprintf(out_buff, SHORT_STR, "WPA IE, type %u, version %u",
                   tag_val[tag_val_off + 3], pletohs(&tag_val[tag_val_off + 4]));
         proto_tree_add_string(tree, tag_interpretation, tvb, offset, 6, out_buff);
         offset += 6;
@@ -865,14 +1068,14 @@ dissect_vendor_specific_ie(proto_tree * tree, tvbuff_t * tvb, int offset,
         if (tag_val_off + 4 <= tag_len) {
           /* multicast cipher suite */
           if (!memcmp(&tag_val[tag_val_off], WPA_OUI, 3)) {
-            snprintf(out_buff, SHORT_STR, "Multicast cipher suite: %s", 
+            g_snprintf(out_buff, SHORT_STR, "Multicast cipher suite: %s",
                       wpa_cipher_idx2str(tag_val[tag_val_off + 3]));
             proto_tree_add_string(tree, tag_interpretation, tvb, offset, 4, out_buff);
             offset += 4;
             tag_val_off += 4;
             /* unicast cipher suites */
             if (tag_val_off + 2 <= tag_len) {
-              snprintf(out_buff, SHORT_STR, "# of unicast cipher suites: %u",
+              g_snprintf(out_buff, SHORT_STR, "# of unicast cipher suites: %u",
                         pletohs(tag_val + tag_val_off));
               proto_tree_add_string(tree, tag_interpretation, tvb, offset, 2, out_buff);
               offset += 2;
@@ -880,7 +1083,7 @@ dissect_vendor_specific_ie(proto_tree * tree, tvbuff_t * tvb, int offset,
               i = 1;
               while (tag_val_off + 4 <= tag_len) {
                 if (!memcmp(&tag_val[tag_val_off], WPA_OUI, 3)) {
-                  snprintf(out_buff, SHORT_STR, "Unicast cipher suite %u: %s", 
+                  g_snprintf(out_buff, SHORT_STR, "Unicast cipher suite %u: %s",
                             i, wpa_cipher_idx2str(tag_val[tag_val_off + 3]));
                   proto_tree_add_string(tree, tag_interpretation, tvb, offset, 4, out_buff);
                   offset += 4;
@@ -892,7 +1095,7 @@ dissect_vendor_specific_ie(proto_tree * tree, tvbuff_t * tvb, int offset,
               }
              /* authenticated key management suites */
               if (tag_val_off + 2 <= tag_len) {
-                snprintf(out_buff, SHORT_STR, "# of auth key management suites: %u",
+                g_snprintf(out_buff, SHORT_STR, "# of auth key management suites: %u",
                           pletohs(tag_val + tag_val_off));
                 proto_tree_add_string(tree, tag_interpretation, tvb, offset, 2, out_buff);
                 offset += 2;
@@ -900,7 +1103,7 @@ dissect_vendor_specific_ie(proto_tree * tree, tvbuff_t * tvb, int offset,
                 i = 1;
                 while (tag_val_off + 4 <= tag_len) {
                   if (!memcmp(&tag_val[tag_val_off], WPA_OUI, 3)) {
-                    snprintf(out_buff, SHORT_STR, "auth key management suite %u: %s", 
+                    g_snprintf(out_buff, SHORT_STR, "auth key management suite %u: %s",
                               i, wpa_keymgmt_idx2str(tag_val[tag_val_off + 3]));
                     proto_tree_add_string(tree, tag_interpretation, tvb, offset, 4, out_buff);
                     offset += 4;
@@ -917,22 +1120,24 @@ dissect_vendor_specific_ie(proto_tree * tree, tvbuff_t * tvb, int offset,
         if (tag_val_off < tag_len)
           proto_tree_add_string(tree, tag_interpretation, tvb,
                                  offset, tag_len - tag_val_off, "Not interpreted");
+       proto_item_append_text(ietree, ": WPA");
       } else if (tag_val_off + 7 <= tag_len && !memcmp(tag_val, WME_OUI"\x02\x00", 5)) {
       /* Wireless Multimedia Enhancements (WME) Information Element */
-        snprintf(out_buff, SHORT_STR, "WME IE: type %u, subtype %u, version %u, parameter set %u",
+        g_snprintf(out_buff, SHORT_STR, "WME IE: type %u, subtype %u, version %u, parameter set %u",
                 tag_val[tag_val_off + 3], tag_val[tag_val_off + 4], tag_val[tag_val_off + 5],
                 tag_val[tag_val_off + 6]);
         proto_tree_add_string(tree, tag_interpretation, tvb, offset, 7, out_buff);
+       proto_item_append_text(ietree, ": WME");
       } else if (tag_val_off + 24 <= tag_len && !memcmp(tag_val, WME_OUI"\x02\x01", 5)) {
       /* Wireless Multimedia Enhancements (WME) Parameter Element */
-        snprintf(out_buff, SHORT_STR, "WME PE: type %u, subtype %u, version %u, parameter set %u",
+        g_snprintf(out_buff, SHORT_STR, "WME PE: type %u, subtype %u, version %u, parameter set %u",
                 tag_val[tag_val_off + 3], tag_val[tag_val_off + 4], tag_val[tag_val_off + 5],
                 tag_val[tag_val_off + 6]);
         proto_tree_add_string(tree, tag_interpretation, tvb, offset, 7, out_buff);
        offset += 8;
        tag_val_off += 8;
        for (i = 0; i < 4; i++) {
-         snprintf(out_buff, SHORT_STR, "WME AC Parameters: ACI %u (%s), Admission Control %sMandatory, AIFSN %u, ECWmin %u, ECWmax %u, TXOP %u",
+         g_snprintf(out_buff, SHORT_STR, "WME AC Parameters: ACI %u (%s), Admission Control %sMandatory, AIFSN %u, ECWmin %u, ECWmax %u, TXOP %u",
                   (tag_val[tag_val_off] & 0x60) >> 5,
                   wme_acs[(tag_val[tag_val_off] & 0x60) >> 5],
                   (tag_val[tag_val_off] & 0x10) ? "" : "not ",
@@ -944,6 +1149,7 @@ dissect_vendor_specific_ie(proto_tree * tree, tvbuff_t * tvb, int offset,
          offset += 4;
          tag_val_off += 4;
        }
+       proto_item_append_text(ietree, ": WME");
       } else if (tag_val_off + 56 <= tag_len && !memcmp(tag_val, WME_OUI"\x02\x02", 5)) {
       /* Wireless Multimedia Enhancements (WME) TSPEC Element */
        guint16 ts_info, msdu_size, surplus_bandwidth;
@@ -963,14 +1169,14 @@ dissect_vendor_specific_ie(proto_tree * tree, tvbuff_t * tvb, int offset,
        };
        const char *field;
 
-        snprintf(out_buff, SHORT_STR, "WME TSPEC: type %u, subtype %u, version %u",
+        g_snprintf(out_buff, SHORT_STR, "WME TSPEC: type %u, subtype %u, version %u",
                 tag_val[tag_val_off + 3], tag_val[tag_val_off + 4], tag_val[tag_val_off + 5]);
         proto_tree_add_string(tree, tag_interpretation, tvb, offset, 6, out_buff);
        offset += 6;
        tag_val_off += 6;
 
        ts_info = tvb_get_letohs(tvb, offset);
-       snprintf(out_buff, SHORT_STR, "WME TS Info: Priority %u (%s) (%s), Contention-based access %sset, %s",
+       g_snprintf(out_buff, SHORT_STR, "WME TS Info: Priority %u (%s) (%s), Contention-based access %sset, %s",
                 (ts_info >> 11) & 0x7, qos_tags[(ts_info >> 11) & 0x7], qos_acs[(ts_info >> 11) & 0x7],
                 (ts_info & 0x0080) ? "" : "not ",
                 direction[(ts_info >> 5) & 0x3]);
@@ -979,19 +1185,19 @@ dissect_vendor_specific_ie(proto_tree * tree, tvbuff_t * tvb, int offset,
        tag_val_off += 2;
 
        msdu_size = tvb_get_letohs(tvb, offset);
-       snprintf(out_buff, SHORT_STR, "WME TSPEC: %s MSDU Size %u",
+       g_snprintf(out_buff, SHORT_STR, "WME TSPEC: %s MSDU Size %u",
                 (msdu_size & 0x8000) ? "Fixed" : "Nominal", msdu_size & 0x7fff);
        proto_tree_add_string(tree, tag_interpretation, tvb, offset, 2, out_buff);
        offset += 2;
        tag_val_off += 2;
 
-       snprintf(out_buff, SHORT_STR, "WME TSPEC: Maximum MSDU Size %u", tvb_get_letohs(tvb, offset));
+       g_snprintf(out_buff, SHORT_STR, "WME TSPEC: Maximum MSDU Size %u", tvb_get_letohs(tvb, offset));
        proto_tree_add_string(tree, tag_interpretation, tvb, offset, 2, out_buff);
        offset += 2;
        tag_val_off += 2;
 
        while ((field = val_to_str(tag_val_off, fields, "Unknown"))) {
-         snprintf(out_buff, SHORT_STR, "WME TSPEC: %s %u", field, tvb_get_letohl(tvb, offset));
+         g_snprintf(out_buff, SHORT_STR, "WME TSPEC: %s %u", field, tvb_get_letohl(tvb, offset));
          proto_tree_add_string(tree, tag_interpretation, tvb, offset, 4, out_buff);
          offset += 4;
          tag_val_off += 4;
@@ -1000,38 +1206,123 @@ dissect_vendor_specific_ie(proto_tree * tree, tvbuff_t * tvb, int offset,
        }
 
        surplus_bandwidth = tvb_get_letohs(tvb, offset);
-       snprintf(out_buff, SHORT_STR, "WME TSPEC: Surplus Bandwidth Allowance Factor %u.%u",
+       g_snprintf(out_buff, SHORT_STR, "WME TSPEC: Surplus Bandwidth Allowance Factor %u.%u",
                 (surplus_bandwidth >> 13) & 0x7, (surplus_bandwidth & 0x1fff));
        offset += 2;
        tag_val_off += 2;
 
-       snprintf(out_buff, SHORT_STR, "WME TSPEC: Medium Time %u", tvb_get_letohs(tvb, offset));
+       g_snprintf(out_buff, SHORT_STR, "WME TSPEC: Medium Time %u", tvb_get_letohs(tvb, offset));
        proto_tree_add_string(tree, tag_interpretation, tvb, offset, 2, out_buff);
        offset += 2;
-       tag_val_off += 2;                
-      } else if (tag_val_off + 4 <= tag_len && !memcmp(tag_val, RSN_OUI"\x04", 4)) {
-       /* IEEE 802.11i / Key Data Encapsulation / Data Type=4 - PMKID.
-        * This is only used within EAPOL-Key frame Key Data. */
-       pos = out_buff;
-       pos += snprintf(pos, out_buff + SHORT_STR - pos, "RSN PMKID: ");
-       if (tag_len - 4 != PMKID_LEN) {
-         pos += snprintf(pos, out_buff + SHORT_STR - pos,
-                         "(invalid PMKID len=%d, expected 16) ", tag_len - 4);
+       tag_val_off += 2;
+       proto_item_append_text(ietree, ": WME");
+      }
+}
+
+static void
+dissect_vendor_ie_rsn(proto_tree * ietree, proto_tree * tree, tvbuff_t * tvb,
+       int offset, guint32 tag_len, const guint8 *tag_val)
+{
+       guint32 tag_val_off = 0;
+       char out_buff[SHORT_STR], *pos;
+       guint i;
+
+       if (tag_val_off + 4 <= tag_len && !memcmp(tag_val, RSN_OUI"\x04", 4)) {
+               /* IEEE 802.11i / Key Data Encapsulation / Data Type=4 - PMKID.
+                * This is only used within EAPOL-Key frame Key Data. */
+               pos = out_buff;
+               pos += g_snprintf(pos, out_buff + SHORT_STR - pos, "RSN PMKID: ");
+               if (tag_len - 4 != PMKID_LEN) {
+                       pos += g_snprintf(pos, out_buff + SHORT_STR - pos,
+                               "(invalid PMKID len=%d, expected 16) ", tag_len - 4);
+               }
+               for (i = 0; i < tag_len - 4; i++) {
+                       pos += g_snprintf(pos, out_buff + SHORT_STR - pos, "%02X",
+                               tag_val[tag_val_off + 4 + i]);
+               }
+               proto_tree_add_string(tree, tag_interpretation, tvb, offset,
+                       tag_len, out_buff);
        }
-       for (i = 0; i < tag_len - 4; i++) {
-         pos += snprintf(pos, out_buff + SHORT_STR - pos, "%02X",
-                         tag_val[tag_val_off + 4 + i]);
+       proto_item_append_text(ietree, ": RSN");
+}
+
+typedef enum {
+       AIRONET_IE_VERSION = 3,
+       AIRONET_IE_QOS,
+       AIRONET_IE_QBSS_V2 = 14
+} aironet_ie_type_t;
+
+static const value_string aironet_ie_type_vals[] = {
+        { AIRONET_IE_VERSION,  "CCX version"},
+        { AIRONET_IE_QOS,      "Qos"},
+        { AIRONET_IE_QBSS_V2,  "QBSS V2 - CCA"},
+
+       { 0,                    NULL }
+};
+
+static void
+dissect_vendor_ie_aironet(proto_item * aironet_item, proto_tree * ietree,
+       tvbuff_t * tvb, int offset, guint32 tag_len)
+{
+       guint8  type;
+       int i;
+       gboolean dont_change = FALSE; /* Don't change the IE item text to default */
+
+       type = tvb_get_guint8(tvb, offset);
+       proto_tree_add_item (ietree, hf_aironet_ie_type, tvb, offset, 1, TRUE);
+       offset += 1;
+
+       switch (type) {
+       case AIRONET_IE_VERSION:
+               proto_tree_add_item (ietree, hf_aironet_ie_version, tvb, offset, 1, TRUE);
+               proto_item_append_text(aironet_item, ": Aironet CCX version = %d",
+                       tvb_get_guint8(tvb, offset));
+               dont_change = TRUE;
+               break;
+       case AIRONET_IE_QOS:
+               proto_tree_add_item (ietree, hf_aironet_ie_qos_unk1, tvb, offset, 1, TRUE);
+               offset += 1;
+               proto_tree_add_item (ietree, hf_aironet_ie_qos_paramset, tvb, offset, 1, TRUE);
+               offset += 1;
+
+               /* XXX: just copied over from WME. Maybe "Best Effort" and "Background"
+                *      need to be swapped. Also, the "TXOP" may be TXOP - or not.
+                */
+               for (i = 0; i < 4; i++) {
+                       guint8 byte1, byte2;
+                       guint16 txop;
+                       byte1 = tvb_get_guint8(tvb, offset);
+                       byte2 = tvb_get_guint8(tvb, offset + 1);
+                       txop = tvb_get_letohs(tvb, offset + 2);
+                       proto_tree_add_bytes_format(ietree, hf_aironet_ie_qos_val, tvb, offset, 4,
+                               tvb_get_ptr(tvb, offset, 4),
+                               "CCX QoS Parameters??: ACI %u (%s), Admission Control %sMandatory, AIFSN %u, ECWmin %u, ECWmax %u, TXOP %u",
+                               (byte1 & 0x60) >> 5, wme_acs[(byte1 & 0x60) >> 5],
+                               (byte1 & 0x10) ? "" : "not ", byte1 & 0x0f,
+                               byte2 & 0x0f, (byte2 & 0xf0) >> 4,
+                               txop);
+                       offset += 4;
+               }
+               break;
+       case AIRONET_IE_QBSS_V2:
+               /* Extract Values */
+               proto_tree_add_item (ietree, hf_qbss2_scount, tvb, offset, 2, TRUE);
+               proto_tree_add_item (ietree, hf_qbss2_cu, tvb, offset + 2, 1, FALSE);
+               proto_tree_add_item (ietree, hf_qbss2_cal, tvb, offset + 3, 1, FALSE);
+               proto_tree_add_item (ietree, hf_qbss2_gl, tvb, offset + 4, 1, FALSE);
+               break;
+       default:
+               proto_tree_add_item(ietree, hf_aironet_ie_data, tvb, offset,
+                       tag_len - 1, FALSE);
+               break;
+       }
+       if (!dont_change) {
+               proto_item_append_text(aironet_item, ": Aironet %s",
+                       val_to_str(type, aironet_ie_type_vals, "Unknown"));
        }
-       proto_tree_add_string(tree, tag_interpretation, tvb, offset,
-                             tag_len, out_buff);
-      } else
-       proto_tree_add_string_format(tree, tag_interpretation,
-               tvb, offset, tag_len, "",
-               "Tag interpretation: Vendor \"%s\" not interpreted",
-               get_manuf_name(tag_val));
 }
 
-static void 
+static void
 dissect_rsn_ie(proto_tree * tree, tvbuff_t * tvb, int offset,
               guint32 tag_len, const guint8 *tag_val)
 {
@@ -1048,7 +1339,7 @@ dissect_rsn_ie(proto_tree * tree, tvbuff_t * tvb, int offset,
     return;
   }
 
-  snprintf(out_buff, SHORT_STR, "RSN IE, version %u",
+  g_snprintf(out_buff, SHORT_STR, "RSN IE, version %u",
           pletohs(&tag_val[tag_val_off]));
   proto_tree_add_string(tree, tag_interpretation, tvb, offset, 2, out_buff);
 
@@ -1060,7 +1351,7 @@ dissect_rsn_ie(proto_tree * tree, tvbuff_t * tvb, int offset,
 
   /* multicast cipher suite */
   if (!memcmp(&tag_val[tag_val_off], RSN_OUI, 3)) {
-    snprintf(out_buff, SHORT_STR, "Multicast cipher suite: %s", 
+    g_snprintf(out_buff, SHORT_STR, "Multicast cipher suite: %s",
             wpa_cipher_idx2str(tag_val[tag_val_off + 3]));
     proto_tree_add_string(tree, tag_interpretation, tvb, offset, 4, out_buff);
     offset += 4;
@@ -1072,7 +1363,7 @@ dissect_rsn_ie(proto_tree * tree, tvbuff_t * tvb, int offset,
 
   /* unicast cipher suites */
   count = pletohs(tag_val + tag_val_off);
-  snprintf(out_buff, SHORT_STR, "# of unicast cipher suites: %u", count);
+  g_snprintf(out_buff, SHORT_STR, "# of unicast cipher suites: %u", count);
   proto_tree_add_string(tree, tag_interpretation, tvb, offset, 2, out_buff);
   offset += 2;
   tag_val_off += 2;
@@ -1080,7 +1371,7 @@ dissect_rsn_ie(proto_tree * tree, tvbuff_t * tvb, int offset,
   while (tag_val_off + 4 <= tag_len && i <= count) {
     if (memcmp(&tag_val[tag_val_off], RSN_OUI, 3) != 0)
       goto done;
-    snprintf(out_buff, SHORT_STR, "Unicast cipher suite %u: %s",
+    g_snprintf(out_buff, SHORT_STR, "Unicast cipher suite %u: %s",
             i, wpa_cipher_idx2str(tag_val[tag_val_off + 3]));
     proto_tree_add_string(tree, tag_interpretation, tvb, offset, 4, out_buff);
     offset += 4;
@@ -1093,7 +1384,7 @@ dissect_rsn_ie(proto_tree * tree, tvbuff_t * tvb, int offset,
 
   /* authenticated key management suites */
   count = pletohs(tag_val + tag_val_off);
-  snprintf(out_buff, SHORT_STR, "# of auth key management suites: %u", count);
+  g_snprintf(out_buff, SHORT_STR, "# of auth key management suites: %u", count);
   proto_tree_add_string(tree, tag_interpretation, tvb, offset, 2, out_buff);
   offset += 2;
   tag_val_off += 2;
@@ -1101,7 +1392,7 @@ dissect_rsn_ie(proto_tree * tree, tvbuff_t * tvb, int offset,
   while (tag_val_off + 4 <= tag_len && i <= count) {
     if (memcmp(&tag_val[tag_val_off], RSN_OUI, 3) != 0)
       goto done;
-    snprintf(out_buff, SHORT_STR, "auth key management suite %u: %s", 
+    g_snprintf(out_buff, SHORT_STR, "auth key management suite %u: %s",
             i, wpa_keymgmt_idx2str(tag_val[tag_val_off + 3]));
     proto_tree_add_string(tree, tag_interpretation, tvb, offset, 4, out_buff);
     offset += 4;
@@ -1113,7 +1404,7 @@ dissect_rsn_ie(proto_tree * tree, tvbuff_t * tvb, int offset,
     goto done;
 
   rsn_capab = pletohs(&tag_val[tag_val_off]);
-  snprintf(out_buff, SHORT_STR, "RSN Capabilities 0x%04x", rsn_capab);
+  g_snprintf(out_buff, SHORT_STR, "RSN Capabilities 0x%04x", rsn_capab);
   cap_item = proto_tree_add_uint_format(tree, rsn_cap, tvb,
                                        offset, 2, rsn_capab,
                                        "RSN Capabilities: 0x%04X", rsn_capab);
@@ -1133,7 +1424,7 @@ dissect_rsn_ie(proto_tree * tree, tvbuff_t * tvb, int offset,
     goto done;
 
   count = pletohs(tag_val + tag_val_off);
-  snprintf(out_buff, SHORT_STR, "# of PMKIDs: %u", count);
+  g_snprintf(out_buff, SHORT_STR, "# of PMKIDs: %u", count);
   proto_tree_add_string(tree, tag_interpretation, tvb, offset, 2, out_buff);
   offset += 2;
   tag_val_off += 2;
@@ -1144,9 +1435,9 @@ dissect_rsn_ie(proto_tree * tree, tvbuff_t * tvb, int offset,
     if (tag_val_off + PMKID_LEN > tag_len)
       goto done;
     pos = out_buff;
-    pos += snprintf(pos, out_buff + SHORT_STR - pos, "PMKID %u: ", i);
+    pos += g_snprintf(pos, out_buff + SHORT_STR - pos, "PMKID %u: ", i);
     for (j = 0; j < PMKID_LEN; j++) {
-      pos += snprintf(pos, out_buff + SHORT_STR - pos, "%02X",
+      pos += g_snprintf(pos, out_buff + SHORT_STR - pos, "%02X",
                      tag_val[tag_val_off + j]);
     }
     proto_tree_add_string(tree, tag_interpretation, tvb, offset,
@@ -1183,6 +1474,27 @@ static const value_string tag_num_vals[] = {
        { TAG_CISCO_UNKNOWN_1,      "Cisco Unknown 1 + Device Name" },
        { TAG_CISCO_UNKNOWN_2,      "Cisco Unknown 2" },
        { TAG_VENDOR_SPECIFIC_IE,   "Vendor Specific" },
+       { TAG_SYMBOL_PROPRIETARY,   "Symbol Proprietary"},
+       { TAG_AGERE_PROPRIETARY,    "Agere Proprietary"},
+       { TAG_REQUEST,              "Request"},
+       { TAG_QBSS_LOAD,            "QBSS Load Element"},
+       { TAG_EDCA_PARAM_SET,       "EDCA Parameter Set"},
+       { TAG_TRAF_SPEC,            "Traffic Specification"},
+       { TAG_TRAF_CLASS,           "Traffic Classification"},
+       { TAG_SCHEDULE,             "Schedule"},
+       { TAG_TS_DELAY,             "TS Delay"},
+       { TAG_TCLAS_PROCESS,        "TCLAS Processing"},
+       { TAG_QOS_CAPABILITY,       "QoS Capability"},
+       { TAG_POWER_CONSTRAINT,     "Power Constraint"},
+       { TAG_POWER_CAPABILITY,     "Power Capability"},
+       { TAG_TPC_REQUEST,          "TPC Request"},
+       { TAG_TPC_REPORT,           "TPC Report"},
+       { TAG_SUPPORTED_CHANNELS,   "Supported Channels"},
+       { TAG_CHANNEL_SWITCH_ANN,   "Channel Switch Announcement"},
+       { TAG_MEASURE_REQ,          "Measurement Request"},
+       { TAG_MEASURE_REP,          "Measurement Report"},
+       { TAG_QUIET,                "Quiet"},
+       { TAG_IBSS_DFS,             "IBSS DFS"},
        { 0,                        NULL }
 };
 
@@ -1193,9 +1505,12 @@ static const value_string environment_vals[] = {
        { 0,    NULL }
 };
 
+static int beacon_padding = 0; /* beacon padding bug */
 static int
 add_tagged_field (packet_info * pinfo, proto_tree * tree, tvbuff_t * tvb, int offset)
 {
+  guint32 oui;
+  const guint8 *tag_val;
   const guint8 *tag_data_ptr;
   guint32 tag_no, tag_len;
   unsigned int i;
@@ -1210,7 +1525,7 @@ add_tagged_field (packet_info * pinfo, proto_tree * tree, tvbuff_t * tvb, int of
 
   ti=proto_tree_add_text(orig_tree,tvb,offset,tag_len+2,"%s",
                          val_to_str(tag_no, tag_num_vals,
-                         (tag_no >= 17 && tag_no <= 31) ? 
+                         (tag_no >= 17 && tag_no <= 31) ?
                          "Reserved for challenge text" : "Reserved tag number" ));
   tree=proto_item_add_subtree(ti,ett_80211_mgt_ie);
 
@@ -1227,10 +1542,11 @@ add_tagged_field (packet_info * pinfo, proto_tree * tree, tvbuff_t * tvb, int of
     {
 
     case TAG_SSID:
+      if(beacon_padding == 0) /* padding bug */
       {
         char *ssid;
 
-        ssid = tvb_get_string(tvb, offset + 2, tag_len);
+        ssid = tvb_get_ephemeral_string(tvb, offset + 2, tag_len);
         proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
                                tag_len, ssid);
         if (check_col (pinfo->cinfo, COL_INFO)) {
@@ -1247,15 +1563,23 @@ add_tagged_field (packet_info * pinfo, proto_tree * tree, tvbuff_t * tvb, int of
         } else {
           proto_item_append_text(ti, ": Broadcast");
         }
-        g_free(ssid);
+       beacon_padding++; /* padding bug */
       }
       break;
 
     case TAG_SUPP_RATES:
     case TAG_EXT_SUPP_RATES:
+      if (tag_len < 1)
+      {
+        proto_tree_add_text (tree, tvb, offset + 2, tag_len,
+               "Tag length %u too short, must be > 0", tag_len);
+        break;
+      }
+      tag_data_ptr = tvb_get_ptr (tvb, offset + 2, tag_len);
+
       tag_data_ptr = tvb_get_ptr (tvb, offset + 2, tag_len);
       for (i = 0, n = 0; i < tag_len && n < SHORT_STR; i++) {
-        ret = snprintf (print_buff + n, SHORT_STR - n, "%2.1f%s ",
+        ret = g_snprintf (print_buff + n, SHORT_STR - n, "%2.1f%s ",
                         (tag_data_ptr[i] & 0x7F) * 0.5,
                         (tag_data_ptr[i] & 0x80) ? "(B)" : "");
         if (ret == -1 || ret >= SHORT_STR - n) {
@@ -1265,7 +1589,7 @@ add_tagged_field (packet_info * pinfo, proto_tree * tree, tvbuff_t * tvb, int of
         }
         n += ret;
       }
-      snprintf (out_buff, SHORT_STR, "Supported rates: %s [Mbit/sec]", print_buff);
+      g_snprintf (out_buff, SHORT_STR, "Supported rates: %s [Mbit/sec]", print_buff);
       out_buff[SHORT_STR-1] = '\0';
       proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
                             tag_len, out_buff);
@@ -1279,7 +1603,7 @@ add_tagged_field (packet_info * pinfo, proto_tree * tree, tvbuff_t * tvb, int of
                              tag_len);
         break;
       }
-      snprintf (out_buff, SHORT_STR,
+      g_snprintf (out_buff, SHORT_STR,
                "Dwell time 0x%04X, Hop Set %2d, Hop Pattern %2d, Hop Index %2d",
                tvb_get_letohs(tvb, offset + 2),
                tvb_get_guint8(tvb, offset + 4),
@@ -1297,7 +1621,7 @@ add_tagged_field (packet_info * pinfo, proto_tree * tree, tvbuff_t * tvb, int of
                              tag_len);
         break;
       }
-      snprintf (out_buff, SHORT_STR, "Current Channel: %u",
+      g_snprintf (out_buff, SHORT_STR, "Current Channel: %u",
                 tvb_get_guint8(tvb, offset + 2));
       out_buff[SHORT_STR-1] = '\0';
       proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
@@ -1312,28 +1636,28 @@ add_tagged_field (packet_info * pinfo, proto_tree * tree, tvbuff_t * tvb, int of
                              tag_len);
         break;
       }
-      snprintf (out_buff, SHORT_STR, "CFP count: %u",
+      g_snprintf (out_buff, SHORT_STR, "CFP count: %u",
                 tvb_get_guint8(tvb, offset + 2));
       out_buff[SHORT_STR-1] = '\0';
       proto_tree_add_string_format(tree, tag_interpretation, tvb, offset + 2,
                                    1, out_buff, "%s", out_buff);
-      snprintf (out_buff, SHORT_STR, "CFP period: %u",
+      g_snprintf (out_buff, SHORT_STR, "CFP period: %u",
                 tvb_get_guint8(tvb, offset + 3));
       out_buff[SHORT_STR-1] = '\0';
       proto_tree_add_string_format(tree, tag_interpretation, tvb, offset + 3,
                                    1, out_buff, "%s", out_buff);
-      snprintf (out_buff, SHORT_STR, "CFP max duration: %u",
+      g_snprintf (out_buff, SHORT_STR, "CFP max duration: %u",
                 tvb_get_letohs(tvb, offset + 4));
       out_buff[SHORT_STR-1] = '\0';
       proto_tree_add_string_format(tree, tag_interpretation, tvb, offset + 4,
                                    2, out_buff, "%s", out_buff);
-      snprintf (out_buff, SHORT_STR, "CFP Remaining: %u",
+      g_snprintf (out_buff, SHORT_STR, "CFP Remaining: %u",
                 tvb_get_letohs(tvb, offset + 6));
       out_buff[SHORT_STR-1] = '\0';
       proto_tree_add_string_format(tree, tag_interpretation, tvb, offset + 6,
                                    2, out_buff, "%s", out_buff);
       proto_item_append_text(ti, ": CFP count %u, CFP period %u, CFP max duration %u, "
-                             "CFP Remaining %u", 
+                             "CFP Remaining %u",
                              tvb_get_guint8(tvb, offset + 2),
                              tvb_get_guint8(tvb, offset + 3),
                              tvb_get_letohs(tvb, offset + 4),
@@ -1378,14 +1702,14 @@ add_tagged_field (packet_info * pinfo, proto_tree * tree, tvbuff_t * tvb, int of
           }
         }
         if (bmaplen>1 || bmap[0]) {
-          int len=snprintf (out_buff, SHORT_STR,
+          int len=g_snprintf (out_buff, SHORT_STR,
                             "Bitmap: traffic for AID's:");
           int i=0;
           for (i=0;i<bmaplen*8;i++) {
             if (bmap[i/8] & (1<<(i%8))) {
-              int aid=i+bmapoff*8;
-              len+=snprintf (out_buff+len, SHORT_STR-len," %u", aid);
-              proto_item_append_text(ti, "  %u", aid);
+              int aid=i+2*bmapoff*8;
+              len+=g_snprintf (out_buff+len, SHORT_STR-len," %u", aid);
+              proto_item_append_text(ti, " %u", aid);
               if (len>=SHORT_STR) {
                 break;
               }
@@ -1405,7 +1729,7 @@ add_tagged_field (packet_info * pinfo, proto_tree * tree, tvbuff_t * tvb, int of
                              tag_len);
         break;
       }
-      snprintf (out_buff, SHORT_STR, "ATIM window 0x%X",
+      g_snprintf (out_buff, SHORT_STR, "ATIM window 0x%X",
                 tvb_get_letohs(tvb, offset + 2));
       out_buff[SHORT_STR-1] = '\0';
       proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
@@ -1425,15 +1749,15 @@ add_tagged_field (packet_info * pinfo, proto_tree * tree, tvbuff_t * tvb, int of
         }
         tvb_memcpy(tvb, ccode, offset + 2, 2);
         ccode[2] = '\0';
-        snprintf (out_buff, SHORT_STR, "Country Code: %s, %s Environment",
-                 format_text(ccode, 2), 
+        g_snprintf (out_buff, SHORT_STR, "Country Code: %s, %s Environment",
+                 format_text(ccode, 2),
                  val_to_str(tvb_get_guint8(tvb, offset + 4), environment_vals,"Unknown (0x%02x)"));
         out_buff[SHORT_STR-1] = '\0';
         proto_item_append_text(ti, ": %s", out_buff);
         proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,3, out_buff);
 
         for (i = 3; (i + 3) <= tag_len; i += 3)
-        { 
+        {
          guint8 val1, val2, val3;
          val1 = tvb_get_guint8(tvb, offset + 2 + i);
          val2 = tvb_get_guint8(tvb, offset + 3 + i);
@@ -1452,6 +1776,39 @@ add_tagged_field (packet_info * pinfo, proto_tree * tree, tvbuff_t * tvb, int of
       }
       break;
 
+    case TAG_QBSS_LOAD:
+      if (tag_len < 4 || tag_len >5)
+      {
+        proto_tree_add_text (tree, tvb, offset + 2, tag_len, "Wrong QBSS Tag Length %u", tag_len);
+        break;
+      }
+
+      if (tag_len == 4)
+      {
+        /* QBSS Version 1 */
+        proto_tree_add_string (tree, tag_interpretation, tvb, offset + 1,
+          tag_len, "Cisco QBSS Version 1 - non CCA");
+
+        /* Extract Values */
+        proto_tree_add_uint (tree, hf_qbss_version, tvb, offset + 2, tag_len, 1);
+        proto_tree_add_item (tree, hf_qbss_scount, tvb, offset + 2, 2, TRUE);
+        proto_tree_add_item (tree, hf_qbss_cu, tvb, offset + 4, 1, FALSE);
+        proto_tree_add_item (tree, hf_qbss_adc, tvb, offset + 5, 1, FALSE);
+      }
+      else if (tag_len == 5)
+      {
+         /* QBSS Version 2 */
+         proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
+           tag_len, "802.11e CCA Version");
+
+         /* Extract Values */
+         proto_tree_add_uint (tree, hf_qbss_version, tvb, offset + 2, tag_len, 2);
+         proto_tree_add_item (tree, hf_qbss_scount, tvb, offset + 2, 2, TRUE);
+         proto_tree_add_item (tree, hf_qbss_cu, tvb, offset + 4, 1, FALSE);
+         proto_tree_add_item (tree, hf_qbss_adc, tvb, offset + 5, 2, FALSE);
+      }
+      break;
+
     case TAG_FH_HOPPING_PARAMETER:
       if (tag_len < 2)
       {
@@ -1459,7 +1816,7 @@ add_tagged_field (packet_info * pinfo, proto_tree * tree, tvbuff_t * tvb, int of
                              tag_len);
         break;
       }
-      snprintf (out_buff, SHORT_STR, "Prime Radix: %u, Number of Channels: %u", 
+      g_snprintf (out_buff, SHORT_STR, "Prime Radix: %u, Number of Channels: %u",
                 tvb_get_guint8(tvb, offset + 2),
                 tvb_get_guint8(tvb, offset + 3));
       out_buff[SHORT_STR-1] = '\0';
@@ -1468,7 +1825,7 @@ add_tagged_field (packet_info * pinfo, proto_tree * tree, tvbuff_t * tvb, int of
       break;
 
     case TAG_CHALLENGE_TEXT:
-      snprintf (out_buff, SHORT_STR, "Challenge text: %s",
+      g_snprintf (out_buff, SHORT_STR, "Challenge text: %s",
                 tvb_bytes_to_str(tvb, offset + 2, tag_len));
       out_buff[SHORT_STR-1] = '\0';
       proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
@@ -1487,12 +1844,14 @@ add_tagged_field (packet_info * pinfo, proto_tree * tree, tvbuff_t * tvb, int of
           break;
         }
         erp_info = tvb_get_guint8 (tvb, offset + 2);
-        snprintf (print_buff, SHORT_STR, "%sNon-ERP STAs, %suse protection, %s preambles",
+        g_snprintf (print_buff, SHORT_STR, "%sNon-ERP STAs, %suse protection, %s preambles",
                   erp_info & 0x01 ? "" : "no ",
                   erp_info & 0x02 ? "" : "do not ",
-                  erp_info & 0x04 ? "short or long": "long");
+                  /* 802.11g, 7.3.2.13: 1 means "one or more ... STAs
+                   * are not short preamble capable" */
+                  erp_info & 0x04 ? "long": "short or long");
         print_buff[SHORT_STR-1] = '\0';
-        snprintf (out_buff, SHORT_STR,
+        g_snprintf (out_buff, SHORT_STR,
                   "ERP info: 0x%x (%s)",erp_info,print_buff);
         out_buff[SHORT_STR-1] = '\0';
         proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
@@ -1502,7 +1861,7 @@ add_tagged_field (packet_info * pinfo, proto_tree * tree, tvbuff_t * tvb, int of
       break;
 
     case TAG_CISCO_UNKNOWN_1:
-      /* The Name of the sending device starts at offset 10 and is up to 
+      /* The Name of the sending device starts at offset 10 and is up to
          15 or 16 bytes in length, \0 padded */
       if (tag_len < 26)
       {
@@ -1510,20 +1869,51 @@ add_tagged_field (packet_info * pinfo, proto_tree * tree, tvbuff_t * tvb, int of
                              tag_len);
         break;
       }
-      snprintf (out_buff, SHORT_STR, "%.16s",
+      /* A cisco AP transmits the first 15 bytes of the AP name, probably
+         followed by '\0' for ASCII termination */
+      g_snprintf (out_buff, SHORT_STR, "%.16s",
                 tvb_format_stringzpad(tvb, offset + 12, 16));
       out_buff[SHORT_STR-1] = '\0';
       proto_tree_add_string_format (tree, tag_interpretation, tvb, offset + 2,
-                            tag_len, "", "Tag interpretation: Unknown + Name: %s",
-                            out_buff);
+                            tag_len, "", "Tag interpretation: Unknown + Name: %s #Clients: %u",
+                            out_buff,
+                            /* Total number off associated clients and
+                               repeater access points */
+                            tvb_get_guint8(tvb, offset + 28));
       if (check_col (pinfo->cinfo, COL_INFO)) {
           col_append_fstr(pinfo->cinfo, COL_INFO, ", Name: \"%s\"", out_buff);
       }
       break;
 
     case TAG_VENDOR_SPECIFIC_IE:
-      dissect_vendor_specific_ie(tree, tvb, offset + 2, tag_len,
-                                tvb_get_ptr (tvb, offset + 2, tag_len));
+      tvb_ensure_bytes_exist (tvb, offset + 2, tag_len);
+      if (tag_len >= 3) {
+               oui = tvb_get_ntoh24(tvb, offset + 2);
+               tag_val = tvb_get_ptr(tvb, offset + 2, tag_len);
+
+#define WPAWME_OUI     0x0050F2
+#define RSNOUI_VAL     0x000FAC
+
+               switch (oui) {
+               case WPAWME_OUI:
+                       dissect_vendor_ie_wpawme(ti, tree, tvb, offset + 2, tag_len, tag_val);
+                       break;
+               case RSNOUI_VAL:
+                       dissect_vendor_ie_rsn(ti, tree, tvb, offset + 2, tag_len, tag_val);
+                       break;
+               case OUI_CISCOWL:       /* Cisco Wireless (Aironet) */
+                       dissect_vendor_ie_aironet(ti, tree, tvb, offset + 5, tag_len - 3);
+                       break;
+               default:
+                       proto_tree_add_bytes_format (tree, tag_oui, tvb, offset + 2, 3,
+                               "", "Vendor: %s", get_manuf_name(tag_val));
+                       proto_item_append_text(ti, ": %s", get_manuf_name(tag_val));
+                       proto_tree_add_string (tree, tag_interpretation, tvb, offset + 5,
+                               tag_len - 3, "Not interpreted");
+                       break;
+               }
+
+      }
       break;
 
     case TAG_RSN_IE:
@@ -1548,6 +1938,7 @@ ieee_80211_add_tagged_parameters (tvbuff_t * tvb, int offset, packet_info * pinf
 {
   int next_len;
 
+  beacon_padding = 0; /* this is for the beacon padding confused with ssid fix */
   while (tagged_parameters_len > 0) {
     if ((next_len=add_tagged_field (pinfo, tree, tvb, offset))==0)
       break;
@@ -1574,6 +1965,8 @@ dissect_ieee80211_mgt (guint16 fcf, tvbuff_t * tvb, packet_info * pinfo,
       int offset;
       int tagged_parameter_tree_len;
 
+      g_pinfo = pinfo;
+
       CHECK_DISPLAY_AS_X(data_handle,proto_wlan_mgt, tvb, pinfo, tree);
 
       ti = proto_tree_add_item (tree, proto_wlan_mgt, tvb, 0, -1, FALSE);
@@ -1586,13 +1979,12 @@ dissect_ieee80211_mgt (guint16 fcf, tvbuff_t * tvb, packet_info * pinfo,
          fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 4);
          add_fixed_field (fixed_tree, tvb, 0, FIELD_CAP_INFO);
          add_fixed_field (fixed_tree, tvb, 2, FIELD_LISTEN_IVAL);
-
          offset = 4;   /* Size of fixed fields */
+
          tagged_parameter_tree_len =
              tvb_reported_length_remaining(tvb, offset);
          tagged_tree = get_tagged_parameter_tree (mgt_tree, tvb, offset,
                                                   tagged_parameter_tree_len);
-
          ieee_80211_add_tagged_parameters (tvb, offset, pinfo, tagged_tree,
              tagged_parameter_tree_len);
          break;
@@ -1603,14 +1995,12 @@ dissect_ieee80211_mgt (guint16 fcf, tvbuff_t * tvb, packet_info * pinfo,
          add_fixed_field (fixed_tree, tvb, 0, FIELD_CAP_INFO);
          add_fixed_field (fixed_tree, tvb, 2, FIELD_STATUS_CODE);
          add_fixed_field (fixed_tree, tvb, 4, FIELD_ASSOC_ID);
-
          offset = 6;   /* Size of fixed fields */
 
          tagged_parameter_tree_len =
              tvb_reported_length_remaining(tvb, offset);
          tagged_tree = get_tagged_parameter_tree (mgt_tree, tvb, offset,
                                                   tagged_parameter_tree_len);
-
          ieee_80211_add_tagged_parameters (tvb, offset, pinfo, tagged_tree,
              tagged_parameter_tree_len);
          break;
@@ -1621,29 +2011,27 @@ dissect_ieee80211_mgt (guint16 fcf, tvbuff_t * tvb, packet_info * pinfo,
          add_fixed_field (fixed_tree, tvb, 0, FIELD_CAP_INFO);
          add_fixed_field (fixed_tree, tvb, 2, FIELD_LISTEN_IVAL);
          add_fixed_field (fixed_tree, tvb, 4, FIELD_CURRENT_AP_ADDR);
-
          offset = 10;  /* Size of fixed fields */
+
          tagged_parameter_tree_len =
              tvb_reported_length_remaining(tvb, offset);
          tagged_tree = get_tagged_parameter_tree (mgt_tree, tvb, offset,
                                                   tagged_parameter_tree_len);
-
          ieee_80211_add_tagged_parameters (tvb, offset, pinfo, tagged_tree,
              tagged_parameter_tree_len);
          break;
 
        case MGT_REASSOC_RESP:
-         fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 10);
+         fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 6);
          add_fixed_field (fixed_tree, tvb, 0, FIELD_CAP_INFO);
          add_fixed_field (fixed_tree, tvb, 2, FIELD_STATUS_CODE);
          add_fixed_field (fixed_tree, tvb, 4, FIELD_ASSOC_ID);
-
          offset = 6;   /* Size of fixed fields */
+
          tagged_parameter_tree_len =
              tvb_reported_length_remaining(tvb, offset);
          tagged_tree = get_tagged_parameter_tree (mgt_tree, tvb, offset,
                                                   tagged_parameter_tree_len);
-
          ieee_80211_add_tagged_parameters (tvb, offset, pinfo, tagged_tree,
              tagged_parameter_tree_len);
          break;
@@ -1655,7 +2043,6 @@ dissect_ieee80211_mgt (guint16 fcf, tvbuff_t * tvb, packet_info * pinfo,
              tvb_reported_length_remaining(tvb, offset);
          tagged_tree = get_tagged_parameter_tree (mgt_tree, tvb, offset,
                                                   tagged_parameter_tree_len);
-
          ieee_80211_add_tagged_parameters (tvb, offset, pinfo, tagged_tree,
              tagged_parameter_tree_len);
          break;
@@ -1666,13 +2053,12 @@ dissect_ieee80211_mgt (guint16 fcf, tvbuff_t * tvb, packet_info * pinfo,
          add_fixed_field (fixed_tree, tvb, 0, FIELD_TIMESTAMP);
          add_fixed_field (fixed_tree, tvb, 8, FIELD_BEACON_INTERVAL);
          add_fixed_field (fixed_tree, tvb, 10, FIELD_CAP_INFO);
-
          offset = 12;  /* Size of fixed fields */
+
          tagged_parameter_tree_len =
              tvb_reported_length_remaining(tvb, offset);
          tagged_tree = get_tagged_parameter_tree (mgt_tree, tvb, offset,
                                                   tagged_parameter_tree_len);
-
          ieee_80211_add_tagged_parameters (tvb, offset, pinfo, tagged_tree,
              tagged_parameter_tree_len);
          break;
@@ -1680,17 +2066,15 @@ dissect_ieee80211_mgt (guint16 fcf, tvbuff_t * tvb, packet_info * pinfo,
 
        case MGT_BEACON:                /* Dissect protocol payload fields  */
          fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 12);
-
          add_fixed_field (fixed_tree, tvb, 0, FIELD_TIMESTAMP);
          add_fixed_field (fixed_tree, tvb, 8, FIELD_BEACON_INTERVAL);
          add_fixed_field (fixed_tree, tvb, 10, FIELD_CAP_INFO);
-
          offset = 12;  /* Size of fixed fields */
+
          tagged_parameter_tree_len =
              tvb_reported_length_remaining(tvb, offset);
          tagged_tree = get_tagged_parameter_tree (mgt_tree, tvb, offset,
                                                   tagged_parameter_tree_len);
-
          ieee_80211_add_tagged_parameters (tvb, offset, pinfo, tagged_tree,
              tagged_parameter_tree_len);
          break;
@@ -1711,7 +2095,6 @@ dissect_ieee80211_mgt (guint16 fcf, tvbuff_t * tvb, packet_info * pinfo,
          add_fixed_field (fixed_tree, tvb, 0, FIELD_AUTH_ALG);
          add_fixed_field (fixed_tree, tvb, 2, FIELD_AUTH_TRANS_SEQ);
          add_fixed_field (fixed_tree, tvb, 4, FIELD_STATUS_CODE);
-
          offset = 6;   /* Size of fixed fields */
 
          tagged_parameter_tree_len =
@@ -1722,7 +2105,6 @@ dissect_ieee80211_mgt (guint16 fcf, tvbuff_t * tvb, packet_info * pinfo,
                                                       tvb,
                                                       offset,
                                                       tagged_parameter_tree_len);
-
              ieee_80211_add_tagged_parameters (tvb, offset, pinfo, tagged_tree,
                tagged_parameter_tree_len);
            }
@@ -1736,60 +2118,103 @@ dissect_ieee80211_mgt (guint16 fcf, tvbuff_t * tvb, packet_info * pinfo,
 
 
        case MGT_ACTION:
-         fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 3);
-         add_fixed_field (fixed_tree, tvb, 0, FIELD_CATEGORY_CODE);
-
          switch (tvb_get_guint8(tvb, 0))
            {
 
-           case 17:    /* Management notification frame */
+           case CAT_SPECTRUM_MGMT:
+             switch (tvb_get_guint8(tvb, 1))
+               {
+               case SM_ACTION_MEASUREMENT_REQUEST:
+               case SM_ACTION_MEASUREMENT_REPORT:
+               case SM_ACTION_TPC_REQUEST:
+               case SM_ACTION_TPC_REPORT:
+                 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 3);
+                 add_fixed_field (fixed_tree, tvb, 0, FIELD_CATEGORY_CODE);
+                 add_fixed_field (fixed_tree, tvb, 1, FIELD_ACTION_CODE);
+                 add_fixed_field (fixed_tree, tvb, 2, FIELD_DIALOG_TOKEN);
+                 offset = 3;   /* Size of fixed fields */
+                 break;
+
+               case SM_ACTION_CHAN_SWITCH_ANNC:
+                 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 2);
+                 add_fixed_field (fixed_tree, tvb, 0, FIELD_CATEGORY_CODE);
+                 offset = 2;   /* Size of fixed fields */
+                 break;
+
+               default:
+                 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 2);
+                 add_fixed_field (fixed_tree, tvb, 0, FIELD_CATEGORY_CODE);
+                 offset = 2;   /* Size of fixed fields */
+                 break;
+               }
+             break;
+
+           case CAT_MGMT_NOTIFICATION: /* Management notification frame */
+             fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 4);
+             add_fixed_field (fixed_tree, tvb, 0, FIELD_CATEGORY_CODE);
              add_fixed_field (fixed_tree, tvb, 1, FIELD_WME_ACTION_CODE);
              add_fixed_field (fixed_tree, tvb, 2, FIELD_DIALOG_TOKEN);
              add_fixed_field (fixed_tree, tvb, 3, FIELD_WME_STATUS_CODE);
-
              offset = 4;       /* Size of fixed fields */
-
-             tagged_parameter_tree_len =
-               tvb_reported_length_remaining(tvb, offset);
-             if (tagged_parameter_tree_len != 0)
-               {
-                 tagged_tree = get_tagged_parameter_tree (mgt_tree, tvb, offset,
-                                                          tagged_parameter_tree_len);
-
-                 ieee_80211_add_tagged_parameters (tvb, offset, pinfo, tagged_tree,
-                                                   tagged_parameter_tree_len);
-               }
              break;
 
-           default:    /* Management action frame */
-             add_fixed_field (fixed_tree, tvb, 1, FIELD_ACTION_CODE);
-             add_fixed_field (fixed_tree, tvb, 2, FIELD_DIALOG_TOKEN);
+           default:
+             fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 1);
+             add_fixed_field (fixed_tree, tvb, 0, FIELD_CATEGORY_CODE);
+             offset = 1;       /* Size of fixed fields */
              break;
            }
+
+           tagged_parameter_tree_len =
+             tvb_reported_length_remaining(tvb, offset);
+           if (tagged_parameter_tree_len != 0)
+             {
+               tagged_tree = get_tagged_parameter_tree (mgt_tree, tvb, offset,
+                                                        tagged_parameter_tree_len);
+               ieee_80211_add_tagged_parameters (tvb, offset, pinfo, tagged_tree,
+                                                 tagged_parameter_tree_len);
+             }
          break;
        }
 }
 
 static void
-set_src_addr_cols(packet_info *pinfo, const guint8 *addr, char *type)
+set_src_addr_cols(packet_info *pinfo, const guint8 *addr, const char *type)
 {
   if (check_col(pinfo->cinfo, COL_RES_DL_SRC))
     col_add_fstr(pinfo->cinfo, COL_RES_DL_SRC, "%s (%s)",
                    get_ether_name(addr), type);
   if (check_col(pinfo->cinfo, COL_UNRES_DL_SRC))
-    col_add_fstr(pinfo->cinfo, COL_UNRES_DL_SRC, "%s (%s)",
-                    ether_to_str(addr), type);
+    col_add_fstr(pinfo->cinfo, COL_UNRES_DL_SRC, "%s",
+                    ether_to_str(addr));
 }
 
 static void
-set_dst_addr_cols(packet_info *pinfo, const guint8 *addr, char *type)
+set_dst_addr_cols(packet_info *pinfo, const guint8 *addr, const char *type)
 {
   if (check_col(pinfo->cinfo, COL_RES_DL_DST))
     col_add_fstr(pinfo->cinfo, COL_RES_DL_DST, "%s (%s)",
                     get_ether_name(addr), type);
   if (check_col(pinfo->cinfo, COL_UNRES_DL_DST))
-    col_add_fstr(pinfo->cinfo, COL_UNRES_DL_DST, "%s (%s)",
-                    ether_to_str(addr), type);
+    col_add_fstr(pinfo->cinfo, COL_UNRES_DL_DST, "%s",
+                    ether_to_str(addr));
+}
+
+static guint32
+crc32_802_tvb_padded(tvbuff_t *tvb, guint hdr_len, guint hdr_size, guint len)
+{
+  guint32 c_crc;
+
+  c_crc = crc32_ccitt_tvb(tvb, hdr_len);
+  c_crc = crc32_ccitt_seed(tvb_get_ptr(tvb, hdr_size, len), len, ~c_crc);
+
+  /* Byte reverse. */
+  c_crc = ((unsigned char)(c_crc>>0)<<24) |
+    ((unsigned char)(c_crc>>8)<<16) |
+    ((unsigned char)(c_crc>>16)<<8) |
+    ((unsigned char)(c_crc>>24)<<0);
+
+  return ( c_crc );
 }
 
 typedef enum {
@@ -1805,20 +2230,22 @@ static void
 dissect_ieee80211_common (tvbuff_t * tvb, packet_info * pinfo,
                          proto_tree * tree, gboolean fixed_length_header,
                          gboolean has_radio_information, gint fcs_len,
-                         gboolean wlan_broken_fc)
+                         gboolean wlan_broken_fc, gboolean datapad)
 {
   guint16 fcf, flags, frame_type_subtype;
   guint16 seq_control;
   guint32 seq_number, frag_number;
   gboolean more_frags;
-  const guint8 *src = NULL, *dst = NULL, *bssid = NULL;
+  const guint8 *src = NULL;
+  const guint8 *dst = NULL;
+  const guint8 *bssid = NULL;
   proto_item *ti = NULL;
   proto_item *flag_item;
   proto_item *fc_item;
   proto_tree *hdr_tree = NULL;
   proto_tree *flag_tree;
   proto_tree *fc_tree;
-  guint16 hdr_len;
+  guint16 hdr_len, ohdr_len;
   gboolean has_fcs;
   gint len, reported_len, ivlen;
   gboolean save_fragmented;
@@ -1862,6 +2289,9 @@ dissect_ieee80211_common (tvbuff_t * tvb, packet_info * pinfo,
     hdr_len = DATA_LONG_HDR_LEN;
   else
     hdr_len = find_header_length (fcf);
+  ohdr_len = hdr_len;
+  if (datapad)
+    hdr_len = roundup2(hdr_len, 4);
   frame_type_subtype = COMPOSE_FRAME_TYPE(fcf);
 
   if (check_col (pinfo->cinfo, COL_INFO))
@@ -1869,9 +2299,10 @@ dissect_ieee80211_common (tvbuff_t * tvb, packet_info * pinfo,
           val_to_str(frame_type_subtype, frame_type_subtype_vals,
               "Unrecognized (Reserved frame)"));
 
-  flags = COOK_FLAGS (fcf);
+  flags = FCF_FLAGS (fcf);
   more_frags = HAVE_FRAGMENTS (flags);
 
+
   /* Add the radio information, if present, and the FC to the current tree */
   if (tree)
     {
@@ -1899,11 +2330,11 @@ dissect_ieee80211_common (tvbuff_t * tvb, packet_info * pinfo,
       }
 
       proto_tree_add_uint (hdr_tree, hf_fc_frame_type_subtype,
-                          tvb, 
+                          tvb,
                           wlan_broken_fc?1:0, 1,
                           frame_type_subtype);
 
-      fc_item = proto_tree_add_uint_format (hdr_tree, hf_fc_field, tvb, 
+      fc_item = proto_tree_add_uint_format (hdr_tree, hf_fc_field, tvb,
                                            0, 2,
                                            fcf,
                                            "Frame Control: 0x%04X (%s)",
@@ -1912,57 +2343,57 @@ dissect_ieee80211_common (tvbuff_t * tvb, packet_info * pinfo,
       fc_tree = proto_item_add_subtree (fc_item, ett_fc_tree);
 
 
-      proto_tree_add_uint (fc_tree, hf_fc_proto_version, tvb, 
+      proto_tree_add_uint (fc_tree, hf_fc_proto_version, tvb,
                           wlan_broken_fc?1:0, 1,
-                          COOK_PROT_VERSION (fcf));
+                          FCF_PROT_VERSION (fcf));
 
-      proto_tree_add_uint (fc_tree, hf_fc_frame_type, tvb, 
+      proto_tree_add_uint (fc_tree, hf_fc_frame_type, tvb,
                           wlan_broken_fc?1:0, 1,
-                          COOK_FRAME_TYPE (fcf));
+                          FCF_FRAME_TYPE (fcf));
 
       proto_tree_add_uint (fc_tree, hf_fc_frame_subtype,
-                          tvb, 
+                          tvb,
                           wlan_broken_fc?1:0, 1,
-                          COOK_FRAME_SUBTYPE (fcf));
+                          FCF_FRAME_SUBTYPE (fcf));
 
       flag_item =
-       proto_tree_add_uint_format (fc_tree, hf_fc_flags, tvb, 
+       proto_tree_add_uint_format (fc_tree, hf_fc_flags, tvb,
                                    wlan_broken_fc?0:1, 1,
                                    flags, "Flags: 0x%X", flags);
 
       flag_tree = proto_item_add_subtree (flag_item, ett_proto_flags);
 
-      proto_tree_add_uint (flag_tree, hf_fc_data_ds, tvb, 
+      proto_tree_add_uint (flag_tree, hf_fc_data_ds, tvb,
                           wlan_broken_fc?0:1, 1,
-                          COOK_DS_STATUS (flags));
-      proto_tree_add_boolean_hidden (flag_tree, hf_fc_to_ds, tvb, 1, 1, 
+                          FLAGS_DS_STATUS (flags));
+      proto_tree_add_boolean_hidden (flag_tree, hf_fc_to_ds, tvb, 1, 1,
                                     flags);
-      proto_tree_add_boolean_hidden (flag_tree, hf_fc_from_ds, tvb, 1, 1, 
+      proto_tree_add_boolean_hidden (flag_tree, hf_fc_from_ds, tvb, 1, 1,
                                     flags);
 
-      proto_tree_add_boolean (flag_tree, hf_fc_more_frag, tvb, 
+      proto_tree_add_boolean (flag_tree, hf_fc_more_frag, tvb,
                              wlan_broken_fc?0:1, 1,
                              flags);
 
-      proto_tree_add_boolean (flag_tree, hf_fc_retry, tvb, 
+      proto_tree_add_boolean (flag_tree, hf_fc_retry, tvb,
                              wlan_broken_fc?0:1, 1, flags);
 
-      proto_tree_add_boolean (flag_tree, hf_fc_pwr_mgt, tvb, 
+      proto_tree_add_boolean (flag_tree, hf_fc_pwr_mgt, tvb,
                              wlan_broken_fc?0:1, 1, flags);
 
-      proto_tree_add_boolean (flag_tree, hf_fc_more_data, tvb, 
+      proto_tree_add_boolean (flag_tree, hf_fc_more_data, tvb,
                              wlan_broken_fc?0:1, 1,
                              flags);
 
-      proto_tree_add_boolean (flag_tree, hf_fc_wep, tvb,
+      proto_tree_add_boolean (flag_tree, hf_fc_protected, tvb,
                              wlan_broken_fc?0:1, 1, flags);
 
-      proto_tree_add_boolean (flag_tree, hf_fc_order, tvb, 
+      proto_tree_add_boolean (flag_tree, hf_fc_order, tvb,
                              wlan_broken_fc?0:1, 1, flags);
 
       if (frame_type_subtype == CTRL_PS_POLL)
        proto_tree_add_uint(hdr_tree, hf_assoc_id,tvb,2,2,
-                           COOK_ASSOC_ID(tvb_get_letohs(tvb,2)));
+                           ASSOC_ID(tvb_get_letohs(tvb,2)));
 
       else
          proto_tree_add_uint (hdr_tree, hf_did_duration, tvb, 2, 2,
@@ -1977,7 +2408,7 @@ dissect_ieee80211_common (tvbuff_t * tvb, packet_info * pinfo,
   frag_number = 0;
   seq_number = 0;
 
-  switch (COOK_FRAME_TYPE (fcf))
+  switch (FCF_FRAME_TYPE (fcf))
     {
 
     case MGT_FRAME:
@@ -1999,8 +2430,17 @@ dissect_ieee80211_common (tvbuff_t * tvb, packet_info * pinfo,
       whdr->type = frame_type_subtype;
 
       seq_control = tvb_get_letohs(tvb, 22);
-      frag_number = COOK_FRAGMENT_NUMBER(seq_control);
-      seq_number = COOK_SEQUENCE_NUMBER(seq_control);
+      frag_number = SEQCTL_FRAGMENT_NUMBER(seq_control);
+      seq_number = SEQCTL_SEQUENCE_NUMBER(seq_control);
+
+      if (check_col (pinfo->cinfo, COL_INFO))
+      {
+       col_append_fstr(pinfo->cinfo, COL_INFO,
+          ",SN=%d", seq_number);
+
+       col_append_fstr(pinfo->cinfo, COL_INFO,
+          ",FN=%d",frag_number);
+      }
 
       if (tree)
        {
@@ -2108,11 +2548,47 @@ dissect_ieee80211_common (tvbuff_t * tvb, packet_info * pinfo,
              proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 10, 6, src);
            }
          break;
+
+       case CTRL_BLOCK_ACK_REQ:
+         {
+           src = tvb_get_ptr (tvb, 10, 6);
+           dst = tvb_get_ptr (tvb, 4, 6);
+
+           set_src_addr_cols(pinfo, src, "TA");
+           set_dst_addr_cols(pinfo, dst, "RA");
+
+           if (tree)
+           {
+             proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6, src);
+
+             proto_tree_add_ether (hdr_tree, hf_addr_ta, tvb, 10, 6, dst);
+           }
+         /* TODO BAR */
+         break;
+         }
+
+       case CTRL_BLOCK_ACK:
+         {
+           src = tvb_get_ptr (tvb, 10, 6);
+           dst = tvb_get_ptr (tvb, 4, 6);
+
+           set_src_addr_cols(pinfo, src, "TA");
+           set_dst_addr_cols(pinfo, dst, "RA");
+
+           if (tree)
+           {
+             proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6, src);
+
+             proto_tree_add_ether (hdr_tree, hf_addr_ta, tvb, 10, 6, dst);
+           }
+           /* TODO BAR Format */
+           break;
+         }
        }
       break;
 
     case DATA_FRAME:
-      addr_type = COOK_ADDR_SELECTOR (fcf);
+      addr_type = FCF_ADDR_SELECTOR (fcf);
 
       /* In order to show src/dst address we must always do the following */
       switch (addr_type)
@@ -2159,8 +2635,17 @@ dissect_ieee80211_common (tvbuff_t * tvb, packet_info * pinfo,
       whdr->type = frame_type_subtype;
 
       seq_control = tvb_get_letohs(tvb, 22);
-      frag_number = COOK_FRAGMENT_NUMBER(seq_control);
-      seq_number = COOK_SEQUENCE_NUMBER(seq_control);
+      frag_number = SEQCTL_FRAGMENT_NUMBER(seq_control);
+      seq_number = SEQCTL_SEQUENCE_NUMBER(seq_control);
+
+      if (check_col (pinfo->cinfo, COL_INFO))
+      {
+       col_append_fstr(pinfo->cinfo, COL_INFO,
+          ",SN=%d", seq_number);
+
+       col_append_fstr(pinfo->cinfo, COL_INFO,
+          ",FN=%d",frag_number);
+      }
 
       /* Now if we have a tree we start adding stuff */
       if (tree)
@@ -2298,8 +2783,13 @@ dissect_ieee80211_common (tvbuff_t * tvb, packet_info * pinfo,
          reported_len -= 4;
          if (tree)
            {
-             guint32 fcs = crc32_802_tvb(tvb, hdr_len + len);
              guint32 sent_fcs = tvb_get_ntohl(tvb, hdr_len + len);
+             guint32 fcs;
+
+             if (datapad)
+               fcs = crc32_802_tvb_padded(tvb, ohdr_len, hdr_len, len);
+             else
+               fcs = crc32_802_tvb(tvb, hdr_len + len);
              if (fcs == sent_fcs)
                proto_tree_add_uint_format(hdr_tree, hf_fcs, tvb,
                        hdr_len + len, 4, sent_fcs,
@@ -2313,60 +2803,126 @@ dissect_ieee80211_common (tvbuff_t * tvb, packet_info * pinfo,
        }
     }
 
-  if (tree && (frame_type_subtype == DATA_QOS_DATA || frame_type_subtype == DATA_QOS_NULL)) {
-      proto_item *qos_fields;
-      proto_tree *qos_tree;
-
-      guint16 qos_control, qos_priority, qos_ack_policy;
-
-      qos_fields = proto_tree_add_text(hdr_tree, tvb, hdr_len - 2, 2,
-                                      "QoS parameters");
-      qos_tree = proto_item_add_subtree (qos_fields, ett_qos_parameters);
-
-      qos_control = tvb_get_letohs(tvb, hdr_len - 2);
-      qos_priority = COOK_QOS_PRIORITY(qos_control);
-      qos_ack_policy = COOK_QOS_ACK_POLICY(qos_control);
-      proto_tree_add_uint_format (qos_tree, hf_qos_priority, tvb,
-                                 hdr_len - 2, 2, qos_priority,
-                                 "Priority: %d (%s) (%s)",
-                                 qos_priority, qos_tags[qos_priority], qos_acs[qos_priority]);
-      proto_tree_add_uint_format (qos_tree, hf_qos_ack_policy, tvb,
-                                 hdr_len - 2, 2, qos_ack_policy,
-                                 "Ack Policy: %d (%sAcknowledge)", 
-                                 qos_ack_policy, qos_ack_policy ? "Do not " : "");
-  }
+
 
   /*
    * Only management and data frames have a body, so we don't have
    * anything more to do for other types of frames.
    */
-  switch (COOK_FRAME_TYPE (fcf))
+  switch (FCF_FRAME_TYPE (fcf))
     {
 
     case MGT_FRAME:
       break;
 
     case DATA_FRAME:
+      if (tree && DATA_FRAME_IS_QOS(frame_type_subtype))
+       {
+
+         proto_item *qos_fields;
+         proto_tree *qos_tree;
+
+         guint16 qosoff;
+         guint16 qos_control;
+         guint16 qos_priority;
+         guint16 qos_ack_policy;
+         guint16 qos_eosp;
+         guint16 qos_field_content;
+
+         /*
+          * We calculate the offset to the QoS header data as
+          * an offset relative to the end of the header.  But
+          * when the header has been padded to align the data
+          * this must be done relative to true header size, not
+          * the padded/aligned value.  To simplify this work we
+          * stash the original header size in ohdr_len instead
+          * of recalculating it.
+          */
+         qosoff = ohdr_len - 2;
+         qos_fields = proto_tree_add_text(hdr_tree, tvb, qosoff, 2,
+             "QoS parameters");
+         qos_tree = proto_item_add_subtree (qos_fields, ett_qos_parameters);
+
+         qos_control = tvb_get_letohs(tvb, qosoff + 0);
+         qos_priority = QOS_PRIORITY(qos_control);
+         qos_ack_policy = QOS_ACK_POLICY(qos_control);
+         qos_eosp = QOS_EOSP(qos_control);
+         qos_field_content = QOS_FIELD_CONTENT( qos_control);
+
+         proto_tree_add_uint_format (qos_tree, hf_qos_priority, tvb,
+             qosoff, 2, qos_priority,
+             "Priority: %d (%s) (%s)",
+             qos_priority, qos_tags[qos_priority], qos_acs[qos_priority]);
+
+         if (flags & FLAG_FROM_DS) {
+           proto_tree_add_boolean (qos_tree, hf_qos_eosp, tvb,
+             qosoff, 1, qos_eosp);
+
+           if (DATA_FRAME_IS_CF_POLL(frame_type_subtype)) {
+             /* txop limit */
+             proto_tree_add_uint_format (qos_tree, hf_qos_field_content, tvb,
+                 qosoff + 1, 1, qos_field_content, "TXOP Limit: %d ", qos_field_content);
+
+           } else {
+             /* qap ps buffer state */
+             proto_item *qos_ps_buf_state_fields;
+             proto_tree *qos_ps_buf_state_tree;
+             guint16 buf_state;
+             guint16 buf_ac;
+             guint16 buf_load;
+
+             buf_state = QOS_PS_BUF_STATE(qos_field_content);
+             buf_ac = QOS_PS_BUF_AC(qos_field_content);  /*access category */
+             buf_load = QOS_PS_BUF_LOAD(qos_field_content);
+
+             qos_ps_buf_state_fields = proto_tree_add_text(qos_tree, tvb, qosoff + 1, 1,
+               "QAP PS Buffer State: 0x%x", qos_field_content);
+             qos_ps_buf_state_tree = proto_item_add_subtree (qos_ps_buf_state_fields, ett_qos_ps_buf_state);
+
+/*     FIXME: hf_ values not defined
+             proto_tree_add_boolean (qos_ps_buf_state_tree, hf_qos_buf_state, tvb,
+                 1, 1, buf_state);
+
+             proto_tree_add_uint_format (qos_ps_buf_state_tree, hf_qos_buf_ac, tvb,
+                 qosoff + 1, 1, buf_ac, "Priority: %d (%s)",
+                 buf_ac, wme_acs[buf_ac]);
+
+             proto_tree_add_uint_format (qos_ps_buf_state_tree, hf_qos_buf_load, tvb,
+                 qosoff + 1, 1, buf_load, "Buffered load: %d ", (buf_load * 4096));
+*/
+
+           }
+         } else if (qos_eosp)  {
+           /* txop limit requested */
+           proto_tree_add_uint_format (qos_tree, hf_qos_field_content, tvb,
+                 qosoff + 1, 1, qos_field_content, "Queue Size: %d ", (qos_field_content * 254));
+         } else {
+           /* queue size */
+           proto_tree_add_uint_format (qos_tree, hf_qos_field_content, tvb,
+                 qosoff + 1, 1, qos_field_content, "TXOP Limit Requested: %d ", qos_field_content);
+         }
+
+         proto_tree_add_uint (qos_tree, hf_qos_ack_policy, tvb, qosoff, 1,
+             qos_ack_policy);
+
+       } /* end of qos control field */
+
       /*
        * No-data frames don't have a body.
        */
-      switch (frame_type_subtype)
-       {
+      if (DATA_FRAME_IS_NULL(frame_type_subtype))
+       return;
 
-       case DATA_NULL_FUNCTION:
-       case DATA_CF_ACK_NOD:
-       case DATA_CF_POLL_NOD:
-       case DATA_CF_ACK_POLL_NOD:
-       case DATA_QOS_NULL:
-         return;
-       }
-       break;
+      break;
+
+    case CONTROL_FRAME:
+      return;
 
     default:
       return;
     }
 
-  if (IS_WEP(COOK_FLAGS(fcf))) {
+  if (IS_PROTECTED(FCF_FLAGS(fcf))) {
     /*
      * It's a WEP-encrypted frame; dissect the WEP parameters and decrypt
      * the data, if we have a matching key.  Otherwise display it as data.
@@ -2377,7 +2933,7 @@ dissect_ieee80211_common (tvbuff_t * tvb, packet_info * pinfo,
     guint8 key, keybyte;
 
     keybyte = tvb_get_guint8(tvb, hdr_len + 3);
-    key = COOK_WEP_KEY(keybyte);
+    key = KEY_OCTET_WEP_KEY(keybyte);
     if ((keybyte & KEY_EXTIV) && (len >= EXTIV_LEN)) {
       /* Extended IV; this frame is likely encrypted with TKIP or CCMP */
       if (tree) {
@@ -2391,15 +2947,15 @@ dissect_ieee80211_common (tvbuff_t * tvb, packet_info * pinfo,
         * determined to be possible only with one of the encryption protocols.
         */
        if (tvb_get_guint8(tvb, hdr_len + 1) & 0x20) {
-         snprintf(out_buff, SHORT_STR, "0x%08X%02X%02X",
+         g_snprintf(out_buff, SHORT_STR, "0x%08X%02X%02X",
                   tvb_get_letohl(tvb, hdr_len + 4),
                   tvb_get_guint8(tvb, hdr_len),
                   tvb_get_guint8(tvb, hdr_len + 2));
          proto_tree_add_string(wep_tree, hf_tkip_extiv, tvb, hdr_len,
                                EXTIV_LEN, out_buff);
-       } 
+       }
        if (tvb_get_guint8(tvb, hdr_len + 2) == 0) {
-         snprintf(out_buff, SHORT_STR, "0x%08X%02X%02X",
+         g_snprintf(out_buff, SHORT_STR, "0x%08X%02X%02X",
                   tvb_get_letohl(tvb, hdr_len + 4),
                   tvb_get_guint8(tvb, hdr_len + 1),
                   tvb_get_guint8(tvb, hdr_len));
@@ -2500,10 +3056,10 @@ dissect_ieee80211_common (tvbuff_t * tvb, packet_info * pinfo,
       next_tvb = tvb_new_subset(tvb, hdr_len + ivlen, len, reported_len);
 
       if (tree && can_decrypt)
-       proto_tree_add_uint_format (wep_tree, hf_wep_icv, tvb, 
-                                   hdr_len + ivlen + len, 4, 
+       proto_tree_add_uint_format (wep_tree, hf_wep_icv, tvb,
+                                   hdr_len + ivlen + len, 4,
                                    tvb_get_ntohl(tvb, hdr_len + ivlen + len),
-                                   "WEP ICV: 0x%08x (not verified)", 
+                                   "WEP ICV: 0x%08x (not verified)",
                                    tvb_get_ntohl(tvb, hdr_len + ivlen + len));
 
       if (pinfo->ethertype != ETHERTYPE_CENTRINO_PROMISC)
@@ -2515,10 +3071,10 @@ dissect_ieee80211_common (tvbuff_t * tvb, packet_info * pinfo,
     } else {
 
       if (tree)
-       proto_tree_add_uint_format (wep_tree, hf_wep_icv, tvb, 
-                                   hdr_len + ivlen + len, 4, 
+       proto_tree_add_uint_format (wep_tree, hf_wep_icv, tvb,
+                                   hdr_len + ivlen + len, 4,
                                    tvb_get_ntohl(tvb, hdr_len + ivlen + len),
-                                   "WEP ICV: 0x%08x (correct)", 
+                                   "WEP ICV: 0x%08x (correct)",
                                    tvb_get_ntohl(tvb, hdr_len + ivlen + len));
 
       add_new_data_source(pinfo, next_tvb, "Decrypted WEP data");
@@ -2621,7 +3177,7 @@ dissect_ieee80211_common (tvbuff_t * tvb, packet_info * pinfo,
     goto end_of_wlan;
   }
 
-  switch (COOK_FRAME_TYPE (fcf))
+  switch (FCF_FRAME_TYPE (fcf))
     {
 
     case MGT_FRAME:
@@ -2703,7 +3259,17 @@ static void
 dissect_ieee80211 (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
 {
   dissect_ieee80211_common (tvb, pinfo, tree, FALSE, FALSE,
-      pinfo->pseudo_header->ieee_802_11.fcs_len, FALSE);
+      pinfo->pseudo_header->ieee_802_11.fcs_len, FALSE, FALSE);
+}
+
+/*
+ * Dissect 802.11 with a variable-length link-layer header and data padding.
+ */
+static void
+dissect_ieee80211_datapad (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
+{
+  dissect_ieee80211_common (tvb, pinfo, tree, FALSE, FALSE,
+      pinfo->pseudo_header->ieee_802_11.fcs_len, FALSE, TRUE);
 }
 
 /*
@@ -2714,7 +3280,7 @@ static void
 dissect_ieee80211_radio (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
 {
   dissect_ieee80211_common (tvb, pinfo, tree, FALSE, TRUE,
-     pinfo->pseudo_header->ieee_802_11.fcs_len, FALSE);
+     pinfo->pseudo_header->ieee_802_11.fcs_len, FALSE, FALSE);
 }
 
 /*
@@ -2725,7 +3291,7 @@ dissect_ieee80211_radio (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
 static void
 dissect_ieee80211_bsfc (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
 {
-  dissect_ieee80211_common (tvb, pinfo, tree, FALSE, FALSE, 0, TRUE);
+  dissect_ieee80211_common (tvb, pinfo, tree, FALSE, FALSE, 0, TRUE, FALSE);
 }
 
 /*
@@ -2735,7 +3301,7 @@ dissect_ieee80211_bsfc (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
 static void
 dissect_ieee80211_fixed (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
 {
-  dissect_ieee80211_common (tvb, pinfo, tree, TRUE, FALSE, 0, FALSE);
+  dissect_ieee80211_common (tvb, pinfo, tree, TRUE, FALSE, 0, FALSE, FALSE);
 }
 
 static void
@@ -2748,6 +3314,9 @@ wlan_defragment_init(void)
 void
 proto_register_ieee80211 (void)
 {
+  int i;
+  GString *key_name, *key_title, *key_desc;
+
   static const value_string frame_type[] = {
     {MGT_FRAME,     "Management frame"},
     {CONTROL_FRAME, "Control frame"},
@@ -2756,10 +3325,14 @@ proto_register_ieee80211 (void)
   };
 
   static const value_string tofrom_ds[] = {
-    {0,                       "Not leaving DS or network is operating in AD-HOC mode (To DS: 0  From DS: 0)"},
-    {FLAG_TO_DS,              "Frame is entering DS (To DS: 1  From DS: 0)"},
-    {FLAG_FROM_DS,            "Frame is exiting DS (To DS: 0  From DS: 1)"},
-    {FLAG_TO_DS|FLAG_FROM_DS, "Frame part of WDS (To DS: 1  From DS: 1)"},
+    {0,                       "Not leaving DS or network is operating "
+      "in AD-HOC mode (To DS: 0 From DS: 0)"},
+    {FLAG_TO_DS,              "Frame from STA to DS via an AP (To DS: 1 "
+      "From DS: 0)"},
+    {FLAG_FROM_DS,            "Frame from DS to a STA via AP(To DS: 0 "
+      "From DS: 1)"},
+    {FLAG_TO_DS|FLAG_FROM_DS, "Frame part of WDS from one AP to another "
+      "AP (To DS: 1 From DS: 1)"},
     {0, NULL}
   };
 
@@ -2793,9 +3366,9 @@ proto_register_ieee80211 (void)
     "No data buffered"
   };
 
-  static const true_false_string wep_flags = {
-    "WEP is enabled",
-    "WEP is disabled"
+  static const true_false_string protected_flags = {
+    "Data is protected",
+    "Data is not protected"
   };
 
   static const true_false_string order_flags = {
@@ -2839,12 +3412,35 @@ proto_register_ieee80211 (void)
     "DSSS-OFDM modulation not allowed"
   };
 
+  static const true_false_string cf_spec_man_flags = {
+    "dot11SpectrumManagementRequired TRUE",
+    "dot11SpectrumManagementRequired FALSE",
+  };
+
+  static const true_false_string cf_apsd_flags = {
+    "apsd implemented",
+    "apsd not implemented",
+  };
 
+  static const true_false_string cf_del_blk_ack_flags = {
+    "delayed block ack implemented",
+    "delayed block ack not implented",
+  };
+
+  static const true_false_string cf_imm_blk_ack_flags = {
+    "immediate block ack implemented",
+    "immediate block ack not implented",
+  };
   static const true_false_string cf_ibss_flags = {
     "Transmitter belongs to an IBSS",
     "Transmitter belongs to a BSS"
   };
 
+  static const true_false_string eosp_flag = {
+    "End of service period",
+    "Service period"
+  };
+
   static const value_string sta_cf_pollable[] = {
     {0x00, "Station is not CF-Pollable"},
     {0x02, "Station is CF-Pollable, "
@@ -2852,6 +3448,7 @@ proto_register_ieee80211 (void)
     {0x01, "Station is CF-Pollable, "
      "requesting to be placed on the CF-polling list"},
     {0x03, "Station is CF-Pollable, requesting never to be polled"},
+    {0x0200, "QSTA requesting association in QBSS"},
     {0, NULL}
   };
 
@@ -2860,6 +3457,10 @@ proto_register_ieee80211 (void)
     {0x02, "Point coordinator at AP for delivery only (no polling)"},
     {0x01, "Point coordinator at AP for delivery and polling"},
     {0x03, "Reserved"},
+    {0x0200, "QAP (HC) does not use CFP for delivery of unicast data type frames"},
+    {0x0202, "QAP (HC) uses CFP for delivery, but does not send CF-Polls to non-QoS STAs"},
+    {0x0201, "QAP (HC) uses CFP for delivery, and sends CF-Polls to non-QoS STAs"},
+    {0x0203, "Reserved"},
     {0, NULL}
   };
 
@@ -2884,7 +3485,11 @@ proto_register_ieee80211 (void)
     {0x07, "Class 3 frame received from nonassociated station"},
     {0x08, "Disassociated because sending STA is leaving (has left) BSS"},
     {0x09, "Station requesting (re)association is not authenticated with "
-     "responding station"},
+      "responding station"},
+    {0x0A, "Disassociated because the information in the Power Capability "
+      "element is unacceptable"},
+    {0x0B, "Disassociated because the information in the Supported"
+      "Channels element is unacceptable"},
     {0x0D, "Invalid Information Element"},
     {0x0E, "Michael MIC failure"},
     {0x0F, "4-Way Handshake timeout"},
@@ -2898,6 +3503,18 @@ proto_register_ieee80211 (void)
     {0x16, "Invalid RSN IE Capabilities"},
     {0x17, "IEEE 802.1X Authentication failed"},
     {0x18, "Cipher suite is rejected per security policy"},
+    {0x20, "Disassociated for unspecified, QoS-related reason"},
+    {0x21, "Disassociated because QAP lacks sufficient bandwidth for this QSTA"},
+    {0x22, "Disassociated because of excessive number of frames that need to be "
+      "acknowledged, but are not acknowledged for AP transmissions and/or poor "
+       "channel conditions"},
+    {0x23, "Disassociated because QSTA is transmitting outside the limits of its TXOPs"},
+    {0x24, "Requested from peer QSTA as the QSTA is leaving the QBSS (or resetting)"},
+    {0x25, "Requested from peer QSTA as it does not want to use the mechanism"},
+    {0x26, "Requested from peer QSTA as the QSTA received frames using the mechanism "
+      "for which a set up is required"},
+    {0x27, "Requested from peer QSTA due to time out"},
+    {0x2D, "Peer QSTA does not support the requested cipher suite"},
     {0x00, NULL}
   };
 
@@ -2929,10 +3546,31 @@ proto_register_ieee80211 (void)
      "PBCC encoding"},
     {0x15, "Association denied due to requesting station not supporting "
      "channel agility"},
+    {0x16, "Association request rejected because Spectrum Management"
+      "capability is required"},
+    {0x17, "Association request rejected because the information in the"
+      "Power Capability element is unacceptable"},
+    {0x18, "Association request rejected because the information in the"
+      "Supported Channels element is unacceptable"},
     {0x19, "Association denied due to requesting station not supporting "
      "short slot operation"},
     {0x1A, "Association denied due to requesting station not supporting "
      "DSSS-OFDM operation"},
+    {0x20, "Unspecified, QoS-related failure"},
+    {0x21, "Association denied due to QAP having insufficient bandwidth "
+      "to handle another QSTA"},
+    {0x22, "Association denied due to excessive frame loss rates and/or "
+      "poor conditions on current operating channel"},
+    {0x23, "Association (with QBSS) denied due to requesting station not "
+      "supporting the QoS facility"},
+    {0x24, "Association denied due to requesting station not supporting "
+      "Block Ack"},
+    {0x25, "The request has been declined."},
+    {0x26, "The request has not been successful as one or more parameters "
+      "have invalid values."},
+    {0x27, "The TS has not been created because the request cannot be honored. "
+      "However, a suggested TSPEC is provided so that the initiating QSTA may "
+       "attempt to set another TS with the suggested changes to the TSPEC."},
     {0x28, "Invalid Information Element"},
     {0x29, "Group Cipher is not valid"},
     {0x2A, "Pairwise Cipher is not valid"},
@@ -2940,16 +3578,30 @@ proto_register_ieee80211 (void)
     {0x2C, "Unsupported RSN IE version"},
     {0x2D, "Invalid RSN IE Capabilities"},
     {0x2E, "Cipher suite is rejected per security policy"},
+    {0x2F, "The TS has not been created. However, the HC may be capable of "
+      "creating a TS, in response to a request, after the time indicated in the TS Delay element."},
+    {0x30, "Direct Link is not allowed in the BSS by policy"},
+    {0x31, "Destination STA is not present within this QBSS."},
+    {0x32, "The Destination STA is not a QSTA."},
     {0x00, NULL}
   };
 
   static const value_string category_codes[] = {
-    {0x11, "Management notification frame"},
-    {0x00, NULL}
+    {CAT_SPECTRUM_MGMT, "Spectrum Management"},
+    {CAT_QOS, "QoS"},
+    {CAT_DLS, "DLS"},
+    {CAT_BLOCK_ACK, "Block Ack"},
+    {CAT_MGMT_NOTIFICATION, "Management notification frame"},
+    {0, NULL}
   };
 
-  static const value_string action_codes[] = {
-    {0x00, NULL}
+  static const value_string action_codes[] ={
+    {SM_ACTION_MEASUREMENT_REQUEST, "Measurement Request"},
+    {SM_ACTION_MEASUREMENT_REPORT, "Measurement Report"},
+    {SM_ACTION_TPC_REQUEST, "TPC Request"},
+    {SM_ACTION_TPC_REPORT, "TPC Report"},
+    {SM_ACTION_CHAN_SWITCH_ANNC, "Channel Switch Announcement"},
+    {0, NULL}
   };
 
   static const value_string wme_action_codes[] = {
@@ -2966,6 +3618,14 @@ proto_register_ieee80211 (void)
     {0x00, NULL}
   };
 
+  static const value_string ack_policy[] = {
+    {0x00, "Normal Ack"},
+    {0x02, "No Ack"},
+    {0x01, "No explicit Ack"},
+    {0x03, "Block Ack"},
+    {0x00, NULL}
+  };
+
   static hf_register_info hf[] = {
     {&hf_data_rate,
      {"Data Rate", "wlan.data_rate", FT_UINT8, BASE_DEC, NULL, 0,
@@ -3031,9 +3691,9 @@ proto_register_ieee80211 (void)
      {"More Data", "wlan.fc.moredata", FT_BOOLEAN, 8, TFS (&md_flags), FLAG_MORE_DATA,
       "More data flag", HFILL }},
 
-    {&hf_fc_wep,
-     {"WEP flag", "wlan.fc.wep", FT_BOOLEAN, 8, TFS (&wep_flags), FLAG_WEP,
-      "WEP flag", HFILL }},
+    {&hf_fc_protected,
+     {"Protected flag", "wlan.fc.protected", FT_BOOLEAN, 8, TFS (&protected_flags), FLAG_PROTECTED,
+      "Protected flag", HFILL }},
 
     {&hf_fc_order,
      {"Order flag", "wlan.fc.order", FT_BOOLEAN, 8, TFS (&order_flags), FLAG_ORDER,
@@ -3083,10 +3743,30 @@ proto_register_ieee80211 (void)
      {"Priority", "wlan.qos.priority", FT_UINT16, BASE_DEC, NULL, 0,
       "802.1D Tag", HFILL }},
 
+    {&hf_qos_eosp,
+     {"EOSP", "wlan.qos.eosp", FT_BOOLEAN, 8, TFS (&eosp_flag), QOS_FLAG_EOSP,
+      "EOSP Field", HFILL }},
+
     {&hf_qos_ack_policy,
-     {"Ack Policy", "wlan.qos.ack", FT_UINT16, BASE_DEC, NULL, 0,
+     {"Ack Policy", "wlan.qos.ack", FT_UINT16, BASE_HEX,  VALS (&ack_policy), 0,
       "Ack Policy", HFILL }},
 
+    {&hf_qos_field_content,
+     {"Content", "wlan.qos.fc_content", FT_UINT16, BASE_DEC, NULL, 0,
+      "Content1", HFILL }},
+
+/*    {&hf_qos_buffer_state,
+     {"QAP PS buffer State", "wlan.qos.ps_buf_state", FT_UINT16, BASE_DEC, NULL, 0,
+      "QAP PS buffer State", HFILL }},
+
+    {&hf_qos_txop_dur_req,
+     {"TXOP Duration Requested", "wlan.qos.txop_dur_req", FT_UINT16, BASE_DEC, NULL, 0,
+      "TXOP Duration Requested", HFILL }},
+
+    {&hf_qos_queue_size,
+     {"Queue Size", "wlan.qos.queue_size", FT_UINT16, BASE_DEC, NULL, 0,
+      "Queue Size", HFILL }},*/
+
     {&hf_fcs,
      {"Frame check sequence", "wlan.fcs", FT_UINT32, BASE_HEX,
       NULL, 0, "FCS", HFILL }},
@@ -3144,8 +3824,8 @@ proto_register_ieee80211 (void)
       BASE_HEX, NULL, 0, "CCMP Extended Initialization Vector", HFILL }},
 
     {&hf_wep_key,
-     {"Key", "wlan.wep.key", FT_UINT8, BASE_DEC, NULL, 0,
-      "Key", HFILL }},
+     {"Key Index", "wlan.wep.key", FT_UINT8, BASE_DEC, NULL, 0,
+      "Key Index", HFILL }},
 
     {&hf_wep_icv,
      {"WEP ICV", "wlan.wep.icv", FT_UINT32, BASE_HEX, NULL, 0,
@@ -3207,12 +3887,12 @@ proto_register_ieee80211 (void)
 
     {&ff_cf_sta_poll,
      {"CFP participation capabilities", "wlan_mgt.fixed.capabilities.cfpoll.sta",
-      FT_UINT16, BASE_HEX, VALS (&sta_cf_pollable), 0x000C,
+      FT_UINT16, BASE_HEX, VALS (&sta_cf_pollable), 0x020C,
       "CF-Poll capabilities for a STA", HFILL }},
 
     {&ff_cf_ap_poll,
      {"CFP participation capabilities", "wlan_mgt.fixed.capabilities.cfpoll.ap",
-      FT_UINT16, BASE_HEX, VALS (&ap_cf_pollable), 0x000C,
+      FT_UINT16, BASE_HEX, VALS (&ap_cf_pollable), 0x020C,
       "CF-Poll capabilities for an AP", HFILL }},
 
     {&ff_cf_privacy,
@@ -3231,16 +3911,35 @@ proto_register_ieee80211 (void)
      {"Channel Agility", "wlan_mgt.fixed.capabilities.agility",
       FT_BOOLEAN, 16, TFS (&cf_agility_flags), 0x0080, "Channel Agility", HFILL }},
 
+    {&ff_cf_spec_man,
+     {"Spectrum Management", "wlan_mgt.fixed.capabilities.spec_man",
+      FT_BOOLEAN, 16, TFS (&cf_spec_man_flags), 0x0100, "Spectrum Management", HFILL }},
+
     {&ff_short_slot_time,
      {"Short Slot Time", "wlan_mgt.fixed.capabilities.short_slot_time",
       FT_BOOLEAN, 16, TFS (&short_slot_time_flags), 0x0400, "Short Slot Time",
       HFILL }},
 
+    {&ff_cf_apsd,
+     {"Automatic Power Save Delivery", "wlan_mgt.fixed.capabilities.apsd",
+      FT_BOOLEAN, 16, TFS (&cf_apsd_flags), 0x0800, "Automatic Power Save "
+       "Delivery", HFILL }},
+
     {&ff_dsss_ofdm,
      {"DSSS-OFDM", "wlan_mgt.fixed.capabilities.dsss_ofdm",
       FT_BOOLEAN, 16, TFS (&dsss_ofdm_flags), 0x2000, "DSSS-OFDM Modulation",
       HFILL }},
 
+    {&ff_cf_del_blk_ack,
+     {"Delayed Block Ack", "wlan_mgt.fixed.capabilities.del_blk_ack",
+      FT_BOOLEAN, 16, TFS (&cf_del_blk_ack_flags), 0x4000, "Delayed Block "
+       "Ack", HFILL }},
+
+    {&ff_cf_imm_blk_ack,
+     {"Immediate Block Ack", "wlan_mgt.fixed.capabilities.imm_blk_ack",
+      FT_BOOLEAN, 16, TFS (&cf_imm_blk_ack_flags), 0x8000, "Immediate Block "
+       "Ack", HFILL }},
+
     {&ff_auth_seq,
      {"Authentication SEQ", "wlan_mgt.fixed.auth_seq",
       FT_UINT16, BASE_HEX, NULL, 0, "Authentication sequence number", HFILL }},
@@ -3269,12 +3968,12 @@ proto_register_ieee80211 (void)
 
     {&ff_category_code,
      {"Category code", "wlan_mgt.fixed.category_code",
-      FT_UINT16, BASE_HEX, VALS (&category_codes), 0,
+      FT_UINT16, BASE_DEC, VALS (&category_codes), 0,
       "Management action category", HFILL }},
 
     {&ff_action_code,
      {"Action code", "wlan_mgt.fixed.action_code",
-      FT_UINT16, BASE_HEX, VALS (&action_codes), 0,
+      FT_UINT16, BASE_DEC, VALS (&action_codes), 0,
       "Management action code", HFILL }},
 
     {&ff_dialog_token,
@@ -3304,6 +4003,10 @@ proto_register_ieee80211 (void)
      {"Tag interpretation", "wlan_mgt.tag.interpretation",
       FT_STRING, BASE_NONE, NULL, 0, "Interpretation of tag", HFILL }},
 
+    {&tag_oui,
+     {"OUI", "wlan_mgt.tag.oui",
+      FT_BYTES, BASE_NONE, NULL, 0, "OUI of vendor specific IE", HFILL }},
+
     {&tim_length,
      {"TIM length", "wlan_mgt.tim.length",
       FT_UINT8, BASE_DEC, NULL, 0,
@@ -3349,6 +4052,63 @@ proto_register_ieee80211 (void)
       "wlan_mgt.rsn.capabilities.gtksa_replay_counter",
       FT_UINT16, BASE_HEX, VALS (&rsn_cap_replay_counter), 0x0030,
       "RSN GTKSA Replay Counter capabilities", HFILL }},
+
+    {&hf_aironet_ie_type,
+     {"Aironet IE type", "wlan_mgt.aironet.type",
+      FT_UINT8, BASE_DEC, VALS(aironet_ie_type_vals), 0, "", HFILL }},
+
+    {&hf_aironet_ie_version,
+     {"Aironet IE CCX version?", "wlan_mgt.aironet.version",
+      FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }},
+
+    { &hf_aironet_ie_data,
+      { "Aironet IE data", "wlan_mgmt.aironet.data",
+        FT_BYTES, BASE_NONE, NULL, 0x0, "", HFILL }},
+
+    {&hf_qbss_version,
+     {"QBSS Version", "wlan_mgt.qbss.version",
+      FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }},
+
+    {&hf_qbss_scount,
+     {"Station Count", "wlan_mgt.qbss.scount",
+      FT_UINT16, BASE_DEC, NULL, 0, "", HFILL }},
+
+    {&hf_qbss_cu,
+     {"Channel Utilization", "wlan_mgt.qbss.cu",
+       FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }},
+
+    {&hf_qbss_adc,
+     {"Available Admission Capabilities", "wlan_mgt.qbss.adc",
+     FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }},
+
+    {&hf_qbss2_cu,
+     {"Channel Utilization", "wlan_mgt.qbss2.cu",
+       FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }},
+
+    {&hf_qbss2_gl,
+     {"G.711 CU Quantum", "wlan_mgt.qbss2.glimit",
+      FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }},
+
+    {&hf_qbss2_cal,
+     {"Call Admission Limit", "wlan_mgt.qbss2.cal",
+      FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }},
+
+    {&hf_qbss2_scount,
+     {"Station Count", "wlan_mgt.qbss2.scount",
+      FT_UINT16, BASE_DEC, NULL, 0, "", HFILL }},
+
+    {&hf_aironet_ie_qos_unk1,
+     {"Aironet IE QoS unknown1", "wlan_mgt.aironet.qos.unk1",
+      FT_UINT8, BASE_HEX, NULL, 0, "", HFILL }},
+
+    {&hf_aironet_ie_qos_paramset,
+     {"Aironet IE QoS paramset", "wlan_mgt.aironet.qos.paramset",
+      FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }},
+
+    {&hf_aironet_ie_qos_val,
+     {"Aironet IE QoS valueset", "wlan_mgt.aironet.qos.val",
+      FT_BYTES, BASE_NONE, NULL, 0, "", HFILL }},
+
   };
 
   static gint *tree_array[] = {
@@ -3361,6 +4121,7 @@ proto_register_ieee80211 (void)
     &ett_fixed_parameters,
     &ett_tagged_parameters,
     &ett_qos_parameters,
+    &ett_qos_ps_buf_state,
     &ett_wep_parameters,
     &ett_cap_tree,
     &ett_rsn_cap_tree,
@@ -3368,14 +4129,7 @@ proto_register_ieee80211 (void)
   };
   module_t *wlan_module;
 
-  static const enum_val_t wep_keys_options[] = {
-    {"0", "0", 0},
-    {"1", "1", 1},
-    {"2", "2", 2},
-    {"3", "3", 3},
-    {"4", "4", 4},
-    {NULL, NULL, -1},
-  };
+  enum_val_t *wep_keys_options = g_malloc(sizeof(enum_val_t) * (MAX_ENCRYPTION_KEYS + 2));
 
 
   proto_wlan = proto_register_protocol ("IEEE 802.11 wireless LAN",
@@ -3389,6 +4143,7 @@ proto_register_ieee80211 (void)
   register_dissector("wlan", dissect_ieee80211, proto_wlan);
   register_dissector("wlan_fixed", dissect_ieee80211_fixed, proto_wlan);
   register_dissector("wlan_bsfc", dissect_ieee80211_bsfc, proto_wlan);
+  register_dissector("wlan_datapad", dissect_ieee80211_datapad, proto_wlan);
   register_init_routine(wlan_defragment_init);
 
   wlan_tap = register_tap("wlan");
@@ -3411,27 +4166,47 @@ proto_register_ieee80211 (void)
                                 &wlan_ignore_wep);
 
 #ifndef USE_ENV
+
+  for (i = 0; i <= MAX_ENCRYPTION_KEYS; i++) {
+    key_name = g_string_new("");
+    g_string_sprintf(key_name, "%d", i);
+    wep_keys_options[i].name = key_name->str;
+    wep_keys_options[i].description = key_name->str;
+    wep_keys_options[i].value = i;
+    g_string_free(key_name, FALSE);
+  }
+  wep_keys_options[i].name = NULL;
+  wep_keys_options[i].description = NULL;
+  wep_keys_options[i].value = -1;
+
+  key_desc = g_string_new("");
+  g_string_sprintf(key_desc, "How many WEP keys do we have to choose from? (0 to disable, up to %d)", MAX_ENCRYPTION_KEYS);
   prefs_register_enum_preference(wlan_module, "wep_keys",
-                                "WEP key count",
-                                "How many WEP keys do we have to choose from? (0 to disable, up to 4)",
+                                "WEP key count", key_desc->str,
                                 &num_wepkeys, wep_keys_options, FALSE);
-
-  prefs_register_string_preference(wlan_module, "wep_key1",
-                                  "WEP key #1",
-                                  "First WEP key (A:B:C:D:E) [40bit], (A:B:C:D:E:F:G:H:I:J:K:L:M) [104bit], or whatever key length you're using",
-                                  &wep_keystr[0]);
-  prefs_register_string_preference(wlan_module, "wep_key2",
-                                  "WEP key #2",
-                                  "Second WEP key (A:B:C:D:E) [40bit], (A:B:C:D:E:F:G:H:I:J:K:L:M) [104bit], or whatever key length you're using",
-                                  &wep_keystr[1]);
-  prefs_register_string_preference(wlan_module, "wep_key3",
-                                  "WEP key #3",
-                                  "Third WEP key (A:B:C:D:E) [40bit], (A:B:C:D:E:F:G:H:I:J:K:L:M) [104bit], or whatever key length you're using",
-                                  &wep_keystr[2]);
-  prefs_register_string_preference(wlan_module, "wep_key4",
-                                  "WEP key #4",
-                                  "Fourth WEP key (A:B:C:D:E) [40bit] (A:B:C:D:E:F:G:H:I:J:K:L:M) [104bit], or whatever key length you're using",
-                                  &wep_keystr[3]);
+  g_string_free(key_desc, FALSE);
+
+  for (i = 0; i < MAX_ENCRYPTION_KEYS; i++) {
+    key_name = g_string_new("");
+    key_title = g_string_new("");
+    key_desc = g_string_new("");
+    wep_keystr[i] = NULL;
+    /* prefs_register_*_preference() expects unique strings, so
+     * we build them using g_string_sprintf and just leave them
+     * allocated. */
+    g_string_sprintf(key_name, "wep_key%d", i + 1);
+    g_string_sprintf(key_title, "WEP key #%d", i + 1);
+    g_string_sprintf(key_desc, "WEP key #%d bytes in hexadecimal (A:B:C:D:E) "
+           "[40bit], (A:B:C:D:E:F:G:H:I:J:K:L:M) [104bit], or whatever key "
+           "length you're using", i + 1);
+
+    prefs_register_string_preference(wlan_module, key_name->str,
+           key_title->str, key_desc->str, &wep_keystr[i]);
+
+    g_string_free(key_name, FALSE);
+    g_string_free(key_title, FALSE);
+    g_string_free(key_desc, FALSE);
+  }
 #endif
 }
 
@@ -3515,7 +4290,7 @@ static int wep_decrypt(guint8 *buf, guint32 len, int key_override) {
   key[0] = buf[0];
   key[1] = buf[1];
   key[2] = buf[2];
-  keyidx = COOK_WEP_KEY(buf[3]);
+  keyidx = KEY_OCTET_WEP_KEY(buf[3]);
 
   if (key_override >= 0)
     keyidx = key_override;
@@ -3589,15 +4364,15 @@ static int wep_decrypt(guint8 *buf, guint32 len, int key_override) {
 }
 
 static void init_wepkeys(void) {
-  char *tmp;
+  const char *tmp;
   int i;
   GByteArray *bytes;
   gboolean res;
 
 #ifdef USE_ENV
-  guint8 buf[128];
+  guint8 *buf;
 
-  tmp = getenv("ETHEREAL_WEPKEYNUM");
+  tmp = getenv("WIRESHARK_WEPKEYNUM");
   if (!tmp) {
     num_wepkeys = 0;
     return;
@@ -3626,7 +4401,8 @@ static void init_wepkeys(void) {
     wep_keylens[i] = 0;
 
 #ifdef USE_ENV
-    sprintf(buf, "ETHEREAL_WEPKEY%d", i+1);
+    buf=ep_alloc(128);
+    g_snprintf(buf, 128, "WIRESHARK_WEPKEY%d", i+1);
     tmp = getenv(buf);
 #else
     tmp = wep_keystr[i];