Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-rf4ce-nwk.c
blob0f209ca4699730cfcac603e7bba6e48d8b7386f4
1 /* packet-rf4ce-nwk.c
2 * Network layer related functions and objects for RF4CE dissector
3 * Copyright (C) Atmosic 2023
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * SPDX-License-Identifier: GPL-2.0-or-later
12 #include <stdbool.h>
13 #include "config.h"
14 #include <epan/packet.h>
15 #include <epan/uat.h>
16 #include <epan/tfs.h>
17 #include <wsutil/array.h>
18 #include "packet-ieee802154.h"
19 #include "packet-rf4ce-secur.h"
21 #define RF4CE_MIN_NWK_LENGTH 5
22 #define RF4CE_MAX_NWK_LENGTH 148
24 /* Profile IDs */
25 #define RF4CE_NWK_PROFILE_ID_GDP 0x00
26 #define RF4CE_NWK_PROFILE_ID_ZRC10 0x01
27 #define RF4CE_NWK_PROFILE_ID_ZID 0x02
28 #define RF4CE_NWK_PROFILE_ID_ZRC20 0x03
30 #define RF4CE_PROTOABBREV_NWK "rf4ce_nwk"
31 #define RF4CE_PROTOABBREV_PROFILE "rf4ce_profile"
33 static int proto_rf4ce_nwk;
34 static dissector_handle_t rf4ce_gdp_handle;
36 /* UAT vars */
37 static uat_t *rf4ce_security_table_uat;
39 #define RF4CE_SEC_STR_TYPE_NWK_KEY 0
40 #define RF4CE_SEC_STR_TYPE_VENDOR_SECRET 1
42 static const value_string sec_str_type_vals[] = {
43 { RF4CE_SEC_STR_TYPE_NWK_KEY, "NWK Key"},
44 { RF4CE_SEC_STR_TYPE_VENDOR_SECRET, "Vendor Secret"},
45 { 0, NULL }
48 UAT_CSTRING_CB_DEF(uat_security_records, sec_str, uat_security_record_t)
49 UAT_VS_DEF(uat_security_records, type, uat_security_record_t, uint8_t, 0, "NWK Key")
50 UAT_CSTRING_CB_DEF(uat_security_records, label, uat_security_record_t)
52 static uat_security_record_t *uat_security_records;
53 static unsigned num_uat_security_records;
55 static int ett_rf4ce_nwk;
56 static int ett_rf4ce_nwk_payload;
57 static int ett_rf4ce_nwk_vendor_info;
58 static int ett_rf4ce_nwk_usr_str;
59 static int ett_rf4ce_nwk_usr_str_class_descriptor;
60 static int ett_rf4ce_nwk_dev_types_list;
61 static int ett_rf4ce_nwk_profiles_list;
63 /* RF4CE NWK header */
64 static int hf_rf4ce_nwk_fcf;
65 static int hf_rf4ce_nwk_fcf_frame_type;
66 static int hf_rf4ce_nwk_fcf_security_enabled;
67 static int hf_rf4ce_nwk_fcf_protocol_version;
68 static int hf_rf4ce_nwk_fcf_reserved;
69 static int hf_rf4ce_nwk_fcf_channel_designator;
70 static int hf_rf4ce_nwk_seq_num;
71 static int hf_rf4ce_nwk_profile_id;
72 static int hf_rf4ce_nwk_vendor_id;
74 /* RF4CE NWK payload common */
75 static int hf_rf4ce_nwk_cmd_id;
77 static int hf_rf4ce_nwk_node_capabilities;
78 static int hf_rf4ce_nwk_node_capabilities_node_type;
79 static int hf_rf4ce_nwk_node_capabilities_power_source;
80 static int hf_rf4ce_nwk_node_capabilities_security;
81 static int hf_rf4ce_nwk_node_capabilities_channel_normalization;
82 static int hf_rf4ce_nwk_node_capabilities_reserved;
84 static int hf_rf4ce_nwk_disc_req_vendor_id;
86 #define RF4CE_NWK_VENDOR_STRING_MAX_LENGTH 7
87 static int hf_rf4ce_nwk_vendor_string;
89 static int hf_rf4ce_nwk_app_capabilities;
90 static int hf_rf4ce_nwk_app_capabilities_usr_str;
91 static int hf_rf4ce_nwk_app_capabilities_supported_dev_num;
92 static int hf_rf4ce_nwk_app_capabilities_reserved1;
93 static int hf_rf4ce_nwk_app_capabilities_supported_profiles_num;
94 static int hf_rf4ce_nwk_app_capabilities_reserved2;
96 static int hf_rf4ce_nwk_usr_str;
97 static int hf_rf4ce_nwk_usr_str_disc_rsp_app_usr_str;
98 static int hf_rf4ce_nwk_usr_str_disc_rsp_null;
99 static int hf_rf4ce_nwk_usr_str_disc_rsp_reserved;
101 static int hf_rf4ce_nwk_usr_str_disc_rsp_class_desc_tertiary;
102 static int hf_rf4ce_nwk_usr_str_disc_rsp_class_desc_secondary;
103 static int hf_rf4ce_nwk_usr_str_disc_rsp_class_desc_primary;
105 static int hf_rf4ce_nwk_usr_str_disc_rsp_class_desc_class_num;
106 static int hf_rf4ce_nwk_usr_str_disc_rsp_class_desc_duplicate_class_num_handling;
107 static int hf_rf4ce_nwk_usr_str_disc_rsp_class_desc_reserved;
109 static int hf_rf4ce_nwk_usr_str_disc_rsp_discovery_lqi_threshold;
111 #define RF4CE_NWK_USR_STR_DISC_RSP_CLASS_DESC_CLASS_NUM_MASK 0b00001111
112 #define RF4CE_NWK_USR_STR_DISC_RSP_CLASS_DESC_DUPLICATE_CLASS_NUM_HANDLING_MASK 0b00110000
113 #define RF4CE_NWK_USR_STR_DISC_RSP_CLASS_DESC_RESERVED_MASK 0b11000000
115 #define RF4CE_NWK_USR_STR_DISC_RSP_CLASS_DESC_CLASS_NUM_PRE_COMMISSIONED 0x00
116 #define RF4CE_NWK_USR_STR_DISC_RSP_CLASS_DESC_CLASS_NUM_BUTTON_PRESS_INDICATION 0x01
117 #define RF4CE_NWK_USR_STR_DISC_RSP_CLASS_DESC_CLASS_NUM_RESERVED_2 0x02
118 #define RF4CE_NWK_USR_STR_DISC_RSP_CLASS_DESC_CLASS_NUM_RESERVED_3 0x03
119 #define RF4CE_NWK_USR_STR_DISC_RSP_CLASS_DESC_CLASS_NUM_IMPLEMENTATION_SPECIFIC_04 0x04
120 #define RF4CE_NWK_USR_STR_DISC_RSP_CLASS_DESC_CLASS_NUM_IMPLEMENTATION_SPECIFIC_05 0x05
121 #define RF4CE_NWK_USR_STR_DISC_RSP_CLASS_DESC_CLASS_NUM_IMPLEMENTATION_SPECIFIC_06 0x06
122 #define RF4CE_NWK_USR_STR_DISC_RSP_CLASS_DESC_CLASS_NUM_IMPLEMENTATION_SPECIFIC_07 0x07
123 #define RF4CE_NWK_USR_STR_DISC_RSP_CLASS_DESC_CLASS_NUM_IMPLEMENTATION_SPECIFIC_08 0x08
124 #define RF4CE_NWK_USR_STR_DISC_RSP_CLASS_DESC_CLASS_NUM_IMPLEMENTATION_SPECIFIC_09 0x09
125 #define RF4CE_NWK_USR_STR_DISC_RSP_CLASS_DESC_CLASS_NUM_IMPLEMENTATION_SPECIFIC_0A 0x0A
126 #define RF4CE_NWK_USR_STR_DISC_RSP_CLASS_DESC_CLASS_NUM_IMPLEMENTATION_SPECIFIC_0B 0x0B
127 #define RF4CE_NWK_USR_STR_DISC_RSP_CLASS_DESC_CLASS_NUM_IMPLEMENTATION_SPECIFIC_0C 0x0C
128 #define RF4CE_NWK_USR_STR_DISC_RSP_CLASS_DESC_CLASS_NUM_IMPLEMENTATION_SPECIFIC_0D 0x0D
129 #define RF4CE_NWK_USR_STR_DISC_RSP_CLASS_DESC_CLASS_NUM_IMPLEMENTATION_SPECIFIC_0E 0x0E
130 #define RF4CE_NWK_USR_STR_DISC_RSP_CLASS_DESC_CLASS_NUM_DISCOVERABLE_ONLY 0x0F
132 static const value_string rf4ce_nwk_usr_str_disc_rsp_class_desc_class_num_vals[] = {
133 { RF4CE_NWK_USR_STR_DISC_RSP_CLASS_DESC_CLASS_NUM_PRE_COMMISSIONED, "Pre-Commissioned" },
134 { RF4CE_NWK_USR_STR_DISC_RSP_CLASS_DESC_CLASS_NUM_BUTTON_PRESS_INDICATION, "Button Press Indication" },
135 { RF4CE_NWK_USR_STR_DISC_RSP_CLASS_DESC_CLASS_NUM_RESERVED_2, "Reserved" },
136 { RF4CE_NWK_USR_STR_DISC_RSP_CLASS_DESC_CLASS_NUM_RESERVED_3, "Reserved" },
137 { RF4CE_NWK_USR_STR_DISC_RSP_CLASS_DESC_CLASS_NUM_IMPLEMENTATION_SPECIFIC_04, "Implementation Specific" },
138 { RF4CE_NWK_USR_STR_DISC_RSP_CLASS_DESC_CLASS_NUM_IMPLEMENTATION_SPECIFIC_05, "Implementation Specific" },
139 { RF4CE_NWK_USR_STR_DISC_RSP_CLASS_DESC_CLASS_NUM_IMPLEMENTATION_SPECIFIC_06, "Implementation Specific" },
140 { RF4CE_NWK_USR_STR_DISC_RSP_CLASS_DESC_CLASS_NUM_IMPLEMENTATION_SPECIFIC_07, "Implementation Specific" },
141 { RF4CE_NWK_USR_STR_DISC_RSP_CLASS_DESC_CLASS_NUM_IMPLEMENTATION_SPECIFIC_08, "Implementation Specific" },
142 { RF4CE_NWK_USR_STR_DISC_RSP_CLASS_DESC_CLASS_NUM_IMPLEMENTATION_SPECIFIC_09, "Implementation Specific" },
143 { RF4CE_NWK_USR_STR_DISC_RSP_CLASS_DESC_CLASS_NUM_IMPLEMENTATION_SPECIFIC_0A, "Implementation Specific" },
144 { RF4CE_NWK_USR_STR_DISC_RSP_CLASS_DESC_CLASS_NUM_IMPLEMENTATION_SPECIFIC_0B, "Implementation Specific" },
145 { RF4CE_NWK_USR_STR_DISC_RSP_CLASS_DESC_CLASS_NUM_IMPLEMENTATION_SPECIFIC_0C, "Implementation Specific" },
146 { RF4CE_NWK_USR_STR_DISC_RSP_CLASS_DESC_CLASS_NUM_IMPLEMENTATION_SPECIFIC_0D, "Implementation Specific" },
147 { RF4CE_NWK_USR_STR_DISC_RSP_CLASS_DESC_CLASS_NUM_IMPLEMENTATION_SPECIFIC_0E, "Implementation Specific" },
148 { RF4CE_NWK_USR_STR_DISC_RSP_CLASS_DESC_CLASS_NUM_DISCOVERABLE_ONLY, "Discoverable Only" },
149 { 0, NULL }
152 #define RF4CE_NWK_USR_STR_DISC_RSP_CLASS_DESC_DUPLICATE_CLASS_NUM_HANDLING_AS_IS 0x00
153 #define RF4CE_NWK_USR_STR_DISC_RSP_CLASS_DESC_DUPLICATE_CLASS_NUM_HANDLING_RECLASSIFY 0x01
154 #define RF4CE_NWK_USR_STR_DISC_RSP_CLASS_DESC_DUPLICATE_CLASS_NUM_HANDLING_ABORT_BINDING 0x02
155 #define RF4CE_NWK_USR_STR_DISC_RSP_CLASS_DESC_DUPLICATE_CLASS_NUM_HANDLING_RESERVED 0x03
157 static const value_string rf4ce_nwk_usr_str_disc_rsp_class_desc_duplicate_class_num_handling_vals[] = {
158 { RF4CE_NWK_USR_STR_DISC_RSP_CLASS_DESC_DUPLICATE_CLASS_NUM_HANDLING_AS_IS, "Use node descriptor as is" },
159 { RF4CE_NWK_USR_STR_DISC_RSP_CLASS_DESC_DUPLICATE_CLASS_NUM_HANDLING_RECLASSIFY, "Reclassify node descriptor" },
160 { RF4CE_NWK_USR_STR_DISC_RSP_CLASS_DESC_DUPLICATE_CLASS_NUM_HANDLING_ABORT_BINDING, "Abort binding" },
161 { RF4CE_NWK_USR_STR_DISC_RSP_CLASS_DESC_DUPLICATE_CLASS_NUM_HANDLING_RESERVED, "Reserved" },
162 { 0, NULL }
165 #define RF4CE_NWK_USR_STR_DISC_RSP_APP_USR_STR_LENGTH 9
167 #define RF4CE_NWK_USR_STR_PARSING_MASK_NONE 0b00000001
168 #define RF4CE_NWK_USR_STR_PARSING_MASK_DISC_RESP 0b00000010
170 static int hf_rf4ce_nwk_app_cap_dev_type;
171 static int hf_rf4ce_nwk_app_cap_profile_id;
173 /* RF4CE NWK Discovery Request */
174 static int hf_rf4ce_nwk_requested_dev_type;
176 /* RF4CE NWK Discovery Response */
177 static int hf_rf4ce_nwk_disc_resp_status;
178 static int hf_rf4ce_nwk_disc_resp_lqi;
180 /* RF4CE NWK Pair Request */
181 static int hf_rf4ce_nwk_pair_req_nwk_addr;
182 static int hf_rf4ce_nwk_pair_req_key_exch_num;
184 /* RF4CE NWK Pair Response */
185 static int hf_rf4ce_nwk_pair_rsp_status;
186 static int hf_rf4ce_nwk_pair_rsp_allocated_nwk_addr;
187 static int hf_rf4ce_nwk_pair_rsp_nwk_addr;
189 /* RF4CE NWK Key Seed */
190 static int hf_rf4ce_nwk_seed_seq_num;
192 #define RF4CE_NWK_KEY_SEED_DATA_LENGTH 80
193 static int hf_rf4ce_nwk_seed_data;
195 /* RF4CE NWK Ping Request and Response */
196 static int hf_rf4ce_nwk_ping_options;
197 static int hf_rf4ce_nwk_ping_payload;
199 #if 0
200 /* Should be at the end of a decrypted NWK packet */
201 static int hf_rf4ce_nwk_mic;
202 #endif
204 static int hf_rf4ce_nwk_unparsed_payload;
206 /* Frame Control Field */
207 #define RF4CE_NWK_FCF_FRAME_TYPE_MASK 0b00000011
208 #define RF4CE_NWK_FCF_SECURITY_MASK 0b00000100
209 #define RF4CE_NWK_FCF_PROTOCOL_VERSION_MASK 0b00011000
210 #define RF4CE_NWK_FCF_RESERVED_MASK 0b00100000
211 #define RF4CE_NWK_FCF_CHANNEL_DESIGNATOR_MASK 0b11000000
213 /* Frame types */
214 #define RF4CE_NWK_FCF_FRAME_TYPE_RESERVED 0
215 #define RF4CE_NWK_FCF_FRAME_TYPE_DATA 1
216 #define RF4CE_NWK_FCF_FRAME_TYPE_CMD 2
217 #define RF4CE_NWK_FCF_FRAME_TYPE_VENDOR_SPECIFIC 3
219 static const value_string rf4ce_nwk_frame_types[] = {
220 { RF4CE_NWK_FCF_FRAME_TYPE_RESERVED, "Reserved" },
221 { RF4CE_NWK_FCF_FRAME_TYPE_DATA, "Standard Data Frame" },
222 { RF4CE_NWK_FCF_FRAME_TYPE_CMD, "NWK Command Frame" },
223 { RF4CE_NWK_FCF_FRAME_TYPE_VENDOR_SPECIFIC, "Vendor-specific data frame" },
224 { 0, NULL }
227 /* Channel Designators */
228 #define RF4CE_NWK_FCF_CHANNEL_NOT_SPECIFIED 0
229 #define RF4CE_NWK_FCF_CHANNEL_15 1
230 #define RF4CE_NWK_FCF_CHANNEL_20 2
231 #define RF4CE_NWK_FCF_CHANNEL_25 3
233 static const value_string rf4ce_nwk_channel_designators[] = {
234 { RF4CE_NWK_FCF_CHANNEL_NOT_SPECIFIED, "Channel not specified" },
235 { RF4CE_NWK_FCF_CHANNEL_15, "Channel 15" },
236 { RF4CE_NWK_FCF_CHANNEL_20, "Channel 20" },
237 { RF4CE_NWK_FCF_CHANNEL_25, "Channel 25" },
238 { 0, NULL }
241 /* Profile IDs */
242 #define RF4CE_NWK_PROFILE_ID_GDP 0x00
243 #define RF4CE_NWK_PROFILE_ID_ZRC10 0x01
244 #define RF4CE_NWK_PROFILE_ID_ZID 0x02
245 #define RF4CE_NWK_PROFILE_ID_ZRC20 0x03
246 #define RF4CE_NWK_PROFILE_ID_WILDCARD 0xff
248 /* Vendor IDs */
249 #define RF4CE_VENDOR_ID_PANASONIC 0x0001
250 #define RF4CE_VENDOR_ID_SONY 0x0002
251 #define RF4CE_VENDOR_ID_SAMSUNG 0x0003
252 #define RF4CE_VENDOR_ID_PHILIPS 0x0004
253 #define RF4CE_VENDOR_ID_FREESCALE 0x0005
254 #define RF4CE_VENDOR_ID_OKI 0x0006
255 #define RF4CE_VENDOR_ID_TEXAS_INSTRUMENTS 0x0007
256 #define RF4CE_VENDOR_ID_TEST_1 0xfff1
257 #define RF4CE_VENDOR_ID_TEST_2 0xfff2
258 #define RF4CE_VENDOR_ID_TEST_3 0xfff3
260 static const value_string rf4ce_nwk_profile_ids[] = {
261 { RF4CE_NWK_PROFILE_ID_GDP, "GDP" },
262 { RF4CE_NWK_PROFILE_ID_ZRC10, "ZRC 1.0" },
263 { RF4CE_NWK_PROFILE_ID_ZID, "ZID" },
264 { RF4CE_NWK_PROFILE_ID_ZRC20, "ZRC 2.0" },
265 { 0, NULL }
268 /* NWK Commands */
269 #define RF4CE_NWK_CMD_DISCOVERY_REQ 0x01
270 #define RF4CE_NWK_CMD_DISCOVERY_RSP 0x02
271 #define RF4CE_NWK_CMD_PAIR_REQ 0x03
272 #define RF4CE_NWK_CMD_PAIR_RSP 0x04
273 #define RF4CE_NWK_CMD_UNPAIR_REQ 0x05
274 #define RF4CE_NWK_CMD_KEY_SEED 0x06
275 #define RF4CE_NWK_CMD_PING_REQ 0x07
276 #define RF4CE_NWK_CMD_PING_RSP 0x08
278 static const value_string rf4ce_nwk_cmd_names[] = {
279 { RF4CE_NWK_CMD_DISCOVERY_REQ, "Discovery Request" },
280 { RF4CE_NWK_CMD_DISCOVERY_RSP, "Discovery Response" },
281 { RF4CE_NWK_CMD_PAIR_REQ, "Pair Request" },
282 { RF4CE_NWK_CMD_PAIR_RSP, "Pair Response" },
283 { RF4CE_NWK_CMD_UNPAIR_REQ, "Unpair Request" },
284 { RF4CE_NWK_CMD_KEY_SEED, "Key Seed" },
285 { RF4CE_NWK_CMD_PING_REQ, "Ping Request" },
286 { RF4CE_NWK_CMD_PING_RSP, "Ping Response" },
287 { 0, NULL }
290 /* NWK Commands - Discovery Request - Node Capabilities */
291 #define RF4CE_NWK_NODE_TYPE_MASK 0b00000001
292 #define RF4CE_NWK_POWER_SOURCE_MASK 0b00000010
293 #define RF4CE_NWK_SECURITY_MASK 0b00000100
294 #define RF4CE_NWK_CHANNEL_NORMALIZATION_MASK 0b00001000
295 #define RF4CE_NWK_RESERVED_MASK 0b11110000
297 #define RF4CE_NWK_NODE_TYPE_CONTROLLER 0
298 #define RF4CE_NWK_NODE_TYPE_TARGET 1
300 static const value_string rf4ce_nwk_node_types[] = {
301 { RF4CE_NWK_NODE_TYPE_CONTROLLER, "Controller" },
302 { RF4CE_NWK_NODE_TYPE_TARGET, "Target" },
303 { 0, NULL }
306 #define RF4CE_NWK_POWER_SOURCE_NO_ALTERNATING_CURRENT_MAINS 0
307 #define RF4CE_NWK_POWER_SOURCE_ALTERNATING_CURRENT_MAINS 1
309 static const value_string rf4ce_nwk_power_sources[] = {
310 { RF4CE_NWK_POWER_SOURCE_NO_ALTERNATING_CURRENT_MAINS, "No Alternating Current Mains" },
311 { RF4CE_NWK_POWER_SOURCE_ALTERNATING_CURRENT_MAINS, "Alternating Current Mains" },
312 { 0, NULL }
315 #define RF4CE_DISC_REQ_VENDOR_ID_TEXAS_INSTRUMENTS 0x0007
316 static const value_string rf4ce_disc_req_vendor_ids[] = {
317 { RF4CE_DISC_REQ_VENDOR_ID_TEXAS_INSTRUMENTS, "Texas Instruments" },
318 { 0, NULL }
321 /* NWK Commands - Discovery Request - App Capabilities */
322 #define RF4CE_NWK_USR_STR_SPECIFIED_MASK 0b00000001
323 #define RF4CE_NWK_SUPPORTED_DEV_NUM_MASK 0b00000110
324 #define RF4CE_NWK_RESERVED1_MASK 0b00001000
325 #define RF4CE_NWK_SUPPORTED_PROFILES_NUM_MASK 0b01110000
326 #define RF4CE_NWK_RESERVED2_MASK 0b10000000
328 #define RF4CE_NWK_USR_STR_LENGTH 15
329 #define RF4CE_NWK_SUPPORTED_DEV_NUM_OFFSET 1
330 #define RF4CE_NWK_SUPPORTED_PROFILES_NUM_OFFSET 4
332 /* NWK Commands - Discovery Request - Device Types */
333 #define RF4CE_DEVICE_RESERVED_INVALID 0x00
334 #define RF4CE_DEVICE_REMOTE_CONTROL 0x01
335 #define RF4CE_DEVICE_TELEVISION 0x02
336 #define RF4CE_DEVICE_PROJECTOR 0x03
337 #define RF4CE_DEVICE_PLAYER 0x04
338 #define RF4CE_DEVICE_RECORDER 0x05
339 #define RF4CE_DEVICE_VIDEO_PLAYER_RECORDER 0x06
340 #define RF4CE_DEVICE_AUDIO_PLAYER_RECORDER 0x07
341 #define RF4CE_DEVICE_AUDIO_VIDEO_RECORDER 0x08
342 #define RF4CE_DEVICE_SET_TOP_BOX 0x09
343 #define RF4CE_DEVICE_HOME_THEATER_SYSTEM 0x0a
344 #define RF4CE_DEVICE_MEDIA_CENTER_PC 0x0b
345 #define RF4CE_DEVICE_GAME_CONSOLE 0x0c
346 #define RF4CE_DEVICE_SATELLITE_RADIO_RECEIVER 0x0d
347 #define RF4CE_DEVICE_IR_EXTENDER 0x0e
348 #define RF4CE_DEVICE_MONITOR 0x0f
349 #define RF4CE_DEVICE_ALL_DEVICES 0xff
351 static const value_string rf4ce_nwk_device_type_vals[] = {
352 { RF4CE_DEVICE_RESERVED_INVALID, "Invalid" },
353 { RF4CE_DEVICE_REMOTE_CONTROL, "Remote Control" },
354 { RF4CE_DEVICE_TELEVISION, "Television" },
355 { RF4CE_DEVICE_PROJECTOR, "Projector" },
356 { RF4CE_DEVICE_PLAYER, "Player" },
357 { RF4CE_DEVICE_RECORDER, "Recorder" },
358 { RF4CE_DEVICE_VIDEO_PLAYER_RECORDER, "Video Player Recorder" },
359 { RF4CE_DEVICE_AUDIO_PLAYER_RECORDER, "Audio Player Recorder" },
360 { RF4CE_DEVICE_AUDIO_VIDEO_RECORDER, "Audio Video Recorder" },
361 { RF4CE_DEVICE_SET_TOP_BOX, "Set Top Box" },
362 { RF4CE_DEVICE_HOME_THEATER_SYSTEM, "Home Theater System" },
363 { RF4CE_DEVICE_MEDIA_CENTER_PC, "Media Center PC" },
364 { RF4CE_DEVICE_GAME_CONSOLE, "Game Console" },
365 { RF4CE_DEVICE_SATELLITE_RADIO_RECEIVER, "Satellite Radio Receiver" },
366 { RF4CE_DEVICE_IR_EXTENDER, "IR Extender" },
367 { RF4CE_DEVICE_MONITOR, "Monitor" },
368 { RF4CE_DEVICE_ALL_DEVICES, "All the Devices" },
369 { 0, NULL }
372 #define RF4CE_NWK_STATUS_SUCCESS 0x00
373 #define RF4CE_NWK_STATUS_NO_ORG_CAPACITY 0xb0
374 #define RF4CE_NWK_STATUS_NO_REC_CAPACITY 0xb1
375 #define RF4CE_NWK_STATUS_NO_PAIRING 0xb2
376 #define RF4CE_NWK_STATUS_NO_RESPONSE 0xb3
377 #define RF4CE_NWK_STATUS_NOT_PERMITTED 0xb4
378 #define RF4CE_NWK_STATUS_DUPLICATE_PAIRING 0xb5
379 #define RF4CE_NWK_STATUS_FRAME_COUNTER_EXPIRED 0xb6
380 #define RF4CE_NWK_STATUS_DISCOVERY_ERROR 0xb7
381 #define RF4CE_NWK_STATUS_DISCOVERY_TIMEOUT 0xb8
382 #define RF4CE_NWK_STATUS_SECURITY_TIMEOUT 0xb9
383 #define RF4CE_NWK_STATUS_SECURITY_FAILURE 0xba
384 #define RF4CE_NWK_STATUS_INVALID_PARAMETER 0xe8
385 #define RF4CE_NWK_STATUS_UNSUPPORTED_ATTRIBUTE 0xf4
386 #define RF4CE_NWK_STATUS_INVALID_INDEX 0xf9
388 static const value_string rf4ce_nwk_disc_status_vals[] = {
389 { RF4CE_NWK_STATUS_SUCCESS, "Success" },
390 { RF4CE_NWK_STATUS_NO_ORG_CAPACITY, "No Org Capacity" },
391 { RF4CE_NWK_STATUS_NO_REC_CAPACITY, "No Rec Capacity" },
392 { RF4CE_NWK_STATUS_NO_PAIRING, "No Pairing" },
393 { RF4CE_NWK_STATUS_NO_RESPONSE, "No Response" },
394 { RF4CE_NWK_STATUS_NOT_PERMITTED, "Not Permitted" },
395 { RF4CE_NWK_STATUS_DUPLICATE_PAIRING, "Duplicate Pairing" },
396 { RF4CE_NWK_STATUS_FRAME_COUNTER_EXPIRED, "Frame Counter Expired" },
397 { RF4CE_NWK_STATUS_DISCOVERY_ERROR, "Discovery Error" },
398 { RF4CE_NWK_STATUS_DISCOVERY_TIMEOUT, "Discovery Timeout" },
399 { RF4CE_NWK_STATUS_SECURITY_TIMEOUT, "Security Timeout" },
400 { RF4CE_NWK_STATUS_SECURITY_FAILURE, "Security Failure" },
401 { RF4CE_NWK_STATUS_INVALID_PARAMETER, "Invalid Parameter" },
402 { RF4CE_NWK_STATUS_UNSUPPORTED_ATTRIBUTE, "Unsupported Attribute" },
403 { RF4CE_NWK_STATUS_INVALID_INDEX, "Invalid Index" },
404 { 0, NULL }
407 static bool dissect_rf4ce_nwk_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data);
409 /* RF4CE NWK commands dissectors */
410 static int dissect_rf4ce_nwk_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_);
412 static void dissect_rf4ce_nwk_cmd(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int *offset);
414 static void dissect_rf4ce_nwk_common_node_capabilities(tvbuff_t *tvb, proto_tree *tree, int *offset);
415 static void dissect_rf4ce_nwk_common_vendor_info(tvbuff_t *tvb, proto_tree *tree, int *offset);
416 static void dissect_rf4ce_nwk_common_app_capabilities(tvbuff_t *tvb, proto_tree *tree, int *offset, uint8_t parsing_mask);
417 static void dissect_rf4ce_nwk_disc_resp_class_descriptor(tvbuff_t *tvb, proto_tree *tree, int *offset, int hf);
419 static void dissect_rf4ce_nwk_cmd_disc_req(tvbuff_t *tvb, proto_tree *tree, int *offset);
420 static void dissect_rf4ce_nwk_cmd_disc_rsp(tvbuff_t *tvb, proto_tree *tree, int *offset);
422 static void dissect_rf4ce_nwk_cmd_pair_req(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int *offset);
423 static void dissect_rf4ce_nwk_cmd_pair_rsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int *offset);
425 static void dissect_rf4ce_nwk_cmd_key_seed(tvbuff_t *tvb, proto_tree *tree, int *offset);
427 static void dissect_rf4ce_nwk_cmd_ping(tvbuff_t *tvb, proto_tree *tree, int *offset);
429 static void rf4ce_cleanup(void)
431 rf4ce_secur_cleanup();
434 static void *uat_sec_record_copy_cb(void *n, const void *o, size_t siz _U_)
436 uat_security_record_t *new_sec_rec = (uat_security_record_t *)n;
437 const uat_security_record_t *old_sec_rec = (const uat_security_record_t *)o;
439 new_sec_rec->sec_str = g_strdup(old_sec_rec->sec_str);
440 new_sec_rec->type = old_sec_rec->type;
441 new_sec_rec->label = g_strdup(old_sec_rec->label);
443 return new_sec_rec;
446 static bool rf4ce_security_parse_sec_str(const char *data_str, uint8_t *dst_buf)
448 int i, j;
449 char temp;
450 bool string_mode = false;
452 if (data_str == NULL || dst_buf == NULL)
454 return false;
457 /* Clear the key. */
458 memset(dst_buf, 0, SEC_STR_LEN);
461 * Attempt to parse the key string. The key string must
462 * be at least 16 pairs of hexidecimal digits with the
463 * following optional separators: ':', '-', " ", or 16
464 * alphanumeric characters after a double-quote.
466 temp = *data_str++;
467 if (temp == '"')
469 string_mode = true;
470 temp = *data_str++;
473 j = 0;
474 for (i = SEC_STR_LEN - 1; i >= 0; i--)
476 if (string_mode)
478 if (g_ascii_isprint(temp))
480 dst_buf[j] = temp;
481 temp = *data_str++;
483 else
485 return false;
488 else
490 /* If this character is a separator, skip it. */
491 if ((temp == ':') || (temp == '-') || (temp == ' '))
493 temp = *(data_str++);
496 /* Process a nibble. */
497 if (g_ascii_isxdigit(temp))
499 dst_buf[j] = g_ascii_xdigit_value(temp) << 4;
501 else
503 return false;
506 /* Get the next nibble. */
507 temp = *(data_str++);
509 /* Process another nibble. */
510 if (g_ascii_isxdigit(temp))
512 dst_buf[j] |= g_ascii_xdigit_value(temp);
514 else
516 return false;
519 /* Get the next nibble. */
520 temp = *(data_str++);
523 j++;
524 } /* for */
526 /* If we get this far, then the key was good. */
527 return true;
530 static bool uat_sec_record_update_cb(void *r, char **err)
532 uat_security_record_t *rec = (uat_security_record_t *)r;
533 uint8_t sec_str[SEC_STR_LEN] = {0};
535 if (rec->sec_str == NULL)
537 *err = g_strdup("Data field can't be blank");
538 return false;
541 g_strstrip(rec->sec_str);
543 if (rf4ce_security_parse_sec_str(rec->sec_str, sec_str))
545 *err = NULL;
547 if (rec->type == RF4CE_SEC_STR_TYPE_NWK_KEY)
549 nwk_key_storage_add_entry(
550 sec_str,
551 NULL, /* controller addr */
552 NULL, /* target addr */
553 true, /* key from GUI */
554 false /* packet number */);
556 vendor_secret_storage_release_entry(sec_str);
558 else
560 vendor_secret_storage_add_entry(sec_str);
561 nwk_key_storage_release_entry(sec_str, true /* key from GUI */);
564 else
566 *err = ws_strdup_printf(
567 "Expecting %d hexadecimal bytes or a %d character double-quoted string", SEC_STR_LEN, SEC_STR_LEN);
568 return false;
571 return true;
574 static void uat_sec_record_free_cb(void *r)
576 uat_security_record_t *sec_record = (uat_security_record_t *)r;
577 uint8_t sec_str[SEC_STR_LEN];
579 if (rf4ce_security_parse_sec_str(sec_record->sec_str, sec_str))
581 if (sec_record->type == RF4CE_SEC_STR_TYPE_NWK_KEY)
583 nwk_key_storage_release_entry(sec_str, true /* key from GUI */);
585 else
587 vendor_secret_storage_release_entry(sec_str);
591 g_free(sec_record->sec_str);
592 g_free(sec_record->label);
595 static void uat_sec_record_post_update(void)
597 uint8_t sec_str[SEC_STR_LEN];
599 vendor_secret_storage_add_entry(DEFAULT_SECRET);
601 /* Load the pre-configured slist from the UAT. */
602 for (unsigned i = 0; (uat_security_records) && (i < num_uat_security_records); i++)
604 if (rf4ce_security_parse_sec_str(uat_security_records[i].sec_str, sec_str))
606 if (uat_security_records[i].type == RF4CE_SEC_STR_TYPE_NWK_KEY)
608 nwk_key_storage_add_entry(
609 sec_str,
610 NULL, /* controller addr */
611 NULL, /* target addr */
612 true, /* key from GUI */
613 false /* packet number */);
615 vendor_secret_storage_release_entry(sec_str);
617 else
619 vendor_secret_storage_add_entry(sec_str);
620 nwk_key_storage_release_entry(sec_str, true /* key from GUI */);
626 static bool dissect_rf4ce_nwk_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
628 unsigned reported_length = tvb_reported_length(tvb);
629 unsigned length = tvb_captured_length(tvb);
630 uint8_t fcf;
631 uint8_t frame_type;
632 uint8_t security_enabled;
633 uint8_t reserved;
634 uint8_t profile_id;
635 uint16_t vendor_id;
636 uint8_t command_id;
638 if (reported_length >= RF4CE_MIN_NWK_LENGTH && reported_length <= RF4CE_MAX_NWK_LENGTH)
640 if (length < RF4CE_MIN_NWK_LENGTH)
642 return false;
644 fcf = tvb_get_uint8(tvb, 0);
645 frame_type = fcf & RF4CE_NWK_FCF_FRAME_TYPE_MASK;
646 security_enabled = fcf & RF4CE_NWK_FCF_SECURITY_MASK;
647 reserved = (fcf & RF4CE_NWK_FCF_RESERVED_MASK) >> 5;
649 switch (frame_type)
651 case RF4CE_NWK_FCF_FRAME_TYPE_DATA:
652 case RF4CE_NWK_FCF_FRAME_TYPE_CMD:
653 case RF4CE_NWK_FCF_FRAME_TYPE_VENDOR_SPECIFIC:
654 /* Accepted frame types */
655 break;
657 default:
658 return false;
660 /* Reserved value must be 1 */
661 if (reserved != 1)
663 return false;
665 if((frame_type == RF4CE_NWK_FCF_FRAME_TYPE_DATA) || (frame_type == RF4CE_NWK_FCF_FRAME_TYPE_VENDOR_SPECIFIC))
667 if (length < 6)
669 return false;
671 profile_id = tvb_get_uint8(tvb, 5);
672 if ((profile_id >= 0x04) && (profile_id <= 0xbf))
674 return false;
676 if (frame_type == RF4CE_NWK_FCF_FRAME_TYPE_VENDOR_SPECIFIC)
678 if (length < 8)
680 return false;
682 vendor_id = tvb_get_letohs(tvb, 6);
683 switch (vendor_id)
685 case RF4CE_VENDOR_ID_PANASONIC:
686 case RF4CE_VENDOR_ID_SONY:
687 case RF4CE_VENDOR_ID_SAMSUNG:
688 case RF4CE_VENDOR_ID_PHILIPS:
689 case RF4CE_VENDOR_ID_FREESCALE:
690 case RF4CE_VENDOR_ID_OKI:
691 case RF4CE_VENDOR_ID_TEXAS_INSTRUMENTS:
692 case RF4CE_VENDOR_ID_TEST_1:
693 case RF4CE_VENDOR_ID_TEST_2:
694 case RF4CE_VENDOR_ID_TEST_3:
695 /* Allowed vendor IDs */
696 break;
698 default:
699 return false;
703 else if(frame_type == RF4CE_NWK_FCF_FRAME_TYPE_CMD)
705 if (length < 6)
707 return false;
709 /* If security is enabled, the command ID will be encrypted */
710 if (!security_enabled)
712 command_id = tvb_get_uint8(tvb, 5);
713 switch (command_id)
715 case RF4CE_NWK_CMD_DISCOVERY_REQ:
716 case RF4CE_NWK_CMD_DISCOVERY_RSP:
717 case RF4CE_NWK_CMD_PAIR_REQ:
718 case RF4CE_NWK_CMD_PAIR_RSP:
719 case RF4CE_NWK_CMD_UNPAIR_REQ:
720 case RF4CE_NWK_CMD_KEY_SEED:
721 case RF4CE_NWK_CMD_PING_REQ:
722 case RF4CE_NWK_CMD_PING_RSP:
723 /* Allowed command IDs */
724 break;
726 default:
727 return false;
731 col_set_str(pinfo->cinfo, COL_PROTOCOL, "RF4CE NWK");
732 col_clear(pinfo->cinfo, COL_INFO);
734 dissect_rf4ce_nwk_common(tvb, pinfo, tree, data);
736 return true;
738 return false;
741 static int dissect_rf4ce_nwk_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
743 unsigned offset = 0;
744 bool success;
745 uint8_t *decrypted = (uint8_t *)wmem_alloc(pinfo->pool, 512);
746 uint8_t src_addr[RF4CE_IEEE_ADDR_LEN] = {0};
747 uint8_t dst_addr[RF4CE_IEEE_ADDR_LEN] = {0};
749 uint8_t fcf = 0xff;
750 uint8_t frame_type = 0xff;
751 uint8_t profile_id = 0xff;
752 uint16_t size;
754 proto_item *ti = proto_tree_add_item(tree, proto_rf4ce_nwk, tvb, 0, -1, ENC_LITTLE_ENDIAN);
755 proto_tree *rf4ce_nwk_tree = proto_item_add_subtree(ti, ett_rf4ce_nwk);
757 static int *const nwk_fcf_bits[] = {
758 &hf_rf4ce_nwk_fcf_frame_type,
759 &hf_rf4ce_nwk_fcf_security_enabled,
760 &hf_rf4ce_nwk_fcf_protocol_version,
761 &hf_rf4ce_nwk_fcf_reserved,
762 &hf_rf4ce_nwk_fcf_channel_designator,
763 NULL};
765 proto_tree_add_bitmask(rf4ce_nwk_tree, tvb, offset, hf_rf4ce_nwk_fcf, ett_rf4ce_nwk, nwk_fcf_bits, ENC_LITTLE_ENDIAN);
766 fcf = tvb_get_uint8(tvb, offset);
767 offset += 1;
769 proto_tree_add_item(rf4ce_nwk_tree, hf_rf4ce_nwk_seq_num, tvb, offset, 4, ENC_LITTLE_ENDIAN);
770 offset += 4;
772 frame_type = fcf & RF4CE_NWK_FCF_FRAME_TYPE_MASK;
774 if (frame_type == RF4CE_NWK_FCF_FRAME_TYPE_DATA || frame_type == RF4CE_NWK_FCF_FRAME_TYPE_VENDOR_SPECIFIC)
776 proto_tree_add_item(rf4ce_nwk_tree, hf_rf4ce_nwk_profile_id, tvb, offset, 1, ENC_LITTLE_ENDIAN);
777 profile_id = tvb_get_uint8(tvb, offset);
778 offset += 1;
781 if (frame_type == RF4CE_NWK_FCF_FRAME_TYPE_VENDOR_SPECIFIC)
783 proto_tree_add_item(rf4ce_nwk_tree, hf_rf4ce_nwk_vendor_id, tvb, offset, 2, ENC_LITTLE_ENDIAN);
784 offset += 2;
787 rf4ce_addr_table_get_ieee_addr(src_addr, pinfo, true);
788 rf4ce_addr_table_get_ieee_addr(dst_addr, pinfo, false);
790 size = tvb_captured_length_remaining(tvb, 0);
792 if (fcf & RF4CE_NWK_FCF_SECURITY_MASK)
794 success = decrypt_data(
795 tvb_get_ptr(tvb, 0, size),
796 decrypted,
797 offset,
798 &size,
799 src_addr,
800 dst_addr);
802 else if (size > offset)
804 size -= offset;
805 tvb_memcpy(tvb, decrypted, offset, size);
806 success = true;
808 else
810 success = false;
813 if (success)
815 unsigned decrypted_offset = 0;
817 /* On decryption success: replace the tvb, make offset point to its beginning */
818 tvb = tvb_new_child_real_data(tvb, decrypted, size, size);
819 add_new_data_source(pinfo, tvb, "CCM* decrypted payload");
821 if (frame_type == RF4CE_NWK_FCF_FRAME_TYPE_CMD)
823 proto_tree *nwk_payload_tree = proto_tree_add_subtree(rf4ce_nwk_tree, tvb, decrypted_offset, tvb_captured_length(tvb) - decrypted_offset, ett_rf4ce_nwk_payload, NULL, "NWK Payload");
824 dissect_rf4ce_nwk_cmd(tvb, pinfo, nwk_payload_tree, &decrypted_offset);
826 else if (frame_type == RF4CE_NWK_FCF_FRAME_TYPE_DATA)
828 if (profile_id == RF4CE_NWK_PROFILE_ID_GDP)
830 decrypted_offset += call_dissector_with_data(rf4ce_gdp_handle, tvb, pinfo, tree, (void *)("GDP"));
832 else if (profile_id == RF4CE_NWK_PROFILE_ID_ZRC20)
834 decrypted_offset += call_dissector_with_data(rf4ce_gdp_handle, tvb, pinfo, tree, (void *)("ZRC 2.0"));
836 else if (profile_id == RF4CE_NWK_PROFILE_ID_ZRC10)
838 decrypted_offset += call_dissector_with_data(rf4ce_gdp_handle, tvb, pinfo, tree, (void *)("ZRC 1.0"));
842 offset += decrypted_offset;
844 else
846 /* On decryption error: make offset point to the end of original tvb */
847 offset = tvb_reported_length(tvb);
850 if (offset < tvb_captured_length(tvb))
852 unsigned unparsed_length = tvb_captured_length(tvb) - offset;
853 proto_tree_add_item(rf4ce_nwk_tree, hf_rf4ce_nwk_unparsed_payload, tvb, offset, unparsed_length, ENC_NA);
854 #if 0
855 /* enable this block if you need to add NWK MIC */
856 offset += unparsed_length;
857 #endif
860 #if 0
861 if (fcf & RF4CE_NWK_FCF_SECURITY_MASK)
863 proto_tree_add_item(rf4ce_nwk_tree, hf_rf4ce_nwk_mic, tvb, offset, 4, ENC_LITTLE_ENDIAN);
864 offset += 4;
866 #endif
868 return tvb_captured_length(tvb);
871 static void dissect_rf4ce_nwk_cmd(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int *offset)
873 int cmd_id = tvb_get_uint8(tvb, *offset);
875 proto_tree_add_item(tree, hf_rf4ce_nwk_cmd_id, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
876 *offset += 1;
878 col_set_str(pinfo->cinfo, COL_INFO, val_to_str_const(cmd_id, rf4ce_nwk_cmd_names, "Unknown Command"));
880 switch (cmd_id)
882 case RF4CE_NWK_CMD_DISCOVERY_REQ:
883 dissect_rf4ce_nwk_cmd_disc_req(tvb, tree, offset);
884 break;
886 case RF4CE_NWK_CMD_DISCOVERY_RSP:
887 dissect_rf4ce_nwk_cmd_disc_rsp(tvb, tree, offset);
888 break;
890 case RF4CE_NWK_CMD_PAIR_REQ:
891 dissect_rf4ce_nwk_cmd_pair_req(tvb, pinfo, tree, offset);
892 break;
894 case RF4CE_NWK_CMD_PAIR_RSP:
895 dissect_rf4ce_nwk_cmd_pair_rsp(tvb, pinfo, tree, offset);
896 break;
898 case RF4CE_NWK_CMD_UNPAIR_REQ:
899 break;
901 case RF4CE_NWK_CMD_KEY_SEED:
902 dissect_rf4ce_nwk_cmd_key_seed(tvb, tree, offset);
903 break;
905 case RF4CE_NWK_CMD_PING_REQ:
906 dissect_rf4ce_nwk_cmd_ping(tvb, tree, offset);
907 break;
909 case RF4CE_NWK_CMD_PING_RSP:
910 dissect_rf4ce_nwk_cmd_ping(tvb, tree, offset);
911 break;
915 static void dissect_rf4ce_nwk_common_node_capabilities(tvbuff_t *tvb, proto_tree *tree, int *offset)
917 static int *const nwk_node_capabilities_bits[] = {
918 &hf_rf4ce_nwk_node_capabilities_node_type,
919 &hf_rf4ce_nwk_node_capabilities_power_source,
920 &hf_rf4ce_nwk_node_capabilities_security,
921 &hf_rf4ce_nwk_node_capabilities_channel_normalization,
922 &hf_rf4ce_nwk_node_capabilities_reserved,
923 NULL};
925 proto_tree_add_bitmask(tree, tvb, *offset, hf_rf4ce_nwk_node_capabilities, ett_rf4ce_nwk, nwk_node_capabilities_bits, ENC_LITTLE_ENDIAN);
926 *offset += 1;
929 static void dissect_rf4ce_nwk_common_vendor_info(tvbuff_t *tvb, proto_tree *tree, int *offset)
931 proto_tree *vendor_info_tree = proto_tree_add_subtree(tree, tvb, *offset, tvb_captured_length(tvb) - *offset, ett_rf4ce_nwk_vendor_info, NULL, "Vendor Information Fields");
933 proto_tree_add_item(vendor_info_tree, hf_rf4ce_nwk_disc_req_vendor_id, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
934 *offset += 2;
936 proto_tree_add_item(vendor_info_tree, hf_rf4ce_nwk_vendor_string, tvb, *offset, RF4CE_NWK_VENDOR_STRING_MAX_LENGTH, ENC_UTF_8);
937 *offset += RF4CE_NWK_VENDOR_STRING_MAX_LENGTH;
940 static void dissect_rf4ce_nwk_common_app_capabilities(tvbuff_t *tvb, proto_tree *tree, int *offset, uint8_t parsing_mask)
942 int nwk_app_capabilities = 0;
943 int supported_devices_num = 0;
944 int supported_profiles_num = 0;
946 static int *const nwk_app_capabilities_bits[] = {
947 &hf_rf4ce_nwk_app_capabilities_usr_str,
948 &hf_rf4ce_nwk_app_capabilities_supported_dev_num,
949 &hf_rf4ce_nwk_app_capabilities_reserved1,
950 &hf_rf4ce_nwk_app_capabilities_supported_profiles_num,
951 &hf_rf4ce_nwk_app_capabilities_reserved2,
952 NULL};
954 proto_tree_add_bitmask(tree, tvb, *offset, hf_rf4ce_nwk_app_capabilities, ett_rf4ce_nwk, nwk_app_capabilities_bits, ENC_LITTLE_ENDIAN);
955 nwk_app_capabilities = tvb_get_uint8(tvb, *offset);
956 *offset += 1;
958 if (nwk_app_capabilities & RF4CE_NWK_USR_STR_SPECIFIED_MASK)
960 if (parsing_mask & RF4CE_NWK_USR_STR_PARSING_MASK_DISC_RESP)
962 proto_tree *usr_str_tree = proto_tree_add_subtree(tree, tvb, *offset, RF4CE_NWK_USR_STR_LENGTH, ett_rf4ce_nwk_usr_str, NULL, "Extra Status Information");
964 proto_tree_add_item(usr_str_tree, hf_rf4ce_nwk_usr_str_disc_rsp_app_usr_str, tvb, *offset, RF4CE_NWK_USR_STR_DISC_RSP_APP_USR_STR_LENGTH, ENC_UTF_8);
965 /* -1: to show the NULL-terminator byte in a tree */
966 *offset += RF4CE_NWK_USR_STR_DISC_RSP_APP_USR_STR_LENGTH - 1;
968 proto_tree_add_item(usr_str_tree, hf_rf4ce_nwk_usr_str_disc_rsp_null, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
969 *offset += 1;
971 proto_tree_add_item(usr_str_tree, hf_rf4ce_nwk_usr_str_disc_rsp_reserved, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
972 *offset += 2;
974 dissect_rf4ce_nwk_disc_resp_class_descriptor(tvb, usr_str_tree, offset, hf_rf4ce_nwk_usr_str_disc_rsp_class_desc_tertiary);
975 dissect_rf4ce_nwk_disc_resp_class_descriptor(tvb, usr_str_tree, offset, hf_rf4ce_nwk_usr_str_disc_rsp_class_desc_secondary);
976 dissect_rf4ce_nwk_disc_resp_class_descriptor(tvb, usr_str_tree, offset, hf_rf4ce_nwk_usr_str_disc_rsp_class_desc_primary);
978 proto_tree_add_item(usr_str_tree, hf_rf4ce_nwk_usr_str_disc_rsp_discovery_lqi_threshold, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
979 *offset += 1;
981 else
983 proto_tree_add_item(tree, hf_rf4ce_nwk_usr_str, tvb, *offset, RF4CE_NWK_USR_STR_LENGTH, ENC_NA);
984 *offset += RF4CE_NWK_USR_STR_LENGTH;
988 supported_devices_num = ((nwk_app_capabilities & RF4CE_NWK_SUPPORTED_DEV_NUM_MASK) >> RF4CE_NWK_SUPPORTED_DEV_NUM_OFFSET);
989 if (supported_devices_num > 0)
991 proto_tree *dev_type_tree = proto_tree_add_subtree(tree, tvb, *offset, supported_devices_num, ett_rf4ce_nwk_dev_types_list, NULL, "Device Type List");
993 for (int i = 0; i < supported_devices_num; i++)
995 proto_tree_add_item(dev_type_tree, hf_rf4ce_nwk_app_cap_dev_type, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
996 *offset += 1;
1000 supported_profiles_num = ((nwk_app_capabilities & RF4CE_NWK_SUPPORTED_PROFILES_NUM_MASK) >> RF4CE_NWK_SUPPORTED_PROFILES_NUM_OFFSET);
1001 if (supported_profiles_num > 0)
1003 proto_tree *profiles_tree = proto_tree_add_subtree(tree, tvb, *offset, supported_profiles_num, ett_rf4ce_nwk_profiles_list, NULL, "Profiles ID List");
1005 for (int i = 0; i < supported_profiles_num; i++)
1007 proto_tree_add_item(profiles_tree, hf_rf4ce_nwk_app_cap_profile_id, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
1008 *offset += 1;
1013 static void dissect_rf4ce_nwk_disc_resp_class_descriptor(tvbuff_t *tvb, proto_tree *tree, int *offset, int hf)
1015 static int *const class_num_bits[] = {
1016 &hf_rf4ce_nwk_usr_str_disc_rsp_class_desc_class_num,
1017 &hf_rf4ce_nwk_usr_str_disc_rsp_class_desc_duplicate_class_num_handling,
1018 &hf_rf4ce_nwk_usr_str_disc_rsp_class_desc_reserved,
1019 NULL};
1021 proto_tree_add_bitmask(tree, tvb, *offset, hf, ett_rf4ce_nwk_usr_str_class_descriptor, class_num_bits, ENC_LITTLE_ENDIAN);
1022 *offset += 1;
1025 static void dissect_rf4ce_nwk_cmd_disc_req(tvbuff_t *tvb, proto_tree *tree, int *offset)
1027 dissect_rf4ce_nwk_common_node_capabilities(tvb, tree, offset);
1028 dissect_rf4ce_nwk_common_vendor_info(tvb, tree, offset);
1029 dissect_rf4ce_nwk_common_app_capabilities(tvb, tree, offset, RF4CE_NWK_USR_STR_PARSING_MASK_NONE);
1031 proto_tree_add_item(tree, hf_rf4ce_nwk_requested_dev_type, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
1032 *offset += 1;
1035 static void dissect_rf4ce_nwk_cmd_disc_rsp(tvbuff_t *tvb, proto_tree *tree, int *offset)
1037 proto_tree_add_item(tree, hf_rf4ce_nwk_disc_resp_status, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
1038 *offset += 1;
1040 dissect_rf4ce_nwk_common_node_capabilities(tvb, tree, offset);
1041 dissect_rf4ce_nwk_common_vendor_info(tvb, tree, offset);
1042 dissect_rf4ce_nwk_common_app_capabilities(tvb, tree, offset, RF4CE_NWK_USR_STR_PARSING_MASK_DISC_RESP);
1044 proto_tree_add_item(tree, hf_rf4ce_nwk_disc_resp_lqi, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
1045 *offset += 1;
1048 static void dissect_rf4ce_nwk_cmd_pair_req(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int *offset)
1050 uint8_t expected_transfer_count;
1052 proto_tree_add_item(tree, hf_rf4ce_nwk_pair_req_nwk_addr, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
1053 *offset += 2;
1055 dissect_rf4ce_nwk_common_node_capabilities(tvb, tree, offset);
1056 dissect_rf4ce_nwk_common_vendor_info(tvb, tree, offset);
1057 dissect_rf4ce_nwk_common_app_capabilities(tvb, tree, offset, RF4CE_NWK_USR_STR_PARSING_MASK_NONE);
1059 proto_tree_add_item(tree, hf_rf4ce_nwk_pair_req_key_exch_num, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
1061 expected_transfer_count = tvb_get_uint8(tvb, *offset) + 1;
1062 keypair_context_init((const uint8_t *)pinfo->dl_src.data, (const uint8_t *)pinfo->dl_dst.data, expected_transfer_count);
1063 *offset += 1;
1066 static void dissect_rf4ce_nwk_cmd_pair_rsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int *offset)
1068 uint16_t allocated_nwk_addr;
1069 uint16_t nwk_addr;
1071 proto_tree_add_item(tree, hf_rf4ce_nwk_pair_rsp_status, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
1072 *offset += 1;
1074 proto_tree_add_item(tree, hf_rf4ce_nwk_pair_rsp_allocated_nwk_addr, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
1075 allocated_nwk_addr = tvb_get_uint16(tvb, *offset, ENC_LITTLE_ENDIAN);
1076 *offset += 2;
1078 proto_tree_add_item(tree, hf_rf4ce_nwk_pair_rsp_nwk_addr, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
1079 nwk_addr = tvb_get_uint16(tvb, *offset, ENC_LITTLE_ENDIAN);
1080 *offset += 2;
1082 dissect_rf4ce_nwk_common_node_capabilities(tvb, tree, offset);
1083 dissect_rf4ce_nwk_common_vendor_info(tvb, tree, offset);
1084 dissect_rf4ce_nwk_common_app_capabilities(tvb, tree, offset, RF4CE_NWK_USR_STR_PARSING_MASK_NONE);
1086 rf4ce_addr_table_add_addrs(pinfo->dl_dst.data, allocated_nwk_addr);
1087 rf4ce_addr_table_add_addrs(pinfo->dl_src.data, nwk_addr);
1090 static void dissect_rf4ce_nwk_cmd_key_seed(tvbuff_t *tvb, proto_tree *tree, int *offset)
1092 uint8_t seed_data[RF4CE_NWK_KEY_SEED_DATA_LENGTH] = {0};
1093 uint8_t seed_seq_num = 0;
1095 proto_tree_add_item(tree, hf_rf4ce_nwk_seed_seq_num, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
1096 seed_seq_num = tvb_get_uint8(tvb, *offset);
1097 *offset += 1;
1099 proto_tree_add_item(tree, hf_rf4ce_nwk_seed_data, tvb, *offset, RF4CE_NWK_KEY_SEED_DATA_LENGTH, ENC_NA);
1100 tvb_memcpy(tvb, (void *)seed_data, *offset, RF4CE_NWK_KEY_SEED_DATA_LENGTH);
1101 *offset += RF4CE_NWK_KEY_SEED_DATA_LENGTH;
1103 keypair_context_update_seed(seed_data, seed_seq_num);
1106 static void dissect_rf4ce_nwk_cmd_ping(tvbuff_t *tvb, proto_tree *tree, int *offset)
1108 proto_tree_add_item(tree, hf_rf4ce_nwk_ping_options, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
1109 *offset += 1;
1111 proto_tree_add_item(tree, hf_rf4ce_nwk_ping_payload, tvb, *offset, 4, ENC_LITTLE_ENDIAN);
1112 *offset += 4;
1115 void proto_register_rf4ce_nwk(void)
1117 static hf_register_info hf[] = {
1118 {&hf_rf4ce_nwk_fcf,
1119 {"Frame Control Field", "rf4ce-nwk.fcf",
1120 FT_UINT8, BASE_HEX,
1121 NULL, 0x00,
1122 NULL, HFILL}},
1123 {&hf_rf4ce_nwk_fcf_frame_type,
1124 {"Frame Type", "rf4ce-nwk.fcf.frame_type",
1125 FT_UINT8, BASE_HEX,
1126 VALS(rf4ce_nwk_frame_types), RF4CE_NWK_FCF_FRAME_TYPE_MASK,
1127 NULL, HFILL}},
1128 {&hf_rf4ce_nwk_fcf_security_enabled,
1129 {"Security enabled", "rf4ce-nwk.fcf.security_enabled",
1130 FT_BOOLEAN, 8,
1131 TFS(&tfs_yes_no), RF4CE_NWK_FCF_SECURITY_MASK,
1132 NULL, HFILL}},
1133 {&hf_rf4ce_nwk_fcf_protocol_version,
1134 {"Protocol version", "rf4ce-nwk.fcf.protocol_version",
1135 FT_UINT8, BASE_HEX,
1136 NULL, RF4CE_NWK_FCF_PROTOCOL_VERSION_MASK,
1137 NULL, HFILL}},
1138 {&hf_rf4ce_nwk_fcf_reserved,
1139 {"Reserved", "rf4ce-nwk.fcf.reserved",
1140 FT_UINT8, BASE_HEX,
1141 NULL, RF4CE_NWK_FCF_RESERVED_MASK,
1142 NULL, HFILL}},
1143 {&hf_rf4ce_nwk_fcf_channel_designator,
1144 {"Channel designator", "rf4ce-nwk.fcf.channel_designator",
1145 FT_UINT8, BASE_HEX,
1146 VALS(rf4ce_nwk_channel_designators), RF4CE_NWK_FCF_CHANNEL_DESIGNATOR_MASK,
1147 NULL, HFILL}},
1148 {&hf_rf4ce_nwk_seq_num,
1149 {"Sequence number", "rf4ce-nwk.seqn",
1150 FT_UINT32, BASE_DEC,
1151 NULL, 0x0,
1152 NULL, HFILL}},
1153 {&hf_rf4ce_nwk_profile_id,
1154 {"Profile ID", "rf4ce-nwk.profile_id",
1155 FT_UINT8, BASE_HEX,
1156 VALS(rf4ce_nwk_profile_ids), 0x0,
1157 NULL, HFILL}},
1158 {&hf_rf4ce_nwk_vendor_id,
1159 {"Vendor ID", "rf4ce-nwk.vendor_id",
1160 FT_UINT16, BASE_HEX,
1161 NULL, 0x0,
1162 NULL, HFILL}},
1163 {&hf_rf4ce_nwk_cmd_id,
1164 {"Command ID", "rf4ce-nwk.cmd_id",
1165 FT_UINT8, BASE_HEX,
1166 VALS(rf4ce_nwk_cmd_names), 0x0,
1167 NULL, HFILL}},
1168 {&hf_rf4ce_nwk_node_capabilities,
1169 {"Node Capabilities", "rf4ce-nwk.node_capabilities",
1170 FT_UINT8, BASE_HEX,
1171 NULL, 0x0,
1172 NULL, HFILL}},
1173 {&hf_rf4ce_nwk_node_capabilities_node_type,
1174 {"Node Type", "rf4ce-nwk.node_capabilities.node_type",
1175 FT_UINT8, BASE_HEX,
1176 VALS(rf4ce_nwk_node_types), RF4CE_NWK_NODE_TYPE_MASK,
1177 NULL, HFILL}},
1178 {&hf_rf4ce_nwk_node_capabilities_power_source,
1179 {"Power Source", "rf4ce-nwk.node_capabilities.power_source",
1180 FT_UINT8, BASE_HEX,
1181 VALS(rf4ce_nwk_power_sources), RF4CE_NWK_POWER_SOURCE_MASK,
1182 NULL, HFILL}},
1183 {&hf_rf4ce_nwk_node_capabilities_security,
1184 {"Security Capable", "rf4ce-nwk.node_capabilities.security",
1185 FT_BOOLEAN, 8,
1186 TFS(&tfs_yes_no), RF4CE_NWK_SECURITY_MASK,
1187 NULL, HFILL}},
1188 {&hf_rf4ce_nwk_node_capabilities_channel_normalization,
1189 {"Channel Normalization", "rf4ce-nwk.node_capabilities.channel_normalization",
1190 FT_BOOLEAN, 8,
1191 TFS(&tfs_yes_no), RF4CE_NWK_CHANNEL_NORMALIZATION_MASK,
1192 NULL, HFILL}},
1193 {&hf_rf4ce_nwk_node_capabilities_reserved,
1194 {"Reserved", "rf4ce-nwk.node_capabilities.reserved",
1195 FT_UINT8, BASE_HEX,
1196 NULL, RF4CE_NWK_RESERVED_MASK,
1197 NULL, HFILL}},
1198 {&hf_rf4ce_nwk_disc_req_vendor_id,
1199 {"Vendor ID", "rf4ce-nwk.disc_req.vendor_id",
1200 FT_UINT16, BASE_HEX,
1201 VALS(rf4ce_disc_req_vendor_ids), 0x0,
1202 NULL, HFILL}},
1203 {&hf_rf4ce_nwk_vendor_string,
1204 {"Vendor String", "rf4ce-nwk.disc_req.vendor_str",
1205 FT_STRING, BASE_NONE,
1206 NULL, 0x0,
1207 NULL, HFILL}},
1208 {&hf_rf4ce_nwk_app_capabilities,
1209 {"App Capabilities", "rf4ce-nwk.app_capabilities",
1210 FT_UINT8, BASE_HEX,
1211 NULL, 0x0,
1212 NULL, HFILL}},
1213 {&hf_rf4ce_nwk_app_capabilities_usr_str,
1214 {"User String Specified", "rf4ce-nwk.app_capabilities.usr_str",
1215 FT_BOOLEAN, 8,
1216 TFS(&tfs_yes_no), RF4CE_NWK_USR_STR_SPECIFIED_MASK,
1217 NULL, HFILL}},
1218 {&hf_rf4ce_nwk_app_capabilities_supported_dev_num,
1219 {"Number of Supported Device Types", "rf4ce-nwk.app_capabilities.supported_dev_num",
1220 FT_UINT8, BASE_DEC,
1221 NULL, RF4CE_NWK_SUPPORTED_DEV_NUM_MASK,
1222 NULL, HFILL}},
1223 {&hf_rf4ce_nwk_app_capabilities_reserved1,
1224 {"Reserved", "rf4ce-nwk.app_capabilities.reserved1",
1225 FT_UINT8, BASE_HEX,
1226 NULL, RF4CE_NWK_RESERVED1_MASK,
1227 NULL, HFILL}},
1228 {&hf_rf4ce_nwk_app_capabilities_supported_profiles_num,
1229 {"Number of Supported Profiles", "rf4ce-nwk.app_capabilities.supported_profiles_num",
1230 FT_UINT8, BASE_DEC,
1231 NULL, RF4CE_NWK_SUPPORTED_PROFILES_NUM_MASK,
1232 NULL, HFILL}},
1233 {&hf_rf4ce_nwk_app_capabilities_reserved2,
1234 {"Reserved", "rf4ce-nwk.app_capabilities.reserved2",
1235 FT_UINT8, BASE_HEX,
1236 NULL, RF4CE_NWK_RESERVED2_MASK,
1237 NULL, HFILL}},
1238 {&hf_rf4ce_nwk_usr_str,
1239 {"User String", "rf4ce-nwk.usr_str",
1240 FT_BYTES, BASE_NONE,
1241 NULL, 0x0,
1242 NULL, HFILL}},
1243 {&hf_rf4ce_nwk_usr_str_disc_rsp_app_usr_str,
1244 {"App Specific User String", "rf4ce-nwk.usr_str.disc_rsp.app_usr_str",
1245 FT_STRING, BASE_NONE,
1246 NULL, 0x0,
1247 NULL, HFILL}},
1248 {&hf_rf4ce_nwk_usr_str_disc_rsp_null,
1249 {"NULL-terminator", "rf4ce-nwk.usr_str.disc_rsp.null",
1250 FT_UINT8, BASE_HEX,
1251 NULL, 0x0,
1252 NULL, HFILL}},
1253 {&hf_rf4ce_nwk_usr_str_disc_rsp_reserved,
1254 {"Reserved", "rf4ce-nwk.usr_str.disc_rsp.reserved",
1255 FT_UINT16, BASE_HEX,
1256 NULL, 0x0,
1257 NULL, HFILL}},
1258 {&hf_rf4ce_nwk_usr_str_disc_rsp_class_desc_tertiary,
1259 {"Tertiary Class Descriptor", "rf4ce-nwk.usr_str.disc_rsp.class_descriptor.tertiary",
1260 FT_UINT8, BASE_HEX,
1261 NULL, 0x0,
1262 NULL, HFILL}},
1263 {&hf_rf4ce_nwk_usr_str_disc_rsp_class_desc_secondary,
1264 {"Secondary Class Descriptor", "rf4ce-nwk.usr_str.disc_rsp.class_descriptor.secondary",
1265 FT_UINT8, BASE_HEX,
1266 NULL, 0x0,
1267 NULL, HFILL}},
1268 {&hf_rf4ce_nwk_usr_str_disc_rsp_class_desc_primary,
1269 {"Primary Class Descriptor", "rf4ce-nwk.usr_str.disc_rsp.class_descriptor.primary",
1270 FT_UINT8, BASE_HEX,
1271 NULL, 0x0,
1272 NULL, HFILL}},
1273 {&hf_rf4ce_nwk_usr_str_disc_rsp_class_desc_class_num,
1274 {"Class Number", "rf4ce-nwk.usr_str.disc_rsp.class_descriptor.class_number",
1275 FT_UINT8, BASE_HEX,
1276 VALS(rf4ce_nwk_usr_str_disc_rsp_class_desc_class_num_vals), RF4CE_NWK_USR_STR_DISC_RSP_CLASS_DESC_CLASS_NUM_MASK,
1277 NULL, HFILL}},
1278 {&hf_rf4ce_nwk_usr_str_disc_rsp_class_desc_duplicate_class_num_handling,
1279 {"Duplicate Class Number Handling", "rf4ce-nwk.usr_str.disc_rsp.class_descriptor.duplicate_class_num_handling",
1280 FT_UINT8, BASE_HEX,
1281 VALS(rf4ce_nwk_usr_str_disc_rsp_class_desc_duplicate_class_num_handling_vals), RF4CE_NWK_USR_STR_DISC_RSP_CLASS_DESC_DUPLICATE_CLASS_NUM_HANDLING_MASK,
1282 NULL, HFILL}},
1283 {&hf_rf4ce_nwk_usr_str_disc_rsp_class_desc_reserved,
1284 {"Reserved", "rf4ce-nwk.usr_str.disc_rsp.class_descriptor.reserved",
1285 FT_UINT8, BASE_HEX,
1286 NULL, RF4CE_NWK_USR_STR_DISC_RSP_CLASS_DESC_RESERVED_MASK,
1287 NULL, HFILL}},
1288 {&hf_rf4ce_nwk_usr_str_disc_rsp_discovery_lqi_threshold,
1289 {"Discovery LQI Threshold", "rf4ce-nwk.usr_str.disc_rsp.discovery_lqi_threshold",
1290 FT_INT8, BASE_DEC,
1291 NULL, 0x0,
1292 NULL, HFILL}},
1293 {&hf_rf4ce_nwk_app_cap_dev_type,
1294 {"Device Type", "rf4ce-nwk.app_cap.dev_type",
1295 FT_UINT8, BASE_HEX,
1296 NULL, 0x0,
1297 NULL, HFILL}},
1298 {&hf_rf4ce_nwk_app_cap_profile_id,
1299 {"Profile ID", "rf4ce-nwk.app_cap.profile_id",
1300 FT_UINT8, BASE_HEX,
1301 NULL, 0x0,
1302 NULL, HFILL}},
1303 {&hf_rf4ce_nwk_requested_dev_type,
1304 {"Requested Device Type", "rf4ce-nwk.requested_dev_type",
1305 FT_UINT8, BASE_HEX,
1306 VALS(rf4ce_nwk_device_type_vals), 0x0,
1307 NULL, HFILL}},
1308 {&hf_rf4ce_nwk_disc_resp_status,
1309 {"Status", "rf4ce-nwk.disc_resp.status",
1310 FT_UINT8, BASE_HEX,
1311 VALS(rf4ce_nwk_disc_status_vals), 0x0,
1312 NULL, HFILL}},
1313 {&hf_rf4ce_nwk_disc_resp_lqi,
1314 {"Discovery Request LQI", "rf4ce-nwk.disc_resp.lqi",
1315 FT_INT8, BASE_DEC,
1316 NULL, 0x0,
1317 NULL, HFILL}},
1318 {&hf_rf4ce_nwk_pair_req_nwk_addr,
1319 {"Network Address", "rf4ce-nwk.pair_req.nwk_addr",
1320 FT_UINT16, BASE_HEX,
1321 NULL, 0x0,
1322 NULL, HFILL}},
1323 {&hf_rf4ce_nwk_pair_req_key_exch_num,
1324 {"Key Exchange Transfer Count", "rf4ce-nwk.pair_req.key_exch_num",
1325 FT_INT8, BASE_DEC,
1326 NULL, 0x0,
1327 NULL, HFILL}},
1328 {&hf_rf4ce_nwk_pair_rsp_status,
1329 {"Status", "rf4ce-nwk.pair_rsp.status",
1330 FT_UINT8, BASE_HEX,
1331 VALS(rf4ce_nwk_disc_status_vals), 0x0,
1332 NULL, HFILL}},
1333 {&hf_rf4ce_nwk_pair_rsp_allocated_nwk_addr,
1334 {"Allocated Network Address", "rf4ce-nwk.pair_rsp.allocated_nwk_addr",
1335 FT_UINT16, BASE_HEX,
1336 NULL, 0x0,
1337 NULL, HFILL}},
1338 {&hf_rf4ce_nwk_pair_rsp_nwk_addr,
1339 {"Network Address", "rf4ce-nwk.pair_rsp.nwk_addr",
1340 FT_UINT16, BASE_HEX,
1341 NULL, 0x0,
1342 NULL, HFILL}},
1343 {&hf_rf4ce_nwk_seed_seq_num,
1344 {"Seed Sequence Number", "rf4ce-nwk.key_seed.seed_seq_num",
1345 FT_INT8, BASE_DEC,
1346 NULL, 0x0,
1347 NULL, HFILL}},
1348 {&hf_rf4ce_nwk_seed_data,
1349 {"Seed Data", "rf4ce-nwk.key_seed.seed_data",
1350 FT_BYTES, SEP_COLON,
1351 NULL, 0x0,
1352 NULL, HFILL}},
1353 {&hf_rf4ce_nwk_ping_options,
1354 {"Ping Options", "rf4ce-nwk.ping_options",
1355 FT_UINT8, BASE_HEX,
1356 NULL, 0x0,
1357 NULL, HFILL}},
1358 {&hf_rf4ce_nwk_ping_payload,
1359 {"Ping Payload", "rf4ce-nwk.ping_payload",
1360 FT_UINT32, BASE_HEX,
1361 NULL, 0x0,
1362 NULL, HFILL}},
1363 #if 0
1364 {&hf_rf4ce_nwk_mic,
1365 {"Ping Payload", "rf4ce-nwk.mic",
1366 FT_UINT32, BASE_HEX,
1367 NULL, 0x0,
1368 NULL, HFILL}},
1369 #endif
1370 {&hf_rf4ce_nwk_unparsed_payload,
1371 {"Unparsed Payload", "rf4ce-nwk.unparsed_payload",
1372 FT_BYTES, SEP_COLON,
1373 NULL, 0x0,
1374 NULL, HFILL}},
1377 /* Setup protocol subtree array */
1378 static int *ett[] = {
1379 &ett_rf4ce_nwk,
1380 &ett_rf4ce_nwk_payload,
1381 &ett_rf4ce_nwk_vendor_info,
1382 &ett_rf4ce_nwk_usr_str,
1383 &ett_rf4ce_nwk_usr_str_class_descriptor,
1384 &ett_rf4ce_nwk_dev_types_list,
1385 &ett_rf4ce_nwk_profiles_list,
1388 proto_rf4ce_nwk = proto_register_protocol("RF4CE Network Layer", "RF4CE", RF4CE_PROTOABBREV_NWK);
1389 proto_register_field_array(proto_rf4ce_nwk, hf, array_length(hf));
1390 proto_register_subtree_array(ett, array_length(ett));
1392 register_cleanup_routine(rf4ce_cleanup);
1394 register_dissector(RF4CE_PROTOABBREV_NWK, dissect_rf4ce_nwk_common, proto_rf4ce_nwk);
1396 static uat_field_t key_uat_fields[] =
1398 UAT_FLD_CSTRING(uat_security_records, sec_str, "Byte sequence",
1399 "In case of NWK key type it is a 16-byte key in hexadecimal with optional dash-,\n"
1400 "colon-, or space-separator characters, or \n"
1401 "a 16-character string in double-quotes.\n"
1402 "In case of Vendor Secret type it is a secret byte sequence\n"
1403 "to calculate NWK keys during Key Exchange procedure."),
1404 UAT_FLD_VS(uat_security_records, type, "Type", sec_str_type_vals, "Type of a security string."),
1405 UAT_FLD_CSTRING(uat_security_records, label, "Label", "User label for a security string."),
1406 UAT_END_FIELDS};
1408 rf4ce_security_table_uat =
1409 uat_new("Pre-configured security table",
1410 sizeof(uat_security_record_t),
1411 "rf4ce_pc_sec",
1412 true,
1413 &uat_security_records,
1414 &num_uat_security_records,
1415 UAT_AFFECTS_DISSECTION, /* affects dissection of packets, but not set of named fields */
1416 NULL, /* TODO: ptr to help manual? */
1417 uat_sec_record_copy_cb,
1418 uat_sec_record_update_cb,
1419 uat_sec_record_free_cb,
1420 uat_sec_record_post_update,
1421 NULL,
1422 key_uat_fields);
1424 module_t *rf4ce_prefs = prefs_register_protocol(proto_rf4ce_nwk, NULL);
1426 prefs_register_uat_preference(
1427 rf4ce_prefs,
1428 "security_table",
1429 "Pre-configured security strings",
1430 "Pre-configured vendor secrets or network keys.",
1431 rf4ce_security_table_uat);
1434 void proto_reg_handoff_rf4ce_nwk(void)
1436 rf4ce_gdp_handle = find_dissector_add_dependency(RF4CE_PROTOABBREV_PROFILE, proto_rf4ce_nwk);
1438 /* create_dissector_handle(dissect_rf4ce_nwk_common, proto_rf4ce_nwk); */
1439 dissector_add_for_decode_as(IEEE802154_PROTOABBREV_WPAN_PANID, find_dissector(RF4CE_PROTOABBREV_NWK));
1440 heur_dissector_add(IEEE802154_PROTOABBREV_WPAN, dissect_rf4ce_nwk_heur, "Radio Frequency for Consumer Electronics over IEEE 802.15.4", RF4CE_PROTOABBREV_NWK, proto_rf4ce_nwk, HEURISTIC_ENABLE);