ZigBee: Enable heuristic dissection of Tunneling cluster payload

The Smart Energy Tunneling cluster can carry various payloads.
The type of payload is determined when the tunnel is established.
However, we cannot be sure to capture the tunnel establishment and
therefore heuristics are used to determine the payload type.

The IP protocol is added as a heuristic dissector because the
specification allows IP in the tunnel payload. However, the only
real life payload type I am aware of is GBCS messages in
UK Smart Metering (https://smartenergycodecompany.co.uk).

Finally, if a heuristic dissector cannot be found, the Data
dissector is used.

Change-Id: I4942bf00d0d0efe7047db6494cd4f8a9d19c96b6
Reviewed-on: https://code.wireshark.org/review/25181
Petri-Dish: Alexis La Goutte <alexis.lagoutte@gmail.com>
Tested-by: Petri Dish Buildbot
Reviewed-by: Martin Boye Petersen <martinboyepetersen@gmail.com>
Reviewed-by: Anders Broman <a.broman58@gmail.com>
This commit is contained in:
Kenneth Soerensen 2018-01-07 10:52:59 +01:00 committed by Anders Broman
parent f5f6ceeb66
commit b3394a76ab
2 changed files with 20 additions and 16 deletions

View File

@ -3066,6 +3066,7 @@ proto_reg_handoff_ip(void)
dissector_add_uint("nsh.next_proto", NSH_IPV4, ip_handle);
heur_dissector_add("tipc", dissect_ip_heur, "IP over TIPC", "ip_tipc", proto_ip, HEURISTIC_ENABLE);
heur_dissector_add("zbee_zcl_se.tun", dissect_ip_heur, "IP over ZigBee SE Tunneling", "ip_zbee_zcl_se.tun", proto_ip, HEURISTIC_ENABLE);
capture_dissector_add_uint("ethertype", ETHERTYPE_IP, ip_cap_handle);
capture_dissector_add_uint("ax25.pid", AX25_P_IP, ip_cap_handle);

View File

@ -6656,16 +6656,13 @@ static int hf_zbee_zcl_tun_protocol_offset = -1;
static int hf_zbee_zcl_tun_protocol_list_complete = -1;
static int hf_zbee_zcl_tun_protocol_count = -1;
static int hf_zbee_zcl_tun_transfer_status = -1;
static int hf_zbee_zcl_tun_transfer_data = -1;
static int hf_zbee_zcl_tun_transfer_data_status = -1;
static heur_dissector_list_t zbee_zcl_tun_heur_subdissector_list;
/* Initialize the subtree pointers */
static gint ett_zbee_zcl_tun = -1;
/* Subdissector handles. */
static dissector_handle_t ipv4_handle;
static dissector_handle_t ipv6_handle;
#define zbee_zcl_tun_protocol_names_VALUE_STRING_LIST(XXX) \
XXX(ZBEE_ZCL_TUN_PROTO_DLMS, 0x00, "DLMS/COSEM (IEC 62056)" ) \
XXX(ZBEE_ZCL_TUN_PROTO_IEC_61107, 0x01, "IEC 61107" ) \
@ -6778,20 +6775,30 @@ dissect_zcl_tun_close_tunnel(tvbuff_t *tvb, proto_tree *tree, guint *offset)
*This function manages the Transfer Data payload
*
*@param tvb pointer to buffer containing raw packet.
*@param pinfo pointer to packet information fields
*@param tree pointer to data tree Wireshark uses to display packet.
*@param offset pointer to offset from caller
*/
static void
dissect_zcl_tun_transfer_data(tvbuff_t *tvb, proto_tree *tree, guint *offset)
dissect_zcl_tun_transfer_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint *offset)
{
gint length;
heur_dtbl_entry_t *hdtbl_entry;
tvbuff_t *data_tvb;
proto_tree *root_tree = proto_tree_get_root(tree);
proto_tree_add_item(tree, hf_zbee_zcl_tun_tunnel_id, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
*offset += 2;
length = tvb_reported_length_remaining(tvb, *offset);
proto_tree_add_item(tree, hf_zbee_zcl_tun_transfer_data, tvb, *offset, length, ENC_NA);
data_tvb = tvb_new_subset_remaining(tvb, *offset);
*offset += length;
if (dissector_try_heuristic(zbee_zcl_tun_heur_subdissector_list, data_tvb, pinfo, root_tree, &hdtbl_entry, NULL)) {
return;
}
call_data_dissector(data_tvb, pinfo, root_tree);
}
/**
@ -6975,7 +6982,7 @@ dissect_zbee_zcl_tun(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void*
break;
case ZBEE_ZCL_CMD_ID_TUN_TRANSFER_DATA:
dissect_zcl_tun_transfer_data(tvb, payload_tree, &offset);
dissect_zcl_tun_transfer_data(tvb, pinfo, payload_tree, &offset);
break;
case ZBEE_ZCL_CMD_ID_TUN_TRANSFER_DATA_ERROR:
@ -7021,7 +7028,7 @@ dissect_zbee_zcl_tun(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void*
break;
case ZBEE_ZCL_CMD_ID_TUN_TRANSFER_DATA_TX:
dissect_zcl_tun_transfer_data(tvb, payload_tree, &offset);
dissect_zcl_tun_transfer_data(tvb, pinfo, payload_tree, &offset);
break;
case ZBEE_ZCL_CMD_ID_TUN_TRANSFER_DATA_ERROR_TX:
@ -7114,10 +7121,6 @@ proto_register_zbee_zcl_tun(void)
{ "Transfer Status", "zbee_zcl_se.tun.transfer_status", FT_UINT8, BASE_HEX, VALS(zbee_zcl_tun_status_names),
0x00, NULL, HFILL } },
{ &hf_zbee_zcl_tun_transfer_data,
{ "Transfer Data", "zbee_zcl_se.tun.transfer_data", FT_BYTES, BASE_NONE, NULL,
0, NULL, HFILL } },
{ &hf_zbee_zcl_tun_transfer_data_status,
{ "Transfer Data Status", "zbee_zcl_se.tun.transfer_data_status", FT_UINT8, BASE_HEX, VALS(zbee_zcl_tun_trans_data_status_names),
0x00, NULL, HFILL } },
@ -7142,6 +7145,9 @@ proto_register_zbee_zcl_tun(void)
proto_register_field_array(proto_zbee_zcl_tun, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
/* Make heuristic dissectors possible */
zbee_zcl_tun_heur_subdissector_list = register_heur_dissector_list(ZBEE_PROTOABBREV_ZCL_TUN, proto_zbee_zcl_tun);
/* Register the ZigBee ZCL Tunneling dissector. */
tun_handle = register_dissector(ZBEE_PROTOABBREV_ZCL_TUN, dissect_zbee_zcl_tun, proto_zbee_zcl_tun);
@ -7154,9 +7160,6 @@ proto_register_zbee_zcl_tun(void)
void
proto_reg_handoff_zbee_zcl_tun(void)
{
ipv4_handle = find_dissector("ipv4");
ipv6_handle = find_dissector("ipv6");
/* Register our dissector with the ZigBee application dissectors. */
dissector_add_uint("zbee.zcl.cluster", ZBEE_ZCL_CID_TUNNELING, tun_handle);