ZigBee: fix ZCL configure reporting response parsing

If configure reporting succeeds for all attributes, then the response
contains only a success status byte but if any attribute fails, then
every record contains a direction byte and attribute identifier.

By handling the "all successful" case specially, add an expert info
message to indicate a problem if the message length indicates that we
have hit this special case but the status is not "success".

Change-Id: I3facae8ac07f1a249cc6ae1b2454f8381151355b
Reviewed-on: https://code.wireshark.org/review/22557
Petri-Dish: Alexis La Goutte <alexis.lagoutte@gmail.com>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Michael Mann <mmann78@netscape.net>
This commit is contained in:
John Keeping 2017-04-22 14:20:11 +01:00 committed by Michael Mann
parent dd0dff78b3
commit 723c76b12c
1 changed files with 30 additions and 10 deletions

View File

@ -29,6 +29,7 @@
#include "config.h"
#include <epan/packet.h>
#include <epan/expert.h>
#include "packet-zbee.h"
#include "packet-zbee-nwk.h"
@ -138,6 +139,8 @@ static gint ett_zbee_zcl_fcf = -1;
static gint ett_zbee_zcl_attr[ZBEE_ZCL_NUM_ATTR_ETT];
static gint ett_zbee_zcl_array_elements[ZBEE_ZCL_NUM_ARRAY_ELEM_ETT];
static expert_field ei_cfg_rpt_rsp_short_non_success = EI_INIT;
/* Dissector List. */
static dissector_table_t zbee_zcl_dissector_table;
@ -1217,7 +1220,7 @@ static void dissect_zcl_config_report(tvbuff_t *tvb, packet_info *pinfo _U_, pro
*@param offset pointer to offset from caller
*@param cluster_id cluster id
*/
static void dissect_zcl_config_report_resp(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
static void dissect_zcl_config_report_resp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
guint *offset, guint16 cluster_id)
{
proto_tree *sub_tree;
@ -1226,21 +1229,27 @@ static void dissect_zcl_config_report_resp(tvbuff_t *tvb, packet_info *pinfo _U_
guint i = 0;
tvb_len = tvb_captured_length(tvb);
while ( *offset < tvb_len && i < ZBEE_ZCL_NUM_ATTR_ETT ) {
/* Special case when all attributes configured successfully */
if ( *offset == tvb_len - 1 ) {
/* Dissect the status */
if ( dissect_zcl_attr_uint8(tvb, tree, offset, &hf_zbee_zcl_attr_status) !=
ZBEE_ZCL_STAT_SUCCESS ) {
expert_add_info(pinfo, tree->last_child, &ei_cfg_rpt_rsp_short_non_success);
}
}
while ( *offset < tvb_len && i < ZBEE_ZCL_NUM_ATTR_ETT ) {
/* Create subtree for attribute status field */
sub_tree = proto_tree_add_subtree(tree, tvb, *offset, 3, ett_zbee_zcl_attr[i], NULL, "Attribute Status Record");
i++;
/* Dissect the status */
if ( dissect_zcl_attr_uint8(tvb, sub_tree, offset, &hf_zbee_zcl_attr_status) !=
ZBEE_ZCL_STAT_SUCCESS ) {
/* Dissect the direction on error */
dissect_zcl_attr_uint8(tvb, sub_tree, offset, &hf_zbee_zcl_attr_dir);
/* Dissect the attribute identifier on error */
dissect_zcl_attr_id(tvb, sub_tree, offset, cluster_id);
}
dissect_zcl_attr_uint8(tvb, sub_tree, offset, &hf_zbee_zcl_attr_status);
/* Dissect the direction */
dissect_zcl_attr_uint8(tvb, sub_tree, offset, &hf_zbee_zcl_attr_dir);
/* Dissect the attribute identifier */
dissect_zcl_attr_id(tvb, sub_tree, offset, cluster_id);
}
} /* dissect_zcl_config_report_resp */
@ -2273,11 +2282,22 @@ void proto_register_zbee_zcl(void)
ett[j] = &ett_zbee_zcl_array_elements[i];
}
static ei_register_info ei[] = {
{ &ei_cfg_rpt_rsp_short_non_success,
{ "zbee_zcl.cfg_rpt_rsp_short_non_success", PI_PROTOCOL, PI_WARN,
"Non-success response without full status records", EXPFILL }},
};
expert_module_t *expert_zbee_zcl;
/* Register ZigBee ZCL protocol with Wireshark. */
proto_zbee_zcl = proto_register_protocol("ZigBee Cluster Library", "ZigBee ZCL", "zbee_zcl");
proto_register_field_array(proto_zbee_zcl, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
expert_zbee_zcl = expert_register_protocol(proto_zbee_zcl);
expert_register_field_array(expert_zbee_zcl, ei, array_length(ei));
/* Register the ZCL dissector and subdissector list. */
zbee_zcl_dissector_table = register_dissector_table("zbee.zcl.cluster", "ZigBee ZCL Cluster ID", proto_zbee_zcl, FT_UINT16, BASE_HEX);
register_dissector(ZBEE_PROTOABBREV_ZCL, dissect_zbee_zcl, proto_zbee_zcl);