2 * Routines for MLE packet dissection
4 * Colin O'Flynn <coflynn@newae.com>
6 * The entire security section of this is lifted from the IEEE 802.15.4
7 * dissectory, as this is done the same way. Should eventually make the
8 * two use some common functions or something. But that section is:
9 * By Owen Kirby <osk@exegin.com>
10 * Copyright 2007 Exegin Technologies Limited
12 * Thread parts added by Robert Cragie <robert.cragie@arm.com>
14 * Wireshark - Network traffic analyzer
15 * By Gerald Combs <gerald@wireshark.org>
16 * Copyright 1998 Gerald Combs
18 * SPDX-License-Identifier: GPL-2.0-or-later
24 #include <epan/packet.h>
26 #include <epan/proto_data.h>
27 #include <epan/wmem_scopes.h>
28 #include <epan/expert.h>
29 #include <epan/prefs.h>
31 #include <wsutil/array.h>
32 #include "packet-ieee802154.h"
33 #include "packet-mle.h"
35 #define MLE_32768_TO_NSEC_FACTOR ((double)30517.578125)
37 /* Forward declarations */
38 void proto_register_mle(void);
39 void proto_reg_handoff_mle(void);
42 static int proto_ieee802154
; /* cache 802.15.4 protocol ID */
44 /* Registered fields for Auxiliary Security Header */
45 static int hf_mle_security_suite
;
46 static int hf_mle_mic
;
48 static int hf_mle_command
;
49 static int hf_mle_tlv
;
50 static int hf_mle_tlv_type
;
51 static int hf_mle_tlv_length
;
52 static int hf_mle_tlv_source_addr
;
53 static int hf_mle_tlv_mode_device_type
;
54 static int hf_mle_tlv_mode_idle_rx
;
55 static int hf_mle_tlv_mode_sec_data_req
;
56 static int hf_mle_tlv_mode_receiver_on_idle
;
57 static int hf_mle_tlv_mode_reserved1
;
58 static int hf_mle_tlv_mode_reserved2
;
59 static int hf_mle_tlv_mode_device_type_bit
;
60 static int hf_mle_tlv_mode_network_data
;
61 static int hf_mle_tlv_mode_nwk_data
;
62 static int hf_mle_tlv_timeout
;
63 static int hf_mle_tlv_challenge
;
64 static int hf_mle_tlv_response
;
65 static int hf_mle_tlv_ll_frm_cntr
;
66 static int hf_mle_tlv_lqi_c
;
67 static int hf_mle_tlv_lqi_size
;
68 static int hf_mle_tlv_neighbor
;
69 static int hf_mle_tlv_neighbor_flagI
;
70 static int hf_mle_tlv_neighbor_flagO
;
71 static int hf_mle_tlv_neighbor_flagP
;
72 static int hf_mle_tlv_neighbor_idr
;
73 static int hf_mle_tlv_neighbor_addr
;
74 static int hf_mle_tlv_network_param_id
;
75 static int hf_mle_tlv_network_delay
;
76 static int hf_mle_tlv_network_channel
;
77 static int hf_mle_tlv_network_pan_id
;
78 static int hf_mle_tlv_network_pmt_join
;
79 static int hf_mle_tlv_network_bcn_payload
;
80 static int hf_mle_tlv_network_unknown
;
81 static int hf_mle_tlv_mle_frm_cntr
;
82 static int hf_mle_tlv_unknown
;
83 static int hf_mle_tlv_route64_id_seq
;
84 static int hf_mle_tlv_route64_id_mask
;
85 static int hf_mle_tlv_route64_entry
;
86 static int hf_mle_tlv_route64_nbr_out
;
87 static int hf_mle_tlv_route64_nbr_in
;
88 static int hf_mle_tlv_route64_cost
;
90 static int hf_mle_tlv_route64_unknown
;
92 static int hf_mle_tlv_addr16
;
93 static int hf_mle_tlv_leader_data_partition_id
;
94 static int hf_mle_tlv_leader_data_weighting
;
95 static int hf_mle_tlv_leader_data_version
;
96 static int hf_mle_tlv_leader_data_stable_version
;
97 static int hf_mle_tlv_leader_data_router_id
;
99 static int hf_mle_tlv_network_data
;
101 static int hf_mle_tlv_scan_mask_r
;
102 static int hf_mle_tlv_scan_mask_e
;
103 static int hf_mle_tlv_conn_flags
;
104 static int hf_mle_tlv_conn_flags_pp
;
105 static int hf_mle_tlv_conn_lq3
;
106 static int hf_mle_tlv_conn_lq2
;
107 static int hf_mle_tlv_conn_lq1
;
108 static int hf_mle_tlv_conn_leader_cost
;
109 static int hf_mle_tlv_conn_id_seq
;
110 static int hf_mle_tlv_conn_active_rtrs
;
111 static int hf_mle_tlv_conn_sed_buf_size
;
112 static int hf_mle_tlv_conn_sed_dgram_cnt
;
113 static int hf_mle_tlv_link_margin
;
114 static int hf_mle_tlv_status
;
115 static int hf_mle_tlv_version
;
116 static int hf_mle_tlv_addr_reg_entry
;
117 static int hf_mle_tlv_addr_reg_iid_type
;
118 static int hf_mle_tlv_addr_reg_cid
;
119 static int hf_mle_tlv_addr_reg_iid
;
120 static int hf_mle_tlv_addr_reg_ipv6
;
122 static int hf_mle_tlv_hold_time
;
124 static int hf_mle_tlv_channel_page
; /* v1.1-draft-2 */
125 static int hf_mle_tlv_channel
; /* v1.1-draft-2 */
126 static int hf_mle_tlv_csl_accuracy
; /* v1.2-draft-5 */
127 static int hf_mle_tlv_csl_synchronied_timeout
; /* v1.2-draft-5 */
128 static int hf_mle_tlv_csl_clock_accuracy
; /* v1.2-draft-5 */
129 static int hf_mle_tlv_csl_uncertainty
;
130 static int hf_mle_tlv_pan_id
; /* v1.1-draft-2 */
131 static int hf_mle_tlv_active_tstamp
; /* SPEC-472 */
132 static int hf_mle_tlv_pending_tstamp
; /* SPEC-472 */
133 static int hf_mle_tlv_supervision_interval
;
135 static int hf_mle_tlv_active_op_dataset
; /* SPEC-472 */
136 static int hf_mle_tlv_pending_op_dataset
; /* SPEC-472 */
139 //Added for Thread 1.2 support
141 static int hf_mle_tlv_metric_type_id_flags
;
142 static int hf_mle_tlv_metric_type_id_flags_l
;
143 static int hf_mle_tlv_metric_type_id_flags_e
;
144 static int hf_mle_tlv_metric_type_id_flags_type
;
145 static int hf_mle_tlv_metric_type_id_flags_metric
;
146 static int hf_mle_tlv_value
;
147 static int hf_mle_tlv_query_id
;
148 static int hf_mle_tlv_link_sub_tlv
;
149 static int hf_mle_tlv_link_status
;
150 static int hf_mle_tlv_link_status_sub_tlv
;
153 static int hf_mle_tlv_link_query_options
;
154 static int hf_mle_tlv_link_enh_ack_flags
;
155 static int hf_mle_tlv_link_requested_type_id_flags
;
156 static int hf_mle_tlv_csl_sychronized_timeout
;
157 static int hf_mle_tlv_link_forward_series
;
158 static int hf_mle_tlv_link_concatenation_link_metric_typeid_flags
;
159 static int hf_mle_tlv_link_timeout
;
160 static int hf_mle_tlv_link_forward_series_flags
;
163 /* End of New support */
167 static int ett_mle_tlv
;
168 static int ett_mle_neighbor
;
169 static int ett_mle_router
;
170 static int ett_mle_addr_reg
;
171 static int ett_mle_conn_flg
;
172 static int ett_mle_thread_nwd
;
173 static int ett_mle_auxiliary_security
;
174 static int ett_mle_aux_sec_control
;
175 static int ett_mle_aux_sec_key_id
;
177 static expert_field ei_mle_cbc_mac_failed
;
178 static expert_field ei_mle_packet_too_small
;
179 static expert_field ei_mle_no_key
;
180 static expert_field ei_mle_decrypt_failed
;
181 static expert_field ei_mle_mic_check_failed
;
182 static expert_field ei_mle_tlv_length_failed
;
183 static expert_field ei_mle_len_size_mismatch
;
185 static dissector_handle_t mle_handle
;
186 static dissector_handle_t thread_nwd_handle
;
187 static dissector_handle_t thread_mc_handle
;
189 #define UDP_PORT_MLE_RANGE "19788" /* IANA registered */
191 /* boolean value set if the MIC must be ok before payload is dissected */
192 static bool mle_mic_ok
;
194 static wmem_tree_t
* mle_key_hash_handlers
;
196 static const value_string mle_sec_suite_names
[] = {
197 { 0, "802.15.4 Security" },
198 { 255, "No Security" },
202 static const value_string mle_status_tlv_enums
[] = {
204 { 2, "Duplicate Address Detected" },
208 static const value_string mle_conn_tlv_flags_pp_enums
[] = {
215 #define MLE_CMD_REQUEST 0
216 #define MLE_CMD_ACCEPT 1
217 #define MLE_CMD_ACCEPTREQ 2
218 #define MLE_CMD_REJECT 3
219 #define MLE_CMD_ADVERTISE 4
220 #define MLE_CMD_UPDATE 5
221 #define MLE_CMD_UPDATE_REQUEST 6
222 #define MLE_CMD_DATA_REQUEST 7
223 #define MLE_CMD_DATA_RESPONSE 8
224 #define MLE_CMD_PARENT_REQUEST 9
225 #define MLE_CMD_PARENT_RESPONSE 10
226 #define MLE_CMD_CHILD_ID_REQUEST 11
227 #define MLE_CMD_CHILD_ID_RESPONSE 12
228 #define MLE_CMD_CHILD_UPDATE_REQUEST 13
229 #define MLE_CMD_CHILD_UPDATE_RESPONSE 14
230 #define MLE_CMD_ANNOUNCE 15
231 #define MLE_CMD_DISCOVERY_REQUEST 16
232 #define MLE_CMD_DISCOVERY_RESPONSE 17
234 //Added new for Thread 1.2
235 #define MLE_CMD_LINK_METRICS_MANAGEMENT_REQUEST 18
236 #define MLE_CMD_LINK_METRICS_MANAGEMENT_RESPONSE 19
237 #define MLE_CMD_LINK_PROBE 20
238 #define MLE_CMD_CIM_DISCOVERY_REQUEST 21
239 #define MLE_CMD_CIM_DISCOVERY_RESPONSE 22
240 #define MLE_CMD_CIM_ANNOUNCE 23
242 static const value_string mle_command_vals
[] = {
243 { MLE_CMD_REQUEST
, "Link Request" },
244 { MLE_CMD_ACCEPT
, "Link Accept" },
245 { MLE_CMD_ACCEPTREQ
, "Link Accept and Request" },
246 { MLE_CMD_REJECT
, "Link Reject" },
247 { MLE_CMD_ADVERTISE
, "Advertisement" },
248 { MLE_CMD_UPDATE
, "Update" },
249 { MLE_CMD_UPDATE_REQUEST
, "Update Request" },
250 { MLE_CMD_DATA_REQUEST
, "Data Request" },
251 { MLE_CMD_DATA_RESPONSE
, "Data Response" },
252 { MLE_CMD_PARENT_REQUEST
, "Parent Request" },
253 { MLE_CMD_PARENT_RESPONSE
, "Parent Response" },
254 { MLE_CMD_CHILD_ID_REQUEST
, "Child ID Request" },
255 { MLE_CMD_CHILD_ID_RESPONSE
, "Child ID Response" },
256 { MLE_CMD_CHILD_UPDATE_REQUEST
, "Child Update Request" },
257 { MLE_CMD_CHILD_UPDATE_RESPONSE
, "Child Update Response" },
258 { MLE_CMD_ANNOUNCE
, "Announce" },
259 { MLE_CMD_DISCOVERY_REQUEST
, "Discovery Request" },
260 { MLE_CMD_DISCOVERY_RESPONSE
, "Discovery Response" },
261 { MLE_CMD_LINK_METRICS_MANAGEMENT_REQUEST
, "Link Metrics Management Request" },
262 { MLE_CMD_LINK_METRICS_MANAGEMENT_RESPONSE
, "Link Metrics Management Response" },
263 { MLE_CMD_LINK_PROBE
, "Link Probe" },
264 { MLE_CMD_CIM_DISCOVERY_REQUEST
, "CIM Discovery Request" },
265 { MLE_CMD_CIM_DISCOVERY_RESPONSE
, "CIM Discovery Response" },
266 { MLE_CMD_CIM_ANNOUNCE
, "CIM Announce" },
270 #define MLE_TLV_SOURCE_ADDRESS 0
271 #define MLE_TLV_MODE 1 /* Modified in Ch04_Mesh Link Establishment */
272 #define MLE_TLV_TIMEOUT 2
273 #define MLE_TLV_CHALLENGE 3
274 #define MLE_TLV_RESPONSE 4
275 #define MLE_TLV_LINK_LAYER_FRAME_COUNTER 5
276 #define MLE_TLV_LINK_QUALITY 6
277 #define MLE_TLV_NETWORK_PARAMETER 7
278 #define MLE_TLV_MLE_FRAME_COUNTER 8
279 #define MLE_TLV_ROUTE64 9 /* Defined in Ch05_Network Layer v1.1-rc1 */
280 #define MLE_TLV_ADDRESS16 10 /* Defined in Ch04_Mesh Link Establishment v1.1-rc1 */
281 #define MLE_TLV_LEADER_DATA 11 /* Defined in Ch04_Mesh Link Establishment v1.1-rc1 */
282 #define MLE_TLV_NETWORK_DATA 12 /* Defined in Ch05_Network Layer v1.1-rc1 */
283 #define MLE_TLV_TLV_REQUEST 13 /* Defined in Ch04_Mesh Link Establishment v1.1-rc1 */
284 #define MLE_TLV_SCAN_MASK 14 /* Defined in Ch04_Mesh Link Establishment v1.1-rc1 */
285 #define MLE_TLV_CONNECTIVITY 15 /* Defined in Ch04_Mesh Link Establishment v1.1-rc1 */
286 #define MLE_TLV_LINK_MARGIN 16 /* Defined in Ch04_Mesh Link Establishment v1.1-rc1 */
287 #define MLE_TLV_STATUS 17 /* Defined in Ch04_Mesh Link Establishment v1.1-rc1 */
288 #define MLE_TLV_VERSION 18 /* Defined in Ch04_Mesh Link Establishment v1.1-rc1 */
289 #define MLE_TLV_ADDRESS_REGISTRATION 19 /* Defined in Ch04_Mesh Link Establishment v1.1-rc1 */
290 #define MLE_TLV_CHANNEL 20 /* Defined in Ch04_Mesh Link Establishment v1.1-rc1 */
291 #define MLE_TLV_PAN_ID 21 /* Defined in Ch04_Mesh Link Establishment v1.1-rc1 */
292 #define MLE_TLV_ACTIVE_TSTAMP 22 /* Defined in Ch04_Mesh Link Establishment v1.1-rc1 */
293 #define MLE_TLV_PENDING_TSTAMP 23 /* Defined in Ch04_Mesh Link Establishment v1.1-rc1 */
294 #define MLE_TLV_ACTIVE_OP_DATASET 24 /* Defined in Ch04_Mesh Link Establishment v1.1-rc1 */
295 #define MLE_TLV_PENDING_OP_DATASET 25 /* Defined in Ch04_Mesh Link Establishment v1.1-rc1 */
296 #define MLE_TLV_THREAD_DISCOVERY 26 /* Defined in Ch04_Mesh Link Establishment v1.1-rc1 */
297 #define MLE_TLV_SUPERVISION_INTERVAL 27 /* Defined in Ch04_Mesh Link Establishment v1.2-Draft3 */
298 #define MLE_TLV_CIM_PROVISIONER_INTERFACE_DATA 28 /* Defined in Ch04_Mesh Link Establishment v1.2-Draft3 */
299 #define MLE_TLV_CIM_PROVISIONING_DATASET 29 /* Defined in Ch04_Mesh Link Establishment v1.2-Draft3 */
300 #define MLE_TLV_CIM_DISCOVERY_REQUEST 30 /* Defined in Ch04_Mesh Link Establishment v1.2-Draft3 */
301 #define MLE_TLV_SECURE_DISSEMINATION 31 /* Defined in Ch04_Mesh Link Establishment v1.2-Draft3 */
303 #define MLE_TLV_CSL_CHANNEL 80 /* Defined in Ch04_Mesh Link Establishment v1.2-Draft3 */
304 #define MLE_TLV_CSL_SYNCHRONIZED_TIMEOUT 85 /* Defined in Ch04_Mesh Link Establishment v1.2-Draft3 */
305 #define MLE_TLV_CSL_ACCURACY 86 /* Defined in Ch04_Mesh Link Establishment v1.2-Draft3 */
306 #define MLE_TLV_LINK_METRICS_QUERY 87 /* Defined in Ch04_Mesh Link Establishment v1.2-Draft3 */
307 #define MLE_TLV_LINK_METRICS_MANAGEMENT 88 /* Defined in Ch04_Mesh Link Establishment v1.2-Draft3 */
308 #define MLE_TLV_LINK_METRICS_REPORT 89 /* Defined in Ch04_Mesh Link Establishment v1.2-Draft3 */
309 #define MLE_TLV_LINK_PROBE 90 /* Defined in Ch04_Mesh Link Establishment v1.2-Draft3 */
312 #define MLE_TLV_CIM_DEVICE_INTERFACE_DATA 27 /* Defined in Ch04_Mesh Link Establishment v1.2-Draft3 */
313 #define MLE_TLV_CIM_PROVISIONER_INTERFACE_DATA 28 /* Defined in Ch04_Mesh Link Establishment v1.2-Draft3 */
314 #define MLE_TLV_CIM_PROVISIONING_DATASET 29 /* Defined in Ch04_Mesh Link Establishment v1.2-Draft3 */
315 #define MLE_TLV_CIM_DISCOVERY_REQUEST 30 /* Defined in Ch04_Mesh Link Establishment v1.2-Draft3 */
316 #define MLE_TLV_SECURE_DISSEMINATION 31 /* Defined in Ch04_Mesh Link Establishment v1.2-Draft3 */
318 #define MLE_TLV_CSL_CHANNEL 80 /* Defined in Ch04_Mesh Link Establishment v1.2-Draft3 */
319 #define MLE_TLV_CSL_SYNCHRONIZED_TIMEOUT 85 /* Defined in Ch04_Mesh Link Establishment v1.2-Draft3 */
320 #define MLE_TLV_CSL_ACCURACY 86 /* Defined in Ch04_Mesh Link Establishment v1.2-Draft3 */
321 #define MLE_TLV_LINK_METRICS_QUERY 87 /* Defined in Ch04_Mesh Link Establishment v1.2-Draft3 */
322 #define MLE_TLV_LINK_METRICS_MANAGEMENT 88 /* Defined in Ch04_Mesh Link Establishment v1.2-Draft3 */
323 #define MLE_TLV_LINK_METRICS_REPORT 89 /* Defined in Ch04_Mesh Link Establishment v1.2-Draft3 */
324 #define MLE_TLV_LINK_PROBE 90 /* Defined in Ch04_Mesh Link Establishment v1.2-Draft3 */
326 static const value_string mle_tlv_vals
[] = {
327 { MLE_TLV_SOURCE_ADDRESS
, "Source Address" },
328 { MLE_TLV_MODE
, "Mode" },
329 { MLE_TLV_TIMEOUT
, "Timeout" },
330 { MLE_TLV_CHALLENGE
, "Challenge" },
331 { MLE_TLV_RESPONSE
, "Response" },
332 { MLE_TLV_LINK_LAYER_FRAME_COUNTER
, "Link Layer Frame Counter"},
333 { MLE_TLV_LINK_QUALITY
, "Link Quality"},
334 { MLE_TLV_NETWORK_PARAMETER
, "Network Parameter"},
335 { MLE_TLV_MLE_FRAME_COUNTER
, "MLE Frame Counter"},
336 { MLE_TLV_ROUTE64
, "Route64"},
337 { MLE_TLV_ADDRESS16
, "Address16"},
338 { MLE_TLV_LEADER_DATA
, "Leader Data"},
339 { MLE_TLV_NETWORK_DATA
, "Network Data"},
340 { MLE_TLV_TLV_REQUEST
, "TLV Request"},
341 { MLE_TLV_SCAN_MASK
, "Scan Mask"},
342 { MLE_TLV_CONNECTIVITY
, "Connectivity"},
343 { MLE_TLV_LINK_MARGIN
, "Link Margin"},
344 { MLE_TLV_STATUS
, "Status"},
345 { MLE_TLV_VERSION
, "Version"},
346 { MLE_TLV_ADDRESS_REGISTRATION
, "Address Registration"},
347 { MLE_TLV_CHANNEL
, "Channel"},
348 { MLE_TLV_PAN_ID
, "PAN ID"},
349 { MLE_TLV_ACTIVE_TSTAMP
, "Active Timestamp"},
350 { MLE_TLV_PENDING_TSTAMP
, "Pending Timestamp"},
351 { MLE_TLV_ACTIVE_OP_DATASET
, "Active Operational Dataset"},
352 { MLE_TLV_PENDING_OP_DATASET
, "Pending Operational Dataset"},
353 { MLE_TLV_THREAD_DISCOVERY
, "Thread Discovery"},
354 { MLE_TLV_SUPERVISION_INTERVAL
, "Supervision Interval"},
355 { MLE_TLV_CSL_CHANNEL
, "CSL Channel"},
356 { MLE_TLV_CSL_SYNCHRONIZED_TIMEOUT
, "CSL Synchronized Timeout"},
357 { MLE_TLV_CSL_ACCURACY
, "CSL Accuracy"},
358 { MLE_TLV_LINK_METRICS_QUERY
, "Link Metrics Query"},
359 { MLE_TLV_LINK_METRICS_MANAGEMENT
, "Link Metrics Management"},
360 { MLE_TLV_LINK_METRICS_REPORT
, "Link Metrics Report"},
361 { MLE_TLV_LINK_PROBE
, "Link Probe"},
366 #define LINK_METRICS_REPORT_SUB_TLV 0
367 #define LINK_METRICS_QUERY_ID_SUB_TLV 1
368 #define LINK_METRICS_QUERY_OPTIONS_SUB_TLV 2
369 #define FORWARD_PROBING_REGISTRATION_SUB_TLV 3
370 //#define REVERSE_PROBING_REGISTRATION_SUB_TLV 4
371 #define LINK_METRICS_STATUS_SUB_TLV 5
372 //#define LINK_METRICS_TRACKING_CAPABILITIES_SUB_TLV 6
373 #define ENHANCED_ACK_LINK_METRICS_CONFIGURATION_SUB_TLV 7
375 static const value_string mle_tlv_link_param_vals
[] = {
376 { LINK_METRICS_REPORT_SUB_TLV
, "Links Metrics Report" },
377 { LINK_METRICS_QUERY_ID_SUB_TLV
, "Link Metrics Query" },
378 { LINK_METRICS_QUERY_OPTIONS_SUB_TLV
, "Link Metrics Query Options" },
379 { FORWARD_PROBING_REGISTRATION_SUB_TLV
, "Forward Probing Registration" },
380 { LINK_METRICS_STATUS_SUB_TLV
, "Link Metrics Status" },
381 { ENHANCED_ACK_LINK_METRICS_CONFIGURATION_SUB_TLV
, "Enhance Ack Link Metrics Configuration" },
385 #define LINK_SUCCESS 0
386 #define LINK_FAILURE_CANNOT_SUPPORT_NEW_SERIES_REGISTRATION 1
387 #define LINK_FAILURE_SERIES_ID_ALREADY_REGISTERED 2
388 #define LINK_FAILURE_SERIES_ID_NOT_RECOGNIZED 3
389 #define LINK_FAILURE_NO_MATCHING_FRAMES_RECEIVED 4
390 #define LINK_FAILURE_OTHER_FAILURE 254
392 static const value_string mle_tlv_link_sub_tlv_vals
[] = {
393 { LINK_SUCCESS
, "Success" },
394 { LINK_FAILURE_CANNOT_SUPPORT_NEW_SERIES_REGISTRATION
, " Failure - Cannot Support New Series Registration" },
395 { LINK_FAILURE_SERIES_ID_ALREADY_REGISTERED
, "Failure - Series ID Already Registered" },
396 { LINK_FAILURE_SERIES_ID_NOT_RECOGNIZED
, "Failure - Series ID not Recognized" },
397 { LINK_FAILURE_NO_MATCHING_FRAMES_RECEIVED
, "Failure - No matching frames received" },
398 { LINK_FAILURE_OTHER_FAILURE
, "Failure - Other Failure" },
402 #define CLEAR_ENHANCED_ACK_LINK_METRICS_CONFIGURATION 0
403 #define REGISTER_ENHANCED_ACK_LINK_METRICS_CONFIGURATION 1
405 static const value_string mle_tlv_link_enh_ack_flags_vals
[] = {
406 { CLEAR_ENHANCED_ACK_LINK_METRICS_CONFIGURATION
, "Clear Enhanced ACK Link Metrics Configuration" },
407 { REGISTER_ENHANCED_ACK_LINK_METRICS_CONFIGURATION
, "Register Enhanced ACK Link Metrics Configuration" },
411 /* Link Metrics End*/
413 #define LINK_SUCCESS 0
414 #define LINK_FAILURE_CANNOT_SUPPORT_NEW_SERIES_REGISTRATION 1
415 #define LINK_FAILURE_SERIES_ID_ALREADY_REGISTERED 2
416 #define LINK_FAILURE_SERIES_ID_NOT_RECOGNIZED 3
417 #define LINK_FAILURE_NO_MATCHING_FRAMES_RECEIVED 4
418 #define LINK_FAILURE_OTHER_FAILURE 254
420 #define LQI_FLAGS_C 0x80
421 #define LQI_FLAGS_SIZE 0x0F
423 #define NEIGHBOR_FLAG_I 0x80
424 #define NEIGHBOR_FLAG_O 0x40
425 #define NEIGHBOR_FLAG_P 0x20
427 #define NETWORK_PARAM_ID_CHANNEL 0
428 #define NETWORK_PARAM_ID_PAN_ID 1
429 #define NETWORK_PARAM_ID_PERMIT_JOIN 2
430 #define NETWORK_PARAM_ID_BCN_PAYLOAD 3
432 static const value_string mle_tlv_nwk_param_vals
[] = {
433 { NETWORK_PARAM_ID_CHANNEL
, "Channel" },
434 { NETWORK_PARAM_ID_PAN_ID
, "PAN ID" },
435 { NETWORK_PARAM_ID_PERMIT_JOIN
, "Permit Join" },
436 { NETWORK_PARAM_ID_BCN_PAYLOAD
, "Beacon Payload" },
440 static const true_false_string mle_tlv_mode_device_type
= {
444 static const true_false_string mle_tlv_mode_nwk_data
= {
448 static const true_false_string mle_tlv_addr_reg_iid_type
= {
453 #define ROUTE_TBL_OUT_MASK 0xC0
454 #define ROUTE_TBL_IN_MASK 0x30
455 #define ROUTE_TBL_COST_MASK 0x0F
457 #define SCAN_MASK_R_MASK 0x80
458 #define SCAN_MASK_D_MASK 0x40
460 #define CONN_MASK_FLAGS_PP_MASK 0xC0
462 #define ADDR_REG_MASK_IID_TYPE_MASK 0x80
463 #define ADDR_REG_MASK_CID_MASK 0x0F
465 #define MLE_CMD_CINFO_SEC_DATA_REQ 0x04
466 #define MLE_CMD_CINFO_NWK_DATA 0x01
468 /*FUNCTION:------------------------------------------------------
470 * dissect_mle_decrypt
474 * tvbuff_t *tvb - IEEE 802.15.4 packet.
475 * packet_info * pinfo - Packet info structure.
476 * unsigned offset - Offset where the ciphertext 'c' starts.
477 * ieee802154_packet *packet - IEEE 802.15.4 packet information.
478 * ws_decrypt_status *status - status of decryption returned through here on failure.
480 * tvbuff_t * - Decrypted payload.
481 *---------------------------------------------------------------
484 dissect_mle_decrypt(tvbuff_t
* tvb
,
487 ieee802154_packet
* packet
,
488 ieee802154_decrypt_info_t
* decrypt_info
)
490 tvbuff_t
* ptext_tvb
;
491 bool have_mic
= false;
493 unsigned char tmp
[16];
498 *decrypt_info
->rx_mic_length
= 0;
499 memset(decrypt_info
->rx_mic
, 0, 16);
501 /* Get the captured and on-the-wire length of the payload. */
502 if (packet
->security_level
> 0) {
503 M
= IEEE802154_MIC_LENGTH(packet
->security_level
);
509 reported_len
= tvb_reported_length_remaining(tvb
, offset
) - M
;
510 if (reported_len
< 0) {
511 *decrypt_info
->status
= DECRYPT_PACKET_TOO_SMALL
;
514 /* Check if the payload is truncated. */
515 if (tvb_bytes_exist(tvb
, offset
, reported_len
)) {
516 captured_len
= reported_len
;
519 captured_len
= tvb_captured_length_remaining(tvb
, offset
);
522 if (packet
->security_level
> 0) {
523 /* Check if the MIC is present in the captured data. */
524 have_mic
= tvb_bytes_exist(tvb
, offset
+ reported_len
, M
);
526 tvb_memcpy(tvb
, decrypt_info
->rx_mic
, offset
+ reported_len
, M
);
530 /*=====================================================
531 * Key Lookup - Need to find the appropriate key.
532 *=====================================================
534 if (packet
->src_addr_mode
== IEEE802154_FCF_ADDR_EXT
) {
535 /* The source EUI-64 is included in the headers. */
536 srcAddr
= packet
->src64
; /* GUINT64_SWAP_LE_BE(packet->src64); */
540 *decrypt_info
->status
= DECRYPT_PACKET_NO_EXT_SRC_ADDR
;
544 /*=====================================================
545 * CCM* - CTR mode payload encryption
546 *=====================================================
548 /* Create the CCM* initial block for decryption (Adata=0, M=0, counter=0). */
549 ccm_init_block(tmp
, false, 0, srcAddr
, packet
->frame_counter
, packet
->security_level
, 0, NULL
);
551 /* Decrypt the ciphertext, and place the plaintext in a new tvb. */
552 if (IEEE802154_IS_ENCRYPTED(packet
->security_level
) && captured_len
) {
556 * Make a copy of the ciphertext in heap memory.
558 * We will decrypt the message in-place and then use the buffer as the
559 * real data for the new tvb.
561 text
= (char *)tvb_memdup(pinfo
->pool
, tvb
, offset
, captured_len
);
563 /* Perform CTR-mode transformation. Try both the likely key and the alternate key */
564 if (!ccm_ctr_encrypt(decrypt_info
->key
, tmp
, decrypt_info
->rx_mic
, text
, captured_len
)) {
565 *decrypt_info
->status
= DECRYPT_PACKET_DECRYPT_FAILED
;
569 /* Create a tvbuff for the plaintext. */
570 ptext_tvb
= tvb_new_real_data((const uint8_t *)text
, captured_len
, reported_len
);
571 tvb_set_child_real_data_tvbuff(tvb
, ptext_tvb
);
572 add_new_data_source(pinfo
, ptext_tvb
, "Decrypted MLE payload");
573 *decrypt_info
->status
= DECRYPT_PACKET_SUCCEEDED
;
575 /* There is no ciphertext. Wrap the plaintext in a new tvb. */
577 /* Decrypt the MIC (if present). */
579 if (!ccm_ctr_encrypt(decrypt_info
->key
, tmp
, decrypt_info
->rx_mic
, NULL
, 0)) {
580 *decrypt_info
->status
= DECRYPT_PACKET_DECRYPT_FAILED
;
585 /* Create a tvbuff for the plaintext. This might result in a zero-length tvbuff. */
586 ptext_tvb
= tvb_new_subset_length_caplen(tvb
, offset
, captured_len
, reported_len
);
587 *decrypt_info
->status
= DECRYPT_PACKET_SUCCEEDED
;
590 /*=====================================================
591 * CCM* - CBC-mode message authentication
592 *=====================================================
594 /* We can only verify the message if the MIC wasn't truncated. */
596 unsigned char dec_mic
[16];
597 unsigned l_m
= captured_len
;
601 DISSECTOR_ASSERT(pinfo
->src
.len
== 16);
602 DISSECTOR_ASSERT(pinfo
->dst
.len
== 16);
603 memcpy(d_a
, pinfo
->src
.data
, pinfo
->src
.len
);
604 memcpy(d_a
+16, pinfo
->dst
.data
, pinfo
->dst
.len
);
606 tvb_memcpy(tvb
, d_a
+32, decrypt_info
->aux_offset
, decrypt_info
->aux_length
);
607 l_a
= 32 + decrypt_info
->aux_length
;
609 /* Adjust the lengths of the plantext and additional data if unencrypted. */
610 if (!IEEE802154_IS_ENCRYPTED(packet
->security_level
)) {
615 /* Create the CCM* initial block for authentication (Adata!=0, M!=0, counter=l(m)). */
616 ccm_init_block(tmp
, true, M
, srcAddr
, packet
->frame_counter
, packet
->security_level
, l_m
, NULL
);
618 /* Compute CBC-MAC authentication tag. */
620 * And yes, despite the warning in tvbuff.h, I think tvb_get_ptr is the
621 * right function here since either A) the payload wasn't encrypted, in
622 * which case l_m is zero, or B) the payload was encrypted, and the tvb
623 * already points to contiguous memory, since we just allocated it in
626 if (!ccm_cbc_mac(decrypt_info
->key
, tmp
, d_a
, l_a
, tvb_get_ptr(ptext_tvb
, 0, l_m
), l_m
, dec_mic
)) {
627 *decrypt_info
->status
= DECRYPT_PACKET_MIC_CHECK_FAILED
;
629 /* Compare the received MIC with the one we generated. */
630 else if (memcmp(decrypt_info
->rx_mic
, dec_mic
, M
) != 0) {
631 *decrypt_info
->status
= DECRYPT_PACKET_MIC_CHECK_FAILED
;
635 *decrypt_info
->rx_mic_length
= M
;
639 } /* dissect_mle_decrypt */
641 void register_mle_key_hash_handler(unsigned hash_identifier
, ieee802154_set_key_func key_func
)
643 /* Ensure no duplication */
644 DISSECTOR_ASSERT(wmem_tree_lookup32(mle_key_hash_handlers
, hash_identifier
) == NULL
);
646 wmem_tree_insert32(mle_key_hash_handlers
, hash_identifier
, (void*)key_func
);
649 /* Set MLE key function. */
650 static unsigned ieee802154_set_mle_key(ieee802154_packet
*packet
, unsigned char *key
, unsigned char *alt_key
, ieee802154_key_t
*uat_key
)
652 ieee802154_set_key_func func
= (ieee802154_set_key_func
)wmem_tree_lookup32(mle_key_hash_handlers
, uat_key
->hash_type
);
655 return func(packet
, key
, alt_key
, uat_key
);
657 /* Right now, KEY_HASH_NONE and KEY_HASH_ZIP are not registered because they
658 work with this "default" behavior */
659 if (packet
->key_index
== uat_key
->key_index
)
661 memcpy(key
, uat_key
->key
, IEEE802154_CIPHER_SIZE
);
669 dissect_mle(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data _U_
)
671 tvbuff_t
*volatile payload_tvb
= NULL
;
672 proto_tree
*volatile mle_tree
= NULL
;
673 proto_item
*volatile proto_root
= NULL
;
676 unsigned aux_header_offset
= 0;
677 ieee802154_decrypt_status status
;
680 proto_item
*mic_item
= NULL
;
681 proto_tree
*header_tree
= NULL
;
682 uint8_t security_suite
;
683 unsigned aux_length
= 0;
684 ieee802154_packet
*packet
;
685 ieee802154_packet
*original_packet
;
686 ieee802154_decrypt_info_t decrypt_info
;
687 ieee802154_hints_t
*ieee_hints
;
690 unsigned char rx_mic
[16];
691 unsigned int rx_mic_len
= 0;
694 uint8_t tlv_type
, tlv_len
;
695 proto_tree
*tlv_tree
;
697 ieee_hints
= (ieee802154_hints_t
*)p_get_proto_data(wmem_file_scope(), pinfo
, proto_ieee802154
, 0);
698 if (ieee_hints
== NULL
) {
699 /* For now, MLE only supported with IEEE802.15.4 as an underlying layer */
702 original_packet
= (ieee802154_packet
*)ieee_hints
->packet
;
704 packet
= wmem_new0(pinfo
->pool
, ieee802154_packet
);
706 /* Copy IEEE 802.15.4 Source Address */
707 packet
->src_addr_mode
= original_packet
->src_addr_mode
;
708 if (packet
->src_addr_mode
== IEEE802154_FCF_ADDR_EXT
) {
709 packet
->src64
= original_packet
->src64
;
711 packet
->src16
= original_packet
->src16
;
714 /* Copy IEEE 802.15.4 Source PAN ID */
715 packet
->src_pan
= original_packet
->src_pan
;
717 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "MLE");
718 col_clear(pinfo
->cinfo
, COL_INFO
);
720 /* Create the protocol tree. */
721 proto_root
= proto_tree_add_item(tree
, proto_mle
, tvb
, 0, tvb_reported_length(tvb
), ENC_NA
);
722 mle_tree
= proto_item_add_subtree(proto_root
, ett_mle
);
724 /* Parse the security suite field. */
725 /* Security Suite Field */
726 security_suite
= tvb_get_uint8(tvb
, offset
);
727 proto_tree_add_item(mle_tree
, hf_mle_security_suite
, tvb
, offset
, 1, ENC_NA
);
730 aux_header_offset
= offset
;
732 /* Security material present if security suite = 0 */
733 if (security_suite
== 0) {
734 dissect_ieee802154_aux_sec_header_and_key(tvb
, pinfo
, mle_tree
, packet
, &offset
);
735 aux_length
= offset
-aux_header_offset
;
737 packet
->security_level
= SECURITY_LEVEL_NONE
;
740 decrypt_info
.key_number
= 0;
742 /* Add additional fields for security level > SECURITY_LEVEL_NONE */
743 if (packet
->security_level
> SECURITY_LEVEL_NONE
) {
745 /* Pass to decryption process */
746 decrypt_info
.rx_mic
= rx_mic
;
747 decrypt_info
.rx_mic_length
= &rx_mic_len
;
748 decrypt_info
.aux_offset
= aux_header_offset
;
749 decrypt_info
.aux_length
= aux_length
;
750 decrypt_info
.status
= &status
;
751 decrypt_info
.key
= NULL
; /* payload function will fill that in */
753 payload_tvb
= decrypt_ieee802154_payload(tvb
, offset
, pinfo
, header_tree
, packet
, &decrypt_info
,
754 ieee802154_set_mle_key
, dissect_mle_decrypt
);
755 if (status
== DECRYPT_PACKET_MIC_CHECK_FAILED
)
756 expert_add_info(pinfo
, proto_root
, &ei_mle_cbc_mac_failed
);
760 mic_item
= proto_tree_add_bytes(header_tree
, hf_mle_mic
, tvb
, 0, rx_mic_len
, rx_mic
);
761 proto_item_set_generated(mic_item
);
764 status
= DECRYPT_NOT_ENCRYPTED
;
767 /* Get the unencrypted data if decryption failed. */
769 /* Deal with possible truncation and the FCS field at the end. */
770 int reported_len
= tvb_reported_length_remaining(tvb
, offset
);
771 int captured_len
= tvb_captured_length_remaining(tvb
, offset
);
772 if (reported_len
< captured_len
) captured_len
= reported_len
;
773 payload_tvb
= tvb_new_subset_length_caplen(tvb
, offset
, captured_len
, reported_len
);
776 /* Display the reason for failure, and abort if the error was fatal. */
778 case DECRYPT_PACKET_SUCCEEDED
:
780 proto_item_append_text(mic_item
, " [correct (key no. %d)]", decrypt_info
.key_number
);
783 case DECRYPT_PACKET_TOO_SMALL
:
784 expert_add_info(pinfo
, proto_root
, &ei_mle_packet_too_small
);
785 call_data_dissector(payload_tvb
, pinfo
, tree
);
786 return tvb_captured_length(tvb
);
788 case DECRYPT_PACKET_NO_KEY
:
789 expert_add_info(pinfo
, proto_root
, &ei_mle_no_key
);
790 call_data_dissector(payload_tvb
, pinfo
, tree
);
791 return tvb_captured_length(tvb
);
793 case DECRYPT_PACKET_DECRYPT_FAILED
:
794 expert_add_info(pinfo
, proto_root
, &ei_mle_decrypt_failed
);
795 call_data_dissector(payload_tvb
, pinfo
, tree
);
796 return tvb_captured_length(tvb
);
798 case DECRYPT_PACKET_MIC_CHECK_FAILED
:
799 expert_add_info(pinfo
, proto_root
, &ei_mle_mic_check_failed
);
800 proto_item_append_text(mic_item
, " [incorrect]");
802 * Abort only if the payload was encrypted, in which case we
803 * probably didn't decrypt the packet right (eg: wrong key).
805 if (IEEE802154_IS_ENCRYPTED(packet
->security_level
)) {
809 case DECRYPT_NOT_ENCRYPTED
:
813 /* This can cause a lot of problems so remove it by default */
814 if (!mic_ok
&& mle_mic_ok
) {
815 call_data_dissector(payload_tvb
, pinfo
, tree
);
816 col_set_str(pinfo
->cinfo
, COL_INFO
, "MIC Failed");
817 return tvb_captured_length(tvb
);
820 /***** NEW CODE HERE ****/
821 /* If we're good, carry on and display the MLE payload */
825 proto_tree_add_item(mle_tree
, hf_mle_command
, payload_tvb
, offset
, 1, ENC_BIG_ENDIAN
);
827 cmd
= tvb_get_uint8(payload_tvb
, offset
);
828 col_add_str(pinfo
->cinfo
, COL_INFO
, val_to_str(cmd
, mle_command_vals
, "Unknown (%x)"));
833 while (tvb_offset_exists(payload_tvb
, offset
)) {
835 /* Get the length ahead of time to pass to next function so we can highlight
836 proper amount of bytes */
837 tlv_len
= tvb_get_uint8(payload_tvb
, offset
+1);
839 ti
= proto_tree_add_item(mle_tree
, hf_mle_tlv
, payload_tvb
, offset
, tlv_len
+2, ENC_NA
);
840 tlv_tree
= proto_item_add_subtree(ti
, ett_mle_tlv
);
843 proto_tree_add_item(tlv_tree
, hf_mle_tlv_type
, payload_tvb
, offset
, 1, ENC_NA
);
844 tlv_type
= tvb_get_uint8(payload_tvb
, offset
);
847 /* Add value name to value root label */
848 proto_item_append_text(ti
, " (%s", val_to_str(tlv_type
, mle_tlv_vals
, "Unknown (%d)"));
851 proto_tree_add_item(tlv_tree
, hf_mle_tlv_length
, payload_tvb
, offset
, 1, ENC_BIG_ENDIAN
);
855 case MLE_TLV_SOURCE_ADDRESS
:
857 bool haveShortTLV
= false;
858 uint16_t shortAddr
= 0;
860 if (!((tlv_len
== 2) || (tlv_len
== 8))) {
861 /* TLV Length must be 2 or 8 */
862 expert_add_info(pinfo
, proto_root
, &ei_mle_tlv_length_failed
);
863 proto_tree_add_item(tlv_tree
, hf_mle_tlv_unknown
, payload_tvb
, offset
, tlv_len
, ENC_NA
);
868 shortAddr
= tvb_get_ntohs(payload_tvb
, offset
);
871 proto_tree_add_item(tlv_tree
, hf_mle_tlv_source_addr
, payload_tvb
, offset
, tlv_len
, ENC_NA
);
872 proto_item_append_text(ti
, " = ");
875 addr
= tvb_get_uint8(payload_tvb
, offset
);
876 proto_item_append_text(ti
, "%02x", addr
);
878 proto_item_append_text(ti
, ":");
882 if ((original_packet
->src_addr_mode
== IEEE802154_FCF_ADDR_EXT
) && haveShortTLV
) {
883 /* Source TLV: use this to update src/long mapping */
884 ieee802154_addr_update(&ieee802154_map
, shortAddr
, original_packet
->src_pan
, original_packet
->src64
, pinfo
->current_proto
, pinfo
->fd
->num
);
887 proto_item_append_text(ti
, ")");
895 capability
= tvb_get_uint8(payload_tvb
, offset
);
896 proto_item_append_text(ti
, " = %02x)", capability
);
897 /* Get and display capability info. (blatantly plagiarised from packet-ieee802154.c */
898 proto_tree_add_bits_item(tlv_tree
, hf_mle_tlv_mode_reserved1
, payload_tvb
, (offset
* 8) + 0, 4, ENC_NA
);//R1
899 proto_tree_add_bits_item(tlv_tree
, hf_mle_tlv_mode_receiver_on_idle
, payload_tvb
, (offset
* 8) + 4, 1, ENC_NA
);//Receiver
900 proto_tree_add_bits_item(tlv_tree
, hf_mle_tlv_mode_reserved2
, payload_tvb
, (offset
* 8) + 5, 1, ENC_NA
);//R2
901 proto_tree_add_bits_item(tlv_tree
, hf_mle_tlv_mode_device_type_bit
, payload_tvb
, (offset
* 8) +6, 1, ENC_NA
);//Device Type
902 proto_tree_add_bits_item(tlv_tree
, hf_mle_tlv_mode_network_data
, payload_tvb
, (offset
* 8) +7, 1, ENC_NA
);//Network Data
905 /* TLV Length must be 1 */
906 expert_add_info(pinfo
, proto_root
, &ei_mle_tlv_length_failed
);
907 proto_tree_add_item(tlv_tree
, hf_mle_tlv_unknown
, payload_tvb
, offset
, tlv_len
, ENC_NA
);
912 case MLE_TLV_TIMEOUT
:
914 /* TLV Length must be 4 */
915 expert_add_info(pinfo
, proto_root
, &ei_mle_tlv_length_failed
);
916 proto_tree_add_item(tlv_tree
, hf_mle_tlv_unknown
, payload_tvb
, offset
, tlv_len
, ENC_NA
);
918 uint32_t to_data
= 0;
919 proto_tree_add_item_ret_uint(tlv_tree
, hf_mle_tlv_timeout
, payload_tvb
, offset
, 4, ENC_BIG_ENDIAN
, &to_data
);
920 proto_item_append_text(ti
, " = %u", to_data
);
922 proto_item_append_text(ti
, ")");
926 case MLE_TLV_CHALLENGE
:
927 proto_tree_add_item(tlv_tree
, hf_mle_tlv_challenge
, payload_tvb
, offset
, tlv_len
, ENC_NA
);
929 proto_item_append_text(ti
, " = %s)", tvb_bytes_to_str(pinfo
->pool
, payload_tvb
, offset
, tlv_len
));
934 case MLE_TLV_RESPONSE
:
935 proto_tree_add_item(tlv_tree
, hf_mle_tlv_response
, payload_tvb
, offset
, tlv_len
, ENC_NA
);
937 proto_item_append_text(ti
, " = %s)", tvb_bytes_to_str(pinfo
->pool
, payload_tvb
, offset
, tlv_len
));
942 case MLE_TLV_LINK_LAYER_FRAME_COUNTER
:
943 case MLE_TLV_MLE_FRAME_COUNTER
:
945 /* TLV Length must be 4 */
946 expert_add_info(pinfo
, proto_root
, &ei_mle_tlv_length_failed
);
947 proto_tree_add_item(tlv_tree
, hf_mle_tlv_unknown
, payload_tvb
, offset
, tlv_len
, ENC_NA
);
951 if (tlv_type
== MLE_TLV_LINK_LAYER_FRAME_COUNTER
) {
952 proto_tree_add_item_ret_uint(tlv_tree
, hf_mle_tlv_ll_frm_cntr
, payload_tvb
, offset
, tlv_len
, ENC_BIG_ENDIAN
, &cntr
);
954 proto_tree_add_item_ret_uint(tlv_tree
, hf_mle_tlv_mle_frm_cntr
, payload_tvb
, offset
, tlv_len
, ENC_BIG_ENDIAN
, &cntr
);
956 proto_item_append_text(ti
, " = %u", cntr
);
958 proto_item_append_text(ti
, ")");
962 case MLE_TLV_LINK_QUALITY
:
964 unsigned numNeighbors
;
965 uint8_t size
= tvb_get_uint8(payload_tvb
, offset
) & LQI_FLAGS_SIZE
;
966 proto_tree
*neig_tree
;
967 proto_tree_add_item(tlv_tree
, hf_mle_tlv_lqi_c
, payload_tvb
, offset
, 1, ENC_BIG_ENDIAN
);
968 proto_tree_add_item(tlv_tree
, hf_mle_tlv_lqi_size
, payload_tvb
, offset
, 1, ENC_BIG_ENDIAN
);
971 if ((tlv_len
- 1) % (size
+ 3)) {
972 expert_add_info(pinfo
, proto_root
, &ei_mle_len_size_mismatch
);
973 proto_tree_add_item(tlv_tree
, hf_mle_tlv_unknown
, payload_tvb
, offset
, tlv_len
, ENC_NA
);
976 numNeighbors
= (tlv_len
- 1) / (size
+ 3);
979 if (numNeighbors
== 0) {
980 proto_item_append_text(ti
, ")");
981 } else if (numNeighbors
== 1) {
982 proto_item_append_text(ti
, ": 1 Neighbor)");
984 proto_item_append_text(ti
, ": %d Neighbors)", numNeighbors
);
992 while (numNeighbors
) {
993 ti
= proto_tree_add_item(tlv_tree
, hf_mle_tlv_neighbor
, payload_tvb
, offset
, size
+2, ENC_NA
);
994 neig_tree
= proto_item_add_subtree(ti
, ett_mle_neighbor
);
996 proto_tree_add_item(neig_tree
, hf_mle_tlv_neighbor_flagI
, payload_tvb
, offset
, 1, ENC_BIG_ENDIAN
);
997 proto_tree_add_item(neig_tree
, hf_mle_tlv_neighbor_flagO
, payload_tvb
, offset
, 1, ENC_BIG_ENDIAN
);
998 proto_tree_add_item(neig_tree
, hf_mle_tlv_neighbor_flagP
, payload_tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1001 proto_tree_add_item(neig_tree
, hf_mle_tlv_neighbor_idr
, payload_tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1004 proto_tree_add_item(neig_tree
, hf_mle_tlv_neighbor_addr
, payload_tvb
, offset
,size
, ENC_NA
);
1012 case MLE_TLV_NETWORK_PARAMETER
:
1014 uint8_t param_id
= tvb_get_uint8(payload_tvb
, offset
);
1016 proto_item_append_text(ti
, " = %s)", val_to_str(param_id
, mle_tlv_nwk_param_vals
, "Unknown (%d)"));
1018 proto_tree_add_item(tlv_tree
, hf_mle_tlv_network_param_id
, payload_tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1020 proto_tree_add_item(tlv_tree
, hf_mle_tlv_network_delay
, payload_tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1024 case NETWORK_PARAM_ID_CHANNEL
:
1025 proto_tree_add_item(tlv_tree
, hf_mle_tlv_network_channel
, payload_tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1028 case NETWORK_PARAM_ID_PAN_ID
:
1029 proto_tree_add_item(tlv_tree
, hf_mle_tlv_network_pan_id
, payload_tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1032 case NETWORK_PARAM_ID_PERMIT_JOIN
:
1033 proto_tree_add_item(tlv_tree
, hf_mle_tlv_network_pmt_join
, payload_tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1036 case NETWORK_PARAM_ID_BCN_PAYLOAD
:
1037 proto_tree_add_item(tlv_tree
, hf_mle_tlv_network_bcn_payload
, payload_tvb
, offset
, tlv_len
-5, ENC_NA
);
1038 offset
+= tlv_len
-5;
1041 proto_tree_add_item(tlv_tree
, hf_mle_tlv_network_unknown
, payload_tvb
, offset
, tlv_len
-5, ENC_NA
);
1042 offset
+= tlv_len
-5;
1048 case MLE_TLV_ROUTE64
:
1050 proto_tree
*rtr_tree
;
1053 uint64_t id_mask
, test_mask
;
1055 proto_item_append_text(ti
, ")");
1056 proto_tree_add_item(tlv_tree
, hf_mle_tlv_route64_id_seq
, payload_tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1059 /* Count number of table entries */
1061 for (i
= 0; i
< 8; i
++) { /* TODO magic - number of routers/8 */
1062 uint8_t id_mask_octet
= tvb_get_uint8(payload_tvb
, offset
+ i
);
1063 for (j
= 0; j
< 8; j
++) {
1064 if (id_mask_octet
& (1 << j
)) {
1071 * | | | | | | | | | | |1|1|1|1|1|1|...|6|
1072 * |0|1|2|3|4|5|6|7|8|9|0|1|2|3|4|5|...|3|
1073 * ---------------------------------------
1074 * |1|0|1|1|1|0|0|0|1|1|0|0|0|1|0|1|...
1076 * is sent as 0xb8, 0xc5
1077 * and represents table entry for routers 0, 2, 3, 4, 8, 9, 13, 15...
1079 /* Get the ID mask as a 64-bit number (BE) */
1080 id_mask
= tvb_get_ntoh64(payload_tvb
, offset
);
1082 /* Just show the string of octets - best representation for a bit mask */
1083 proto_tree_add_item(tlv_tree
, hf_mle_tlv_route64_id_mask
, payload_tvb
, offset
, 8, ENC_NA
);
1086 if (count
!= (tlv_len
- 9))
1088 expert_add_info(pinfo
, proto_root
, &ei_mle_tlv_length_failed
);
1089 proto_tree_add_item(tlv_tree
, hf_mle_tlv_unknown
, payload_tvb
, offset
, tlv_len
, ENC_NA
);
1090 offset
+= (tlv_len
- 9);
1093 for (i
= 0; i
< count
; i
++) {
1094 /* Find first bit set */
1095 for (j
= 0, test_mask
= (UINT64_C(1) << 63); test_mask
!= 1; test_mask
>>= 1, j
++) {
1096 if (test_mask
& id_mask
) {
1097 id_mask
&= ~test_mask
;
1101 ti
= proto_tree_add_item(tlv_tree
, hf_mle_tlv_route64_entry
, payload_tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1102 proto_item_append_text(ti
, " (%d)", j
);
1103 rtr_tree
= proto_item_add_subtree(ti
, ett_mle_router
);
1105 proto_tree_add_item(rtr_tree
, hf_mle_tlv_route64_nbr_out
, payload_tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1106 proto_tree_add_item(rtr_tree
, hf_mle_tlv_route64_nbr_in
, payload_tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1107 proto_tree_add_item(rtr_tree
, hf_mle_tlv_route64_cost
, payload_tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1114 case MLE_TLV_ADDRESS16
:
1116 /* TLV Length must be 2 */
1117 expert_add_info(pinfo
, proto_root
, &ei_mle_tlv_length_failed
);
1118 proto_tree_add_item(tlv_tree
, hf_mle_tlv_unknown
, payload_tvb
, offset
, tlv_len
, ENC_NA
);
1120 uint16_t addr16
= tvb_get_ntohs(payload_tvb
, offset
);
1121 proto_item_append_text(ti
, " = ");
1123 uint8_t a16_len
= 2; /* Fix it at 2 */
1124 unsigned stroffset
= offset
;
1128 a16_data
= tvb_get_uint8(payload_tvb
, stroffset
);
1129 proto_item_append_text(ti
, "%02x", a16_data
);
1131 proto_item_append_text(ti
, ":");
1136 proto_tree_add_item(tlv_tree
, hf_mle_tlv_addr16
, payload_tvb
, offset
, 2, ENC_NA
);
1137 if (original_packet
->dst_addr_mode
== IEEE802154_FCF_ADDR_EXT
) {
1138 /* Allocated Address16 TLV: use this to update dst/long mapping */
1139 ieee802154_addr_update(&ieee802154_map
, addr16
, original_packet
->dst_pan
, original_packet
->dst64
, pinfo
->current_proto
, pinfo
->fd
->num
);
1142 proto_item_append_text(ti
, ")");
1146 case MLE_TLV_LEADER_DATA
:
1147 proto_item_append_text(ti
, ")");
1149 /* TLV Length must be 8 */
1150 expert_add_info(pinfo
, proto_root
, &ei_mle_tlv_length_failed
);
1151 proto_tree_add_item(tlv_tree
, hf_mle_tlv_unknown
, payload_tvb
, offset
, tlv_len
, ENC_NA
);
1154 proto_tree_add_item(tlv_tree
, hf_mle_tlv_leader_data_partition_id
, payload_tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1156 proto_tree_add_item(tlv_tree
, hf_mle_tlv_leader_data_weighting
, payload_tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1158 proto_tree_add_item(tlv_tree
, hf_mle_tlv_leader_data_version
, payload_tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1160 proto_tree_add_item(tlv_tree
, hf_mle_tlv_leader_data_stable_version
, payload_tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1162 proto_tree_add_item(tlv_tree
, hf_mle_tlv_leader_data_router_id
, payload_tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1167 case MLE_TLV_NETWORK_DATA
:
1170 proto_item_append_text(ti
, ")");
1172 sub_tvb
= tvb_new_subset_length(payload_tvb
, offset
, tlv_len
);
1173 call_dissector(thread_nwd_handle
, sub_tvb
, pinfo
, tlv_tree
);
1179 case MLE_TLV_ACTIVE_OP_DATASET
:
1180 case MLE_TLV_PENDING_OP_DATASET
:
1181 case MLE_TLV_THREAD_DISCOVERY
:
1184 proto_item_append_text(ti
, ")");
1186 sub_tvb
= tvb_new_subset_length(payload_tvb
, offset
, tlv_len
);
1187 call_dissector(thread_mc_handle
, sub_tvb
, pinfo
, tlv_tree
);
1193 case MLE_TLV_TLV_REQUEST
:
1194 proto_item_append_text(ti
, ")");
1196 proto_tree_add_item(tlv_tree
, hf_mle_tlv_type
, payload_tvb
, offset
, 1, ENC_NA
);
1202 case MLE_TLV_SCAN_MASK
:
1204 /* TLV Length must be 1 */
1205 proto_item_append_text(ti
, ")");
1206 expert_add_info(pinfo
, proto_root
, &ei_mle_tlv_length_failed
);
1207 proto_tree_add_item(tlv_tree
, hf_mle_tlv_unknown
, payload_tvb
, offset
, tlv_len
, ENC_NA
);
1211 mask
= tvb_get_uint8(payload_tvb
, offset
);
1212 proto_item_append_text(ti
, " = %02x)", mask
);
1213 proto_tree_add_item(tlv_tree
, hf_mle_tlv_scan_mask_r
, payload_tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1214 proto_tree_add_item(tlv_tree
, hf_mle_tlv_scan_mask_e
, payload_tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1219 case MLE_TLV_CONNECTIVITY
:
1220 proto_item_append_text(ti
, ")");
1221 if ((tlv_len
== 7) || (tlv_len
== 10)) {
1222 proto_tree
*fl_tree
;
1224 ti
= proto_tree_add_item(tlv_tree
, hf_mle_tlv_conn_flags
, payload_tvb
, offset
, 1, ENC_NA
);
1225 fl_tree
= proto_item_add_subtree(ti
, ett_mle_conn_flg
);
1226 proto_tree_add_item(fl_tree
, hf_mle_tlv_conn_flags_pp
, payload_tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1228 proto_tree_add_item(tlv_tree
, hf_mle_tlv_conn_lq3
, payload_tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1230 proto_tree_add_item(tlv_tree
, hf_mle_tlv_conn_lq2
, payload_tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1232 proto_tree_add_item(tlv_tree
, hf_mle_tlv_conn_lq1
, payload_tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1234 proto_tree_add_item(tlv_tree
, hf_mle_tlv_conn_leader_cost
, payload_tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1236 proto_tree_add_item(tlv_tree
, hf_mle_tlv_conn_id_seq
, payload_tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1238 proto_tree_add_item(tlv_tree
, hf_mle_tlv_conn_active_rtrs
, payload_tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1240 if (tlv_len
== 10) {
1241 proto_tree_add_item(tlv_tree
, hf_mle_tlv_conn_sed_buf_size
, payload_tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1243 proto_tree_add_item(tlv_tree
, hf_mle_tlv_conn_sed_dgram_cnt
, payload_tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1247 /* TLV Length must be 7 (old style) or 10 */
1248 expert_add_info(pinfo
, proto_root
, &ei_mle_tlv_length_failed
);
1249 proto_tree_add_item(tlv_tree
, hf_mle_tlv_unknown
, payload_tvb
, offset
, tlv_len
, ENC_NA
);
1254 case MLE_TLV_LINK_MARGIN
:
1256 /* TLV Length must be 1 */
1257 proto_item_append_text(ti
, ")");
1258 expert_add_info(pinfo
, proto_root
, &ei_mle_tlv_length_failed
);
1259 proto_tree_add_item(tlv_tree
, hf_mle_tlv_unknown
, payload_tvb
, offset
, tlv_len
, ENC_NA
);
1261 uint8_t link_margin
;
1263 link_margin
= tvb_get_uint8(payload_tvb
, offset
);
1264 proto_item_append_text(ti
, " = %udB)", link_margin
);
1265 proto_tree_add_item(tlv_tree
, hf_mle_tlv_link_margin
, payload_tvb
, offset
, tlv_len
, ENC_BIG_ENDIAN
);
1270 case MLE_TLV_STATUS
:
1272 /* TLV Length must be 1 */
1273 proto_item_append_text(ti
, ")");
1274 expert_add_info(pinfo
, proto_root
, &ei_mle_tlv_length_failed
);
1275 proto_tree_add_item(tlv_tree
, hf_mle_tlv_unknown
, payload_tvb
, offset
, tlv_len
, ENC_NA
);
1279 stat
= tvb_get_uint8(payload_tvb
, offset
);
1280 proto_item_append_text(ti
, " = %d)", stat
);
1281 proto_tree_add_item(tlv_tree
, hf_mle_tlv_status
, payload_tvb
, offset
, tlv_len
, ENC_BIG_ENDIAN
);
1286 case MLE_TLV_VERSION
:
1288 /* TLV Length must be 2 */
1289 proto_item_append_text(ti
, ")");
1290 expert_add_info(pinfo
, proto_root
, &ei_mle_tlv_length_failed
);
1291 proto_tree_add_item(tlv_tree
, hf_mle_tlv_unknown
, payload_tvb
, offset
, tlv_len
, ENC_NA
);
1295 version
= tvb_get_ntohs(payload_tvb
, offset
);
1296 proto_item_append_text(ti
, " = %d)", version
);
1297 proto_tree_add_item(tlv_tree
, hf_mle_tlv_version
, payload_tvb
, offset
, tlv_len
, ENC_BIG_ENDIAN
);
1302 case MLE_TLV_ADDRESS_REGISTRATION
:
1304 uint8_t iid_type
, i
;
1305 uint8_t entries
= 0;
1306 int16_t check_len
= tlv_len
;
1307 unsigned check_offset
= offset
;
1309 /* Check consistency of entries */
1310 while (check_len
> 0) {
1313 iid_type
= tvb_get_uint8(payload_tvb
, check_offset
);
1314 if (iid_type
& ADDR_REG_MASK_IID_TYPE_MASK
) {
1319 check_offset
+= ar_len
;
1320 check_len
-= ar_len
;
1324 proto_item_append_text(ti
, ")");
1325 if (check_len
!= 0) {
1326 /* Not an integer number of entries */
1327 expert_add_info(pinfo
, proto_root
, &ei_mle_tlv_length_failed
);
1328 proto_tree_add_item(tlv_tree
, hf_mle_tlv_unknown
, payload_tvb
, offset
, tlv_len
, ENC_NA
);
1331 for (i
= 0; i
< entries
; i
++) {
1332 proto_tree
*ar_tree
;
1334 ti
= proto_tree_add_item(tlv_tree
, hf_mle_tlv_addr_reg_entry
, payload_tvb
, offset
, 1, ENC_NA
);
1335 ar_tree
= proto_item_add_subtree(ti
, ett_mle_addr_reg
);
1336 iid_type
= tvb_get_uint8(payload_tvb
, offset
);
1337 if (iid_type
& ADDR_REG_MASK_IID_TYPE_MASK
) {
1338 proto_tree_add_item(ar_tree
, hf_mle_tlv_addr_reg_iid_type
, payload_tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1339 proto_tree_add_item(ar_tree
, hf_mle_tlv_addr_reg_cid
, payload_tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1341 proto_tree_add_item(ar_tree
, hf_mle_tlv_addr_reg_iid
, payload_tvb
, offset
, 8, ENC_NA
);
1344 proto_tree_add_item(ar_tree
, hf_mle_tlv_addr_reg_iid_type
, payload_tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1346 proto_tree_add_item(ar_tree
, hf_mle_tlv_addr_reg_ipv6
, payload_tvb
, offset
, 16, ENC_NA
);
1354 case MLE_TLV_CHANNEL
:
1356 proto_item_append_text(ti
, ")");
1358 /* Check length is consistent */
1360 expert_add_info(pinfo
, proto_root
, &ei_mle_tlv_length_failed
);
1361 proto_tree_add_item(tlv_tree
, hf_mle_tlv_unknown
, payload_tvb
, offset
, tlv_len
, ENC_NA
);
1364 proto_tree_add_item(tlv_tree
, hf_mle_tlv_channel_page
, payload_tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1366 proto_tree_add_item(tlv_tree
, hf_mle_tlv_channel
, payload_tvb
, offset
+1, 2, ENC_BIG_ENDIAN
);
1372 case MLE_TLV_PAN_ID
:
1374 proto_item_append_text(ti
, ")");
1376 /* Check length is consistent */
1378 expert_add_info(pinfo
, proto_root
, &ei_mle_tlv_length_failed
);
1379 proto_tree_add_item(tlv_tree
, hf_mle_tlv_unknown
, payload_tvb
, offset
, tlv_len
, ENC_NA
);
1382 proto_tree_add_item(tlv_tree
, hf_mle_tlv_pan_id
, payload_tvb
, offset
, tlv_len
, ENC_BIG_ENDIAN
);
1388 case MLE_TLV_ACTIVE_TSTAMP
:
1389 case MLE_TLV_PENDING_TSTAMP
:
1393 proto_item_append_text(ti
, ")");
1396 expert_add_info(pinfo
, proto_root
, &ei_mle_tlv_length_failed
);
1397 proto_tree_add_item(tlv_tree
, hf_mle_tlv_unknown
, payload_tvb
, offset
, tlv_len
, ENC_NA
);
1399 /* Fill in the nstime_t structure */
1400 timestamp
.secs
= (time_t)tvb_get_ntoh48(payload_tvb
, offset
);
1401 timestamp
.nsecs
= (int)lround((double)(tvb_get_ntohs(payload_tvb
, offset
+ 6) >> 1) * MLE_32768_TO_NSEC_FACTOR
);
1402 if (tlv_type
== MLE_TLV_ACTIVE_TSTAMP
) {
1403 proto_tree_add_time(tlv_tree
, hf_mle_tlv_active_tstamp
, payload_tvb
, offset
, 8, ×tamp
);
1405 proto_tree_add_time(tlv_tree
, hf_mle_tlv_pending_tstamp
, payload_tvb
, offset
, 8, ×tamp
);
1412 case MLE_TLV_CSL_CHANNEL
:
1414 /* Check length is consistent */
1416 expert_add_info(pinfo
, proto_root
, &ei_mle_tlv_length_failed
);
1417 proto_tree_add_item(tlv_tree
, hf_mle_tlv_unknown
, payload_tvb
, offset
, tlv_len
, ENC_NA
);
1420 proto_tree_add_item(tlv_tree
, hf_mle_tlv_channel_page
, payload_tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1422 proto_tree_add_item(tlv_tree
, hf_mle_tlv_channel
, payload_tvb
, offset
+1, 2, ENC_BIG_ENDIAN
);
1428 case MLE_TLV_CSL_SYNCHRONIZED_TIMEOUT
:/*Defined in Ch04_Mesh Link Establishment v1.2*/
1429 /* Check length is consistent */
1431 expert_add_info(pinfo
, proto_root
, &ei_mle_tlv_length_failed
);
1432 proto_tree_add_item(tlv_tree
, hf_mle_tlv_unknown
, payload_tvb
, offset
, tlv_len
, ENC_NA
);
1434 /* CSL synchronized timeout */
1435 uint32_t to_data
= 0;
1436 proto_tree_add_item_ret_uint(tlv_tree
, hf_mle_tlv_csl_synchronied_timeout
, payload_tvb
, offset
, 4, ENC_BIG_ENDIAN
, &to_data
);
1437 proto_item_append_text(ti
, " = %u", to_data
);
1439 proto_item_append_text(ti
, ")");
1442 case MLE_TLV_CSL_ACCURACY
:
1443 proto_item_append_text(ti
, ")");
1445 /* TLV Length must be 2 */
1446 expert_add_info(pinfo
, proto_root
, &ei_mle_tlv_length_failed
);
1447 proto_tree_add_item(tlv_tree
, hf_mle_tlv_unknown
, payload_tvb
, offset
, tlv_len
, ENC_NA
);
1449 proto_tree_add_item(tlv_tree
, hf_mle_tlv_csl_clock_accuracy
, payload_tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1451 proto_tree_add_item(tlv_tree
, hf_mle_tlv_csl_uncertainty
, payload_tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1455 case MLE_TLV_LINK_METRICS_QUERY
:
1456 case MLE_TLV_LINK_METRICS_MANAGEMENT
:
1457 case MLE_TLV_LINK_METRICS_REPORT
:
1459 proto_item_append_text(ti
, ")");
1460 proto_item
*sub_item
;
1461 proto_tree
*sub_tree
;
1462 uint8_t metrics_tlv
;
1463 while (tvb_offset_exists(payload_tvb
, offset
)) {
1464 uint8_t sub_tlv
= tvb_get_uint8(payload_tvb
, offset
);
1466 sub_tree
= proto_tree_add_subtree(tlv_tree
, payload_tvb
, offset
, -1, 1, &sub_item
, "Sub TLV");
1467 sub_item
= proto_tree_add_item(sub_tree
, hf_mle_tlv_link_sub_tlv
, payload_tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1470 proto_tree_add_item(sub_tree
, hf_mle_tlv_length
, payload_tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1471 uint8_t length_sub_tlv
= tvb_get_uint8(payload_tvb
,offset
);
1474 case LINK_METRICS_REPORT_SUB_TLV
:
1475 metrics_tlv
= tvb_get_uint8(payload_tvb
, offset
);
1477 proto_tree_add_bits_item(sub_tree
, hf_mle_tlv_metric_type_id_flags_e
, payload_tvb
, (offset
* 8) + 0, 1, ENC_NA
);//E
1478 proto_tree_add_bits_item(sub_tree
, hf_mle_tlv_metric_type_id_flags_l
, payload_tvb
, (offset
* 8) + 1, 1, ENC_NA
);//L
1479 proto_tree_add_bits_item(sub_tree
, hf_mle_tlv_metric_type_id_flags_type
, payload_tvb
, (offset
* 8) + 2, 3, ENC_NA
);//Type enum
1480 proto_tree_add_bits_item(sub_tree
, hf_mle_tlv_metric_type_id_flags_metric
, payload_tvb
, (offset
* 8) + 5, 3, ENC_NA
);//Metric enum
1483 //latest draft the length is 1 indicates that the extended value is 4 else 1
1484 if((metrics_tlv
& 0x40) == 0x40)
1486 sub_item
= proto_tree_add_item(sub_tree
, hf_mle_tlv_value
, payload_tvb
, offset
, 4, ENC_NA
);
1491 sub_item
= proto_tree_add_item(sub_tree
, hf_mle_tlv_value
, payload_tvb
, offset
, 1, ENC_NA
);
1495 case LINK_METRICS_QUERY_ID_SUB_TLV
:
1497 proto_tree_add_item(sub_tree
, hf_mle_tlv_query_id
, payload_tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1500 case LINK_METRICS_QUERY_OPTIONS_SUB_TLV
:
1501 proto_tree_add_item(sub_tree
, hf_mle_tlv_link_query_options
, payload_tvb
, offset
, length_sub_tlv
, ENC_NA
);
1502 offset
+= length_sub_tlv
;
1504 case FORWARD_PROBING_REGISTRATION_SUB_TLV
:
1505 proto_tree_add_item(sub_tree
, hf_mle_tlv_link_forward_series
, payload_tvb
, offset
, 1, ENC_NA
);
1507 proto_tree_add_item(sub_tree
, hf_mle_tlv_link_forward_series_flags
, payload_tvb
, offset
, 1, ENC_NA
);
1508 uint8_t forward_series_flag
= tvb_get_uint8(payload_tvb
, offset
);
1510 if (forward_series_flag
> 0)
1512 proto_tree_add_bits_item(sub_tree
, hf_mle_tlv_metric_type_id_flags_e
, payload_tvb
, (offset
* 8) + 0, 1, ENC_NA
);//Receiver
1513 proto_tree_add_bits_item(sub_tree
, hf_mle_tlv_metric_type_id_flags_l
, payload_tvb
, (offset
* 8) + 1, 1, ENC_NA
);//Receiver
1514 proto_tree_add_bits_item(sub_tree
, hf_mle_tlv_metric_type_id_flags_type
, payload_tvb
, (offset
* 8) + 2, 3, ENC_NA
);//Receiver
1515 proto_tree_add_bits_item(sub_tree
, hf_mle_tlv_metric_type_id_flags_metric
, payload_tvb
, (offset
* 8) + 5, 3, ENC_NA
);//Receiver
1519 case LINK_METRICS_STATUS_SUB_TLV
:
1520 proto_tree_add_item(sub_tree
, hf_mle_tlv_link_status_sub_tlv
, payload_tvb
, offset
, 1, ENC_NA
);
1523 case ENHANCED_ACK_LINK_METRICS_CONFIGURATION_SUB_TLV
:
1524 if(length_sub_tlv
== 1)
1526 sub_item
= proto_tree_add_item(sub_tree
, hf_mle_tlv_link_enh_ack_flags
, payload_tvb
, offset
, 1, ENC_NA
);
1530 sub_item
= proto_tree_add_item(sub_tree
, hf_mle_tlv_link_enh_ack_flags
, payload_tvb
, offset
, 1, ENC_NA
);
1531 sub_item
= proto_tree_add_item(sub_tree
, hf_mle_tlv_link_requested_type_id_flags
, payload_tvb
, offset
+1, (length_sub_tlv
-1), ENC_NA
);
1533 offset
+= length_sub_tlv
;
1539 case MLE_TLV_LINK_PROBE
:
1541 proto_item_append_text(ti
, ")");
1542 proto_tree_add_item(tlv_tree
, hf_mle_tlv_link_status
, payload_tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1546 case MLE_TLV_SUPERVISION_INTERVAL
:
1548 /* TLV Length must be 2 */
1549 proto_item_append_text(ti
, ")");
1550 expert_add_info(pinfo
, proto_root
, &ei_mle_tlv_length_failed
);
1551 proto_tree_add_item(tlv_tree
, hf_mle_tlv_unknown
, payload_tvb
, offset
, tlv_len
, ENC_NA
);
1556 interval
= tvb_get_ntohs(payload_tvb
, offset
);
1557 proto_item_append_text(ti
, " = %d)", interval
);
1558 proto_tree_add_item(tlv_tree
, hf_mle_tlv_supervision_interval
, payload_tvb
, offset
, tlv_len
, ENC_BIG_ENDIAN
);
1562 case MLE_TLV_CIM_PROVISIONER_INTERFACE_DATA
:
1563 case MLE_TLV_CIM_PROVISIONING_DATASET
:
1564 case MLE_TLV_CIM_DISCOVERY_REQUEST
:
1565 case MLE_TLV_SECURE_DISSEMINATION
:
1568 proto_item_append_text(ti
, ")");
1569 proto_tree_add_item(tlv_tree
, hf_mle_tlv_unknown
, payload_tvb
, offset
, tlv_len
, ENC_NA
);
1574 return tvb_captured_length(tvb
);
1578 proto_register_mle(void)
1580 static hf_register_info hf
[] = {
1582 /* Auxiliary Security Header Fields */
1583 /*----------------------------------*/
1584 { &hf_mle_security_suite
,
1587 FT_UINT8
, BASE_HEX
, VALS(mle_sec_suite_names
), 0x0,
1588 "The Security Suite of the frame",
1595 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1596 "The decrypted MIC",
1604 FT_UINT8
, BASE_DEC
, VALS(mle_command_vals
), 0x0,
1613 FT_NONE
, BASE_NONE
, NULL
, 0x0,
1614 "Type-Length-Value",
1621 FT_UINT8
, BASE_DEC
, VALS(mle_tlv_vals
), 0x0,
1626 { &hf_mle_tlv_length
,
1629 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1634 /* Type-Specific TLV Fields */
1635 { &hf_mle_tlv_source_addr
,
1637 "mle.tlv.source_addr",
1638 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1643 /* Capability Information Fields */
1644 { &hf_mle_tlv_mode_nwk_data
,
1646 "mle.tlv.mode.nwk_data",
1647 FT_BOOLEAN
, 8, TFS(&mle_tlv_mode_nwk_data
), MLE_CMD_CINFO_NWK_DATA
,
1652 { &hf_mle_tlv_mode_device_type
,
1654 "mle.tlv.mode.device_type",
1655 FT_BOOLEAN
, 8, TFS(&mle_tlv_mode_device_type
), IEEE802154_CMD_CINFO_DEVICE_TYPE
,
1660 { &hf_mle_tlv_mode_sec_data_req
,
1661 { "Secure Data Requests",
1662 "mle.tlv.mode.sec_data_req",
1663 FT_BOOLEAN
, 8, NULL
, MLE_CMD_CINFO_SEC_DATA_REQ
,
1668 { &hf_mle_tlv_mode_receiver_on_idle
,
1669 { "R(Receiver/rx)-on-idle",
1670 "mle.tlv.mode.receiver_on_idle",
1671 FT_UINT8
, BASE_HEX
, NULL
, 0x0,
1676 { &hf_mle_tlv_mode_reserved1
,
1678 "mle.tlv.mode.reserved1",
1679 FT_UINT8
, BASE_HEX
, NULL
, 0x0,
1684 { &hf_mle_tlv_mode_reserved2
,
1686 "mle.tlv.mode.reserved2",
1687 FT_UINT8
, BASE_HEX
, NULL
, 0x0,
1692 { &hf_mle_tlv_mode_device_type_bit
,
1694 "mle.tlv.mode.device_type_bit",
1695 FT_UINT8
, BASE_HEX
, NULL
, 0x0,
1700 { &hf_mle_tlv_mode_network_data
,
1701 { "N(Network Data)",
1702 "mle.tlv.mode.network_data",
1703 FT_UINT8
, BASE_HEX
, NULL
, 0x0,
1708 { &hf_mle_tlv_mode_idle_rx
,
1709 { "Receive On When Idle",
1710 "mle.tlv.mode.idle_rx",
1711 FT_BOOLEAN
, 8, NULL
, IEEE802154_CMD_CINFO_IDLE_RX
,
1716 { &hf_mle_tlv_timeout
,
1719 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
1720 "Expected interval between transmissions in seconds",
1724 { &hf_mle_tlv_challenge
,
1726 "mle.tlv.challenge",
1727 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1728 "Challenge to be echoed back",
1732 { &hf_mle_tlv_response
,
1735 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1736 "Response to a challenge",
1740 { &hf_mle_tlv_ll_frm_cntr
,
1741 { "Link Layer Frame Counter",
1742 "mle.tlv.ll_frm_cntr",
1743 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
1744 "The Link layer frame counter",
1748 { &hf_mle_tlv_mle_frm_cntr
,
1749 { "MLE Frame Counter",
1750 "mle.tlv.mle_frm_cntr",
1751 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
1752 "The MLE frame counter",
1756 { &hf_mle_tlv_unknown
,
1759 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1760 "Unknown TLV, raw value",
1764 { &hf_mle_tlv_lqi_c
,
1766 "mle.tlv.lqi.complete",
1767 FT_BOOLEAN
, 8, NULL
, LQI_FLAGS_C
,
1772 { &hf_mle_tlv_lqi_size
,
1775 FT_UINT8
, BASE_DEC
, NULL
, LQI_FLAGS_SIZE
,
1780 { &hf_mle_tlv_neighbor
,
1781 { "Neighbor Record",
1783 FT_NONE
, BASE_NONE
, NULL
, 0x0,
1788 { &hf_mle_tlv_neighbor_flagI
,
1790 "mle.tlv.neighbor.flagI",
1791 FT_BOOLEAN
, 8, NULL
, NEIGHBOR_FLAG_I
,
1792 "Set if the sender has configured its link with this neighbor and will accept incoming messages from them.",
1796 { &hf_mle_tlv_neighbor_flagO
,
1798 "mle.tlv.neighbor.flagO",
1799 FT_BOOLEAN
, 8, NULL
, NEIGHBOR_FLAG_O
,
1800 "Set if the sender believes that the neighbor has configured its link with the sender and will accept incoming messages from the sender.",
1804 { &hf_mle_tlv_neighbor_flagP
,
1806 "mle.tlv.neighbor.flagP",
1807 FT_BOOLEAN
, 8, NULL
, NEIGHBOR_FLAG_P
,
1808 "Set if the sender expects to use this link for sending messages to this neighbor.",
1812 { &hf_mle_tlv_neighbor_idr
,
1813 { "Inverse Delivery Ratio",
1814 "mle.tlv.neighbor.idr",
1815 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1820 { &hf_mle_tlv_neighbor_addr
,
1822 "mle.tlv.neighbor.addr",
1823 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1828 { &hf_mle_tlv_network_param_id
,
1830 "mle.tlv.network.param_id",
1831 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1836 { &hf_mle_tlv_network_delay
,
1838 "mle.tlv.network.delay",
1839 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
1844 { &hf_mle_tlv_network_channel
,
1846 "mle.tlv.network.channel",
1847 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1852 { &hf_mle_tlv_network_pan_id
,
1854 "mle.tlv.network.pan_id",
1855 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
1860 { &hf_mle_tlv_network_pmt_join
,
1862 "mle.tlv.network.pmt_join",
1863 FT_BOOLEAN
, 8, NULL
, 0x1,
1868 { &hf_mle_tlv_network_bcn_payload
,
1870 "mle.tlv.network.bcn_payload",
1871 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1876 { &hf_mle_tlv_route64_id_seq
,
1878 "mle.tlv.route64.id_seq",
1879 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1884 { &hf_mle_tlv_route64_id_mask
,
1885 { "Assigned Router ID Mask",
1886 "mle.tlv.route64.id_mask",
1887 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1892 { &hf_mle_tlv_route64_entry
,
1893 { "Routing Table Entry",
1895 FT_UINT8
, BASE_HEX
, NULL
, 0x0,
1900 { &hf_mle_tlv_route64_nbr_out
,
1901 { "Neighbor Out Link Quality",
1902 "mle.tlv.route64.nbr_out",
1903 FT_UINT8
, BASE_DEC
, NULL
, ROUTE_TBL_OUT_MASK
,
1908 { &hf_mle_tlv_route64_nbr_in
,
1909 { "Neighbor In Link Quality",
1910 "mle.tlv.route64.nbr_in",
1911 FT_UINT8
, BASE_DEC
, NULL
, ROUTE_TBL_IN_MASK
,
1916 { &hf_mle_tlv_route64_cost
,
1918 "mle.tlv.route64.cost",
1919 FT_UINT8
, BASE_DEC
, NULL
, ROUTE_TBL_COST_MASK
,
1925 { &hf_mle_tlv_route64_unknown
,
1927 "mle.tlv.route64.unknown",
1928 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1934 { &hf_mle_tlv_metric_type_id_flags_l
,
1936 "mle.tlv.metric_type_id_flags.l",
1937 FT_UINT8
, BASE_HEX
, NULL
, 0x0,
1942 { &hf_mle_tlv_metric_type_id_flags_e
,
1944 "mle.tlv.metric_type_id_flags.e",
1945 FT_UINT8
, BASE_HEX
, NULL
, 0x0,
1950 { &hf_mle_tlv_metric_type_id_flags_type
,
1951 { "Type/average enum",
1952 "mle.tlv.metric_type_id_flags.type",
1953 FT_UINT8
, BASE_HEX
, NULL
, 0x0,
1958 { &hf_mle_tlv_metric_type_id_flags_metric
,
1960 "mle.tlv.metric_type_id_flags.metric",
1961 FT_UINT8
, BASE_HEX
, NULL
, 0x0,
1966 { &hf_mle_tlv_addr16
,
1969 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1974 { &hf_mle_tlv_leader_data_partition_id
,
1976 "mle.tlv.leader_data.partition_id",
1977 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
1982 { &hf_mle_tlv_leader_data_weighting
,
1984 "mle.tlv.leader_data.weighting",
1985 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1990 { &hf_mle_tlv_leader_data_version
,
1992 "mle.tlv.leader_data.data_version",
1993 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1998 { &hf_mle_tlv_leader_data_stable_version
,
1999 { "Stable Data Version",
2000 "mle.tlv.leader_data.stable_data_version",
2001 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
2006 { &hf_mle_tlv_leader_data_router_id
,
2007 { "Leader Router ID",
2008 "mle.tlv.leader_data.router_id",
2009 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
2015 { &hf_mle_tlv_network_data
,
2017 "mle.tlv.network_data",
2018 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
2019 "Network data (opaque data)",
2024 { &hf_mle_tlv_scan_mask_r
,
2026 "mle.tlv.scan_mask.r",
2027 FT_BOOLEAN
, 8, NULL
, SCAN_MASK_R_MASK
,
2032 { &hf_mle_tlv_scan_mask_e
,
2034 "mle.tlv.scan_mask.e",
2035 FT_BOOLEAN
, 8, NULL
, SCAN_MASK_D_MASK
,
2040 { &hf_mle_tlv_conn_flags
,
2042 "mle.tlv.conn.flags",
2043 FT_NONE
, BASE_NONE
, NULL
, 0x0,
2048 { &hf_mle_tlv_conn_flags_pp
,
2049 { "Parent Priority",
2050 "mle.tlv.conn.flags.pp",
2051 FT_INT8
, BASE_DEC
, VALS(mle_conn_tlv_flags_pp_enums
), CONN_MASK_FLAGS_PP_MASK
,
2056 { &hf_mle_tlv_conn_lq3
,
2059 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
2064 { &hf_mle_tlv_conn_lq2
,
2067 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
2072 { &hf_mle_tlv_conn_lq1
,
2075 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
2080 { &hf_mle_tlv_conn_leader_cost
,
2082 "mle.tlv.conn.leader_cost",
2083 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
2088 { &hf_mle_tlv_conn_id_seq
,
2090 "mle.tlv.conn.id_seq",
2091 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
2096 { &hf_mle_tlv_conn_active_rtrs
,
2098 "mle.tlv.conn.active_rtrs",
2099 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
2104 { &hf_mle_tlv_conn_sed_buf_size
,
2105 { "SED Buffer Size",
2106 "mle.tlv.conn.sed_buf_size",
2107 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2112 { &hf_mle_tlv_conn_sed_dgram_cnt
,
2113 { "SED Datagram Count",
2114 "mle.tlv.conn.sed_dgram_cnt",
2115 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
2120 { &hf_mle_tlv_link_margin
,
2122 "mle.tlv.link_margin",
2123 FT_UINT8
, BASE_DEC
, NULL
, 0,
2124 "Link margin in dB",
2128 { &hf_mle_tlv_status
,
2131 FT_UINT8
, BASE_DEC
, VALS(mle_status_tlv_enums
), 0,
2136 { &hf_mle_tlv_version
,
2139 FT_UINT16
, BASE_DEC
, NULL
, 0,
2144 { &hf_mle_tlv_supervision_interval
,
2145 { "Supervision Interval",
2146 "mle.tlv.supervision_interval",
2147 FT_UINT16
, BASE_DEC
, NULL
, 0,
2152 { &hf_mle_tlv_addr_reg_entry
,
2153 { "Address Registration Entry",
2155 FT_NONE
, BASE_NONE
, NULL
, 0x0,
2160 { &hf_mle_tlv_addr_reg_iid_type
,
2162 "mle.tlv.addr_reg_iid_type",
2163 FT_BOOLEAN
, 8, TFS(&mle_tlv_addr_reg_iid_type
), ADDR_REG_MASK_IID_TYPE_MASK
,
2168 { &hf_mle_tlv_addr_reg_cid
,
2170 "mle.tlv.addr_reg_cid",
2171 FT_UINT8
, BASE_DEC
, NULL
, ADDR_REG_MASK_CID_MASK
,
2172 "6LoWPAN Context ID",
2176 { &hf_mle_tlv_addr_reg_iid
,
2178 "mle.tlv.addr_reg_iid",
2179 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
2180 "Interface identifier",
2184 { &hf_mle_tlv_addr_reg_ipv6
,
2186 "mle.tlv.addr_reg_ipv6",
2187 FT_IPv6
, BASE_NONE
, NULL
, 0x0,
2193 { &hf_mle_tlv_hold_time
,
2195 "mle.tlv.hold_time",
2196 FT_UINT16
, BASE_DEC
, NULL
, 0,
2202 { &hf_mle_tlv_network_unknown
,
2204 "mle.tlv.network.unknown",
2205 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
2210 { &hf_mle_tlv_channel_page
,
2212 "mle.tlv.channel_page",
2213 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
2218 { &hf_mle_tlv_channel
,
2221 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2226 { &hf_mle_tlv_csl_accuracy
,
2228 "mle.tlv.csl_accuracy",
2229 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
2234 { &hf_mle_tlv_csl_clock_accuracy
,
2235 { "CSL Clock Accuracy",
2236 "mle.tlv.csl_clock_accuracy",
2237 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
2242 { &hf_mle_tlv_csl_uncertainty
,
2243 { "CSL Uncertainty",
2244 "mle.tlv.csl_uncertainty",
2245 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
2250 { &hf_mle_tlv_pan_id
,
2253 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
2258 { &hf_mle_tlv_active_tstamp
,
2259 { "Active Timestamp",
2260 "mle.tlv.active_tstamp",
2261 FT_ABSOLUTE_TIME
, ABSOLUTE_TIME_LOCAL
, NULL
, 0x0,
2266 { &hf_mle_tlv_pending_tstamp
,
2267 { "Pending Timestamp",
2268 "mle.tlv.pending_tstamp",
2269 FT_ABSOLUTE_TIME
, ABSOLUTE_TIME_LOCAL
, NULL
, 0x0,
2275 { &hf_mle_tlv_active_op_dataset
,
2276 { "Active Operational Dataset",
2277 "mle.tlv.active_op_dataset",
2278 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
2279 "Thread Active Operational Dataset",
2283 { &hf_mle_tlv_pending_op_dataset
,
2284 { "Pending Operational Dataset",
2285 "mle.tlv.pending_op_dataset",
2286 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
2287 "Thread Pending Operational Dataset",
2292 { &hf_mle_tlv_link_query_options
,
2293 { "Link Query options",
2294 "mle.tlv.link_query_options",
2295 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
2300 { &hf_mle_tlv_csl_sychronized_timeout
,
2301 { "CSL Synchronized Timeout",
2302 "mle.tlv.link_csl_synchronized_timeout",
2303 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
2304 "Thread CSL Synchronized Timeout",
2308 { &hf_mle_tlv_link_enh_ack_flags
,
2310 "mle.tlv.link_enh_ack_flags",
2311 FT_UINT8
, BASE_DEC
, VALS(mle_tlv_link_enh_ack_flags_vals
), 0x0,
2312 "Thread Enh-ACK Flags",
2316 { &hf_mle_tlv_link_requested_type_id_flags
,
2317 { "Requested Type ID flags",
2318 "mle.tlv.link_requested_type_id_flags",
2319 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
2320 "Thread Requested Type ID flags",
2324 { &hf_mle_tlv_link_forward_series
,
2325 { "Link Forward Series",
2326 "mle.tlv.link_forward_series",
2327 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
2332 { &hf_mle_tlv_link_forward_series_flags
,
2333 { "Link Forward Series Flags",
2334 "mle.tlv.link_forward_series_flags",
2335 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
2340 { &hf_mle_tlv_link_timeout
,
2342 "mle.tlv.link_timeout",
2343 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
2348 { &hf_mle_tlv_link_concatenation_link_metric_typeid_flags
,
2349 { "Concatenation of Link Metric Type ID Flags",
2350 "mle.tlv.link_concatenation_link_metric_typeid_flags",
2351 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
2356 { &hf_mle_tlv_link_status
,
2358 "mle.tlv.link_status",
2359 FT_UINT8
, BASE_DEC
, VALS(mle_tlv_link_param_vals
), 0x0,
2364 { &hf_mle_tlv_link_status_sub_tlv
,
2365 { "Link Sub TLV Status",
2366 "mle.tlv.link_status_sub_tlv",
2367 FT_UINT8
, BASE_DEC
, VALS(mle_tlv_link_sub_tlv_vals
), 0x0,
2368 "Thread Link Sub TLV Status",
2372 { &hf_mle_tlv_link_sub_tlv
,
2373 { "Link Metrics Sub TLV",
2374 "mle.tlv.link_sub_tlv",
2375 FT_UINT8
, BASE_DEC
, VALS(mle_tlv_link_param_vals
), 0x0,
2380 { &hf_mle_tlv_metric_type_id_flags
,
2381 { "Metric Type ID Flags",
2382 "mle.tlv.metric_type_id_flags",
2383 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
2384 "Thread Metric Type ID Flags",
2388 { &hf_mle_tlv_value
,
2391 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
2396 { &hf_mle_tlv_query_id
,
2399 FT_UINT8
, BASE_HEX
, NULL
, 0x0,
2407 static int *ett
[] = {
2409 &ett_mle_auxiliary_security
,
2410 &ett_mle_aux_sec_control
,
2411 &ett_mle_aux_sec_key_id
,
2420 static ei_register_info ei
[] = {
2421 { &ei_mle_cbc_mac_failed
, { "mle.cbc_mac_failed", PI_UNDECODED
, PI_WARN
, "Call to ccm_cbc_mac() failed", EXPFILL
}},
2422 { &ei_mle_packet_too_small
, { "mle.packet_too_small", PI_UNDECODED
, PI_WARN
, "Packet was too small to include the CRC and MIC", EXPFILL
}},
2423 { &ei_mle_no_key
, { "mle.no_key", PI_UNDECODED
, PI_WARN
, "No encryption key set - can't decrypt", EXPFILL
}},
2424 { &ei_mle_decrypt_failed
, { "mle.decrypt_failed", PI_UNDECODED
, PI_WARN
, "Decrypt failed", EXPFILL
}},
2425 { &ei_mle_mic_check_failed
, { "mle.mic_check_failed", PI_UNDECODED
, PI_WARN
, "MIC check failed", EXPFILL
}},
2426 { &ei_mle_tlv_length_failed
, { "mle.tlv_length_failed", PI_UNDECODED
, PI_WARN
, "TLV Length inconsistent", EXPFILL
}},
2427 { &ei_mle_len_size_mismatch
, { "mle.len_size_mismatch", PI_UNDECODED
, PI_WARN
, "TLV Length & Size field disagree", EXPFILL
}},
2430 module_t
*mle_module
;
2431 expert_module_t
* expert_mle
;
2433 proto_mle
= proto_register_protocol("Mesh Link Establishment", "MLE", "mle");
2434 proto_register_field_array(proto_mle
, hf
, array_length(hf
));
2435 proto_register_subtree_array(ett
, array_length(ett
));
2436 expert_mle
= expert_register_protocol(proto_mle
);
2437 expert_register_field_array(expert_mle
, ei
, array_length(ei
));
2439 mle_handle
= register_dissector("mle", dissect_mle
, proto_mle
);
2441 mle_module
= prefs_register_protocol(proto_mle
, NULL
);
2443 prefs_register_bool_preference(mle_module
, "meshlink_mic_ok",
2444 "Dissect only good MIC",
2445 "Dissect payload only if MIC is valid.",
2448 /* setup registration for other dissectors to provide mle key hash algorithms */
2449 mle_key_hash_handlers
= wmem_tree_new(wmem_epan_scope());
2453 proto_reg_handoff_mle(void)
2455 thread_nwd_handle
= find_dissector_add_dependency("thread_nwd", proto_mle
);
2456 thread_mc_handle
= find_dissector_add_dependency("thread_meshcop", proto_mle
);
2458 //heur_dissector_add("stun", dissect_embeddedmle_heur, proto_mle);
2460 dissector_add_uint_range_with_preference("udp.port", UDP_PORT_MLE_RANGE
, mle_handle
);
2462 proto_ieee802154
= proto_get_id_by_filter_name(IEEE802154_PROTOABBREV_WPAN
);
2466 * Editor modelines - https://www.wireshark.org/tools/modelines.html
2471 * indent-tabs-mode: nil
2474 * vi: set shiftwidth=2 tabstop=8 expandtab
2475 * :indentSize=2:tabSize=8:noTabs=true: