epan/dissectors/pidl/ C99 drsuapi
[wireshark-sm.git] / epan / dissectors / packet-zbee-nwk.c
blobeda398f1485ec1a22f567d3007bec050de28f7e3
1 /* packet-zbee-nwk.c
2 * Dissector routines for the ZigBee Network Layer (NWK)
3 * By Owen Kirby <osk@exegin.com>
4 * Copyright 2009 Exegin Technologies Limited
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * SPDX-License-Identifier: GPL-2.0-or-later
13 /* Include Files */
14 #include "config.h"
17 #include <epan/packet.h>
18 #include <epan/exceptions.h>
19 #include <epan/prefs.h>
20 #include <epan/addr_resolv.h>
21 #include <epan/address_types.h>
22 #include <epan/expert.h>
23 #include <epan/proto_data.h>
24 #include <epan/conversation_table.h>
25 #include <epan/conversation_filter.h>
26 #include <epan/tap.h>
27 #include <wsutil/bits_ctz.h> /* for ws_ctz */
28 #include <wsutil/pint.h>
29 #include "packet-ieee802154.h"
30 #include "packet-zbee.h"
31 #include "packet-zbee-nwk.h"
32 #include "packet-zbee-aps.h" /* for ZBEE_APS_CMD_KEY_LENGTH */
33 #include "packet-zbee-zdp.h"
34 #include "packet-zbee-security.h"
35 #include "packet-zbee-tlv.h"
37 /*************************/
38 /* Function Declarations */
39 /*************************/
40 /* Dissector Routines */
41 static int dissect_zbee_nwk (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data);
42 static void dissect_zbee_nwk_cmd (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, zbee_nwk_packet* packet);
43 static int dissect_zbee_beacon (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data);
44 static int dissect_zbip_beacon (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data);
45 static int dissect_zbee_ie (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data);
46 static void dissect_ieee802154_zigbee_rejoin(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, unsigned *offset);
47 static void dissect_ieee802154_zigbee_txpower(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, unsigned *offset);
49 /* Command Dissector Helpers */
50 static unsigned dissect_zbee_nwk_route_req (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
51 zbee_nwk_packet * packet, unsigned offset);
52 static unsigned dissect_zbee_nwk_route_rep (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, uint8_t version);
53 static unsigned dissect_zbee_nwk_status (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset);
54 static unsigned dissect_zbee_nwk_leave (tvbuff_t *tvb, proto_tree *tree, unsigned offset);
55 static unsigned dissect_zbee_nwk_route_rec (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
56 zbee_nwk_packet * packet, unsigned offset);
57 static unsigned dissect_zbee_nwk_rejoin_req (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
58 zbee_nwk_packet * packet, unsigned offset);
59 static unsigned dissect_zbee_nwk_rejoin_resp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
60 zbee_nwk_packet * packet, unsigned offset);
61 static unsigned dissect_zbee_nwk_link_status(tvbuff_t *tvb, proto_tree *tree, unsigned offset);
62 static unsigned dissect_zbee_nwk_report (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset);
63 static unsigned dissect_zbee_nwk_update (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset);
64 static unsigned dissect_zbee_nwk_ed_timeout_request(tvbuff_t *tvb, proto_tree *tree, unsigned offset);
65 static unsigned dissect_zbee_nwk_ed_timeout_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset);
66 static unsigned dissect_zbee_nwk_link_pwr_delta(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset);
67 static unsigned dissect_zbee_nwk_commissioning_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
68 zbee_nwk_packet * packet, unsigned offset);
69 static unsigned dissect_zbee_nwk_commissioning_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
70 zbee_nwk_packet * packet, unsigned offset);
71 static void proto_init_zbee_nwk (void);
72 static void proto_cleanup_zbee_nwk(void);
73 void proto_register_zbee_nwk(void);
74 void proto_reg_handoff_zbee_nwk(void);
76 /********************/
77 /* Global Variables */
78 /********************/
79 static int proto_zbee_nwk;
80 static int proto_zbee_beacon;
81 static int proto_zbip_beacon;
82 static int proto_zbee_ie;
83 static int hf_zbee_nwk_fcf;
84 static int hf_zbee_nwk_frame_type;
85 static int hf_zbee_nwk_proto_version;
86 static int hf_zbee_nwk_discover_route;
87 static int hf_zbee_nwk_multicast;
88 static int hf_zbee_nwk_security;
89 static int hf_zbee_nwk_source_route;
90 static int hf_zbee_nwk_ext_dst;
91 static int hf_zbee_nwk_ext_src;
92 static int hf_zbee_nwk_end_device_initiator;
93 static int hf_zbee_nwk_dst;
94 static int hf_zbee_nwk_src;
95 static int hf_zbee_nwk_addr;
96 static int hf_zbee_nwk_radius;
97 static int hf_zbee_nwk_seqno;
98 static int hf_zbee_nwk_mcast;
99 static int hf_zbee_nwk_mcast_mode;
100 static int hf_zbee_nwk_mcast_radius;
101 static int hf_zbee_nwk_mcast_max_radius;
102 static int hf_zbee_nwk_dst64;
103 static int hf_zbee_nwk_src64;
104 static int hf_zbee_nwk_addr64;
105 static int hf_zbee_nwk_src64_origin;
106 static int hf_zbee_nwk_relay_count;
107 static int hf_zbee_nwk_relay_index;
108 static int hf_zbee_nwk_relay;
110 static int hf_zbee_nwk_cmd_id;
111 static int hf_zbee_nwk_cmd_addr;
112 static int hf_zbee_nwk_cmd_route_id;
113 static int hf_zbee_nwk_cmd_route_dest;
114 static int hf_zbee_nwk_cmd_route_orig;
115 static int hf_zbee_nwk_cmd_route_resp;
116 static int hf_zbee_nwk_cmd_route_dest_ext;
117 static int hf_zbee_nwk_cmd_route_orig_ext;
118 static int hf_zbee_nwk_cmd_route_resp_ext;
119 static int hf_zbee_nwk_cmd_route_cost;
120 static int hf_zbee_nwk_cmd_route_options;
121 static int hf_zbee_nwk_cmd_route_opt_repair;
122 static int hf_zbee_nwk_cmd_route_opt_multicast;
123 static int hf_zbee_nwk_cmd_route_opt_dest_ext;
124 static int hf_zbee_nwk_cmd_route_opt_resp_ext;
125 static int hf_zbee_nwk_cmd_route_opt_orig_ext;
126 static int hf_zbee_nwk_cmd_route_opt_many_to_one;
127 static int hf_zbee_nwk_cmd_nwk_status;
128 static int hf_zbee_nwk_cmd_nwk_status_command_id;
129 static int hf_zbee_nwk_cmd_leave_rejoin;
130 static int hf_zbee_nwk_cmd_leave_request;
131 static int hf_zbee_nwk_cmd_leave_children;
132 static int hf_zbee_nwk_cmd_relay_count;
133 static int hf_zbee_nwk_cmd_relay_device;
134 static int hf_zbee_nwk_cmd_cinfo;
135 static int hf_zbee_nwk_cmd_cinfo_alt_coord;
136 static int hf_zbee_nwk_cmd_cinfo_type;
137 static int hf_zbee_nwk_cmd_cinfo_power;
138 static int hf_zbee_nwk_cmd_cinfo_idle_rx;
139 static int hf_zbee_nwk_cmd_cinfo_security;
140 static int hf_zbee_nwk_cmd_cinfo_alloc;
141 static int hf_zbee_nwk_cmd_rejoin_status;
142 static int hf_zbee_nwk_cmd_link_last;
143 static int hf_zbee_nwk_cmd_link_first;
144 static int hf_zbee_nwk_cmd_link_count;
145 static int hf_zbee_nwk_cmd_link_address;
146 static int hf_zbee_nwk_cmd_link_incoming_cost;
147 static int hf_zbee_nwk_cmd_link_outgoing_cost;
148 static int hf_zbee_nwk_cmd_report_type;
149 static int hf_zbee_nwk_cmd_report_count;
150 static int hf_zbee_nwk_cmd_update_type;
151 static int hf_zbee_nwk_cmd_update_count;
152 static int hf_zbee_nwk_cmd_update_id;
153 static int hf_zbee_nwk_panid;
154 static int hf_zbee_zboss_nwk_cmd_key;
155 static int hf_zbee_nwk_cmd_epid;
156 static int hf_zbee_nwk_cmd_end_device_timeout_request_enum;
157 static int hf_zbee_nwk_cmd_end_device_configuration;
158 static int hf_zbee_nwk_cmd_end_device_timeout_resp_status;
159 static int hf_zbee_nwk_cmd_end_device_timeout_resp_parent_info;
160 static int hf_zbee_nwk_cmd_prnt_info_mac_data_poll_keepalive_supported;
161 static int hf_zbee_nwk_cmd_prnt_info_ed_to_req_keepalive_supported;
162 static int hf_zbee_nwk_cmd_prnt_info_power_negotiation_supported;
163 static int hf_zbee_nwk_cmd_link_pwr_list_count;
164 static int hf_zbee_nwk_cmd_link_pwr_type;
165 static int hf_zbee_nwk_cmd_link_pwr_device_address;
166 static int hf_zbee_nwk_cmd_link_pwr_power_delta;
167 static int hf_zbee_nwk_cmd_association_type;
169 /* ZigBee Beacons */
170 static int hf_zbee_beacon_protocol;
171 static int hf_zbee_beacon_stack_profile;
172 static int hf_zbee_beacon_version;
173 static int hf_zbee_beacon_router_capacity;
174 static int hf_zbee_beacon_depth;
175 static int hf_zbee_beacon_end_device_capacity;
176 static int hf_zbee_beacon_epid;
177 static int hf_zbee_beacon_tx_offset;
178 static int hf_zbee_beacon_update_id;
180 static int hf_zbip_beacon_allow_join;
181 static int hf_zbip_beacon_router_capacity;
182 static int hf_zbip_beacon_host_capacity;
183 static int hf_zbip_beacon_unsecure;
184 static int hf_zbip_beacon_network_id;
186 /* IEEE 802.15.4 IEs (Information Elements) */
187 static int hf_ieee802154_zigbee_ie;
188 static int hf_ieee802154_zigbee_ie_id;
189 static int hf_ieee802154_zigbee_ie_length;
190 static int hf_ieee802154_zigbee_ie_tx_power;
191 static int hf_ieee802154_zigbee_ie_source_addr;
193 static int hf_ieee802154_zigbee_rejoin_epid;
194 static int hf_ieee802154_zigbee_rejoin_source_addr;
196 static int ett_zbee_nwk;
197 static int ett_zbee_nwk_beacon;
198 static int ett_zbee_nwk_fcf;
199 static int ett_zbee_nwk_fcf_ext;
200 static int ett_zbee_nwk_mcast;
201 static int ett_zbee_nwk_route;
202 static int ett_zbee_nwk_cmd;
203 static int ett_zbee_nwk_cmd_options;
204 static int ett_zbee_nwk_cmd_cinfo;
205 static int ett_zbee_nwk_cmd_link;
206 static int ett_zbee_nwk_cmd_ed_to_rsp_prnt_info;
207 static int ett_zbee_nwk_cmd_link_pwr_struct;
208 static int ett_zbee_nwk_zigbee_ie_fields;
209 static int ett_zbee_nwk_ie_rejoin;
210 static int ett_zbee_nwk_header;
211 static int ett_zbee_nwk_header_ie;
212 static int ett_zbee_nwk_beacon_bitfield;
214 static expert_field ei_zbee_nwk_missing_payload;
216 static dissector_handle_t aps_handle;
217 static dissector_handle_t zbee_gp_handle;
219 static int zbee_nwk_address_type = -1;
221 static int zbee_nwk_tap;
223 /********************/
224 /* Field Names */
225 /********************/
226 /* Frame Types */
227 static const value_string zbee_nwk_frame_types[] = {
228 { ZBEE_NWK_FCF_DATA, "Data" },
229 { ZBEE_NWK_FCF_CMD, "Command" },
230 { ZBEE_NWK_FCF_INTERPAN,"Interpan" },
231 { 0, NULL }
234 /* Route Discovery Modes */
235 static const value_string zbee_nwk_discovery_modes[] = {
236 { ZBEE_NWK_FCF_DISCOVERY_SUPPRESS, "Suppress" },
237 { ZBEE_NWK_FCF_DISCOVERY_ENABLE, "Enable" },
238 { ZBEE_NWK_FCF_DISCOVERY_FORCE, "Force" },
239 { 0, NULL }
242 /* Command Names*/
243 static const value_string zbee_nwk_cmd_names[] = {
244 { ZBEE_NWK_CMD_ROUTE_REQ, "Route Request" },
245 { ZBEE_NWK_CMD_ROUTE_REPLY, "Route Reply" },
246 { ZBEE_NWK_CMD_NWK_STATUS, "Network Status" },
247 { ZBEE_NWK_CMD_LEAVE, "Leave" },
248 { ZBEE_NWK_CMD_ROUTE_RECORD, "Route Record" },
249 { ZBEE_NWK_CMD_REJOIN_REQ, "Rejoin Request" },
250 { ZBEE_NWK_CMD_REJOIN_RESP, "Rejoin Response" },
251 { ZBEE_NWK_CMD_LINK_STATUS, "Link Status" },
252 { ZBEE_NWK_CMD_NWK_REPORT, "Network Report" },
253 { ZBEE_NWK_CMD_NWK_UPDATE, "Network Update" },
254 { ZBEE_NWK_CMD_ED_TIMEOUT_REQUEST, "End Device Timeout Request" },
255 { ZBEE_NWK_CMD_ED_TIMEOUT_RESPONSE, "End Device Timeout Response" },
256 { ZBEE_NWK_CMD_LINK_PWR_DELTA, "Link Power Delta" },
257 { ZBEE_NWK_CMD_COMMISSIONING_REQUEST, "Network Commissioning Request" },
258 { ZBEE_NWK_CMD_COMMISSIONING_RESPONSE, "Network Commissioning Response" },
259 { 0, NULL }
262 /* Many-To-One Route Discovery Modes. */
263 static const value_string zbee_nwk_cmd_route_many_modes[] = {
264 { ZBEE_NWK_CMD_ROUTE_OPTION_MANY_NONE, "Not Many-to-One" },
265 { ZBEE_NWK_CMD_ROUTE_OPTION_MANY_REC, "With Source Routing" },
266 { ZBEE_NWK_CMD_ROUTE_OPTION_MANY_NOREC, "Without Source Routing" },
267 { 0, NULL }
270 /* Rejoin Status Codes */
271 static const value_string zbee_nwk_rejoin_codes[] = {
272 { IEEE802154_CMD_ASRSP_AS_SUCCESS, "Success" },
273 { IEEE802154_CMD_ASRSP_PAN_FULL, "PAN Full" },
274 { IEEE802154_CMD_ASRSP_PAN_DENIED, "PAN Access Denied" },
275 { 0, NULL }
278 /* Network Report Types */
279 static const value_string zbee_nwk_report_types[] = {
280 { ZBEE_NWK_CMD_NWK_REPORT_ID_PAN_CONFLICT, "PAN Identifier Conflict" },
281 { ZBEE_NWK_CMD_NWK_REPORT_ID_ZBOSS_KEY_TRACE, "ZBOSS key trace" },
282 { 0, NULL }
285 /* Network Update Types */
286 static const value_string zbee_nwk_update_types[] = {
287 { ZBEE_NWK_CMD_NWK_UPDATE_ID_PAN_UPDATE, "PAN Identifier Update" },
288 { 0, NULL }
291 /* Network Status Codes */
292 static const value_string zbee_nwk_status_codes[] = {
293 { ZBEE_NWK_STATUS_NO_ROUTE_AVAIL, "No Route Available" },
294 { ZBEE_NWK_STATUS_TREE_LINK_FAIL, "Tree Link Failure" },
295 { ZBEE_NWK_STATUS_NON_TREE_LINK_FAIL, "Non-tree Link Failure" },
296 { ZBEE_NWK_STATUS_LOW_BATTERY, "Low Battery" },
297 { ZBEE_NWK_STATUS_NO_ROUTING, "No Routing Capacity" },
298 { ZBEE_NWK_STATUS_NO_INDIRECT, "No Indirect Capacity" },
299 { ZBEE_NWK_STATUS_INDIRECT_EXPIRE, "Indirect Transaction Expiry" },
300 { ZBEE_NWK_STATUS_DEVICE_UNAVAIL, "Target Device Unavailable" },
301 { ZBEE_NWK_STATUS_ADDR_UNAVAIL, "Target Address Unallocated" },
302 { ZBEE_NWK_STATUS_PARENT_LINK_FAIL, "Parent Link Failure" },
303 { ZBEE_NWK_STATUS_VALIDATE_ROUTE, "Validate Route" },
304 { ZBEE_NWK_STATUS_SOURCE_ROUTE_FAIL, "Source Route Failure" },
305 { ZBEE_NWK_STATUS_MANY_TO_ONE_FAIL, "Many-to-One Route Failure" },
306 { ZBEE_NWK_STATUS_ADDRESS_CONFLICT, "Address Conflict" },
307 { ZBEE_NWK_STATUS_VERIFY_ADDRESS, "Verify Address" },
308 { ZBEE_NWK_STATUS_PANID_UPDATE, "PAN ID Update" },
309 { ZBEE_NWK_STATUS_ADDRESS_UPDATE, "Network Address Update" },
310 { ZBEE_NWK_STATUS_BAD_FRAME_COUNTER, "Bad Frame Counter" },
311 { ZBEE_NWK_STATUS_BAD_KEY_SEQNO, "Bad Key Sequence Number" },
312 { 0, NULL }
315 /* Stack Profile Values. */
316 static const value_string zbee_nwk_stack_profiles[] = {
317 { 0x00, "Network Specific" },
318 { 0x01, "ZigBee Home" },
319 { 0x02, "ZigBee PRO" },
320 { 0, NULL }
323 /* ED Requested Timeout Enumerated Values */
324 static const value_string zbee_nwk_end_device_timeout_request[] = {
325 { 0, "10 sec" },
326 { 1, "2 min" },
327 { 2, "4 min" },
328 { 3, "8 min" },
329 { 4, "16 min" },
330 { 5, "32 min" },
331 { 6, "64 min" },
332 { 7, "128 min" },
333 { 8, "256 min" },
334 { 9, "512 min" },
335 { 10, "1024 min" },
336 { 11, "2048 min" },
337 { 12, "4096 min" },
338 { 13, "8192 min" },
339 { 14, "16384 min" },
340 { 0, NULL }
344 /* End Device Timeout Response Status Codes */
345 static const value_string zbee_nwk_end_device_timeout_resp_status[] = {
346 { 0, "Success" },
347 { 1, "Incorrect value" },
348 { 0, NULL }
351 /* Names of IEEE 802.15.4 IEs (Information Elements) for ZigBee */
352 static const value_string ieee802154_zigbee_ie_names[] = {
353 { ZBEE_ZIGBEE_IE_REJOIN, "Rejoin" },
354 { ZBEE_ZIGBEE_IE_TX_POWER, "Tx Power" },
355 { ZBEE_ZIGBEE_IE_BEACON_PAYLOAD, "Extended Beacon Payload" },
356 { 0, NULL }
359 /* Stack Profile Values. */
360 static const value_string zbee_nwk_link_power_delta_types[] = {
361 { 0x00, "Notification" },
362 { 0x01, "Request" },
363 { 0x02, "Response" },
364 { 0x03, "Reserved" },
365 { 0, NULL }
368 static const value_string zbee_nwk_commissioning_types[] = {
369 { 0x00, "Initial Join with Key Negotiation" },
370 { 0x01, "Rejoin with Key Negotiation" },
371 { 0, NULL }
374 /* TODO: much of the following copied from ieee80154 dissector */
375 /*-------------------------------------
376 * Hash Tables and Lists
377 *-------------------------------------
379 ieee802154_map_tab_t zbee_nwk_map;
380 GHashTable *zbee_table_nwk_keyring;
381 GHashTable *zbee_table_link_keyring;
383 static int zbee_nwk_address_to_str(const address* addr, char *buf, int buf_len)
385 uint16_t zbee_nwk_addr = pletoh16(addr->data);
387 if ((zbee_nwk_addr == ZBEE_BCAST_ALL) || (zbee_nwk_addr == ZBEE_BCAST_ACTIVE) || (zbee_nwk_addr == ZBEE_BCAST_ROUTERS)) {
388 return (int)g_strlcpy(buf, "Broadcast", buf_len) + 1;
390 else {
391 return snprintf(buf, buf_len, "0x%04x", zbee_nwk_addr) + 1;
395 static int zbee_nwk_address_str_len(const address* addr _U_)
397 return sizeof("Broadcast");
400 static int zbee_nwk_address_len(void)
402 return sizeof(uint16_t);
406 *Extracts an integer sub-field from an int with a given mask
409 unsigned
410 zbee_get_bit_field(unsigned input, unsigned mask)
412 /* Sanity Check, don't want infinite loops. */
413 if (mask == 0) return 0;
414 /* Shift input and mask together. */
415 while (!(mask & 0x1)) {
416 input >>= 1;
417 mask >>=1;
418 } /* while */
419 return (input & mask);
420 } /* zbee_get_bit_field */
423 *Heuristic interpreter for the ZigBee network dissectors.
425 *@param tvb pointer to buffer containing raw packet.
426 *@param pinfo pointer to packet information fields
427 *@param tree pointer to data tree Wireshark uses to display packet.
428 *@return Boolean value, whether it handles the packet or not.
430 static bool
431 dissect_zbee_nwk_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
433 ieee802154_packet *packet = (ieee802154_packet *)data;
434 uint16_t fcf;
435 unsigned ver;
436 unsigned type;
438 /* All ZigBee frames must always have a 16-bit source and destination address. */
439 if (packet == NULL) return false;
441 /* If the frame type and version are not sane, then it's probably not ZigBee. */
442 fcf = tvb_get_letohs(tvb, 0);
443 ver = zbee_get_bit_field(fcf, ZBEE_NWK_FCF_VERSION);
444 type = zbee_get_bit_field(fcf, ZBEE_NWK_FCF_FRAME_TYPE);
445 if ((ver < ZBEE_VERSION_2004) || (ver > ZBEE_VERSION_2007)) return false;
446 if (!try_val_to_str(type, zbee_nwk_frame_types)) return false;
448 /* All interpan frames should originate from an extended address. */
449 if (type == ZBEE_NWK_FCF_INTERPAN) {
450 if (packet->src_addr_mode != IEEE802154_FCF_ADDR_EXT) return false;
452 /* All other ZigBee frames must have 16-bit source and destination addresses. */
453 else {
454 if (packet->src_addr_mode != IEEE802154_FCF_ADDR_SHORT) return false;
455 if (packet->dst_addr_mode != IEEE802154_FCF_ADDR_SHORT) return false;
458 /* Assume it's ZigBee */
459 dissect_zbee_nwk(tvb, pinfo, tree, packet);
460 return true;
461 } /* dissect_zbee_heur */
464 *ZigBee NWK packet dissection routine for 2006, 2007 and Pro stack versions.
466 *@param tvb pointer to buffer containing raw packet.
467 *@param pinfo pointer to packet information fields.
468 *@param tree pointer to data tree Wireshark uses to display packet.
469 *@param data raw packet private data.
472 static int
473 dissect_zbee_nwk_full(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
475 tvbuff_t *payload_tvb = NULL;
477 proto_item *proto_root;
478 proto_item *ti = NULL;
479 proto_tree *nwk_tree;
481 zbee_nwk_packet packet;
482 ieee802154_packet *ieee_packet;
484 unsigned offset = 0;
485 char *src_addr, *dst_addr;
487 uint16_t fcf;
489 ieee802154_short_addr addr16;
490 ieee802154_map_rec *map_rec;
491 ieee802154_hints_t *ieee_hints;
493 zbee_nwk_hints_t *nwk_hints;
494 bool unicast_src;
496 static int * const fcf_flags_2007[] = {
497 &hf_zbee_nwk_frame_type,
498 &hf_zbee_nwk_proto_version,
499 &hf_zbee_nwk_discover_route,
500 &hf_zbee_nwk_multicast,
501 &hf_zbee_nwk_security,
502 &hf_zbee_nwk_source_route,
503 &hf_zbee_nwk_ext_dst,
504 &hf_zbee_nwk_ext_src,
505 &hf_zbee_nwk_end_device_initiator,
506 NULL
509 static int * const fcf_flags[] = {
510 &hf_zbee_nwk_frame_type,
511 &hf_zbee_nwk_proto_version,
512 &hf_zbee_nwk_discover_route,
513 &hf_zbee_nwk_security,
514 NULL
517 /* Reject the packet if data is NULL */
518 if (data == NULL)
519 return 0;
520 ieee_packet = (ieee802154_packet *)data;
522 memset(&packet, 0, sizeof(packet));
524 /* Set up hint structures */
525 if (!pinfo->fd->visited) {
526 /* Allocate frame data with hints for upper layers */
527 nwk_hints = wmem_new0(wmem_file_scope(), zbee_nwk_hints_t);
528 p_add_proto_data(wmem_file_scope(), pinfo, proto_zbee_nwk, 0, nwk_hints);
529 } else {
530 /* Retrieve existing structure */
531 nwk_hints = (zbee_nwk_hints_t *)p_get_proto_data(wmem_file_scope(), pinfo, proto_zbee_nwk, 0);
534 ieee_hints = (ieee802154_hints_t *)p_get_proto_data(wmem_file_scope(), pinfo,
535 proto_get_id_by_filter_name(IEEE802154_PROTOABBREV_WPAN), 0);
537 /* Add ourself to the protocol column, clear the info column, and create the protocol tree. */
538 col_set_str(pinfo->cinfo, COL_PROTOCOL, "ZigBee");
539 col_clear(pinfo->cinfo, COL_INFO);
540 proto_root = proto_tree_add_item(tree, proto_zbee_nwk, tvb, offset, -1, ENC_NA);
541 nwk_tree = proto_item_add_subtree(proto_root, ett_zbee_nwk);
543 /* Get and parse the FCF */
544 fcf = tvb_get_letohs(tvb, offset);
545 packet.type = zbee_get_bit_field(fcf, ZBEE_NWK_FCF_FRAME_TYPE);
546 packet.version = zbee_get_bit_field(fcf, ZBEE_NWK_FCF_VERSION);
547 packet.discovery = zbee_get_bit_field(fcf, ZBEE_NWK_FCF_DISCOVER_ROUTE);
548 packet.security = zbee_get_bit_field(fcf, ZBEE_NWK_FCF_SECURITY);
549 packet.multicast = zbee_get_bit_field(fcf, ZBEE_NWK_FCF_MULTICAST);
550 packet.route = zbee_get_bit_field(fcf, ZBEE_NWK_FCF_SOURCE_ROUTE);
551 packet.ext_dst = zbee_get_bit_field(fcf, ZBEE_NWK_FCF_EXT_DEST);
552 packet.ext_src = zbee_get_bit_field(fcf, ZBEE_NWK_FCF_EXT_SOURCE);
554 /* Display the FCF. */
555 if (packet.version >= ZBEE_VERSION_2007) {
556 ti = proto_tree_add_bitmask(nwk_tree, tvb, offset, hf_zbee_nwk_fcf, ett_zbee_nwk_fcf, fcf_flags_2007, ENC_LITTLE_ENDIAN);
557 } else {
558 ti = proto_tree_add_bitmask(nwk_tree, tvb, offset, hf_zbee_nwk_fcf, ett_zbee_nwk_fcf, fcf_flags, ENC_LITTLE_ENDIAN);
560 proto_item_append_text(ti, " %s", val_to_str_const(packet.type, zbee_nwk_frame_types, "Unknown"));
561 offset += 2;
563 /* Add the frame type to the info column and protocol root. */
564 proto_item_append_text(proto_root, " %s", val_to_str_const(packet.type, zbee_nwk_frame_types, "Unknown Type"));
565 col_set_str(pinfo->cinfo, COL_INFO, val_to_str_const(packet.type, zbee_nwk_frame_types, "Reserved Frame Type"));
567 if (packet.type != ZBEE_NWK_FCF_INTERPAN) {
568 /* Get the destination address. */
569 packet.dst = tvb_get_letohs(tvb, offset);
571 set_address_tvb(&pinfo->net_dst, zbee_nwk_address_type, 2, tvb, offset);
572 copy_address_shallow(&pinfo->dst, &pinfo->net_dst);
573 dst_addr = address_to_str(pinfo->pool, &pinfo->dst);
575 proto_tree_add_uint(nwk_tree, hf_zbee_nwk_dst, tvb, offset, 2, packet.dst);
576 ti = proto_tree_add_uint(nwk_tree, hf_zbee_nwk_addr, tvb, offset, 2, packet.dst);
577 proto_item_set_generated(ti);
578 proto_item_set_hidden(ti);
579 offset += 2;
581 proto_item_append_text(proto_root, ", Dst: %s", dst_addr);
582 col_append_fstr(pinfo->cinfo, COL_INFO, ", Dst: %s", dst_addr);
584 /* Get the short nwk source address and pass it to upper layers */
585 packet.src = tvb_get_letohs(tvb, offset);
587 set_address_tvb(&pinfo->net_src, zbee_nwk_address_type, 2, tvb, offset);
588 copy_address_shallow(&pinfo->src, &pinfo->net_src);
589 src_addr = address_to_str(pinfo->pool, &pinfo->src);
591 if (nwk_hints)
592 nwk_hints->src = packet.src;
593 proto_tree_add_uint(nwk_tree, hf_zbee_nwk_src, tvb, offset, 2, packet.src);
594 ti = proto_tree_add_uint(nwk_tree, hf_zbee_nwk_addr, tvb, offset, 2, packet.src);
595 proto_item_set_generated(ti);
596 proto_item_set_hidden(ti);
597 offset += 2;
599 if ( (packet.src == ZBEE_BCAST_ALL)
600 || (packet.src == ZBEE_BCAST_ACTIVE)
601 || (packet.src == ZBEE_BCAST_ROUTERS)){
602 /* Source Broadcast doesn't make much sense. */
603 unicast_src = false;
605 else {
606 unicast_src = true;
609 proto_item_append_text(proto_root, ", Src: %s", src_addr);
610 col_append_fstr(pinfo->cinfo, COL_INFO, ", Src: %s", src_addr);
612 /* Get and display the radius. */
613 packet.radius = tvb_get_uint8(tvb, offset);
614 proto_tree_add_uint(nwk_tree, hf_zbee_nwk_radius, tvb, offset, 1, packet.radius);
615 offset += 1;
617 /* Get and display the sequence number. */
618 packet.seqno = tvb_get_uint8(tvb, offset);
619 proto_tree_add_uint(nwk_tree, hf_zbee_nwk_seqno, tvb, offset, 1, packet.seqno);
620 offset += 1;
622 /* Add the extended destination address (ZigBee 2006 and later). */
623 if ((packet.version >= ZBEE_VERSION_2007) && packet.ext_dst) {
624 packet.dst64 = tvb_get_letoh64(tvb, offset);
625 proto_tree_add_item(nwk_tree, hf_zbee_nwk_dst64, tvb, offset, 8, ENC_LITTLE_ENDIAN);
626 ti = proto_tree_add_eui64(nwk_tree, hf_zbee_nwk_addr64, tvb, offset, 8, packet.dst64);
627 proto_item_set_generated(ti);
628 proto_item_set_hidden(ti);
629 offset += 8;
632 /* Display the extended source address. (ZigBee 2006 and later). */
633 if (packet.version >= ZBEE_VERSION_2007) {
634 addr16.pan = ieee_packet->src_pan;
636 if (packet.ext_src) {
637 packet.src64 = tvb_get_letoh64(tvb, offset);
638 proto_tree_add_item(nwk_tree, hf_zbee_nwk_src64, tvb, offset, 8, ENC_LITTLE_ENDIAN);
639 ti = proto_tree_add_eui64(nwk_tree, hf_zbee_nwk_addr64, tvb, offset, 8, packet.src64);
640 proto_item_set_generated(ti);
641 proto_item_set_hidden(ti);
642 offset += 8;
644 if (!pinfo->fd->visited && nwk_hints) {
645 /* Provide hints to upper layers */
646 nwk_hints->src_pan = ieee_packet->src_pan;
648 /* Update nwk extended address hash table */
649 if ( unicast_src ) {
650 nwk_hints->map_rec = ieee802154_addr_update(&zbee_nwk_map,
651 packet.src, addr16.pan, packet.src64, pinfo->current_proto, pinfo->num);
655 else {
656 /* See if extended source info was previously sniffed */
657 if (!pinfo->fd->visited && nwk_hints) {
658 nwk_hints->src_pan = ieee_packet->src_pan;
659 addr16.addr = packet.src;
661 map_rec = (ieee802154_map_rec *) g_hash_table_lookup(zbee_nwk_map.short_table, &addr16);
662 if (map_rec) {
663 /* found a nwk mapping record */
664 nwk_hints->map_rec = map_rec;
666 else {
667 /* does ieee layer know? */
668 map_rec = (ieee802154_map_rec *) g_hash_table_lookup(ieee_packet->short_table, &addr16);
669 if (map_rec) nwk_hints->map_rec = map_rec;
671 } /* (!pinfo->fd->visited) */
672 else {
673 if (nwk_hints && nwk_hints->map_rec ) {
674 /* Display inferred source address info */
675 ti = proto_tree_add_eui64(nwk_tree, hf_zbee_nwk_src64, tvb, offset, 0,
676 nwk_hints->map_rec->addr64);
677 proto_item_set_generated(ti);
678 ti = proto_tree_add_eui64(nwk_tree, hf_zbee_nwk_addr64, tvb, offset, 0, nwk_hints->map_rec->addr64);
679 proto_item_set_generated(ti);
680 proto_item_set_hidden(ti);
682 if ( nwk_hints->map_rec->start_fnum ) {
683 ti = proto_tree_add_uint(nwk_tree, hf_zbee_nwk_src64_origin, tvb, 0, 0,
684 nwk_hints->map_rec->start_fnum);
686 else {
687 ti = proto_tree_add_uint_format_value(nwk_tree, hf_zbee_nwk_src64_origin, tvb, 0, 0, 0, "Pre-configured");
689 proto_item_set_generated(ti);
694 /* If ieee layer didn't know its extended source address, and nwk layer does, fill it in */
695 if (!pinfo->fd->visited) {
696 if ( (ieee_packet->src_addr_mode == IEEE802154_FCF_ADDR_SHORT) &&
697 ieee_hints && !ieee_hints->map_rec ) {
698 addr16.pan = ieee_packet->src_pan;
699 addr16.addr = ieee_packet->src16;
700 map_rec = (ieee802154_map_rec *) g_hash_table_lookup(zbee_nwk_map.short_table, &addr16);
702 if (map_rec) {
703 /* found a ieee mapping record */
704 ieee_hints->map_rec = map_rec;
707 } /* (!pinfo->fd->visited */
708 } /* (pinfo->zbee_stack_vers >= ZBEE_VERSION_2007) */
710 /* Add multicast control field (ZigBee 2006 and later). */
711 if ((packet.version >= ZBEE_VERSION_2007) && packet.multicast) {
712 static int * const multicast_flags[] = {
713 &hf_zbee_nwk_mcast_mode,
714 &hf_zbee_nwk_mcast_radius,
715 &hf_zbee_nwk_mcast_max_radius,
716 NULL
719 uint8_t mcast_control = tvb_get_uint8(tvb, offset);
720 packet.mcast_mode = zbee_get_bit_field(mcast_control, ZBEE_NWK_MCAST_MODE);
721 packet.mcast_radius = zbee_get_bit_field(mcast_control, ZBEE_NWK_MCAST_RADIUS);
722 packet.mcast_max_radius = zbee_get_bit_field(mcast_control, ZBEE_NWK_MCAST_MAX_RADIUS);
724 proto_tree_add_bitmask(nwk_tree, tvb, offset, hf_zbee_nwk_mcast, ett_zbee_nwk_mcast, multicast_flags, ENC_NA);
725 offset += 1;
728 /* Add the Source Route field. (ZigBee 2006 and later). */
729 if ((packet.version >= ZBEE_VERSION_2007) && packet.route) {
730 proto_tree *field_tree;
731 uint8_t relay_count;
732 uint16_t relay_addr;
733 unsigned i;
735 /* Create a subtree for the source route field. */
736 field_tree = proto_tree_add_subtree(nwk_tree, tvb, offset, 1, ett_zbee_nwk_route, &ti, "Source Route");
738 /* Get and display the relay count. */
739 relay_count = tvb_get_uint8(tvb, offset);
740 proto_tree_add_uint(field_tree, hf_zbee_nwk_relay_count, tvb, offset, 1, relay_count);
741 proto_item_append_text(ti, ", Length: %d", relay_count);
742 offset += 1;
744 /* Correct the length of the source route fields. */
745 proto_item_set_len(ti, 1 + relay_count*2);
747 /* Get and display the relay index. */
748 proto_tree_add_item(field_tree, hf_zbee_nwk_relay_index, tvb, offset, 1, ENC_NA);
749 offset += 1;
751 /* Get and display the relay list. */
752 for (i=0; i<relay_count; i++) {
753 relay_addr = tvb_get_letohs(tvb, offset);
754 proto_tree_add_uint_format(field_tree, hf_zbee_nwk_relay, tvb, offset, 2, relay_addr, "Relay %d: 0x%04x", i+1, relay_addr);
755 offset += 2;
756 } /* for */
758 } /* if not interpan */
761 * Ensure that the payload exists. There are no valid ZigBee network
762 * packets that have no payload.
764 if (offset >= tvb_captured_length(tvb)) {
765 /* Non-existent or truncated payload. */
766 expert_add_info(pinfo, proto_root, &ei_zbee_nwk_missing_payload);
767 return tvb_captured_length(tvb);
769 /* Payload is encrypted, attempt security operations. */
770 else if (packet.security) {
771 payload_tvb = dissect_zbee_secure(tvb, pinfo, nwk_tree, offset);
772 if (payload_tvb == NULL) {
773 /* If Payload_tvb is NULL, then the security dissector cleaned up. */
774 return tvb_captured_length(tvb);
777 /* Plaintext payload. */
778 else {
779 payload_tvb = tvb_new_subset_remaining(tvb, offset);
782 if (packet.type == ZBEE_NWK_FCF_CMD) {
783 /* Dissect the Network Command. */
784 dissect_zbee_nwk_cmd(payload_tvb, pinfo, nwk_tree, &packet);
786 else if (packet.type == ZBEE_NWK_FCF_DATA || packet.type == ZBEE_NWK_FCF_INTERPAN) {
787 /* Dissect the Network Payload (APS layer). */
788 call_dissector_with_data(aps_handle, payload_tvb, pinfo, tree, &packet);
790 else {
791 /* Invalid type. */
792 call_data_dissector(payload_tvb, pinfo, tree);
795 tap_queue_packet(zbee_nwk_tap, pinfo, NULL);
797 return tvb_captured_length(tvb);
798 } /* dissect_zbee_nwk */
801 *ZigBee packet dissection with proto version determination.
803 *@param tvb pointer to buffer containing raw packet.
804 *@param pinfo pointer to packet information fields.
805 *@param tree pointer to data tree Wireshark uses to display packet.
806 *@param data raw packet private data.
808 static int
809 dissect_zbee_nwk(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
811 uint8_t fcf0;
812 uint8_t proto_version;
814 fcf0 = tvb_get_uint8(tvb, 0);
815 proto_version = (fcf0 & ZBEE_NWK_FCF_VERSION) >> 2;
816 if (proto_version == ZBEE_VERSION_GREEN_POWER) {
817 call_dissector(zbee_gp_handle, tvb, pinfo, tree);
818 } else {
819 /* TODO: add check for FCF proto versions. */
820 dissect_zbee_nwk_full(tvb, pinfo, tree, data);
822 return tvb_captured_length(tvb);
826 *ZigBee Network command packet dissection routine for Wireshark.
828 *@param tvb pointer to buffer containing raw packet.
829 *@param pinfo pointer to packet information fields
830 *@param tree pointer to data tree Wireshark uses to display packet.
832 static void dissect_zbee_nwk_cmd(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, zbee_nwk_packet* packet)
834 proto_tree *cmd_tree;
835 proto_item *cmd_root;
837 unsigned offset=0;
838 uint8_t cmd_id = tvb_get_uint8(tvb, offset);
840 /* Create a subtree for this command. */
841 cmd_tree = proto_tree_add_subtree_format(tree, tvb, offset, -1, ett_zbee_nwk_cmd, &cmd_root, "Command Frame: %s",
842 val_to_str_const(cmd_id, zbee_nwk_cmd_names, "Unknown"));
844 /* Add the command ID. */
845 proto_tree_add_uint(cmd_tree, hf_zbee_nwk_cmd_id, tvb, offset, 1, cmd_id);
846 offset += 1;
848 /* Add the command name to the info column. */
849 col_set_str(pinfo->cinfo, COL_INFO, val_to_str_const(cmd_id, zbee_nwk_cmd_names, "Unknown Command"));
852 /* Handle the command. */
853 switch(cmd_id){
854 case ZBEE_NWK_CMD_ROUTE_REQ:
855 /* Route Request Command. */
856 offset = dissect_zbee_nwk_route_req(tvb, pinfo, cmd_tree, packet, offset);
857 break;
859 case ZBEE_NWK_CMD_ROUTE_REPLY:
860 /* Route Reply Command. */
861 offset = dissect_zbee_nwk_route_rep(tvb, pinfo, cmd_tree, offset, packet->version);
862 break;
864 case ZBEE_NWK_CMD_NWK_STATUS:
865 /* Network Status Command. */
866 offset = dissect_zbee_nwk_status(tvb, pinfo, cmd_tree, offset);
867 break;
869 case ZBEE_NWK_CMD_LEAVE:
870 /* Leave Command. */
871 offset = dissect_zbee_nwk_leave(tvb, cmd_tree, offset);
872 break;
874 case ZBEE_NWK_CMD_ROUTE_RECORD:
875 /* Route Record Command. */
876 offset = dissect_zbee_nwk_route_rec(tvb, pinfo, cmd_tree, packet, offset);
877 break;
879 case ZBEE_NWK_CMD_REJOIN_REQ:
880 /* Rejoin Request Command. */
881 offset = dissect_zbee_nwk_rejoin_req(tvb, pinfo, cmd_tree, packet, offset);
882 break;
884 case ZBEE_NWK_CMD_REJOIN_RESP:
885 /* Rejoin Response Command. */
886 offset = dissect_zbee_nwk_rejoin_resp(tvb, pinfo, cmd_tree, packet, offset);
887 break;
889 case ZBEE_NWK_CMD_LINK_STATUS:
890 /* Link Status Command. */
891 offset = dissect_zbee_nwk_link_status(tvb, cmd_tree, offset);
892 break;
894 case ZBEE_NWK_CMD_NWK_REPORT:
895 /* Network Report Command. */
896 offset = dissect_zbee_nwk_report(tvb, pinfo, cmd_tree, offset);
897 break;
899 case ZBEE_NWK_CMD_NWK_UPDATE:
900 /* Network Update Command. */
901 offset = dissect_zbee_nwk_update(tvb, pinfo, cmd_tree, offset);
902 break;
904 case ZBEE_NWK_CMD_ED_TIMEOUT_REQUEST:
905 /* Network End Device Timeout Request Command. */
906 offset = dissect_zbee_nwk_ed_timeout_request(tvb, cmd_tree, offset);
907 break;
909 case ZBEE_NWK_CMD_ED_TIMEOUT_RESPONSE:
910 /* Network End Device Timeout Response Command. */
911 offset = dissect_zbee_nwk_ed_timeout_response(tvb, pinfo, cmd_tree, offset);
912 break;
914 case ZBEE_NWK_CMD_LINK_PWR_DELTA:
915 offset = dissect_zbee_nwk_link_pwr_delta(tvb, pinfo, cmd_tree, offset);
916 break;
918 case ZBEE_NWK_CMD_COMMISSIONING_REQUEST:
919 /* Network Commissioning Request Command. */
920 offset = dissect_zbee_nwk_commissioning_request(tvb, pinfo, cmd_tree, packet, offset);
921 break;
923 case ZBEE_NWK_CMD_COMMISSIONING_RESPONSE:
924 /* Network Commissioning Response Command. */
925 offset = dissect_zbee_nwk_commissioning_response(tvb, pinfo, cmd_tree, packet, offset);
926 break;
928 default:
929 /* Just break out and let the overflow handler deal with the payload. */
930 break;
931 } /* switch */
933 /* Dissect any TLVs */
934 offset = dissect_zbee_tlvs(tvb, pinfo, tree, offset, NULL, ZBEE_TLV_SRC_TYPE_ZBEE_NWK, cmd_id);
936 /* There is excess data in the packet. */
937 if (offset < tvb_captured_length(tvb)) {
938 /* There are leftover bytes! */
939 tvbuff_t *leftover_tvb = tvb_new_subset_remaining(tvb, offset);
940 proto_tree *root;
942 /* Correct the length of the command tree. */
943 root = proto_tree_get_root(tree);
944 proto_item_set_len(cmd_root, offset);
946 /* Dump the leftover to the data dissector. */
947 call_data_dissector(leftover_tvb, pinfo, root);
949 } /* dissect_zbee_nwk_cmd */
952 *Helper dissector for the Route Request command.
954 *@param tvb pointer to buffer containing raw packet.
955 *@param pinfo pointer to packet information fields
956 *@param tree pointer to the command subtree.
957 *@param packet pointer to the network packet struct.
958 *@param offset into the tvb to begin dissection.
959 *@return offset after command dissection.
961 static unsigned
962 dissect_zbee_nwk_route_req(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, zbee_nwk_packet * packet, unsigned offset)
964 uint8_t route_options;
965 uint16_t dest_addr;
967 static int * const nwk_route_command_options_2007[] = {
968 &hf_zbee_nwk_cmd_route_opt_multicast,
969 &hf_zbee_nwk_cmd_route_opt_dest_ext,
970 &hf_zbee_nwk_cmd_route_opt_many_to_one,
971 NULL
974 static int * const nwk_route_command_options[] = {
975 &hf_zbee_nwk_cmd_route_opt_repair,
976 NULL
979 /* Get and display the route options field. */
980 route_options = tvb_get_uint8(tvb, offset);
981 if (packet->version >= ZBEE_VERSION_2007) {
982 proto_tree_add_bitmask(tree, tvb, offset, hf_zbee_nwk_cmd_route_options, ett_zbee_nwk_cmd_options, nwk_route_command_options_2007, ENC_NA);
983 } else {
984 proto_tree_add_bitmask(tree, tvb, offset, hf_zbee_nwk_cmd_route_options, ett_zbee_nwk_cmd_options, nwk_route_command_options, ENC_NA);
986 offset += 1;
988 /* Get and display the route request ID. */
989 proto_tree_add_item(tree, hf_zbee_nwk_cmd_route_id, tvb, offset, 1, ENC_NA);
990 offset += 1;
992 /* Get and display the destination address. */
993 dest_addr = tvb_get_letohs(tvb, offset);
994 proto_tree_add_uint(tree, hf_zbee_nwk_cmd_route_dest, tvb, offset, 2, dest_addr);
995 offset += 2;
997 /* Get and display the path cost. */
998 proto_tree_add_item(tree, hf_zbee_nwk_cmd_route_cost, tvb, offset, 1, ENC_NA);
999 offset += 1;
1001 /* Get and display the extended destination address. */
1002 if (route_options & ZBEE_NWK_CMD_ROUTE_OPTION_DEST_EXT) {
1003 proto_tree_add_item(tree, hf_zbee_nwk_cmd_route_dest_ext, tvb, offset, 8, ENC_LITTLE_ENDIAN);
1004 offset += 8;
1007 /* Update the info column. */
1008 if (route_options & ZBEE_NWK_CMD_ROUTE_OPTION_MANY_MASK) {
1009 col_clear(pinfo->cinfo, COL_INFO);
1010 col_append_str(pinfo->cinfo, COL_INFO, "Many-to-One Route Request");
1012 col_append_fstr(pinfo->cinfo, COL_INFO, ", Dst: 0x%04x, Src: 0x%04x", dest_addr, packet->src);
1014 /* Done */
1015 return offset;
1016 } /* dissect_zbee_nwk_route_req */
1019 *Helper dissector for the Route Reply command.
1021 *@param tvb pointer to buffer containing raw packet.
1022 *@param pinfo pointer to packet information fields
1023 *@param tree pointer to the command subtree.
1024 *@param offset into the tvb to begin dissection.
1025 *@return offset after command dissection.
1027 static unsigned
1028 dissect_zbee_nwk_route_rep(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, uint8_t version)
1030 uint8_t route_options;
1031 uint16_t orig_addr;
1032 uint16_t resp_addr;
1034 static int * const nwk_route_command_options_2007[] = {
1035 &hf_zbee_nwk_cmd_route_opt_multicast,
1036 &hf_zbee_nwk_cmd_route_opt_resp_ext,
1037 &hf_zbee_nwk_cmd_route_opt_orig_ext,
1038 NULL
1041 static int * const nwk_route_command_options[] = {
1042 &hf_zbee_nwk_cmd_route_opt_repair,
1043 NULL
1046 /* Get and display the route options field. */
1047 route_options = tvb_get_uint8(tvb, offset);
1048 if (version >= ZBEE_VERSION_2007) {
1049 proto_tree_add_bitmask(tree, tvb, offset, hf_zbee_nwk_cmd_route_options, ett_zbee_nwk_cmd_options, nwk_route_command_options_2007, ENC_NA);
1050 } else {
1051 proto_tree_add_bitmask(tree, tvb, offset, hf_zbee_nwk_cmd_route_options, ett_zbee_nwk_cmd_options, nwk_route_command_options, ENC_NA);
1053 offset += 1;
1055 /* Get and display the route request ID. */
1056 proto_tree_add_item(tree, hf_zbee_nwk_cmd_route_id, tvb, offset, 1, ENC_NA);
1057 offset += 1;
1059 /* Get and display the originator address. */
1060 orig_addr = tvb_get_letohs(tvb, offset);
1061 proto_tree_add_uint(tree, hf_zbee_nwk_cmd_route_orig, tvb, offset, 2, orig_addr);
1062 offset += 2;
1064 /* Get and display the responder address. */
1065 resp_addr = tvb_get_letohs(tvb, offset);
1066 proto_tree_add_uint(tree, hf_zbee_nwk_cmd_route_resp, tvb, offset, 2, resp_addr);
1067 offset += 2;
1069 /* Get and display the path cost. */
1070 proto_tree_add_item(tree, hf_zbee_nwk_cmd_route_cost, tvb, offset, 1, ENC_NA);
1071 offset += 1;
1073 /* Get and display the originator extended address. */
1074 if (route_options & ZBEE_NWK_CMD_ROUTE_OPTION_ORIG_EXT) {
1075 proto_tree_add_item(tree, hf_zbee_nwk_cmd_route_orig_ext, tvb, offset, 8, ENC_LITTLE_ENDIAN);
1076 offset += 8;
1079 /* Get and display the responder extended address. */
1080 if (route_options & ZBEE_NWK_CMD_ROUTE_OPTION_RESP_EXT) {
1081 proto_tree_add_item(tree, hf_zbee_nwk_cmd_route_resp_ext, tvb, offset, 8, ENC_LITTLE_ENDIAN);
1082 offset += 8;
1085 /* Update the info column. */
1086 col_append_fstr(pinfo->cinfo, COL_INFO, ", Responder: 0x%04x, Originator: 0x%04x", resp_addr, orig_addr);
1088 /* Done */
1089 return offset;
1090 } /* dissect_zbee_nwk_route_rep */
1093 *Helper dissector for the Network Status command.
1095 *@param tvb pointer to buffer containing raw packet.
1096 *@param pinfo pointer to packet information fields
1097 *@param tree pointer to the command subtree.
1098 *@param offset into the tvb to begin dissection.
1099 *@return offset after command dissection.
1101 static unsigned
1102 dissect_zbee_nwk_status(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset)
1104 uint8_t status_code;
1105 uint8_t command_id;
1106 uint16_t addr;
1108 /* Get and display the status code. */
1109 status_code = tvb_get_uint8(tvb, offset);
1110 proto_tree_add_uint(tree, hf_zbee_nwk_cmd_nwk_status, tvb, offset, 1, status_code);
1111 offset += 1;
1113 /* Get and display the destination address. */
1114 addr = tvb_get_letohs(tvb, offset);
1115 proto_tree_add_uint(tree, hf_zbee_nwk_cmd_route_dest, tvb, offset, 2, addr);
1116 offset += 2;
1118 /* Update the info column. */
1119 col_append_fstr(pinfo->cinfo, COL_INFO, ", 0x%04x: %s", addr, val_to_str_const(status_code, zbee_nwk_status_codes, "Unknown Status Code"));
1121 if (status_code == ZBEE_NWK_STATUS_UNKNOWN_COMMAND) {
1122 command_id = tvb_get_uint8(tvb, offset);
1123 proto_tree_add_uint(tree, hf_zbee_nwk_cmd_nwk_status_command_id, tvb, offset, 1, command_id);
1124 col_append_fstr(pinfo->cinfo, COL_INFO, ", Unknown Command ID 0x%02x (%s)", command_id,
1125 val_to_str_const(command_id, zbee_nwk_cmd_names, "Unknown ID"));
1126 offset++;
1129 /* Done */
1130 return offset;
1131 } /* dissect_zbee_nwk_status */
1134 *Helper dissector for the Leave command.
1136 *@param tvb pointer to buffer containing raw packet.
1137 *@param tree pointer to the command subtree.
1138 *@param offset into the tvb to begin dissection.
1139 *@return offset after command dissection.
1141 static unsigned
1142 dissect_zbee_nwk_leave(tvbuff_t *tvb, proto_tree *tree, unsigned offset)
1144 static int * const leave_options[] = {
1145 &hf_zbee_nwk_cmd_leave_rejoin,
1146 &hf_zbee_nwk_cmd_leave_request,
1147 &hf_zbee_nwk_cmd_leave_children,
1148 NULL
1151 /* Get and display the leave options. */
1152 proto_tree_add_bitmask_list(tree, tvb, offset, 1, leave_options, ENC_NA);
1153 offset += 1;
1155 /* Done */
1156 return offset;
1157 } /* dissect_zbee_nwk_leave */
1160 *Helper dissector for the Route Record command.
1162 *@param tvb pointer to buffer containing raw packet.
1163 *@param pinfo pointer to packet information fields
1164 *@param tree pointer to the command subtree.
1165 *@param packet pointer to the network packet struct.
1166 *@param offset into the tvb to begin dissection.
1167 *@return offset after command dissection.
1169 static unsigned
1170 dissect_zbee_nwk_route_rec(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, zbee_nwk_packet * packet, unsigned offset)
1172 uint8_t relay_count;
1173 uint16_t relay_addr;
1174 unsigned i;
1176 /* Get and display the relay count. */
1177 relay_count = tvb_get_uint8(tvb, offset);
1178 proto_tree_add_uint(tree, hf_zbee_nwk_cmd_relay_count, tvb, offset, 1, relay_count);
1179 offset += 1;
1181 /* Get and display the relay addresses. */
1182 for (i=0; i<relay_count; i++) {
1183 relay_addr = tvb_get_letohs(tvb, offset);
1184 proto_tree_add_uint_format(tree, hf_zbee_nwk_cmd_relay_device, tvb, offset, 2, relay_addr,
1185 "Relay Device %d: 0x%04x", i+1, relay_addr);
1186 offset += 2;
1187 } /* for */
1189 /* Update the info column. */
1190 col_append_fstr(pinfo->cinfo, COL_INFO, ", Dst: 0x%04x", packet->dst);
1193 /* Done */
1194 return offset;
1195 } /* dissect_zbee_nwk_route_rec */
1198 *Helper dissector for the Rejoin Request command.
1200 *@param tvb pointer to buffer containing raw packet.
1201 *@param pinfo pointer to packet information fields
1202 *@param tree pointer to the command subtree.
1203 *@param packet pointer to the network packet struct.
1204 *@param offset into the tvb to begin dissection.
1205 *@return offset after command dissection.
1207 static unsigned
1208 dissect_zbee_nwk_rejoin_req(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, zbee_nwk_packet * packet, unsigned offset)
1210 static int * const capabilities[] = {
1211 &hf_zbee_nwk_cmd_cinfo_alt_coord,
1212 &hf_zbee_nwk_cmd_cinfo_type,
1213 &hf_zbee_nwk_cmd_cinfo_power,
1214 &hf_zbee_nwk_cmd_cinfo_idle_rx,
1215 &hf_zbee_nwk_cmd_cinfo_security,
1216 &hf_zbee_nwk_cmd_cinfo_alloc,
1217 NULL
1220 proto_tree_add_bitmask(tree, tvb, offset, hf_zbee_nwk_cmd_cinfo, ett_zbee_nwk_cmd_cinfo, capabilities, ENC_NA);
1221 offset += 1;
1223 /* Update the info column.*/
1224 col_append_fstr(pinfo->cinfo, COL_INFO, ", Device: 0x%04x", packet->src);
1226 /* Done */
1227 return offset;
1228 } /* dissect_zbee_nwk_rejoin_req */
1231 *Helper dissector for the Rejoin Response command.
1233 *@param tvb pointer to buffer containing raw packet.
1234 *@param pinfo pointer to packet information fields
1235 *@param tree pointer to the command subtree.
1236 *@param packet pointer to the network packet struct.
1237 *@param offset into the tvb to begin dissection.
1238 *@return offset after command dissection.
1240 static unsigned
1241 dissect_zbee_nwk_rejoin_resp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, zbee_nwk_packet * packet _U_, unsigned offset)
1243 uint8_t status;
1244 uint16_t new_address;
1246 /* Get and display the short address. */
1247 new_address = tvb_get_uint16(tvb, offset, ENC_LITTLE_ENDIAN);
1248 proto_tree_add_item(tree, hf_zbee_nwk_cmd_addr, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1249 offset += 2;
1251 /* Get and display the rejoin status. */
1252 status = tvb_get_uint8(tvb, offset);
1253 proto_tree_add_uint(tree, hf_zbee_nwk_cmd_rejoin_status, tvb, offset, 1, status);
1254 offset += 1;
1256 /* Update the info column. */
1257 if (status == IEEE802154_CMD_ASRSP_AS_SUCCESS) {
1258 col_append_fstr(pinfo->cinfo, COL_INFO, ", New Address: 0x%04x", new_address);
1260 else {
1261 col_append_fstr(pinfo->cinfo, COL_INFO, ", %s", val_to_str_const(status, zbee_nwk_rejoin_codes, "Unknown Rejoin Response"));
1264 /* Done */
1265 return offset;
1266 } /* dissect_zbee_nwk_rejoin_resp */
1269 *Helper dissector for the Link Status command.
1271 *@param tvb pointer to buffer containing raw packet.
1272 *@param tree pointer to the command subtree.
1273 *@param offset into the tvb to begin dissection.
1274 *@return offset after command dissection.
1276 static unsigned
1277 dissect_zbee_nwk_link_status(tvbuff_t *tvb, proto_tree *tree, unsigned offset)
1279 uint8_t options;
1280 int i, link_count;
1281 proto_tree *subtree;
1282 static int * const link_options[] = {
1283 &hf_zbee_nwk_cmd_link_last,
1284 &hf_zbee_nwk_cmd_link_first,
1285 &hf_zbee_nwk_cmd_link_count,
1286 NULL
1289 /* Get and Display the link status options. */
1290 options = tvb_get_uint8(tvb, offset);
1291 link_count = options & ZBEE_NWK_CMD_LINK_OPTION_COUNT_MASK;
1292 proto_tree_add_bitmask_list(tree, tvb, offset, 1, link_options, ENC_NA);
1293 offset += 1;
1295 /* Get and Display the link status list. */
1296 for (i=0; i<link_count; i++) {
1297 /* Get the address and link status. */
1298 subtree = proto_tree_add_subtree_format(tree, tvb, offset, 3, ett_zbee_nwk_cmd_link, NULL, "Link %d", i+1);
1299 proto_tree_add_item(subtree, hf_zbee_nwk_cmd_link_address, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1300 proto_tree_add_item(subtree, hf_zbee_nwk_cmd_link_incoming_cost, tvb, offset+2, 1, ENC_NA);
1301 proto_tree_add_item(subtree, hf_zbee_nwk_cmd_link_outgoing_cost, tvb, offset+2, 1, ENC_NA);
1302 offset += (2+1);
1303 } /* for */
1305 /* TODO: Update the info column. */
1306 return offset;
1307 } /* dissect_zbee_nwk_link_status */
1310 *Helper dissector for the End Device Timeout Request command.
1312 *@param tvb pointer to buffer containing raw packet.
1313 *@param tree pointer to the command subtree.
1314 *@param offset into the tvb to begin dissection.
1315 *@return offset after command dissection.
1317 static unsigned
1318 dissect_zbee_nwk_ed_timeout_request(tvbuff_t *tvb, proto_tree *tree, unsigned offset)
1320 /* See 3.4.11 End Device Timeout Request Command */
1322 /* 3.4.11.3.1 Requested Timeout Field */
1323 proto_tree_add_item(tree, hf_zbee_nwk_cmd_end_device_timeout_request_enum, tvb, offset, 1, ENC_NA);
1324 offset++;
1326 /* 3.4.11.3.2 End Device Configuration Field */
1327 proto_tree_add_item(tree, hf_zbee_nwk_cmd_end_device_configuration, tvb, offset, 1, ENC_NA);
1328 offset++;
1330 return offset;
1331 } /* dissect_zbee_nwk_ed_timeout_request */
1334 *Helper dissector for the End Device Timeout Response command.
1336 *@param tvb pointer to buffer containing raw packet.
1337 *@param tree pointer to the command subtree.
1338 *@param offset into the tvb to begin dissection.
1339 *@return offset after command dissection.
1341 static unsigned
1342 dissect_zbee_nwk_ed_timeout_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset)
1344 static int * const end_device_parent_info[] = {
1345 &hf_zbee_nwk_cmd_prnt_info_mac_data_poll_keepalive_supported,
1346 &hf_zbee_nwk_cmd_prnt_info_ed_to_req_keepalive_supported,
1347 &hf_zbee_nwk_cmd_prnt_info_power_negotiation_supported,
1348 NULL
1350 unsigned status = tvb_get_uint8(tvb, offset);
1351 /* 3.4.12 End Device Timeout Response Command */
1353 /* status */
1354 proto_tree_add_item(tree, hf_zbee_nwk_cmd_end_device_timeout_resp_status, tvb, offset, 1, ENC_NA);
1355 offset++;
1357 /* Parent Information bitmask */
1358 proto_tree_add_bitmask(tree, tvb, offset, hf_zbee_nwk_cmd_end_device_timeout_resp_parent_info, ett_zbee_nwk_cmd_ed_to_rsp_prnt_info, end_device_parent_info, ENC_NA);
1359 offset++;
1361 proto_item_append_text(tree, ", %s", val_to_str_const(status, zbee_nwk_end_device_timeout_resp_status, "Unknown Status"));
1362 col_append_fstr(pinfo->cinfo, COL_INFO, ", %s", val_to_str_const(status, zbee_nwk_end_device_timeout_resp_status, "Unknown Status"));
1364 return offset;
1365 } /* dissect_zbee_nwk_ed_timeout_response */
1368 *Helper dissector for the Link Power Delta command.
1370 *@param tvb pointer to buffer containing raw packet.
1371 *@param tree pointer to the command subtree.
1372 *@param offset into the tvb to begin dissection.
1373 *@return offset after command dissection.
1375 static unsigned
1376 dissect_zbee_nwk_link_pwr_delta(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, unsigned offset)
1378 int i;
1379 int count;
1380 int delta;
1381 uint8_t type;
1382 uint16_t addr;
1383 proto_tree *subtree;
1385 type = tvb_get_uint8(tvb, offset) & ZBEE_NWK_CMD_NWK_LINK_PWR_DELTA_TYPE_MASK;
1386 proto_tree_add_item(tree, hf_zbee_nwk_cmd_link_pwr_type, tvb, offset, 1, ENC_NA);
1387 offset++;
1389 count = tvb_get_uint8(tvb, offset);
1390 proto_tree_add_item(tree, hf_zbee_nwk_cmd_link_pwr_list_count, tvb, offset, 1, ENC_NA);
1391 offset++;
1393 proto_item_append_text(tree, ": %s, Count %d", val_to_str_const(type, zbee_nwk_link_power_delta_types, "Unknown"), count);
1395 for (i=0; i<count; i++) {
1396 subtree = proto_tree_add_subtree(tree, tvb, count, 3, ett_zbee_nwk_cmd_link_pwr_struct, NULL, "Power Delta Structure");
1397 addr = tvb_get_uint16(tvb, offset, ENC_LITTLE_ENDIAN);
1398 proto_tree_add_item(subtree, hf_zbee_nwk_cmd_link_pwr_device_address, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1399 offset += 2;
1400 delta = (char)tvb_get_uint8(tvb, offset);
1401 proto_tree_add_item(subtree, hf_zbee_nwk_cmd_link_pwr_power_delta, tvb, offset, 1, ENC_NA);
1402 offset++;
1403 proto_item_append_text(subtree, ": Device Address 0x%04X, Power Delta %d dBm", addr, delta);
1405 return offset;
1409 *Helper dissector for the Network Commissioning Request command.
1411 *@param tvb pointer to buffer containing raw packet.
1412 *@param tree pointer to the command subtree.
1413 *@param offset into the tvb to begin dissection.
1414 *@return offset after command dissection.
1416 static unsigned
1417 dissect_zbee_nwk_commissioning_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, zbee_nwk_packet * packet, unsigned offset)
1419 /* See 3.4.14 Network Commissioning Request Command */
1421 static int * const capabilities[] = {
1422 &hf_zbee_nwk_cmd_cinfo_alt_coord,
1423 &hf_zbee_nwk_cmd_cinfo_type,
1424 &hf_zbee_nwk_cmd_cinfo_power,
1425 &hf_zbee_nwk_cmd_cinfo_idle_rx,
1426 &hf_zbee_nwk_cmd_cinfo_security,
1427 &hf_zbee_nwk_cmd_cinfo_alloc,
1428 NULL
1431 /* 3.4.14.3 Association Type */
1432 proto_tree_add_item(tree, hf_zbee_nwk_cmd_association_type, tvb, offset, 1, ENC_NA);
1433 offset += 1;
1435 proto_tree_add_bitmask(tree, tvb, offset, hf_zbee_nwk_cmd_cinfo, ett_zbee_nwk_cmd_cinfo, capabilities, ENC_NA);
1436 offset += 1;
1438 /* Update the info column.*/
1439 col_append_fstr(pinfo->cinfo, COL_INFO, ", Device: 0x%04x", packet->src);
1441 return offset;
1442 } /* dissect_zbee_nwk_commissioning_request */
1445 *Helper dissector for the Commissioning Response command.
1447 *@param tvb pointer to buffer containing raw packet.
1448 *@param tree pointer to the command subtree.
1449 *@param offset into the tvb to begin dissection.
1450 *@return offset after command dissection.
1452 static unsigned
1453 dissect_zbee_nwk_commissioning_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, zbee_nwk_packet * packet _U_, unsigned offset)
1455 uint8_t status;
1456 uint16_t new_address;
1458 /* Get and display the short address. */
1459 new_address = tvb_get_uint16(tvb, offset, ENC_LITTLE_ENDIAN);
1460 proto_tree_add_item(tree, hf_zbee_nwk_cmd_addr, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1461 offset += 2;
1463 /* Get and display the rejoin status. */
1464 status = tvb_get_uint8(tvb, offset);
1465 proto_tree_add_uint(tree, hf_zbee_nwk_cmd_rejoin_status, tvb, offset, 1, status);
1466 offset += 1;
1468 /* Update the info column. */
1469 if (status == IEEE802154_CMD_ASRSP_AS_SUCCESS) {
1470 col_append_fstr(pinfo->cinfo, COL_INFO, ", New Address: 0x%04x", new_address);
1472 else {
1473 col_append_fstr(pinfo->cinfo, COL_INFO, ", %s", val_to_str_const(status, zbee_nwk_rejoin_codes, "Unknown Commissioning Response"));
1476 return offset;
1477 } /* dissect_zbee_nwk_commissioning_response */
1480 *Helper dissector for the Network Report command.
1482 *@param tvb pointer to buffer containing raw packet.
1483 *@param pinfo pointer to packet information fields
1484 *@param tree pointer to the command subtree.
1485 *@param offset into the tvb to begin dissection.
1486 *@return offset after command dissection.
1488 static unsigned
1489 dissect_zbee_nwk_report(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset)
1491 uint8_t options;
1492 uint8_t report_type;
1493 int report_count;
1494 int i;
1496 /* Get and display the command options field. */
1497 options = tvb_get_uint8(tvb, offset);
1498 report_count = options & ZBEE_NWK_CMD_NWK_REPORT_COUNT_MASK;
1499 report_type = options & ZBEE_NWK_CMD_NWK_REPORT_ID_MASK;
1500 proto_tree_add_uint(tree, hf_zbee_nwk_cmd_report_type, tvb, offset, 1, report_type);
1501 proto_tree_add_uint(tree, hf_zbee_nwk_cmd_report_count, tvb, offset, 1, report_count);
1502 offset += 1;
1503 report_type >>= ws_ctz(ZBEE_NWK_CMD_NWK_REPORT_ID_MASK);
1505 /* Get and display the epid. */
1506 proto_tree_add_item(tree, hf_zbee_nwk_cmd_epid, tvb, offset, 8, ENC_LITTLE_ENDIAN);
1507 offset += 8;
1509 if (report_type == ZBEE_NWK_CMD_NWK_REPORT_ID_PAN_CONFLICT) {
1511 /* Report information contains a list of PANS with range of the sender. */
1512 for (i=0; i<report_count; i++) {
1513 proto_tree_add_item(tree, hf_zbee_nwk_panid, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1514 offset += 2;
1515 } /* for */
1517 if (report_type == ZBEE_NWK_CMD_NWK_REPORT_ID_ZBOSS_KEY_TRACE) {
1518 uint8_t key[ZBEE_APS_CMD_KEY_LENGTH];
1520 for (i=0; i<ZBEE_APS_CMD_KEY_LENGTH ; i++) {
1521 key[i] = tvb_get_uint8(tvb, offset+i);
1522 } /* for */
1523 proto_tree_add_item(tree, hf_zbee_zboss_nwk_cmd_key, tvb, offset, ZBEE_APS_CMD_KEY_LENGTH, ENC_NA);
1524 offset += ZBEE_APS_CMD_KEY_LENGTH;
1525 zbee_sec_add_key_to_keyring(pinfo, key);
1528 /* Update the info column. */
1529 col_append_fstr(pinfo->cinfo, COL_INFO, ", %s", val_to_str_const(report_type, zbee_nwk_report_types, "Unknown Report Type"));
1531 /* Done */
1532 return offset;
1533 } /* dissect_zbee_nwk_report */
1536 *Helper dissector for the Network Update command.
1538 *@param tvb pointer to buffer containing raw packet.
1539 *@param pinfo pointer to packet information fields
1540 *@param tree pointer to the command subtree.
1541 *@param offset into the tvb to begin dissection.
1542 *@return offset after command dissection.
1544 static unsigned
1545 dissect_zbee_nwk_update(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset)
1547 uint8_t options;
1548 uint8_t update_type;
1549 uint8_t update_id;
1550 int update_count;
1551 int i;
1553 /* Get and display the command options field. */
1554 options = tvb_get_uint8(tvb, offset);
1555 update_count = options & ZBEE_NWK_CMD_NWK_UPDATE_COUNT_MASK;
1556 update_type = options & ZBEE_NWK_CMD_NWK_UPDATE_ID_MASK;
1557 proto_tree_add_uint(tree, hf_zbee_nwk_cmd_update_type, tvb, offset, 1, update_type);
1558 proto_tree_add_uint(tree, hf_zbee_nwk_cmd_update_count, tvb, offset, 1, update_count);
1559 offset += 1;
1561 /* Get and display the epid. */
1562 proto_tree_add_item(tree, hf_zbee_nwk_cmd_epid, tvb, offset, 8, ENC_LITTLE_ENDIAN);
1563 offset += 8;
1565 /* Get and display the updateID. */
1566 update_id = tvb_get_uint8(tvb, offset);
1567 proto_tree_add_uint(tree, hf_zbee_nwk_cmd_update_id, tvb, offset, 1, update_id);
1568 offset += 1;
1570 if (update_type == ZBEE_NWK_CMD_NWK_UPDATE_ID_PAN_UPDATE) {
1572 /* Report information contains a list of PANS with range of the sender. */
1573 for (i=0; i<update_count; i++) {
1574 proto_tree_add_item(tree, hf_zbee_nwk_panid, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1575 offset += 2;
1576 } /* for */
1579 /* Update the info column. */
1580 col_append_fstr(pinfo->cinfo, COL_INFO, ", %s", val_to_str_const(update_type, zbee_nwk_update_types, "Unknown Update Type"));
1582 /* Done */
1583 return offset;
1584 } /* dissect_zbee_nwk_update */
1588 *Heuristic interpreter for the ZigBee PRO beacon dissectors.
1590 *@param tvb pointer to buffer containing raw packet.
1591 *@param pinfo pointer to packet information fields
1592 *@param tree pointer to data tree Wireshark uses to display packet.
1593 *@return Boolean value, whether it handles the packet or not.
1595 static bool
1596 dissect_zbee_beacon_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
1598 ieee802154_packet *packet = (ieee802154_packet *)data;
1600 /* All ZigBee frames must always have a 16-bit source address. */
1601 if (!packet) return false;
1602 if (packet->src_addr_mode != IEEE802154_FCF_ADDR_SHORT) return false;
1603 if (tvb_captured_length(tvb) == 0) return false;
1605 /* ZigBee beacons begin with a protocol identifier. */
1606 if (tvb_get_uint8(tvb, 0) != ZBEE_NWK_BEACON_PROTOCOL_ID) return false;
1607 dissect_zbee_beacon(tvb, pinfo, tree, packet);
1608 return true;
1609 } /* dissect_zbee_beacon_heur */
1612 *Dissector for Legacy ZigBee Beacon Payloads (prior to the Enhanced Beacon)
1614 *@param tvb pointer to buffer containing raw packet.
1615 *@param pinfo pointer to packet information fields
1616 *@param tree pointer to data tree Wireshark uses to display packet.
1618 static int dissect_zbee_beacon(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
1621 proto_item *beacon_root;
1622 proto_tree *beacon_tree;
1623 unsigned offset = 0;
1624 uint8_t version;
1625 uint32_t profile;
1627 static int * const beacon_fields[] = {
1628 &hf_zbee_beacon_stack_profile,
1629 &hf_zbee_beacon_version,
1630 &hf_zbee_beacon_router_capacity,
1631 &hf_zbee_beacon_depth,
1632 &hf_zbee_beacon_end_device_capacity,
1633 NULL
1636 /* Add ourself to the protocol column. */
1637 col_set_str(pinfo->cinfo, COL_PROTOCOL, "ZigBee");
1638 /* Create the tree for this beacon. */
1639 beacon_root = proto_tree_add_item(tree, proto_zbee_beacon, tvb, 0, -1, ENC_NA);
1640 beacon_tree = proto_item_add_subtree(beacon_root, ett_zbee_nwk_beacon);
1642 /* Get and display the protocol id, must be 0 on all ZigBee beacons. */
1643 proto_tree_add_item(beacon_tree, hf_zbee_beacon_protocol, tvb, offset, 1, ENC_NA);
1644 offset += 1;
1646 proto_tree_add_bitmask_text(beacon_tree, tvb, offset, 2, "Beacon: ", NULL , ett_zbee_nwk_beacon_bitfield, beacon_fields,
1647 ENC_LITTLE_ENDIAN, BMT_NO_INT|BMT_NO_TFS);
1649 /* Get and display the stack profile and protocol version. */
1650 version = (uint8_t)((tvb_get_uint16(tvb, offset, ENC_LITTLE_ENDIAN) & ZBEE_NWK_BEACON_PROTOCOL_VERSION) >> 4);
1651 profile = (uint32_t)(tvb_get_uint16(tvb, offset, ENC_LITTLE_ENDIAN) & ZBEE_NWK_BEACON_STACK_PROFILE);
1652 proto_item_append_text(beacon_root, ", %s", val_to_str_const(profile, zbee_nwk_stack_profiles, "Unknown Profile"));
1653 offset += 2;
1655 if (version >= ZBEE_VERSION_2007) {
1656 /* In ZigBee 2006 and later, the beacon contains an extended PAN ID. */
1657 proto_tree_add_item(beacon_tree, hf_zbee_beacon_epid, tvb, offset, 8, ENC_LITTLE_ENDIAN);
1658 col_append_fstr(pinfo->cinfo, COL_INFO, ", EPID: %s", eui64_to_display(pinfo->pool,
1659 tvb_get_uint64(tvb, offset, ENC_LITTLE_ENDIAN)));
1660 proto_item_append_text(beacon_root, ", EPID: %s", eui64_to_display(pinfo->pool,
1661 tvb_get_uint64(tvb, offset, ENC_LITTLE_ENDIAN)));
1662 offset += 8;
1665 * In ZigBee 2006 the Tx-Offset is optional, while in the 2007 and
1666 * later versions, the Tx-Offset is a required value. Since both 2006 and
1667 * and 2007 versions have the same protocol version (2), we should treat
1668 * the Tx-Offset as well as the update ID as optional elements
1670 if (tvb_bytes_exist(tvb, offset, 3)) {
1671 proto_tree_add_item(beacon_tree, hf_zbee_beacon_tx_offset, tvb, offset, 3, ENC_LITTLE_ENDIAN);
1672 offset += 3;
1674 /* Get and display the update ID. */
1675 if(tvb_captured_length_remaining(tvb, offset)) {
1676 proto_tree_add_item(beacon_tree, hf_zbee_beacon_update_id, tvb, offset, 1, ENC_NA);
1677 offset += 1;
1681 else if (tvb_bytes_exist(tvb, offset, 3)) {
1682 /* In ZigBee 2004, the Tx-Offset is an optional value. */
1683 proto_tree_add_item(beacon_tree, hf_zbee_beacon_tx_offset, tvb, offset, 3, ENC_LITTLE_ENDIAN);
1684 offset += 3;
1688 offset = dissect_zbee_tlvs(tvb, pinfo, beacon_tree, offset, data, ZBEE_TLV_SRC_TYPE_DEFAULT, 0);
1690 return offset;
1691 } /* dissect_zbee_beacon */
1694 *Heuristic interpreter for the ZigBee IP beacon dissectors.
1696 *@param tvb pointer to buffer containing raw packet.
1697 *@param pinfo pointer to packet information fields
1698 *@param tree pointer to data tree Wireshark uses to display packet.
1699 *@return Boolean value, whether it handles the packet or not.
1701 static bool
1702 dissect_zbip_beacon_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
1704 ieee802154_packet *packet = (ieee802154_packet *)data;
1706 /* All ZigBee frames must always have a 16-bit source address. */
1707 if (!packet) return false;
1708 if (packet->src_addr_mode != IEEE802154_FCF_ADDR_SHORT) return false;
1709 if (tvb_captured_length(tvb) == 0) return false;
1711 /* ZigBee beacons begin with a protocol identifier. */
1712 if (tvb_get_uint8(tvb, 0) != ZBEE_IP_BEACON_PROTOCOL_ID) return false;
1713 dissect_zbip_beacon(tvb, pinfo, tree, packet);
1714 return true;
1715 } /* dissect_zbip_beacon_heur */
1718 *Dissector for ZigBee IP beacons.
1720 *@param tvb pointer to buffer containing raw packet.
1721 *@param pinfo pointer to packet information fields
1722 *@param tree pointer to data tree Wireshark uses to display packet.
1724 static int dissect_zbip_beacon(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
1726 ieee802154_packet *packet = (ieee802154_packet *)data;
1728 proto_item *beacon_root;
1729 proto_tree *beacon_tree;
1730 unsigned offset = 0;
1731 uint8_t proto_id;
1732 char *ssid;
1734 /* Reject the packet if data is NULL */
1735 if (!packet) return 0;
1737 /* Add ourself to the protocol column. */
1738 col_set_str(pinfo->cinfo, COL_PROTOCOL, "ZigBee IP");
1739 /* Create the tree for this beacon. */
1740 beacon_root = proto_tree_add_item(tree, proto_zbip_beacon, tvb, 0, -1, ENC_NA);
1741 beacon_tree = proto_item_add_subtree(beacon_root, ett_zbee_nwk_beacon);
1743 /* Update the info column. */
1744 col_clear(pinfo->cinfo, COL_INFO);
1745 col_append_fstr(pinfo->cinfo, COL_INFO, "Beacon, Src: 0x%04x", packet->src16);
1747 /* Get and display the protocol id, must be 0x02 on all ZigBee beacons. */
1748 proto_id = tvb_get_uint8(tvb, offset);
1749 proto_tree_add_uint(beacon_tree, hf_zbee_beacon_protocol, tvb, offset, 1, proto_id);
1750 offset += 1;
1752 /* Get and display the beacon flags */
1753 proto_tree_add_item(beacon_tree, hf_zbip_beacon_allow_join, tvb, offset, 1, ENC_BIG_ENDIAN);
1754 proto_tree_add_item(beacon_tree, hf_zbip_beacon_router_capacity, tvb, offset, 1, ENC_BIG_ENDIAN);
1755 proto_tree_add_item(beacon_tree, hf_zbip_beacon_host_capacity, tvb, offset, 1, ENC_BIG_ENDIAN);
1756 proto_tree_add_item(beacon_tree, hf_zbip_beacon_unsecure, tvb, offset, 1, ENC_BIG_ENDIAN);
1757 offset += 1;
1759 /* Get and display the network ID. */
1760 proto_tree_add_item(beacon_tree, hf_zbip_beacon_network_id, tvb, offset, 16, ENC_ASCII);
1762 ssid = tvb_get_string_enc(pinfo->pool, tvb, offset, 16, ENC_ASCII|ENC_NA);
1763 col_append_fstr(pinfo->cinfo, COL_INFO, ", SSID: %s", ssid);
1764 offset += 16;
1766 offset = dissect_zbee_tlvs(tvb, pinfo, beacon_tree, offset, data, ZBEE_TLV_SRC_TYPE_DEFAULT, 0);
1768 /* Check for leftover bytes. */
1769 if (offset < tvb_captured_length(tvb)) {
1770 /* Bytes leftover! */
1771 tvbuff_t *leftover_tvb = tvb_new_subset_remaining(tvb, offset);
1772 proto_tree *root;
1774 /* Correct the length of the beacon tree. */
1775 root = proto_tree_get_root(tree);
1776 proto_item_set_len(beacon_root, offset);
1778 /* Dump the leftover to the data dissector. */
1779 call_data_dissector(leftover_tvb, pinfo, root);
1781 return tvb_captured_length(tvb);
1782 } /* dissect_zbip_beacon */
1785 *Subdissector command for ZigBee Specific IEs (Information Elements)
1787 *@param tvb pointer to buffer containing raw packet.
1788 *@param pinfo pointer to packet information fields (unused).
1789 *@param tree pointer to command subtree.
1790 *@param data pointer to the length of the payload IE.
1792 static int
1793 dissect_zbee_ie(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
1795 proto_tree *subtree;
1796 tvbuff_t *ie_tvb;
1797 uint16_t zigbee_ie;
1798 uint16_t id;
1799 uint16_t length;
1800 unsigned pie_length;
1801 unsigned offset = 0;
1803 static int * const fields[] = {
1804 &hf_ieee802154_zigbee_ie_id,
1805 &hf_ieee802154_zigbee_ie_length,
1806 NULL
1809 pie_length = *(int *)data;
1811 do {
1812 zigbee_ie = tvb_get_letohs(tvb, offset);
1813 id = (zigbee_ie & ZBEE_ZIGBEE_IE_ID_MASK) >> 6;
1814 length = zigbee_ie & ZBEE_ZIGBEE_IE_LENGTH_MASK;
1816 /* Create a subtree for this command frame. */
1817 subtree = proto_tree_add_subtree(tree, tvb, offset, 2+length, ett_zbee_nwk_header, NULL, "ZigBee IE");
1818 proto_item_append_text(subtree, ", %s, Length: %d", val_to_str_const(id, ieee802154_zigbee_ie_names, "Unknown"), length);
1820 proto_tree_add_bitmask(subtree, tvb, offset, hf_ieee802154_zigbee_ie,
1821 ett_zbee_nwk_zigbee_ie_fields, fields, ENC_LITTLE_ENDIAN);
1822 offset += 2;
1824 switch (id) {
1825 case ZBEE_ZIGBEE_IE_REJOIN:
1826 dissect_ieee802154_zigbee_rejoin(tvb, pinfo, subtree, &offset);
1827 break;
1829 case ZBEE_ZIGBEE_IE_TX_POWER:
1830 dissect_ieee802154_zigbee_txpower(tvb, pinfo, subtree, &offset);
1831 break;
1833 case ZBEE_ZIGBEE_IE_BEACON_PAYLOAD:
1834 ie_tvb = tvb_new_subset_length(tvb, offset, ZBEE_NWK_BEACON_LENGTH);
1835 offset += dissect_zbee_beacon(ie_tvb, pinfo, subtree, NULL); /* Legacy ZigBee Beacon */
1836 dissect_ieee802154_superframe(tvb, pinfo, subtree, &offset);
1837 proto_tree_add_item(subtree, hf_ieee802154_zigbee_ie_source_addr, tvb, offset, 2, ENC_NA);
1838 offset += 2;
1839 break;
1841 default:
1842 if (length > 0) { /* just use the data dissector */
1843 call_data_dissector(tvb, pinfo, tree);
1844 offset += length;
1846 break;
1848 } while (offset < pie_length);
1850 return tvb_captured_length(tvb);
1854 *Subdissector for the ZigBee specific TX Power IE (information element)
1856 *@param tvb pointer to buffer containing raw packet.
1857 *@param pinfo pointer to packet information fields (unused).
1858 *@param tree pointer to command subtree.
1859 *@param offset offset into the tvbuff to begin dissection.
1861 static void
1862 dissect_ieee802154_zigbee_txpower(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, unsigned *offset)
1864 int32_t txpower;
1866 txpower = (char)tvb_get_uint8(tvb, *offset); /* tx power is a signed byte */
1868 proto_tree_add_item_ret_int(tree, hf_ieee802154_zigbee_ie_tx_power, tvb, *offset, 1, ENC_NA, &txpower);
1869 proto_item_append_text(tree, ", TX Power %d dBm", txpower);
1871 *offset += 1;
1875 *Subdissector for the ZigBee specific Rejoin IE (information element)
1877 *@param tvb pointer to buffer containing raw packet.
1878 *@param pinfo pointer to packet information fields (unused).
1879 *@param tree pointer to command subtree.
1880 *@param offset offset into the tvbuff to begin dissection.
1882 static void
1883 dissect_ieee802154_zigbee_rejoin(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, unsigned *offset)
1885 proto_tree *subtree;
1887 subtree = proto_tree_add_subtree(tree, tvb, *offset, 10, ett_zbee_nwk_ie_rejoin, NULL, "ZigBee Rejoin");
1889 proto_tree_add_item(subtree, hf_ieee802154_zigbee_rejoin_epid, tvb, *offset, 8, ENC_LITTLE_ENDIAN);
1890 proto_item_append_text(tree, ", EPID %s", eui64_to_display(pinfo->pool,
1891 tvb_get_uint64(tvb, *offset, ENC_LITTLE_ENDIAN)));
1892 *offset += 8;
1894 proto_tree_add_item(subtree, hf_ieee802154_zigbee_rejoin_source_addr, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
1895 proto_item_append_text(tree, ", Src: 0x%04x",
1896 tvb_get_uint16(tvb, *offset, ENC_LITTLE_ENDIAN));
1897 *offset += 2;
1899 } /* dissect_ieee802154_zigbee_rejoin */
1901 static const char* zbee_nwk_conv_get_filter_type(conv_item_t* conv, conv_filter_type_e filter)
1903 if ((filter == CONV_FT_SRC_ADDRESS) && (conv->src_address.type == zbee_nwk_address_type))
1904 return "zbee_nwk.src";
1906 if ((filter == CONV_FT_DST_ADDRESS) && (conv->dst_address.type == zbee_nwk_address_type))
1907 return "zbee_nwk.dst";
1909 if ((filter == CONV_FT_ANY_ADDRESS) && (conv->src_address.type == zbee_nwk_address_type))
1910 return "zbee_nwk.addr";
1912 return CONV_FILTER_INVALID;
1915 static ct_dissector_info_t zbee_nwk_ct_dissector_info = {&zbee_nwk_conv_get_filter_type };
1917 static tap_packet_status zbee_nwk_conversation_packet(void *pct, packet_info *pinfo, epan_dissect_t *edt _U_, const void *vip _U_, tap_flags_t flags)
1919 conv_hash_t *hash = (conv_hash_t*)pct;
1920 hash->flags = flags;
1922 add_conversation_table_data(hash, &pinfo->net_src, &pinfo->net_dst, 0, 0, 1,
1923 pinfo->fd->pkt_len, &pinfo->rel_ts, &pinfo->abs_ts,
1924 &zbee_nwk_ct_dissector_info, CONVERSATION_NONE);
1926 return TAP_PACKET_REDRAW;
1929 static const char* zbee_nwk_endpoint_get_filter_type(endpoint_item_t* endpoint, conv_filter_type_e filter)
1931 if ((filter == CONV_FT_ANY_ADDRESS) && (endpoint->myaddress.type == zbee_nwk_address_type))
1933 return "zbee_nwk.addr";
1935 else
1937 return CONV_FILTER_INVALID;
1941 static et_dissector_info_t zbee_nwk_endpoint_dissector_info = {&zbee_nwk_endpoint_get_filter_type };
1943 static tap_packet_status zbee_nwk_endpoint_packet(void *pit, packet_info *pinfo, epan_dissect_t *edt _U_, const void *vip _U_, tap_flags_t flags)
1945 conv_hash_t *hash = (conv_hash_t*)pit;
1946 hash->flags = flags;
1948 /* Take two "add" passes per packet, adding for each direction, ensures that all
1949 packets are counted properly (even if address is sending to itself)
1950 XXX - this could probably be done more efficiently inside endpoint_table */
1951 add_endpoint_table_data(hash, &pinfo->net_src, 0, true, 1,
1952 pinfo->fd->pkt_len, &zbee_nwk_endpoint_dissector_info, ENDPOINT_NONE);
1953 add_endpoint_table_data(hash, &pinfo->net_dst, 0, false, 1,
1954 pinfo->fd->pkt_len, &zbee_nwk_endpoint_dissector_info, ENDPOINT_NONE);
1956 return TAP_PACKET_REDRAW;
1959 static bool zbee_nwk_filter_valid(packet_info *pinfo, void *user_data _U_)
1961 return proto_is_frame_protocol(pinfo->layers, "zbee_nwk");
1964 static char* zbee_nwk_build_filter(packet_info *pinfo, void *user_data _U_)
1966 return ws_strdup_printf("zbee_nwk.addr eq %s and zbee_nwk.addr eq %s",
1967 address_to_str(pinfo->pool, &pinfo->net_src),
1968 address_to_str(pinfo->pool, &pinfo->net_dst));
1972 *ZigBee protocol registration routine.
1975 void proto_register_zbee_nwk(void)
1977 static hf_register_info hf[] = {
1979 { &hf_zbee_nwk_fcf,
1980 { "Frame Control Field", "zbee_nwk.fcf", FT_UINT16, BASE_HEX, NULL,
1981 0x0, NULL, HFILL }},
1983 { &hf_zbee_nwk_frame_type,
1984 { "Frame Type", "zbee_nwk.frame_type", FT_UINT16, BASE_HEX, VALS(zbee_nwk_frame_types),
1985 ZBEE_NWK_FCF_FRAME_TYPE, NULL, HFILL }},
1987 { &hf_zbee_nwk_proto_version,
1988 { "Protocol Version", "zbee_nwk.proto_version", FT_UINT16, BASE_DEC, NULL, ZBEE_NWK_FCF_VERSION,
1989 NULL, HFILL }},
1991 { &hf_zbee_nwk_discover_route,
1992 { "Discover Route", "zbee_nwk.discovery", FT_UINT16, BASE_HEX, VALS(zbee_nwk_discovery_modes),
1993 ZBEE_NWK_FCF_DISCOVER_ROUTE,
1994 "Determines how route discovery may be handled, if at all.", HFILL }},
1996 { &hf_zbee_nwk_multicast,
1997 { "Multicast", "zbee_nwk.multicast", FT_BOOLEAN, 16, NULL, ZBEE_NWK_FCF_MULTICAST,
1998 NULL, HFILL }},
2000 { &hf_zbee_nwk_security,
2001 { "Security", "zbee_nwk.security", FT_BOOLEAN, 16, NULL, ZBEE_NWK_FCF_SECURITY,
2002 "Whether or not security operations are performed on the network payload.", HFILL }},
2004 { &hf_zbee_nwk_source_route,
2005 { "Source Route", "zbee_nwk.src_route", FT_BOOLEAN, 16, NULL, ZBEE_NWK_FCF_SOURCE_ROUTE,
2006 NULL, HFILL }},
2008 { &hf_zbee_nwk_ext_dst,
2009 { "Destination", "zbee_nwk.ext_dst", FT_BOOLEAN, 16, NULL, ZBEE_NWK_FCF_EXT_DEST,
2010 NULL, HFILL }},
2012 { &hf_zbee_nwk_ext_src,
2013 { "Extended Source", "zbee_nwk.ext_src", FT_BOOLEAN, 16, NULL, ZBEE_NWK_FCF_EXT_SOURCE,
2014 NULL, HFILL }},
2016 { &hf_zbee_nwk_end_device_initiator,
2017 { "End Device Initiator", "zbee_nwk.end_device_initiator", FT_BOOLEAN, 16, NULL, ZBEE_NWK_FCF_END_DEVICE_INITIATOR,
2018 NULL, HFILL }},
2020 { &hf_zbee_nwk_dst,
2021 { "Destination", "zbee_nwk.dst", FT_UINT16, BASE_HEX, NULL, 0x0,
2022 NULL, HFILL }},
2024 { &hf_zbee_nwk_src,
2025 { "Source", "zbee_nwk.src", FT_UINT16, BASE_HEX, NULL, 0x0,
2026 NULL, HFILL }},
2028 { &hf_zbee_nwk_addr,
2029 { "Address", "zbee_nwk.addr", FT_UINT16, BASE_HEX, NULL, 0x0,
2030 NULL, HFILL }},
2032 { &hf_zbee_nwk_radius,
2033 { "Radius", "zbee_nwk.radius", FT_UINT8, BASE_DEC, NULL, 0x0,
2034 "Number of hops remaining for a range-limited broadcast packet.", HFILL }},
2036 { &hf_zbee_nwk_seqno,
2037 { "Sequence Number", "zbee_nwk.seqno", FT_UINT8, BASE_DEC, NULL, 0x0,
2038 NULL, HFILL }},
2040 { &hf_zbee_nwk_mcast,
2041 { "Multicast Control Field", "zbee_nwk.multicast.cf", FT_UINT8, BASE_HEX, NULL, 0x0,
2042 NULL, HFILL }},
2044 { &hf_zbee_nwk_mcast_mode,
2045 { "Multicast Mode", "zbee_nwk.multicast.mode", FT_UINT8, BASE_DEC, NULL, ZBEE_NWK_MCAST_MODE,
2046 "Controls whether this packet is permitted to be routed through non-members of the multicast group.",
2047 HFILL }},
2049 { &hf_zbee_nwk_mcast_radius,
2050 { "Non-Member Radius", "zbee_nwk.multicast.radius", FT_UINT8, BASE_DEC, NULL, ZBEE_NWK_MCAST_RADIUS,
2051 "Limits the range of multicast packets when being routed through non-members.", HFILL }},
2053 { &hf_zbee_nwk_mcast_max_radius,
2054 { "Max Non-Member Radius", "zbee_nwk.multicast.max_radius", FT_UINT8, BASE_DEC, NULL,
2055 ZBEE_NWK_MCAST_MAX_RADIUS, NULL, HFILL }},
2057 { &hf_zbee_nwk_dst64,
2058 { "Destination", "zbee_nwk.dst64", FT_EUI64, BASE_NONE, NULL, 0x0,
2059 NULL, HFILL }},
2061 { &hf_zbee_nwk_src64,
2062 { "Extended Source", "zbee_nwk.src64", FT_EUI64, BASE_NONE, NULL, 0x0,
2063 NULL, HFILL }},
2065 { &hf_zbee_nwk_addr64,
2066 { "Extended Address", "zbee_nwk.addr64", FT_EUI64, BASE_NONE, NULL, 0x0,
2067 NULL, HFILL }},
2069 { &hf_zbee_nwk_src64_origin,
2070 { "Origin", "zbee_nwk.src64.origin", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
2071 NULL, HFILL }},
2073 { &hf_zbee_nwk_relay_count,
2074 { "Relay Count", "zbee_nwk.relay.count", FT_UINT8, BASE_DEC, NULL, 0x0,
2075 "Number of entries in the relay list.", HFILL }},
2077 { &hf_zbee_nwk_relay_index,
2078 { "Relay Index", "zbee_nwk.relay.index", FT_UINT8, BASE_DEC, NULL, 0x0,
2079 "Number of relays required to route to the source device.", HFILL }},
2081 { &hf_zbee_nwk_relay,
2082 { "Relay", "zbee_nwk.relay", FT_UINT16, BASE_DEC, NULL, 0x0,
2083 NULL, HFILL }},
2085 { &hf_zbee_nwk_cmd_id,
2086 { "Command Identifier", "zbee_nwk.cmd.id", FT_UINT8, BASE_HEX, VALS(zbee_nwk_cmd_names), 0x0,
2087 NULL, HFILL }},
2089 { &hf_zbee_nwk_cmd_addr,
2090 { "Address", "zbee_nwk.cmd.addr", FT_UINT16, BASE_HEX, NULL, 0x0,
2091 NULL, HFILL }},
2093 { &hf_zbee_nwk_cmd_route_id,
2094 { "Route ID", "zbee_nwk.cmd.route.id", FT_UINT8, BASE_DEC, NULL, 0x0,
2095 "A sequence number for routing commands.", HFILL }},
2097 { &hf_zbee_nwk_cmd_route_dest,
2098 { "Destination", "zbee_nwk.cmd.route.dest", FT_UINT16, BASE_HEX, NULL, 0x0,
2099 NULL, HFILL }},
2101 { &hf_zbee_nwk_cmd_route_orig,
2102 { "Originator", "zbee_nwk.cmd.route.orig", FT_UINT16, BASE_HEX, NULL, 0x0,
2103 NULL, HFILL }},
2105 { &hf_zbee_nwk_cmd_route_resp,
2106 { "Responder", "zbee_nwk.cmd.route.resp", FT_UINT16, BASE_HEX, NULL, 0x0,
2107 NULL, HFILL }},
2109 { &hf_zbee_nwk_cmd_route_dest_ext,
2110 { "Extended Destination", "zbee_nwk.cmd.route.dest_ext", FT_EUI64, BASE_NONE, NULL, 0x0,
2111 NULL, HFILL }},
2113 { &hf_zbee_nwk_cmd_route_orig_ext,
2114 { "Extended Originator", "zbee_nwk.cmd.route.orig_ext", FT_EUI64, BASE_NONE, NULL, 0x0,
2115 NULL, HFILL }},
2117 { &hf_zbee_nwk_cmd_route_resp_ext,
2118 { "Extended Responder", "zbee_nwk.cmd.route.resp_ext", FT_EUI64, BASE_NONE, NULL, 0x0,
2119 NULL, HFILL }},
2121 { &hf_zbee_nwk_cmd_route_cost,
2122 { "Path Cost", "zbee_nwk.cmd.route.cost", FT_UINT8, BASE_DEC, NULL, 0x0,
2123 "A value specifying the efficiency of this route.", HFILL }},
2125 { &hf_zbee_nwk_cmd_route_options,
2126 { "Command Options", "zbee_nwk.cmd.route.opts", FT_UINT8, BASE_HEX, NULL, 0x0,
2127 NULL, HFILL }},
2129 { &hf_zbee_nwk_cmd_route_opt_repair,
2130 { "Route Repair", "zbee_nwk.cmd.route.opts.repair", FT_BOOLEAN, 8, NULL,
2131 ZBEE_NWK_CMD_ROUTE_OPTION_REPAIR,
2132 "Flag identifying whether the route request command was to repair a failed route.", HFILL }},
2134 { &hf_zbee_nwk_cmd_route_opt_multicast,
2135 { "Multicast", "zbee_nwk.cmd.route.opts.mcast", FT_BOOLEAN, 8, NULL,
2136 ZBEE_NWK_CMD_ROUTE_OPTION_MCAST,
2137 "Flag identifying this as a multicast route request.", HFILL }},
2139 { &hf_zbee_nwk_cmd_route_opt_dest_ext,
2140 { "Extended Destination", "zbee_nwk.cmd.route.opts.dest_ext", FT_BOOLEAN, 8, NULL,
2141 ZBEE_NWK_CMD_ROUTE_OPTION_DEST_EXT, NULL, HFILL }},
2143 { &hf_zbee_nwk_cmd_route_opt_resp_ext,
2144 { "Extended Responder", "zbee_nwk.cmd.route.opts.resp_ext", FT_BOOLEAN, 8, NULL,
2145 ZBEE_NWK_CMD_ROUTE_OPTION_RESP_EXT, NULL, HFILL }},
2147 { &hf_zbee_nwk_cmd_route_opt_orig_ext,
2148 { "Extended Originator", "zbee_nwk.cmd.route.opts.orig_ext", FT_BOOLEAN, 8, NULL,
2149 ZBEE_NWK_CMD_ROUTE_OPTION_ORIG_EXT, NULL, HFILL }},
2151 { &hf_zbee_nwk_cmd_route_opt_many_to_one,
2152 { "Many-to-One Discovery", "zbee_nwk.cmd.route.opts.many2one", FT_UINT8, BASE_HEX,
2153 VALS(zbee_nwk_cmd_route_many_modes), ZBEE_NWK_CMD_ROUTE_OPTION_MANY_MASK,
2154 NULL, HFILL }},
2156 { &hf_zbee_nwk_cmd_nwk_status,
2157 { "Status Code", "zbee_nwk.cmd.status", FT_UINT8, BASE_HEX, VALS(zbee_nwk_status_codes), 0x0,
2158 NULL, HFILL }},
2160 { &hf_zbee_nwk_cmd_nwk_status_command_id,
2161 { "Unknown Command ID", "zbee_nwk.cmd.status.unknown_command_id", FT_UINT8, BASE_HEX,
2162 VALS(zbee_nwk_cmd_names), 0x0, NULL, HFILL }},
2164 { &hf_zbee_nwk_cmd_leave_rejoin,
2165 { "Rejoin", "zbee_nwk.cmd.leave.rejoin", FT_BOOLEAN, 8, NULL,
2166 ZBEE_NWK_CMD_LEAVE_OPTION_REJOIN, "Flag instructing the device to rejoin the network.", HFILL }},
2168 { &hf_zbee_nwk_cmd_leave_request,
2169 { "Request", "zbee_nwk.cmd.leave.request", FT_BOOLEAN, 8, NULL,
2170 ZBEE_NWK_CMD_LEAVE_OPTION_REQUEST,
2171 "Flag identifying the direction of this command. 1=Request, 0=Indication", HFILL }},
2173 { &hf_zbee_nwk_cmd_leave_children,
2174 { "Remove Children", "zbee_nwk.cmd.leave.children", FT_BOOLEAN, 8, NULL,
2175 ZBEE_NWK_CMD_LEAVE_OPTION_CHILDREN,
2176 "Flag instructing the device to remove its children in addition to itself.", HFILL }},
2178 { &hf_zbee_nwk_cmd_relay_count,
2179 { "Relay Count", "zbee_nwk.cmd.relay_count", FT_UINT8, BASE_DEC, NULL, 0x0,
2180 "Number of relays required to route to the destination.", HFILL }},
2182 { &hf_zbee_nwk_cmd_relay_device,
2183 { "Relay Device", "zbee_nwk.cmd.relay_device", FT_UINT16, BASE_HEX, NULL, 0x0,
2184 NULL, HFILL }},
2186 { &hf_zbee_nwk_cmd_cinfo,
2187 { "Capability Information", "zbee_nwk.cmd.cinfo", FT_UINT8, BASE_HEX, NULL,
2188 0x0, NULL, HFILL }},
2190 { &hf_zbee_nwk_cmd_cinfo_alt_coord,
2191 { "Alternate Coordinator", "zbee_nwk.cmd.cinfo.alt_coord", FT_BOOLEAN, 8, NULL,
2192 IEEE802154_CMD_CINFO_ALT_PAN_COORD,
2193 "Indicates that the device is able to operate as a PAN coordinator.", HFILL }},
2195 { &hf_zbee_nwk_cmd_cinfo_type,
2196 { "Full-Function Device", "zbee_nwk.cmd.cinfo.ffd", FT_BOOLEAN, 8, NULL,
2197 IEEE802154_CMD_CINFO_DEVICE_TYPE, NULL, HFILL }},
2199 { &hf_zbee_nwk_cmd_cinfo_power,
2200 { "AC Power", "zbee_nwk.cmd.cinfo.power", FT_BOOLEAN, 8, NULL,
2201 IEEE802154_CMD_CINFO_POWER_SRC, "Indicates this device is using AC/Mains power.", HFILL }},
2203 { &hf_zbee_nwk_cmd_cinfo_idle_rx,
2204 { "Rx On When Idle", "zbee_nwk.cmd.cinfo.on_idle", FT_BOOLEAN, 8, NULL,
2205 IEEE802154_CMD_CINFO_IDLE_RX,
2206 "Indicates the receiver is active when the device is idle.", HFILL }},
2208 { &hf_zbee_nwk_cmd_cinfo_security,
2209 { "Security Capability", "zbee_nwk.cmd.cinfo.security", FT_BOOLEAN, 8, NULL,
2210 IEEE802154_CMD_CINFO_SEC_CAPABLE,
2211 "Indicates this device is capable of performing encryption/decryption.", HFILL }},
2213 { &hf_zbee_nwk_cmd_cinfo_alloc,
2214 { "Allocate Short Address", "zbee_nwk.cmd.cinfo.alloc", FT_BOOLEAN, 8, NULL,
2215 IEEE802154_CMD_CINFO_ALLOC_ADDR,
2216 "Flag requesting the parent to allocate a short address for this device.", HFILL }},
2218 { &hf_zbee_nwk_cmd_rejoin_status,
2219 { "Status", "zbee_nwk.cmd.rejoin_status", FT_UINT8, BASE_HEX,
2220 VALS(zbee_nwk_rejoin_codes), 0x0, NULL, HFILL }},
2222 { &hf_zbee_nwk_cmd_link_last,
2223 { "Last Frame", "zbee_nwk.cmd.link.last", FT_BOOLEAN, 8, NULL,
2224 ZBEE_NWK_CMD_LINK_OPTION_LAST_FRAME,
2225 "Flag indicating the last in a series of link status commands.", HFILL }},
2227 { &hf_zbee_nwk_cmd_link_first,
2228 { "First Frame", "zbee_nwk.cmd.link.first", FT_BOOLEAN, 8, NULL,
2229 ZBEE_NWK_CMD_LINK_OPTION_FIRST_FRAME,
2230 "Flag indicating the first in a series of link status commands.", HFILL }},
2232 { &hf_zbee_nwk_cmd_link_count,
2233 { "Link Status Count", "zbee_nwk.cmd.link.count", FT_UINT8, BASE_DEC, NULL,
2234 ZBEE_NWK_CMD_LINK_OPTION_COUNT_MASK, NULL, HFILL }},
2236 { &hf_zbee_nwk_cmd_link_address,
2237 { "Address", "zbee_nwk.cmd.link.address", FT_UINT16, BASE_HEX, NULL,
2238 0x0, NULL, HFILL }},
2240 { &hf_zbee_nwk_cmd_link_incoming_cost,
2241 { "Incoming Cost", "zbee_nwk.cmd.link.incoming_cost", FT_UINT8, BASE_DEC, NULL,
2242 ZBEE_NWK_CMD_LINK_INCOMMING_COST_MASK, NULL, HFILL }},
2244 { &hf_zbee_nwk_cmd_link_outgoing_cost,
2245 { "Outgoing Cost", "zbee_nwk.cmd.link.outgoing_cost", FT_UINT8, BASE_DEC, NULL,
2246 ZBEE_NWK_CMD_LINK_OUTGOING_COST_MASK, NULL, HFILL }},
2248 { &hf_zbee_nwk_cmd_report_type,
2249 { "Report Type", "zbee_nwk.cmd.report.type", FT_UINT8, BASE_HEX,
2250 VALS(zbee_nwk_report_types), ZBEE_NWK_CMD_NWK_REPORT_ID_MASK, NULL, HFILL }},
2252 { &hf_zbee_nwk_cmd_report_count,
2253 { "Report Information Count", "zbee_nwk.cmd.report.count", FT_UINT8, BASE_DEC, NULL,
2254 ZBEE_NWK_CMD_NWK_REPORT_COUNT_MASK, NULL, HFILL }},
2256 { &hf_zbee_nwk_cmd_update_type,
2257 { "Update Type", "zbee_nwk.cmd.update.type", FT_UINT8, BASE_HEX,
2258 VALS(zbee_nwk_update_types), ZBEE_NWK_CMD_NWK_UPDATE_ID_MASK, NULL, HFILL }},
2260 { &hf_zbee_nwk_cmd_update_count,
2261 { "Update Information Count", "zbee_nwk.cmd.update.count", FT_UINT8, BASE_DEC, NULL,
2262 ZBEE_NWK_CMD_NWK_UPDATE_COUNT_MASK, NULL, HFILL }},
2264 { &hf_zbee_nwk_cmd_update_id,
2265 { "Update ID", "zbee_nwk.cmd.update.id", FT_UINT8, BASE_DEC, NULL, 0x0,
2266 NULL, HFILL }},
2268 { &hf_zbee_nwk_panid,
2269 { "PAN ID", "zbee_nwk.panid", FT_UINT16, BASE_HEX, NULL, 0x0,
2270 NULL, HFILL }},
2272 { &hf_zbee_zboss_nwk_cmd_key,
2273 { "ZBOSS Key", "zbee_nwk.zboss_key", FT_BYTES, BASE_NONE, NULL, 0x0,
2274 NULL, HFILL }},
2276 { &hf_zbee_nwk_cmd_epid,
2277 { "Extended PAN ID", "zbee_nwk.cmd.epid", FT_EUI64, BASE_NONE, NULL, 0x0,
2278 NULL, HFILL }},
2280 { &hf_zbee_nwk_cmd_end_device_timeout_request_enum,
2281 { "Requested Timeout Enumeration", "zbee_nwk.cmd.ed_tmo_req", FT_UINT8, BASE_DEC,
2282 VALS(zbee_nwk_end_device_timeout_request), 0, NULL, HFILL }},
2284 { &hf_zbee_nwk_cmd_end_device_configuration,
2285 { "End Device Configuration", "zbee_nwk.cmd.ed_config", FT_UINT8, BASE_HEX, NULL, 0x0,
2286 NULL, HFILL }},
2288 { &hf_zbee_nwk_cmd_end_device_timeout_resp_status,
2289 { "Status", "zbee_nwk.cmd.ed_tmo_rsp_status", FT_UINT8, BASE_DEC,
2290 VALS(zbee_nwk_end_device_timeout_resp_status), 0, NULL, HFILL }},
2292 { &hf_zbee_nwk_cmd_end_device_timeout_resp_parent_info,
2293 { "Parent Information", "zbee_nwk.cmd.ed_prnt_info", FT_UINT8, BASE_HEX, NULL, 0x0,
2294 NULL, HFILL }},
2296 { &hf_zbee_nwk_cmd_prnt_info_mac_data_poll_keepalive_supported,
2297 { "MAC Data Poll Keepalive", "zbee_nwk.cmd.ed_prnt_info.mac_data_poll_keepalive", FT_BOOLEAN, 8, NULL,
2298 ZBEE_NWK_CMD_ED_TIMEO_RSP_PRNT_INFO_MAC_DATA_POLL_KEEPAL_SUPP,
2299 NULL, HFILL }},
2301 { &hf_zbee_nwk_cmd_prnt_info_ed_to_req_keepalive_supported,
2302 { "End Device Timeout Request Keepalive", "zbee_nwk.cmd.ed_prnt_info.ed_tmo_req_keepalive", FT_BOOLEAN, 8, NULL,
2303 ZBEE_NWK_CMD_ED_TIMEO_RSP_PRNT_INFO_ED_TIMOU_REQ_KEEPAL_SUPP,
2304 NULL, HFILL }},
2306 { &hf_zbee_nwk_cmd_prnt_info_power_negotiation_supported,
2307 { "Power Negotiation Supported", "zbee_nwk.cmd.power_negotiation_supported", FT_BOOLEAN, 8, NULL,
2308 ZBEE_NWK_CMD_ED_TIMEO_RSP_PRNT_INFO_PWR_NEG_SUPP,
2309 NULL, HFILL }},
2311 { &hf_zbee_nwk_cmd_link_pwr_type,
2312 { "Type", "zbee_nwk.cmd.link_pwr_delta.type", FT_UINT8, BASE_HEX,
2313 VALS(zbee_nwk_link_power_delta_types), ZBEE_NWK_CMD_NWK_LINK_PWR_DELTA_TYPE_MASK, NULL, HFILL }},
2315 { &hf_zbee_nwk_cmd_link_pwr_list_count,
2316 { "Structure Count", "zbee_nwk.cmd.link_pwr_delta.list_count", FT_UINT8, BASE_DEC, NULL, 0x0,
2317 NULL, HFILL }},
2319 { &hf_zbee_nwk_cmd_link_pwr_device_address,
2320 { "Device Address", "zbee_nwk.cmd.link_pwr_delta.address", FT_UINT16, BASE_HEX, NULL,
2321 0x0, NULL, HFILL }},
2323 { &hf_zbee_nwk_cmd_link_pwr_power_delta,
2324 { "Power Delta", "zbee_nwk.cmd.link_pwr_delta.power_delta", FT_INT8, BASE_DEC, NULL, 0x0,
2325 NULL, HFILL }},
2327 { &hf_zbee_nwk_cmd_association_type,
2328 { "Association Type", "zbee_nwk.cmd.association_type", FT_UINT8, BASE_HEX,
2329 VALS(zbee_nwk_commissioning_types), 0x0, NULL, HFILL }},
2331 { &hf_zbee_beacon_protocol,
2332 { "Protocol ID", "zbee_beacon.protocol", FT_UINT8, BASE_DEC, NULL, 0x0,
2333 NULL, HFILL }},
2335 { &hf_zbee_beacon_stack_profile,
2336 { "Stack Profile", "zbee_beacon.profile", FT_UINT16, BASE_HEX,
2337 VALS(zbee_nwk_stack_profiles), ZBEE_NWK_BEACON_STACK_PROFILE, NULL, HFILL }},
2339 { &hf_zbee_beacon_version,
2340 { "Protocol Version", "zbee_beacon.version", FT_UINT16, BASE_DEC, NULL, ZBEE_NWK_BEACON_PROTOCOL_VERSION,
2341 NULL, HFILL }},
2343 { &hf_zbee_beacon_router_capacity,
2344 { "Router Capacity", "zbee_beacon.router", FT_BOOLEAN, 16, NULL, ZBEE_NWK_BEACON_ROUTER_CAPACITY,
2345 "Whether the device can accept join requests from routing capable devices.", HFILL }},
2347 { &hf_zbee_beacon_depth,
2348 { "Device Depth", "zbee_beacon.depth", FT_UINT16, BASE_DEC, NULL, ZBEE_NWK_BEACON_NETWORK_DEPTH,
2349 "The tree depth of the device, 0 indicates the network coordinator.", HFILL }},
2351 { &hf_zbee_beacon_end_device_capacity,
2352 { "End Device Capacity", "zbee_beacon.end_dev", FT_BOOLEAN, 16, NULL, ZBEE_NWK_BEACON_END_DEVICE_CAPACITY,
2353 "Whether the device can accept join requests from ZigBee end devices.", HFILL }},
2355 { &hf_zbee_beacon_epid,
2356 { "Extended PAN ID", "zbee_beacon.ext_panid", FT_EUI64, BASE_NONE, NULL, 0x0,
2357 "Extended PAN identifier.", HFILL }},
2359 { &hf_zbee_beacon_tx_offset,
2360 { "Tx Offset", "zbee_beacon.tx_offset", FT_UINT24, BASE_DEC, NULL, 0x0,
2361 "The time difference between a device and its parent's beacon.", HFILL }},
2363 { &hf_zbee_beacon_update_id,
2364 { "Update ID", "zbee_beacon.update_id", FT_UINT8, BASE_DEC, NULL, 0x0,
2365 NULL, HFILL }},
2367 { &hf_zbip_beacon_allow_join,
2368 { "Allow Join", "zbip_beacon.allow_join", FT_BOOLEAN, 8, NULL, ZBEE_IP_BEACON_ALLOW_JOIN,
2369 NULL, HFILL }},
2371 { &hf_zbip_beacon_router_capacity,
2372 { "Router Capacity", "zbip_beacon.router", FT_BOOLEAN, 8, NULL, ZBEE_IP_BEACON_ROUTER_CAPACITY,
2373 "Whether this device can accept new routers on the network.", HFILL }},
2375 { &hf_zbip_beacon_host_capacity,
2376 { "Host Capacity", "zbip_beacon.host", FT_BOOLEAN, 8, NULL, ZBEE_IP_BEACON_HOST_CAPACITY,
2377 "Whether this device can accept new host on the network.", HFILL }},
2379 { &hf_zbip_beacon_unsecure,
2380 { "Unsecure Network", "zbip_beacon.unsecure", FT_BOOLEAN, 8, NULL, ZBEE_IP_BEACON_UNSECURE,
2381 "Indicates that this network is not using link layer security.", HFILL }},
2383 { &hf_zbip_beacon_network_id,
2384 { "Network ID", "zbip_beacon.network_id", FT_STRING, BASE_NONE, NULL, 0x0,
2385 "A string that uniquely identifies this network.", HFILL }},
2387 { &hf_ieee802154_zigbee_ie,
2388 { "IE header", "zbee_nwk.zigbee_ie", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2390 { &hf_ieee802154_zigbee_ie_id,
2391 { "Id", "zbee_nwk.zigbee_ie.id", FT_UINT16, BASE_HEX, VALS(ieee802154_zigbee_ie_names),
2392 ZBEE_ZIGBEE_IE_ID_MASK, NULL, HFILL }},
2394 { &hf_ieee802154_zigbee_ie_length,
2395 { "Length", "zbee_nwk.zigbee_ie.length", FT_UINT16, BASE_DEC, NULL,
2396 ZBEE_ZIGBEE_IE_LENGTH_MASK, NULL, HFILL }},
2398 { &hf_ieee802154_zigbee_ie_tx_power,
2399 { "Tx Power (dBm)", "zbee_nwk.zigbee_ie.tx_power", FT_INT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
2401 { &hf_ieee802154_zigbee_ie_source_addr,
2402 { "Source Address", "zbee_nwk.zigbee_ie.source_address", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2405 { &hf_ieee802154_zigbee_rejoin_epid,
2406 { "Extended PAN ID", "zbee_nwk.zigbee_rejoin.ext_panid", FT_EUI64, BASE_NONE, NULL, 0x0,
2407 "Extended PAN identifier", HFILL }},
2409 { &hf_ieee802154_zigbee_rejoin_source_addr,
2410 { "Source Address", "zbee_nwk.zigbee_rejoin.source_address", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2415 /* NWK Layer subtrees */
2416 static int *ett[] = {
2417 &ett_zbee_nwk,
2418 &ett_zbee_nwk_beacon,
2419 &ett_zbee_nwk_fcf,
2420 &ett_zbee_nwk_fcf_ext,
2421 &ett_zbee_nwk_mcast,
2422 &ett_zbee_nwk_route,
2423 &ett_zbee_nwk_cmd,
2424 &ett_zbee_nwk_cmd_options,
2425 &ett_zbee_nwk_cmd_cinfo,
2426 &ett_zbee_nwk_cmd_link,
2427 &ett_zbee_nwk_cmd_ed_to_rsp_prnt_info,
2428 &ett_zbee_nwk_cmd_link_pwr_struct,
2429 &ett_zbee_nwk_zigbee_ie_fields,
2430 &ett_zbee_nwk_ie_rejoin,
2431 &ett_zbee_nwk_header,
2432 &ett_zbee_nwk_header_ie,
2433 &ett_zbee_nwk_beacon_bitfield,
2436 static ei_register_info ei[] = {
2437 { &ei_zbee_nwk_missing_payload, { "zbee_nwk.missing_payload", PI_MALFORMED, PI_ERROR, "Missing Payload", EXPFILL }},
2440 expert_module_t* expert_zbee_nwk;
2442 register_init_routine(proto_init_zbee_nwk);
2443 register_cleanup_routine(proto_cleanup_zbee_nwk);
2445 /* Register the protocol with Wireshark. */
2446 proto_zbee_nwk = proto_register_protocol("ZigBee Network Layer", "ZigBee", ZBEE_PROTOABBREV_NWK);
2447 proto_zbee_beacon = proto_register_protocol("ZigBee Beacon", "ZigBee Beacon", "zbee_beacon");
2448 proto_zbip_beacon = proto_register_protocol("ZigBee IP Beacon", "ZigBee IP Beacon", "zbip_beacon");
2449 proto_zbee_ie = proto_register_protocol("ZigBee IE", "ZigBee IE", "zbee_ie");
2450 proto_register_field_array(proto_zbee_nwk, hf, array_length(hf));
2451 proto_register_subtree_array(ett, array_length(ett));
2453 expert_zbee_nwk = expert_register_protocol(proto_zbee_nwk);
2454 expert_register_field_array(expert_zbee_nwk, ei, array_length(ei));
2456 /* Register the dissectors with Wireshark. */
2457 register_dissector(ZBEE_PROTOABBREV_NWK, dissect_zbee_nwk, proto_zbee_nwk);
2458 register_dissector("zbee_beacon", dissect_zbee_beacon, proto_zbee_beacon);
2459 register_dissector("zbip_beacon", dissect_zbip_beacon, proto_zbip_beacon);
2460 register_dissector("zbee_ie", dissect_zbee_ie, proto_zbee_ie);
2462 zbee_nwk_address_type = address_type_dissector_register("AT_ZIGBEE", "ZigBee 16-bit address",
2463 zbee_nwk_address_to_str, zbee_nwk_address_str_len, NULL, NULL, zbee_nwk_address_len, NULL, NULL);
2465 /* Register the Security dissector. */
2466 zbee_security_register(NULL, proto_zbee_nwk);
2468 zbee_nwk_tap = register_tap(ZBEE_PROTOABBREV_NWK);
2470 register_conversation_table(proto_zbee_nwk, true, zbee_nwk_conversation_packet, zbee_nwk_endpoint_packet);
2471 register_conversation_filter(ZBEE_PROTOABBREV_NWK, "ZigBee Network Layer", zbee_nwk_filter_valid, zbee_nwk_build_filter, NULL);
2472 } /* proto_register_zbee_nwk */
2475 *Registers the zigbee dissector with Wireshark.
2478 void proto_reg_handoff_zbee_nwk(void)
2480 /* Find the other dissectors we need. */
2481 aps_handle = find_dissector_add_dependency(ZBEE_PROTOABBREV_APS, proto_zbee_nwk);
2482 zbee_gp_handle = find_dissector_add_dependency(ZBEE_PROTOABBREV_NWK_GP, proto_zbee_nwk);
2484 /* Register our dissector with IEEE 802.15.4 */
2485 dissector_add_for_decode_as(IEEE802154_PROTOABBREV_WPAN_PANID, find_dissector(ZBEE_PROTOABBREV_NWK));
2486 heur_dissector_add(IEEE802154_PROTOABBREV_WPAN_BEACON, dissect_zbee_beacon_heur, "ZigBee Beacon", "zbee_wpan_beacon", proto_zbee_beacon, HEURISTIC_ENABLE);
2487 heur_dissector_add(IEEE802154_PROTOABBREV_WPAN_BEACON, dissect_zbip_beacon_heur, "ZigBee IP Beacon", "zbip_wpan_beacon", proto_zbip_beacon, HEURISTIC_ENABLE);
2488 heur_dissector_add(IEEE802154_PROTOABBREV_WPAN, dissect_zbee_nwk_heur, "ZigBee Network Layer over IEEE 802.15.4", "zbee_nwk_wpan", proto_zbee_nwk, HEURISTIC_ENABLE);
2489 } /* proto_reg_handoff_zbee */
2491 static void free_keyring_key(void *key)
2493 g_free(key);
2496 static void free_keyring_val(void *a)
2498 GSList **slist = (GSList **)a;
2499 g_slist_free_full(*slist, g_free);
2500 g_free(slist);
2504 *Init routine for the nwk dissector. Creates a
2507 static void
2508 proto_init_zbee_nwk(void)
2510 zbee_nwk_map.short_table = g_hash_table_new(ieee802154_short_addr_hash, ieee802154_short_addr_equal);
2511 zbee_nwk_map.long_table = g_hash_table_new(ieee802154_long_addr_hash, ieee802154_long_addr_equal);
2512 zbee_table_nwk_keyring = g_hash_table_new_full(g_int_hash, g_int_equal, free_keyring_key, free_keyring_val);
2513 } /* proto_init_zbee_nwk */
2515 static void
2516 proto_cleanup_zbee_nwk(void)
2518 g_hash_table_destroy(zbee_nwk_map.short_table);
2519 g_hash_table_destroy(zbee_nwk_map.long_table);
2520 g_hash_table_destroy(zbee_table_nwk_keyring);
2524 * Editor modelines - https://www.wireshark.org/tools/modelines.html
2526 * Local variables:
2527 * c-basic-offset: 4
2528 * tab-width: 8
2529 * indent-tabs-mode: nil
2530 * End:
2532 * vi: set shiftwidth=4 tabstop=8 expandtab:
2533 * :indentSize=4:tabSize=8:noTabs=true: