aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-ieee80211.c
diff options
context:
space:
mode:
authorAlexis La Goutte <alexis.lagoutte@gmail.com>2013-07-26 08:51:59 +0000
committerAlexis La Goutte <alexis.lagoutte@gmail.com>2013-07-26 08:51:59 +0000
commit5988d137d8433192e39a216935b143cf2f4171a6 (patch)
tree2953a6df5b89fd0413481d83f7d7874486389ca0 /epan/dissectors/packet-ieee80211.c
parent09dd1313203fcec9f66819c99602fe6a031adff7 (diff)
From Jouni Malinen via https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=8972 ieee80211: Dissect QoS Mapping information
This patch adds support for dissecting QoS Map Configure frame and QoS Map Set element per Interworking functionality that was added in IEEE 802.11u svn path=/trunk/; revision=50908
Diffstat (limited to 'epan/dissectors/packet-ieee80211.c')
-rw-r--r--epan/dissectors/packet-ieee80211.c157
1 files changed, 156 insertions, 1 deletions
diff --git a/epan/dissectors/packet-ieee80211.c b/epan/dissectors/packet-ieee80211.c
index f0b9aa9919..7f8a3e7d2c 100644
--- a/epan/dissectors/packet-ieee80211.c
+++ b/epan/dissectors/packet-ieee80211.c
@@ -1177,6 +1177,7 @@ static value_string_ext aruba_mgt_typevals_ext = VALUE_STRING_EXT_INIT(aruba_mgt
#define SM_ACTION_ADDTS_RESPONSE 1
#define SM_ACTION_DELTS 2
#define SM_ACTION_QOS_SCHEDULE 3
+#define SM_ACTION_QOS_MAP_CONFIGURE 4
#define SM_ACTION_DLS_REQUEST 0
#define SM_ACTION_DLS_RESPONSE 1
@@ -1949,6 +1950,7 @@ static const value_string qos_action_codes[] = {
{SM_ACTION_ADDTS_RESPONSE, "ADDTS Response"},
{SM_ACTION_DELTS, "DELTS"},
{SM_ACTION_QOS_SCHEDULE, "Schedule"},
+ {SM_ACTION_QOS_MAP_CONFIGURE, "QoS Map Configure"},
{0, NULL}
};
@@ -3710,6 +3712,14 @@ static int hf_ieee80211_tag_interworking_esr = -1;
static int hf_ieee80211_tag_interworking_uesa = -1;
static int hf_ieee80211_tag_interworking_hessid = -1;
+/* IEEE Std 802.11-2012, 8.4.2.97 */
+static int hf_ieee80211_tag_qos_map_set_dscp_exc = -1;
+static int hf_ieee80211_tag_qos_map_set_dscp_exc_val = -1;
+static int hf_ieee80211_tag_qos_map_set_dscp_exc_up = -1;
+static int hf_ieee80211_tag_qos_map_set_range = -1;
+static int hf_ieee80211_tag_qos_map_set_low = -1;
+static int hf_ieee80211_tag_qos_map_set_high = -1;
+
/* IEEE Std 802.11u-2011 7.3.2.93 */
static int hf_ieee80211_tag_adv_proto_resp_len_limit = -1;
static int hf_ieee80211_tag_adv_proto_pame_bi = -1;
@@ -4221,6 +4231,12 @@ static gint ett_ssid_list = -1;
static gint ett_nintendo = -1;
+static gint ett_qos_map_set_exception = -1;
+static gint ett_qos_map_set_range = -1;
+
+static expert_field ei_ieee80211_bad_length = EI_INIT;
+static expert_field ei_ieee80211_inv_val = EI_INIT;
+
static const fragment_items frag_items = {
&ett_fragment,
&ett_fragments,
@@ -6615,6 +6631,10 @@ add_ff_action_qos(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, int offse
add_fixed_field(tree, tvb, pinfo, offset, FIELD_CATEGORY_CODE);
add_fixed_field(tree, tvb, pinfo, offset + 1, FIELD_QOS_ACTION_CODE);
return 2;
+ case SM_ACTION_QOS_MAP_CONFIGURE:
+ 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, pinfo, offset, FIELD_CATEGORY_CODE);
return 2;
@@ -10683,6 +10703,92 @@ dissect_interworking(packet_info *pinfo, proto_tree *tree, proto_item *item,
}
static guint
+dissect_qos_map_set(packet_info *pinfo, proto_tree *tree, proto_item *item,
+ tvbuff_t *tvb, int offset)
+{
+ guint8 len, left;
+ guint8 val, val2;
+ int i;
+ proto_item *dscp_item;
+ proto_tree *dscp_tree;
+
+ offset++;
+ len = tvb_get_guint8(tvb, offset);
+ offset++;
+
+ if (tvb_reported_length_remaining(tvb, offset) < len || len < 16 || len & 1) {
+ expert_add_info_format_text(pinfo, item, &ei_ieee80211_bad_length,
+ "Truncated QoS Map Set element");
+ return 2 + len;
+ }
+
+ left = len - 16;
+ while (left >= 2) {
+ dscp_item = proto_tree_add_item(tree, hf_ieee80211_tag_qos_map_set_dscp_exc,
+ tvb, offset, 2, ENC_NA);
+ dscp_tree = proto_item_add_subtree(dscp_item, ett_qos_map_set_exception);
+
+ item = proto_tree_add_item(dscp_tree,
+ hf_ieee80211_tag_qos_map_set_dscp_exc_val,
+ tvb, offset, 1, ENC_NA);
+ val = tvb_get_guint8(tvb, offset);
+ if (val > 63 && val != 255) {
+ expert_add_info_format_text(pinfo, item, &ei_ieee80211_inv_val,
+ "Invalid DSCP Value");
+ }
+ offset++;
+
+ item = proto_tree_add_item(dscp_tree,
+ hf_ieee80211_tag_qos_map_set_dscp_exc_up,
+ tvb, offset, 1, ENC_NA);
+ val2 = tvb_get_guint8(tvb, offset);
+ if (val2 > 7) {
+ expert_add_info_format_text(pinfo, item, &ei_ieee80211_inv_val,
+ "Invalid User Priority");
+ }
+ offset++;
+
+ proto_item_append_text(dscp_item, " (0x%02x: UP %u)", val, val2);
+
+ left -= 2;
+ }
+
+ for (i = 0; i < 8; i++) {
+ dscp_item = proto_tree_add_item(tree, hf_ieee80211_tag_qos_map_set_range,
+ tvb, offset, 2, ENC_NA);
+ dscp_tree = proto_item_add_subtree(dscp_item, ett_qos_map_set_exception);
+
+ item = proto_tree_add_item(dscp_tree, hf_ieee80211_tag_qos_map_set_low,
+ tvb, offset, 1, ENC_NA);
+ val = tvb_get_guint8(tvb, offset);
+ if (val > 63 && val != 255) {
+ expert_add_info_format_text(pinfo, item, &ei_ieee80211_inv_val,
+ "Invalid DSCP Value");
+ }
+ offset++;
+
+ item = proto_tree_add_item(dscp_tree, hf_ieee80211_tag_qos_map_set_high,
+ tvb, offset, 1, ENC_NA);
+ val2 = tvb_get_guint8(tvb, offset);
+ if ((val2 > 63 && val2 != 255) || val2 < val ||
+ (val == 255 && val2 != 255) || (val != 255 && val2 == 255)) {
+ expert_add_info_format_text(pinfo, item, &ei_ieee80211_inv_val,
+ "Invalid DSCP Value");
+ }
+ offset++;
+
+ if (val == 255 && val2 == 255) {
+ proto_item_append_text(dscp_item, " (UP %u not in use)", i + 1);
+ } else {
+ proto_item_append_text(dscp_item, " (0x%02x-0x%02x: UP %u)",
+ val, val2, i + 1);
+ }
+ }
+
+ return 2 + len;
+}
+
+static guint
dissect_roaming_consortium(packet_info *pinfo, proto_tree *tree,
proto_item *item, tvbuff_t *tvb, int offset)
{
@@ -12622,6 +12728,9 @@ add_tagged_field(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset
dissect_advertisement_protocol(pinfo, tree, tvb, offset, NULL);
break;
}
+ case TAG_QOS_MAP_SET:
+ dissect_qos_map_set(pinfo, tree, ti, tvb, offset);
+ break;
case TAG_ROAMING_CONSORTIUM:
dissect_roaming_consortium(pinfo, tree, ti, tvb, offset);
break;
@@ -20594,6 +20703,35 @@ proto_register_ieee80211 (void)
FT_ETHER, BASE_NONE, NULL, 0,
"Homogeneous ESS identifier", HFILL }},
+ /* QoS Map Set element */
+ {&hf_ieee80211_tag_qos_map_set_dscp_exc,
+ {"DSCP Exception", "wlan_mgt.qos_map_set.dscp_exception",
+ FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL }},
+
+ {&hf_ieee80211_tag_qos_map_set_dscp_exc_val,
+ {"DSCP Value", "wlan_mgt.qos_map_set.dscp_value",
+ FT_UINT8, BASE_DEC, NULL, 0,
+ "DSCP Exception - DSCP Value", HFILL }},
+
+ {&hf_ieee80211_tag_qos_map_set_dscp_exc_up,
+ {"User Priority", "wlan_mgt.qos_map_set.up",
+ FT_UINT8, BASE_DEC, NULL, 0,
+ "DSCP Exception - User Priority", HFILL }},
+
+ {&hf_ieee80211_tag_qos_map_set_range,
+ {"DSCP Range description", "wlan_mgt.qos_map_set.range",
+ FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL }},
+
+ {&hf_ieee80211_tag_qos_map_set_low,
+ {"DSCP Low Value", "wlan_mgt.qos_map_set.dscp_low_value",
+ FT_UINT8, BASE_DEC, NULL, 0,
+ "DSCP Range description - DSCP Low Value", HFILL }},
+
+ {&hf_ieee80211_tag_qos_map_set_high,
+ {"DSCP High Value", "wlan_mgt.qos_map_set.dscp_high_value",
+ FT_UINT8, BASE_DEC, NULL, 0,
+ "DSCP Range description - DSCP High Value", HFILL }},
+
/* Advertisement Protocol */
{&hf_ieee80211_tag_adv_proto_resp_len_limit,
{"Query Response Length Limit", "wlan_mgt.adv_proto.resp_len_limit",
@@ -20886,8 +21024,22 @@ proto_register_ieee80211 (void)
&ett_anqp_vendor_capab,
&ett_hs20_cc_proto_port_tuple,
&ett_ssid_list,
- &ett_nintendo
+ &ett_nintendo,
+ &ett_qos_map_set_exception,
+ &ett_qos_map_set_range
+ };
+
+ static ei_register_info ei[] = {
+ { &ei_ieee80211_bad_length,
+ { "ieee80211.bad_length", PI_MALFORMED, PI_ERROR,
+ "Wrong length indicated", EXPFILL }},
+ { &ei_ieee80211_inv_val,
+ { "ieee80211.invalid_value", PI_MALFORMED, PI_WARN,
+ "Invalid value", EXPFILL }},
};
+
+ expert_module_t *expert_ieee80211;
+
module_t *wlan_module;
memset (&wlan_stats, 0, sizeof wlan_stats);
@@ -20906,6 +21058,9 @@ proto_register_ieee80211 (void)
proto_register_subtree_array (tree_array, array_length (tree_array));
+ expert_ieee80211 = expert_register_protocol(proto_wlan);
+ expert_register_field_array(expert_ieee80211, ei, array_length(ei));
+
register_dissector("wlan", dissect_ieee80211, proto_wlan);
register_dissector("wlan_fixed", dissect_ieee80211_fixed, proto_wlan);
register_dissector("wlan_bsfc", dissect_ieee80211_bsfc, proto_wlan);