Cisco WIDS wlan frames as sent by standalone APs do not include the QoS control

stuff.

Bug: 12421
Change-Id: Idc56bd573b72465e36c8141d3c0736b286ff220a
Reviewed-on: https://code.wireshark.org/review/15448
Reviewed-by: Michael Mann <mmann78@netscape.net>
Petri-Dish: Michael Mann <mmann78@netscape.net>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Jörg Mayer <jmayer@loplof.de>
This commit is contained in:
Joerg Mayer 2016-05-20 06:05:47 +02:00 committed by Jörg Mayer
parent 9cd10f0805
commit 3b7d139708
3 changed files with 61 additions and 13 deletions

View File

@ -206,7 +206,7 @@ proto_reg_handoff_cwids(void)
if (!initialized) {
cwids_handle = create_dissector_handle(dissect_cwids, proto_cwids);
dissector_add_for_decode_as("udp.port", cwids_handle);
ieee80211_radio_handle = find_dissector_add_dependency("wlan_radio", proto_cwids);
ieee80211_radio_handle = find_dissector_add_dependency("wlan_noqos_radio", proto_cwids);
initialized = TRUE;
} else {
if (saved_udp_port != 0) {

View File

@ -35,7 +35,9 @@ void proto_register_ieee80211_radio(void);
void proto_reg_handoff_ieee80211_radio(void);
static dissector_handle_t wlan_radio_handle;
static dissector_handle_t wlan_noqos_radio_handle;
static dissector_handle_t ieee80211_handle;
static dissector_handle_t ieee80211_noqos_handle;
static int proto_wlan_radio = -1;
@ -278,11 +280,10 @@ static gint ett_wlan_radio_11ac_user = -1;
static gint ett_wlan_radio_duration = -1;
/*
* Dissect 802.11 with a variable-length link-layer header and a pseudo-
* header containing radio information.
* Dissect 802.11 pseudo-header containing radio information.
*/
static int
dissect_wlan_radio (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, void *data)
static void
dissect_wlan_radio_phdr (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, void *data)
{
struct ieee_802_11_phdr *phdr = (struct ieee_802_11_phdr *)data;
proto_item *ti = NULL;
@ -854,11 +855,34 @@ dissect_wlan_radio (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, void
}
}
} /* if (tree) */
}
/*
* Dissect 802.11 with a variable-length link-layer header and a pseudo-
* header containing radio information.
*/
static int
dissect_wlan_radio (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, void *data)
{
dissect_wlan_radio_phdr (tvb, pinfo, tree, data);
/* dissect the 802.11 packet next */
return call_dissector_with_data(ieee80211_handle, tvb, pinfo, tree, data);
}
/*
* Dissect 802.11 with a variable-length link-layer header without qos elements and
* a pseudo-header containing radio information.
*/
static int
dissect_wlan_noqos_radio (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, void *data)
{
dissect_wlan_radio_phdr (tvb, pinfo, tree, data);
/* dissect the 802.11 packet next */
return call_dissector_with_data(ieee80211_noqos_handle, tvb, pinfo, tree, data);
}
static hf_register_info hf_wlan_radio[] = {
{&hf_wlan_radio_phy,
{"PHY type", "wlan_radio.phy", FT_UINT32, BASE_DEC, VALS(phy_vals), 0,
@ -1072,6 +1096,7 @@ void proto_register_ieee80211_radio(void)
expert_register_field_array(expert_wlan_radio, ei, array_length(ei));
wlan_radio_handle = register_dissector("wlan_radio", dissect_wlan_radio, proto_wlan_radio);
wlan_noqos_radio_handle = register_dissector("wlan_noqos_radio", dissect_wlan_noqos_radio, proto_wlan_radio);
}
void proto_reg_handoff_ieee80211_radio(void)
@ -1080,6 +1105,7 @@ void proto_reg_handoff_ieee80211_radio(void)
dissector_add_uint("wtap_encap", WTAP_ENCAP_IEEE_802_11_WITH_RADIO,
wlan_radio_handle);
ieee80211_handle = find_dissector_add_dependency("wlan", proto_wlan_radio);
ieee80211_noqos_handle = find_dissector_add_dependency("wlan_noqos", proto_wlan_radio);
}
/*

View File

@ -13057,6 +13057,7 @@ dissect_ht_control(proto_tree *tree, tvbuff_t *tvb, int offset)
#define IEEE80211_COMMON_OPT_BROKEN_FC 0x00000001
#define IEEE80211_COMMON_OPT_IS_CENTRINO 0x00000002
#define IEEE80211_COMMON_OPT_NORMAL_QOS 0x00000004
static void
dissect_frame_control(proto_tree *tree, tvbuff_t *tvb, guint32 option_flags,
@ -16784,7 +16785,7 @@ dissect_ieee80211_common (tvbuff_t *tvb, packet_info *pinfo,
case DATA_FRAME:
hdr_len = (FCF_ADDR_SELECTOR(fcf) == DATA_ADDR_T4) ? DATA_LONG_HDR_LEN : DATA_SHORT_HDR_LEN;
if (DATA_FRAME_IS_QOS(frame_type_subtype)) {
if ((option_flags & IEEE80211_COMMON_OPT_NORMAL_QOS) && DATA_FRAME_IS_QOS(frame_type_subtype)) {
/* QoS frame */
qosoff = hdr_len;
hdr_len += 2; /* Include the QoS field in the header length */
@ -17799,7 +17800,7 @@ dissect_ieee80211_common (tvbuff_t *tvb, packet_info *pinfo,
break;
case DATA_FRAME:
if (tree && DATA_FRAME_IS_QOS(frame_type_subtype))
if ((option_flags & IEEE80211_COMMON_OPT_NORMAL_QOS) && tree && DATA_FRAME_IS_QOS(frame_type_subtype))
{
proto_item *qos_fields, *qos_ti;
proto_tree *qos_tree;
@ -18530,7 +18531,7 @@ dissect_ieee80211 (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *da
ourphdr.phy = PHDR_802_11_PHY_UNKNOWN;
phdr = &ourphdr;
}
return dissect_ieee80211_common (tvb, pinfo, tree, 0, phdr);
return dissect_ieee80211_common (tvb, pinfo, tree, IEEE80211_COMMON_OPT_NORMAL_QOS, phdr);
}
/*
@ -18548,7 +18549,7 @@ dissect_ieee80211_withfcs (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
phdr.decrypted = FALSE;
phdr.datapad = FALSE;
phdr.phy = PHDR_802_11_PHY_UNKNOWN;
dissect_ieee80211_common (tvb, pinfo, tree, 0, &phdr);
dissect_ieee80211_common (tvb, pinfo, tree, IEEE80211_COMMON_OPT_NORMAL_QOS, &phdr);
return tvb_captured_length(tvb);
}
@ -18566,7 +18567,7 @@ dissect_ieee80211_withoutfcs (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tre
phdr.decrypted = FALSE;
phdr.datapad = FALSE;
phdr.phy = PHDR_802_11_PHY_UNKNOWN;
dissect_ieee80211_common (tvb, pinfo, tree, 0, &phdr);
dissect_ieee80211_common (tvb, pinfo, tree, IEEE80211_COMMON_OPT_NORMAL_QOS, &phdr);
return tvb_captured_length(tvb);
}
@ -18611,7 +18612,7 @@ dissect_ieee80211_centrino(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
phdr.decrypted = FALSE;
phdr.datapad = FALSE;
phdr.phy = PHDR_802_11_PHY_UNKNOWN;
dissect_ieee80211_common (tvb, pinfo, tree, IEEE80211_COMMON_OPT_IS_CENTRINO, &phdr);
dissect_ieee80211_common (tvb, pinfo, tree, IEEE80211_COMMON_OPT_IS_CENTRINO|IEEE80211_COMMON_OPT_NORMAL_QOS, &phdr);
return tvb_captured_length(tvb);
}
@ -18630,10 +18631,30 @@ dissect_ieee80211_bsfc (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, voi
phdr.decrypted = FALSE;
phdr.datapad = FALSE;
phdr.phy = PHDR_802_11_PHY_UNKNOWN;
dissect_ieee80211_common (tvb, pinfo, tree, IEEE80211_COMMON_OPT_BROKEN_FC, &phdr);
dissect_ieee80211_common (tvb, pinfo, tree, IEEE80211_COMMON_OPT_BROKEN_FC|IEEE80211_COMMON_OPT_NORMAL_QOS, &phdr);
return tvb_captured_length(tvb);
}
/*
* Dissect 802.11 with a variable-length link-layer header without qos elements
* in data+qos frames and with no FCS (sent as WIDS frames by Cisco standalone
* APs).
*/
static int
dissect_ieee80211_noqos (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
{
struct ieee_802_11_phdr phdr;
/* Construct a pseudo-header to hand to the common code. */
memset(&phdr, 0, sizeof(phdr));
phdr.decrypted = FALSE;
phdr.datapad = FALSE;
phdr.phy = PHDR_802_11_PHY_UNKNOWN;
dissect_ieee80211_common (tvb, pinfo, tree, 0, &phdr);
return tvb_captured_length(tvb);
}
static void
wlan_defragment_init(void)
{
@ -27265,10 +27286,11 @@ proto_register_ieee80211 (void)
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", dissect_ieee80211, proto_wlan);
register_dissector("wlan_withfcs", dissect_ieee80211_withfcs, proto_wlan);
register_dissector("wlan_withoutfcs", dissect_ieee80211_withoutfcs, proto_wlan);
register_dissector("wlan_bsfc", dissect_ieee80211_bsfc, proto_wlan);
register_dissector("wlan_noqos", dissect_ieee80211_noqos, proto_wlan);
register_init_routine(wlan_defragment_init);
register_cleanup_routine(wlan_defragment_cleanup);