1 /* packet-zbee-nwk-gp.c
2 * Dissector routines for the ZigBee Green Power profile (GP)
3 * Copyright 2013 DSR Corporation, http://dsr-wireless.com/
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * Used Owen Kirby's packet-zbee-aps module as a template. Based
10 * on ZigBee Cluster Library Specification document 075123r02ZB
12 * SPDX-License-Identifier: GPL-2.0-or-later
18 #include <epan/packet.h>
19 #include <epan/exceptions.h>
20 #include <epan/expert.h>
21 #include <epan/prefs.h>
23 #include <wsutil/bits_ctz.h>
24 #include <wsutil/pint.h>
25 #include "packet-zbee.h"
26 #include "packet-zbee-nwk.h"
27 #include "packet-zbee-security.h"
28 #include "packet-zbee-aps.h"
29 #include "packet-zbee-zcl.h"
31 void proto_register_zbee_nwk_gp(void);
32 void proto_reg_handoff_zbee_nwk_gp(void);
34 /**************************/
36 /**************************/
38 /* ZigBee NWK GP FCF frame types. */
39 #define ZBEE_NWK_GP_FCF_DATA 0x00
40 #define ZBEE_NWK_GP_FCF_MAINTENANCE 0x01
42 /* ZigBee NWK GP FCF fields. */
43 #define ZBEE_NWK_GP_FCF_AUTO_COMMISSIONING 0x40
44 #define ZBEE_NWK_GP_FCF_CONTROL_EXTENSION 0x80
45 #define ZBEE_NWK_GP_FCF_FRAME_TYPE 0x03
46 #define ZBEE_NWK_GP_FCF_VERSION 0x3C
48 /* Extended NWK Frame Control field. */
49 #define ZBEE_NWK_GP_FCF_EXT_APP_ID 0x07 /* 0 - 2 b. */
50 #define ZBEE_NWK_GP_FCF_EXT_SECURITY_LEVEL 0x18 /* 3 - 4 b. */
51 #define ZBEE_NWK_GP_FCF_EXT_SECURITY_KEY 0x20 /* 5 b. */
52 #define ZBEE_NWK_GP_FCF_EXT_RX_AFTER_TX 0x40 /* 6 b. */
53 #define ZBEE_NWK_GP_FCF_EXT_DIRECTION 0x80 /* 7 b. */
55 /* Definitions for application IDs. */
56 #define ZBEE_NWK_GP_APP_ID_DEFAULT 0x00
57 #define ZBEE_NWK_GP_APP_ID_LPED 0x01
58 #define ZBEE_NWK_GP_APP_ID_ZGP 0x02
60 /* Definitions for GP directions. */
61 #define ZBEE_NWK_GP_FC_EXT_DIRECTION_DEFAULT 0x00
62 #define ZBEE_NWK_GP_FC_EXT_DIRECTION_FROM_ZGPD 0x00
63 #define ZBEE_NWK_GP_FC_EXT_DIRECTION_FROM_ZGPP 0x01
65 /* Definitions for ZGPD Source IDs. */
66 #define ZBEE_NWK_GP_ZGPD_SRCID_ALL 0xFFFFFFFF
67 #define ZBEE_NWK_GP_ZGPD_SRCID_UNKNOWN 0x00000000
69 /* Security level values. */
70 #define ZBEE_NWK_GP_SECURITY_LEVEL_NO 0x00
71 #define ZBEE_NWK_GP_SECURITY_LEVEL_1LSB 0x01
72 #define ZBEE_NWK_GP_SECURITY_LEVEL_FULL 0x02
73 #define ZBEE_NWK_GP_SECURITY_LEVEL_FULLENCR 0x03
75 /* GP Security key types. */
76 #define ZBEE_NWK_GP_SECURITY_KEY_TYPE_NO_KEY 0x00
77 #define ZBEE_NWK_GP_SECURITY_KEY_TYPE_ZB_NWK_KEY 0x01
78 #define ZBEE_NWK_GP_SECURITY_KEY_TYPE_GPD_GROUP_KEY 0x02
79 #define ZBEE_NWK_GP_SECURITY_KEY_TYPE_NWK_KEY_DERIVED_GPD_KEY_GROUP_KEY 0x03
80 #define ZBEE_NWK_GP_SECURITY_KEY_TYPE_PRECONFIGURED_INDIVIDUAL_GPD_KEY 0x04
81 #define ZBEE_NWK_GP_SECURITY_KEY_TYPE_DERIVED_INDIVIDUAL_GPD_KEY 0x07
86 bool nwk_frame_control_extension
;
89 uint8_t application_id
;
90 uint8_t security_level
;
99 /* Security Frame Counter. */
100 uint32_t security_frame_counter
;
106 /* Application Payload. */
109 /* Source IEEE address from parent */
110 uint64_t ieee_packet_src64
;
111 } zbee_nwk_green_power_packet
;
113 /* Definitions for GP Commissioning command opt field (bitmask). */
114 #define ZBEE_NWK_GP_CMD_COMMISSIONING_OPT_MAC_SEQ 0x01
115 #define ZBEE_NWK_GP_CMD_COMMISSIONING_OPT_RX_ON_CAP 0x02
116 #define ZBEE_NWK_GP_CMD_COMMISSIONING_OPT_APPLICATION_INFO 0x04
117 #define ZBEE_NWK_GP_CMD_COMMISSIONING_OPT_PAN_ID_REQ 0x10
118 #define ZBEE_NWK_GP_CMD_COMMISSIONING_OPT_GP_SEC_KEY_REQ 0x20
119 #define ZBEE_NWK_GP_CMD_COMMISSIONING_OPT_FIXED_LOCATION 0x40
120 #define ZBEE_NWK_GP_CMD_COMMISSIONING_OPT_EXT_OPTIONS 0x80
122 /* Definitions for GP Commissioning command ext_opt field (bitmask). */
123 #define ZBEE_NWK_GP_CMD_COMMISSIONING_EXT_OPT_SEC_LEVEL_CAP 0x03
124 #define ZBEE_NWK_GP_CMD_COMMISSIONING_EXT_OPT_KEY_TYPE 0x1C
125 #define ZBEE_NWK_GP_CMD_COMMISSIONING_EXT_OPT_GPD_KEY_PRESENT 0x20
126 #define ZBEE_NWK_GP_CMD_COMMISSIONING_EXT_OPT_GPD_KEY_ENCR 0x40
127 #define ZBEE_NWK_GP_CMD_COMMISSIONING_EXT_OPT_OUT_COUNTER 0x80
129 /* Definitions for GP Commissioning command application information field (bitmask). */
130 #define ZBEE_NWK_GP_CMD_COMMISSIONING_APPLI_INFO_MIP 0x01
131 #define ZBEE_NWK_GP_CMD_COMMISSIONING_APPLI_INFO_MMIP 0x02
132 #define ZBEE_NWK_GP_CMD_COMMISSIONING_APPLI_INFO_GCLP 0x04
133 #define ZBEE_NWK_GP_CMD_COMMISSIONING_APPLI_INFO_CRP 0x08
135 /* Definitions for GP Commissioning command Number of server ClusterIDs (bitmask) */
136 #define ZBEE_NWK_GP_CMD_COMMISSIONING_CLID_LIST_LEN_SRV 0x0F
137 #define ZBEE_NWK_GP_CMD_COMMISSIONING_CLID_LIST_LEN_CLI 0xF0
139 /* Definitions for GP Decommissioning command opt field (bitmask). */
140 #define ZBEE_NWK_GP_CMD_COMMISSIONING_REP_OPT_PAN_ID_PRESENT 0x01
141 #define ZBEE_NWK_GP_CMD_COMMISSIONING_REP_OPT_SEC_KEY_PRESENT 0x02
142 #define ZBEE_NWK_GP_CMD_COMMISSIONING_REP_OPT_KEY_ENCR 0x04
143 #define ZBEE_NWK_GP_CMD_COMMISSIONING_REP_OPT_SEC_LEVEL 0x18
144 #define ZBEE_NWK_GP_CMD_COMMISSIONING_REP_OPT_KEY_TYPE 0xE0
146 /* Definition for GP read attributes command opt field (bitmask). */
147 #define ZBEE_NWK_GP_CMD_READ_ATTRIBUTE_OPT_MULTI_RECORD 0x01
148 #define ZBEE_NWK_GP_CMD_READ_ATTRIBUTE_OPT_MAN_FIELD_PRESENT 0x02
150 /* Definitions for GP Channel Request command. */
151 #define ZBEE_NWK_GP_CMD_CHANNEL_REQUEST_1ST 0x0F
152 #define ZBEE_NWK_GP_CMD_CHANNEL_REQUEST_2ND 0xF0
154 /* GP Channel Configuration command. */
155 #define ZBEE_NWK_GP_CMD_CHANNEL_CONFIGURATION_OPERATION_CH 0x0F
157 /* GP GENERIC IDS. */
158 #define GPD_DEVICE_ID_GENERIC_GP_SIMPLE_GENERIC_1STATE_SWITCH 0x00
159 #define GPD_DEVICE_ID_GENERIC_GP_SIMPLE_GENERIC_2STATE_SWITCH 0x01
160 #define GPD_DEVICE_ID_GENERIC_GP_ON_OFF_SWITCH 0x02
161 #define GPD_DEVICE_ID_GENERIC_GP_LEVEL_CONTROL_SWITCH 0x03
162 #define GPD_DEVICE_ID_GENERIC_GP_SIMPLE_SENSOR 0x04
163 #define GPD_DEVICE_ID_GENERIC_GP_ADVANCED_GENERIC_1STATE_SWITCH 0x05
164 #define GPD_DEVICE_ID_GENERIC_GP_ADVANCED_GENERIC_2STATE_SWITCH 0x06
166 /* GP LIGHTING IDS. */
167 #define GPD_DEVICE_ID_LIGHTING_GP_COLOR_DIMMER_SWITCH 0x10
168 #define GPD_DEVICE_ID_LIGHTING_GP_LIGHT_SENSOR 0x11
169 #define GPD_DEVICE_ID_LIGHTING_GP_OCCUPANCY_SENSOR 0x12
171 /* GP CLOSURES IDS. */
172 #define GPD_DEVICE_ID_CLOSURES_GP_DOOR_LOCK_CONTROLLER 0x20
175 #define GPD_DEVICE_ID_HVAC_GP_TEMPERATURE_SENSOR 0x30
176 #define GPD_DEVICE_ID_HVAC_GP_PRESSURE_SENSOR 0x31
177 #define GPD_DEVICE_ID_HVAC_GP_FLOW_SENSOR 0x32
178 #define GPD_DEVICE_ID_HVAC_GP_INDOOR_ENVIRONMENT_SENSOR 0x33
180 /* Manufacturer specific device. */
181 #define GPD_DEVICE_ID_MANUFACTURER_SPECIFIC 0xFE
183 /* GPD manufacturers. */
184 #define ZBEE_NWK_GP_MANUF_ID_GREENPEAK 0x10D0
186 /* GPD devices by GreenPeak. */
187 #define ZBEE_NWK_GP_MANUF_GREENPEAK_IZDS 0x0000
188 #define ZBEE_NWK_GP_MANUF_GREENPEAK_IZDWS 0x0001
189 #define ZBEE_NWK_GP_MANUF_GREENPEAK_IZLS 0x0002
190 #define ZBEE_NWK_GP_MANUF_GREENPEAK_IZRHS 0x0003
192 /*********************/
193 /* Global variables. */
194 /*********************/
196 /* GP proto handle. */
197 static int proto_zbee_nwk_gp
;
200 static int hf_zbee_nwk_gp_auto_commissioning
;
201 static int hf_zbee_nwk_gp_fc_ext
;
202 static int hf_zbee_nwk_gp_fcf
;
203 static int hf_zbee_nwk_gp_frame_type
;
204 static int hf_zbee_nwk_gp_proto_version
;
206 /* GP NWK FC extension. */
207 static int hf_zbee_nwk_gp_fc_ext_field
;
208 static int hf_zbee_nwk_gp_fc_ext_app_id
;
209 static int hf_zbee_nwk_gp_fc_ext_direction
;
210 static int hf_zbee_nwk_gp_fc_ext_rx_after_tx
;
211 static int hf_zbee_nwk_gp_fc_ext_sec_key
;
212 static int hf_zbee_nwk_gp_fc_ext_sec_level
;
215 static int hf_zbee_nwk_gp_zgpd_src_id
;
218 static int hf_zbee_nwk_gp_zgpd_endpoint
;
220 /* Security frame counter. */
221 static int hf_zbee_nwk_gp_security_frame_counter
;
224 static int hf_zbee_nwk_gp_security_mic_2b
;
225 static int hf_zbee_nwk_gp_security_mic_4b
;
227 /* Payload subframe. */
228 static int hf_zbee_nwk_gp_command_id
;
231 static int hf_zbee_nwk_gp_cmd_comm_device_id
;
232 static int hf_zbee_nwk_gp_cmd_comm_ext_opt
;
233 static int hf_zbee_nwk_gp_cmd_comm_ext_opt_gpd_key_encr
;
234 static int hf_zbee_nwk_gp_cmd_comm_ext_opt_gpd_key_present
;
235 static int hf_zbee_nwk_gp_cmd_comm_ext_opt_key_type
;
236 static int hf_zbee_nwk_gp_cmd_comm_ext_opt_outgoing_counter
;
237 static int hf_zbee_nwk_gp_cmd_comm_ext_opt_sec_level_cap
;
238 static int hf_zbee_nwk_gp_cmd_comm_security_key
;
239 static int hf_zbee_nwk_gp_cmd_comm_gpd_sec_key_mic
;
240 static int hf_zbee_nwk_gp_cmd_comm_opt_ext_opt
;
241 static int hf_zbee_nwk_gp_cmd_comm_opt
;
242 static int hf_zbee_nwk_gp_cmd_comm_opt_fixed_location
;
243 static int hf_zbee_nwk_gp_cmd_comm_opt_mac_sec_num_cap
;
244 static int hf_zbee_nwk_gp_cmd_comm_opt_appli_info_present
;
245 static int hf_zbee_nwk_gp_cmd_comm_opt_panid_req
;
246 static int hf_zbee_nwk_gp_cmd_comm_opt_rx_on_cap
;
247 static int hf_zbee_nwk_gp_cmd_comm_opt_sec_key_req
;
248 static int hf_zbee_nwk_gp_cmd_comm_outgoing_counter
;
249 static int hf_zbee_nwk_gp_cmd_comm_manufacturer_greenpeak_dev_id
;
250 static int hf_zbee_nwk_gp_cmd_comm_manufacturer_dev_id
;
251 static int hf_zbee_nwk_gp_cmd_comm_manufacturer_id
;
252 static int hf_zbee_nwk_gp_cmd_comm_appli_info
;
253 static int hf_zbee_nwk_gp_cmd_comm_appli_info_crp
;
254 static int hf_zbee_nwk_gp_cmd_comm_appli_info_gclp
;
255 static int hf_zbee_nwk_gp_cmd_comm_appli_info_mip
;
256 static int hf_zbee_nwk_gp_cmd_comm_appli_info_mmip
;
257 static int hf_zbee_nwk_gp_cmd_comm_gpd_cmd_num
;
258 static int hf_zbee_nwk_gp_cmd_comm_gpd_cmd_id_list
;
259 static int hf_zbee_nwk_gp_cmd_comm_length_of_clid_list
;
260 static int hf_zbee_nwk_gp_cmd_comm_length_of_clid_list_server
;
261 static int hf_zbee_nwk_gp_cmd_comm_length_of_clid_list_client
;
262 static int hf_zbee_nwk_cmd_comm_clid_list_server
;
263 static int hf_zbee_nwk_cmd_comm_clid_list_client
;
264 static int hf_zbee_nwk_cmd_comm_cluster_id
;
266 /* Commissioning reply. */
267 static int hf_zbee_nwk_gp_cmd_comm_rep_opt
;
268 static int hf_zbee_nwk_gp_cmd_comm_rep_opt_key_encr
;
269 static int hf_zbee_nwk_gp_cmd_comm_rep_opt_panid_present
;
270 static int hf_zbee_nwk_gp_cmd_comm_rep_opt_sec_key_present
;
271 static int hf_zbee_nwk_gp_cmd_comm_rep_opt_sec_level
;
272 static int hf_zbee_nwk_gp_cmd_comm_rep_opt_sec_type
;
273 static int hf_zbee_nwk_gp_cmd_comm_rep_pan_id
;
274 static int hf_zbee_nwk_gp_cmd_comm_rep_frame_counter
;
276 /* Read attribute and read attribute response. */
277 static int hf_zbee_nwk_gp_cmd_read_att_opt_multi_rec
;
278 static int hf_zbee_nwk_gp_cmd_read_att_opt_man_field_present
;
279 static int hf_zbee_nwk_gp_cmd_read_att_opt
;
280 static int hf_zbee_nwk_gp_cmd_read_att_record_len
;
282 /* Common to commands returning data */
283 static int hf_zbee_nwk_gp_zcl_attr_status
;
284 static int hf_zbee_nwk_gp_zcl_attr_data_type
;
285 static int hf_zbee_nwk_gp_zcl_attr_cluster_id
;
287 /* Common to all manufacturer specific commands */
288 static int hf_zbee_zcl_gp_cmd_ms_manufacturer_code
;
290 /* Channel request. */
291 static int hf_zbee_nwk_gp_cmd_channel_request_toggling_behaviour
;
292 static int hf_zbee_nwk_gp_cmd_channel_request_toggling_behaviour_1st
;
293 static int hf_zbee_nwk_gp_cmd_channel_request_toggling_behaviour_2nd
;
295 /* Channel Configuration command. */
296 static int hf_zbee_nwk_gp_cmd_operational_channel
;
297 static int hf_zbee_nwk_gp_cmd_channel_configuration
;
299 /* Move Color command. */
300 static int hf_zbee_nwk_gp_cmd_move_color_ratex
;
301 static int hf_zbee_nwk_gp_cmd_move_color_ratey
;
303 /* Move Up/Down command. */
304 static int hf_zbee_nwk_gp_cmd_move_up_down_rate
;
306 /* Step Color command. */
307 static int hf_zbee_nwk_gp_cmd_step_color_stepx
;
308 static int hf_zbee_nwk_gp_cmd_step_color_stepy
;
309 static int hf_zbee_nwk_gp_cmd_step_color_transition_time
;
311 /* Step Up/Down command. */
312 static int hf_zbee_nwk_gp_cmd_step_up_down_step_size
;
313 static int hf_zbee_nwk_gp_cmd_step_up_down_transition_time
;
315 static expert_field ei_zbee_nwk_gp_no_payload
;
316 static expert_field ei_zbee_nwk_gp_inval_residual_data
;
317 static expert_field ei_zbee_nwk_gp_com_rep_no_out_cnt
;
319 /* Proto tree elements. */
320 static int ett_zbee_nwk
;
321 static int ett_zbee_nwk_cmd
;
322 static int ett_zbee_nwk_cmd_cinfo
;
323 static int ett_zbee_nwk_cmd_appli_info
;
324 static int ett_zbee_nwk_cmd_options
;
325 static int ett_zbee_nwk_fcf
;
326 static int ett_zbee_nwk_fcf_ext
;
327 static int ett_zbee_nwk_clu_rec
;
328 static int ett_zbee_nwk_att_rec
;
329 static int ett_zbee_nwk_cmd_comm_gpd_cmd_id_list
;
330 static int ett_zbee_nwk_cmd_comm_length_of_clid_list
;
331 static int ett_zbee_nwk_cmd_comm_clid_list_server
;
332 static int ett_zbee_nwk_cmd_comm_clid_list_client
;
335 static GSList
*zbee_gp_keyring
;
336 static unsigned num_uat_key_records
;
342 uint8_t key
[ZBEE_SEC_CONST_KEYSIZE
];
345 static const uint8_t empty_key
[ZBEE_SEC_CONST_KEYSIZE
] = {
346 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
347 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
349 static uat_key_record_t
*gp_uat_key_records
;
350 static uat_t
*zbee_gp_sec_key_table_uat
;
353 UAT_CSTRING_CB_DEF(gp_uat_key_records
, string
, uat_key_record_t
)
354 UAT_VS_DEF(gp_uat_key_records
, byte_order
, uat_key_record_t
, uint8_t, 0, "Normal")
355 UAT_CSTRING_CB_DEF(gp_uat_key_records
, label
, uat_key_record_t
)
362 static const value_string byte_order_vals
[] = {
369 /* Application ID names. */
370 static const value_string zbee_nwk_gp_app_id_names
[] = {
371 { ZBEE_NWK_GP_APP_ID_LPED
, "LPED" },
372 { ZBEE_NWK_GP_APP_ID_ZGP
, "ZGP" },
377 /* Green Power commands. */
380 * GPDF commands sent:
381 * From GPD w/o payload: "F "
382 * From GPD w payload: "FP"
386 #define zbee_nwk_gp_cmd_names_VALUE_STRING_LIST(XXX) \
387 XXX( /*F */ ZB_GP_CMD_ID_IDENTIFY , 0x00, "Identify" ) \
388 XXX( /*F */ ZB_GP_CMD_ID_RECALL_SCENE0 , 0x10, "Recall Scene 0" ) \
389 XXX( /*F */ ZB_GP_CMD_ID_RECALL_SCENE1 , 0x11, "Recall Scene 1" ) \
390 XXX( /*F */ ZB_GP_CMD_ID_RECALL_SCENE2 , 0x12, "Recall Scene 2" ) \
391 XXX( /*F */ ZB_GP_CMD_ID_RECALL_SCENE3 , 0x13, "Recall Scene 3" ) \
392 XXX( /*F */ ZB_GP_CMD_ID_RECALL_SCENE4 , 0x14, "Recall Scene 4" ) \
393 XXX( /*F */ ZB_GP_CMD_ID_RECALL_SCENE5 , 0x15, "Recall Scene 5" ) \
394 XXX( /*F */ ZB_GP_CMD_ID_RECALL_SCENE6 , 0x16, "Recall Scene 6" ) \
395 XXX( /*F */ ZB_GP_CMD_ID_RECALL_SCENE7 , 0x17, "Recall Scene 7" ) \
396 XXX( /*F */ ZB_GP_CMD_ID_STORE_SCENE0 , 0x18, "Store Scene 0" ) \
397 XXX( /*F */ ZB_GP_CMD_ID_STORE_SCENE1 , 0x19, "Store Scene 1" ) \
398 XXX( /*F */ ZB_GP_CMD_ID_STORE_SCENE2 , 0x1A, "Store Scene 2" ) \
399 XXX( /*F */ ZB_GP_CMD_ID_STORE_SCENE3 , 0x1B, "Store Scene 3" ) \
400 XXX( /*F */ ZB_GP_CMD_ID_STORE_SCENE4 , 0x1C, "Store Scene 4" ) \
401 XXX( /*F */ ZB_GP_CMD_ID_STORE_SCENE5 , 0x1D, "Store Scene 5" ) \
402 XXX( /*F */ ZB_GP_CMD_ID_STORE_SCENE6 , 0x1E, "Store Scene 6" ) \
403 XXX( /*F */ ZB_GP_CMD_ID_STORE_SCENE7 , 0x1F, "Store Scene 7" ) \
404 XXX( /*F */ ZB_GP_CMD_ID_OFF , 0x20, "Off" ) \
405 XXX( /*F */ ZB_GP_CMD_ID_ON , 0x21, "On" ) \
406 XXX( /*F */ ZB_GP_CMD_ID_TOGGLE , 0x22, "Toggle" ) \
407 XXX( /*F */ ZB_GP_CMD_ID_RELEASE , 0x23, "Release" ) \
408 XXX( /*FP*/ ZB_GP_CMD_ID_MOVE_UP , 0x30, "Move Up" ) \
409 XXX( /*FP*/ ZB_GP_CMD_ID_MOVE_DOWN , 0x31, "Move Down" ) \
410 XXX( /*FP*/ ZB_GP_CMD_ID_STEP_UP , 0x32, "Step Up" ) \
411 XXX( /*FP*/ ZB_GP_CMD_ID_STEP_DOWN , 0x33, "Step Down" ) \
412 XXX( /*F */ ZB_GP_CMD_ID_LEVEL_CONTROL_STOP , 0x34, "Level Control/Stop" ) \
413 XXX( /*FP*/ ZB_GP_CMD_ID_MOVE_UP_WITH_ON_OFF , 0x35, "Move Up (with On/Off)" ) \
414 XXX( /*FP*/ ZB_GP_CMD_ID_MOVE_DOWN_WITH_ON_OFF , 0x36, "Move Down (with On/Off)" ) \
415 XXX( /*FP*/ ZB_GP_CMD_ID_STEP_UP_WITH_ON_OFF , 0x37, "Step Up (with On/Off)" ) \
416 XXX( /*FP*/ ZB_GP_CMD_ID_STEP_DOWN_WITH_ON_OFF , 0x38, "Step Down (with On/Off)" ) \
417 XXX( /*F */ ZB_GP_CMD_ID_MOVE_HUE_STOP , 0x40, "Move Hue Stop" ) \
418 XXX( /*FP*/ ZB_GP_CMD_ID_MOVE_HUE_UP , 0x41, "Move Hue Up" ) \
419 XXX( /*FP*/ ZB_GP_CMD_ID_MOVE_HUE_DOWN , 0x42, "Move Hue Down" ) \
420 XXX( /*FP*/ ZB_GP_CMD_ID_STEP_HUE_UP , 0x43, "Step Hue Up" ) \
421 XXX( /*FP*/ ZB_GP_CMD_ID_STEP_HUW_DOWN , 0x44, "Step Hue Down" ) \
422 XXX( /*F */ ZB_GP_CMD_ID_MOVE_SATURATION_STOP , 0x45, "Move Saturation Stop" ) \
423 XXX( /*FP*/ ZB_GP_CMD_ID_MOVE_SATURATION_UP , 0x46, "Move Saturation Up" ) \
424 XXX( /*FP*/ ZB_GP_CMD_ID_MOVE_SATURATION_DOWN , 0x47, "Move Saturation Down" ) \
425 XXX( /*FP*/ ZB_GP_CMD_ID_STEP_SATURATION_UP , 0x48, "Step Saturation Up" ) \
426 XXX( /*FP*/ ZB_GP_CMD_ID_STEP_SATURATION_DOWN , 0x49, "Step Saturation Down" ) \
427 XXX( /*FP*/ ZB_GP_CMD_ID_MOVE_COLOR , 0x4A, "Move Color" ) \
428 XXX( /*FP*/ ZB_GP_CMD_ID_STEP_COLOR , 0x4B, "Step Color" ) \
429 XXX( /*F */ ZB_GP_CMD_ID_LOCK_DOOR , 0x50, "Lock Door" ) \
430 XXX( /*F */ ZB_GP_CMD_ID_UNLOCK_DOOR , 0x51, "Unlock Door" ) \
431 XXX( /*F */ ZB_GP_CMD_ID_PRESS11 , 0x60, "Press 1 of 1" ) \
432 XXX( /*F */ ZB_GP_CMD_ID_RELEASE11 , 0x61, "Release 1 of 1" ) \
433 XXX( /*F */ ZB_GP_CMD_ID_PRESS12 , 0x62, "Press 1 of 2" ) \
434 XXX( /*F */ ZB_GP_CMD_ID_RELEASE12 , 0x63, "Release 1 of 2" ) \
435 XXX( /*F */ ZB_GP_CMD_ID_PRESS22 , 0x64, "Press 2 of 2" ) \
436 XXX( /*F */ ZB_GP_CMD_ID_RELEASE22 , 0x65, "Release 2 of 2" ) \
437 XXX( /*F */ ZB_GP_CMD_ID_SHORT_PRESS11 , 0x66, "Short press 1 of 1" ) \
438 XXX( /*F */ ZB_GP_CMD_ID_SHORT_PRESS12 , 0x67, "Short press 1 of 2" ) \
439 XXX( /*F */ ZB_GP_CMD_ID_SHORT_PRESS22 , 0x68, "Short press 2 of 2" ) \
440 XXX( /*FP*/ ZB_GP_CMD_ID_ATTRIBUTE_REPORTING , 0xA0, "Attribute reporting" ) \
441 XXX( /*FP*/ ZB_GP_CMD_ID_MANUFACTURE_SPECIFIC_ATTR_REPORTING , 0xA1, "Manufacturer-specific attribute reporting" ) \
442 XXX( /*FP*/ ZB_GP_CMD_ID_MULTI_CLUSTER_REPORTING , 0xA2, "Multi-cluster reporting" ) \
443 XXX( /*FP*/ ZB_GP_CMD_ID_MANUFACTURER_SPECIFIC_MCLUSTER_REPORTING , 0xA3, "Manufacturer-specific multi-cluster reporting" ) \
444 XXX( /*FP*/ ZB_GP_CMD_ID_REQUEST_ATTRIBUTES , 0xA4, "Request Attributes" ) \
445 XXX( /*FP*/ ZB_GP_CMD_ID_READ_ATTRIBUTES_RESPONSE , 0xA5, "Read Attributes Response" ) \
446 XXX( /*FP*/ ZB_GP_CMD_ID_ANY_SENSOR_COMMAND_A0_A3 , 0xAF, "Any GPD sensor command (0xA0 - 0xA3)" ) \
447 XXX( /*FP*/ ZB_GP_CMD_ID_COMMISSIONING , 0xE0, "Commissioning" ) \
448 XXX( /*F */ ZB_GP_CMD_ID_DECOMMISSIONING , 0xE1, "Decommissioning" ) \
449 XXX( /*F */ ZB_GP_CMD_ID_SUCCESS , 0xE2, "Success" ) \
450 XXX( /*FP*/ ZB_GP_CMD_ID_CHANNEL_REQUEST , 0xE3, "Channel Request" ) \
451 XXX( /*T */ ZB_GP_CMD_ID_COMMISSIONING_REPLY , 0xF0, "Commissioning Reply" ) \
452 XXX( /*T */ ZB_GP_CMD_ID_WRITE_ATTRIBUTES , 0xF1, "Write Attributes" ) \
453 XXX( /*T */ ZB_GP_CMD_ID_READ_ATTRIBUTES , 0xF2, "Read Attributes" ) \
454 XXX( /*T */ ZB_GP_CMD_ID_CHANNEL_CONFIGURATION , 0xF3, "Channel Configuration" )
456 VALUE_STRING_ENUM(zbee_nwk_gp_cmd_names
);
458 VALUE_STRING_ARRAY(zbee_nwk_gp_cmd_names
);
459 value_string_ext zbee_nwk_gp_cmd_names_ext
= VALUE_STRING_EXT_INIT(zbee_nwk_gp_cmd_names
);
462 /* Green Power devices. */
463 const value_string zbee_nwk_gp_device_ids_names
[] = {
466 { GPD_DEVICE_ID_GENERIC_GP_SIMPLE_GENERIC_1STATE_SWITCH
, "Generic: GP Simple Generic 1-state Switch" },
467 { GPD_DEVICE_ID_GENERIC_GP_SIMPLE_GENERIC_2STATE_SWITCH
, "Generic: GP Simple Generic 2-state Switch" },
468 { GPD_DEVICE_ID_GENERIC_GP_ON_OFF_SWITCH
, "Generic: GP On/Off Switch" },
469 { GPD_DEVICE_ID_GENERIC_GP_LEVEL_CONTROL_SWITCH
, "Generic: GP Level Control Switch" },
470 { GPD_DEVICE_ID_GENERIC_GP_SIMPLE_SENSOR
, "Generic: GP Simple Sensor" },
471 { GPD_DEVICE_ID_GENERIC_GP_ADVANCED_GENERIC_1STATE_SWITCH
, "Generic: GP Advanced Generic 1-state Switch" },
472 { GPD_DEVICE_ID_GENERIC_GP_ADVANCED_GENERIC_2STATE_SWITCH
, "Generic: GP Advanced Generic 2-state Switch" },
475 { GPD_DEVICE_ID_LIGHTING_GP_COLOR_DIMMER_SWITCH
, "Lighting: GP Color Dimmer Switch" },
476 { GPD_DEVICE_ID_LIGHTING_GP_LIGHT_SENSOR
, "Lighting: GP Light Sensor" },
477 { GPD_DEVICE_ID_LIGHTING_GP_OCCUPANCY_SENSOR
, "Lighting: GP Occupancy Sensor" },
480 { GPD_DEVICE_ID_CLOSURES_GP_DOOR_LOCK_CONTROLLER
, "Closures: GP Door Lock Controller" },
483 { GPD_DEVICE_ID_HVAC_GP_TEMPERATURE_SENSOR
, "HVAC: GP Temperature Sensor" },
484 { GPD_DEVICE_ID_HVAC_GP_PRESSURE_SENSOR
, "HVAC: GP Pressure Sensor" },
485 { GPD_DEVICE_ID_HVAC_GP_FLOW_SENSOR
, "HVAC: GP Flow Sensor" },
486 { GPD_DEVICE_ID_HVAC_GP_INDOOR_ENVIRONMENT_SENSOR
, "HVAC: GP Indoor Environment Sensor" },
489 { GPD_DEVICE_ID_MANUFACTURER_SPECIFIC
, "Manufacturer Specific" },
493 static value_string_ext zbee_nwk_gp_device_ids_names_ext
= VALUE_STRING_EXT_INIT(zbee_nwk_gp_device_ids_names
);
496 static const value_string zbee_nwk_gp_directions
[] = {
497 { ZBEE_NWK_GP_FC_EXT_DIRECTION_FROM_ZGPD
, "From ZGPD" },
498 { ZBEE_NWK_GP_FC_EXT_DIRECTION_FROM_ZGPP
, "From ZGPP" },
503 /* Frame types for Green Power profile. */
504 static const value_string zbee_nwk_gp_frame_types
[] = {
505 { ZBEE_NWK_GP_FCF_DATA
, "Data" },
506 { ZBEE_NWK_GP_FCF_MAINTENANCE
, "Maintenance" },
511 /* GreenPeak Green Power devices. */
512 static const value_string zbee_nwk_gp_manufacturer_greenpeak_dev_names
[] = {
513 { ZBEE_NWK_GP_MANUF_GREENPEAK_IZDS
, "IAS Zone Door Sensor" },
514 { ZBEE_NWK_GP_MANUF_GREENPEAK_IZDWS
, "IAS Zone Door/Window Sensor" },
515 { ZBEE_NWK_GP_MANUF_GREENPEAK_IZLS
, "IAS Zone Leakage Sensor" },
516 { ZBEE_NWK_GP_MANUF_GREENPEAK_IZRHS
, "IAS Zone Relative Humidity Sensor" },
521 /* GP Src ID names. */
522 static const value_string zbee_nwk_gp_src_id_names
[] = {
523 { ZBEE_NWK_GP_ZGPD_SRCID_ALL
, "All" },
524 { ZBEE_NWK_GP_ZGPD_SRCID_UNKNOWN
, "Unspecified" },
529 /* GP security key type names. */
530 static const value_string zbee_nwk_gp_src_sec_keys_type_names
[] = {
531 { ZBEE_NWK_GP_SECURITY_KEY_TYPE_DERIVED_INDIVIDUAL_GPD_KEY
, "Derived individual GPD key" },
532 { ZBEE_NWK_GP_SECURITY_KEY_TYPE_GPD_GROUP_KEY
, "GPD group key" },
533 { ZBEE_NWK_GP_SECURITY_KEY_TYPE_NO_KEY
, "No key" },
534 { ZBEE_NWK_GP_SECURITY_KEY_TYPE_NWK_KEY_DERIVED_GPD_KEY_GROUP_KEY
, "NWK key derived GPD group key" },
535 { ZBEE_NWK_GP_SECURITY_KEY_TYPE_PRECONFIGURED_INDIVIDUAL_GPD_KEY
, "Individual, out of the box GPD key" },
536 { ZBEE_NWK_GP_SECURITY_KEY_TYPE_ZB_NWK_KEY
, "ZigBee NWK key" },
541 /* GP security levels. */
542 static const value_string zbee_nwk_gp_src_sec_levels_names
[] = {
543 { ZBEE_NWK_GP_SECURITY_LEVEL_1LSB
, "1 LSB of frame counter and short MIC only" },
544 { ZBEE_NWK_GP_SECURITY_LEVEL_FULL
, "Full frame counter and full MIC only" },
545 { ZBEE_NWK_GP_SECURITY_LEVEL_FULLENCR
, "Encryption with full frame counter and full MIC" },
546 { ZBEE_NWK_GP_SECURITY_LEVEL_NO
, "No security" },
551 /*************************/
552 /* Function definitions. */
553 /*************************/
555 /* UAT record copy callback. */
557 uat_key_record_copy_cb(void *n
, const void *o
, size_t siz _U_
)
559 uat_key_record_t
*new_key
= (uat_key_record_t
*)n
;
560 const uat_key_record_t
*old_key
= (const uat_key_record_t
*)o
;
562 new_key
->string
= g_strdup(old_key
->string
);
563 new_key
->label
= g_strdup(old_key
->label
);
568 /* UAT record free callback. */
570 uat_key_record_free_cb(void *r
)
572 uat_key_record_t
*key
= (uat_key_record_t
*)r
;
578 *Parses a key string from left to right into a buffer with increasing (normal byte order) or decreasing (reverse
580 *@param key_str pointer to the string
581 *@param key_buf destination buffer in memory
582 *@param byte_order byte order
585 zbee_gp_security_parse_key(const char *key_str
, uint8_t *key_buf
, bool byte_order
)
587 bool string_mode
= false;
591 memset(key_buf
, 0, ZBEE_SEC_CONST_KEYSIZE
);
592 if (key_str
== NULL
) {
595 if ((temp
= *key_str
++) == '"') {
599 j
= byte_order
? ZBEE_SEC_CONST_KEYSIZE
- 1 : 0;
600 for (i
= ZBEE_SEC_CONST_KEYSIZE
- 1; i
>= 0; i
--) {
602 if (g_ascii_isprint(temp
)) {
609 if ((temp
== ':') || (temp
== '-') || (temp
== ' ')) {
612 if (g_ascii_isxdigit(temp
)) {
613 key_buf
[j
] = g_ascii_xdigit_value(temp
) << 4;
618 if (g_ascii_isxdigit(temp
)) {
619 key_buf
[j
] |= g_ascii_xdigit_value(temp
);
634 /* UAT record update callback. */
636 uat_key_record_update_cb(void *r
, char **err
)
638 uat_key_record_t
*rec
= (uat_key_record_t
*)r
;
640 if (rec
->string
== NULL
) {
641 *err
= g_strdup("Key can't be blank.");
644 g_strstrip(rec
->string
);
645 if (rec
->string
[0] != 0) {
647 if (!zbee_gp_security_parse_key(rec
->string
, rec
->key
, rec
->byte_order
)) {
648 *err
= ws_strdup_printf("Expecting %d hexadecimal bytes or a %d character double-quoted string",
649 ZBEE_SEC_CONST_KEYSIZE
, ZBEE_SEC_CONST_KEYSIZE
);
653 *err
= g_strdup("Key can't be blank.");
660 static void uat_key_record_post_update_cb(void) {
663 for (i
= 0; i
< num_uat_key_records
; i
++) {
664 if (memcmp(gp_uat_key_records
[i
].key
, empty_key
, ZBEE_SEC_CONST_KEYSIZE
) == 0) {
665 /* key was not loaded from string yet */
666 zbee_gp_security_parse_key(gp_uat_key_records
[i
].string
, gp_uat_key_records
[i
].key
,
667 gp_uat_key_records
[i
].byte_order
);
673 *Fills in ZigBee GP security nonce from the provided packet structure.
675 *@param packet ZigBee NWK packet.
676 *@param nonce nonce buffer.
679 zbee_gp_make_nonce(zbee_nwk_green_power_packet
*packet
, char *nonce
)
681 memset(nonce
, 0, ZBEE_SEC_CONST_NONCE_LEN
);
684 if (packet
->application_id
== ZBEE_NWK_GP_APP_ID_DEFAULT
)
686 if (packet
->direction
== ZBEE_NWK_GP_FC_EXT_DIRECTION_FROM_ZGPD
) {
687 phtole32(nonce
, packet
->source_id
);
689 phtole32(nonce
+4, packet
->source_id
);
691 else if (packet
->application_id
== ZBEE_NWK_GP_APP_ID_ZGP
)
693 phtole64(nonce
, packet
->ieee_packet_src64
);
697 phtole32(nonce
+8, packet
->security_frame_counter
);
699 /* Security control */
700 if ((packet
->application_id
== ZBEE_NWK_GP_APP_ID_ZGP
) &&
701 (packet
->direction
!= ZBEE_NWK_GP_FC_EXT_DIRECTION_FROM_ZGPD
)) {
702 nonce
[12] = (char)0xc5; /* Security level = 0b101, Key Identifier = 0x00,
703 Extended nonce = 0b0, Reserved = 0b00 */
705 nonce
[12] = (char)0x05; /* Security level = 0b101, Key Identifier = 0x00,
706 Extended nonce = 0b0, Reserved = 0b11 */
711 *Creates a nonce and decrypts secured ZigBee GP payload.
713 *@param packet ZigBee NWK packet.
714 *@param enc_buffer encoded payload buffer.
715 *@param offset payload offset.
716 *@param dec_buffer decoded payload buffer.
717 *@param payload_len payload length.
718 *@param mic_len MIC length.
722 zbee_gp_decrypt_payload(zbee_nwk_green_power_packet
*packet
, const char *enc_buffer
, const char offset
, uint8_t
723 *dec_buffer
, unsigned payload_len
, unsigned mic_len
, uint8_t *key
)
725 uint8_t *key_buffer
= key
;
726 uint8_t nonce
[ZBEE_SEC_CONST_NONCE_LEN
];
728 zbee_gp_make_nonce(packet
, nonce
);
729 if (zbee_sec_ccm_decrypt(key_buffer
, nonce
, enc_buffer
, enc_buffer
+ offset
, dec_buffer
, offset
, payload_len
,
738 *Dissector for ZigBee Green Power commissioning.
740 *@param tvb pointer to buffer containing raw packet.
741 *@param pinfo pointer to packet information fields.
742 *@param tree pointer to data tree Wireshark uses to display packet.
743 *@param packet packet data.
744 *@param offset current payload offset.
745 *@return payload processed offset.
748 dissect_zbee_nwk_gp_cmd_commissioning(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
,
749 zbee_nwk_green_power_packet
*packet
, unsigned offset
)
751 uint8_t comm_options
;
752 uint8_t comm_ext_options
= 0;
753 uint8_t appli_info_options
= 0;
754 uint16_t manufacturer_id
= 0;
757 uint8_t gpd_cmd_num
= 0;
758 proto_item
*gpd_cmd_list
;
759 proto_tree
*gpd_cmd_list_tree
;
761 uint8_t length_of_clid_list_bm
;
762 uint8_t server_clid_num
;
763 uint8_t client_clid_num
;
764 proto_item
*server_clid_list
, *client_clid_list
;
765 proto_tree
*server_clid_list_tree
, *client_clid_list_tree
;
768 uint8_t *enc_buffer_withA
;
772 tvbuff_t
*payload_tvb
;
774 static int * const options
[] = {
775 &hf_zbee_nwk_gp_cmd_comm_opt_mac_sec_num_cap
,
776 &hf_zbee_nwk_gp_cmd_comm_opt_rx_on_cap
,
777 &hf_zbee_nwk_gp_cmd_comm_opt_appli_info_present
,
778 &hf_zbee_nwk_gp_cmd_comm_opt_panid_req
,
779 &hf_zbee_nwk_gp_cmd_comm_opt_sec_key_req
,
780 &hf_zbee_nwk_gp_cmd_comm_opt_fixed_location
,
781 &hf_zbee_nwk_gp_cmd_comm_opt_ext_opt
,
784 static int * const ext_options
[] = {
785 &hf_zbee_nwk_gp_cmd_comm_ext_opt_sec_level_cap
,
786 &hf_zbee_nwk_gp_cmd_comm_ext_opt_key_type
,
787 &hf_zbee_nwk_gp_cmd_comm_ext_opt_gpd_key_present
,
788 &hf_zbee_nwk_gp_cmd_comm_ext_opt_gpd_key_encr
,
789 &hf_zbee_nwk_gp_cmd_comm_ext_opt_outgoing_counter
,
792 static int * const appli_info
[] = {
793 &hf_zbee_nwk_gp_cmd_comm_appli_info_mip
,
794 &hf_zbee_nwk_gp_cmd_comm_appli_info_mmip
,
795 &hf_zbee_nwk_gp_cmd_comm_appli_info_gclp
,
796 &hf_zbee_nwk_gp_cmd_comm_appli_info_crp
,
799 static int * const length_of_clid_list
[] = {
800 &hf_zbee_nwk_gp_cmd_comm_length_of_clid_list_server
,
801 &hf_zbee_nwk_gp_cmd_comm_length_of_clid_list_client
,
805 /* Get Device ID and display it. */
806 proto_tree_add_item(tree
, hf_zbee_nwk_gp_cmd_comm_device_id
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
808 /* Get Options Field, build subtree and display the results. */
809 comm_options
= tvb_get_uint8(tvb
, offset
);
810 proto_tree_add_bitmask(tree
, tvb
, offset
, hf_zbee_nwk_gp_cmd_comm_opt
, ett_zbee_nwk_cmd_options
, options
, ENC_NA
);
813 if (comm_options
& ZBEE_NWK_GP_CMD_COMMISSIONING_OPT_EXT_OPTIONS
) {
814 /* Get extended Options Field, build subtree and display the results. */
815 comm_ext_options
= tvb_get_uint8(tvb
, offset
);
816 proto_tree_add_bitmask(tree
, tvb
, offset
, hf_zbee_nwk_gp_cmd_comm_ext_opt
, ett_zbee_nwk_cmd_options
, ext_options
, ENC_NA
);
818 if (comm_ext_options
& ZBEE_NWK_GP_CMD_COMMISSIONING_EXT_OPT_GPD_KEY_PRESENT
) {
819 /* Get security key and display it. */
820 proto_tree_add_item(tree
, hf_zbee_nwk_gp_cmd_comm_security_key
, tvb
, offset
, ZBEE_SEC_CONST_KEYSIZE
, ENC_NA
);
821 offset
+= ZBEE_SEC_CONST_KEYSIZE
;
823 /* Key is encrypted */
824 if (comm_ext_options
& ZBEE_NWK_GP_CMD_COMMISSIONING_EXT_OPT_GPD_KEY_ENCR
) {
825 /* Get Security MIC and display it. */
826 proto_tree_add_item(tree
, hf_zbee_nwk_gp_cmd_comm_gpd_sec_key_mic
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
831 /* Decrypt the security key */
832 dec_buffer
= (uint8_t *)wmem_alloc(pinfo
->pool
, ZBEE_SEC_CONST_KEYSIZE
);
833 enc_buffer_withA
= (uint8_t *)wmem_alloc(pinfo
->pool
, 4 + ZBEE_SEC_CONST_KEYSIZE
+ 4); /* CCM* a (this is SrcID) + encKey + MIC */
834 enc_buffer
= tvb_memdup(pinfo
->pool
, tvb
, offset
- ZBEE_SEC_CONST_KEYSIZE
- 4, ZBEE_SEC_CONST_KEYSIZE
+ 4);
835 phtole32(enc_buffer_withA
, packet
->source_id
);
836 memcpy(enc_buffer_withA
+4, enc_buffer
, ZBEE_SEC_CONST_KEYSIZE
+ 4);
837 gp_decrypted
= false;
839 for (GSList_i
= zbee_gp_keyring
; GSList_i
&& !gp_decrypted
; GSList_i
= g_slist_next(GSList_i
)) {
840 packet
->security_frame_counter
= packet
->source_id
; /* for Nonce creation*/
841 gp_decrypted
= zbee_gp_decrypt_payload(packet
, enc_buffer_withA
, 4
842 , dec_buffer
, ZBEE_SEC_CONST_KEYSIZE
, 4, ((key_record_t
*)(GSList_i
->data
))->key
);
846 key_record_t key_record
;
848 key_record
.frame_num
= 0;
849 key_record
.label
= NULL
;
850 memcpy(key_record
.key
, dec_buffer
, ZBEE_SEC_CONST_KEYSIZE
);
851 zbee_gp_keyring
= g_slist_prepend(zbee_gp_keyring
, g_memdup2(&key_record
, sizeof(key_record_t
)));
853 payload_tvb
= tvb_new_child_real_data(tvb
, dec_buffer
, ZBEE_SEC_CONST_KEYSIZE
, ZBEE_SEC_CONST_KEYSIZE
);
854 add_new_data_source(pinfo
, payload_tvb
, "Decrypted security key");
860 key_record_t key_record
;
863 key_record
.frame_num
= 0;
864 key_record
.label
= NULL
;
865 key
= tvb_memdup(pinfo
->pool
, tvb
, offset
- ZBEE_SEC_CONST_KEYSIZE
, ZBEE_SEC_CONST_KEYSIZE
);
866 memcpy(key_record
.key
, key
, ZBEE_SEC_CONST_KEYSIZE
);
867 zbee_gp_keyring
= g_slist_prepend(zbee_gp_keyring
, g_memdup2(&key_record
, sizeof(key_record_t
)));
871 if (comm_ext_options
& ZBEE_NWK_GP_CMD_COMMISSIONING_EXT_OPT_OUT_COUNTER
) {
872 /* Get GPD Outgoing Frame Counter and display it. */
873 proto_tree_add_item(tree
, hf_zbee_nwk_gp_cmd_comm_outgoing_counter
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
877 /* Display manufacturer specific data. */
878 if (comm_options
& ZBEE_NWK_GP_CMD_COMMISSIONING_OPT_APPLICATION_INFO
) {
879 /* Display application information. */
880 appli_info_options
= tvb_get_uint8(tvb
, offset
);
881 proto_tree_add_bitmask(tree
, tvb
, offset
, hf_zbee_nwk_gp_cmd_comm_appli_info
, ett_zbee_nwk_cmd_appli_info
, appli_info
, ENC_NA
);
883 if (appli_info_options
& ZBEE_NWK_GP_CMD_COMMISSIONING_APPLI_INFO_MIP
) {
884 /* Get Manufacturer ID. */
885 manufacturer_id
= tvb_get_letohs(tvb
, offset
);
886 proto_tree_add_item(tree
, hf_zbee_nwk_gp_cmd_comm_manufacturer_id
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
889 if (appli_info_options
& ZBEE_NWK_GP_CMD_COMMISSIONING_APPLI_INFO_MMIP
) {
890 /* Get Manufacturer Device ID. */
891 switch (manufacturer_id
) {
892 case ZBEE_NWK_GP_MANUF_ID_GREENPEAK
:
893 proto_tree_add_item(tree
, hf_zbee_nwk_gp_cmd_comm_manufacturer_greenpeak_dev_id
, tvb
, offset
, 2,
898 proto_tree_add_item(tree
, hf_zbee_nwk_gp_cmd_comm_manufacturer_dev_id
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
903 if (appli_info_options
& ZBEE_NWK_GP_CMD_COMMISSIONING_APPLI_INFO_GCLP
) {
904 /* Get and display number of GPD commands */
905 gpd_cmd_num
= tvb_get_uint8(tvb
, offset
);
906 proto_tree_add_item(tree
, hf_zbee_nwk_gp_cmd_comm_gpd_cmd_num
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
908 /* Display GPD command list */
909 if (gpd_cmd_num
> 0) {
910 gpd_cmd_list
= proto_tree_add_item(tree
, hf_zbee_nwk_gp_cmd_comm_gpd_cmd_id_list
,
911 tvb
, offset
, gpd_cmd_num
, ENC_NA
);
912 gpd_cmd_list_tree
= proto_item_add_subtree(gpd_cmd_list
, ett_zbee_nwk_cmd_comm_gpd_cmd_id_list
);
913 for (i
= 0; i
< gpd_cmd_num
; i
++, offset
++) {
914 /* Display command id */
915 proto_tree_add_item(gpd_cmd_list_tree
, hf_zbee_nwk_gp_command_id
,
916 tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
920 if (appli_info_options
& ZBEE_NWK_GP_CMD_COMMISSIONING_APPLI_INFO_CRP
) {
921 /* Get and display Cluster List */
922 length_of_clid_list_bm
= tvb_get_uint8(tvb
, offset
);
923 server_clid_num
= (length_of_clid_list_bm
& ZBEE_NWK_GP_CMD_COMMISSIONING_CLID_LIST_LEN_SRV
) >>
924 ws_ctz(ZBEE_NWK_GP_CMD_COMMISSIONING_CLID_LIST_LEN_SRV
);
925 client_clid_num
= (length_of_clid_list_bm
& ZBEE_NWK_GP_CMD_COMMISSIONING_CLID_LIST_LEN_CLI
) >>
926 ws_ctz(ZBEE_NWK_GP_CMD_COMMISSIONING_CLID_LIST_LEN_CLI
);
928 proto_tree_add_bitmask(tree
, tvb
, offset
, hf_zbee_nwk_gp_cmd_comm_length_of_clid_list
,
929 ett_zbee_nwk_cmd_comm_length_of_clid_list
, length_of_clid_list
, ENC_NA
);
932 if (server_clid_num
> 0) {
933 /* Display server cluster list */
934 server_clid_list
= proto_tree_add_item(tree
, hf_zbee_nwk_cmd_comm_clid_list_server
,
935 tvb
, offset
, 2*server_clid_num
, ENC_NA
);
936 server_clid_list_tree
= proto_item_add_subtree(server_clid_list
, ett_zbee_nwk_cmd_comm_clid_list_server
);
937 /* Retrieve server clusters */
938 for (i
= 0; i
< server_clid_num
; i
++, offset
+= 2) {
939 proto_tree_add_item(server_clid_list_tree
, hf_zbee_nwk_cmd_comm_cluster_id
,
940 tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
943 if (client_clid_num
> 0) {
944 /* Display client cluster list */
945 client_clid_list
= proto_tree_add_item(tree
, hf_zbee_nwk_cmd_comm_clid_list_client
,
946 tvb
, offset
, 2*client_clid_num
, ENC_NA
);
947 client_clid_list_tree
= proto_item_add_subtree(client_clid_list
, ett_zbee_nwk_cmd_comm_clid_list_client
);
948 /* Retrieve client clusters */
949 for (i
= 0; i
< client_clid_num
; i
++, offset
+= 2) {
950 proto_tree_add_item(client_clid_list_tree
, hf_zbee_nwk_cmd_comm_cluster_id
,
951 tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
957 } /* dissect_zbee_nwk_gp_cmd_commissioning */
960 *Dissector for ZigBee Green Power channel request.
962 *@param tvb pointer to buffer containing raw packet.
963 *@param pinfo pointer to packet information fields.
964 *@param tree pointer to data tree Wireshark uses to display packet.
965 *@param packet packet data.
966 *@param offset current payload offset.
967 *@return payload processed offset.
970 dissect_zbee_nwk_gp_cmd_channel_request(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
,
971 zbee_nwk_green_power_packet
*packet _U_
, unsigned offset
)
973 static int * const channels
[] = {
974 &hf_zbee_nwk_gp_cmd_channel_request_toggling_behaviour_1st
,
975 &hf_zbee_nwk_gp_cmd_channel_request_toggling_behaviour_2nd
,
979 /* Get Command Options Field, build subtree and display the results. */
980 proto_tree_add_bitmask(tree
, tvb
, offset
, hf_zbee_nwk_gp_cmd_channel_request_toggling_behaviour
, ett_zbee_nwk_cmd_options
, channels
, ENC_NA
);
983 } /* dissect_zbee_nwk_gp_cmd_channel_request */
986 *Dissector for ZigBee Green Power channel configuration.
988 *@param tvb pointer to buffer containing raw packet.
989 *@param pinfo pointer to packet information fields.
990 *@param tree pointer to data tree Wireshark uses to display packet.
991 *@param packet packet data.
992 *@param offset current payload offset.
993 *@return payload processed offset.
996 dissect_zbee_nwk_gp_cmd_channel_configuration(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
,
997 zbee_nwk_green_power_packet
*packet _U_
, unsigned offset
)
999 static int * const channels
[] = {
1000 &hf_zbee_nwk_gp_cmd_channel_configuration
,
1004 /* Get Command Options Field, build subtree and display the results. */
1005 proto_tree_add_bitmask(tree
, tvb
, offset
, hf_zbee_nwk_gp_cmd_operational_channel
, ett_zbee_nwk_cmd_options
, channels
, ENC_NA
);
1009 } /* dissect_zbee_nwk_gp_cmd_channel_configuration */
1012 *Dissector for ZigBee Green Power commands attrib reporting.
1014 *@param tvb pointer to buffer containing raw packet.
1015 *@param pinfo pointer to packet information fields.
1016 *@param tree pointer to data tree Wireshark uses to display packet.
1017 *@param packet packet data.
1018 *@param offset current payload offset.
1019 *@param mfr_code manufacturer code.
1020 *@return payload processed offset.
1023 dissect_zbee_nwk_gp_cmd_attr_reporting(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
,
1024 zbee_nwk_green_power_packet
*packet _U_
, unsigned offset
, uint16_t mfr_code
)
1026 uint16_t cluster_id
;
1027 proto_tree
*field_tree
;
1029 /* Get cluster ID and add it into the tree. */
1030 cluster_id
= tvb_get_letohs(tvb
, offset
);
1031 proto_tree_add_item(tree
, hf_zbee_nwk_gp_zcl_attr_cluster_id
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1034 /* Create subtree and parse ZCL Write Attribute Payload. */
1035 field_tree
= proto_tree_add_subtree_format(tree
, tvb
, offset
, 2, ett_zbee_nwk_cmd_options
, NULL
,
1036 "Attribute reporting command for cluster: 0x%04X", cluster_id
);
1038 dissect_zcl_report_attr(tvb
, pinfo
, field_tree
, &offset
, cluster_id
, mfr_code
, ZBEE_ZCL_FCF_TO_CLIENT
);
1041 } /* dissect_zbee_nwk_gp_cmd_attr_reporting */
1045 * Dissector for ZigBee Green Power manufacturer specific attribute reporting.
1047 *@param tvb pointer to buffer containing raw packet.
1048 *@param pinfo pointer to packet information fields.
1049 *@param tree pointer to data tree Wireshark uses to display packet.
1050 *@param packet packet data.
1051 *@param offset current payload offset.
1052 *@return payload processed offset.
1055 dissect_zbee_nwk_gp_cmd_MS_attr_reporting(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
,
1056 zbee_nwk_green_power_packet
*packet _U_
, unsigned offset
)
1060 /*dissect manufacturer ID*/
1061 proto_tree_add_item(tree
, hf_zbee_zcl_gp_cmd_ms_manufacturer_code
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1062 mfr_code
= tvb_get_letohs(tvb
, offset
);
1065 offset
= dissect_zbee_nwk_gp_cmd_attr_reporting(tvb
, pinfo
, tree
, packet
, offset
, mfr_code
);
1068 }/*dissect_zbee_nwk_gp_cmd_MS_attr_reporting*/
1074 *Dissector for ZigBee Green Power commissioning reply.
1076 *@param tvb pointer to buffer containing raw packet.
1077 *@param pinfo pointer to packet information fields.
1078 *@param tree pointer to data tree Wireshark uses to display packet.
1079 *@param packet packet data.
1080 *@param offset current payload offset.
1081 *@return payload processed offset.
1084 dissect_zbee_nwk_gp_cmd_commissioning_reply(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
,
1085 zbee_nwk_green_power_packet
*packet
, unsigned offset
)
1088 uint8_t cr_sec_level
;
1091 uint8_t *enc_buffer_withA
;
1092 uint8_t *dec_buffer
;
1095 tvbuff_t
*payload_tvb
;
1097 static int * const options
[] = {
1098 &hf_zbee_nwk_gp_cmd_comm_rep_opt_panid_present
,
1099 &hf_zbee_nwk_gp_cmd_comm_rep_opt_sec_key_present
,
1100 &hf_zbee_nwk_gp_cmd_comm_rep_opt_key_encr
,
1101 &hf_zbee_nwk_gp_cmd_comm_rep_opt_sec_level
,
1102 &hf_zbee_nwk_gp_cmd_comm_rep_opt_sec_type
,
1106 /* Get Options Field, build subtree and display the results. */
1107 cr_options
= tvb_get_uint8(tvb
, offset
);
1108 proto_tree_add_bitmask(tree
, tvb
, offset
, hf_zbee_nwk_gp_cmd_comm_rep_opt
, ett_zbee_nwk_cmd_options
, options
, ENC_NA
);
1111 /* Parse and display security Pan ID value. */
1112 if (cr_options
& ZBEE_NWK_GP_CMD_COMMISSIONING_REP_OPT_PAN_ID_PRESENT
) {
1113 proto_tree_add_item(tree
, hf_zbee_nwk_gp_cmd_comm_rep_pan_id
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1117 cr_sec_level
= (cr_options
& ZBEE_NWK_GP_CMD_COMMISSIONING_REP_OPT_SEC_LEVEL
) >>
1118 ws_ctz(ZBEE_NWK_GP_CMD_COMMISSIONING_REP_OPT_SEC_LEVEL
);
1120 /* Parse and display security key. */
1121 if (cr_options
& ZBEE_NWK_GP_CMD_COMMISSIONING_REP_OPT_SEC_KEY_PRESENT
) {
1122 proto_tree_add_item(tree
, hf_zbee_nwk_gp_cmd_comm_security_key
, tvb
, offset
, ZBEE_SEC_CONST_KEYSIZE
, ENC_NA
);
1123 offset
+= ZBEE_SEC_CONST_KEYSIZE
;
1125 /* Key is present clear, add to the key ring */
1126 if (!(cr_options
& ZBEE_NWK_GP_CMD_COMMISSIONING_REP_OPT_KEY_ENCR
)) {
1127 key_record_t key_record
;
1130 key_record
.frame_num
= 0;
1131 key_record
.label
= NULL
;
1132 key
= tvb_memdup(pinfo
->pool
, tvb
, offset
- ZBEE_SEC_CONST_KEYSIZE
, ZBEE_SEC_CONST_KEYSIZE
);
1133 memcpy(key_record
.key
, key
, ZBEE_SEC_CONST_KEYSIZE
);
1134 zbee_gp_keyring
= g_slist_prepend(zbee_gp_keyring
, g_memdup2(&key_record
, sizeof(key_record_t
)));
1137 /* Parse and display security MIC. */
1138 if ((cr_options
& ZBEE_NWK_GP_CMD_COMMISSIONING_REP_OPT_KEY_ENCR
) &&
1139 (cr_options
& ZBEE_NWK_GP_CMD_COMMISSIONING_REP_OPT_SEC_KEY_PRESENT
)) {
1140 proto_tree_add_item(tree
, hf_zbee_nwk_gp_cmd_comm_gpd_sec_key_mic
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1144 /* Parse and display Frame Counter and decrypt key */
1145 if ((cr_options
& ZBEE_NWK_GP_CMD_COMMISSIONING_REP_OPT_KEY_ENCR
) &&
1146 (cr_options
& ZBEE_NWK_GP_CMD_COMMISSIONING_REP_OPT_SEC_KEY_PRESENT
) &&
1147 ((cr_sec_level
== ZBEE_NWK_GP_SECURITY_LEVEL_FULL
) ||
1148 (cr_sec_level
== ZBEE_NWK_GP_SECURITY_LEVEL_FULLENCR
))) {
1149 if (offset
+ 4 <= tvb_captured_length(tvb
)){
1150 proto_tree_add_item(tree
, hf_zbee_nwk_gp_cmd_comm_rep_frame_counter
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1155 /* decrypt the security key*/
1156 dec_buffer
= (uint8_t *)wmem_alloc(pinfo
->pool
, ZBEE_SEC_CONST_KEYSIZE
);
1157 enc_buffer_withA
= (uint8_t *)wmem_alloc(pinfo
->pool
, 4 + ZBEE_SEC_CONST_KEYSIZE
+ 4); /* CCM* a (this is SrcID) + encKey + MIC */
1158 enc_buffer
= tvb_memdup(pinfo
->pool
, tvb
, offset
- ZBEE_SEC_CONST_KEYSIZE
- 4 - 4, ZBEE_SEC_CONST_KEYSIZE
+ 4);
1159 phtole32(enc_buffer_withA
, packet
->source_id
); /* enc_buffer_withA = CCM* a (srcID) | enc_buffer */
1160 memcpy(enc_buffer_withA
+4, enc_buffer
, ZBEE_SEC_CONST_KEYSIZE
+ 4);
1161 gp_decrypted
= false;
1163 for (GSList_i
= zbee_gp_keyring
; GSList_i
&& !gp_decrypted
; GSList_i
= g_slist_next(GSList_i
)) {
1164 packet
->security_frame_counter
= tvb_get_uint32(tvb
, offset
- 4, ENC_LITTLE_ENDIAN
); /*for Nonce creation */
1165 gp_decrypted
= zbee_gp_decrypt_payload(packet
, enc_buffer_withA
, 4
1166 , dec_buffer
, ZBEE_SEC_CONST_KEYSIZE
, 4, ((key_record_t
*)(GSList_i
->data
))->key
);
1170 key_record_t key_record
;
1172 key_record
.frame_num
= 0;
1173 key_record
.label
= NULL
;
1174 memcpy(key_record
.key
, dec_buffer
, ZBEE_SEC_CONST_KEYSIZE
);
1175 zbee_gp_keyring
= g_slist_prepend(zbee_gp_keyring
, g_memdup2(&key_record
, sizeof(key_record_t
)));
1177 payload_tvb
= tvb_new_child_real_data(tvb
, dec_buffer
, ZBEE_SEC_CONST_KEYSIZE
, ZBEE_SEC_CONST_KEYSIZE
);
1178 add_new_data_source(pinfo
, payload_tvb
, "Decrypted security key");
1183 /* This field is new in 2016 specification, older implementation may exist without it */
1184 proto_tree_add_expert(tree
, pinfo
, &ei_zbee_nwk_gp_com_rep_no_out_cnt
, tvb
, 0, -1);
1188 } /* dissect_zbee_nwk_gp_cmd_commissioning_reply */
1191 * Dissector for ZigBee Green Power read attributes and request attributes commands.
1193 *@param tvb pointer to buffer containing raw packet.
1194 *@param pinfo pointer to packet information fields.
1195 *@param tree pointer to data tree Wireshark uses to display packet.
1196 *@param packet packet data.
1197 *@param offset current payload offset.
1198 *@return payload processed offset.
1201 dissect_zbee_nwk_gp_cmd_read_attributes(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
,
1202 zbee_nwk_green_power_packet
*packet _U_
, unsigned offset
)
1204 uint8_t cr_options
= 0;
1205 proto_tree
*subtree
= NULL
;
1206 uint16_t cluster_id
;
1207 uint16_t mfr_code
= ZBEE_MFG_CODE_NONE
;
1208 uint8_t record_list_len
;
1212 static int * const options
[] = {
1213 &hf_zbee_nwk_gp_cmd_read_att_opt_multi_rec
,
1214 &hf_zbee_nwk_gp_cmd_read_att_opt_man_field_present
,
1218 /* Get Options Field, build subtree and display the results. */
1219 cr_options
= tvb_get_uint8(tvb
, offset
);
1220 proto_tree_add_bitmask(tree
, tvb
, offset
, hf_zbee_nwk_gp_cmd_read_att_opt
, ett_zbee_nwk_cmd_options
, options
, ENC_NA
);
1223 /* Parse and display manufacturer ID value. */
1224 if (cr_options
& ZBEE_NWK_GP_CMD_READ_ATTRIBUTE_OPT_MAN_FIELD_PRESENT
) {
1225 proto_tree_add_item(tree
, hf_zbee_zcl_gp_cmd_ms_manufacturer_code
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1226 mfr_code
= tvb_get_letohs(tvb
, offset
);
1230 tvb_len
= tvb_captured_length(tvb
);
1231 while (offset
< tvb_len
)
1233 /* Create subtree and parse attributes list. */
1234 subtree
= proto_tree_add_subtree_format(tree
, tvb
, offset
, -1, ett_zbee_nwk_clu_rec
, NULL
, "Cluster Record Request");
1236 /* Get cluster ID and add it into the subtree. */
1237 cluster_id
= tvb_get_letohs(tvb
, offset
);
1238 proto_tree_add_item(subtree
, hf_zbee_nwk_gp_zcl_attr_cluster_id
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1240 /* Get length of record list (number of attributes * 2). */
1241 record_list_len
= tvb_get_uint8(tvb
, offset
);
1242 proto_tree_add_item(subtree
, hf_zbee_nwk_gp_cmd_read_att_record_len
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
1245 for(i
=0 ; i
<record_list_len
; i
+=2)
1247 /* Dissect the attribute identifier */
1248 dissect_zcl_attr_id(tvb
, subtree
, &offset
, cluster_id
, mfr_code
, ZBEE_ZCL_FCF_TO_CLIENT
);
1252 } /* dissect_zbee_nwk_gp_cmd_read_attributes */
1254 * Dissector for ZigBee Green Power write attributes commands.
1256 *@param tvb pointer to buffer containing raw packet.
1257 *@param pinfo pointer to packet information fields.
1258 *@param tree pointer to data tree Wireshark uses to display packet.
1259 *@param packet packet data.
1260 *@param offset current payload offset.
1261 *@return payload processed offset.
1264 dissect_zbee_nwk_gp_cmd_write_attributes(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
,
1265 zbee_nwk_green_power_packet
*packet _U_
, unsigned offset
)
1267 uint8_t cr_options
= 0;
1268 proto_tree
*subtree
= NULL
;
1269 proto_tree
*att_tree
= NULL
;
1270 uint16_t mfr_code
= ZBEE_MFG_CODE_NONE
;
1271 uint16_t cluster_id
;
1272 uint8_t record_list_len
;
1278 static int * const options
[] = {
1279 &hf_zbee_nwk_gp_cmd_read_att_opt_multi_rec
,
1280 &hf_zbee_nwk_gp_cmd_read_att_opt_man_field_present
,
1284 /* Get Options Field, build subtree and display the results. */
1285 cr_options
= tvb_get_uint8(tvb
, offset
);
1286 proto_tree_add_bitmask(tree
, tvb
, offset
, hf_zbee_nwk_gp_cmd_read_att_opt
, ett_zbee_nwk_cmd_options
, options
, ENC_NA
);
1289 /* Parse and display manufacturer ID value. */
1290 if (cr_options
& ZBEE_NWK_GP_CMD_READ_ATTRIBUTE_OPT_MAN_FIELD_PRESENT
) {
1291 proto_tree_add_item(tree
, hf_zbee_zcl_gp_cmd_ms_manufacturer_code
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1292 mfr_code
= tvb_get_letohs(tvb
, offset
);
1296 tvb_len
= tvb_captured_length(tvb
);
1297 while (offset
< tvb_len
)
1299 /* Create subtree and parse attributes list. */
1300 subtree
= proto_tree_add_subtree_format(tree
, tvb
, offset
, -1, ett_zbee_nwk_clu_rec
, NULL
, "Write Cluster Record");
1302 /* Get cluster ID and add it into the subtree. */
1303 cluster_id
= tvb_get_letohs(tvb
, offset
);
1304 proto_tree_add_item(subtree
, hf_zbee_nwk_gp_zcl_attr_cluster_id
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1306 /* Get length of record list. */
1307 record_list_len
= tvb_get_uint8(tvb
, offset
);
1308 proto_tree_add_item(subtree
, hf_zbee_nwk_gp_cmd_read_att_record_len
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
1311 end_byte
= offset
+ record_list_len
;
1312 while ( offset
< end_byte
)
1314 /* Create subtree for attribute status field */
1315 att_tree
= proto_tree_add_subtree_format(subtree
, tvb
, offset
, 0, ett_zbee_nwk_att_rec
, NULL
, "Write Attribute record");
1317 /* Dissect the attribute identifier */
1318 attr_id
= tvb_get_letohs(tvb
, offset
);
1319 dissect_zcl_attr_id(tvb
, att_tree
, &offset
, cluster_id
, mfr_code
, ZBEE_ZCL_FCF_TO_CLIENT
);
1321 /* Dissect the attribute data type and data */
1322 dissect_zcl_attr_data_type_val(tvb
, att_tree
, &offset
, attr_id
, cluster_id
, mfr_code
, ZBEE_ZCL_FCF_TO_CLIENT
);
1326 } /* dissect_zbee_nwk_gp_cmd_write_attributes */
1330 * Dissector for ZigBee Green Power read attribute response command.
1332 *@param tvb pointer to buffer containing raw packet.
1333 *@param pinfo pointer to packet information fields.
1334 *@param tree pointer to data tree Wireshark uses to display packet.
1335 *@param packet packet data.
1336 *@param offset current payload offset.
1337 *@return payload processed offset.
1340 dissect_zbee_nwk_gp_cmd_read_attributes_response(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
,
1341 zbee_nwk_green_power_packet
*packet _U_
, unsigned offset
)
1344 proto_tree
*subtree
= NULL
;
1345 proto_tree
*att_tree
= NULL
;
1346 uint16_t cluster_id
;
1348 uint16_t mfr_code
= ZBEE_MFG_CODE_NONE
;
1349 uint8_t record_list_len
;
1353 static int * const options
[] = {
1354 &hf_zbee_nwk_gp_cmd_read_att_opt_multi_rec
,
1355 &hf_zbee_nwk_gp_cmd_read_att_opt_man_field_present
,
1359 /* Get Options Field, build subtree and display the results. */
1360 cr_options
= tvb_get_uint8(tvb
, offset
);
1361 proto_tree_add_bitmask(tree
, tvb
, offset
, hf_zbee_nwk_gp_cmd_read_att_opt
, ett_zbee_nwk_cmd_options
, options
, ENC_NA
);
1364 /* Parse and display manufacturer ID value. */
1365 if (cr_options
& ZBEE_NWK_GP_CMD_READ_ATTRIBUTE_OPT_MAN_FIELD_PRESENT
) {
1366 proto_tree_add_item(tree
, hf_zbee_zcl_gp_cmd_ms_manufacturer_code
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1367 mfr_code
= tvb_get_letohs(tvb
, offset
);
1371 tvb_len
= tvb_captured_length(tvb
);
1372 while (offset
< tvb_len
)
1374 /* Create subtree and parse attributes list. */
1375 subtree
= proto_tree_add_subtree_format(tree
, tvb
, offset
,0, ett_zbee_nwk_clu_rec
, NULL
, "Cluster record");
1377 /* Get cluster ID and add it into the subtree. */
1378 cluster_id
= tvb_get_letohs(tvb
, offset
);
1379 proto_tree_add_item(subtree
, hf_zbee_nwk_gp_zcl_attr_cluster_id
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1381 /* Get length of record list in bytes. */
1382 record_list_len
= tvb_get_uint8(tvb
, offset
);
1383 proto_tree_add_item(subtree
, hf_zbee_nwk_gp_cmd_read_att_record_len
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
1386 end_byte
= offset
+ record_list_len
;
1387 while ( offset
< end_byte
)
1389 /* Create subtree for attribute status field */
1390 /* TODO ett_ could be an array to permit not to unroll all always */
1391 att_tree
= proto_tree_add_subtree_format(subtree
, tvb
, offset
, 0, ett_zbee_nwk_att_rec
, NULL
, "Read Attribute record");
1393 /* Dissect the attribute identifier */
1394 attr_id
= tvb_get_letohs(tvb
, offset
);
1395 dissect_zcl_attr_id(tvb
, att_tree
, &offset
, cluster_id
, mfr_code
, ZBEE_ZCL_FCF_TO_CLIENT
);
1397 /* Dissect the status and optionally the data type and value */
1398 if (dissect_zcl_attr_uint8(tvb
, att_tree
, &offset
, &hf_zbee_nwk_gp_zcl_attr_status
)
1399 == ZBEE_ZCL_STAT_SUCCESS
)
1401 /* Dissect the attribute data type and data */
1402 dissect_zcl_attr_data_type_val(tvb
, att_tree
, &offset
, attr_id
, cluster_id
, mfr_code
, ZBEE_ZCL_FCF_TO_CLIENT
);
1406 /* Data type field is always present (not like in ZCL read attribute response command) */
1407 dissect_zcl_attr_data(tvb
, att_tree
, &offset
,
1408 dissect_zcl_attr_uint8(tvb
, att_tree
, &offset
, &hf_zbee_nwk_gp_zcl_attr_data_type
), ZBEE_ZCL_FCF_TO_CLIENT
);
1413 } /* dissect_zbee_nwk_gp_cmd_read_attributes_response */
1417 *Dissector for ZigBee Green Power multi-cluster reporting command.
1419 *@param tvb pointer to buffer containing raw packet.
1420 *@param pinfo pointer to packet information fields.
1421 *@param tree pointer to data tree Wireshark uses to display packet.
1422 *@param packet packet data.
1423 *@param offset current payload offset.
1424 *@param mfr_code manufacturer code.
1425 *@return payload processed offset.
1428 dissect_zbee_nwk_gp_cmd_multi_cluster_reporting(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
,
1429 zbee_nwk_green_power_packet
*packet _U_
, unsigned offset
, uint16_t mfr_code
)
1431 proto_tree
*subtree
= NULL
;
1432 uint16_t cluster_id
;
1436 tvb_len
= tvb_captured_length(tvb
);
1437 while (offset
< tvb_len
)
1439 /* Create subtree and parse attributes list. */
1440 subtree
= proto_tree_add_subtree_format(tree
, tvb
, offset
, 0, ett_zbee_nwk_clu_rec
, NULL
, "Cluster record"); //TODO for cluster %% blabla
1442 /* Get cluster ID and add it into the subtree. */
1443 cluster_id
= tvb_get_letohs(tvb
, offset
);
1444 proto_tree_add_item(subtree
, hf_zbee_nwk_gp_zcl_attr_cluster_id
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1447 /* Dissect the attribute identifier */
1448 attr_id
= tvb_get_letohs(tvb
, offset
);
1449 dissect_zcl_attr_id(tvb
, subtree
, &offset
, cluster_id
, mfr_code
, ZBEE_ZCL_FCF_TO_CLIENT
);
1451 /* Dissect the attribute data type and data */
1452 dissect_zcl_attr_data_type_val(tvb
, subtree
, &offset
, attr_id
, cluster_id
, mfr_code
, ZBEE_ZCL_FCF_TO_CLIENT
);
1453 // TODO how to dissect when data type is different from expected one for this attribute ? this shouldn't happen
1456 } /* dissect_zbee_nwk_gp_cmd_multi_cluster_reporting */
1460 *Dissector for ZigBee Green Power commands manufacturer specific attrib reporting.
1462 *@param tvb pointer to buffer containing raw packet.
1463 *@param pinfo pointer to packet information fields.
1464 *@param tree pointer to data tree Wireshark uses to display packet.
1465 *@param packet packet data.
1466 *@param offset current payload offset.
1467 *@return payload processed offset.
1470 dissect_zbee_nwk_gp_cmd_MS_multi_cluster_reporting(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
,
1471 zbee_nwk_green_power_packet
*packet _U_
, unsigned offset
)
1475 /*dissect manufacturer ID*/
1476 proto_tree_add_item(tree
, hf_zbee_zcl_gp_cmd_ms_manufacturer_code
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1477 mfr_code
= tvb_get_letohs(tvb
, offset
);
1480 offset
= dissect_zbee_nwk_gp_cmd_multi_cluster_reporting(tvb
, pinfo
, tree
, packet
, offset
, mfr_code
);
1483 }/*dissect_zbee_nwk_gp_cmd_MS_multi_cluster_reporting*/
1486 *Dissector for ZigBee Green Power Move Color.
1488 *@param tvb pointer to buffer containing raw packet.
1489 *@param pinfo pointer to packet information fields.
1490 *@param tree pointer to data tree Wireshark uses to display packet.
1491 *@param packet packet data.
1492 *@param offset current payload offset.
1493 *@return payload processed offset.
1496 dissect_zbee_nwk_gp_cmd_move_color(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
,
1497 zbee_nwk_green_power_packet
*packet _U_
, unsigned offset
)
1499 proto_tree_add_item(tree
, hf_zbee_nwk_gp_cmd_move_color_ratex
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1501 proto_tree_add_item(tree
, hf_zbee_nwk_gp_cmd_move_color_ratey
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1504 } /* dissect_zbee_nwk_gp_cmd_move_color */
1507 *Dissector for ZigBee Green Power Move Up/Down.
1509 *@param tvb pointer to buffer containing raw packet.
1510 *@param pinfo pointer to packet information fields.
1511 *@param tree pointer to data tree Wireshark uses to display packet.
1512 *@param packet packet data.
1513 *@param offset current payload offset.
1514 *@return payload processed offset.
1517 dissect_zbee_nwk_gp_cmd_move_up_down(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
,
1518 zbee_nwk_green_power_packet
*packet _U_
, unsigned offset
)
1520 /* Optional rate field. */
1521 if (tvb_reported_length(tvb
) - offset
>= 1) {
1522 proto_tree_add_item(tree
, hf_zbee_nwk_gp_cmd_move_up_down_rate
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
1526 } /* dissect_zbee_nwk_gp_cmd_move_up_down */
1529 *Dissector for ZigBee Green Power Step Color.
1531 *@param tvb pointer to buffer containing raw packet.
1532 *@param pinfo pointer to packet information fields.
1533 *@param tree pointer to data tree Wireshark uses to display packet.
1534 *@param packet packet data.
1535 *@param offset current payload offset.
1536 *@return payload processed offset.
1539 dissect_zbee_nwk_gp_cmd_step_color(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
,
1540 zbee_nwk_green_power_packet
*packet _U_
, unsigned offset
)
1542 proto_tree_add_item(tree
, hf_zbee_nwk_gp_cmd_step_color_stepx
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1544 proto_tree_add_item(tree
, hf_zbee_nwk_gp_cmd_step_color_stepy
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1546 /* Optional time field. */
1547 if (tvb_reported_length(tvb
) - offset
>= 2) {
1548 proto_tree_add_item(tree
, hf_zbee_nwk_gp_cmd_step_color_transition_time
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1552 } /* dissect_zbee_nwk_gp_cmd_step_color */
1555 *Dissector for ZigBee Green Power Step Up/Down.
1557 *@param tvb pointer to buffer containing raw packet.
1558 *@param pinfo pointer to packet information fields.
1559 *@param tree pointer to data tree Wireshark uses to display packet.
1560 *@param packet packet data.
1561 *@param offset current payload offset.
1562 *@return payload processed offset.
1565 dissect_zbee_nwk_gp_cmd_step_up_down(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
,
1566 zbee_nwk_green_power_packet
*packet _U_
, unsigned offset
)
1568 proto_tree_add_item(tree
, hf_zbee_nwk_gp_cmd_step_up_down_step_size
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
1570 /* Optional time field. */
1571 if (tvb_reported_length(tvb
) - offset
>= 2) {
1572 proto_tree_add_item(tree
, hf_zbee_nwk_gp_cmd_step_up_down_transition_time
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1576 } /* dissect_zbee_nwk_gp_cmd_step_up_down */
1579 *Dissector for ZigBee Green Power commands.
1581 *@param tvb pointer to buffer containing raw packet.
1582 *@param pinfo pointer to packet information fields.
1583 *@param tree pointer to data tree Wireshark uses to display packet.
1584 *@param data raw packet private data.
1585 *@return payload processed offset
1588 dissect_zbee_nwk_gp_cmd(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data
)
1590 unsigned offset
= 0;
1591 uint8_t cmd_id
= tvb_get_uint8(tvb
, offset
);
1592 proto_item
*cmd_root
;
1593 proto_tree
*cmd_tree
;
1594 zbee_nwk_green_power_packet
*packet
= (zbee_nwk_green_power_packet
*)data
;
1596 /* Create a subtree for the command. */
1597 cmd_tree
= proto_tree_add_subtree_format(tree
, tvb
, offset
, -1, ett_zbee_nwk_cmd
, &cmd_root
,
1598 "Command Frame: %s", val_to_str_ext_const(cmd_id
,
1599 &zbee_nwk_gp_cmd_names_ext
,
1600 "Unknown Command Frame"));
1601 /* Add the command ID. */
1602 proto_tree_add_uint(cmd_tree
, hf_zbee_nwk_gp_command_id
, tvb
, offset
, 1, cmd_id
);
1605 /* Add the command name to the info column. */
1606 col_set_str(pinfo
->cinfo
, COL_INFO
, val_to_str_ext_const(cmd_id
, &zbee_nwk_gp_cmd_names_ext
, "Unknown command"));
1607 /* Handle the command for one of the following devices:
1608 * - Door Lock Controller (IDs: 0x50 - 0x51);
1609 * - GP Flow Sensor (IDs: 0xE0, 0xA0 - 0xA3);
1610 * - GP Temperature Sensor (IDs: 0xE0, 0xA0 - 0xA3); */
1612 /* Payloadless GPDF commands sent by GPD. */
1613 case ZB_GP_CMD_ID_IDENTIFY
:
1614 case ZB_GP_CMD_ID_RECALL_SCENE0
:
1615 case ZB_GP_CMD_ID_RECALL_SCENE1
:
1616 case ZB_GP_CMD_ID_RECALL_SCENE2
:
1617 case ZB_GP_CMD_ID_RECALL_SCENE3
:
1618 case ZB_GP_CMD_ID_RECALL_SCENE4
:
1619 case ZB_GP_CMD_ID_RECALL_SCENE5
:
1620 case ZB_GP_CMD_ID_RECALL_SCENE6
:
1621 case ZB_GP_CMD_ID_RECALL_SCENE7
:
1622 case ZB_GP_CMD_ID_STORE_SCENE0
:
1623 case ZB_GP_CMD_ID_STORE_SCENE1
:
1624 case ZB_GP_CMD_ID_STORE_SCENE2
:
1625 case ZB_GP_CMD_ID_STORE_SCENE3
:
1626 case ZB_GP_CMD_ID_STORE_SCENE4
:
1627 case ZB_GP_CMD_ID_STORE_SCENE5
:
1628 case ZB_GP_CMD_ID_STORE_SCENE6
:
1629 case ZB_GP_CMD_ID_STORE_SCENE7
:
1630 case ZB_GP_CMD_ID_OFF
:
1631 case ZB_GP_CMD_ID_ON
:
1632 case ZB_GP_CMD_ID_TOGGLE
:
1633 case ZB_GP_CMD_ID_RELEASE
:
1634 case ZB_GP_CMD_ID_LEVEL_CONTROL_STOP
:
1635 case ZB_GP_CMD_ID_MOVE_HUE_STOP
:
1636 case ZB_GP_CMD_ID_MOVE_SATURATION_STOP
:
1637 case ZB_GP_CMD_ID_LOCK_DOOR
:
1638 case ZB_GP_CMD_ID_UNLOCK_DOOR
:
1639 case ZB_GP_CMD_ID_PRESS11
:
1640 case ZB_GP_CMD_ID_RELEASE11
:
1641 case ZB_GP_CMD_ID_PRESS12
:
1642 case ZB_GP_CMD_ID_RELEASE12
:
1643 case ZB_GP_CMD_ID_PRESS22
:
1644 case ZB_GP_CMD_ID_RELEASE22
:
1645 case ZB_GP_CMD_ID_SHORT_PRESS11
:
1646 case ZB_GP_CMD_ID_SHORT_PRESS12
:
1647 case ZB_GP_CMD_ID_SHORT_PRESS22
:
1648 case ZB_GP_CMD_ID_DECOMMISSIONING
:
1649 case ZB_GP_CMD_ID_SUCCESS
:
1651 /* GPDF commands with payload sent by GPD. */
1652 case ZB_GP_CMD_ID_MOVE_UP
:
1653 case ZB_GP_CMD_ID_MOVE_DOWN
:
1654 case ZB_GP_CMD_ID_MOVE_UP_WITH_ON_OFF
:
1655 case ZB_GP_CMD_ID_MOVE_DOWN_WITH_ON_OFF
:
1656 case ZB_GP_CMD_ID_MOVE_HUE_UP
:
1657 case ZB_GP_CMD_ID_MOVE_HUE_DOWN
:
1658 case ZB_GP_CMD_ID_MOVE_SATURATION_UP
:
1659 case ZB_GP_CMD_ID_MOVE_SATURATION_DOWN
:
1660 offset
= dissect_zbee_nwk_gp_cmd_move_up_down(tvb
, pinfo
, cmd_tree
, packet
, offset
);
1662 case ZB_GP_CMD_ID_STEP_UP
:
1663 case ZB_GP_CMD_ID_STEP_DOWN
:
1664 case ZB_GP_CMD_ID_STEP_UP_WITH_ON_OFF
:
1665 case ZB_GP_CMD_ID_STEP_DOWN_WITH_ON_OFF
:
1666 case ZB_GP_CMD_ID_STEP_HUE_UP
:
1667 case ZB_GP_CMD_ID_STEP_HUW_DOWN
:
1668 case ZB_GP_CMD_ID_STEP_SATURATION_UP
:
1669 case ZB_GP_CMD_ID_STEP_SATURATION_DOWN
:
1670 offset
= dissect_zbee_nwk_gp_cmd_step_up_down(tvb
, pinfo
, cmd_tree
, packet
, offset
);
1672 case ZB_GP_CMD_ID_MOVE_COLOR
:
1673 offset
= dissect_zbee_nwk_gp_cmd_move_color(tvb
, pinfo
, cmd_tree
, packet
, offset
);
1675 case ZB_GP_CMD_ID_STEP_COLOR
:
1676 offset
= dissect_zbee_nwk_gp_cmd_step_color(tvb
, pinfo
, cmd_tree
, packet
, offset
);
1678 case ZB_GP_CMD_ID_ATTRIBUTE_REPORTING
:
1679 offset
= dissect_zbee_nwk_gp_cmd_attr_reporting(tvb
, pinfo
, cmd_tree
, packet
, offset
, ZBEE_MFG_CODE_NONE
);
1681 case ZB_GP_CMD_ID_MANUFACTURE_SPECIFIC_ATTR_REPORTING
:
1682 offset
= dissect_zbee_nwk_gp_cmd_MS_attr_reporting(tvb
, pinfo
, cmd_tree
, packet
, offset
);
1684 case ZB_GP_CMD_ID_MULTI_CLUSTER_REPORTING
:
1685 offset
= dissect_zbee_nwk_gp_cmd_multi_cluster_reporting(tvb
, pinfo
, cmd_tree
, packet
, offset
, ZBEE_MFG_CODE_NONE
);
1687 case ZB_GP_CMD_ID_MANUFACTURER_SPECIFIC_MCLUSTER_REPORTING
:
1688 offset
= dissect_zbee_nwk_gp_cmd_MS_multi_cluster_reporting(tvb
, pinfo
, cmd_tree
, packet
, offset
);
1690 case ZB_GP_CMD_ID_READ_ATTRIBUTES_RESPONSE
:
1691 offset
= dissect_zbee_nwk_gp_cmd_read_attributes_response(tvb
, pinfo
, cmd_tree
, packet
, offset
);
1693 case ZB_GP_CMD_ID_ANY_SENSOR_COMMAND_A0_A3
:
1694 /* TODO: implement it. */
1696 case ZB_GP_CMD_ID_COMMISSIONING
:
1697 offset
= dissect_zbee_nwk_gp_cmd_commissioning(tvb
, pinfo
, cmd_tree
, packet
, offset
);
1699 case ZB_GP_CMD_ID_CHANNEL_REQUEST
:
1700 offset
= dissect_zbee_nwk_gp_cmd_channel_request(tvb
, pinfo
, cmd_tree
, packet
, offset
);
1702 case ZB_GP_CMD_ID_REQUEST_ATTRIBUTES
:
1703 /* GPDF commands sent to GPD. */
1704 case ZB_GP_CMD_ID_READ_ATTRIBUTES
:
1705 offset
= dissect_zbee_nwk_gp_cmd_read_attributes(tvb
, pinfo
, cmd_tree
, packet
, offset
);
1707 case ZB_GP_CMD_ID_COMMISSIONING_REPLY
:
1708 offset
= dissect_zbee_nwk_gp_cmd_commissioning_reply(tvb
, pinfo
, cmd_tree
, packet
, offset
);
1710 case ZB_GP_CMD_ID_WRITE_ATTRIBUTES
:
1711 offset
= dissect_zbee_nwk_gp_cmd_write_attributes(tvb
, pinfo
, cmd_tree
, packet
, offset
);
1713 case ZB_GP_CMD_ID_CHANNEL_CONFIGURATION
:
1714 offset
= dissect_zbee_nwk_gp_cmd_channel_configuration(tvb
, pinfo
, cmd_tree
, packet
, offset
);
1717 if (offset
< tvb_reported_length(tvb
)) {
1718 /* There are leftover bytes! */
1720 tvbuff_t
*leftover_tvb
= tvb_new_subset_remaining(tvb
, offset
);
1722 /* Correct the length of the command tree. */
1723 root
= proto_tree_get_root(tree
);
1724 proto_item_set_len(cmd_root
, offset
);
1726 /* Dump the tail. */
1727 call_data_dissector(leftover_tvb
, pinfo
, root
);
1730 } /* dissect_zbee_nwk_gp_cmd */
1733 *ZigBee NWK packet dissection routine for Green Power profile.
1735 *@param tvb pointer to buffer containing raw packet.
1736 *@param pinfo pointer to packet information fields.
1737 *@param tree pointer to data tree Wireshark uses to display packet.
1738 *@param data raw packet private data.
1741 dissect_zbee_nwk_gp(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data
)
1743 ieee802154_packet
*ieee_packet
= (ieee802154_packet
*)data
;
1746 unsigned offset
= 0;
1747 uint8_t *dec_buffer
;
1748 uint8_t *enc_buffer
;
1750 proto_tree
*nwk_tree
;
1751 proto_item
*proto_root
;
1752 proto_item
*ti
= NULL
;
1753 tvbuff_t
*payload_tvb
;
1754 zbee_nwk_green_power_packet packet
;
1755 static int * const fields
[] = {
1756 &hf_zbee_nwk_gp_frame_type
,
1757 &hf_zbee_nwk_gp_proto_version
,
1758 &hf_zbee_nwk_gp_auto_commissioning
,
1759 &hf_zbee_nwk_gp_fc_ext
,
1762 static int * const ext_fields
[] = {
1763 &hf_zbee_nwk_gp_fc_ext_app_id
,
1764 &hf_zbee_nwk_gp_fc_ext_sec_level
,
1765 &hf_zbee_nwk_gp_fc_ext_sec_key
,
1766 &hf_zbee_nwk_gp_fc_ext_rx_after_tx
,
1767 &hf_zbee_nwk_gp_fc_ext_direction
,
1774 memset(&packet
, 0, sizeof(packet
));
1775 packet
.ieee_packet_src64
= ieee_packet
->src64
;
1776 /* Add ourself to the protocol column, clear the info column and create the protocol tree. */
1777 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "ZigBee Green Power");
1778 col_clear(pinfo
->cinfo
, COL_INFO
);
1780 proto_root
= proto_tree_add_protocol_format(tree
, proto_zbee_nwk_gp
, tvb
, offset
, tvb_captured_length(tvb
),
1781 "ZGP stub NWK header");
1782 nwk_tree
= proto_item_add_subtree(proto_root
, ett_zbee_nwk
);
1784 enc_buffer
= (uint8_t *)tvb_memdup(pinfo
->pool
, tvb
, 0, tvb_captured_length(tvb
));
1785 /* Get and parse the FCF. */
1786 fcf
= tvb_get_uint8(tvb
, offset
);
1787 packet
.frame_type
= zbee_get_bit_field(fcf
, ZBEE_NWK_GP_FCF_FRAME_TYPE
);
1788 packet
.nwk_frame_control_extension
= zbee_get_bit_field(fcf
, ZBEE_NWK_GP_FCF_CONTROL_EXTENSION
);
1790 /* Display the FCF. */
1791 ti
= proto_tree_add_bitmask(nwk_tree
, tvb
, offset
, hf_zbee_nwk_gp_fcf
, ett_zbee_nwk_fcf
, fields
, ENC_NA
);
1792 proto_item_append_text(ti
, " %s", val_to_str_const(packet
.frame_type
, zbee_nwk_gp_frame_types
, "Unknown Frame Type"));
1795 /* Add the frame type to the info column and protocol root. */
1796 proto_item_append_text(proto_root
, " %s", val_to_str_const(packet
.frame_type
, zbee_nwk_gp_frame_types
, "Unknown type"));
1797 col_set_str(pinfo
->cinfo
, COL_INFO
, val_to_str_const(packet
.frame_type
, zbee_nwk_gp_frame_types
, "Reserved frame type"));
1799 if (packet
.nwk_frame_control_extension
) {
1800 /* Display ext FCF. */
1801 fcf
= tvb_get_uint8(tvb
, offset
);
1802 packet
.application_id
= zbee_get_bit_field(fcf
, ZBEE_NWK_GP_FCF_EXT_APP_ID
);
1803 packet
.security_level
= zbee_get_bit_field(fcf
, ZBEE_NWK_GP_FCF_EXT_SECURITY_LEVEL
);
1804 packet
.direction
= zbee_get_bit_field(fcf
, ZBEE_NWK_GP_FCF_EXT_DIRECTION
);
1806 /* Create a subtree for the extended FCF. */
1807 proto_tree_add_bitmask(nwk_tree
, tvb
, offset
, hf_zbee_nwk_gp_fc_ext_field
, ett_zbee_nwk_fcf_ext
, ext_fields
, ENC_NA
);
1810 if ((packet
.frame_type
== ZBEE_NWK_GP_FCF_DATA
&& !packet
.nwk_frame_control_extension
) || (packet
.frame_type
==
1811 ZBEE_NWK_GP_FCF_DATA
&& packet
.nwk_frame_control_extension
&& packet
.application_id
==
1812 ZBEE_NWK_GP_APP_ID_DEFAULT
) || (packet
.frame_type
== ZBEE_NWK_GP_FCF_MAINTENANCE
&&
1813 packet
.nwk_frame_control_extension
&& packet
.application_id
== ZBEE_NWK_GP_APP_ID_DEFAULT
&& tvb_get_uint8(tvb
,
1814 offset
) != ZB_GP_CMD_ID_CHANNEL_CONFIGURATION
)) {
1815 /* Display GPD Src ID. */
1816 packet
.source_id
= tvb_get_letohl(tvb
, offset
);
1817 proto_tree_add_item(nwk_tree
, hf_zbee_nwk_gp_zgpd_src_id
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1818 proto_item_append_text(proto_root
, ", GPD Src ID: 0x%08x", packet
.source_id
);
1820 col_append_fstr(pinfo
->cinfo
, COL_INFO
, ", GPD Src ID: 0x%08x", packet
.source_id
);
1822 col_clear(pinfo
->cinfo
, COL_DEF_SRC
);
1823 col_append_fstr(pinfo
->cinfo
, COL_DEF_SRC
, "0x%08x", packet
.source_id
);
1827 if (packet
.application_id
== ZBEE_NWK_GP_APP_ID_ZGP
) {
1828 /* Display GPD endpoint */
1829 packet
.endpoint
= tvb_get_uint8(tvb
, offset
);
1830 proto_tree_add_item(nwk_tree
, hf_zbee_nwk_gp_zgpd_endpoint
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
1831 proto_item_append_text(proto_root
, ", Endpoint: %d", packet
.endpoint
);
1833 col_append_fstr(pinfo
->cinfo
, COL_INFO
, ", Endpoint: %d", packet
.endpoint
);
1836 /* Display Security Frame Counter. */
1837 packet
.mic_size
= 0;
1838 if (packet
.nwk_frame_control_extension
) {
1839 if (packet
.application_id
== ZBEE_NWK_GP_APP_ID_DEFAULT
|| packet
.application_id
== ZBEE_NWK_GP_APP_ID_ZGP
1840 || packet
.application_id
== ZBEE_NWK_GP_APP_ID_LPED
) {
1841 if (packet
.security_level
== ZBEE_NWK_GP_SECURITY_LEVEL_1LSB
1842 && packet
.application_id
!= ZBEE_NWK_GP_APP_ID_LPED
) {
1843 packet
.mic_size
= 2;
1844 } else if (packet
.security_level
== ZBEE_NWK_GP_SECURITY_LEVEL_FULL
|| packet
.security_level
==
1845 ZBEE_NWK_GP_SECURITY_LEVEL_FULLENCR
) {
1846 /* Get Security Frame Counter and display it. */
1847 packet
.mic_size
= 4;
1848 packet
.security_frame_counter
= tvb_get_letohl(tvb
, offset
);
1849 proto_tree_add_item(nwk_tree
, hf_zbee_nwk_gp_security_frame_counter
, tvb
, offset
, 4,
1855 /* Parse application payload. */
1856 /* This is a uint8_t, but tvb_reported_length might be larger; e.g.,
1857 * SCOP over TCP, presumably with errors. It's bogus either way; perhaps
1860 packet
.payload_len
= tvb_reported_length(tvb
) - offset
- packet
.mic_size
;
1861 /* Ensure that the payload exists. */
1862 if (packet
.payload_len
<= 0) {
1863 proto_tree_add_expert(nwk_tree
, pinfo
, &ei_zbee_nwk_gp_no_payload
, tvb
, 0, -1);
1866 /* OK, payload exists. Parse MIC field if needed. */
1867 if (packet
.mic_size
== 2) {
1868 packet
.mic
= tvb_get_letohs(tvb
, offset
+ packet
.payload_len
);
1869 } else if (packet
.mic_size
== 4) {
1870 packet
.mic
= tvb_get_letohl(tvb
, offset
+ packet
.payload_len
);
1872 /* Save packet private data. */
1873 data
= (void *)&packet
;
1874 payload_tvb
= tvb_new_subset_length(tvb
, offset
, packet
.payload_len
);
1875 if (packet
.security_level
!= ZBEE_NWK_GP_SECURITY_LEVEL_FULLENCR
) {
1876 dissect_zbee_nwk_gp_cmd(payload_tvb
, pinfo
, nwk_tree
, data
);
1878 offset
+= packet
.payload_len
;
1879 /* Display MIC field. */
1880 if (packet
.mic_size
) {
1881 proto_tree_add_uint(nwk_tree
, packet
.mic_size
== 4 ? hf_zbee_nwk_gp_security_mic_4b
:
1882 hf_zbee_nwk_gp_security_mic_2b
, tvb
, offset
, packet
.mic_size
, packet
.mic
);
1883 offset
+= packet
.mic_size
;
1885 if ((offset
< tvb_captured_length(tvb
)) && (packet
.security_level
!= ZBEE_NWK_GP_SECURITY_LEVEL_FULLENCR
)) {
1886 proto_tree_add_expert(nwk_tree
, pinfo
, &ei_zbee_nwk_gp_inval_residual_data
, tvb
, offset
, -1);
1889 if (packet
.security_level
== ZBEE_NWK_GP_SECURITY_LEVEL_FULLENCR
) {
1890 gp_decrypted
= false;
1892 if (tvb_captured_length(tvb
) >= tvb_reported_length(tvb
)) {
1893 dec_buffer
= (uint8_t *)wmem_alloc(pinfo
->pool
, packet
.payload_len
);
1894 for (GSList_i
= zbee_gp_keyring
; GSList_i
&& !gp_decrypted
; GSList_i
= g_slist_next(GSList_i
)) {
1895 gp_decrypted
= zbee_gp_decrypt_payload(&packet
, enc_buffer
, offset
- packet
.payload_len
-
1896 packet
.mic_size
, dec_buffer
, packet
.payload_len
, packet
.mic_size
,
1897 ((key_record_t
*)(GSList_i
->data
))->key
);
1902 payload_tvb
= tvb_new_child_real_data(tvb
, dec_buffer
, packet
.payload_len
, packet
.payload_len
);
1903 add_new_data_source(pinfo
, payload_tvb
, "Decrypted GP Payload");
1904 dissect_zbee_nwk_gp_cmd(payload_tvb
, pinfo
, nwk_tree
, data
);
1906 payload_tvb
= tvb_new_subset_length_caplen(tvb
, offset
- packet
.payload_len
- packet
.mic_size
, packet
.payload_len
, -1);
1907 call_data_dissector(payload_tvb
, pinfo
, tree
);
1910 return tvb_captured_length(tvb
);
1911 } /* dissect_zbee_nwk_gp */
1914 *Heuristic interpreter for the ZigBee Green Power dissectors.
1916 *@param tvb pointer to buffer containing raw packet.
1917 *@param pinfo pointer to packet information fields.
1918 *@param tree pointer to data tree Wireshark uses to display packet.
1919 *@param data raw packet private data.
1922 dissect_zbee_nwk_heur_gp(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data
)
1924 ieee802154_packet
*packet
= (ieee802154_packet
*)data
;
1927 /* We must have the IEEE 802.15.4 headers. */
1928 if (packet
== NULL
) return false;
1929 /* ZigBee green power never uses 16-bit source addresses. */
1930 if (packet
->src_addr_mode
== IEEE802154_FCF_ADDR_SHORT
) return false;
1932 /* If the frame type and version are not sane, then it's probably not ZGP. */
1933 fcf
= tvb_get_uint8(tvb
, 0);
1934 if (zbee_get_bit_field(fcf
, ZBEE_NWK_GP_FCF_VERSION
) != ZBEE_VERSION_GREEN_POWER
) return false;
1935 if (!try_val_to_str(zbee_get_bit_field(fcf
, ZBEE_NWK_FCF_FRAME_TYPE
), zbee_nwk_gp_frame_types
)) return false;
1937 /* ZigBee greenpower frames are either sent to broadcast or the extended address. */
1938 if (packet
->dst_addr_mode
== IEEE802154_FCF_ADDR_SHORT
&& packet
->dst16
== IEEE802154_BCAST_ADDR
) {
1939 dissect_zbee_nwk_gp(tvb
, pinfo
, tree
, data
);
1942 /* 64-bit destination addressing mode support. */
1943 if (packet
->dst_addr_mode
== IEEE802154_FCF_ADDR_EXT
) {
1944 dissect_zbee_nwk_gp(tvb
, pinfo
, tree
, data
);
1949 } /* dissect_zbee_nwk_heur_gp */
1952 *Init routine for the ZigBee GP profile security.
1956 gp_init_zbee_security(void)
1959 key_record_t key_record
;
1961 for (i
= 0; gp_uat_key_records
&& (i
< num_uat_key_records
); i
++) {
1962 key_record
.frame_num
= 0;
1963 key_record
.label
= g_strdup(gp_uat_key_records
[i
].label
);
1964 memcpy(key_record
.key
, gp_uat_key_records
[i
].key
, ZBEE_SEC_CONST_KEYSIZE
);
1965 zbee_gp_keyring
= g_slist_prepend(zbee_gp_keyring
, g_memdup2(&key_record
, sizeof(key_record_t
)));
1969 static void zbee_free_key_record(void *ptr
)
1973 k
= (key_record_t
*)ptr
;
1982 gp_cleanup_zbee_security(void)
1984 if (!zbee_gp_keyring
)
1987 g_slist_free_full(zbee_gp_keyring
, zbee_free_key_record
);
1988 zbee_gp_keyring
= NULL
;
1992 *ZigBee NWK GP protocol registration routine.
1996 proto_register_zbee_nwk_gp(void)
1998 module_t
*gp_zbee_prefs
;
1999 expert_module_t
* expert_zbee_nwk_gp
;
2001 static hf_register_info hf
[] = {
2002 { &hf_zbee_nwk_gp_auto_commissioning
,
2003 { "Auto Commissioning", "zbee_nwk_gp.auto_commissioning", FT_BOOLEAN
, 8, NULL
,
2004 ZBEE_NWK_GP_FCF_AUTO_COMMISSIONING
, NULL
, HFILL
}},
2006 { &hf_zbee_nwk_gp_fc_ext
,
2007 { "NWK Frame Extension", "zbee_nwk_gp.fc_extension", FT_BOOLEAN
, 8, NULL
, ZBEE_NWK_GP_FCF_CONTROL_EXTENSION
,
2010 { &hf_zbee_nwk_gp_fcf
,
2011 { "Frame Control Field", "zbee_nwk_gp.fcf", FT_UINT8
, BASE_HEX
, NULL
,
2012 0x0, NULL
, HFILL
}},
2014 { &hf_zbee_nwk_gp_frame_type
,
2015 { "Frame Type", "zbee_nwk_gp.frame_type", FT_UINT8
, BASE_HEX
, VALS(zbee_nwk_gp_frame_types
),
2016 ZBEE_NWK_GP_FCF_FRAME_TYPE
, NULL
, HFILL
}},
2018 { &hf_zbee_nwk_gp_proto_version
,
2019 { "Protocol Version", "zbee_nwk_gp.proto_version", FT_UINT8
, BASE_DEC
, NULL
, ZBEE_NWK_GP_FCF_VERSION
, NULL
,
2022 { &hf_zbee_nwk_gp_fc_ext_field
,
2023 { "Extended NWK Frame Control Field", "zbee_nwk_gp.fc_ext", FT_UINT8
, BASE_HEX
, NULL
,
2024 0x0, NULL
, HFILL
}},
2026 { &hf_zbee_nwk_gp_fc_ext_app_id
,
2027 { "Application ID", "zbee_nwk_gp.fc_ext_app_id", FT_UINT8
, BASE_HEX
, VALS(zbee_nwk_gp_app_id_names
),
2028 ZBEE_NWK_GP_FCF_EXT_APP_ID
, NULL
, HFILL
}},
2030 { &hf_zbee_nwk_gp_fc_ext_direction
,
2031 { "Direction", "zbee_nwk_gp.fc_ext_direction", FT_UINT8
, BASE_HEX
, VALS(zbee_nwk_gp_directions
),
2032 ZBEE_NWK_GP_FCF_EXT_DIRECTION
, NULL
, HFILL
}},
2034 { &hf_zbee_nwk_gp_fc_ext_rx_after_tx
,
2035 { "Rx After Tx", "zbee_nwk_gp.fc_ext_rxaftertx", FT_BOOLEAN
, 8, NULL
, ZBEE_NWK_GP_FCF_EXT_RX_AFTER_TX
, NULL
,
2038 { &hf_zbee_nwk_gp_fc_ext_sec_key
,
2039 { "Security Key", "zbee_nwk_gp.fc_ext_security_key", FT_BOOLEAN
, 8, NULL
, ZBEE_NWK_GP_FCF_EXT_SECURITY_KEY
,
2042 { &hf_zbee_nwk_gp_fc_ext_sec_level
,
2043 { "Security Level", "zbee_nwk_gp.fc_ext_security_level", FT_UINT8
, BASE_HEX
,
2044 VALS(zbee_nwk_gp_src_sec_levels_names
), ZBEE_NWK_GP_FCF_EXT_SECURITY_LEVEL
, NULL
, HFILL
}},
2046 { &hf_zbee_nwk_gp_zgpd_src_id
,
2047 { "Src ID", "zbee_nwk_gp.source_id", FT_UINT32
, BASE_HEX
, VALS(zbee_nwk_gp_src_id_names
), 0x0, NULL
,
2050 { &hf_zbee_nwk_gp_zgpd_endpoint
,
2051 { "Endpoint", "zbee_nwk_gp.endpoint", FT_UINT8
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
2053 { &hf_zbee_nwk_gp_security_frame_counter
,
2054 { "Security Frame Counter", "zbee_nwk_gp.security_frame_counter", FT_UINT32
, BASE_DEC
, NULL
, 0x0, NULL
,
2057 { &hf_zbee_nwk_gp_security_mic_2b
,
2058 { "Security MIC", "zbee_nwk_gp.security_mic2", FT_UINT16
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
}},
2060 { &hf_zbee_nwk_gp_security_mic_4b
,
2061 { "Security MIC", "zbee_nwk_gp.security_mic4", FT_UINT32
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
}},
2063 { &hf_zbee_nwk_gp_command_id
,
2064 { "ZGPD Command ID", "zbee_nwk_gp.command_id", FT_UINT8
, BASE_HEX
| BASE_EXT_STRING
, &zbee_nwk_gp_cmd_names_ext
, 0x0, NULL
,
2067 { &hf_zbee_nwk_gp_cmd_comm_device_id
,
2068 { "ZGPD Device ID", "zbee_nwk_gp.cmd.comm.dev_id", FT_UINT8
, BASE_HEX
| BASE_EXT_STRING
, &zbee_nwk_gp_device_ids_names_ext
,
2069 0x0, NULL
, HFILL
}},
2071 { &hf_zbee_nwk_gp_cmd_comm_ext_opt_gpd_key_encr
,
2072 { "GPD Key Encryption", "zbee_nwk_gp.cmd.comm.ext_opt.gpd_key_encr", FT_BOOLEAN
, 8, NULL
,
2073 ZBEE_NWK_GP_CMD_COMMISSIONING_EXT_OPT_GPD_KEY_ENCR
, NULL
, HFILL
}},
2075 { &hf_zbee_nwk_gp_cmd_comm_ext_opt_gpd_key_present
,
2076 { "GPD Key Present", "zbee_nwk_gp.cmd.comm.ext_opt.gpd_key_present", FT_BOOLEAN
, 8, NULL
,
2077 ZBEE_NWK_GP_CMD_COMMISSIONING_EXT_OPT_GPD_KEY_PRESENT
, NULL
, HFILL
}},
2079 { &hf_zbee_nwk_gp_cmd_comm_ext_opt_key_type
,
2080 { "Key Type", "zbee_nwk_gp.cmd.comm.ext_opt.key_type", FT_UINT8
, BASE_HEX
,
2081 VALS(zbee_nwk_gp_src_sec_keys_type_names
), ZBEE_NWK_GP_CMD_COMMISSIONING_EXT_OPT_KEY_TYPE
, NULL
,
2084 { &hf_zbee_nwk_gp_cmd_comm_outgoing_counter
,
2085 { "GPD Outgoing Counter", "zbee_nwk_gp.cmd.comm.out_counter", FT_UINT32
, BASE_HEX
, NULL
, 0x0, NULL
,
2088 { &hf_zbee_nwk_gp_cmd_comm_ext_opt_sec_level_cap
,
2089 { "Security Level Capabilities", "zbee_nwk_gp.cmd.comm.ext_opt.seclevel_cap", FT_UINT8
, BASE_HEX
, NULL
,
2090 ZBEE_NWK_GP_CMD_COMMISSIONING_EXT_OPT_SEC_LEVEL_CAP
, NULL
, HFILL
}},
2092 { &hf_zbee_nwk_gp_cmd_comm_security_key
,
2093 { "Security Key", "zbee_nwk_gp.cmd.comm.security_key", FT_BYTES
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
2095 { &hf_zbee_nwk_gp_cmd_comm_gpd_sec_key_mic
,
2096 { "GPD Key MIC", "zbee_nwk_gp.cmd.comm.gpd_key_mic", FT_UINT32
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
}},
2098 { &hf_zbee_nwk_gp_cmd_comm_opt_ext_opt
,
2099 { "Extended Option Field", "zbee_nwk_gp.cmd.comm.opt.ext_opt_field", FT_BOOLEAN
, 8, NULL
,
2100 ZBEE_NWK_GP_CMD_COMMISSIONING_OPT_EXT_OPTIONS
, NULL
, HFILL
}},
2102 { &hf_zbee_nwk_gp_cmd_comm_opt
,
2103 { "Options Field", "zbee_nwk_gp.cmd.comm.opt", FT_UINT8
, BASE_HEX
, NULL
,
2104 0x0, NULL
, HFILL
}},
2106 { &hf_zbee_nwk_gp_cmd_comm_opt_fixed_location
,
2107 { "Fixed Location", "zbee_nwk_gp.cmd.comm.opt.fixed_location", FT_BOOLEAN
, 8, NULL
,
2108 ZBEE_NWK_GP_CMD_COMMISSIONING_OPT_FIXED_LOCATION
, NULL
, HFILL
}},
2110 { &hf_zbee_nwk_gp_cmd_comm_opt_mac_sec_num_cap
,
2111 { "MAC Sequence number capability", "zbee_nwk_gp.cmd.comm.opt.mac_seq_num_cap", FT_BOOLEAN
, 8, NULL
,
2112 ZBEE_NWK_GP_CMD_COMMISSIONING_OPT_MAC_SEQ
, NULL
, HFILL
}},
2114 { &hf_zbee_nwk_gp_cmd_comm_opt_appli_info_present
,
2115 { "Application information present", "zbee_nwk_gp.cmd.comm.opt.appli_info_present", FT_BOOLEAN
, 8, NULL
,
2116 ZBEE_NWK_GP_CMD_COMMISSIONING_OPT_APPLICATION_INFO
, NULL
, HFILL
}},
2118 { &hf_zbee_nwk_gp_cmd_comm_opt_panid_req
,
2119 { "PANId request", "zbee_nwk_gp.cmd.comm.opt.panid_req", FT_BOOLEAN
, 8, NULL
,
2120 ZBEE_NWK_GP_CMD_COMMISSIONING_OPT_PAN_ID_REQ
, NULL
, HFILL
}},
2122 { &hf_zbee_nwk_gp_cmd_comm_opt_rx_on_cap
,
2123 { "RxOnCapability", "zbee_nwk_gp.cmd.comm.opt.rxon_cap", FT_BOOLEAN
, 8, NULL
,
2124 ZBEE_NWK_GP_CMD_COMMISSIONING_OPT_RX_ON_CAP
, NULL
, HFILL
}},
2126 { &hf_zbee_nwk_gp_cmd_comm_opt_sec_key_req
,
2127 { "GP Security Key Request", "zbee_nwk_gp.cmd.comm.opt.seq_key_req", FT_BOOLEAN
, 8, NULL
,
2128 ZBEE_NWK_GP_CMD_COMMISSIONING_OPT_GP_SEC_KEY_REQ
, NULL
, HFILL
}},
2130 { &hf_zbee_nwk_gp_cmd_comm_ext_opt
,
2131 { "Extended Options Field", "zbee_nwk_gp.cmd.comm.ext_opt", FT_UINT8
, BASE_HEX
, NULL
,
2132 0x0, NULL
, HFILL
}},
2134 { &hf_zbee_nwk_gp_cmd_comm_ext_opt_outgoing_counter
,
2135 { "GPD Outgoing present", "zbee_nwk_gp.cmd.comm.ext_opt.outgoing_counter", FT_BOOLEAN
, 8, NULL
,
2136 ZBEE_NWK_GP_CMD_COMMISSIONING_EXT_OPT_OUT_COUNTER
, NULL
, HFILL
}},
2138 { &hf_zbee_nwk_gp_cmd_comm_manufacturer_greenpeak_dev_id
,
2139 { "Manufacturer Model ID", "zbee_nwk_gp.cmd.comm.manufacturer_model_id", FT_UINT16
, BASE_HEX
,
2140 VALS(zbee_nwk_gp_manufacturer_greenpeak_dev_names
), 0x0, NULL
, HFILL
}},
2142 { &hf_zbee_nwk_gp_cmd_comm_manufacturer_dev_id
,
2143 { "Manufacturer Model ID", "zbee_nwk_gp.cmd.comm.manufacturer_model_id", FT_UINT16
, BASE_HEX
,
2144 NULL
, 0x0, NULL
, HFILL
}},
2146 { &hf_zbee_nwk_gp_cmd_comm_manufacturer_id
,
2147 { "Manufacturer ID", "zbee_nwk_gp.cmd.comm.manufacturer_id", FT_UINT16
, BASE_HEX
,
2148 VALS(zbee_mfr_code_names
), 0x0, NULL
, HFILL
}},
2150 { &hf_zbee_nwk_gp_cmd_comm_appli_info_crp
,
2151 { "Cluster reports present", "zbee_nwk_gp.cmd.comm.appli_info.crp", FT_BOOLEAN
, 8, NULL
,
2152 ZBEE_NWK_GP_CMD_COMMISSIONING_APPLI_INFO_CRP
, NULL
, HFILL
}},
2154 { &hf_zbee_nwk_gp_cmd_comm_appli_info_gclp
,
2155 { "GP commands list present", "zbee_nwk_gp.cmd.comm.appli_info.gclp", FT_BOOLEAN
, 8, NULL
,
2156 ZBEE_NWK_GP_CMD_COMMISSIONING_APPLI_INFO_GCLP
, NULL
, HFILL
}},
2158 { &hf_zbee_nwk_gp_cmd_comm_appli_info
,
2159 { "Application information Field", "zbee_nwk_gp.cmd.comm.appli_info", FT_UINT8
, BASE_HEX
, NULL
,
2160 0x0, NULL
, HFILL
}},
2162 { &hf_zbee_nwk_gp_cmd_comm_appli_info_mip
,
2163 { "Manufacturer ID present", "zbee_nwk_gp.cmd.comm.appli_info.mip", FT_BOOLEAN
, 8, NULL
,
2164 ZBEE_NWK_GP_CMD_COMMISSIONING_APPLI_INFO_MIP
, NULL
, HFILL
}},
2166 { &hf_zbee_nwk_gp_cmd_comm_appli_info_mmip
,
2167 { "Manufacturer Model ID present", "zbee_nwk_gp.cmd.comm.appli_info.mmip", FT_BOOLEAN
, 8, NULL
,
2168 ZBEE_NWK_GP_CMD_COMMISSIONING_APPLI_INFO_MMIP
, NULL
, HFILL
}},
2170 { &hf_zbee_nwk_gp_cmd_comm_gpd_cmd_num
,
2171 { "Number of GPD commands", "zbee_nwk_gp.cmd.comm.gpd_cmd_num", FT_UINT8
, BASE_DEC
, NULL
,
2172 0x0 , NULL
, HFILL
}},
2174 { &hf_zbee_nwk_gp_cmd_comm_gpd_cmd_id_list
,
2175 { "GPD CommandID list", "zbee_nwk_gp.cmd.comm.gpd_cmd_id_list", FT_NONE
, BASE_NONE
, NULL
,
2176 0x0 , NULL
, HFILL
}},
2178 { &hf_zbee_nwk_gp_cmd_comm_length_of_clid_list
,
2179 { "Length of ClusterID list", "zbee_nwk_gp.cmd.comm.length_of_clid_list", FT_UINT8
, BASE_HEX
, NULL
,
2180 0x0 , NULL
, HFILL
}},
2182 { &hf_zbee_nwk_gp_cmd_comm_length_of_clid_list_server
,
2183 { "Number of server ClusterIDs", "zbee_nwk_gp.cmd.comm.length_of_clid_list_srv", FT_UINT8
, BASE_DEC
, NULL
,
2184 ZBEE_NWK_GP_CMD_COMMISSIONING_CLID_LIST_LEN_SRV
, NULL
, HFILL
}},
2186 { &hf_zbee_nwk_gp_cmd_comm_length_of_clid_list_client
,
2187 { "Number of client ClusterIDs", "zbee_nwk_gp.cmd.comm.length_of_clid_list_cli", FT_UINT8
, BASE_DEC
, NULL
,
2188 ZBEE_NWK_GP_CMD_COMMISSIONING_CLID_LIST_LEN_CLI
, NULL
, HFILL
}},
2190 { &hf_zbee_nwk_cmd_comm_clid_list_server
,
2191 { "Cluster ID List Server", "zbee_nwk_gp.cmd.comm.clid_list_server", FT_NONE
, BASE_NONE
, NULL
,
2192 0x0 , NULL
, HFILL
}},
2194 { &hf_zbee_nwk_cmd_comm_clid_list_client
,
2195 { "ClusterID List Client", "zbee_nwk_gp.cmd.comm.clid_list_client", FT_NONE
, BASE_NONE
, NULL
,
2196 0x0 , NULL
, HFILL
}},
2198 { &hf_zbee_nwk_cmd_comm_cluster_id
,
2199 { "Cluster ID", "zbee_nwk_gp.cmd.comm.cluster_id", FT_UINT16
, BASE_HEX
, NULL
,
2200 0x0 , NULL
, HFILL
}},
2202 { &hf_zbee_nwk_gp_cmd_comm_rep_opt_key_encr
,
2203 { "GPD Key Encryption", "zbee_nwk_gp.cmd.comm_reply.opt.sec_key_encr", FT_BOOLEAN
, 8, NULL
,
2204 ZBEE_NWK_GP_CMD_COMMISSIONING_REP_OPT_KEY_ENCR
, NULL
, HFILL
}},
2206 { &hf_zbee_nwk_gp_cmd_comm_rep_opt
,
2207 { "Options Field", "zbee_nwk_gp.cmd.comm_reply.opt", FT_UINT8
, BASE_HEX
, NULL
,
2208 0x0, NULL
, HFILL
}},
2210 { &hf_zbee_nwk_gp_cmd_comm_rep_opt_panid_present
,
2211 { "PANID Present", "zbee_nwk_gp.cmd.comm_reply.opt.pan_id_present", FT_BOOLEAN
, 8, NULL
,
2212 ZBEE_NWK_GP_CMD_COMMISSIONING_REP_OPT_PAN_ID_PRESENT
, NULL
, HFILL
}},
2214 { &hf_zbee_nwk_gp_cmd_comm_rep_opt_sec_key_present
,
2215 { "GPD Security Key Present", "zbee_nwk_gp.cmd.comm_reply.opt.sec_key_present", FT_BOOLEAN
, 8, NULL
,
2216 ZBEE_NWK_GP_CMD_COMMISSIONING_REP_OPT_SEC_KEY_PRESENT
, NULL
, HFILL
}},
2218 { &hf_zbee_nwk_gp_cmd_comm_rep_opt_sec_level
,
2219 { "Security Level", "zbee_nwk_gp.cmd.comm_reply.opt.sec_level", FT_UINT8
, BASE_HEX
, NULL
,
2220 ZBEE_NWK_GP_CMD_COMMISSIONING_REP_OPT_SEC_LEVEL
, NULL
, HFILL
}},
2222 { &hf_zbee_nwk_gp_cmd_comm_rep_opt_sec_type
,
2223 { "Key Type", "zbee_nwk_gp.cmd.comm_reply.opt.key_type", FT_UINT8
, BASE_HEX
, NULL
,
2224 ZBEE_NWK_GP_CMD_COMMISSIONING_REP_OPT_KEY_TYPE
, NULL
, HFILL
}},
2226 { &hf_zbee_nwk_gp_cmd_comm_rep_pan_id
,
2227 { "PAN ID", "zbee_nwk_gp.cmd.comm_reply.pan_id", FT_UINT16
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
}},
2229 { &hf_zbee_nwk_gp_cmd_comm_rep_frame_counter
,
2230 { "Frame Counter", "zbee_nwk_gp.cmd.comm_reply.frame_counter", FT_UINT32
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
}},
2232 { &hf_zbee_nwk_gp_cmd_read_att_opt_multi_rec
,
2233 { "Multi-record", "zbee_nwk_gp.cmd.read_att.opt.multi_record", FT_BOOLEAN
, 8, NULL
,
2234 ZBEE_NWK_GP_CMD_READ_ATTRIBUTE_OPT_MULTI_RECORD
, NULL
, HFILL
}},
2236 { &hf_zbee_nwk_gp_cmd_read_att_opt_man_field_present
,
2237 { "Manufacturer field present", "zbee_nwk_gp.cmd.read_att.opt.man_field_present", FT_BOOLEAN
, 8, NULL
,
2238 ZBEE_NWK_GP_CMD_READ_ATTRIBUTE_OPT_MAN_FIELD_PRESENT
, NULL
, HFILL
}},
2240 { &hf_zbee_nwk_gp_cmd_read_att_opt
,
2241 { "Option field", "zbee_nwk_gp.cmd.read_att.opt", FT_UINT8
, BASE_HEX
, NULL
,
2242 0x0, NULL
, HFILL
}},
2244 { &hf_zbee_zcl_gp_cmd_ms_manufacturer_code
,
2245 { "Manufacturer Code", "zbee_nwk_gp.cmd.manufacturer_code", FT_UINT16
, BASE_HEX
, VALS(zbee_mfr_code_names
),
2246 0x0, NULL
, HFILL
}},
2248 { &hf_zbee_nwk_gp_cmd_read_att_record_len
,
2249 { "Length of Record List", "zbee_nwk_gp.cmd.read_att.record_len", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
2252 { &hf_zbee_nwk_gp_zcl_attr_status
,
2253 { "Status", "zbee_nwk_gp.zcl.attr.status", FT_UINT8
, BASE_HEX
, VALS(zbee_zcl_status_names
),
2254 0x0, NULL
, HFILL
}},
2256 { &hf_zbee_nwk_gp_zcl_attr_data_type
,
2257 { "Data Type", "zbee_nwk_gp.zcl.attr.datatype", FT_UINT8
, BASE_HEX
, VALS(zbee_zcl_short_data_type_names
),
2258 0x0, NULL
, HFILL
} },
2260 { &hf_zbee_nwk_gp_zcl_attr_cluster_id
,
2261 { "ZigBee Cluster ID", "zbee_nwk_gp.zcl.attr.cluster_id", FT_UINT16
, BASE_HEX
| BASE_RANGE_STRING
, RVALS(zbee_aps_cid_names
),
2262 0x0, NULL
, HFILL
}},
2264 { &hf_zbee_nwk_gp_cmd_channel_request_toggling_behaviour
,
2265 { "Channel Toggling Behaviour", "zbee_nwk_gp.cmd.ch_req", FT_UINT8
, BASE_HEX
, NULL
,
2266 0x0, NULL
, HFILL
}},
2268 { &hf_zbee_nwk_gp_cmd_channel_request_toggling_behaviour_1st
,
2269 { "Rx channel in the next attempt", "zbee_nwk_gp.cmd.ch_req.1st", FT_UINT8
, BASE_HEX
, NULL
,
2270 ZBEE_NWK_GP_CMD_CHANNEL_REQUEST_1ST
, NULL
, HFILL
}},
2272 { &hf_zbee_nwk_gp_cmd_channel_request_toggling_behaviour_2nd
,
2273 { "Rx channel in the second next attempt", "zbee_nwk_gp.ch_req.2nd", FT_UINT8
, BASE_HEX
, NULL
,
2274 ZBEE_NWK_GP_CMD_CHANNEL_REQUEST_2ND
, NULL
, HFILL
}},
2276 { &hf_zbee_nwk_gp_cmd_operational_channel
,
2277 { "Operational Channel", "zbee_nwk_gp.cmd.configuration_ch", FT_UINT8
, BASE_HEX
, NULL
,
2278 0x0, NULL
, HFILL
}},
2280 { &hf_zbee_nwk_gp_cmd_channel_configuration
,
2281 { "Operation channel", "zbee_nwk_gp.cmd.configuration_ch.operation_ch", FT_UINT8
, BASE_HEX
, NULL
,
2282 ZBEE_NWK_GP_CMD_CHANNEL_CONFIGURATION_OPERATION_CH
, NULL
, HFILL
}},
2284 { &hf_zbee_nwk_gp_cmd_move_color_ratex
,
2285 { "RateX", "zbee_nwk_gp.cmd.move_color.ratex", FT_UINT16
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
2287 { &hf_zbee_nwk_gp_cmd_move_color_ratey
,
2288 { "RateY", "zbee_nwk_gp.cmd.move_color.ratey", FT_UINT16
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
2290 { &hf_zbee_nwk_gp_cmd_move_up_down_rate
,
2291 { "Rate", "zbee_nwk_gp.cmd.move_up_down.rate", FT_UINT8
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
2293 { &hf_zbee_nwk_gp_cmd_step_color_stepx
,
2294 { "StepX", "zbee_nwk_gp.cmd.step_color.stepx", FT_UINT16
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
2296 { &hf_zbee_nwk_gp_cmd_step_color_stepy
,
2297 { "StepY", "zbee_nwk_gp.cmd.step_color.stepy", FT_UINT16
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
2299 { &hf_zbee_nwk_gp_cmd_step_color_transition_time
,
2300 { "Transition Time", "zbee_nwk_gp.cmd.step_color.transition_time", FT_UINT16
, BASE_DEC
, NULL
, 0x0, NULL
,
2303 { &hf_zbee_nwk_gp_cmd_step_up_down_step_size
,
2304 { "Step Size", "zbee_nwk_gp.cmd.step_up_down.step_size", FT_UINT8
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
2306 { &hf_zbee_nwk_gp_cmd_step_up_down_transition_time
,
2307 { "Transition Time", "zbee_nwk_gp.cmd.step_up_down.transition_time", FT_UINT16
, BASE_DEC
, NULL
, 0x0, NULL
,
2311 static ei_register_info ei
[] = {
2312 { &ei_zbee_nwk_gp_no_payload
,
2313 { "zbee_nwk_gp.no_payload", PI_MALFORMED
, PI_ERROR
,
2314 "Payload is missing", EXPFILL
}},
2315 { &ei_zbee_nwk_gp_inval_residual_data
,
2316 { "zbee_nwk_gp.inval_residual_data", PI_MALFORMED
, PI_ERROR
,
2317 "Invalid residual data", EXPFILL
}},
2318 { &ei_zbee_nwk_gp_com_rep_no_out_cnt
,
2319 { "zbee_nwk_gp.com_rep_no_out_cnt", PI_DEBUG
, PI_WARN
,
2320 "Missing outgoing frame counter", EXPFILL
}}
2323 static int *ett
[] = {
2326 &ett_zbee_nwk_cmd_cinfo
,
2327 &ett_zbee_nwk_cmd_appli_info
,
2328 &ett_zbee_nwk_cmd_options
,
2330 &ett_zbee_nwk_fcf_ext
,
2331 &ett_zbee_nwk_clu_rec
,
2332 &ett_zbee_nwk_att_rec
,
2333 &ett_zbee_nwk_cmd_comm_gpd_cmd_id_list
,
2334 &ett_zbee_nwk_cmd_comm_length_of_clid_list
,
2335 &ett_zbee_nwk_cmd_comm_clid_list_server
,
2336 &ett_zbee_nwk_cmd_comm_clid_list_client
2339 static uat_field_t key_uat_fields
[] = {
2340 UAT_FLD_CSTRING(gp_uat_key_records
, string
, "Key", "A 16-byte key."),
2341 UAT_FLD_VS(gp_uat_key_records
, byte_order
, "Byte Order", byte_order_vals
, "Byte order of a key."),
2342 UAT_FLD_LSTRING(gp_uat_key_records
, label
, "Label", "User label for a key."),
2346 proto_zbee_nwk_gp
= proto_register_protocol("ZigBee Green Power Profile", "ZigBee Green Power",
2347 ZBEE_PROTOABBREV_NWK_GP
);
2349 gp_zbee_prefs
= prefs_register_protocol(proto_zbee_nwk_gp
, NULL
);
2351 zbee_gp_sec_key_table_uat
= uat_new("ZigBee GP Security Keys", sizeof(uat_key_record_t
), "zigbee_gp_keys", true,
2352 &gp_uat_key_records
, &num_uat_key_records
, UAT_AFFECTS_DISSECTION
, NULL
, uat_key_record_copy_cb
,
2353 uat_key_record_update_cb
, uat_key_record_free_cb
, uat_key_record_post_update_cb
, NULL
, key_uat_fields
);
2355 prefs_register_uat_preference(gp_zbee_prefs
, "gp_key_table", "Pre-configured GP Security Keys",
2356 "Pre-configured GP Security Keys.", zbee_gp_sec_key_table_uat
);
2358 register_init_routine(gp_init_zbee_security
);
2359 register_cleanup_routine(gp_cleanup_zbee_security
);
2361 /* Register the Wireshark protocol. */
2362 proto_register_field_array(proto_zbee_nwk_gp
, hf
, array_length(hf
));
2363 proto_register_subtree_array(ett
, array_length(ett
));
2365 expert_zbee_nwk_gp
= expert_register_protocol(proto_zbee_nwk_gp
);
2366 expert_register_field_array(expert_zbee_nwk_gp
, ei
, array_length(ei
));
2368 /* Register the dissectors. */
2369 register_dissector(ZBEE_PROTOABBREV_NWK_GP
, dissect_zbee_nwk_gp
, proto_zbee_nwk_gp
);
2370 register_dissector(ZBEE_PROTOABBREV_NWK_GP_CMD
, dissect_zbee_nwk_gp_cmd
, proto_zbee_nwk_gp
);
2371 } /* proto_register_zbee_nwk_gp */
2374 *Registers the ZigBee dissector with Wireshark.
2378 proto_reg_handoff_zbee_nwk_gp(void)
2380 /* Register our dissector with IEEE 802.15.4. */
2381 dissector_add_for_decode_as(IEEE802154_PROTOABBREV_WPAN_PANID
, find_dissector(ZBEE_PROTOABBREV_NWK_GP
));
2382 heur_dissector_add(IEEE802154_PROTOABBREV_WPAN
, dissect_zbee_nwk_heur_gp
, "ZigBee Green Power over IEEE 802.15.4", "zbee_nwk_gp_wlan", proto_zbee_nwk_gp
, HEURISTIC_ENABLE
);
2383 } /* proto_reg_handoff_zbee */
2391 * indent-tabs-mode: nil
2394 * ex: set shiftwidth=4 tabstop=8 expandtab:
2395 * :indentSize=4:tabSize=8:noTabs=true: