40f28408eea70e81a760db1c99b4495390b7407b
[obnox/wireshark/wip.git] / epan / dissectors / packet-zbee-zdp.c
1 /* packet-zbee-zdp.c
2  * Dissector routines for the ZigBee Device Profile (ZDP)
3  * By Owen Kirby <osk@exegin.com>
4  * Copyright 2009 Exegin Technologies Limited
5  *
6  * $Id$
7  *
8  * Wireshark - Network traffic analyzer
9  * By Gerald Combs <gerald@wireshark.org>
10  * Copyright 1998 Gerald Combs
11  *
12  * This program is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU General Public License
14  * as published by the Free Software Foundation; either version 2
15  * of the License, or (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
25  */
26
27 /*  Include Files */
28 #ifdef HAVE_CONFIG_H
29 #include "config.h"
30 #endif /* HAVE_CONFIG_H */
31
32 #include <string.h>
33 #include <stdlib.h>
34 #include <glib.h>
35 #include <gmodule.h>
36 #include <epan/packet.h>
37 #include <epan/expert.h>
38
39 #include "packet-zbee.h"
40 #include "packet-zbee-zdp.h"
41
42 /*************************/
43 /* Function Declarations */
44 /*************************/
45 /* Local Helper routines. */
46 static guint16 zdp_convert_2003cluster     (guint8 cluster);
47
48 /* Message dissector routines. */
49 extern void dissect_zbee_zdp_req_nwk_addr           (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
50 extern void dissect_zbee_zdp_req_ext_addr           (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
51 extern void dissect_zbee_zdp_req_node_desc          (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
52 extern void dissect_zbee_zdp_req_power_desc         (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
53 extern void dissect_zbee_zdp_req_simple_desc        (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
54 extern void dissect_zbee_zdp_req_active_ep          (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
55 extern void dissect_zbee_zdp_req_match_desc         (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
56 extern void dissect_zbee_zdp_req_complex_desc       (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
57 extern void dissect_zbee_zdp_req_user_desc          (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
58 extern void dissect_zbee_zdp_req_discovery_cache    (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
59 extern void dissect_zbee_zdp_device_annce           (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
60 extern void dissect_zbee_zdp_req_set_user_desc      (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
61 extern void dissect_zbee_zdp_req_system_server_disc (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
62 extern void dissect_zbee_zdp_req_store_discovery    (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
63 extern void dissect_zbee_zdp_req_store_node_desc    (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
64 extern void dissect_zbee_zdp_req_store_power_desc   (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
65 extern void dissect_zbee_zdp_req_store_active_ep    (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
66 extern void dissect_zbee_zdp_req_store_simple_desc  (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
67 extern void dissect_zbee_zdp_req_remove_node_cache  (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
68 extern void dissect_zbee_zdp_req_find_node_cache    (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
69 extern void dissect_zbee_zdp_req_ext_simple_desc    (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
70 extern void dissect_zbee_zdp_req_ext_active_ep      (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
71
72 extern void dissect_zbee_zdp_req_end_device_bind    (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
73 extern void dissect_zbee_zdp_req_bind               (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
74 extern void dissect_zbee_zdp_req_unbind             (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
75 extern void dissect_zbee_zdp_req_bind_register      (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
76 extern void dissect_zbee_zdp_req_replace_device     (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
77 extern void dissect_zbee_zdp_req_store_bak_bind_entry   (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
78 extern void dissect_zbee_zdp_req_remove_bak_bind_entry  (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
79 extern void dissect_zbee_zdp_req_backup_bind_table  (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
80 extern void dissect_zbee_zdp_req_recover_bind_table (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
81 extern void dissect_zbee_zdp_req_backup_source_bind (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
82 extern void dissect_zbee_zdp_req_recover_source_bind(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
83
84 extern void dissect_zbee_zdp_req_mgmt_nwk_disc      (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
85 extern void dissect_zbee_zdp_req_mgmt_lqi           (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
86 extern void dissect_zbee_zdp_req_mgmt_rtg           (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
87 extern void dissect_zbee_zdp_req_mgmt_bind          (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
88 extern void dissect_zbee_zdp_req_mgmt_leave         (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
89 extern void dissect_zbee_zdp_req_mgmt_direct_join   (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
90 extern void dissect_zbee_zdp_req_mgmt_permit_join   (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
91 extern void dissect_zbee_zdp_req_mgmt_cache         (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
92 extern void dissect_zbee_zdp_req_mgmt_nwkupdate     (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
93
94 extern void dissect_zbee_zdp_rsp_nwk_addr           (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
95 extern void dissect_zbee_zdp_rsp_ext_addr           (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
96 extern void dissect_zbee_zdp_rsp_node_desc          (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
97 extern void dissect_zbee_zdp_rsp_power_desc         (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
98 extern void dissect_zbee_zdp_rsp_simple_desc        (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
99 extern void dissect_zbee_zdp_rsp_active_ep          (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
100 extern void dissect_zbee_zdp_rsp_match_desc         (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
101 extern void dissect_zbee_zdp_rsp_complex_desc       (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
102 extern void dissect_zbee_zdp_rsp_user_desc          (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
103 extern void dissect_zbee_zdp_rsp_user_desc_conf     (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
104 extern void dissect_zbee_zdp_rsp_discovery_cache    (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
105 extern void dissect_zbee_zdp_rsp_system_server_disc (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
106 extern void dissect_zbee_zdp_rsp_discovery_store    (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
107 extern void dissect_zbee_zdp_rsp_store_node_desc    (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
108 extern void dissect_zbee_zdp_rsp_store_power_desc   (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
109 extern void dissect_zbee_zdp_rsp_store_active_ep    (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
110 extern void dissect_zbee_zdp_rsp_store_simple_desc  (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
111 extern void dissect_zbee_zdp_rsp_remove_node_cache  (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
112 extern void dissect_zbee_zdp_rsp_find_node_cache    (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
113 extern void dissect_zbee_zdp_rsp_ext_simple_desc    (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
114 extern void dissect_zbee_zdp_rsp_ext_active_ep      (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
115
116 extern void dissect_zbee_zdp_rsp_end_device_bind    (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
117 extern void dissect_zbee_zdp_rsp_bind               (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
118 extern void dissect_zbee_zdp_rsp_unbind             (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
119 extern void dissect_zbee_zdp_rsp_bind_register      (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
120 extern void dissect_zbee_zdp_rsp_replace_device     (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
121 extern void dissect_zbee_zdp_rsp_store_bak_bind_entry   (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
122 extern void dissect_zbee_zdp_rsp_remove_bak_bind_entry  (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
123 extern void dissect_zbee_zdp_rsp_backup_bind_table  (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
124 extern void dissect_zbee_zdp_rsp_recover_bind_table (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
125 extern void dissect_zbee_zdp_rsp_backup_source_bind (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
126 extern void dissect_zbee_zdp_rsp_recover_source_bind(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
127
128 extern void dissect_zbee_zdp_rsp_mgmt_nwk_disc      (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
129 extern void dissect_zbee_zdp_rsp_mgmt_lqi           (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
130 extern void dissect_zbee_zdp_rsp_mgmt_rtg           (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
131 extern void dissect_zbee_zdp_rsp_mgmt_bind          (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
132 extern void dissect_zbee_zdp_rsp_mgmt_leave         (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
133 extern void dissect_zbee_zdp_rsp_mgmt_direct_join   (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
134 extern void dissect_zbee_zdp_rsp_mgmt_permit_join   (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
135 extern void dissect_zbee_zdp_rsp_mgmt_cache         (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
136 extern void dissect_zbee_zdp_rsp_mgmt_nwkupdate     (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
137
138 /**************************************
139  * Field Indicies
140  **************************************
141  */
142 /* Global field indicies. */
143 int proto_zbee_zdp = -1;
144 int hf_zbee_zdp_seqno = -1;
145 int hf_zbee_zdp_length = -1; /* Deprecates since ZigBee 2006. */
146
147 /* General indicies. */
148 int hf_zbee_zdp_ext_addr = -1;
149 int hf_zbee_zdp_device = -1;
150 int hf_zbee_zdp_req_type = -1;
151 int hf_zbee_zdp_index = -1;
152 int hf_zbee_zdp_status = -1;
153 int hf_zbee_zdp_ep_count = -1;
154 int hf_zbee_zdp_endpoint = -1;
155 int hf_zbee_zdp_profile = -1;
156 int hf_zbee_zdp_cluster = -1;
157 int hf_zbee_zdp_addr_mode = -1;
158 int hf_zbee_zdp_table_size = -1;
159 int hf_zbee_zdp_table_count = -1;
160 int hf_zbee_zdp_in_count = -1;
161 int hf_zbee_zdp_out_count = -1;
162 int hf_zbee_zdp_in_cluster = -1;
163 int hf_zbee_zdp_out_cluster = -1;
164 int hf_zbee_zdp_assoc_device_count = -1;
165 int hf_zbee_zdp_assoc_device = -1;
166
167 /* Capability information indicies. */
168 int hf_zbee_zdp_cinfo_alloc = -1;
169 int hf_zbee_zdp_cinfo_security = -1;
170 int hf_zbee_zdp_cinfo_idle_rx = -1;
171 int hf_zbee_zdp_cinfo_power = -1;
172 int hf_zbee_zdp_cinfo_ffd = -1;
173 int hf_zbee_zdp_cinfo_alt_coord = -1;
174
175 /* Server mode flag indicies. */
176 int hf_zbee_zdp_server_pri_trust = -1;
177 int hf_zbee_zdp_server_bak_trust = -1;
178 int hf_zbee_zdp_server_pri_bind = -1;
179 int hf_zbee_zdp_server_bak_bind = -1;
180 int hf_zbee_zdp_server_pri_disc = -1;
181 int hf_zbee_zdp_server_bak_disc = -1;
182
183 /* Node descriptor indicies. */
184 int hf_zbee_zdp_node_type = -1;
185 int hf_zbee_zdp_node_complex = -1;
186 int hf_zbee_zdp_node_user = -1;
187 int hf_zbee_zdp_node_freq_868 = -1;
188 int hf_zbee_zdp_node_freq_900 = -1;
189 int hf_zbee_zdp_node_freq_2400 = -1;
190 int hf_zbee_zdp_node_manufacturer = -1;
191 int hf_zbee_zdp_node_max_buffer = -1;
192 int hf_zbee_zdp_node_max_transfer = -1;
193
194 /* Power descriptor indicies. */
195 int hf_zbee_zdp_power_mode = -1;
196 int hf_zbee_zdp_power_avail_ac = -1;
197 int hf_zbee_zdp_power_avail_recharge = -1;
198 int hf_zbee_zdp_power_avail_dispose = -1;
199 int hf_zbee_zdp_power_source_ac = -1;
200 int hf_zbee_zdp_power_source_recharge = -1;
201 int hf_zbee_zdp_power_source_dispose = -1;
202 int hf_zbee_zdp_power_level = -1;
203
204 /* Simple descriptor indicies. */
205 int hf_zbee_zdp_simple_app_device = -1;
206 int hf_zbee_zdp_simple_app_version = -1;
207 int hf_zbee_zdp_simple_length = -1;
208
209 /* Complex descriptor indicies. */
210 int hf_zbee_zdp_complex_length = -1;
211 int hf_zbee_zdp_complex_tag = -1;
212 int hf_zbee_zdp_complex = -1;
213
214 /* User descriptor indicies. */
215 int hf_zbee_zdp_user = -1;
216 int hf_zbee_zdp_user_length = -1;
217
218 /* Discovery indicies. */
219 int hf_zbee_zdp_cache = -1;
220 int hf_zbee_zdp_disc_node_size = -1;
221 int hf_zbee_zdp_disc_power_size = -1;
222 int hf_zbee_zdp_disc_ep_count = -1;
223 int hf_zbee_zdp_disc_simple_count = -1;
224 int hf_zbee_zdp_disc_simple_size = -1;
225
226 /* Binding indicies. */
227 int hf_zbee_zdp_target = -1;
228 int hf_zbee_zdp_target64 = -1;
229 int hf_zbee_zdp_target_ep = -1;
230 int hf_zbee_zdp_replacement = -1;
231 int hf_zbee_zdp_replacement_ep = -1;
232 int hf_zbee_zdp_bind_src = -1;
233 int hf_zbee_zdp_bind_src64 = -1;
234 int hf_zbee_zdp_bind_src_ep = -1;
235 int hf_zbee_zdp_bind_dst = -1;
236 int hf_zbee_zdp_bind_dst64 = -1;
237 int hf_zbee_zdp_bind_dst_ep = -1;
238
239 /* Network Management indicies. */
240 int hf_zbee_zdp_duration = -1;
241 int hf_zbee_zdp_leave_children = -1;
242 int hf_zbee_zdp_leave_rejoin = -1;
243 int hf_zbee_zdp_significance = -1;
244 int hf_zbee_zdp_scan_count = -1;
245 int hf_zbee_zdp_update_id = -1;
246 int hf_zbee_zdp_manager = -1;
247 int hf_zbee_zdp_tx_total = -1;
248 int hf_zbee_zdp_tx_fail = -1;
249 int hf_zbee_zdp_channel_count = -1;
250
251 /* Subtree indicies. */
252 gint ett_zbee_zdp = -1;
253 gint ett_zbee_zdp_endpoint = -1;
254 gint ett_zbee_zdp_match_in = -1;
255 gint ett_zbee_zdp_match_out = -1;
256 gint ett_zbee_zdp_node = -1;
257 gint ett_zbee_zdp_node_in = -1;
258 gint ett_zbee_zdp_node_out = -1;
259 gint ett_zbee_zdp_power = -1;
260 gint ett_zbee_zdp_simple = -1;
261 gint ett_zbee_zdp_complex = -1;
262 gint ett_zbee_zdp_cinfo = -1;
263 gint ett_zbee_zdp_server = -1;
264 gint ett_zbee_zdp_simple_sizes = -1;
265 gint ett_zbee_zdp_bind = -1;
266 gint ett_zbee_zdp_bind_end_in = -1;
267 gint ett_zbee_zdp_bind_end_out = -1;
268 gint ett_zbee_zdp_bind_table = -1;
269 gint ett_zbee_zdp_bind_source = -1;
270 gint ett_zbee_zdp_channels = -1;
271 gint ett_zbee_zdp_assoc_device = -1;
272 gint ett_zbee_zdp_nwk = -1;
273 gint ett_zbee_zdp_lqi = -1;
274 gint ett_zbee_zdp_rtg = -1;
275 gint ett_zbee_zdp_cache = -1;
276
277 /* Data dissector handle. */
278 dissector_handle_t  data_handle;
279
280 /**************************************
281  * Value Strings
282  **************************************
283  */
284 static const value_string zbee_zdp_req_types[] = {
285     { ZBEE_ZDP_REQ_TYPE_SINGLE,     "Single Device Response" },
286     { ZBEE_ZDP_REQ_TYPE_EXTENDED,   "Extended Response" },
287     { 0, NULL }
288 };
289
290 static const value_string zbee_zdp_cluster_names[] = {
291     { ZBEE_ZDP_REQ_NWK_ADDR,            "Network Address Request" },
292     { ZBEE_ZDP_REQ_IEEE_ADDR,           "Extended Address Request" },
293     { ZBEE_ZDP_REQ_NODE_DESC,           "Node Descriptor Request" },
294     { ZBEE_ZDP_REQ_POWER_DESC,          "Power Descriptor Request" },
295     { ZBEE_ZDP_REQ_SIMPLE_DESC,         "Simple Descriptor Request" },
296     { ZBEE_ZDP_REQ_ACTIVE_EP,           "Active Endpoint Request" },
297     { ZBEE_ZDP_REQ_MATCH_DESC,          "Match Descriptor Request" },
298     { ZBEE_ZDP_REQ_COMPLEX_DESC,        "Complex Descriptor Request" },
299     { ZBEE_ZDP_REQ_USER_DESC,           "User Descriptor Request" },
300     { ZBEE_ZDP_REQ_DISCOVERY_CACHE,     "Discovery Cache Request" },
301     { ZBEE_ZDP_REQ_DEVICE_ANNCE,        "Device Announcement" },
302     { ZBEE_ZDP_REQ_SET_USER_DESC,       "Set User Descriptor Request" },
303     { ZBEE_ZDP_REQ_SYSTEM_SERVER_DISC,  "Server Discovery Request" },
304     { ZBEE_ZDP_REQ_STORE_DISCOVERY,     "Store Discovery Request" },
305     { ZBEE_ZDP_REQ_STORE_NODE_DESC,     "Store Node Descriptor Request" },
306     { ZBEE_ZDP_REQ_STORE_POWER_DESC,    "Store Power Descriptor Request" },
307     { ZBEE_ZDP_REQ_STORE_ACTIVE_EP,     "Store Active Endpoints Request" },
308     { ZBEE_ZDP_REQ_STORE_SIMPLE_DESC,   "Store Simple Descriptor Request" },
309     { ZBEE_ZDP_REQ_REMOVE_NODE_CACHE,   "Remove Node Cache Request" },
310     { ZBEE_ZDP_REQ_FIND_NODE_CACHE,     "Find Node Cache Request" },
311     { ZBEE_ZDP_REQ_EXT_SIMPLE_DESC,     "Extended Simple Descriptor Request" },
312     { ZBEE_ZDP_REQ_EXT_ACTIVE_EP,       "Extended Active Endpoint Request" },
313     { ZBEE_ZDP_REQ_END_DEVICE_BIND,     "End Device Bind Request" },
314     { ZBEE_ZDP_REQ_BIND,                "Bind Request" },
315     { ZBEE_ZDP_REQ_UNBIND,              "Unbind Request" },
316     { ZBEE_ZDP_REQ_BIND_REGISTER,       "Bind Register Request" },
317     { ZBEE_ZDP_REQ_REPLACE_DEVICE,      "Replace Device Request" },
318     { ZBEE_ZDP_REQ_STORE_BAK_BIND_ENTRY,    "Store Backup Binding Request" },
319     { ZBEE_ZDP_REQ_REMOVE_BAK_BIND_ENTRY,   "Remove Backup Binding Request" },
320     { ZBEE_ZDP_REQ_BACKUP_BIND_TABLE,   "Backup Binding Table Request" },
321     { ZBEE_ZDP_REQ_RECOVER_BIND_TABLE,  "Recover Binding Table Request" },
322     { ZBEE_ZDP_REQ_BACKUP_SOURCE_BIND,  "Backup Source Binding Request" },
323     { ZBEE_ZDP_REQ_RECOVER_SOURCE_BIND, "Recover Source Binding Request" },
324     { ZBEE_ZDP_REQ_MGMT_NWK_DISC,       "Network Discovery Request" },
325     { ZBEE_ZDP_REQ_MGMT_LQI,            "Link Quality Request" },
326     { ZBEE_ZDP_REQ_MGMT_RTG,            "Routing Table Request" },
327     { ZBEE_ZDP_REQ_MGMT_BIND,           "Binding Table Request" },
328     { ZBEE_ZDP_REQ_MGMT_LEAVE,          "Leave Request" },
329     { ZBEE_ZDP_REQ_MGMT_DIRECT_JOIN,    "Direct Join Request" },
330     { ZBEE_ZDP_REQ_MGMT_PERMIT_JOIN,    "Permit Join Request" },
331     { ZBEE_ZDP_REQ_MGMT_CACHE,          "Cache Request" },
332     { ZBEE_ZDP_REQ_MGMT_NWKUPDATE,      "Network Update Request" },
333
334     { ZBEE_ZDP_RSP_NWK_ADDR,            "Network Address Response" },
335     { ZBEE_ZDP_RSP_IEEE_ADDR,           "Extended Address Response" },
336     { ZBEE_ZDP_RSP_NODE_DESC,           "Node Descriptor Response" },
337     { ZBEE_ZDP_RSP_POWER_DESC,          "Power Descriptor Response" },
338     { ZBEE_ZDP_RSP_SIMPLE_DESC,         "Simple Descriptor Response" },
339     { ZBEE_ZDP_RSP_ACTIVE_EP,           "Active Endpoint Response" },
340     { ZBEE_ZDP_RSP_MATCH_DESC,          "Match Descriptor Response" },
341     { ZBEE_ZDP_RSP_COMPLEX_DESC,        "Complex Descriptor Response" },
342     { ZBEE_ZDP_RSP_USER_DESC,           "User Descriptor Request" },
343     { ZBEE_ZDP_RSP_DISCOVERY_CACHE,     "Discovery Cache Response" },
344     { ZBEE_ZDP_RSP_CONF_USER_DESC,      "Set User Descriptor Confirm" },
345     { ZBEE_ZDP_RSP_SYSTEM_SERVER_DISC,  "Server Discovery Response" },
346     { ZBEE_ZDP_RSP_STORE_DISCOVERY,     "Store Discovery Response" },
347     { ZBEE_ZDP_RSP_STORE_NODE_DESC,     "Store Node Descriptor Response" },
348     { ZBEE_ZDP_RSP_STORE_POWER_DESC,    "Store Power Descriptor Response" },
349     { ZBEE_ZDP_RSP_STORE_ACTIVE_EP,     "Store Active Endpoints Response" },
350     { ZBEE_ZDP_RSP_STORE_SIMPLE_DESC,   "Store Simple Descriptor Response" },
351     { ZBEE_ZDP_RSP_REMOVE_NODE_CACHE,   "Remove Node Cache Response" },
352     { ZBEE_ZDP_RSP_FIND_NODE_CACHE,     "Find Node Cache Response" },
353     { ZBEE_ZDP_RSP_EXT_SIMPLE_DESC,     "Extended Simple Descriptor Response" },
354     { ZBEE_ZDP_RSP_EXT_ACTIVE_EP,       "Extended Active Endpoint Response" },
355     { ZBEE_ZDP_RSP_END_DEVICE_BIND,     "End Device Bind Response" },
356     { ZBEE_ZDP_RSP_BIND,                "Bind Response" },
357     { ZBEE_ZDP_RSP_UNBIND,              "Unbind Response" },
358     { ZBEE_ZDP_RSP_BIND_REGISTER,       "Bind Register Response" },
359     { ZBEE_ZDP_RSP_REPLACE_DEVICE,      "Replace Device Response" },
360     { ZBEE_ZDP_RSP_STORE_BAK_BIND_ENTRY,    "Store Backup Binding Response" },
361     { ZBEE_ZDP_RSP_REMOVE_BAK_BIND_ENTRY,   "Remove Backup Binding Response" },
362     { ZBEE_ZDP_RSP_BACKUP_BIND_TABLE,   "Backup Binding Table Response" },
363     { ZBEE_ZDP_RSP_RECOVER_BIND_TABLE,  "Recover Binding Table Response" },
364     { ZBEE_ZDP_RSP_BACKUP_SOURCE_BIND,  "Backup Source Binding Response" },
365     { ZBEE_ZDP_RSP_RECOVER_SOURCE_BIND, "Recover Source Binding Response" },
366     { ZBEE_ZDP_RSP_MGMT_NWK_DISC,       "Network Discovery Response" },
367     { ZBEE_ZDP_RSP_MGMT_LQI,            "Link Quality Response" },
368     { ZBEE_ZDP_RSP_MGMT_RTG,            "Routing Table Response" },
369     { ZBEE_ZDP_RSP_MGMT_BIND,           "Binding Table Response" },
370     { ZBEE_ZDP_RSP_MGMT_LEAVE,          "Leave Response" },
371     { ZBEE_ZDP_RSP_MGMT_DIRECT_JOIN,    "Direct Join Response" },
372     { ZBEE_ZDP_RSP_MGMT_PERMIT_JOIN,    "Permit Join Response" },
373     { ZBEE_ZDP_RSP_MGMT_CACHE,          "Cache Response" },
374     { ZBEE_ZDP_RSP_MGMT_NWKUPDATE,      "Network Update Notify" },
375     { 0, NULL }
376 };
377
378 static const value_string zbee_zdp_status_names[] = {
379     { ZBEE_ZDP_STATUS_SUCCESS,          "Success" },
380     { ZBEE_ZDP_STATUS_INV_REQUESTTYPE,  "Invalid Request Type" },
381     { ZBEE_ZDP_STATUS_DEVICE_NOT_FOUND, "Device Not Found" },
382     { ZBEE_ZDP_STATUS_INVALID_EP,       "Invalid Endpoint" },
383     { ZBEE_ZDP_STATUS_NOT_ACTIVE,       "Not Active" },
384     { ZBEE_ZDP_STATUS_NOT_SUPPORTED,    "Not Supported" },
385     { ZBEE_ZDP_STATUS_TIMEOUT,          "Timeout" },
386     { ZBEE_ZDP_STATUS_NO_MATCH,         "No Match" },
387     { ZBEE_ZDP_STATUS_NO_ENTRY,         "No Entry" },
388     { ZBEE_ZDP_STATUS_NO_DESCRIPTOR,    "No Descriptor" },
389     { ZBEE_ZDP_STATUS_INSUFFICIENT_SPACE,   "Insufficient Space" },
390     { ZBEE_ZDP_STATUS_NOT_PERMITTED,    "Not Permitted" },
391     { ZBEE_ZDP_STATUS_TABLE_FULL,       "Table Full" },
392     { 0, NULL }
393 };
394
395 /*FUNCTION:------------------------------------------------------
396  *  NAME
397  *      zdp_status_name
398  *  DESCRIPTION
399  *      Returns a status name for a given status value.
400  *  PARAMETERS
401  *      guint8  status;
402  *  RETURNS
403  *      const gchar *
404  *---------------------------------------------------------------
405  */
406 const gchar *
407 zdp_status_name(guint8 status)
408 {
409     return val_to_str(status, zbee_zdp_status_names, "Reserved");
410 } /* zdp_status_name */
411
412 /*FUNCTION:------------------------------------------------------
413  *  NAME
414  *      zdp_convert_2003cluster
415  *  DESCRIPTION
416  *      Converts a ZigBee 2003 & earlier cluster ID to a 2006
417  *      cluster ID. This change is necessary because the cluster
418  *      ID field was enlarged from 8 to 16 bits in 2006, and the
419  *      values for the response messages was changed.
420  *  PARAMETERS
421  *      guint8  cluster;
422  *  RETURNS
423  *      guint16
424  *---------------------------------------------------------------
425  */
426 static guint16
427 zdp_convert_2003cluster(guint8 cluster)
428 {
429     if (cluster & ZBEE_ZDP_MSG_RESPONSE_BIT_2003) {
430         /* Clear the 2003 request bit. */
431         cluster &= ~(ZBEE_ZDP_MSG_RESPONSE_BIT_2003);
432         /* Set the 2006 request bit. */
433         cluster |= (ZBEE_ZDP_MSG_RESPONSE_BIT);
434     }
435     return (guint16)cluster;
436 } /* zdp_convert_2003cluster */
437
438 /*FUNCTION:------------------------------------------------------
439  *  NAME
440  *      zdp_dump_excess
441  *  DESCRIPTION
442  *      Helper functions dumps any excess data into the data dissector.
443  *  PARAMETERS
444  *      tvbuff_t    *tvb    - pointer to buffer containing raw packet.
445  *      guint       offset  - offset after parsing last item.
446  *      packet_info *pinfo  - packet information structure.
447  *      proto_tree  *tree   - pointer to data tree Wireshark uses to display packet.
448  *  RETURNS
449  *      void
450  *---------------------------------------------------------------
451  */
452 void
453 zdp_dump_excess(tvbuff_t *tvb, guint offset, packet_info *pinfo, proto_tree *tree)
454 {
455     proto_tree  *root = proto_tree_get_root(tree);
456     guint       length = tvb_length_remaining(tvb, offset);
457     tvbuff_t    *excess;
458
459     if (length > 0) {
460         excess = tvb_new_subset(tvb, offset, length, length);
461         call_dissector(data_handle, excess, pinfo, root);
462     }
463 } /* zdp_dump_excess */
464
465 /*FUNCTION:------------------------------------------------------
466  *  NAME
467  *      zbee_append_info
468  *  DESCRIPTION
469  *      ZigBee helper function. Appends the info to the info column
470  *      and proto item.
471  *  PARAMETERS
472  *      proto_item  *item   - item to display info on.
473  *      packet_info *pinfo  - packet info struct.
474  *      const gchar *format - format string.
475  *      ...                 - variable argument list.
476  *  RETURNS
477  *      none
478  *---------------------------------------------------------------
479  */
480 void
481 zbee_append_info(proto_item *item, packet_info *pinfo, const gchar *format, ...)
482 {
483     static gchar    buffer[512];
484     va_list         ap;
485
486     va_start(ap, format);
487     g_vsnprintf(buffer, 512, format, ap);
488     va_end(ap);
489
490     if (item) {
491         proto_item_append_text(item, "%s", buffer);
492     }
493     if (check_col(pinfo->cinfo, COL_INFO)) {
494         col_append_str(pinfo->cinfo, COL_INFO, buffer);
495     }
496 } /* zbee_add_info */
497
498 /*FUNCTION:------------------------------------------------------
499  *  NAME
500  *      zbee_parse_uint
501  *  DESCRIPTION
502  *      ZigBee helper function. extracts an integer and displays it to the tree.
503  *  PARAMETERS
504  *      proto_tree  *tree   - pointer to data tree Wireshark uses to display packet.
505  *      int         hfindex - index to field information.
506  *      tvbuff_t    *tvb    - pointer to buffer containing raw packet.
507  *      guint       *offset - pointer to value of offset.
508  *      guint       length  - length of the value to extract.
509  *      proto_item  **ti    - optional pointer to get the created proto item.
510  *  RETURNS
511  *      guint   - the value read out of the tvbuff and added to the tree.
512  *---------------------------------------------------------------
513  */
514 guint
515 zbee_parse_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb, guint *offset, guint length, proto_item **ti)
516 {
517     proto_item          *item = NULL;
518     guint               value = 0;
519
520     /* Get the value. */
521     if (length == 0) {
522         /* ??? */
523         return 0;
524     }
525     else if (length == 1) {
526         value = tvb_get_guint8(tvb, *offset);
527     }
528     else if (length == 2) {
529         value = tvb_get_letohs(tvb, *offset);
530     }
531     else if (length == 3) {
532         value = tvb_get_letohs(tvb, *offset);
533         value += ((guint32)tvb_get_guint8(tvb, *offset + 2) << 16);
534     }
535     else {
536         value = tvb_get_letohl(tvb, *offset);
537     }
538
539     /* Display it. */
540     if (tree) {
541         item = proto_tree_add_uint(tree, hfindex, tvb, *offset, length, value);
542     }
543
544     /* Increment the offset. */
545     *offset += length;
546
547     /* return the item if requested. */
548     if (ti) *ti = item;
549
550     /* return the value. */
551     return value;
552 } /* zbee_parse_uint */
553
554 /*FUNCTION:------------------------------------------------------
555  *  NAME
556  *      zbee_parse_eui64
557  *  DESCRIPTION
558  *      ZigBee helper function. extracts an EUI64 address and displays
559  *      it to the tree.
560  *  PARAMETERS
561  *      proto_tree  *tree   - pointer to data tree Wireshark uses to display packet.
562  *      int         hfindex - index to field information.
563  *      tvbuff_t    *tvb    - pointer to buffer containing raw packet.
564  *      guint       *offset - pointer to value of offset.
565  *      guint       length  - length of the value to extract.
566  *      proto_item  **ti    - optional pointer to get the created proto item.
567  *  RETURNS
568  *      guint64   - the value read out of the tvbuff and added to the tree.
569  *---------------------------------------------------------------
570  */
571 guint64
572 zbee_parse_eui64(proto_tree *tree, int hfindex, tvbuff_t *tvb, guint *offset, guint length, proto_item **ti)
573 {
574     proto_item          *item = NULL;
575     guint64             value;
576
577     /* Get the value. */
578     value = tvb_get_letoh64(tvb, *offset);
579
580     /* Display it. */
581     if (tree) {
582         item = proto_tree_add_eui64(tree, hfindex, tvb, *offset, length, value);
583     }
584
585     /* Increment the offset. */
586     *offset += sizeof(guint64);
587
588     /* return the item if requested. */
589     if (ti) *ti = item;
590
591     /* return the value. */
592     return value;
593 } /* zbee_parse_eui64 */
594
595 /*FUNCTION:------------------------------------------------------
596  *  NAME
597  *      zdp_parse_status
598  *  DESCRIPTION
599  *      Parses and displays the status value.
600  *  PARAMETERS
601  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
602  *      tvbuff_t   *tvb     - pointer to buffer containing raw packet.
603  *      guint      *offset  - offset into the tvb to find the status value.
604  *  RETURNS
605  *      guint8
606  *---------------------------------------------------------------
607  */
608 guint8
609 zdp_parse_status(proto_tree *tree, tvbuff_t *tvb, guint *offset)
610 {
611     guint8      status;
612
613     /* Get and display the flags. */
614     status = tvb_get_guint8(tvb, *offset);
615     if (tree) {
616         proto_tree_add_uint(tree, hf_zbee_zdp_status, tvb, *offset, sizeof(guint8), status);
617     }
618     *offset += sizeof(guint8);
619
620     return status;
621 } /* zdp_parse_status */
622
623 /*FUNCTION:------------------------------------------------------
624  *  NAME
625  *      zdp_parse_chanmask
626  *  DESCRIPTION
627  *      Parses and displays the a channel mask.
628  *  PARAMETERS
629  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
630  *      tvbuff_t   *tvb     - pointer to buffer containing raw packet.
631  *      guint      *offset  - offset into the tvb to find the status value.
632  *  RETURNS
633  *      guint32
634  *---------------------------------------------------------------
635  */
636 guint32
637 zdp_parse_chanmask(proto_tree *tree, tvbuff_t *tvb, guint *offset)
638 {
639     int         i;
640     guint32     mask;
641     proto_item  *ti;
642
643     /* Get and display the channel mask. */
644     mask = tvb_get_letohl(tvb, *offset);
645     if (tree) {
646         ti = proto_tree_add_text(tree, tvb, *offset, sizeof(guint32), "Channels: ");
647
648         /* Check if there are any channels to display. */
649         if (mask==0) {
650             proto_item_append_text(ti, "None");
651         }
652         /* Display the first channel #. */
653         for (i=0; i<(8*(int)sizeof(guint32)); i++) {
654             if ((1<<i) & mask) {
655                 proto_item_append_text(ti, "%d", i++);
656                 break;
657             }
658         } /* for */
659         /* Display the rest of the channels. */
660         for (;i<(8*(int)sizeof(guint32)); i++) {
661             if (!((1<<i) & mask)) {
662                 /* This channel isn't selected. */
663                 continue;
664             }
665             /* If the previous channel wasn't selected, then display the
666              * channel number.
667              */
668             if ( ! ((1<<(i-1)) & mask) ) {
669                 proto_item_append_text(ti, ", %d", i);
670             }
671             /*
672              * If the next channel is selected too, skip past it and display
673              * a range of values instead.
674              */
675             if ((2<<i) & mask) {
676                 while ((2<<i) & mask) i++;
677                 proto_item_append_text(ti, "-%d", i);
678             }
679         } /* for */
680     }
681     *offset += sizeof(guint32);
682
683     return mask;
684 } /* zdp_parse_chanmask */
685
686 /*FUNCTION:------------------------------------------------------
687  *  NAME
688  *      zdp_parse_cinfo
689  *  DESCRIPTION
690  *      Parses and displays MAC capability info flags.
691  *  PARAMETERS
692  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
693  *      gint       ettindex - subtree index to create the node descriptor in, or -1
694  *                              to create it without a subtree.
695  *      tvbuff_t   *tvb     - pointer to buffer containing raw packet.
696  *      guint      *offset  - offset into the tvb to find the node descriptor.
697  *  RETURNS
698  *      guint8
699  *---------------------------------------------------------------
700  */
701 guint8
702 zdp_parse_cinfo(proto_tree *tree, gint ettindex, tvbuff_t *tvb, guint *offset)
703 {
704     proto_item  *ti;
705     proto_tree  *field_tree;
706     guint8      flags;
707
708     /* Get and display the flags. */
709     flags = tvb_get_guint8(tvb, *offset);
710     if (tree) {
711         if (ettindex != -1) {
712             ti = proto_tree_add_text(tree, tvb, *offset, sizeof(guint8), "Capability Information");
713             field_tree = proto_item_add_subtree(ti, ettindex);
714         }
715         else field_tree = tree;
716
717         proto_tree_add_boolean(field_tree, hf_zbee_zdp_cinfo_alt_coord, tvb, *offset, sizeof(guint8), flags & ZBEE_CINFO_ALT_COORD);
718         proto_tree_add_boolean(field_tree, hf_zbee_zdp_cinfo_ffd, tvb, *offset, sizeof(guint8), flags & ZBEE_CINFO_FFD);
719         proto_tree_add_boolean(field_tree, hf_zbee_zdp_cinfo_power, tvb, *offset, sizeof(guint8), flags & ZBEE_CINFO_POWER);
720         proto_tree_add_boolean(field_tree, hf_zbee_zdp_cinfo_idle_rx, tvb, *offset, sizeof(guint8), flags & ZBEE_CINFO_IDLE_RX);
721         proto_tree_add_boolean(field_tree, hf_zbee_zdp_cinfo_security, tvb, *offset, sizeof(guint8), flags & ZBEE_CINFO_SECURITY);
722         proto_tree_add_boolean(field_tree, hf_zbee_zdp_cinfo_alloc, tvb, *offset, sizeof(guint8), flags & ZBEE_CINFO_ALLOC);
723     }
724     *offset += sizeof(guint8);
725
726     return flags;
727 } /* zdp_parse_cinfo */
728
729 /*FUNCTION:------------------------------------------------------
730  *  NAME
731  *      zdp_parse_server_flags
732  *  DESCRIPTION
733  *      Parses and displays server mode flags.
734  *  PARAMETERS
735  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
736  *      gint       ettindex - subtree index to create the node descriptor in, or -1
737  *                              to create it without a subtree.
738  *      tvbuff_t   *tvb     - pointer to buffer containing raw packet.
739  *      guint      *offset  - offset into the tvb to find the node descriptor.
740  *  RETURNS
741  *      guint16
742  *---------------------------------------------------------------
743  */
744 guint16
745 zdp_parse_server_flags(proto_tree *tree, gint ettindex, tvbuff_t *tvb, guint *offset)
746 {
747     proto_item  *ti;
748     proto_tree  *field_tree;
749     guint16      flags;
750
751     /* Get and display the flags. */
752     flags = tvb_get_letohs(tvb, *offset);
753     if (tree) {
754         if (ettindex != -1) {
755             ti = proto_tree_add_text(tree, tvb, *offset, sizeof(guint8), "Server Flags");
756             field_tree = proto_item_add_subtree(ti, ettindex);
757         }
758         else field_tree = tree;
759
760         proto_tree_add_boolean(field_tree, hf_zbee_zdp_server_pri_trust, tvb, *offset, sizeof(guint16), flags & ZBEE_ZDP_NODE_SERVER_PRIMARY_TRUST);
761         proto_tree_add_boolean(field_tree, hf_zbee_zdp_server_bak_trust, tvb, *offset, sizeof(guint16), flags & ZBEE_ZDP_NODE_SERVER_BACKUP_TRUST);
762         proto_tree_add_boolean(field_tree, hf_zbee_zdp_server_pri_bind, tvb, *offset, sizeof(guint16), flags & ZBEE_ZDP_NODE_SERVER_PRIMARY_BIND);
763         proto_tree_add_boolean(field_tree, hf_zbee_zdp_server_bak_bind, tvb, *offset, sizeof(guint16), flags & ZBEE_ZDP_NODE_SERVER_BACKUP_BIND);
764         proto_tree_add_boolean(field_tree, hf_zbee_zdp_server_pri_disc, tvb, *offset, sizeof(guint16), flags & ZBEE_ZDP_NODE_SERVER_PRIMARY_DISC);
765         proto_tree_add_boolean(field_tree, hf_zbee_zdp_server_bak_disc, tvb, *offset, sizeof(guint16), flags & ZBEE_ZDP_NODE_SERVER_BACKUP_DISC);
766     }
767     *offset += sizeof(guint16);
768
769     return flags;
770 } /* zdp_parse_server_flags */
771
772 /*FUNCTION:------------------------------------------------------
773  *  NAME
774  *      zdp_parse_node_desc
775  *  DESCRIPTION
776  *      Parses and displays a node descriptor to the the specified
777  *      tree.
778  *  PARAMETERS
779  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
780  *      gint       ettindex - subtree index to create the node descriptor in, or -1
781  *                              to create it without a subtree.
782  *      tvbuff_t   *tvb     - pointer to buffer containing raw packet.
783  *      guint      *offset  - offset into the tvb to find the node descriptor.
784  *      packet_info *pinfo  - packet information structure.
785  *  RETURNS
786  *      void
787  *---------------------------------------------------------------
788  */
789 void
790 zdp_parse_node_desc(proto_tree *tree, gint ettindex, tvbuff_t *tvb, guint *offset, packet_info *pinfo)
791 {
792     proto_item  *ti;
793     proto_item  *field_root = NULL;
794     proto_tree  *field_tree = NULL;
795
796     guint16     flags;
797     guint8      capability;
798     guint16     mfr_code;
799     guint8      max_buff;
800     guint16     max_transfer;
801
802     if ((tree) && (ettindex != -1)) {
803         field_root = proto_tree_add_text(tree, tvb, *offset, tvb_length_remaining(tvb, *offset), "Node Descriptor");
804         field_tree = proto_item_add_subtree(field_root, ettindex);
805     }
806     else field_tree = tree;
807
808     /* Get and display the flags. */
809     flags = tvb_get_letohs(tvb, *offset);
810     if (tree) {
811         guint16 type = flags & ZBEE_ZDP_NODE_TYPE;
812         ti = proto_tree_add_uint(field_tree, hf_zbee_zdp_node_type, tvb, *offset, sizeof(guint16), type);
813         proto_tree_add_boolean(field_tree, hf_zbee_zdp_node_complex, tvb, *offset, sizeof(guint16), flags & ZBEE_ZDP_NODE_COMPLEX);
814         proto_tree_add_boolean(field_tree, hf_zbee_zdp_node_user, tvb, *offset, sizeof(guint16), flags & ZBEE_ZDP_NODE_USER);
815         proto_tree_add_boolean(field_tree, hf_zbee_zdp_node_freq_868, tvb, *offset, sizeof(guint16), flags & ZBEE_ZDP_NODE_FREQ_868MHZ);
816         proto_tree_add_boolean(field_tree, hf_zbee_zdp_node_freq_900, tvb, *offset, sizeof(guint16), flags & ZBEE_ZDP_NODE_FREQ_900MHZ);
817         proto_tree_add_boolean(field_tree, hf_zbee_zdp_node_freq_2400, tvb, *offset, sizeof(guint16), flags & ZBEE_ZDP_NODE_FREQ_2400MHZ);
818
819         /* Enumerate the type field. */
820         if (type == ZBEE_ZDP_NODE_TYPE_COORD)    proto_item_append_text(ti, " (Coordinator)");
821         else if (type == ZBEE_ZDP_NODE_TYPE_FFD) proto_item_append_text(ti, " (Router)");
822         else if (type == ZBEE_ZDP_NODE_TYPE_RFD) proto_item_append_text(ti, " (End Device)");
823         else proto_item_append_text(ti, " (Reserved)");
824     }
825     *offset += sizeof(guint16);
826
827     /* Get and display the capability flags. */
828     capability      = zdp_parse_cinfo(field_tree, ett_zbee_zdp_cinfo, tvb, offset);
829     mfr_code        = zbee_parse_uint(field_tree, hf_zbee_zdp_node_manufacturer, tvb, offset, sizeof(guint16), NULL);
830     max_buff        = zbee_parse_uint(field_tree, hf_zbee_zdp_node_max_buffer, tvb, offset, sizeof(guint8), NULL);
831     max_transfer    = zbee_parse_uint(field_tree, hf_zbee_zdp_node_max_transfer, tvb, offset, sizeof(guint16), NULL);
832
833     /* Get and display the server flags. */
834     if (pinfo->zbee_stack_vers >= ZBEE_VERSION_2007) {
835         zdp_parse_server_flags(field_tree, ett_zbee_zdp_server, tvb, offset);
836     }
837
838     /* Correct the length of the subtree. */
839     if (tree && (ettindex != -1)) {
840         proto_item_set_len(field_root, *offset);
841     }
842
843 } /* zdp_parse_node_desc */
844
845 /*FUNCTION:------------------------------------------------------
846  *  NAME
847  *      zdp_parse_power_desc
848  *  DESCRIPTION
849  *      Parses and displays a node descriptor to the the specified
850  *      tree.
851  *  PARAMETERS
852  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
853  *      gint       ettindex - subtree index to create the node descriptor in, or -1
854  *                              to create it without a subtree.
855  *      tvbuff_t   *tvb     - pointer to buffer containing raw packet.
856  *      guint      *offset  - offset into the tvb to find the node descriptor.
857  *      packet_info *pinfo  - packet information structure.
858  *  RETURNS
859  *      void
860  *---------------------------------------------------------------
861  */
862 void
863 zdp_parse_power_desc(proto_tree *tree, gint ettindex, tvbuff_t *tvb, guint *offset)
864 {
865     proto_item  *ti;
866     proto_tree  *field_tree;
867
868     guint16     flags;
869     guint16     mode;
870     guint16     level;
871
872     if ((tree) && (ettindex != -1)) {
873         ti = proto_tree_add_text(tree, tvb, *offset, sizeof(guint16), "Power Descriptor");
874         field_tree = proto_item_add_subtree(ti, ettindex);
875     }
876     else field_tree = tree;
877
878     flags = tvb_get_letohs(tvb, *offset);
879     mode  = flags & ZBEE_ZDP_POWER_MODE;
880     level = flags & ZBEE_ZDP_POWER_LEVEL;
881     if (tree) {
882         ti = proto_tree_add_uint(field_tree, hf_zbee_zdp_power_mode, tvb, *offset, sizeof(guint16), mode);
883         if (mode == ZBEE_ZDP_POWER_MODE_RX_ON)              proto_item_append_text(ti, " (Receiver Always On)");
884         else if (mode == ZBEE_ZDP_POWER_MODE_RX_PERIODIC)   proto_item_append_text(ti, " (Receiver Periodically On)");
885         else if (mode == ZBEE_ZDP_POWER_MODE_RX_STIMULATE)  proto_item_append_text(ti, " (Receiver On When Stimulated)");
886         else proto_item_append_text(ti, " (Reserved)");
887
888         proto_tree_add_boolean(field_tree, hf_zbee_zdp_power_avail_ac, tvb, *offset, sizeof(guint16), flags & ZBEE_ZDP_POWER_AVAIL_AC);
889         proto_tree_add_boolean(field_tree, hf_zbee_zdp_power_avail_recharge, tvb, *offset, sizeof(guint16), flags & ZBEE_ZDP_POWER_AVAIL_RECHARGEABLE);
890         proto_tree_add_boolean(field_tree, hf_zbee_zdp_power_avail_dispose, tvb, *offset, sizeof(guint16), flags & ZBEE_ZDP_POWER_AVAIL_DISPOSEABLE);
891
892         proto_tree_add_boolean(field_tree, hf_zbee_zdp_power_source_ac, tvb, *offset, sizeof(guint16), flags & ZBEE_ZDP_POWER_SOURCE_AC);
893         proto_tree_add_boolean(field_tree, hf_zbee_zdp_power_source_recharge, tvb, *offset, sizeof(guint16), flags & ZBEE_ZDP_POWER_SOURCE_RECHARGEABLE);
894         proto_tree_add_boolean(field_tree, hf_zbee_zdp_power_source_dispose, tvb, *offset, sizeof(guint16), flags & ZBEE_ZDP_POWER_SOURCE_DISPOSEABLE);
895
896         if (level == ZBEE_ZDP_POWER_LEVEL_FULL)
897             proto_tree_add_uint_format_value(field_tree, hf_zbee_zdp_power_level, tvb, *offset, sizeof(guint16), level, "Full");
898         else if (level == ZBEE_ZDP_POWER_LEVEL_OK)
899             proto_tree_add_uint_format_value(field_tree, hf_zbee_zdp_power_level, tvb, *offset, sizeof(guint16), level, "OK");
900         else if (level == ZBEE_ZDP_POWER_LEVEL_LOW)
901             proto_tree_add_uint_format_value(field_tree, hf_zbee_zdp_power_level, tvb, *offset, sizeof(guint16), level, "Low");
902         else if (level == ZBEE_ZDP_POWER_LEVEL_CRITICAL)
903             proto_tree_add_uint_format_value(field_tree, hf_zbee_zdp_power_level, tvb, *offset, sizeof(guint16), level, "Critical");
904         else proto_tree_add_uint_format_value(field_tree, hf_zbee_zdp_power_level, tvb, *offset, sizeof(guint16), level, "Reserved");
905     }
906     *offset += sizeof(guint16);
907 } /* zdp_parse_power_desc */
908
909 /*FUNCTION:------------------------------------------------------
910  *  NAME
911  *      zdp_parse_simple_desc
912  *  DESCRIPTION
913  *      Parses and displays a simple descriptor to the the specified
914  *      tree.
915  *  PARAMETERS
916  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
917  *      gint       ettindex - subtree index to create the node descriptor in, or -1
918  *                              to create it without a subtree.
919  *      tvbuff_t   *tvb     - pointer to buffer containing raw packet.
920  *      guint      *offset  - offset into the tvb to find the node descriptor.
921  *      packet_info *pinfo  - packet information structure.
922  *  RETURNS
923  *      void
924  *---------------------------------------------------------------
925  */
926 void
927 zdp_parse_simple_desc(proto_tree *tree, gint ettindex, tvbuff_t *tvb, guint *offset, packet_info *pinfo)
928 {
929     proto_item  *ti;
930     proto_item  *field_root = NULL;
931     proto_tree  *field_tree = NULL, *cluster_tree = NULL;
932     guint       i, sizeof_cluster;
933
934     guint8      endpoint;
935     guint16     profile;
936     guint16     app_device;
937     guint8      app_version;
938     guint8      in_count;
939     guint8      out_count;
940
941     if ((tree) && (ettindex != -1)) {
942         field_root = proto_tree_add_text(tree, tvb, *offset, tvb_length_remaining(tvb, *offset), "Simple Descriptor");
943         field_tree = proto_item_add_subtree(field_root, ettindex);
944     }
945     else field_tree = tree;
946
947     endpoint    = zbee_parse_uint(field_tree, hf_zbee_zdp_endpoint, tvb, offset, sizeof(guint8), NULL);
948     profile     = zbee_parse_uint(field_tree, hf_zbee_zdp_profile, tvb, offset, sizeof(guint16), NULL);
949     app_device  = zbee_parse_uint(field_tree, hf_zbee_zdp_simple_app_device, tvb, offset, sizeof(guint16), NULL);
950     app_version = zbee_parse_uint(field_tree, hf_zbee_zdp_simple_app_version, tvb, offset, sizeof(guint8), NULL);
951
952     sizeof_cluster = (pinfo->zbee_stack_vers >= ZBEE_VERSION_2007)?sizeof(guint16):sizeof(guint8);
953
954     in_count    = zbee_parse_uint(field_tree, hf_zbee_zdp_in_count, tvb, offset, sizeof(guint8), NULL);
955     if ((tree) && (in_count)) {
956         ti = proto_tree_add_text(field_tree, tvb, *offset, in_count*sizeof_cluster, "Input Cluster List");
957         cluster_tree = proto_item_add_subtree(ti, ett_zbee_zdp_node_in);
958     }
959     for (i=0; i<in_count && tvb_bytes_exist(tvb, *offset, sizeof_cluster); i++) {
960         zbee_parse_uint(cluster_tree, hf_zbee_zdp_in_cluster, tvb, offset, sizeof_cluster, NULL);
961     }
962
963     out_count = zbee_parse_uint(field_tree, hf_zbee_zdp_out_count, tvb, offset, sizeof(guint8), NULL);
964     if ((tree) && (out_count)) {
965         ti = proto_tree_add_text(field_tree, tvb, *offset, in_count*sizeof_cluster, "Output Cluster List");
966         cluster_tree = proto_item_add_subtree(ti, ett_zbee_zdp_node_out);
967     }
968     for (i=0; (i<out_count) && tvb_bytes_exist(tvb, *offset, sizeof_cluster); i++) {
969         zbee_parse_uint(cluster_tree, hf_zbee_zdp_out_cluster, tvb, offset, sizeof_cluster, NULL);
970     }
971
972     if (tree && (ettindex != -1)) {
973         proto_item_set_len(field_root, *offset);
974     }
975 } /* zdp_parse_simple_desc */
976
977 /*FUNCTION:------------------------------------------------------
978  *  NAME
979  *      zdp_parse_complex_desc
980  *  DESCRIPTION
981  *      Parses and displays a simple descriptor to the the specified
982  *      tree.
983  *  PARAMETERS
984  *      proto_tree  *tree    - pointer to data tree Wireshark uses to display packet.
985  *      gint        ettindex - subtree index to create the node descriptor in, or -1
986  *                              to create it without a subtree.
987  *      tvbuff_t    *tvb     - pointer to buffer containing raw packet.
988  *      guint       *offset  - offset into the tvb to find the node descriptor.
989  *      guint       length   - length of the complex descriptor.
990  *      packet_info *pinfo   - packet information structure.
991  *  RETURNS
992  *      void
993  *---------------------------------------------------------------
994  */
995 void
996 zdp_parse_complex_desc(proto_tree *tree, gint ettindex, tvbuff_t *tvb, guint *offset, guint length)
997 {
998     enum {
999         tag_charset = 1,
1000         tag_mfr_name = 2,
1001         tag_model_name = 3,
1002         tag_serial_no = 4,
1003         tag_url = 5,
1004         tag_icon = 6,
1005         tag_icon_url = 7
1006     };
1007
1008     const gchar *tag_name[] = {
1009         "Reserved Tag",
1010         "languageChar",
1011         "manufacturerName",
1012         "modelName",
1013         "serialNumber",
1014         "deviceURL",
1015         "icon",
1016         "outliner"
1017     };
1018
1019     const gint max_len = 128;
1020
1021     proto_item  *field_root;
1022     proto_tree  *field_tree;
1023
1024     gchar   *str = ep_alloc(length);
1025     gchar   *complex = ep_alloc(max_len);
1026     guint8  tag;
1027
1028     if ((tree) && (ettindex != -1)) {
1029         field_root = proto_tree_add_text(tree, tvb, *offset, length, "Complex Descriptor");
1030         field_tree = proto_item_add_subtree(field_root, ettindex);
1031     }
1032     else field_tree = tree;
1033
1034     tag = tvb_get_guint8(tvb, *offset);
1035     if (tag == tag_charset) {
1036         gchar   lang_str[3];
1037         guint8  charset  = tvb_get_guint8(tvb, *offset + 3);
1038         gchar   *charset_str;
1039
1040         if (charset == 0x00) charset_str = "ASCII";
1041         else                 charset_str = "Unknown Character Set";
1042
1043         lang_str[0] = tvb_get_guint8(tvb, *offset + 1);
1044         lang_str[1] = tvb_get_guint8(tvb, *offset + 2);
1045         lang_str[2] = '\0';
1046
1047         g_snprintf(complex, max_len, "<%s>%s, %s</%s>", tag_name[tag_charset], lang_str, charset_str, tag_name[tag_charset]);
1048     }
1049     else if (tag == tag_icon) {
1050         /* TODO: */
1051         g_snprintf(complex, max_len, "<%s>FixMe</%s>", tag_name[tag_icon], tag_name[tag_icon]);
1052     }
1053     else {
1054         tvb_memcpy(tvb, str, *offset+1, length-1);
1055         str[length-1] = '\0';
1056         /* Handles all string type XML tags. */
1057         if (tag <= tag_icon_url) {
1058             g_snprintf(complex, max_len, "<%s>%s</%s>", tag_name[tag], str, tag_name[tag]);
1059         }
1060         else {
1061             g_snprintf(complex, max_len, "<%s>%s</%s>", tag_name[0], str, tag_name[0]);
1062         }
1063     }
1064     if (tree) {
1065         proto_tree_add_string(field_tree, hf_zbee_zdp_complex, tvb, *offset, length, complex);
1066     }
1067     *offset += (length);
1068 } /* zdp_parse_complex_desc */
1069
1070 /*FUNCTION:------------------------------------------------------
1071  *  NAME
1072  *      dissect_zbee_zdp
1073  *  DESCRIPTION
1074  *      ZigBee Device Profile dissector for wireshark.
1075  *  PARAMETERS
1076  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
1077  *      packet_into *pinfo  - pointer to packet information fields
1078  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
1079  *  RETURNS
1080  *      void
1081  *---------------------------------------------------------------
1082  */
1083 static void
1084 dissect_zbee_zdp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1085 {
1086     proto_tree      *zdp_tree = NULL;
1087     proto_item      *proto_root;
1088     tvbuff_t        *zdp_tvb;
1089
1090     guint8          seqno;
1091     guint16         cluster;
1092     guint           offset = 0;
1093
1094     /* Create the protocol tree. */
1095     if (tree) {
1096         proto_root = proto_tree_add_protocol_format(tree, proto_zbee_zdp, tvb, offset, tvb_length(tvb), "ZigBee Device Profile");
1097         zdp_tree = proto_item_add_subtree(proto_root, ett_zbee_zdp);
1098     }
1099 #if 0   
1100     /* Overwrite the protocol column */
1101     col_set_str(pinfo->cinfo, COL_PROTOCOL, "ZigBee ZDP");
1102 #endif
1103     /* Get and display the sequence number. */
1104     seqno = tvb_get_guint8(tvb, offset);
1105     if (tree) {
1106         proto_tree_add_uint(zdp_tree, hf_zbee_zdp_seqno, tvb, offset, sizeof(guint8), seqno);
1107     }
1108     offset += sizeof(guint8);
1109
1110     if (pinfo->zbee_stack_vers <= ZBEE_VERSION_2004) {
1111         /* ZigBee 2004 and earlier had different cluster identifiers, need to convert
1112          * them into the ZigBee 2006 & later values. */
1113         cluster = zdp_convert_2003cluster((guint8)pinfo->zbee_cluster_id);
1114     }
1115     else {
1116         cluster = pinfo->zbee_cluster_id;
1117     }
1118
1119     /* Update info. */
1120     if (tree) {
1121         proto_item_append_text(zdp_tree, ", %s", val_to_str(cluster, zbee_zdp_cluster_names, "Unknown Cluster"));
1122     }
1123     if (check_col(pinfo->cinfo, COL_INFO)) {
1124         col_set_str(pinfo->cinfo, COL_INFO, val_to_str_const(cluster, zbee_zdp_cluster_names, "Unknown Cluster"));
1125     }
1126
1127     /* Create a new tvb for the zdp message. */
1128     zdp_tvb = tvb_new_subset_remaining(tvb, offset);
1129
1130     switch (cluster) {
1131         case ZBEE_ZDP_REQ_NWK_ADDR:
1132             dissect_zbee_zdp_req_nwk_addr(zdp_tvb, pinfo, zdp_tree);
1133             break;
1134         case ZBEE_ZDP_REQ_IEEE_ADDR:
1135             dissect_zbee_zdp_req_ext_addr(zdp_tvb, pinfo, zdp_tree);
1136             break;
1137         case ZBEE_ZDP_REQ_NODE_DESC:
1138             dissect_zbee_zdp_req_node_desc(zdp_tvb, pinfo, zdp_tree);
1139             break;
1140         case ZBEE_ZDP_REQ_POWER_DESC:
1141             dissect_zbee_zdp_req_power_desc(zdp_tvb, pinfo, zdp_tree);
1142             break;
1143         case ZBEE_ZDP_REQ_SIMPLE_DESC:
1144             dissect_zbee_zdp_req_simple_desc(zdp_tvb, pinfo, zdp_tree);
1145             break;
1146         case ZBEE_ZDP_REQ_ACTIVE_EP:
1147             dissect_zbee_zdp_req_active_ep(zdp_tvb, pinfo, zdp_tree);
1148             break;
1149         case ZBEE_ZDP_REQ_MATCH_DESC:
1150             dissect_zbee_zdp_req_match_desc(zdp_tvb, pinfo, zdp_tree);
1151             break;
1152         case ZBEE_ZDP_REQ_COMPLEX_DESC:
1153             dissect_zbee_zdp_req_complex_desc(zdp_tvb, pinfo, zdp_tree);
1154             break;
1155         case ZBEE_ZDP_REQ_USER_DESC:
1156             dissect_zbee_zdp_req_user_desc(zdp_tvb, pinfo, zdp_tree);
1157             break;
1158         case ZBEE_ZDP_REQ_DISCOVERY_CACHE:
1159             dissect_zbee_zdp_req_discovery_cache(zdp_tvb, pinfo, zdp_tree);
1160             break;
1161         case ZBEE_ZDP_REQ_DEVICE_ANNCE:
1162             dissect_zbee_zdp_device_annce(zdp_tvb, pinfo, zdp_tree);
1163             break;
1164         case ZBEE_ZDP_REQ_SET_USER_DESC:
1165             dissect_zbee_zdp_req_set_user_desc(zdp_tvb, pinfo, zdp_tree);
1166             break;
1167         case ZBEE_ZDP_REQ_SYSTEM_SERVER_DISC:
1168             dissect_zbee_zdp_req_system_server_disc(zdp_tvb, pinfo, zdp_tree);
1169             break;
1170         case ZBEE_ZDP_REQ_STORE_DISCOVERY:
1171             dissect_zbee_zdp_req_store_discovery(zdp_tvb, pinfo, zdp_tree);
1172             break;
1173         case ZBEE_ZDP_REQ_STORE_NODE_DESC:
1174             dissect_zbee_zdp_req_store_node_desc(zdp_tvb, pinfo, zdp_tree);
1175             break;
1176         case ZBEE_ZDP_REQ_STORE_POWER_DESC:
1177             dissect_zbee_zdp_req_store_power_desc(zdp_tvb, pinfo, zdp_tree);
1178             break;
1179         case ZBEE_ZDP_REQ_STORE_ACTIVE_EP:
1180             dissect_zbee_zdp_req_store_active_ep(zdp_tvb, pinfo, zdp_tree);
1181             break;
1182         case ZBEE_ZDP_REQ_STORE_SIMPLE_DESC:
1183             dissect_zbee_zdp_req_store_simple_desc(zdp_tvb, pinfo, zdp_tree);
1184             break;
1185         case ZBEE_ZDP_REQ_REMOVE_NODE_CACHE:
1186             dissect_zbee_zdp_req_remove_node_cache(zdp_tvb, pinfo, zdp_tree);
1187             break;
1188         case ZBEE_ZDP_REQ_FIND_NODE_CACHE:
1189             dissect_zbee_zdp_req_find_node_cache(zdp_tvb, pinfo, zdp_tree);
1190             break;
1191         case ZBEE_ZDP_REQ_EXT_SIMPLE_DESC:
1192             dissect_zbee_zdp_req_ext_simple_desc(zdp_tvb, pinfo, zdp_tree);
1193             break;
1194         case ZBEE_ZDP_REQ_EXT_ACTIVE_EP:
1195             dissect_zbee_zdp_req_ext_active_ep(zdp_tvb, pinfo, zdp_tree);
1196             break;
1197         case ZBEE_ZDP_REQ_END_DEVICE_BIND:
1198             dissect_zbee_zdp_req_end_device_bind(zdp_tvb, pinfo, zdp_tree);
1199             break;
1200         case ZBEE_ZDP_REQ_BIND:
1201             dissect_zbee_zdp_req_bind(zdp_tvb, pinfo, zdp_tree);
1202             break;
1203         case ZBEE_ZDP_REQ_UNBIND:
1204             dissect_zbee_zdp_req_unbind(zdp_tvb, pinfo, zdp_tree);
1205             break;
1206         case ZBEE_ZDP_REQ_BIND_REGISTER:
1207             dissect_zbee_zdp_req_bind_register(zdp_tvb, pinfo, zdp_tree);
1208             break;
1209         case ZBEE_ZDP_REQ_REPLACE_DEVICE:
1210             dissect_zbee_zdp_req_replace_device(zdp_tvb, pinfo, zdp_tree);
1211             break;
1212         case ZBEE_ZDP_REQ_STORE_BAK_BIND_ENTRY:
1213             dissect_zbee_zdp_req_store_bak_bind_entry(zdp_tvb, pinfo, zdp_tree);
1214             break;
1215         case ZBEE_ZDP_REQ_REMOVE_BAK_BIND_ENTRY:
1216             dissect_zbee_zdp_req_remove_bak_bind_entry(zdp_tvb, pinfo, zdp_tree);
1217             break;
1218         case ZBEE_ZDP_REQ_BACKUP_BIND_TABLE:
1219             dissect_zbee_zdp_req_backup_bind_table(zdp_tvb, pinfo, zdp_tree);
1220             break;
1221         case ZBEE_ZDP_REQ_RECOVER_BIND_TABLE:
1222             dissect_zbee_zdp_req_recover_bind_table(zdp_tvb, pinfo, zdp_tree);
1223             break;
1224         case ZBEE_ZDP_REQ_BACKUP_SOURCE_BIND:
1225             dissect_zbee_zdp_req_backup_source_bind(zdp_tvb, pinfo, zdp_tree);
1226             break;
1227         case ZBEE_ZDP_REQ_RECOVER_SOURCE_BIND:
1228             dissect_zbee_zdp_req_recover_source_bind(zdp_tvb, pinfo, zdp_tree);
1229             break;
1230         case ZBEE_ZDP_REQ_MGMT_NWK_DISC:
1231             dissect_zbee_zdp_req_mgmt_nwk_disc(zdp_tvb, pinfo, zdp_tree);
1232             break;
1233         case ZBEE_ZDP_REQ_MGMT_LQI:
1234             dissect_zbee_zdp_req_mgmt_lqi(zdp_tvb, pinfo, zdp_tree);
1235             break;
1236         case ZBEE_ZDP_REQ_MGMT_RTG:
1237             dissect_zbee_zdp_req_mgmt_rtg(zdp_tvb, pinfo, zdp_tree);
1238             break;
1239         case ZBEE_ZDP_REQ_MGMT_BIND:
1240             dissect_zbee_zdp_req_mgmt_bind(zdp_tvb, pinfo, zdp_tree);
1241             break;
1242         case ZBEE_ZDP_REQ_MGMT_LEAVE:
1243             dissect_zbee_zdp_req_mgmt_leave(zdp_tvb, pinfo, zdp_tree);
1244             break;
1245         case ZBEE_ZDP_REQ_MGMT_DIRECT_JOIN:
1246             dissect_zbee_zdp_req_mgmt_direct_join(zdp_tvb, pinfo, zdp_tree);
1247             break;
1248         case ZBEE_ZDP_REQ_MGMT_PERMIT_JOIN:
1249             dissect_zbee_zdp_req_mgmt_permit_join(zdp_tvb, pinfo, zdp_tree);
1250             break;
1251         case ZBEE_ZDP_REQ_MGMT_CACHE:
1252             dissect_zbee_zdp_req_mgmt_cache(zdp_tvb, pinfo, zdp_tree);
1253             break;
1254         case ZBEE_ZDP_REQ_MGMT_NWKUPDATE:
1255             dissect_zbee_zdp_req_mgmt_nwkupdate(zdp_tvb, pinfo, zdp_tree);
1256             break;
1257         case ZBEE_ZDP_RSP_NWK_ADDR:
1258             dissect_zbee_zdp_rsp_nwk_addr(zdp_tvb, pinfo, zdp_tree);
1259             break;
1260         case ZBEE_ZDP_RSP_IEEE_ADDR:
1261             dissect_zbee_zdp_rsp_ext_addr(zdp_tvb, pinfo, zdp_tree);
1262             break;
1263         case ZBEE_ZDP_RSP_NODE_DESC:
1264             dissect_zbee_zdp_rsp_node_desc(zdp_tvb, pinfo, zdp_tree);
1265             break;
1266         case ZBEE_ZDP_RSP_POWER_DESC:
1267             dissect_zbee_zdp_rsp_power_desc(zdp_tvb, pinfo, zdp_tree);
1268             break;
1269         case ZBEE_ZDP_RSP_SIMPLE_DESC:
1270             dissect_zbee_zdp_rsp_simple_desc(zdp_tvb, pinfo, zdp_tree);
1271             break;
1272         case ZBEE_ZDP_RSP_ACTIVE_EP:
1273             dissect_zbee_zdp_rsp_active_ep(zdp_tvb, pinfo, zdp_tree);
1274             break;
1275         case ZBEE_ZDP_RSP_MATCH_DESC:
1276             dissect_zbee_zdp_rsp_match_desc(zdp_tvb, pinfo, zdp_tree);
1277             break;
1278         case ZBEE_ZDP_RSP_COMPLEX_DESC:
1279             dissect_zbee_zdp_rsp_complex_desc(zdp_tvb, pinfo, zdp_tree);
1280             break;
1281         case ZBEE_ZDP_RSP_USER_DESC:
1282             dissect_zbee_zdp_rsp_user_desc(zdp_tvb, pinfo, zdp_tree);
1283             break;
1284         case ZBEE_ZDP_RSP_DISCOVERY_CACHE:
1285             dissect_zbee_zdp_rsp_discovery_cache(zdp_tvb, pinfo, zdp_tree);
1286             break;
1287         case ZBEE_ZDP_RSP_CONF_USER_DESC:
1288             dissect_zbee_zdp_rsp_user_desc_conf(zdp_tvb, pinfo, zdp_tree);
1289             break;
1290         case ZBEE_ZDP_RSP_SYSTEM_SERVER_DISC:
1291             dissect_zbee_zdp_rsp_system_server_disc(zdp_tvb, pinfo, zdp_tree);
1292             break;
1293         case ZBEE_ZDP_RSP_STORE_DISCOVERY:
1294             dissect_zbee_zdp_rsp_discovery_store(zdp_tvb, pinfo, zdp_tree);
1295             break;
1296         case ZBEE_ZDP_RSP_STORE_NODE_DESC:
1297             dissect_zbee_zdp_rsp_store_node_desc(zdp_tvb, pinfo, zdp_tree);
1298             break;
1299         case ZBEE_ZDP_RSP_STORE_POWER_DESC:
1300             dissect_zbee_zdp_rsp_store_power_desc(zdp_tvb, pinfo, zdp_tree);
1301             break;
1302         case ZBEE_ZDP_RSP_STORE_ACTIVE_EP:
1303             dissect_zbee_zdp_rsp_store_active_ep(zdp_tvb, pinfo, zdp_tree);
1304             break;
1305         case ZBEE_ZDP_RSP_STORE_SIMPLE_DESC:
1306             dissect_zbee_zdp_rsp_store_simple_desc(zdp_tvb, pinfo, zdp_tree);
1307             break;
1308         case ZBEE_ZDP_RSP_REMOVE_NODE_CACHE:
1309             dissect_zbee_zdp_rsp_remove_node_cache(zdp_tvb, pinfo, zdp_tree);
1310             break;
1311         case ZBEE_ZDP_RSP_FIND_NODE_CACHE:
1312             dissect_zbee_zdp_rsp_find_node_cache(zdp_tvb, pinfo, zdp_tree);
1313             break;
1314         case ZBEE_ZDP_RSP_EXT_SIMPLE_DESC:
1315             dissect_zbee_zdp_rsp_ext_simple_desc(zdp_tvb, pinfo, zdp_tree);
1316             break;
1317         case ZBEE_ZDP_RSP_EXT_ACTIVE_EP:
1318             dissect_zbee_zdp_rsp_ext_active_ep(zdp_tvb, pinfo, zdp_tree);
1319             break;
1320         case ZBEE_ZDP_RSP_END_DEVICE_BIND:
1321             dissect_zbee_zdp_rsp_end_device_bind(zdp_tvb, pinfo, zdp_tree);
1322             break;
1323         case ZBEE_ZDP_RSP_BIND:
1324             dissect_zbee_zdp_rsp_bind(zdp_tvb, pinfo, zdp_tree);
1325             break;
1326         case ZBEE_ZDP_RSP_UNBIND:
1327             dissect_zbee_zdp_rsp_unbind(zdp_tvb, pinfo, zdp_tree);
1328             break;
1329         case ZBEE_ZDP_RSP_BIND_REGISTER:
1330             dissect_zbee_zdp_rsp_bind_register(zdp_tvb, pinfo, zdp_tree);
1331             break;
1332         case ZBEE_ZDP_RSP_REPLACE_DEVICE:
1333             dissect_zbee_zdp_rsp_replace_device(zdp_tvb, pinfo, zdp_tree);
1334             break;
1335         case ZBEE_ZDP_RSP_STORE_BAK_BIND_ENTRY:
1336             dissect_zbee_zdp_rsp_store_bak_bind_entry(zdp_tvb, pinfo, zdp_tree);
1337             break;
1338         case ZBEE_ZDP_RSP_REMOVE_BAK_BIND_ENTRY:
1339             dissect_zbee_zdp_rsp_remove_bak_bind_entry(zdp_tvb, pinfo, zdp_tree);
1340             break;
1341         case ZBEE_ZDP_RSP_BACKUP_BIND_TABLE:
1342             dissect_zbee_zdp_rsp_backup_bind_table(zdp_tvb, pinfo, zdp_tree);
1343             break;
1344         case ZBEE_ZDP_RSP_RECOVER_BIND_TABLE:
1345             dissect_zbee_zdp_rsp_recover_bind_table(zdp_tvb, pinfo, zdp_tree);
1346             break;
1347         case ZBEE_ZDP_RSP_BACKUP_SOURCE_BIND:
1348             dissect_zbee_zdp_rsp_backup_source_bind(zdp_tvb, pinfo, zdp_tree);
1349             break;
1350         case ZBEE_ZDP_RSP_RECOVER_SOURCE_BIND:
1351             dissect_zbee_zdp_rsp_recover_source_bind(zdp_tvb, pinfo, zdp_tree);
1352             break;
1353         case ZBEE_ZDP_RSP_MGMT_NWK_DISC:
1354             dissect_zbee_zdp_rsp_mgmt_nwk_disc(zdp_tvb, pinfo, zdp_tree);
1355             break;
1356         case ZBEE_ZDP_RSP_MGMT_LQI:
1357             dissect_zbee_zdp_rsp_mgmt_lqi(zdp_tvb, pinfo, zdp_tree);
1358             break;
1359         case ZBEE_ZDP_RSP_MGMT_RTG:
1360             dissect_zbee_zdp_rsp_mgmt_rtg(zdp_tvb, pinfo, zdp_tree);
1361             break;
1362         case ZBEE_ZDP_RSP_MGMT_BIND:
1363             dissect_zbee_zdp_rsp_mgmt_bind(zdp_tvb, pinfo, zdp_tree);
1364             break;
1365         case ZBEE_ZDP_RSP_MGMT_LEAVE:
1366             dissect_zbee_zdp_rsp_mgmt_leave(zdp_tvb, pinfo, zdp_tree);
1367             break;
1368         case ZBEE_ZDP_RSP_MGMT_DIRECT_JOIN:
1369             dissect_zbee_zdp_rsp_mgmt_direct_join(zdp_tvb, pinfo, zdp_tree);
1370             break;
1371         case ZBEE_ZDP_RSP_MGMT_PERMIT_JOIN:
1372             dissect_zbee_zdp_rsp_mgmt_permit_join(zdp_tvb, pinfo, zdp_tree);
1373             break;
1374         case ZBEE_ZDP_RSP_MGMT_CACHE:
1375             dissect_zbee_zdp_rsp_mgmt_cache(zdp_tvb, pinfo, zdp_tree);
1376             break;
1377         case ZBEE_ZDP_RSP_MGMT_NWKUPDATE:
1378             dissect_zbee_zdp_rsp_mgmt_nwkupdate(zdp_tvb, pinfo, zdp_tree);
1379             break;
1380         default:
1381             /* Invalid Cluster Identifier. */
1382             call_dissector(data_handle, zdp_tvb, pinfo, tree);
1383             break;
1384     } /* switch */
1385 } /* dissect_zbee_zdp */
1386
1387 /*FUNCTION:------------------------------------------------------
1388  *  NAME
1389  *      proto_register_zbee_zdp
1390  *  DESCRIPTION
1391  *      ZigBee Device Profile protocol registration routine.
1392  *  PARAMETERS
1393  *      none
1394  *  RETURNS
1395  *      void
1396  *---------------------------------------------------------------
1397  */
1398 void proto_register_zbee_zdp(void)
1399 {
1400     static hf_register_info hf[] = {
1401         { &hf_zbee_zdp_seqno,
1402         { "Sequence Number",            "zbee.zdp.seqno", FT_UINT8, BASE_DEC, NULL, 0x0,
1403             NULL, HFILL }},
1404
1405         { &hf_zbee_zdp_length,
1406         { "Length",                     "zbee.zdp.length", FT_UINT8, BASE_DEC, NULL, 0x0,
1407             NULL, HFILL }},
1408
1409         { &hf_zbee_zdp_ext_addr,
1410         { "Extended Address",           "zbee.zdp.ext_addr", FT_UINT64, BASE_HEX, NULL, 0x0,
1411             NULL, HFILL }},
1412
1413         { &hf_zbee_zdp_device,
1414         { "Device",                     "zbee.zdp.device", FT_UINT16, BASE_HEX, NULL, 0x0,
1415             NULL, HFILL }},
1416
1417         { &hf_zbee_zdp_req_type,
1418         { "Request Type",               "zbee.zdp.req_type", FT_UINT8, BASE_DEC, VALS(zbee_zdp_req_types), 0x0,
1419             NULL, HFILL }},
1420
1421         { &hf_zbee_zdp_index,
1422         { "Index",                      "zbee.zdp.index", FT_UINT8, BASE_DEC, NULL, 0x0,
1423             NULL, HFILL }},
1424
1425         { &hf_zbee_zdp_status,
1426         { "Status",                     "zbee.zdp.status", FT_UINT8, BASE_DEC, VALS(zbee_zdp_status_names), 0x0,
1427             NULL, HFILL }},
1428
1429         { &hf_zbee_zdp_endpoint,
1430         { "Endpoint",                   "zbee.zdp.endpoint", FT_UINT8, BASE_DEC, NULL, 0x0,
1431             NULL, HFILL }},
1432
1433         { &hf_zbee_zdp_ep_count,
1434         { "Endpoint Count",             "zbee.zdp.ep_count", FT_UINT8, BASE_DEC, NULL, 0x0,
1435             NULL, HFILL }},
1436
1437         { &hf_zbee_zdp_profile,
1438         { "Profile",                    "zbee.zdp.profile", FT_UINT16, BASE_HEX, NULL, 0x0,
1439             NULL, HFILL }},
1440
1441         { &hf_zbee_zdp_addr_mode,
1442         { "Address Mode",               "zbee.zdp.addr_mode", FT_UINT8, BASE_DEC, NULL, 0x0,
1443             NULL, HFILL }},
1444
1445         { &hf_zbee_zdp_cluster,
1446         { "Cluster",                    "zbee.zdp.cluster", FT_UINT16, BASE_DEC, NULL, 0x0,
1447             NULL, HFILL }},
1448
1449         { &hf_zbee_zdp_table_size,
1450         { "Table Size",                 "zbee.zdp.table_size", FT_UINT16, BASE_DEC, NULL, 0x0,
1451             "Number of entries in the table.", HFILL }},
1452
1453         { &hf_zbee_zdp_table_count,
1454         { "Table Count",                "zbee.zdp.table_count", FT_UINT16, BASE_DEC, NULL, 0x0,
1455             "Number of table entries included in this message.", HFILL }},
1456
1457         { &hf_zbee_zdp_in_count,
1458         { "Input Cluster Count",        "zbee.zdp.in_count", FT_UINT8, BASE_DEC, NULL, 0x0,
1459             NULL, HFILL }},
1460
1461         { &hf_zbee_zdp_out_count,
1462         { "Output Cluster Count",       "zbee.zdp.out_count", FT_UINT8, BASE_DEC, NULL, 0x0,
1463             NULL, HFILL }},
1464
1465         { &hf_zbee_zdp_in_cluster,
1466         { "Input Cluster",              "zbee.zdp.in_cluster", FT_UINT16, BASE_DEC, NULL, 0x0,
1467             NULL, HFILL }},
1468
1469         { &hf_zbee_zdp_out_cluster,
1470         { "Output Cluster",             "zbee.zdp.out_cluster", FT_UINT16, BASE_DEC, NULL, 0x0,
1471             NULL, HFILL }},
1472
1473         { &hf_zbee_zdp_assoc_device_count,
1474         { "Associated Device Count",    "zbee.zdp.assoc_device_count", FT_UINT8, BASE_DEC, NULL, 0x0,
1475             NULL, HFILL }},
1476
1477         { &hf_zbee_zdp_assoc_device,
1478         { "Associated Device",          "zbee.zdp.assoc_device", FT_UINT16, BASE_HEX, NULL, 0x0,
1479             NULL, HFILL }},
1480
1481         { &hf_zbee_zdp_cinfo_alt_coord,
1482         { "Alternate Coordinator",      "zbee.zdp.cinfo.alt_coord", FT_BOOLEAN, 8, NULL, ZBEE_CINFO_ALT_COORD,
1483             "Indicates that the device is able to operate as a PAN coordinator.", HFILL }},
1484
1485         { &hf_zbee_zdp_cinfo_ffd,
1486         { "Full-Function Device",       "zbee.zdp.cinfo.ffd", FT_BOOLEAN, 8, NULL, ZBEE_CINFO_FFD,
1487             NULL, HFILL }},
1488
1489         { &hf_zbee_zdp_cinfo_power,
1490         { "AC Power",                   "zbee.zdp.cinfo.power", FT_BOOLEAN, 8, NULL, ZBEE_CINFO_POWER,
1491             "Indicates this device is using AC/Mains power.", HFILL }},
1492
1493         { &hf_zbee_zdp_cinfo_idle_rx,
1494         { "Rx On When Idle",            "zbee.zdp.cinfo.power", FT_BOOLEAN, 8, NULL, ZBEE_CINFO_IDLE_RX,
1495             "Indicates the receiver is active when the device is idle.", HFILL }},
1496
1497         { &hf_zbee_zdp_cinfo_security,
1498         { "Security Capability",        "zbee.zdp.cinfo.security", FT_BOOLEAN, 8, NULL, ZBEE_CINFO_SECURITY,
1499             "Indicates this device is capable of performing encryption/decryption.", HFILL }},
1500
1501         { &hf_zbee_zdp_cinfo_alloc,
1502         { "Allocate Short Address",     "zbee.zdp.cinfo.alloc", FT_BOOLEAN, 8, NULL, ZBEE_CINFO_ALLOC,
1503             "Flag requesting the parent to allocate a short address for this device.", HFILL }},
1504
1505         { &hf_zbee_zdp_server_pri_trust,
1506         { "Primary Trust Center",       "zbee.zdp.server.pri_trust", FT_BOOLEAN, 16, NULL, ZBEE_ZDP_NODE_SERVER_PRIMARY_TRUST,
1507             NULL, HFILL }},
1508
1509         { &hf_zbee_zdp_server_bak_trust,
1510         { "Backup Trust Center",        "zbee.zdp.server.bak_trust", FT_BOOLEAN, 16, NULL, ZBEE_ZDP_NODE_SERVER_BACKUP_TRUST,
1511             NULL, HFILL }},
1512
1513         { &hf_zbee_zdp_server_pri_bind,
1514         { "Primary Binding Table Cache","zbee.zdp.server.pri_bind", FT_BOOLEAN, 16, NULL, ZBEE_ZDP_NODE_SERVER_PRIMARY_BIND,
1515             NULL, HFILL }},
1516
1517         { &hf_zbee_zdp_server_bak_bind,
1518         { "Backup Binding Table Cache", "zbee.zdp.server.bak_bind", FT_BOOLEAN, 16, NULL, ZBEE_ZDP_NODE_SERVER_BACKUP_BIND,
1519             NULL, HFILL }},
1520
1521         { &hf_zbee_zdp_server_pri_disc,
1522         { "Primary Discovery Cache",    "zbee.zdp.server.pri_disc", FT_BOOLEAN, 16, NULL, ZBEE_ZDP_NODE_SERVER_PRIMARY_DISC,
1523             NULL, HFILL }},
1524
1525         { &hf_zbee_zdp_server_bak_disc,
1526         { "Backup Discovery Cache",     "zbee.zdp.server.bak_bind", FT_BOOLEAN, 16, NULL, ZBEE_ZDP_NODE_SERVER_BACKUP_DISC,
1527             NULL, HFILL }},
1528
1529         { &hf_zbee_zdp_node_type,
1530         { "Type",                       "zbee.zdp.node.type", FT_UINT16, BASE_DEC, NULL, ZBEE_ZDP_NODE_TYPE,
1531             NULL, HFILL }},
1532
1533         { &hf_zbee_zdp_node_complex,
1534         { "Complex Descriptor",         "zbee.zdp.node.complex", FT_BOOLEAN, 16, NULL, ZBEE_ZDP_NODE_COMPLEX,
1535             NULL, HFILL }},
1536
1537         { &hf_zbee_zdp_node_user,
1538         { "User Descriptor",            "zbee.zdp.node.user", FT_BOOLEAN, 16, NULL, ZBEE_ZDP_NODE_USER,
1539             NULL, HFILL }},
1540
1541         { &hf_zbee_zdp_node_freq_868,
1542         { "868MHz Band",                "zbee.zdp.node.freq.868mhz", FT_BOOLEAN, 16, NULL, ZBEE_ZDP_NODE_FREQ_868MHZ,
1543             NULL, HFILL }},
1544
1545         { &hf_zbee_zdp_node_freq_900,
1546         { "900MHz Band",                "zbee.zdp.node.freq.900mhz", FT_BOOLEAN, 16, NULL, ZBEE_ZDP_NODE_FREQ_900MHZ,
1547             NULL, HFILL }},
1548
1549         { &hf_zbee_zdp_node_freq_2400,
1550         { "2.4GHz Band",                "zbee.zdp.node.freq.2400mhz", FT_BOOLEAN, 16, NULL, ZBEE_ZDP_NODE_FREQ_2400MHZ,
1551             NULL, HFILL }},
1552
1553         { &hf_zbee_zdp_node_manufacturer,
1554         { "Manufacturer Code",          "zbee.zdp.node.manufacturer", FT_UINT16, BASE_HEX, NULL, 0x0,
1555             NULL, HFILL }},
1556
1557         { &hf_zbee_zdp_node_max_buffer,
1558         { "Max Buffer Size",            "zbee.zdp.node.max_buffer", FT_UINT8, BASE_DEC, NULL, 0x0,
1559             NULL, HFILL }},
1560
1561         { &hf_zbee_zdp_node_max_transfer,
1562         { "Max Transfer Size",          "zbee.zdp.node.max_transfer", FT_UINT16, BASE_DEC, NULL, 0x0,
1563             NULL, HFILL }},
1564
1565         { &hf_zbee_zdp_power_mode,
1566         { "Mode",                       "zbee.zdp.power.mode", FT_UINT16, BASE_DEC, NULL, ZBEE_ZDP_POWER_MODE,
1567             NULL, HFILL }},
1568
1569         { &hf_zbee_zdp_power_avail_ac,
1570         { "Available AC Power",         "zbee.zdp.power.avail.ac", FT_BOOLEAN, 16, NULL, ZBEE_ZDP_POWER_AVAIL_AC,
1571             NULL, HFILL }},
1572
1573         { &hf_zbee_zdp_power_avail_recharge,
1574         { "Available Rechargeable Battery", "zbee.zdp.power.avail.rech", FT_BOOLEAN, 16, NULL, ZBEE_ZDP_POWER_AVAIL_RECHARGEABLE,
1575             NULL, HFILL }},
1576
1577         { &hf_zbee_zdp_power_avail_dispose,
1578         { "Available Disposeable Battery",  "zbee.zdp.power.avail.disp", FT_BOOLEAN, 16, NULL, ZBEE_ZDP_POWER_AVAIL_DISPOSEABLE,
1579             NULL, HFILL }},
1580
1581         { &hf_zbee_zdp_power_source_ac,
1582         { "Using AC Power",             "zbee.zdp.power.source.ac", FT_BOOLEAN, 16, NULL, ZBEE_ZDP_POWER_SOURCE_AC,
1583             NULL, HFILL }},
1584
1585         { &hf_zbee_zdp_power_source_recharge,
1586         { "Using Rechargeable Battery", "zbee.zdp.power.source.ac", FT_BOOLEAN, 16, NULL, ZBEE_ZDP_POWER_SOURCE_RECHARGEABLE,
1587             NULL, HFILL }},
1588
1589         { &hf_zbee_zdp_power_source_dispose,
1590         { "Using Disposeable Battery",  "zbee.zdp.power.source.ac", FT_BOOLEAN, 16, NULL, ZBEE_ZDP_POWER_SOURCE_DISPOSEABLE,
1591             NULL, HFILL }},
1592
1593         { &hf_zbee_zdp_power_level,
1594         { "Level",                      "zbee.zdp.power.level", FT_UINT16, BASE_DEC, NULL, ZBEE_ZDP_POWER_LEVEL,
1595             NULL, HFILL }},
1596
1597         { &hf_zbee_zdp_simple_app_device,
1598         { "Application Device",         "zbee.zdp.app.device", FT_UINT16, BASE_HEX, NULL, 0x0,
1599             NULL, HFILL }},
1600
1601         { &hf_zbee_zdp_simple_app_version,
1602         { "Application Version",        "zbee.zdp.app.version", FT_UINT16, BASE_HEX, NULL, 0x0,
1603             NULL, HFILL }},
1604
1605         { &hf_zbee_zdp_complex_length,
1606         { "Complex Descriptor Length",  "zbee.zdp.complex_length", FT_UINT8, BASE_DEC, NULL, 0x0,
1607             NULL, HFILL }},
1608
1609         { &hf_zbee_zdp_complex,
1610         { "Complex Descriptor",         "zbee.zdp.complex", FT_STRING, BASE_NONE, NULL, 0x0,
1611             NULL, HFILL }},
1612
1613         { &hf_zbee_zdp_user,
1614         { "User Descriptor",            "zbee.zdp.user", FT_STRING, BASE_NONE, NULL, 0x0,
1615             NULL, HFILL }},
1616
1617         { &hf_zbee_zdp_user_length,
1618         { "User Descriptor Length",     "zbee.zdp.user_length", FT_UINT8, BASE_DEC, NULL, 0x0,
1619             NULL, HFILL }},
1620
1621         { &hf_zbee_zdp_simple_length,
1622         { "Simple Descriptor Length",   "zbee.zdp.simple_length", FT_UINT8, BASE_DEC, NULL, 0x0,
1623             NULL, HFILL }},
1624
1625         { &hf_zbee_zdp_disc_node_size,
1626         { "Node Descriptor Size",       "zbee.zdp.node_size", FT_UINT8, BASE_DEC, NULL, 0x0,
1627             NULL, HFILL }},
1628
1629         { &hf_zbee_zdp_disc_power_size,
1630         { "Power Descriptor Size",      "zbee.zdp.power_size", FT_UINT8, BASE_DEC, NULL, 0x0,
1631             NULL, HFILL }},
1632
1633         { &hf_zbee_zdp_cache,
1634         { "Cache",                      "zbee.zdp.cache", FT_UINT16, BASE_HEX, NULL, 0x0,
1635             "Address of the device containing the discovery cache.", HFILL }},
1636
1637         { &hf_zbee_zdp_disc_ep_count,
1638         { "Active Endpoint Count",      "zbee.zdp.ep_count", FT_UINT8, BASE_DEC, NULL, 0x0,
1639             NULL, HFILL }},
1640
1641         { &hf_zbee_zdp_disc_simple_count,
1642         { "Simple Descriptor Count",    "zbee.zdp.simple_count", FT_UINT8, BASE_DEC, NULL, 0x0,
1643             NULL, HFILL }},
1644
1645         { &hf_zbee_zdp_disc_simple_size,
1646         { "Simple Descriptor Size",     "zbee.zdp.simple_size", FT_UINT8, BASE_DEC, NULL, 0x0,
1647             NULL, HFILL }},
1648
1649         { &hf_zbee_zdp_target,
1650         { "Target",                     "zbee.zdp.target", FT_UINT16, BASE_HEX, NULL, 0x0,
1651             NULL, HFILL }},
1652
1653         { &hf_zbee_zdp_target64,
1654         { "Target",                     "zbee.zdp.target64", FT_UINT64, BASE_HEX, NULL, 0x0,
1655             NULL, HFILL }},
1656
1657         { &hf_zbee_zdp_target_ep,
1658         { "Target Endpoint",            "zbee.zdp.target_ep", FT_UINT8, BASE_DEC, NULL, 0x0,
1659             NULL, HFILL }},
1660
1661         { &hf_zbee_zdp_replacement,
1662         { "Replacement",                "zbee.zdp.replacement", FT_UINT64, BASE_HEX, NULL, 0x0,
1663             NULL, HFILL }},
1664
1665         { &hf_zbee_zdp_replacement_ep,
1666         { "Replacement Endpoint",       "zbee.zdp.replacement_ep", FT_UINT8, BASE_DEC, NULL, 0x0,
1667             NULL, HFILL }},
1668
1669         { &hf_zbee_zdp_bind_src,
1670         { "Source",                     "zbee.zdp.bind.src", FT_UINT16, BASE_HEX, NULL, 0x0,
1671             NULL, HFILL }},
1672
1673         { &hf_zbee_zdp_bind_src64,
1674         { "Source",                     "zbee.zdp.bind.src64", FT_UINT64, BASE_HEX, NULL, 0x0,
1675             NULL, HFILL }},
1676
1677         { &hf_zbee_zdp_bind_src_ep,
1678         { "Source Endpoint",            "zbee.zdp.bind.src_ep", FT_UINT8, BASE_DEC, NULL, 0x0,
1679             NULL, HFILL }},
1680
1681         { &hf_zbee_zdp_bind_dst,
1682         { "Destination",                "zbee.zdp.bind.dst", FT_UINT16, BASE_HEX, NULL, 0x0,
1683             NULL, HFILL }},
1684
1685         { &hf_zbee_zdp_bind_dst64,
1686         { "Destination",                "zbee.zdp.bind.dst64", FT_UINT64, BASE_HEX, NULL, 0x0,
1687             NULL, HFILL }},
1688
1689         { &hf_zbee_zdp_bind_dst_ep,
1690         { "Destination Endpoint",       "zbee.zdp.bind.dst_ep", FT_UINT8, BASE_DEC, NULL, 0x0,
1691             NULL, HFILL }},
1692
1693         { &hf_zbee_zdp_duration,
1694         { "Duration",                   "zbee.zdp.duration", FT_UINT8, BASE_DEC, NULL, 0x0,
1695             NULL, HFILL }},
1696
1697         { &hf_zbee_zdp_leave_children,
1698         { "Remove Children",            "zbee.zdp.leave.children", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1699             NULL, HFILL }},
1700
1701         { &hf_zbee_zdp_leave_rejoin,
1702         { "Rejoin",                     "zbee.zdp.leave.rejoin", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1703             NULL, HFILL }},
1704
1705         { &hf_zbee_zdp_significance,
1706         { "Significance",               "zbee.zdp.significance", FT_UINT8, BASE_DEC, NULL, 0x0,
1707             NULL, HFILL }},
1708
1709         { &hf_zbee_zdp_scan_count,
1710         { "Scan Count",                 "zbee.zdp.scan_count", FT_UINT8, BASE_DEC, NULL, 0x0,
1711             NULL, HFILL }},
1712
1713         { &hf_zbee_zdp_update_id,
1714         { "Update ID",                  "zbee.zdp.update_id", FT_UINT8, BASE_DEC, NULL, 0x0,
1715             NULL, HFILL }},
1716
1717         { &hf_zbee_zdp_manager,
1718         { "Network Manager",            "zbee.zdp.manager", FT_UINT16, BASE_HEX, NULL, 0x0,
1719             NULL, HFILL }},
1720
1721         { &hf_zbee_zdp_tx_total,
1722         { "Total Transmissions",        "zbee.zdp.tx_total", FT_UINT16, BASE_DEC, NULL, 0x0,
1723             NULL, HFILL }},
1724
1725         { &hf_zbee_zdp_tx_fail,
1726         { "Failed Transmissions",       "zbee.zdp.tx_fail", FT_UINT16, BASE_DEC, NULL, 0x0,
1727             NULL, HFILL }},
1728
1729         { &hf_zbee_zdp_channel_count,
1730         { "Channel List Count",         "zbee.zdp.channel_count", FT_UINT8, BASE_DEC, NULL, 0x0,
1731             NULL, HFILL }}
1732     };
1733
1734     /*  APS subtrees */
1735     static gint *ett[] = {
1736         &ett_zbee_zdp,
1737         &ett_zbee_zdp_endpoint,
1738         &ett_zbee_zdp_match_in,
1739         &ett_zbee_zdp_match_out,
1740         &ett_zbee_zdp_node,
1741         &ett_zbee_zdp_node_in,
1742         &ett_zbee_zdp_node_out,
1743         &ett_zbee_zdp_power,
1744         &ett_zbee_zdp_simple,
1745         &ett_zbee_zdp_complex,
1746         &ett_zbee_zdp_cinfo,
1747         &ett_zbee_zdp_server,
1748         &ett_zbee_zdp_simple_sizes,
1749         &ett_zbee_zdp_bind,
1750         &ett_zbee_zdp_bind_end_in,
1751         &ett_zbee_zdp_bind_end_out,
1752         &ett_zbee_zdp_bind_table,
1753         &ett_zbee_zdp_bind_source,
1754         &ett_zbee_zdp_channels,
1755         &ett_zbee_zdp_assoc_device,
1756         &ett_zbee_zdp_nwk,
1757         &ett_zbee_zdp_lqi,
1758         &ett_zbee_zdp_rtg,
1759         &ett_zbee_zdp_cache
1760     };
1761
1762     /* Register ZigBee ZDP protocol with Wireshark. */
1763     proto_zbee_zdp = proto_register_protocol("ZigBee Device Profile", "ZigBee ZDP", "zbee.zdp");
1764     proto_register_field_array(proto_zbee_zdp, hf, array_length(hf));
1765     proto_register_subtree_array(ett, array_length(ett));
1766
1767     /* Register the ZDP dissector. */
1768     register_dissector("zbee.zdp", dissect_zbee_zdp, proto_zbee_zdp);
1769 } /* proto_register_zbee_zdp */
1770
1771 /*FUNCTION:------------------------------------------------------
1772  *  NAME
1773  *      proto_reg_handoff_zbee_zdp
1774  *  DESCRIPTION
1775  *      Registers the Zigbee Device Profile dissector with Wireshark.
1776  *  PARAMETERS
1777  *      none
1778  *  RETURNS
1779  *      void
1780  *---------------------------------------------------------------
1781  */
1782 void proto_reg_handoff_zbee_zdp(void)
1783 {
1784     dissector_handle_t  zdp_handle;
1785
1786     /* Find the other dissectors we need. */
1787     data_handle     = find_dissector("data");
1788
1789     /* Register our dissector with the ZigBee application dissectors. */
1790     zdp_handle = find_dissector("zbee.zdp");
1791     dissector_add("zbee.profile", ZBEE_ZDP_PROFILE, zdp_handle);
1792 } /* proto_reg_handoff_zbee_zdp */