From Jouni Malinen via https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=8711 Wi...
[metze/wireshark/wip.git] / epan / dissectors / packet-ieee80211.c
index 0584472b65f897bf5efd18c520d0320b82ab167c..73171282ab9d2f5ca8cb9d02b24bba95d4be1b43 100644 (file)
@@ -526,6 +526,8 @@ enum fixed_field {
   FIELD_MESH_CONTROL,
   FIELD_SELFPROT_ACTION,
   FIELD_WNM_ACTION_CODE,
+  FIELD_KEY_DATA_LENGTH,
+  FIELD_WNM_NOTIFICATION_TYPE,
                                               /* add any new fixed field value above this line */
   MAX_FIELD_NUM
 };
@@ -613,7 +615,7 @@ enum fixed_field {
 #define TAG_BSS_MAX_IDLE_PERIOD       90
 #define TAG_TFS_REQUEST               91
 #define TAG_TFS_RESPONSE              92
-#define TAG_WMM_SLEEP_MODE            93
+#define TAG_WNM_SLEEP_MODE            93
 #define TAG_TIM_BROADCAST_REQUEST     94
 #define TAG_TIM_BROADCAST_RESPONSE    95
 #define TAG_COLLOCATED_INTER_REPORT   96
@@ -744,7 +746,7 @@ static const value_string tag_num_vals[] = {
   { TAG_BSS_MAX_IDLE_PERIOD,                  "BSS Max Idle Period" },
   { TAG_TFS_REQUEST,                          "TFS Request" },
   { TAG_TFS_RESPONSE,                         "TFS Response" },
-  { TAG_WMM_SLEEP_MODE,                       "WMM Sleep Mode" },
+  { TAG_WNM_SLEEP_MODE,                       "WNM-Sleep Mode" },
   { TAG_TIM_BROADCAST_REQUEST,                "TIM Broadcast Request" },
   { TAG_TIM_BROADCAST_RESPONSE,               "TIM Broadcast Response" },
   { TAG_COLLOCATED_INTER_REPORT,              "Collocated Interference Report" },
@@ -803,6 +805,16 @@ static value_string_ext tag_num_vals_ext = VALUE_STRING_EXT_INIT(tag_num_vals);
 
 /* WFA vendor specific subtypes */
 #define WFA_SUBTYPE_P2P 9
+#define WFA_SUBTYPE_WIFI_DISPLAY 10
+#define WFA_SUBTYPE_HS20_INDICATION 16
+#define WFA_SUBTYPE_HS20_ANQP 17
+
+static const value_string wfa_subtype_vals[] = {
+  { WFA_SUBTYPE_P2P, "P2P" },
+  { WFA_SUBTYPE_HS20_INDICATION, "Hotspot 2.0 Indication" },
+  { WFA_SUBTYPE_HS20_ANQP, "Hotspot 2.0 ANQP" },
+  { 0, NULL }
+};
 
 /* ************************************************************************* */
 /*              Supported Rates (7.3.2.2)                                    */
@@ -1367,6 +1379,17 @@ static const value_string wnm_action_codes[] = {
 };
 static value_string_ext wnm_action_codes_ext = VALUE_STRING_EXT_INIT(wnm_action_codes);
 
+
+static const value_string wnm_notification_types[] = {
+  { 0, "Firmware Update Notification" },
+  { 1, "Reserved for use by WFA" },
+  { 221, "Vendor Specific" },
+  { 0, NULL }
+};
+
+static value_string_ext wnm_notification_types_ext =
+  VALUE_STRING_EXT_INIT(wnm_notification_types);
+
 /*** End: Action Fixed Parameter ***/
 
 static const value_string ieee80211_tag_measure_request_type_flags[] = {
@@ -2553,7 +2576,6 @@ static const value_string ieee80211_ht_pren_type_vals[] = {
 
 static int proto_wlan = -1;
 static int proto_aggregate = -1;
-static packet_info * g_pinfo;
 static gboolean ieee80211_tvb_invalid = FALSE;
 
 /* ************************************************************************* */
@@ -2757,6 +2779,9 @@ static int hf_ieee80211_ff_tdls_action_code = -1;
 static int hf_ieee80211_ff_target_channel = -1;
 static int hf_ieee80211_ff_regulatory_class = -1;
 static int hf_ieee80211_ff_wnm_action_code = -1;
+static int hf_ieee80211_ff_key_data_length = -1;
+static int hf_ieee80211_ff_key_data = -1;
+static int hf_ieee80211_ff_wnm_notification_type = -1;
 static int hf_ieee80211_ff_request_mode_pref_cand = -1;
 static int hf_ieee80211_ff_request_mode_abridged = -1;
 static int hf_ieee80211_ff_request_mode_disassoc_imminent = -1;
@@ -3637,6 +3662,30 @@ static int hf_ieee80211_tag_time_adv_time_value_reserved = -1;
 static int hf_ieee80211_tag_time_adv_time_error = -1;
 static int hf_ieee80211_tag_time_adv_time_update_counter = -1;
 
+/* IEEE Std 802.11-2012 8.4.2.81 */
+static int hf_ieee80211_tag_bss_max_idle_period = -1;
+static int hf_ieee80211_tag_bss_max_idle_options_protected = -1;
+
+/* IEEE Std 802.11-2012 8.4.2.82 */
+static int hf_ieee80211_tag_tfs_request_id = -1;
+static int hf_ieee80211_tag_tfs_request_ac_delete_after_match = -1;
+static int hf_ieee80211_tag_tfs_request_ac_notify = -1;
+static int hf_ieee80211_tag_tfs_request_subelem_id = -1;
+static int hf_ieee80211_tag_tfs_request_subelem_len = -1;
+static int hf_ieee80211_tag_tfs_request_subelem = -1;
+
+/* IEEE Std 802.11-2012 8.4.2.83 */
+static int hf_ieee80211_tag_tfs_response_subelem_id = -1;
+static int hf_ieee80211_tag_tfs_response_subelem_len = -1;
+static int hf_ieee80211_tag_tfs_response_subelem = -1;
+static int hf_ieee80211_tag_tfs_response_status = -1;
+static int hf_ieee80211_tag_tfs_response_id = -1;
+
+/* IEEE Std 802.11-2012 8.4.2.84 */
+static int hf_ieee80211_tag_wnm_sleep_mode_action_type = -1;
+static int hf_ieee80211_tag_wnm_sleep_mode_response_status = -1;
+static int hf_ieee80211_tag_wnm_sleep_mode_interval = -1;
+
 /* IEEE Std 802.11v-2011 7.3.2.87 */
 static int hf_ieee80211_tag_time_zone = -1;
 
@@ -3905,6 +3954,18 @@ static int hf_ieee80211_sched_spec_int = -1;
 static int hf_ieee80211_tclas_up = -1;
 static int hf_ieee80211_tclas_class_type = -1;
 static int hf_ieee80211_tclas_class_mask = -1;
+static int hf_ieee80211_tclas_class_mask0_src_addr = -1;
+static int hf_ieee80211_tclas_class_mask0_dst_addr = -1;
+static int hf_ieee80211_tclas_class_mask0_type = -1;
+static int hf_ieee80211_tclas_class_mask1_ver = -1;
+static int hf_ieee80211_tclas_class_mask1_src_ip = -1;
+static int hf_ieee80211_tclas_class_mask1_dst_ip = -1;
+static int hf_ieee80211_tclas_class_mask1_src_port = -1;
+static int hf_ieee80211_tclas_class_mask1_dst_port = -1;
+static int hf_ieee80211_tclas_class_mask1_ipv4_dscp = -1;
+static int hf_ieee80211_tclas_class_mask1_ipv4_proto = -1;
+static int hf_ieee80211_tclas_class_mask1_ipv6_flow = -1;
+static int hf_ieee80211_tclas_class_mask2_tci = -1;
 static int hf_ieee80211_tclas_src_mac_addr = -1;
 static int hf_ieee80211_tclas_dst_mac_addr = -1;
 static int hf_ieee80211_tclas_ether_type = -1;
@@ -3960,6 +4021,37 @@ static int hf_ieee80211_tag_timeout_int_value = -1;
 /* Ethertype 89-0d */
 static int hf_ieee80211_data_encap_payload_type = -1;
 
+static int hf_ieee80211_anqp_wfa_subtype = -1;
+
+/* Hotspot 2.0 */
+static int hf_hs20_indication_dgaf_disabled = -1;
+
+static int hf_hs20_anqp_subtype = -1;
+static int hf_hs20_anqp_reserved = -1;
+static int hf_hs20_anqp_payload = -1;
+static int hf_hs20_anqp_hs_query_list = -1;
+static int hf_hs20_anqp_hs_capability_list = -1;
+static int hf_hs20_anqp_ofn_length = -1;
+static int hf_hs20_anqp_ofn_language = -1;
+static int hf_hs20_anqp_ofn_name = -1;
+static int hf_hs20_anqp_wan_metrics_link_status = -1;
+static int hf_hs20_anqp_wan_metrics_symmetric_link = -1;
+static int hf_hs20_anqp_wan_metrics_at_capacity = -1;
+static int hf_hs20_anqp_wan_metrics_reserved = -1;
+static int hf_hs20_anqp_wan_metrics_downlink_speed = -1;
+static int hf_hs20_anqp_wan_metrics_uplink_speed = -1;
+static int hf_hs20_anqp_wan_metrics_downlink_load = -1;
+static int hf_hs20_anqp_wan_metrics_uplink_load = -1;
+static int hf_hs20_anqp_wan_metrics_lmd = -1;
+static int hf_hs20_anqp_cc_proto_ip_proto = -1;
+static int hf_hs20_anqp_cc_proto_port_num = -1;
+static int hf_hs20_anqp_cc_proto_status = -1;
+static int hf_hs20_anqp_nai_hrq_count = -1;
+static int hf_hs20_anqp_nai_hrq_encoding_type = -1;
+static int hf_hs20_anqp_nai_hrq_length = -1;
+static int hf_hs20_anqp_nai_hrq_realm_name = -1;
+static int hf_hs20_anqp_oper_class_indic = -1;
+
 /* ************************************************************************* */
 /*                               Protocol trees                              */
 /* ************************************************************************* */
@@ -4056,7 +4148,7 @@ static gint ett_tag_rm_cap2 = -1;
 static gint ett_tag_rm_cap3 = -1;
 static gint ett_tag_rm_cap4 = -1;
 static gint ett_tag_rm_cap5 = -1;
-
+static gint ett_tag_tclas_mask_tree = -1;
 
 static gint ett_tag_supported_channels = -1;
 
@@ -4102,6 +4194,10 @@ static gint ett_nai_realm_eap = -1;
 static gint ett_tag_ric_data_desc_ie = -1;
 static gint ett_anqp_vendor_capab = -1;
 
+static gint ett_hs20_cc_proto_port_tuple = -1;
+
+static gint ett_ssid_list = -1;
+
 static const fragment_items frag_items = {
   &ett_fragment,
   &ett_fragments,
@@ -4893,7 +4989,7 @@ dissect_advertisement_protocol(packet_info *pinfo, proto_tree *tree,
 }
 
 static void
-dissect_anqp_query_list(proto_tree *tree, tvbuff_t *tvb, int offset, int end)
+dissect_anqp_query_list(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, int offset, int end)
 {
   while (offset + 2 <= end) {
     proto_tree_add_item(tree, hf_ieee80211_ff_anqp_query_id,
@@ -4901,18 +4997,30 @@ dissect_anqp_query_list(proto_tree *tree, tvbuff_t *tvb, int offset, int end)
     offset += 2;
   }
   if (offset != end) {
-    expert_add_info_format(g_pinfo, tree, PI_MALFORMED, PI_ERROR,
+    expert_add_info_format(pinfo, tree, PI_MALFORMED, PI_ERROR,
                            "Unexpected ANQP Query list format");
   }
 }
 
+static void dissect_hs20_anqp_hs_capability_list(proto_tree *tree,
+                                                 tvbuff_t *tvb,
+                                                 int offset, int end)
+{
+  while (offset < end) {
+    proto_tree_add_item(tree, hf_hs20_anqp_hs_capability_list,
+                        tvb, offset, 1, ENC_LITTLE_ENDIAN);
+    offset++;
+  }
+}
+
 static void
-dissect_anqp_capab_list(proto_tree *tree, tvbuff_t *tvb, int offset, int end)
+dissect_anqp_capab_list(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, int offset, int end)
 {
   guint16     id, len;
   proto_item *item;
   proto_tree *vtree;
   guint32     oui;
+  guint8      subtype;
 
   while (offset + 2 <= end) {
     id = tvb_get_letohs(tvb, offset);
@@ -4926,7 +5034,7 @@ dissect_anqp_capab_list(proto_tree *tree, tvbuff_t *tvb, int offset, int end)
                           tvb, offset, 2, ENC_LITTLE_ENDIAN);
       offset += 2;
       if ((len < 3) || ((offset + len) > end)) {
-        expert_add_info_format(g_pinfo, tree, PI_MALFORMED, PI_ERROR,
+        expert_add_info_format(pinfo, tree, PI_MALFORMED, PI_ERROR,
                                "Invalid vendor-specific ANQP capability");
         return;
       }
@@ -4936,6 +5044,27 @@ dissect_anqp_capab_list(proto_tree *tree, tvbuff_t *tvb, int offset, int end)
       len    -= 3;
 
       switch (oui) {
+      case OUI_WFA:
+        if (len == 0)
+          break;
+        subtype = tvb_get_guint8(tvb, offset);
+        proto_item_append_text(vtree, " - WFA - %s",
+                               val_to_str(subtype, wfa_subtype_vals,
+                                          "Unknown (%u)"));
+        proto_tree_add_item(vtree, hf_ieee80211_anqp_wfa_subtype,
+                            tvb, offset, 1, ENC_NA);
+        offset++;
+        len--;
+        switch (subtype) {
+        case WFA_SUBTYPE_HS20_ANQP:
+          dissect_hs20_anqp_hs_capability_list(vtree, tvb, offset, end);
+          break;
+        default:
+          proto_tree_add_item(vtree, hf_ieee80211_ff_anqp_capability_vendor,
+                              tvb, offset, len, ENC_NA);
+          break;
+        }
+        break;
       default:
         proto_tree_add_item(vtree, hf_ieee80211_ff_anqp_capability_vendor,
                             tvb, offset, len, ENC_NA);
@@ -4946,7 +5075,7 @@ dissect_anqp_capab_list(proto_tree *tree, tvbuff_t *tvb, int offset, int end)
     }
   }
   if (offset != end) {
-    expert_add_info_format(g_pinfo, tree, PI_MALFORMED, PI_ERROR,
+    expert_add_info_format(pinfo, tree, PI_MALFORMED, PI_ERROR,
                            "Unexpected ANQP Capability list format");
   }
 }
@@ -4978,7 +5107,7 @@ dissect_venue_info(proto_tree *tree, tvbuff_t *tvb, int offset)
 }
 
 static void
-dissect_venue_name_info(proto_tree *tree, tvbuff_t *tvb, int offset, int end)
+dissect_venue_name_info(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, int offset, int end)
 {
   proto_item *item;
 
@@ -4990,14 +5119,14 @@ dissect_venue_name_info(proto_tree *tree, tvbuff_t *tvb, int offset, int end)
                                tvb, offset, 1, ENC_BIG_ENDIAN);
     offset += 1;
     if ((vlen > (end - offset)) || (vlen < 3)) {
-      expert_add_info_format(g_pinfo, item, PI_MALFORMED, PI_ERROR,
+      expert_add_info_format(pinfo, item, PI_MALFORMED, PI_ERROR,
                              "Invalid Venue Name Duple length");
       break;
     }
     proto_tree_add_item(tree, hf_ieee80211_ff_anqp_venue_language,
                         tvb, offset, 3, ENC_ASCII|ENC_NA);
     proto_tree_add_item(tree, hf_ieee80211_ff_anqp_venue_name,
-                        tvb, offset + 3, vlen - 3, ENC_ASCII|ENC_NA);
+                        tvb, offset + 3, vlen - 3, ENC_UTF_8|ENC_NA);
     offset += vlen;
   }
 }
@@ -5041,7 +5170,7 @@ add_manuf(proto_item *item, tvbuff_t *tvb, int offset)
 }
 
 static void
-dissect_roaming_consortium_list(proto_tree *tree, tvbuff_t *tvb, int offset,
+dissect_roaming_consortium_list(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, int offset,
                                 int end)
 {
   proto_item *item;
@@ -5054,7 +5183,7 @@ dissect_roaming_consortium_list(proto_tree *tree, tvbuff_t *tvb, int offset,
                                tvb, offset, 1, ENC_BIG_ENDIAN);
     offset += 1;
     if ((len > (end - offset)) || (len < 3)) {
-      expert_add_info_format(g_pinfo, item, PI_MALFORMED, PI_ERROR,
+      expert_add_info_format(pinfo, item, PI_MALFORMED, PI_ERROR,
                              "Invalid Roaming Consortium OI");
       break;
     }
@@ -5113,7 +5242,7 @@ static const value_string nai_realm_auth_param_id_vals[] = {
 };
 
 static void
-dissect_nai_realm_list(proto_tree *tree, tvbuff_t *tvb, int offset, int end)
+dissect_nai_realm_list(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, int offset, int end)
 {
   guint16     count, len;
   proto_item *item, *r_item;
@@ -5136,7 +5265,7 @@ dissect_nai_realm_list(proto_tree *tree, tvbuff_t *tvb, int offset, int end)
                                tvb, offset, 2, ENC_LITTLE_ENDIAN);
     offset += 2;
     if (offset + len > end) {
-      expert_add_info_format(g_pinfo, item, PI_MALFORMED, PI_ERROR,
+      expert_add_info_format(pinfo, item, PI_MALFORMED, PI_ERROR,
                              "Invalid NAI Realm List");
       break;
     }
@@ -5150,7 +5279,7 @@ dissect_nai_realm_list(proto_tree *tree, tvbuff_t *tvb, int offset, int end)
                                tvb, offset, 1, ENC_LITTLE_ENDIAN);
     offset += 1;
     if (offset + nai_len > f_end) {
-      expert_add_info_format(g_pinfo, item, PI_MALFORMED, PI_ERROR,
+      expert_add_info_format(pinfo, item, PI_MALFORMED, PI_ERROR,
                              "Invalid NAI Realm Data");
       break;
     }
@@ -5178,7 +5307,7 @@ dissect_nai_realm_list(proto_tree *tree, tvbuff_t *tvb, int offset, int end)
                                  tvb, offset, 1, ENC_LITTLE_ENDIAN);
       offset += 1;
       if (offset + eap_len > f_end) {
-        expert_add_info_format(g_pinfo, item, PI_MALFORMED, PI_ERROR,
+        expert_add_info_format(pinfo, item, PI_MALFORMED, PI_ERROR,
                                "Invalid EAP Method subfield");
         break;
       }
@@ -5288,13 +5417,241 @@ dissect_domain_name_list(proto_tree *tree, tvbuff_t *tvb, int offset, int end)
   }
 }
 
+#define HS20_ANQP_HS_QUERY_LIST 1
+#define HS20_ANQP_HS_CAPABILITY_LIST 2
+#define HS20_ANQP_OPERATOR_FRIENDLY_NAME 3
+#define HS20_ANQP_WAN_METRICS 4
+#define HS20_ANQP_CONNECTION_CAPABILITY 5
+#define HS20_ANQP_NAI_HOME_REALM_QUERY 6
+#define HS20_ANQP_OPERATING_CLASS_INDICATION 7
+
+static const value_string hs20_anqp_subtype_vals[] = {
+  { HS20_ANQP_HS_QUERY_LIST, "HS Query list" },
+  { HS20_ANQP_HS_CAPABILITY_LIST, "HS Capability List" },
+  { HS20_ANQP_OPERATOR_FRIENDLY_NAME, "Operator Friendly Name" },
+  { HS20_ANQP_WAN_METRICS, "WAN Metrics" },
+  { HS20_ANQP_CONNECTION_CAPABILITY, "Connection Capability" },
+  { HS20_ANQP_NAI_HOME_REALM_QUERY, "NAI Home Realm Query" },
+  { HS20_ANQP_OPERATING_CLASS_INDICATION, "Operating Class Indication" },
+  { 0, NULL }
+};
+
+static void dissect_hs20_anqp_hs_query_list(proto_tree *tree, tvbuff_t *tvb,
+                                            int offset, int end)
+{
+  while (offset < end) {
+    proto_tree_add_item(tree, hf_hs20_anqp_hs_query_list,
+                        tvb, offset, 1, ENC_LITTLE_ENDIAN);
+    offset++;
+  }
+}
+
+static void dissect_hs20_anqp_operator_friendly_name(proto_tree *tree,
+                                                     tvbuff_t *tvb, packet_info *pinfo,
+                                                     int offset, int end)
+{
+  while (offset + 4 <= end) {
+    guint8 vlen = tvb_get_guint8(tvb, offset);
+    proto_item *item = proto_tree_add_item(tree, hf_hs20_anqp_ofn_length,
+                                           tvb, offset, 1, ENC_LITTLE_ENDIAN);
+    offset++;
+    if (vlen > end - offset || vlen < 3) {
+      expert_add_info_format(pinfo, item, PI_MALFORMED, PI_ERROR,
+                             "Invalid Operator Friendly Name Duple length");
+      break;
+    }
+    proto_tree_add_item(tree, hf_hs20_anqp_ofn_language,
+                        tvb, offset, 3, ENC_ASCII|ENC_NA);
+    proto_tree_add_item(tree, hf_hs20_anqp_ofn_name,
+                        tvb, offset + 3, vlen - 3, ENC_UTF_8|ENC_NA);
+    offset += vlen;
+  }
+}
+
+static const value_string hs20_wm_link_status_vals[] = {
+  { 0, "Reserved" },
+  { 1, "Link up" },
+  { 2, "Link down" },
+  { 3, "Link in test state" },
+  { 0, NULL }
+};
+
+static void dissect_hs20_anqp_wan_metrics(proto_tree *tree, tvbuff_t *tvb,
+                                          int offset, gboolean request)
+{
+  if (request)
+    return;
+
+  proto_tree_add_item(tree, hf_hs20_anqp_wan_metrics_link_status,
+                      tvb, offset, 1, ENC_LITTLE_ENDIAN);
+  proto_tree_add_item(tree, hf_hs20_anqp_wan_metrics_symmetric_link,
+                      tvb, offset, 1, ENC_LITTLE_ENDIAN);
+  proto_tree_add_item(tree, hf_hs20_anqp_wan_metrics_at_capacity,
+                      tvb, offset, 1, ENC_LITTLE_ENDIAN);
+  proto_tree_add_item(tree, hf_hs20_anqp_wan_metrics_reserved,
+                      tvb, offset, 1, ENC_LITTLE_ENDIAN);
+  offset++;
+
+  proto_tree_add_item(tree, hf_hs20_anqp_wan_metrics_downlink_speed,
+                      tvb, offset, 4, ENC_LITTLE_ENDIAN);
+  offset += 4;
+
+  proto_tree_add_item(tree, hf_hs20_anqp_wan_metrics_uplink_speed,
+                      tvb, offset, 4, ENC_LITTLE_ENDIAN);
+  offset += 4;
+
+  proto_tree_add_item(tree, hf_hs20_anqp_wan_metrics_downlink_load,
+                      tvb, offset, 1, ENC_LITTLE_ENDIAN);
+  offset++;
+
+  proto_tree_add_item(tree, hf_hs20_anqp_wan_metrics_uplink_load,
+                      tvb, offset, 1, ENC_LITTLE_ENDIAN);
+  offset++;
+
+  proto_tree_add_item(tree, hf_hs20_anqp_wan_metrics_lmd,
+                      tvb, offset, 2, ENC_LITTLE_ENDIAN);
+}
+
+static const value_string hs20_cc_status_vals[] = {
+  { 0, "Closed" },
+  { 1, "Open" },
+  { 2, "Unknown" },
+  { 0, NULL }
+};
+
+static void
+dissect_hs20_anqp_connection_capability(proto_tree *tree, tvbuff_t *tvb,
+                                        int offset, int end)
+{
+  proto_item *item;
+  proto_tree *tuple;
+  while (offset + 4 <= end) {
+    guint8 ip_proto, status;
+    guint16 port_num;
+
+    ip_proto = tvb_get_guint8(tvb, offset);
+    port_num = tvb_get_letohs(tvb, offset + 1);
+    status = tvb_get_guint8(tvb, offset + 3);
+
+    item = proto_tree_add_text(tree, tvb, offset, 4, "ProtoPort Tuple - "
+                               "ip_proto=%u port_num=%u status=%s",
+                               ip_proto, port_num,
+                               val_to_str(status, hs20_cc_status_vals,
+                                          "Unknown (%u)"));
+    tuple = proto_item_add_subtree(item, ett_hs20_cc_proto_port_tuple);
+    proto_tree_add_item(tuple, hf_hs20_anqp_cc_proto_ip_proto,
+                        tvb, offset, 1, ENC_LITTLE_ENDIAN);
+    offset++;
+    proto_tree_add_item(tuple, hf_hs20_anqp_cc_proto_port_num,
+                        tvb, offset, 2, ENC_LITTLE_ENDIAN);
+    offset += 2;
+    proto_tree_add_item(tuple, hf_hs20_anqp_cc_proto_status,
+                        tvb, offset, 1, ENC_LITTLE_ENDIAN);
+    offset++;
+  }
+}
+
+static void
+dissect_hs20_anqp_nai_home_realm_query(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo,
+                                       int offset, int end)
+{
+  guint8 len;
+  proto_item *item;
+
+  proto_tree_add_item(tree, hf_hs20_anqp_nai_hrq_count,
+                      tvb, offset, 1, ENC_LITTLE_ENDIAN);
+  offset++;
+
+  while (offset + 2 <= end) {
+    proto_tree_add_item(tree, hf_hs20_anqp_nai_hrq_encoding_type,
+                        tvb, offset, 1, ENC_LITTLE_ENDIAN);
+    offset++;
+    len = tvb_get_guint8(tvb, offset);
+    item = proto_tree_add_item(tree, hf_hs20_anqp_nai_hrq_length,
+                               tvb, offset, 1, ENC_LITTLE_ENDIAN);
+    offset++;
+    if (offset + len > end) {
+      expert_add_info_format(pinfo, item, PI_MALFORMED, PI_ERROR,
+                             "Invalid NAI Home Realm Query length");
+      break;
+    }
+    proto_tree_add_item(tree, hf_hs20_anqp_nai_hrq_realm_name,
+                        tvb, offset, len, ENC_ASCII|ENC_NA);
+    offset += len;
+  }
+}
+
+static void dissect_hs20_anqp_oper_class_indic(proto_tree *tree, tvbuff_t *tvb,
+                                               int offset, int end)
+{
+  while (offset < end) {
+    proto_tree_add_item(tree, hf_hs20_anqp_oper_class_indic,
+                        tvb, offset, 1, ENC_LITTLE_ENDIAN);
+    offset++;
+  }
+}
+
+static void dissect_hs20_anqp(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, int offset,
+                              int end, gboolean request, int idx)
+{
+  guint8 subtype;
+
+  subtype = tvb_get_guint8(tvb, offset);
+  proto_item_append_text(tree, " - HS 2.0 %s",
+                         val_to_str(subtype, hs20_anqp_subtype_vals,
+                                    "Unknown (%u)"));
+  if (idx == 0) {
+    col_append_fstr(pinfo->cinfo, COL_INFO, " HS 2.0 %s",
+                    val_to_str(subtype, hs20_anqp_subtype_vals,
+                               "Unknown (%u)"));
+  } else if (idx == 1) {
+    col_append_fstr(pinfo->cinfo, COL_INFO, ", ..");
+  }
+  proto_tree_add_item(tree, hf_hs20_anqp_subtype, tvb, offset, 1,
+                      ENC_LITTLE_ENDIAN);
+  offset++;
+
+  proto_tree_add_item(tree, hf_hs20_anqp_reserved, tvb, offset, 1,
+                      ENC_LITTLE_ENDIAN);
+  offset++;
+
+  switch (subtype) {
+  case HS20_ANQP_HS_QUERY_LIST:
+    dissect_hs20_anqp_hs_query_list(tree, tvb, offset, end);
+    break;
+  case HS20_ANQP_HS_CAPABILITY_LIST:
+    dissect_hs20_anqp_hs_capability_list(tree, tvb, offset, end);
+    break;
+  case HS20_ANQP_OPERATOR_FRIENDLY_NAME:
+    dissect_hs20_anqp_operator_friendly_name(tree, tvb, pinfo, offset, end);
+    break;
+  case HS20_ANQP_WAN_METRICS:
+    dissect_hs20_anqp_wan_metrics(tree, tvb, offset, request);
+    break;
+  case HS20_ANQP_CONNECTION_CAPABILITY:
+    dissect_hs20_anqp_connection_capability(tree, tvb, offset, end);
+    break;
+  case HS20_ANQP_NAI_HOME_REALM_QUERY:
+    dissect_hs20_anqp_nai_home_realm_query(tree, tvb, pinfo, offset, end);
+    break;
+  case HS20_ANQP_OPERATING_CLASS_INDICATION:
+    dissect_hs20_anqp_oper_class_indic(tree, tvb, offset, end);
+    break;
+  default:
+    if (offset == end)
+      break;
+    proto_tree_add_item(tree, hf_hs20_anqp_payload, tvb, offset,
+                        end - offset, ENC_NA);
+    break;
+  }
+}
+
 static int
-dissect_anqp_info(proto_tree *tree, tvbuff_t *tvb, int offset,
+dissect_anqp_info(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, int offset,
                   gboolean request, int idx)
 {
   guint16     id, len;
   guint32     oui;
-  guint8      subtype;
   proto_item *item;
 
   item = proto_tree_add_item(tree, hf_ieee80211_ff_anqp_info_id,
@@ -5304,11 +5661,11 @@ dissect_anqp_info(proto_tree *tree, tvbuff_t *tvb, int offset,
     if (idx == 0) {
       proto_item_append_text(tree, " - %s",
                              val_to_str_ext(id, &anqp_info_id_vals_ext, "Unknown (%u)"));
-      col_append_fstr(g_pinfo->cinfo, COL_INFO, " %s",
+      col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
                       val_to_str_ext(id, &anqp_info_id_vals_ext, "Unknown (%u)"));
     } else if (idx == 1) {
       proto_item_append_text(tree, ", ..");
-      col_append_fstr(g_pinfo->cinfo, COL_INFO, ", ..");
+      col_append_fstr(pinfo->cinfo, COL_INFO, ", ..");
     }
   }
   tree = proto_item_add_subtree(item, ett_gas_anqp);
@@ -5318,32 +5675,32 @@ dissect_anqp_info(proto_tree *tree, tvbuff_t *tvb, int offset,
   len = tvb_get_letohs(tvb, offset);
   offset += 2;
   if (tvb_reported_length_remaining(tvb, offset) < len) {
-    expert_add_info_format(g_pinfo, tree, PI_MALFORMED, PI_ERROR,
+    expert_add_info_format(pinfo, tree, PI_MALFORMED, PI_ERROR,
                            "Invalid ANQP Info length");
     return 4 + len;
   }
   switch (id)
   {
   case ANQP_INFO_ANQP_QUERY_LIST:
-    dissect_anqp_query_list(tree, tvb, offset, offset + len);
+    dissect_anqp_query_list(tree, tvb, pinfo, offset, offset + len);
     break;
   case ANQP_INFO_ANQP_CAPAB_LIST:
-    dissect_anqp_capab_list(tree, tvb, offset, offset + len);
+    dissect_anqp_capab_list(tree, tvb, pinfo, offset, offset + len);
     break;
   case ANQP_INFO_VENUE_NAME_INFO:
-    dissect_venue_name_info(tree, tvb, offset, offset + len);
+    dissect_venue_name_info(tree, tvb, pinfo, offset, offset + len);
     break;
   case ANQP_INFO_NETWORK_AUTH_TYPE_INFO:
     dissect_network_auth_type(tree, tvb, offset, offset + len);
     break;
   case ANQP_INFO_ROAMING_CONSORTIUM_LIST:
-    dissect_roaming_consortium_list(tree, tvb, offset, offset + len);
+    dissect_roaming_consortium_list(tree, tvb, pinfo, offset, offset + len);
     break;
   case ANQP_INFO_IP_ADDR_TYPE_AVAILABILITY_INFO:
     dissect_ip_addr_type_availability_info(tree, tvb, offset);
     break;
   case ANQP_INFO_NAI_REALM_LIST:
-    dissect_nai_realm_list(tree, tvb, offset, offset + len);
+    dissect_nai_realm_list(tree, tvb, pinfo, offset, offset + len);
     break;
   case ANQP_INFO_3GPP_CELLULAR_NETWORK_INFO:
     dissect_3gpp_cellular_network_info(tree, tvb, offset);
@@ -5358,13 +5715,16 @@ dissect_anqp_info(proto_tree *tree, tvbuff_t *tvb, int offset,
 
     switch (oui) {
     case OUI_WFA:
-      subtype = tvb_get_guint8(tvb, offset);
-      if (subtype == WFA_SUBTYPE_P2P) {
-        proto_tree_add_text(tree, tvb, offset, 1, "Subtype %u: P2P ANQP",
-                            subtype);
-        dissect_wifi_p2p_anqp(g_pinfo, tree, tvb, offset + 1, request);
-      } else {
-        proto_tree_add_text(tree, tvb, offset, 1, "Subtype %u", subtype);
+      proto_tree_add_item(tree, hf_ieee80211_anqp_wfa_subtype, tvb, offset, 1,
+                          ENC_NA);
+      switch (tvb_get_guint8(tvb, offset)) {
+      case WFA_SUBTYPE_P2P:
+        dissect_wifi_p2p_anqp(pinfo, tree, tvb, offset + 1, request);
+        break;
+      case WFA_SUBTYPE_HS20_ANQP:
+        dissect_hs20_anqp(tree, tvb, pinfo, offset + 1, offset + len - 3, request,
+                          idx);
+        break;
       }
       break;
     default:
@@ -5383,27 +5743,27 @@ dissect_anqp_info(proto_tree *tree, tvbuff_t *tvb, int offset,
 }
 
 static void
-dissect_anqp(proto_tree *tree, tvbuff_t *tvb, int offset, gboolean request)
+dissect_anqp(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, int offset, gboolean request)
 {
   int idx = 0;
 
   proto_item_append_text(tree, ": ANQP ");
   proto_item_append_text(tree, request ? "Request" : "Response");
   if (tvb_reported_length_remaining(tvb, offset) < 4) {
-    expert_add_info_format(g_pinfo, tree, PI_MALFORMED, PI_ERROR,
+    expert_add_info_format(pinfo, tree, PI_MALFORMED, PI_ERROR,
                            "Not enough room for ANQP header");
     return;
   }
-  col_append_fstr(g_pinfo->cinfo, COL_INFO, ", ANQP %s",
+  col_append_fstr(pinfo->cinfo, COL_INFO, ", ANQP %s",
                   request ? "Req" : "Resp");
   while (tvb_reported_length_remaining(tvb, offset) > 0) {
-    offset += dissect_anqp_info(tree, tvb, offset, request, idx);
+    offset += dissect_anqp_info(tree, tvb, pinfo, offset, request, idx);
     idx += 1;
   }
 }
 
 static guint
-dissect_gas_initial_request(proto_tree *tree, tvbuff_t *tvb, int offset,
+dissect_gas_initial_request(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, int offset,
                             gboolean anqp)
 {
   guint16     req_len;
@@ -5416,7 +5776,7 @@ dissect_gas_initial_request(proto_tree *tree, tvbuff_t *tvb, int offset,
 
   item = proto_tree_add_text(tree, tvb, offset, 2 + req_len, "Query Request");
   if (tvb_reported_length_remaining(tvb, offset) < 2 + req_len) {
-    expert_add_info_format(g_pinfo, tree, PI_MALFORMED, PI_ERROR,
+    expert_add_info_format(pinfo, tree, PI_MALFORMED, PI_ERROR,
                            "Invalid Query Request Length");
     return tvb_reported_length_remaining(tvb, offset);
   }
@@ -5430,7 +5790,7 @@ dissect_gas_initial_request(proto_tree *tree, tvbuff_t *tvb, int offset,
    * Advertisement Protocol IE)
    */
   if (anqp)
-    dissect_anqp(query, tvb, offset, TRUE);
+    dissect_anqp(query, tvb, pinfo, offset, TRUE);
   else
     proto_tree_add_item(query, hf_ieee80211_ff_query_request,
                         tvb, offset, req_len, ENC_NA);
@@ -5440,7 +5800,7 @@ dissect_gas_initial_request(proto_tree *tree, tvbuff_t *tvb, int offset,
 }
 
 static guint
-dissect_gas_initial_response(proto_tree *tree, tvbuff_t *tvb, int offset,
+dissect_gas_initial_response(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, int offset,
                              gboolean anqp)
 {
   guint16     resp_len;
@@ -5454,7 +5814,7 @@ dissect_gas_initial_response(proto_tree *tree, tvbuff_t *tvb, int offset,
   item = proto_tree_add_text(tree, tvb, offset, 2 + resp_len,
                              "Query Response");
   if (tvb_reported_length_remaining(tvb, offset) < 2 + resp_len) {
-    expert_add_info_format(g_pinfo, tree, PI_MALFORMED, PI_ERROR,
+    expert_add_info_format(pinfo, tree, PI_MALFORMED, PI_ERROR,
                            "Invalid Query Response Length");
     return tvb_reported_length_remaining(tvb, offset);
   }
@@ -5466,7 +5826,7 @@ dissect_gas_initial_response(proto_tree *tree, tvbuff_t *tvb, int offset,
   /* Query Response (optional) */
   if (resp_len) {
     if (anqp)
-      dissect_anqp(query, tvb, offset, FALSE);
+      dissect_anqp(query, tvb, pinfo, offset, FALSE);
     else
       proto_tree_add_item(query, hf_ieee80211_ff_query_response,
                           tvb, offset, resp_len, ENC_NA);
@@ -5518,7 +5878,7 @@ static const fragment_items gas_resp_frag_items = {
 };
 
 static guint
-dissect_gas_comeback_response(proto_tree *tree, tvbuff_t *tvb, int offset,
+dissect_gas_comeback_response(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, int offset,
                               gboolean anqp, guint8 frag, gboolean more,
                               guint8 dialog_token)
 {
@@ -5533,7 +5893,7 @@ dissect_gas_comeback_response(proto_tree *tree, tvbuff_t *tvb, int offset,
   item = proto_tree_add_text(tree, tvb, offset, 2 + resp_len,
                              "Query Response");
   if (tvb_reported_length_remaining(tvb, offset) < 2 + resp_len) {
-    expert_add_info_format(g_pinfo, tree, PI_MALFORMED, PI_ERROR,
+    expert_add_info_format(pinfo, tree, PI_MALFORMED, PI_ERROR,
                            "Invalid Query Response Length");
     return tvb_reported_length_remaining(tvb, offset);
   }
@@ -5545,24 +5905,24 @@ dissect_gas_comeback_response(proto_tree *tree, tvbuff_t *tvb, int offset,
   /* Query Response (optional) */
   if (resp_len) {
     if (anqp && (frag == 0) && !more)
-      dissect_anqp(query, tvb, offset, FALSE);
+      dissect_anqp(query, tvb, pinfo, offset, FALSE);
     else {
       fragment_data *frag_msg;
       gboolean save_fragmented;
       tvbuff_t *new_tvb;
 
-      save_fragmented = g_pinfo->fragmented;
-      g_pinfo->fragmented = TRUE;
+      save_fragmented = pinfo->fragmented;
+      pinfo->fragmented = TRUE;
       frag_msg = fragment_add_seq_check(&gas_reassembly_table, tvb, offset,
-                                        g_pinfo, dialog_token, NULL,
+                                        pinfo, dialog_token, NULL,
                                         frag, resp_len, more);
-      new_tvb = process_reassembled_data(tvb, offset, g_pinfo,
+      new_tvb = process_reassembled_data(tvb, offset, pinfo,
                                          "Reassembled GAS Query Response",
                                          frag_msg, &gas_resp_frag_items,
                                          NULL, tree);
       if (new_tvb) {
         if (anqp)
-          dissect_anqp(query, new_tvb, 0, FALSE);
+          dissect_anqp(query, new_tvb, pinfo, 0, FALSE);
         else
           proto_tree_add_item(query, hf_ieee80211_ff_query_response,
                               new_tvb, 0,
@@ -5573,7 +5933,7 @@ dissect_gas_comeback_response(proto_tree *tree, tvbuff_t *tvb, int offset,
       /* The old tvb cannot be used anymore */
       ieee80211_tvb_invalid = TRUE;
 
-      g_pinfo->fragmented = save_fragmented;
+      pinfo->fragmented = save_fragmented;
     }
     offset += resp_len;
   }
@@ -5586,13 +5946,13 @@ dissect_gas_comeback_response(proto_tree *tree, tvbuff_t *tvb, int offset,
 /* ************************************************************************* */
 
 static guint
-add_fixed_field(proto_tree *tree, tvbuff_t *tvb, int offset,
+add_fixed_field(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, int offset,
                 enum fixed_field lfcode);
 
 static guint64 last_timestamp;
 
 static guint
-add_ff_timestamp(proto_tree *tree, tvbuff_t *tvb, int offset)
+add_ff_timestamp(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo _U_, int offset)
 {
   last_timestamp = tvb_get_letoh64(tvb, offset);
   proto_tree_add_item(tree, hf_ieee80211_ff_timestamp, tvb, offset, 8,
@@ -5601,17 +5961,17 @@ add_ff_timestamp(proto_tree *tree, tvbuff_t *tvb, int offset)
 }
 
 static guint
-add_ff_beacon_interval(proto_tree *tree, tvbuff_t *tvb, int offset)
+add_ff_beacon_interval(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, int offset)
 {
   proto_tree_add_item(tree, hf_ieee80211_ff_beacon_interval, tvb, offset, 2,
                       ENC_LITTLE_ENDIAN);
-  col_append_fstr(g_pinfo->cinfo, COL_INFO, ", BI=%d",
+  col_append_fstr(pinfo->cinfo, COL_INFO, ", BI=%d",
                   tvb_get_letohs(tvb, offset));
   return 2;
 }
 
 static guint
-add_ff_cap_info(proto_tree *tree, tvbuff_t *tvb, int offset)
+add_ff_cap_info(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo _U_, int offset)
 {
   proto_item *cap_item;
   proto_tree *cap_tree;
@@ -5660,7 +6020,7 @@ add_ff_cap_info(proto_tree *tree, tvbuff_t *tvb, int offset)
 }
 
 static guint
-add_ff_auth_alg(proto_tree *tree, tvbuff_t *tvb, int offset)
+add_ff_auth_alg(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo _U_, int offset)
 {
   proto_tree_add_item(tree, hf_ieee80211_ff_auth_alg, tvb, offset, 2,
                       ENC_LITTLE_ENDIAN);
@@ -5668,7 +6028,7 @@ add_ff_auth_alg(proto_tree *tree, tvbuff_t *tvb, int offset)
 }
 
 static guint
-add_ff_auth_trans_seq(proto_tree *tree, tvbuff_t *tvb, int offset)
+add_ff_auth_trans_seq(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo _U_, int offset)
 {
   proto_tree_add_item(tree, hf_ieee80211_ff_auth_seq, tvb, offset, 2,
                       ENC_LITTLE_ENDIAN);
@@ -5676,7 +6036,7 @@ add_ff_auth_trans_seq(proto_tree *tree, tvbuff_t *tvb, int offset)
 }
 
 static guint
-add_ff_current_ap_addr(proto_tree *tree, tvbuff_t *tvb, int offset)
+add_ff_current_ap_addr(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo _U_, int offset)
 {
   proto_tree_add_item(tree, hf_ieee80211_ff_current_ap, tvb, offset, 6,
                       ENC_NA);
@@ -5684,7 +6044,7 @@ add_ff_current_ap_addr(proto_tree *tree, tvbuff_t *tvb, int offset)
 }
 
 static guint
-add_ff_listen_ival(proto_tree *tree, tvbuff_t *tvb, int offset)
+add_ff_listen_ival(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo _U_, int offset)
 {
   proto_tree_add_item(tree, hf_ieee80211_ff_listen_ival, tvb, offset, 2,
                       ENC_LITTLE_ENDIAN);
@@ -5692,7 +6052,7 @@ add_ff_listen_ival(proto_tree *tree, tvbuff_t *tvb, int offset)
 }
 
 static guint
-add_ff_reason_code(proto_tree *tree, tvbuff_t *tvb, int offset)
+add_ff_reason_code(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo _U_, int offset)
 {
   proto_tree_add_item(tree, hf_ieee80211_ff_reason, tvb, offset, 2,
                       ENC_LITTLE_ENDIAN);
@@ -5700,7 +6060,7 @@ add_ff_reason_code(proto_tree *tree, tvbuff_t *tvb, int offset)
 }
 
 static guint
-add_ff_assoc_id(proto_tree *tree, tvbuff_t *tvb, int offset)
+add_ff_assoc_id(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo _U_, int offset)
 {
   proto_tree_add_item(tree, hf_ieee80211_ff_assoc_id, tvb, offset, 2,
                       ENC_LITTLE_ENDIAN);
@@ -5708,7 +6068,7 @@ add_ff_assoc_id(proto_tree *tree, tvbuff_t *tvb, int offset)
 }
 
 static guint
-add_ff_status_code(proto_tree *tree, tvbuff_t *tvb, int offset)
+add_ff_status_code(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo _U_, int offset)
 {
   proto_tree_add_item(tree, hf_ieee80211_ff_status_code, tvb, offset, 2,
                       ENC_LITTLE_ENDIAN);
@@ -5716,7 +6076,7 @@ add_ff_status_code(proto_tree *tree, tvbuff_t *tvb, int offset)
 }
 
 static guint
-add_ff_category_code(proto_tree *tree, tvbuff_t *tvb, int offset)
+add_ff_category_code(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo _U_, int offset)
 {
   proto_tree_add_item(tree, hf_ieee80211_ff_category_code, tvb, offset, 1,
                       ENC_LITTLE_ENDIAN);
@@ -5724,7 +6084,7 @@ add_ff_category_code(proto_tree *tree, tvbuff_t *tvb, int offset)
 }
 
 static guint
-add_ff_action_code(proto_tree *tree, tvbuff_t *tvb, int offset)
+add_ff_action_code(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo _U_, int offset)
 {
   proto_tree_add_item(tree, hf_ieee80211_ff_action_code, tvb, offset, 1,
                       ENC_LITTLE_ENDIAN);
@@ -5732,7 +6092,7 @@ add_ff_action_code(proto_tree *tree, tvbuff_t *tvb, int offset)
 }
 
 static guint
-add_ff_dialog_token(proto_tree *tree, tvbuff_t *tvb, int offset)
+add_ff_dialog_token(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo _U_, int offset)
 {
   proto_tree_add_item(tree, hf_ieee80211_ff_dialog_token, tvb, offset, 1,
                       ENC_LITTLE_ENDIAN);
@@ -5740,7 +6100,7 @@ add_ff_dialog_token(proto_tree *tree, tvbuff_t *tvb, int offset)
 }
 
 static guint
-add_ff_wme_action_code(proto_tree *tree, tvbuff_t *tvb, int offset)
+add_ff_wme_action_code(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo _U_, int offset)
 {
   proto_tree_add_item(tree, hf_ieee80211_ff_wme_action_code, tvb, offset, 1,
                       ENC_LITTLE_ENDIAN);
@@ -5748,7 +6108,7 @@ add_ff_wme_action_code(proto_tree *tree, tvbuff_t *tvb, int offset)
 }
 
 static guint
-add_ff_wme_status_code(proto_tree *tree, tvbuff_t *tvb, int offset)
+add_ff_wme_status_code(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo _U_, int offset)
 {
   proto_tree_add_item(tree, hf_ieee80211_ff_wme_status_code, tvb, offset, 1,
                       ENC_LITTLE_ENDIAN);
@@ -5756,7 +6116,7 @@ add_ff_wme_status_code(proto_tree *tree, tvbuff_t *tvb, int offset)
 }
 
 static guint
-add_ff_qos_action_code(proto_tree *tree, tvbuff_t *tvb, int offset)
+add_ff_qos_action_code(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo _U_, int offset)
 {
   proto_tree_add_item(tree, hf_ieee80211_ff_qos_action_code, tvb, offset, 1,
                       ENC_LITTLE_ENDIAN);
@@ -5764,7 +6124,7 @@ add_ff_qos_action_code(proto_tree *tree, tvbuff_t *tvb, int offset)
 }
 
 static guint
-add_ff_block_ack_action_code(proto_tree *tree, tvbuff_t *tvb, int offset)
+add_ff_block_ack_action_code(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo _U_, int offset)
 {
   proto_tree_add_item(tree, hf_ieee80211_ff_ba_action, tvb, offset, 1,
                       ENC_LITTLE_ENDIAN);
@@ -5772,7 +6132,7 @@ add_ff_block_ack_action_code(proto_tree *tree, tvbuff_t *tvb, int offset)
 }
 
 static guint
-add_ff_block_ack_param(proto_tree *tree, tvbuff_t *tvb, int offset)
+add_ff_block_ack_param(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo _U_, int offset)
 {
   proto_tree_add_bitmask(tree, tvb, offset, hf_ieee80211_ff_block_ack_params,
                          ett_ff_ba_param_tree,
@@ -5782,7 +6142,7 @@ add_ff_block_ack_param(proto_tree *tree, tvbuff_t *tvb, int offset)
 }
 
 static guint
-add_ff_block_ack_timeout(proto_tree *tree, tvbuff_t *tvb, int offset)
+add_ff_block_ack_timeout(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo _U_, int offset)
 {
   proto_tree_add_item(tree, hf_ieee80211_ff_block_ack_timeout, tvb, offset, 2,
                       ENC_LITTLE_ENDIAN);
@@ -5790,7 +6150,7 @@ add_ff_block_ack_timeout(proto_tree *tree, tvbuff_t *tvb, int offset)
 }
 
 static guint
-add_ff_block_ack_ssc(proto_tree *tree, tvbuff_t *tvb, int offset)
+add_ff_block_ack_ssc(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo _U_, int offset)
 {
   proto_tree_add_bitmask(tree, tvb, offset, hf_ieee80211_ff_block_ack_ssc,
                          ett_ff_ba_ssc_tree, ieee80211_ff_block_ack_ssc_fields,
@@ -5799,7 +6159,7 @@ add_ff_block_ack_ssc(proto_tree *tree, tvbuff_t *tvb, int offset)
 }
 
 static guint
-add_ff_qos_ts_info(proto_tree *tree, tvbuff_t *tvb, int offset)
+add_ff_qos_ts_info(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo _U_, int offset)
 {
   proto_tree_add_bitmask(tree, tvb, offset, hf_ieee80211_tsinfo,
                          ett_tsinfo_tree, ieee80211_tsinfo_fields,
@@ -5808,7 +6168,7 @@ add_ff_qos_ts_info(proto_tree *tree, tvbuff_t *tvb, int offset)
 }
 
 static guint
-add_ff_mesh_action(proto_tree *tree, tvbuff_t *tvb, int offset)
+add_ff_mesh_action(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo _U_, int offset)
 {
   proto_tree_add_item(tree, hf_ieee80211_ff_mesh_action, tvb, offset, 1,
                       ENC_LITTLE_ENDIAN);
@@ -5816,7 +6176,7 @@ add_ff_mesh_action(proto_tree *tree, tvbuff_t *tvb, int offset)
 }
 
 static guint
-add_ff_multihop_action(proto_tree *tree, tvbuff_t *tvb, int offset)
+add_ff_multihop_action(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo _U_, int offset)
 {
   proto_tree_add_item(tree, hf_ieee80211_ff_multihop_action, tvb, offset, 1,
                       ENC_LITTLE_ENDIAN);
@@ -5824,7 +6184,7 @@ add_ff_multihop_action(proto_tree *tree, tvbuff_t *tvb, int offset)
 }
 
 static guint
-add_ff_mesh_control(proto_tree *tree, tvbuff_t *tvb, int offset)
+add_ff_mesh_control(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo _U_, int offset)
 {
   int    start = offset;
   guint8 flags;
@@ -5866,7 +6226,7 @@ add_ff_mesh_control(proto_tree *tree, tvbuff_t *tvb, int offset)
 }
 
 static guint
-add_ff_selfprot_action(proto_tree *tree, tvbuff_t *tvb, int offset)
+add_ff_selfprot_action(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo _U_, int offset)
 {
   proto_tree_add_item(tree, hf_ieee80211_ff_selfprot_action, tvb, offset, 1,
                       ENC_LITTLE_ENDIAN);
@@ -5874,7 +6234,7 @@ add_ff_selfprot_action(proto_tree *tree, tvbuff_t *tvb, int offset)
 }
 
 static guint
-add_ff_dls_action_code(proto_tree *tree, tvbuff_t *tvb, int offset)
+add_ff_dls_action_code(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo _U_, int offset)
 {
   proto_tree_add_item(tree, hf_ieee80211_ff_dls_action_code, tvb, offset, 1,
                       ENC_LITTLE_ENDIAN);
@@ -5882,7 +6242,7 @@ add_ff_dls_action_code(proto_tree *tree, tvbuff_t *tvb, int offset)
 }
 
 static guint
-add_ff_dst_mac_addr(proto_tree *tree, tvbuff_t *tvb, int offset)
+add_ff_dst_mac_addr(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo _U_, int offset)
 {
   proto_tree_add_item(tree, hf_ieee80211_ff_dst_mac_addr, tvb, offset, 6,
                       ENC_NA);
@@ -5890,7 +6250,7 @@ add_ff_dst_mac_addr(proto_tree *tree, tvbuff_t *tvb, int offset)
 }
 
 static guint
-add_ff_src_mac_addr(proto_tree *tree, tvbuff_t *tvb, int offset)
+add_ff_src_mac_addr(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo _U_, int offset)
 {
   proto_tree_add_item(tree, hf_ieee80211_ff_src_mac_addr, tvb, offset, 6,
                       ENC_NA);
@@ -5898,7 +6258,7 @@ add_ff_src_mac_addr(proto_tree *tree, tvbuff_t *tvb, int offset)
 }
 
 static guint
-add_ff_dls_timeout(proto_tree *tree, tvbuff_t *tvb, int offset)
+add_ff_dls_timeout(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo _U_, int offset)
 {
   proto_tree_add_item(tree, hf_ieee80211_ff_dls_timeout, tvb, offset, 2,
                       ENC_LITTLE_ENDIAN);
@@ -5906,7 +6266,7 @@ add_ff_dls_timeout(proto_tree *tree, tvbuff_t *tvb, int offset)
 }
 
 static guint
-add_ff_delba_param_set(proto_tree *tree, tvbuff_t *tvb, int offset)
+add_ff_delba_param_set(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo _U_, int offset)
 {
   proto_tree_add_bitmask(tree, tvb, offset, hf_ieee80211_ff_delba_param,
                          ett_ff_ba_param_tree, ieee80211_ff_delba_param_fields,
@@ -5915,7 +6275,7 @@ add_ff_delba_param_set(proto_tree *tree, tvbuff_t *tvb, int offset)
 }
 
 static guint
-add_ff_max_reg_pwr(proto_tree *tree, tvbuff_t *tvb, int offset)
+add_ff_max_reg_pwr(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo _U_, int offset)
 {
   proto_tree_add_item(tree, hf_ieee80211_ff_max_reg_pwr, tvb, offset, 2,
                       ENC_LITTLE_ENDIAN);
@@ -5923,7 +6283,7 @@ add_ff_max_reg_pwr(proto_tree *tree, tvbuff_t *tvb, int offset)
 }
 
 static guint
-add_ff_measurement_pilot_int(proto_tree *tree, tvbuff_t *tvb, int offset)
+add_ff_measurement_pilot_int(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo _U_, int offset)
 {
   proto_tree_add_item(tree, hf_ieee80211_ff_measurement_pilot_int, tvb, offset,
                       2, ENC_LITTLE_ENDIAN);
@@ -5931,7 +6291,7 @@ add_ff_measurement_pilot_int(proto_tree *tree, tvbuff_t *tvb, int offset)
 }
 
 static guint
-add_ff_country_str(proto_tree *tree, tvbuff_t *tvb, int offset)
+add_ff_country_str(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo _U_, int offset)
 {
   proto_tree_add_item(tree, hf_ieee80211_ff_country_str, tvb, offset, 3,
                       ENC_ASCII|ENC_NA);
@@ -5939,7 +6299,7 @@ add_ff_country_str(proto_tree *tree, tvbuff_t *tvb, int offset)
 }
 
 static guint
-add_ff_max_tx_pwr(proto_tree *tree, tvbuff_t *tvb, int offset)
+add_ff_max_tx_pwr(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo _U_, int offset)
 {
   proto_tree_add_item(tree, hf_ieee80211_ff_max_tx_pwr, tvb, offset, 1,
                       ENC_LITTLE_ENDIAN);
@@ -5947,7 +6307,7 @@ add_ff_max_tx_pwr(proto_tree *tree, tvbuff_t *tvb, int offset)
 }
 
 static guint
-add_ff_tx_pwr_used(proto_tree *tree, tvbuff_t *tvb, int offset)
+add_ff_tx_pwr_used(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo _U_, int offset)
 {
   proto_tree_add_item(tree, hf_ieee80211_ff_tx_pwr_used, tvb, offset, 1,
                       ENC_LITTLE_ENDIAN);
@@ -5955,7 +6315,7 @@ add_ff_tx_pwr_used(proto_tree *tree, tvbuff_t *tvb, int offset)
 }
 
 static guint
-add_ff_transceiver_noise_floor(proto_tree *tree, tvbuff_t *tvb, int offset)
+add_ff_transceiver_noise_floor(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo _U_, int offset)
 {
   proto_tree_add_item(tree, hf_ieee80211_ff_transceiver_noise_floor, tvb,
                       offset, 1, ENC_LITTLE_ENDIAN);
@@ -5963,7 +6323,7 @@ add_ff_transceiver_noise_floor(proto_tree *tree, tvbuff_t *tvb, int offset)
 }
 
 static guint
-add_ff_channel_width(proto_tree *tree, tvbuff_t *tvb, int offset)
+add_ff_channel_width(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo _U_, int offset)
 {
   proto_tree_add_item(tree, hf_ieee80211_ff_channel_width, tvb, offset, 1,
                       ENC_LITTLE_ENDIAN);
@@ -5971,7 +6331,7 @@ add_ff_channel_width(proto_tree *tree, tvbuff_t *tvb, int offset)
 }
 
 static guint
-add_ff_qos_info_ap(proto_tree *tree, tvbuff_t *tvb, int offset)
+add_ff_qos_info_ap(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo _U_, int offset)
 {
   proto_tree_add_bitmask(tree, tvb, offset, hf_ieee80211_ff_qos_info_ap,
                          ett_ff_qos_info, ieee80211_ff_qos_info_ap_fields,
@@ -5980,7 +6340,7 @@ add_ff_qos_info_ap(proto_tree *tree, tvbuff_t *tvb, int offset)
 }
 
 static guint
-add_ff_qos_info_sta(proto_tree *tree, tvbuff_t *tvb, int offset)
+add_ff_qos_info_sta(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo _U_, int offset)
 {
   proto_tree_add_bitmask(tree, tvb, offset, hf_ieee80211_ff_qos_info_sta,
                          ett_ff_qos_info, ieee80211_ff_qos_info_sta_fields,
@@ -5989,7 +6349,7 @@ add_ff_qos_info_sta(proto_tree *tree, tvbuff_t *tvb, int offset)
 }
 
 static guint
-add_ff_sm_pwr_cntrl(proto_tree *tree, tvbuff_t *tvb, int offset)
+add_ff_sm_pwr_cntrl(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo _U_, int offset)
 {
   proto_tree_add_bitmask(tree, tvb, offset, hf_ieee80211_ff_sm_pwr_save,
                          ett_ff_sm_pwr_save, ieee80211_ff_sw_pwr_save_fields,
@@ -5998,7 +6358,7 @@ add_ff_sm_pwr_cntrl(proto_tree *tree, tvbuff_t *tvb, int offset)
 }
 
 static guint
-add_ff_pco_phase_cntrl(proto_tree *tree, tvbuff_t *tvb, int offset)
+add_ff_pco_phase_cntrl(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo _U_, int offset)
 {
   proto_tree_add_item(tree, hf_ieee80211_ff_pco_phase_cntrl, tvb, offset, 1,
                       ENC_LITTLE_ENDIAN);
@@ -6006,7 +6366,7 @@ add_ff_pco_phase_cntrl(proto_tree *tree, tvbuff_t *tvb, int offset)
 }
 
 static guint
-add_ff_psmp_param_set(proto_tree *tree, tvbuff_t *tvb, int offset)
+add_ff_psmp_param_set(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo _U_, int offset)
 {
   proto_tree_add_bitmask(tree, tvb, offset, hf_ieee80211_ff_psmp_param_set,
                          ett_ff_psmp_param_set,
@@ -6016,7 +6376,7 @@ add_ff_psmp_param_set(proto_tree *tree, tvbuff_t *tvb, int offset)
 }
 
 static guint
-add_ff_mimo_cntrl(proto_tree *tree, tvbuff_t *tvb, int offset)
+add_ff_mimo_cntrl(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo _U_, int offset)
 {
   proto_item *mimo_item;
   proto_tree *mimo_tree;
@@ -6051,7 +6411,7 @@ add_ff_mimo_cntrl(proto_tree *tree, tvbuff_t *tvb, int offset)
 }
 
 static guint
-add_ff_ant_selection(proto_tree *tree, tvbuff_t *tvb, int offset)
+add_ff_ant_selection(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo _U_, int offset)
 {
   proto_tree_add_bitmask(tree, tvb, offset, hf_ieee80211_ff_ant_selection,
                          ett_ff_ant_sel, ieee80211_ff_ant_selection_fields,
@@ -6061,7 +6421,7 @@ add_ff_ant_selection(proto_tree *tree, tvbuff_t *tvb, int offset)
 
 static guint
 add_ff_extended_channel_switch_announcement(proto_tree *tree, tvbuff_t *tvb,
-                                            int offset)
+                                            packet_info *pinfo _U_, int offset)
 {
   proto_tree_add_bitmask(tree, tvb, offset,
                          hf_ieee80211_ff_ext_channel_switch_announcement,
@@ -6072,7 +6432,7 @@ add_ff_extended_channel_switch_announcement(proto_tree *tree, tvbuff_t *tvb,
 }
 
 static guint
-add_ff_ht_information(proto_tree *tree, tvbuff_t *tvb, int offset)
+add_ff_ht_information(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo _U_, int offset)
 {
   proto_tree_add_bitmask(tree, tvb, offset, hf_ieee80211_ff_ht_info,
                          ett_ff_ht_info, ieee80211_ff_ht_info_fields,
@@ -6081,7 +6441,7 @@ add_ff_ht_information(proto_tree *tree, tvbuff_t *tvb, int offset)
 }
 
 static guint
-add_ff_ht_action_code(proto_tree *tree, tvbuff_t *tvb, int offset)
+add_ff_ht_action_code(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo _U_, int offset)
 {
   proto_tree_add_item(tree, hf_ieee80211_ff_ht_action, tvb, offset, 1,
                       ENC_LITTLE_ENDIAN);
@@ -6089,7 +6449,7 @@ add_ff_ht_action_code(proto_tree *tree, tvbuff_t *tvb, int offset)
 }
 
 static guint
-add_ff_psmp_sta_info(proto_tree *tree, tvbuff_t *tvb, int offset)
+add_ff_psmp_sta_info(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo _U_, int offset)
 {
   proto_item *psmp_item;
   proto_tree *psmp_tree;
@@ -6154,7 +6514,7 @@ add_ff_psmp_sta_info(proto_tree *tree, tvbuff_t *tvb, int offset)
 }
 
 static guint
-add_ff_schedule_info(proto_tree *tree, tvbuff_t *tvb, int offset)
+add_ff_schedule_info(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo _U_, int offset)
 {
   proto_item *sched_item;
   proto_tree *sched_tree;
@@ -6176,7 +6536,7 @@ add_ff_schedule_info(proto_tree *tree, tvbuff_t *tvb, int offset)
 }
 
 static guint
-add_ff_pa_action_code(proto_tree *tree, tvbuff_t *tvb, int offset)
+add_ff_pa_action_code(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo _U_, int offset)
 {
   proto_tree_add_item(tree, hf_ieee80211_ff_public_action, tvb, offset, 1,
                       ENC_BIG_ENDIAN);
@@ -6184,122 +6544,122 @@ add_ff_pa_action_code(proto_tree *tree, tvbuff_t *tvb, int offset)
 }
 
 static guint
-add_ff_action_spectrum_mgmt(proto_tree *tree, tvbuff_t *tvb, int offset)
+add_ff_action_spectrum_mgmt(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, int offset)
 {
     switch (tvb_get_guint8(tvb, offset + 1)) {
     case SM_ACTION_MEASUREMENT_REQUEST:
     case SM_ACTION_MEASUREMENT_REPORT:
     case SM_ACTION_TPC_REQUEST:
     case SM_ACTION_TPC_REPORT:
-      add_fixed_field(tree, tvb, offset,     FIELD_CATEGORY_CODE);
-      add_fixed_field(tree, tvb, offset + 1, FIELD_ACTION_CODE);
-      add_fixed_field(tree, tvb, offset + 2, FIELD_DIALOG_TOKEN);
+      add_fixed_field(tree, tvb, pinfo, offset,     FIELD_CATEGORY_CODE);
+      add_fixed_field(tree, tvb, pinfo, offset + 1, FIELD_ACTION_CODE);
+      add_fixed_field(tree, tvb, pinfo, offset + 2, FIELD_DIALOG_TOKEN);
       return 3;
     case SM_ACTION_CHAN_SWITCH_ANNC:
     case SM_ACTION_EXT_CHAN_SWITCH_ANNC:
-      add_fixed_field(tree, tvb, offset,     FIELD_CATEGORY_CODE);
-      add_fixed_field(tree, tvb, offset + 1, FIELD_ACTION_CODE);
+      add_fixed_field(tree, tvb, pinfo, offset,     FIELD_CATEGORY_CODE);
+      add_fixed_field(tree, tvb, pinfo, offset + 1, FIELD_ACTION_CODE);
       return 2;
     default:
-      add_fixed_field(tree, tvb, offset,     FIELD_CATEGORY_CODE);
-      add_fixed_field(tree, tvb, offset + 1, FIELD_ACTION_CODE);
+      add_fixed_field(tree, tvb, pinfo, offset,     FIELD_CATEGORY_CODE);
+      add_fixed_field(tree, tvb, pinfo, offset + 1, FIELD_ACTION_CODE);
       return 2;
     }
 }
 
 static guint
-add_ff_action_qos(proto_tree *tree, tvbuff_t *tvb, int offset)
+add_ff_action_qos(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, int offset)
 {
   switch (tvb_get_guint8(tvb, offset + 1)) {
   case SM_ACTION_ADDTS_REQUEST:
-    add_fixed_field(tree, tvb, offset, FIELD_CATEGORY_CODE);
-    add_fixed_field(tree, tvb, offset + 1, FIELD_QOS_ACTION_CODE);
-    add_fixed_field(tree, tvb, offset + 2, FIELD_DIALOG_TOKEN);
+    add_fixed_field(tree, tvb, pinfo, offset, FIELD_CATEGORY_CODE);
+    add_fixed_field(tree, tvb, pinfo, offset + 1, FIELD_QOS_ACTION_CODE);
+    add_fixed_field(tree, tvb, pinfo, offset + 2, FIELD_DIALOG_TOKEN);
     return 3;
   case SM_ACTION_ADDTS_RESPONSE:
-    add_fixed_field(tree, tvb, offset, FIELD_CATEGORY_CODE);
-    add_fixed_field(tree, tvb, offset + 1, FIELD_QOS_ACTION_CODE);
-    add_fixed_field(tree, tvb, offset + 2, FIELD_DIALOG_TOKEN);
-    add_fixed_field(tree, tvb, offset + 3, FIELD_STATUS_CODE);
+    add_fixed_field(tree, tvb, pinfo, offset, FIELD_CATEGORY_CODE);
+    add_fixed_field(tree, tvb, pinfo, offset + 1, FIELD_QOS_ACTION_CODE);
+    add_fixed_field(tree, tvb, pinfo, offset + 2, FIELD_DIALOG_TOKEN);
+    add_fixed_field(tree, tvb, pinfo, offset + 3, FIELD_STATUS_CODE);
     return 5;
   case SM_ACTION_DELTS:
-    add_fixed_field(tree, tvb, offset,     FIELD_CATEGORY_CODE);
-    add_fixed_field(tree, tvb, offset + 1, FIELD_QOS_ACTION_CODE);
-    add_fixed_field(tree, tvb, offset + 2, FIELD_QOS_TS_INFO);
-    add_fixed_field(tree, tvb, offset + 5, FIELD_REASON_CODE);
+    add_fixed_field(tree, tvb, pinfo, offset,     FIELD_CATEGORY_CODE);
+    add_fixed_field(tree, tvb, pinfo, offset + 1, FIELD_QOS_ACTION_CODE);
+    add_fixed_field(tree, tvb, pinfo, offset + 2, FIELD_QOS_TS_INFO);
+    add_fixed_field(tree, tvb, pinfo, offset + 5, FIELD_REASON_CODE);
     return 7;
   case SM_ACTION_QOS_SCHEDULE:
-    add_fixed_field(tree, tvb, offset,     FIELD_CATEGORY_CODE);
-    add_fixed_field(tree, tvb, offset + 1, FIELD_QOS_ACTION_CODE);
+    add_fixed_field(tree, tvb, pinfo, offset,     FIELD_CATEGORY_CODE);
+    add_fixed_field(tree, tvb, pinfo, offset + 1, FIELD_QOS_ACTION_CODE);
     return 2;
   default:
-    add_fixed_field(tree, tvb, offset,     FIELD_CATEGORY_CODE);
+    add_fixed_field(tree, tvb, pinfo, offset,     FIELD_CATEGORY_CODE);
     return 2;
   }
 }
 
 static guint
-add_ff_action_dls(proto_tree *tree, tvbuff_t *tvb, int offset)
+add_ff_action_dls(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, int offset)
 {
   switch (tvb_get_guint8(tvb, offset + 1)) {
   case SM_ACTION_DLS_REQUEST:
-    add_fixed_field(tree, tvb, offset,      FIELD_CATEGORY_CODE);
-    add_fixed_field(tree, tvb, offset +  1, FIELD_DLS_ACTION_CODE);
-    add_fixed_field(tree, tvb, offset +  2, FIELD_DST_MAC_ADDR);
-    add_fixed_field(tree, tvb, offset +  8, FIELD_SRC_MAC_ADDR);
-    add_fixed_field(tree, tvb, offset + 14, FIELD_CAP_INFO);
-    add_fixed_field(tree, tvb, offset + 16, FIELD_DLS_TIMEOUT);
+    add_fixed_field(tree, tvb, pinfo, offset,      FIELD_CATEGORY_CODE);
+    add_fixed_field(tree, tvb, pinfo, offset +  1, FIELD_DLS_ACTION_CODE);
+    add_fixed_field(tree, tvb, pinfo, offset +  2, FIELD_DST_MAC_ADDR);
+    add_fixed_field(tree, tvb, pinfo, offset +  8, FIELD_SRC_MAC_ADDR);
+    add_fixed_field(tree, tvb, pinfo, offset + 14, FIELD_CAP_INFO);
+    add_fixed_field(tree, tvb, pinfo, offset + 16, FIELD_DLS_TIMEOUT);
     return 18;
   case SM_ACTION_DLS_RESPONSE:
-    add_fixed_field(tree, tvb, offset, FIELD_CATEGORY_CODE);
-    add_fixed_field(tree, tvb, offset +  1, FIELD_DLS_ACTION_CODE);
-    add_fixed_field(tree, tvb, offset +  2, FIELD_STATUS_CODE);
-    add_fixed_field(tree, tvb, offset +  4, FIELD_DST_MAC_ADDR);
-    add_fixed_field(tree, tvb, offset + 10, FIELD_SRC_MAC_ADDR);
+    add_fixed_field(tree, tvb, pinfo, offset, FIELD_CATEGORY_CODE);
+    add_fixed_field(tree, tvb, pinfo, offset +  1, FIELD_DLS_ACTION_CODE);
+    add_fixed_field(tree, tvb, pinfo, offset +  2, FIELD_STATUS_CODE);
+    add_fixed_field(tree, tvb, pinfo, offset +  4, FIELD_DST_MAC_ADDR);
+    add_fixed_field(tree, tvb, pinfo, offset + 10, FIELD_SRC_MAC_ADDR);
     if (!hf_ieee80211_ff_status_code) {
-      add_fixed_field(tree, tvb, offset + 16, FIELD_CAP_INFO);
+      add_fixed_field(tree, tvb, pinfo, offset + 16, FIELD_CAP_INFO);
     }
     return 16;
   case SM_ACTION_DLS_TEARDOWN:
-    add_fixed_field(tree, tvb, offset, FIELD_CATEGORY_CODE);
-    add_fixed_field(tree, tvb, offset +  1, FIELD_DLS_ACTION_CODE);
-    add_fixed_field(tree, tvb, offset +  2, FIELD_DST_MAC_ADDR);
-    add_fixed_field(tree, tvb, offset +  8, FIELD_SRC_MAC_ADDR);
-    add_fixed_field(tree, tvb, offset + 14, FIELD_REASON_CODE);
+    add_fixed_field(tree, tvb, pinfo, offset, FIELD_CATEGORY_CODE);
+    add_fixed_field(tree, tvb, pinfo, offset +  1, FIELD_DLS_ACTION_CODE);
+    add_fixed_field(tree, tvb, pinfo, offset +  2, FIELD_DST_MAC_ADDR);
+    add_fixed_field(tree, tvb, pinfo, offset +  8, FIELD_SRC_MAC_ADDR);
+    add_fixed_field(tree, tvb, pinfo, offset + 14, FIELD_REASON_CODE);
     return 16;
   default:
-    add_fixed_field(tree, tvb, offset, FIELD_CATEGORY_CODE);
+    add_fixed_field(tree, tvb, pinfo, offset, FIELD_CATEGORY_CODE);
     return 2;
   }
 }
 
 static guint
-add_ff_action_block_ack(proto_tree *tree, tvbuff_t *tvb, int offset)
+add_ff_action_block_ack(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, int offset)
 {
   guint start = offset;
 
   switch (tvb_get_guint8(tvb, offset + 1)) {
   case BA_ADD_BLOCK_ACK_REQUEST:
-    offset += add_fixed_field(tree, tvb, offset, FIELD_CATEGORY_CODE);
-    offset += add_fixed_field(tree, tvb, offset, FIELD_BLOCK_ACK_ACTION_CODE);
-    offset += add_fixed_field(tree, tvb, offset, FIELD_DIALOG_TOKEN);
-    offset += add_fixed_field(tree, tvb, offset, FIELD_BLOCK_ACK_PARAM);
-    offset += add_fixed_field(tree, tvb, offset, FIELD_BLOCK_ACK_TIMEOUT);
-    offset += add_fixed_field(tree, tvb, offset, FIELD_BLOCK_ACK_SSC);
+    offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_CATEGORY_CODE);
+    offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_BLOCK_ACK_ACTION_CODE);
+    offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_DIALOG_TOKEN);
+    offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_BLOCK_ACK_PARAM);
+    offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_BLOCK_ACK_TIMEOUT);
+    offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_BLOCK_ACK_SSC);
     break;
   case BA_ADD_BLOCK_ACK_RESPONSE:
-    offset += add_fixed_field(tree, tvb, offset, FIELD_CATEGORY_CODE);
-    offset += add_fixed_field(tree, tvb, offset, FIELD_BLOCK_ACK_ACTION_CODE);
-    offset += add_fixed_field(tree, tvb, offset, FIELD_DIALOG_TOKEN);
-    offset += add_fixed_field(tree, tvb, offset, FIELD_STATUS_CODE);
-    offset += add_fixed_field(tree, tvb, offset, FIELD_BLOCK_ACK_PARAM);
-    offset += add_fixed_field(tree, tvb, offset, FIELD_BLOCK_ACK_TIMEOUT);
+    offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_CATEGORY_CODE);
+    offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_BLOCK_ACK_ACTION_CODE);
+    offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_DIALOG_TOKEN);
+    offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_STATUS_CODE);
+    offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_BLOCK_ACK_PARAM);
+    offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_BLOCK_ACK_TIMEOUT);
     break;
   case BA_DELETE_BLOCK_ACK:
-    offset += add_fixed_field(tree, tvb, offset, FIELD_CATEGORY_CODE);
-    offset += add_fixed_field(tree, tvb, offset, FIELD_BLOCK_ACK_ACTION_CODE);
-    offset += add_fixed_field(tree, tvb, offset, FIELD_DELBA_PARAM_SET);
-    offset += add_fixed_field(tree, tvb, offset, FIELD_REASON_CODE);
+    offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_CATEGORY_CODE);
+    offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_BLOCK_ACK_ACTION_CODE);
+    offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_DELBA_PARAM_SET);
+    offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_REASON_CODE);
     break;
   }
 
@@ -6307,7 +6667,7 @@ add_ff_action_block_ack(proto_tree *tree, tvbuff_t *tvb, int offset)
 }
 
 static guint
-add_ff_action_public(proto_tree *tree, tvbuff_t *tvb, int offset)
+add_ff_action_public(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, int offset)
 {
   guint    start = offset;
   guint32  oui;
@@ -6318,13 +6678,13 @@ add_ff_action_public(proto_tree *tree, tvbuff_t *tvb, int offset)
   guint8   frag;
   gboolean more;
 
-  offset += add_fixed_field(tree, tvb, offset, FIELD_CATEGORY_CODE);
+  offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_CATEGORY_CODE);
   code    = tvb_get_guint8(tvb, offset);
-  offset += add_fixed_field(tree, tvb, offset, FIELD_PA_ACTION_CODE);
+  offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_PA_ACTION_CODE);
 
   switch (code) {
   case PA_EXT_CHANNEL_SWITCH_ANNOUNCEMENT:
-    offset += add_ff_extended_channel_switch_announcement(tree, tvb, offset);
+    offset += add_ff_extended_channel_switch_announcement(tree, tvb, pinfo, offset);
     break;
   case PA_VENDOR_SPECIFIC:
     oui = tvb_get_ntoh24(tvb, offset);
@@ -6336,7 +6696,7 @@ add_ff_action_public(proto_tree *tree, tvbuff_t *tvb, int offset)
       proto_tree_add_text(tree, tvb, offset, 1, "Subtype %u", subtype);
       offset += 1;
       if (subtype == WFA_SUBTYPE_P2P) {
-        offset = dissect_wifi_p2p_public_action(g_pinfo, tree, tvb, offset);
+        offset = dissect_wifi_p2p_public_action(pinfo, tree, tvb, offset);
       }
       break;
     default:
@@ -6345,40 +6705,40 @@ add_ff_action_public(proto_tree *tree, tvbuff_t *tvb, int offset)
     }
     break;
   case PA_GAS_INITIAL_REQUEST:
-    offset += add_fixed_field(tree, tvb, offset, FIELD_DIALOG_TOKEN);
-    offset += dissect_advertisement_protocol(g_pinfo, tree, tvb, offset,
+    offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_DIALOG_TOKEN);
+    offset += dissect_advertisement_protocol(pinfo, tree, tvb, offset,
                                              &anqp);
-    offset += dissect_gas_initial_request(tree, tvb, offset, anqp);
+    offset += dissect_gas_initial_request(tree, tvb, pinfo, offset, anqp);
     break;
   case PA_GAS_INITIAL_RESPONSE:
-    offset += add_fixed_field(tree, tvb, offset, FIELD_DIALOG_TOKEN);
-    offset += add_fixed_field(tree, tvb, offset, FIELD_STATUS_CODE);
-    offset += add_fixed_field(tree, tvb, offset, FIELD_GAS_COMEBACK_DELAY);
-    offset += dissect_advertisement_protocol(g_pinfo, tree, tvb, offset,
+    offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_DIALOG_TOKEN);
+    offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_STATUS_CODE);
+    offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_GAS_COMEBACK_DELAY);
+    offset += dissect_advertisement_protocol(pinfo, tree, tvb, offset,
                                              &anqp);
-    offset += dissect_gas_initial_response(tree, tvb, offset, anqp);
+    offset += dissect_gas_initial_response(tree, tvb, pinfo, offset, anqp);
     break;
   case PA_GAS_COMEBACK_REQUEST:
-    offset += add_fixed_field(tree, tvb, offset, FIELD_DIALOG_TOKEN);
+    offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_DIALOG_TOKEN);
     break;
   case PA_GAS_COMEBACK_RESPONSE:
     dialog_token = tvb_get_guint8(tvb, offset);
-    offset += add_fixed_field(tree, tvb, offset, FIELD_DIALOG_TOKEN);
-    offset += add_fixed_field(tree, tvb, offset, FIELD_STATUS_CODE);
+    offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_DIALOG_TOKEN);
+    offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_STATUS_CODE);
     frag = tvb_get_guint8(tvb, offset) & 0x7f;
     more = (tvb_get_guint8(tvb, offset) & 0x80) != 0;
-    offset += add_fixed_field(tree, tvb, offset, FIELD_GAS_FRAGMENT_ID);
-    offset += add_fixed_field(tree, tvb, offset, FIELD_GAS_COMEBACK_DELAY);
-    offset += dissect_advertisement_protocol(g_pinfo, tree, tvb, offset,
+    offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_GAS_FRAGMENT_ID);
+    offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_GAS_COMEBACK_DELAY);
+    offset += dissect_advertisement_protocol(pinfo, tree, tvb, offset,
                                              &anqp);
-    offset += dissect_gas_comeback_response(tree, tvb, offset, anqp, frag,
+    offset += dissect_gas_comeback_response(tree, tvb, pinfo, offset, anqp, frag,
                                             more, dialog_token);
     break;
   case PA_TDLS_DISCOVERY_RESPONSE:
-    col_set_str(g_pinfo->cinfo, COL_PROTOCOL, "TDLS");
-    col_set_str(g_pinfo->cinfo, COL_INFO, "TDLS Discovery Response");
-    offset += add_fixed_field(tree, tvb, offset, FIELD_DIALOG_TOKEN);
-    offset += add_fixed_field(tree, tvb, offset, FIELD_CAP_INFO);
+    col_set_str(pinfo->cinfo, COL_PROTOCOL, "TDLS");
+    col_set_str(pinfo->cinfo, COL_INFO, "TDLS Discovery Response");
+    offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_DIALOG_TOKEN);
+    offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_CAP_INFO);
     break;
   }
 
@@ -6386,36 +6746,36 @@ add_ff_action_public(proto_tree *tree, tvbuff_t *tvb, int offset)
 }
 
 static guint
-add_ff_action_fast_bss_transition(proto_tree *tree, tvbuff_t *tvb, int offset)
+add_ff_action_fast_bss_transition(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, int offset)
 {
   guint  start = offset;
   guint8 code;
 
-  offset += add_fixed_field(tree, tvb, offset, FIELD_CATEGORY_CODE);
+  offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_CATEGORY_CODE);
   code    = tvb_get_guint8(tvb, offset);
-  offset += add_fixed_field(tree, tvb, offset, FIELD_FT_ACTION_CODE);
+  offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_FT_ACTION_CODE);
 
   switch (code) {
   case FT_ACTION_REQUEST:
-    offset += add_fixed_field(tree, tvb, offset, FIELD_STA_ADDRESS);
-    offset += add_fixed_field(tree, tvb, offset, FIELD_TARGET_AP_ADDRESS);
+    offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_STA_ADDRESS);
+    offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_TARGET_AP_ADDRESS);
     /* Followed by FT Request frame body (IEs) */
     break;
   case FT_ACTION_RESPONSE:
-    offset += add_fixed_field(tree, tvb, offset, FIELD_STA_ADDRESS);
-    offset += add_fixed_field(tree, tvb, offset, FIELD_TARGET_AP_ADDRESS);
-    offset += add_fixed_field(tree, tvb, offset, FIELD_STATUS_CODE);
+    offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_STA_ADDRESS);
+    offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_TARGET_AP_ADDRESS);
+    offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_STATUS_CODE);
     /* Followed by FT Response frame body (IEs) */
     break;
   case FT_ACTION_CONFIRM:
-    offset += add_fixed_field(tree, tvb, offset, FIELD_STA_ADDRESS);
-    offset += add_fixed_field(tree, tvb, offset, FIELD_TARGET_AP_ADDRESS);
+    offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_STA_ADDRESS);
+    offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_TARGET_AP_ADDRESS);
     /* Followed by FT Confirm frame body (IEs) */
     break;
   case FT_ACTION_ACK:
-    offset += add_fixed_field(tree, tvb, offset, FIELD_STA_ADDRESS);
-    offset += add_fixed_field(tree, tvb, offset, FIELD_TARGET_AP_ADDRESS);
-    offset += add_fixed_field(tree, tvb, offset, FIELD_STATUS_CODE);
+    offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_STA_ADDRESS);
+    offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_TARGET_AP_ADDRESS);
+    offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_STATUS_CODE);
     /* Followed by FT Ack frame body (IEs) */
     break;
   }
@@ -6424,21 +6784,21 @@ add_ff_action_fast_bss_transition(proto_tree *tree, tvbuff_t *tvb, int offset)
 }
 
 static guint
-add_ff_action_sa_query(proto_tree *tree, tvbuff_t *tvb, int offset)
+add_ff_action_sa_query(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, int offset)
 {
   guint  start = offset;
   guint8 code;
 
-  offset += add_fixed_field(tree, tvb, offset, FIELD_CATEGORY_CODE);
+  offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_CATEGORY_CODE);
   code    = tvb_get_guint8(tvb, offset);
-  offset += add_fixed_field(tree, tvb, offset, FIELD_SA_QUERY_ACTION_CODE);
+  offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_SA_QUERY_ACTION_CODE);
 
   switch (code) {
   case SA_QUERY_REQUEST:
-    offset += add_fixed_field(tree, tvb, offset, FIELD_TRANSACTION_ID);
+    offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_TRANSACTION_ID);
     break;
   case SA_QUERY_RESPONSE:
-    offset += add_fixed_field(tree, tvb, offset, FIELD_TRANSACTION_ID);
+    offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_TRANSACTION_ID);
     break;
   }
 
@@ -6446,49 +6806,49 @@ add_ff_action_sa_query(proto_tree *tree, tvbuff_t *tvb, int offset)
 }
 
 static guint
-add_ff_action_mesh(proto_tree *tree, tvbuff_t *tvb, int offset)
+add_ff_action_mesh(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, int offset)
 {
   guint length;
 
-  offset += add_fixed_field(tree, tvb, offset, FIELD_CATEGORY_CODE);
-  offset += add_fixed_field(tree, tvb, offset, FIELD_MESH_ACTION);
+  offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_CATEGORY_CODE);
+  offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_MESH_ACTION);
   /* The only fixed fields are the category and mesh action.  The rest are IEs.
    */
   length = 2;
   if (tvb_get_guint8(tvb, 1) == MESH_ACTION_TBTT_ADJ_RESPONSE) {
     /* ..except for the TBTT Adjustment Response, which has a status code field
      */
-    length += add_fixed_field(tree, tvb, offset, FIELD_STATUS_CODE);
+    length += add_fixed_field(tree, tvb, pinfo, offset, FIELD_STATUS_CODE);
   }
   return length;
 }
 
 static guint
-add_ff_action_multihop(proto_tree *tree, tvbuff_t *tvb, int offset)
+add_ff_action_multihop(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, int offset)
 {
   guint start = offset;
 
-  offset += add_fixed_field(tree, tvb, offset, FIELD_CATEGORY_CODE);
-  offset += add_fixed_field(tree, tvb, offset, FIELD_MULTIHOP_ACTION);
-  offset += add_fixed_field(tree, tvb, offset, FIELD_MESH_CONTROL);
+  offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_CATEGORY_CODE);
+  offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_MULTIHOP_ACTION);
+  offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_MESH_CONTROL);
   return offset - start;
 }
 
 static guint
-add_ff_action_self_protected(proto_tree *tree, tvbuff_t *tvb, int offset)
+add_ff_action_self_protected(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, int offset)
 {
   guint start = offset;
 
-  offset += add_fixed_field(tree, tvb, offset, FIELD_CATEGORY_CODE);
-  offset += add_fixed_field(tree, tvb, offset, FIELD_SELFPROT_ACTION);
+  offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_CATEGORY_CODE);
+  offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_SELFPROT_ACTION);
 
   switch (tvb_get_guint8(tvb, start + 1)) {
   case SELFPROT_ACTION_MESH_PEERING_OPEN:
-    offset += add_fixed_field(tree, tvb, offset, FIELD_CAP_INFO);
+    offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_CAP_INFO);
     break;
   case SELFPROT_ACTION_MESH_PEERING_CONFIRM:
-    offset += add_fixed_field(tree, tvb, offset, FIELD_CAP_INFO);
-    offset += add_fixed_field(tree, tvb, offset, FIELD_ASSOC_ID);
+    offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_CAP_INFO);
+    offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_ASSOC_ID);
     break;
   }
 
@@ -6496,13 +6856,13 @@ add_ff_action_self_protected(proto_tree *tree, tvbuff_t *tvb, int offset)
 }
 
 static guint
-wnm_bss_trans_mgmt_req(proto_tree *tree, tvbuff_t *tvb, int offset)
+wnm_bss_trans_mgmt_req(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, int offset)
 {
   int    start = offset;
   guint8 mode;
   gint   left;
 
-  offset += add_fixed_field(tree, tvb, offset, FIELD_DIALOG_TOKEN);
+  offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_DIALOG_TOKEN);
 
   mode = tvb_get_guint8(tvb, offset);
   proto_tree_add_item(tree, hf_ieee80211_ff_request_mode_pref_cand,
@@ -6552,17 +6912,88 @@ wnm_bss_trans_mgmt_req(proto_tree *tree, tvbuff_t *tvb, int offset)
 }
 
 static guint
-add_ff_action_wnm(proto_tree *tree, tvbuff_t *tvb, int offset)
+wnm_sleep_mode_req(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, int offset)
+{
+  int start = offset;
+  offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_DIALOG_TOKEN);
+  return offset - start;
+}
+
+static guint
+wnm_sleep_mode_resp(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, int offset)
+{
+  int start = offset;
+  guint16 key_data_len;
+  gint left;
+
+  offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_DIALOG_TOKEN);
+  key_data_len = tvb_get_letohs(tvb, offset);
+  offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_KEY_DATA_LENGTH);
+  left = tvb_reported_length_remaining(tvb, offset);
+  if (left < key_data_len) {
+    expert_add_info_format(pinfo, tree, PI_MALFORMED, PI_ERROR,
+                           "WNM-Sleep Mode Response is not long enough to "
+                           "include Key Data");
+    return offset - start;
+  }
+  proto_tree_add_item(tree, hf_ieee80211_ff_key_data, tvb, offset,
+                      key_data_len, ENC_NA);
+  offset += key_data_len;
+  return offset - start;
+}
+
+static guint
+wnm_tfs_req(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, int offset)
+{
+  int start = offset;
+  offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_DIALOG_TOKEN);
+  return offset - start;
+}
+
+static guint
+wnm_tfs_resp(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, int offset)
+{
+  int start = offset;
+  offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_DIALOG_TOKEN);
+  return offset - start;
+}
+
+static guint
+wnm_notification_req(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, int offset)
+{
+  int start = offset;
+  offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_DIALOG_TOKEN);
+  offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_WNM_NOTIFICATION_TYPE);
+  return offset - start;
+}
+
+static guint
+add_ff_action_wnm(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, int offset)
 {
   guint8 code;
   guint  start = offset;
 
-  offset += add_fixed_field(tree, tvb, offset, FIELD_CATEGORY_CODE);
+  offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_CATEGORY_CODE);
   code    = tvb_get_guint8(tvb, offset);
-  offset += add_fixed_field(tree, tvb, offset, FIELD_WNM_ACTION_CODE);
+  offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_WNM_ACTION_CODE);
   switch (code) {
   case WNM_BSS_TRANS_MGMT_REQ:
-    offset += wnm_bss_trans_mgmt_req(tree, tvb, offset);
+    offset += wnm_bss_trans_mgmt_req(tree, tvb, pinfo, offset);
+    break;
+  case WNM_TFS_REQ:
+    offset += wnm_tfs_req(tree, tvb, pinfo, offset);
+    break;
+  case WNM_TFS_RESP:
+    offset += wnm_tfs_resp(tree, tvb, pinfo, offset);
+    break;
+  case WNM_SLEEP_MODE_REQ:
+    offset += wnm_sleep_mode_req(tree, tvb, pinfo, offset);
+    break;
+  case WNM_SLEEP_MODE_RESP:
+    offset += wnm_sleep_mode_resp(tree, tvb, pinfo, offset);
+    break;
+  case WNM_NOTIFICATION_REQ:
+    offset += wnm_notification_req(tree, tvb, pinfo, offset);
     break;
   }
 
@@ -6570,72 +7001,72 @@ add_ff_action_wnm(proto_tree *tree, tvbuff_t *tvb, int offset)
 }
 
 static guint
-add_ff_action_tdls(proto_tree *tree, tvbuff_t *tvb, int offset)
+add_ff_action_tdls(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, int offset)
 {
   guint8  code;
   guint16 status;
   guint   start = offset;
 
-  offset += add_fixed_field(tree, tvb, offset, FIELD_CATEGORY_CODE);
+  offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_CATEGORY_CODE);
   code = tvb_get_guint8(tvb, offset);
-  offset += add_fixed_field(tree, tvb, offset, FIELD_TDLS_ACTION_CODE);
+  offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_TDLS_ACTION_CODE);
   switch (code) {
   case TDLS_SETUP_REQUEST:
-    offset += add_fixed_field(tree, tvb, offset, FIELD_DIALOG_TOKEN);
-    offset += add_fixed_field(tree, tvb, offset, FIELD_CAP_INFO);
+    offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_DIALOG_TOKEN);
+    offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_CAP_INFO);
     break;
   case TDLS_SETUP_RESPONSE:
     status = tvb_get_letohs(tvb, offset);
-    offset += add_fixed_field(tree, tvb, offset, FIELD_STATUS_CODE);
-    offset += add_fixed_field(tree, tvb, offset, FIELD_DIALOG_TOKEN);
+    offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_STATUS_CODE);
+    offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_DIALOG_TOKEN);
     if (tvb_reported_length_remaining(tvb, offset) < 2) {
       if (status == 0) {
-        expert_add_info_format(g_pinfo, tree, PI_MALFORMED, PI_ERROR,
+        expert_add_info_format(pinfo, tree, PI_MALFORMED, PI_ERROR,
                                "TDLS Setup Response (success) does not "
                                "include mandatory fields");
       }
       break;
     }
-    offset += add_fixed_field(tree, tvb, offset, FIELD_CAP_INFO);
+    offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_CAP_INFO);
     break;
   case TDLS_SETUP_CONFIRM:
     status = tvb_get_letohs(tvb, offset);
-    offset += add_fixed_field(tree, tvb, offset, FIELD_STATUS_CODE);
+    offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_STATUS_CODE);
     if (tvb_reported_length_remaining(tvb, offset) < 1) {
       if (status == 0) {
-        expert_add_info_format(g_pinfo, tree, PI_MALFORMED, PI_ERROR,
+        expert_add_info_format(pinfo, tree, PI_MALFORMED, PI_ERROR,
                                "TDLS Setup Confirm (success) does not include "
                                "mandatory fields");
       }
       break;
     }
-    offset += add_fixed_field(tree, tvb, offset, FIELD_DIALOG_TOKEN);
+    offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_DIALOG_TOKEN);
     break;
   case TDLS_TEARDOWN:
-    offset += add_fixed_field(tree, tvb, offset, FIELD_REASON_CODE);
+    offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_REASON_CODE);
     break;
   case TDLS_PEER_TRAFFIC_INDICATION:
-    offset += add_fixed_field(tree, tvb, offset, FIELD_DIALOG_TOKEN);
+    offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_DIALOG_TOKEN);
     break;
   case TDLS_CHANNEL_SWITCH_REQUEST:
-    offset += add_fixed_field(tree, tvb, offset, FIELD_TARGET_CHANNEL);
-    offset += add_fixed_field(tree, tvb, offset, FIELD_REGULATORY_CLASS);
+    offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_TARGET_CHANNEL);
+    offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_REGULATORY_CLASS);
     break;
   case TDLS_CHANNEL_SWITCH_RESPONSE:
-    offset += add_fixed_field(tree, tvb, offset, FIELD_STATUS_CODE);
+    offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_STATUS_CODE);
     break;
   case TDLS_PEER_PSM_REQUEST:
-    offset += add_fixed_field(tree, tvb, offset, FIELD_DIALOG_TOKEN);
+    offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_DIALOG_TOKEN);
     break;
   case TDLS_PEER_PSM_RESPONSE:
-    offset += add_fixed_field(tree, tvb, offset, FIELD_DIALOG_TOKEN);
-    offset += add_fixed_field(tree, tvb, offset, FIELD_STATUS_CODE);
+    offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_DIALOG_TOKEN);
+    offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_STATUS_CODE);
     break;
   case TDLS_PEER_TRAFFIC_RESPONSE:
-    offset += add_fixed_field(tree, tvb, offset, FIELD_DIALOG_TOKEN);
+    offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_DIALOG_TOKEN);
     break;
   case TDLS_DISCOVERY_REQUEST:
-    offset += add_fixed_field(tree, tvb, offset, FIELD_DIALOG_TOKEN);
+    offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_DIALOG_TOKEN);
     break;
   }
 
@@ -6643,26 +7074,26 @@ add_ff_action_tdls(proto_tree *tree, tvbuff_t *tvb, int offset)
 }
 
 static guint
-add_ff_action_mgmt_notification(proto_tree *tree, tvbuff_t *tvb, int offset)
+add_ff_action_mgmt_notification(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, int offset)
 {
   guint start = offset;
 
-  offset += add_fixed_field(tree, tvb, offset, FIELD_CATEGORY_CODE);
-  offset += add_fixed_field(tree, tvb, offset, FIELD_WME_ACTION_CODE);
-  offset += add_fixed_field(tree, tvb, offset, FIELD_DIALOG_TOKEN);
-  offset += add_fixed_field(tree, tvb, offset, FIELD_WME_STATUS_CODE);
+  offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_CATEGORY_CODE);
+  offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_WME_ACTION_CODE);
+  offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_DIALOG_TOKEN);
+  offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_WME_STATUS_CODE);
 
   return offset - start;  /* Size of fixed fields */
 }
 
 static guint
-add_ff_action_vendor_specific(proto_tree *tree, tvbuff_t *tvb, int offset)
+add_ff_action_vendor_specific(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, int offset)
 {
   guint   start = offset;
   guint32 oui;
   guint8  subtype;
 
-  offset += add_fixed_field(tree, tvb, offset, FIELD_CATEGORY_CODE);
+  offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_CATEGORY_CODE);
   oui = tvb_get_ntoh24(tvb, offset);
   proto_tree_add_item(tree, hf_ieee80211_tag_oui, tvb, offset, 3, ENC_NA);
   offset += 3;
@@ -6687,55 +7118,55 @@ add_ff_action_vendor_specific(proto_tree *tree, tvbuff_t *tvb, int offset)
 }
 
 static guint
-add_ff_action_ht(proto_tree *tree, tvbuff_t *tvb, int offset)
+add_ff_action_ht(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, int offset)
 {
   guint  start = offset;
   guint8 n_sta, i;
   mimo_control_t mimo_cntrl;
 
-  offset += add_fixed_field(tree, tvb, offset, FIELD_CATEGORY_CODE);
-  offset += add_fixed_field(tree, tvb, offset, FIELD_HT_ACTION_CODE);
+  offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_CATEGORY_CODE);
+  offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_HT_ACTION_CODE);
 
   switch (tvb_get_guint8(tvb, offset - 1)) {
   case HT_ACTION_NOTIFY_CHAN_WIDTH:
-    offset += add_fixed_field(tree, tvb, offset, FIELD_CHANNEL_WIDTH);
+    offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_CHANNEL_WIDTH);
     break;
   case HT_ACTION_SM_PWR_SAVE:
-    offset += add_fixed_field(tree, tvb, offset, FIELD_SM_PWR_CNTRL);
+    offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_SM_PWR_CNTRL);
     break;
   case HT_ACTION_PSMP_ACTION:
     n_sta = tvb_get_guint8(tvb, offset);
-    offset += add_fixed_field(tree, tvb, offset, FIELD_PSMP_PARAM_SET);
+    offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_PSMP_PARAM_SET);
     for (i = 0; i < (n_sta & 0x0F); i++) {
-      offset += add_fixed_field(tree, tvb, offset, FIELD_PSMP_STA_INFO);
+      offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_PSMP_STA_INFO);
     }
     break;
   case HT_ACTION_SET_PCO_PHASE:
-    offset += add_fixed_field(tree, tvb, offset, FIELD_PCO_PHASE_CNTRL);
+    offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_PCO_PHASE_CNTRL);
     break;
   case HT_ACTION_MIMO_CSI:
     mimo_cntrl = get_mimo_control(tvb, offset);
-    offset += add_fixed_field(tree, tvb, offset, FIELD_MIMO_CNTRL);
+    offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_MIMO_CNTRL);
     offset += add_mimo_csi_matrices_report(tree, tvb, offset, mimo_cntrl);
     break;
   case HT_ACTION_MIMO_BEAMFORMING:
     mimo_cntrl = get_mimo_control(tvb, offset);
-    offset += add_fixed_field(tree, tvb, offset, FIELD_MIMO_CNTRL);
+    offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_MIMO_CNTRL);
     offset += add_mimo_beamforming_feedback_report(tree, tvb, offset,
                                                    mimo_cntrl);
     break;
   case HT_ACTION_MIMO_COMPRESSED_BEAMFORMING:
     mimo_cntrl = get_mimo_control(tvb, offset);
-    offset += add_fixed_field(tree, tvb, offset, FIELD_MIMO_CNTRL);
+    offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_MIMO_CNTRL);
     offset += add_mimo_compressed_beamforming_feedback_report(tree, tvb,
                                                               offset,
                                                               mimo_cntrl);
     break;
   case HT_ACTION_ANT_SEL_FEEDBACK:
-    offset += add_fixed_field(tree, tvb, offset, FIELD_ANT_SELECTION);
+    offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_ANT_SELECTION);
     break;
   case HT_ACTION_HT_INFO_EXCHANGE:
-    offset += add_fixed_field(tree, tvb, offset, FIELD_HT_INFORMATION);
+    offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_HT_INFORMATION);
     break;
   }
 
@@ -6743,47 +7174,47 @@ add_ff_action_ht(proto_tree *tree, tvbuff_t *tvb, int offset)
 }
 
 static guint
-add_ff_action(proto_tree *tree, tvbuff_t *tvb, int offset)
+add_ff_action(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, int offset)
 {
   switch (tvb_get_guint8(tvb, offset) & 0x7f) {
   case CAT_SPECTRUM_MGMT:
-    return add_ff_action_spectrum_mgmt(tree, tvb, offset);
+    return add_ff_action_spectrum_mgmt(tree, tvb, pinfo, offset);
   case CAT_QOS:
-    return add_ff_action_qos(tree, tvb, offset);
+    return add_ff_action_qos(tree, tvb, pinfo, offset);
   case CAT_DLS:
-    return add_ff_action_dls(tree, tvb, offset);
+    return add_ff_action_dls(tree, tvb, pinfo, offset);
   case CAT_BLOCK_ACK:
-    return add_ff_action_block_ack(tree, tvb, offset);
+    return add_ff_action_block_ack(tree, tvb, pinfo, offset);
   case CAT_PUBLIC:
-    return add_ff_action_public(tree, tvb, offset);
+    return add_ff_action_public(tree, tvb, pinfo, offset);
   case CAT_FAST_BSS_TRANSITION:
-    return add_ff_action_fast_bss_transition(tree, tvb, offset);
+    return add_ff_action_fast_bss_transition(tree, tvb, pinfo, offset);
   case CAT_SA_QUERY:
-    return add_ff_action_sa_query(tree, tvb, offset);
+    return add_ff_action_sa_query(tree, tvb, pinfo, offset);
   case CAT_MESH:
-    return add_ff_action_mesh(tree, tvb, offset);
+    return add_ff_action_mesh(tree, tvb, pinfo, offset);
   case CAT_MULTIHOP:
-    return add_ff_action_multihop(tree, tvb, offset);
+    return add_ff_action_multihop(tree, tvb, pinfo, offset);
   case CAT_SELF_PROTECTED:
-    return add_ff_action_self_protected(tree, tvb, offset);
+    return add_ff_action_self_protected(tree, tvb, pinfo, offset);
   case CAT_WNM:
-    return add_ff_action_wnm(tree, tvb, offset);
+    return add_ff_action_wnm(tree, tvb, pinfo, offset);
   case CAT_TDLS:
-    return add_ff_action_tdls(tree, tvb, offset);
+    return add_ff_action_tdls(tree, tvb, pinfo, offset);
   case CAT_MGMT_NOTIFICATION:  /* Management notification frame */
-    return add_ff_action_mgmt_notification(tree, tvb, offset);
+    return add_ff_action_mgmt_notification(tree, tvb, pinfo, offset);
   case CAT_VENDOR_SPECIFIC:  /* Vendor Specific Category */
-    return add_ff_action_vendor_specific(tree, tvb, offset);
+    return add_ff_action_vendor_specific(tree, tvb, pinfo, offset);
   case CAT_HT:
-    return add_ff_action_ht(tree, tvb, offset);
+    return add_ff_action_ht(tree, tvb, pinfo, offset);
   default:
-    add_fixed_field(tree, tvb, offset, FIELD_CATEGORY_CODE);
+    add_fixed_field(tree, tvb, pinfo, offset, FIELD_CATEGORY_CODE);
     return 1;
   }
 }
 
 static guint
-add_ff_ft_action_code(proto_tree *tree, tvbuff_t *tvb, int offset)
+add_ff_ft_action_code(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo _U_, int offset)
 {
   proto_tree_add_item(tree, hf_ieee80211_ff_ft_action_code, tvb, offset, 1,
                       ENC_BIG_ENDIAN);
@@ -6791,7 +7222,7 @@ add_ff_ft_action_code(proto_tree *tree, tvbuff_t *tvb, int offset)
 }
 
 static guint
-add_ff_sta_address(proto_tree *tree, tvbuff_t *tvb, int offset)
+add_ff_sta_address(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo _U_, int offset)
 {
   proto_tree_add_item(tree, hf_ieee80211_ff_sta_address, tvb, offset, 6,
                       ENC_NA);
@@ -6799,7 +7230,7 @@ add_ff_sta_address(proto_tree *tree, tvbuff_t *tvb, int offset)
 }
 
 static guint
-add_ff_target_ap_address(proto_tree *tree, tvbuff_t *tvb, int offset)
+add_ff_target_ap_address(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo _U_, int offset)
 {
   proto_tree_add_item(tree, hf_ieee80211_ff_target_ap_address, tvb, offset, 6,
                       ENC_NA);
@@ -6807,7 +7238,7 @@ add_ff_target_ap_address(proto_tree *tree, tvbuff_t *tvb, int offset)
 }
 
 static guint
-add_ff_gas_comeback_delay(proto_tree *tree, tvbuff_t *tvb, int offset)
+add_ff_gas_comeback_delay(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo _U_, int offset)
 {
   proto_tree_add_item(tree, hf_ieee80211_ff_gas_comeback_delay, tvb, offset, 2,
                       ENC_LITTLE_ENDIAN);
@@ -6815,7 +7246,7 @@ add_ff_gas_comeback_delay(proto_tree *tree, tvbuff_t *tvb, int offset)
 }
 
 static guint
-add_ff_gas_fragment_id(proto_tree *tree, tvbuff_t *tvb, int offset)
+add_ff_gas_fragment_id(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo _U_, int offset)
 {
   proto_tree_add_item(tree, hf_ieee80211_ff_gas_fragment_id, tvb, offset, 1,
                       ENC_BIG_ENDIAN);
@@ -6825,7 +7256,7 @@ add_ff_gas_fragment_id(proto_tree *tree, tvbuff_t *tvb, int offset)
 }
 
 static guint
-add_ff_sa_query_action_code(proto_tree *tree, tvbuff_t *tvb, int offset)
+add_ff_sa_query_action_code(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo _U_, int offset)
 {
   proto_tree_add_item(tree, hf_ieee80211_ff_sa_query_action_code, tvb, offset,
                       1, ENC_BIG_ENDIAN);
@@ -6833,7 +7264,7 @@ add_ff_sa_query_action_code(proto_tree *tree, tvbuff_t *tvb, int offset)
 }
 
 static guint
-add_ff_transaction_id(proto_tree *tree, tvbuff_t *tvb, int offset)
+add_ff_transaction_id(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo _U_, int offset)
 {
   proto_tree_add_item(tree, hf_ieee80211_ff_transaction_id, tvb, offset, 2,
                       ENC_LITTLE_ENDIAN);
@@ -6841,11 +7272,11 @@ add_ff_transaction_id(proto_tree *tree, tvbuff_t *tvb, int offset)
 }
 
 static guint
-add_ff_tdls_action_code(proto_tree *tree, tvbuff_t *tvb, int offset)
+add_ff_tdls_action_code(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, int offset)
 {
   guint8 code;
   code = tvb_get_guint8(tvb, offset);
-  col_set_str(g_pinfo->cinfo, COL_INFO,
+  col_set_str(pinfo->cinfo, COL_INFO,
               val_to_str_ext_const(code, &tdls_action_codes_ext,
                                    "Unknown TDLS Action"));
   proto_tree_add_item(tree, hf_ieee80211_ff_tdls_action_code, tvb, offset, 1,
@@ -6854,7 +7285,7 @@ add_ff_tdls_action_code(proto_tree *tree, tvbuff_t *tvb, int offset)
 }
 
 static guint
-add_ff_target_channel(proto_tree *tree, tvbuff_t *tvb, int offset)
+add_ff_target_channel(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo _U_, int offset)
 {
   proto_tree_add_item(tree, hf_ieee80211_ff_target_channel, tvb, offset, 1,
                       ENC_BIG_ENDIAN);
@@ -6862,7 +7293,7 @@ add_ff_target_channel(proto_tree *tree, tvbuff_t *tvb, int offset)
 }
 
 static guint
-add_ff_regulatory_class(proto_tree *tree, tvbuff_t *tvb, int offset)
+add_ff_regulatory_class(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo _U_, int offset)
 {
   proto_tree_add_item(tree, hf_ieee80211_ff_regulatory_class, tvb, offset, 1,
                       ENC_BIG_ENDIAN);
@@ -6870,22 +7301,38 @@ add_ff_regulatory_class(proto_tree *tree, tvbuff_t *tvb, int offset)
 }
 
 static guint
-add_ff_wnm_action_code(proto_tree *tree, tvbuff_t *tvb, int offset)
+add_ff_wnm_action_code(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, int offset)
 {
   guint8 code;
 
   code = tvb_get_guint8(tvb, offset);
-  col_set_str(g_pinfo->cinfo, COL_INFO,
+  col_set_str(pinfo->cinfo, COL_INFO,
               val_to_str_ext_const(code, &wnm_action_codes_ext, "Unknown WNM Action"));
   proto_tree_add_item(tree, hf_ieee80211_ff_wnm_action_code, tvb, offset, 1, ENC_BIG_ENDIAN);
   return 1;
 }
 
+static guint
+add_ff_key_data_length(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo _U_, int offset)
+{
+  proto_tree_add_item(tree, hf_ieee80211_ff_key_data_length, tvb, offset, 2,
+                      ENC_LITTLE_ENDIAN);
+  return 2;
+}
+
 struct ieee80211_fixed_field_dissector {
   enum fixed_field lfcode;
-  guint (*dissector)(proto_tree *tree, tvbuff_t *tvb, int offset);
+  guint (*dissector)(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, int offset);
 };
 
+static guint
+add_ff_wnm_notification_type(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo _U_, int offset)
+{
+  proto_tree_add_item(tree, hf_ieee80211_ff_wnm_notification_type,
+                      tvb, offset, 1, ENC_NA);
+  return 1;
+}
+
 #define FF_FIELD(f, func) { FIELD_ ## f, add_ff_ ## func }
 
 static const struct ieee80211_fixed_field_dissector ff_dissectors[] = {
@@ -6951,19 +7398,21 @@ static const struct ieee80211_fixed_field_dissector ff_dissectors[] = {
   FF_FIELD(TARGET_CHANNEL                        , target_channel),
   FF_FIELD(REGULATORY_CLASS                      , regulatory_class),
   FF_FIELD(WNM_ACTION_CODE                       , wnm_action_code),
+  FF_FIELD(KEY_DATA_LENGTH                       , key_data_length),
+  FF_FIELD(WNM_NOTIFICATION_TYPE                 , wnm_notification_type),
   { (enum fixed_field)-1                         , NULL }
 };
 
 #undef FF_FIELD
 
 static guint
-add_fixed_field(proto_tree *tree, tvbuff_t *tvb, int offset,
+add_fixed_field(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, int offset,
                 enum fixed_field lfcode)
 {
   int i;
   for (i = 0; ff_dissectors[i].dissector; i++) {
     if (ff_dissectors[i].lfcode == lfcode) {
-      return ff_dissectors[i].dissector(tree, tvb, offset);
+      return ff_dissectors[i].dissector(tree, tvb, pinfo, offset);
     }
   }
   return 0;
@@ -7272,7 +7721,7 @@ static const value_string ft_subelem_id_vals[] = {
 };
 
 static int
-dissect_qos_info(proto_tree *tree, tvbuff_t *tvb, int offset, int ftype)
+dissect_qos_info(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, int offset, int ftype)
 {
   proto_tree *qos_info_tree;
   proto_item *qos_info_item;
@@ -7306,7 +7755,7 @@ dissect_qos_info(proto_tree *tree, tvbuff_t *tvb, int offset, int ftype)
       break;
     }
     default:
-        expert_add_info_format(g_pinfo, qos_info_item, PI_UNDECODED, PI_WARN, "Could not deduce direction to decode correctly, ftype %u", ftype);
+        expert_add_info_format(pinfo, qos_info_item, PI_UNDECODED, PI_WARN, "Could not deduce direction to decode correctly, ftype %u", ftype);
       break;
     }
 
@@ -7315,7 +7764,7 @@ dissect_qos_info(proto_tree *tree, tvbuff_t *tvb, int offset, int ftype)
 }
 
 static int
-dissect_vendor_ie_wpawme(proto_tree *tree, tvbuff_t *tvb, int offset, guint32 tag_len, int ftype)
+dissect_vendor_ie_wpawme(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, int offset, guint32 tag_len, int ftype)
 {
   guint8 type;
 
@@ -7414,14 +7863,14 @@ dissect_vendor_ie_wpawme(proto_tree *tree, tvbuff_t *tvb, int offset, guint32 ta
         case 0: /* WME Information Element */
         {
           /* WME QoS Info Field */
-          offset = dissect_qos_info(tree, tvb, offset, ftype);
+          offset = dissect_qos_info(tree, tvb, pinfo, offset, ftype);
           break;
         }
         case 1: /* WME Parameter Element */
         {
           int i;
           /* WME QoS Info Field */
-          offset = dissect_qos_info(tree, tvb, offset, ftype);
+          offset = dissect_qos_info(tree, tvb, pinfo, offset, ftype);
           proto_tree_add_item(tree, hf_ieee80211_wfa_ie_wme_reserved, tvb, offset, 1, ENC_NA);
           offset += 1;
           /* AC Parameters */
@@ -7545,6 +7994,13 @@ dissect_vendor_ie_wpawme(proto_tree *tree, tvbuff_t *tvb, int offset, guint32 ta
   return offset;
 }
 
+static void dissect_hs20_indication(proto_tree *tree, tvbuff_t *tvb,
+                                    int offset)
+{
+  proto_tree_add_item(tree, hf_hs20_indication_dgaf_disabled, tvb, offset, 1,
+                      ENC_LITTLE_ENDIAN);
+}
+
 static void
 dissect_vendor_ie_wfa(packet_info *pinfo, proto_item *item, tvbuff_t *tag_tvb)
 {
@@ -7558,6 +8014,14 @@ dissect_vendor_ie_wfa(packet_info *pinfo, proto_item *item, tvbuff_t *tag_tvb)
     dissect_wifi_p2p_ie(pinfo, item, tag_tvb, 4, tag_len - 4);
     proto_item_append_text(item, ": P2P");
     break;
+  case WFA_SUBTYPE_WIFI_DISPLAY:
+    dissect_wifi_display_ie(pinfo, item, tag_tvb, 4, tag_len - 4);
+    proto_item_append_text(item, ": Wi-Fi Display");
+    break;
+  case WFA_SUBTYPE_HS20_INDICATION:
+    dissect_hs20_indication(item, tag_tvb, 4);
+    proto_item_append_text(item, ": Hotspot 2.0 Indication");
+    break;
   }
 }
 
@@ -7882,7 +8346,7 @@ dissect_vendor_ie_aruba(proto_item *item, proto_tree *ietree,
 
 /* 802.11e 7.3.2.33 QoS Capability element */
 static int
-dissect_qos_capability(proto_tree *tree, tvbuff_t *tvb, int offset, int ftype)
+dissect_qos_capability(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, int offset, int ftype)
 {
   proto_item *cap_info_item;
   proto_tree *cap_info_tree;
@@ -7918,7 +8382,7 @@ dissect_qos_capability(proto_tree *tree, tvbuff_t *tvb, int offset, int ftype)
       break;
     }
     default:
-        expert_add_info_format(g_pinfo, cap_info_item, PI_UNDECODED, PI_WARN, "Could not deduce direction to decode correctly, ftype %u", ftype);
+        expert_add_info_format(pinfo, cap_info_item, PI_UNDECODED, PI_WARN, "Could not deduce direction to decode correctly, ftype %u", ftype);
       break;
   }
 
@@ -8521,6 +8985,37 @@ dissect_mmie(proto_tree *tree, tvbuff_t *tvb, int offset, guint32 tag_len)
                       ENC_NA);
 }
 
+static void
+dissect_ssid_list(proto_tree *tree, tvbuff_t *tvb, int offset, guint32 tag_len)
+{
+  int end = offset + tag_len;
+  proto_item *ssid;
+  proto_tree *entry;
+  gboolean first = TRUE;
+
+  while (offset + 1 <= end) {
+    guint8 len = tvb_get_guint8(tvb, offset + 1);
+    guint8 *str;
+
+    if (offset + 2 + len > end)
+      break;
+
+    str = tvb_get_ephemeral_string(tvb, offset + 2, len);
+    proto_item_append_text(tree, "%c %s", (first ? ':' : ','), str);
+    first = FALSE;
+    ssid = proto_tree_add_text(tree, tvb, offset, 2 + len, "SSID: %s", str);
+    entry = proto_item_add_subtree(ssid, ett_ssid_list);
+    proto_tree_add_item(entry, hf_ieee80211_tag_number, tvb, offset, 1,
+                        ENC_BIG_ENDIAN);
+    offset++;
+    proto_tree_add_uint(entry, hf_ieee80211_tag_length, tvb, offset, 1, len);
+    offset++;
+    proto_tree_add_item(entry, hf_ieee80211_tag_ssid, tvb, offset, len,
+                        ENC_ASCII|ENC_NA);
+    offset += len;
+  }
+}
+
 static void
 dissect_link_identifier(proto_tree *tree, tvbuff_t *tvb, int offset,
                         guint32 tag_len)
@@ -8633,7 +9128,7 @@ dissect_pu_buffer_status(proto_tree *tree, tvbuff_t *tvb, int offset,
 }
 
 static void
-dissect_timeout_interval(proto_tree *tree, tvbuff_t *tvb, int offset,
+dissect_timeout_interval(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, int offset,
                          guint32 tag_len)
 {
   proto_item *pi;
@@ -8641,7 +9136,7 @@ dissect_timeout_interval(proto_tree *tree, tvbuff_t *tvb, int offset,
   pi = proto_tree_add_item(tree, hf_ieee80211_tag_timeout_int_type, tvb,
                            offset, 1, ENC_BIG_ENDIAN);
   if (tag_len < 5) {
-    expert_add_info_format(g_pinfo, pi, PI_MALFORMED, PI_ERROR,
+    expert_add_info_format(pinfo, pi, PI_MALFORMED, PI_ERROR,
                            "Timeout Interval content length must be at least "
                           "5 bytes");
     return;
@@ -8986,6 +9481,199 @@ dissect_wapi_param_set(tvbuff_t *tvb, packet_info *pinfo,
   return offset;
 }
 
+static int dissect_bss_max_idle_period(proto_tree *tree, tvbuff_t *tvb,
+                                       int offset)
+{
+  proto_tree_add_item(tree, hf_ieee80211_tag_bss_max_idle_period,
+                      tvb, offset, 2, ENC_LITTLE_ENDIAN);
+  offset += 2;
+  proto_tree_add_item(tree, hf_ieee80211_tag_bss_max_idle_options_protected,
+                      tvb, offset, 1, ENC_LITTLE_ENDIAN);
+  offset++;
+  return offset;
+}
+
+static int add_tagged_field(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb,
+                            int offset, int ftype);
+
+enum tfs_request_subelem_id {
+  TFS_REQ_SUBELEM_TFS = 1,
+  TFS_REQ_SUBELEM_VENDOR_SPECIFIC = 221
+};
+
+static const value_string tfs_request_subelem_ids[] = {
+  { TFS_REQ_SUBELEM_TFS, "TFS subelement" },
+  { TFS_REQ_SUBELEM_VENDOR_SPECIFIC, "Vendor Specific subelement" },
+  { 0, NULL }
+};
+
+static int dissect_tfs_request(packet_info *pinfo, proto_tree *tree,
+                               tvbuff_t *tvb, int offset, guint32 tag_len,
+                               int ftype)
+{
+  int end = offset + tag_len;
+
+  proto_tree_add_item(tree, hf_ieee80211_tag_tfs_request_id,
+                      tvb, offset, 1, ENC_LITTLE_ENDIAN);
+  offset++;
+  proto_tree_add_item(tree, hf_ieee80211_tag_tfs_request_ac_delete_after_match,
+                      tvb, offset, 1, ENC_LITTLE_ENDIAN);
+  proto_tree_add_item(tree, hf_ieee80211_tag_tfs_request_ac_notify,
+                      tvb, offset, 1, ENC_LITTLE_ENDIAN);
+  offset++;
+  if (offset + 1 >= end) {
+    expert_add_info_format(pinfo, tree, PI_MALFORMED, PI_WARN,
+                           "No TFS Request subelements in TFS Request");
+    return end;
+  }
+
+  while (offset + 1 < end) {
+    guint8 id, len;
+    int s_offset, s_end;
+
+    id = tvb_get_guint8(tvb, offset);
+    proto_tree_add_item(tree, hf_ieee80211_tag_tfs_request_subelem_id,
+                        tvb, offset, 1, ENC_LITTLE_ENDIAN);
+    offset++;
+    len = tvb_get_guint8(tvb, offset);
+    proto_tree_add_item(tree, hf_ieee80211_tag_tfs_request_subelem_len,
+                        tvb, offset, 1, ENC_LITTLE_ENDIAN);
+    offset++;
+    if (offset + len > end) {
+      expert_add_info_format(pinfo, tree, PI_MALFORMED, PI_ERROR,
+                             "Not enough data for TFS Request subelement");
+      return end;
+    }
+    switch (id) {
+    case TFS_REQ_SUBELEM_TFS:
+      s_offset = offset;
+      s_end = offset + len;
+      while (s_offset < s_end) {
+        int tlen = add_tagged_field(pinfo, tree, tvb, s_offset, ftype);
+        s_offset += tlen;
+      }
+      break;
+    default:
+      proto_tree_add_item(tree, hf_ieee80211_tag_tfs_request_subelem,
+                          tvb, offset, len, ENC_NA);
+      break;
+    }
+    offset += len;
+  }
+
+  if (offset < end) {
+    proto_tree_add_text(tree, tvb, offset, end - offset,
+                        "Unexpected extra data");
+    expert_add_info_format(pinfo, tree, PI_MALFORMED, PI_WARN,
+                           "Extra data after TFS Subelements");
+  }
+
+  return end;
+}
+
+enum tfs_response_subelem_id {
+  TFS_RESP_SUBELEM_TFS_STATUS = 1,
+  TFS_RESP_SUBELEM_TFS = 2,
+  TFS_RESP_SUBELEM_VENDOR_SPECIFIC = 221
+};
+
+static const value_string tfs_response_subelem_ids[] = {
+  { TFS_RESP_SUBELEM_TFS_STATUS, "TFS Status subelement" },
+  { TFS_RESP_SUBELEM_TFS, "TFS subelement" },
+  { TFS_RESP_SUBELEM_VENDOR_SPECIFIC, "Vendor Specific subelement" },
+  { 0, NULL }
+};
+
+static int dissect_tfs_response(packet_info *pinfo, proto_tree *tree,
+                                tvbuff_t *tvb, int offset, guint32 tag_len,
+                                int ftype)
+{
+  int end = offset + tag_len;
+
+  while (offset + 3 <= end) {
+    guint8 id, len;
+    int s_offset, s_end;
+
+    id = tvb_get_guint8(tvb, offset);
+    proto_tree_add_item(tree, hf_ieee80211_tag_tfs_response_subelem_id,
+                        tvb, offset, 1, ENC_LITTLE_ENDIAN);
+    offset++;
+    len = tvb_get_guint8(tvb, offset);
+    proto_tree_add_item(tree, hf_ieee80211_tag_tfs_response_subelem_len,
+                        tvb, offset, 1, ENC_LITTLE_ENDIAN);
+    offset++;
+    if (offset + len > end) {
+      expert_add_info_format(pinfo, tree, PI_MALFORMED, PI_ERROR,
+                             "Not enough data for TFS Request subelement");
+      return end;
+    }
+    switch (id) {
+    case TFS_RESP_SUBELEM_TFS_STATUS:
+      proto_tree_add_item(tree, hf_ieee80211_tag_tfs_response_status,
+                          tvb, offset, 1, ENC_LITTLE_ENDIAN);
+      proto_tree_add_item(tree, hf_ieee80211_tag_tfs_response_id,
+                          tvb, offset + 1, 1, ENC_LITTLE_ENDIAN);
+      break;
+    case TFS_RESP_SUBELEM_TFS:
+      s_offset = offset;
+      s_end = offset + len;
+      while (s_offset < s_end) {
+        int tlen = add_tagged_field(pinfo, tree, tvb, s_offset, ftype);
+        s_offset += tlen;
+      }
+      break;
+    default:
+      proto_tree_add_item(tree, hf_ieee80211_tag_tfs_response_subelem,
+                          tvb, offset, len, ENC_NA);
+      break;
+    }
+
+    offset += len;
+  }
+
+  if (offset < end) {
+    proto_tree_add_text(tree, tvb, offset, end - offset,
+                        "Unexpected extra data");
+    expert_add_info_format(pinfo, tree, PI_MALFORMED, PI_WARN,
+                           "Extra data after TFS Status subelements");
+  }
+
+  return end;
+}
+
+static const value_string wnm_sleep_mode_action_types[] = {
+  { 0, "Enter WNM-Sleep Mode" },
+  { 1, "Exit WNM-Sleep Mode" },
+  { 0, NULL }
+};
+
+static const value_string wnm_sleep_mode_response_status_vals[] = {
+  { 0, "Enter/Exit WNM-Sleep Mode Accept" },
+  { 1, "Exit WNM-Sleep Mode Accept, GTK/IGTK update required" },
+  { 2, "Denied. The AP is unable to perform the requested action." },
+  { 3, "Denied temporarily. The AP is unable to perform the requested action "
+    "at the current time. The request can be submitted again at a later time."
+  },
+  { 4, "Denied. Due to the pending key expiration." },
+  { 5, "Denied. The requested action was not granted due to other WNM services "
+    "in use by the requesting STA." },
+  { 0, NULL }
+};
+
+static int dissect_wnm_sleep_mode(proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+  proto_tree_add_item(tree, hf_ieee80211_tag_wnm_sleep_mode_action_type,
+                      tvb, offset, 1, ENC_LITTLE_ENDIAN);
+  offset++;
+  proto_tree_add_item(tree, hf_ieee80211_tag_wnm_sleep_mode_response_status,
+                      tvb, offset, 1, ENC_LITTLE_ENDIAN);
+  offset++;
+  proto_tree_add_item(tree, hf_ieee80211_tag_wnm_sleep_mode_interval,
+                      tvb, offset, 2, ENC_LITTLE_ENDIAN);
+  offset += 2;
+  return offset;
+}
+
 static const value_string time_adv_timing_capab_vals[] = {
   { 0, "No standardized external time source" },
   { 1, "Timestamp offset based on UTC" },
@@ -9901,7 +10589,6 @@ dissect_roaming_consortium(packet_info *pinfo, proto_tree *tree,
 /*           Dissect and add tagged (optional) fields to proto tree          */
 /* ************************************************************************* */
 
-
 static int beacon_padding = 0; /* beacon padding bug */
 
 static int
@@ -10442,7 +11129,7 @@ add_tagged_field(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset
       }
       offset += 2;
 
-      add_fixed_field(tree, tvb, offset, FIELD_QOS_TS_INFO);
+      add_fixed_field(tree, tvb, pinfo, offset, FIELD_QOS_TS_INFO);
       offset += 3;
 
       proto_tree_add_item(tree, hf_ieee80211_tspec_nor_msdu, tvb, offset, 2, ENC_LITTLE_ENDIAN);
@@ -10501,21 +11188,38 @@ add_tagged_field(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset
       {
       guint8 type;
       guint8 version;
+      proto_item *class_mask;
+      proto_tree *mask_tree;
 
       offset += 2;
       proto_tree_add_item(tree, hf_ieee80211_tclas_up, tvb, offset, 1, ENC_LITTLE_ENDIAN);
-      type = tvb_get_guint8(tvb, offset);
       offset += 1;
 
+      type = tvb_get_guint8(tvb, offset);
       proto_tree_add_item(tree, hf_ieee80211_tclas_class_type, tvb, offset, 1, ENC_LITTLE_ENDIAN);
       offset += 1;
 
-      proto_tree_add_item(tree, hf_ieee80211_tclas_class_mask, tvb, offset, 1, ENC_LITTLE_ENDIAN);
+      class_mask = proto_tree_add_item(tree, hf_ieee80211_tclas_class_mask,
+                                       tvb, offset, 1, ENC_LITTLE_ENDIAN);
       offset += 1;
 
       switch (type)
         {
           case 0:
+            offset--;
+            mask_tree = proto_item_add_subtree(class_mask,
+                                               ett_tag_tclas_mask_tree);
+            proto_tree_add_item(mask_tree,
+                                hf_ieee80211_tclas_class_mask0_src_addr,
+                                tvb, offset, 1, ENC_LITTLE_ENDIAN);
+            proto_tree_add_item(mask_tree,
+                                hf_ieee80211_tclas_class_mask0_dst_addr,
+                                tvb, offset, 1, ENC_LITTLE_ENDIAN);
+            proto_tree_add_item(mask_tree,
+                                hf_ieee80211_tclas_class_mask0_type,
+                                tvb, offset, 1, ENC_LITTLE_ENDIAN);
+            offset++;
+
             proto_tree_add_item(tree, hf_ieee80211_tclas_src_mac_addr, tvb, offset, 6, ENC_NA);
             offset += 6;
 
@@ -10527,8 +11231,41 @@ add_tagged_field(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset
             break;
 
           case 1:
-            version = tvb_get_guint8(tvb, offset + 5);
-            proto_tree_add_item(tree, hf_ieee80211_tclas_version, tvb, offset + 5, 1, ENC_LITTLE_ENDIAN);
+            version = tvb_get_guint8(tvb, offset);
+            offset--;
+
+            mask_tree = proto_item_add_subtree(class_mask,
+                                               ett_tag_tclas_mask_tree);
+            proto_tree_add_item(mask_tree,
+                                hf_ieee80211_tclas_class_mask1_ver,
+                                tvb, offset, 1, ENC_LITTLE_ENDIAN);
+            proto_tree_add_item(mask_tree,
+                                hf_ieee80211_tclas_class_mask1_src_ip,
+                                tvb, offset, 1, ENC_LITTLE_ENDIAN);
+            proto_tree_add_item(mask_tree,
+                                hf_ieee80211_tclas_class_mask1_dst_ip,
+                                tvb, offset, 1, ENC_LITTLE_ENDIAN);
+            proto_tree_add_item(mask_tree,
+                                hf_ieee80211_tclas_class_mask1_src_port,
+                                tvb, offset, 1, ENC_LITTLE_ENDIAN);
+            proto_tree_add_item(mask_tree,
+                                hf_ieee80211_tclas_class_mask1_dst_port,
+                                tvb, offset, 1, ENC_LITTLE_ENDIAN);
+            if (version == 4) {
+              proto_tree_add_item(mask_tree,
+                                  hf_ieee80211_tclas_class_mask1_ipv4_dscp,
+                                  tvb, offset, 1, ENC_LITTLE_ENDIAN);
+              proto_tree_add_item(mask_tree,
+                                  hf_ieee80211_tclas_class_mask1_ipv4_proto,
+                                  tvb, offset, 1, ENC_LITTLE_ENDIAN);
+            } else {
+              proto_tree_add_item(mask_tree,
+                                  hf_ieee80211_tclas_class_mask1_ipv6_flow,
+                                  tvb, offset, 1, ENC_LITTLE_ENDIAN);
+            }
+            offset += 1;
+
+            proto_tree_add_item(tree, hf_ieee80211_tclas_version, tvb, offset, 1, ENC_LITTLE_ENDIAN);
             offset += 1;
             if (version == 4)
             {
@@ -10561,6 +11298,14 @@ add_tagged_field(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset
             break;
 
           case 2:
+            offset--;
+            mask_tree = proto_item_add_subtree(class_mask,
+                                               ett_tag_tclas_mask_tree);
+            proto_tree_add_item(mask_tree,
+                                hf_ieee80211_tclas_class_mask2_tci,
+                                tvb, offset, 1, ENC_LITTLE_ENDIAN);
+            offset++;
+
             proto_tree_add_item(tree, hf_ieee80211_tclas_tag_type, tvb, offset, 2, ENC_LITTLE_ENDIAN);
             offset += 2;
             break;
@@ -10579,7 +11324,7 @@ add_tagged_field(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset
       }
       offset += 2;
 
-      add_fixed_field(tree, tvb, offset, FIELD_SCHEDULE_INFO);
+      add_fixed_field(tree, tvb, pinfo, offset, FIELD_SCHEDULE_INFO);
       offset += 2;
 
       proto_tree_add_item(tree, hf_ieee80211_sched_srv_start, tvb, offset, 4, ENC_LITTLE_ENDIAN);
@@ -11262,7 +12007,7 @@ add_tagged_field(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset
         /* proto_item *ti_cap;
         proto_tree *cap_tree; */
         offset += 2;
-        offset = dissect_qos_capability(tree, tvb, offset, ftype);
+        offset = dissect_qos_capability(tree, tvb, pinfo, offset, ftype);
       }
       break;
 
@@ -11362,7 +12107,7 @@ add_tagged_field(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset
       switch (oui) {
         /* 802.11 specific vendor ids */
         case OUI_WPAWME:
-          offset = dissect_vendor_ie_wpawme(tree, tvb, offset, tag_vs_len, ftype);
+          offset = dissect_vendor_ie_wpawme(tree, tvb, pinfo, offset, tag_vs_len, ftype);
           break;
         case OUI_RSN:
           dissect_vendor_ie_rsn(ti, tree, tvb, offset, tag_vs_len);
@@ -11407,12 +12152,16 @@ add_tagged_field(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset
       dissect_mmie(tree, tvb, offset + 2, tag_len);
       break;
 
+    case TAG_SSID_LIST:
+      dissect_ssid_list(tree, tvb, offset + 2, tag_len);
+      break;
+
     case TAG_TIME_ZONE:
       dissect_time_zone(tree, tvb, offset + 2, tag_len);
       break;
 
     case TAG_TIMEOUT_INTERVAL:
-      dissect_timeout_interval(tree, tvb, offset + 2, tag_len);
+      dissect_timeout_interval(tree, tvb, pinfo, offset + 2, tag_len);
       break;
 
     case TAG_RIC_DATA: /* RIC Data (RDE) (57) */
@@ -11479,6 +12228,22 @@ add_tagged_field(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset
       }
       break;
 
+    case TAG_BSS_MAX_IDLE_PERIOD:
+      dissect_bss_max_idle_period(tree, tvb, offset + 2);
+      break;
+
+    case TAG_TFS_REQUEST:
+      dissect_tfs_request(pinfo, tree, tvb, offset + 2, tag_len, ftype);
+      break;
+
+    case TAG_TFS_RESPONSE:
+      dissect_tfs_response(pinfo, tree, tvb, offset + 2, tag_len, ftype);
+      break;
+
+    case TAG_WNM_SLEEP_MODE:
+      dissect_wnm_sleep_mode(tree, tvb, offset + 2);
+      break;
+
     case TAG_TIME_ADV:
       dissect_time_adv(tree, tvb, offset + 2);
       break;
@@ -11515,7 +12280,7 @@ add_tagged_field(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset
                 proto_tree_add_item (tree, hf_ieee80211_mesh_peering_peer_link_id, tvb, offset, 2, ENC_LITTLE_ENDIAN);
                 offset += 2;
               }
-            offset += add_fixed_field(tree, tvb, offset, FIELD_REASON_CODE);
+            offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_REASON_CODE);
             break;
 
           /* unexpected values */
@@ -11656,7 +12421,7 @@ add_tagged_field(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset
             proto_tree_add_item (tree, hf_ieee80211_ff_hwmp_targ_ext, tvb, offset, 6, ENC_NA);
             offset += 6;
           }
-          offset += add_fixed_field(tree, tvb, offset, FIELD_REASON_CODE);
+          offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_REASON_CODE);
         }
         break;
       }
@@ -11815,7 +12580,7 @@ add_tagged_field(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset
       offset += 2;
       tag_offset = offset;
 
-      offset += add_fixed_field(tree, tvb, offset, FIELD_EXTENDED_CHANNEL_SWITCH_ANNOUNCEMENT);
+      offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_EXTENDED_CHANNEL_SWITCH_ANNOUNCEMENT);
 
       if (tag_len > (offset - tag_offset))
       {
@@ -11908,7 +12673,6 @@ dissect_ieee80211_mgt (guint16 fcf, tvbuff_t *tvb, packet_info *pinfo, proto_tre
   int         offset = 0;
   int         tagged_parameter_tree_len;
 
-  g_pinfo = pinfo;
   ieee80211_tvb_invalid = FALSE;
 
   CHECK_DISPLAY_AS_X(data_handle,proto_wlan_mgt, tvb, pinfo, tree);
@@ -11921,8 +12685,8 @@ dissect_ieee80211_mgt (guint16 fcf, tvbuff_t *tvb, packet_info *pinfo, proto_tre
 
     case MGT_ASSOC_REQ:
       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);
+      add_fixed_field(fixed_tree, tvb, pinfo, 0, FIELD_CAP_INFO);
+      add_fixed_field(fixed_tree, tvb, pinfo, 2, FIELD_LISTEN_IVAL);
       offset = 4;  /* Size of fixed fields */
 
       tagged_parameter_tree_len =
@@ -11936,9 +12700,9 @@ dissect_ieee80211_mgt (guint16 fcf, tvbuff_t *tvb, packet_info *pinfo, proto_tre
 
     case MGT_ASSOC_RESP:
       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);
+      add_fixed_field(fixed_tree, tvb, pinfo, 0, FIELD_CAP_INFO);
+      add_fixed_field(fixed_tree, tvb, pinfo, 2, FIELD_STATUS_CODE);
+      add_fixed_field(fixed_tree, tvb, pinfo, 4, FIELD_ASSOC_ID);
       offset = 6;  /* Size of fixed fields */
 
       tagged_parameter_tree_len =
@@ -11952,9 +12716,9 @@ dissect_ieee80211_mgt (guint16 fcf, tvbuff_t *tvb, packet_info *pinfo, proto_tre
 
     case MGT_REASSOC_REQ:
       fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 10);
-      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);
+      add_fixed_field(fixed_tree, tvb, pinfo, 0, FIELD_CAP_INFO);
+      add_fixed_field(fixed_tree, tvb, pinfo, 2, FIELD_LISTEN_IVAL);
+      add_fixed_field(fixed_tree, tvb, pinfo, 4, FIELD_CURRENT_AP_ADDR);
       offset = 10;  /* Size of fixed fields */
 
       tagged_parameter_tree_len =
@@ -11967,9 +12731,9 @@ dissect_ieee80211_mgt (guint16 fcf, tvbuff_t *tvb, packet_info *pinfo, proto_tre
 
     case MGT_REASSOC_RESP:
       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);
+      add_fixed_field(fixed_tree, tvb, pinfo, 0, FIELD_CAP_INFO);
+      add_fixed_field(fixed_tree, tvb, pinfo, 2, FIELD_STATUS_CODE);
+      add_fixed_field(fixed_tree, tvb, pinfo, 4, FIELD_ASSOC_ID);
       offset = 6;  /* Size of fixed fields */
 
       tagged_parameter_tree_len =
@@ -11994,9 +12758,9 @@ dissect_ieee80211_mgt (guint16 fcf, tvbuff_t *tvb, packet_info *pinfo, proto_tre
     case MGT_PROBE_RESP:
     {
       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);
+      add_fixed_field(fixed_tree, tvb, pinfo, 0, FIELD_TIMESTAMP);
+      add_fixed_field(fixed_tree, tvb, pinfo, 8, FIELD_BEACON_INTERVAL);
+      add_fixed_field(fixed_tree, tvb, pinfo, 10, FIELD_CAP_INFO);
       offset = 12;  /* Size of fixed fields */
 
       tagged_parameter_tree_len = tvb_reported_length_remaining(tvb, offset);
@@ -12007,15 +12771,15 @@ dissect_ieee80211_mgt (guint16 fcf, tvbuff_t *tvb, packet_info *pinfo, proto_tre
     case MGT_MEASUREMENT_PILOT:
     {
       fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 12);
-      offset += add_fixed_field(fixed_tree, tvb, offset, FIELD_TIMESTAMP);
-      offset += add_fixed_field(fixed_tree, tvb, offset, FIELD_MEASUREMENT_PILOT_INT);
-      offset += add_fixed_field(fixed_tree, tvb, offset, FIELD_BEACON_INTERVAL);
-      offset += add_fixed_field(fixed_tree, tvb, offset, FIELD_CAP_INFO);
-      offset += add_fixed_field(fixed_tree, tvb, offset, FIELD_COUNTRY_STR);
-      offset += add_fixed_field(fixed_tree, tvb, offset, FIELD_MAX_REG_PWR);
-      offset += add_fixed_field(fixed_tree, tvb, offset, FIELD_MAX_TX_PWR);
-      offset += add_fixed_field(fixed_tree, tvb, offset, FIELD_TX_PWR_USED);
-      offset += add_fixed_field(fixed_tree, tvb, offset, FIELD_TRANSCEIVER_NOISE_FLOOR);
+      offset += add_fixed_field(fixed_tree, tvb, pinfo, offset, FIELD_TIMESTAMP);
+      offset += add_fixed_field(fixed_tree, tvb, pinfo, offset, FIELD_MEASUREMENT_PILOT_INT);
+      offset += add_fixed_field(fixed_tree, tvb, pinfo, offset, FIELD_BEACON_INTERVAL);
+      offset += add_fixed_field(fixed_tree, tvb, pinfo, offset, FIELD_CAP_INFO);
+      offset += add_fixed_field(fixed_tree, tvb, pinfo, offset, FIELD_COUNTRY_STR);
+      offset += add_fixed_field(fixed_tree, tvb, pinfo, offset, FIELD_MAX_REG_PWR);
+      offset += add_fixed_field(fixed_tree, tvb, pinfo, offset, FIELD_MAX_TX_PWR);
+      offset += add_fixed_field(fixed_tree, tvb, pinfo, offset, FIELD_TX_PWR_USED);
+      offset += add_fixed_field(fixed_tree, tvb, pinfo, offset, FIELD_TRANSCEIVER_NOISE_FLOOR);
       /* TODO DS Parameter Set ??? */
 
       tagged_parameter_tree_len = tvb_reported_length_remaining(tvb, offset);
@@ -12025,9 +12789,9 @@ dissect_ieee80211_mgt (guint16 fcf, tvbuff_t *tvb, packet_info *pinfo, proto_tre
     }
     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);
+      add_fixed_field(fixed_tree, tvb, pinfo, 0, FIELD_TIMESTAMP);
+      add_fixed_field(fixed_tree, tvb, pinfo, 8, FIELD_BEACON_INTERVAL);
+      add_fixed_field(fixed_tree, tvb, pinfo, 10, FIELD_CAP_INFO);
       offset = 12;  /* Size of fixed fields */
 
       tagged_parameter_tree_len =
@@ -12043,7 +12807,7 @@ dissect_ieee80211_mgt (guint16 fcf, tvbuff_t *tvb, packet_info *pinfo, proto_tre
 
     case MGT_DISASS:
       fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 2);
-      add_fixed_field(fixed_tree, tvb, 0, FIELD_REASON_CODE);
+      add_fixed_field(fixed_tree, tvb, pinfo, 0, FIELD_REASON_CODE);
       offset = 2; /* Size of fixed fields */
       tagged_parameter_tree_len = tvb_reported_length_remaining(tvb, offset);
       if (tagged_parameter_tree_len > 0) {
@@ -12056,9 +12820,9 @@ dissect_ieee80211_mgt (guint16 fcf, tvbuff_t *tvb, packet_info *pinfo, proto_tre
 
     case MGT_AUTHENTICATION:
       fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 6);
-      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);
+      add_fixed_field(fixed_tree, tvb, pinfo, 0, FIELD_AUTH_ALG);
+      add_fixed_field(fixed_tree, tvb, pinfo, 2, FIELD_AUTH_TRANS_SEQ);
+      add_fixed_field(fixed_tree, tvb, pinfo, 4, FIELD_STATUS_CODE);
       offset = 6;  /* Size of fixed fields */
 
       tagged_parameter_tree_len =
@@ -12076,7 +12840,7 @@ dissect_ieee80211_mgt (guint16 fcf, tvbuff_t *tvb, packet_info *pinfo, proto_tre
 
     case MGT_DEAUTHENTICATION:
       fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 2);
-      add_fixed_field(fixed_tree, tvb, 0, FIELD_REASON_CODE);
+      add_fixed_field(fixed_tree, tvb, pinfo, 0, FIELD_REASON_CODE);
       offset = 2; /* Size of fixed fields */
       tagged_parameter_tree_len = tvb_reported_length_remaining(tvb, offset);
       if (tagged_parameter_tree_len > 0) {
@@ -12094,7 +12858,7 @@ dissect_ieee80211_mgt (guint16 fcf, tvbuff_t *tvb, packet_info *pinfo, proto_tre
       lcl_fixed_hdr = proto_tree_add_text(mgt_tree, tvb, 0, 0, "Fixed parameters");
       lcl_fixed_tree = proto_item_add_subtree (lcl_fixed_hdr, ett_fixed_parameters);
 
-      offset += add_fixed_field(lcl_fixed_tree, tvb, 0, FIELD_ACTION);
+      offset += add_fixed_field(lcl_fixed_tree, tvb, pinfo, 0, FIELD_ACTION);
 
       proto_item_set_len(lcl_fixed_hdr, offset);
       if (ieee80211_tvb_invalid)
@@ -12116,7 +12880,7 @@ dissect_ieee80211_mgt (guint16 fcf, tvbuff_t *tvb, packet_info *pinfo, proto_tre
       lcl_fixed_hdr = proto_tree_add_text(mgt_tree, tvb, 0, 0, "Fixed parameters");
       lcl_fixed_tree = proto_item_add_subtree (lcl_fixed_hdr, ett_fixed_parameters);
 
-      offset += add_fixed_field(lcl_fixed_tree, tvb, 0, FIELD_ACTION);
+      offset += add_fixed_field(lcl_fixed_tree, tvb, pinfo, 0, FIELD_ACTION);
 
       proto_item_set_len(lcl_fixed_hdr, offset);
       if (ieee80211_tvb_invalid)
@@ -12534,7 +13298,7 @@ dissect_ieee80211_common (tvbuff_t *tvb, packet_info *pinfo,
                 hf_ieee80211_block_ack_control_basic_tid_info, tvb, offset, 2, ENC_LITTLE_ENDIAN);
                 offset += 2;
 
-                /*offset +=*/ add_fixed_field(hdr_tree, tvb, offset,
+                /*offset +=*/ add_fixed_field(hdr_tree, tvb, pinfo, offset,
                   FIELD_BLOCK_ACK_SSC);
                 break;
               }
@@ -12544,7 +13308,7 @@ dissect_ieee80211_common (tvbuff_t *tvb, packet_info *pinfo,
                 hf_ieee80211_block_ack_control_compressed_tid_info, tvb, offset, 2, ENC_LITTLE_ENDIAN);
                 offset += 2;
 
-                /*offset +=*/ add_fixed_field(hdr_tree, tvb, offset,
+                /*offset +=*/ add_fixed_field(hdr_tree, tvb, pinfo, offset,
                   FIELD_BLOCK_ACK_SSC);
                 break;
               }
@@ -12568,7 +13332,7 @@ dissect_ieee80211_common (tvbuff_t *tvb, packet_info *pinfo,
                   proto_tree_add_item(bar_mtid_sub_tree, hf_ieee80211_block_ack_multi_tid_value, tvb, offset, 2, ENC_LITTLE_ENDIAN);
                   offset += 2;
 
-                  offset += add_fixed_field(bar_mtid_sub_tree, tvb, offset, FIELD_BLOCK_ACK_SSC);
+                  offset += add_fixed_field(bar_mtid_sub_tree, tvb, pinfo, offset, FIELD_BLOCK_ACK_SSC);
                 }
                 break;
               }
@@ -12618,7 +13382,7 @@ dissect_ieee80211_common (tvbuff_t *tvb, packet_info *pinfo,
                 hf_ieee80211_block_ack_control_basic_tid_info, tvb, offset, 2, ENC_LITTLE_ENDIAN);
                 offset += 2;
 
-                offset += add_fixed_field(hdr_tree, tvb, offset, FIELD_BLOCK_ACK_SSC);
+                offset += add_fixed_field(hdr_tree, tvb, pinfo, offset, FIELD_BLOCK_ACK_SSC);
                 proto_tree_add_item(hdr_tree, hf_ieee80211_block_ack_bitmap, tvb, offset, 128, ENC_NA);
                 /*offset += 128;*/
                 break;
@@ -12636,7 +13400,7 @@ dissect_ieee80211_common (tvbuff_t *tvb, packet_info *pinfo,
 
                 ssn = tvb_get_letohs(tvb, offset);
                 ssn >>= 4;
-                offset += add_fixed_field(hdr_tree, tvb, offset, FIELD_BLOCK_ACK_SSC);
+                offset += add_fixed_field(hdr_tree, tvb, pinfo, offset, FIELD_BLOCK_ACK_SSC);
                 bmap = tvb_get_letoh64(tvb, offset);
                 ba_bitmap_item = proto_tree_add_item(hdr_tree, hf_ieee80211_block_ack_bitmap, tvb, offset, 8, ENC_NA);
                 ba_bitmap_tree = proto_item_add_subtree(ba_bitmap_item, ett_block_ack_bitmap);
@@ -12670,7 +13434,7 @@ dissect_ieee80211_common (tvbuff_t *tvb, packet_info *pinfo,
                   proto_tree_add_item(ba_mtid_sub_tree, hf_ieee80211_block_ack_multi_tid_value, tvb, offset, 2, ENC_LITTLE_ENDIAN);
                   offset += 2;
 
-                  offset += add_fixed_field(ba_mtid_sub_tree, tvb, offset, FIELD_BLOCK_ACK_SSC);
+                  offset += add_fixed_field(ba_mtid_sub_tree, tvb, pinfo, offset, FIELD_BLOCK_ACK_SSC);
                   proto_tree_add_item(ba_mtid_sub_tree, hf_ieee80211_block_ack_bitmap, tvb, offset, 8, ENC_NA);
                   offset += 8;
                 }
@@ -13070,7 +13834,7 @@ dissect_ieee80211_common (tvbuff_t *tvb, packet_info *pinfo,
 
           msh_fields = proto_tree_add_item(hdr_tree, hf_ieee80211_mesh_control_field, tvb, meshoff, meshctl_len, ENC_NA);
           msh_tree = proto_item_add_subtree (msh_fields, ett_msh_control);
-          add_fixed_field(msh_tree, tvb, meshoff, FIELD_MESH_CONTROL);
+          add_fixed_field(msh_tree, tvb, pinfo, meshoff, FIELD_MESH_CONTROL);
         }
 
       } /* end of qos control field */
@@ -13949,8 +14713,6 @@ dissect_data_encap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
   int         tagged_parameter_tree_len;
   proto_tree *tagged_tree;
 
-  g_pinfo = pinfo;
-
   type = tvb_get_guint8(tvb, offset);
   proto_tree_add_item(tree, hf_ieee80211_data_encap_payload_type, tvb, offset,
                       1, ENC_BIG_ENDIAN);
@@ -13963,7 +14725,7 @@ dissect_data_encap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
   case 2:
     col_set_str(pinfo->cinfo, COL_PROTOCOL, "TDLS");
     col_clear(pinfo->cinfo, COL_INFO);
-    offset += add_fixed_field(tree, tvb, offset, FIELD_ACTION);
+    offset += add_fixed_field(tree, tvb, pinfo, offset, FIELD_ACTION);
     tagged_parameter_tree_len = tvb_reported_length_remaining(tvb, offset);
     if (tagged_parameter_tree_len > 0) {
       tagged_tree = get_tagged_parameter_tree(tree, tvb, offset,
@@ -14391,6 +15153,19 @@ proto_register_ieee80211 (void)
       FT_UINT8, BASE_DEC|BASE_EXT_STRING, &wnm_action_codes_ext, 0,
       "Management action code", HFILL }},
 
+    {&hf_ieee80211_ff_key_data,
+     {"Key Data", "wlan_mgt.fixed.key_data",
+      FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }},
+
+    {&hf_ieee80211_ff_key_data_length,
+     {"Key Data Length", "wlan_mgt.fixed.key_data_length",
+      FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }},
+
+    {&hf_ieee80211_ff_wnm_notification_type,
+     {"WNM-Notification type", "wlan_mgt.fixed.wnm_notification_type",
+      FT_UINT8, BASE_DEC|BASE_EXT_STRING, &wnm_notification_types_ext, 0,
+      NULL, HFILL }},
+
     {&hf_ieee80211_ff_request_mode_pref_cand,
      {"Preferred Candidate List Included","wlan_mgt.fixed.request_mode.pref_cand",
       FT_UINT8, BASE_DEC, NULL, 0x01,
@@ -15664,6 +16439,126 @@ proto_register_ieee80211 (void)
       FT_UINT16, BASE_HEX, NULL, 0,
       NULL, HFILL }},
 
+    {&hf_ieee80211_anqp_wfa_subtype,
+     {"ANQP WFA Subtype", "wlan_mgt.anqp.wfa.subtype",
+      FT_UINT8, BASE_DEC, VALS(wfa_subtype_vals), 0, NULL, HFILL }},
+
+    {&hf_hs20_indication_dgaf_disabled,
+     {"DGAF Disabled", "wlan_mgt.hs20.indication.dgaf_disabled",
+      FT_UINT8, BASE_DEC, NULL, 0x01, NULL, HFILL }},
+
+    {&hf_hs20_anqp_subtype,
+     {"Subtype", "wlan_mgt.hs20.anqp.subtype",
+      FT_UINT8, BASE_DEC, VALS(hs20_anqp_subtype_vals), 0,
+      "Hotspot 2.0 ANQP Subtype", HFILL }},
+
+    {&hf_hs20_anqp_reserved,
+     {"Reserved", "wlan_mgt.hs20.anqp.reserved",
+      FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }},
+
+    {&hf_hs20_anqp_payload,
+     {"Payload", "wlan_mgt.hs20.anqp.payload",
+      FT_BYTES, BASE_NONE, NULL, 0,
+      "Hotspot 2.0 ANQP Payload", HFILL }},
+
+    {&hf_hs20_anqp_hs_query_list,
+     {"Queried Subtype", "wlan_mgt.hs20.anqp.hs_query_list",
+      FT_UINT8, BASE_DEC, VALS(hs20_anqp_subtype_vals), 0,
+      "Queried HS 2.0 Element Subtype", HFILL }},
+
+    {&hf_hs20_anqp_hs_capability_list,
+     {"Capability", "wlan_mgt.hs20.anqp.hs_capability_list",
+      FT_UINT8, BASE_DEC, VALS(hs20_anqp_subtype_vals), 0,
+      "Hotspot 2.0 ANQP Subtype Capability", HFILL }},
+
+    {&hf_hs20_anqp_ofn_length,
+     {"Length", "wlan_mgt.hs20.anqp.ofn.length",
+      FT_UINT8, BASE_DEC, NULL, 0,
+      "Operator Friendly Name Length", HFILL }},
+
+    {&hf_hs20_anqp_ofn_language,
+     {"Language Code", "wlan_mgt.hs20.anqp.ofn.language",
+      FT_STRING, BASE_NONE, NULL, 0,
+      "Operator Friendly Name Language Code", HFILL }},
+
+    {&hf_hs20_anqp_ofn_name,
+     {"Operator Friendly Name", "wlan_mgt.hs20.anqp.ofn.name",
+      FT_STRING, BASE_NONE, NULL, 0,
+      NULL, HFILL }},
+
+    {&hf_hs20_anqp_wan_metrics_link_status,
+     {"Link Status", "wlan_mgt.hs20.anqp.wan_metrics.link_status",
+      FT_UINT8, BASE_DEC, VALS(hs20_wm_link_status_vals), 0x03, NULL, HFILL }},
+
+    {&hf_hs20_anqp_wan_metrics_symmetric_link,
+     {"Symmetric Link", "wlan_mgt.hs20.anqp.wan_metrics.symmetric_link",
+      FT_UINT8, BASE_DEC, NULL, 0x04, NULL, HFILL }},
+
+    {&hf_hs20_anqp_wan_metrics_at_capacity,
+     {"At Capacity", "wlan_mgt.hs20.anqp.wan_metrics.at_capacity",
+      FT_UINT8, BASE_DEC, NULL, 0x08, NULL, HFILL }},
+
+    {&hf_hs20_anqp_wan_metrics_reserved,
+     {"Reserved", "wlan_mgt.hs20.anqp.wan_metrics.reserved",
+      FT_UINT8, BASE_DEC, NULL, 0xf0, NULL, HFILL }},
+
+    {&hf_hs20_anqp_wan_metrics_downlink_speed,
+     {"Downlink Speed", "wlan_mgt.hs20.anqp.wan_metrics.downlink_speed",
+      FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }},
+
+    {&hf_hs20_anqp_wan_metrics_uplink_speed,
+     {"Uplink Speed", "wlan_mgt.hs20.anqp.wan_metrics.uplink_speed",
+      FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }},
+
+    {&hf_hs20_anqp_wan_metrics_downlink_load,
+     {"Downlink Load", "wlan_mgt.hs20.anqp.wan_metrics.downlink_load",
+      FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }},
+
+    {&hf_hs20_anqp_wan_metrics_uplink_load,
+     {"Uplink Load", "wlan_mgt.hs20.anqp.wan_metrics.uplink_load",
+      FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }},
+
+    {&hf_hs20_anqp_wan_metrics_lmd,
+     {"LMD", "wlan_mgt.hs20.anqp.wan_metrics.lmd",
+      FT_UINT16, BASE_DEC, NULL, 0, "Load Measurement Duration", HFILL }},
+
+    {&hf_hs20_anqp_cc_proto_ip_proto,
+     {"IP Protocol", "wlan_mgt.hs20.anqp.cc.ip_proto",
+      FT_UINT8, BASE_DEC, NULL, 0,
+      "ProtoPort Tuple - IP Protocol", HFILL }},
+
+    {&hf_hs20_anqp_cc_proto_port_num,
+     {"Port Number", "wlan_mgt.hs20.anqp.cc.port_num",
+      FT_UINT16, BASE_DEC, NULL, 0,
+      "ProtoPort Tuple - Port Number", HFILL }},
+
+    {&hf_hs20_anqp_cc_proto_status,
+     {"Status", "wlan_mgt.hs20.anqp.cc.status",
+      FT_UINT8, BASE_DEC, VALS(hs20_cc_status_vals), 0,
+      "ProtoPort Tuple - Status", HFILL }},
+
+    {&hf_hs20_anqp_nai_hrq_count,
+     {"NAI Home Realm Count", "wlan_mgt.hs20.anqp.nai_hrq.count",
+      FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }},
+
+    {&hf_hs20_anqp_nai_hrq_encoding_type,
+     {"NAI Home Realm Encoding Type",
+      "wlan_mgt.hs20.anqp.nai_hrq.encoding_type",
+      FT_UINT8, BASE_DEC, VALS(nai_realm_encoding_vals),
+      0x01, NULL, HFILL }},
+
+    {&hf_hs20_anqp_nai_hrq_length,
+     {"NAI Home Realm Name Length", "wlan_mgt.hs20.anqp.nai_hrq.length",
+      FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }},
+
+    {&hf_hs20_anqp_nai_hrq_realm_name,
+     {"NAI Home Realm Name", "wlan_mgt.hs20.anqp.nai_hrq.name",
+      FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }},
+
+    {&hf_hs20_anqp_oper_class_indic,
+     {"Operating Class", "wlan_mgt.hs20.anqp.oper_class_indic.oper_class",
+      FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }},
+
     {&hf_ieee80211_tag,
      {"Tag", "wlan_mgt.tag",
       FT_NONE, BASE_NONE, 0x0, 0,
@@ -15872,6 +16767,42 @@ proto_register_ieee80211 (void)
      {"Classifier Mask", "wlan_mgt.tclas.class_mask",
       FT_UINT8, BASE_HEX,  NULL, 0,
       "Specifies a bitmap where bits that are set to 1 identify a subset of the classifier parameters", HFILL }},
+    {&hf_ieee80211_tclas_class_mask0_src_addr,
+     {"Source Address", "wlan_mgt.tclas.class_mask.src_addr",
+      FT_UINT8, BASE_HEX, NULL, 0x01, NULL, HFILL }},
+    {&hf_ieee80211_tclas_class_mask0_dst_addr,
+     {"Destination Address", "wlan_mgt.tclas.class_mask.dst_addr",
+      FT_UINT8, BASE_HEX, NULL, 0x02, NULL, HFILL }},
+    {&hf_ieee80211_tclas_class_mask0_type,
+     {"Type", "wlan_mgt.tclas.class_mask.type",
+      FT_UINT8, BASE_HEX, NULL, 0x04, NULL, HFILL }},
+    {&hf_ieee80211_tclas_class_mask1_ver,
+     {"Version", "wlan_mgt.tclas.class_mask.version",
+      FT_UINT8, BASE_HEX, NULL, 0x01, NULL, HFILL }},
+    {&hf_ieee80211_tclas_class_mask1_src_ip,
+     {"Source IP Address", "wlan_mgt.tclas.class_mask.src_ip",
+      FT_UINT8, BASE_HEX, NULL, 0x02, NULL, HFILL }},
+    {&hf_ieee80211_tclas_class_mask1_dst_ip,
+     {"Destination IP Address", "wlan_mgt.tclas.class_mask.dst_ip",
+      FT_UINT8, BASE_HEX, NULL, 0x04, NULL, HFILL }},
+    {&hf_ieee80211_tclas_class_mask1_src_port,
+     {"Source Port", "wlan_mgt.tclas.class_mask.src_port",
+      FT_UINT8, BASE_HEX, NULL, 0x08, NULL, HFILL }},
+    {&hf_ieee80211_tclas_class_mask1_dst_port,
+     {"Destination Port", "wlan_mgt.tclas.class_mask.dst_port",
+      FT_UINT8, BASE_HEX, NULL, 0x10, NULL, HFILL }},
+    {&hf_ieee80211_tclas_class_mask1_ipv4_dscp,
+     {"DSCP", "wlan_mgt.tclas.class_mask.dscp",
+      FT_UINT8, BASE_HEX, NULL, 0x20, NULL, HFILL }},
+    {&hf_ieee80211_tclas_class_mask1_ipv4_proto,
+     {"Protocol", "wlan_mgt.tclas.class_mask.proto",
+      FT_UINT8, BASE_HEX, NULL, 0x40, NULL, HFILL }},
+    {&hf_ieee80211_tclas_class_mask1_ipv6_flow,
+     {"Flow Label", "wlan_mgt.tclas.class_mask.flow_label",
+      FT_UINT8, BASE_HEX, NULL, 0x20, NULL, HFILL }},
+    {&hf_ieee80211_tclas_class_mask2_tci,
+     {"802.1Q CLAN TCI", "wlan_mgt.tclas.class_mask.tci",
+      FT_UINT8, BASE_HEX, NULL, 0x01, NULL, HFILL }},
 
     {&hf_ieee80211_tclas_src_mac_addr,
      {"Source address", "wlan_mgt.tclas.type",
@@ -19259,6 +20190,74 @@ proto_register_ieee80211 (void)
       FT_BYTES, BASE_NONE, NULL, 0,
       NULL, HFILL }},
 
+    /* BSS Max Idle Period */
+    {&hf_ieee80211_tag_bss_max_idle_period,
+     {"BSS Max Idle Period (1000 TUs)", "wlan_mgt.bss_max_idle.period",
+      FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }},
+    {&hf_ieee80211_tag_bss_max_idle_options_protected,
+     {"BSS Max Idle Period Options: Protected Keep-Alive Required",
+      "wlan_mgt.bss_max_idle.options.protected",
+      FT_UINT8, BASE_DEC, NULL, 0x01, NULL, HFILL }},
+
+    /* TFS Request */
+    {&hf_ieee80211_tag_tfs_request_id,
+     {"TFS ID", "wlan_mgt.tfs_request.id",
+      FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }},
+    {&hf_ieee80211_tag_tfs_request_ac_delete_after_match,
+     {"TFS Action Code - Delete after match",
+      "wlan_mgt.tfs_request.action_code.delete_after_match",
+      FT_UINT8, BASE_DEC, NULL, 0x01, NULL, HFILL }},
+    {&hf_ieee80211_tag_tfs_request_ac_notify,
+     {"TFS Action Code - Notify",
+      "wlan_mgt.tfs_request.action_code.notify",
+      FT_UINT8, BASE_DEC, NULL, 0x02, NULL, HFILL }},
+    {&hf_ieee80211_tag_tfs_request_subelem_id,
+     {"Subelement ID", "wlan_mgt.tfs_request.subelem.id",
+      FT_UINT8, BASE_DEC, VALS(tfs_request_subelem_ids), 0,
+      "TFS Request Subelement ID", HFILL }},
+    {&hf_ieee80211_tag_tfs_request_subelem_len,
+     {"Length", "wlan_mgt.tfs_request.subelem.len",
+      FT_UINT8, BASE_DEC, NULL, 0,
+      "TFS Request Subelement Length", HFILL }},
+    {&hf_ieee80211_tag_tfs_request_subelem,
+     {"Subelement Data", "wlan_mgt.tfs_request.subelem",
+      FT_BYTES, BASE_NONE, NULL, 0,
+      "TFS Request Subelement Data", HFILL }},
+
+    /* TFS Response */
+    {&hf_ieee80211_tag_tfs_response_subelem_id,
+     {"Subelement ID", "wlan_mgt.tfs_response.subelem.id",
+      FT_UINT8, BASE_DEC, VALS(tfs_response_subelem_ids), 0,
+      "TFS Response Subelement ID", HFILL }},
+    {&hf_ieee80211_tag_tfs_response_subelem_len,
+     {"Length", "wlan_mgt.tfs_response.subelem.len",
+      FT_UINT8, BASE_DEC, NULL, 0,
+      "TFS Response Subelement Length", HFILL }},
+    {&hf_ieee80211_tag_tfs_response_subelem,
+     {"Subelement Data", "wlan_mgt.tfs_response.subelem",
+      FT_BYTES, BASE_NONE, NULL, 0,
+      "TFS Response Subelement Data", HFILL }},
+    {&hf_ieee80211_tag_tfs_response_status,
+     {"TFS Response Status", "wlan_mgt.tfs_response.status",
+      FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }},
+    {&hf_ieee80211_tag_tfs_response_id,
+     {"TFS ID", "wlan_mgt.tfs_response.tfs_id",
+      FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }},
+
+    /* WNM-Sleep Mode */
+    {&hf_ieee80211_tag_wnm_sleep_mode_action_type,
+     {"Action Type", "wlan_mgt.wnm_sleep_mode.action_type",
+      FT_UINT8, BASE_DEC, VALS(wnm_sleep_mode_action_types), 0,
+      "WNM-Sleep Mode Action Type", HFILL }},
+    {&hf_ieee80211_tag_wnm_sleep_mode_response_status,
+     {"WNM-Sleep Mode Response Status",
+      "wlan_mgt.wnm_sleep_mode.response_status",
+      FT_UINT8, BASE_DEC, VALS(wnm_sleep_mode_response_status_vals), 0, NULL,
+      HFILL }},
+    {&hf_ieee80211_tag_wnm_sleep_mode_interval,
+     {"WNM-Sleep Interval", "wlan_mgt.wnm_sleep_mode.interval",
+      FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }},
+
     /* Time Advertisement */
     {&hf_ieee80211_tag_time_adv_timing_capab,
      {"Timing capabilities", "wlan_mgt.time_adv.timing_capab",
@@ -19611,6 +20610,7 @@ proto_register_ieee80211 (void)
     &ett_tag_rm_cap3,
     &ett_tag_rm_cap4,
     &ett_tag_rm_cap5,
+    &ett_tag_tclas_mask_tree,
     &ett_tag_supported_channels,
     &ett_tag_neighbor_report_bssid_info_tree,
     &ett_tag_neighbor_report_bssid_info_capability_tree,
@@ -19644,7 +20644,9 @@ proto_register_ieee80211 (void)
     &ett_nai_realm,
     &ett_nai_realm_eap,
     &ett_tag_ric_data_desc_ie,
-    &ett_anqp_vendor_capab
+    &ett_anqp_vendor_capab,
+    &ett_hs20_cc_proto_port_tuple,
+    &ett_ssid_list
   };
   module_t *wlan_module;