Coverage Report

Created: 2026-09-28 06:52

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wireshark/epan/dissectors/packet-mle.c
Line
Count
Source
1
/* packet-mle.c
2
 * Routines for MLE packet dissection
3
 *
4
 * Colin O'Flynn <coflynn@newae.com>
5
 *
6
 * The entire security section of this is lifted from the IEEE 802.15.4
7
 * dissector, 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
11
 *
12
 * Thread parts added by Robert Cragie <robert.cragie@arm.com>
13
 *
14
 * Wireshark - Network traffic analyzer
15
 * By Gerald Combs <gerald@wireshark.org>
16
 * Copyright 1998 Gerald Combs
17
 *
18
 * SPDX-License-Identifier: GPL-2.0-or-later
19
 */
20
21
#include "config.h"
22
23
#include <math.h>
24
#include <epan/packet.h>
25
26
#include <epan/proto_data.h>
27
#include <epan/wmem_scopes.h>
28
#include <epan/expert.h>
29
#include <epan/prefs.h>
30
#include <epan/tfs.h>
31
#include <wsutil/array.h>
32
#include "packet-ieee802154.h"
33
#include "packet-mle.h"
34
35
1
#define MLE_32768_TO_NSEC_FACTOR ((double)30517.578125)
36
37
/* Forward declarations */
38
void proto_register_mle(void);
39
void proto_reg_handoff_mle(void);
40
41
static int proto_mle;
42
static int proto_ieee802154; /* cache 802.15.4 protocol ID */
43
44
/*  Registered fields for Auxiliary Security Header */
45
static int hf_mle_security_suite;
46
static int hf_mle_mic;
47
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;
89
#if 0
90
static int hf_mle_tlv_route64_unknown;
91
#endif
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;
98
#if 0
99
static int hf_mle_tlv_network_data;
100
#endif
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;
121
#if 0
122
static int hf_mle_tlv_hold_time;
123
#endif
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_synchronized_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;
134
#if 0
135
static int hf_mle_tlv_active_op_dataset; /* SPEC-472 */
136
static int hf_mle_tlv_pending_op_dataset; /* SPEC-472 */
137
#endif
138
139
//Added for Thread 1.2 support
140
/* New 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;
151
152
/*Link TLVs*/
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_link_forward_series;
157
static int hf_mle_tlv_link_concatenation_link_metric_typeid_flags;
158
static int hf_mle_tlv_link_timeout;
159
static int hf_mle_tlv_link_forward_series_flags;
160
161
162
/* End of New support */
163
164
165
static int ett_mle;
166
static int ett_mle_tlv;
167
static int ett_mle_neighbor;
168
static int ett_mle_router;
169
static int ett_mle_addr_reg;
170
static int ett_mle_conn_flg;
171
static int ett_mle_thread_nwd;
172
static int ett_mle_auxiliary_security;
173
static int ett_mle_aux_sec_control;
174
static int ett_mle_aux_sec_key_id;
175
176
static int hf_mle_aux_security_header;
177
static int hf_mle_aux_sec_security_control;
178
static int hf_mle_aux_sec_security_level;
179
static int hf_mle_aux_sec_key_id_mode;
180
static int hf_mle_aux_sec_frame_counter_suppression;
181
static int hf_mle_aux_sec_asn_in_nonce;
182
static int hf_mle_aux_sec_reserved;
183
static int hf_mle_aux_sec_frame_counter;
184
static int hf_mle_aux_sec_key_source;
185
static int hf_mle_aux_sec_key_source_bytes;
186
static int hf_mle_aux_sec_key_index;
187
188
static ieee802154_aux_sec_hf_t mle_aux_sec_hf;
189
190
static expert_field ei_mle_cbc_mac_failed;
191
static expert_field ei_mle_packet_too_small;
192
static expert_field ei_mle_no_key;
193
static expert_field ei_mle_decrypt_failed;
194
static expert_field ei_mle_mic_check_failed;
195
static expert_field ei_mle_tlv_length_failed;
196
static expert_field ei_mle_len_size_mismatch;
197
198
static dissector_handle_t mle_handle;
199
static dissector_handle_t thread_nwd_handle;
200
static dissector_handle_t thread_mc_handle;
201
202
16
#define UDP_PORT_MLE_RANGE    "19788" /* IANA registered */
203
204
/* boolean value set if the MIC must be ok before payload is dissected */
205
static bool mle_mic_ok;
206
207
static wmem_tree_t* mle_key_hash_handlers;
208
209
static const value_string mle_sec_suite_names[] = {
210
    { 0,   "802.15.4 Security" },
211
    { 255, "No Security" },
212
    { 0, NULL }
213
};
214
215
static const value_string mle_status_tlv_enums[] = {
216
    { 1, "Error" },
217
    { 2, "Duplicate Address Detected" },
218
    { 0, NULL }
219
};
220
221
static const value_string mle_conn_tlv_flags_pp_enums[] = {
222
    { 1, "High" },
223
    { 0, "Medium" },
224
    { -1, "Low" },
225
    { 0, NULL }
226
};
227
228
#define MLE_CMD_REQUEST               0
229
#define MLE_CMD_ACCEPT                1
230
#define MLE_CMD_ACCEPTREQ             2
231
#define MLE_CMD_REJECT                3
232
#define MLE_CMD_ADVERTISE             4
233
#define MLE_CMD_UPDATE                5
234
#define MLE_CMD_UPDATE_REQUEST        6
235
#define MLE_CMD_DATA_REQUEST          7
236
#define MLE_CMD_DATA_RESPONSE         8
237
#define MLE_CMD_PARENT_REQUEST        9
238
#define MLE_CMD_PARENT_RESPONSE       10
239
#define MLE_CMD_CHILD_ID_REQUEST      11
240
#define MLE_CMD_CHILD_ID_RESPONSE     12
241
#define MLE_CMD_CHILD_UPDATE_REQUEST  13
242
#define MLE_CMD_CHILD_UPDATE_RESPONSE 14
243
#define MLE_CMD_ANNOUNCE              15
244
#define MLE_CMD_DISCOVERY_REQUEST     16
245
#define MLE_CMD_DISCOVERY_RESPONSE    17
246
247
//Added new for Thread 1.2
248
#define MLE_CMD_LINK_METRICS_MANAGEMENT_REQUEST  18
249
#define MLE_CMD_LINK_METRICS_MANAGEMENT_RESPONSE 19
250
#define MLE_CMD_LINK_PROBE                       20
251
#define MLE_CMD_CIM_DISCOVERY_REQUEST                21
252
#define MLE_CMD_CIM_DISCOVERY_RESPONSE               22
253
#define MLE_CMD_CIM_ANNOUNCE                         23
254
255
static const value_string mle_command_vals[] = {
256
    { MLE_CMD_REQUEST,                  "Link Request" },
257
    { MLE_CMD_ACCEPT,                   "Link Accept" },
258
    { MLE_CMD_ACCEPTREQ,                "Link Accept and Request" },
259
    { MLE_CMD_REJECT,                   "Link Reject" },
260
    { MLE_CMD_ADVERTISE,                "Advertisement" },
261
    { MLE_CMD_UPDATE,                   "Update" },
262
    { MLE_CMD_UPDATE_REQUEST,           "Update Request" },
263
    { MLE_CMD_DATA_REQUEST,             "Data Request" },
264
    { MLE_CMD_DATA_RESPONSE,            "Data Response" },
265
    { MLE_CMD_PARENT_REQUEST,           "Parent Request" },
266
    { MLE_CMD_PARENT_RESPONSE,          "Parent Response" },
267
    { MLE_CMD_CHILD_ID_REQUEST,         "Child ID Request" },
268
    { MLE_CMD_CHILD_ID_RESPONSE,        "Child ID Response" },
269
    { MLE_CMD_CHILD_UPDATE_REQUEST,     "Child Update Request" },
270
    { MLE_CMD_CHILD_UPDATE_RESPONSE,    "Child Update Response" },
271
    { MLE_CMD_ANNOUNCE,                 "Announce" },
272
    { MLE_CMD_DISCOVERY_REQUEST,        "Discovery Request" },
273
    { MLE_CMD_DISCOVERY_RESPONSE,       "Discovery Response" },
274
    { MLE_CMD_LINK_METRICS_MANAGEMENT_REQUEST, "Link Metrics Management Request" },
275
    { MLE_CMD_LINK_METRICS_MANAGEMENT_RESPONSE, "Link Metrics Management Response" },
276
    { MLE_CMD_LINK_PROBE, "Link Probe" },
277
    { MLE_CMD_CIM_DISCOVERY_REQUEST,    "CIM Discovery Request" },
278
    { MLE_CMD_CIM_DISCOVERY_RESPONSE,   "CIM Discovery Response" },
279
    { MLE_CMD_CIM_ANNOUNCE,             "CIM Announce" },
280
    { 0, NULL}
281
};
282
283
2.08k
#define MLE_TLV_SOURCE_ADDRESS              0
284
325
#define MLE_TLV_MODE                        1  /* Modified in Ch04_Mesh Link Establishment */
285
132
#define MLE_TLV_TIMEOUT                     2
286
135
#define MLE_TLV_CHALLENGE                   3
287
73
#define MLE_TLV_RESPONSE                    4
288
22
#define MLE_TLV_LINK_LAYER_FRAME_COUNTER    5
289
353
#define MLE_TLV_LINK_QUALITY                6
290
113
#define MLE_TLV_NETWORK_PARAMETER           7
291
90
#define MLE_TLV_MLE_FRAME_COUNTER           8
292
109
#define MLE_TLV_ROUTE64                     9  /* Defined in Ch05_Network Layer v1.1-rc1 */
293
43
#define MLE_TLV_ADDRESS16                   10 /* Defined in Ch04_Mesh Link Establishment v1.1-rc1 */
294
19
#define MLE_TLV_LEADER_DATA                 11 /* Defined in Ch04_Mesh Link Establishment v1.1-rc1 */
295
49
#define MLE_TLV_NETWORK_DATA                12 /* Defined in Ch05_Network Layer v1.1-rc1 */
296
37
#define MLE_TLV_TLV_REQUEST                 13 /* Defined in Ch04_Mesh Link Establishment v1.1-rc1 */
297
19
#define MLE_TLV_SCAN_MASK                   14 /* Defined in Ch04_Mesh Link Establishment v1.1-rc1 */
298
21
#define MLE_TLV_CONNECTIVITY                15 /* Defined in Ch04_Mesh Link Establishment v1.1-rc1 */
299
21
#define MLE_TLV_LINK_MARGIN                 16 /* Defined in Ch04_Mesh Link Establishment v1.1-rc1 */
300
15
#define MLE_TLV_STATUS                      17 /* Defined in Ch04_Mesh Link Establishment v1.1-rc1 */
301
11
#define MLE_TLV_VERSION                     18 /* Defined in Ch04_Mesh Link Establishment v1.1-rc1 */
302
46
#define MLE_TLV_ADDRESS_REGISTRATION        19 /* Defined in Ch04_Mesh Link Establishment v1.1-rc1 */
303
13
#define MLE_TLV_CHANNEL                     20 /* Defined in Ch04_Mesh Link Establishment v1.1-rc1 */
304
33
#define MLE_TLV_PAN_ID                      21 /* Defined in Ch04_Mesh Link Establishment v1.1-rc1 */
305
8
#define MLE_TLV_ACTIVE_TSTAMP               22 /* Defined in Ch04_Mesh Link Establishment v1.1-rc1 */
306
60
#define MLE_TLV_PENDING_TSTAMP              23 /* Defined in Ch04_Mesh Link Establishment v1.1-rc1 */
307
148
#define MLE_TLV_ACTIVE_OP_DATASET           24 /* Defined in Ch04_Mesh Link Establishment v1.1-rc1 */
308
152
#define MLE_TLV_PENDING_OP_DATASET          25 /* Defined in Ch04_Mesh Link Establishment v1.1-rc1 */
309
155
#define MLE_TLV_THREAD_DISCOVERY            26 /* Defined in Ch04_Mesh Link Establishment v1.1-rc1 */
310
35
#define MLE_TLV_SUPERVISION_INTERVAL        27 /* Defined in Ch04_Mesh Link Establishment v1.2-Draft3 */
311
#define MLE_TLV_CIM_PROVISIONER_INTERFACE_DATA 28 /* Defined in Ch04_Mesh Link Establishment v1.2-Draft3 */
312
#define MLE_TLV_CIM_PROVISIONING_DATASET    29 /* Defined in Ch04_Mesh Link Establishment v1.2-Draft3 */
313
#define MLE_TLV_CIM_DISCOVERY_REQUEST       30 /* Defined in Ch04_Mesh Link Establishment v1.2-Draft3 */
314
#define MLE_TLV_SECURE_DISSEMINATION        31 /* Defined in Ch04_Mesh Link Establishment v1.2-Draft3 */
315
316
#define MLE_TLV_CSL_CHANNEL                 80  /* Defined in Ch04_Mesh Link Establishment v1.2-Draft3 */
317
#define MLE_TLV_CSL_SYNCHRONIZED_TIMEOUT    85  /* Defined in Ch04_Mesh Link Establishment v1.2-Draft3 */
318
#define MLE_TLV_CSL_ACCURACY                86  /* Defined in Ch04_Mesh Link Establishment v1.2-Draft3 */
319
#define MLE_TLV_LINK_METRICS_QUERY          87  /* Defined in Ch04_Mesh Link Establishment v1.2-Draft3 */
320
#define MLE_TLV_LINK_METRICS_MANAGEMENT     88  /* Defined in Ch04_Mesh Link Establishment v1.2-Draft3 */
321
#define MLE_TLV_LINK_METRICS_REPORT         89  /* Defined in Ch04_Mesh Link Establishment v1.2-Draft3 */
322
#define MLE_TLV_LINK_PROBE                  90  /* Defined in Ch04_Mesh Link Establishment v1.2-Draft3 */
323
324
325
#define MLE_TLV_CIM_DEVICE_INTERFACE_DATA   27 /* Defined in Ch04_Mesh Link Establishment v1.2-Draft3 */
326
13
#define MLE_TLV_CIM_PROVISIONER_INTERFACE_DATA 28 /* Defined in Ch04_Mesh Link Establishment v1.2-Draft3 */
327
14
#define MLE_TLV_CIM_PROVISIONING_DATASET    29 /* Defined in Ch04_Mesh Link Establishment v1.2-Draft3 */
328
15
#define MLE_TLV_CIM_DISCOVERY_REQUEST       30 /* Defined in Ch04_Mesh Link Establishment v1.2-Draft3 */
329
15
#define MLE_TLV_SECURE_DISSEMINATION        31 /* Defined in Ch04_Mesh Link Establishment v1.2-Draft3 */
330
331
18
#define MLE_TLV_CSL_CHANNEL                 80  /* Defined in Ch04_Mesh Link Establishment v1.2-Draft3 */
332
10
#define MLE_TLV_CSL_SYNCHRONIZED_TIMEOUT    85  /* Defined in Ch04_Mesh Link Establishment v1.2-Draft3 */
333
51
#define MLE_TLV_CSL_ACCURACY                86  /* Defined in Ch04_Mesh Link Establishment v1.2-Draft3 */
334
7
#define MLE_TLV_LINK_METRICS_QUERY          87  /* Defined in Ch04_Mesh Link Establishment v1.2-Draft3 */
335
32
#define MLE_TLV_LINK_METRICS_MANAGEMENT     88  /* Defined in Ch04_Mesh Link Establishment v1.2-Draft3 */
336
39
#define MLE_TLV_LINK_METRICS_REPORT         89  /* Defined in Ch04_Mesh Link Establishment v1.2-Draft3 */
337
172
#define MLE_TLV_LINK_PROBE                  90  /* Defined in Ch04_Mesh Link Establishment v1.2-Draft3 */
338
339
static const value_string mle_tlv_vals[] = {
340
    { MLE_TLV_SOURCE_ADDRESS,           "Source Address" },
341
    { MLE_TLV_MODE,                     "Mode" },
342
    { MLE_TLV_TIMEOUT,                  "Timeout" },
343
    { MLE_TLV_CHALLENGE,                "Challenge" },
344
    { MLE_TLV_RESPONSE,                 "Response" },
345
    { MLE_TLV_LINK_LAYER_FRAME_COUNTER, "Link Layer Frame Counter"},
346
    { MLE_TLV_LINK_QUALITY,             "Link Quality"},
347
    { MLE_TLV_NETWORK_PARAMETER,        "Network Parameter"},
348
    { MLE_TLV_MLE_FRAME_COUNTER,        "MLE Frame Counter"},
349
    { MLE_TLV_ROUTE64,                  "Route64"},
350
    { MLE_TLV_ADDRESS16,                "Address16"},
351
    { MLE_TLV_LEADER_DATA,              "Leader Data"},
352
    { MLE_TLV_NETWORK_DATA,             "Network Data"},
353
    { MLE_TLV_TLV_REQUEST,              "TLV Request"},
354
    { MLE_TLV_SCAN_MASK,                "Scan Mask"},
355
    { MLE_TLV_CONNECTIVITY,             "Connectivity"},
356
    { MLE_TLV_LINK_MARGIN,              "Link Margin"},
357
    { MLE_TLV_STATUS,                   "Status"},
358
    { MLE_TLV_VERSION,                  "Version"},
359
    { MLE_TLV_ADDRESS_REGISTRATION,     "Address Registration"},
360
    { MLE_TLV_CHANNEL,                  "Channel"},
361
    { MLE_TLV_PAN_ID,                   "PAN ID"},
362
    { MLE_TLV_ACTIVE_TSTAMP,            "Active Timestamp"},
363
    { MLE_TLV_PENDING_TSTAMP,           "Pending Timestamp"},
364
    { MLE_TLV_ACTIVE_OP_DATASET,        "Active Operational Dataset"},
365
    { MLE_TLV_PENDING_OP_DATASET,       "Pending Operational Dataset"},
366
    { MLE_TLV_THREAD_DISCOVERY,         "Thread Discovery"},
367
    { MLE_TLV_SUPERVISION_INTERVAL,     "Supervision Interval"},
368
    { MLE_TLV_CSL_CHANNEL,              "CSL Channel"},
369
    { MLE_TLV_CSL_SYNCHRONIZED_TIMEOUT, "CSL Synchronized Timeout"},
370
    { MLE_TLV_CSL_ACCURACY,             "CSL Accuracy"},
371
    { MLE_TLV_LINK_METRICS_QUERY,       "Link Metrics Query"},
372
    { MLE_TLV_LINK_METRICS_MANAGEMENT,  "Link Metrics Management"},
373
    { MLE_TLV_LINK_METRICS_REPORT,      "Link Metrics Report"},
374
    { MLE_TLV_LINK_PROBE,               "Link Probe"},
375
    { 0, NULL}
376
};
377
378
/*Link Metrics*/
379
730
#define LINK_METRICS_REPORT_SUB_TLV          0
380
243
#define LINK_METRICS_QUERY_ID_SUB_TLV        1
381
52
#define LINK_METRICS_QUERY_OPTIONS_SUB_TLV   2
382
47
#define FORWARD_PROBING_REGISTRATION_SUB_TLV 3
383
//#define REVERSE_PROBING_REGISTRATION_SUB_TLV 4
384
52
#define LINK_METRICS_STATUS_SUB_TLV          5
385
//#define LINK_METRICS_TRACKING_CAPABILITIES_SUB_TLV   6
386
39
#define ENHANCED_ACK_LINK_METRICS_CONFIGURATION_SUB_TLV 7
387
388
static const value_string mle_tlv_link_param_vals[] = {
389
    { LINK_METRICS_REPORT_SUB_TLV,                      "Links Metrics Report" },
390
    { LINK_METRICS_QUERY_ID_SUB_TLV,                    "Link Metrics Query" },
391
    { LINK_METRICS_QUERY_OPTIONS_SUB_TLV,               "Link Metrics Query Options" },
392
    { FORWARD_PROBING_REGISTRATION_SUB_TLV ,            "Forward Probing Registration" },
393
    { LINK_METRICS_STATUS_SUB_TLV ,                     "Link Metrics Status" },
394
    { ENHANCED_ACK_LINK_METRICS_CONFIGURATION_SUB_TLV , "Enhance Ack Link Metrics Configuration" },
395
    { 0, NULL}
396
};
397
398
#define LINK_SUCCESS                                        0
399
#define LINK_FAILURE_CANNOT_SUPPORT_NEW_SERIES_REGISTRATION 1
400
#define LINK_FAILURE_SERIES_ID_ALREADY_REGISTERED           2
401
#define LINK_FAILURE_SERIES_ID_NOT_RECOGNIZED               3
402
#define LINK_FAILURE_NO_MATCHING_FRAMES_RECEIVED            4
403
#define LINK_FAILURE_OTHER_FAILURE                          254
404
405
static const value_string mle_tlv_link_sub_tlv_vals[] = {
406
    { LINK_SUCCESS,                                         "Success" },
407
    { LINK_FAILURE_CANNOT_SUPPORT_NEW_SERIES_REGISTRATION,  " Failure - Cannot Support New Series Registration" },
408
    { LINK_FAILURE_SERIES_ID_ALREADY_REGISTERED ,           "Failure - Series ID Already Registered" },
409
    { LINK_FAILURE_SERIES_ID_NOT_RECOGNIZED ,               "Failure - Series ID not Recognized" },
410
    { LINK_FAILURE_NO_MATCHING_FRAMES_RECEIVED ,            "Failure - No matching frames received" },
411
    { LINK_FAILURE_OTHER_FAILURE ,                          "Failure - Other Failure" },
412
    { 0, NULL}
413
};
414
415
#define CLEAR_ENHANCED_ACK_LINK_METRICS_CONFIGURATION     0
416
#define REGISTER_ENHANCED_ACK_LINK_METRICS_CONFIGURATION  1
417
418
static const value_string mle_tlv_link_enh_ack_flags_vals[] = {
419
    { CLEAR_ENHANCED_ACK_LINK_METRICS_CONFIGURATION,    "Clear Enhanced ACK Link Metrics Configuration" },
420
    { REGISTER_ENHANCED_ACK_LINK_METRICS_CONFIGURATION, "Register Enhanced ACK Link Metrics Configuration" },
421
    { 0, NULL}
422
};
423
424
/* Link Metrics End*/
425
426
#define LINK_SUCCESS                                        0
427
#define LINK_FAILURE_CANNOT_SUPPORT_NEW_SERIES_REGISTRATION 1
428
#define LINK_FAILURE_SERIES_ID_ALREADY_REGISTERED           2
429
#define LINK_FAILURE_SERIES_ID_NOT_RECOGNIZED               3
430
#define LINK_FAILURE_NO_MATCHING_FRAMES_RECEIVED            4
431
#define LINK_FAILURE_OTHER_FAILURE                          254
432
433
16
#define LQI_FLAGS_C         0x80
434
369
#define LQI_FLAGS_SIZE      0x0F
435
436
16
#define NEIGHBOR_FLAG_I     0x80
437
16
#define NEIGHBOR_FLAG_O     0x40
438
16
#define NEIGHBOR_FLAG_P     0x20
439
440
15
#define NETWORK_PARAM_ID_CHANNEL        0
441
3
#define NETWORK_PARAM_ID_PAN_ID         1
442
2
#define NETWORK_PARAM_ID_PERMIT_JOIN    2
443
0
#define NETWORK_PARAM_ID_BCN_PAYLOAD    3
444
445
static const value_string mle_tlv_nwk_param_vals[] = {
446
    { NETWORK_PARAM_ID_CHANNEL,     "Channel" },
447
    { NETWORK_PARAM_ID_PAN_ID,      "PAN ID" },
448
    { NETWORK_PARAM_ID_PERMIT_JOIN, "Permit Join" },
449
    { NETWORK_PARAM_ID_BCN_PAYLOAD, "Beacon Payload" },
450
    { 0, NULL}
451
};
452
453
static const true_false_string mle_tlv_mode_device_type = {
454
    "FFD",
455
    "RFD"
456
};
457
static const true_false_string mle_tlv_mode_nwk_data = {
458
    "Full",
459
    "Stable"
460
};
461
static const true_false_string mle_tlv_addr_reg_iid_type = {
462
    "Compressed",
463
    "Full"
464
};
465
466
16
#define ROUTE_TBL_OUT_MASK          0xC0
467
16
#define ROUTE_TBL_IN_MASK           0x30
468
16
#define ROUTE_TBL_COST_MASK         0x0F
469
470
16
#define SCAN_MASK_R_MASK            0x80
471
16
#define SCAN_MASK_D_MASK            0x40
472
473
16
#define CONN_MASK_FLAGS_PP_MASK     0xC0
474
475
232
#define ADDR_REG_MASK_IID_TYPE_MASK 0x80
476
16
#define ADDR_REG_MASK_CID_MASK      0x0F
477
478
16
#define MLE_CMD_CINFO_SEC_DATA_REQ  0x04
479
16
#define MLE_CMD_CINFO_NWK_DATA      0x01
480
481
/*FUNCTION:------------------------------------------------------
482
 *  NAME
483
 *      dissect_mle_decrypt
484
 *  DESCRIPTION
485
 *      MLE dissector.
486
 *  PARAMETERS
487
 *      tvbuff_t * tvb                           - IEEE 802.15.4 packet.
488
 *      unsigned offset                          - Offset where the ciphertext 'c' starts.
489
 *      packet_info * pinfo                      - Packet info structure.
490
 *      ieee802154_packet * packet               - IEEE 802.15.4 packet information.
491
 *      ieee802154_decrypt_info_t * decrypt_info - information for decryption
492
 *      unsigned char * key                      - key for decryption
493
 *  RETURNS
494
 *      tvbuff_t *                               - Decrypted payload.
495
 *---------------------------------------------------------------
496
 */
497
static tvbuff_t *
498
dissect_mle_decrypt(tvbuff_t * tvb,
499
                    unsigned offset,
500
                    packet_info * pinfo,
501
                    ieee802154_packet * packet,
502
                    ieee802154_decrypt_info_t * decrypt_info,
503
                    unsigned char * key)
504
0
{
505
0
    tvbuff_t *          ptext_tvb;
506
0
    bool                have_mic = false;
507
0
    uint64_t            srcAddr;
508
0
    unsigned char       tmp[16];
509
0
    unsigned            M;
510
0
    int                 captured_len;
511
0
    int                 reported_len;
512
513
0
    *decrypt_info->rx_mic_length = 0;
514
0
    memset(decrypt_info->rx_mic, 0, 16);
515
516
    /* Get the captured and on-the-wire length of the payload. */
517
0
    if (packet->security_level > 0) {
518
0
        M = IEEE802154_MIC_LENGTH(packet->security_level);
519
0
    }
520
0
    else {
521
0
        M = 0;
522
0
    }
523
524
0
    reported_len = tvb_reported_length_remaining(tvb, offset) - M;
525
0
    if (reported_len < 0) {
526
0
        *decrypt_info->status = DECRYPT_PACKET_TOO_SMALL;
527
0
        return NULL;
528
0
    }
529
    /* Check if the payload is truncated.  */
530
0
    if (tvb_bytes_exist(tvb, offset, reported_len)) {
531
0
        captured_len = reported_len;
532
0
    }
533
0
    else {
534
0
        captured_len = tvb_captured_length_remaining(tvb, offset);
535
0
    }
536
537
0
    if (packet->security_level > 0) {
538
        /* Check if the MIC is present in the captured data. */
539
0
        have_mic = tvb_bytes_exist(tvb, offset + reported_len, M);
540
0
        if (have_mic) {
541
0
            tvb_memcpy(tvb, decrypt_info->rx_mic, offset + reported_len, M);
542
0
        }
543
0
    }
544
545
    /*=====================================================
546
     * Key Lookup - Need to find the appropriate key.
547
     *=====================================================
548
     */
549
0
    if (packet->src_addr_mode == IEEE802154_FCF_ADDR_EXT) {
550
        /* The source EUI-64 is included in the headers. */
551
0
        srcAddr = packet->src64; /* GUINT64_SWAP_LE_BE(packet->src64); */
552
0
    }
553
0
    else {
554
        /* Lookup failed.  */
555
0
        *decrypt_info->status = DECRYPT_PACKET_NO_EXT_SRC_ADDR;
556
0
        return NULL;
557
0
    }
558
559
    /*=====================================================
560
     * CCM* - CTR mode payload encryption
561
     *=====================================================
562
     */
563
    /* Create the CCM* initial block for decryption (Adata=0, M=0, counter=0). */
564
0
    ccm_init_block(tmp, false, 0, srcAddr, packet->frame_counter, packet->security_level, 0, NULL);
565
566
    /* Decrypt the ciphertext, and place the plaintext in a new tvb. */
567
0
    if (IEEE802154_IS_ENCRYPTED(packet->security_level) && captured_len) {
568
0
        uint8_t *text;
569
570
        /*
571
         * Make a copy of the ciphertext in heap memory.
572
         *
573
         * We will decrypt the message in-place and then use the buffer as the
574
         * real data for the new tvb.
575
         */
576
0
        text = (uint8_t *)tvb_memdup(pinfo->pool, tvb, offset, captured_len);
577
578
        /* Perform CTR-mode transformation. Try both the likely key and the alternate key */
579
0
        if (!ccm_ctr_encrypt(key, tmp, decrypt_info->rx_mic, text, captured_len)) {
580
0
            *decrypt_info->status = DECRYPT_PACKET_DECRYPT_FAILED;
581
0
            return NULL;
582
0
        }
583
584
        /* Create a tvbuff for the plaintext. */
585
0
        ptext_tvb = tvb_new_real_data((const uint8_t *)text, captured_len, reported_len);
586
0
        tvb_set_child_real_data_tvbuff(tvb, ptext_tvb);
587
0
        add_new_data_source(pinfo, ptext_tvb, "Decrypted MLE payload");
588
0
        *decrypt_info->status = DECRYPT_PACKET_SUCCEEDED;
589
0
    }
590
    /* There is no ciphertext. Wrap the plaintext in a new tvb. */
591
0
    else {
592
        /* Decrypt the MIC (if present). */
593
0
        if (have_mic) {
594
0
            if (!ccm_ctr_encrypt(key, tmp, decrypt_info->rx_mic, NULL, 0)) {
595
0
                *decrypt_info->status = DECRYPT_PACKET_DECRYPT_FAILED;
596
0
                return NULL;
597
0
            }
598
0
        }
599
600
        /* Create a tvbuff for the plaintext. This might result in a zero-length tvbuff. */
601
0
        ptext_tvb = tvb_new_subset_length(tvb, offset, reported_len);
602
0
        *decrypt_info->status = DECRYPT_PACKET_SUCCEEDED;
603
0
    }
604
605
    /*=====================================================
606
     * CCM* - CBC-mode message authentication
607
     *=====================================================
608
     */
609
    /* We can only verify the message if the MIC wasn't truncated. */
610
0
    if (have_mic) {
611
0
        unsigned char           dec_mic[16];
612
0
        unsigned                l_m = captured_len;
613
0
        unsigned                l_a;
614
0
        uint8_t                 d_a[256];
615
616
0
        DISSECTOR_ASSERT(pinfo->src.len == 16);
617
0
        DISSECTOR_ASSERT(pinfo->dst.len == 16);
618
0
        memcpy(d_a, pinfo->src.data, pinfo->src.len);
619
0
        memcpy(d_a+16, pinfo->dst.data, pinfo->dst.len);
620
621
0
        tvb_memcpy(tvb, d_a+32, decrypt_info->aux_offset, decrypt_info->aux_length);
622
0
        l_a = 32 + decrypt_info->aux_length;
623
624
        /* Adjust the lengths of the plantext and additional data if unencrypted. */
625
0
        if (!IEEE802154_IS_ENCRYPTED(packet->security_level)) {
626
0
            l_a += l_m;
627
0
            l_m = 0;
628
0
        }
629
630
        /* Create the CCM* initial block for authentication (Adata!=0, M!=0, counter=l(m)). */
631
0
        ccm_init_block(tmp, true, M, srcAddr, packet->frame_counter, packet->security_level, l_m, NULL);
632
633
        /* Compute CBC-MAC authentication tag. */
634
        /*
635
         * And yes, despite the warning in tvbuff.h, I think tvb_get_ptr is the
636
         * right function here since either A) the payload wasn't encrypted, in
637
         * which case l_m is zero, or B) the payload was encrypted, and the tvb
638
         * already points to contiguous memory, since we just allocated it in
639
         * decryption phase.
640
         */
641
0
        if (!ccm_cbc_mac(key, tmp, d_a, l_a, tvb_get_ptr(ptext_tvb, 0, l_m), l_m, dec_mic)) {
642
0
            *decrypt_info->status = DECRYPT_PACKET_MIC_CHECK_FAILED;
643
0
        }
644
        /* Compare the received MIC with the one we generated. */
645
0
        else if (memcmp(decrypt_info->rx_mic, dec_mic, M) != 0) {
646
0
            *decrypt_info->status = DECRYPT_PACKET_MIC_CHECK_FAILED;
647
0
        }
648
0
    }
649
650
0
    *decrypt_info->rx_mic_length = M;
651
652
    /* Done! */
653
0
    return ptext_tvb;
654
0
} /* dissect_mle_decrypt */
655
656
void register_mle_key_hash_handler(unsigned hash_identifier, ieee802154_set_key_func key_func)
657
16
{
658
    /* Ensure no duplication */
659
16
    DISSECTOR_ASSERT(wmem_tree_lookup32(mle_key_hash_handlers, hash_identifier) == NULL);
660
661
16
    wmem_tree_insert32(mle_key_hash_handlers, hash_identifier, (void*)key_func);
662
16
}
663
664
/* Set MLE key function. */
665
static unsigned ieee802154_set_mle_key(ieee802154_packet *packet, unsigned char *key, unsigned char *alt_key, ieee802154_key_t *uat_key)
666
0
{
667
0
    ieee802154_set_key_func func = (ieee802154_set_key_func)wmem_tree_lookup32(mle_key_hash_handlers, uat_key->hash_type);
668
669
0
    if (func != NULL)
670
0
        return func(packet, key, alt_key, uat_key);
671
672
    /* Right now, KEY_HASH_NONE and KEY_HASH_ZIP are not registered because they
673
        work with this "default" behavior */
674
0
    if (packet->key_index == uat_key->key_index)
675
0
    {
676
0
        memcpy(key, uat_key->key, IEEE802154_CIPHER_SIZE);
677
0
        return 1;
678
0
    }
679
680
0
    return 0;
681
0
}
682
683
static int
684
dissect_mle(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
685
373
{
686
373
    tvbuff_t                *volatile payload_tvb = NULL;
687
373
    proto_tree              *volatile mle_tree = NULL;
688
373
    proto_item              *volatile proto_root = NULL;
689
690
373
    unsigned                offset = 0;
691
373
    unsigned                aux_header_offset = 0;
692
373
    ieee802154_decrypt_status status;
693
694
373
    proto_item              *ti;
695
373
    proto_item              *mic_item = NULL;
696
373
    proto_tree              *header_tree = NULL;
697
373
    uint8_t                 security_suite;
698
373
    unsigned                aux_length = 0;
699
373
    ieee802154_packet       *packet;
700
373
    ieee802154_packet       *original_packet;
701
373
    ieee802154_decrypt_info_t decrypt_info;
702
373
    ieee802154_hints_t      *ieee_hints;
703
373
    bool                    mic_ok=true;
704
705
373
    unsigned char           rx_mic[16];
706
373
    unsigned int            rx_mic_len = 0;
707
708
373
    uint8_t                 cmd;
709
373
    uint8_t                 tlv_type, tlv_len;
710
373
    proto_tree              *tlv_tree;
711
712
373
    ieee_hints = (ieee802154_hints_t *)p_get_proto_data(wmem_file_scope(), pinfo, proto_ieee802154, 0);
713
373
    if (ieee_hints == NULL) {
714
        /* For now, MLE only supported with IEEE802.15.4 as an underlying layer */
715
1
        return 0;
716
1
    }
717
372
    original_packet = (ieee802154_packet *)ieee_hints->packet;
718
719
372
    packet = wmem_new0(pinfo->pool, ieee802154_packet);
720
721
    /* Copy IEEE 802.15.4 Source Address */
722
372
    packet->src_addr_mode = original_packet->src_addr_mode;
723
372
    if (packet->src_addr_mode == IEEE802154_FCF_ADDR_EXT) {
724
0
        packet->src64 = original_packet->src64;
725
372
    } else {
726
372
        packet->src16 = original_packet->src16;
727
372
    }
728
729
    /* Copy IEEE 802.15.4 Source PAN ID */
730
372
    packet->src_pan = original_packet->src_pan;
731
732
372
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "MLE");
733
372
    col_clear(pinfo->cinfo,   COL_INFO);
734
735
    /* Create the protocol tree. */
736
372
    proto_root = proto_tree_add_item(tree, proto_mle, tvb, 0, tvb_reported_length(tvb), ENC_NA);
737
372
    mle_tree = proto_item_add_subtree(proto_root, ett_mle);
738
739
    /* Parse the security suite field. */
740
    /* Security Suite Field */
741
372
    proto_tree_add_item_ret_uint8(mle_tree, hf_mle_security_suite, tvb, offset, 1, ENC_NA, &security_suite);
742
372
    offset++;
743
744
372
    aux_header_offset = offset;
745
746
    /* Security material present if security suite = 0 */
747
372
    if (security_suite == 0) {
748
71
        dissect_ieee802154_aux_sec_header_and_key_with_hf(tvb, pinfo, mle_tree, packet, &offset, &mle_aux_sec_hf);
749
71
        aux_length = offset-aux_header_offset;
750
301
    } else {
751
301
        packet->security_level = SECURITY_LEVEL_NONE;
752
301
    }
753
754
372
    decrypt_info.key_number = 0;
755
756
    /* Add additional fields for security level > SECURITY_LEVEL_NONE */
757
372
    if (packet->security_level > SECURITY_LEVEL_NONE) {
758
759
        /* Pass to decryption process */
760
1
        decrypt_info.rx_mic = rx_mic;
761
1
        decrypt_info.rx_mic_length = &rx_mic_len;
762
1
        decrypt_info.aux_offset = aux_header_offset;
763
1
        decrypt_info.aux_length = aux_length;
764
1
        decrypt_info.status = &status;
765
766
1
        payload_tvb = decrypt_ieee802154_payload(tvb, offset, pinfo, header_tree, packet, &decrypt_info,
767
1
                                     ieee802154_set_mle_key, dissect_mle_decrypt);
768
1
        if (status == DECRYPT_PACKET_MIC_CHECK_FAILED)
769
0
            expert_add_info(pinfo, proto_root, &ei_mle_cbc_mac_failed);
770
771
        /* MIC */
772
1
        if (rx_mic_len) {
773
0
            mic_item = proto_tree_add_bytes(header_tree, hf_mle_mic, tvb, 0, rx_mic_len, rx_mic);
774
0
            proto_item_set_generated(mic_item);
775
0
        }
776
371
    } else {
777
371
        status = DECRYPT_NOT_ENCRYPTED;
778
371
    }
779
780
    /* Get the unencrypted data if decryption failed.  */
781
372
    if (!payload_tvb) {
782
        /* Deal with possible truncation and the FCS field at the end. */
783
372
        payload_tvb = tvb_new_subset_remaining(tvb, offset);
784
372
    }
785
786
    /* Display the reason for failure, and abort if the error was fatal. */
787
372
    switch (status) {
788
0
    case DECRYPT_PACKET_SUCCEEDED:
789
        /* No problem. */
790
0
        proto_item_append_text(mic_item, " [correct (key no. %d)]", decrypt_info.key_number);
791
0
        break;
792
793
0
    case DECRYPT_PACKET_TOO_SMALL:
794
0
        expert_add_info(pinfo, proto_root, &ei_mle_packet_too_small);
795
0
        call_data_dissector(payload_tvb, pinfo, tree);
796
0
        return tvb_captured_length(tvb);
797
798
1
    case DECRYPT_PACKET_NO_KEY:
799
1
        expert_add_info(pinfo, proto_root, &ei_mle_no_key);
800
1
        call_data_dissector(payload_tvb, pinfo, tree);
801
1
        return tvb_captured_length(tvb);
802
803
0
    case DECRYPT_PACKET_DECRYPT_FAILED:
804
0
        expert_add_info(pinfo, proto_root, &ei_mle_decrypt_failed);
805
0
        call_data_dissector(payload_tvb, pinfo, tree);
806
0
        return tvb_captured_length(tvb);
807
808
0
    case DECRYPT_PACKET_MIC_CHECK_FAILED:
809
0
        expert_add_info(pinfo, proto_root, &ei_mle_mic_check_failed);
810
0
        proto_item_append_text(mic_item, " [incorrect]");
811
        /*
812
         * Abort only if the payload was encrypted, in which case we
813
         * probably didn't decrypt the packet right (eg: wrong key).
814
         */
815
0
        if (IEEE802154_IS_ENCRYPTED(packet->security_level)) {
816
0
            mic_ok = false;
817
0
        }
818
0
        break;
819
371
    case DECRYPT_NOT_ENCRYPTED:
820
371
    default:
821
371
        break;
822
372
    }
823
    /* This can cause a lot of problems so remove it by default */
824
371
    if (!mic_ok && mle_mic_ok) {
825
0
        call_data_dissector(payload_tvb, pinfo, tree);
826
0
        col_set_str(pinfo->cinfo, COL_INFO, "MIC Failed");
827
0
        return tvb_captured_length(tvb);
828
0
    }
829
830
    /***** NEW CODE HERE ****/
831
    /* If we're good, carry on and display the MLE payload */
832
371
    offset = 0;
833
834
    /* MLE Command */
835
371
    proto_tree_add_item(mle_tree, hf_mle_command, payload_tvb, offset, 1, ENC_BIG_ENDIAN);
836
837
371
    cmd = tvb_get_uint8(payload_tvb, offset);
838
371
    col_add_str(pinfo->cinfo, COL_INFO, val_to_str(pinfo->pool, cmd, mle_command_vals, "Unknown (%x)"));
839
840
371
    offset++;
841
842
    /* MLE TLVs */
843
4.83k
    while (tvb_offset_exists(payload_tvb, offset)) {
844
845
        /* Get the length ahead of time to pass to next function so we can highlight
846
           proper amount of bytes */
847
4.80k
        tlv_len = tvb_get_uint8(payload_tvb, offset+1);
848
849
4.80k
        ti = proto_tree_add_item(mle_tree, hf_mle_tlv, payload_tvb, offset, tlv_len+2, ENC_NA);
850
4.80k
        tlv_tree = proto_item_add_subtree(ti, ett_mle_tlv);
851
852
        /* Type */
853
4.80k
        proto_tree_add_item_ret_uint8(tlv_tree, hf_mle_tlv_type, payload_tvb, offset, 1, ENC_NA, &tlv_type);
854
4.80k
        offset++;
855
856
        /* Add value name to value root label */
857
4.80k
        proto_item_append_text(ti, " (%s", val_to_str(pinfo->pool, tlv_type, mle_tlv_vals, "Unknown (%d)"));
858
859
        /* Length */
860
4.80k
        proto_tree_add_item(tlv_tree, hf_mle_tlv_length, payload_tvb, offset, 1, ENC_BIG_ENDIAN);
861
4.80k
        offset++;
862
863
4.80k
        switch(tlv_type){
864
2.08k
            case MLE_TLV_SOURCE_ADDRESS:
865
2.08k
                {
866
2.08k
                    bool haveShortTLV = false;
867
2.08k
                    uint16_t shortAddr = 0;
868
869
2.08k
                    if (!((tlv_len == 2) || (tlv_len == 8))) {
870
                        /* TLV Length must be 2 or 8 */
871
2.04k
                        expert_add_info(pinfo, proto_root, &ei_mle_tlv_length_failed);
872
2.04k
                        proto_tree_add_item(tlv_tree, hf_mle_tlv_unknown, payload_tvb, offset, tlv_len, ENC_NA);
873
2.04k
                        offset += tlv_len;
874
2.04k
                    } else {
875
36
                        if (tlv_len == 2) {
876
17
                            haveShortTLV = true;
877
17
                            shortAddr = tvb_get_ntohs(payload_tvb, offset);
878
17
                        }
879
880
36
                        proto_tree_add_item(tlv_tree, hf_mle_tlv_source_addr, payload_tvb, offset, tlv_len, ENC_NA);
881
36
                        proto_item_append_text(ti, " = ");
882
222
                        while (tlv_len) {
883
186
                            uint8_t addr;
884
186
                            addr = tvb_get_uint8(payload_tvb, offset);
885
186
                            proto_item_append_text(ti, "%02x", addr);
886
186
                            if (--tlv_len) {
887
150
                                proto_item_append_text(ti, ":");
888
150
                            }
889
186
                            offset++;
890
186
                        }
891
36
                        if ((original_packet->src_addr_mode == IEEE802154_FCF_ADDR_EXT) && haveShortTLV) {
892
                            /* Source TLV: use this to update src/long mapping */
893
0
                            ieee802154_addr_update(&ieee802154_map, shortAddr, original_packet->src_pan, original_packet->src64, pinfo->current_proto, pinfo->fd->num);
894
0
                        }
895
36
                    }
896
2.08k
                    proto_item_append_text(ti, ")");
897
2.08k
                }
898
2.08k
                break;
899
900
325
            case MLE_TLV_MODE:
901
325
                if (tlv_len == 1) {
902
258
                    uint8_t capability;
903
904
258
                    capability = tvb_get_uint8(payload_tvb, offset);
905
258
                    proto_item_append_text(ti, " = %02x)", capability);
906
                    /* Get and display capability info. (blatantly plagiarised from packet-ieee802154.c */
907
258
                    proto_tree_add_bits_item(tlv_tree, hf_mle_tlv_mode_reserved1, payload_tvb, (offset * 8) + 0, 4, ENC_NA);//R1
908
258
                    proto_tree_add_bits_item(tlv_tree, hf_mle_tlv_mode_receiver_on_idle, payload_tvb, (offset * 8) + 4, 1, ENC_NA);//Receiver
909
258
                    proto_tree_add_bits_item(tlv_tree, hf_mle_tlv_mode_reserved2, payload_tvb, (offset * 8) + 5, 1, ENC_NA);//R2
910
258
                    proto_tree_add_bits_item(tlv_tree, hf_mle_tlv_mode_device_type_bit, payload_tvb, (offset * 8) +6, 1, ENC_NA);//Device Type
911
258
                    proto_tree_add_bits_item(tlv_tree, hf_mle_tlv_mode_network_data, payload_tvb, (offset * 8) +7, 1, ENC_NA);//Network Data
912
258
                }
913
67
                else {
914
                    /* TLV Length must be 1 */
915
67
                    expert_add_info(pinfo, proto_root, &ei_mle_tlv_length_failed);
916
67
                    proto_tree_add_item(tlv_tree, hf_mle_tlv_unknown, payload_tvb, offset, tlv_len, ENC_NA);
917
67
                }
918
325
                offset += tlv_len;
919
325
                break;
920
921
132
            case MLE_TLV_TIMEOUT:
922
132
                if (tlv_len != 4) {
923
                    /* TLV Length must be 4 */
924
132
                    expert_add_info(pinfo, proto_root, &ei_mle_tlv_length_failed);
925
132
                    proto_tree_add_item(tlv_tree, hf_mle_tlv_unknown, payload_tvb, offset, tlv_len, ENC_NA);
926
132
                } else {
927
0
                    uint32_t to_data = 0;
928
0
                    proto_tree_add_item_ret_uint(tlv_tree, hf_mle_tlv_timeout, payload_tvb, offset, 4, ENC_BIG_ENDIAN, &to_data);
929
0
                    proto_item_append_text(ti, " = %u", to_data);
930
0
                }
931
132
                proto_item_append_text(ti, ")");
932
132
                offset += tlv_len;
933
132
                break;
934
935
135
            case MLE_TLV_CHALLENGE:
936
135
                proto_tree_add_item(tlv_tree, hf_mle_tlv_challenge, payload_tvb, offset, tlv_len, ENC_NA);
937
135
                if (tlv_len) {
938
127
                    proto_item_append_text(ti, " = %s)", tvb_bytes_to_str(pinfo->pool, payload_tvb, offset, tlv_len));
939
127
                }
940
135
                offset += tlv_len;
941
135
                break;
942
943
73
            case MLE_TLV_RESPONSE:
944
73
                proto_tree_add_item(tlv_tree, hf_mle_tlv_response, payload_tvb, offset, tlv_len, ENC_NA);
945
73
                if (tlv_len) {
946
54
                    proto_item_append_text(ti, " = %s)", tvb_bytes_to_str(pinfo->pool, payload_tvb, offset, tlv_len));
947
54
                }
948
73
                offset += tlv_len;
949
73
                break;
950
951
18
            case MLE_TLV_LINK_LAYER_FRAME_COUNTER:
952
90
            case MLE_TLV_MLE_FRAME_COUNTER:
953
90
                if (tlv_len != 4) {
954
                    /* TLV Length must be 4 */
955
86
                    expert_add_info(pinfo, proto_root, &ei_mle_tlv_length_failed);
956
86
                    proto_tree_add_item(tlv_tree, hf_mle_tlv_unknown, payload_tvb, offset, tlv_len, ENC_NA);
957
86
                } else {
958
4
                    uint32_t cntr;
959
960
4
                    if (tlv_type == MLE_TLV_LINK_LAYER_FRAME_COUNTER) {
961
1
                        proto_tree_add_item_ret_uint(tlv_tree, hf_mle_tlv_ll_frm_cntr, payload_tvb, offset, tlv_len, ENC_BIG_ENDIAN, &cntr);
962
3
                    } else {
963
3
                        proto_tree_add_item_ret_uint(tlv_tree, hf_mle_tlv_mle_frm_cntr, payload_tvb, offset, tlv_len, ENC_BIG_ENDIAN, &cntr);
964
3
                    }
965
4
                    proto_item_append_text(ti, " = %u", cntr);
966
4
                }
967
90
                proto_item_append_text(ti, ")");
968
90
                offset += tlv_len;
969
90
                break;
970
971
353
            case MLE_TLV_LINK_QUALITY:
972
353
                {
973
353
                    unsigned numNeighbors;
974
353
                    uint8_t size = tvb_get_uint8(payload_tvb, offset) & LQI_FLAGS_SIZE;
975
353
                    proto_tree *neig_tree;
976
353
                    proto_tree_add_item(tlv_tree, hf_mle_tlv_lqi_c, payload_tvb, offset, 1, ENC_BIG_ENDIAN);
977
353
                    proto_tree_add_item(tlv_tree, hf_mle_tlv_lqi_size, payload_tvb, offset, 1, ENC_BIG_ENDIAN);
978
353
                    offset++;
979
980
353
                    if ((tlv_len - 1) % (size + 3)) {
981
308
                        expert_add_info(pinfo, proto_root, &ei_mle_len_size_mismatch);
982
308
                        proto_tree_add_item(tlv_tree, hf_mle_tlv_unknown, payload_tvb, offset, tlv_len, ENC_NA);
983
308
                        numNeighbors = 0;
984
308
                    } else {
985
45
                        numNeighbors = (tlv_len - 1) / (size + 3);
986
45
                    }
987
988
353
                    if (numNeighbors == 0) {
989
324
                        proto_item_append_text(ti, ")");
990
324
                    } else if (numNeighbors == 1) {
991
11
                        proto_item_append_text(ti, ": 1 Neighbor)");
992
18
                    } else {
993
18
                        proto_item_append_text(ti, ": %d Neighbors)", numNeighbors);
994
18
                    }
995
996
                    /* Add subtrees */
997
998
                    //Size is off by 1
999
353
                    size++;
1000
1001
502
                    while (numNeighbors) {
1002
149
                        ti = proto_tree_add_item(tlv_tree, hf_mle_tlv_neighbor, payload_tvb, offset, size+2, ENC_NA);
1003
149
                        neig_tree = proto_item_add_subtree(ti, ett_mle_neighbor);
1004
1005
149
                        proto_tree_add_item(neig_tree, hf_mle_tlv_neighbor_flagI, payload_tvb, offset, 1, ENC_BIG_ENDIAN);
1006
149
                        proto_tree_add_item(neig_tree, hf_mle_tlv_neighbor_flagO, payload_tvb, offset, 1, ENC_BIG_ENDIAN);
1007
149
                        proto_tree_add_item(neig_tree, hf_mle_tlv_neighbor_flagP, payload_tvb, offset, 1, ENC_BIG_ENDIAN);
1008
149
                        offset++;
1009
1010
149
                        proto_tree_add_item(neig_tree, hf_mle_tlv_neighbor_idr, payload_tvb, offset, 1, ENC_BIG_ENDIAN);
1011
149
                        offset++;
1012
1013
149
                        proto_tree_add_item(neig_tree, hf_mle_tlv_neighbor_addr, payload_tvb, offset,size, ENC_NA);
1014
149
                        offset += size;
1015
1016
149
                        numNeighbors--;
1017
149
                    }
1018
353
                }
1019
353
                break;
1020
1021
113
            case MLE_TLV_NETWORK_PARAMETER:
1022
113
                {
1023
113
                    uint8_t param_id = tvb_get_uint8(payload_tvb, offset);
1024
1025
113
                    proto_item_append_text(ti, " = %s)", val_to_str(pinfo->pool, param_id, mle_tlv_nwk_param_vals, "Unknown (%d)"));
1026
1027
113
                    proto_tree_add_item(tlv_tree, hf_mle_tlv_network_param_id, payload_tvb, offset, 1, ENC_BIG_ENDIAN);
1028
113
                    offset++;
1029
113
                    proto_tree_add_item(tlv_tree, hf_mle_tlv_network_delay, payload_tvb, offset, 4, ENC_BIG_ENDIAN);
1030
113
                    offset += 4;
1031
1032
113
                    switch (param_id) {
1033
15
                    case NETWORK_PARAM_ID_CHANNEL:
1034
15
                        proto_tree_add_item(tlv_tree, hf_mle_tlv_network_channel, payload_tvb, offset, 2, ENC_BIG_ENDIAN);
1035
15
                        offset += 2;
1036
15
                        break;
1037
3
                    case NETWORK_PARAM_ID_PAN_ID:
1038
3
                        proto_tree_add_item(tlv_tree, hf_mle_tlv_network_pan_id, payload_tvb, offset, 2, ENC_BIG_ENDIAN);
1039
3
                        offset += 2;
1040
3
                        break;
1041
2
                    case NETWORK_PARAM_ID_PERMIT_JOIN:
1042
2
                        proto_tree_add_item(tlv_tree, hf_mle_tlv_network_pmt_join, payload_tvb, offset, 1, ENC_BIG_ENDIAN);
1043
2
                        offset++;
1044
2
                        break;
1045
0
                    case NETWORK_PARAM_ID_BCN_PAYLOAD:
1046
0
                        proto_tree_add_item(tlv_tree, hf_mle_tlv_network_bcn_payload, payload_tvb, offset, tlv_len-5, ENC_NA);
1047
0
                        offset += tlv_len-5;
1048
0
                        break;
1049
93
                    default:
1050
93
                        proto_tree_add_item(tlv_tree, hf_mle_tlv_network_unknown, payload_tvb, offset, tlv_len-5, ENC_NA);
1051
93
                        offset += tlv_len-5;
1052
93
                        break;
1053
113
                    }
1054
113
                }
1055
113
                break;
1056
1057
113
            case MLE_TLV_ROUTE64:
1058
109
                {
1059
109
                    proto_tree *rtr_tree;
1060
109
                    unsigned i, j;
1061
109
                    uint8_t count;
1062
109
                    uint64_t id_mask, test_mask;
1063
1064
109
                    proto_item_append_text(ti, ")");
1065
109
                    proto_tree_add_item(tlv_tree, hf_mle_tlv_route64_id_seq, payload_tvb, offset, 1, ENC_BIG_ENDIAN);
1066
109
                    offset++;
1067
1068
                    /* Count number of table entries */
1069
109
                    count = 0;
1070
972
                    for (i = 0; i < 8; i++) { /* TODO magic - number of routers/8 */
1071
863
                        uint8_t id_mask_octet = tvb_get_uint8(payload_tvb, offset + i);
1072
7.73k
                        for (j = 0; j < 8; j++) {
1073
6.87k
                            if (id_mask_octet & (1 << j)) {
1074
2.13k
                                count++;
1075
2.13k
                            }
1076
6.87k
                        }
1077
863
                    }
1078
1079
                    /*
1080
                     * | | | | | | | | | | |1|1|1|1|1|1|...|6|
1081
                     * |0|1|2|3|4|5|6|7|8|9|0|1|2|3|4|5|...|3|
1082
                     * ---------------------------------------
1083
                     * |1|0|1|1|1|0|0|0|1|1|0|0|0|1|0|1|...
1084
                     *
1085
                     * is sent as 0xb8, 0xc5
1086
                     * and represents table entry for routers 0, 2, 3, 4, 8, 9, 13, 15...
1087
                     */
1088
                    /* Get the ID mask as a 64-bit number (BE) */
1089
109
                    id_mask = tvb_get_ntoh64(payload_tvb, offset);
1090
1091
                    /* Just show the string of octets - best representation for a bit mask */
1092
109
                    proto_tree_add_item(tlv_tree, hf_mle_tlv_route64_id_mask, payload_tvb, offset, 8, ENC_NA);
1093
109
                    offset += 8;
1094
1095
109
                    if (count != (tlv_len - 9))
1096
103
                    {
1097
103
                        expert_add_info(pinfo, proto_root, &ei_mle_tlv_length_failed);
1098
103
                        proto_tree_add_item(tlv_tree, hf_mle_tlv_unknown, payload_tvb, offset, tlv_len, ENC_NA);
1099
103
                        offset += (tlv_len - 9);
1100
103
                    } else {
1101
                        /* Add subtrees */
1102
6
                        for (i = 0; i < count; i++) {
1103
                            /* Find first bit set */
1104
0
                            for (j = 0, test_mask = (UINT64_C(1) << 63); test_mask != 1; test_mask >>= 1, j++) {
1105
0
                                if (test_mask & id_mask) {
1106
0
                                    id_mask &= ~test_mask;
1107
0
                                    break;
1108
0
                                }
1109
0
                            }
1110
0
                            ti = proto_tree_add_item(tlv_tree, hf_mle_tlv_route64_entry, payload_tvb, offset, 1, ENC_BIG_ENDIAN);
1111
0
                            proto_item_append_text(ti, " (%d)", j);
1112
0
                            rtr_tree = proto_item_add_subtree(ti, ett_mle_router);
1113
1114
0
                            proto_tree_add_item(rtr_tree, hf_mle_tlv_route64_nbr_out, payload_tvb, offset, 1, ENC_BIG_ENDIAN);
1115
0
                            proto_tree_add_item(rtr_tree, hf_mle_tlv_route64_nbr_in, payload_tvb, offset, 1, ENC_BIG_ENDIAN);
1116
0
                            proto_tree_add_item(rtr_tree, hf_mle_tlv_route64_cost, payload_tvb, offset, 1, ENC_BIG_ENDIAN);
1117
0
                            offset++;
1118
0
                        }
1119
6
                    }
1120
109
                }
1121
109
                break;
1122
1123
43
            case MLE_TLV_ADDRESS16:
1124
43
                if (tlv_len != 2) {
1125
                    /* TLV Length must be 2 */
1126
42
                    expert_add_info(pinfo, proto_root, &ei_mle_tlv_length_failed);
1127
42
                    proto_tree_add_item(tlv_tree, hf_mle_tlv_unknown, payload_tvb, offset, tlv_len, ENC_NA);
1128
42
                } else {
1129
1
                    uint16_t addr16 = tvb_get_ntohs(payload_tvb, offset);
1130
1
                    proto_item_append_text(ti, " = ");
1131
1
                    {
1132
1
                        uint8_t a16_len = 2; /* Fix it at 2 */
1133
1
                        unsigned stroffset = offset;
1134
1135
3
                        while (a16_len) {
1136
2
                            uint8_t a16_data;
1137
2
                            a16_data = tvb_get_uint8(payload_tvb, stroffset);
1138
2
                            proto_item_append_text(ti, "%02x", a16_data);
1139
2
                            if (--a16_len) {
1140
1
                                proto_item_append_text(ti, ":");
1141
1
                            }
1142
2
                            stroffset++;
1143
2
                        }
1144
1
                    }
1145
1
                    proto_tree_add_item(tlv_tree, hf_mle_tlv_addr16, payload_tvb, offset, 2, ENC_NA);
1146
1
                    if (original_packet->dst_addr_mode == IEEE802154_FCF_ADDR_EXT) {
1147
                        /* Allocated Address16 TLV: use this to update dst/long mapping */
1148
0
                        ieee802154_addr_update(&ieee802154_map, addr16, original_packet->dst_pan, original_packet->dst64, pinfo->current_proto, pinfo->fd->num);
1149
0
                    }
1150
1
                }
1151
43
                proto_item_append_text(ti, ")");
1152
43
                offset += tlv_len;
1153
43
                break;
1154
1155
19
            case MLE_TLV_LEADER_DATA:
1156
19
                proto_item_append_text(ti, ")");
1157
19
                if (tlv_len != 8) {
1158
                    /* TLV Length must be 8 */
1159
18
                    expert_add_info(pinfo, proto_root, &ei_mle_tlv_length_failed);
1160
18
                    proto_tree_add_item(tlv_tree, hf_mle_tlv_unknown, payload_tvb, offset, tlv_len, ENC_NA);
1161
18
                    offset += tlv_len;
1162
18
                } else {
1163
1
                    proto_tree_add_item(tlv_tree, hf_mle_tlv_leader_data_partition_id, payload_tvb, offset, 4, ENC_BIG_ENDIAN);
1164
1
                    offset += 4;
1165
1
                    proto_tree_add_item(tlv_tree, hf_mle_tlv_leader_data_weighting, payload_tvb, offset, 1, ENC_BIG_ENDIAN);
1166
1
                    offset++;
1167
1
                    proto_tree_add_item(tlv_tree, hf_mle_tlv_leader_data_version, payload_tvb, offset, 1, ENC_BIG_ENDIAN);
1168
1
                    offset++;
1169
1
                    proto_tree_add_item(tlv_tree, hf_mle_tlv_leader_data_stable_version, payload_tvb, offset, 1, ENC_BIG_ENDIAN);
1170
1
                    offset++;
1171
1
                    proto_tree_add_item(tlv_tree, hf_mle_tlv_leader_data_router_id, payload_tvb, offset, 1, ENC_BIG_ENDIAN);
1172
1
                    offset++;
1173
1
                }
1174
19
                break;
1175
1176
49
            case MLE_TLV_NETWORK_DATA:
1177
49
                {
1178
49
                    tvbuff_t *sub_tvb;
1179
49
                    proto_item_append_text(ti, ")");
1180
49
                    if (tlv_len > 0) {
1181
46
                        sub_tvb = tvb_new_subset_length(payload_tvb, offset, tlv_len);
1182
46
                        call_dissector(thread_nwd_handle, sub_tvb, pinfo, tlv_tree);
1183
46
                    }
1184
49
                    offset += tlv_len;
1185
49
                }
1186
49
                break;
1187
1188
148
            case MLE_TLV_ACTIVE_OP_DATASET:
1189
152
            case MLE_TLV_PENDING_OP_DATASET:
1190
155
            case MLE_TLV_THREAD_DISCOVERY:
1191
155
                {
1192
155
                    tvbuff_t *sub_tvb;
1193
155
                    proto_item_append_text(ti, ")");
1194
155
                    if (tlv_len > 0) {
1195
151
                        sub_tvb = tvb_new_subset_length(payload_tvb, offset, tlv_len);
1196
151
                        call_dissector(thread_mc_handle, sub_tvb, pinfo, tlv_tree);
1197
151
                    }
1198
155
                    offset += tlv_len;
1199
155
                }
1200
155
                break;
1201
1202
37
            case MLE_TLV_TLV_REQUEST:
1203
37
                proto_item_append_text(ti, ")");
1204
493
                while (tlv_len) {
1205
456
                    proto_tree_add_item(tlv_tree, hf_mle_tlv_type, payload_tvb, offset, 1, ENC_NA);
1206
456
                    offset++;
1207
456
                    tlv_len--;
1208
456
                }
1209
37
                break;
1210
1211
19
            case MLE_TLV_SCAN_MASK:
1212
19
                if (tlv_len != 1) {
1213
                    /* TLV Length must be 1 */
1214
19
                    proto_item_append_text(ti, ")");
1215
19
                    expert_add_info(pinfo, proto_root, &ei_mle_tlv_length_failed);
1216
19
                    proto_tree_add_item(tlv_tree, hf_mle_tlv_unknown, payload_tvb, offset, tlv_len, ENC_NA);
1217
19
                } else {
1218
0
                    uint8_t mask;
1219
1220
0
                    mask = tvb_get_uint8(payload_tvb, offset);
1221
0
                    proto_item_append_text(ti, " = %02x)", mask);
1222
0
                    proto_tree_add_item(tlv_tree, hf_mle_tlv_scan_mask_r, payload_tvb, offset, 1, ENC_BIG_ENDIAN);
1223
0
                    proto_tree_add_item(tlv_tree, hf_mle_tlv_scan_mask_e, payload_tvb, offset, 1, ENC_BIG_ENDIAN);
1224
0
                }
1225
19
                offset += tlv_len;
1226
19
                break;
1227
1228
21
            case MLE_TLV_CONNECTIVITY:
1229
21
                proto_item_append_text(ti, ")");
1230
21
                if ((tlv_len == 7) || (tlv_len == 10)) {
1231
1
                    proto_tree *fl_tree;
1232
1233
1
                    ti = proto_tree_add_item(tlv_tree, hf_mle_tlv_conn_flags, payload_tvb, offset, 1, ENC_NA);
1234
1
                    fl_tree = proto_item_add_subtree(ti, ett_mle_conn_flg);
1235
1
                    proto_tree_add_item(fl_tree, hf_mle_tlv_conn_flags_pp, payload_tvb, offset, 1, ENC_BIG_ENDIAN);
1236
1
                    offset++;
1237
1
                    proto_tree_add_item(tlv_tree, hf_mle_tlv_conn_lq3, payload_tvb, offset, 1, ENC_BIG_ENDIAN);
1238
1
                    offset++;
1239
1
                    proto_tree_add_item(tlv_tree, hf_mle_tlv_conn_lq2, payload_tvb, offset, 1, ENC_BIG_ENDIAN);
1240
1
                    offset++;
1241
1
                    proto_tree_add_item(tlv_tree, hf_mle_tlv_conn_lq1, payload_tvb, offset, 1, ENC_BIG_ENDIAN);
1242
1
                    offset++;
1243
1
                    proto_tree_add_item(tlv_tree, hf_mle_tlv_conn_leader_cost, payload_tvb, offset, 1, ENC_BIG_ENDIAN);
1244
1
                    offset++;
1245
1
                    proto_tree_add_item(tlv_tree, hf_mle_tlv_conn_id_seq, payload_tvb, offset, 1, ENC_BIG_ENDIAN);
1246
1
                    offset++;
1247
1
                    proto_tree_add_item(tlv_tree, hf_mle_tlv_conn_active_rtrs, payload_tvb, offset, 1, ENC_BIG_ENDIAN);
1248
1
                    offset++;
1249
1
                    if (tlv_len == 10) {
1250
0
                        proto_tree_add_item(tlv_tree, hf_mle_tlv_conn_sed_buf_size, payload_tvb, offset, 2, ENC_BIG_ENDIAN);
1251
0
                        offset += 2;
1252
0
                        proto_tree_add_item(tlv_tree, hf_mle_tlv_conn_sed_dgram_cnt, payload_tvb, offset, 1, ENC_BIG_ENDIAN);
1253
0
                        offset++;
1254
0
                    }
1255
20
                } else {
1256
                    /* TLV Length must be 7 (old style) or 10 */
1257
20
                    expert_add_info(pinfo, proto_root, &ei_mle_tlv_length_failed);
1258
20
                    proto_tree_add_item(tlv_tree, hf_mle_tlv_unknown, payload_tvb, offset, tlv_len, ENC_NA);
1259
20
                    offset += tlv_len;
1260
20
                }
1261
21
                break;
1262
1263
21
            case MLE_TLV_LINK_MARGIN:
1264
21
                if (tlv_len != 1) {
1265
                    /* TLV Length must be 1 */
1266
20
                    proto_item_append_text(ti, ")");
1267
20
                    expert_add_info(pinfo, proto_root, &ei_mle_tlv_length_failed);
1268
20
                    proto_tree_add_item(tlv_tree, hf_mle_tlv_unknown, payload_tvb, offset, tlv_len, ENC_NA);
1269
20
                } else {
1270
1
                    uint8_t link_margin;
1271
1272
1
                    link_margin = tvb_get_uint8(payload_tvb, offset);
1273
1
                    proto_item_append_text(ti, " = %udB)", link_margin);
1274
1
                    proto_tree_add_item(tlv_tree, hf_mle_tlv_link_margin, payload_tvb, offset, tlv_len, ENC_BIG_ENDIAN);
1275
1
                }
1276
21
                offset += tlv_len;
1277
21
                break;
1278
1279
15
            case MLE_TLV_STATUS:
1280
15
                if (tlv_len != 1) {
1281
                    /* TLV Length must be 1 */
1282
14
                    proto_item_append_text(ti, ")");
1283
14
                    expert_add_info(pinfo, proto_root, &ei_mle_tlv_length_failed);
1284
14
                    proto_tree_add_item(tlv_tree, hf_mle_tlv_unknown, payload_tvb, offset, tlv_len, ENC_NA);
1285
14
                } else {
1286
1
                    uint8_t stat;
1287
1288
1
                    stat = tvb_get_uint8(payload_tvb, offset);
1289
1
                    proto_item_append_text(ti, " = %d)", stat);
1290
1
                    proto_tree_add_item(tlv_tree, hf_mle_tlv_status, payload_tvb, offset, tlv_len, ENC_BIG_ENDIAN);
1291
1
                }
1292
15
                offset += tlv_len;
1293
15
                break;
1294
1295
11
            case MLE_TLV_VERSION:
1296
11
                if (tlv_len != 2) {
1297
                    /* TLV Length must be 2 */
1298
10
                    proto_item_append_text(ti, ")");
1299
10
                    expert_add_info(pinfo, proto_root, &ei_mle_tlv_length_failed);
1300
10
                    proto_tree_add_item(tlv_tree, hf_mle_tlv_unknown, payload_tvb, offset, tlv_len, ENC_NA);
1301
10
                } else {
1302
1
                    uint16_t version;
1303
1304
1
                    version = tvb_get_ntohs(payload_tvb, offset);
1305
1
                    proto_item_append_text(ti, " = %d)", version);
1306
1
                    proto_tree_add_item(tlv_tree, hf_mle_tlv_version, payload_tvb, offset, tlv_len, ENC_BIG_ENDIAN);
1307
1
                }
1308
11
                offset += tlv_len;
1309
11
                break;
1310
1311
46
            case MLE_TLV_ADDRESS_REGISTRATION:
1312
46
                {
1313
46
                    uint8_t iid_type, i;
1314
46
                    uint8_t entries = 0;
1315
46
                    int16_t check_len = tlv_len;
1316
46
                    unsigned check_offset = offset;
1317
1318
                    /* Check consistency of entries */
1319
207
                    while (check_len > 0) {
1320
161
                        uint8_t ar_len;
1321
1322
161
                        iid_type = tvb_get_uint8(payload_tvb, check_offset);
1323
161
                        if (iid_type & ADDR_REG_MASK_IID_TYPE_MASK) {
1324
48
                            ar_len = 9;
1325
113
                        } else {
1326
113
                            ar_len = 17;
1327
113
                        }
1328
161
                        check_offset += ar_len;
1329
161
                        check_len -= ar_len;
1330
161
                        entries++;
1331
161
                    }
1332
1333
46
                    proto_item_append_text(ti, ")");
1334
46
                    if (check_len != 0) {
1335
                        /* Not an integer number of entries */
1336
32
                        expert_add_info(pinfo, proto_root, &ei_mle_tlv_length_failed);
1337
32
                        proto_tree_add_item(tlv_tree, hf_mle_tlv_unknown, payload_tvb, offset, tlv_len, ENC_NA);
1338
32
                        offset += tlv_len;
1339
32
                    } else {
1340
69
                        for (i = 0; i < entries; i++) {
1341
55
                            proto_tree *ar_tree;
1342
1343
55
                            ti = proto_tree_add_item(tlv_tree, hf_mle_tlv_addr_reg_entry, payload_tvb, offset, 1, ENC_NA);
1344
55
                            ar_tree = proto_item_add_subtree(ti, ett_mle_addr_reg);
1345
55
                            iid_type = tvb_get_uint8(payload_tvb, offset);
1346
55
                            if (iid_type & ADDR_REG_MASK_IID_TYPE_MASK) {
1347
30
                                proto_tree_add_item(ar_tree, hf_mle_tlv_addr_reg_iid_type, payload_tvb, offset, 1, ENC_BIG_ENDIAN);
1348
30
                                proto_tree_add_item(ar_tree, hf_mle_tlv_addr_reg_cid, payload_tvb, offset, 1, ENC_BIG_ENDIAN);
1349
30
                                offset++;
1350
30
                                proto_tree_add_item(ar_tree, hf_mle_tlv_addr_reg_iid, payload_tvb, offset, 8, ENC_NA);
1351
30
                                offset += 8;
1352
30
                            } else {
1353
25
                                proto_tree_add_item(ar_tree, hf_mle_tlv_addr_reg_iid_type, payload_tvb, offset, 1, ENC_BIG_ENDIAN);
1354
25
                                offset++;
1355
25
                                proto_tree_add_item(ar_tree, hf_mle_tlv_addr_reg_ipv6, payload_tvb, offset, 16, ENC_NA);
1356
25
                                offset += 16;
1357
25
                            }
1358
55
                        }
1359
14
                    }
1360
46
                }
1361
46
                break;
1362
1363
13
            case MLE_TLV_CHANNEL:
1364
13
                {
1365
13
                    proto_item_append_text(ti, ")");
1366
1367
                    /* Check length is consistent */
1368
13
                    if (tlv_len != 3) {
1369
13
                        expert_add_info(pinfo, proto_root, &ei_mle_tlv_length_failed);
1370
13
                        proto_tree_add_item(tlv_tree, hf_mle_tlv_unknown, payload_tvb, offset, tlv_len, ENC_NA);
1371
13
                    } else {
1372
                        /* Channel page */
1373
0
                        proto_tree_add_item(tlv_tree, hf_mle_tlv_channel_page, payload_tvb, offset, 1, ENC_BIG_ENDIAN);
1374
                        /* Channel */
1375
0
                        proto_tree_add_item(tlv_tree, hf_mle_tlv_channel, payload_tvb, offset+1, 2, ENC_BIG_ENDIAN);
1376
0
                    }
1377
13
                    offset += tlv_len;
1378
13
                }
1379
13
                break;
1380
1381
33
            case MLE_TLV_PAN_ID:
1382
33
                {
1383
33
                    proto_item_append_text(ti, ")");
1384
1385
                    /* Check length is consistent */
1386
33
                    if (tlv_len != 2) {
1387
33
                        expert_add_info(pinfo, proto_root, &ei_mle_tlv_length_failed);
1388
33
                        proto_tree_add_item(tlv_tree, hf_mle_tlv_unknown, payload_tvb, offset, tlv_len, ENC_NA);
1389
33
                    } else {
1390
                        /* PAN ID */
1391
0
                        proto_tree_add_item(tlv_tree, hf_mle_tlv_pan_id, payload_tvb, offset, tlv_len, ENC_BIG_ENDIAN);
1392
0
                    }
1393
33
                    offset += tlv_len;
1394
33
                }
1395
33
                break;
1396
1397
7
            case MLE_TLV_ACTIVE_TSTAMP:
1398
60
            case MLE_TLV_PENDING_TSTAMP:
1399
60
                {
1400
60
                    nstime_t timestamp;
1401
1402
60
                    proto_item_append_text(ti, ")");
1403
1404
60
                    if (tlv_len != 8) {
1405
59
                        expert_add_info(pinfo, proto_root, &ei_mle_tlv_length_failed);
1406
59
                        proto_tree_add_item(tlv_tree, hf_mle_tlv_unknown, payload_tvb, offset, tlv_len, ENC_NA);
1407
59
                    } else {
1408
                        /* Fill in the nstime_t structure */
1409
1
                        timestamp.secs = (time_t)tvb_get_ntoh48(payload_tvb, offset);
1410
1
                        timestamp.nsecs = (int)lround((double)(tvb_get_ntohs(payload_tvb, offset + 6) >> 1) * MLE_32768_TO_NSEC_FACTOR);
1411
1
                        if (tlv_type == MLE_TLV_ACTIVE_TSTAMP) {
1412
0
                            proto_tree_add_time(tlv_tree, hf_mle_tlv_active_tstamp, payload_tvb, offset, 8, &timestamp);
1413
1
                        } else {
1414
1
                            proto_tree_add_time(tlv_tree, hf_mle_tlv_pending_tstamp, payload_tvb, offset, 8, &timestamp);
1415
1
                        }
1416
1
                    }
1417
60
                    offset += tlv_len;
1418
60
                }
1419
60
                break;
1420
1421
18
            case MLE_TLV_CSL_CHANNEL:
1422
18
              {
1423
                  /* Check length is consistent */
1424
18
                  if (tlv_len != 3) {
1425
15
                      expert_add_info(pinfo, proto_root, &ei_mle_tlv_length_failed);
1426
15
                      proto_tree_add_item(tlv_tree, hf_mle_tlv_unknown, payload_tvb, offset, tlv_len, ENC_NA);
1427
15
                  } else {
1428
3
                      uint8_t page;
1429
3
                      uint16_t channel;
1430
1431
                      /* Channel page */
1432
3
                      proto_tree_add_item_ret_uint8(tlv_tree, hf_mle_tlv_channel_page, payload_tvb, offset, 1, ENC_BIG_ENDIAN, &page);
1433
                      /* Channel */
1434
3
                      proto_tree_add_item_ret_uint16(tlv_tree, hf_mle_tlv_channel, payload_tvb, offset+1, 2, ENC_BIG_ENDIAN, &channel);
1435
1436
3
                      proto_item_append_text(ti, " = %u/%u", page, channel);
1437
3
                  }
1438
18
                  proto_item_append_text(ti, ")");
1439
18
                  offset += tlv_len;
1440
18
              }
1441
18
              break;
1442
1443
10
            case MLE_TLV_CSL_SYNCHRONIZED_TIMEOUT:/*Defined in Ch04_Mesh Link Establishment v1.2*/
1444
            /* Check length is consistent */
1445
10
                if (tlv_len != 4) {
1446
10
                    expert_add_info(pinfo, proto_root, &ei_mle_tlv_length_failed);
1447
10
                    proto_tree_add_item(tlv_tree, hf_mle_tlv_unknown, payload_tvb, offset, tlv_len, ENC_NA);
1448
10
                } else {
1449
                    /*  CSL synchronized timeout */
1450
0
                    uint32_t to_data = 0;
1451
0
                    proto_tree_add_item_ret_uint(tlv_tree, hf_mle_tlv_csl_synchronized_timeout, payload_tvb, offset, 4, ENC_BIG_ENDIAN, &to_data);
1452
0
                    proto_item_append_text(ti, " = %u", to_data);
1453
0
                }
1454
10
                proto_item_append_text(ti, ")");
1455
10
                offset += tlv_len;
1456
10
                break;
1457
51
            case MLE_TLV_CSL_ACCURACY:
1458
51
            proto_item_append_text(ti, ")");
1459
51
              if (tlv_len != 2) {
1460
                  /* TLV Length must be 2 */
1461
51
                  expert_add_info(pinfo, proto_root, &ei_mle_tlv_length_failed);
1462
51
                  proto_tree_add_item(tlv_tree, hf_mle_tlv_unknown, payload_tvb, offset, tlv_len, ENC_NA);
1463
51
              } else {
1464
0
                  proto_tree_add_item(tlv_tree, hf_mle_tlv_csl_clock_accuracy, payload_tvb, offset, 1, ENC_BIG_ENDIAN);
1465
0
                  offset++;
1466
0
                  proto_tree_add_item(tlv_tree, hf_mle_tlv_csl_uncertainty, payload_tvb, offset, 1, ENC_BIG_ENDIAN);
1467
0
                  offset++;
1468
0
              }
1469
51
            break;
1470
7
            case MLE_TLV_LINK_METRICS_QUERY:
1471
32
            case MLE_TLV_LINK_METRICS_MANAGEMENT:
1472
39
            case MLE_TLV_LINK_METRICS_REPORT:
1473
39
            {
1474
39
                proto_item_append_text(ti, ")");
1475
39
                proto_item *sub_item;
1476
39
                proto_tree *sub_tree;
1477
39
                uint8_t metrics_tlv;
1478
3.31k
                while (tvb_offset_exists(payload_tvb, offset)) {
1479
3.29k
                    uint8_t sub_tlv = tvb_get_uint8(payload_tvb, offset);
1480
1481
3.29k
                    sub_tree = proto_tree_add_subtree(tlv_tree, payload_tvb, offset, -1, 1, &sub_item, "Sub TLV");
1482
3.29k
                    sub_item = proto_tree_add_item(sub_tree, hf_mle_tlv_link_sub_tlv, payload_tvb, offset, 1, ENC_BIG_ENDIAN);
1483
3.29k
                    offset++;
1484
                    /* Length */
1485
3.29k
                    proto_tree_add_item(sub_tree, hf_mle_tlv_length, payload_tvb, offset, 1, ENC_BIG_ENDIAN);
1486
3.29k
                    uint8_t length_sub_tlv = tvb_get_uint8(payload_tvb,offset);
1487
3.29k
                    offset++;
1488
3.29k
                    switch (sub_tlv) {
1489
730
                    case LINK_METRICS_REPORT_SUB_TLV:
1490
730
                        metrics_tlv = tvb_get_uint8(payload_tvb, offset);
1491
                        /* Type ID Flags */
1492
730
                        proto_tree_add_bits_item(sub_tree, hf_mle_tlv_metric_type_id_flags_e, payload_tvb, (offset * 8) + 0, 1, ENC_NA);//E
1493
730
                        proto_tree_add_bits_item(sub_tree, hf_mle_tlv_metric_type_id_flags_l, payload_tvb, (offset * 8) + 1, 1, ENC_NA);//L
1494
730
                        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
1495
730
                        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
1496
                        /* Type ID Flags */
1497
730
                        offset++;
1498
                        //latest draft the length is 1 indicates that the extended value is 4 else 1
1499
730
                        if((metrics_tlv & 0x40) == 0x40)
1500
119
                        {
1501
119
                            sub_item = proto_tree_add_item(sub_tree, hf_mle_tlv_value, payload_tvb, offset, 4, ENC_NA);
1502
119
                            offset+=4;
1503
119
                        }
1504
611
                        else
1505
611
                        {
1506
611
                            sub_item = proto_tree_add_item(sub_tree, hf_mle_tlv_value, payload_tvb, offset, 1, ENC_NA);
1507
611
                            offset++;
1508
611
                        }
1509
730
                        break;
1510
243
                    case LINK_METRICS_QUERY_ID_SUB_TLV:
1511
                        /* Query ID */
1512
243
                        proto_tree_add_item(sub_tree, hf_mle_tlv_query_id, payload_tvb, offset, 1, ENC_BIG_ENDIAN);
1513
243
                        offset++;
1514
243
                        break;
1515
52
                    case LINK_METRICS_QUERY_OPTIONS_SUB_TLV:
1516
52
                        proto_tree_add_item(sub_tree, hf_mle_tlv_link_query_options, payload_tvb, offset, length_sub_tlv, ENC_NA);
1517
52
                        offset+= length_sub_tlv;
1518
52
                        break;
1519
47
                    case FORWARD_PROBING_REGISTRATION_SUB_TLV:
1520
47
                        proto_tree_add_item(sub_tree, hf_mle_tlv_link_forward_series, payload_tvb, offset, 1, ENC_NA);
1521
47
                        offset++;
1522
47
                        proto_tree_add_item(sub_tree, hf_mle_tlv_link_forward_series_flags, payload_tvb, offset, 1, ENC_NA);
1523
47
                        uint8_t forward_series_flag = tvb_get_uint8(payload_tvb, offset);
1524
47
                        offset++;
1525
47
                        if (forward_series_flag > 0)
1526
27
                        {
1527
27
                            proto_tree_add_bits_item(sub_tree, hf_mle_tlv_metric_type_id_flags_e, payload_tvb, (offset * 8) + 0, 1, ENC_NA);//Receiver
1528
27
                            proto_tree_add_bits_item(sub_tree, hf_mle_tlv_metric_type_id_flags_l, payload_tvb, (offset * 8) + 1, 1, ENC_NA);//Receiver
1529
27
                            proto_tree_add_bits_item(sub_tree, hf_mle_tlv_metric_type_id_flags_type, payload_tvb, (offset * 8) + 2, 3, ENC_NA);//Receiver
1530
27
                            proto_tree_add_bits_item(sub_tree, hf_mle_tlv_metric_type_id_flags_metric, payload_tvb, (offset * 8) + 5, 3, ENC_NA);//Receiver
1531
27
                            offset+=1;
1532
27
                        }
1533
47
                        break;
1534
52
                    case LINK_METRICS_STATUS_SUB_TLV:
1535
52
                        proto_tree_add_item(sub_tree, hf_mle_tlv_link_status_sub_tlv, payload_tvb, offset, 1, ENC_NA);
1536
52
                        offset++;
1537
52
                        break;
1538
39
                    case ENHANCED_ACK_LINK_METRICS_CONFIGURATION_SUB_TLV:
1539
39
                        if(length_sub_tlv == 1)
1540
3
                        {
1541
3
                           sub_item = proto_tree_add_item(sub_tree, hf_mle_tlv_link_enh_ack_flags, payload_tvb, offset, 1, ENC_NA);
1542
3
                        }
1543
36
                        else
1544
36
                        {
1545
36
                           sub_item = proto_tree_add_item(sub_tree, hf_mle_tlv_link_enh_ack_flags, payload_tvb, offset, 1, ENC_NA);
1546
36
                           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);
1547
36
                        }
1548
39
                        offset+= length_sub_tlv;
1549
39
                        break;
1550
3.29k
                    }
1551
3.29k
                }
1552
39
            }
1553
18
            break;
1554
172
            case MLE_TLV_LINK_PROBE:
1555
172
            {
1556
172
                proto_item_append_text(ti, ")");
1557
172
                proto_tree_add_item(tlv_tree, hf_mle_tlv_link_status, payload_tvb, offset, 1, ENC_BIG_ENDIAN);
1558
172
                offset++;
1559
172
            }
1560
172
            break;
1561
35
            case MLE_TLV_SUPERVISION_INTERVAL:
1562
35
                if (tlv_len != 2) {
1563
                    /* TLV Length must be 2 */
1564
30
                    proto_item_append_text(ti, ")");
1565
30
                    expert_add_info(pinfo, proto_root, &ei_mle_tlv_length_failed);
1566
30
                    proto_tree_add_item(tlv_tree, hf_mle_tlv_unknown, payload_tvb, offset, tlv_len, ENC_NA);
1567
30
                }
1568
5
                else {
1569
5
                    uint16_t interval;
1570
1571
5
                    interval = tvb_get_ntohs(payload_tvb, offset);
1572
5
                    proto_item_append_text(ti, " = %d)", interval);
1573
5
                    proto_tree_add_item(tlv_tree, hf_mle_tlv_supervision_interval, payload_tvb, offset, tlv_len, ENC_BIG_ENDIAN);
1574
5
                }
1575
35
                offset += tlv_len;
1576
35
                break;
1577
13
            case MLE_TLV_CIM_PROVISIONER_INTERFACE_DATA:
1578
14
            case MLE_TLV_CIM_PROVISIONING_DATASET:
1579
15
            case MLE_TLV_CIM_DISCOVERY_REQUEST:
1580
15
            case MLE_TLV_SECURE_DISSEMINATION:
1581
1582
526
            default:
1583
526
                proto_item_append_text(ti, ")");
1584
526
                proto_tree_add_item(tlv_tree, hf_mle_tlv_unknown, payload_tvb, offset, tlv_len, ENC_NA);
1585
526
                offset += tlv_len;
1586
4.80k
        }
1587
4.80k
    }
1588
1589
30
    return tvb_captured_length(tvb);
1590
371
}
1591
1592
void
1593
proto_register_mle(void)
1594
16
{
1595
16
  static hf_register_info hf[] = {
1596
1597
    /* Auxiliary Security Header Fields */
1598
    /*----------------------------------*/
1599
16
    { &hf_mle_security_suite,
1600
16
      { "Security Suite",
1601
16
        "mle.sec_suite",
1602
16
        FT_UINT8, BASE_HEX, VALS(mle_sec_suite_names), 0x0,
1603
16
        "The Security Suite of the frame",
1604
16
        HFILL
1605
16
      }
1606
16
    },
1607
16
    { &hf_mle_mic,
1608
16
      { "Decrypted MIC",
1609
16
        "mle.mic",
1610
16
        FT_BYTES, BASE_NONE, NULL, 0x0,
1611
16
        "The decrypted MIC",
1612
16
        HFILL
1613
16
      }
1614
16
    },
1615
    /*MLE Command*/
1616
16
    { &hf_mle_command,
1617
16
      { "Command",
1618
16
        "mle.cmd",
1619
16
        FT_UINT8, BASE_DEC, VALS(mle_command_vals), 0x0,
1620
16
        "MLE command type",
1621
16
        HFILL
1622
16
      }
1623
16
    },
1624
    /* Generic TLV */
1625
16
    { &hf_mle_tlv,
1626
16
      { "TLV",
1627
16
        "mle.tlv",
1628
16
        FT_NONE, BASE_NONE, NULL, 0x0,
1629
16
        "Type-Length-Value",
1630
16
        HFILL
1631
16
      }
1632
16
    },
1633
16
    { &hf_mle_tlv_type,
1634
16
      { "Type",
1635
16
        "mle.tlv.type",
1636
16
        FT_UINT8, BASE_DEC, VALS(mle_tlv_vals), 0x0,
1637
16
        "Type of value",
1638
16
        HFILL
1639
16
      }
1640
16
    },
1641
16
    { &hf_mle_tlv_length,
1642
16
      { "Length",
1643
16
        "mle.tlv.len",
1644
16
        FT_UINT8, BASE_DEC, NULL, 0x0,
1645
16
        "Length of value",
1646
16
        HFILL
1647
16
      }
1648
16
    },
1649
    /* Type-Specific TLV Fields */
1650
16
    { &hf_mle_tlv_source_addr,
1651
16
      { "Address",
1652
16
        "mle.tlv.source_addr",
1653
16
        FT_BYTES, BASE_NONE, NULL, 0x0,
1654
16
        "Source address",
1655
16
        HFILL
1656
16
      }
1657
16
    },
1658
    /*  Capability Information Fields */
1659
16
    { &hf_mle_tlv_mode_nwk_data,
1660
16
      { "Network Data",
1661
16
        "mle.tlv.mode.nwk_data",
1662
16
        FT_BOOLEAN, 8, TFS(&mle_tlv_mode_nwk_data), MLE_CMD_CINFO_NWK_DATA,
1663
16
        NULL,
1664
16
        HFILL
1665
16
      }
1666
16
    },
1667
16
    { &hf_mle_tlv_mode_device_type,
1668
16
      { "Device Type",
1669
16
        "mle.tlv.mode.device_type",
1670
16
        FT_BOOLEAN, 8, TFS(&mle_tlv_mode_device_type), IEEE802154_CMD_CINFO_DEVICE_TYPE,
1671
16
        NULL,
1672
16
        HFILL
1673
16
      }
1674
16
    },
1675
16
    { &hf_mle_tlv_mode_sec_data_req,
1676
16
      { "Secure Data Requests",
1677
16
        "mle.tlv.mode.sec_data_req",
1678
16
        FT_BOOLEAN, 8, NULL, MLE_CMD_CINFO_SEC_DATA_REQ,
1679
16
        NULL,
1680
16
        HFILL
1681
16
      }
1682
16
    },
1683
16
    { &hf_mle_tlv_mode_receiver_on_idle,
1684
16
      { "R(Receiver/rx)-on-idle",
1685
16
        "mle.tlv.mode.receiver_on_idle",
1686
16
        FT_UINT8, BASE_HEX, NULL, 0x0,
1687
16
        NULL,
1688
16
       HFILL
1689
16
      }
1690
16
    },
1691
16
    { &hf_mle_tlv_mode_reserved1,
1692
16
     { "R1(Reserved)",
1693
16
        "mle.tlv.mode.reserved1",
1694
16
        FT_UINT8, BASE_HEX, NULL, 0x0,
1695
16
        NULL,
1696
16
        HFILL
1697
16
      }
1698
16
    },
1699
16
    { &hf_mle_tlv_mode_reserved2,
1700
16
      { "R2(Reserved)",
1701
16
        "mle.tlv.mode.reserved2",
1702
16
        FT_UINT8, BASE_HEX, NULL, 0x0,
1703
16
        NULL,
1704
16
        HFILL
1705
16
      }
1706
16
    },
1707
16
    { &hf_mle_tlv_mode_device_type_bit,
1708
16
      { "D(Device Type)",
1709
16
       "mle.tlv.mode.device_type_bit",
1710
16
        FT_UINT8, BASE_HEX, NULL, 0x0,
1711
16
        NULL,
1712
16
        HFILL
1713
16
     }
1714
16
    },
1715
16
    { &hf_mle_tlv_mode_network_data,
1716
16
       { "N(Network Data)",
1717
16
         "mle.tlv.mode.network_data",
1718
16
        FT_UINT8, BASE_HEX, NULL, 0x0,
1719
16
        NULL,
1720
16
        HFILL
1721
16
     }
1722
16
    },
1723
16
    { &hf_mle_tlv_mode_idle_rx,
1724
16
      { "Receive On When Idle",
1725
16
        "mle.tlv.mode.idle_rx",
1726
16
        FT_BOOLEAN, 8, NULL, IEEE802154_CMD_CINFO_IDLE_RX,
1727
16
        NULL,
1728
16
        HFILL
1729
16
      }
1730
16
    },
1731
16
    { &hf_mle_tlv_timeout,
1732
16
      { "Timeout",
1733
16
        "mle.tlv.timeout",
1734
16
        FT_UINT32, BASE_DEC, NULL, 0x0,
1735
16
        "Expected interval between transmissions in seconds",
1736
16
        HFILL
1737
16
      }
1738
16
    },
1739
16
    { &hf_mle_tlv_challenge,
1740
16
      { "Challenge",
1741
16
        "mle.tlv.challenge",
1742
16
        FT_BYTES, BASE_NONE, NULL, 0x0,
1743
16
        "Challenge to be echoed back",
1744
16
        HFILL
1745
16
      }
1746
16
    },
1747
16
    { &hf_mle_tlv_response,
1748
16
      { "Response",
1749
16
        "mle.tlv.response",
1750
16
        FT_BYTES, BASE_NONE, NULL, 0x0,
1751
16
        "Response to a challenge",
1752
16
        HFILL
1753
16
      }
1754
16
    },
1755
16
    { &hf_mle_tlv_ll_frm_cntr,
1756
16
      { "Link Layer Frame Counter",
1757
16
        "mle.tlv.ll_frm_cntr",
1758
16
        FT_UINT32, BASE_DEC, NULL, 0x0,
1759
16
        "The Link layer frame counter",
1760
16
        HFILL
1761
16
      }
1762
16
    },
1763
16
    { &hf_mle_tlv_mle_frm_cntr,
1764
16
      { "MLE Frame Counter",
1765
16
        "mle.tlv.mle_frm_cntr",
1766
16
        FT_UINT32, BASE_DEC, NULL, 0x0,
1767
16
        "The MLE frame counter",
1768
16
        HFILL
1769
16
      }
1770
16
    },
1771
16
    { &hf_mle_tlv_unknown,
1772
16
      { "Unknown",
1773
16
        "mle.tlv.unknown",
1774
16
        FT_BYTES, BASE_NONE, NULL, 0x0,
1775
16
        "Unknown TLV, raw value",
1776
16
        HFILL
1777
16
      }
1778
16
    },
1779
16
    { &hf_mle_tlv_lqi_c,
1780
16
      { "Complete Flag",
1781
16
        "mle.tlv.lqi.complete",
1782
16
        FT_BOOLEAN, 8, NULL, LQI_FLAGS_C,
1783
16
        NULL,
1784
16
        HFILL
1785
16
      }
1786
16
    },
1787
16
    { &hf_mle_tlv_lqi_size,
1788
16
      { "Address Size",
1789
16
        "mle.tlv.lqi.size",
1790
16
        FT_UINT8, BASE_DEC, NULL, LQI_FLAGS_SIZE,
1791
16
        NULL,
1792
16
        HFILL
1793
16
      }
1794
16
    },
1795
16
    { &hf_mle_tlv_neighbor,
1796
16
      { "Neighbor Record",
1797
16
        "mle.tlv.neighbor",
1798
16
        FT_NONE, BASE_NONE, NULL, 0x0,
1799
16
        NULL,
1800
16
        HFILL
1801
16
      }
1802
16
    },
1803
16
    { &hf_mle_tlv_neighbor_flagI,
1804
16
      { "Incoming",
1805
16
        "mle.tlv.neighbor.flagI",
1806
16
        FT_BOOLEAN, 8, NULL, NEIGHBOR_FLAG_I,
1807
16
        "Set if the sender has configured its link with this neighbor and will accept incoming messages from them.",
1808
16
        HFILL
1809
16
      }
1810
16
    },
1811
16
    { &hf_mle_tlv_neighbor_flagO,
1812
16
      { "Outgoing",
1813
16
        "mle.tlv.neighbor.flagO",
1814
16
        FT_BOOLEAN, 8, NULL, NEIGHBOR_FLAG_O,
1815
16
        "Set if the sender believes that the neighbor has configured its link with the sender and will accept incoming messages from the sender.",
1816
16
        HFILL
1817
16
      }
1818
16
    },
1819
16
    { &hf_mle_tlv_neighbor_flagP,
1820
16
      { "Priority",
1821
16
        "mle.tlv.neighbor.flagP",
1822
16
        FT_BOOLEAN, 8, NULL, NEIGHBOR_FLAG_P,
1823
16
        "Set if the sender expects to use this link for sending messages to this neighbor.",
1824
16
        HFILL
1825
16
      }
1826
16
    },
1827
16
    { &hf_mle_tlv_neighbor_idr,
1828
16
      { "Inverse Delivery Ratio",
1829
16
        "mle.tlv.neighbor.idr",
1830
16
        FT_UINT8, BASE_DEC, NULL, 0x0,
1831
16
        NULL,
1832
16
        HFILL
1833
16
      }
1834
16
    },
1835
16
    { &hf_mle_tlv_neighbor_addr,
1836
16
      { "Address",
1837
16
        "mle.tlv.neighbor.addr",
1838
16
        FT_BYTES, BASE_NONE, NULL, 0x0,
1839
16
        NULL,
1840
16
        HFILL
1841
16
      }
1842
16
    },
1843
16
    { &hf_mle_tlv_network_param_id,
1844
16
      { "Parameter ID",
1845
16
        "mle.tlv.network.param_id",
1846
16
        FT_UINT8, BASE_DEC, NULL, 0x0,
1847
16
        NULL,
1848
16
        HFILL
1849
16
      }
1850
16
    },
1851
16
    { &hf_mle_tlv_network_delay,
1852
16
      { "Delay",
1853
16
        "mle.tlv.network.delay",
1854
16
        FT_UINT32, BASE_DEC, NULL, 0x0,
1855
16
        NULL,
1856
16
        HFILL
1857
16
      }
1858
16
    },
1859
16
    { &hf_mle_tlv_network_channel,
1860
16
      { "Channel",
1861
16
        "mle.tlv.network.channel",
1862
16
        FT_UINT16, BASE_DEC, NULL, 0x0,
1863
16
        NULL,
1864
16
        HFILL
1865
16
      }
1866
16
    },
1867
16
    { &hf_mle_tlv_network_pan_id,
1868
16
      { "PAN ID",
1869
16
        "mle.tlv.network.pan_id",
1870
16
        FT_UINT16, BASE_HEX, NULL, 0x0,
1871
16
        NULL,
1872
16
        HFILL
1873
16
      }
1874
16
    },
1875
16
    { &hf_mle_tlv_network_pmt_join,
1876
16
      { "Permit Join",
1877
16
        "mle.tlv.network.pmt_join",
1878
16
        FT_BOOLEAN, 8, NULL, 0x1,
1879
16
        NULL,
1880
16
        HFILL
1881
16
      }
1882
16
    },
1883
16
    { &hf_mle_tlv_network_bcn_payload,
1884
16
      { "Beacon Payload",
1885
16
        "mle.tlv.network.bcn_payload",
1886
16
        FT_BYTES, BASE_NONE, NULL, 0x0,
1887
16
        NULL,
1888
16
        HFILL
1889
16
      }
1890
16
    },
1891
16
    { &hf_mle_tlv_route64_id_seq,
1892
16
      { "ID Sequence",
1893
16
        "mle.tlv.route64.id_seq",
1894
16
        FT_UINT8, BASE_DEC, NULL, 0x0,
1895
16
        NULL,
1896
16
        HFILL
1897
16
      }
1898
16
    },
1899
16
    { &hf_mle_tlv_route64_id_mask,
1900
16
      { "Assigned Router ID Mask",
1901
16
        "mle.tlv.route64.id_mask",
1902
16
        FT_BYTES, BASE_NONE, NULL, 0x0,
1903
16
        NULL,
1904
16
        HFILL
1905
16
      }
1906
16
    },
1907
16
    { &hf_mle_tlv_route64_entry,
1908
16
      { "Routing Table Entry",
1909
16
        "mle.tlv.route64",
1910
16
        FT_UINT8, BASE_HEX, NULL, 0x0,
1911
16
        NULL,
1912
16
        HFILL
1913
16
      }
1914
16
    },
1915
16
    { &hf_mle_tlv_route64_nbr_out,
1916
16
      { "Neighbor Out Link Quality",
1917
16
        "mle.tlv.route64.nbr_out",
1918
16
        FT_UINT8, BASE_DEC, NULL, ROUTE_TBL_OUT_MASK,
1919
16
        NULL,
1920
16
        HFILL
1921
16
      }
1922
16
    },
1923
16
    { &hf_mle_tlv_route64_nbr_in,
1924
16
      { "Neighbor In Link Quality",
1925
16
        "mle.tlv.route64.nbr_in",
1926
16
        FT_UINT8, BASE_DEC, NULL, ROUTE_TBL_IN_MASK,
1927
16
        NULL,
1928
16
        HFILL
1929
16
      }
1930
16
    },
1931
16
    { &hf_mle_tlv_route64_cost,
1932
16
      { "Router Cost",
1933
16
        "mle.tlv.route64.cost",
1934
16
        FT_UINT8, BASE_DEC, NULL, ROUTE_TBL_COST_MASK,
1935
16
        NULL,
1936
16
        HFILL
1937
16
      }
1938
16
    },
1939
#if 0
1940
    { &hf_mle_tlv_route64_unknown,
1941
      { "(unknown)",
1942
        "mle.tlv.route64.unknown",
1943
        FT_BYTES, BASE_NONE, NULL, 0x0,
1944
        NULL,
1945
        HFILL
1946
      }
1947
    },
1948
#endif
1949
16
    { &hf_mle_tlv_metric_type_id_flags_l,
1950
16
      { "L",
1951
16
        "mle.tlv.metric_type_id_flags.l",
1952
16
        FT_UINT8, BASE_HEX, NULL, 0x0,
1953
16
        NULL,
1954
16
        HFILL
1955
16
      }
1956
16
    },
1957
16
    { &hf_mle_tlv_metric_type_id_flags_e,
1958
16
      { "E",
1959
16
        "mle.tlv.metric_type_id_flags.e",
1960
16
        FT_UINT8, BASE_HEX, NULL, 0x0,
1961
16
        NULL,
1962
16
        HFILL
1963
16
      }
1964
16
    },
1965
16
    { &hf_mle_tlv_metric_type_id_flags_type,
1966
16
      { "Type/average enum",
1967
16
        "mle.tlv.metric_type_id_flags.type",
1968
16
        FT_UINT8, BASE_HEX, NULL, 0x0,
1969
16
        NULL,
1970
16
        HFILL
1971
16
      }
1972
16
    },
1973
16
    { &hf_mle_tlv_metric_type_id_flags_metric,
1974
16
      { "Metric enum",
1975
16
        "mle.tlv.metric_type_id_flags.metric",
1976
16
        FT_UINT8, BASE_HEX, NULL, 0x0,
1977
16
        NULL,
1978
16
        HFILL
1979
16
      }
1980
16
    },
1981
16
    { &hf_mle_tlv_addr16,
1982
16
      { "Address16",
1983
16
        "mle.tlv.addr16",
1984
16
        FT_BYTES, BASE_NONE, NULL, 0x0,
1985
16
        NULL,
1986
16
        HFILL
1987
16
      }
1988
16
    },
1989
16
    { &hf_mle_tlv_leader_data_partition_id,
1990
16
      { "Partition ID",
1991
16
        "mle.tlv.leader_data.partition_id",
1992
16
        FT_UINT32, BASE_HEX, NULL, 0x0,
1993
16
        NULL,
1994
16
        HFILL
1995
16
      }
1996
16
    },
1997
16
    { &hf_mle_tlv_leader_data_weighting,
1998
16
      { "Weighting",
1999
16
        "mle.tlv.leader_data.weighting",
2000
16
        FT_UINT8, BASE_DEC, NULL, 0x0,
2001
16
        NULL,
2002
16
        HFILL
2003
16
      }
2004
16
    },
2005
16
    { &hf_mle_tlv_leader_data_version,
2006
16
      { "Data Version",
2007
16
        "mle.tlv.leader_data.data_version",
2008
16
        FT_UINT8, BASE_DEC, NULL, 0x0,
2009
16
        NULL,
2010
16
        HFILL
2011
16
      }
2012
16
    },
2013
16
    { &hf_mle_tlv_leader_data_stable_version,
2014
16
      { "Stable Data Version",
2015
16
        "mle.tlv.leader_data.stable_data_version",
2016
16
        FT_UINT8, BASE_DEC, NULL, 0x0,
2017
16
        NULL,
2018
16
        HFILL
2019
16
      }
2020
16
    },
2021
16
    { &hf_mle_tlv_leader_data_router_id,
2022
16
      { "Leader Router ID",
2023
16
        "mle.tlv.leader_data.router_id",
2024
16
        FT_UINT8, BASE_DEC, NULL, 0x0,
2025
16
        NULL,
2026
16
        HFILL
2027
16
      }
2028
16
    },
2029
#if 0
2030
    { &hf_mle_tlv_network_data,
2031
      { "Network Data",
2032
        "mle.tlv.network_data",
2033
        FT_BYTES, BASE_NONE, NULL, 0x0,
2034
        "Network data (opaque data)",
2035
        HFILL
2036
      }
2037
    },
2038
#endif
2039
16
    { &hf_mle_tlv_scan_mask_r,
2040
16
      { "Router",
2041
16
        "mle.tlv.scan_mask.r",
2042
16
        FT_BOOLEAN, 8, NULL, SCAN_MASK_R_MASK,
2043
16
        NULL,
2044
16
        HFILL
2045
16
      }
2046
16
    },
2047
16
    { &hf_mle_tlv_scan_mask_e,
2048
16
      { "End Device",
2049
16
        "mle.tlv.scan_mask.e",
2050
16
        FT_BOOLEAN, 8, NULL, SCAN_MASK_D_MASK,
2051
16
        NULL,
2052
16
        HFILL
2053
16
      }
2054
16
    },
2055
16
    { &hf_mle_tlv_conn_flags,
2056
16
      { "Flags",
2057
16
        "mle.tlv.conn.flags",
2058
16
        FT_NONE, BASE_NONE, NULL, 0x0,
2059
16
        NULL,
2060
16
        HFILL
2061
16
      }
2062
16
    },
2063
16
    { &hf_mle_tlv_conn_flags_pp,
2064
16
      { "Parent Priority",
2065
16
        "mle.tlv.conn.flags.pp",
2066
16
        FT_INT8, BASE_DEC, VALS(mle_conn_tlv_flags_pp_enums), CONN_MASK_FLAGS_PP_MASK,
2067
16
        NULL,
2068
16
        HFILL
2069
16
      }
2070
16
    },
2071
16
    { &hf_mle_tlv_conn_lq3,
2072
16
      { "Link Quality 3",
2073
16
        "mle.tlv.conn.lq3",
2074
16
        FT_UINT8, BASE_DEC, NULL, 0x0,
2075
16
        NULL,
2076
16
        HFILL
2077
16
      }
2078
16
    },
2079
16
    { &hf_mle_tlv_conn_lq2,
2080
16
      { "Link Quality 2",
2081
16
        "mle.tlv.conn.lq2",
2082
16
        FT_UINT8, BASE_DEC, NULL, 0x0,
2083
16
        NULL,
2084
16
        HFILL
2085
16
      }
2086
16
    },
2087
16
    { &hf_mle_tlv_conn_lq1,
2088
16
      { "Link Quality 1",
2089
16
        "mle.tlv.conn.lq1",
2090
16
        FT_UINT8, BASE_DEC, NULL, 0x0,
2091
16
        NULL,
2092
16
        HFILL
2093
16
      }
2094
16
    },
2095
16
    { &hf_mle_tlv_conn_leader_cost,
2096
16
      { "Leader Cost",
2097
16
        "mle.tlv.conn.leader_cost",
2098
16
        FT_UINT8, BASE_DEC, NULL, 0x0,
2099
16
        NULL,
2100
16
        HFILL
2101
16
      }
2102
16
    },
2103
16
    { &hf_mle_tlv_conn_id_seq,
2104
16
      { "ID Sequence",
2105
16
        "mle.tlv.conn.id_seq",
2106
16
        FT_UINT8, BASE_DEC, NULL, 0x0,
2107
16
        NULL,
2108
16
        HFILL
2109
16
      }
2110
16
    },
2111
16
    { &hf_mle_tlv_conn_active_rtrs,
2112
16
      { "Active Routers",
2113
16
        "mle.tlv.conn.active_rtrs",
2114
16
        FT_UINT8, BASE_DEC, NULL, 0x0,
2115
16
        NULL,
2116
16
        HFILL
2117
16
      }
2118
16
    },
2119
16
    { &hf_mle_tlv_conn_sed_buf_size,
2120
16
      { "SED Buffer Size",
2121
16
        "mle.tlv.conn.sed_buf_size",
2122
16
        FT_UINT16, BASE_DEC, NULL, 0x0,
2123
16
        NULL,
2124
16
        HFILL
2125
16
      }
2126
16
    },
2127
16
    { &hf_mle_tlv_conn_sed_dgram_cnt,
2128
16
      { "SED Datagram Count",
2129
16
        "mle.tlv.conn.sed_dgram_cnt",
2130
16
        FT_UINT8, BASE_DEC, NULL, 0x0,
2131
16
        NULL,
2132
16
        HFILL
2133
16
      }
2134
16
    },
2135
16
    { &hf_mle_tlv_link_margin,
2136
16
      { "Link Margin",
2137
16
        "mle.tlv.link_margin",
2138
16
        FT_UINT8, BASE_DEC, NULL, 0,
2139
16
        "Link margin in dB",
2140
16
        HFILL
2141
16
      }
2142
16
    },
2143
16
    { &hf_mle_tlv_status,
2144
16
      { "Status",
2145
16
        "mle.tlv.status",
2146
16
        FT_UINT8, BASE_DEC, VALS(mle_status_tlv_enums), 0,
2147
16
        NULL,
2148
16
        HFILL
2149
16
      }
2150
16
    },
2151
16
    { &hf_mle_tlv_version,
2152
16
      { "Version",
2153
16
        "mle.tlv.version",
2154
16
        FT_UINT16, BASE_DEC, NULL, 0,
2155
16
        NULL,
2156
16
        HFILL
2157
16
      }
2158
16
    },
2159
16
    { &hf_mle_tlv_supervision_interval,
2160
16
      { "Supervision Interval",
2161
16
        "mle.tlv.supervision_interval",
2162
16
        FT_UINT16, BASE_DEC, NULL, 0,
2163
16
        NULL,
2164
16
        HFILL
2165
16
      }
2166
16
    },
2167
16
    { &hf_mle_tlv_addr_reg_entry,
2168
16
      { "Address Registration Entry",
2169
16
        "mle.tlv.addr_reg",
2170
16
        FT_NONE, BASE_NONE, NULL, 0x0,
2171
16
        NULL,
2172
16
        HFILL
2173
16
      }
2174
16
    },
2175
16
    { &hf_mle_tlv_addr_reg_iid_type,
2176
16
      { "IID type",
2177
16
        "mle.tlv.addr_reg_iid_type",
2178
16
        FT_BOOLEAN, 8, TFS(&mle_tlv_addr_reg_iid_type), ADDR_REG_MASK_IID_TYPE_MASK,
2179
16
        "Context ID",
2180
16
        HFILL
2181
16
      }
2182
16
    },
2183
16
    { &hf_mle_tlv_addr_reg_cid,
2184
16
      { "Context ID",
2185
16
        "mle.tlv.addr_reg_cid",
2186
16
        FT_UINT8, BASE_DEC, NULL, ADDR_REG_MASK_CID_MASK,
2187
16
        "6LoWPAN Context ID",
2188
16
        HFILL
2189
16
      }
2190
16
    },
2191
16
    { &hf_mle_tlv_addr_reg_iid,
2192
16
      { "IID",
2193
16
        "mle.tlv.addr_reg_iid",
2194
16
        FT_BYTES, BASE_NONE, NULL, 0x0,
2195
16
        "Interface identifier",
2196
16
        HFILL
2197
16
      }
2198
16
    },
2199
16
    { &hf_mle_tlv_addr_reg_ipv6,
2200
16
      { "IPv6 Address",
2201
16
        "mle.tlv.addr_reg_ipv6",
2202
16
        FT_IPv6, BASE_NONE, NULL, 0x0,
2203
16
        "IID",
2204
16
        HFILL
2205
16
      }
2206
16
    },
2207
#if 0
2208
    { &hf_mle_tlv_hold_time,
2209
      { "Hold Time",
2210
        "mle.tlv.hold_time",
2211
        FT_UINT16, BASE_DEC, NULL, 0,
2212
        NULL,
2213
        HFILL
2214
      }
2215
    },
2216
#endif
2217
16
    { &hf_mle_tlv_network_unknown,
2218
16
      { "(unknown)",
2219
16
        "mle.tlv.network.unknown",
2220
16
        FT_BYTES, BASE_NONE, NULL, 0x0,
2221
16
        NULL,
2222
16
        HFILL
2223
16
      }
2224
16
    },
2225
16
    { &hf_mle_tlv_channel_page,
2226
16
      { "Channel Page",
2227
16
        "mle.tlv.channel_page",
2228
16
        FT_UINT8, BASE_DEC, NULL, 0x0,
2229
16
        NULL,
2230
16
        HFILL
2231
16
      }
2232
16
    },
2233
16
    { &hf_mle_tlv_channel,
2234
16
      { "Channel",
2235
16
        "mle.tlv.channel",
2236
16
        FT_UINT16, BASE_DEC, NULL, 0x0,
2237
16
        NULL,
2238
16
        HFILL
2239
16
      }
2240
16
    },
2241
16
    { &hf_mle_tlv_csl_accuracy,
2242
16
      { "CSL Accuracy",
2243
16
        "mle.tlv.csl_accuracy",
2244
16
        FT_UINT8, BASE_DEC, NULL, 0x0,
2245
16
        NULL,
2246
16
        HFILL
2247
16
      }
2248
16
    },
2249
16
    { &hf_mle_tlv_csl_clock_accuracy,
2250
16
      { "CSL Clock Accuracy",
2251
16
        "mle.tlv.csl_clock_accuracy",
2252
16
        FT_UINT8, BASE_DEC, NULL, 0x0,
2253
16
        NULL,
2254
16
        HFILL
2255
16
      }
2256
16
    },
2257
16
    { &hf_mle_tlv_csl_uncertainty,
2258
16
      { "CSL Uncertainty",
2259
16
        "mle.tlv.csl_uncertainty",
2260
16
         FT_UINT8, BASE_DEC, NULL, 0x0,
2261
16
         NULL,
2262
16
         HFILL
2263
16
       }
2264
16
    },
2265
16
    { &hf_mle_tlv_pan_id,
2266
16
      { "PAN ID",
2267
16
        "mle.tlv.pan_id",
2268
16
        FT_UINT16, BASE_HEX, NULL, 0x0,
2269
16
        NULL,
2270
16
        HFILL
2271
16
      }
2272
16
    },
2273
16
    { &hf_mle_tlv_active_tstamp,
2274
16
      { "Active Timestamp",
2275
16
        "mle.tlv.active_tstamp",
2276
16
        FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x0,
2277
16
        NULL,
2278
16
        HFILL
2279
16
      }
2280
16
    },
2281
16
    { &hf_mle_tlv_pending_tstamp,
2282
16
      { "Pending Timestamp",
2283
16
        "mle.tlv.pending_tstamp",
2284
16
        FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x0,
2285
16
        NULL,
2286
16
        HFILL
2287
16
      }
2288
16
    },
2289
#if 0
2290
    { &hf_mle_tlv_active_op_dataset,
2291
      { "Active Operational Dataset",
2292
        "mle.tlv.active_op_dataset",
2293
        FT_BYTES, BASE_NONE, NULL, 0x0,
2294
        "Thread Active Operational Dataset",
2295
        HFILL
2296
      }
2297
    },
2298
    { &hf_mle_tlv_pending_op_dataset,
2299
      { "Pending Operational Dataset",
2300
        "mle.tlv.pending_op_dataset",
2301
        FT_BYTES, BASE_NONE, NULL, 0x0,
2302
        "Thread Pending Operational Dataset",
2303
        HFILL
2304
      }
2305
    },
2306
#endif
2307
16
    { &hf_mle_tlv_link_query_options,
2308
16
      { "Link Query options",
2309
16
        "mle.tlv.link_query_options",
2310
16
          FT_BYTES, BASE_NONE, NULL, 0x0,
2311
16
          "Link Sub TLV",
2312
16
          HFILL
2313
16
      }
2314
16
    },
2315
16
    { &hf_mle_tlv_csl_synchronized_timeout,
2316
16
        { "CSL Synchronized Timeout",
2317
16
          "mle.tlv.link_csl_synchronized_timeout",
2318
16
          FT_UINT32, BASE_HEX, NULL, 0x0,
2319
16
          "Thread CSL Synchronized Timeout",
2320
16
          HFILL
2321
16
        }
2322
16
      },
2323
16
    { &hf_mle_tlv_link_enh_ack_flags,
2324
16
      { "Enh-ACK Flags",
2325
16
        "mle.tlv.link_enh_ack_flags",
2326
16
          FT_UINT8, BASE_DEC, VALS(mle_tlv_link_enh_ack_flags_vals), 0x0,
2327
16
          "Thread Enh-ACK Flags",
2328
16
          HFILL
2329
16
      }
2330
16
    },
2331
16
    { &hf_mle_tlv_link_requested_type_id_flags,
2332
16
      { "Requested Type ID flags",
2333
16
        "mle.tlv.link_requested_type_id_flags",
2334
16
          FT_BYTES, BASE_NONE, NULL, 0x0,
2335
16
          "Thread Requested Type ID flags",
2336
16
          HFILL
2337
16
      }
2338
16
    },
2339
16
    { &hf_mle_tlv_link_forward_series,
2340
16
        { "Link Forward Series",
2341
16
          "mle.tlv.link_forward_series",
2342
16
          FT_UINT8, BASE_DEC, NULL, 0x0,
2343
16
          "Link Sub TLV",
2344
16
          HFILL
2345
16
        }
2346
16
    },
2347
16
    { &hf_mle_tlv_link_forward_series_flags,
2348
16
      { "Link Forward Series Flags",
2349
16
        "mle.tlv.link_forward_series_flags",
2350
16
        FT_UINT8, BASE_DEC, NULL, 0x0,
2351
16
        "Link Sub TLV",
2352
16
        HFILL
2353
16
      }
2354
16
    },
2355
16
    { &hf_mle_tlv_link_timeout,
2356
16
      { "Link Timeout",
2357
16
        "mle.tlv.link_timeout",
2358
16
        FT_UINT8, BASE_DEC, NULL, 0x0,
2359
16
        "Link Sub TLV",
2360
16
        HFILL
2361
16
      }
2362
16
    },
2363
16
    { &hf_mle_tlv_link_concatenation_link_metric_typeid_flags,
2364
16
      { "Concatenation of Link Metric Type ID Flags",
2365
16
        "mle.tlv.link_concatenation_link_metric_typeid_flags",
2366
16
        FT_UINT8, BASE_DEC, NULL, 0x0,
2367
16
        "Link Sub TLV",
2368
16
        HFILL
2369
16
      }
2370
16
    },
2371
16
    { &hf_mle_tlv_link_status,
2372
16
      { "Link Status",
2373
16
        "mle.tlv.link_status",
2374
16
        FT_UINT8, BASE_DEC,  VALS(mle_tlv_link_param_vals), 0x0,
2375
16
        "Link Sub TLV",
2376
16
        HFILL
2377
16
      }
2378
16
    },
2379
16
    { &hf_mle_tlv_link_status_sub_tlv,
2380
16
      { "Link Sub TLV Status",
2381
16
        "mle.tlv.link_status_sub_tlv",
2382
16
        FT_UINT8, BASE_DEC,  VALS(mle_tlv_link_sub_tlv_vals), 0x0,
2383
16
        "Thread Link Sub TLV Status",
2384
16
        HFILL
2385
16
      }
2386
16
    },
2387
16
    { &hf_mle_tlv_link_sub_tlv,
2388
16
      { "Link Metrics Sub TLV",
2389
16
        "mle.tlv.link_sub_tlv",
2390
16
        FT_UINT8, BASE_DEC,  VALS(mle_tlv_link_param_vals), 0x0,
2391
16
        NULL,
2392
16
        HFILL
2393
16
      }
2394
16
    },
2395
16
    { &hf_mle_tlv_metric_type_id_flags,
2396
16
      { "Metric Type ID Flags",
2397
16
        "mle.tlv.metric_type_id_flags",
2398
16
        FT_BYTES, BASE_NONE, NULL, 0x0,
2399
16
        "Thread Metric Type ID Flags",
2400
16
        HFILL
2401
16
      }
2402
16
    },
2403
16
    { &hf_mle_tlv_value,
2404
16
      { "Value",
2405
16
        "mle.tlv.value",
2406
16
        FT_BYTES, BASE_NONE, NULL, 0x0,
2407
16
        "Thread Value",
2408
16
        HFILL
2409
16
      }
2410
16
    },
2411
16
    { &hf_mle_tlv_query_id,
2412
16
      { "Query ID",
2413
16
        "mle.tlv.query_id",
2414
16
        FT_UINT8, BASE_HEX, NULL, 0x0,
2415
16
        "Thread Query ID",
2416
16
        HFILL
2417
16
      }
2418
16
    },
2419
16
    { &hf_mle_aux_security_header,
2420
16
      { "Auxiliary Security Header", "mle.aux_sec.hdr", FT_NONE, BASE_NONE, NULL,
2421
16
        0x0, "The Auxiliary Security Header of the message", HFILL }
2422
16
    },
2423
16
    { &hf_mle_aux_sec_security_level,
2424
16
      { "Security Level", "mle.aux_sec.sec_level", FT_UINT8, BASE_HEX, VALS(ieee802154_sec_level_names),
2425
16
        IEEE802154_AUX_SEC_LEVEL_MASK, "The Security Level of the message", HFILL }
2426
16
    },
2427
16
    { &hf_mle_aux_sec_security_control,
2428
16
      { "Security Control Field", "mle.aux_sec.security_control_field", FT_UINT8, BASE_HEX, NULL,
2429
16
        0x0, NULL, HFILL }
2430
16
    },
2431
16
    { &hf_mle_aux_sec_key_id_mode,
2432
16
      { "Key Identifier Mode", "mle.aux_sec.key_id_mode", FT_UINT8, BASE_HEX, VALS(ieee802154_key_id_mode_names),
2433
16
        IEEE802154_AUX_KEY_ID_MODE_MASK,
2434
16
        "The scheme to use by the recipient to lookup the key in its key table", HFILL }
2435
16
    },
2436
16
    { &hf_mle_aux_sec_frame_counter_suppression,
2437
16
      { "Frame Counter Suppression", "mle.aux_sec.frame_counter_suppression", FT_BOOLEAN, 8, NULL,
2438
16
        IEEE802154_AUX_FRAME_COUNTER_SUPPRESSION_MASK,
2439
16
        "Whether the frame counter is omitted from the Auxiliary Security Header", HFILL }
2440
16
    },
2441
16
    { &hf_mle_aux_sec_asn_in_nonce,
2442
16
      { "ASN in Nonce", "mle.aux_sec.asn_in_nonce", FT_BOOLEAN, 8, NULL,
2443
16
        IEEE802154_AUX_ASN_IN_NONCE_MASK,
2444
16
        "Whether the ASN is used to generate the nonce instead of the frame counter", HFILL }
2445
16
    },
2446
16
    { &hf_mle_aux_sec_reserved,
2447
16
      { "Reserved", "mle.aux_sec.reserved", FT_UINT8, BASE_HEX, NULL, IEEE802154_AUX_CTRL_RESERVED_MASK,
2448
16
        NULL, HFILL }
2449
16
    },
2450
16
    { &hf_mle_aux_sec_frame_counter,
2451
16
      { "Frame Counter", "mle.aux_sec.frame_counter", FT_UINT32, BASE_DEC, NULL, 0x0,
2452
16
        "Frame counter of the originator of the protected message", HFILL }
2453
16
    },
2454
16
    { &hf_mle_aux_sec_key_source,
2455
16
      { "Key Source", "mle.aux_sec.key_source", FT_UINT64, BASE_HEX, NULL, 0x0,
2456
16
        "Key Source for processing of the protected message", HFILL }
2457
16
    },
2458
16
    { &hf_mle_aux_sec_key_source_bytes,
2459
16
      { "Key Source", "mle.aux_sec.key_source.bytes", FT_BYTES, BASE_NONE, NULL, 0x0,
2460
16
        "Key Source for processing of the protected message", HFILL }
2461
16
    },
2462
16
    { &hf_mle_aux_sec_key_index,
2463
16
      { "Key Index", "mle.aux_sec.key_index", FT_UINT8, BASE_HEX, NULL, 0x0,
2464
16
        "Key Index for processing of the protected message", HFILL }
2465
16
    }
2466
2467
16
  };
2468
2469
16
  static int *ett[] = {
2470
16
    &ett_mle,
2471
16
    &ett_mle_auxiliary_security,
2472
16
    &ett_mle_aux_sec_control,
2473
16
    &ett_mle_aux_sec_key_id,
2474
16
    &ett_mle_tlv,
2475
16
    &ett_mle_neighbor,
2476
16
    &ett_mle_router,
2477
16
    &ett_mle_addr_reg,
2478
16
    &ett_mle_conn_flg,
2479
16
    &ett_mle_thread_nwd
2480
16
};
2481
2482
16
  static ei_register_info ei[] = {
2483
16
    { &ei_mle_cbc_mac_failed, { "mle.cbc_mac_failed", PI_UNDECODED, PI_WARN, "Call to ccm_cbc_mac() failed", EXPFILL }},
2484
16
    { &ei_mle_packet_too_small, { "mle.packet_too_small", PI_UNDECODED, PI_WARN, "Packet was too small to include the CRC and MIC", EXPFILL }},
2485
16
    { &ei_mle_no_key, { "mle.no_key", PI_UNDECODED, PI_WARN, "No encryption key set - can't decrypt", EXPFILL }},
2486
16
    { &ei_mle_decrypt_failed, { "mle.decrypt_failed", PI_UNDECODED, PI_WARN, "Decrypt failed", EXPFILL }},
2487
16
    { &ei_mle_mic_check_failed, { "mle.mic_check_failed", PI_UNDECODED, PI_WARN, "MIC check failed", EXPFILL }},
2488
16
    { &ei_mle_tlv_length_failed, { "mle.tlv_length_failed", PI_UNDECODED, PI_WARN, "TLV Length inconsistent", EXPFILL }},
2489
16
    { &ei_mle_len_size_mismatch, { "mle.len_size_mismatch", PI_UNDECODED, PI_WARN, "TLV Length & Size field disagree", EXPFILL }},
2490
16
  };
2491
2492
16
  module_t *mle_module;
2493
16
  expert_module_t* expert_mle;
2494
2495
16
  proto_mle = proto_register_protocol("Mesh Link Establishment", "MLE", "mle");
2496
16
  proto_register_field_array(proto_mle, hf, array_length(hf));
2497
16
  proto_register_subtree_array(ett, array_length(ett));
2498
16
  expert_mle = expert_register_protocol(proto_mle);
2499
16
  expert_register_field_array(expert_mle, ei, array_length(ei));
2500
2501
16
  mle_aux_sec_hf.hf_aux_security_header = hf_mle_aux_security_header;
2502
16
  mle_aux_sec_hf.hf_aux_sec_security_control = hf_mle_aux_sec_security_control;
2503
16
  mle_aux_sec_hf.hf_aux_sec_security_level = hf_mle_aux_sec_security_level;
2504
16
  mle_aux_sec_hf.hf_aux_sec_key_id_mode = hf_mle_aux_sec_key_id_mode;
2505
16
  mle_aux_sec_hf.hf_aux_sec_frame_counter_suppression = hf_mle_aux_sec_frame_counter_suppression;
2506
16
  mle_aux_sec_hf.hf_aux_sec_asn_in_nonce = hf_mle_aux_sec_asn_in_nonce;
2507
16
  mle_aux_sec_hf.hf_aux_sec_reserved = hf_mle_aux_sec_reserved;
2508
16
  mle_aux_sec_hf.hf_aux_sec_frame_counter = hf_mle_aux_sec_frame_counter;
2509
16
  mle_aux_sec_hf.hf_aux_sec_key_source = hf_mle_aux_sec_key_source;
2510
16
  mle_aux_sec_hf.hf_aux_sec_key_source_bytes = hf_mle_aux_sec_key_source_bytes;
2511
16
  mle_aux_sec_hf.hf_aux_sec_key_index = hf_mle_aux_sec_key_index;
2512
16
  mle_aux_sec_hf.ett_auxiliary_security = ett_mle_auxiliary_security;
2513
16
  mle_aux_sec_hf.ett_aux_sec_control = ett_mle_aux_sec_control;
2514
16
  mle_aux_sec_hf.ett_aux_sec_key_id = ett_mle_aux_sec_key_id;
2515
2516
16
  mle_handle = register_dissector("mle", dissect_mle, proto_mle);
2517
2518
16
  mle_module = prefs_register_protocol(proto_mle, NULL);
2519
2520
16
  prefs_register_bool_preference(mle_module, "meshlink_mic_ok",
2521
16
                  "Dissect only good MIC",
2522
16
                  "Dissect payload only if MIC is valid.",
2523
16
                   &mle_mic_ok);
2524
2525
    /* setup registration for other dissectors to provide mle key hash algorithms */
2526
16
    mle_key_hash_handlers = wmem_tree_new(wmem_epan_scope());
2527
16
 }
2528
2529
void
2530
proto_reg_handoff_mle(void)
2531
16
{
2532
16
    thread_nwd_handle = find_dissector_add_dependency("thread_nwd", proto_mle);
2533
16
    thread_mc_handle = find_dissector_add_dependency("thread_meshcop", proto_mle);
2534
2535
    //heur_dissector_add("stun", dissect_embeddedmle_heur, proto_mle);
2536
2537
16
    dissector_add_uint_range_with_preference("udp.port", UDP_PORT_MLE_RANGE, mle_handle);
2538
2539
16
    proto_ieee802154 = proto_get_id_by_filter_name(IEEE802154_PROTOABBREV_WPAN);
2540
16
}
2541
2542
/*
2543
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
2544
 *
2545
 * Local variables:
2546
 * c-basic-offset: 2
2547
 * tab-width: 8
2548
 * indent-tabs-mode: nil
2549
 * End:
2550
 *
2551
 * vi: set shiftwidth=2 tabstop=8 expandtab
2552
 * :indentSize=2:tabSize=8:noTabs=true:
2553
 */