2 * Routines for Thread over CoAP and beacon packet dissection
4 * Robert Cragie <robert.cragie@arm.com>
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * SPDX-License-Identifier: GPL-2.0-or-later
16 #include <epan/packet.h>
17 #include <epan/proto_data.h>
18 #include <epan/wmem_scopes.h>
19 #include <epan/expert.h>
20 #include <epan/prefs.h>
21 #include <epan/strutil.h>
22 #include <epan/to_str.h>
24 #include <wsutil/array.h>
25 #include "packet-coap.h"
26 #include "packet-ieee802154.h"
27 #include "packet-mle.h"
29 /* Use libgcrypt for cipher libraries. */
30 #include <wsutil/wsgcrypt.h>
32 /* Thread Vendor Sub IE Fields */
33 #define THREAD_IE_ID_MASK 0xFFC0
34 #define THREAD_IE_LENGTH_MASK 0x003F
36 /* Forward declarations */
37 void proto_register_thread_coap(void);
39 void proto_register_thread_address(void);
40 void proto_reg_handoff_thread_address(void);
42 void proto_register_thread_dg(void);
43 void proto_reg_handoff_thread_dg(void);
45 void proto_register_thread_mc(void);
46 void proto_reg_handoff_thread_mc(void);
48 void proto_register_thread_nwd(void);
50 void proto_register_thread_bcn(void);
51 void proto_reg_handoff_thread_bcn(void);
53 void proto_register_thread(void);
54 void proto_reg_handoff_thread(void);
56 void proto_register_thread_nm(void);
57 void proto_reg_handoff_thread_nm(void);
59 void proto_register_thread_bl(void);
60 void proto_reg_handoff_thread_bl(void);
62 static int proto_thread_address
;
63 static int proto_thread_dg
;
64 static int proto_thread_mc
;
65 static int proto_thread_nwd
;
66 static int proto_thread_coap
;
67 static int proto_thread_bcn
;
68 static int proto_thread_nm
;
69 static int proto_thread_bl
;
70 static int proto_thread
;
71 static int proto_thread_ie
;
72 static int proto_coap
;
78 static int hf_thread_address_tlv
;
79 static int hf_thread_address_tlv_type
;
80 static int hf_thread_address_tlv_length
;
81 static int hf_thread_address_tlv_unknown
;
82 /* static int hf_thread_address_tlv_sub_tlvs; */
84 /* Target EID TLV fields */
85 static int hf_thread_address_tlv_target_eid
;
87 /* Ext. MAC address TLV fields */
88 static int hf_thread_address_tlv_ext_mac_addr
;
90 /* RLOC16 TLV fields */
91 static int hf_thread_address_tlv_rloc16
;
93 /* Mesh Local IID TLV fields */
94 static int hf_thread_address_tlv_ml_eid
;
96 /* Status TLV fields */
97 static int hf_thread_address_tlv_status
;
99 /* Attached time TLV fields */
100 /* static int hf_thread_address_tlv_attached_time; */
102 /* Last transaction time TLV fields */
103 static int hf_thread_address_tlv_last_transaction_time
;
105 /* Router Mask TLV fields */
106 static int hf_thread_address_tlv_router_mask_id_seq
;
107 static int hf_thread_address_tlv_router_mask_assigned
;
109 /* ND option fields */
110 static int hf_thread_address_tlv_nd_option
;
113 static int hf_thread_address_tlv_nd_data
;
114 static int hf_thread_address_tlv_timeout
;
116 /* Thread diagnostics */
118 static int hf_thread_dg_tlv
;
119 static int hf_thread_dg_tlv_type
;
120 static int hf_thread_dg_tlv_length8
;
121 static int hf_thread_dg_tlv_length16
;
122 static int hf_thread_dg_tlv_general
;
123 static int hf_thread_dg_tlv_unknown
;
126 /**** TBC: will be added later. For now, just use general string ****/
127 static int hf_thread_dg_tlv_source_addr
;
128 static int hf_thread_dg_tlv_mode_device_type
;
129 static int hf_thread_dg_tlv_mode_idle_rx
;
130 static int hf_thread_dg_tlv_mode_sec_data_req
;
131 static int hf_thread_dg_tlv_mode_nwk_data
;
132 static int hf_thread_dg_tlv_timeout
;
133 static int hf_thread_dg_tlv_lqi_c
;
134 static int hf_thread_dg_tlv_lqi_size
;
135 static int hf_thread_dg_tlv_neighbor
;
136 static int hf_thread_dg_tlv_neighbor_flagI
;
137 static int hf_thread_dg_tlv_neighbor_flagO
;
138 static int hf_thread_dg_tlv_neighbor_flagP
;
139 static int hf_thread_dg_tlv_neighbor_idr
;
140 static int hf_thread_dg_tlv_neighbor_addr
;
141 static int hf_thread_dg_tlv_network_param_id
;
142 static int hf_thread_dg_tlv_network_delay
;
143 static int hf_thread_dg_tlv_network_channel
;
144 static int hf_thread_dg_tlv_network_pan_id
;
145 static int hf_thread_dg_tlv_network_pmt_join
;
146 static int hf_thread_dg_tlv_network_bcn_payload
;
147 static int hf_thread_dg_tlv_network_unknown
;
148 static int hf_thread_dg_tlv_mle_frm_cntr
;
149 static int hf_thread_dg_tlv_route_tbl_id_seq
;
150 static int hf_thread_dg_tlv_route_tbl_id_mask
;
151 static int hf_thread_dg_tlv_route_tbl_entry
;
152 static int hf_thread_dg_tlv_route_tbl_nbr_out
;
153 static int hf_thread_dg_tlv_route_tbl_nbr_in
;
154 static int hf_thread_dg_tlv_route_tbl_cost
;
155 static int hf_thread_dg_tlv_route_tbl_unknown
;
156 static int hf_thread_dg_tlv_addr_16
;
157 static int hf_thread_dg_tlv_leader_data_partition_id
;
158 static int hf_thread_dg_tlv_leader_data_weighting
;
159 static int hf_thread_dg_tlv_leader_data_version
;
160 static int hf_thread_dg_tlv_leader_data_stable_version
;
161 static int hf_thread_dg_tlv_leader_data_router_id
;
162 static int hf_thread_dg_tlv_network_data
;
163 static int hf_thread_dg_tlv_scan_mask_r
;
164 static int hf_thread_dg_tlv_scan_mask_e
;
165 static int hf_thread_dg_tlv_conn_max_child_cnt
;
166 static int hf_thread_dg_tlv_conn_child_cnt
;
167 static int hf_thread_dg_tlv_conn_lq3
;
168 static int hf_thread_dg_tlv_conn_lq2
;
169 static int hf_thread_dg_tlv_conn_lq1
;
170 static int hf_thread_dg_tlv_conn_leader_cost
;
171 static int hf_thread_dg_tlv_conn_id_seq
;
172 static int hf_thread_dg_tlv_link_margin
;
173 static int hf_thread_dg_tlv_status
;
174 static int hf_thread_dg_tlv_version
;
175 static int hf_thread_dg_tlv_addr_reg_entry
;
176 static int hf_thread_dg_tlv_addr_reg_iid_type
;
177 static int hf_thread_dg_tlv_addr_reg_cid
;
178 static int hf_thread_dg_tlv_addr_reg_iid
;
179 static int hf_thread_dg_tlv_addr_reg_ipv6
;
180 static int hf_thread_dg_tlv_hold_time
;
185 static int hf_thread_mc_tlv
;
186 static int hf_thread_mc_tlv_type
;
187 static int hf_thread_mc_tlv_length8
;
188 static int hf_thread_mc_tlv_length16
;
189 static int hf_thread_mc_tlv_unknown
;
190 /* static int hf_thread_mc_tlv_sub_tlvs; */
192 /* Channel TLV fields */
193 static int hf_thread_mc_tlv_channel_page
;
194 static int hf_thread_mc_tlv_channel
;
196 /* PAN ID TLV fields */
197 static int hf_thread_mc_tlv_pan_id
;
199 /* Extended PAN ID TLV fields */
200 static int hf_thread_mc_tlv_xpan_id
;
202 /* Network Name TLV fields */
203 static int hf_thread_mc_tlv_net_name
;
205 /* PSKc TLV fields */
206 static int hf_thread_mc_tlv_pskc
;
208 /* Master Key TLV fields */
209 static int hf_thread_mc_tlv_master_key
;
211 /* Network Key Sequence TLV fields */
212 static int hf_thread_mc_tlv_net_key_seq_ctr
;
214 /* Mesh Local ULA TLV fields */
215 static int hf_thread_mc_tlv_ml_prefix
;
217 /* Steering Data TLV fields */
218 static int hf_thread_mc_tlv_steering_data
;
220 /* Border Agent Locator TLV fields */
221 static int hf_thread_mc_tlv_ba_locator
;
223 /* Commissioner ID TLV fields */
224 static int hf_thread_mc_tlv_commissioner_id
;
226 /* Commissioner ID TLV fields */
227 static int hf_thread_mc_tlv_commissioner_sess_id
;
229 /* Security Policy TLV fields */
230 static int hf_thread_mc_tlv_sec_policy_rot
;
231 static int hf_thread_mc_tlv_sec_policy_o
;
232 static int hf_thread_mc_tlv_sec_policy_n
;
233 static int hf_thread_mc_tlv_sec_policy_r
;
234 static int hf_thread_mc_tlv_sec_policy_c
;
235 static int hf_thread_mc_tlv_sec_policy_b
;
236 static int hf_thread_mc_tlv_sec_policy_ccm
;
237 static int hf_thread_mc_tlv_sec_policy_ae
;
238 static int hf_thread_mc_tlv_sec_policy_nmp
;
239 static int hf_thread_mc_tlv_sec_policy_l
;
240 static int hf_thread_mc_tlv_sec_policy_ncr
;
241 static int hf_thread_mc_tlv_sec_policy_rsv
;
242 static int hf_thread_mc_tlv_sec_policy_rsv1
;
243 static int hf_thread_mc_tlv_sec_policy_vr
;
246 /* State TLV fields */
247 static int hf_thread_mc_tlv_state
;
249 /* Timestamp TLV fields */
250 static int hf_thread_mc_tlv_active_tstamp
;
251 static int hf_thread_mc_tlv_pending_tstamp
;
253 /* Delay Timer TLV fields */
254 static int hf_thread_mc_tlv_delay_timer
;
256 /* UDP Encapsulation TLV fields */
257 static int hf_thread_mc_tlv_udp_encap_src_port
;
258 static int hf_thread_mc_tlv_udp_encap_dst_port
;
260 /* IPv6 Address fields */
261 static int hf_thread_mc_tlv_ipv6_addr
;
263 /* UDP Port TLV fields */
264 static int hf_thread_mc_tlv_udp_port
;
267 static int hf_thread_mc_tlv_iid
;
269 /* Joiner Router locator TLV fields */
270 static int hf_thread_mc_tlv_jr_locator
;
273 static int hf_thread_mc_tlv_kek
;
275 /* Provisioning URL TLV fields */
276 static int hf_thread_mc_tlv_provisioning_url
;
278 /* Vendor TLV fields */
279 static int hf_thread_mc_tlv_vendor_name
;
280 static int hf_thread_mc_tlv_vendor_model
;
281 static int hf_thread_mc_tlv_vendor_sw_ver
;
282 static int hf_thread_mc_tlv_vendor_data
;
283 static int hf_thread_mc_tlv_vendor_stack_ver_oui
;
284 static int hf_thread_mc_tlv_vendor_stack_ver_build
;
285 static int hf_thread_mc_tlv_vendor_stack_ver_rev
;
286 static int hf_thread_mc_tlv_vendor_stack_ver_min
;
287 static int hf_thread_mc_tlv_vendor_stack_ver_maj
;
289 /* Channel Mask TLV fields */
290 static int hf_thread_mc_tlv_chan_mask
;
291 static int hf_thread_mc_tlv_chan_mask_page
;
292 static int hf_thread_mc_tlv_chan_mask_len
;
293 static int hf_thread_mc_tlv_chan_mask_mask
;
295 /* Count TLV fields */
296 static int hf_thread_mc_tlv_count
;
298 /* Period TLV fields */
299 static int hf_thread_mc_tlv_period
;
301 /* Period TLV fields */
302 static int hf_thread_mc_tlv_scan_duration
;
304 /* Energy List TLV fields */
305 static int hf_thread_mc_tlv_energy_list
;
306 static int hf_thread_mc_tlv_el_count
;
308 /* Domain Name TLV fields */
309 static int hf_thread_mc_tlv_domain_name
;
311 /* AE Steering Data TLV fields */
312 static int hf_thread_mc_tlv_ae_steering_data
;
314 /* NMKP Steering Data TLV fields */
315 static int hf_thread_mc_tlv_nmkp_steering_data
;
317 /* Commissioner Signature TLV fields */
318 static int hf_thread_mc_tlv_commissioner_signature
;
320 /* AE UDP Port TLV fields */
321 static int hf_thread_mc_tlv_ae_udp_port
;
323 /* NMKP UDP Port TLV fields */
324 static int hf_thread_mc_tlv_nmkp_udp_port
;
326 /* Registrar IPv6 Address fields */
327 static int hf_thread_mc_tlv_registrar_ipv6_addr
;
329 /* Registrar Hostname fields */
330 static int hf_thread_mc_tlv_registrar_hostname
;
332 /* Discovery Request TLV fields */
333 static int hf_thread_mc_tlv_discovery_req_ver
;
334 static int hf_thread_mc_tlv_discovery_req_j
;
336 /* Discovery Response TLV fields */
337 static int hf_thread_mc_tlv_discovery_rsp_ver
;
338 static int hf_thread_mc_tlv_discovery_rsp_n
;
339 static int hf_thread_mc_tlv_discovery_rsp_c
;
341 /* Thread Network Data */
343 static int hf_thread_nwd_tlv
;
344 static int hf_thread_nwd_tlv_type
;
345 static int hf_thread_nwd_tlv_stable
;
346 static int hf_thread_nwd_tlv_length
;
347 static int hf_thread_nwd_tlv_unknown
;
348 static int hf_thread_nwd_tlv_sub_tlvs
;
350 /* Has Route TLV fields */
351 static int hf_thread_nwd_tlv_has_route
;
352 static int hf_thread_nwd_tlv_has_route_br_16
;
353 static int hf_thread_nwd_tlv_has_route_pref
;
354 static int hf_thread_nwd_tlv_has_route_np
;
355 static int hf_thread_nwd_tlv_has_route_reserved
;
358 /* Prefix TLV fields */
359 static int hf_thread_nwd_tlv_prefix
;
360 static int hf_thread_nwd_tlv_prefix_domain_id
;
361 static int hf_thread_nwd_tlv_prefix_length
;
363 /* Border Router TLV fields */
364 static int hf_thread_nwd_tlv_border_router
;
365 static int hf_thread_nwd_tlv_border_router_16
;
366 static int hf_thread_nwd_tlv_border_router_pref
;
367 static int hf_thread_nwd_tlv_border_router_p
;
368 static int hf_thread_nwd_tlv_border_router_s
;
369 static int hf_thread_nwd_tlv_border_router_d
;
370 static int hf_thread_nwd_tlv_border_router_c
;
371 static int hf_thread_nwd_tlv_border_router_r
;
372 static int hf_thread_nwd_tlv_border_router_o
;
373 static int hf_thread_nwd_tlv_border_router_n
;
374 static int hf_thread_nwd_tlv_border_router_dp
;
376 /* 6LoWPAN ID TLV fields */
377 static int hf_thread_nwd_tlv_6lowpan_id_6co_context_length
;
378 static int hf_thread_nwd_tlv_6lowpan_id_6co_flag
;
379 static int hf_thread_nwd_tlv_6lowpan_id_6co_flag_c
;
380 static int hf_thread_nwd_tlv_6lowpan_id_6co_flag_cid
;
381 static int hf_thread_nwd_tlv_6lowpan_id_6co_flag_reserved
;
383 /* Commissioning Data fields */
384 /* static int hf_thread_nwd_tlv_comm_data; */
387 static int hf_thread_nwd_tlv_service_t
;
388 static int hf_thread_nwd_tlv_service_s_id
;
389 static int hf_thread_nwd_tlv_service_s_ent_num
;
390 static int hf_thread_nwd_tlv_service_s_data_len
;
391 static int hf_thread_nwd_tlv_service_s_data
;
392 static int hf_thread_nwd_tlv_service_s_data_seqno
;
393 static int hf_thread_nwd_tlv_service_s_data_rrdelay
;
394 static int hf_thread_nwd_tlv_service_s_data_mlrtimeout
;
396 // Thread 1.3 Service TLV code
397 static int hf_thread_nwd_tlv_service_srp_dataset_identifier
;
398 static int hf_thread_nwd_tlv_service_anycast_seqno
;
399 static int hf_thread_nwd_tlv_service_unicast_ipv6_address
;
400 static int hf_thread_nwd_tlv_service_unicast_port_number
;
403 static int hf_thread_nwd_tlv_server_16
;
404 static int hf_thread_nwd_tlv_server_data
;
408 static int hf_thread_bcn_protocol
;
409 static int hf_thread_bcn_joining
;
410 static int hf_thread_bcn_native
;
411 static int hf_thread_bcn_version
;
412 static int hf_thread_bcn_network_id
;
413 static int hf_thread_bcn_epid
;
414 static int hf_thread_bcn_tlv
;
415 static int hf_thread_bcn_tlv_type
;
416 static int hf_thread_bcn_tlv_length
;
417 static int hf_thread_bcn_tlv_steering_data
;
418 static int hf_thread_bcn_tlv_unknown
;
422 static int ett_thread_address
;
423 static int ett_thread_address_tlv
;
424 static int ett_thread_dg
;
425 static int ett_thread_dg_tlv
;
426 static int ett_thread_mc
;
427 static int ett_thread_mc_tlv
;
428 static int ett_thread_mc_chan_mask
;
429 static int ett_thread_mc_el_count
;
430 static int ett_thread_nwd
;
431 static int ett_thread_nwd_tlv
;
432 static int ett_thread_nwd_has_route
;
433 static int ett_thread_nwd_6co_flag
;
434 static int ett_thread_nwd_border_router
;
435 static int ett_thread_nwd_prefix_sub_tlvs
;
436 static int ett_thread_bcn
;
437 static int ett_thread_bcn_tlv
;
438 static int ett_thread_nm
;
439 static int ett_thread_nm_tlv
;
440 static int ett_thread_bl
;
441 static int ett_thread_bl_tlv
;
443 static int ett_thread
;
444 /* static int ett_thread_header_ie; */
445 static int ett_thread_ie_fields
;
451 /* static expert_field ei_thread_address_tlv_length_failed; */
452 static expert_field ei_thread_address_len_size_mismatch
;
453 /* static expert_field ei_thread_dg_tlv_length_failed; */
454 /* static expert_field ei_thread_dg_len_size_mismatch; */
455 static expert_field ei_thread_mc_tlv_length_failed
;
456 static expert_field ei_thread_mc_len_size_mismatch
;
457 static expert_field ei_thread_mc_len_too_long
;
458 /* static expert_field ei_thread_nwd_tlv_length_failed; */
459 static expert_field ei_thread_nwd_len_size_mismatch
;
460 static expert_field ei_thread_nm_len_size_mismatch
;
461 static expert_field ei_thread_bl_len_size_mismatch
;
464 static dissector_table_t thread_coap_namespace
;
466 /* Dissector handles */
467 static dissector_handle_t thread_address_nwd_handle
;
468 static dissector_handle_t thread_dg_handle
;
469 static dissector_handle_t thread_mc_handle
;
470 static dissector_handle_t thread_dtls_handle
;
471 static dissector_handle_t thread_udp_handle
;
472 static dissector_handle_t thread_coap_handle
;
473 static dissector_handle_t thread_address_handle
;
474 static dissector_handle_t thread_nm_handle
;
475 static dissector_handle_t thread_bl_handle
;
477 /* 802.15.4 Thread ID */
478 static int hf_ieee802154_thread_ie
;
479 static int hf_ieee802154_thread_ie_id
;
480 static int hf_ieee802154_thread_ie_length
;
482 #define THREAD_SERVICE_DATA_BBR 0x1
484 #define THREAD_TLV_LENGTH_ESC 0xFF
486 #define THREAD_URI_NAMESPACE_IDX 1
488 #define THREAD_MC_32768_TO_NSEC_FACTOR ((double)30517.578125)
489 #define THREAD_MC_TSTAMP_MASK_U_MASK 0x80
490 #define THREAD_MC_SEC_POLICY_MASK_O_MASK 0x80
491 #define THREAD_MC_SEC_POLICY_MASK_N_MASK 0x40
492 #define THREAD_MC_SEC_POLICY_MASK_R_MASK 0x20
493 #define THREAD_MC_SEC_POLICY_MASK_C_MASK 0x10
494 #define THREAD_MC_SEC_POLICY_MASK_B_MASK 0x08
495 #define THREAD_MC_SEC_POLICY_MASK_CCM_MASK 0x04
496 #define THREAD_MC_SEC_POLICY_MASK_AE_MASK 0x02
497 #define THREAD_MC_SEC_POLICY_MASK_NMP_MASK 0x01
498 #define THREAD_MC_SEC_POLICY_MASK_L_MASK 0x80
499 #define THREAD_MC_SEC_POLICY_MASK_NCR_MASK 0x40
500 #define THREAD_MC_SEC_POLICY_MASK_RSV_MASK 0x38
501 #define THREAD_MC_SEC_POLICY_MASK_RSV1_MASK 0x07
502 #define THREAD_MC_SEC_POLICY_MASK_VR_MASK 0x07
503 #define THREAD_MC_STACK_VER_REV_MASK 0x0F
504 #define THREAD_MC_STACK_VER_MIN_MASK 0xF0
505 #define THREAD_MC_STACK_VER_MAJ_MASK 0x0F
506 #define THREAD_MC_DISCOVERY_REQ_MASK_VER_MASK 0xF0
507 #define THREAD_MC_DISCOVERY_REQ_MASK_J_MASK 0x08
508 #define THREAD_MC_DISCOVERY_RSP_MASK_VER_MASK 0xF0
509 #define THREAD_MC_DISCOVERY_RSP_MASK_N_MASK 0x08
510 #define THREAD_MC_DISCOVERY_RSP_MASK_C_MASK 0x04
511 #define THREAD_MC_INVALID_CHAN_COUNT 0xFFFF
513 #define THREAD_NWD_TLV_HAS_ROUTE_PREF 0xC0
514 #define THREAD_NWD_TLV_HAS_ROUTE_NP 0x20
515 #define THREAD_NWD_TLV_HAS_ROUTE_RESERVED 0x1F
516 #define THREAD_NWD_TLV_HAS_ROUTE_SIZE 3
518 #define THREAD_NWD_TLV_BORDER_ROUTER_PREF 0xC0
519 #define THREAD_NWD_TLV_HAS_ROUTE_NP 0x20
520 #define THREAD_NWD_TLV_HAS_ROUTE_RESERVED 0x1F
521 #define THREAD_NWD_TLV_BORDER_ROUTER_P 0x20
522 #define THREAD_NWD_TLV_BORDER_ROUTER_S 0x10
523 #define THREAD_NWD_TLV_BORDER_ROUTER_D 0x08
524 #define THREAD_NWD_TLV_BORDER_ROUTER_C 0x04
525 #define THREAD_NWD_TLV_BORDER_ROUTER_R 0x02
526 #define THREAD_NWD_TLV_BORDER_ROUTER_O 0x01
527 #define THREAD_NWD_TLV_BORDER_ROUTER_N 0x80
528 #define THREAD_NWD_TLV_BORDER_ROUTER_DP 0x40 //Thread 1.2 Draft5
530 #define THREAD_BCN_PROTOCOL_ID 0x03
531 #define THREAD_BCN_JOINING 0x01
532 #define THREAD_BCN_NATIVE 0x08
533 #define THREAD_BCN_PROTOCOL_VERSION 0xf0
534 #define THREAD_BCN_TLV_STEERING_DATA_S 0x80
535 #define THREAD_BCN_TLV_STEERING_DATA 8
537 #define ND_OPT_6CO_FLAG_C 0x10
538 #define ND_OPT_6CO_FLAG_CID 0x0F
539 #define ND_OPT_6CO_FLAG_RESERVED 0xE0
541 #define THREAD_NWD_TLV_SERVICE_T 0x80
542 #define THREAD_NWD_TLV_SERVICE_S_ID 0x0F
558 #define THREAD_ADDRESS_TLV_TARGET_EID 0
559 #define THREAD_ADDRESS_TLV_EXT_MAC_ADDR 1
560 #define THREAD_ADDRESS_TLV_RLOC16 2
561 #define THREAD_ADDRESS_TLV_ML_EID 3
562 #define THREAD_ADDRESS_TLV_STATUS 4
564 #define THREAD_ADDRESS_TLV_LAST_TRANSACTION_TIME 6
565 #define THREAD_ADDRESS_TLV_ROUTER_MASK 7
566 #define THREAD_ADDRESS_TLV_ND_OPTION 8
567 #define THREAD_ADDRESS_TLV_ND_DATA 9
568 #define THREAD_ADDRESS_TLV_THREAD_NETWORK_DATA 10
569 #define THREAD_ADDRESS_TLV_TIMEOUT 11
570 #define THREAD_ADDRESS_TLV_THREAD_NETWORK_NAME 12
571 #define THREAD_ADDRESS_TLV_IPV6_ADDRESS 14
573 static const value_string thread_address_tlv_vals
[] = {
574 { THREAD_ADDRESS_TLV_TARGET_EID
, "Target EID" },
575 { THREAD_ADDRESS_TLV_EXT_MAC_ADDR
, "Extended MAC Address" },
576 { THREAD_ADDRESS_TLV_RLOC16
, "RLOC16" },
577 { THREAD_ADDRESS_TLV_ML_EID
, "ML-EID" },
578 { THREAD_ADDRESS_TLV_STATUS
, "Status" },
580 { THREAD_ADDRESS_TLV_LAST_TRANSACTION_TIME
, "Last Transaction Time" },
581 { THREAD_ADDRESS_TLV_ROUTER_MASK
, "Router Mask" },
582 { THREAD_ADDRESS_TLV_ND_OPTION
, "ND Option" },
583 { THREAD_ADDRESS_TLV_ND_DATA
, "ND Data" },
584 { THREAD_ADDRESS_TLV_THREAD_NETWORK_DATA
, "Thread Network Data" },
585 { THREAD_ADDRESS_TLV_TIMEOUT
, "Timeout"},
586 { THREAD_ADDRESS_TLV_THREAD_NETWORK_NAME
, "Thread Network Name" },
587 { THREAD_ADDRESS_TLV_IPV6_ADDRESS
, "IPv6 Address"},
591 static const value_string thread_address_tlv_status_vals
[] = {
593 { 1, "No Address Available" },
594 { 2, "TOO_FEW_ROUTERS" },
595 { 3, "HAVE_CHILD_ID_REQUEST" },
596 { 4, "PARENT_PARTITION_CHANGE" },
600 /* Network Layer (Address) mirrors */
601 #define THREAD_DG_TLV_EXT_MAC_ADDR 0 /* As THREAD_ADDRESS_TLV_EXT_MAC_ADDR */
603 #define THREAD_DG_TLV_ADDRESS16 1 /* As MLE_TLV_ADDRESS16 */
604 #define THREAD_DG_TLV_MODE 2 /* As MLE_TLV_MODE */
605 #define THREAD_DG_TLV_TIMEOUT 3 /* As MLE_TLV_TIMEOUT */
606 #define THREAD_DG_TLV_CONNECTIVITY 4 /* As MLE_TLV_CONNECTIVITY */
607 #define THREAD_DG_TLV_ROUTE64 5 /* As MLE_TLV_ROUTE64 */
608 #define THREAD_DG_TLV_LEADER_DATA 6 /* As MLE_TLV_LEADER_DATA */
609 #define THREAD_DG_TLV_NETWORK_DATA 7 /* As MLE_TLV_NETWORK_DATA */
611 #define THREAD_DG_TLV_IPV6_ADDR_LIST 8
612 #define THREAD_DG_TLV_MAC_COUNTERS 9
614 #define THREAD_DG_TLV_BATTERY_LEVEL 14
615 #define THREAD_DG_TLV_VOLTAGE 15
616 #define THREAD_DG_TLV_CHILD_TABLE 16
617 #define THREAD_DG_TLV_CHANNEL_PAGES 17
618 #define THREAD_DG_TLV_TYPE_LIST 18
619 #define THREAD_DG_TLV_MAX_CHILD_TIMEOUT 19
620 #define THREAD_DG_TLV_LDEVID_SUBJECT_PUBLIC_KEY_INFO 20
621 #define THREAD_DG_TLV_IDEVID_CERTIFICATE 21
623 #define THREAD_DG_TLV_EUI_64 23
624 #define THREAD_DG_TLV_VERSION 24
625 #define THREAD_DG_TLV_VENDOR_NAME 25
626 #define THREAD_DG_TLV_VENDOR_MODEL 26
627 #define THREAD_DG_TLV_VENDOR_SW_VERSION 27
628 #define THREAD_DG_TLV_THREAD_STACK_VERSION 28
629 #define THREAD_DG_TLV_CHILD 29
630 #define THREAD_DG_TLV_CHILD_IPV6_ADDRESS_LIST 30
631 #define THREAD_DG_TLV_ROUTER_NEIGHBOR 31
632 #define THREAD_DG_TLV_ANSWER 32
633 #define THREAD_DG_TLV_QUERY_ID 33
634 #define THREAD_DG_TLV_MLE_COUNTERS 34
635 #define THREAD_DG_TLV_UNKNOWN 255
637 static const value_string thread_dg_tlv_vals
[] = {
638 /* Network Layer (Address) mirrors */
639 { THREAD_DG_TLV_EXT_MAC_ADDR
, "Extended MAC Address" },
641 { THREAD_DG_TLV_ADDRESS16
, "Address16" },
642 { THREAD_DG_TLV_MODE
, "Mode" },
643 { THREAD_DG_TLV_TIMEOUT
, "Timeout" },
644 { THREAD_DG_TLV_CONNECTIVITY
, "Connectivity" },
645 { THREAD_DG_TLV_ROUTE64
, "Route64" },
646 { THREAD_DG_TLV_LEADER_DATA
, "Leader Data" },
647 { THREAD_DG_TLV_NETWORK_DATA
, "Network Data" },
649 { THREAD_DG_TLV_IPV6_ADDR_LIST
, "IPv6 Address List" },
650 { THREAD_DG_TLV_MAC_COUNTERS
, "MAC Counters" },
652 { THREAD_DG_TLV_BATTERY_LEVEL
, "Battery level (%)" },
653 { THREAD_DG_TLV_VOLTAGE
, "Voltage (mV)" },
654 { THREAD_DG_TLV_CHILD_TABLE
, "Child Table" },
655 { THREAD_DG_TLV_CHANNEL_PAGES
, "Channel Pages" },
656 { THREAD_DG_TLV_TYPE_LIST
, "Type List" },
657 { THREAD_DG_TLV_MAX_CHILD_TIMEOUT
, "Max Child Timeout"},
658 { THREAD_DG_TLV_LDEVID_SUBJECT_PUBLIC_KEY_INFO
, "LDevID Subject Public Key Info"},
659 { THREAD_DG_TLV_IDEVID_CERTIFICATE
, "IDevID Certificate"},
660 { THREAD_DG_TLV_EUI_64
, "EUI-64"},
661 { THREAD_DG_TLV_VERSION
, "Version"},
662 { THREAD_DG_TLV_VENDOR_NAME
, "Vendor Name"},
663 { THREAD_DG_TLV_VENDOR_MODEL
, "Vendor Model"},
664 { THREAD_DG_TLV_VENDOR_SW_VERSION
, "Vendor SW Version"},
665 { THREAD_DG_TLV_THREAD_STACK_VERSION
, "Thread Stack Version"},
666 { THREAD_DG_TLV_CHILD
, "Child"},
667 { THREAD_DG_TLV_CHILD_IPV6_ADDRESS_LIST
, "Child IPV6 Address List"},
668 { THREAD_DG_TLV_ROUTER_NEIGHBOR
, "Router Neighbor"},
669 { THREAD_DG_TLV_ANSWER
, "Answer"},
670 { THREAD_DG_TLV_QUERY_ID
, "Query ID"},
671 { THREAD_DG_TLV_MLE_COUNTERS
, "MLE Counters"},
672 { THREAD_DG_TLV_UNKNOWN
, "Unknown" },
676 #define THREAD_MC_TLV_CHANNEL 0 /* Modified for new features */
677 #define THREAD_MC_TLV_PANID 1
678 #define THREAD_MC_TLV_XPANID 2
679 #define THREAD_MC_TLV_NETWORK_NAME 3
680 #define THREAD_MC_TLV_PSKC 4
681 #define THREAD_MC_TLV_NETWORK_MASTER_KEY 5
682 #define THREAD_MC_TLV_NETWORK_KEY_SEQ_CTR 6
683 #define THREAD_MC_TLV_NETWORK_ML_PREFIX 7
684 #define THREAD_MC_TLV_STEERING_DATA 8
685 #define THREAD_MC_TLV_BORDER_AGENT_LOCATOR 9
686 #define THREAD_MC_TLV_COMMISSIONER_ID 10
687 #define THREAD_MC_TLV_COMMISSIONER_SESSION_ID 11
688 #define THREAD_MC_TLV_SECURITY_POLICY 12
689 #define THREAD_MC_TLV_GET 13
690 #define THREAD_MC_TLV_ACTIVE_TSTAMP 14 /* Was "Commissioning Dataset Timestamp TLV" */
691 #define THREAD_MC_TLV_COMMISSIONER_UDP_PORT 15
692 #define THREAD_MC_TLV_STATE 16
693 #define THREAD_MC_TLV_JOINER_DTLS_ENCAP 17
694 #define THREAD_MC_TLV_JOINER_UDP_PORT 18
695 #define THREAD_MC_TLV_JOINER_IID 19
696 #define THREAD_MC_TLV_JOINER_ROUTER_LOCATOR 20
697 #define THREAD_MC_TLV_JOINER_KEK 21
699 #define THREAD_MC_TLV_PROVISIONING_URL 32
700 #define THREAD_MC_TLV_VENDOR_NAME 33
701 #define THREAD_MC_TLV_VENDOR_MODEL 34
702 #define THREAD_MC_TLV_VENDOR_SW_VERSION 35
703 #define THREAD_MC_TLV_VENDOR_DATA 36
704 #define THREAD_MC_TLV_VENDOR_STACK_VERSION 37
706 #define THREAD_MC_TLV_UDP_ENCAPSULATION 48
707 #define THREAD_MC_TLV_IPV6_ADDRESS 49
710 #define THREAD_MC_TLV_PENDING_TSTAMP 51
711 #define THREAD_MC_TLV_DELAY_TIMER 52
712 #define THREAD_MC_TLV_CHANNEL_MASK 53
713 #define THREAD_MC_TLV_COUNT 54
714 #define THREAD_MC_TLV_PERIOD 55
715 #define THREAD_MC_TLV_SCAN_DURATION 56
716 #define THREAD_MC_TLV_ENERGY_LIST 57
717 #define THREAD_MC_TLV_DOMAIN_NAME 59
718 #define THREAD_MC_TLV_DOMAIN_PREFIX 60
719 #define THREAD_MC_TLV_AE_STEERING_DATA 61
720 #define THREAD_MC_TLV_NMKP_STEERING_DATA 62
721 #define THREAD_MC_TLV_COMMISSIONER_TOKEN 63
722 #define THREAD_MC_TLV_COMMISSIONER_SIGNATURE 64
723 #define THREAD_MC_TLV_AE_UDP_PORT 65
724 #define THREAD_MC_TLV_NMKP_UDP_PORT 66
725 #define THREAD_MC_TLV_TRI_HOSTNAME 67
726 #define THREAD_MC_TLV_REGISTRAR_IPV6_ADDRESS 68
727 #define THREAD_MC_TLV_REGISTRAR_HOSTNAME 69
728 #define THREAD_MC_TLV_COMMISSIONER_PEN_SIGNATURE 70
729 #define THREAD_MC_TLV_COMMISSIONER_PEN_TOKEN 71
732 /* New discovery mechanism */
733 #define THREAD_MC_TLV_DISCOVERY_REQUEST 128
734 #define THREAD_MC_TLV_DISCOVERY_RESPONSE 129
736 static const value_string thread_mc_tlv_vals
[] = {
737 { THREAD_MC_TLV_CHANNEL
, "Channel" },
738 { THREAD_MC_TLV_PANID
, "PAN ID" },
739 { THREAD_MC_TLV_XPANID
, "Extended PAN ID" },
740 { THREAD_MC_TLV_NETWORK_NAME
, "Network Name" },
741 { THREAD_MC_TLV_PSKC
, "PSKc" },
742 { THREAD_MC_TLV_NETWORK_MASTER_KEY
, "Network Master Key" },
743 { THREAD_MC_TLV_NETWORK_KEY_SEQ_CTR
, "Network Key Sequence Counter" },
744 { THREAD_MC_TLV_NETWORK_ML_PREFIX
, "Mesh Local ULA Prefix" },
745 { THREAD_MC_TLV_STEERING_DATA
, "Steering Data" },
746 { THREAD_MC_TLV_BORDER_AGENT_LOCATOR
, "Border Agent Locator" },
747 { THREAD_MC_TLV_COMMISSIONER_ID
, "Commissioner ID" },
748 { THREAD_MC_TLV_COMMISSIONER_SESSION_ID
, "Commissioner Session ID" },
749 { THREAD_MC_TLV_SECURITY_POLICY
, "Security Policy" },
750 { THREAD_MC_TLV_GET
, "Get" },
751 { THREAD_MC_TLV_ACTIVE_TSTAMP
, "Active Timestamp" },
752 { THREAD_MC_TLV_COMMISSIONER_UDP_PORT
, "Commissioner UDP Port" },
753 { THREAD_MC_TLV_STATE
, "State" },
754 { THREAD_MC_TLV_JOINER_DTLS_ENCAP
, "Joiner DTLS Encapsulation" },
755 { THREAD_MC_TLV_JOINER_UDP_PORT
, "Joiner UDP Port" },
756 { THREAD_MC_TLV_JOINER_IID
, "Joiner IID" },
757 { THREAD_MC_TLV_JOINER_ROUTER_LOCATOR
, "Joiner Router Locator" },
758 { THREAD_MC_TLV_JOINER_KEK
, "Joiner KEK" },
759 { THREAD_MC_TLV_PROVISIONING_URL
, "Provisioning URL" },
760 { THREAD_MC_TLV_VENDOR_NAME
, "Vendor Name" },
761 { THREAD_MC_TLV_VENDOR_MODEL
, "Vendor Model" },
762 { THREAD_MC_TLV_VENDOR_SW_VERSION
, "Vendor Software Version" },
763 { THREAD_MC_TLV_VENDOR_DATA
, "Vendor Data" },
764 { THREAD_MC_TLV_VENDOR_STACK_VERSION
, "Vendor Stack Version" },
765 { THREAD_MC_TLV_UDP_ENCAPSULATION
, "UDP Encapsulation" },
766 { THREAD_MC_TLV_IPV6_ADDRESS
, "IPv6 Address" },
768 { THREAD_MC_TLV_PENDING_TSTAMP
, "Pending Timestamp" },
769 { THREAD_MC_TLV_DELAY_TIMER
, "Delay Timer" },
770 { THREAD_MC_TLV_CHANNEL_MASK
, "Channel Mask" },
771 { THREAD_MC_TLV_COUNT
, "Count" },
772 { THREAD_MC_TLV_PERIOD
, "Period" },
773 { THREAD_MC_TLV_SCAN_DURATION
, "Scan Duration" },
774 { THREAD_MC_TLV_ENERGY_LIST
, "Energy List" },
775 { THREAD_MC_TLV_DOMAIN_NAME
, "Domain Name" },
776 { THREAD_MC_TLV_DOMAIN_PREFIX
, "Domain Prefix" },
777 { THREAD_MC_TLV_AE_STEERING_DATA
, "AE Steering Data" },
778 { THREAD_MC_TLV_NMKP_STEERING_DATA
, "NMKP Steering Data" },
779 { THREAD_MC_TLV_COMMISSIONER_TOKEN
, "Commissioner Token" },
780 { THREAD_MC_TLV_COMMISSIONER_SIGNATURE
, "Commissioner Signature" },
781 { THREAD_MC_TLV_AE_UDP_PORT
, "AE UDP Port" },
782 { THREAD_MC_TLV_NMKP_UDP_PORT
, "NMKP UDP Port" },
783 { THREAD_MC_TLV_TRI_HOSTNAME
, "TRI Hostname" },
784 { THREAD_MC_TLV_REGISTRAR_IPV6_ADDRESS
, "Registrar IPv6 Address" },
785 { THREAD_MC_TLV_REGISTRAR_HOSTNAME
, "Registrar Hostname" },
786 { THREAD_MC_TLV_COMMISSIONER_PEN_SIGNATURE
,"Commissioner PEN Signature" },
787 { THREAD_MC_TLV_COMMISSIONER_PEN_TOKEN
, "Commissioner PEN Token" },
788 /* New discovery mechanism */
789 { THREAD_MC_TLV_DISCOVERY_REQUEST
, "Discovery Request" },
790 { THREAD_MC_TLV_DISCOVERY_RESPONSE
, "Discovery Response" },
794 static const value_string thread_mc_state_vals
[] = {
801 static const true_false_string thread_mc_tlv_join_intent
= {
806 #define THREAD_NWD_TLV_HAS_ROUTE 0
807 #define THREAD_NWD_TLV_PREFIX 1
808 #define THREAD_NWD_TLV_BORDER_ROUTER 2
809 #define THREAD_NWD_TLV_6LOWPAN_ID 3
810 #define THREAD_NWD_TLV_COMMISSIONING_DATA 4
811 #define THREAD_NWD_TLV_SERVICE 5
812 #define THREAD_NWD_TLV_SERVER 6
814 static const value_string thread_nwd_tlv_vals
[] = {
815 { THREAD_NWD_TLV_HAS_ROUTE
, "Has Route" },
816 { THREAD_NWD_TLV_PREFIX
, "Prefix" },
817 { THREAD_NWD_TLV_BORDER_ROUTER
, "Border Router" },
818 { THREAD_NWD_TLV_6LOWPAN_ID
, "6LoWPAN ID" },
819 { THREAD_NWD_TLV_COMMISSIONING_DATA
, "Commissioning Data" },
820 { THREAD_NWD_TLV_SERVICE
, "Service" },
821 { THREAD_NWD_TLV_SERVER
, "Server" },
825 #define THREAD_NWD_TLV_TYPE_M 0xFE
826 #define THREAD_NWD_TLV_STABLE_M 0x01
828 static const true_false_string tfs_thread_nwd_tlv_border_router_p
= {
829 "Autoconfigured preferred",
830 "Autoconfigured deprecated"
833 static const true_false_string tfs_thread_nwd_tlv_border_router_c
= {
834 "Additional config. data",
835 "No additional config. data"
838 static const true_false_string tfs_thread_nwd_tlv_border_router_o
= {
843 /*Network Management TLVs*/
844 static int hf_thread_nm_tlv
;
845 static int hf_thread_nm_tlv_type
;
846 static int hf_thread_nm_tlv_length
;
847 static int hf_thread_nm_tlv_unknown
;
848 /* static int hf_thread_nm_tlv_sub_tlvs; */
850 /* Target EID TLV fields */
851 static int hf_thread_nm_tlv_target_eid
;
853 /* Ext. MAC address TLV fields */
854 static int hf_thread_nm_tlv_ext_mac_addr
;
856 /* RLOC16 TLV fields */
857 static int hf_thread_nm_tlv_rloc16
;
859 /* Mesh Local IID TLV fields */
860 static int hf_thread_nm_tlv_ml_eid
;
862 /* Status TLV fields */
863 static int hf_thread_nm_tlv_status
;
865 /* Last transaction time TLV fields */
866 static int hf_thread_nm_tlv_last_transaction_time
;
868 /* Router Mask TLV fields */
869 static int hf_thread_nm_tlv_router_mask_id_seq
;
870 static int hf_thread_nm_tlv_router_mask_assigned
;
872 /* ND option fields */
873 static int hf_thread_nm_tlv_nd_option
;
876 static int hf_thread_nm_tlv_nd_data
;
878 static int hf_thread_nm_tlv_timeout
;
882 #define THREAD_NM_TLV_TARGET_EID 0
883 #define THREAD_NM_TLV_EXT_MAC_ADDR 1
884 #define THREAD_NM_TLV_RLOC16 2
885 #define THREAD_NM_TLV_ML_EID 3
886 #define THREAD_NM_TLV_STATUS 4
888 #define THREAD_NM_TLV_LAST_TRANSACTION_TIME 6
889 #define THREAD_NM_TLV_ROUTER_MASK 7
890 #define THREAD_NM_TLV_ND_OPTION 8
891 #define THREAD_NM_TLV_ND_DATA 9
892 #define THREAD_NM_TLV_THREAD_NETWORK_DATA 10
893 #define THREAD_NM_TLV_TIMEOUT 11
894 #define THREAD_NM_TLV_THREAD_NETWORK_NAME 12
895 #define THREAD_NM_TLV_IPV6_ADDRESS 14
896 #define THREAD_NM_TLV_COMMISSIONER_SESSION_ID 15
898 static const value_string thread_nm_tlv_vals
[] = {
899 { THREAD_NM_TLV_TARGET_EID
, "Target EID" },
900 { THREAD_NM_TLV_EXT_MAC_ADDR
, "Extended MAC Address" },
901 { THREAD_NM_TLV_RLOC16
, "RLOC16" },
902 { THREAD_NM_TLV_ML_EID
, "ML-EID" },
903 { THREAD_NM_TLV_STATUS
, "Status" },
905 { THREAD_NM_TLV_LAST_TRANSACTION_TIME
, "Last Transaction Time" },
906 { THREAD_NM_TLV_ROUTER_MASK
, "Router Mask" },
907 { THREAD_NM_TLV_ND_OPTION
, "ND Option" },
908 { THREAD_NM_TLV_ND_DATA
, "ND Data" },
909 { THREAD_NM_TLV_THREAD_NETWORK_DATA
, "Thread Network Data" },
910 { THREAD_NM_TLV_TIMEOUT
, "Timeout"},
911 { THREAD_NM_TLV_THREAD_NETWORK_NAME
, "Thread Network Name" },
912 { THREAD_NM_TLV_IPV6_ADDRESS
, "IPv6 Address"},
913 { THREAD_NM_TLV_COMMISSIONER_SESSION_ID
, "Commissioner Session ID"},
918 static const value_string thread_nm_tlv_status_vals
[] = {
919 { 0, "Successful registration" },
920 { 1, "Registration was accepted but immediate reregistration is required \
921 to resolve any potential conflicting state across Domain BBRs." },
922 { 2, "Registration rejected: Target EID is not a valid DUA" },
923 { 3, "Registration rejected: DUA is already in use by another Device" },
924 { 4, "Registration rejected: BBR resource shortage" },
925 { 5, "Registration rejected: BBR is not Primary at this moment" },
926 { 6, "Registration failure: Reason(s) not further specified" },
930 /* Network Management TLVs end*/
932 /*Backbone Link TLVs*/
934 static int hf_thread_bl_tlv
;
935 static int hf_thread_bl_tlv_type
;
936 static int hf_thread_bl_tlv_length
;
937 static int hf_thread_bl_tlv_unknown
;
938 /* static int hf_thread_bl_tlv_sub_tlvs; */
940 /* Target EID TLV fields */
941 static int hf_thread_bl_tlv_target_eid
;
943 /* Ext. MAC address TLV fields */
944 static int hf_thread_bl_tlv_ext_mac_addr
;
946 /* RLOC16 TLV fields */
947 static int hf_thread_bl_tlv_rloc16
;
949 /* Mesh Local IID TLV fields */
950 static int hf_thread_bl_tlv_ml_eid
;
952 /* Status TLV fields */
953 static int hf_thread_bl_tlv_status
;
955 /* Attached time TLV fields */
956 /* static int hf_thread_bl_tlv_attached_time; */
958 /* Last transaction time TLV fields */
959 static int hf_thread_bl_tlv_last_transaction_time
;
961 /* Router Mask TLV fields */
962 static int hf_thread_bl_tlv_router_mask_id_seq
;
963 static int hf_thread_bl_tlv_router_mask_assigned
;
965 /* ND option fields */
966 static int hf_thread_bl_tlv_nd_option
;
969 static int hf_thread_bl_tlv_nd_data
;
971 static int hf_thread_bl_tlv_timeout
;
974 #define THREAD_BL_TLV_TARGET_EID 0
975 #define THREAD_BL_TLV_EXT_MAC_ADDR 1
976 #define THREAD_BL_TLV_RLOC16 2
977 #define THREAD_BL_TLV_ML_EID 3
978 #define THREAD_BL_TLV_STATUS 4
980 #define THREAD_BL_TLV_LAST_TRANSACTION_TIME 6
981 #define THREAD_BL_TLV_ROUTER_MASK 7
982 #define THREAD_BL_TLV_ND_OPTION 8
983 #define THREAD_BL_TLV_ND_DATA 9
984 #define THREAD_BL_TLV_THREAD_NETWORK_DATA 10
985 #define THREAD_BL_TLV_TIMEOUT 11
986 #define THREAD_BL_TLV_THREAD_NETWORK_NAME 12
987 #define THREAD_BL_TLV_IPV6_ADDRESS 14
989 static const value_string thread_bl_tlv_vals
[] = {
990 { THREAD_BL_TLV_TARGET_EID
, "Target EID" },
991 { THREAD_BL_TLV_EXT_MAC_ADDR
, "Extended MAC Address" },
992 { THREAD_BL_TLV_RLOC16
, "RLOC16" },
993 { THREAD_BL_TLV_ML_EID
, "ML-EID" },
994 { THREAD_BL_TLV_STATUS
, "Status" },
996 { THREAD_BL_TLV_LAST_TRANSACTION_TIME
, "Last Transaction Time" },
997 { THREAD_BL_TLV_ROUTER_MASK
, "Router Mask" },
998 { THREAD_BL_TLV_ND_OPTION
, "ND Option" },
999 { THREAD_BL_TLV_ND_DATA
, "ND Data" },
1000 { THREAD_BL_TLV_THREAD_NETWORK_DATA
, "Thread Network Data" },
1001 { THREAD_BL_TLV_TIMEOUT
, "Timeout"},
1002 { THREAD_BL_TLV_THREAD_NETWORK_NAME
, "Thread Network Name" },
1003 { THREAD_BL_TLV_IPV6_ADDRESS
, "IPv6 Address"},
1007 static const value_string thread_bl_tlv_status_vals
[] = {
1009 { 1, "No Address Available" },
1010 { 2, "TOO_FEW_ROUTERS" },
1011 { 3, "HAVE_CHILD_ID_REQUEST" },
1012 { 4, "PARENT_PARTITION_CHANGE" },
1015 /* Backbone Link TLVs end*/
1017 /* Thread Beacon TLV Values. */
1018 static const value_string thread_bcn_tlv_vals
[] = {
1019 { THREAD_BCN_TLV_STEERING_DATA
, "Steering Data" },
1024 dissect_thread_ie(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data
);
1027 static bool thread_use_pan_id_in_key
;
1028 static const char *thread_seq_ctr_str
;
1029 static bool thread_auto_acq_seq_ctr
= true;
1032 static bool thread_seq_ctr_acqd
;
1033 static uint8_t thread_seq_ctr_bytes
[4];
1034 static const uint8_t thread_well_known_key
[IEEE802154_CIPHER_SIZE
] =
1035 { 0x78, 0x58, 0x16, 0x86, 0xfd, 0xb4, 0x58, 0x0f, 0xb0, 0x92, 0x54, 0x6a, 0xec, 0xbd, 0x15, 0x66 };
1037 static GByteArray
*set_thread_seq_ctr_from_key_index(uint8_t key_index
)
1039 GByteArray
*seq_ctr_bytes
= NULL
;
1041 seq_ctr_bytes
= g_byte_array_new();
1042 if (thread_seq_ctr_acqd
) {
1043 seq_ctr_bytes
= g_byte_array_set_size(seq_ctr_bytes
, 4);
1044 memcpy(seq_ctr_bytes
->data
, thread_seq_ctr_bytes
, 4);
1046 hex_str_to_bytes(thread_seq_ctr_str
, seq_ctr_bytes
, false);
1047 if (seq_ctr_bytes
->len
!= 4) {
1048 /* Not read correctly - assume value is 0 */
1049 seq_ctr_bytes
= g_byte_array_set_size(seq_ctr_bytes
, 4);
1050 memset(seq_ctr_bytes
->data
, 0, 4);
1053 /* Replace lower part with counter based on packet key index */
1054 seq_ctr_bytes
->data
[3] = (seq_ctr_bytes
->data
[3] & 0x80) + ((key_index
- 1) & 0x7F);
1056 return seq_ctr_bytes
;
1059 static void create_thread_temp_keys(GByteArray
*seq_ctr_bytes
, uint16_t src_pan
, ieee802154_key_t
* key
, unsigned char *mac_key
, unsigned char *mle_key
)
1065 bool verbatim_key
= true;
1067 /* Get the IEEE 802.15.4 decryption key. */
1068 bytes
= g_byte_array_new();
1069 res
= hex_str_to_bytes(key
->pref_key
, bytes
, false);
1070 key_valid
= (res
&& bytes
->len
>= IEEE802154_CIPHER_SIZE
);
1072 if (thread_use_pan_id_in_key
) {
1073 /* Substitute the bottom two keys bytes with PAN ID */
1074 bytes
->data
[0] = (uint8_t)(src_pan
& 0xFF);
1075 bytes
->data
[1] = (uint8_t)(src_pan
>> 8);
1077 if (key
->hash_type
!= KEY_HASH_NONE
) {
1080 if (key
->hash_type
== KEY_HASH_THREAD
) {
1081 memcpy(buffer
, seq_ctr_bytes
->data
, 4);
1082 memcpy(&buffer
[4], "Thread", 6); /* len("Thread") */
1084 if (!ws_hmac_buffer(GCRY_MD_SHA256
, digest
, buffer
, 10, bytes
->data
, IEEE802154_CIPHER_SIZE
)) {
1085 /* Copy upper hashed bytes to the MAC key */
1087 memcpy(mac_key
, &digest
[IEEE802154_CIPHER_SIZE
], IEEE802154_CIPHER_SIZE
);
1089 /* Copy lower hashed bytes to the MLE key */
1091 memcpy(mle_key
, digest
, IEEE802154_CIPHER_SIZE
);
1093 verbatim_key
= false;
1098 /* Just copy the keys verbatim */
1100 memcpy(mac_key
, bytes
->data
, IEEE802154_CIPHER_SIZE
);
1103 memcpy(mle_key
, bytes
->data
, IEEE802154_CIPHER_SIZE
);
1107 g_byte_array_free(bytes
, true);
1110 /* Set MAC key for Thread hash */
1111 static unsigned set_thread_mac_key(ieee802154_packet
*packet
, unsigned char *key
, unsigned char *alt_key
, ieee802154_key_t
*uat_key
)
1113 GByteArray
*seq_ctr_bytes
= NULL
;
1115 if (packet
->key_id_mode
== KEY_ID_MODE_KEY_INDEX
) {
1116 seq_ctr_bytes
= set_thread_seq_ctr_from_key_index(packet
->key_index
);
1117 } else if ((packet
->key_id_mode
== KEY_ID_MODE_KEY_EXPLICIT_4
) &&
1118 (packet
->key_index
== IEEE802154_THR_WELL_KNOWN_KEY_INDEX
) &&
1119 (packet
->key_source
.addr32
== IEEE802154_THR_WELL_KNOWN_KEY_SRC
))
1121 /* This is the well-known Thread key. No need for an alternative key */
1122 memcpy(key
, thread_well_known_key
, IEEE802154_CIPHER_SIZE
);
1125 if (seq_ctr_bytes
!= NULL
) {
1126 create_thread_temp_keys(seq_ctr_bytes
, packet
->src_pan
, uat_key
, key
, NULL
);
1127 /* Create an alternate key based on the wraparound case */
1128 seq_ctr_bytes
->data
[3] ^= 0x80;
1129 create_thread_temp_keys(seq_ctr_bytes
, packet
->src_pan
, uat_key
, alt_key
, NULL
);
1130 g_byte_array_free(seq_ctr_bytes
, true);
1137 /* Set MLE key for Thread hash */
1138 static unsigned set_thread_mle_key(ieee802154_packet
*packet
, unsigned char *key
, unsigned char *alt_key
, ieee802154_key_t
*uat_key
)
1140 GByteArray
*seq_ctr_bytes
= NULL
;
1141 if (packet
->key_id_mode
== KEY_ID_MODE_KEY_INDEX
) {
1142 seq_ctr_bytes
= set_thread_seq_ctr_from_key_index(packet
->key_index
);
1144 else if (packet
->key_id_mode
== KEY_ID_MODE_KEY_EXPLICIT_4
) {
1145 /* Reconstruct the key source from the key source in the packet */
1146 seq_ctr_bytes
= g_byte_array_new();
1147 seq_ctr_bytes
= g_byte_array_set_size(seq_ctr_bytes
, 4);
1148 seq_ctr_bytes
->data
[0] = (packet
->key_source
.addr32
>> 24) & 0xFF;
1149 seq_ctr_bytes
->data
[1] = (packet
->key_source
.addr32
>> 16) & 0xFF;
1150 seq_ctr_bytes
->data
[2] = (packet
->key_source
.addr32
>> 8) & 0xFF;
1151 seq_ctr_bytes
->data
[3] = packet
->key_source
.addr32
& 0xFF;
1152 /* Acquire the sequence counter if configured in preferences */
1153 if (thread_auto_acq_seq_ctr
&& !thread_seq_ctr_acqd
) {
1154 memcpy(thread_seq_ctr_bytes
, seq_ctr_bytes
->data
, 4);
1155 thread_seq_ctr_acqd
= true;
1158 if (seq_ctr_bytes
!= NULL
) {
1159 create_thread_temp_keys(seq_ctr_bytes
, packet
->src_pan
, uat_key
, NULL
, key
);
1160 /* Create an alternate key based on the wraparound case */
1161 seq_ctr_bytes
->data
[3] ^= 0x80;
1162 create_thread_temp_keys(seq_ctr_bytes
, packet
->src_pan
, uat_key
, NULL
, alt_key
);
1163 g_byte_array_free(seq_ctr_bytes
, true);
1171 count_bits_in_byte(uint8_t byte
)
1173 static const uint8_t lut
[16] = {0, /* 0b0000 */
1189 return lut
[byte
>> 4] + lut
[byte
& 0xf];
1193 get_chancount(tvbuff_t
*tvb
)
1198 tlv_len_len_e tlv_len_len
;
1199 unsigned chancount
= THREAD_MC_INVALID_CHAN_COUNT
;
1203 /* Thread Network Data TLVs */
1204 while (tvb_offset_exists(tvb
, offset
)) {
1206 /* Get the type and length ahead of time to pass to next function so we can highlight
1207 proper amount of bytes */
1208 tlv_type
= tvb_get_uint8(tvb
, offset
);
1209 tlv_len
= (uint16_t)tvb_get_uint8(tvb
, offset
+ 1);
1211 /* TODO: need to make sure this applies to all MeshCoP TLVs */
1212 if (THREAD_TLV_LENGTH_ESC
== tlv_len
) {
1213 /* 16-bit length field */
1214 tlv_len
= tvb_get_ntohs(tvb
, offset
+ 2);
1215 tlv_len_len
= TLV_LEN_LEN16
;
1217 tlv_len_len
= TLV_LEN_LEN8
;
1220 /* Skip over Type and Length */
1221 offset
+= 1 + tlv_len_len
;
1225 case THREAD_MC_TLV_CHANNEL_MASK
:
1228 uint8_t entries
= 0;
1229 int32_t check_len
= tlv_len
;
1230 int check_offset
= offset
+ 1; /* Channel page first */
1233 /* Check consistency of entries */
1234 while (check_len
> 0) {
1236 masklen
= tvb_get_uint8(tvb
, check_offset
);
1238 break; /* Get out or we might spin forever */
1240 masklen
+= 2; /* Add in page and length */
1241 check_offset
+= masklen
;
1242 check_len
-= masklen
;
1246 if (check_len
!= 0) {
1247 /* Not an integer number of entries */
1248 /* offset += tlv_len; */
1252 for (i
= 0; i
< entries
; i
++) {
1253 /* Skip over channel page */
1255 masklen
= tvb_get_uint8(tvb
, offset
);
1257 /* Count the number of channels in the channel mask */
1258 for (j
= 0; j
< masklen
; j
++) {
1259 chancount
+= count_bits_in_byte(tvb_get_uint8(tvb
, offset
));
1268 /* Skip over any other TLVs */
1276 dissect_thread_address(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data _U_
)
1278 proto_item
*proto_root
;
1279 proto_tree
*thread_address_tree
;
1280 proto_tree
*tlv_tree
;
1282 unsigned offset
= 0;
1284 uint8_t tlv_type
, tlv_len
;
1286 /* Create the protocol tree. */
1287 proto_root
= proto_tree_add_item(tree
, proto_thread_address
, tvb
, 0, tvb_reported_length(tvb
), ENC_NA
);
1288 thread_address_tree
= proto_item_add_subtree(proto_root
, ett_thread_address
);
1290 /* Thread Network Data TLVs */
1291 while (tvb_offset_exists(tvb
, offset
)) {
1293 /* Get the length ahead of time to pass to next function so we can highlight
1294 proper amount of bytes */
1295 tlv_len
= tvb_get_uint8(tvb
, offset
+ 1);
1297 ti
= proto_tree_add_item(thread_address_tree
, hf_thread_address_tlv
, tvb
, offset
, tlv_len
+2, ENC_NA
);
1298 tlv_tree
= proto_item_add_subtree(ti
, ett_thread_address_tlv
);
1301 proto_tree_add_item(tlv_tree
, hf_thread_address_tlv_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1302 tlv_type
= tvb_get_uint8(tvb
, offset
);
1305 /* Add value name to value root label */
1306 proto_item_append_text(ti
, " (%s)", val_to_str(tlv_type
, thread_address_tlv_vals
, "Unknown (%d)"));
1309 proto_tree_add_item(tlv_tree
, hf_thread_address_tlv_length
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1313 case THREAD_ADDRESS_TLV_TARGET_EID
:
1315 /* Check length is consistent */
1316 if (tlv_len
!= 16) {
1317 expert_add_info(pinfo
, proto_root
, &ei_thread_address_len_size_mismatch
);
1318 proto_tree_add_item(tlv_tree
, hf_thread_address_tlv_unknown
, tvb
, offset
, tlv_len
, ENC_NA
);
1321 proto_tree_add_item(tlv_tree
, hf_thread_address_tlv_target_eid
, tvb
, offset
, tlv_len
, ENC_NA
);
1327 case THREAD_ADDRESS_TLV_EXT_MAC_ADDR
:
1329 /* Check length is consistent */
1331 expert_add_info(pinfo
, proto_root
, &ei_thread_address_len_size_mismatch
);
1332 proto_tree_add_item(tlv_tree
, hf_thread_address_tlv_unknown
, tvb
, offset
, tlv_len
, ENC_NA
);
1334 /* Extended MAC address */
1335 proto_tree_add_item(tlv_tree
, hf_thread_address_tlv_ext_mac_addr
, tvb
, offset
, tlv_len
, ENC_BIG_ENDIAN
);
1341 case THREAD_ADDRESS_TLV_RLOC16
:
1343 /* Check length is consistent */
1345 expert_add_info(pinfo
, proto_root
, &ei_thread_address_len_size_mismatch
);
1346 proto_tree_add_item(tlv_tree
, hf_thread_address_tlv_unknown
, tvb
, offset
, tlv_len
, ENC_NA
);
1349 proto_tree_add_item(tlv_tree
, hf_thread_address_tlv_rloc16
, tvb
, offset
, tlv_len
, ENC_BIG_ENDIAN
);
1355 case THREAD_ADDRESS_TLV_ML_EID
:
1357 /* Check length is consistent */
1359 expert_add_info(pinfo
, proto_root
, &ei_thread_address_len_size_mismatch
);
1360 proto_tree_add_item(tlv_tree
, hf_thread_address_tlv_unknown
, tvb
, offset
, tlv_len
, ENC_NA
);
1363 proto_tree_add_item(tlv_tree
, hf_thread_address_tlv_ml_eid
, tvb
, offset
, tlv_len
, ENC_NA
);
1369 case THREAD_ADDRESS_TLV_STATUS
:
1371 /* Check length is consistent */
1373 expert_add_info(pinfo
, proto_root
, &ei_thread_address_len_size_mismatch
);
1374 proto_tree_add_item(tlv_tree
, hf_thread_address_tlv_unknown
, tvb
, offset
, tlv_len
, ENC_NA
);
1377 proto_tree_add_item(tlv_tree
, hf_thread_address_tlv_status
, tvb
, offset
, tlv_len
, ENC_BIG_ENDIAN
);
1383 case THREAD_ADDRESS_TLV_LAST_TRANSACTION_TIME
:
1385 /* Check length is consistent */
1387 expert_add_info(pinfo
, proto_root
, &ei_thread_address_len_size_mismatch
);
1388 proto_tree_add_item(tlv_tree
, hf_thread_address_tlv_unknown
, tvb
, offset
, tlv_len
, ENC_NA
);
1390 /* Last transaction time */
1391 proto_tree_add_item(tlv_tree
, hf_thread_address_tlv_last_transaction_time
, tvb
, offset
, tlv_len
, ENC_BIG_ENDIAN
);
1397 case THREAD_ADDRESS_TLV_ROUTER_MASK
:
1399 /* Check length is consistent */
1401 expert_add_info(pinfo
, proto_root
, &ei_thread_address_len_size_mismatch
);
1402 proto_tree_add_item(tlv_tree
, hf_thread_address_tlv_unknown
, tvb
, offset
, tlv_len
, ENC_NA
);
1406 proto_tree_add_item(tlv_tree
, hf_thread_address_tlv_router_mask_id_seq
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1410 * | | | | | | | | | | |1|1|1|1|1|1|...|6|
1411 * |0|1|2|3|4|5|6|7|8|9|0|1|2|3|4|5|...|3|
1412 * ---------------------------------------
1413 * |1|0|1|1|1|0|0|0|1|1|0|0|0|1|0|1|...
1415 * is sent as 0xb8, 0xc5
1416 * and represents table entry for routers 0, 2, 3, 4, 8, 9, 13, 15...
1419 /* Just show the string of octets - best representation for a bit mask */
1420 proto_tree_add_item(tlv_tree
, hf_thread_address_tlv_router_mask_assigned
, tvb
, offset
, 8, ENC_NA
);
1426 case THREAD_ADDRESS_TLV_ND_OPTION
:
1427 /* Just show the data */
1428 proto_tree_add_item(tlv_tree
, hf_thread_address_tlv_nd_option
, tvb
, offset
, tlv_len
, ENC_NA
);
1432 case THREAD_ADDRESS_TLV_ND_DATA
:
1433 /* Just show the data. Note there is no icmpv6 options dissector so would have to copy it */
1434 proto_tree_add_item(tlv_tree
, hf_thread_address_tlv_nd_data
, tvb
, offset
, tlv_len
, ENC_NA
);
1438 case THREAD_ADDRESS_TLV_THREAD_NETWORK_DATA
:
1440 sub_tvb
= tvb_new_subset_length(tvb
, offset
, tlv_len
);
1441 call_dissector(thread_address_nwd_handle
, sub_tvb
, pinfo
, tlv_tree
);
1446 case THREAD_ADDRESS_TLV_TIMEOUT
:
1448 expert_add_info(pinfo
, proto_root
, &ei_thread_address_len_size_mismatch
);
1449 proto_tree_add_item(tlv_tree
, hf_thread_address_tlv_unknown
, tvb
, offset
, tlv_len
, ENC_NA
);
1453 proto_tree_add_item(tlv_tree
, hf_thread_address_tlv_timeout
, tvb
, offset
, tlv_len
, ENC_NA
);
1457 case THREAD_ADDRESS_TLV_THREAD_NETWORK_NAME
:
1459 expert_add_info(pinfo
, proto_root
, &ei_thread_address_len_size_mismatch
);
1460 proto_tree_add_item(tlv_tree
, hf_thread_address_tlv_unknown
, tvb
, offset
, tlv_len
, ENC_NA
);
1464 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_net_name
, tvb
, offset
, tlv_len
, ENC_ASCII
| ENC_UTF_8
);
1468 case THREAD_ADDRESS_TLV_IPV6_ADDRESS
:
1469 if ((tlv_len
% 16) != 0) {
1470 expert_add_info(pinfo
, proto_root
, &ei_thread_mc_len_size_mismatch
);
1471 proto_tree_add_item(tlv_tree
, hf_thread_address_tlv_unknown
, tvb
, offset
, tlv_len
, ENC_NA
);
1475 //Need to only take 16 bytes for the IPv6 address
1476 for (int i
= 0; i
< (tlv_len
/ 16); i
++)
1478 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_ipv6_addr
, tvb
, offset
, 16, ENC_NA
);
1485 proto_tree_add_item(tlv_tree
, hf_thread_address_tlv_unknown
, tvb
, offset
, tlv_len
, ENC_NA
);
1489 return tvb_captured_length(tvb
);
1493 dissect_thread_nm(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data _U_
)
1495 proto_item
*proto_root
;
1496 proto_tree
*thread_nm_tree
;
1497 proto_tree
*tlv_tree
;
1499 unsigned offset
= 0;
1501 uint8_t tlv_type
, tlv_len
;
1503 /* Create the protocol tree. */
1504 proto_root
= proto_tree_add_item(tree
, proto_thread_nm
, tvb
, 0, tvb_reported_length(tvb
), ENC_NA
);
1505 thread_nm_tree
= proto_item_add_subtree(proto_root
, ett_thread_nm
);
1507 /* Thread Network Data TLVs */
1508 while (tvb_offset_exists(tvb
, offset
)) {
1510 /* Get the length ahead of time to pass to next function so we can highlight
1511 proper amount of bytes */
1512 tlv_len
= tvb_get_uint8(tvb
, offset
+ 1);
1514 /* Create the tree */
1515 ti
= proto_tree_add_item(thread_nm_tree
, hf_thread_nm_tlv
, tvb
, offset
, tlv_len
+2, ENC_NA
);
1516 tlv_tree
= proto_item_add_subtree(ti
, ett_thread_nm_tlv
);
1519 proto_tree_add_item(tlv_tree
, hf_thread_nm_tlv_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1520 tlv_type
= tvb_get_uint8(tvb
, offset
);
1523 /* Add value name to value root label */
1524 proto_item_append_text(ti
, " (%s)", val_to_str(tlv_type
, thread_nm_tlv_vals
, "Unknown (%d)"));
1527 proto_tree_add_item(tlv_tree
, hf_thread_nm_tlv_length
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1532 case THREAD_NM_TLV_TARGET_EID
:
1534 /* Check length is consistent */
1535 if (tlv_len
!= 16) {
1536 expert_add_info(pinfo
, proto_root
, &ei_thread_nm_len_size_mismatch
);
1537 proto_tree_add_item(tlv_tree
, hf_thread_nm_tlv_unknown
, tvb
, offset
, tlv_len
, ENC_NA
);
1540 proto_tree_add_item(tlv_tree
, hf_thread_nm_tlv_target_eid
, tvb
, offset
, tlv_len
, ENC_NA
);
1546 case THREAD_NM_TLV_EXT_MAC_ADDR
:
1548 /* Check length is consistent */
1550 expert_add_info(pinfo
, proto_root
, &ei_thread_nm_len_size_mismatch
);
1551 proto_tree_add_item(tlv_tree
, hf_thread_nm_tlv_unknown
, tvb
, offset
, tlv_len
, ENC_NA
);
1553 /* Extended MAC address */
1554 proto_tree_add_item(tlv_tree
, hf_thread_nm_tlv_ext_mac_addr
, tvb
, offset
, tlv_len
, ENC_BIG_ENDIAN
);
1560 case THREAD_NM_TLV_RLOC16
:
1562 /* Check length is consistent */
1564 expert_add_info(pinfo
, proto_root
, &ei_thread_bl_len_size_mismatch
);
1565 proto_tree_add_item(tlv_tree
, hf_thread_bl_tlv_unknown
, tvb
, offset
, tlv_len
, ENC_NA
);
1568 proto_tree_add_item(tlv_tree
, hf_thread_bl_tlv_rloc16
, tvb
, offset
, tlv_len
, ENC_BIG_ENDIAN
);
1574 case THREAD_NM_TLV_ML_EID
:
1576 /* Check length is consistent */
1578 expert_add_info(pinfo
, proto_root
, &ei_thread_nm_len_size_mismatch
);
1579 proto_tree_add_item(tlv_tree
, hf_thread_nm_tlv_unknown
, tvb
, offset
, tlv_len
, ENC_NA
);
1582 proto_tree_add_item(tlv_tree
, hf_thread_nm_tlv_ml_eid
, tvb
, offset
, tlv_len
, ENC_NA
);
1588 case THREAD_NM_TLV_STATUS
:
1590 /* Check length is consistent */
1592 expert_add_info(pinfo
, proto_root
, &ei_thread_nm_len_size_mismatch
);
1593 proto_tree_add_item(tlv_tree
, hf_thread_nm_tlv_unknown
, tvb
, offset
, tlv_len
, ENC_NA
);
1596 proto_tree_add_item(tlv_tree
, hf_thread_nm_tlv_status
, tvb
, offset
, tlv_len
, ENC_BIG_ENDIAN
);
1602 case THREAD_NM_TLV_LAST_TRANSACTION_TIME
:
1604 /* Check length is consistent */
1606 expert_add_info(pinfo
, proto_root
, &ei_thread_nm_len_size_mismatch
);
1607 proto_tree_add_item(tlv_tree
, hf_thread_nm_tlv_unknown
, tvb
, offset
, tlv_len
, ENC_NA
);
1609 /* Last transaction time */
1610 proto_tree_add_item(tlv_tree
, hf_thread_nm_tlv_last_transaction_time
, tvb
, offset
, tlv_len
, ENC_BIG_ENDIAN
);
1616 case THREAD_NM_TLV_ROUTER_MASK
:
1618 /* Check length is consistent */
1620 expert_add_info(pinfo
, proto_root
, &ei_thread_nm_len_size_mismatch
);
1621 proto_tree_add_item(tlv_tree
, hf_thread_nm_tlv_unknown
, tvb
, offset
, tlv_len
, ENC_NA
);
1625 proto_tree_add_item(tlv_tree
, hf_thread_nm_tlv_router_mask_id_seq
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1629 * | | | | | | | | | | |1|1|1|1|1|1|...|6|
1630 * |0|1|2|3|4|5|6|7|8|9|0|1|2|3|4|5|...|3|
1631 * ---------------------------------------
1632 * |1|0|1|1|1|0|0|0|1|1|0|0|0|1|0|1|...
1634 * is sent as 0xb8, 0xc5
1635 * and represents table entry for routers 0, 2, 3, 4, 8, 9, 13, 15...
1638 /* Just show the string of octets - best representation for a bit mask */
1639 proto_tree_add_item(tlv_tree
, hf_thread_nm_tlv_router_mask_assigned
, tvb
, offset
, 8, ENC_NA
);
1645 case THREAD_NM_TLV_ND_OPTION
:
1646 /* Just show the data */
1647 proto_tree_add_item(tlv_tree
, hf_thread_nm_tlv_nd_option
, tvb
, offset
, tlv_len
, ENC_NA
);
1651 case THREAD_NM_TLV_ND_DATA
:
1652 /* Just show the data. Note there is no icmpv6 options dissector so would have to copy it */
1653 proto_tree_add_item(tlv_tree
, hf_thread_nm_tlv_nd_data
, tvb
, offset
, tlv_len
, ENC_NA
);
1657 case THREAD_NM_TLV_THREAD_NETWORK_DATA
:
1659 sub_tvb
= tvb_new_subset_length(tvb
, offset
, tlv_len
);
1660 call_dissector(thread_address_nwd_handle
, sub_tvb
, pinfo
, tlv_tree
);
1665 case THREAD_NM_TLV_TIMEOUT
:
1667 expert_add_info(pinfo
, proto_root
, &ei_thread_nm_len_size_mismatch
);
1668 proto_tree_add_item(tlv_tree
, hf_thread_nm_tlv_unknown
, tvb
, offset
, tlv_len
, ENC_NA
);
1672 proto_tree_add_item(tlv_tree
, hf_thread_nm_tlv_timeout
, tvb
, offset
, tlv_len
, ENC_NA
);
1679 case THREAD_NM_TLV_THREAD_NETWORK_NAME
:
1681 expert_add_info(pinfo
, proto_root
, &ei_thread_nm_len_size_mismatch
);
1682 proto_tree_add_item(tlv_tree
, hf_thread_nm_tlv_unknown
, tvb
, offset
, tlv_len
, ENC_NA
);
1686 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_net_name
, tvb
, offset
, tlv_len
, ENC_ASCII
| ENC_UTF_8
);
1692 case THREAD_NM_TLV_IPV6_ADDRESS
:
1693 if ((tlv_len
% 16) != 0) {
1694 expert_add_info(pinfo
, proto_root
, &ei_thread_mc_len_size_mismatch
);
1695 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_unknown
, tvb
, offset
, tlv_len
, ENC_NA
);
1699 //Need to only take 16 bytes for the IPv6 address
1700 for (int i
= 0; i
< (tlv_len
/ 16); i
++)
1702 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_ipv6_addr
, tvb
, offset
, 16, ENC_NA
);
1708 case THREAD_NM_TLV_COMMISSIONER_SESSION_ID
:
1710 /* Check length is consistent */
1712 expert_add_info(pinfo
, proto_root
, &ei_thread_mc_len_size_mismatch
);
1714 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_unknown
, tvb
, offset
, tlv_len
, ENC_NA
);
1716 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_commissioner_sess_id
, tvb
, offset
, tlv_len
, ENC_NA
);
1723 proto_tree_add_item(tlv_tree
, hf_thread_nm_tlv_unknown
, tvb
, offset
, tlv_len
, ENC_NA
);
1727 return tvb_captured_length(tvb
);
1730 dissect_thread_bl(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data _U_
)
1732 proto_item
*proto_root
;
1733 proto_tree
*thread_bl_tree
;
1734 proto_tree
*tlv_tree
;
1736 unsigned offset
= 0;
1738 uint8_t tlv_type
, tlv_len
;
1740 /* Create the protocol tree. */
1741 proto_root
= proto_tree_add_item(tree
, proto_thread_bl
, tvb
, 0, tvb_reported_length(tvb
), ENC_NA
);
1742 thread_bl_tree
= proto_item_add_subtree(proto_root
, ett_thread_bl
);
1744 /* Thread Network Data TLVs */
1745 while (tvb_offset_exists(tvb
, offset
)) {
1747 /* Get the length ahead of time to pass to next function so we can highlight
1748 proper amount of bytes */
1749 tlv_len
= tvb_get_uint8(tvb
, offset
+ 1);
1751 ti
= proto_tree_add_item(thread_bl_tree
, hf_thread_bl_tlv
, tvb
, offset
, tlv_len
+2, ENC_NA
);
1752 tlv_tree
= proto_item_add_subtree(ti
, ett_thread_bl_tlv
);
1755 proto_tree_add_item(tlv_tree
, hf_thread_bl_tlv_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1756 tlv_type
= tvb_get_uint8(tvb
, offset
);
1759 /* Add value name to value root label */
1760 proto_item_append_text(ti
, " (%s)", val_to_str(tlv_type
, thread_bl_tlv_vals
, "Unknown (%d)"));
1763 proto_tree_add_item(tlv_tree
, hf_thread_bl_tlv_length
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1766 case THREAD_NM_TLV_TARGET_EID
:
1768 /* Check length is consistent */
1769 if (tlv_len
!= 16) {
1770 expert_add_info(pinfo
, proto_root
, &ei_thread_bl_len_size_mismatch
);
1771 proto_tree_add_item(tlv_tree
, hf_thread_bl_tlv_unknown
, tvb
, offset
, tlv_len
, ENC_NA
);
1774 proto_tree_add_item(tlv_tree
, hf_thread_bl_tlv_target_eid
, tvb
, offset
, tlv_len
, ENC_NA
);
1780 case THREAD_NM_TLV_EXT_MAC_ADDR
:
1782 /* Check length is consistent */
1784 expert_add_info(pinfo
, proto_root
, &ei_thread_bl_len_size_mismatch
);
1785 proto_tree_add_item(tlv_tree
, hf_thread_bl_tlv_unknown
, tvb
, offset
, tlv_len
, ENC_NA
);
1787 /* Extended MAC address */
1788 proto_tree_add_item(tlv_tree
, hf_thread_bl_tlv_ext_mac_addr
, tvb
, offset
, tlv_len
, ENC_BIG_ENDIAN
);
1794 case THREAD_NM_TLV_RLOC16
:
1796 /* Check length is consistent */
1798 expert_add_info(pinfo
, proto_root
, &ei_thread_address_len_size_mismatch
);
1799 proto_tree_add_item(tlv_tree
, hf_thread_address_tlv_unknown
, tvb
, offset
, tlv_len
, ENC_NA
);
1802 proto_tree_add_item(tlv_tree
, hf_thread_address_tlv_rloc16
, tvb
, offset
, tlv_len
, ENC_BIG_ENDIAN
);
1808 case THREAD_NM_TLV_ML_EID
:
1810 /* Check length is consistent */
1812 expert_add_info(pinfo
, proto_root
, &ei_thread_bl_len_size_mismatch
);
1813 proto_tree_add_item(tlv_tree
, hf_thread_bl_tlv_unknown
, tvb
, offset
, tlv_len
, ENC_NA
);
1816 proto_tree_add_item(tlv_tree
, hf_thread_bl_tlv_ml_eid
, tvb
, offset
, tlv_len
, ENC_NA
);
1822 case THREAD_NM_TLV_STATUS
:
1824 /* Check length is consistent */
1826 expert_add_info(pinfo
, proto_root
, &ei_thread_bl_len_size_mismatch
);
1827 proto_tree_add_item(tlv_tree
, hf_thread_bl_tlv_unknown
, tvb
, offset
, tlv_len
, ENC_NA
);
1830 proto_tree_add_item(tlv_tree
, hf_thread_bl_tlv_status
, tvb
, offset
, tlv_len
, ENC_BIG_ENDIAN
);
1836 case THREAD_NM_TLV_LAST_TRANSACTION_TIME
:
1838 /* Check length is consistent */
1840 expert_add_info(pinfo
, proto_root
, &ei_thread_bl_len_size_mismatch
);
1841 proto_tree_add_item(tlv_tree
, hf_thread_bl_tlv_unknown
, tvb
, offset
, tlv_len
, ENC_NA
);
1843 /* Last transaction time */
1844 proto_tree_add_item(tlv_tree
, hf_thread_bl_tlv_last_transaction_time
, tvb
, offset
, tlv_len
, ENC_BIG_ENDIAN
);
1850 case THREAD_NM_TLV_ROUTER_MASK
:
1852 /* Check length is consistent */
1854 expert_add_info(pinfo
, proto_root
, &ei_thread_bl_len_size_mismatch
);
1855 proto_tree_add_item(tlv_tree
, hf_thread_bl_tlv_unknown
, tvb
, offset
, tlv_len
, ENC_NA
);
1859 proto_tree_add_item(tlv_tree
, hf_thread_bl_tlv_router_mask_id_seq
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1863 * | | | | | | | | | | |1|1|1|1|1|1|...|6|
1864 * |0|1|2|3|4|5|6|7|8|9|0|1|2|3|4|5|...|3|
1865 * ---------------------------------------
1866 * |1|0|1|1|1|0|0|0|1|1|0|0|0|1|0|1|...
1868 * is sent as 0xb8, 0xc5
1869 * and represents table entry for routers 0, 2, 3, 4, 8, 9, 13, 15...
1872 /* Just show the string of octets - best representation for a bit mask */
1873 proto_tree_add_item(tlv_tree
, hf_thread_address_tlv_router_mask_assigned
, tvb
, offset
, 8, ENC_NA
);
1879 case THREAD_NM_TLV_ND_OPTION
:
1880 /* Just show the data */
1881 proto_tree_add_item(tlv_tree
, hf_thread_bl_tlv_nd_option
, tvb
, offset
, tlv_len
, ENC_NA
);
1885 case THREAD_NM_TLV_ND_DATA
:
1886 /* Just show the data. Note there is no icmpv6 options dissector so would have to copy it */
1887 proto_tree_add_item(tlv_tree
, hf_thread_bl_tlv_nd_data
, tvb
, offset
, tlv_len
, ENC_NA
);
1891 case THREAD_NM_TLV_THREAD_NETWORK_DATA
:
1893 sub_tvb
= tvb_new_subset_length(tvb
, offset
, tlv_len
);
1894 call_dissector(thread_address_nwd_handle
, sub_tvb
, pinfo
, tlv_tree
);
1899 case THREAD_NM_TLV_TIMEOUT
:
1901 expert_add_info(pinfo
, proto_root
, &ei_thread_bl_len_size_mismatch
);
1902 proto_tree_add_item(tlv_tree
, hf_thread_bl_tlv_unknown
, tvb
, offset
, tlv_len
, ENC_NA
);
1906 proto_tree_add_item(tlv_tree
, hf_thread_bl_tlv_timeout
, tvb
, offset
, tlv_len
, ENC_NA
);
1913 case THREAD_NM_TLV_THREAD_NETWORK_NAME
:
1915 expert_add_info(pinfo
, proto_root
, &ei_thread_bl_len_size_mismatch
);
1916 proto_tree_add_item(tlv_tree
, hf_thread_bl_tlv_unknown
, tvb
, offset
, tlv_len
, ENC_NA
);
1920 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_net_name
, tvb
, offset
, tlv_len
, ENC_ASCII
| ENC_UTF_8
);
1926 case THREAD_NM_TLV_IPV6_ADDRESS
:
1927 if ((tlv_len
% 16) != 0) {
1928 expert_add_info(pinfo
, proto_root
, &ei_thread_mc_len_size_mismatch
);
1929 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_unknown
, tvb
, offset
, tlv_len
, ENC_NA
);
1933 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_ipv6_addr
, tvb
, offset
, tlv_len
, ENC_NA
);
1934 for(int i
= 0; i
< (tlv_len
/16) ; i
++)
1936 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_ipv6_addr
, tvb
, offset
, 16, ENC_NA
);
1944 proto_tree_add_item(tlv_tree
, hf_thread_bl_tlv_unknown
, tvb
, offset
, tlv_len
, ENC_NA
);
1948 return tvb_captured_length(tvb
);
1952 dissect_thread_dg(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, void *data _U_
)
1954 proto_item
*proto_root
;
1955 proto_tree
*thread_dg_tree
;
1956 proto_tree
*tlv_tree
;
1957 unsigned offset
= 0;
1961 tlv_len_len_e tlv_len_len
;
1963 /* Create the protocol tree. */
1964 proto_root
= proto_tree_add_item(tree
, proto_thread_dg
, tvb
, 0, tvb_reported_length(tvb
), ENC_NA
);
1965 thread_dg_tree
= proto_item_add_subtree(proto_root
, ett_thread_dg
);
1967 /* Thread Network Data TLVs */
1968 while (tvb_offset_exists(tvb
, offset
)) {
1970 /* Get the type and length ahead of time to pass to next function so we can highlight
1971 proper amount of bytes */
1972 tlv_type
= tvb_get_uint8(tvb
, offset
);
1973 tlv_len
= (uint16_t)tvb_get_uint8(tvb
, offset
+ 1);
1975 /* TODO: need to make sure this applies to all Diagnostic TLVs */
1976 if (THREAD_TLV_LENGTH_ESC
== tlv_len
) {
1977 /* 16-bit length field */
1978 tlv_len
= tvb_get_ntohs(tvb
, offset
+ 2);
1979 tlv_len_len
= TLV_LEN_LEN16
;
1981 tlv_len_len
= TLV_LEN_LEN8
;
1984 /* Create the tree */
1985 ti
= proto_tree_add_item(thread_dg_tree
, hf_thread_dg_tlv
, tvb
, offset
, 1 + tlv_len_len
+ tlv_len
, ENC_NA
);
1986 tlv_tree
= proto_item_add_subtree(ti
, ett_thread_dg_tlv
);
1989 proto_tree_add_item(tlv_tree
, hf_thread_dg_tlv_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1992 /* Add value name to value root label */
1993 proto_item_append_text(ti
, " (%s)", val_to_str(tlv_type
, thread_dg_tlv_vals
, "Unknown (%d)"));
1996 switch (tlv_len_len
) {
1998 proto_tree_add_item(tlv_tree
, hf_thread_dg_tlv_length8
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2001 proto_tree_add_item(tlv_tree
, hf_thread_dg_tlv_length16
, tvb
, offset
+ 1, 2, ENC_BIG_ENDIAN
);
2006 offset
+= tlv_len_len
;
2009 case THREAD_DG_TLV_TYPE_LIST
:
2013 for (i
= 0; i
< tlv_len
; i
++) {
2014 proto_tree_add_item(tlv_tree
, hf_thread_dg_tlv_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2020 case THREAD_DG_TLV_EXT_MAC_ADDR
:
2021 case THREAD_DG_TLV_ADDRESS16
:
2022 case THREAD_DG_TLV_MODE
:
2023 case THREAD_DG_TLV_TIMEOUT
:
2024 case THREAD_DG_TLV_CONNECTIVITY
:
2025 case THREAD_DG_TLV_ROUTE64
:
2026 case THREAD_DG_TLV_LEADER_DATA
:
2027 case THREAD_DG_TLV_NETWORK_DATA
:
2028 case THREAD_DG_TLV_IPV6_ADDR_LIST
:
2030 case THREAD_DG_TLV_MAC_COUNTERS
:
2031 case THREAD_DG_TLV_BATTERY_LEVEL
:
2032 case THREAD_DG_TLV_VOLTAGE
:
2033 case THREAD_DG_TLV_CHILD_TABLE
:
2034 case THREAD_DG_TLV_CHANNEL_PAGES
:
2035 case THREAD_DG_TLV_MAX_CHILD_TIMEOUT
:
2036 case THREAD_DG_TLV_LDEVID_SUBJECT_PUBLIC_KEY_INFO
:
2037 case THREAD_DG_TLV_IDEVID_CERTIFICATE
:
2038 case THREAD_DG_TLV_EUI_64
:
2039 case THREAD_DG_TLV_VERSION
:
2040 case THREAD_DG_TLV_VENDOR_NAME
:
2041 case THREAD_DG_TLV_VENDOR_MODEL
:
2042 case THREAD_DG_TLV_VENDOR_SW_VERSION
:
2043 case THREAD_DG_TLV_THREAD_STACK_VERSION
:
2044 case THREAD_DG_TLV_CHILD
:
2045 case THREAD_DG_TLV_CHILD_IPV6_ADDRESS_LIST
:
2046 case THREAD_DG_TLV_ROUTER_NEIGHBOR
:
2047 case THREAD_DG_TLV_ANSWER
:
2048 case THREAD_DG_TLV_QUERY_ID
:
2049 case THREAD_DG_TLV_MLE_COUNTERS
:
2050 proto_tree_add_item(tlv_tree
, hf_thread_dg_tlv_general
, tvb
, offset
, tlv_len
, ENC_NA
);
2055 proto_tree_add_item(tlv_tree
, hf_thread_dg_tlv_unknown
, tvb
, offset
, tlv_len
, ENC_NA
);
2059 return tvb_captured_length(tvb
);
2063 dissect_thread_mc(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data _U_
)
2065 proto_item
*proto_root
;
2066 proto_tree
*thread_mc_tree
;
2067 proto_tree
*tlv_tree
;
2068 unsigned offset
= 0;
2073 tlv_len_len_e tlv_len_len
;
2077 /* Create the protocol tree. */
2078 proto_root
= proto_tree_add_item(tree
, proto_thread_mc
, tvb
, 0, tvb_reported_length(tvb
), ENC_NA
);
2079 thread_mc_tree
= proto_item_add_subtree(proto_root
, ett_thread_mc
);
2081 /* Get channel count a priori so we can process energy list better */
2082 chancount
= get_chancount(tvb
);
2084 /* Thread Network Data TLVs */
2085 while (tvb_offset_exists(tvb
, offset
)) {
2087 /* Get the type and length ahead of time to pass to next function so we can highlight
2088 proper amount of bytes */
2089 tlv_type
= tvb_get_uint8(tvb
, offset
);
2090 tlv_len
= (uint16_t)tvb_get_uint8(tvb
, offset
+ 1);
2092 /* TODO: need to make sure this applies to all MeshCoP TLVs */
2093 if (THREAD_TLV_LENGTH_ESC
== tlv_len
) {
2094 /* 16-bit length field */
2095 tlv_len
= tvb_get_ntohs(tvb
, offset
+ 2);
2096 tlv_len_len
= TLV_LEN_LEN16
;
2098 tlv_len_len
= TLV_LEN_LEN8
;
2101 /* Create the tree */
2102 ti
= proto_tree_add_item(thread_mc_tree
, hf_thread_mc_tlv
, tvb
, offset
, 1 + tlv_len_len
+ tlv_len
, ENC_NA
);
2103 tlv_tree
= proto_item_add_subtree(ti
, ett_thread_mc_tlv
);
2106 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2109 /* Add value name to value root label */
2110 proto_item_append_text(ti
, " (%s)", val_to_str(tlv_type
, thread_mc_tlv_vals
, "Unknown (%d)"));
2113 switch (tlv_len_len
) {
2115 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_length8
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2118 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_length16
, tvb
, offset
+ 1, 2, ENC_BIG_ENDIAN
);
2123 offset
+= tlv_len_len
;
2126 case THREAD_MC_TLV_CHANNEL
:
2128 /* Check length is consistent */
2130 expert_add_info(pinfo
, proto_root
, &ei_thread_mc_len_size_mismatch
);
2131 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_unknown
, tvb
, offset
, tlv_len
, ENC_NA
);
2134 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_channel_page
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2136 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_channel
, tvb
, offset
+1, 2, ENC_BIG_ENDIAN
);
2142 case THREAD_MC_TLV_PANID
:
2144 /* Check length is consistent */
2146 expert_add_info(pinfo
, proto_root
, &ei_thread_mc_len_size_mismatch
);
2147 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_unknown
, tvb
, offset
, tlv_len
, ENC_NA
);
2150 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_pan_id
, tvb
, offset
, tlv_len
, ENC_BIG_ENDIAN
);
2156 case THREAD_MC_TLV_XPANID
:
2158 /* Check length is consistent */
2160 expert_add_info(pinfo
, proto_root
, &ei_thread_mc_len_size_mismatch
);
2161 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_unknown
, tvb
, offset
, tlv_len
, ENC_NA
);
2164 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_xpan_id
, tvb
, offset
, tlv_len
, ENC_BIG_ENDIAN
);
2170 case THREAD_MC_TLV_NETWORK_NAME
:
2172 /* Check length is consistent */
2174 expert_add_info(pinfo
, proto_root
, &ei_thread_mc_len_too_long
);
2175 //proto_tree_add_item(tlv_tree, hf_thread_mc_tlv_unknown, tvb, offset, tlv_len, ENC_NA);
2176 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_net_name
, tvb
, offset
, tlv_len
, ENC_ASCII
| ENC_UTF_8
);
2178 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_net_name
, tvb
, offset
, tlv_len
, ENC_ASCII
| ENC_UTF_8
);
2184 case THREAD_MC_TLV_PSKC
:
2186 /* Check length is consistent */
2187 if (tlv_len
!= 16) {
2188 expert_add_info(pinfo
, proto_root
, &ei_thread_mc_len_size_mismatch
);
2189 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_unknown
, tvb
, offset
, tlv_len
, ENC_NA
);
2191 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_pskc
, tvb
, offset
, tlv_len
, ENC_NA
);
2197 case THREAD_MC_TLV_NETWORK_MASTER_KEY
:
2199 /* Check length is consistent */
2200 if (tlv_len
!= 16) {
2201 expert_add_info(pinfo
, proto_root
, &ei_thread_mc_len_size_mismatch
);
2202 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_unknown
, tvb
, offset
, tlv_len
, ENC_NA
);
2204 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_master_key
, tvb
, offset
, tlv_len
, ENC_NA
);
2210 case THREAD_MC_TLV_NETWORK_KEY_SEQ_CTR
:
2212 /* Check length is consistent */
2214 expert_add_info(pinfo
, proto_root
, &ei_thread_mc_len_size_mismatch
);
2215 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_unknown
, tvb
, offset
, tlv_len
, ENC_NA
);
2217 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_net_key_seq_ctr
, tvb
, offset
, tlv_len
, ENC_NA
);
2223 case THREAD_MC_TLV_NETWORK_ML_PREFIX
:
2225 /* Check length is consistent */
2227 expert_add_info(pinfo
, proto_root
, &ei_thread_mc_len_size_mismatch
);
2228 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_unknown
, tvb
, offset
, tlv_len
, ENC_NA
);
2232 memset(&prefix
, 0, sizeof(prefix
));
2233 tvb_memcpy(tvb
, (uint8_t *)&prefix
.bytes
, offset
, tlv_len
);
2234 pi
= proto_tree_add_ipv6(tlv_tree
, hf_thread_mc_tlv_ml_prefix
, tvb
, offset
, tlv_len
, &prefix
);
2235 proto_item_append_text(pi
, "/%d", tlv_len
* 8);
2241 case THREAD_MC_TLV_STEERING_DATA
:
2243 /* Check length is consistent */
2245 expert_add_info(pinfo
, proto_root
, &ei_thread_mc_len_too_long
);
2246 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_unknown
, tvb
, offset
, tlv_len
, ENC_NA
);
2248 /* Display it simply */
2249 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_steering_data
, tvb
, offset
, tlv_len
, ENC_NA
);
2255 case THREAD_MC_TLV_BORDER_AGENT_LOCATOR
:
2257 /* Check length is consistent */
2259 expert_add_info(pinfo
, proto_root
, &ei_thread_mc_len_size_mismatch
);
2260 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_unknown
, tvb
, offset
, tlv_len
, ENC_NA
);
2262 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_ba_locator
, tvb
, offset
, tlv_len
, ENC_NA
);
2268 case THREAD_MC_TLV_COMMISSIONER_ID
:
2270 /* Check length is consistent */
2272 expert_add_info(pinfo
, proto_root
, &ei_thread_mc_len_too_long
);
2273 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_unknown
, tvb
, offset
, tlv_len
, ENC_NA
);
2275 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_commissioner_id
, tvb
, offset
, tlv_len
, ENC_NA
|ENC_UTF_8
);
2281 case THREAD_MC_TLV_COMMISSIONER_SESSION_ID
:
2283 /* Check length is consistent */
2285 expert_add_info(pinfo
, proto_root
, &ei_thread_mc_len_size_mismatch
);
2286 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_unknown
, tvb
, offset
, tlv_len
, ENC_NA
);
2288 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_commissioner_sess_id
, tvb
, offset
, tlv_len
, ENC_NA
);
2294 case THREAD_MC_TLV_SECURITY_POLICY
:
2296 /* Check length is consistent */
2297 //Thread 1.1 has length 3
2298 //Thread 1.2 has length 4
2301 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_sec_policy_rot
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2303 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_sec_policy_o
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2304 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_sec_policy_n
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2305 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_sec_policy_r
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2306 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_sec_policy_c
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2307 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_sec_policy_b
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2308 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_sec_policy_rsv1
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2310 } else if (tlv_len
== 4) {
2311 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_sec_policy_rot
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2313 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_sec_policy_o
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2314 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_sec_policy_n
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2315 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_sec_policy_r
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2316 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_sec_policy_c
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2317 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_sec_policy_b
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2318 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_sec_policy_ccm
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2319 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_sec_policy_ae
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2320 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_sec_policy_nmp
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2322 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_sec_policy_l
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2323 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_sec_policy_ncr
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2324 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_sec_policy_rsv
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2325 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_sec_policy_vr
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2329 expert_add_info(pinfo
, proto_root
, &ei_thread_mc_len_size_mismatch
);
2330 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_unknown
, tvb
, offset
, tlv_len
, ENC_NA
);
2336 case THREAD_MC_TLV_GET
:
2340 for (i
= 0; i
< tlv_len
; i
++) {
2341 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2347 case THREAD_MC_TLV_ACTIVE_TSTAMP
:
2348 case THREAD_MC_TLV_PENDING_TSTAMP
:
2353 expert_add_info(pinfo
, proto_root
, &ei_thread_mc_len_size_mismatch
);
2354 //proto_tree_add_item(tlv_tree, hf_thread_mc_tlv_unknown, tvb, offset, tlv_len, ENC_NA);
2355 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_pending_tstamp
, tvb
, offset
, tlv_len
, ENC_NA
);
2357 /* Fill in the nstime_t structure */
2358 timestamp
.secs
= (time_t)tvb_get_ntoh48(tvb
, offset
);
2359 timestamp
.nsecs
= (int)lround((double)(tvb_get_ntohs(tvb
, offset
+ 6) >> 1) * THREAD_MC_32768_TO_NSEC_FACTOR
);
2360 if (tlv_type
== THREAD_MC_TLV_ACTIVE_TSTAMP
) {
2361 proto_tree_add_time(tlv_tree
, hf_thread_mc_tlv_active_tstamp
, tvb
, offset
, 8, ×tamp
);
2363 proto_tree_add_time(tlv_tree
, hf_thread_mc_tlv_pending_tstamp
, tvb
, offset
, 8, ×tamp
);
2370 case THREAD_MC_TLV_STATE
:
2372 /* Check length is consistent */
2374 expert_add_info(pinfo
, proto_root
, &ei_thread_mc_len_size_mismatch
);
2375 //proto_tree_add_item(tlv_tree, hf_thread_mc_tlv_unknown, tvb, offset, tlv_len, ENC_NA);
2376 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_state
, tvb
, offset
, tlv_len
, ENC_NA
);
2378 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_state
, tvb
, offset
, tlv_len
, ENC_BIG_ENDIAN
);
2384 case THREAD_MC_TLV_JOINER_DTLS_ENCAP
:
2389 sub_tvb
= tvb_new_subset_length(tvb
, offset
, tlv_len
);
2390 call_dissector(thread_dtls_handle
, sub_tvb
, pinfo
, tree
);
2396 case THREAD_MC_TLV_COMMISSIONER_UDP_PORT
:
2397 case THREAD_MC_TLV_JOINER_UDP_PORT
:
2400 expert_add_info(pinfo
, proto_root
, &ei_thread_mc_len_size_mismatch
);
2401 //proto_tree_add_item(tlv_tree, hf_thread_mc_tlv_unknown, tvb, offset, tlv_len, ENC_NA);
2402 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_udp_port
, tvb
, offset
, tlv_len
, ENC_NA
);
2405 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_udp_port
, tvb
, offset
, tlv_len
, ENC_BIG_ENDIAN
);
2411 case THREAD_MC_TLV_JOINER_IID
:
2414 expert_add_info(pinfo
, proto_root
, &ei_thread_mc_len_size_mismatch
);
2415 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_unknown
, tvb
, offset
, tlv_len
, ENC_NA
);
2418 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_iid
, tvb
, offset
, tlv_len
, ENC_NA
);
2424 case THREAD_MC_TLV_JOINER_ROUTER_LOCATOR
:
2427 expert_add_info(pinfo
, proto_root
, &ei_thread_mc_len_size_mismatch
);
2428 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_unknown
, tvb
, offset
, tlv_len
, ENC_NA
);
2430 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_jr_locator
, tvb
, offset
, tlv_len
, ENC_NA
);
2436 case THREAD_MC_TLV_JOINER_KEK
:
2438 if (tlv_len
!= 16) {
2439 expert_add_info(pinfo
, proto_root
, &ei_thread_mc_len_size_mismatch
);
2440 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_unknown
, tvb
, offset
, tlv_len
, ENC_NA
);
2442 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_kek
, tvb
, offset
, tlv_len
, ENC_NA
);
2448 case THREAD_MC_TLV_PROVISIONING_URL
:
2450 /* Check length is consistent */
2452 expert_add_info(pinfo
, proto_root
, &ei_thread_mc_len_too_long
);
2453 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_unknown
, tvb
, offset
, tlv_len
, ENC_NA
);
2455 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_provisioning_url
, tvb
, offset
, tlv_len
, ENC_NA
|ENC_UTF_8
);
2461 case THREAD_MC_TLV_VENDOR_NAME
:
2463 /* Check length is consistent */
2465 expert_add_info(pinfo
, proto_root
, &ei_thread_mc_len_too_long
);
2466 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_unknown
, tvb
, offset
, tlv_len
, ENC_NA
);
2468 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_vendor_name
, tvb
, offset
, tlv_len
, ENC_NA
|ENC_UTF_8
);
2474 case THREAD_MC_TLV_VENDOR_MODEL
:
2476 /* Check length is consistent: TODO not specified in spec. */
2478 expert_add_info(pinfo
, proto_root
, &ei_thread_mc_len_too_long
);
2479 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_unknown
, tvb
, offset
, tlv_len
, ENC_NA
);
2481 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_vendor_model
, tvb
, offset
, tlv_len
, ENC_NA
|ENC_UTF_8
);
2487 case THREAD_MC_TLV_VENDOR_SW_VERSION
:
2489 /* Check length is consistent */
2491 expert_add_info(pinfo
, proto_root
, &ei_thread_mc_len_too_long
);
2492 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_unknown
, tvb
, offset
, tlv_len
, ENC_NA
);
2494 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_vendor_sw_ver
, tvb
, offset
, tlv_len
, ENC_NA
|ENC_UTF_8
);
2500 case THREAD_MC_TLV_VENDOR_DATA
:
2502 /* Check length is consistent */
2504 expert_add_info(pinfo
, proto_root
, &ei_thread_mc_len_too_long
);
2505 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_unknown
, tvb
, offset
, tlv_len
, ENC_NA
);
2507 /* Display it simply */
2508 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_vendor_data
, tvb
, offset
, tlv_len
, ENC_ASCII
);
2514 case THREAD_MC_TLV_VENDOR_STACK_VERSION
:
2516 /* Check length is consistent */
2518 expert_add_info(pinfo
, proto_root
, &ei_thread_mc_len_size_mismatch
);
2519 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_unknown
, tvb
, offset
, tlv_len
, ENC_NA
);
2525 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_vendor_stack_ver_oui
, tvb
, offset
, 3, ENC_BIG_ENDIAN
);
2527 build_u8
= tvb_get_uint8(tvb
, offset
);
2529 build
= (uint16_t)build_u8
<< 4;
2530 build_u8
= tvb_get_uint8(tvb
, offset
);
2531 build
|= (uint16_t)build_u8
>> 4;
2532 pi
= proto_tree_add_uint(tlv_tree
, hf_thread_mc_tlv_vendor_stack_ver_build
, tvb
, 0, 0, build
);
2533 proto_item_set_generated(pi
);
2534 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_vendor_stack_ver_rev
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2536 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_vendor_stack_ver_min
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2537 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_vendor_stack_ver_maj
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2543 case THREAD_MC_TLV_UDP_ENCAPSULATION
:
2549 src_port
= tvb_get_ntohs(tvb
, offset
);
2550 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_udp_encap_src_port
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2552 dst_port
= tvb_get_ntohs(tvb
, offset
);
2553 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_udp_encap_dst_port
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2558 /* Allocate a buffer for the fake UDP datagram and create the fake header. */
2559 udp_hdr_t
* udp_hdr
= (udp_hdr_t
*)wmem_alloc(pinfo
->pool
, sizeof(udp_hdr_t
) + (tlv_len
- 4));
2561 /* Create pseudo UDP header */
2562 udp_hdr
->src_port
= g_htons(src_port
);
2563 udp_hdr
->dst_port
= g_htons(dst_port
);
2564 udp_hdr
->length
= g_htons(tlv_len
+ 4); /* Includes UDP header length */
2565 udp_hdr
->checksum
= 0;
2566 /* Copy UDP payload in */
2567 tvb_memcpy(tvb
, udp_hdr
+ 1, offset
, tlv_len
- 4);
2568 /* Create child tvb */
2569 sub_tvb
= tvb_new_child_real_data(tvb
, (uint8_t *)udp_hdr
, tlv_len
+ 4, tvb_reported_length(tvb
) + 4);
2570 call_dissector(thread_udp_handle
, sub_tvb
, pinfo
, tree
);
2572 offset
+= (tlv_len
-4);
2576 case THREAD_MC_TLV_IPV6_ADDRESS
:
2578 /* Check length is consistent */
2579 if (tlv_len
!= 16) {
2580 expert_add_info(pinfo
, proto_root
, &ei_thread_mc_len_size_mismatch
);
2581 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_unknown
, tvb
, offset
, tlv_len
, ENC_NA
);
2583 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_ipv6_addr
, tvb
, offset
, tlv_len
, ENC_NA
);
2589 /* case THREAD_MC_TLV_PENDING_TSTAMP: Handled in THREAD_MC_TLV_ACTIVE_TSTAMP case */
2591 case THREAD_MC_TLV_DELAY_TIMER
:
2594 expert_add_info(pinfo
, proto_root
, &ei_thread_mc_len_size_mismatch
);
2595 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_unknown
, tvb
, offset
, tlv_len
, ENC_NA
);
2597 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_delay_timer
, tvb
, offset
, tlv_len
, ENC_BIG_ENDIAN
);
2603 case THREAD_MC_TLV_CHANNEL_MASK
:
2605 proto_tree
*cm_tree
;
2607 uint8_t entries
= 0;
2608 int32_t check_len
= tlv_len
;
2609 int check_offset
= offset
+ 1; /* Channel page first */
2612 /* Check consistency of entries */
2613 while (check_len
> 0) {
2615 masklen
= tvb_get_uint8(tvb
, check_offset
);
2617 break; /* Get out or we might spin forever */
2619 masklen
+= 2; /* Add in page and length */
2620 check_offset
+= masklen
;
2621 check_len
-= masklen
;
2625 if (check_len
!= 0) {
2626 /* Not an integer number of entries */
2627 expert_add_info(pinfo
, proto_root
, &ei_thread_mc_tlv_length_failed
);
2628 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_unknown
, tvb
, offset
, tlv_len
, ENC_NA
);
2631 for (i
= 0; i
< entries
; i
++) {
2632 pi
= proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_chan_mask
, tvb
, offset
, 1, ENC_NA
);
2633 cm_tree
= proto_item_add_subtree(pi
, ett_thread_mc_chan_mask
);
2634 proto_tree_add_item(cm_tree
, hf_thread_mc_tlv_chan_mask_page
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2636 masklen
= tvb_get_uint8(tvb
, offset
);
2637 proto_tree_add_item(cm_tree
, hf_thread_mc_tlv_chan_mask_len
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2639 proto_tree_add_item(cm_tree
, hf_thread_mc_tlv_chan_mask_mask
, tvb
, offset
, masklen
, ENC_NA
);
2646 case THREAD_MC_TLV_COUNT
:
2649 expert_add_info(pinfo
, proto_root
, &ei_thread_mc_len_size_mismatch
);
2650 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_unknown
, tvb
, offset
, tlv_len
, ENC_NA
);
2652 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_count
, tvb
, offset
, tlv_len
, ENC_BIG_ENDIAN
);
2658 case THREAD_MC_TLV_PERIOD
:
2661 expert_add_info(pinfo
, proto_root
, &ei_thread_mc_len_size_mismatch
);
2662 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_unknown
, tvb
, offset
, tlv_len
, ENC_NA
);
2664 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_period
, tvb
, offset
, tlv_len
, ENC_BIG_ENDIAN
);
2670 case THREAD_MC_TLV_SCAN_DURATION
:
2673 expert_add_info(pinfo
, proto_root
, &ei_thread_mc_len_size_mismatch
);
2674 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_unknown
, tvb
, offset
, tlv_len
, ENC_NA
);
2676 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_scan_duration
, tvb
, offset
, tlv_len
, ENC_BIG_ENDIAN
);
2682 case THREAD_MC_TLV_ENERGY_LIST
:
2684 proto_tree
*it_tree
;
2687 if ((chancount
!= THREAD_MC_INVALID_CHAN_COUNT
) && (chancount
!= 0) && ((tlv_len
% chancount
) == 0)) {
2688 /* Go through the number of el_counts of scan */
2689 for (i
= 0; i
< (int)(tlv_len
/ (uint16_t)chancount
); i
++) {
2690 pi
= proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_el_count
, tvb
, offset
, 1, ENC_NA
);
2691 proto_item_append_text(pi
, " %d", i
+ 1);
2692 it_tree
= proto_item_add_subtree(pi
, ett_thread_mc_el_count
);
2693 proto_tree_add_item(it_tree
, hf_thread_mc_tlv_energy_list
, tvb
, offset
, chancount
, ENC_NA
);
2694 offset
+= chancount
;
2697 /* This might not work but try and display as string */
2698 /* Something wrong with channel count so just show it as a simple string */
2699 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_energy_list
, tvb
, offset
, tlv_len
, ENC_NA
);
2705 case THREAD_MC_TLV_DOMAIN_NAME
:
2707 /* Check length is consistent */
2709 expert_add_info(pinfo
, proto_root
, &ei_thread_mc_len_size_mismatch
);
2710 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_unknown
, tvb
, offset
, tlv_len
, ENC_NA
);
2712 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_domain_name
, tvb
, offset
, tlv_len
, ENC_NA
);
2718 case THREAD_MC_TLV_DOMAIN_PREFIX
:
2719 //To be defined in future in draft
2722 case THREAD_MC_TLV_AE_STEERING_DATA
:
2724 /* Check length is consistent */
2726 expert_add_info(pinfo
, proto_root
, &ei_thread_mc_len_size_mismatch
);
2727 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_unknown
, tvb
, offset
, tlv_len
, ENC_NA
);
2729 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_ae_steering_data
, tvb
, offset
, tlv_len
, ENC_NA
);
2735 case THREAD_MC_TLV_NMKP_STEERING_DATA
:
2737 /* Check length is consistent */
2739 expert_add_info(pinfo
, proto_root
, &ei_thread_mc_len_size_mismatch
);
2740 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_unknown
, tvb
, offset
, tlv_len
, ENC_NA
);
2742 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_nmkp_steering_data
, tvb
, offset
, tlv_len
, ENC_NA
);
2748 case THREAD_MC_TLV_COMMISSIONER_TOKEN
:
2751 case THREAD_MC_TLV_COMMISSIONER_SIGNATURE
:
2752 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_commissioner_signature
, tvb
, offset
, tlv_len
, ENC_NA
);
2756 case THREAD_MC_TLV_AE_UDP_PORT
:
2758 /* Check length is consistent */
2760 expert_add_info(pinfo
, proto_root
, &ei_thread_mc_len_size_mismatch
);
2761 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_unknown
, tvb
, offset
, tlv_len
, ENC_NA
);
2763 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_ae_udp_port
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2769 case THREAD_MC_TLV_NMKP_UDP_PORT
:
2771 /* Check length is consistent */
2773 expert_add_info(pinfo
, proto_root
, &ei_thread_mc_len_size_mismatch
);
2774 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_unknown
, tvb
, offset
, tlv_len
, ENC_NA
);
2776 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_nmkp_udp_port
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2782 case THREAD_MC_TLV_TRI_HOSTNAME
:
2785 case THREAD_MC_TLV_REGISTRAR_IPV6_ADDRESS
:
2787 /* Check length is consistent */
2788 if (tlv_len
!= 16) {
2789 expert_add_info(pinfo
, proto_root
, &ei_thread_mc_len_size_mismatch
);
2790 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_unknown
, tvb
, offset
, tlv_len
, ENC_NA
);
2792 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_registrar_ipv6_addr
, tvb
, offset
, tlv_len
, ENC_NA
);
2798 case THREAD_MC_TLV_REGISTRAR_HOSTNAME
:
2799 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_registrar_hostname
, tvb
, offset
, tlv_len
, ENC_NA
);
2803 case THREAD_MC_TLV_COMMISSIONER_PEN_SIGNATURE
:
2806 case THREAD_MC_TLV_COMMISSIONER_PEN_TOKEN
:
2809 case THREAD_MC_TLV_DISCOVERY_REQUEST
:
2811 /* Check length is consistent */
2813 expert_add_info(pinfo
, proto_root
, &ei_thread_mc_len_size_mismatch
);
2814 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_unknown
, tvb
, offset
, tlv_len
, ENC_NA
);
2816 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_discovery_req_ver
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2817 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_discovery_req_j
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2823 case THREAD_MC_TLV_DISCOVERY_RESPONSE
:
2825 /* Check length is consistent */
2827 expert_add_info(pinfo
, proto_root
, &ei_thread_mc_len_size_mismatch
);
2828 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_unknown
, tvb
, offset
, tlv_len
, ENC_NA
);
2830 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_discovery_rsp_ver
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2831 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_discovery_rsp_n
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2832 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_discovery_rsp_c
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2839 proto_tree_add_item(tlv_tree
, hf_thread_mc_tlv_unknown
, tvb
, offset
, tlv_len
, ENC_NA
);
2843 return tvb_captured_length(tvb
);
2847 // NOLINTNEXTLINE(misc-no-recursion)
2848 dissect_thread_nwd(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data _U_
)
2850 proto_item
*proto_root
;
2851 proto_tree
*thread_nwd_tree
;
2852 proto_tree
*tlv_tree
;
2854 unsigned offset
= 0, tlv_offset
;
2856 uint8_t tlv_type
, tlv_len
;
2857 int g_server_decode
= 1; /* used to check if the full decoding of Server TLV has to be done or not */
2859 /* Create the protocol tree. */
2860 proto_root
= proto_tree_add_item(tree
, proto_thread_nwd
, tvb
, 0, tvb_reported_length(tvb
), ENC_NA
);
2861 thread_nwd_tree
= proto_item_add_subtree(proto_root
, ett_thread_nwd
);
2863 /* Thread Network Data TLVs */
2864 increment_dissection_depth(pinfo
);
2865 while (tvb_offset_exists(tvb
, offset
)) {
2867 /* Get the length ahead of time to pass to next function so we can highlight
2868 proper amount of bytes */
2869 tlv_len
= tvb_get_uint8(tvb
, offset
+ 1);
2871 ti
= proto_tree_add_item(thread_nwd_tree
, hf_thread_nwd_tlv
, tvb
, offset
, tlv_len
+2, ENC_NA
);
2872 tlv_tree
= proto_item_add_subtree(ti
, ett_thread_nwd_tlv
);
2875 proto_tree_add_item(tlv_tree
, hf_thread_nwd_tlv_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2876 tlv_type
= tvb_get_uint8(tvb
, offset
) >> 1;
2879 proto_tree_add_item(tlv_tree
, hf_thread_nwd_tlv_stable
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2882 /* Add value name to value root label */
2883 proto_item_append_text(ti
, " (%s)", val_to_str(tlv_type
, thread_nwd_tlv_vals
, "Unknown (%d)"));
2886 proto_tree_add_item(tlv_tree
, hf_thread_nwd_tlv_length
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2890 case THREAD_NWD_TLV_HAS_ROUTE
:
2892 /* Has Route TLV can be top level TLV or sub-TLV */
2894 /* Check length is consistent */
2895 if ((tlv_len
% THREAD_NWD_TLV_HAS_ROUTE_SIZE
) != 0)
2897 expert_add_info(pinfo
, proto_root
, &ei_thread_nwd_len_size_mismatch
);
2898 proto_tree_add_item(tlv_tree
, hf_thread_nwd_tlv_unknown
, tvb
, offset
, tlv_len
, ENC_NA
);
2901 proto_tree
*has_route_tree
;
2903 unsigned count
= tlv_len
/ THREAD_NWD_TLV_HAS_ROUTE_SIZE
;
2906 for (i
= 0; i
< count
; i
++) {
2907 ti
= proto_tree_add_item(tlv_tree
, hf_thread_nwd_tlv_has_route
, tvb
, offset
, 1, ENC_NA
);
2908 has_route_tree
= proto_item_add_subtree(ti
, ett_thread_nwd_has_route
);
2909 proto_tree_add_item(has_route_tree
, hf_thread_nwd_tlv_has_route_br_16
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2911 proto_tree_add_item(has_route_tree
, hf_thread_nwd_tlv_has_route_pref
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2912 proto_tree_add_item(has_route_tree
, hf_thread_nwd_tlv_has_route_np
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2913 proto_tree_add_item(has_route_tree
, hf_thread_nwd_tlv_has_route_reserved
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2920 case THREAD_NWD_TLV_PREFIX
:
2923 uint8_t prefix_byte_len
;
2925 address prefix_addr
;
2928 proto_tree_add_item(tlv_tree
, hf_thread_nwd_tlv_prefix_domain_id
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2933 proto_tree_add_item(tlv_tree
, hf_thread_nwd_tlv_prefix_length
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2934 prefix_len
= tvb_get_uint8(tvb
, offset
);
2935 prefix_byte_len
= (prefix_len
+ 7) / 8;
2940 memset(&prefix
.bytes
, 0, sizeof(prefix
));
2941 if (prefix_byte_len
<= sizeof(prefix
))
2942 tvb_memcpy(tvb
, (uint8_t *)&prefix
.bytes
, offset
, prefix_byte_len
);
2943 proto_tree_add_ipv6(tlv_tree
, hf_thread_nwd_tlv_prefix
, tvb
, offset
, prefix_byte_len
, &prefix
);
2944 set_address(&prefix_addr
, AT_IPv6
, 16, prefix
.bytes
);
2945 proto_item_append_text(ti
, " = %s/%d", address_to_str(pinfo
->pool
, &prefix_addr
), prefix_len
);
2946 offset
+= prefix_byte_len
;
2947 tlv_offset
+= prefix_byte_len
;
2949 if (tlv_offset
< tlv_len
) {
2950 proto_tree
*sub_tlv_tree
;
2951 unsigned remaining
= tlv_len
- tlv_offset
;
2953 ti
= proto_tree_add_item(tlv_tree
, hf_thread_nwd_tlv_sub_tlvs
, tvb
, offset
, 1, ENC_NA
);
2954 sub_tlv_tree
= proto_item_add_subtree(ti
, ett_thread_nwd_prefix_sub_tlvs
);
2955 /* Call this dissector for sub-TLVs */
2956 sub_tvb
= tvb_new_subset_length(tvb
, offset
, remaining
); /* remove prefix length (1) and prefix (prefix_byte_len) */
2957 dissect_thread_nwd(sub_tvb
, pinfo
, sub_tlv_tree
, data
);
2958 offset
+= remaining
;
2963 case THREAD_NWD_TLV_BORDER_ROUTER
:
2965 /* Border Router TLV can only be sub-TLV */
2967 /* Check length is consistent */
2968 if ((tlv_len
% 4) != 0)
2970 expert_add_info(pinfo
, proto_root
, &ei_thread_nwd_len_size_mismatch
);
2971 proto_tree_add_item(tlv_tree
, hf_thread_nwd_tlv_unknown
, tvb
, offset
, tlv_len
, ENC_NA
);
2974 proto_tree
*border_router_tree
;
2976 unsigned count
= tlv_len
/ 4;
2979 for (i
= 0; i
< count
; i
++) {
2980 ti
= proto_tree_add_item(tlv_tree
, hf_thread_nwd_tlv_border_router
, tvb
, offset
, 1, ENC_NA
);
2981 border_router_tree
= proto_item_add_subtree(ti
, ett_thread_nwd_border_router
);
2983 proto_tree_add_item(border_router_tree
, hf_thread_nwd_tlv_border_router_16
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2985 proto_tree_add_item(border_router_tree
, hf_thread_nwd_tlv_border_router_pref
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2986 proto_tree_add_item(border_router_tree
, hf_thread_nwd_tlv_border_router_p
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2987 proto_tree_add_item(border_router_tree
, hf_thread_nwd_tlv_border_router_s
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2988 proto_tree_add_item(border_router_tree
, hf_thread_nwd_tlv_border_router_d
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2989 proto_tree_add_item(border_router_tree
, hf_thread_nwd_tlv_border_router_c
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2990 proto_tree_add_item(border_router_tree
, hf_thread_nwd_tlv_border_router_r
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2991 proto_tree_add_item(border_router_tree
, hf_thread_nwd_tlv_border_router_o
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2993 proto_tree_add_item(border_router_tree
, hf_thread_nwd_tlv_border_router_n
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2994 proto_tree_add_item(border_router_tree
, hf_thread_nwd_tlv_border_router_dp
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3001 case THREAD_NWD_TLV_6LOWPAN_ID
:
3003 static int * const nwd_6lowpan_flags
[] = {
3004 &hf_thread_nwd_tlv_6lowpan_id_6co_flag_reserved
,
3005 &hf_thread_nwd_tlv_6lowpan_id_6co_flag_c
,
3006 &hf_thread_nwd_tlv_6lowpan_id_6co_flag_cid
,
3011 proto_tree_add_bitmask(tlv_tree
, tvb
, offset
, hf_thread_nwd_tlv_6lowpan_id_6co_flag
, ett_thread_nwd_6co_flag
, nwd_6lowpan_flags
, ENC_BIG_ENDIAN
);
3014 /* Context Length */
3015 proto_tree_add_item(tlv_tree
, hf_thread_nwd_tlv_6lowpan_id_6co_context_length
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3020 case THREAD_NWD_TLV_COMMISSIONING_DATA
:
3023 sub_tvb
= tvb_new_subset_length(tvb
, offset
, tlv_len
);
3024 call_dissector(thread_mc_handle
, sub_tvb
, pinfo
, tlv_tree
);
3030 case THREAD_NWD_TLV_SERVICE
:
3035 /* Flags and S_id */
3036 flags
= tvb_get_uint8(tvb
, offset
);
3037 proto_tree_add_item(tlv_tree
, hf_thread_nwd_tlv_service_t
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3038 proto_tree_add_item(tlv_tree
, hf_thread_nwd_tlv_service_s_id
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3042 /* Enterprise number */
3043 if ((flags
& THREAD_NWD_TLV_SERVICE_T
) == 0) {
3044 proto_tree_add_item(tlv_tree
, hf_thread_nwd_tlv_service_s_ent_num
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
3050 s_data_len
= tvb_get_uint8(tvb
, offset
);
3051 proto_tree_add_item(tlv_tree
, hf_thread_nwd_tlv_service_s_data_len
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3054 uint8_t thread_service_data
= tvb_get_uint8(tvb
, offset
);
3055 // Thread 1.3 Service TLV code
3056 if((s_data_len
== 2) && (thread_service_data
== 0x5c))
3058 proto_tree_add_item(tlv_tree
, hf_thread_nwd_tlv_service_s_data
, tvb
, offset
, s_data_len
, ENC_NA
);
3059 proto_tree_add_item(tlv_tree
, hf_thread_nwd_tlv_service_srp_dataset_identifier
, tvb
, offset
, 1, ENC_NA
);
3060 proto_tree_add_item(tlv_tree
, hf_thread_nwd_tlv_service_anycast_seqno
, tvb
, offset
+ 1, 1, ENC_NA
);
3063 g_server_decode
= 2;
3064 } else if(((s_data_len
== 1) && (thread_service_data
== 0x5d)) || ((s_data_len
== 19) && (thread_service_data
== 0x5d)))
3066 proto_tree_add_item(tlv_tree
, hf_thread_nwd_tlv_service_s_data
, tvb
, offset
, s_data_len
, ENC_NA
);
3067 proto_tree_add_item(tlv_tree
, hf_thread_nwd_tlv_service_srp_dataset_identifier
, tvb
, offset
, 1, ENC_NA
);
3072 g_server_decode
= 3;
3074 else if(s_data_len
== 19)
3076 g_server_decode
= 2;
3077 proto_tree_add_item(tlv_tree
, hf_thread_nwd_tlv_service_unicast_ipv6_address
, tvb
, offset
, 16, ENC_NA
);
3078 proto_tree_add_item(tlv_tree
, hf_thread_nwd_tlv_service_unicast_port_number
, tvb
, offset
+ 16, 2, ENC_NA
);
3085 proto_tree_add_item(tlv_tree
, hf_thread_nwd_tlv_service_s_data
, tvb
, offset
, s_data_len
, ENC_NA
);
3086 offset
+= s_data_len
;
3087 tlv_offset
+= s_data_len
;
3088 //Flag to be 1 (BIG_ENDIAN so check the MSB) and thread_service_data = 1 then Server Sub TLV needs to be decoded with s_server_data fields
3089 if(((flags
& THREAD_NWD_TLV_SERVICE_T
) == THREAD_NWD_TLV_SERVICE_T
) &&
3090 (thread_service_data
== THREAD_SERVICE_DATA_BBR
)) {
3091 g_server_decode
= 1;
3094 g_server_decode
= 0;
3098 // proto_tree_add_item(tlv_tree, hf_thread_nwd_tlv_service_s_data, tvb, offset, s_data_len, ENC_NA);
3099 // offset += s_data_len;
3100 // tlv_offset += s_data_len;
3101 // //Flag to be 1 (BIG_ENDIAN so check the MSB) and thread_service_data = 1 then Server Sub TLV needs to be decoded with s_server_data fields
3102 // if(((flags & THREAD_NWD_TLV_SERVICE_T) == THREAD_NWD_TLV_SERVICE_T) &&
3103 // (thread_service_data == THREAD_SERVICE_DATA_BBR)) {
3104 // g_server_decode = 1;
3107 // g_server_decode = 0;
3109 // Thread 1.3 Service TLV code
3113 if (tlv_offset
< tlv_len
) {
3114 proto_tree
*sub_tlv_tree
;
3115 unsigned remaining
= tlv_len
- tlv_offset
;
3117 ti
= proto_tree_add_item(tlv_tree
, hf_thread_nwd_tlv_sub_tlvs
, tvb
, offset
, 1, ENC_NA
);
3118 sub_tlv_tree
= proto_item_add_subtree(ti
, ett_thread_nwd_prefix_sub_tlvs
);
3119 /* Call this dissector for sub-TLVs. Should only be server TLVs */
3120 sub_tvb
= tvb_new_subset_length(tvb
, offset
, remaining
); /* remove prefix length (1) and prefix (prefix_byte_len) */
3121 dissect_thread_nwd(sub_tvb
, pinfo
, sub_tlv_tree
, data
);
3122 offset
+= remaining
;
3127 case THREAD_NWD_TLV_SERVER
:
3129 if(g_server_decode
== 1) {
3130 //2 bytes of server 16
3131 proto_tree_add_item(tlv_tree
, hf_thread_nwd_tlv_server_16
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
3133 /* tlv_offset = 2; */
3134 //7 bytes of server data
3135 proto_tree_add_item(tlv_tree
, hf_thread_nwd_tlv_service_s_data_seqno
, tvb
, offset
, 1, ENC_NA
);
3137 /* tlv_offset += 1; */
3138 proto_tree_add_item(tlv_tree
, hf_thread_nwd_tlv_service_s_data_rrdelay
, tvb
, offset
, 2, ENC_NA
);
3140 /* tlv_offset += 2; */
3141 proto_tree_add_item(tlv_tree
, hf_thread_nwd_tlv_service_s_data_mlrtimeout
, tvb
, offset
, 4, ENC_NA
);
3144 else if(g_server_decode
== 0) {
3145 //2 bytes of server 16
3146 proto_tree_add_item(tlv_tree
, hf_thread_nwd_tlv_server_16
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
3150 if (tlv_offset
< tlv_len
)
3152 unsigned remaining
= tlv_len
- tlv_offset
;
3153 //remaining bytes - server data
3154 proto_tree_add_item(tlv_tree
, hf_thread_nwd_tlv_server_data
, tvb
, offset
, remaining
, ENC_NA
);
3155 offset
+= remaining
;
3159 // Thread 1.3 Service TLV code
3160 else if(g_server_decode
== 2) {
3161 //2 bytes of server 16
3162 proto_tree_add_item(tlv_tree
, hf_thread_nwd_tlv_server_16
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
3165 if (tlv_offset
< tlv_len
)
3167 unsigned remaining
= tlv_len
- tlv_offset
;
3168 //remaining bytes - server data
3169 proto_tree_add_item(tlv_tree
, hf_thread_nwd_tlv_server_data
, tvb
, offset
, remaining
, ENC_NA
);
3170 offset
+= remaining
;
3173 else if(g_server_decode
== 3) {
3174 //2 bytes of server 16
3175 proto_tree_add_item(tlv_tree
, hf_thread_nwd_tlv_server_16
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
3178 proto_tree_add_item(tlv_tree
, hf_thread_nwd_tlv_service_unicast_ipv6_address
, tvb
, offset
, 16, ENC_NA
);
3179 proto_tree_add_item(tlv_tree
, hf_thread_nwd_tlv_service_unicast_port_number
, tvb
, offset
+ 16, 2, ENC_NA
);
3183 if (tlv_offset
< tlv_len
)
3185 unsigned remaining
= tlv_len
- tlv_offset
;
3186 //remaining bytes - server data
3187 proto_tree_add_item(tlv_tree
, hf_thread_nwd_tlv_server_data
, tvb
, offset
, remaining
, ENC_NA
);
3188 offset
+= remaining
;
3191 // Thread 1.3 Service TLV code
3196 proto_tree_add_item(tlv_tree
, hf_thread_nwd_tlv_unknown
, tvb
, offset
, tlv_len
, ENC_NA
);
3200 decrement_dissection_depth(pinfo
);
3201 return tvb_captured_length(tvb
);
3205 dissect_thread_coap(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data _U_
)
3211 /* Obtain the CoAP info */
3212 coinfo
= (coap_info
*)p_get_proto_data(wmem_file_scope(), pinfo
, proto_coap
, 0);
3214 /* Reject the packet if not CoAP */
3215 if (!coinfo
) return 0;
3217 uri
= wmem_strbuf_get_str(coinfo
->uri_str_strbuf
);
3219 tokens
= wmem_strsplit(pinfo
->pool
, uri
, "/", 3);
3220 if (g_strv_length(tokens
) == 3) {
3221 /* No need to create a subset as we are dissecting the tvb as it is. */
3222 dissector_try_string_with_data(thread_coap_namespace
, tokens
[1], tvb
, pinfo
, tree
, true, NULL
);
3225 return tvb_captured_length(tvb
);
3228 static int dissect_thread_bcn(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data
)
3230 ieee802154_packet
*packet
= (ieee802154_packet
*)data
;
3231 proto_item
*ti
, *beacon_root
;
3232 proto_tree
*beacon_tree
;
3233 unsigned offset
= 0;
3234 const uint8_t *ssid
;
3235 uint8_t tlv_type
, tlv_len
;
3236 proto_tree
*tlv_tree
= NULL
;
3238 /* Reject the packet if data is NULL */
3239 if (!packet
) return 0;
3241 /* Add ourself to the protocol column. */
3242 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "Thread");
3243 /* Create the tree for this beacon. */
3244 beacon_root
= proto_tree_add_item(tree
, proto_thread_bcn
, tvb
, 0, -1, ENC_NA
);
3245 beacon_tree
= proto_item_add_subtree(beacon_root
, ett_thread_bcn
);
3247 /* Update the info column. */
3248 col_clear(pinfo
->cinfo
, COL_INFO
);
3249 col_append_fstr(pinfo
->cinfo
, COL_INFO
, "Beacon, Src: 0x%04x", packet
->src16
);
3251 /* Get and display the protocol id, must be 0x03 on all Thread beacons. */
3252 proto_tree_add_item(beacon_tree
, hf_thread_bcn_protocol
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3255 /* Get and display the beacon flags */
3256 proto_tree_add_item(beacon_tree
, hf_thread_bcn_joining
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3257 proto_tree_add_item(beacon_tree
, hf_thread_bcn_native
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3258 proto_tree_add_item(beacon_tree
, hf_thread_bcn_version
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3261 /* Get and display the network ID. */
3262 proto_tree_add_item_ret_string(beacon_tree
, hf_thread_bcn_network_id
, tvb
, offset
, 16, ENC_ASCII
|ENC_NA
, pinfo
->pool
, &ssid
);
3263 col_append_fstr(pinfo
->cinfo
, COL_INFO
, ", Network ID: %s", ssid
);
3266 /* See if we're at the end */
3267 if (offset
>= tvb_captured_length(tvb
)) {
3268 return tvb_captured_length(tvb
);
3272 proto_tree_add_item(beacon_tree
, hf_thread_bcn_epid
, tvb
, offset
, 8, ENC_BIG_ENDIAN
);
3275 /* See if we're at the end */
3276 if (offset
>= tvb_captured_length(tvb
)) {
3277 return tvb_captured_length(tvb
);
3280 /* Steering data TLV present */
3282 /* Get the length ahead of time to pass to next function so we can highlight
3283 proper amount of bytes */
3284 tlv_len
= tvb_get_uint8(tvb
, offset
+1);
3287 ti
= proto_tree_add_item(beacon_tree
, hf_thread_bcn_tlv
, tvb
, offset
, tlv_len
+2, ENC_NA
);
3288 tlv_tree
= proto_item_add_subtree(ti
, ett_thread_bcn_tlv
);
3289 proto_tree_add_item(tlv_tree
, hf_thread_bcn_tlv_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3291 tlv_type
= tvb_get_uint8(tvb
, offset
);
3294 /* Add value name to value root label */
3295 proto_item_append_text(ti
, " (%s)", val_to_str(tlv_type
, thread_bcn_tlv_vals
, "Unknown (%d)"));
3298 proto_tree_add_item(tlv_tree
, hf_thread_bcn_tlv_length
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3301 if (tlv_len
) { /* Belt 'n' braces check */
3303 case THREAD_BCN_TLV_STEERING_DATA
:
3304 proto_tree_add_item(tlv_tree
, hf_thread_bcn_tlv_steering_data
, tvb
, offset
, tlv_len
, ENC_NA
);
3305 /* offset += tlv_len; */
3308 proto_tree_add_item(tlv_tree
, hf_thread_bcn_tlv_unknown
, tvb
, offset
, tlv_len
, ENC_NA
);
3309 /* offset += tlv_len; */
3313 return tvb_captured_length(tvb
);
3317 dissect_thread_bcn_heur(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data
)
3319 ieee802154_packet
*packet
= (ieee802154_packet
*)data
;
3321 /* Thread beacon frames can be 16 or 64-bit source */
3322 if (!packet
) return false;
3323 if (!((packet
->src_addr_mode
== IEEE802154_FCF_ADDR_SHORT
) ||
3324 (packet
->src_addr_mode
== IEEE802154_FCF_ADDR_EXT
))) return false;
3326 if (tvb_captured_length(tvb
) > 0) {
3327 /* Thread beacons begin with a protocol identifier. */
3328 if (tvb_get_uint8(tvb
, 0) != THREAD_BCN_PROTOCOL_ID
) return false;
3329 dissect_thread_bcn(tvb
, pinfo
, tree
, packet
);
3336 proto_register_thread_nm(void)
3338 static hf_register_info hf
[] = {
3341 { &hf_thread_nm_tlv
,
3344 FT_NONE
, BASE_NONE
, NULL
, 0x0,
3345 "Type-Length-Value",
3349 { &hf_thread_nm_tlv_type
,
3351 "thread_nm.tlv.type",
3352 FT_UINT8
, BASE_DEC
, VALS(thread_nm_tlv_vals
), 0x0,
3357 { &hf_thread_nm_tlv_length
,
3359 "thread_nm.tlv.len",
3360 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
3365 { &hf_thread_nm_tlv_unknown
,
3367 "thread_nm.tlv.unknown",
3368 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
3369 "Unknown TLV, raw value",
3373 { &hf_thread_nm_tlv_sub_tlvs
,
3375 "thread_nm.tlv.sub_tlvs",
3376 FT_NONE
, BASE_NONE
, NULL
, 0x0,
3382 /* Type-Specific TLV Fields */
3383 { &hf_thread_nm_tlv_target_eid
,
3385 "thread_nm.tlv.target_eid",
3386 FT_IPv6
, BASE_NONE
, NULL
, 0x0,
3391 { &hf_thread_nm_tlv_ext_mac_addr
,
3392 { "Extended MAC Address",
3393 "thread_nm.tlv.ext_mac_addr",
3394 FT_EUI64
, BASE_NONE
, NULL
, 0x0,
3399 { &hf_thread_nm_tlv_rloc16
,
3401 "thread_nm.tlv.rloc16",
3402 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
3407 { &hf_thread_nm_tlv_ml_eid
,
3409 "thread_nm.tlv.ml_eid",
3410 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
3415 { &hf_thread_nm_tlv_status
,
3417 "thread_nm.tlv.status",
3418 FT_UINT8
, BASE_DEC
, VALS(thread_nm_tlv_status_vals
), 0x0,
3423 { &hf_thread_nm_tlv_last_transaction_time
,
3424 { "Last Transaction Time",
3425 "thread_nm.tlv.last_transaction_time",
3426 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
3431 { &hf_thread_nm_tlv_router_mask_id_seq
,
3433 "thread_nm.tlv.router_mask_id_seq",
3434 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
3439 { &hf_thread_nm_tlv_router_mask_assigned
,
3440 { "Assigned Router ID Mask",
3441 "thread_nm.tlv.router_mask_assigned",
3442 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
3447 { &hf_thread_nm_tlv_nd_option
,
3449 "thread_nm.tlv.nd_option",
3450 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
3455 { &hf_thread_nm_tlv_nd_data
,
3457 "thread_nm.tlv.nd_data",
3458 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
3463 { &hf_thread_nm_tlv_timeout
,
3465 "thread_nm.tlv.timeout",
3466 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
3473 static int *ett
[] = {
3476 /* These need to be registered somewhere.. */
3478 &ett_thread_ie_fields
3481 static ei_register_info ei
[] = {
3483 { &ei_thread_nm_tlv_length_failed
,{ "thread_nm.tlv_length_failed", PI_UNDECODED
, PI_WARN
, "TLV Length inconsistent", EXPFILL
} },
3485 { &ei_thread_nm_len_size_mismatch
,{ "thread_nm.len_size_mismatch", PI_UNDECODED
, PI_WARN
, "TLV Length & Size field disagree", EXPFILL
} },
3488 expert_module_t
* expert_thread_nm
;
3490 proto_thread_nm
= proto_register_protocol("Thread Network Management", "Thread Network Management", "thread_nm");
3491 proto_register_field_array(proto_thread_nm
, hf
, array_length(hf
));
3492 proto_register_subtree_array(ett
, array_length(ett
));
3493 expert_thread_nm
= expert_register_protocol(proto_thread_nm
);
3494 expert_register_field_array(expert_thread_nm
, ei
, array_length(ei
));
3496 thread_nm_handle
= register_dissector("thread_nm", dissect_thread_nm
, proto_thread_nm
);
3500 proto_register_thread_bl(void)
3502 static hf_register_info hf
[] = {
3505 { &hf_thread_bl_tlv
,
3508 FT_NONE
, BASE_NONE
, NULL
, 0x0,
3509 "Type-Length-Value",
3514 { &hf_thread_bl_tlv_type
,
3516 "thread_bl.tlv.type",
3517 FT_UINT8
, BASE_DEC
, VALS(thread_bl_tlv_vals
), 0x0,
3523 { &hf_thread_bl_tlv_length
,
3525 "thread_bl.tlv.len",
3526 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
3532 { &hf_thread_bl_tlv_unknown
,
3534 "thread_bl.tlv.unknown",
3535 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
3536 "Unknown TLV, raw value",
3541 { &hf_thread_bl_tlv_sub_tlvs
,
3543 "thread_bl.tlv.sub_tlvs",
3544 FT_NONE
, BASE_NONE
, NULL
, 0x0,
3550 /* Type-Specific TLV Fields */
3551 { &hf_thread_bl_tlv_target_eid
,
3553 "thread_bl.tlv.target_eid",
3554 FT_IPv6
, BASE_NONE
, NULL
, 0x0,
3560 { &hf_thread_bl_tlv_ext_mac_addr
,
3561 { "Extended MAC Address",
3562 "thread_bl.tlv.ext_mac_addr",
3563 FT_EUI64
, BASE_NONE
, NULL
, 0x0,
3568 { &hf_thread_bl_tlv_rloc16
,
3570 "thread_bl.tlv.rloc16",
3571 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
3576 { &hf_thread_bl_tlv_ml_eid
,
3578 "thread_bl.tlv.ml_eid",
3579 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
3584 { &hf_thread_bl_tlv_status
,
3586 "thread_bl.tlv.status",
3587 FT_UINT8
, BASE_DEC
, VALS(thread_bl_tlv_status_vals
), 0x0,
3592 { &hf_thread_bl_tlv_attached_time
,
3594 "thread_bl.tlv.attached_time",
3595 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
3600 { &hf_thread_bl_tlv_last_transaction_time
,
3601 { "Last Transaction Time",
3602 "thread_bl.tlv.last_transaction_time",
3603 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
3608 { &hf_thread_bl_tlv_router_mask_id_seq
,
3610 "thread_bl.tlv.router_mask_id_seq",
3611 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
3616 { &hf_thread_bl_tlv_router_mask_assigned
,
3617 { "Assigned Router ID Mask",
3618 "thread_bl.tlv.router_mask_assigned",
3619 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
3624 { &hf_thread_bl_tlv_nd_option
,
3626 "thread_bl.tlv.nd_option",
3627 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
3632 { &hf_thread_bl_tlv_nd_data
,
3634 "thread_bl.tlv.nd_data",
3635 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
3639 { &hf_thread_bl_tlv_timeout
,
3641 "thread_bl.tlv.timeout",
3642 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
3651 static int *ett
[] = {
3656 static ei_register_info ei
[] = {
3658 { &ei_thread_bl_tlv_length_failed
,{ "thread_bl.tlv_length_failed", PI_UNDECODED
, PI_WARN
, "TLV Length inconsistent", EXPFILL
} },
3660 { &ei_thread_bl_len_size_mismatch
,{ "thread_bl.len_size_mismatch", PI_UNDECODED
, PI_WARN
, "TLV Length & Size field disagree", EXPFILL
} },
3663 expert_module_t
* expert_thread_bl
;
3665 proto_thread_bl
= proto_register_protocol("Thread Backbone Link", "Thread Backbone Link", "thread_bl");
3666 proto_register_field_array(proto_thread_bl
, hf
, array_length(hf
));
3667 proto_register_subtree_array(ett
, array_length(ett
));
3668 expert_thread_bl
= expert_register_protocol(proto_thread_bl
);
3669 expert_register_field_array(expert_thread_bl
, ei
, array_length(ei
));
3671 thread_bl_handle
= register_dissector("thread_bl", dissect_thread_bl
, proto_thread_bl
);
3675 proto_register_thread_address(void)
3677 static hf_register_info hf
[] = {
3680 { &hf_thread_address_tlv
,
3682 "thread_address.tlv",
3683 FT_NONE
, BASE_NONE
, NULL
, 0x0,
3684 "Type-Length-Value",
3688 { &hf_thread_address_tlv_type
,
3690 "thread_address.tlv.type",
3691 FT_UINT8
, BASE_DEC
, VALS(thread_address_tlv_vals
), 0x0,
3696 { &hf_thread_address_tlv_length
,
3698 "thread_address.tlv.len",
3699 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
3704 { &hf_thread_address_tlv_unknown
,
3706 "thread_address.tlv.unknown",
3707 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
3708 "Unknown TLV, raw value",
3712 { &hf_thread_address_tlv_sub_tlvs
,
3714 "thread_address.tlv.sub_tlvs",
3715 FT_NONE
, BASE_NONE
, NULL
, 0x0,
3720 /* Type-Specific TLV Fields */
3721 { &hf_thread_address_tlv_target_eid
,
3723 "thread_address.tlv.target_eid",
3724 FT_IPv6
, BASE_NONE
, NULL
, 0x0,
3729 { &hf_thread_address_tlv_ext_mac_addr
,
3730 { "Extended MAC Address",
3731 "thread_address.tlv.ext_mac_addr",
3732 FT_EUI64
, BASE_NONE
, NULL
, 0x0,
3737 { &hf_thread_address_tlv_rloc16
,
3739 "thread_address.tlv.rloc16",
3740 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
3745 { &hf_thread_address_tlv_ml_eid
,
3747 "thread_address.tlv.ml_eid",
3748 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
3753 { &hf_thread_address_tlv_status
,
3755 "thread_address.tlv.status",
3756 FT_UINT8
, BASE_DEC
, VALS(thread_address_tlv_status_vals
), 0x0,
3761 { &hf_thread_address_tlv_attached_time
,
3763 "thread_address.tlv.attached_time",
3764 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
3769 { &hf_thread_address_tlv_last_transaction_time
,
3770 { "Last Transaction Time",
3771 "thread_address.tlv.last_transaction_time",
3772 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
3777 { &hf_thread_address_tlv_router_mask_id_seq
,
3779 "thread_address.tlv.router_mask_id_seq",
3780 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
3785 { &hf_thread_address_tlv_router_mask_assigned
,
3786 { "Assigned Router ID Mask",
3787 "thread_address.tlv.router_mask_assigned",
3788 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
3793 { &hf_thread_address_tlv_nd_option
,
3795 "thread_address.tlv.nd_option",
3796 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
3801 { &hf_thread_address_tlv_nd_data
,
3803 "thread_address.tlv.nd_data",
3804 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
3809 { &hf_thread_address_tlv_timeout
,
3811 "thread_address.tlv.timeout",
3812 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
3818 static int *ett
[] = {
3819 &ett_thread_address
,
3820 &ett_thread_address_tlv
,
3823 static ei_register_info ei
[] = {
3825 { &ei_thread_address_tlv_length_failed
, { "thread_address.tlv_length_failed", PI_UNDECODED
, PI_WARN
, "TLV Length inconsistent", EXPFILL
}},
3827 { &ei_thread_address_len_size_mismatch
, { "thread_address.len_size_mismatch", PI_UNDECODED
, PI_WARN
, "TLV Length & Size field disagree", EXPFILL
}},
3830 expert_module_t
* expert_thread_address
;
3832 proto_thread_address
= proto_register_protocol("Thread Address", "Thread Address", "thread_address");
3833 proto_register_field_array(proto_thread_address
, hf
, array_length(hf
));
3834 proto_register_subtree_array(ett
, array_length(ett
));
3835 expert_thread_address
= expert_register_protocol(proto_thread_address
);
3836 expert_register_field_array(expert_thread_address
, ei
, array_length(ei
));
3838 thread_address_handle
= register_dissector("thread_address", dissect_thread_address
, proto_thread_address
);
3842 proto_register_thread_dg(void)
3844 static hf_register_info hf
[] = {
3847 { &hf_thread_dg_tlv
,
3849 "thread_diagnostic.tlv",
3850 FT_NONE
, BASE_NONE
, NULL
, 0x0,
3851 "Type-Length-Value",
3855 { &hf_thread_dg_tlv_type
,
3857 "thread_diagnostic.tlv.type",
3858 FT_UINT8
, BASE_DEC
, VALS(thread_dg_tlv_vals
), 0x0,
3863 { &hf_thread_dg_tlv_length8
,
3865 "thread_diagnostic.tlv.len8",
3866 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
3867 "Length of value (8-bit)",
3871 { &hf_thread_dg_tlv_length16
,
3873 "thread_diagnostic.tlv.len16",
3874 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
3875 "Length of value (16-bit)",
3879 { &hf_thread_dg_tlv_general
,
3881 "thread_diagnostic.tlv.general",
3882 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
3883 "General TLV, raw value",
3887 { &hf_thread_dg_tlv_unknown
,
3889 "thread_diagnostic.tlv.unknown",
3890 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
3891 "Unknown TLV, raw value",
3896 static int *ett
[] = {
3902 static ei_register_info ei
[] = {
3903 { &ei_thread_dg_tlv_length_failed
, { "thread_diagnostic.tlv_length_failed", PI_UNDECODED
, PI_WARN
, "TLV Length inconsistent", EXPFILL
}},
3904 { &ei_thread_dg_len_size_mismatch
, { "thread_diagnostic.len_size_mismatch", PI_UNDECODED
, PI_WARN
, "TLV Length & Size field disagree", EXPFILL
}},
3907 expert_module_t
* expert_thread_dg
;
3910 proto_thread_dg
= proto_register_protocol("Thread Diagnostics", "Thread Diagnostics", "thread_diagnostic");
3911 proto_register_field_array(proto_thread_dg
, hf
, array_length(hf
));
3912 proto_register_subtree_array(ett
, array_length(ett
));
3914 expert_thread_dg
= expert_register_protocol(proto_thread_dg
);
3915 expert_register_field_array(expert_thread_dg
, ei
, array_length(ei
));
3918 thread_dg_handle
= register_dissector("thread_diagnostic", dissect_thread_dg
, proto_thread_dg
);
3922 proto_register_thread_mc(void)
3924 static hf_register_info hf
[] = {
3927 { &hf_thread_mc_tlv
,
3929 "thread_meshcop.tlv",
3930 FT_NONE
, BASE_NONE
, NULL
, 0x0,
3931 "Type-Length-Value",
3935 { &hf_thread_mc_tlv_type
,
3937 "thread_meshcop.tlv.type",
3938 FT_UINT8
, BASE_DEC
, VALS(thread_mc_tlv_vals
), 0x0,
3943 { &hf_thread_mc_tlv_length8
,
3945 "thread_meshcop.tlv.len8",
3946 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
3947 "Length of value (8-bit)",
3951 { &hf_thread_mc_tlv_length16
,
3953 "thread_meshcop.tlv.len16",
3954 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
3955 "Length of value (16-bit)",
3959 { &hf_thread_mc_tlv_unknown
,
3961 "thread_meshcop.tlv.unknown",
3962 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
3963 "Unknown TLV, raw value",
3967 { &hf_thread_mc_tlv_sub_tlvs
,
3969 "thread_meshcop.tlv.sub_tlvs",
3970 FT_NONE
, BASE_NONE
, NULL
, 0x0,
3975 /* Type-Specific TLV Fields */
3976 { &hf_thread_mc_tlv_channel_page
,
3978 "thread_meshcop.tlv.channel_page",
3979 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
3984 { &hf_thread_mc_tlv_channel
,
3986 "thread_meshcop.tlv.channel",
3987 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
3992 { &hf_thread_mc_tlv_pan_id
,
3994 "thread_meshcop.tlv.pan_id",
3995 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
4000 { &hf_thread_mc_tlv_xpan_id
,
4001 { "Extended PAN ID",
4002 "thread_meshcop.tlv.xpan_id",
4003 FT_UINT64
, BASE_HEX
, NULL
, 0x0,
4008 { &hf_thread_mc_tlv_net_name
,
4010 "thread_meshcop.tlv.net_name",
4011 FT_STRING
, BASE_NONE
, NULL
, 0x0,
4016 { &hf_thread_mc_tlv_pskc
,
4018 "thread_meshcop.tlv.pskc",
4019 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
4024 { &hf_thread_mc_tlv_master_key
,
4026 "thread_meshcop.tlv.master_key",
4027 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
4032 { &hf_thread_mc_tlv_net_key_seq_ctr
,
4033 { "Network Key Sequence Counter",
4034 "thread_meshcop.tlv.net_key_seq_ctr",
4035 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
4040 { &hf_thread_mc_tlv_ml_prefix
,
4041 { "Mesh Local Prefix",
4042 "thread_meshcop.tlv.ml_prefix",
4043 FT_IPv6
, BASE_NONE
, NULL
, 0x0,
4048 { &hf_thread_mc_tlv_steering_data
,
4050 "thread_meshcop.tlv.steering_data",
4051 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
4056 { &hf_thread_mc_tlv_ba_locator
,
4057 { "Border Agent Locator",
4058 "thread_meshcop.tlv.ba_locator",
4059 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
4064 { &hf_thread_mc_tlv_commissioner_id
,
4065 { "Commissioner ID",
4066 "thread_meshcop.tlv.commissioner_id",
4067 FT_STRING
, BASE_NONE
, NULL
, 0x0,
4072 { &hf_thread_mc_tlv_commissioner_sess_id
,
4073 { "Commissioner Session ID",
4074 "thread_meshcop.tlv.commissioner_sess_id",
4075 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
4080 { &hf_thread_mc_tlv_sec_policy_rot
,
4082 "thread_meshcop.tlv.sec_policy_rot",
4083 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
4088 { &hf_thread_mc_tlv_sec_policy_o
,
4089 { "Out-of-band Commissioning",
4090 "thread_meshcop.tlv.sec_policy_o",
4091 FT_BOOLEAN
, 8, TFS(&tfs_allowed_not_allowed
), THREAD_MC_SEC_POLICY_MASK_O_MASK
,
4096 { &hf_thread_mc_tlv_sec_policy_n
,
4097 { "Native Commissioning",
4098 "thread_meshcop.tlv.sec_policy_n",
4099 FT_BOOLEAN
, 8, TFS(&tfs_allowed_not_allowed
), THREAD_MC_SEC_POLICY_MASK_N_MASK
,
4104 { &hf_thread_mc_tlv_sec_policy_r
,
4105 { "Thread 1.x Routers",
4106 "thread_meshcop.tlv.sec_policy_r",
4107 FT_BOOLEAN
, 8, TFS(&tfs_enabled_disabled
), THREAD_MC_SEC_POLICY_MASK_R_MASK
,
4112 { &hf_thread_mc_tlv_sec_policy_c
,
4113 { "PSKc-based Commissioning",
4114 "thread_meshcop.tlv.sec_policy_c",
4115 FT_BOOLEAN
, 8, TFS(&tfs_allowed_not_allowed
), THREAD_MC_SEC_POLICY_MASK_C_MASK
,
4120 { &hf_thread_mc_tlv_sec_policy_b
,
4121 { "Thread 1.x Beacons",
4122 "thread_meshcop.tlv.sec_policy_b",
4123 FT_BOOLEAN
, 8, TFS(&tfs_allowed_not_allowed
), THREAD_MC_SEC_POLICY_MASK_B_MASK
,
4128 { &hf_thread_mc_tlv_sec_policy_ccm
,
4129 { "Commercial Commissioning Mode Bit disabled",
4130 "thread_meshcop.tlv.sec_policy_ccm",
4131 FT_BOOLEAN
, 8, TFS(&tfs_enabled_disabled
), THREAD_MC_SEC_POLICY_MASK_CCM_MASK
,
4136 { &hf_thread_mc_tlv_sec_policy_ae
,
4137 { "Autonomous Enrollment disabled",
4138 "thread_meshcop.tlv.sec_policy_ae",
4139 FT_BOOLEAN
, 8, TFS(&tfs_enabled_disabled
), THREAD_MC_SEC_POLICY_MASK_AE_MASK
,
4144 { &hf_thread_mc_tlv_sec_policy_nmp
,
4145 { "Network Master-key Provisioning disabled",
4146 "thread_meshcop.tlv.sec_policy_nmp",
4147 FT_BOOLEAN
, 8, TFS(&tfs_enabled_disabled
), THREAD_MC_SEC_POLICY_MASK_NMP_MASK
,
4152 { &hf_thread_mc_tlv_sec_policy_l
,
4153 { "ToBLE Link Enabled",
4154 "thread_meshcop.tlv.sec_policy_l",
4155 FT_BOOLEAN
, 8, TFS(&tfs_enabled_disabled
), THREAD_MC_SEC_POLICY_MASK_L_MASK
,
4160 { &hf_thread_mc_tlv_sec_policy_ncr
,
4161 { "Non-CCM Routers disabled",
4162 "thread_meshcop.tlv.sec_policy_ncr",
4163 FT_BOOLEAN
, 8, TFS(&tfs_enabled_disabled
), THREAD_MC_SEC_POLICY_MASK_NCR_MASK
,
4168 { &hf_thread_mc_tlv_sec_policy_rsv
,
4170 "thread_meshcop.tlv.sec_policy_rsv",
4171 FT_UINT8
, BASE_DEC
, NULL
, THREAD_MC_SEC_POLICY_MASK_RSV_MASK
,
4176 { &hf_thread_mc_tlv_sec_policy_rsv1
,
4178 "thread_meshcop.tlv.sec_policy_rsv",
4179 FT_UINT8
, BASE_DEC
, NULL
, THREAD_MC_SEC_POLICY_MASK_RSV1_MASK
,
4184 { &hf_thread_mc_tlv_sec_policy_vr
,
4185 { "Version-threshold for Routing",
4186 "thread_meshcop.tlv.sec_policy_vr",
4187 FT_UINT8
, BASE_DEC
, NULL
, THREAD_MC_SEC_POLICY_MASK_VR_MASK
,
4192 { &hf_thread_mc_tlv_state
,
4194 "thread_meshcop.tlv.state",
4195 FT_INT8
, BASE_DEC
, VALS(thread_mc_state_vals
), 0x0,
4200 { &hf_thread_mc_tlv_active_tstamp
,
4201 { "Active Timestamp",
4202 "thread_meshcop.tlv.active_tstamp",
4203 FT_ABSOLUTE_TIME
, ABSOLUTE_TIME_LOCAL
, NULL
, 0x0,
4208 { &hf_thread_mc_tlv_pending_tstamp
,
4209 { "Pending Timestamp",
4210 "thread_meshcop.tlv.pending_tstamp",
4211 FT_ABSOLUTE_TIME
, ABSOLUTE_TIME_LOCAL
, NULL
, 0x0,
4216 { &hf_thread_mc_tlv_udp_port
,
4218 "thread_meshcop.tlv.udp_port",
4219 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
4224 { &hf_thread_mc_tlv_iid
,
4225 { "Interface Identifier",
4226 "thread_meshcop.tlv.iid",
4227 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
4232 { &hf_thread_mc_tlv_jr_locator
,
4233 { "Joiner Router Locator",
4234 "thread_meshcop.tlv.jr_locator",
4235 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
4240 { &hf_thread_mc_tlv_kek
,
4241 { "Key Encryption Key (KEK)",
4242 "thread_meshcop.tlv.kek",
4243 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
4248 { &hf_thread_mc_tlv_provisioning_url
,
4249 { "Provisioning URL",
4250 "thread_meshcop.tlv.provisioning_url",
4251 FT_STRING
, BASE_NONE
, NULL
, 0x0,
4256 { &hf_thread_mc_tlv_vendor_name
,
4258 "thread_meshcop.tlv.vendor_name",
4259 FT_STRING
, BASE_NONE
, NULL
, 0x0,
4264 { &hf_thread_mc_tlv_vendor_model
,
4266 "thread_meshcop.tlv.vendor_model",
4267 FT_STRING
, BASE_NONE
, NULL
, 0x0,
4272 { &hf_thread_mc_tlv_vendor_sw_ver
,
4273 { "Vendor Software Version",
4274 "thread_meshcop.tlv.vendor_sw_ver",
4275 FT_STRING
, BASE_NONE
, NULL
, 0x0,
4280 { &hf_thread_mc_tlv_vendor_data
,
4282 "thread_meshcop.tlv.vendor_data",
4283 FT_STRING
, BASE_NONE
, NULL
, 0x0,
4288 { &hf_thread_mc_tlv_vendor_stack_ver_oui
,
4290 "thread_meshcop.tlv.vendor_stack_ver_oui",
4291 FT_UINT24
, BASE_OUI
, NULL
, 0x0,
4296 { &hf_thread_mc_tlv_vendor_stack_ver_build
,
4298 "thread_meshcop.tlv.vendor_stack_ver_build",
4299 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
4304 { &hf_thread_mc_tlv_vendor_stack_ver_rev
,
4306 "thread_meshcop.tlv.vendor_stack_ver_rev",
4307 FT_UINT8
, BASE_DEC
, NULL
, THREAD_MC_STACK_VER_REV_MASK
,
4312 { &hf_thread_mc_tlv_vendor_stack_ver_min
,
4314 "thread_meshcop.tlv.vendor_stack_ver_min",
4315 FT_UINT8
, BASE_DEC
, NULL
, THREAD_MC_STACK_VER_MIN_MASK
,
4320 { &hf_thread_mc_tlv_vendor_stack_ver_maj
,
4322 "thread_meshcop.tlv.vendor_stack_ver_maj",
4323 FT_UINT8
, BASE_DEC
, NULL
, THREAD_MC_STACK_VER_MAJ_MASK
,
4328 { &hf_thread_mc_tlv_udp_encap_src_port
,
4329 { "Source UDP Port",
4330 "thread_meshcop.tlv.udp_encap_src_port",
4331 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
4336 { &hf_thread_mc_tlv_udp_encap_dst_port
,
4337 { "Destination UDP Port",
4338 "thread_meshcop.tlv.udp_encap_dst_port",
4339 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
4344 { &hf_thread_mc_tlv_ipv6_addr
,
4346 "thread_meshcop.tlv.ipv6_addr",
4347 FT_IPv6
, BASE_NONE
, NULL
, 0x0,
4352 { &hf_thread_mc_tlv_delay_timer
,
4354 "thread_meshcop.tlv.delay_timer",
4355 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
4360 { &hf_thread_mc_tlv_chan_mask
,
4362 "thread_meshcop.tlv.chan_mask",
4363 FT_NONE
, BASE_NONE
, NULL
, 0x0,
4368 { &hf_thread_mc_tlv_chan_mask_page
,
4370 "thread_meshcop.tlv.chan_mask_page",
4371 FT_UINT8
, BASE_DEC
, NULL
, 0,
4376 { &hf_thread_mc_tlv_chan_mask_len
,
4378 "thread_meshcop.tlv.chan_mask_len",
4379 FT_UINT8
, BASE_DEC
, NULL
, 0,
4384 { &hf_thread_mc_tlv_chan_mask_mask
,
4386 "thread_meshcop.tlv.chan_mask_mask",
4387 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
4392 { &hf_thread_mc_tlv_el_count
,
4394 "thread_meshcop.tlv.el_count",
4395 FT_NONE
, BASE_NONE
, NULL
, 0x0,
4400 { &hf_thread_mc_tlv_count
,
4402 "thread_meshcop.tlv.count",
4403 FT_UINT8
, BASE_DEC
, NULL
, 0,
4408 { &hf_thread_mc_tlv_period
,
4410 "thread_meshcop.tlv.period",
4411 FT_UINT16
, BASE_DEC
, NULL
, 0,
4416 { &hf_thread_mc_tlv_scan_duration
,
4418 "thread_meshcop.tlv.scan_duration",
4419 FT_UINT16
, BASE_DEC
, NULL
, 0,
4424 { &hf_thread_mc_tlv_energy_list
,
4426 "thread_meshcop.tlv.energy_list",
4427 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
4432 { &hf_thread_mc_tlv_domain_name
,
4434 "thread_meshcop.tlv.domain_name",
4435 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
4440 { &hf_thread_mc_tlv_ae_steering_data
,
4441 { "AE Steering Data",
4442 "thread_meshcop.tlv.ae_steering_data",
4443 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
4448 { &hf_thread_mc_tlv_nmkp_steering_data
,
4449 { "NMKP Steering Data",
4450 "thread_meshcop.tlv.nmkp_steering_data",
4451 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
4456 { &hf_thread_mc_tlv_commissioner_signature
,
4457 { "Commissioner Signature",
4458 "thread_meshcop.tlv.nmkp_commissioner_signature",
4459 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
4465 { &hf_thread_mc_tlv_ae_udp_port
,
4467 "thread_meshcop.tlv.ae_udp_port",
4468 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
4473 { &hf_thread_mc_tlv_nmkp_udp_port
,
4475 "thread_meshcop.tlv.nmkp_udp_port",
4476 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
4481 { &hf_thread_mc_tlv_registrar_ipv6_addr
,
4482 { "Registrar IPv6 Address",
4483 "thread_meshcop.tlv.registrar_ipv6_addr",
4484 FT_IPv6
, BASE_NONE
, NULL
, 0x0,
4489 { &hf_thread_mc_tlv_registrar_hostname
,
4490 { "Registrar IPv6 Hostname",
4491 "thread_meshcop.tlv.registrar_hostname",
4492 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
4497 { &hf_thread_mc_tlv_discovery_req_ver
,
4499 "thread_meshcop.tlv.discovery_req_ver",
4500 FT_UINT8
, BASE_DEC
, NULL
, THREAD_MC_DISCOVERY_REQ_MASK_VER_MASK
,
4505 { &hf_thread_mc_tlv_discovery_req_j
,
4507 "thread_meshcop.tlv.discovery_req_j",
4508 FT_BOOLEAN
, 8, TFS(&thread_mc_tlv_join_intent
), THREAD_MC_DISCOVERY_REQ_MASK_J_MASK
,
4513 { &hf_thread_mc_tlv_discovery_rsp_ver
,
4515 "thread_meshcop.tlv.discovery_rsp_ver",
4516 FT_UINT8
, BASE_DEC
, NULL
, THREAD_MC_DISCOVERY_RSP_MASK_VER_MASK
,
4521 { &hf_thread_mc_tlv_discovery_rsp_n
,
4522 { "Native Commissioning",
4523 "thread_meshcop.tlv.discovery_rsp_n",
4524 FT_BOOLEAN
, 8, TFS(&tfs_allowed_not_allowed
), THREAD_MC_DISCOVERY_RSP_MASK_N_MASK
,
4529 { &hf_thread_mc_tlv_discovery_rsp_c
,
4530 { "Commercial Commissioning",
4531 "thread_meshcop.tlv.discovery_rsp_c",
4532 FT_BOOLEAN
, 8, TFS(&tfs_supported_not_supported
), THREAD_MC_DISCOVERY_RSP_MASK_C_MASK
,
4538 static int *ett
[] = {
4541 &ett_thread_mc_chan_mask
,
4542 &ett_thread_mc_el_count
4545 static ei_register_info ei
[] = {
4546 { &ei_thread_mc_tlv_length_failed
, { "thread_meshcop.tlv_length_failed", PI_UNDECODED
, PI_WARN
, "TLV Length inconsistent", EXPFILL
}},
4547 { &ei_thread_mc_len_size_mismatch
, { "thread_meshcop.len_size_mismatch", PI_UNDECODED
, PI_WARN
, "TLV Length & Size field disagree", EXPFILL
}},
4548 { &ei_thread_mc_len_too_long
, { "thread_meshcop.len_too_long", PI_UNDECODED
, PI_WARN
, "TLV Length too long", EXPFILL
}}
4551 expert_module_t
* expert_thread_mc
;
4553 proto_thread_mc
= proto_register_protocol("Thread MeshCoP", "Thread MeshCoP", "thread_meshcop");
4554 proto_register_field_array(proto_thread_mc
, hf
, array_length(hf
));
4555 proto_register_subtree_array(ett
, array_length(ett
));
4556 expert_thread_mc
= expert_register_protocol(proto_thread_mc
);
4557 expert_register_field_array(expert_thread_mc
, ei
, array_length(ei
));
4559 thread_mc_handle
= register_dissector("thread_meshcop", dissect_thread_mc
, proto_thread_mc
);
4563 proto_register_thread_nwd(void)
4565 static hf_register_info hf
[] = {
4568 { &hf_thread_nwd_tlv
,
4571 FT_NONE
, BASE_NONE
, NULL
, 0x0,
4572 "Type-Length-Value",
4576 { &hf_thread_nwd_tlv_type
,
4578 "thread_nwd.tlv.type",
4579 FT_UINT8
, BASE_DEC
, VALS(thread_nwd_tlv_vals
), THREAD_NWD_TLV_TYPE_M
,
4584 { &hf_thread_nwd_tlv_stable
,
4586 "thread_nwd.tlv.stable",
4587 FT_BOOLEAN
, 8, NULL
, THREAD_NWD_TLV_STABLE_M
,
4588 "Stability or transience of network data",
4592 { &hf_thread_nwd_tlv_length
,
4594 "thread_nwd.tlv.len",
4595 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
4600 { &hf_thread_nwd_tlv_unknown
,
4602 "thread_nwd.tlv.unknown",
4603 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
4604 "Unknown TLV, raw value",
4608 { &hf_thread_nwd_tlv_sub_tlvs
,
4610 "thread_nwd.tlv.sub_tlvs",
4611 FT_NONE
, BASE_NONE
, NULL
, 0x0,
4616 /* Type-Specific TLV Fields */
4617 { &hf_thread_nwd_tlv_has_route
,
4619 "thread_nwd.tlv.has_route",
4620 FT_NONE
, BASE_NONE
, NULL
, 0x0,
4625 { &hf_thread_nwd_tlv_has_route_br_16
,
4626 { "Border Router 16",
4627 "thread_nwd.tlv.has_route.br_16",
4628 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
4629 "Has Route Border Router 16-bit address",
4633 { &hf_thread_nwd_tlv_has_route_pref
,
4635 "thread_nwd.tlv.has_route.pref",
4636 FT_UINT8
, BASE_DEC
, NULL
, THREAD_NWD_TLV_HAS_ROUTE_PREF
,
4637 "Has Route preference",
4641 { &hf_thread_nwd_tlv_has_route_np
,
4643 "thread_nwd.tlv.has_route.np",
4644 FT_UINT8
, BASE_DEC
, NULL
, THREAD_NWD_TLV_HAS_ROUTE_NP
,
4649 { &hf_thread_nwd_tlv_has_route_reserved
,
4651 "thread_nwd.tlv.has_route.reserved",
4652 FT_UINT8
, BASE_DEC
, NULL
, THREAD_NWD_TLV_HAS_ROUTE_RESERVED
,
4653 "Has Route Reserved",
4657 { &hf_thread_nwd_tlv_prefix_domain_id
,
4659 "thread_nwd.tlv.prefix.domain_id",
4660 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
4665 { &hf_thread_nwd_tlv_prefix_length
,
4667 "thread_nwd.tlv.prefix.length",
4668 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
4673 { &hf_thread_nwd_tlv_prefix
,
4675 "thread_nwd.tlv.prefix",
4676 FT_IPv6
, BASE_NONE
, NULL
, 0x0,
4681 { &hf_thread_nwd_tlv_border_router
,
4683 "thread_nwd.tlv.border_router",
4684 FT_NONE
, BASE_NONE
, NULL
, 0x0,
4689 { &hf_thread_nwd_tlv_border_router_16
,
4690 { "Border Router 16",
4691 "thread_nwd.tlv.border_router.16",
4692 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
4693 "Border Router 16-bit address",
4697 { &hf_thread_nwd_tlv_border_router_pref
,
4699 "thread_nwd.tlv.border_router.pref",
4700 FT_UINT8
, BASE_DEC
, NULL
, THREAD_NWD_TLV_BORDER_ROUTER_PREF
,
4701 "Value of P_preference",
4705 { &hf_thread_nwd_tlv_border_router_p
,
4707 "thread_nwd.tlv.border_router.flag.p",
4708 FT_BOOLEAN
, 8, TFS(&tfs_thread_nwd_tlv_border_router_p
), THREAD_NWD_TLV_BORDER_ROUTER_P
,
4709 "Value of P_preferred",
4713 { &hf_thread_nwd_tlv_border_router_s
,
4715 "thread_nwd.tlv.border_router.flag.s",
4716 FT_BOOLEAN
, 8, TFS(&tfs_allowed_not_allowed
), THREAD_NWD_TLV_BORDER_ROUTER_S
,
4721 { &hf_thread_nwd_tlv_border_router_d
,
4723 "thread_nwd.tlv.border_router.flag.d",
4724 FT_BOOLEAN
, 8, TFS(&tfs_allowed_not_allowed
), THREAD_NWD_TLV_BORDER_ROUTER_D
,
4729 { &hf_thread_nwd_tlv_border_router_c
,
4731 "thread_nwd.tlv.border_router.flag.c",
4732 FT_BOOLEAN
, 8, TFS(&tfs_thread_nwd_tlv_border_router_c
), THREAD_NWD_TLV_BORDER_ROUTER_C
,
4733 "Value of P_configure",
4737 { &hf_thread_nwd_tlv_border_router_r
,
4739 "thread_nwd.tlv.border_router.flag.r",
4740 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), THREAD_NWD_TLV_BORDER_ROUTER_R
,
4741 "Value of P_default",
4745 { &hf_thread_nwd_tlv_border_router_o
,
4747 "thread_nwd.tlv.border_router.flag.o",
4748 FT_BOOLEAN
, 8, TFS(&tfs_thread_nwd_tlv_border_router_o
), THREAD_NWD_TLV_BORDER_ROUTER_O
,
4749 "Value of P_on_mesh",
4753 { &hf_thread_nwd_tlv_border_router_n
,
4755 "thread_nwd.tlv.border_router.flag.n",
4756 FT_BOOLEAN
, 8, TFS(&tfs_available_not_available
), THREAD_NWD_TLV_BORDER_ROUTER_N
,
4757 "Value of P_nd_dns",
4761 { &hf_thread_nwd_tlv_border_router_dp
,
4763 "thread_nwd.tlv.border_router.flag.dp",
4764 FT_BOOLEAN
, 8, TFS(&tfs_available_not_available
), THREAD_NWD_TLV_BORDER_ROUTER_DP
,
4769 { &hf_thread_nwd_tlv_6lowpan_id_6co_flag
,
4771 "thread_nwd.tlv.6co.flag",
4772 FT_UINT8
, BASE_HEX
, NULL
, 0x00,
4777 { &hf_thread_nwd_tlv_6lowpan_id_6co_flag_c
,
4778 { "Compression Flag",
4779 "thread_nwd.tlv.6co.flag.c",
4780 FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), ND_OPT_6CO_FLAG_C
,
4781 "This flag indicates if the context is valid for use in compression",
4785 { &hf_thread_nwd_tlv_6lowpan_id_6co_flag_cid
,
4787 "thread_nwd.tlv.6co.flag.cid",
4788 FT_UINT8
, BASE_DEC
, NULL
, ND_OPT_6CO_FLAG_CID
,
4789 "Context Identifier for this prefix information",
4793 { &hf_thread_nwd_tlv_6lowpan_id_6co_flag_reserved
,
4795 "thread_nwd.tlv.6co.flag.reserved",
4796 FT_UINT8
, BASE_DEC
, NULL
, ND_OPT_6CO_FLAG_RESERVED
,
4801 { &hf_thread_nwd_tlv_6lowpan_id_6co_context_length
,
4803 "thread_nwd.tlv.6co.context_length",
4804 FT_UINT8
, BASE_DEC
, NULL
, 0x00,
4805 "The number of leading bits in the Context Prefix field that are valid",
4809 { &hf_thread_nwd_tlv_comm_data
,
4810 { "Commissioning Data",
4811 "thread_nwd.tlv.comm_data",
4812 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
4813 "Contains Thread Commissioning data",
4817 { &hf_thread_nwd_tlv_service_t
,
4819 "thread_nwd.tlv.service.t",
4820 FT_UINT8
, BASE_HEX
, NULL
, THREAD_NWD_TLV_SERVICE_T
,
4825 { &hf_thread_nwd_tlv_service_s_id
,
4826 { "Service Type ID",
4827 "thread_nwd.tlv.service.s_id",
4828 FT_UINT8
, BASE_HEX
, NULL
, THREAD_NWD_TLV_SERVICE_S_ID
,
4833 { &hf_thread_nwd_tlv_service_s_ent_num
,
4834 { "Enterprise Number",
4835 "thread_nwd.tlv.service.s_ent_num",
4836 FT_UINT32
, BASE_DEC
, NULL
, 0,
4841 { &hf_thread_nwd_tlv_service_s_data_len
,
4842 { "Service Data Length",
4843 "thread_nwd.tlv.service.s_data_len",
4844 FT_UINT8
, BASE_DEC
, NULL
, 0,
4849 { &hf_thread_nwd_tlv_service_s_data
,
4851 "thread_nwd.tlv.service.s_data",
4852 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
4853 "Service data in raw bytes",
4857 { &hf_thread_nwd_tlv_service_s_data_seqno
,
4858 { "Service Data - BBR Sequence Number",
4859 "thread_nwd.tlv.service.s_data.seqno",
4860 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
4861 "Service data in raw bytes",
4865 { &hf_thread_nwd_tlv_service_s_data_rrdelay
,
4866 { "Service Data - Reregistration Delay(s)",
4867 "thread_nwd.tlv.service.s_data.rrdelay",
4868 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
4869 "Service data in raw bytes",
4873 { &hf_thread_nwd_tlv_service_s_data_mlrtimeout
,
4874 { "Service Data - MLR Timeout(s)",
4875 "thread_nwd.tlv.service.s_data.mlrtimeout",
4876 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
4877 "Service data in raw bytes",
4881 { &hf_thread_nwd_tlv_server_16
,
4883 "thread_nwd.tlv.server.16",
4884 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
4885 "Server 16-bit address",
4889 { &hf_thread_nwd_tlv_server_data
,
4891 "thread_nwd.tlv.server.data",
4892 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
4893 "Server data in raw bytes",
4897 // Thread 1.3 Service TLV code
4899 { &hf_thread_nwd_tlv_service_srp_dataset_identifier
,
4900 { "Service Data SRP Dataset Identifier",
4901 "thread_nwd.tlv.service.srp_dataset_identifier",
4902 FT_UINT8
, BASE_HEX
, NULL
, 0x0,
4907 { &hf_thread_nwd_tlv_service_anycast_seqno
,
4908 { "Service Data Anycast Sequence Number",
4909 "thread_nwd.tlv.service.anycast_seqno",
4910 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
4911 "Sequence Number of Anycast Dataset",
4915 { &hf_thread_nwd_tlv_service_unicast_ipv6_address
,
4916 { "Service Data Unicast Server IPV6 Address",
4917 "thread_nwd.tlv.service.unicast_server_ipv6_address",
4918 FT_IPv6
, BASE_NONE
, NULL
, 0x0,
4919 "IPV6 Address of Unicast SRP Server",
4923 { &hf_thread_nwd_tlv_service_unicast_port_number
,
4924 { "Service Data Unicast Port Number",
4925 "thread_nwd.tlv.service.unicast_port_no",
4926 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
4927 "Port Number of Unicast SRP Server",
4933 static int *ett
[] = {
4935 &ett_thread_nwd_tlv
,
4936 &ett_thread_nwd_has_route
,
4937 &ett_thread_nwd_6co_flag
,
4938 &ett_thread_nwd_border_router
,
4939 &ett_thread_nwd_prefix_sub_tlvs
4942 static ei_register_info ei
[] = {
4944 { &ei_thread_nwd_tlv_length_failed
, { "thread_nwd.tlv_length_failed", PI_UNDECODED
, PI_WARN
, "TLV Length inconsistent", EXPFILL
}},
4946 { &ei_thread_nwd_len_size_mismatch
, { "thread_nwd.len_size_mismatch", PI_UNDECODED
, PI_WARN
, "TLV Length & Size field disagree", EXPFILL
}},
4949 expert_module_t
* expert_thread_nwd
;
4951 proto_thread_nwd
= proto_register_protocol("Thread Network Data", "Thread NWD", "thread_nwd");
4952 proto_register_field_array(proto_thread_nwd
, hf
, array_length(hf
));
4953 proto_register_subtree_array(ett
, array_length(ett
));
4954 expert_thread_nwd
= expert_register_protocol(proto_thread_nwd
);
4955 expert_register_field_array(expert_thread_nwd
, ei
, array_length(ei
));
4957 thread_address_nwd_handle
= register_dissector("thread_nwd", dissect_thread_nwd
, proto_thread_nwd
);
4960 void proto_register_thread_bcn(void)
4962 static hf_register_info hf
[] = {
4964 { &hf_thread_bcn_protocol
,
4965 { "Protocol ID", "thread_bcn.protocol", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
4968 { &hf_thread_bcn_joining
,
4969 { "Joining", "thread_bcn.joining", FT_BOOLEAN
, 8, NULL
, THREAD_BCN_JOINING
,
4972 { &hf_thread_bcn_native
,
4973 { "Native", "thread_bcn.native", FT_BOOLEAN
, 8, NULL
, THREAD_BCN_NATIVE
,
4976 { &hf_thread_bcn_version
,
4977 { "Version", "thread_bcn.version", FT_UINT8
, BASE_DEC
, NULL
, THREAD_BCN_PROTOCOL_VERSION
,
4980 { &hf_thread_bcn_network_id
,
4981 { "Network Name", "thread_bcn.network_name", FT_STRING
, BASE_NONE
, NULL
, 0x0,
4982 "A string that uniquely identifies this network.", HFILL
}},
4984 { &hf_thread_bcn_epid
,
4985 { "Extended PAN ID", "thread_bcn.epid", FT_EUI64
, BASE_NONE
, NULL
, 0x0,
4988 { &hf_thread_bcn_tlv
,
4989 { "TLV", "thread_bcn.tlv", FT_NONE
, BASE_NONE
, NULL
, 0x0,
4990 "Type-Length-Value", HFILL
}},
4992 { &hf_thread_bcn_tlv_type
,
4993 { "Type", "thread_bcn.tlv.type", FT_UINT8
, BASE_DEC
, VALS(thread_bcn_tlv_vals
), 0x0,
4994 "Type of Value", HFILL
}},
4996 { &hf_thread_bcn_tlv_length
,
4997 { "Length", "thread_bcn.tlv.len", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
4998 "Length of Value", HFILL
}},
5000 { &hf_thread_bcn_tlv_steering_data
,
5001 { "Steering Data", "thread_bcn.tlv.steering_data", FT_BYTES
, BASE_NONE
, NULL
, 0x0,
5002 "Steering data for joining devices", HFILL
}},
5004 { &hf_thread_bcn_tlv_unknown
,
5005 { "Unknown", "thread_bcn.tlv.unknown", FT_BYTES
, BASE_NONE
, NULL
, 0x0,
5006 "Unknown TLV, raw value", HFILL
}}
5009 /* NWK Layer subtrees */
5010 static int *ett
[] = {
5015 /* Register the protocol with Wireshark. */
5016 proto_thread_bcn
= proto_register_protocol("Thread Beacon", "Thread Beacon", "thread_bcn");
5017 proto_register_field_array(proto_thread_bcn
, hf
, array_length(hf
));
5018 proto_register_subtree_array(ett
, array_length(ett
));
5020 /* Register the dissectors with Wireshark. */
5021 register_dissector("thread_bcn", dissect_thread_bcn
, proto_thread_bcn
);
5025 proto_init_thread(void)
5027 /* Reset the sequence counter variables */
5028 thread_seq_ctr_acqd
= false;
5029 memset(thread_seq_ctr_bytes
, 0, 4);
5033 proto_register_thread(void)
5035 module_t
*thread_module
;
5037 proto_thread
= proto_register_protocol("Thread", "Thread", "thread");
5039 thread_module
= prefs_register_protocol(proto_thread
, NULL
);
5040 prefs_register_obsolete_preference(thread_module
, "thr_coap_decode");
5041 prefs_register_string_preference(thread_module
, "thr_seq_ctr",
5042 "Thread sequence counter",
5043 "32-bit sequence counter for hash",
5044 (const char **)&thread_seq_ctr_str
);
5046 prefs_register_bool_preference(thread_module
, "thr_use_pan_id_in_key",
5047 "Use PAN ID as first two octets of master key",
5048 "Set if the PAN ID should be used as the first two octets of the master key (PAN ID LSB), (PAN ID MSB), Key[2]...",
5049 &thread_use_pan_id_in_key
);
5051 prefs_register_bool_preference(thread_module
, "thr_auto_acq_thr_seq_ctr",
5052 "Automatically acquire Thread sequence counter",
5053 "Set if the Thread sequence counter should be automatically acquired from Key ID mode 2 MLE messages.",
5054 &thread_auto_acq_seq_ctr
);
5056 /*static hf_register_info hf[] = {
5057 { &hf_ieee802154_thread_ie,
5058 { "IE header", "thread_ie", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
5060 { &hf_ieee802154_thread_ie_length,
5061 { "Length", "thread_ie.length", FT_UINT16, BASE_DEC, NULL,
5062 THREAD_IE_LENGTH_MASK, NULL, HFILL }}
5065 static int *ett[] = {
5066 &ett_thread_header_ie,
5069 register_init_routine(proto_init_thread
);
5071 // proto_register_field_array(proto_thread_ie, hf, array_length(hf));
5072 // proto_register_subtree_array(ett, array_length(ett));
5074 /* Register Dissector */
5075 register_dissector("thread_ie", dissect_thread_ie
, proto_thread_ie
);
5079 proto_register_thread_coap(void)
5081 proto_thread_coap
= proto_register_protocol("Thread CoAP", "Thread CoAP", "thread_coap");
5082 thread_coap_handle
= register_dissector("thread_coap", dissect_thread_coap
, proto_thread_coap
);
5084 dissector_add_string("coap_tmf_media_type", "application/octet-stream", thread_coap_handle
);
5085 thread_coap_namespace
= register_dissector_table("thread.coap_namespace", "Thread CoAP namespace", proto_thread_coap
, FT_STRING
, STRING_CASE_SENSITIVE
);
5089 proto_reg_handoff_thread_mc(void)
5091 thread_dtls_handle
= find_dissector_add_dependency("dtls", proto_thread_mc
);
5092 thread_udp_handle
= find_dissector_add_dependency("udp", proto_thread_mc
);
5094 dissector_add_string("thread.coap_namespace", "c", thread_mc_handle
);
5098 proto_reg_handoff_thread_address(void)
5100 dissector_add_string("thread.coap_namespace", "a", thread_address_handle
);
5101 dissector_add_string("thread.coap_namespace", "n", thread_address_handle
);
5105 proto_reg_handoff_thread_nm(void)
5107 dissector_add_string("thread.coap_namespace", "n", thread_nm_handle
);
5111 proto_reg_handoff_thread_bl(void)
5113 dissector_add_string("thread.coap_namespace", "b", thread_bl_handle
);
5117 proto_reg_handoff_thread_dg(void)
5119 dissector_add_string("thread.coap_namespace", "d", thread_dg_handle
);
5122 void proto_reg_handoff_thread_bcn(void)
5124 /* Register our dissector with IEEE 802.15.4 */
5125 heur_dissector_add(IEEE802154_PROTOABBREV_WPAN_BEACON
, dissect_thread_bcn_heur
, "Thread Beacon", "thread_wlan_beacon", proto_thread_bcn
, HEURISTIC_ENABLE
);
5127 register_mle_key_hash_handler(KEY_HASH_THREAD
, set_thread_mle_key
);
5128 register_ieee802154_mac_key_hash_handler(KEY_HASH_THREAD
, set_thread_mac_key
);
5132 proto_reg_handoff_thread(void)
5134 /* Thread Content-Format is opaque byte string, i.e. application/octet-stream */
5135 /* Enable decoding "Internet media type" as Thread over CoAP */
5136 dissector_add_for_decode_as("media_type", thread_coap_handle
);
5137 /* Do NOT add the thread dissector to the generic media_type table for
5138 * "application/octet-stream", which is for "arbitrary binary data":
5139 * https://www.iana.org/assignments/media-types/application/octet-stream
5140 * Doing so hijacks *all* "application/octet-stream", including in HTTP, etc.
5141 * That is why there is a separate coap_tmf_media_type table and a
5142 * special CoAP-TMF dissector. (#14729).
5144 //dissector_add_string("media_type", "application/octet-stream", thread_coap_handle);
5146 proto_coap
= proto_get_id_by_filter_name("coap");
5150 *Subdissector command for Thread Specific IEs (Information Elements)
5152 *@param tvb pointer to buffer containing raw packet.
5153 *@param pinfo pointer to packet information fields (unused).
5154 *@param tree pointer to command subtree.
5155 *@param data pointer to the length of the payload IE.
5158 dissect_thread_ie(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, void *data
)
5161 proto_tree
*subtree
;
5166 unsigned pie_length
;
5167 unsigned offset
= 0;
5169 static int * fields
[] = {
5170 &hf_ieee802154_thread_ie_id
,
5171 &hf_ieee802154_thread_ie_length
,
5175 pie_length
= *(int *)data
;
5178 thread_ie
= tvb_get_letohs(tvb
, offset
);
5179 id
= (thread_ie
& THREAD_IE_ID_MASK
) >> 6;
5180 length
= thread_ie
& THREAD_IE_LENGTH_MASK
;
5182 /* Create a subtree for this command frame. */
5183 subtree
= proto_tree_add_subtree(tree
, tvb
, offset
, 2+length
, ett_thread
, NULL
, "Thread IE");
5184 //proto_item_append_text(subtree, ", %s, Length: %d", val_to_str_const(id, ieee802154_zigbee_ie_names, "Unknown"), length);
5186 proto_tree_add_bitmask(subtree
, tvb
, offset
, hf_ieee802154_thread_ie
,
5187 ett_thread_ie_fields
, fields
, ENC_LITTLE_ENDIAN
);
5191 /*case ZBEE_ZIGBEE_IE_REJOIN:
5192 dissect_ieee802154_zigbee_rejoin(tvb, pinfo, subtree, &offset);
5195 case ZBEE_ZIGBEE_IE_TX_POWER:
5196 dissect_ieee802154_zigbee_txpower(tvb, pinfo, subtree, &offset);
5199 case ZBEE_ZIGBEE_IE_BEACON_PAYLOAD:
5200 ie_tvb = tvb_new_subset_length(tvb, offset, ZBEE_NWK_BEACON_LENGTH);
5201 offset += dissect_zbee_beacon(ie_tvb, pinfo, subtree, NULL);
5202 dissect_ieee802154_superframe(tvb, pinfo, subtree, &offset);
5203 proto_tree_add_item(subtree, hf_ieee802154_zigbee_ie_source_addr, tvb, offset, 2, ENC_NA);
5209 //proto_tree_add_item(tree, hf_thread_mc_tlv_unknown, tvb, offset, tlv_len, ENC_NA);
5214 } while (offset
< pie_length
);
5215 return tvb_captured_length(tvb
);
5219 * Editor modelines - https://www.wireshark.org/tools/modelines.html
5224 * indent-tabs-mode: nil
5227 * vi: set shiftwidth=4 tabstop=8 expandtab:
5228 * :indentSize=4:tabSize=8:noTabs=true: