/* packet-zbee-zdp-discovery.c * Dissector helper routines for the discovery services of the ZigBee Device Profile * By Owen Kirby * Copyright 2009 Exegin Technologies Limited * * Wireshark - Network traffic analyzer * By Gerald Combs * Copyright 1998 Gerald Combs * * SPDX-License-Identifier: GPL-2.0-or-later */ /* Include Files */ #include "config.h" #include #include #include "packet-zbee.h" #include "packet-zbee-zdp.h" #include "packet-zbee-aps.h" /************************************** * DISCOVERY REQUESTS ************************************** */ /** *ZigBee Device Profile dissector for the network address * *@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. */ void dissect_zbee_zdp_req_nwk_addr(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { guint offset = 0; guint64 ext_addr; ext_addr = zbee_parse_eui64(tree, hf_zbee_zdp_ext_addr, tvb, &offset, sizeof(guint64), NULL); proto_tree_add_item(tree, hf_zbee_zdp_req_type, tvb, offset, 1, ENC_LITTLE_ENDIAN); offset += 1; proto_tree_add_item(tree, hf_zbee_zdp_index, tvb, offset, 1, ENC_LITTLE_ENDIAN); offset += 1; zbee_append_info(tree, pinfo, ", Address: %s", eui64_to_display(wmem_packet_scope(), ext_addr)); /* Dump any leftover bytes. */ zdp_dump_excess(tvb, offset, pinfo, tree); } /* dissect_zbee_zdp_req_nwk_addr */ /** *ZigBee Device Profile dissector for the extended address * *@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. */ void dissect_zbee_zdp_req_ext_addr(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { guint offset = 0; guint32 device; proto_tree_add_item_ret_uint(tree, hf_zbee_zdp_nwk_addr, tvb, offset, 2, ENC_LITTLE_ENDIAN, &device); offset += 2; proto_tree_add_item(tree, hf_zbee_zdp_req_type, tvb, offset, 1, ENC_LITTLE_ENDIAN); offset += 1; proto_tree_add_item(tree, hf_zbee_zdp_index, tvb, offset, 1, ENC_LITTLE_ENDIAN); offset += 1; zbee_append_info(tree, pinfo, ", Nwk Addr: 0x%04x", device); /* Dump any leftover bytes. */ zdp_dump_excess(tvb, offset, pinfo, tree); } /* dissect_zbee_zdp_req_ext_addr */ /** *ZigBee Device Profile dissector for the descriptor * *@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. */ void dissect_zbee_zdp_req_node_desc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { guint offset = 0; guint32 device; proto_tree_add_item_ret_uint(tree, hf_zbee_zdp_nwk_addr, tvb, offset, 2, ENC_LITTLE_ENDIAN, &device); offset += 2; zbee_append_info(tree, pinfo, ", Nwk Addr: 0x%04x", device); /* Dump any leftover bytes. */ zdp_dump_excess(tvb, offset, pinfo, tree); } /* dissect_zbee_zdp_req_node_desc */ /** *ZigBee Device Profile dissector for the node descriptor * *@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. */ void dissect_zbee_zdp_req_power_desc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { guint offset = 0; guint32 device; proto_tree_add_item_ret_uint(tree, hf_zbee_zdp_nwk_addr, tvb, offset, 2, ENC_LITTLE_ENDIAN, &device); offset += 2; zbee_append_info(tree, pinfo, ", Nwk Addr: 0x%04x", device); /* Dump any leftover bytes. */ zdp_dump_excess(tvb, offset, pinfo, tree); } /* dissect_zbee_zdp_req_power_desc */ /** *ZigBee Device Profile dissector for the simple descriptor * *@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. */ void dissect_zbee_zdp_req_simple_desc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { guint offset = 0; guint32 device, endpt; proto_tree_add_item_ret_uint(tree, hf_zbee_zdp_nwk_addr, tvb, offset, 2, ENC_LITTLE_ENDIAN, &device); offset += 2; proto_tree_add_item_ret_uint(tree, hf_zbee_zdp_endpoint, tvb, offset, 1, ENC_LITTLE_ENDIAN, &endpt); offset += 1; zbee_append_info(tree, pinfo, ", Nwk Addr: 0x%04x, Endpoint: %d", device, endpt); /* Dump any leftover bytes. */ zdp_dump_excess(tvb, offset, pinfo, tree); } /* dissect_zbee_zdp_req_simple_desc */ /** *ZigBee Device Profile dissector for the active endpoint list * *@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. */ void dissect_zbee_zdp_req_active_ep(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { guint offset = 0; guint32 device; proto_tree_add_item_ret_uint(tree, hf_zbee_zdp_nwk_addr, tvb, offset, 2, ENC_LITTLE_ENDIAN, &device); offset += 2; zbee_append_info(tree, pinfo, ", Nwk Addr: 0x%04x", device); /* Dump any leftover bytes. */ zdp_dump_excess(tvb, offset, pinfo, tree); } /* dissect_zbee_zdp_req_active_ep */ /** *ZigBee Device Profile dissector for the matching descriptor * *@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. */ void dissect_zbee_zdp_req_match_desc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint8 version) { proto_item *ti; proto_tree *field_tree = NULL; guint offset = 0, i; guint sizeof_cluster = (version >= ZBEE_VERSION_2007)?(int)sizeof(guint16):(int)sizeof(guint8); guint32 device, profile, cluster, in_count, out_count; proto_tree_add_item_ret_uint(tree, hf_zbee_zdp_nwk_addr, tvb, offset, 2, ENC_LITTLE_ENDIAN, &device); offset += 2; proto_tree_add_item_ret_uint(tree, hf_zbee_zdp_profile, tvb, offset, 2, ENC_LITTLE_ENDIAN, &profile); offset += 2; /* Add the input cluster list. */ proto_tree_add_item_ret_uint(tree, hf_zbee_zdp_in_count, tvb, offset, 1, ENC_LITTLE_ENDIAN, &in_count); offset += 1; if (tree && in_count) { field_tree = proto_tree_add_subtree(tree, tvb, offset, in_count*sizeof_cluster, ett_zbee_zdp_match_in, NULL, "Input Cluster List"); } for (i=0; i= ZBEE_VERSION_2007) { proto_tree_add_item_ret_uint(tree, hf_zbee_zdp_user_length, tvb, offset, 1, ENC_LITTLE_ENDIAN, &user_length); offset += 1; } else { /* No Length field in ZigBee 2003 & earlier, uses a fixed length of 16. */ user_length = 16; } proto_tree_add_item_ret_string(tree, hf_zbee_zdp_user, tvb, offset, user_length, ENC_ASCII, wmem_packet_scope(), &user); offset += user_length; zbee_append_info(tree, pinfo, ", Nwk Addr: 0x%04x, Desc: \'%s\'", device, user); /* Dump any leftover bytes. */ zdp_dump_excess(tvb, offset, pinfo, tree); } /* dissect_zbee_zdp_req_set_user_desc */ /** *ZigBee Device Profile dissector for the system server * *@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. */ void dissect_zbee_zdp_req_system_server_disc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { guint offset = 0; /*guint16 server_flags;*/ /*server_flags =*/ zdp_parse_server_flags(tree, ett_zbee_zdp_server, tvb, &offset); /* Dump any leftover bytes. */ zdp_dump_excess(tvb, offset, pinfo, tree); } /* dissect_zbee_zdp_req_system_server_disc */ /** *ZigBee Device Profile dissector for the store node cache * *@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. */ void dissect_zbee_zdp_req_store_discovery(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_tree *field_tree; guint offset = 0; guint i; guint64 ext_addr; guint32 simple_count; proto_tree_add_item(tree, hf_zbee_zdp_nwk_addr, tvb, offset, 2, ENC_LITTLE_ENDIAN); offset += 2; ext_addr = zbee_parse_eui64(tree, hf_zbee_zdp_ext_addr, tvb, &offset, (int)sizeof(guint64), NULL); proto_tree_add_item(tree, hf_zbee_zdp_disc_node_size, tvb, offset, 1, ENC_LITTLE_ENDIAN); offset += 1; proto_tree_add_item(tree, hf_zbee_zdp_disc_power_size, tvb, offset, 1, ENC_LITTLE_ENDIAN); offset += 1; proto_tree_add_item(tree, hf_zbee_zdp_disc_ep_count, tvb, offset, 1, ENC_LITTLE_ENDIAN); offset += 1; proto_tree_add_item_ret_uint(tree, hf_zbee_zdp_disc_simple_count, tvb, offset, 1, ENC_LITTLE_ENDIAN, &simple_count); offset += 1; field_tree = proto_tree_add_subtree(tree, tvb, offset, simple_count, ett_zbee_zdp_simple_sizes, NULL, "Simple Descriptor Sizes"); for (i=0; i= ZBEE_VERSION_2007) || (status == ZBEE_ZDP_STATUS_SUCCESS)) { /* In ZigBee 2003 & earlier, the length field is omitted if not successful. */ proto_tree_add_item_ret_uint(tree, hf_zbee_zdp_user_length, tvb, offset, 1, ENC_LITTLE_ENDIAN, &user_length); offset += 1; } else user_length = 0; user = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, user_length, ENC_ASCII); if (tree) { proto_tree_add_string(tree, hf_zbee_zdp_user, tvb, offset, user_length, user); } offset += user_length; zbee_append_info(tree, pinfo, ", Nwk Addr: 0x%04x", device); if (status == ZBEE_ZDP_STATUS_SUCCESS) { zbee_append_info(tree, pinfo, ", Desc: \'%s\'", user); } zbee_append_info(tree, pinfo, ", Status: %s", zdp_status_name(status)); /* Dump any leftover bytes. */ zdp_dump_excess(tvb, offset, pinfo, tree); } /* dissect_zbee_zdp_rsp_user_desc */ /** *ZigBee Device Profile dissector for the set user descriptor * *@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. */ void dissect_zbee_zdp_rsp_user_desc_conf(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint8 version) { guint offset = 0; guint8 status; guint32 device = 0; status = zdp_parse_status(tree, tvb, &offset); if (version >= ZBEE_VERSION_2007) { /* Device address present only on ZigBee 2006 & later. */ proto_tree_add_item_ret_uint(tree, hf_zbee_zdp_nwk_addr, tvb, offset, 2, ENC_LITTLE_ENDIAN, &device); offset += 2; } zbee_append_info(tree, pinfo, ", Nwk Addr: 0x%04x", device); zbee_append_info(tree, pinfo, ", Status: %s", zdp_status_name(status)); /* Dump any leftover bytes. */ zdp_dump_excess(tvb, offset, pinfo, tree); } /* dissect_zbee_zdp_rsp_user_desc_conf */ /** *ZigBee Device Profile dissector for the discovery cache * *@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. */ void dissect_zbee_zdp_rsp_discovery_cache(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { guint offset = 0; guint8 status; status = zdp_parse_status(tree, tvb, &offset); zbee_append_info(tree, pinfo, ", Status: %s", zdp_status_name(status)); /* Dump any leftover bytes. */ zdp_dump_excess(tvb, offset, pinfo, tree); } /* dissect_zbee_zdp_rsp_discovery_cache */ /** *ZigBee Device Profile dissector for the system server discovery * *@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. */ void dissect_zbee_zdp_rsp_system_server_disc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { guint offset = 0; guint8 status; /*guint16 server;*/ status = zdp_parse_status(tree, tvb, &offset); /*server =*/ zdp_parse_server_flags(tree, ett_zbee_zdp_server, tvb, &offset); zbee_append_info(tree, pinfo, ", Status: %s", zdp_status_name(status)); /* Dump any leftover bytes. */ zdp_dump_excess(tvb, offset, pinfo, tree); } /* dissect_zbee_zdp_rsp_system_server_disc */ /** *ZigBee Device Profile dissector for the discovery store * *@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. */ void dissect_zbee_zdp_rsp_discovery_store(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { guint offset = 0; guint8 status; status = zdp_parse_status(tree, tvb, &offset); zbee_append_info(tree, pinfo, ", Status: %s", zdp_status_name(status)); /* Dump any leftover bytes. */ zdp_dump_excess(tvb, offset, pinfo, tree); } /* dissect_zbee_zdp_rsp_discovery_store */ /** *ZigBee Device Profile dissector for the store node descriptor * *@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. */ void dissect_zbee_zdp_rsp_store_node_desc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { guint offset = 0; guint8 status; status = zdp_parse_status(tree, tvb, &offset); zbee_append_info(tree, pinfo, ", Status: %s", zdp_status_name(status)); /* Dump any leftover bytes. */ zdp_dump_excess(tvb, offset, pinfo, tree); } /* dissect_zbee_zdp_rsp_store_node_desc */ /** *ZigBee Device Profile dissector for the store power descriptor * *@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. */ void dissect_zbee_zdp_rsp_store_power_desc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { guint offset = 0; guint8 status; status = zdp_parse_status(tree, tvb, &offset); zbee_append_info(tree, pinfo, ", Status: %s", zdp_status_name(status)); /* Dump any leftover bytes. */ zdp_dump_excess(tvb, offset, pinfo, tree); } /* dissect_zbee_zdp_rsp_store_power_desc */ /** *ZigBee Device Profile dissector for the store active endpoints * *@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. */ void dissect_zbee_zdp_rsp_store_active_ep(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { guint offset = 0; guint8 status; status = zdp_parse_status(tree, tvb, &offset); zbee_append_info(tree, pinfo, ", Status: %s", zdp_status_name(status)); /* Dump any leftover bytes. */ zdp_dump_excess(tvb, offset, pinfo, tree); } /* dissect_zbee_zdp_rsp_store_active_ep */ /** *ZigBee Device Profile dissector for the store power descriptor * *@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. */ void dissect_zbee_zdp_rsp_store_simple_desc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { guint offset = 0; guint8 status; status = zdp_parse_status(tree, tvb, &offset); zbee_append_info(tree, pinfo, ", Status: %s", zdp_status_name(status)); /* Dump any leftover bytes. */ zdp_dump_excess(tvb, offset, pinfo, tree); } /* dissect_zbee_zdp_rsp_store_simple_desc */ /** *ZigBee Device Profile dissector for the remove node cache * *@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. */ void dissect_zbee_zdp_rsp_remove_node_cache(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { guint offset = 0; guint8 status; status = zdp_parse_status(tree, tvb, &offset); zbee_append_info(tree, pinfo, ", Status: %s", zdp_status_name(status)); /* Dump any leftover bytes. */ zdp_dump_excess(tvb, offset, pinfo, tree); } /* dissect_zbee_zdp_rsp_remove_node_cache */ /** *ZigBee Device Profile dissector for the find node cache * *@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. */ void dissect_zbee_zdp_rsp_find_node_cache(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { guint offset = 0; guint32 device, cache; proto_tree_add_item_ret_uint(tree, hf_zbee_zdp_cache, tvb, offset, 2, ENC_LITTLE_ENDIAN, &cache); offset += 2; proto_tree_add_item_ret_uint(tree, hf_zbee_zdp_nwk_addr, tvb, offset, 2, ENC_LITTLE_ENDIAN, &device); offset += 2; /*ext_addr =*/ zbee_parse_eui64(tree, hf_zbee_zdp_ext_addr, tvb, &offset, (int)sizeof(guint64), NULL); zbee_append_info(tree, pinfo, ", Cache: 0x%04x", cache); zbee_append_info(tree, pinfo, ", Nwk Addr: 0x%04x", device); /* Dump any leftover bytes. */ zdp_dump_excess(tvb, offset, pinfo, tree); } /* dissect_zbee_zdp_rsp_find_node_cache */ /** *ZigBee Device Profile dissector for the extended simple * *@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. */ void dissect_zbee_zdp_rsp_ext_simple_desc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_item *ti; guint offset = 0; guint i; guint sizeof_cluster = (int)sizeof(guint16); guint8 status; guint32 device, cluster, in_count, out_count, idx; status = zdp_parse_status(tree, tvb, &offset); proto_tree_add_item_ret_uint(tree, hf_zbee_zdp_nwk_addr, tvb, offset, 2, ENC_LITTLE_ENDIAN, &device); offset += 2; proto_tree_add_item(tree, hf_zbee_zdp_endpoint, tvb, offset, 1, ENC_LITTLE_ENDIAN); offset += 1; proto_tree_add_item_ret_uint(tree, hf_zbee_zdp_in_count, tvb, offset, 1, ENC_LITTLE_ENDIAN, &in_count); offset += 1; proto_tree_add_item_ret_uint(tree, hf_zbee_zdp_out_count, tvb, offset, 1, ENC_LITTLE_ENDIAN, &out_count); offset += 1; proto_tree_add_item_ret_uint(tree, hf_zbee_zdp_index, tvb, offset, 1, ENC_LITTLE_ENDIAN, &idx); offset += 1; /* Display the input cluster list. */ for (i=idx; (i