Coverage Report

Created: 2026-07-12 07:10

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