Enable Lua tcp tap userdata.
[obnox/wireshark/wip.git] / epan / dissectors / packet-zbee-zdp-management.c
1 /* packet-zbee-zdp-management.c
2  * Dissector helper routines for the management services of the ZigBee Device Profile
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
38 #include "packet-zbee.h"
39 #include "packet-zbee-zdp.h"
40
41 /**************************************
42  * HELPER FUNCTIONS
43  **************************************
44  */
45 /*FUNCTION:------------------------------------------------------
46  *  NAME
47  *      zdp_parse_nwk_desc
48  *  DESCRIPTION
49  *      Parses and displays a single network descriptor
50  *  PARAMETERS
51  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
52  *      packet_into *pinfo  - pointer to packet information fields
53  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
54  *  RETURNS
55  *      void
56  *---------------------------------------------------------------
57  */
58 void
59 zdp_parse_nwk_desc(proto_tree *tree, tvbuff_t *tvb, guint *offset, packet_info *pinfo)
60 {
61     proto_item      *ti = NULL;
62     guint           len = 0;
63
64     guint64     ext_pan;
65     guint16     pan;
66     guint8      channel;
67     guint8      profile;
68     guint8      version;
69     guint8      beacon;
70     guint8      superframe;
71     gboolean    permit;
72
73     if (pinfo->zbee_stack_vers >= ZBEE_VERSION_2007) {
74         /* Extended PAN Identifiers are used in ZigBee 2006 & later. */
75         ext_pan = tvb_get_letoh64(tvb, *offset + len);
76         if (tree) ti = proto_tree_add_text(tree, tvb, *offset, 0, "{Pan: %s", print_eui64(ext_pan));
77         len += sizeof(guint64);
78     }
79     else {
80         /* Short PAN Identifiers are used in ZigBee 2003 and earlier. */
81         pan = tvb_get_letohs(tvb, *offset + len);
82         if (tree) ti = proto_tree_add_text(tree, tvb, *offset, 0, "{Pan: 0x%04x", pan);
83         len += sizeof(guint16);
84     }
85
86     channel = tvb_get_guint8(tvb, *offset + len);
87     if (tree) proto_item_append_text(ti, ", Channel: %d", channel);
88     len += sizeof(guint8);
89
90     profile = (tvb_get_guint8(tvb, *offset + len) & 0x0f) >> 0;
91     version = (tvb_get_guint8(tvb, *offset + len) & 0xf0) >> 4;
92     if (tree) proto_item_append_text(ti, ", Profile: 0x%01x, Version: %d", profile, version);
93     len += sizeof(guint8);
94
95     beacon      = (tvb_get_guint8(tvb, *offset + len) & 0x0f) >> 0;
96     superframe  = (tvb_get_guint8(tvb, *offset + len) & 0xf0) >> 4;
97     if ((tree) && (beacon == 0xf)) {
98         proto_item_append_text(ti, ", Beacons Disabled");
99     }
100     else if (tree) {
101         proto_item_append_text(ti, ", BeaconOrder: %d, SuperframeOrder: %d", beacon, superframe);
102     }
103     len += sizeof(guint8);
104
105     permit = tvb_get_guint8(tvb, *offset) & 0x01;
106     if (tree) proto_item_append_text(ti, ", PermitJoining: %s}", permit?"True":"False");
107     len += sizeof(guint8);
108
109     if (tree) proto_item_set_len(ti, len);
110     *offset += len;
111 } /* zdp_parse_nwk_desc */
112
113 /*FUNCTION:------------------------------------------------------
114  *  NAME
115  *      zdp_parse_neighbor_table_entry
116  *  DESCRIPTION
117  *      Parses and displays a neighbor table entry.
118  *  PARAMETERS
119  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
120  *      packet_into *pinfo  - pointer to packet information fields
121  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
122  *  RETURNS
123  *      void
124  *---------------------------------------------------------------
125  */
126 void
127 zdp_parse_neighbor_table_entry(proto_tree *tree, tvbuff_t *tvb, guint *offset, packet_info *pinfo)
128 {
129     proto_item      *ti = NULL;
130     guint           len = 0;
131
132     guint64 ext_pan;
133     guint16 pan;
134     guint64 ext_addr;
135     guint16 device;
136     guint8  type;
137     guint8  idle_rx;
138     guint8  rel;
139     guint8  permit_joining;
140     guint8  depth;
141     guint8  lqi;
142
143     if (pinfo->zbee_stack_vers >= ZBEE_VERSION_2007) {
144         /* ZigBee 2006 & later use an extended PAN Identifier. */
145         ext_pan = tvb_get_letoh64(tvb, *offset + len);
146         if (tree) ti = proto_tree_add_text(tree, tvb, *offset, 0, "{Extended PAN: %s", print_eui64(ext_pan));
147         len += sizeof(guint64);
148     }
149     else {
150         /* ZigBee 2003 & earlier use a short PAN Identifier. */
151         pan = tvb_get_letohs(tvb, *offset + len);
152         if (tree) ti = proto_tree_add_text(tree, tvb, *offset, 0, "{PAN: 0x%04x", pan);
153         len += sizeof(guint16);
154     }
155
156     ext_addr = tvb_get_letoh64(tvb, *offset + len);
157     if (tree) proto_item_append_text(ti, ", Extended Addr: %s", print_eui64_oui(ext_addr));
158     len += sizeof(guint64);
159
160     device = tvb_get_letohs(tvb, *offset + len);
161     if (tree) proto_item_append_text(ti, ", Addr: 0x%04x", device);
162     len += sizeof(guint16);
163
164     if (pinfo->zbee_stack_vers >= ZBEE_VERSION_2007) {
165         type    = (tvb_get_guint8(tvb, *offset + len) & 0x03) >> 0;
166         idle_rx = (tvb_get_guint8(tvb, *offset + len) & 0x0c) >> 2;
167         rel     = (tvb_get_guint8(tvb, *offset + len) & 0x70) >> 4;
168     }
169     else {
170         type    = (tvb_get_guint8(tvb, *offset + len) & 0x03) >> 0;
171         idle_rx = (tvb_get_guint8(tvb, *offset + len) & 0x04) >> 2;
172         rel     = (tvb_get_guint8(tvb, *offset + len) & 0x18) >> 3;
173     }
174     if (tree) {
175         if (type == 0x00)       proto_item_append_text(ti, ", Type: Coordinator");
176         else if (type == 0x01)  proto_item_append_text(ti, ", Type: Router");
177         else if (type == 0x02)  proto_item_append_text(ti, ", Type: End Device");
178         else                    proto_item_append_text(ti, ", Type: Unknown");
179
180         if (idle_rx == 0x00)    proto_item_append_text(ti, ", Idle Rx: False");
181         else if (idle_rx==0x01) proto_item_append_text(ti, ", Idle Rx: True");
182         else                    proto_item_append_text(ti, ", Idle Rx: Unknown");
183
184         if (rel == 0x00)        proto_item_append_text(ti, ", Relationship: Parent");
185         else if (rel == 0x01)   proto_item_append_text(ti, ", Relationship: Child");
186         else if (rel == 0x02)   proto_item_append_text(ti, ", Relationship: Sibling");
187         else if (rel == 0x03)   proto_item_append_text(ti, ", Relationship: None");
188         else if (rel == 0x04)   proto_item_append_text(ti, ", Relationship: Previous Child");
189         else                    proto_item_append_text(ti, ", Relationship: Unknown");
190     }
191     len += sizeof(guint8);
192
193     if (pinfo->zbee_stack_vers <= ZBEE_VERSION_2004) {
194         /* In ZigBee 2003 & earlier, the depth field is before the permit joining field. */
195         depth = tvb_get_guint8(tvb, *offset + len);
196         if (tree) proto_item_append_text(ti, ", Depth: %d", depth);
197         len += sizeof(guint8);
198     }
199
200     permit_joining = (tvb_get_guint8(tvb, *offset + len) & 0x03) >> 0;
201     if (tree) {
202         if (permit_joining == 0x00)     proto_item_append_text(ti, ", Permit Joining: False");
203         else if (permit_joining == 0x01)proto_item_append_text(ti, ", Permit Joining: True");
204         else                            proto_item_append_text(ti, ", Permit Joining: Unknown");
205     }
206     len += sizeof(guint8);
207
208     if (pinfo->zbee_stack_vers >= ZBEE_VERSION_2007) {
209         /* In ZigBee 2006 & later, the depth field is after the permit joining field. */
210         depth = tvb_get_guint8(tvb, *offset + len);
211         if (tree) proto_item_append_text(ti, ", Depth: %d", depth);
212         len += sizeof(guint8);
213     }
214
215     lqi = tvb_get_guint8(tvb, *offset + len);
216     if (tree) proto_item_append_text(ti, ", LQI: %d}", lqi);
217     len += sizeof(guint8);
218
219     if (tree) proto_item_set_len(ti, len);
220     *offset += len;
221 } /* zdp_parse_neighbor_table_entry */
222
223 /*FUNCTION:------------------------------------------------------
224  *  NAME
225  *      zdp_parse_routing_table_entry
226  *  DESCRIPTION
227  *      Parses and displays a routing table entry.
228  *  PARAMETERS
229  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
230  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
231  *  RETURNS
232  *      void
233  *---------------------------------------------------------------
234  */
235 static void
236 zdp_parse_routing_table_entry(proto_tree *tree, tvbuff_t *tvb, guint *offset)
237 {
238     proto_item  *ti = NULL;
239     guint       len = 0;
240
241     guint16     dest;
242     guint8      status;
243     guint16     next;
244
245     dest = tvb_get_letohs(tvb, *offset + len);
246     if (tree) ti = proto_tree_add_text(tree, tvb, *offset, 2*sizeof(guint16) + sizeof(guint8), "{Destination: 0x%04x", dest);
247     len += sizeof(guint16);
248
249     status = tvb_get_guint8(tvb, *offset + len);
250     next   = tvb_get_letohs(tvb, *offset + len + sizeof(guint8));
251     if (tree) {
252         /* Display the next hop first, because it looks a lot cleaner that way. */
253         proto_item_append_text(ti, ", Next Hop: 0x%04x", next);
254
255         if (status == 0x00)     proto_item_append_text(ti, ", Status: Active}");
256         else if (status == 0x01)proto_item_append_text(ti, ", Status: Discovery Underway}");
257         else if (status == 0x02)proto_item_append_text(ti, ", Status: Discovery Failed}");
258         else if (status == 0x03)proto_item_append_text(ti, ", Status: Inactive}");
259         else                    proto_item_append_text(ti, ", Status: Unknown}");
260     }
261     len += sizeof(guint8) + sizeof(guint16);
262
263     *offset += len;
264 } /* zdp_parse_routing_table_entry */
265
266 /*FUNCTION:------------------------------------------------------
267  *  NAME
268  *      zdp_parse_bind_table_entry
269  *  DESCRIPTION
270  *      Parses and displays a single binding table entry.
271  *  PARAMETERS
272  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
273  *      packet_into *pinfo  - pointer to packet information fields
274  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
275  *  RETURNS
276  *      void
277  *---------------------------------------------------------------
278  */
279 extern void zdp_parse_bind_table_entry(proto_tree *tree, tvbuff_t *tvb, guint *offset, packet_info *pinfo);
280
281 /**************************************
282  * MANAGEMENT REQUESTS
283  **************************************
284  */
285 /*FUNCTION:------------------------------------------------------
286  *  NAME
287  *      dissect_zbee_zdp_req_mgmt_nwk_disc
288  *  DESCRIPTION
289  *      ZigBee Device Profile dissector for the network discovery
290  *      request. Cluster ID = 0x0030.
291  *  PARAMETERS
292  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
293  *      packet_into *pinfo  - pointer to packet information fields
294  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
295  *  RETURNS
296  *      void
297  *---------------------------------------------------------------
298  */
299 void
300 dissect_zbee_zdp_req_mgmt_nwk_disc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
301 {
302     proto_item  *ti;
303     guint       i;
304
305     guint   offset = 0;
306     guint32 channels;
307     guint8  duration;
308     guint8  index;
309
310     /* Get the channel bitmap. */
311     channels = tvb_get_letohl(tvb, offset);
312     if (tree) {
313         gboolean    first = 1;
314         ti = proto_tree_add_text(tree, tvb, offset, sizeof(guint32), "Scan Channels: ");
315
316         for (i=0; i<27; i++) {
317             if (channels & (1<<i)) {
318                 if (first) proto_item_append_text(ti, "%d", i);
319                 else       proto_item_append_text(ti, ", %d", i);
320                 if (channels & (2<<i)) {
321                     while ((channels&(2<<i)) && (i<26)) i++;
322                     proto_item_append_text(ti, "-%d", i);
323                 }
324                 first = 0;
325             }
326         }
327         if (first) proto_item_append_text(ti, "None");
328     }
329     offset += sizeof(guint32);
330
331     duration = zbee_parse_uint(tree, hf_zbee_zdp_duration, tvb, &offset, sizeof(guint8), NULL);
332     index    = zbee_parse_uint(tree, hf_zbee_zdp_index, tvb, &offset, sizeof(guint8), NULL);
333
334     /* Dump any leftover bytes. */
335     zdp_dump_excess(tvb, offset, pinfo, tree);
336 } /* dissect_zbee_zdp_req_mgmt_nwk_disc */
337
338 /*FUNCTION:------------------------------------------------------
339  *  NAME
340  *      dissect_zbee_zdp_req_mgmt_lqi
341  *  DESCRIPTION
342  *      ZigBee Device Profile dissector for the link quality information
343  *      request. Cluster ID = 0x0031.
344  *  PARAMETERS
345  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
346  *      packet_into *pinfo  - pointer to packet information fields
347  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
348  *  RETURNS
349  *      void
350  *---------------------------------------------------------------
351  */
352 void
353 dissect_zbee_zdp_req_mgmt_lqi(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
354 {
355     guint   offset = 0;
356     guint8  index;
357
358     index = zbee_parse_uint(tree, hf_zbee_zdp_index, tvb, &offset, sizeof(guint8), NULL);
359
360     /* Dump any leftover bytes. */
361     zdp_dump_excess(tvb, offset, pinfo, tree);
362 } /* dissect_zbee_zdp_req_mgmt_lqi */
363
364 /*FUNCTION:------------------------------------------------------
365  *  NAME
366  *      dissect_zbee_zdp_req_mgmt_rtg
367  *  DESCRIPTION
368  *      ZigBee Device Profile dissector for the routing table
369  *      request. Cluster ID = 0x0032.
370  *  PARAMETERS
371  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
372  *      packet_into *pinfo  - pointer to packet information fields
373  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
374  *  RETURNS
375  *      void
376  *---------------------------------------------------------------
377  */
378 void
379 dissect_zbee_zdp_req_mgmt_rtg(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
380 {
381     guint   offset = 0;
382     guint8  index;
383
384     index = zbee_parse_uint(tree, hf_zbee_zdp_index, tvb, &offset, sizeof(guint8), NULL);
385
386     /* Dump any leftover bytes. */
387     zdp_dump_excess(tvb, offset, pinfo, tree);
388 } /* dissect_zbee_zdp_req_mgmt_rtg */
389
390 /*FUNCTION:------------------------------------------------------
391  *  NAME
392  *      dissect_zbee_zdp_req_mgmt_bind
393  *  DESCRIPTION
394  *      ZigBee Device Profile dissector for the binding table
395  *      request. Cluster ID = 0x0033.
396  *  PARAMETERS
397  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
398  *      packet_into *pinfo  - pointer to packet information fields
399  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
400  *  RETURNS
401  *      void
402  *---------------------------------------------------------------
403  */
404 void
405 dissect_zbee_zdp_req_mgmt_bind(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
406 {
407     guint   offset = 0;
408     guint8  index;
409
410     index = zbee_parse_uint(tree, hf_zbee_zdp_index, tvb, &offset, sizeof(guint8), NULL);
411
412     /* Dump any leftover bytes. */
413     zdp_dump_excess(tvb, offset, pinfo, tree);
414 } /* dissect_zbee_zdp_req_mgmt_bind */
415
416 /*FUNCTION:------------------------------------------------------
417  *  NAME
418  *      dissect_zbee_zdp_req_mgmt_leave
419  *  DESCRIPTION
420  *      ZigBee Device Profile dissector for the leave request.
421  *      Cluster ID = 0x0034.
422  *  PARAMETERS
423  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
424  *      packet_into *pinfo  - pointer to packet information fields
425  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
426  *  RETURNS
427  *      void
428  *---------------------------------------------------------------
429  */
430 void
431 dissect_zbee_zdp_req_mgmt_leave(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
432 {
433     guint   offset = 0;
434     guint64 ext_addr;
435     guint8  flags;
436
437     ext_addr = zbee_parse_eui64(tree, hf_zbee_zdp_ext_addr, tvb, &offset, sizeof(guint64), NULL);
438     if (pinfo->zbee_stack_vers >= ZBEE_VERSION_2007) {
439         /* Flags present on ZigBee 2006 & later. */
440         flags    = tvb_get_guint8(tvb, offset);
441         if (tree) {
442             proto_tree_add_boolean(tree, hf_zbee_zdp_leave_children, tvb, offset, sizeof(guint8), flags & ZBEE_ZDP_MGMT_LEAVE_CHILDREN);
443             proto_tree_add_boolean(tree, hf_zbee_zdp_leave_rejoin, tvb, offset, sizeof(guint8), flags & ZBEE_ZDP_MGMT_LEAVE_REJOIN);
444         }
445         offset += sizeof(guint8);
446     }
447
448     zbee_append_info(tree, pinfo, ", Device: %s", print_eui64_oui(ext_addr));
449
450     /* Dump any leftover bytes. */
451     zdp_dump_excess(tvb, offset, pinfo, tree);
452 } /* dissect_zbee_zdp_req_mgmt_bind */
453
454 /*FUNCTION:------------------------------------------------------
455  *  NAME
456  *      dissect_zbee_zdp_req_mgmt_direct_join
457  *  DESCRIPTION
458  *      ZigBee Device Profile dissector for the direct join request.
459  *      Cluster ID = 0x0035.
460  *  PARAMETERS
461  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
462  *      packet_into *pinfo  - pointer to packet information fields
463  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
464  *  RETURNS
465  *      void
466  *---------------------------------------------------------------
467  */
468 void
469 dissect_zbee_zdp_req_mgmt_direct_join(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
470 {
471     guint   offset = 0;
472     guint64 ext_addr;
473     guint8  cinfo;
474
475     ext_addr = zbee_parse_eui64(tree, hf_zbee_zdp_ext_addr, tvb, &offset, sizeof(guint64), NULL);
476     cinfo    = zdp_parse_cinfo(tree, ett_zbee_zdp_cinfo, tvb, &offset);
477
478     zbee_append_info(tree, pinfo, ", Device: %s", print_eui64_oui(ext_addr));
479
480     /* Dump any leftover bytes. */
481     zdp_dump_excess(tvb, offset, pinfo, tree);
482 } /* dissect_zbee_zdp_req_mgmt_direct_join */
483
484 /*FUNCTION:------------------------------------------------------
485  *  NAME
486  *      dissect_zbee_zdp_req_mgmt_permit_join
487  *  DESCRIPTION
488  *      ZigBee Device Profile dissector for the permit joining
489  *      request. Cluster ID = 0x0036.
490  *  PARAMETERS
491  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
492  *      packet_into *pinfo  - pointer to packet information fields
493  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
494  *  RETURNS
495  *      void
496  *---------------------------------------------------------------
497  */
498 void
499 dissect_zbee_zdp_req_mgmt_permit_join(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
500 {
501     guint   offset = 0;
502     guint8  duration;
503     guint8  significance;
504
505     duration     = zbee_parse_uint(tree, hf_zbee_zdp_duration, tvb, &offset, sizeof(guint8), NULL);
506     significance = zbee_parse_uint(tree, hf_zbee_zdp_significance, tvb, &offset, sizeof(guint8), NULL);
507
508     /* Dump any leftover bytes. */
509     zdp_dump_excess(tvb, offset, pinfo, tree);
510 } /* dissect_zbee_zdp_req_mgmt_permit_join */
511
512 /*FUNCTION:------------------------------------------------------
513  *  NAME
514  *      dissect_zbee_zdp_req_mgmt_cache
515  *  DESCRIPTION
516  *      ZigBee Device Profile dissector for the cache request.
517  *      Cluster ID = 0x0037.
518  *  PARAMETERS
519  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
520  *      packet_into *pinfo  - pointer to packet information fields
521  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
522  *  RETURNS
523  *      void
524  *---------------------------------------------------------------
525  */
526 void
527 dissect_zbee_zdp_req_mgmt_cache(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
528 {
529     guint   offset = 0;
530     guint8  index;
531
532     index = zbee_parse_uint(tree, hf_zbee_zdp_index, tvb, &offset, sizeof(guint8), NULL);
533
534     /* Dump any leftover bytes. */
535     zdp_dump_excess(tvb, offset, pinfo, tree);
536 } /* dissect_zbee_zdp_req_mgmt_cache */
537
538 /*FUNCTION:------------------------------------------------------
539  *  NAME
540  *      dissect_zbee_zdp_req_mgmt_nwkupdate
541  *  DESCRIPTION
542  *      ZigBee Device Profile dissector for the nwk update request.
543  *      Cluster ID = 0x0038.
544  *  PARAMETERS
545  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
546  *      packet_into *pinfo  - pointer to packet information fields
547  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
548  *  RETURNS
549  *      void
550  *---------------------------------------------------------------
551  */
552 void
553 dissect_zbee_zdp_req_mgmt_nwkupdate(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
554 {
555     guint   offset = 0;
556     guint32 channels;
557     guint8  duration;
558     guint8  count;
559     guint8  update_id;
560     guint16 manager;
561
562     channels = zdp_parse_chanmask(tree, tvb, &offset);
563     duration = zbee_parse_uint(tree, hf_zbee_zdp_duration, tvb, &offset, sizeof(guint8), NULL);
564     if (duration == ZBEE_ZDP_NWKUPDATE_PARAMETERS) {
565         update_id = zbee_parse_uint(tree, hf_zbee_zdp_update_id, tvb, &offset, sizeof(guint8), NULL);
566         manager = zbee_parse_uint(tree, hf_zbee_zdp_manager, tvb, &offset, sizeof(guint16), NULL);
567     }
568     else if (duration == ZBEE_ZDP_NWKUPDATE_CHANNEL_HOP) {
569         update_id = zbee_parse_uint(tree, hf_zbee_zdp_update_id, tvb, &offset, sizeof(guint8), NULL);
570     }
571     else if (duration <= ZBEE_ZDP_NWKUPDATE_SCAN_MAX) {
572         count = zbee_parse_uint(tree, hf_zbee_zdp_scan_count, tvb, &offset, sizeof(guint8), NULL);
573     }
574
575     /* Dump any leftover bytes. */
576     zdp_dump_excess(tvb, offset, pinfo, tree);
577 } /* dissect_zbee_zdp_req_mgmt_nwkupdate */
578
579 /**************************************
580  * MANAGEMENT RESPONSES
581  **************************************
582  */
583 /*FUNCTION:------------------------------------------------------
584  *  NAME
585  *      dissect_zbee_zdp_rsp_mgmt_nwk_disc
586  *  DESCRIPTION
587  *      ZigBee Device Profile dissector for the network discovery
588  *      response. Cluster ID = 0x8030.
589  *  PARAMETERS
590  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
591  *      packet_into *pinfo  - pointer to packet information fields
592  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
593  *  RETURNS
594  *      void
595  *---------------------------------------------------------------
596  */
597 void
598 dissect_zbee_zdp_rsp_mgmt_nwk_disc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
599 {
600     proto_item  *ti;
601     proto_tree  *field_tree = NULL;
602     guint       offset = 0;
603     guint       i;
604
605     guint8  status;
606     guint8  table_size;
607     guint8  index;
608     guint8  table_count;
609
610     status      = zdp_parse_status(tree, tvb, &offset);
611     table_size  = zbee_parse_uint(tree, hf_zbee_zdp_table_size, tvb, &offset, sizeof(guint8), NULL);
612     index       = zbee_parse_uint(tree, hf_zbee_zdp_index, tvb, &offset, sizeof(guint8), NULL);
613     table_count = zbee_parse_uint(tree, hf_zbee_zdp_table_count, tvb, &offset, sizeof(guint8), NULL);
614
615     if (tree && table_count) {
616         ti = proto_tree_add_text(tree, tvb, offset, tvb_length_remaining(tvb, offset), "Network List");
617         field_tree = proto_item_add_subtree(ti, ett_zbee_zdp_nwk);
618     }
619     for (i=0; i<table_count; i++) {
620         zdp_parse_nwk_desc(field_tree, tvb, &offset, pinfo);
621     } /* for */
622
623     zbee_append_info(tree, pinfo, ", Status: %s", zdp_status_name(status));
624
625     /* Dump any leftover bytes. */
626     zdp_dump_excess(tvb, offset, pinfo, tree);
627 } /* dissect_zbee_zdp_rsp_mgmt_nwk_disc */
628
629 /*FUNCTION:------------------------------------------------------
630  *  NAME
631  *      dissect_zbee_zdp_rsp_mgmt_lqi
632  *  DESCRIPTION
633  *      ZigBee Device Profile dissector for the link quality information
634  *      response. Cluster ID = 0x8031.
635  *  PARAMETERS
636  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
637  *      packet_into *pinfo  - pointer to packet information fields
638  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
639  *  RETURNS
640  *      void
641  *---------------------------------------------------------------
642  */
643 void
644 dissect_zbee_zdp_rsp_mgmt_lqi(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
645 {
646     proto_item  *ti;
647     proto_tree  *field_tree = NULL;
648     guint       offset = 0;
649     guint       i;
650
651     guint8  status;
652     guint8  table_size;
653     guint8  index;
654     guint8  table_count;
655
656     status      = zdp_parse_status(tree, tvb, &offset);
657     table_size  = zbee_parse_uint(tree, hf_zbee_zdp_table_size, tvb, &offset, sizeof(guint8), NULL);
658     index       = zbee_parse_uint(tree, hf_zbee_zdp_index, tvb, &offset, sizeof(guint8), NULL);
659     table_count = zbee_parse_uint(tree, hf_zbee_zdp_table_count, tvb, &offset, sizeof(guint8), NULL);
660
661     if (tree && table_count) {
662         ti = proto_tree_add_text(tree, tvb, offset, tvb_length_remaining(tvb, offset), "Neighbor Table");
663         field_tree = proto_item_add_subtree(ti, ett_zbee_zdp_lqi);
664     }
665     for (i=0; i<table_count; i++) {
666         zdp_parse_neighbor_table_entry(field_tree, tvb, &offset, pinfo);
667     } /* for */
668
669     zbee_append_info(tree, pinfo, ", Status: %s", zdp_status_name(status));
670
671     /* Dump any leftover bytes. */
672     zdp_dump_excess(tvb, offset, pinfo, tree);
673 } /* dissect_zbee_zdp_rsp_mgmt_lqi */
674
675 /*FUNCTION:------------------------------------------------------
676  *  NAME
677  *      dissect_zbee_zdp_rsp_mgmt_rtg
678  *  DESCRIPTION
679  *      ZigBee Device Profile dissector for the routing table
680  *      response. Cluster ID = 0x8032.
681  *  PARAMETERS
682  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
683  *      packet_into *pinfo  - pointer to packet information fields
684  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
685  *  RETURNS
686  *      void
687  *---------------------------------------------------------------
688  */
689 void
690 dissect_zbee_zdp_rsp_mgmt_rtg(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
691 {
692     proto_item  *ti;
693     proto_tree  *field_tree = NULL;
694     guint       offset = 0;
695     guint       i;
696
697     guint8  status;
698     guint8  table_size;
699     guint8  index;
700     guint8  table_count;
701
702     status      = zdp_parse_status(tree, tvb, &offset);
703     table_size  = zbee_parse_uint(tree, hf_zbee_zdp_table_size, tvb, &offset, sizeof(guint8), NULL);
704     index       = zbee_parse_uint(tree, hf_zbee_zdp_index, tvb, &offset, sizeof(guint8), NULL);
705     table_count = zbee_parse_uint(tree, hf_zbee_zdp_table_count, tvb, &offset, sizeof(guint8), NULL);
706
707     if (tree && table_count) {
708         ti = proto_tree_add_text(tree, tvb, offset, tvb_length_remaining(tvb, offset), "Routing Table");
709         field_tree = proto_item_add_subtree(ti, ett_zbee_zdp_rtg);
710     }
711     for (i=0; i<table_count; i++) {
712         zdp_parse_routing_table_entry(field_tree, tvb, &offset);
713     } /* for */
714
715     zbee_append_info(tree, pinfo, ", Status: %s", zdp_status_name(status));
716
717     /* Dump any leftover bytes. */
718     zdp_dump_excess(tvb, offset, pinfo, tree);
719 } /* dissect_zbee_zdp_rsp_mgmt_rtg */
720
721 /*FUNCTION:------------------------------------------------------
722  *  NAME
723  *      dissect_zbee_zdp_rsp_mgmt_bind
724  *  DESCRIPTION
725  *      ZigBee Device Profile dissector for the binding table
726  *      response. Cluster ID = 0x8033.
727  *  PARAMETERS
728  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
729  *      packet_into *pinfo  - pointer to packet information fields
730  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
731  *  RETURNS
732  *      void
733  *---------------------------------------------------------------
734  */
735 void
736 dissect_zbee_zdp_rsp_mgmt_bind(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
737 {
738     proto_item  *ti;
739     proto_tree  *field_tree = NULL;
740     guint       offset = 0;
741     guint       i;
742
743     guint8  status;
744     guint8  table_size;
745     guint8  index;
746     guint8  table_count;
747
748     status      = zdp_parse_status(tree, tvb, &offset);
749     table_size  = zbee_parse_uint(tree, hf_zbee_zdp_table_size, tvb, &offset, sizeof(guint8), NULL);
750     index       = zbee_parse_uint(tree, hf_zbee_zdp_index, tvb, &offset, sizeof(guint8), NULL);
751     table_count = zbee_parse_uint(tree, hf_zbee_zdp_table_count, tvb, &offset, sizeof(guint8), NULL);
752
753     if (tree && table_count) {
754         ti = proto_tree_add_text(tree, tvb, offset, tvb_length_remaining(tvb, offset), "Binding Table");
755         field_tree = proto_item_add_subtree(ti, ett_zbee_zdp_bind);
756     }
757     for (i=0; i<table_count; i++) {
758         zdp_parse_bind_table_entry(field_tree, tvb, &offset, pinfo);
759     } /* for */
760
761     zbee_append_info(tree, pinfo, ", Status: %s", zdp_status_name(status));
762
763     /* Dump any leftover bytes. */
764     zdp_dump_excess(tvb, offset, pinfo, tree);
765 } /* dissect_zbee_zdp_rsp_mgmt_bind */
766
767 /*FUNCTION:------------------------------------------------------
768  *  NAME
769  *      dissect_zbee_zdp_rsp_mgmt_leave
770  *  DESCRIPTION
771  *      ZigBee Device Profile dissector for the leave response.
772  *      Cluster ID = 0x8034.
773  *  PARAMETERS
774  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
775  *      packet_into *pinfo  - pointer to packet information fields
776  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
777  *  RETURNS
778  *      void
779  *---------------------------------------------------------------
780  */
781 void
782 dissect_zbee_zdp_rsp_mgmt_leave(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
783 {
784     guint   offset = 0;
785     guint8  status;
786
787     status = zdp_parse_status(tree, tvb, &offset);
788
789     zbee_append_info(tree, pinfo, ", Status: %s", zdp_status_name(status));
790
791     /* Dump any leftover bytes. */
792     zdp_dump_excess(tvb, offset, pinfo, tree);
793 } /* dissect_zbee_zdp_rsp_mgmt_bind */
794
795 /*FUNCTION:------------------------------------------------------
796  *  NAME
797  *      dissect_zbee_zdp_rsp_mgmt_direct_join
798  *  DESCRIPTION
799  *      ZigBee Device Profile dissector for the direct join response.
800  *      Cluster ID = 0x8035.
801  *  PARAMETERS
802  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
803  *      packet_into *pinfo  - pointer to packet information fields
804  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
805  *  RETURNS
806  *      void
807  *---------------------------------------------------------------
808  */
809 void
810 dissect_zbee_zdp_rsp_mgmt_direct_join(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
811 {
812     guint   offset = 0;
813     guint8  status;
814
815     status = zdp_parse_status(tree, tvb, &offset);
816
817     zbee_append_info(tree, pinfo, ", Status: %s", zdp_status_name(status));
818
819     /* Dump any leftover bytes. */
820     zdp_dump_excess(tvb, offset, pinfo, tree);
821 } /* dissect_zbee_zdp_rsp_mgmt_direct_join */
822
823 /*FUNCTION:------------------------------------------------------
824  *  NAME
825  *      dissect_zbee_zdp_rsp_mgmt_permit_join
826  *  DESCRIPTION
827  *      ZigBee Device Profile dissector for the permit joining response.
828  *      Cluster ID = 0x8036.
829  *  PARAMETERS
830  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
831  *      packet_into *pinfo  - pointer to packet information fields
832  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
833  *  RETURNS
834  *      void
835  *---------------------------------------------------------------
836  */
837 void
838 dissect_zbee_zdp_rsp_mgmt_permit_join(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
839 {
840     guint   offset = 0;
841     guint8  status;
842
843     status = zdp_parse_status(tree, tvb, &offset);
844
845     zbee_append_info(tree, pinfo, ", Status: %s", zdp_status_name(status));
846
847     /* Dump any leftover bytes. */
848     zdp_dump_excess(tvb, offset, pinfo, tree);
849 } /* dissect_zbee_zdp_rsp_mgmt_permit_join */
850
851 /*FUNCTION:------------------------------------------------------
852  *  NAME
853  *      dissect_zbee_zdp_rsp_mgmt_cache
854  *  DESCRIPTION
855  *      ZigBee Device Profile dissector for the cache response.
856  *      Cluster ID = 0x8037.
857  *  PARAMETERS
858  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
859  *      packet_into *pinfo  - pointer to packet information fields
860  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
861  *  RETURNS
862  *      void
863  *---------------------------------------------------------------
864  */
865 void
866 dissect_zbee_zdp_rsp_mgmt_cache(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
867 {
868     proto_item  *ti;
869     proto_tree  *field_tree;
870     guint       offset = 0;
871     guint       i;
872
873     guint8  status;
874     guint8  table_size;
875     guint8  index;
876     guint8  table_count;
877
878     status      = zdp_parse_status(tree, tvb, &offset);
879     table_size  = zbee_parse_uint(tree, hf_zbee_zdp_table_size, tvb, &offset, sizeof(guint8), NULL);
880     index       = zbee_parse_uint(tree, hf_zbee_zdp_index, tvb, &offset, sizeof(guint8), NULL);
881     table_count = zbee_parse_uint(tree, hf_zbee_zdp_table_count, tvb, &offset, sizeof(guint8), NULL);
882
883     if (tree && table_count) {
884         ti = proto_tree_add_text(tree, tvb, offset, table_count*(sizeof(guint16)+sizeof(guint64)), "Discovery Cache");
885         field_tree = proto_item_add_subtree(ti, ett_zbee_zdp_cache);
886     }
887     for (i=0; i<table_count; i++) {
888         guint64 addr64 = tvb_get_letoh64(tvb, offset);
889         guint16 addr16 = tvb_get_letohs(tvb, offset+sizeof(guint64));
890
891         if (tree) {
892             proto_tree_add_text(tree, tvb, offset, sizeof(guint16)+sizeof(guint64), "{%s = 0x%04x}", print_eui64_oui(addr64), addr16);
893         }
894         offset += sizeof(guint16)+sizeof(guint64);
895     } /* for */
896
897     zbee_append_info(tree, pinfo, ", Status: %s", zdp_status_name(status));
898
899     /* Dump any leftover bytes. */
900     zdp_dump_excess(tvb, offset, pinfo, tree);
901 } /* dissect_zbee_zdp_rsp_mgmt_bind */
902
903 /*FUNCTION:------------------------------------------------------
904  *  NAME
905  *      dissect_zbee_zdp_rsp_mgmt_nwkupdate
906  *  DESCRIPTION
907  *      ZigBee Device Profile dissector for the nwk update notify.
908  *      Cluster ID = 0x8038.
909  *  PARAMETERS
910  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
911  *      packet_into *pinfo  - pointer to packet information fields
912  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
913  *  RETURNS
914  *      void
915  *---------------------------------------------------------------
916  */
917 void
918 dissect_zbee_zdp_rsp_mgmt_nwkupdate(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
919 {
920     guint       offset = 0;
921     guint       i, j;
922
923     guint8      status;
924     guint32     channels;
925     guint16     tx_total;
926     guint16     tx_fail;
927     guint8      channel_count;
928
929     status      = zdp_parse_status(tree, tvb, &offset);
930     channels    = zdp_parse_chanmask(tree, tvb, &offset);
931     tx_total    = zbee_parse_uint(tree, hf_zbee_zdp_tx_total, tvb, &offset, sizeof(guint16), NULL);
932     tx_fail     = zbee_parse_uint(tree, hf_zbee_zdp_tx_fail, tvb, &offset, sizeof(guint16), NULL);
933     channel_count     = zbee_parse_uint(tree, hf_zbee_zdp_channel_count, tvb, &offset, sizeof(guint8), NULL);
934
935     /* Display the channel list. */
936     for (i=0, j=0; i<(8*sizeof(guint32)); i++) {
937         guint8  energy;
938
939         if ( ! ((1<<i) & channels) ) {
940             /* Channel not scanned. */
941             continue;
942         }
943         if (j>=channel_count) {
944             /* Channel list has ended. */
945             break;
946         }
947         /* Get and display the channel energy. */
948         energy = tvb_get_guint8(tvb, offset);
949         if (tree) {
950             proto_tree_add_text(tree, tvb, offset, sizeof(guint8), "Channel %d Energy = 0x%02x", i, energy);
951         }
952         offset += sizeof(guint8);
953         /* Increment the number of channels we found energy values for. */
954         j++;
955     } /* for */
956
957     /* Dump any leftover bytes. */
958     zdp_dump_excess(tvb, offset, pinfo, tree);
959 } /* dissect_zbee_zdp_rsp_mgmt_nwkupdate */