aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-zbee-zdp-management.c
diff options
context:
space:
mode:
authorgerald <gerald@f5534014-38df-0310-8fa8-9805f1628bb7>2009-05-20 19:29:39 +0000
committergerald <gerald@f5534014-38df-0310-8fa8-9805f1628bb7>2009-05-20 19:29:39 +0000
commitb88af83b5f89dce7283b0ef8a6f2d8c008e4f579 (patch)
treecf014ea9608d08848508d6b9bc54bda8f10cc80c /epan/dissectors/packet-zbee-zdp-management.c
parent54cd1504535bfa852c938f1f6e0464ba1896e76f (diff)
From Owen Kirby via bug 3431:
The attached patch file adds dissectors for the ZigBee protocol stack, which runs atop the IEEE 802.15.4 dissector. Also included is the dissector for the ZigBee Encapsulation Protocol (packet-zep.c), used by the Exegin Q51 protocol analyzer. From me: Fix a bunch of gcc (the compiler, not me) warnings. git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@28429 f5534014-38df-0310-8fa8-9805f1628bb7
Diffstat (limited to 'epan/dissectors/packet-zbee-zdp-management.c')
-rw-r--r--epan/dissectors/packet-zbee-zdp-management.c959
1 files changed, 959 insertions, 0 deletions
diff --git a/epan/dissectors/packet-zbee-zdp-management.c b/epan/dissectors/packet-zbee-zdp-management.c
new file mode 100644
index 0000000000..d62ce5d38e
--- /dev/null
+++ b/epan/dissectors/packet-zbee-zdp-management.c
@@ -0,0 +1,959 @@
+/* packet-zbee-zdp-management.c
+ * Dissector helper routines for the management services of the ZigBee Device Profile
+ * By Owen Kirby <osk@exegin.com>
+ * Copyright 2009 Exegin Technologies Limited
+ *
+ * $Id$
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/* Include Files */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif /* HAVE_CONFIG_H */
+
+#include <string.h>
+#include <stdlib.h>
+#include <glib.h>
+#include <gmodule.h>
+#include <epan/packet.h>
+
+#include "packet-zbee.h"
+#include "packet-zbee-zdp.h"
+
+/**************************************
+ * HELPER FUNCTIONS
+ **************************************
+ */
+/*FUNCTION:------------------------------------------------------
+ * NAME
+ * zdp_parse_nwk_desc
+ * DESCRIPTION
+ * Parses and displays a single network descriptor
+ * PARAMETERS
+ * tvbuff_t *tvb - pointer to buffer containing raw packet.
+ * packet_into *pinfo - pointer to packet information fields
+ * proto_tree *tree - pointer to data tree ethereal uses to display packet.
+ * RETURNS
+ * void
+ *---------------------------------------------------------------
+ */
+void
+zdp_parse_nwk_desc(proto_tree *tree, tvbuff_t *tvb, guint *offset, packet_info *pinfo)
+{
+ proto_item *ti = NULL;
+ guint len = 0;
+
+ guint64 ext_pan;
+ guint16 pan;
+ guint8 channel;
+ guint8 profile;
+ guint8 version;
+ guint8 beacon;
+ guint8 superframe;
+ gboolean permit;
+
+ if (pinfo->zbee_stack_vers >= ZBEE_VERSION_2007) {
+ /* Extended PAN Identifiers are used in ZigBee 2006 & later. */
+ ext_pan = tvb_get_letoh64(tvb, *offset + len);
+ if (tree) ti = proto_tree_add_text(tree, tvb, *offset, 0, "{Pan: %s", print_eui64(ext_pan));
+ len += sizeof(guint64);
+ }
+ else {
+ /* Short PAN Identifiers are used in ZigBee 2003 and earlier. */
+ pan = tvb_get_letohs(tvb, *offset + len);
+ if (tree) ti = proto_tree_add_text(tree, tvb, *offset, 0, "{Pan: 0x%04x", pan);
+ len += sizeof(guint16);
+ }
+
+ channel = tvb_get_guint8(tvb, *offset + len);
+ if (tree) proto_item_append_text(ti, ", Channel: %d", channel);
+ len += sizeof(guint8);
+
+ profile = (tvb_get_guint8(tvb, *offset + len) & 0x0f) >> 0;
+ version = (tvb_get_guint8(tvb, *offset + len) & 0xf0) >> 4;
+ if (tree) proto_item_append_text(ti, ", Profile: 0x%01x, Version: %d", profile, version);
+ len += sizeof(guint8);
+
+ beacon = (tvb_get_guint8(tvb, *offset + len) & 0x0f) >> 0;
+ superframe = (tvb_get_guint8(tvb, *offset + len) & 0xf0) >> 4;
+ if ((tree) && (beacon == 0xf)) {
+ proto_item_append_text(ti, ", Beacons Disabled");
+ }
+ else if (tree) {
+ proto_item_append_text(ti, ", BeaconOrder: %d, SuperframeOrder: %d", beacon, superframe);
+ }
+ len += sizeof(guint8);
+
+ permit = tvb_get_guint8(tvb, *offset) & 0x01;
+ if (tree) proto_item_append_text(ti, ", PermitJoining: %s}", permit?"True":"False");
+ len += sizeof(guint8);
+
+ if (tree) proto_item_set_len(ti, len);
+ *offset += len;
+} /* zdp_parse_nwk_desc */
+
+/*FUNCTION:------------------------------------------------------
+ * NAME
+ * zdp_parse_neighbor_table_entry
+ * DESCRIPTION
+ * Parses and displays a neighbor table entry.
+ * PARAMETERS
+ * tvbuff_t *tvb - pointer to buffer containing raw packet.
+ * packet_into *pinfo - pointer to packet information fields
+ * proto_tree *tree - pointer to data tree ethereal uses to display packet.
+ * RETURNS
+ * void
+ *---------------------------------------------------------------
+ */
+void
+zdp_parse_neighbor_table_entry(proto_tree *tree, tvbuff_t *tvb, guint *offset, packet_info *pinfo)
+{
+ proto_item *ti = NULL;
+ guint len = 0;
+
+ guint64 ext_pan;
+ guint16 pan;
+ guint64 ext_addr;
+ guint16 device;
+ guint8 type;
+ guint8 idle_rx;
+ guint8 rel;
+ guint8 permit_joining;
+ guint8 depth;
+ guint8 lqi;
+
+ if (pinfo->zbee_stack_vers >= ZBEE_VERSION_2007) {
+ /* ZigBee 2006 & later use an extended PAN Identifier. */
+ ext_pan = tvb_get_letoh64(tvb, *offset + len);
+ if (tree) ti = proto_tree_add_text(tree, tvb, *offset, 0, "{Extended PAN: %s", print_eui64(ext_pan));
+ len += sizeof(guint64);
+ }
+ else {
+ /* ZigBee 2003 & earlier use a short PAN Identifier. */
+ pan = tvb_get_letohs(tvb, *offset + len);
+ if (tree) ti = proto_tree_add_text(tree, tvb, *offset, 0, "{PAN: 0x%04x", pan);
+ len += sizeof(guint16);
+ }
+
+ ext_addr = tvb_get_letoh64(tvb, *offset + len);
+ if (tree) proto_item_append_text(ti, ", Extended Addr: %s", print_eui64_oui(ext_addr));
+ len += sizeof(guint64);
+
+ device = tvb_get_letohs(tvb, *offset + len);
+ if (tree) proto_item_append_text(ti, ", Addr: 0x%04x", device);
+ len += sizeof(guint16);
+
+ if (pinfo->zbee_stack_vers >= ZBEE_VERSION_2007) {
+ type = (tvb_get_guint8(tvb, *offset + len) & 0x03) >> 0;
+ idle_rx = (tvb_get_guint8(tvb, *offset + len) & 0x0c) >> 2;
+ rel = (tvb_get_guint8(tvb, *offset + len) & 0x70) >> 4;
+ }
+ else {
+ type = (tvb_get_guint8(tvb, *offset + len) & 0x03) >> 0;
+ idle_rx = (tvb_get_guint8(tvb, *offset + len) & 0x04) >> 2;
+ rel = (tvb_get_guint8(tvb, *offset + len) & 0x18) >> 3;
+ }
+ if (tree) {
+ if (type == 0x00) proto_item_append_text(ti, ", Type: Coordinator");
+ else if (type == 0x01) proto_item_append_text(ti, ", Type: Router");
+ else if (type == 0x02) proto_item_append_text(ti, ", Type: End Device");
+ else proto_item_append_text(ti, ", Type: Unknown");
+
+ if (idle_rx == 0x00) proto_item_append_text(ti, ", Idle Rx: False");
+ else if (idle_rx==0x01) proto_item_append_text(ti, ", Idle Rx: True");
+ else proto_item_append_text(ti, ", Idle Rx: Unknown");
+
+ if (rel == 0x00) proto_item_append_text(ti, ", Relationship: Parent");
+ else if (rel == 0x01) proto_item_append_text(ti, ", Relationship: Child");
+ else if (rel == 0x02) proto_item_append_text(ti, ", Relationship: Sibling");
+ else if (rel == 0x03) proto_item_append_text(ti, ", Relationship: None");
+ else if (rel == 0x04) proto_item_append_text(ti, ", Relationship: Previous Child");
+ else proto_item_append_text(ti, ", Relationship: Unknown");
+ }
+ len += sizeof(guint8);
+
+ if (pinfo->zbee_stack_vers <= ZBEE_VERSION_2004) {
+ /* In ZigBee 2003 & earlier, the depth field is before the permit joining field. */
+ depth = tvb_get_guint8(tvb, *offset + len);
+ if (tree) proto_item_append_text(ti, ", Depth: %d", depth);
+ len += sizeof(guint8);
+ }
+
+ permit_joining = (tvb_get_guint8(tvb, *offset + len) & 0x03) >> 0;
+ if (tree) {
+ if (permit_joining == 0x00) proto_item_append_text(ti, ", Permit Joining: False");
+ else if (permit_joining == 0x01)proto_item_append_text(ti, ", Permit Joining: True");
+ else proto_item_append_text(ti, ", Permit Joining: Unknown");
+ }
+ len += sizeof(guint8);
+
+ if (pinfo->zbee_stack_vers >= ZBEE_VERSION_2007) {
+ /* In ZigBee 2006 & later, the depth field is after the permit joining field. */
+ depth = tvb_get_guint8(tvb, *offset + len);
+ if (tree) proto_item_append_text(ti, ", Depth: %d", depth);
+ len += sizeof(guint8);
+ }
+
+ lqi = tvb_get_guint8(tvb, *offset + len);
+ if (tree) proto_item_append_text(ti, ", LQI: %d}", lqi);
+ len += sizeof(guint8);
+
+ if (tree) proto_item_set_len(ti, len);
+ *offset += len;
+} /* zdp_parse_neighbor_table_entry */
+
+/*FUNCTION:------------------------------------------------------
+ * NAME
+ * zdp_parse_routing_table_entry
+ * DESCRIPTION
+ * Parses and displays a routing table entry.
+ * PARAMETERS
+ * tvbuff_t *tvb - pointer to buffer containing raw packet.
+ * proto_tree *tree - pointer to data tree ethereal uses to display packet.
+ * RETURNS
+ * void
+ *---------------------------------------------------------------
+ */
+static void
+zdp_parse_routing_table_entry(proto_tree *tree, tvbuff_t *tvb, guint *offset)
+{
+ proto_item *ti = NULL;
+ guint len = 0;
+
+ guint16 dest;
+ guint8 status;
+ guint16 next;
+
+ dest = tvb_get_letohs(tvb, *offset + len);
+ if (tree) ti = proto_tree_add_text(tree, tvb, *offset, 2*sizeof(guint16) + sizeof(guint8), "{Destination: 0x%04x", dest);
+ len += sizeof(guint16);
+
+ status = tvb_get_guint8(tvb, *offset + len);
+ next = tvb_get_letohs(tvb, *offset + len + sizeof(guint8));
+ if (tree) {
+ /* Display the next hop first, because it looks a lot cleaner that way. */
+ proto_item_append_text(ti, ", Next Hop: 0x%04x", next);
+
+ if (status == 0x00) proto_item_append_text(ti, ", Status: Active}");
+ else if (status == 0x01)proto_item_append_text(ti, ", Status: Discovery Underway}");
+ else if (status == 0x02)proto_item_append_text(ti, ", Status: Discovery Failed}");
+ else if (status == 0x03)proto_item_append_text(ti, ", Status: Inactive}");
+ else proto_item_append_text(ti, ", Status: Unknown}");
+ }
+ len += sizeof(guint8) + sizeof(guint16);
+
+ *offset += len;
+} /* zdp_parse_routing_table_entry */
+
+/*FUNCTION:------------------------------------------------------
+ * NAME
+ * zdp_parse_bind_table_entry
+ * DESCRIPTION
+ * Parses and displays a single binding table entry.
+ * PARAMETERS
+ * tvbuff_t *tvb - pointer to buffer containing raw packet.
+ * packet_into *pinfo - pointer to packet information fields
+ * proto_tree *tree - pointer to data tree ethereal uses to display packet.
+ * RETURNS
+ * void
+ *---------------------------------------------------------------
+ */
+extern void zdp_parse_bind_table_entry(proto_tree *tree, tvbuff_t *tvb, guint *offset, packet_info *pinfo);
+
+/**************************************
+ * MANAGEMENT REQUESTS
+ **************************************
+ */
+/*FUNCTION:------------------------------------------------------
+ * NAME
+ * dissect_zbee_zdp_req_mgmt_nwk_disc
+ * DESCRIPTION
+ * ZigBee Device Profile dissector for the network discovery
+ * request. Cluster ID = 0x0030.
+ * PARAMETERS
+ * tvbuff_t *tvb - pointer to buffer containing raw packet.
+ * packet_into *pinfo - pointer to packet information fields
+ * proto_tree *tree - pointer to data tree ethereal uses to display packet.
+ * RETURNS
+ * void
+ *---------------------------------------------------------------
+ */
+void
+dissect_zbee_zdp_req_mgmt_nwk_disc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+ proto_item *ti;
+ guint i;
+
+ guint offset = 0;
+ guint32 channels;
+ guint8 duration;
+ guint8 index;
+
+ /* Get the channel bitmap. */
+ channels = tvb_get_letohl(tvb, offset);
+ if (tree) {
+ gboolean first = 1;
+ ti = proto_tree_add_text(tree, tvb, offset, sizeof(guint32), "Scan Channels: ");
+
+ for (i=0; i<27; i++) {
+ if (channels & (1<<i)) {
+ if (first) proto_item_append_text(ti, "%d", i);
+ else proto_item_append_text(ti, ", %d", i);
+ if (channels & (2<<i)) {
+ while ((channels&(2<<i)) && (i<26)) i++;
+ proto_item_append_text(ti, "-%d", i);
+ }
+ first = 0;
+ }
+ }
+ if (first) proto_item_append_text(ti, "None");
+ }
+ offset += sizeof(guint32);
+
+ duration = zbee_parse_uint(tree, hf_zbee_zdp_duration, tvb, &offset, sizeof(guint8), NULL);
+ index = zbee_parse_uint(tree, hf_zbee_zdp_index, tvb, &offset, sizeof(guint8), NULL);
+
+ /* Dump any leftover bytes. */
+ zdp_dump_excess(tvb, offset, pinfo, tree);
+} /* dissect_zbee_zdp_req_mgmt_nwk_disc */
+
+/*FUNCTION:------------------------------------------------------
+ * NAME
+ * dissect_zbee_zdp_req_mgmt_lqi
+ * DESCRIPTION
+ * ZigBee Device Profile dissector for the link quality information
+ * request. Cluster ID = 0x0031.
+ * PARAMETERS
+ * tvbuff_t *tvb - pointer to buffer containing raw packet.
+ * packet_into *pinfo - pointer to packet information fields
+ * proto_tree *tree - pointer to data tree ethereal uses to display packet.
+ * RETURNS
+ * void
+ *---------------------------------------------------------------
+ */
+void
+dissect_zbee_zdp_req_mgmt_lqi(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+ guint offset = 0;
+ guint8 index;
+
+ index = zbee_parse_uint(tree, hf_zbee_zdp_index, tvb, &offset, sizeof(guint8), NULL);
+
+ /* Dump any leftover bytes. */
+ zdp_dump_excess(tvb, offset, pinfo, tree);
+} /* dissect_zbee_zdp_req_mgmt_lqi */
+
+/*FUNCTION:------------------------------------------------------
+ * NAME
+ * dissect_zbee_zdp_req_mgmt_rtg
+ * DESCRIPTION
+ * ZigBee Device Profile dissector for the routing table
+ * request. Cluster ID = 0x0032.
+ * PARAMETERS
+ * tvbuff_t *tvb - pointer to buffer containing raw packet.
+ * packet_into *pinfo - pointer to packet information fields
+ * proto_tree *tree - pointer to data tree ethereal uses to display packet.
+ * RETURNS
+ * void
+ *---------------------------------------------------------------
+ */
+void
+dissect_zbee_zdp_req_mgmt_rtg(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+ guint offset = 0;
+ guint8 index;
+
+ index = zbee_parse_uint(tree, hf_zbee_zdp_index, tvb, &offset, sizeof(guint8), NULL);
+
+ /* Dump any leftover bytes. */
+ zdp_dump_excess(tvb, offset, pinfo, tree);
+} /* dissect_zbee_zdp_req_mgmt_rtg */
+
+/*FUNCTION:------------------------------------------------------
+ * NAME
+ * dissect_zbee_zdp_req_mgmt_bind
+ * DESCRIPTION
+ * ZigBee Device Profile dissector for the binding table
+ * request. Cluster ID = 0x0033.
+ * PARAMETERS
+ * tvbuff_t *tvb - pointer to buffer containing raw packet.
+ * packet_into *pinfo - pointer to packet information fields
+ * proto_tree *tree - pointer to data tree ethereal uses to display packet.
+ * RETURNS
+ * void
+ *---------------------------------------------------------------
+ */
+void
+dissect_zbee_zdp_req_mgmt_bind(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+ guint offset = 0;
+ guint8 index;
+
+ index = zbee_parse_uint(tree, hf_zbee_zdp_index, tvb, &offset, sizeof(guint8), NULL);
+
+ /* Dump any leftover bytes. */
+ zdp_dump_excess(tvb, offset, pinfo, tree);
+} /* dissect_zbee_zdp_req_mgmt_bind */
+
+/*FUNCTION:------------------------------------------------------
+ * NAME
+ * dissect_zbee_zdp_req_mgmt_leave
+ * DESCRIPTION
+ * ZigBee Device Profile dissector for the leave request.
+ * Cluster ID = 0x0034.
+ * PARAMETERS
+ * tvbuff_t *tvb - pointer to buffer containing raw packet.
+ * packet_into *pinfo - pointer to packet information fields
+ * proto_tree *tree - pointer to data tree ethereal uses to display packet.
+ * RETURNS
+ * void
+ *---------------------------------------------------------------
+ */
+void
+dissect_zbee_zdp_req_mgmt_leave(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+ guint offset = 0;
+ guint64 ext_addr;
+ guint8 flags;
+
+ ext_addr = zbee_parse_eui64(tree, hf_zbee_zdp_ext_addr, tvb, &offset, sizeof(guint64), NULL);
+ if (pinfo->zbee_stack_vers >= ZBEE_VERSION_2007) {
+ /* Flags present on ZigBee 2006 & later. */
+ flags = tvb_get_guint8(tvb, offset);
+ if (tree) {
+ proto_tree_add_boolean(tree, hf_zbee_zdp_leave_children, tvb, offset, sizeof(guint8), flags & ZBEE_ZDP_MGMT_LEAVE_CHILDREN);
+ proto_tree_add_boolean(tree, hf_zbee_zdp_leave_rejoin, tvb, offset, sizeof(guint8), flags & ZBEE_ZDP_MGMT_LEAVE_REJOIN);
+ }
+ offset += sizeof(guint8);
+ }
+
+ zbee_append_info(tree, pinfo, ", Device: %s", print_eui64_oui(ext_addr));
+
+ /* Dump any leftover bytes. */
+ zdp_dump_excess(tvb, offset, pinfo, tree);
+} /* dissect_zbee_zdp_req_mgmt_bind */
+
+/*FUNCTION:------------------------------------------------------
+ * NAME
+ * dissect_zbee_zdp_req_mgmt_direct_join
+ * DESCRIPTION
+ * ZigBee Device Profile dissector for the direct join request.
+ * Cluster ID = 0x0035.
+ * PARAMETERS
+ * tvbuff_t *tvb - pointer to buffer containing raw packet.
+ * packet_into *pinfo - pointer to packet information fields
+ * proto_tree *tree - pointer to data tree ethereal uses to display packet.
+ * RETURNS
+ * void
+ *---------------------------------------------------------------
+ */
+void
+dissect_zbee_zdp_req_mgmt_direct_join(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+ guint offset = 0;
+ guint64 ext_addr;
+ guint8 cinfo;
+
+ ext_addr = zbee_parse_eui64(tree, hf_zbee_zdp_ext_addr, tvb, &offset, sizeof(guint64), NULL);
+ cinfo = zdp_parse_cinfo(tree, ett_zbee_zdp_cinfo, tvb, &offset);
+
+ zbee_append_info(tree, pinfo, ", Device: %s", print_eui64_oui(ext_addr));
+
+ /* Dump any leftover bytes. */
+ zdp_dump_excess(tvb, offset, pinfo, tree);
+} /* dissect_zbee_zdp_req_mgmt_direct_join */
+
+/*FUNCTION:------------------------------------------------------
+ * NAME
+ * dissect_zbee_zdp_req_mgmt_permit_join
+ * DESCRIPTION
+ * ZigBee Device Profile dissector for the permit joining
+ * request. Cluster ID = 0x0036.
+ * PARAMETERS
+ * tvbuff_t *tvb - pointer to buffer containing raw packet.
+ * packet_into *pinfo - pointer to packet information fields
+ * proto_tree *tree - pointer to data tree ethereal uses to display packet.
+ * RETURNS
+ * void
+ *---------------------------------------------------------------
+ */
+void
+dissect_zbee_zdp_req_mgmt_permit_join(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+ guint offset = 0;
+ guint8 duration;
+ guint8 significance;
+
+ duration = zbee_parse_uint(tree, hf_zbee_zdp_duration, tvb, &offset, sizeof(guint8), NULL);
+ significance = zbee_parse_uint(tree, hf_zbee_zdp_significance, tvb, &offset, sizeof(guint8), NULL);
+
+ /* Dump any leftover bytes. */
+ zdp_dump_excess(tvb, offset, pinfo, tree);
+} /* dissect_zbee_zdp_req_mgmt_permit_join */
+
+/*FUNCTION:------------------------------------------------------
+ * NAME
+ * dissect_zbee_zdp_req_mgmt_cache
+ * DESCRIPTION
+ * ZigBee Device Profile dissector for the cache request.
+ * Cluster ID = 0x0037.
+ * PARAMETERS
+ * tvbuff_t *tvb - pointer to buffer containing raw packet.
+ * packet_into *pinfo - pointer to packet information fields
+ * proto_tree *tree - pointer to data tree ethereal uses to display packet.
+ * RETURNS
+ * void
+ *---------------------------------------------------------------
+ */
+void
+dissect_zbee_zdp_req_mgmt_cache(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+ guint offset = 0;
+ guint8 index;
+
+ index = zbee_parse_uint(tree, hf_zbee_zdp_index, tvb, &offset, sizeof(guint8), NULL);
+
+ /* Dump any leftover bytes. */
+ zdp_dump_excess(tvb, offset, pinfo, tree);
+} /* dissect_zbee_zdp_req_mgmt_cache */
+
+/*FUNCTION:------------------------------------------------------
+ * NAME
+ * dissect_zbee_zdp_req_mgmt_nwkupdate
+ * DESCRIPTION
+ * ZigBee Device Profile dissector for the nwk update request.
+ * Cluster ID = 0x0038.
+ * PARAMETERS
+ * tvbuff_t *tvb - pointer to buffer containing raw packet.
+ * packet_into *pinfo - pointer to packet information fields
+ * proto_tree *tree - pointer to data tree ethereal uses to display packet.
+ * RETURNS
+ * void
+ *---------------------------------------------------------------
+ */
+void
+dissect_zbee_zdp_req_mgmt_nwkupdate(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+ guint offset = 0;
+ guint32 channels;
+ guint8 duration;
+ guint8 count;
+ guint8 update_id;
+ guint16 manager;
+
+ channels = zdp_parse_chanmask(tree, tvb, &offset);
+ duration = zbee_parse_uint(tree, hf_zbee_zdp_duration, tvb, &offset, sizeof(guint8), NULL);
+ if (duration == ZBEE_ZDP_NWKUPDATE_PARAMETERS) {
+ update_id = zbee_parse_uint(tree, hf_zbee_zdp_update_id, tvb, &offset, sizeof(guint8), NULL);
+ manager = zbee_parse_uint(tree, hf_zbee_zdp_manager, tvb, &offset, sizeof(guint16), NULL);
+ }
+ else if (duration == ZBEE_ZDP_NWKUPDATE_CHANNEL_HOP) {
+ update_id = zbee_parse_uint(tree, hf_zbee_zdp_update_id, tvb, &offset, sizeof(guint8), NULL);
+ }
+ else if (duration <= ZBEE_ZDP_NWKUPDATE_SCAN_MAX) {
+ count = zbee_parse_uint(tree, hf_zbee_zdp_scan_count, tvb, &offset, sizeof(guint8), NULL);
+ }
+
+ /* Dump any leftover bytes. */
+ zdp_dump_excess(tvb, offset, pinfo, tree);
+} /* dissect_zbee_zdp_req_mgmt_nwkupdate */
+
+/**************************************
+ * MANAGEMENT RESPONSES
+ **************************************
+ */
+/*FUNCTION:------------------------------------------------------
+ * NAME
+ * dissect_zbee_zdp_rsp_mgmt_nwk_disc
+ * DESCRIPTION
+ * ZigBee Device Profile dissector for the network discovery
+ * response. Cluster ID = 0x8030.
+ * PARAMETERS
+ * tvbuff_t *tvb - pointer to buffer containing raw packet.
+ * packet_into *pinfo - pointer to packet information fields
+ * proto_tree *tree - pointer to data tree ethereal uses to display packet.
+ * RETURNS
+ * void
+ *---------------------------------------------------------------
+ */
+void
+dissect_zbee_zdp_rsp_mgmt_nwk_disc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+ proto_item *ti;
+ proto_tree *field_tree = NULL;
+ guint offset = 0;
+ guint i;
+
+ guint8 status;
+ guint8 table_size;
+ guint8 index;
+ guint8 table_count;
+
+ status = zdp_parse_status(tree, tvb, &offset);
+ table_size = zbee_parse_uint(tree, hf_zbee_zdp_table_size, tvb, &offset, sizeof(guint8), NULL);
+ index = zbee_parse_uint(tree, hf_zbee_zdp_index, tvb, &offset, sizeof(guint8), NULL);
+ table_count = zbee_parse_uint(tree, hf_zbee_zdp_table_count, tvb, &offset, sizeof(guint8), NULL);
+
+ if (tree && table_count) {
+ ti = proto_tree_add_text(tree, tvb, offset, tvb_length_remaining(tvb, offset), "Network List");
+ field_tree = proto_item_add_subtree(ti, ett_zbee_zdp_nwk);
+ }
+ for (i=0; i<table_count; i++) {
+ zdp_parse_nwk_desc(field_tree, tvb, &offset, pinfo);
+ } /* for */
+
+ 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_mgmt_nwk_disc */
+
+/*FUNCTION:------------------------------------------------------
+ * NAME
+ * dissect_zbee_zdp_rsp_mgmt_lqi
+ * DESCRIPTION
+ * ZigBee Device Profile dissector for the link quality information
+ * response. Cluster ID = 0x8031.
+ * PARAMETERS
+ * tvbuff_t *tvb - pointer to buffer containing raw packet.
+ * packet_into *pinfo - pointer to packet information fields
+ * proto_tree *tree - pointer to data tree ethereal uses to display packet.
+ * RETURNS
+ * void
+ *---------------------------------------------------------------
+ */
+void
+dissect_zbee_zdp_rsp_mgmt_lqi(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+ proto_item *ti;
+ proto_tree *field_tree = NULL;
+ guint offset = 0;
+ guint i;
+
+ guint8 status;
+ guint8 table_size;
+ guint8 index;
+ guint8 table_count;
+
+ status = zdp_parse_status(tree, tvb, &offset);
+ table_size = zbee_parse_uint(tree, hf_zbee_zdp_table_size, tvb, &offset, sizeof(guint8), NULL);
+ index = zbee_parse_uint(tree, hf_zbee_zdp_index, tvb, &offset, sizeof(guint8), NULL);
+ table_count = zbee_parse_uint(tree, hf_zbee_zdp_table_count, tvb, &offset, sizeof(guint8), NULL);
+
+ if (tree && table_count) {
+ ti = proto_tree_add_text(tree, tvb, offset, tvb_length_remaining(tvb, offset), "Neighbor Table");
+ field_tree = proto_item_add_subtree(ti, ett_zbee_zdp_lqi);
+ }
+ for (i=0; i<table_count; i++) {
+ zdp_parse_neighbor_table_entry(field_tree, tvb, &offset, pinfo);
+ } /* for */
+
+ 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_mgmt_lqi */
+
+/*FUNCTION:------------------------------------------------------
+ * NAME
+ * dissect_zbee_zdp_rsp_mgmt_rtg
+ * DESCRIPTION
+ * ZigBee Device Profile dissector for the routing table
+ * response. Cluster ID = 0x8032.
+ * PARAMETERS
+ * tvbuff_t *tvb - pointer to buffer containing raw packet.
+ * packet_into *pinfo - pointer to packet information fields
+ * proto_tree *tree - pointer to data tree ethereal uses to display packet.
+ * RETURNS
+ * void
+ *---------------------------------------------------------------
+ */
+void
+dissect_zbee_zdp_rsp_mgmt_rtg(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+ proto_item *ti;
+ proto_tree *field_tree = NULL;
+ guint offset = 0;
+ guint i;
+
+ guint8 status;
+ guint8 table_size;
+ guint8 index;
+ guint8 table_count;
+
+ status = zdp_parse_status(tree, tvb, &offset);
+ table_size = zbee_parse_uint(tree, hf_zbee_zdp_table_size, tvb, &offset, sizeof(guint8), NULL);
+ index = zbee_parse_uint(tree, hf_zbee_zdp_index, tvb, &offset, sizeof(guint8), NULL);
+ table_count = zbee_parse_uint(tree, hf_zbee_zdp_table_count, tvb, &offset, sizeof(guint8), NULL);
+
+ if (tree && table_count) {
+ ti = proto_tree_add_text(tree, tvb, offset, tvb_length_remaining(tvb, offset), "Routing Table");
+ field_tree = proto_item_add_subtree(ti, ett_zbee_zdp_rtg);
+ }
+ for (i=0; i<table_count; i++) {
+ zdp_parse_routing_table_entry(field_tree, tvb, &offset);
+ } /* for */
+
+ 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_mgmt_rtg */
+
+/*FUNCTION:------------------------------------------------------
+ * NAME
+ * dissect_zbee_zdp_rsp_mgmt_bind
+ * DESCRIPTION
+ * ZigBee Device Profile dissector for the binding table
+ * response. Cluster ID = 0x8033.
+ * PARAMETERS
+ * tvbuff_t *tvb - pointer to buffer containing raw packet.
+ * packet_into *pinfo - pointer to packet information fields
+ * proto_tree *tree - pointer to data tree ethereal uses to display packet.
+ * RETURNS
+ * void
+ *---------------------------------------------------------------
+ */
+void
+dissect_zbee_zdp_rsp_mgmt_bind(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+ proto_item *ti;
+ proto_tree *field_tree = NULL;
+ guint offset = 0;
+ guint i;
+
+ guint8 status;
+ guint8 table_size;
+ guint8 index;
+ guint8 table_count;
+
+ status = zdp_parse_status(tree, tvb, &offset);
+ table_size = zbee_parse_uint(tree, hf_zbee_zdp_table_size, tvb, &offset, sizeof(guint8), NULL);
+ index = zbee_parse_uint(tree, hf_zbee_zdp_index, tvb, &offset, sizeof(guint8), NULL);
+ table_count = zbee_parse_uint(tree, hf_zbee_zdp_table_count, tvb, &offset, sizeof(guint8), NULL);
+
+ if (tree && table_count) {
+ ti = proto_tree_add_text(tree, tvb, offset, tvb_length_remaining(tvb, offset), "Binding Table");
+ field_tree = proto_item_add_subtree(ti, ett_zbee_zdp_bind);
+ }
+ for (i=0; i<table_count; i++) {
+ zdp_parse_bind_table_entry(field_tree, tvb, &offset, pinfo);
+ } /* for */
+
+ 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_mgmt_bind */
+
+/*FUNCTION:------------------------------------------------------
+ * NAME
+ * dissect_zbee_zdp_rsp_mgmt_leave
+ * DESCRIPTION
+ * ZigBee Device Profile dissector for the leave response.
+ * Cluster ID = 0x8034.
+ * PARAMETERS
+ * tvbuff_t *tvb - pointer to buffer containing raw packet.
+ * packet_into *pinfo - pointer to packet information fields
+ * proto_tree *tree - pointer to data tree ethereal uses to display packet.
+ * RETURNS
+ * void
+ *---------------------------------------------------------------
+ */
+void
+dissect_zbee_zdp_rsp_mgmt_leave(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_mgmt_bind */
+
+/*FUNCTION:------------------------------------------------------
+ * NAME
+ * dissect_zbee_zdp_rsp_mgmt_direct_join
+ * DESCRIPTION
+ * ZigBee Device Profile dissector for the direct join response.
+ * Cluster ID = 0x8035.
+ * PARAMETERS
+ * tvbuff_t *tvb - pointer to buffer containing raw packet.
+ * packet_into *pinfo - pointer to packet information fields
+ * proto_tree *tree - pointer to data tree ethereal uses to display packet.
+ * RETURNS
+ * void
+ *---------------------------------------------------------------
+ */
+void
+dissect_zbee_zdp_rsp_mgmt_direct_join(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_mgmt_direct_join */
+
+/*FUNCTION:------------------------------------------------------
+ * NAME
+ * dissect_zbee_zdp_rsp_mgmt_permit_join
+ * DESCRIPTION
+ * ZigBee Device Profile dissector for the permit joining response.
+ * Cluster ID = 0x8036.
+ * PARAMETERS
+ * tvbuff_t *tvb - pointer to buffer containing raw packet.
+ * packet_into *pinfo - pointer to packet information fields
+ * proto_tree *tree - pointer to data tree ethereal uses to display packet.
+ * RETURNS
+ * void
+ *---------------------------------------------------------------
+ */
+void
+dissect_zbee_zdp_rsp_mgmt_permit_join(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_mgmt_permit_join */
+
+/*FUNCTION:------------------------------------------------------
+ * NAME
+ * dissect_zbee_zdp_rsp_mgmt_cache
+ * DESCRIPTION
+ * ZigBee Device Profile dissector for the cache response.
+ * Cluster ID = 0x8037.
+ * PARAMETERS
+ * tvbuff_t *tvb - pointer to buffer containing raw packet.
+ * packet_into *pinfo - pointer to packet information fields
+ * proto_tree *tree - pointer to data tree ethereal uses to display packet.
+ * RETURNS
+ * void
+ *---------------------------------------------------------------
+ */
+void
+dissect_zbee_zdp_rsp_mgmt_cache(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+ proto_item *ti;
+ proto_tree *field_tree;
+ guint offset = 0;
+ guint i;
+
+ guint8 status;
+ guint8 table_size;
+ guint8 index;
+ guint8 table_count;
+
+ status = zdp_parse_status(tree, tvb, &offset);
+ table_size = zbee_parse_uint(tree, hf_zbee_zdp_table_size, tvb, &offset, sizeof(guint8), NULL);
+ index = zbee_parse_uint(tree, hf_zbee_zdp_index, tvb, &offset, sizeof(guint8), NULL);
+ table_count = zbee_parse_uint(tree, hf_zbee_zdp_table_count, tvb, &offset, sizeof(guint8), NULL);
+
+ if (tree && table_count) {
+ ti = proto_tree_add_text(tree, tvb, offset, table_count*(sizeof(guint16)+sizeof(guint64)), "Discovery Cache");
+ field_tree = proto_item_add_subtree(ti, ett_zbee_zdp_cache);
+ }
+ for (i=0; i<table_count; i++) {
+ guint64 addr64 = tvb_get_letoh64(tvb, offset);
+ guint16 addr16 = tvb_get_letohs(tvb, offset+sizeof(guint64));
+
+ if (tree) {
+ proto_tree_add_text(tree, tvb, offset, sizeof(guint16)+sizeof(guint64), "{%s = 0x%04x}", print_eui64_oui(addr64), addr16);
+ }
+ offset += sizeof(guint16)+sizeof(guint64);
+ } /* for */
+
+ 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_mgmt_bind */
+
+/*FUNCTION:------------------------------------------------------
+ * NAME
+ * dissect_zbee_zdp_rsp_mgmt_nwkupdate
+ * DESCRIPTION
+ * ZigBee Device Profile dissector for the nwk update notify.
+ * Cluster ID = 0x8038.
+ * PARAMETERS
+ * tvbuff_t *tvb - pointer to buffer containing raw packet.
+ * packet_into *pinfo - pointer to packet information fields
+ * proto_tree *tree - pointer to data tree ethereal uses to display packet.
+ * RETURNS
+ * void
+ *---------------------------------------------------------------
+ */
+void
+dissect_zbee_zdp_rsp_mgmt_nwkupdate(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+ guint offset = 0;
+ guint i, j;
+
+ guint8 status;
+ guint32 channels;
+ guint16 tx_total;
+ guint16 tx_fail;
+ guint8 channel_count;
+
+ status = zdp_parse_status(tree, tvb, &offset);
+ channels = zdp_parse_chanmask(tree, tvb, &offset);
+ tx_total = zbee_parse_uint(tree, hf_zbee_zdp_tx_total, tvb, &offset, sizeof(guint16), NULL);
+ tx_fail = zbee_parse_uint(tree, hf_zbee_zdp_tx_fail, tvb, &offset, sizeof(guint16), NULL);
+ channel_count = zbee_parse_uint(tree, hf_zbee_zdp_channel_count, tvb, &offset, sizeof(guint8), NULL);
+
+ /* Display the channel list. */
+ for (i=0, j=0; i<(8*sizeof(guint32)); i++) {
+ guint8 energy;
+
+ if ( ! ((1<<i) & channels) ) {
+ /* Channel not scanned. */
+ continue;
+ }
+ if (j>=channel_count) {
+ /* Channel list has ended. */
+ break;
+ }
+ /* Get and display the channel energy. */
+ energy = tvb_get_guint8(tvb, offset);
+ if (tree) {
+ proto_tree_add_text(tree, tvb, offset, sizeof(guint8), "Channel %d Energy = 0x%02x", i, energy);
+ }
+ offset += sizeof(guint8);
+ /* Increment the number of channels we found energy values for. */
+ j++;
+ } /* for */
+
+ /* Dump any leftover bytes. */
+ zdp_dump_excess(tvb, offset, pinfo, tree);
+} /* dissect_zbee_zdp_rsp_mgmt_nwkupdate */