Coverage Report

Created: 2026-07-12 07:10

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wireshark/epan/dissectors/packet-zbee-nwk-gp.c
Line
Count
Source
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/
4
 *
5
 * Wireshark - Network traffic analyzer
6
 * By Gerald Combs <gerald@wireshark.org>
7
 * Copyright 1998 Gerald Combs
8
 *
9
 * Used Owen Kirby's packet-zbee-aps module as a template. Based
10
 * on ZigBee Cluster Library Specification document 075123r02ZB
11
 *
12
 * SPDX-License-Identifier: GPL-2.0-or-later
13
 */
14
15
/* Include files. */
16
#include "config.h"
17
18
#include <epan/packet.h>
19
#include <epan/exceptions.h>
20
#include <epan/expert.h>
21
#include <epan/prefs.h>
22
#include <epan/uat.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"
30
31
void proto_register_zbee_nwk_gp(void);
32
void proto_reg_handoff_zbee_nwk_gp(void);
33
34
/**************************/
35
/* Defines. */
36
/**************************/
37
38
/* ZigBee NWK GP FCF frame types. */
39
3.06k
#define ZBEE_NWK_GP_FCF_DATA        0x00
40
1.46k
#define ZBEE_NWK_GP_FCF_MAINTENANCE 0x01
41
42
/* ZigBee NWK GP FCF fields. */
43
15
#define ZBEE_NWK_GP_FCF_AUTO_COMMISSIONING  0x40
44
801
#define ZBEE_NWK_GP_FCF_CONTROL_EXTENSION   0x80
45
801
#define ZBEE_NWK_GP_FCF_FRAME_TYPE          0x03
46
1.38k
#define ZBEE_NWK_GP_FCF_VERSION             0x3C
47
48
/* Extended NWK Frame Control field. */
49
758
#define ZBEE_NWK_GP_FCF_EXT_APP_ID          0x07 /* 0 - 2 b. */
50
758
#define ZBEE_NWK_GP_FCF_EXT_SECURITY_LEVEL  0x18 /* 3 - 4 b. */
51
15
#define ZBEE_NWK_GP_FCF_EXT_SECURITY_KEY    0x20 /* 5 b. */
52
15
#define ZBEE_NWK_GP_FCF_EXT_RX_AFTER_TX     0x40 /* 6 b. */
53
758
#define ZBEE_NWK_GP_FCF_EXT_DIRECTION       0x80 /* 7 b. */
54
55
/* Definitions for application IDs. */
56
2.96k
#define ZBEE_NWK_GP_APP_ID_DEFAULT  0x00
57
651
#define ZBEE_NWK_GP_APP_ID_LPED     0x01
58
2.26k
#define ZBEE_NWK_GP_APP_ID_ZGP      0x02
59
60
/* Definitions for GP directions. */
61
#define ZBEE_NWK_GP_FC_EXT_DIRECTION_DEFAULT    0x00
62
0
#define ZBEE_NWK_GP_FC_EXT_DIRECTION_FROM_ZGPD  0x00
63
#define ZBEE_NWK_GP_FC_EXT_DIRECTION_FROM_ZGPP  0x01
64
65
/* Definitions for ZGPD Source IDs. */
66
#define ZBEE_NWK_GP_ZGPD_SRCID_ALL      0xFFFFFFFF
67
#define ZBEE_NWK_GP_ZGPD_SRCID_UNKNOWN  0x00000000
68
69
/* Security level values. */
70
#define ZBEE_NWK_GP_SECURITY_LEVEL_NO       0x00
71
656
#define ZBEE_NWK_GP_SECURITY_LEVEL_1LSB     0x01
72
644
#define ZBEE_NWK_GP_SECURITY_LEVEL_FULL     0x02
73
1.88k
#define ZBEE_NWK_GP_SECURITY_LEVEL_FULLENCR 0x03
74
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
82
83
typedef struct {
84
    /* FCF Data. */
85
    uint8_t frame_type;
86
    bool nwk_frame_control_extension;
87
88
    /* Ext FCF Data. */
89
    uint8_t application_id;
90
    uint8_t security_level;
91
    uint8_t direction;
92
93
    /* Src ID. */
94
    uint32_t source_id;
95
96
    /* GPD Endpoint */
97
    uint8_t endpoint;
98
99
    /* Security Frame Counter. */
100
    uint32_t security_frame_counter;
101
102
    /* MIC. */
103
    uint8_t mic_size;
104
    uint32_t mic;
105
106
    /* Application Payload. */
107
    uint8_t payload_len;
108
109
    /* Source IEEE address from parent */
110
    uint64_t ieee_packet_src64;
111
} zbee_nwk_green_power_packet;
112
113
/* Definitions for GP Commissioning command opt field (bitmask). */
114
15
#define ZBEE_NWK_GP_CMD_COMMISSIONING_OPT_MAC_SEQ           0x01
115
15
#define ZBEE_NWK_GP_CMD_COMMISSIONING_OPT_RX_ON_CAP         0x02
116
25
#define ZBEE_NWK_GP_CMD_COMMISSIONING_OPT_APPLICATION_INFO  0x04
117
15
#define ZBEE_NWK_GP_CMD_COMMISSIONING_OPT_PAN_ID_REQ        0x10
118
15
#define ZBEE_NWK_GP_CMD_COMMISSIONING_OPT_GP_SEC_KEY_REQ    0x20
119
15
#define ZBEE_NWK_GP_CMD_COMMISSIONING_OPT_FIXED_LOCATION    0x40
120
25
#define ZBEE_NWK_GP_CMD_COMMISSIONING_OPT_EXT_OPTIONS       0x80
121
122
/* Definitions for GP Commissioning command ext_opt field (bitmask). */
123
15
#define ZBEE_NWK_GP_CMD_COMMISSIONING_EXT_OPT_SEC_LEVEL_CAP     0x03
124
15
#define ZBEE_NWK_GP_CMD_COMMISSIONING_EXT_OPT_KEY_TYPE          0x1C
125
18
#define ZBEE_NWK_GP_CMD_COMMISSIONING_EXT_OPT_GPD_KEY_PRESENT   0x20
126
17
#define ZBEE_NWK_GP_CMD_COMMISSIONING_EXT_OPT_GPD_KEY_ENCR      0x40
127
18
#define ZBEE_NWK_GP_CMD_COMMISSIONING_EXT_OPT_OUT_COUNTER       0x80
128
129
/* Definitions for GP Commissioning command application information field (bitmask). */
130
23
#define ZBEE_NWK_GP_CMD_COMMISSIONING_APPLI_INFO_MIP    0x01
131
23
#define ZBEE_NWK_GP_CMD_COMMISSIONING_APPLI_INFO_MMIP   0x02
132
23
#define ZBEE_NWK_GP_CMD_COMMISSIONING_APPLI_INFO_GCLP   0x04
133
23
#define ZBEE_NWK_GP_CMD_COMMISSIONING_APPLI_INFO_CRP    0x08
134
135
/* Definitions for GP Commissioning command Number of server ClusterIDs (bitmask) */
136
27
#define ZBEE_NWK_GP_CMD_COMMISSIONING_CLID_LIST_LEN_SRV 0x0F
137
27
#define ZBEE_NWK_GP_CMD_COMMISSIONING_CLID_LIST_LEN_CLI 0xF0
138
139
/* Definitions for GP Decommissioning command opt field (bitmask). */
140
18
#define ZBEE_NWK_GP_CMD_COMMISSIONING_REP_OPT_PAN_ID_PRESENT    0x01
141
20
#define ZBEE_NWK_GP_CMD_COMMISSIONING_REP_OPT_SEC_KEY_PRESENT   0x02
142
22
#define ZBEE_NWK_GP_CMD_COMMISSIONING_REP_OPT_KEY_ENCR          0x04
143
21
#define ZBEE_NWK_GP_CMD_COMMISSIONING_REP_OPT_SEC_LEVEL         0x18
144
15
#define ZBEE_NWK_GP_CMD_COMMISSIONING_REP_OPT_KEY_TYPE          0xE0
145
146
/* Definition for GP read attributes command opt field (bitmask). */
147
15
#define ZBEE_NWK_GP_CMD_READ_ATTRIBUTE_OPT_MULTI_RECORD         0x01
148
565
#define ZBEE_NWK_GP_CMD_READ_ATTRIBUTE_OPT_MAN_FIELD_PRESENT    0x02
149
150
15
#define ZBEE_NWK_GP_CMD_ZCL_TUNNEL_OPT_FRAME_TYPE               0x03
151
16
#define ZBEE_NWK_GP_CMD_ZCL_TUNNEL_OPT_MAN_FIELD_PRESENT        0x04
152
15
#define ZBEE_NWK_GP_CMD_ZCL_TUNNEL_OPT_DIRECTION                0x08
153
154
/* Definitions for GP Channel Request command. */
155
15
#define ZBEE_NWK_GP_CMD_CHANNEL_REQUEST_1ST 0x0F
156
15
#define ZBEE_NWK_GP_CMD_CHANNEL_REQUEST_2ND 0xF0
157
158
/* GP Channel Configuration command. */
159
15
#define ZBEE_NWK_GP_CMD_CHANNEL_CONFIGURATION_OPERATION_CH 0x0F
160
161
/* GP GENERIC IDS. */
162
#define GPD_DEVICE_ID_GENERIC_GP_SIMPLE_GENERIC_1STATE_SWITCH   0x00
163
#define GPD_DEVICE_ID_GENERIC_GP_SIMPLE_GENERIC_2STATE_SWITCH   0x01
164
#define GPD_DEVICE_ID_GENERIC_GP_ON_OFF_SWITCH                  0x02
165
#define GPD_DEVICE_ID_GENERIC_GP_LEVEL_CONTROL_SWITCH           0x03
166
#define GPD_DEVICE_ID_GENERIC_GP_SIMPLE_SENSOR                  0x04
167
#define GPD_DEVICE_ID_GENERIC_GP_ADVANCED_GENERIC_1STATE_SWITCH 0x05
168
#define GPD_DEVICE_ID_GENERIC_GP_ADVANCED_GENERIC_2STATE_SWITCH 0x06
169
170
/* GP LIGHTING IDS. */
171
#define GPD_DEVICE_ID_LIGHTING_GP_COLOR_DIMMER_SWITCH           0x10
172
#define GPD_DEVICE_ID_LIGHTING_GP_LIGHT_SENSOR                  0x11
173
#define GPD_DEVICE_ID_LIGHTING_GP_OCCUPANCY_SENSOR              0x12
174
175
/* GP CLOSURES IDS. */
176
#define GPD_DEVICE_ID_CLOSURES_GP_DOOR_LOCK_CONTROLLER          0x20
177
178
/* HVAC IDS. */
179
#define GPD_DEVICE_ID_HVAC_GP_TEMPERATURE_SENSOR                0x30
180
#define GPD_DEVICE_ID_HVAC_GP_PRESSURE_SENSOR                   0x31
181
#define GPD_DEVICE_ID_HVAC_GP_FLOW_SENSOR                       0x32
182
#define GPD_DEVICE_ID_HVAC_GP_INDOOR_ENVIRONMENT_SENSOR         0x33
183
184
/* Manufacturer specific device. */
185
#define GPD_DEVICE_ID_MANUFACTURER_SPECIFIC                     0xFE
186
187
/* GPD manufacturers. */
188
0
#define ZBEE_NWK_GP_MANUF_ID_GREENPEAK      0x10D0
189
190
/* GPD devices by GreenPeak. */
191
#define ZBEE_NWK_GP_MANUF_GREENPEAK_IZDS    0x0000
192
#define ZBEE_NWK_GP_MANUF_GREENPEAK_IZDWS   0x0001
193
#define ZBEE_NWK_GP_MANUF_GREENPEAK_IZLS    0x0002
194
#define ZBEE_NWK_GP_MANUF_GREENPEAK_IZRHS   0x0003
195
196
/*********************/
197
/* Global variables. */
198
/*********************/
199
200
/* GP proto handle. */
201
static int proto_zbee_nwk_gp;
202
203
/* GP NWK FC. */
204
static int hf_zbee_nwk_gp_auto_commissioning;
205
static int hf_zbee_nwk_gp_fc_ext;
206
static int hf_zbee_nwk_gp_fcf;
207
static int hf_zbee_nwk_gp_frame_type;
208
static int hf_zbee_nwk_gp_proto_version;
209
210
/* GP NWK FC extension. */
211
static int hf_zbee_nwk_gp_fc_ext_field;
212
static int hf_zbee_nwk_gp_fc_ext_app_id;
213
static int hf_zbee_nwk_gp_fc_ext_direction;
214
static int hf_zbee_nwk_gp_fc_ext_rx_after_tx;
215
static int hf_zbee_nwk_gp_fc_ext_sec_key;
216
static int hf_zbee_nwk_gp_fc_ext_sec_level;
217
218
/* ZGPD Src ID. */
219
static int hf_zbee_nwk_gp_zgpd_src_id;
220
221
/* ZGPD Endpoint */
222
static int hf_zbee_nwk_gp_zgpd_endpoint;
223
224
/* Security frame counter. */
225
static int hf_zbee_nwk_gp_security_frame_counter;
226
227
/* Security MIC. */
228
static int hf_zbee_nwk_gp_security_mic_2b;
229
static int hf_zbee_nwk_gp_security_mic_4b;
230
231
/* Payload subframe. */
232
static int hf_zbee_nwk_gp_command_id;
233
234
/* Commissioning. */
235
static int hf_zbee_nwk_gp_cmd_comm_device_id;
236
static int hf_zbee_nwk_gp_cmd_comm_ext_opt;
237
static int hf_zbee_nwk_gp_cmd_comm_ext_opt_gpd_key_encr;
238
static int hf_zbee_nwk_gp_cmd_comm_ext_opt_gpd_key_present;
239
static int hf_zbee_nwk_gp_cmd_comm_ext_opt_key_type;
240
static int hf_zbee_nwk_gp_cmd_comm_ext_opt_outgoing_counter;
241
static int hf_zbee_nwk_gp_cmd_comm_ext_opt_sec_level_cap;
242
static int hf_zbee_nwk_gp_cmd_comm_security_key;
243
static int hf_zbee_nwk_gp_cmd_comm_gpd_sec_key_mic;
244
static int hf_zbee_nwk_gp_cmd_comm_opt_ext_opt;
245
static int hf_zbee_nwk_gp_cmd_comm_opt;
246
static int hf_zbee_nwk_gp_cmd_comm_opt_fixed_location;
247
static int hf_zbee_nwk_gp_cmd_comm_opt_mac_sec_num_cap;
248
static int hf_zbee_nwk_gp_cmd_comm_opt_appli_info_present;
249
static int hf_zbee_nwk_gp_cmd_comm_opt_panid_req;
250
static int hf_zbee_nwk_gp_cmd_comm_opt_rx_on_cap;
251
static int hf_zbee_nwk_gp_cmd_comm_opt_sec_key_req;
252
static int hf_zbee_nwk_gp_cmd_comm_outgoing_counter;
253
static int hf_zbee_nwk_gp_cmd_comm_manufacturer_greenpeak_dev_id;
254
static int hf_zbee_nwk_gp_cmd_comm_manufacturer_dev_id;
255
static int hf_zbee_nwk_gp_cmd_comm_manufacturer_id;
256
static int hf_zbee_nwk_gp_cmd_comm_appli_info;
257
static int hf_zbee_nwk_gp_cmd_comm_appli_info_crp;
258
static int hf_zbee_nwk_gp_cmd_comm_appli_info_gclp;
259
static int hf_zbee_nwk_gp_cmd_comm_appli_info_mip;
260
static int hf_zbee_nwk_gp_cmd_comm_appli_info_mmip;
261
static int hf_zbee_nwk_gp_cmd_comm_gpd_cmd_num;
262
static int hf_zbee_nwk_gp_cmd_comm_gpd_cmd_id_list;
263
static int hf_zbee_nwk_gp_cmd_comm_length_of_clid_list;
264
static int hf_zbee_nwk_gp_cmd_comm_length_of_clid_list_server;
265
static int hf_zbee_nwk_gp_cmd_comm_length_of_clid_list_client;
266
static int hf_zbee_nwk_cmd_comm_clid_list_server;
267
static int hf_zbee_nwk_cmd_comm_clid_list_client;
268
static int hf_zbee_nwk_cmd_comm_cluster_id;
269
270
/* Commissioning reply. */
271
static int hf_zbee_nwk_gp_cmd_comm_rep_opt;
272
static int hf_zbee_nwk_gp_cmd_comm_rep_opt_key_encr;
273
static int hf_zbee_nwk_gp_cmd_comm_rep_opt_panid_present;
274
static int hf_zbee_nwk_gp_cmd_comm_rep_opt_sec_key_present;
275
static int hf_zbee_nwk_gp_cmd_comm_rep_opt_sec_level;
276
static int hf_zbee_nwk_gp_cmd_comm_rep_opt_sec_type;
277
static int hf_zbee_nwk_gp_cmd_comm_rep_pan_id;
278
static int hf_zbee_nwk_gp_cmd_comm_rep_frame_counter;
279
280
/* Read attribute and read attribute response. */
281
static int hf_zbee_nwk_gp_cmd_read_att_opt_multi_rec;
282
static int hf_zbee_nwk_gp_cmd_read_att_opt_man_field_present;
283
static int hf_zbee_nwk_gp_cmd_read_att_opt;
284
static int hf_zbee_nwk_gp_cmd_read_att_record_len;
285
286
/* ZCL Tunnel */
287
static int hf_zbee_nwk_gp_cmd_zcl_tunnel_opt_frame_type;
288
static int hf_zbee_nwk_gp_cmd_zcl_tunnel_opt_man_field_present;
289
static int hf_zbee_nwk_gp_cmd_zcl_tunnel_opt_direction;
290
static int hf_zbee_nwk_gp_cmd_zcl_tunnel_opt;
291
static int hf_zbee_nwk_gp_cmd_zcl_tunnel_command_id;
292
static int hf_zbee_nwk_gp_cmd_zcl_tunnel_payload_len;
293
294
/* Common to commands returning data */
295
static int hf_zbee_nwk_gp_zcl_attr_status;
296
static int hf_zbee_nwk_gp_zcl_attr_data_type;
297
static int hf_zbee_nwk_gp_zcl_attr_cluster_id;
298
299
/* Common to all manufacturer specific commands */
300
static int hf_zbee_zcl_gp_cmd_ms_manufacturer_code;
301
302
/* Channel request. */
303
static int hf_zbee_nwk_gp_cmd_channel_request_toggling_behaviour;
304
static int hf_zbee_nwk_gp_cmd_channel_request_toggling_behaviour_1st;
305
static int hf_zbee_nwk_gp_cmd_channel_request_toggling_behaviour_2nd;
306
307
/* Channel Configuration command. */
308
static int hf_zbee_nwk_gp_cmd_operational_channel;
309
static int hf_zbee_nwk_gp_cmd_channel_configuration;
310
311
/* Move Color command. */
312
static int hf_zbee_nwk_gp_cmd_move_color_ratex;
313
static int hf_zbee_nwk_gp_cmd_move_color_ratey;
314
315
/* Move Up/Down command. */
316
static int hf_zbee_nwk_gp_cmd_move_up_down_rate;
317
318
/* Step Color command. */
319
static int hf_zbee_nwk_gp_cmd_step_color_stepx;
320
static int hf_zbee_nwk_gp_cmd_step_color_stepy;
321
static int hf_zbee_nwk_gp_cmd_step_color_transition_time;
322
323
/* Step Up/Down command. */
324
static int hf_zbee_nwk_gp_cmd_step_up_down_step_size;
325
static int hf_zbee_nwk_gp_cmd_step_up_down_transition_time;
326
327
static expert_field ei_zbee_nwk_gp_no_payload;
328
static expert_field ei_zbee_nwk_gp_inval_residual_data;
329
static expert_field ei_zbee_nwk_gp_com_rep_no_out_cnt;
330
331
/* Proto tree elements. */
332
static int ett_zbee_nwk;
333
static int ett_zbee_nwk_cmd;
334
static int ett_zbee_nwk_cmd_cinfo;
335
static int ett_zbee_nwk_cmd_appli_info;
336
static int ett_zbee_nwk_cmd_options;
337
static int ett_zbee_nwk_fcf;
338
static int ett_zbee_nwk_fcf_ext;
339
static int ett_zbee_nwk_clu_rec;
340
static int ett_zbee_nwk_att_rec;
341
static int ett_zbee_nwk_cmd_comm_gpd_cmd_id_list;
342
static int ett_zbee_nwk_cmd_comm_length_of_clid_list;
343
static int ett_zbee_nwk_cmd_comm_clid_list_server;
344
static int ett_zbee_nwk_cmd_comm_clid_list_client;
345
346
/* Common. */
347
static GSList *zbee_gp_keyring;
348
static unsigned num_uat_key_records;
349
350
typedef struct {
351
    char *string;
352
    uint8_t byte_order;
353
    char *label;
354
    uint8_t key[ZBEE_SEC_CONST_KEYSIZE];
355
} uat_key_record_t;
356
357
static const uint8_t empty_key[ZBEE_SEC_CONST_KEYSIZE] = {
358
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
359
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
360
};
361
static uat_key_record_t *gp_uat_key_records;
362
static uat_t *zbee_gp_sec_key_table_uat;
363
364
/* UAT. */
365
0
UAT_CSTRING_CB_DEF(gp_uat_key_records, string, uat_key_record_t)
366
0
UAT_VS_DEF(gp_uat_key_records, byte_order, uat_key_record_t, uint8_t, 0, "Normal")
Unexecuted instantiation: packet-zbee-nwk-gp.c:gp_uat_key_records_byte_order_set_cb
Unexecuted instantiation: packet-zbee-nwk-gp.c:gp_uat_key_records_byte_order_tostr_cb
367
0
UAT_CSTRING_CB_DEF(gp_uat_key_records, label, uat_key_record_t)
368
369
/****************/
370
/* Field names. */
371
/****************/
372
373
/* Byte order. */
374
static const value_string byte_order_vals[] = {
375
    { 0, "Normal"},
376
    { 1, "Reverse"},
377
378
    { 0, NULL }
379
};
380
381
/* Application ID names. */
382
static const value_string zbee_nwk_gp_app_id_names[] = {
383
    { ZBEE_NWK_GP_APP_ID_LPED, "LPED" },
384
    { ZBEE_NWK_GP_APP_ID_ZGP, "ZGP" },
385
386
    { 0, NULL }
387
};
388
389
/* Green Power commands. */
390
391
/* Abbreviations:
392
 * GPDF commands sent:
393
 *   From GPD w/o payload: "F "
394
 *   From GPD w   payload: "FP"
395
 *   To GPD:               "T "
396
 */
397
398
#define zbee_nwk_gp_cmd_names_VALUE_STRING_LIST(XXX) \
399
    XXX( /*F */ ZB_GP_CMD_ID_IDENTIFY                                 , 0x00, "Identify" ) \
400
    XXX( /*F */ ZB_GP_CMD_ID_RECALL_SCENE0                            , 0x10, "Recall Scene 0" ) \
401
    XXX( /*F */ ZB_GP_CMD_ID_RECALL_SCENE1                            , 0x11, "Recall Scene 1" ) \
402
    XXX( /*F */ ZB_GP_CMD_ID_RECALL_SCENE2                            , 0x12, "Recall Scene 2" ) \
403
    XXX( /*F */ ZB_GP_CMD_ID_RECALL_SCENE3                            , 0x13, "Recall Scene 3" ) \
404
    XXX( /*F */ ZB_GP_CMD_ID_RECALL_SCENE4                            , 0x14, "Recall Scene 4" ) \
405
    XXX( /*F */ ZB_GP_CMD_ID_RECALL_SCENE5                            , 0x15, "Recall Scene 5" ) \
406
    XXX( /*F */ ZB_GP_CMD_ID_RECALL_SCENE6                            , 0x16, "Recall Scene 6" ) \
407
    XXX( /*F */ ZB_GP_CMD_ID_RECALL_SCENE7                            , 0x17, "Recall Scene 7" ) \
408
    XXX( /*F */ ZB_GP_CMD_ID_STORE_SCENE0                             , 0x18, "Store Scene 0" ) \
409
    XXX( /*F */ ZB_GP_CMD_ID_STORE_SCENE1                             , 0x19, "Store Scene 1" ) \
410
    XXX( /*F */ ZB_GP_CMD_ID_STORE_SCENE2                             , 0x1A, "Store Scene 2" ) \
411
    XXX( /*F */ ZB_GP_CMD_ID_STORE_SCENE3                             , 0x1B, "Store Scene 3" ) \
412
    XXX( /*F */ ZB_GP_CMD_ID_STORE_SCENE4                             , 0x1C, "Store Scene 4" ) \
413
    XXX( /*F */ ZB_GP_CMD_ID_STORE_SCENE5                             , 0x1D, "Store Scene 5" ) \
414
    XXX( /*F */ ZB_GP_CMD_ID_STORE_SCENE6                             , 0x1E, "Store Scene 6" ) \
415
    XXX( /*F */ ZB_GP_CMD_ID_STORE_SCENE7                             , 0x1F, "Store Scene 7" ) \
416
    XXX( /*F */ ZB_GP_CMD_ID_OFF                                      , 0x20, "Off" ) \
417
    XXX( /*F */ ZB_GP_CMD_ID_ON                                       , 0x21, "On" ) \
418
    XXX( /*F */ ZB_GP_CMD_ID_TOGGLE                                   , 0x22, "Toggle" ) \
419
    XXX( /*F */ ZB_GP_CMD_ID_RELEASE                                  , 0x23, "Release" ) \
420
    XXX( /*FP*/ ZB_GP_CMD_ID_MOVE_UP                                  , 0x30, "Move Up" ) \
421
    XXX( /*FP*/ ZB_GP_CMD_ID_MOVE_DOWN                                , 0x31, "Move Down" ) \
422
    XXX( /*FP*/ ZB_GP_CMD_ID_STEP_UP                                  , 0x32, "Step Up" ) \
423
    XXX( /*FP*/ ZB_GP_CMD_ID_STEP_DOWN                                , 0x33, "Step Down" ) \
424
    XXX( /*F */ ZB_GP_CMD_ID_LEVEL_CONTROL_STOP                       , 0x34, "Level Control/Stop" ) \
425
    XXX( /*FP*/ ZB_GP_CMD_ID_MOVE_UP_WITH_ON_OFF                      , 0x35, "Move Up (with On/Off)" ) \
426
    XXX( /*FP*/ ZB_GP_CMD_ID_MOVE_DOWN_WITH_ON_OFF                    , 0x36, "Move Down (with On/Off)" ) \
427
    XXX( /*FP*/ ZB_GP_CMD_ID_STEP_UP_WITH_ON_OFF                      , 0x37, "Step Up (with On/Off)" ) \
428
    XXX( /*FP*/ ZB_GP_CMD_ID_STEP_DOWN_WITH_ON_OFF                    , 0x38, "Step Down (with On/Off)" ) \
429
    XXX( /*F */ ZB_GP_CMD_ID_MOVE_HUE_STOP                            , 0x40, "Move Hue Stop" ) \
430
    XXX( /*FP*/ ZB_GP_CMD_ID_MOVE_HUE_UP                              , 0x41, "Move Hue Up" ) \
431
    XXX( /*FP*/ ZB_GP_CMD_ID_MOVE_HUE_DOWN                            , 0x42, "Move Hue Down" ) \
432
    XXX( /*FP*/ ZB_GP_CMD_ID_STEP_HUE_UP                              , 0x43, "Step Hue Up" ) \
433
    XXX( /*FP*/ ZB_GP_CMD_ID_STEP_HUW_DOWN                            , 0x44, "Step Hue Down" ) \
434
    XXX( /*F */ ZB_GP_CMD_ID_MOVE_SATURATION_STOP                     , 0x45, "Move Saturation Stop" ) \
435
    XXX( /*FP*/ ZB_GP_CMD_ID_MOVE_SATURATION_UP                       , 0x46, "Move Saturation Up" ) \
436
    XXX( /*FP*/ ZB_GP_CMD_ID_MOVE_SATURATION_DOWN                     , 0x47, "Move Saturation Down" ) \
437
    XXX( /*FP*/ ZB_GP_CMD_ID_STEP_SATURATION_UP                       , 0x48, "Step Saturation Up" ) \
438
    XXX( /*FP*/ ZB_GP_CMD_ID_STEP_SATURATION_DOWN                     , 0x49, "Step Saturation Down" ) \
439
    XXX( /*FP*/ ZB_GP_CMD_ID_MOVE_COLOR                               , 0x4A, "Move Color" ) \
440
    XXX( /*FP*/ ZB_GP_CMD_ID_STEP_COLOR                               , 0x4B, "Step Color" ) \
441
    XXX( /*F */ ZB_GP_CMD_ID_LOCK_DOOR                                , 0x50, "Lock Door" ) \
442
    XXX( /*F */ ZB_GP_CMD_ID_UNLOCK_DOOR                              , 0x51, "Unlock Door" ) \
443
    XXX( /*F */ ZB_GP_CMD_ID_PRESS11                                  , 0x60, "Press 1 of 1" ) \
444
    XXX( /*F */ ZB_GP_CMD_ID_RELEASE11                                , 0x61, "Release 1 of 1" ) \
445
    XXX( /*F */ ZB_GP_CMD_ID_PRESS12                                  , 0x62, "Press 1 of 2" ) \
446
    XXX( /*F */ ZB_GP_CMD_ID_RELEASE12                                , 0x63, "Release 1 of 2" ) \
447
    XXX( /*F */ ZB_GP_CMD_ID_PRESS22                                  , 0x64, "Press 2 of 2" ) \
448
    XXX( /*F */ ZB_GP_CMD_ID_RELEASE22                                , 0x65, "Release 2 of 2" ) \
449
    XXX( /*F */ ZB_GP_CMD_ID_SHORT_PRESS11                            , 0x66, "Short press 1 of 1" ) \
450
    XXX( /*F */ ZB_GP_CMD_ID_SHORT_PRESS12                            , 0x67, "Short press 1 of 2" ) \
451
    XXX( /*F */ ZB_GP_CMD_ID_SHORT_PRESS22                            , 0x68, "Short press 2 of 2" ) \
452
    XXX( /*FP*/ ZB_GP_CMD_ID_ATTRIBUTE_REPORTING                      , 0xA0, "Attribute reporting" ) \
453
    XXX( /*FP*/ ZB_GP_CMD_ID_MANUFACTURE_SPECIFIC_ATTR_REPORTING      , 0xA1, "Manufacturer-specific attribute reporting" ) \
454
    XXX( /*FP*/ ZB_GP_CMD_ID_MULTI_CLUSTER_REPORTING                  , 0xA2, "Multi-cluster reporting" ) \
455
    XXX( /*FP*/ ZB_GP_CMD_ID_MANUFACTURER_SPECIFIC_MCLUSTER_REPORTING , 0xA3, "Manufacturer-specific multi-cluster reporting" ) \
456
    XXX( /*FP*/ ZB_GP_CMD_ID_REQUEST_ATTRIBUTES                       , 0xA4, "Request Attributes" ) \
457
    XXX( /*FP*/ ZB_GP_CMD_ID_READ_ATTRIBUTES_RESPONSE                 , 0xA5, "Read Attributes Response" ) \
458
    XXX( /*FP*/ ZB_GP_CMD_ID_ZCL_TUNNELING                            , 0xA6, "ZCL Tunneling" ) \
459
    XXX( /*FP*/ ZB_GP_CMD_ID_ANY_SENSOR_COMMAND_A0_A3                 , 0xAF, "Any GPD sensor command (0xA0 - 0xA3)" ) \
460
    XXX( /*FP*/ ZB_GP_CMD_ID_COMMISSIONING                            , 0xE0, "Commissioning" ) \
461
    XXX( /*F */ ZB_GP_CMD_ID_DECOMMISSIONING                          , 0xE1, "Decommissioning" ) \
462
    XXX( /*F */ ZB_GP_CMD_ID_SUCCESS                                  , 0xE2, "Success" ) \
463
    XXX( /*FP*/ ZB_GP_CMD_ID_CHANNEL_REQUEST                          , 0xE3, "Channel Request" ) \
464
    XXX( /*T */ ZB_GP_CMD_ID_COMMISSIONING_REPLY                      , 0xF0, "Commissioning Reply" ) \
465
    XXX( /*T */ ZB_GP_CMD_ID_WRITE_ATTRIBUTES                         , 0xF1, "Write Attributes" ) \
466
    XXX( /*T */ ZB_GP_CMD_ID_READ_ATTRIBUTES                          , 0xF2, "Read Attributes" ) \
467
    XXX( /*T */ ZB_GP_CMD_ID_CHANNEL_CONFIGURATION                    , 0xF3, "Channel Configuration" )
468
469
VALUE_STRING_ENUM(zbee_nwk_gp_cmd_names);
470
471
VALUE_STRING_ARRAY(zbee_nwk_gp_cmd_names);
472
value_string_ext zbee_nwk_gp_cmd_names_ext = VALUE_STRING_EXT_INIT(zbee_nwk_gp_cmd_names);
473
474
475
/* Green Power devices. */
476
const value_string zbee_nwk_gp_device_ids_names[] = {
477
478
    /* GP GENERIC */
479
    { GPD_DEVICE_ID_GENERIC_GP_SIMPLE_GENERIC_1STATE_SWITCH,   "Generic: GP Simple Generic 1-state Switch" },
480
    { GPD_DEVICE_ID_GENERIC_GP_SIMPLE_GENERIC_2STATE_SWITCH,   "Generic: GP Simple Generic 2-state Switch" },
481
    { GPD_DEVICE_ID_GENERIC_GP_ON_OFF_SWITCH,                  "Generic: GP On/Off Switch" },
482
    { GPD_DEVICE_ID_GENERIC_GP_LEVEL_CONTROL_SWITCH,           "Generic: GP Level Control Switch" },
483
    { GPD_DEVICE_ID_GENERIC_GP_SIMPLE_SENSOR,                  "Generic: GP Simple Sensor" },
484
    { GPD_DEVICE_ID_GENERIC_GP_ADVANCED_GENERIC_1STATE_SWITCH, "Generic: GP Advanced Generic 1-state Switch" },
485
    { GPD_DEVICE_ID_GENERIC_GP_ADVANCED_GENERIC_2STATE_SWITCH, "Generic: GP Advanced Generic 2-state Switch" },
486
487
    /* GP LIGHTING */
488
    { GPD_DEVICE_ID_LIGHTING_GP_COLOR_DIMMER_SWITCH,           "Lighting: GP Color Dimmer Switch" },
489
    { GPD_DEVICE_ID_LIGHTING_GP_LIGHT_SENSOR,                  "Lighting: GP Light Sensor" },
490
    { GPD_DEVICE_ID_LIGHTING_GP_OCCUPANCY_SENSOR,              "Lighting: GP Occupancy Sensor" },
491
492
    /* GP CLOSURES */
493
    { GPD_DEVICE_ID_CLOSURES_GP_DOOR_LOCK_CONTROLLER,          "Closures: GP Door Lock Controller" },
494
495
    /* HVAC */
496
    { GPD_DEVICE_ID_HVAC_GP_TEMPERATURE_SENSOR,                "HVAC: GP Temperature Sensor" },
497
    { GPD_DEVICE_ID_HVAC_GP_PRESSURE_SENSOR,                   "HVAC: GP Pressure Sensor" },
498
    { GPD_DEVICE_ID_HVAC_GP_FLOW_SENSOR,                       "HVAC: GP Flow Sensor" },
499
    { GPD_DEVICE_ID_HVAC_GP_INDOOR_ENVIRONMENT_SENSOR,         "HVAC: GP Indoor Environment Sensor" },
500
501
    /* CUSTOM */
502
    { GPD_DEVICE_ID_MANUFACTURER_SPECIFIC,                     "Manufacturer Specific" },
503
504
    { 0, NULL }
505
};
506
static value_string_ext zbee_nwk_gp_device_ids_names_ext = VALUE_STRING_EXT_INIT(zbee_nwk_gp_device_ids_names);
507
508
/* GP directions. */
509
static const value_string zbee_nwk_gp_directions[] = {
510
    { ZBEE_NWK_GP_FC_EXT_DIRECTION_FROM_ZGPD, "From ZGPD" },
511
    { ZBEE_NWK_GP_FC_EXT_DIRECTION_FROM_ZGPP, "From ZGPP" },
512
513
    { 0, NULL }
514
};
515
516
/* Frame types for Green Power profile. */
517
static const value_string zbee_nwk_gp_frame_types[] = {
518
    { ZBEE_NWK_GP_FCF_DATA,        "Data" },
519
    { ZBEE_NWK_GP_FCF_MAINTENANCE, "Maintenance" },
520
521
    { 0, NULL }
522
};
523
524
/* GreenPeak Green Power devices. */
525
static const value_string zbee_nwk_gp_manufacturer_greenpeak_dev_names[] = {
526
    { ZBEE_NWK_GP_MANUF_GREENPEAK_IZDS,  "IAS Zone Door Sensor" },
527
    { ZBEE_NWK_GP_MANUF_GREENPEAK_IZDWS, "IAS Zone Door/Window Sensor" },
528
    { ZBEE_NWK_GP_MANUF_GREENPEAK_IZLS,  "IAS Zone Leakage Sensor" },
529
    { ZBEE_NWK_GP_MANUF_GREENPEAK_IZRHS, "IAS Zone Relative Humidity Sensor" },
530
531
    { 0, NULL }
532
};
533
534
/* GP Src ID names. */
535
static const value_string zbee_nwk_gp_src_id_names[] = {
536
    { ZBEE_NWK_GP_ZGPD_SRCID_ALL,     "All" },
537
    { ZBEE_NWK_GP_ZGPD_SRCID_UNKNOWN, "Unspecified" },
538
539
    { 0, NULL }
540
};
541
542
/* GP security key type names. */
543
static const value_string zbee_nwk_gp_src_sec_keys_type_names[] = {
544
    { ZBEE_NWK_GP_SECURITY_KEY_TYPE_NO_KEY,                            "No key" },
545
    { ZBEE_NWK_GP_SECURITY_KEY_TYPE_ZB_NWK_KEY,                        "ZigBee NWK key" },
546
    { ZBEE_NWK_GP_SECURITY_KEY_TYPE_GPD_GROUP_KEY,                     "GPD group key" },
547
    { ZBEE_NWK_GP_SECURITY_KEY_TYPE_NWK_KEY_DERIVED_GPD_KEY_GROUP_KEY, "NWK key derived GPD group key" },
548
    { ZBEE_NWK_GP_SECURITY_KEY_TYPE_PRECONFIGURED_INDIVIDUAL_GPD_KEY,  "Individual, out of the box GPD key" },
549
    { ZBEE_NWK_GP_SECURITY_KEY_TYPE_DERIVED_INDIVIDUAL_GPD_KEY,        "Derived individual GPD key" },
550
551
    { 0, NULL }
552
};
553
554
/* GP security levels. */
555
static const value_string zbee_nwk_gp_src_sec_levels_names[] = {
556
    { ZBEE_NWK_GP_SECURITY_LEVEL_NO,       "No security" },
557
    { ZBEE_NWK_GP_SECURITY_LEVEL_1LSB,     "1 LSB of frame counter and short MIC only" },
558
    { ZBEE_NWK_GP_SECURITY_LEVEL_FULL,     "Full frame counter and full MIC only" },
559
    { ZBEE_NWK_GP_SECURITY_LEVEL_FULLENCR, "Encryption with full frame counter and full MIC" },
560
561
    { 0, NULL }
562
};
563
564
/*************************/
565
/* Function definitions. */
566
/*************************/
567
568
/* UAT record copy callback. */
569
static void *
570
uat_key_record_copy_cb(void *n, const void *o, size_t siz _U_)
571
0
{
572
0
    uat_key_record_t *new_key = (uat_key_record_t *)n;
573
0
    const uat_key_record_t *old_key = (const uat_key_record_t *)o;
574
575
0
    new_key->string = g_strdup(old_key->string);
576
0
    new_key->label = g_strdup(old_key->label);
577
578
0
    return new_key;
579
0
}
580
581
/* UAT record free callback. */
582
static void
583
uat_key_record_free_cb(void *r)
584
0
{
585
0
    uat_key_record_t *key = (uat_key_record_t *)r;
586
0
    g_free(key->string);
587
0
    g_free(key->label);
588
0
}
589
590
/**
591
 *Parses a key string from left to right into a buffer with increasing (normal byte order) or decreasing (reverse
592
 *
593
 *@param key_str pointer to the string
594
 *@param key_buf destination buffer in memory
595
 *@param byte_order byte order
596
*/
597
static bool
598
zbee_gp_security_parse_key(const char *key_str, uint8_t *key_buf, bool byte_order)
599
0
{
600
0
    bool string_mode = false;
601
0
    char temp;
602
0
    int i, j;
603
604
0
    memset(key_buf, 0, ZBEE_SEC_CONST_KEYSIZE);
605
0
    if (key_str == NULL) {
606
0
        return false;
607
0
    }
608
0
    if ((temp = *key_str++) == '"') {
609
0
        string_mode = true;
610
0
        temp = *key_str++;
611
0
    }
612
0
    j = byte_order ? ZBEE_SEC_CONST_KEYSIZE - 1 : 0;
613
0
    for (i = ZBEE_SEC_CONST_KEYSIZE - 1; i >= 0; i--) {
614
0
        if (string_mode) {
615
0
            if (g_ascii_isprint(temp)) {
616
0
                key_buf[j] = temp;
617
0
                temp = *key_str++;
618
0
            } else {
619
0
                return false;
620
0
            }
621
0
        } else {
622
0
            if ((temp == ':') || (temp == '-') || (temp == ' ')) {
623
0
                temp = *(key_str++);
624
0
            }
625
0
            if (g_ascii_isxdigit(temp)) {
626
0
                key_buf[j] = g_ascii_xdigit_value(temp) << 4;
627
0
            } else {
628
0
                return false;
629
0
            }
630
0
            temp = *(key_str++);
631
0
            if (g_ascii_isxdigit(temp)) {
632
0
                key_buf[j] |= g_ascii_xdigit_value(temp);
633
0
            } else {
634
0
                return false;
635
0
            }
636
0
            temp = *(key_str++);
637
0
        }
638
0
        if (byte_order) {
639
0
            j--;
640
0
        } else {
641
0
            j++;
642
0
        }
643
0
    }
644
0
    return true;
645
0
}
646
647
/* UAT record update callback. */
648
static bool
649
uat_key_record_update_cb(void *r, char **err)
650
0
{
651
0
    uat_key_record_t *rec = (uat_key_record_t *)r;
652
653
0
    if (rec->string == NULL) {
654
0
         *err = g_strdup("Key can't be blank.");
655
0
         return false;
656
0
    } else {
657
0
        g_strstrip(rec->string);
658
0
        if (rec->string[0] != 0) {
659
0
            *err = NULL;
660
0
            if (!zbee_gp_security_parse_key(rec->string, rec->key, rec->byte_order)) {
661
0
                *err = ws_strdup_printf("Expecting %d hexadecimal bytes or a %d character double-quoted string",
662
0
                    ZBEE_SEC_CONST_KEYSIZE, ZBEE_SEC_CONST_KEYSIZE);
663
0
                return false;
664
0
            }
665
0
        } else {
666
0
            *err = g_strdup("Key can't be blank.");
667
0
            return false;
668
0
        }
669
0
    }
670
0
    return true;
671
0
}
672
673
15
static void uat_key_record_post_update_cb(void) {
674
15
    unsigned i;
675
676
15
    for (i = 0; i < num_uat_key_records; i++) {
677
0
        if (memcmp(gp_uat_key_records[i].key, empty_key, ZBEE_SEC_CONST_KEYSIZE) == 0) {
678
            /* key was not loaded from string yet */
679
0
            zbee_gp_security_parse_key(gp_uat_key_records[i].string, gp_uat_key_records[i].key,
680
0
                                       gp_uat_key_records[i].byte_order);
681
0
        }
682
0
    }
683
15
}
684
685
/**
686
 *Fills in ZigBee GP security nonce from the provided packet structure.
687
 *
688
 *@param packet ZigBee NWK packet.
689
 *@param nonce nonce buffer.
690
*/
691
static void
692
zbee_gp_make_nonce(zbee_nwk_green_power_packet *packet, uint8_t *nonce)
693
3
{
694
3
    memset(nonce, 0, ZBEE_SEC_CONST_NONCE_LEN);
695
696
    /* Source address */
697
3
    if (packet->application_id == ZBEE_NWK_GP_APP_ID_DEFAULT)
698
0
    {
699
0
        if (packet->direction == ZBEE_NWK_GP_FC_EXT_DIRECTION_FROM_ZGPD) {
700
0
            phtoleu32(nonce, packet->source_id);
701
0
        }
702
0
        phtoleu32(nonce+4, packet->source_id);
703
0
    }
704
3
    else if (packet->application_id == ZBEE_NWK_GP_APP_ID_ZGP)
705
0
    {
706
0
        phtoleu64(nonce, packet->ieee_packet_src64);
707
0
    }
708
709
    /* Frame counter */
710
3
    phtoleu32(nonce+8, packet->security_frame_counter);
711
712
    /* Security control */
713
3
    if ((packet->application_id == ZBEE_NWK_GP_APP_ID_ZGP) &&
714
0
        (packet->direction != ZBEE_NWK_GP_FC_EXT_DIRECTION_FROM_ZGPD)) {
715
0
        nonce[12] = (char)0xc5;    /* Security level = 0b101, Key Identifier = 0x00,
716
                                        Extended nonce = 0b0, Reserved = 0b00 */
717
3
    } else {
718
3
        nonce[12] = (char)0x05;    /* Security level = 0b101, Key Identifier = 0x00,
719
                                        Extended nonce = 0b0, Reserved = 0b11 */
720
3
    }
721
3
}
722
723
/**
724
 *Creates a nonce and decrypts secured ZigBee GP payload.
725
 *
726
 *@param packet ZigBee NWK packet.
727
 *@param enc_buffer encoded payload buffer.
728
 *@param offset payload offset.
729
 *@param dec_buffer decoded payload buffer.
730
 *@param payload_len payload length.
731
 *@param mic_len MIC length.
732
 *@param key key.
733
*/
734
static bool
735
zbee_gp_decrypt_payload(zbee_nwk_green_power_packet *packet, const uint8_t *enc_buffer, const unsigned offset, uint8_t
736
    *dec_buffer, unsigned payload_len, unsigned mic_len, uint8_t *key)
737
3
{
738
3
    uint8_t *key_buffer = key;
739
3
    uint8_t nonce[ZBEE_SEC_CONST_NONCE_LEN];
740
741
3
    zbee_gp_make_nonce(packet, nonce);
742
3
    if (zbee_sec_ccm_decrypt(key_buffer, nonce, enc_buffer, enc_buffer + offset, dec_buffer, offset, payload_len,
743
3
        mic_len)) {
744
1
        return true;
745
1
    }
746
747
2
    return false;
748
3
}
749
750
/**
751
 *Dissector for ZigBee Green Power commissioning.
752
 *
753
 *@param tvb pointer to buffer containing raw packet.
754
 *@param pinfo pointer to packet information fields.
755
 *@param tree pointer to data tree Wireshark uses to display packet.
756
 *@param packet packet data.
757
 *@param offset current payload offset.
758
 *@return payload processed offset.
759
*/
760
static unsigned
761
dissect_zbee_nwk_gp_cmd_commissioning(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
762
    zbee_nwk_green_power_packet *packet, unsigned offset)
763
10
{
764
10
    uint8_t comm_options;
765
10
    uint8_t comm_ext_options = 0;
766
10
    uint8_t appli_info_options = 0;
767
10
    uint16_t manufacturer_id = 0;
768
769
10
    uint8_t i;
770
10
    uint8_t gpd_cmd_num = 0;
771
10
    proto_item *gpd_cmd_list;
772
10
    proto_tree *gpd_cmd_list_tree;
773
774
10
    uint8_t length_of_clid_list_bm;
775
10
    uint8_t server_clid_num;
776
10
    uint8_t client_clid_num;
777
10
    proto_item *server_clid_list, *client_clid_list;
778
10
    proto_tree *server_clid_list_tree, *client_clid_list_tree;
779
780
10
    void *enc_buffer;
781
10
    uint8_t *enc_buffer_withA;
782
10
    uint8_t *dec_buffer;
783
10
    bool gp_decrypted;
784
10
    GSList *GSList_i;
785
10
    tvbuff_t *payload_tvb;
786
787
10
    static int * const options[] = {
788
10
        &hf_zbee_nwk_gp_cmd_comm_opt_mac_sec_num_cap,
789
10
        &hf_zbee_nwk_gp_cmd_comm_opt_rx_on_cap,
790
10
        &hf_zbee_nwk_gp_cmd_comm_opt_appli_info_present,
791
10
        &hf_zbee_nwk_gp_cmd_comm_opt_panid_req,
792
10
        &hf_zbee_nwk_gp_cmd_comm_opt_sec_key_req,
793
10
        &hf_zbee_nwk_gp_cmd_comm_opt_fixed_location,
794
10
        &hf_zbee_nwk_gp_cmd_comm_opt_ext_opt,
795
10
        NULL
796
10
    };
797
10
    static int * const ext_options[] = {
798
10
        &hf_zbee_nwk_gp_cmd_comm_ext_opt_sec_level_cap,
799
10
        &hf_zbee_nwk_gp_cmd_comm_ext_opt_key_type,
800
10
        &hf_zbee_nwk_gp_cmd_comm_ext_opt_gpd_key_present,
801
10
        &hf_zbee_nwk_gp_cmd_comm_ext_opt_gpd_key_encr,
802
10
        &hf_zbee_nwk_gp_cmd_comm_ext_opt_outgoing_counter,
803
10
        NULL
804
10
    };
805
10
    static int * const appli_info[] = {
806
10
        &hf_zbee_nwk_gp_cmd_comm_appli_info_mip,
807
10
        &hf_zbee_nwk_gp_cmd_comm_appli_info_mmip,
808
10
        &hf_zbee_nwk_gp_cmd_comm_appli_info_gclp,
809
10
        &hf_zbee_nwk_gp_cmd_comm_appli_info_crp,
810
10
        NULL
811
10
    };
812
10
    static int * const length_of_clid_list[] = {
813
10
        &hf_zbee_nwk_gp_cmd_comm_length_of_clid_list_server,
814
10
        &hf_zbee_nwk_gp_cmd_comm_length_of_clid_list_client,
815
10
        NULL
816
10
    };
817
818
    /* Get Device ID and display it. */
819
10
    proto_tree_add_item(tree, hf_zbee_nwk_gp_cmd_comm_device_id, tvb, offset, 1, ENC_LITTLE_ENDIAN);
820
10
    offset += 1;
821
    /* Get Options Field, build subtree and display the results. */
822
10
    comm_options = tvb_get_uint8(tvb, offset);
823
10
    proto_tree_add_bitmask(tree, tvb, offset, hf_zbee_nwk_gp_cmd_comm_opt, ett_zbee_nwk_cmd_options, options, ENC_NA);
824
10
    offset += 1;
825
826
10
    if (comm_options & ZBEE_NWK_GP_CMD_COMMISSIONING_OPT_EXT_OPTIONS) {
827
        /* Get extended Options Field, build subtree and display the results. */
828
3
        comm_ext_options = tvb_get_uint8(tvb, offset);
829
3
        proto_tree_add_bitmask(tree, tvb, offset, hf_zbee_nwk_gp_cmd_comm_ext_opt, ett_zbee_nwk_cmd_options, ext_options, ENC_NA);
830
3
        offset += 1;
831
3
        if (comm_ext_options & ZBEE_NWK_GP_CMD_COMMISSIONING_EXT_OPT_GPD_KEY_PRESENT) {
832
            /* Get security key and display it. */
833
2
            proto_tree_add_item(tree, hf_zbee_nwk_gp_cmd_comm_security_key, tvb, offset, ZBEE_SEC_CONST_KEYSIZE, ENC_NA);
834
2
            offset += ZBEE_SEC_CONST_KEYSIZE;
835
836
            /* Key is encrypted */
837
2
            if (comm_ext_options & ZBEE_NWK_GP_CMD_COMMISSIONING_EXT_OPT_GPD_KEY_ENCR) {
838
                /* Get Security MIC and display it. */
839
1
                proto_tree_add_item(tree, hf_zbee_nwk_gp_cmd_comm_gpd_sec_key_mic, tvb, offset, 4, ENC_LITTLE_ENDIAN);
840
1
                offset += 4;
841
842
1
                if (packet != NULL)
843
1
                {
844
                    /* Decrypt the security key */
845
1
                    dec_buffer = (uint8_t *)wmem_alloc(pinfo->pool, ZBEE_SEC_CONST_KEYSIZE);
846
1
                    enc_buffer_withA = (uint8_t *)wmem_alloc(pinfo->pool, 4 + ZBEE_SEC_CONST_KEYSIZE + 4); /* CCM* a (this is SrcID) + encKey + MIC */
847
1
                    enc_buffer = tvb_memdup(pinfo->pool, tvb, offset - ZBEE_SEC_CONST_KEYSIZE - 4, ZBEE_SEC_CONST_KEYSIZE + 4);
848
1
                    phtoleu32(enc_buffer_withA, packet->source_id);
849
1
                    memcpy(enc_buffer_withA+4, enc_buffer, ZBEE_SEC_CONST_KEYSIZE + 4);
850
1
                    gp_decrypted = false;
851
852
3
                    for (GSList_i = zbee_gp_keyring; GSList_i && !gp_decrypted; GSList_i = g_slist_next(GSList_i)) {
853
2
                        packet->security_frame_counter = packet->source_id; /* for Nonce creation*/
854
2
                        gp_decrypted = zbee_gp_decrypt_payload(packet, enc_buffer_withA, 4
855
2
                            , dec_buffer, ZBEE_SEC_CONST_KEYSIZE, 4, ((key_record_t *)(GSList_i->data))->key);
856
2
                    }
857
858
1
                    if (gp_decrypted) {
859
0
                        key_record_t key_record;
860
861
0
                        key_record.frame_num = 0;
862
0
                        key_record.label = NULL;
863
0
                        memcpy(key_record.key, dec_buffer, ZBEE_SEC_CONST_KEYSIZE);
864
0
                        zbee_gp_keyring = g_slist_prepend(zbee_gp_keyring, g_memdup2(&key_record, sizeof(key_record_t)));
865
866
0
                        payload_tvb = tvb_new_child_real_data(tvb, dec_buffer, ZBEE_SEC_CONST_KEYSIZE, ZBEE_SEC_CONST_KEYSIZE);
867
0
                        add_new_data_source(pinfo, payload_tvb, "Decrypted security key");
868
0
                    }
869
1
                }
870
1
            }
871
1
            else
872
1
            {
873
1
                key_record_t key_record;
874
1
                void *key;
875
876
1
                key_record.frame_num = 0;
877
1
                key_record.label = NULL;
878
1
                key = tvb_memdup(pinfo->pool, tvb, offset - ZBEE_SEC_CONST_KEYSIZE, ZBEE_SEC_CONST_KEYSIZE);
879
1
                memcpy(key_record.key, key, ZBEE_SEC_CONST_KEYSIZE);
880
1
                zbee_gp_keyring = g_slist_prepend(zbee_gp_keyring, g_memdup2(&key_record, sizeof(key_record_t)));
881
1
            }
882
2
        }
883
884
3
        if (comm_ext_options & ZBEE_NWK_GP_CMD_COMMISSIONING_EXT_OPT_OUT_COUNTER) {
885
            /* Get GPD Outgoing Frame Counter and display it. */
886
1
            proto_tree_add_item(tree, hf_zbee_nwk_gp_cmd_comm_outgoing_counter, tvb, offset, 4, ENC_LITTLE_ENDIAN);
887
1
            offset += 4;
888
1
        }
889
3
    }
890
    /* Display manufacturer specific data. */
891
10
    if (comm_options & ZBEE_NWK_GP_CMD_COMMISSIONING_OPT_APPLICATION_INFO) {
892
        /* Display application information. */
893
8
        appli_info_options = tvb_get_uint8(tvb, offset);
894
8
        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);
895
8
        offset += 1;
896
8
        if (appli_info_options & ZBEE_NWK_GP_CMD_COMMISSIONING_APPLI_INFO_MIP) {
897
            /* Get Manufacturer ID. */
898
4
            proto_tree_add_item_ret_uint16(tree, hf_zbee_nwk_gp_cmd_comm_manufacturer_id, tvb, offset, 2, ENC_LITTLE_ENDIAN, &manufacturer_id);
899
4
            offset += 2;
900
4
        }
901
8
        if (appli_info_options & ZBEE_NWK_GP_CMD_COMMISSIONING_APPLI_INFO_MMIP) {
902
            /* Get Manufacturer Device ID. */
903
6
            switch (manufacturer_id) {
904
0
                case ZBEE_NWK_GP_MANUF_ID_GREENPEAK:
905
0
                    proto_tree_add_item(tree, hf_zbee_nwk_gp_cmd_comm_manufacturer_greenpeak_dev_id, tvb, offset, 2,
906
0
                        ENC_LITTLE_ENDIAN);
907
0
                    offset += 2;
908
0
                    break;
909
6
                default:
910
6
                    proto_tree_add_item(tree, hf_zbee_nwk_gp_cmd_comm_manufacturer_dev_id, tvb, offset, 2, ENC_LITTLE_ENDIAN);
911
6
                    offset += 2;
912
6
                    break;
913
6
            }
914
6
        }
915
8
        if (appli_info_options & ZBEE_NWK_GP_CMD_COMMISSIONING_APPLI_INFO_GCLP) {
916
            /* Get and display number of GPD commands */
917
5
            proto_tree_add_item_ret_uint8(tree, hf_zbee_nwk_gp_cmd_comm_gpd_cmd_num, tvb, offset, 1, ENC_LITTLE_ENDIAN, &gpd_cmd_num);
918
5
            offset += 1;
919
            /* Display GPD command list */
920
5
            if (gpd_cmd_num > 0) {
921
4
                gpd_cmd_list = proto_tree_add_item(tree, hf_zbee_nwk_gp_cmd_comm_gpd_cmd_id_list,
922
4
                    tvb, offset, gpd_cmd_num, ENC_NA);
923
4
                gpd_cmd_list_tree = proto_item_add_subtree(gpd_cmd_list, ett_zbee_nwk_cmd_comm_gpd_cmd_id_list);
924
234
                for (i = 0; i < gpd_cmd_num; i++, offset++) {
925
                    /* Display command id */
926
230
                    proto_tree_add_item(gpd_cmd_list_tree, hf_zbee_nwk_gp_command_id,
927
230
                        tvb, offset, 1, ENC_LITTLE_ENDIAN);
928
230
                }
929
4
            }
930
5
        }
931
8
        if (appli_info_options & ZBEE_NWK_GP_CMD_COMMISSIONING_APPLI_INFO_CRP) {
932
            /* Get and display Cluster List */
933
6
            length_of_clid_list_bm = tvb_get_uint8(tvb, offset);
934
6
            server_clid_num = (length_of_clid_list_bm & ZBEE_NWK_GP_CMD_COMMISSIONING_CLID_LIST_LEN_SRV) >>
935
6
                ws_ctz(ZBEE_NWK_GP_CMD_COMMISSIONING_CLID_LIST_LEN_SRV);
936
6
            client_clid_num = (length_of_clid_list_bm & ZBEE_NWK_GP_CMD_COMMISSIONING_CLID_LIST_LEN_CLI ) >>
937
6
                ws_ctz(ZBEE_NWK_GP_CMD_COMMISSIONING_CLID_LIST_LEN_CLI);
938
939
6
            proto_tree_add_bitmask(tree, tvb, offset, hf_zbee_nwk_gp_cmd_comm_length_of_clid_list,
940
6
                ett_zbee_nwk_cmd_comm_length_of_clid_list, length_of_clid_list, ENC_NA);
941
6
            offset += 1;
942
943
6
            if (server_clid_num > 0) {
944
                /* Display server cluster list */
945
4
                server_clid_list = proto_tree_add_item(tree, hf_zbee_nwk_cmd_comm_clid_list_server,
946
4
                    tvb, offset, 2*server_clid_num, ENC_NA);
947
4
                server_clid_list_tree = proto_item_add_subtree(server_clid_list, ett_zbee_nwk_cmd_comm_clid_list_server);
948
                /* Retrieve server clusters */
949
35
                for (i = 0; i < server_clid_num; i++, offset += 2) {
950
31
                    proto_tree_add_item(server_clid_list_tree, hf_zbee_nwk_cmd_comm_cluster_id,
951
31
                        tvb, offset, 2, ENC_LITTLE_ENDIAN);
952
31
                }
953
4
            }
954
6
            if (client_clid_num > 0) {
955
                /* Display client cluster list */
956
4
                client_clid_list = proto_tree_add_item(tree, hf_zbee_nwk_cmd_comm_clid_list_client,
957
4
                    tvb, offset, 2*client_clid_num, ENC_NA);
958
4
                client_clid_list_tree = proto_item_add_subtree(client_clid_list, ett_zbee_nwk_cmd_comm_clid_list_client);
959
                /* Retrieve client clusters */
960
44
                for (i = 0; i < client_clid_num; i++, offset += 2) {
961
40
                    proto_tree_add_item(client_clid_list_tree, hf_zbee_nwk_cmd_comm_cluster_id,
962
40
                        tvb, offset, 2, ENC_LITTLE_ENDIAN);
963
40
                }
964
4
            }
965
6
        }
966
8
    }
967
10
    return offset;
968
10
} /* dissect_zbee_nwk_gp_cmd_commissioning */
969
970
/**
971
 *Dissector for ZigBee Green Power channel request.
972
 *
973
 *@param tvb pointer to buffer containing raw packet.
974
 *@param pinfo pointer to packet information fields.
975
 *@param tree pointer to data tree Wireshark uses to display packet.
976
 *@param packet packet data.
977
 *@param offset current payload offset.
978
 *@return payload processed offset.
979
*/
980
static unsigned
981
dissect_zbee_nwk_gp_cmd_channel_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
982
    zbee_nwk_green_power_packet *packet _U_, unsigned offset)
983
1
{
984
1
    static int * const channels[] = {
985
1
        &hf_zbee_nwk_gp_cmd_channel_request_toggling_behaviour_1st,
986
1
        &hf_zbee_nwk_gp_cmd_channel_request_toggling_behaviour_2nd,
987
1
        NULL
988
1
    };
989
990
    /* Get Command Options Field, build subtree and display the results. */
991
1
    proto_tree_add_bitmask(tree, tvb, offset, hf_zbee_nwk_gp_cmd_channel_request_toggling_behaviour, ett_zbee_nwk_cmd_options, channels, ENC_NA);
992
1
    offset += 1;
993
1
    return offset;
994
1
} /* dissect_zbee_nwk_gp_cmd_channel_request */
995
996
/**
997
 *Dissector for ZigBee Green Power channel configuration.
998
 *
999
 *@param tvb pointer to buffer containing raw packet.
1000
 *@param pinfo pointer to packet information fields.
1001
 *@param tree pointer to data tree Wireshark uses to display packet.
1002
 *@param packet packet data.
1003
 *@param offset current payload offset.
1004
 *@return payload processed offset.
1005
*/
1006
static unsigned
1007
dissect_zbee_nwk_gp_cmd_channel_configuration(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
1008
    zbee_nwk_green_power_packet *packet _U_, unsigned offset)
1009
1
{
1010
1
    static int * const channels[] = {
1011
1
        &hf_zbee_nwk_gp_cmd_channel_configuration,
1012
1
        NULL
1013
1
    };
1014
1015
    /* Get Command Options Field, build subtree and display the results. */
1016
1
    proto_tree_add_bitmask(tree, tvb, offset, hf_zbee_nwk_gp_cmd_operational_channel, ett_zbee_nwk_cmd_options, channels, ENC_NA);
1017
1018
1
    offset += 1;
1019
1
    return offset;
1020
1
} /* dissect_zbee_nwk_gp_cmd_channel_configuration */
1021
1022
/**
1023
 *Dissector for ZigBee Green Power commands attrib reporting.
1024
 *
1025
 *@param tvb pointer to buffer containing raw packet.
1026
 *@param pinfo pointer to packet information fields.
1027
 *@param tree pointer to data tree Wireshark uses to display packet.
1028
 *@param packet packet data.
1029
 *@param offset current payload offset.
1030
 *@param mfr_code manufacturer code.
1031
 *@return payload processed offset.
1032
*/
1033
static unsigned
1034
dissect_zbee_nwk_gp_cmd_attr_reporting(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
1035
    zbee_nwk_green_power_packet *packet _U_, unsigned offset, uint16_t mfr_code)
1036
30
{
1037
30
    uint16_t cluster_id;
1038
30
    proto_tree *field_tree;
1039
1040
    /* Get cluster ID and add it into the tree. */
1041
30
    proto_tree_add_item_ret_uint16(tree, hf_zbee_nwk_gp_zcl_attr_cluster_id, tvb, offset, 2, ENC_LITTLE_ENDIAN, &cluster_id);
1042
1043
30
    offset += 2;
1044
    /* Create subtree and parse ZCL Write Attribute Payload. */
1045
30
    field_tree = proto_tree_add_subtree_format(tree, tvb, offset, 2, ett_zbee_nwk_cmd_options, NULL,
1046
30
                                "Attribute reporting command for cluster: 0x%04X", cluster_id);
1047
1048
30
    dissect_zcl_report_attr(tvb, pinfo, field_tree, &offset, cluster_id, mfr_code, ZBEE_ZCL_FCF_TO_CLIENT);
1049
1050
30
    return offset;
1051
30
} /* dissect_zbee_nwk_gp_cmd_attr_reporting */
1052
1053
1054
/**
1055
 *      Dissector for ZigBee Green Power manufacturer specific attribute reporting.
1056
 *
1057
 *@param tvb pointer to buffer containing raw packet.
1058
 *@param pinfo pointer to packet information fields.
1059
 *@param tree pointer to data tree Wireshark uses to display packet.
1060
 *@param packet packet data.
1061
 *@param offset current payload offset.
1062
 *@return payload processed offset.
1063
 */
1064
static unsigned
1065
dissect_zbee_nwk_gp_cmd_MS_attr_reporting(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
1066
    zbee_nwk_green_power_packet *packet _U_, unsigned offset)
1067
11
{
1068
11
    uint16_t mfr_code;
1069
1070
    /*dissect manufacturer ID*/
1071
11
    proto_tree_add_item_ret_uint16(tree, hf_zbee_zcl_gp_cmd_ms_manufacturer_code, tvb, offset, 2, ENC_LITTLE_ENDIAN, &mfr_code);
1072
11
    offset += 2;
1073
1074
11
    offset = dissect_zbee_nwk_gp_cmd_attr_reporting(tvb, pinfo, tree, packet, offset, mfr_code);
1075
1076
11
    return offset;
1077
11
}/*dissect_zbee_nwk_gp_cmd_MS_attr_reporting*/
1078
1079
1080
1081
1082
/**
1083
 *Dissector for ZigBee Green Power commissioning reply.
1084
 *
1085
 *@param tvb pointer to buffer containing raw packet.
1086
 *@param pinfo pointer to packet information fields.
1087
 *@param tree pointer to data tree Wireshark uses to display packet.
1088
 *@param packet packet data.
1089
 *@param offset current payload offset.
1090
 *@return payload processed offset.
1091
*/
1092
static unsigned
1093
dissect_zbee_nwk_gp_cmd_commissioning_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1094
    zbee_nwk_green_power_packet *packet, unsigned offset)
1095
3
{
1096
3
    uint8_t cr_options;
1097
3
    uint8_t cr_sec_level;
1098
1099
3
    void *enc_buffer;
1100
3
    uint8_t *enc_buffer_withA;
1101
3
    uint8_t *dec_buffer;
1102
3
    bool gp_decrypted;
1103
3
    GSList *GSList_i;
1104
3
    tvbuff_t *payload_tvb;
1105
1106
3
    static int * const options[] = {
1107
3
        &hf_zbee_nwk_gp_cmd_comm_rep_opt_panid_present,
1108
3
        &hf_zbee_nwk_gp_cmd_comm_rep_opt_sec_key_present,
1109
3
        &hf_zbee_nwk_gp_cmd_comm_rep_opt_key_encr,
1110
3
        &hf_zbee_nwk_gp_cmd_comm_rep_opt_sec_level,
1111
3
        &hf_zbee_nwk_gp_cmd_comm_rep_opt_sec_type,
1112
3
        NULL
1113
3
    };
1114
1115
    /* Get Options Field, build subtree and display the results. */
1116
3
    cr_options = tvb_get_uint8(tvb, offset);
1117
3
    proto_tree_add_bitmask(tree, tvb, offset, hf_zbee_nwk_gp_cmd_comm_rep_opt, ett_zbee_nwk_cmd_options, options, ENC_NA);
1118
3
    offset += 1;
1119
1120
    /* Parse and display security Pan ID value. */
1121
3
    if (cr_options & ZBEE_NWK_GP_CMD_COMMISSIONING_REP_OPT_PAN_ID_PRESENT) {
1122
1
        proto_tree_add_item(tree, hf_zbee_nwk_gp_cmd_comm_rep_pan_id, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1123
1
        offset += 2;
1124
1
    }
1125
1126
3
    cr_sec_level = (cr_options & ZBEE_NWK_GP_CMD_COMMISSIONING_REP_OPT_SEC_LEVEL) >>
1127
3
        ws_ctz(ZBEE_NWK_GP_CMD_COMMISSIONING_REP_OPT_SEC_LEVEL);
1128
1129
    /* Parse and display security key. */
1130
3
    if (cr_options & ZBEE_NWK_GP_CMD_COMMISSIONING_REP_OPT_SEC_KEY_PRESENT) {
1131
1
        proto_tree_add_item(tree, hf_zbee_nwk_gp_cmd_comm_security_key, tvb, offset, ZBEE_SEC_CONST_KEYSIZE, ENC_NA);
1132
1
        offset += ZBEE_SEC_CONST_KEYSIZE;
1133
1134
        /* Key is present clear, add to the key ring */
1135
1
        if (!(cr_options & ZBEE_NWK_GP_CMD_COMMISSIONING_REP_OPT_KEY_ENCR)) {
1136
1
            key_record_t key_record;
1137
1
            void *key;
1138
1139
1
            key_record.frame_num = 0;
1140
1
            key_record.label = NULL;
1141
1
            key = tvb_memdup(pinfo->pool, tvb, offset - ZBEE_SEC_CONST_KEYSIZE, ZBEE_SEC_CONST_KEYSIZE);
1142
1
            memcpy(key_record.key, key, ZBEE_SEC_CONST_KEYSIZE);
1143
1
            zbee_gp_keyring = g_slist_prepend(zbee_gp_keyring, g_memdup2(&key_record, sizeof(key_record_t)));
1144
1
        }
1145
1
    }
1146
    /* Parse and display security MIC. */
1147
3
    if ((cr_options & ZBEE_NWK_GP_CMD_COMMISSIONING_REP_OPT_KEY_ENCR) &&
1148
1
        (cr_options & ZBEE_NWK_GP_CMD_COMMISSIONING_REP_OPT_SEC_KEY_PRESENT)) {
1149
0
        proto_tree_add_item(tree, hf_zbee_nwk_gp_cmd_comm_gpd_sec_key_mic, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1150
0
        offset += 4;
1151
0
    }
1152
1153
    /* Parse and display Frame Counter and decrypt key */
1154
3
    if ((cr_options & ZBEE_NWK_GP_CMD_COMMISSIONING_REP_OPT_KEY_ENCR) &&
1155
1
        (cr_options & ZBEE_NWK_GP_CMD_COMMISSIONING_REP_OPT_SEC_KEY_PRESENT) &&
1156
0
        ((cr_sec_level == ZBEE_NWK_GP_SECURITY_LEVEL_FULL) ||
1157
0
        (cr_sec_level == ZBEE_NWK_GP_SECURITY_LEVEL_FULLENCR))) {
1158
0
        if (offset + 4 <= tvb_captured_length(tvb)){
1159
0
            proto_tree_add_item(tree, hf_zbee_nwk_gp_cmd_comm_rep_frame_counter, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1160
0
            offset += 4;
1161
1162
0
            if (packet != NULL)
1163
0
            {
1164
                /* decrypt the security key*/
1165
0
                dec_buffer = (uint8_t *)wmem_alloc(pinfo->pool, ZBEE_SEC_CONST_KEYSIZE);
1166
0
                enc_buffer_withA = (uint8_t *)wmem_alloc(pinfo->pool, 4 + ZBEE_SEC_CONST_KEYSIZE + 4); /* CCM* a (this is SrcID) + encKey + MIC */
1167
0
                enc_buffer = tvb_memdup(pinfo->pool, tvb, offset - ZBEE_SEC_CONST_KEYSIZE - 4 - 4, ZBEE_SEC_CONST_KEYSIZE + 4);
1168
0
                phtoleu32(enc_buffer_withA, packet->source_id); /* enc_buffer_withA = CCM* a (srcID) | enc_buffer */
1169
0
                memcpy(enc_buffer_withA+4, enc_buffer, ZBEE_SEC_CONST_KEYSIZE + 4);
1170
0
                gp_decrypted = false;
1171
1172
0
                for (GSList_i = zbee_gp_keyring; GSList_i && !gp_decrypted; GSList_i = g_slist_next(GSList_i)) {
1173
0
                    packet->security_frame_counter = tvb_get_uint32(tvb, offset - 4, ENC_LITTLE_ENDIAN); /*for Nonce creation */
1174
0
                    gp_decrypted = zbee_gp_decrypt_payload(packet, enc_buffer_withA, 4
1175
0
                        , dec_buffer, ZBEE_SEC_CONST_KEYSIZE, 4, ((key_record_t *)(GSList_i->data))->key);
1176
0
                }
1177
1178
0
                if (gp_decrypted) {
1179
0
                    key_record_t key_record;
1180
1181
0
                    key_record.frame_num = 0;
1182
0
                    key_record.label = NULL;
1183
0
                    memcpy(key_record.key, dec_buffer, ZBEE_SEC_CONST_KEYSIZE);
1184
0
                    zbee_gp_keyring = g_slist_prepend(zbee_gp_keyring, g_memdup2(&key_record, sizeof(key_record_t)));
1185
1186
0
                    payload_tvb = tvb_new_child_real_data(tvb, dec_buffer, ZBEE_SEC_CONST_KEYSIZE, ZBEE_SEC_CONST_KEYSIZE);
1187
0
                    add_new_data_source(pinfo, payload_tvb, "Decrypted security key");
1188
0
                }
1189
0
            }
1190
0
        }
1191
0
        else{
1192
            /* This field is new in 2016 specification, older implementation may exist without it */
1193
0
            proto_tree_add_expert_remaining(tree, pinfo, &ei_zbee_nwk_gp_com_rep_no_out_cnt, tvb, 0);
1194
0
        }
1195
0
    }
1196
3
    return offset;
1197
3
} /* dissect_zbee_nwk_gp_cmd_commissioning_reply */
1198
1199
/**
1200
 * Dissector for ZigBee Green Power read attributes and request attributes commands.
1201
 *
1202
 *@param tvb pointer to buffer containing raw packet.
1203
 *@param pinfo pointer to packet information fields.
1204
 *@param tree pointer to data tree Wireshark uses to display packet.
1205
 *@param packet packet data.
1206
 *@param offset current payload offset.
1207
 *@return payload processed offset.
1208
 */
1209
static unsigned
1210
dissect_zbee_nwk_gp_cmd_read_attributes(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
1211
    zbee_nwk_green_power_packet *packet _U_, unsigned offset)
1212
26
{
1213
26
    uint8_t cr_options = 0;
1214
26
    proto_tree *subtree = NULL;
1215
26
    uint16_t cluster_id;
1216
26
    uint16_t mfr_code = ZBEE_MFG_CODE_NONE;
1217
26
    uint8_t record_list_len;
1218
26
    unsigned tvb_len;
1219
26
    uint8_t i;
1220
1221
26
    static int * const options[] = {
1222
26
        &hf_zbee_nwk_gp_cmd_read_att_opt_multi_rec,
1223
26
        &hf_zbee_nwk_gp_cmd_read_att_opt_man_field_present,
1224
26
        NULL
1225
26
    };
1226
1227
    /* Get Options Field, build subtree and display the results. */
1228
26
    cr_options = tvb_get_uint8(tvb, offset);
1229
26
    proto_tree_add_bitmask(tree, tvb, offset, hf_zbee_nwk_gp_cmd_read_att_opt, ett_zbee_nwk_cmd_options, options, ENC_NA);
1230
1231
26
    offset += 1;
1232
    /* Parse and display manufacturer ID value. */
1233
26
    if (cr_options & ZBEE_NWK_GP_CMD_READ_ATTRIBUTE_OPT_MAN_FIELD_PRESENT) {
1234
13
        proto_tree_add_item_ret_uint16(tree, hf_zbee_zcl_gp_cmd_ms_manufacturer_code, tvb, offset, 2, ENC_LITTLE_ENDIAN, &mfr_code);
1235
13
        offset += 2;
1236
13
    }
1237
1238
26
    tvb_len = tvb_captured_length(tvb);
1239
232
    while (offset < tvb_len)
1240
206
    {
1241
        /* Create subtree and parse attributes list. */
1242
206
        subtree = proto_tree_add_subtree_format(tree, tvb, offset, -1, ett_zbee_nwk_clu_rec, NULL, "Cluster Record Request");
1243
1244
        /* Get cluster ID and add it into the subtree. */
1245
206
        proto_tree_add_item_ret_uint16(subtree, hf_zbee_nwk_gp_zcl_attr_cluster_id, tvb, offset, 2, ENC_LITTLE_ENDIAN, &cluster_id);
1246
206
        offset += 2;
1247
        /* Get length of record list (number of attributes * 2). */
1248
206
        proto_tree_add_item_ret_uint8(subtree, hf_zbee_nwk_gp_cmd_read_att_record_len, tvb, offset, 1, ENC_LITTLE_ENDIAN, &record_list_len);
1249
206
        offset += 1;
1250
1251
1.77k
        for(i=0 ; i<record_list_len ; i+=2)
1252
1.56k
        {
1253
            /* Dissect the attribute identifier */
1254
1.56k
            dissect_zcl_attr_id(tvb, subtree, &offset, cluster_id, mfr_code, ZBEE_ZCL_FCF_TO_CLIENT);
1255
1.56k
        }
1256
206
    }
1257
26
    return offset;
1258
26
} /* dissect_zbee_nwk_gp_cmd_read_attributes */
1259
/**
1260
 * Dissector for ZigBee Green Power write attributes commands.
1261
 *
1262
 *@param tvb pointer to buffer containing raw packet.
1263
 *@param pinfo pointer to packet information fields.
1264
 *@param tree pointer to data tree Wireshark uses to display packet.
1265
 *@param packet packet data.
1266
 *@param offset current payload offset.
1267
 *@return payload processed offset.
1268
 */
1269
static unsigned
1270
dissect_zbee_nwk_gp_cmd_write_attributes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1271
    zbee_nwk_green_power_packet *packet _U_, unsigned offset)
1272
368
{
1273
368
    uint8_t cr_options = 0;
1274
368
    proto_tree *subtree = NULL;
1275
368
    proto_tree *att_tree = NULL;
1276
368
    uint16_t mfr_code = ZBEE_MFG_CODE_NONE;
1277
368
    uint16_t cluster_id;
1278
368
    uint8_t record_list_len;
1279
368
    unsigned tvb_len;
1280
368
    uint16_t attr_id;
1281
368
    unsigned end_byte;
1282
    //uint8_t i;
1283
1284
368
    static int * const options[] = {
1285
368
        &hf_zbee_nwk_gp_cmd_read_att_opt_multi_rec,
1286
368
        &hf_zbee_nwk_gp_cmd_read_att_opt_man_field_present,
1287
368
        NULL
1288
368
    };
1289
1290
    /* Get Options Field, build subtree and display the results. */
1291
368
    cr_options = tvb_get_uint8(tvb, offset);
1292
368
    proto_tree_add_bitmask(tree, tvb, offset, hf_zbee_nwk_gp_cmd_read_att_opt, ett_zbee_nwk_cmd_options, options, ENC_NA);
1293
1294
368
    offset += 1;
1295
    /* Parse and display manufacturer ID value. */
1296
368
    if (cr_options & ZBEE_NWK_GP_CMD_READ_ATTRIBUTE_OPT_MAN_FIELD_PRESENT) {
1297
8
        proto_tree_add_item_ret_uint16(tree, hf_zbee_zcl_gp_cmd_ms_manufacturer_code, tvb, offset, 2, ENC_LITTLE_ENDIAN, &mfr_code);
1298
8
        offset += 2;
1299
8
    }
1300
1301
368
    tvb_len = tvb_captured_length(tvb);
1302
1.90k
    while (offset < tvb_len)
1303
1.53k
    {
1304
        /* Create subtree and parse attributes list. */
1305
1.53k
        subtree = proto_tree_add_subtree_format(tree, tvb, offset, -1, ett_zbee_nwk_clu_rec, NULL, "Write Cluster Record");
1306
1307
        /* Get cluster ID and add it into the subtree. */
1308
1.53k
        proto_tree_add_item_ret_uint16(subtree, hf_zbee_nwk_gp_zcl_attr_cluster_id, tvb, offset, 2, ENC_LITTLE_ENDIAN, &cluster_id);
1309
1.53k
        offset += 2;
1310
        /* Get length of record list. */
1311
1.53k
        record_list_len = tvb_get_uint8(tvb, offset);
1312
1.53k
        proto_tree_add_item(subtree, hf_zbee_nwk_gp_cmd_read_att_record_len, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1313
1.53k
        offset += 1;
1314
1315
1.53k
        end_byte = offset + record_list_len;
1316
8.81k
        while ( offset < end_byte)
1317
7.27k
        {
1318
            /* Create subtree for attribute status field */
1319
7.27k
            att_tree = proto_tree_add_subtree_format(subtree, tvb, offset, 0, ett_zbee_nwk_att_rec, NULL, "Write Attribute record");
1320
1321
            /* Dissect the attribute identifier */
1322
7.27k
            attr_id = tvb_get_letohs(tvb, offset);
1323
7.27k
            dissect_zcl_attr_id(tvb, att_tree, &offset, cluster_id, mfr_code, ZBEE_ZCL_FCF_TO_CLIENT);
1324
1325
            /* Dissect the attribute data type and data */
1326
7.27k
            dissect_zcl_attr_data_type_val(tvb, pinfo, att_tree, &offset, attr_id, cluster_id, mfr_code, ZBEE_ZCL_FCF_TO_CLIENT);
1327
7.27k
        }
1328
1.53k
    }
1329
368
    return offset;
1330
368
} /* dissect_zbee_nwk_gp_cmd_write_attributes */
1331
1332
1333
/**
1334
 * Dissector for ZigBee Green Power read attribute response command.
1335
 *
1336
 *@param tvb pointer to buffer containing raw packet.
1337
 *@param pinfo pointer to packet information fields.
1338
 *@param tree pointer to data tree Wireshark uses to display packet.
1339
 *@param packet packet data.
1340
 *@param offset current payload offset.
1341
 *@return payload processed offset.
1342
 */
1343
static unsigned
1344
dissect_zbee_nwk_gp_cmd_read_attributes_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1345
    zbee_nwk_green_power_packet *packet _U_, unsigned offset)
1346
156
{
1347
156
    uint8_t cr_options;
1348
156
    proto_tree *subtree = NULL;
1349
156
    proto_tree *att_tree = NULL;
1350
156
    uint16_t cluster_id;
1351
156
    uint16_t attr_id;
1352
156
    uint16_t mfr_code = ZBEE_MFG_CODE_NONE;
1353
156
    uint8_t record_list_len;
1354
156
    unsigned tvb_len;
1355
156
    unsigned end_byte;
1356
1357
156
    static int * const options[] = {
1358
156
        &hf_zbee_nwk_gp_cmd_read_att_opt_multi_rec,
1359
156
        &hf_zbee_nwk_gp_cmd_read_att_opt_man_field_present,
1360
156
        NULL
1361
156
    };
1362
1363
    /* Get Options Field, build subtree and display the results. */
1364
156
    cr_options = tvb_get_uint8(tvb, offset);
1365
156
    proto_tree_add_bitmask(tree, tvb, offset, hf_zbee_nwk_gp_cmd_read_att_opt, ett_zbee_nwk_cmd_options, options, ENC_NA);
1366
156
    offset += 1;
1367
1368
    /* Parse and display manufacturer ID value. */
1369
156
    if (cr_options & ZBEE_NWK_GP_CMD_READ_ATTRIBUTE_OPT_MAN_FIELD_PRESENT) {
1370
55
        proto_tree_add_item_ret_uint16(tree, hf_zbee_zcl_gp_cmd_ms_manufacturer_code, tvb, offset, 2, ENC_LITTLE_ENDIAN, &mfr_code);
1371
55
        offset += 2;
1372
55
    }
1373
1374
156
    tvb_len = tvb_captured_length(tvb);
1375
1.00k
    while (offset < tvb_len)
1376
845
    {
1377
        /* Create subtree and parse attributes list. */
1378
845
        subtree = proto_tree_add_subtree_format(tree, tvb, offset,0, ett_zbee_nwk_clu_rec, NULL, "Cluster record");
1379
1380
        /* Get cluster ID and add it into the subtree. */
1381
845
        proto_tree_add_item_ret_uint16(subtree, hf_zbee_nwk_gp_zcl_attr_cluster_id, tvb, offset, 2, ENC_LITTLE_ENDIAN, &cluster_id);
1382
845
        offset += 2;
1383
        /* Get length of record list in bytes. */
1384
845
        record_list_len = tvb_get_uint8(tvb, offset);
1385
845
        proto_tree_add_item(subtree, hf_zbee_nwk_gp_cmd_read_att_record_len, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1386
845
        offset += 1;
1387
1388
845
        end_byte = offset + record_list_len;
1389
4.34k
        while ( offset < end_byte)
1390
3.49k
        {
1391
            /* Create subtree for attribute status field */
1392
            /* TODO ett_ could be an array to permit not to unroll all always */
1393
3.49k
            att_tree = proto_tree_add_subtree_format(subtree, tvb, offset, 0, ett_zbee_nwk_att_rec, NULL, "Read Attribute record");
1394
1395
            /* Dissect the attribute identifier */
1396
3.49k
            attr_id = tvb_get_letohs(tvb, offset);
1397
3.49k
            dissect_zcl_attr_id(tvb, att_tree, &offset, cluster_id, mfr_code, ZBEE_ZCL_FCF_TO_CLIENT);
1398
1399
            /* Dissect the status and optionally the data type and value */
1400
3.49k
            if (dissect_zcl_attr_uint8(tvb, att_tree, &offset, &hf_zbee_nwk_gp_zcl_attr_status)
1401
3.49k
                == ZBEE_ZCL_STAT_SUCCESS)
1402
1.14k
            {
1403
                /* Dissect the attribute data type and data */
1404
1.14k
                dissect_zcl_attr_data_type_val(tvb, pinfo, att_tree, &offset, attr_id, cluster_id, mfr_code, ZBEE_ZCL_FCF_TO_CLIENT);
1405
1.14k
            }
1406
2.34k
            else
1407
2.34k
            {
1408
                /* Data type field is always present (not like in ZCL read attribute response command) */
1409
2.34k
                dissect_zcl_attr_data(tvb, pinfo, att_tree, &offset,
1410
2.34k
                    dissect_zcl_attr_uint8(tvb, att_tree, &offset, &hf_zbee_nwk_gp_zcl_attr_data_type), ZBEE_ZCL_FCF_TO_CLIENT );
1411
2.34k
            }
1412
3.49k
        }
1413
845
    }
1414
156
    return offset;
1415
156
} /* dissect_zbee_nwk_gp_cmd_read_attributes_response */
1416
1417
/**
1418
 * Dissector for ZigBee Green Power ZCL tunneling command.
1419
 *
1420
 *@param tvb pointer to buffer containing raw packet.
1421
 *@param pinfo pointer to packet information fields.
1422
 *@param tree pointer to data tree Wireshark uses to display packet.
1423
 *@param packet packet data.
1424
 *@param offset current payload offset.
1425
 *@return payload processed offset.
1426
 */
1427
static unsigned
1428
dissect_zbee_nwk_gp_cmd_zcl_tunneling(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
1429
    zbee_nwk_green_power_packet *packet _U_, unsigned offset)
1430
1
{
1431
1
    uint8_t tun_options;
1432
1433
1
    static int * const options[] = {
1434
1
        &hf_zbee_nwk_gp_cmd_zcl_tunnel_opt_frame_type,
1435
1
        &hf_zbee_nwk_gp_cmd_zcl_tunnel_opt_man_field_present,
1436
1
        &hf_zbee_nwk_gp_cmd_zcl_tunnel_opt_direction,
1437
1
        NULL
1438
1
    };
1439
1440
    /* Get Options Field, build subtree and display the results. */
1441
1
    tun_options = tvb_get_uint8(tvb, offset);
1442
1
    proto_tree_add_bitmask(tree, tvb, offset, hf_zbee_nwk_gp_cmd_zcl_tunnel_opt, ett_zbee_nwk_cmd_options, options, ENC_NA);
1443
1
    offset += 1;
1444
1445
    /* Parse and display manufacturer ID value. */
1446
1
    if (tun_options & ZBEE_NWK_GP_CMD_ZCL_TUNNEL_OPT_MAN_FIELD_PRESENT) {
1447
1
        proto_tree_add_item(tree, hf_zbee_zcl_gp_cmd_ms_manufacturer_code, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1448
1
        offset += 2;
1449
1
    }
1450
1451
1
    proto_tree_add_item(tree, hf_zbee_nwk_gp_zcl_attr_cluster_id, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1452
1
    offset += 2;
1453
1454
1
    proto_tree_add_item(tree, hf_zbee_nwk_gp_cmd_zcl_tunnel_command_id, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1455
1
    offset += 1;
1456
1457
1
    proto_tree_add_item(tree, hf_zbee_nwk_gp_cmd_zcl_tunnel_payload_len, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1458
1
    offset += 1;
1459
1460
    /* We're not parsing the ZCL payload, as it's non-trivial and will require a lot of refactoring of the
1461
     * ZCL data parsers to make work. For now, let it just show up as raw data. */
1462
1463
1
    return offset;
1464
1
} /* dissect_zbee_nwk_gp_cmd_zcl_tunneling */
1465
1466
/**
1467
 *Dissector for ZigBee Green Power multi-cluster reporting command.
1468
 *
1469
 *@param tvb pointer to buffer containing raw packet.
1470
 *@param pinfo pointer to packet information fields.
1471
 *@param tree pointer to data tree Wireshark uses to display packet.
1472
 *@param packet packet data.
1473
 *@param offset current payload offset.
1474
 *@param mfr_code manufacturer code.
1475
 *@return payload processed offset.
1476
 */
1477
static unsigned
1478
dissect_zbee_nwk_gp_cmd_multi_cluster_reporting(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
1479
    zbee_nwk_green_power_packet *packet _U_, unsigned offset, uint16_t mfr_code)
1480
154
{
1481
154
    proto_tree *subtree = NULL;
1482
154
    uint16_t cluster_id;
1483
154
    uint16_t attr_id;
1484
154
    unsigned tvb_len;
1485
1486
154
    tvb_len = tvb_captured_length(tvb);
1487
3.55k
    while (offset < tvb_len)
1488
3.40k
    {
1489
        /* Create subtree and parse attributes list. */
1490
3.40k
        subtree = proto_tree_add_subtree_format(tree, tvb, offset, 0, ett_zbee_nwk_clu_rec, NULL, "Cluster record"); //TODO for cluster %% blabla
1491
1492
        /* Get cluster ID and add it into the subtree. */
1493
3.40k
        proto_tree_add_item_ret_uint16(subtree, hf_zbee_nwk_gp_zcl_attr_cluster_id, tvb, offset, 2, ENC_LITTLE_ENDIAN, &cluster_id);
1494
3.40k
        offset += 2;
1495
1496
        /* Dissect the attribute identifier */
1497
3.40k
        attr_id = tvb_get_letohs(tvb, offset);
1498
3.40k
        dissect_zcl_attr_id(tvb, subtree, &offset, cluster_id, mfr_code, ZBEE_ZCL_FCF_TO_CLIENT);
1499
1500
        /* Dissect the attribute data type and data */
1501
3.40k
        dissect_zcl_attr_data_type_val(tvb, pinfo, subtree, &offset, attr_id, cluster_id, mfr_code, ZBEE_ZCL_FCF_TO_CLIENT);
1502
        // TODO how to dissect when data type is different from expected one for this attribute ? this shouldn't happen
1503
3.40k
    }
1504
154
    return offset;
1505
154
} /* dissect_zbee_nwk_gp_cmd_multi_cluster_reporting */
1506
1507
1508
/**
1509
 *Dissector for ZigBee Green Power commands manufacturer specific attrib reporting.
1510
 *
1511
 *@param tvb pointer to buffer containing raw packet.
1512
 *@param pinfo pointer to packet information fields.
1513
 *@param tree pointer to data tree Wireshark uses to display packet.
1514
 *@param packet packet data.
1515
 *@param offset current payload offset.
1516
 *@return payload processed offset.
1517
 */
1518
static unsigned
1519
dissect_zbee_nwk_gp_cmd_MS_multi_cluster_reporting(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
1520
    zbee_nwk_green_power_packet *packet _U_, unsigned offset)
1521
3
{
1522
3
    uint16_t mfr_code;
1523
1524
    /*dissect manufacturer ID*/
1525
3
    proto_tree_add_item_ret_uint16(tree, hf_zbee_zcl_gp_cmd_ms_manufacturer_code, tvb, offset, 2, ENC_LITTLE_ENDIAN, &mfr_code);
1526
3
    offset += 2;
1527
1528
3
    offset = dissect_zbee_nwk_gp_cmd_multi_cluster_reporting(tvb, pinfo, tree, packet, offset, mfr_code);
1529
1530
3
    return offset;
1531
3
}/*dissect_zbee_nwk_gp_cmd_MS_multi_cluster_reporting*/
1532
1533
/**
1534
 *Dissector for ZigBee Green Power Move Color.
1535
 *
1536
 *@param tvb pointer to buffer containing raw packet.
1537
 *@param pinfo pointer to packet information fields.
1538
 *@param tree pointer to data tree Wireshark uses to display packet.
1539
 *@param packet packet data.
1540
 *@param offset current payload offset.
1541
 *@return payload processed offset.
1542
*/
1543
static unsigned
1544
dissect_zbee_nwk_gp_cmd_move_color(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
1545
    zbee_nwk_green_power_packet *packet _U_, unsigned offset)
1546
1
{
1547
1
    proto_tree_add_item(tree, hf_zbee_nwk_gp_cmd_move_color_ratex, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1548
1
    offset += 2;
1549
1
    proto_tree_add_item(tree, hf_zbee_nwk_gp_cmd_move_color_ratey, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1550
1
    offset += 2;
1551
1
    return offset;
1552
1
} /* dissect_zbee_nwk_gp_cmd_move_color */
1553
1554
/**
1555
 *Dissector for ZigBee Green Power Move Up/Down.
1556
 *
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.
1563
*/
1564
static unsigned
1565
dissect_zbee_nwk_gp_cmd_move_up_down(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
1566
    zbee_nwk_green_power_packet *packet _U_, unsigned offset)
1567
10
{
1568
    /* Optional rate field. */
1569
10
    if (tvb_reported_length(tvb) - offset >= 1) {
1570
9
        proto_tree_add_item(tree, hf_zbee_nwk_gp_cmd_move_up_down_rate, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1571
9
        offset += 1;
1572
9
    }
1573
10
    return offset;
1574
10
} /* dissect_zbee_nwk_gp_cmd_move_up_down */
1575
1576
/**
1577
 *Dissector for ZigBee Green Power Step Color.
1578
 *
1579
 *@param tvb pointer to buffer containing raw packet.
1580
 *@param pinfo pointer to packet information fields.
1581
 *@param tree pointer to data tree Wireshark uses to display packet.
1582
 *@param packet packet data.
1583
 *@param offset current payload offset.
1584
 *@return payload processed offset.
1585
*/
1586
static unsigned
1587
dissect_zbee_nwk_gp_cmd_step_color(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
1588
    zbee_nwk_green_power_packet *packet _U_, unsigned offset)
1589
2
{
1590
2
    proto_tree_add_item(tree, hf_zbee_nwk_gp_cmd_step_color_stepx, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1591
2
    offset += 2;
1592
2
    proto_tree_add_item(tree, hf_zbee_nwk_gp_cmd_step_color_stepy, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1593
2
    offset += 2;
1594
    /* Optional time field. */
1595
2
    if (tvb_reported_length(tvb) - offset >= 2) {
1596
2
        proto_tree_add_item(tree, hf_zbee_nwk_gp_cmd_step_color_transition_time, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1597
2
        offset += 2;
1598
2
    }
1599
2
    return offset;
1600
2
} /* dissect_zbee_nwk_gp_cmd_step_color */
1601
1602
/**
1603
 *Dissector for ZigBee Green Power Step Up/Down.
1604
 *
1605
 *@param tvb pointer to buffer containing raw packet.
1606
 *@param pinfo pointer to packet information fields.
1607
 *@param tree pointer to data tree Wireshark uses to display packet.
1608
 *@param packet packet data.
1609
 *@param offset current payload offset.
1610
 *@return payload processed offset.
1611
*/
1612
static unsigned
1613
dissect_zbee_nwk_gp_cmd_step_up_down(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
1614
    zbee_nwk_green_power_packet *packet _U_, unsigned offset)
1615
9
{
1616
9
    proto_tree_add_item(tree, hf_zbee_nwk_gp_cmd_step_up_down_step_size, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1617
9
    offset += 1;
1618
    /* Optional time field. */
1619
9
    if (tvb_reported_length(tvb) - offset >= 2) {
1620
8
        proto_tree_add_item(tree, hf_zbee_nwk_gp_cmd_step_up_down_transition_time, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1621
8
        offset += 2;
1622
8
    }
1623
9
    return offset;
1624
9
} /* dissect_zbee_nwk_gp_cmd_step_up_down */
1625
1626
/**
1627
 *Dissector for ZigBee Green Power commands.
1628
 *
1629
 *@param tvb pointer to buffer containing raw packet.
1630
 *@param pinfo pointer to packet information fields.
1631
 *@param tree pointer to data tree Wireshark uses to display packet.
1632
 *@param data raw packet private data.
1633
 *@return payload processed offset
1634
*/
1635
static int
1636
dissect_zbee_nwk_gp_cmd(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
1637
797
{
1638
797
    unsigned offset = 0;
1639
797
    uint8_t cmd_id = tvb_get_uint8(tvb, offset);
1640
797
    proto_item *cmd_root;
1641
797
    proto_tree *cmd_tree;
1642
797
    zbee_nwk_green_power_packet *packet = (zbee_nwk_green_power_packet *)data;
1643
1644
    /* Create a subtree for the command. */
1645
797
    cmd_tree = proto_tree_add_subtree_format(tree, tvb, offset, -1, ett_zbee_nwk_cmd, &cmd_root,
1646
797
                                        "Command Frame: %s", val_to_str_ext_const(cmd_id,
1647
797
                                                            &zbee_nwk_gp_cmd_names_ext,
1648
797
                                                            "Unknown Command Frame"));
1649
    /* Add the command ID. */
1650
797
    proto_tree_add_uint(cmd_tree, hf_zbee_nwk_gp_command_id, tvb, offset, 1, cmd_id);
1651
1652
797
    offset += 1;
1653
    /* Add the command name to the info column. */
1654
797
    col_set_str(pinfo->cinfo, COL_INFO, val_to_str_ext_const(cmd_id, &zbee_nwk_gp_cmd_names_ext, "Unknown command"));
1655
    /* Handle the command for one of the following devices:
1656
     * - Door Lock Controller (IDs: 0x50 - 0x51);
1657
     * - GP Flow Sensor (IDs: 0xE0, 0xA0 - 0xA3);
1658
     * - GP Temperature Sensor (IDs: 0xE0, 0xA0 - 0xA3); */
1659
797
    switch(cmd_id) {
1660
        /* Payloadless GPDF commands sent by GPD. */
1661
4
        case ZB_GP_CMD_ID_IDENTIFY:
1662
4
        case ZB_GP_CMD_ID_RECALL_SCENE0:
1663
4
        case ZB_GP_CMD_ID_RECALL_SCENE1:
1664
4
        case ZB_GP_CMD_ID_RECALL_SCENE2:
1665
4
        case ZB_GP_CMD_ID_RECALL_SCENE3:
1666
4
        case ZB_GP_CMD_ID_RECALL_SCENE4:
1667
4
        case ZB_GP_CMD_ID_RECALL_SCENE5:
1668
4
        case ZB_GP_CMD_ID_RECALL_SCENE6:
1669
4
        case ZB_GP_CMD_ID_RECALL_SCENE7:
1670
4
        case ZB_GP_CMD_ID_STORE_SCENE0:
1671
4
        case ZB_GP_CMD_ID_STORE_SCENE1:
1672
4
        case ZB_GP_CMD_ID_STORE_SCENE2:
1673
4
        case ZB_GP_CMD_ID_STORE_SCENE3:
1674
4
        case ZB_GP_CMD_ID_STORE_SCENE4:
1675
4
        case ZB_GP_CMD_ID_STORE_SCENE5:
1676
4
        case ZB_GP_CMD_ID_STORE_SCENE6:
1677
4
        case ZB_GP_CMD_ID_STORE_SCENE7:
1678
4
        case ZB_GP_CMD_ID_OFF:
1679
4
        case ZB_GP_CMD_ID_ON:
1680
4
        case ZB_GP_CMD_ID_TOGGLE:
1681
4
        case ZB_GP_CMD_ID_RELEASE:
1682
4
        case ZB_GP_CMD_ID_LEVEL_CONTROL_STOP:
1683
4
        case ZB_GP_CMD_ID_MOVE_HUE_STOP:
1684
4
        case ZB_GP_CMD_ID_MOVE_SATURATION_STOP:
1685
4
        case ZB_GP_CMD_ID_LOCK_DOOR:
1686
4
        case ZB_GP_CMD_ID_UNLOCK_DOOR:
1687
4
        case ZB_GP_CMD_ID_PRESS11:
1688
4
        case ZB_GP_CMD_ID_RELEASE11:
1689
4
        case ZB_GP_CMD_ID_PRESS12:
1690
4
        case ZB_GP_CMD_ID_RELEASE12:
1691
4
        case ZB_GP_CMD_ID_PRESS22:
1692
4
        case ZB_GP_CMD_ID_RELEASE22:
1693
4
        case ZB_GP_CMD_ID_SHORT_PRESS11:
1694
4
        case ZB_GP_CMD_ID_SHORT_PRESS12:
1695
4
        case ZB_GP_CMD_ID_SHORT_PRESS22:
1696
4
        case ZB_GP_CMD_ID_DECOMMISSIONING:
1697
4
        case ZB_GP_CMD_ID_SUCCESS:
1698
4
            break;
1699
        /* GPDF commands with payload sent by GPD. */
1700
1
        case ZB_GP_CMD_ID_MOVE_UP:
1701
2
        case ZB_GP_CMD_ID_MOVE_DOWN:
1702
2
        case ZB_GP_CMD_ID_MOVE_UP_WITH_ON_OFF:
1703
3
        case ZB_GP_CMD_ID_MOVE_DOWN_WITH_ON_OFF:
1704
6
        case ZB_GP_CMD_ID_MOVE_HUE_UP:
1705
7
        case ZB_GP_CMD_ID_MOVE_HUE_DOWN:
1706
8
        case ZB_GP_CMD_ID_MOVE_SATURATION_UP:
1707
10
        case ZB_GP_CMD_ID_MOVE_SATURATION_DOWN:
1708
10
            offset = dissect_zbee_nwk_gp_cmd_move_up_down(tvb, pinfo, cmd_tree, packet, offset);
1709
10
            break;
1710
2
        case ZB_GP_CMD_ID_STEP_UP:
1711
3
        case ZB_GP_CMD_ID_STEP_DOWN:
1712
3
        case ZB_GP_CMD_ID_STEP_UP_WITH_ON_OFF:
1713
4
        case ZB_GP_CMD_ID_STEP_DOWN_WITH_ON_OFF:
1714
5
        case ZB_GP_CMD_ID_STEP_HUE_UP:
1715
6
        case ZB_GP_CMD_ID_STEP_HUW_DOWN:
1716
7
        case ZB_GP_CMD_ID_STEP_SATURATION_UP:
1717
9
        case ZB_GP_CMD_ID_STEP_SATURATION_DOWN:
1718
9
            offset = dissect_zbee_nwk_gp_cmd_step_up_down(tvb, pinfo, cmd_tree, packet, offset);
1719
9
            break;
1720
1
        case ZB_GP_CMD_ID_MOVE_COLOR:
1721
1
            offset = dissect_zbee_nwk_gp_cmd_move_color(tvb, pinfo, cmd_tree, packet, offset);
1722
1
            break;
1723
2
        case ZB_GP_CMD_ID_STEP_COLOR:
1724
2
            offset = dissect_zbee_nwk_gp_cmd_step_color(tvb, pinfo, cmd_tree, packet, offset);
1725
2
            break;
1726
19
        case ZB_GP_CMD_ID_ATTRIBUTE_REPORTING:
1727
19
            offset = dissect_zbee_nwk_gp_cmd_attr_reporting(tvb, pinfo, cmd_tree, packet, offset, ZBEE_MFG_CODE_NONE);
1728
19
            break;
1729
11
        case ZB_GP_CMD_ID_MANUFACTURE_SPECIFIC_ATTR_REPORTING:
1730
11
            offset = dissect_zbee_nwk_gp_cmd_MS_attr_reporting(tvb, pinfo, cmd_tree, packet, offset);
1731
11
            break;
1732
151
        case ZB_GP_CMD_ID_MULTI_CLUSTER_REPORTING:
1733
151
            offset = dissect_zbee_nwk_gp_cmd_multi_cluster_reporting(tvb, pinfo, cmd_tree, packet, offset, ZBEE_MFG_CODE_NONE);
1734
151
            break;
1735
3
        case ZB_GP_CMD_ID_MANUFACTURER_SPECIFIC_MCLUSTER_REPORTING:
1736
3
            offset = dissect_zbee_nwk_gp_cmd_MS_multi_cluster_reporting(tvb, pinfo, cmd_tree, packet, offset);
1737
3
            break;
1738
156
        case ZB_GP_CMD_ID_READ_ATTRIBUTES_RESPONSE:
1739
156
            offset = dissect_zbee_nwk_gp_cmd_read_attributes_response(tvb, pinfo, cmd_tree, packet, offset);
1740
156
            break;
1741
1
        case ZB_GP_CMD_ID_ZCL_TUNNELING:
1742
1
            offset = dissect_zbee_nwk_gp_cmd_zcl_tunneling(tvb, pinfo, cmd_tree, packet, offset);
1743
1
            break;
1744
0
        case ZB_GP_CMD_ID_ANY_SENSOR_COMMAND_A0_A3:
1745
            /* TODO: implement it. */
1746
0
            break;
1747
10
        case ZB_GP_CMD_ID_COMMISSIONING:
1748
10
            offset = dissect_zbee_nwk_gp_cmd_commissioning(tvb, pinfo, cmd_tree, packet, offset);
1749
10
            break;
1750
1
        case ZB_GP_CMD_ID_CHANNEL_REQUEST:
1751
1
            offset = dissect_zbee_nwk_gp_cmd_channel_request(tvb, pinfo, cmd_tree, packet, offset);
1752
1
            break;
1753
25
        case ZB_GP_CMD_ID_REQUEST_ATTRIBUTES:
1754
        /* GPDF commands sent to GPD. */
1755
26
        case ZB_GP_CMD_ID_READ_ATTRIBUTES:
1756
26
            offset = dissect_zbee_nwk_gp_cmd_read_attributes(tvb, pinfo, cmd_tree, packet, offset);
1757
26
            break;
1758
3
        case ZB_GP_CMD_ID_COMMISSIONING_REPLY:
1759
3
            offset = dissect_zbee_nwk_gp_cmd_commissioning_reply(tvb, pinfo, cmd_tree, packet, offset);
1760
3
            break;
1761
368
        case ZB_GP_CMD_ID_WRITE_ATTRIBUTES:
1762
368
            offset = dissect_zbee_nwk_gp_cmd_write_attributes(tvb, pinfo, cmd_tree, packet, offset);
1763
368
            break;
1764
1
        case ZB_GP_CMD_ID_CHANNEL_CONFIGURATION:
1765
1
            offset = dissect_zbee_nwk_gp_cmd_channel_configuration(tvb, pinfo, cmd_tree, packet, offset);
1766
1
            break;
1767
797
    }
1768
124
    if (offset < tvb_reported_length(tvb)) {
1769
        /* There are leftover bytes! */
1770
69
        proto_tree *root;
1771
69
        tvbuff_t *leftover_tvb = tvb_new_subset_remaining(tvb, offset);
1772
1773
        /* Correct the length of the command tree. */
1774
69
        root = proto_tree_get_root(tree);
1775
69
        proto_item_set_len(cmd_root, offset);
1776
1777
        /* Dump the tail. */
1778
69
        call_data_dissector(leftover_tvb, pinfo, root);
1779
69
    }
1780
124
    return offset;
1781
797
} /* dissect_zbee_nwk_gp_cmd */
1782
1783
/**
1784
 *ZigBee NWK packet dissection routine for Green Power profile.
1785
 *
1786
 *@param tvb pointer to buffer containing raw packet.
1787
 *@param pinfo pointer to packet information fields.
1788
 *@param tree pointer to data tree Wireshark uses to display packet.
1789
 *@param data raw packet private data.
1790
*/
1791
static int
1792
dissect_zbee_nwk_gp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
1793
786
{
1794
786
    ieee802154_packet *ieee_packet = (ieee802154_packet *)data;
1795
786
    bool gp_decrypted;
1796
786
    GSList *GSList_i;
1797
786
    unsigned offset = 0;
1798
786
    uint8_t *dec_buffer;
1799
786
    uint8_t *enc_buffer;
1800
786
    uint8_t fcf;
1801
786
    proto_tree *nwk_tree;
1802
786
    proto_item *proto_root;
1803
786
    proto_item *ti = NULL;
1804
786
    tvbuff_t *payload_tvb;
1805
786
    zbee_nwk_green_power_packet packet;
1806
786
    static int * const fields[] = {
1807
786
        &hf_zbee_nwk_gp_frame_type,
1808
786
        &hf_zbee_nwk_gp_proto_version,
1809
786
        &hf_zbee_nwk_gp_auto_commissioning,
1810
786
        &hf_zbee_nwk_gp_fc_ext,
1811
786
        NULL
1812
786
    };
1813
786
    static int * const ext_fields[] = {
1814
786
        &hf_zbee_nwk_gp_fc_ext_app_id,
1815
786
        &hf_zbee_nwk_gp_fc_ext_sec_level,
1816
786
        &hf_zbee_nwk_gp_fc_ext_sec_key,
1817
786
        &hf_zbee_nwk_gp_fc_ext_rx_after_tx,
1818
786
        &hf_zbee_nwk_gp_fc_ext_direction,
1819
786
        NULL
1820
786
    };
1821
1822
786
    if (data == NULL)
1823
0
        return 0;
1824
1825
786
    memset(&packet, 0, sizeof(packet));
1826
786
    packet.ieee_packet_src64 = ieee_packet->src64;
1827
    /* Add ourself to the protocol column, clear the info column and create the protocol tree. */
1828
786
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "ZigBee Green Power");
1829
786
    col_clear(pinfo->cinfo, COL_INFO);
1830
1831
786
    proto_root = proto_tree_add_protocol_format(tree, proto_zbee_nwk_gp, tvb, offset, tvb_captured_length(tvb),
1832
786
            "ZGP stub NWK header");
1833
786
    nwk_tree = proto_item_add_subtree(proto_root, ett_zbee_nwk);
1834
1835
786
    enc_buffer = (uint8_t *)tvb_memdup(pinfo->pool, tvb, 0, tvb_captured_length(tvb));
1836
    /* Get and parse the FCF. */
1837
786
    fcf = tvb_get_uint8(tvb, offset);
1838
786
    packet.frame_type = zbee_get_bit_field(fcf, ZBEE_NWK_GP_FCF_FRAME_TYPE);
1839
786
    packet.nwk_frame_control_extension = zbee_get_bit_field(fcf, ZBEE_NWK_GP_FCF_CONTROL_EXTENSION);
1840
1841
    /* Display the FCF. */
1842
786
    ti = proto_tree_add_bitmask(nwk_tree, tvb, offset, hf_zbee_nwk_gp_fcf, ett_zbee_nwk_fcf, fields, ENC_NA);
1843
786
    proto_item_append_text(ti, " %s", val_to_str_const(packet.frame_type, zbee_nwk_gp_frame_types, "Unknown Frame Type"));
1844
786
    offset += 1;
1845
1846
    /* Add the frame type to the info column and protocol root. */
1847
786
    proto_item_append_text(proto_root, " %s", val_to_str_const(packet.frame_type, zbee_nwk_gp_frame_types, "Unknown type"));
1848
786
    col_set_str(pinfo->cinfo, COL_INFO, val_to_str_const(packet.frame_type, zbee_nwk_gp_frame_types, "Reserved frame type"));
1849
1850
786
    if (packet.nwk_frame_control_extension) {
1851
        /* Display ext FCF. */
1852
743
        fcf = tvb_get_uint8(tvb, offset);
1853
743
        packet.application_id = zbee_get_bit_field(fcf, ZBEE_NWK_GP_FCF_EXT_APP_ID);
1854
743
        packet.security_level = zbee_get_bit_field(fcf, ZBEE_NWK_GP_FCF_EXT_SECURITY_LEVEL);
1855
743
        packet.direction = zbee_get_bit_field(fcf, ZBEE_NWK_GP_FCF_EXT_DIRECTION);
1856
1857
        /* Create a subtree for the extended FCF. */
1858
743
        proto_tree_add_bitmask(nwk_tree, tvb, offset, hf_zbee_nwk_gp_fc_ext_field, ett_zbee_nwk_fcf_ext, ext_fields, ENC_NA);
1859
743
        offset += 1;
1860
743
    }
1861
786
    if ((packet.frame_type == ZBEE_NWK_GP_FCF_DATA && !packet.nwk_frame_control_extension) || (packet.frame_type ==
1862
744
        ZBEE_NWK_GP_FCF_DATA && packet.nwk_frame_control_extension && packet.application_id ==
1863
731
        ZBEE_NWK_GP_APP_ID_DEFAULT) || (packet.frame_type == ZBEE_NWK_GP_FCF_MAINTENANCE &&
1864
436
        packet.nwk_frame_control_extension && packet.application_id == ZBEE_NWK_GP_APP_ID_DEFAULT && tvb_get_uint8(tvb,
1865
58
        offset) != ZB_GP_CMD_ID_CHANNEL_CONFIGURATION)) {
1866
        /* Display GPD Src ID. */
1867
58
        packet.source_id = tvb_get_letohl(tvb, offset);
1868
58
        proto_tree_add_item(nwk_tree, hf_zbee_nwk_gp_zgpd_src_id, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1869
58
        proto_item_append_text(proto_root, ", GPD Src ID: 0x%08x", packet.source_id);
1870
1871
58
        col_append_fstr(pinfo->cinfo, COL_INFO, ", GPD Src ID: 0x%08x", packet.source_id);
1872
1873
58
        col_clear(pinfo->cinfo, COL_DEF_SRC);
1874
58
        col_append_fstr(pinfo->cinfo, COL_DEF_SRC, "0x%08x", packet.source_id);
1875
1876
58
        offset += 4;
1877
58
    }
1878
786
    if (packet.application_id == ZBEE_NWK_GP_APP_ID_ZGP) {
1879
        /* Display GPD endpoint */
1880
85
        packet.endpoint = tvb_get_uint8(tvb, offset);
1881
85
        proto_tree_add_item(nwk_tree, hf_zbee_nwk_gp_zgpd_endpoint, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1882
85
        proto_item_append_text(proto_root, ", Endpoint: %d", packet.endpoint);
1883
1884
85
        col_append_fstr(pinfo->cinfo, COL_INFO, ", Endpoint: %d", packet.endpoint);
1885
85
        offset += 1;
1886
85
    }
1887
    /* Display Security Frame Counter. */
1888
786
    packet.mic_size = 0;
1889
786
    if (packet.nwk_frame_control_extension) {
1890
743
        if (packet.application_id == ZBEE_NWK_GP_APP_ID_DEFAULT || packet.application_id == ZBEE_NWK_GP_APP_ID_ZGP
1891
642
            || packet.application_id == ZBEE_NWK_GP_APP_ID_LPED) {
1892
328
            if (packet.security_level == ZBEE_NWK_GP_SECURITY_LEVEL_1LSB
1893
9
                && packet.application_id != ZBEE_NWK_GP_APP_ID_LPED) {
1894
6
                packet.mic_size = 2;
1895
322
            } else if (packet.security_level == ZBEE_NWK_GP_SECURITY_LEVEL_FULL || packet.security_level ==
1896
315
                ZBEE_NWK_GP_SECURITY_LEVEL_FULLENCR) {
1897
                /* Get Security Frame Counter and display it. */
1898
11
                packet.mic_size = 4;
1899
11
                packet.security_frame_counter = tvb_get_letohl(tvb, offset);
1900
11
                proto_tree_add_item(nwk_tree, hf_zbee_nwk_gp_security_frame_counter, tvb, offset, 4,
1901
11
                    ENC_LITTLE_ENDIAN);
1902
11
                offset += 4;
1903
11
            }
1904
328
        }
1905
743
    }
1906
    /* Parse application payload. */
1907
    /* This is a uint8_t, but tvb_reported_length might be larger; e.g.,
1908
     * SCOP over TCP, presumably with errors. It's bogus either way; perhaps
1909
     * we should warn.
1910
     */
1911
786
    packet.payload_len = tvb_reported_length(tvb) - offset - packet.mic_size;
1912
    /* Ensure that the payload exists. */
1913
786
    if (packet.payload_len <= 0) {
1914
1
        proto_tree_add_expert_remaining(nwk_tree, pinfo, &ei_zbee_nwk_gp_no_payload, tvb, 0);
1915
1
        return offset;
1916
1
    }
1917
    /* OK, payload exists. Parse MIC field if needed. */
1918
785
    if (packet.mic_size == 2) {
1919
6
        packet.mic = tvb_get_letohs(tvb, offset + packet.payload_len);
1920
779
    } else if (packet.mic_size == 4) {
1921
11
        packet.mic = tvb_get_letohl(tvb, offset + packet.payload_len);
1922
11
    }
1923
    /* Save packet private data. */
1924
785
    data = (void *)&packet;
1925
785
    payload_tvb = tvb_new_subset_length(tvb, offset, packet.payload_len);
1926
785
    if (packet.security_level != ZBEE_NWK_GP_SECURITY_LEVEL_FULLENCR) {
1927
774
        dissect_zbee_nwk_gp_cmd(payload_tvb, pinfo, nwk_tree, data);
1928
774
    }
1929
785
    offset += packet.payload_len;
1930
    /* Display MIC field. */
1931
785
    if (packet.mic_size) {
1932
6
        proto_tree_add_uint(nwk_tree, packet.mic_size == 4 ? hf_zbee_nwk_gp_security_mic_4b :
1933
6
                hf_zbee_nwk_gp_security_mic_2b, tvb, offset, packet.mic_size, packet.mic);
1934
6
        offset += packet.mic_size;
1935
6
    }
1936
785
    if ((offset < tvb_captured_length(tvb)) && (packet.security_level != ZBEE_NWK_GP_SECURITY_LEVEL_FULLENCR)) {
1937
14
        proto_tree_add_expert_remaining(nwk_tree, pinfo, &ei_zbee_nwk_gp_inval_residual_data, tvb, offset);
1938
14
        return offset;
1939
14
    }
1940
771
    if (packet.security_level == ZBEE_NWK_GP_SECURITY_LEVEL_FULLENCR) {
1941
5
        gp_decrypted = false;
1942
1943
5
        if (tvb_captured_length(tvb) >= tvb_reported_length(tvb)) {
1944
3
            dec_buffer = (uint8_t *)wmem_alloc(pinfo->pool, packet.payload_len);
1945
4
            for (GSList_i = zbee_gp_keyring; GSList_i && !gp_decrypted; GSList_i = g_slist_next(GSList_i)) {
1946
1
                gp_decrypted = zbee_gp_decrypt_payload(&packet, enc_buffer, offset - packet.payload_len -
1947
1
                    packet.mic_size, dec_buffer, packet.payload_len, packet.mic_size,
1948
1
                    ((key_record_t *)(GSList_i->data))->key);
1949
1
            }
1950
3
        }
1951
1952
5
        if (gp_decrypted) {
1953
1
            payload_tvb = tvb_new_child_real_data(tvb, dec_buffer, packet.payload_len, packet.payload_len);
1954
1
            add_new_data_source(pinfo, payload_tvb, "Decrypted GP Payload");
1955
1
            dissect_zbee_nwk_gp_cmd(payload_tvb, pinfo, nwk_tree, data);
1956
4
        } else {
1957
4
            payload_tvb = tvb_new_subset_length(tvb, offset - packet.payload_len - packet.mic_size, packet.payload_len);
1958
4
            call_data_dissector(payload_tvb, pinfo, tree);
1959
4
        }
1960
5
    }
1961
771
    return tvb_captured_length(tvb);
1962
785
} /* dissect_zbee_nwk_gp */
1963
1964
/**
1965
 *Heuristic interpreter for the ZigBee Green Power dissectors.
1966
 *
1967
 *@param tvb pointer to buffer containing raw packet.
1968
 *@param pinfo pointer to packet information fields.
1969
 *@param tree pointer to data tree Wireshark uses to display packet.
1970
 *@param data raw packet private data.
1971
*/
1972
static bool
1973
dissect_zbee_nwk_heur_gp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
1974
1.36k
{
1975
1.36k
    ieee802154_packet   *packet = (ieee802154_packet *)data;
1976
1.36k
    uint8_t             fcf;
1977
1978
    /* We must have the IEEE 802.15.4 headers. */
1979
1.36k
    if (packet == NULL) return false;
1980
1981
    /* If the frame type and version are not sane, then it's probably not ZGP. */
1982
1.36k
    fcf = tvb_get_uint8(tvb, 0);
1983
1.36k
    if (zbee_get_bit_field(fcf, ZBEE_NWK_GP_FCF_VERSION) != ZBEE_VERSION_GREEN_POWER) return false;
1984
795
    if (!try_val_to_str(zbee_get_bit_field(fcf, ZBEE_NWK_FCF_FRAME_TYPE), zbee_nwk_gp_frame_types)) return false;
1985
1986
    /* ZigBee greenpower frames are either sent to broadcast or the extended address. */
1987
791
    if (packet->dst_addr_mode == IEEE802154_FCF_ADDR_SHORT && packet->dst16 == IEEE802154_BCAST_ADDR) {
1988
2
        dissect_zbee_nwk_gp(tvb, pinfo, tree, data);
1989
2
        return true;
1990
2
    }
1991
    /* 64-bit destination addressing mode support. */
1992
789
    if (packet->dst_addr_mode == IEEE802154_FCF_ADDR_EXT) {
1993
784
        dissect_zbee_nwk_gp(tvb, pinfo, tree, data);
1994
784
        return true;
1995
784
    }
1996
1997
5
    return false;
1998
789
} /* dissect_zbee_nwk_heur_gp */
1999
2000
/**
2001
 *Init routine for the ZigBee GP profile security.
2002
 *
2003
*/
2004
static void
2005
gp_init_zbee_security(void)
2006
15
{
2007
15
    unsigned i;
2008
15
    key_record_t key_record;
2009
2010
15
    for (i = 0; gp_uat_key_records && (i < num_uat_key_records); i++) {
2011
0
        key_record.frame_num = 0;
2012
0
        key_record.label = g_strdup(gp_uat_key_records[i].label);
2013
0
        memcpy(key_record.key, gp_uat_key_records[i].key, ZBEE_SEC_CONST_KEYSIZE);
2014
0
        zbee_gp_keyring = g_slist_prepend(zbee_gp_keyring, g_memdup2(&key_record, sizeof(key_record_t)));
2015
0
    }
2016
15
}
2017
2018
static void zbee_free_key_record(void *ptr)
2019
0
{
2020
0
    key_record_t *k;
2021
2022
0
    k = (key_record_t *)ptr;
2023
0
    if (!k)
2024
0
        return;
2025
2026
0
    g_free(k->label);
2027
0
    g_free(k);
2028
0
}
2029
2030
static void
2031
gp_cleanup_zbee_security(void)
2032
0
{
2033
0
    if (!zbee_gp_keyring)
2034
0
        return;
2035
2036
0
    g_slist_free_full(zbee_gp_keyring, zbee_free_key_record);
2037
0
    zbee_gp_keyring = NULL;
2038
0
}
2039
2040
/**
2041
 *ZigBee NWK GP protocol registration routine.
2042
 *
2043
*/
2044
void
2045
proto_register_zbee_nwk_gp(void)
2046
15
{
2047
15
    module_t *gp_zbee_prefs;
2048
15
    expert_module_t* expert_zbee_nwk_gp;
2049
2050
15
    static hf_register_info hf[] = {
2051
15
        { &hf_zbee_nwk_gp_auto_commissioning,
2052
15
            { "Auto Commissioning", "zbee_nwk_gp.auto_commissioning", FT_BOOLEAN, 8, NULL,
2053
15
                ZBEE_NWK_GP_FCF_AUTO_COMMISSIONING, NULL, HFILL }},
2054
2055
15
        { &hf_zbee_nwk_gp_fc_ext,
2056
15
            { "NWK Frame Extension", "zbee_nwk_gp.fc_extension", FT_BOOLEAN, 8, NULL, ZBEE_NWK_GP_FCF_CONTROL_EXTENSION,
2057
15
                NULL, HFILL }},
2058
2059
15
        { &hf_zbee_nwk_gp_fcf,
2060
15
            { "Frame Control Field", "zbee_nwk_gp.fcf", FT_UINT8, BASE_HEX, NULL,
2061
15
                0x0, NULL, HFILL }},
2062
2063
15
        { &hf_zbee_nwk_gp_frame_type,
2064
15
            { "Frame Type", "zbee_nwk_gp.frame_type", FT_UINT8, BASE_HEX, VALS(zbee_nwk_gp_frame_types),
2065
15
                ZBEE_NWK_GP_FCF_FRAME_TYPE, NULL, HFILL }},
2066
2067
15
        { &hf_zbee_nwk_gp_proto_version,
2068
15
            { "Protocol Version", "zbee_nwk_gp.proto_version", FT_UINT8, BASE_DEC, NULL, ZBEE_NWK_GP_FCF_VERSION, NULL,
2069
15
                HFILL }},
2070
2071
15
        { &hf_zbee_nwk_gp_fc_ext_field,
2072
15
            { "Extended NWK Frame Control Field", "zbee_nwk_gp.fc_ext", FT_UINT8, BASE_HEX, NULL,
2073
15
                0x0, NULL, HFILL }},
2074
2075
15
        { &hf_zbee_nwk_gp_fc_ext_app_id,
2076
15
            { "Application ID", "zbee_nwk_gp.fc_ext_app_id", FT_UINT8, BASE_HEX, VALS(zbee_nwk_gp_app_id_names),
2077
15
                ZBEE_NWK_GP_FCF_EXT_APP_ID, NULL, HFILL }},
2078
2079
15
        { &hf_zbee_nwk_gp_fc_ext_direction,
2080
15
            { "Direction", "zbee_nwk_gp.fc_ext_direction", FT_UINT8, BASE_HEX, VALS(zbee_nwk_gp_directions),
2081
15
                ZBEE_NWK_GP_FCF_EXT_DIRECTION, NULL, HFILL }},
2082
2083
15
        { &hf_zbee_nwk_gp_fc_ext_rx_after_tx,
2084
15
            { "Rx After Tx", "zbee_nwk_gp.fc_ext_rxaftertx", FT_BOOLEAN, 8, NULL, ZBEE_NWK_GP_FCF_EXT_RX_AFTER_TX, NULL,
2085
15
                HFILL }},
2086
2087
15
        { &hf_zbee_nwk_gp_fc_ext_sec_key,
2088
15
            { "Security Key", "zbee_nwk_gp.fc_ext_security_key", FT_BOOLEAN, 8, NULL, ZBEE_NWK_GP_FCF_EXT_SECURITY_KEY,
2089
15
                NULL, HFILL }},
2090
2091
15
        { &hf_zbee_nwk_gp_fc_ext_sec_level,
2092
15
            { "Security Level", "zbee_nwk_gp.fc_ext_security_level", FT_UINT8, BASE_HEX,
2093
15
                VALS(zbee_nwk_gp_src_sec_levels_names), ZBEE_NWK_GP_FCF_EXT_SECURITY_LEVEL, NULL, HFILL }},
2094
2095
15
        { &hf_zbee_nwk_gp_zgpd_src_id,
2096
15
            { "Src ID", "zbee_nwk_gp.source_id", FT_UINT32, BASE_HEX, VALS(zbee_nwk_gp_src_id_names), 0x0, NULL,
2097
15
                HFILL }},
2098
2099
15
        { &hf_zbee_nwk_gp_zgpd_endpoint,
2100
15
            { "Endpoint", "zbee_nwk_gp.endpoint", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
2101
2102
15
        { &hf_zbee_nwk_gp_security_frame_counter,
2103
15
            { "Security Frame Counter", "zbee_nwk_gp.security_frame_counter", FT_UINT32, BASE_DEC, NULL, 0x0, NULL,
2104
15
                HFILL }},
2105
2106
15
        { &hf_zbee_nwk_gp_security_mic_2b,
2107
15
            { "Security MIC", "zbee_nwk_gp.security_mic2", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2108
2109
15
        { &hf_zbee_nwk_gp_security_mic_4b,
2110
15
            { "Security MIC", "zbee_nwk_gp.security_mic4", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2111
2112
15
        { &hf_zbee_nwk_gp_command_id,
2113
15
            { "ZGPD Command ID", "zbee_nwk_gp.command_id", FT_UINT8, BASE_HEX | BASE_EXT_STRING, &zbee_nwk_gp_cmd_names_ext, 0x0, NULL,
2114
15
                HFILL }},
2115
2116
15
        { &hf_zbee_nwk_gp_cmd_comm_device_id,
2117
15
            { "ZGPD Device ID", "zbee_nwk_gp.cmd.comm.dev_id", FT_UINT8, BASE_HEX | BASE_EXT_STRING, &zbee_nwk_gp_device_ids_names_ext,
2118
15
                0x0, NULL, HFILL }},
2119
2120
15
        { &hf_zbee_nwk_gp_cmd_comm_ext_opt_gpd_key_encr,
2121
15
            { "GPD Key Encryption", "zbee_nwk_gp.cmd.comm.ext_opt.gpd_key_encr", FT_BOOLEAN, 8, NULL,
2122
15
                ZBEE_NWK_GP_CMD_COMMISSIONING_EXT_OPT_GPD_KEY_ENCR, NULL, HFILL }},
2123
2124
15
        { &hf_zbee_nwk_gp_cmd_comm_ext_opt_gpd_key_present,
2125
15
            { "GPD Key Present", "zbee_nwk_gp.cmd.comm.ext_opt.gpd_key_present", FT_BOOLEAN, 8, NULL,
2126
15
                ZBEE_NWK_GP_CMD_COMMISSIONING_EXT_OPT_GPD_KEY_PRESENT, NULL, HFILL }},
2127
2128
15
        { &hf_zbee_nwk_gp_cmd_comm_ext_opt_key_type,
2129
15
            { "Key Type", "zbee_nwk_gp.cmd.comm.ext_opt.key_type", FT_UINT8, BASE_HEX,
2130
15
                VALS(zbee_nwk_gp_src_sec_keys_type_names), ZBEE_NWK_GP_CMD_COMMISSIONING_EXT_OPT_KEY_TYPE, NULL,
2131
15
                HFILL }},
2132
2133
15
        { &hf_zbee_nwk_gp_cmd_comm_outgoing_counter,
2134
15
            { "GPD Outgoing Counter", "zbee_nwk_gp.cmd.comm.out_counter", FT_UINT32, BASE_HEX, NULL, 0x0, NULL,
2135
15
                HFILL }},
2136
2137
15
        { &hf_zbee_nwk_gp_cmd_comm_ext_opt_sec_level_cap,
2138
15
            { "Security Level Capabilities", "zbee_nwk_gp.cmd.comm.ext_opt.seclevel_cap", FT_UINT8, BASE_HEX, NULL,
2139
15
                ZBEE_NWK_GP_CMD_COMMISSIONING_EXT_OPT_SEC_LEVEL_CAP, NULL, HFILL }},
2140
2141
15
        { &hf_zbee_nwk_gp_cmd_comm_security_key,
2142
15
            { "Security Key", "zbee_nwk_gp.cmd.comm.security_key", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2143
2144
15
        { &hf_zbee_nwk_gp_cmd_comm_gpd_sec_key_mic,
2145
15
            { "GPD Key MIC", "zbee_nwk_gp.cmd.comm.gpd_key_mic", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2146
2147
15
        { &hf_zbee_nwk_gp_cmd_comm_opt_ext_opt,
2148
15
            { "Extended Option Field", "zbee_nwk_gp.cmd.comm.opt.ext_opt_field", FT_BOOLEAN, 8, NULL,
2149
15
                ZBEE_NWK_GP_CMD_COMMISSIONING_OPT_EXT_OPTIONS, NULL, HFILL }},
2150
2151
15
        { &hf_zbee_nwk_gp_cmd_comm_opt,
2152
15
            { "Options Field", "zbee_nwk_gp.cmd.comm.opt", FT_UINT8, BASE_HEX, NULL,
2153
15
                0x0, NULL, HFILL }},
2154
2155
15
        { &hf_zbee_nwk_gp_cmd_comm_opt_fixed_location,
2156
15
            { "Fixed Location", "zbee_nwk_gp.cmd.comm.opt.fixed_location", FT_BOOLEAN, 8, NULL,
2157
15
                ZBEE_NWK_GP_CMD_COMMISSIONING_OPT_FIXED_LOCATION, NULL, HFILL }},
2158
2159
15
        { &hf_zbee_nwk_gp_cmd_comm_opt_mac_sec_num_cap,
2160
15
            { "MAC Sequence number capability", "zbee_nwk_gp.cmd.comm.opt.mac_seq_num_cap", FT_BOOLEAN, 8, NULL,
2161
15
                ZBEE_NWK_GP_CMD_COMMISSIONING_OPT_MAC_SEQ, NULL, HFILL }},
2162
2163
15
        { &hf_zbee_nwk_gp_cmd_comm_opt_appli_info_present,
2164
15
            { "Application information present", "zbee_nwk_gp.cmd.comm.opt.appli_info_present", FT_BOOLEAN, 8, NULL,
2165
15
                ZBEE_NWK_GP_CMD_COMMISSIONING_OPT_APPLICATION_INFO, NULL, HFILL }},
2166
2167
15
        { &hf_zbee_nwk_gp_cmd_comm_opt_panid_req,
2168
15
            { "PANId request", "zbee_nwk_gp.cmd.comm.opt.panid_req", FT_BOOLEAN, 8, NULL,
2169
15
                ZBEE_NWK_GP_CMD_COMMISSIONING_OPT_PAN_ID_REQ, NULL, HFILL }},
2170
2171
15
        { &hf_zbee_nwk_gp_cmd_comm_opt_rx_on_cap,
2172
15
            { "RxOnCapability", "zbee_nwk_gp.cmd.comm.opt.rxon_cap", FT_BOOLEAN, 8, NULL,
2173
15
                ZBEE_NWK_GP_CMD_COMMISSIONING_OPT_RX_ON_CAP, NULL, HFILL }},
2174
2175
15
        { &hf_zbee_nwk_gp_cmd_comm_opt_sec_key_req,
2176
15
            { "GP Security Key Request", "zbee_nwk_gp.cmd.comm.opt.seq_key_req", FT_BOOLEAN, 8, NULL,
2177
15
                ZBEE_NWK_GP_CMD_COMMISSIONING_OPT_GP_SEC_KEY_REQ, NULL, HFILL }},
2178
2179
15
        { &hf_zbee_nwk_gp_cmd_comm_ext_opt,
2180
15
            { "Extended Options Field", "zbee_nwk_gp.cmd.comm.ext_opt", FT_UINT8, BASE_HEX, NULL,
2181
15
                0x0, NULL, HFILL }},
2182
2183
15
        { &hf_zbee_nwk_gp_cmd_comm_ext_opt_outgoing_counter,
2184
15
            { "GPD Outgoing present", "zbee_nwk_gp.cmd.comm.ext_opt.outgoing_counter", FT_BOOLEAN, 8, NULL,
2185
15
                ZBEE_NWK_GP_CMD_COMMISSIONING_EXT_OPT_OUT_COUNTER, NULL, HFILL }},
2186
2187
15
        { &hf_zbee_nwk_gp_cmd_comm_manufacturer_greenpeak_dev_id,
2188
15
            { "Manufacturer Model ID", "zbee_nwk_gp.cmd.comm.manufacturer_model_id", FT_UINT16, BASE_HEX,
2189
15
                VALS(zbee_nwk_gp_manufacturer_greenpeak_dev_names), 0x0, NULL, HFILL }},
2190
2191
15
        { &hf_zbee_nwk_gp_cmd_comm_manufacturer_dev_id,
2192
15
            { "Manufacturer Model ID", "zbee_nwk_gp.cmd.comm.manufacturer_model_id", FT_UINT16, BASE_HEX,
2193
15
                NULL, 0x0, NULL, HFILL }},
2194
2195
15
        { &hf_zbee_nwk_gp_cmd_comm_manufacturer_id,
2196
15
            { "Manufacturer ID", "zbee_nwk_gp.cmd.comm.manufacturer_id", FT_UINT16, BASE_HEX,
2197
15
                VALS(zbee_mfr_code_names), 0x0, NULL, HFILL }},
2198
2199
15
        { &hf_zbee_nwk_gp_cmd_comm_appli_info_crp,
2200
15
            { "Cluster reports present", "zbee_nwk_gp.cmd.comm.appli_info.crp", FT_BOOLEAN, 8, NULL,
2201
15
                ZBEE_NWK_GP_CMD_COMMISSIONING_APPLI_INFO_CRP , NULL, HFILL }},
2202
2203
15
        { &hf_zbee_nwk_gp_cmd_comm_appli_info_gclp,
2204
15
            { "GP commands list present", "zbee_nwk_gp.cmd.comm.appli_info.gclp", FT_BOOLEAN, 8, NULL,
2205
15
                ZBEE_NWK_GP_CMD_COMMISSIONING_APPLI_INFO_GCLP , NULL, HFILL }},
2206
2207
15
        { &hf_zbee_nwk_gp_cmd_comm_appli_info,
2208
15
            { "Application information Field", "zbee_nwk_gp.cmd.comm.appli_info", FT_UINT8, BASE_HEX, NULL,
2209
15
                0x0, NULL, HFILL }},
2210
2211
15
        { &hf_zbee_nwk_gp_cmd_comm_appli_info_mip,
2212
15
            { "Manufacturer ID present", "zbee_nwk_gp.cmd.comm.appli_info.mip", FT_BOOLEAN, 8, NULL,
2213
15
                ZBEE_NWK_GP_CMD_COMMISSIONING_APPLI_INFO_MIP , NULL, HFILL }},
2214
2215
15
        { &hf_zbee_nwk_gp_cmd_comm_appli_info_mmip,
2216
15
            { "Manufacturer Model ID present", "zbee_nwk_gp.cmd.comm.appli_info.mmip", FT_BOOLEAN, 8, NULL,
2217
15
                ZBEE_NWK_GP_CMD_COMMISSIONING_APPLI_INFO_MMIP , NULL, HFILL }},
2218
2219
15
        { &hf_zbee_nwk_gp_cmd_comm_gpd_cmd_num,
2220
15
            { "Number of GPD commands", "zbee_nwk_gp.cmd.comm.gpd_cmd_num", FT_UINT8, BASE_DEC, NULL,
2221
15
                0x0 , NULL, HFILL }},
2222
2223
15
        { &hf_zbee_nwk_gp_cmd_comm_gpd_cmd_id_list,
2224
15
            { "GPD CommandID list", "zbee_nwk_gp.cmd.comm.gpd_cmd_id_list", FT_NONE, BASE_NONE, NULL,
2225
15
                0x0 , NULL, HFILL }},
2226
2227
15
        { &hf_zbee_nwk_gp_cmd_comm_length_of_clid_list,
2228
15
            { "Length of ClusterID list", "zbee_nwk_gp.cmd.comm.length_of_clid_list", FT_UINT8, BASE_HEX, NULL,
2229
15
                0x0 , NULL, HFILL }},
2230
2231
15
        { &hf_zbee_nwk_gp_cmd_comm_length_of_clid_list_server,
2232
15
            { "Number of server ClusterIDs", "zbee_nwk_gp.cmd.comm.length_of_clid_list_srv", FT_UINT8, BASE_DEC, NULL,
2233
15
                ZBEE_NWK_GP_CMD_COMMISSIONING_CLID_LIST_LEN_SRV, NULL, HFILL }},
2234
2235
15
        { &hf_zbee_nwk_gp_cmd_comm_length_of_clid_list_client,
2236
15
            { "Number of client ClusterIDs", "zbee_nwk_gp.cmd.comm.length_of_clid_list_cli", FT_UINT8, BASE_DEC, NULL,
2237
15
                ZBEE_NWK_GP_CMD_COMMISSIONING_CLID_LIST_LEN_CLI, NULL, HFILL }},
2238
2239
15
        { &hf_zbee_nwk_cmd_comm_clid_list_server,
2240
15
            { "Cluster ID List Server", "zbee_nwk_gp.cmd.comm.clid_list_server", FT_NONE, BASE_NONE, NULL,
2241
15
                0x0 , NULL, HFILL }},
2242
2243
15
        { &hf_zbee_nwk_cmd_comm_clid_list_client,
2244
15
            { "ClusterID List Client", "zbee_nwk_gp.cmd.comm.clid_list_client", FT_NONE, BASE_NONE, NULL,
2245
15
                0x0 , NULL, HFILL }},
2246
2247
15
        { &hf_zbee_nwk_cmd_comm_cluster_id,
2248
15
            { "Cluster ID", "zbee_nwk_gp.cmd.comm.cluster_id", FT_UINT16, BASE_HEX, NULL,
2249
15
                0x0 , NULL, HFILL }},
2250
2251
15
        { &hf_zbee_nwk_gp_cmd_comm_rep_opt_key_encr,
2252
15
            { "GPD Key Encryption", "zbee_nwk_gp.cmd.comm_reply.opt.sec_key_encr", FT_BOOLEAN, 8, NULL,
2253
15
                ZBEE_NWK_GP_CMD_COMMISSIONING_REP_OPT_KEY_ENCR, NULL, HFILL }},
2254
2255
15
        { &hf_zbee_nwk_gp_cmd_comm_rep_opt,
2256
15
            { "Options Field", "zbee_nwk_gp.cmd.comm_reply.opt", FT_UINT8, BASE_HEX, NULL,
2257
15
                0x0, NULL, HFILL }},
2258
2259
15
        { &hf_zbee_nwk_gp_cmd_comm_rep_opt_panid_present,
2260
15
            { "PANID Present", "zbee_nwk_gp.cmd.comm_reply.opt.pan_id_present", FT_BOOLEAN, 8, NULL,
2261
15
                ZBEE_NWK_GP_CMD_COMMISSIONING_REP_OPT_PAN_ID_PRESENT, NULL, HFILL }},
2262
2263
15
        { &hf_zbee_nwk_gp_cmd_comm_rep_opt_sec_key_present,
2264
15
            { "GPD Security Key Present", "zbee_nwk_gp.cmd.comm_reply.opt.sec_key_present", FT_BOOLEAN, 8, NULL,
2265
15
                ZBEE_NWK_GP_CMD_COMMISSIONING_REP_OPT_SEC_KEY_PRESENT, NULL, HFILL }},
2266
2267
15
        { &hf_zbee_nwk_gp_cmd_comm_rep_opt_sec_level,
2268
15
            { "Security Level", "zbee_nwk_gp.cmd.comm_reply.opt.sec_level", FT_UINT8, BASE_HEX, NULL,
2269
15
                ZBEE_NWK_GP_CMD_COMMISSIONING_REP_OPT_SEC_LEVEL, NULL, HFILL }},
2270
2271
15
        { &hf_zbee_nwk_gp_cmd_comm_rep_opt_sec_type,
2272
15
            { "Key Type", "zbee_nwk_gp.cmd.comm_reply.opt.key_type", FT_UINT8, BASE_HEX, NULL,
2273
15
                ZBEE_NWK_GP_CMD_COMMISSIONING_REP_OPT_KEY_TYPE, NULL, HFILL }},
2274
2275
15
        { &hf_zbee_nwk_gp_cmd_comm_rep_pan_id,
2276
15
            { "PAN ID", "zbee_nwk_gp.cmd.comm_reply.pan_id", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2277
2278
15
        { &hf_zbee_nwk_gp_cmd_comm_rep_frame_counter,
2279
15
            { "Frame Counter", "zbee_nwk_gp.cmd.comm_reply.frame_counter", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2280
2281
15
        { &hf_zbee_nwk_gp_cmd_read_att_opt_multi_rec,
2282
15
            { "Multi-record", "zbee_nwk_gp.cmd.read_att.opt.multi_record", FT_BOOLEAN, 8, NULL,
2283
15
                ZBEE_NWK_GP_CMD_READ_ATTRIBUTE_OPT_MULTI_RECORD, NULL, HFILL }},
2284
2285
15
        { &hf_zbee_nwk_gp_cmd_read_att_opt_man_field_present,
2286
15
            { "Manufacturer field present", "zbee_nwk_gp.cmd.read_att.opt.man_field_present", FT_BOOLEAN, 8, NULL,
2287
15
                ZBEE_NWK_GP_CMD_READ_ATTRIBUTE_OPT_MAN_FIELD_PRESENT, NULL, HFILL }},
2288
2289
15
        { &hf_zbee_nwk_gp_cmd_read_att_opt,
2290
15
            { "Option field", "zbee_nwk_gp.cmd.read_att.opt", FT_UINT8, BASE_HEX, NULL,
2291
15
                0x0, NULL, HFILL }},
2292
2293
15
        { &hf_zbee_nwk_gp_cmd_zcl_tunnel_opt_frame_type,
2294
15
            { "Frame type", "zbee_nwk_gp.cmd.zcl_tunnel.opt.frame_type", FT_UINT8, BASE_HEX, NULL,
2295
15
                ZBEE_NWK_GP_CMD_ZCL_TUNNEL_OPT_FRAME_TYPE, NULL, HFILL }},
2296
2297
15
        { &hf_zbee_nwk_gp_cmd_zcl_tunnel_opt_man_field_present,
2298
15
            { "Manufacturer field present", "zbee_nwk_gp.cmd.zcl_tunnel.opt.man_field_present", FT_BOOLEAN, 8, NULL,
2299
15
                ZBEE_NWK_GP_CMD_ZCL_TUNNEL_OPT_MAN_FIELD_PRESENT, NULL, HFILL }},
2300
2301
15
        { &hf_zbee_nwk_gp_cmd_zcl_tunnel_opt_direction,
2302
15
            { "Direction", "zbee_nwk_gp.cmd.zcl_tunnel.opt.direction", FT_UINT8, BASE_HEX, NULL,
2303
15
                ZBEE_NWK_GP_CMD_ZCL_TUNNEL_OPT_DIRECTION, NULL, HFILL }},
2304
2305
15
        { &hf_zbee_nwk_gp_cmd_zcl_tunnel_opt,
2306
15
            { "Option field", "zbee_nwk_gp.cmd.zcl_tunnel.opt", FT_UINT8, BASE_HEX, NULL,
2307
15
                0x0, NULL, HFILL }},
2308
2309
15
        { &hf_zbee_nwk_gp_cmd_zcl_tunnel_command_id,
2310
15
            { "Zigbee Command ID", "zbee_nwk_gp.cmd.zcl_tunnel.command_id", FT_UINT8, BASE_HEX, NULL, 0x0,
2311
15
                NULL, HFILL }},
2312
2313
15
        { &hf_zbee_nwk_gp_cmd_zcl_tunnel_payload_len,
2314
15
            { "Length of Payload",  "zbee_nwk_gp.cmd.zcl_tunnel.payload_len", FT_UINT8, BASE_DEC, NULL, 0x0,
2315
15
                NULL, HFILL }},
2316
2317
15
        { &hf_zbee_zcl_gp_cmd_ms_manufacturer_code,
2318
15
            { "Manufacturer Code", "zbee_nwk_gp.cmd.manufacturer_code", FT_UINT16, BASE_HEX, VALS(zbee_mfr_code_names),
2319
15
                0x0, NULL, HFILL }},
2320
2321
15
        { &hf_zbee_nwk_gp_cmd_read_att_record_len,
2322
15
            { "Length of Record List",  "zbee_nwk_gp.cmd.read_att.record_len", FT_UINT8, BASE_DEC, NULL, 0x0,
2323
15
                NULL, HFILL }},
2324
2325
15
        { &hf_zbee_nwk_gp_zcl_attr_status,
2326
15
            { "Status", "zbee_nwk_gp.zcl.attr.status", FT_UINT8, BASE_HEX, VALS(zbee_zcl_status_names),
2327
15
                0x0, NULL, HFILL }},
2328
2329
15
        { &hf_zbee_nwk_gp_zcl_attr_data_type,
2330
15
            { "Data Type", "zbee_nwk_gp.zcl.attr.datatype", FT_UINT8, BASE_HEX, VALS(zbee_zcl_short_data_type_names),
2331
15
                0x0, NULL, HFILL } },
2332
2333
15
        { &hf_zbee_nwk_gp_zcl_attr_cluster_id,
2334
15
            { "ZigBee Cluster ID", "zbee_nwk_gp.zcl.attr.cluster_id", FT_UINT16, BASE_HEX | BASE_RANGE_STRING, RVALS(zbee_aps_cid_names),
2335
15
                0x0, NULL, HFILL }},
2336
2337
15
        { &hf_zbee_nwk_gp_cmd_channel_request_toggling_behaviour,
2338
15
            { "Channel Toggling Behaviour", "zbee_nwk_gp.cmd.ch_req", FT_UINT8, BASE_HEX, NULL,
2339
15
                0x0, NULL, HFILL }},
2340
2341
15
        { &hf_zbee_nwk_gp_cmd_channel_request_toggling_behaviour_1st,
2342
15
            { "Rx channel in the next attempt", "zbee_nwk_gp.cmd.ch_req.1st", FT_UINT8, BASE_HEX, NULL,
2343
15
                ZBEE_NWK_GP_CMD_CHANNEL_REQUEST_1ST, NULL, HFILL }},
2344
2345
15
        { &hf_zbee_nwk_gp_cmd_channel_request_toggling_behaviour_2nd,
2346
15
            { "Rx channel in the second next attempt", "zbee_nwk_gp.ch_req.2nd", FT_UINT8, BASE_HEX, NULL,
2347
15
                ZBEE_NWK_GP_CMD_CHANNEL_REQUEST_2ND, NULL, HFILL }},
2348
2349
15
        { &hf_zbee_nwk_gp_cmd_operational_channel,
2350
15
            { "Operational Channel", "zbee_nwk_gp.cmd.configuration_ch", FT_UINT8, BASE_HEX, NULL,
2351
15
                0x0, NULL, HFILL }},
2352
2353
15
        { &hf_zbee_nwk_gp_cmd_channel_configuration,
2354
15
            { "Operation channel", "zbee_nwk_gp.cmd.configuration_ch.operation_ch", FT_UINT8, BASE_HEX, NULL,
2355
15
                ZBEE_NWK_GP_CMD_CHANNEL_CONFIGURATION_OPERATION_CH, NULL, HFILL }},
2356
2357
15
        { &hf_zbee_nwk_gp_cmd_move_color_ratex,
2358
15
            { "RateX", "zbee_nwk_gp.cmd.move_color.ratex", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
2359
2360
15
        { &hf_zbee_nwk_gp_cmd_move_color_ratey,
2361
15
            { "RateY", "zbee_nwk_gp.cmd.move_color.ratey", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
2362
2363
15
        { &hf_zbee_nwk_gp_cmd_move_up_down_rate,
2364
15
            { "Rate", "zbee_nwk_gp.cmd.move_up_down.rate", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
2365
2366
15
        { &hf_zbee_nwk_gp_cmd_step_color_stepx,
2367
15
            { "StepX", "zbee_nwk_gp.cmd.step_color.stepx", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
2368
2369
15
        { &hf_zbee_nwk_gp_cmd_step_color_stepy,
2370
15
            { "StepY", "zbee_nwk_gp.cmd.step_color.stepy", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
2371
2372
15
        { &hf_zbee_nwk_gp_cmd_step_color_transition_time,
2373
15
            { "Transition Time", "zbee_nwk_gp.cmd.step_color.transition_time", FT_UINT16, BASE_DEC, NULL, 0x0, NULL,
2374
15
                HFILL }},
2375
2376
15
        { &hf_zbee_nwk_gp_cmd_step_up_down_step_size,
2377
15
            { "Step Size", "zbee_nwk_gp.cmd.step_up_down.step_size", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
2378
2379
15
        { &hf_zbee_nwk_gp_cmd_step_up_down_transition_time,
2380
15
            { "Transition Time", "zbee_nwk_gp.cmd.step_up_down.transition_time", FT_UINT16, BASE_DEC, NULL, 0x0, NULL,
2381
15
                HFILL }}
2382
15
    };
2383
2384
15
    static ei_register_info ei[] = {
2385
15
        { &ei_zbee_nwk_gp_no_payload,
2386
15
            { "zbee_nwk_gp.no_payload", PI_MALFORMED, PI_ERROR,
2387
15
                "Payload is missing", EXPFILL }},
2388
15
        { &ei_zbee_nwk_gp_inval_residual_data,
2389
15
            { "zbee_nwk_gp.inval_residual_data", PI_MALFORMED, PI_ERROR,
2390
15
                "Invalid residual data", EXPFILL }},
2391
15
        { &ei_zbee_nwk_gp_com_rep_no_out_cnt,
2392
15
            { "zbee_nwk_gp.com_rep_no_out_cnt", PI_DEBUG, PI_WARN,
2393
15
                "Missing outgoing frame counter", EXPFILL }}
2394
15
    };
2395
2396
15
    static int *ett[] = {
2397
15
        &ett_zbee_nwk,
2398
15
        &ett_zbee_nwk_cmd,
2399
15
        &ett_zbee_nwk_cmd_cinfo,
2400
15
        &ett_zbee_nwk_cmd_appli_info,
2401
15
        &ett_zbee_nwk_cmd_options,
2402
15
        &ett_zbee_nwk_fcf,
2403
15
        &ett_zbee_nwk_fcf_ext,
2404
15
        &ett_zbee_nwk_clu_rec,
2405
15
        &ett_zbee_nwk_att_rec,
2406
15
        &ett_zbee_nwk_cmd_comm_gpd_cmd_id_list,
2407
15
        &ett_zbee_nwk_cmd_comm_length_of_clid_list,
2408
15
        &ett_zbee_nwk_cmd_comm_clid_list_server,
2409
15
        &ett_zbee_nwk_cmd_comm_clid_list_client
2410
15
    };
2411
2412
15
    static uat_field_t key_uat_fields[] = {
2413
15
        UAT_FLD_CSTRING(gp_uat_key_records, string, "Key", "A 16-byte key."),
2414
15
        UAT_FLD_VS(gp_uat_key_records, byte_order, "Byte Order", byte_order_vals, "Byte order of a key."),
2415
15
        UAT_FLD_LSTRING(gp_uat_key_records, label, "Label", "User label for a key."),
2416
15
        UAT_END_FIELDS
2417
15
    };
2418
2419
15
    proto_zbee_nwk_gp = proto_register_protocol("ZigBee Green Power Profile", "ZigBee Green Power",
2420
15
        ZBEE_PROTOABBREV_NWK_GP);
2421
2422
15
    gp_zbee_prefs = prefs_register_protocol(proto_zbee_nwk_gp, NULL);
2423
2424
15
    zbee_gp_sec_key_table_uat = uat_new("ZigBee GP Security Keys", sizeof(uat_key_record_t), "zigbee_gp_keys", true,
2425
15
        &gp_uat_key_records, &num_uat_key_records, UAT_AFFECTS_DISSECTION, NULL, uat_key_record_copy_cb,
2426
15
        uat_key_record_update_cb, uat_key_record_free_cb, uat_key_record_post_update_cb, NULL, key_uat_fields);
2427
2428
15
    prefs_register_uat_preference(gp_zbee_prefs, "gp_key_table", "Pre-configured GP Security Keys",
2429
15
        "Pre-configured GP Security Keys.", zbee_gp_sec_key_table_uat);
2430
2431
15
    register_init_routine(gp_init_zbee_security);
2432
15
    register_cleanup_routine(gp_cleanup_zbee_security);
2433
2434
    /* Register the Wireshark protocol. */
2435
15
    proto_register_field_array(proto_zbee_nwk_gp, hf, array_length(hf));
2436
15
    proto_register_subtree_array(ett, array_length(ett));
2437
2438
15
    expert_zbee_nwk_gp = expert_register_protocol(proto_zbee_nwk_gp);
2439
15
    expert_register_field_array(expert_zbee_nwk_gp, ei, array_length(ei));
2440
2441
    /* Register the dissectors. */
2442
15
    register_dissector(ZBEE_PROTOABBREV_NWK_GP, dissect_zbee_nwk_gp, proto_zbee_nwk_gp);
2443
15
    register_dissector(ZBEE_PROTOABBREV_NWK_GP_CMD, dissect_zbee_nwk_gp_cmd, proto_zbee_nwk_gp);
2444
15
} /* proto_register_zbee_nwk_gp */
2445
2446
/**
2447
 *Registers the ZigBee dissector with Wireshark.
2448
 *
2449
*/
2450
void
2451
proto_reg_handoff_zbee_nwk_gp(void)
2452
15
{
2453
    /* Register our dissector with IEEE 802.15.4. */
2454
15
    dissector_add_for_decode_as(IEEE802154_PROTOABBREV_WPAN_PANID, find_dissector(ZBEE_PROTOABBREV_NWK_GP));
2455
15
    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);
2456
15
} /* proto_reg_handoff_zbee */
2457
2458
/*
2459
 * Editor modelines
2460
 *
2461
 * Local Variables:
2462
 * c-basic-offset: 4
2463
 * tab-width: 8
2464
 * indent-tabs-mode: nil
2465
 * End:
2466
 *
2467
 * ex: set shiftwidth=4 tabstop=8 expandtab:
2468
 * :indentSize=4:tabSize=8:noTabs=true:
2469
 */