1 /* packet-icmpv6.c
2  * Routines for ICMPv6 packet disassembly
3  *
4  * Wireshark - Network traffic analyzer
5  * By Gerald Combs <gerald@wireshark.org>
6  * Copyright 1998 Gerald Combs
7  *
8  * MobileIPv6 support added by Tomislav Borosa <tomislav.borosa@siemens.hr>
9  * Copyright 2006, Nicolas DICHTEL - 6WIND - <nicolas.dichtel@6wind.com>
10  *
11  * HMIPv6 support added by Martti Kuparinen <martti.kuparinen@iki.fi>
12  *
13  * FMIPv6 support added by Martin Andre <andre@clarinet.u-strasbg.fr>
14  *
15  * RPL support added by Colin O'Flynn & Owen Kirby.
16  *
17  * Enhance ICMPv6 dissector by Alexis La Goutte
18  *
19  * P2P-RPL support added by Cenk Gundogan <cnkgndgn@gmail.com>
20  *
21  * SPDX-License-Identifier: GPL-2.0-or-later
22  */
23 
24 #include "config.h"
25 
26 #include <epan/packet.h>
27 #include <epan/in_cksum.h>
28 #include <epan/ipproto.h>
29 #include <epan/expert.h>
30 #include <epan/conversation.h>
31 #include <epan/sequence_analysis.h>
32 #include <epan/tap.h>
33 #include <epan/capture_dissectors.h>
34 #include <epan/proto_data.h>
35 #include <epan/strutil.h>
36 
37 #include <wsutil/pow2.h>
38 
39 #include "packet-ber.h"
40 #include "packet-dns.h"
41 #include "packet-x509af.h"
42 #include "packet-x509if.h"
43 #include "packet-icmp.h"    /* same transaction_t used both both v4 and v6 */
44 #include "packet-ieee802154.h"
45 #include "packet-6lowpan.h"
46 #include "packet-ip.h"
47 
48 void proto_register_icmpv6(void);
49 void proto_reg_handoff_icmpv6(void);
50 
51 /*
52  * The information used comes from:
53  * RFC 1885/2463/4443: Internet Control Message Protocol (ICMPv6) for the Internet Protocol Version 6 (IPv6) Specification
54  * RFC 2461/4861: Neighbor Discovery for IP Version 6 (IPv6)
55  * RFC 2491: IPv6 over Non-Broadcast Multiple Access (NBMA) networks
56  * RFC 2710: Multicast Listener Discovery for IPv6
57  * RFC 2894: Router Renumbering for IPv6
58  * RFC 3122: Extensions to IPv6 Neighbor Discovery for Inverse Discovery Specification
59  * RFC 3775/6275: Mobility Support in IPv6
60  * RFC 3810: Multicast Listener Discovery Version 2 (MLDv2) for IPv6
61  * RFC 3971: SEcure Neighbor Discovery (SEND)
62  * RFC 4065: Instructions for Seamoby and Experimental Mobility Protocol IANA Allocations
63  * RFC 4068/5268/5568: Fast Handovers for Mobile IPv6 (Mobile IPv6 Fast Handovers)
64  * RFC 4140/5380: Hierarchical Mobile IPv6 Mobility Management (HMIPv6)
65  * RFC 4191: Default Router Preferences and More-Specific Routes
66  * RFC 4286: Multicast Router Discovery
67  * RFC 4620: IPv6 Node Information Queries
68  * RFC 5006/6106: IPv6 Router Advertisement Options for DNS Configuration
69  * RFC 5075/5175: IPv6 Router Advertisement Flags Option
70  * RFC 5269: Distributing a Symmetric Fast Mobile IPv6 (FMIPv6) Handover Key Using SEcure Neighbor Discovery (SEND)
71  * RFC 5271: Mobile IPv6 Fast Handovers for 3G CDMA Networks
72  * RFC 6275: Mobility Support in IPv6
73  * RFC 6495: Subject Key Identifier (SKI) SEND Name Type fields
74  * RFC 6496: Secure Proxy ND Support for SEND
75  * RFC 6550: RPL: IPv6 Routing Protocol for Low power and Lossy Networks
76  * RFC 6554: An IPv6 Routing Header for Source Routes with RPL
77  * RFC 6743: ICMP Locator Update message for ILNPv6
78  * RFC 6775: Neighbor Discovery Optimization for Low Power and Lossy Networks (6LoWPAN)
79  * RFC 6997: Reactive Discovery of Point-to-Point Routes in Low-Power and Lossy Networks
80  * RFC 7112: Implications of Oversized IPv6 Header Chains
81  * RFC 7400: 6LoWPAN-GHC: Generic Header Compression for IPv6 over Low-Power Wireless Personal Area Networks (6LoWPANs)
82  * RFC 7731: MPL Control Message
83  * RFC 8335: PROBE: A Utility for Probing Interfaces
84  * RFC 8781: Discovering PREF64 in Router Advertisements
85  * http://www.iana.org/assignments/icmpv6-parameters (last updated 2016-02-24)
86  */
87 
88 static int proto_icmpv6 = -1;
89 static int hf_icmpv6_type = -1;
90 static int hf_icmpv6_code = -1;
91 static int hf_icmpv6_checksum = -1;
92 static int hf_icmpv6_checksum_status = -1;
93 static int hf_icmpv6_reserved = -1;
94 static int hf_icmpv6_data = -1;
95 static int hf_icmpv6_unknown_data = -1;
96 static int hf_icmpv6_mtu = -1;
97 static int hf_icmpv6_pointer = -1;
98 static int hf_icmpv6_echo_identifier = -1;
99 static int hf_icmpv6_echo_sequence_number = -1;
100 static int hf_icmpv6_nonce = -1;
101 
102 /* RFC 2461/4861 : Neighbor Discovery for IP version 6 (IPv6) */
103 static int hf_icmpv6_nd_ra_cur_hop_limit = -1;
104 static int hf_icmpv6_nd_ra_flag = -1;
105 static int hf_icmpv6_nd_ra_flag_m = -1;
106 static int hf_icmpv6_nd_ra_flag_o = -1;
107 static int hf_icmpv6_nd_ra_flag_h = -1;
108 static int hf_icmpv6_nd_ra_flag_prf = -1;
109 static int hf_icmpv6_nd_ra_flag_p = -1;
110 static int hf_icmpv6_nd_ra_flag_rsv = -1;
111 static int hf_icmpv6_nd_ra_router_lifetime = -1;
112 static int hf_icmpv6_nd_ra_reachable_time = -1;
113 static int hf_icmpv6_nd_ra_retrans_timer = -1;
114 static int hf_icmpv6_nd_ns_target_address = -1;
115 static int hf_icmpv6_nd_na_flag = -1;
116 static int hf_icmpv6_nd_na_flag_r = -1;
117 static int hf_icmpv6_nd_na_flag_s = -1;
118 static int hf_icmpv6_nd_na_flag_o = -1;
119 static int hf_icmpv6_nd_na_flag_rsv = -1;
120 static int hf_icmpv6_nd_na_target_address = -1;
121 static int hf_icmpv6_nd_rd_target_address = -1;
122 static int hf_icmpv6_nd_rd_destination_address = -1;
123 
124 /* ND Options */
125 static int hf_icmpv6_opt = -1;
126 static int hf_icmpv6_opt_type = -1;
127 static int hf_icmpv6_opt_length = -1;
128 static int hf_icmpv6_opt_linkaddr_mac = -1;
129 static int hf_icmpv6_opt_src_linkaddr_mac = -1;
130 static int hf_icmpv6_opt_target_linkaddr_mac = -1;
131 static int hf_icmpv6_opt_linkaddr = -1;
132 static int hf_icmpv6_opt_src_linkaddr = -1;
133 static int hf_icmpv6_opt_target_linkaddr = -1;
134 static int hf_icmpv6_opt_linkaddr_eui64 = -1;
135 static int hf_icmpv6_opt_src_linkaddr_eui64 = -1;
136 static int hf_icmpv6_opt_target_linkaddr_eui64 = -1;
137 static int hf_icmpv6_opt_prefix_len = -1;
138 static int hf_icmpv6_opt_prefix_flag = -1;
139 static int hf_icmpv6_opt_prefix_flag_l = -1;
140 static int hf_icmpv6_opt_prefix_flag_a = -1;
141 static int hf_icmpv6_opt_prefix_flag_r = -1;
142 static int hf_icmpv6_opt_prefix_flag_reserved = -1;
143 static int hf_icmpv6_opt_prefix_valid_lifetime = -1;
144 static int hf_icmpv6_opt_prefix_preferred_lifetime = -1;
145 static int hf_icmpv6_opt_prefix = -1;
146 static int hf_icmpv6_opt_naack_option_code = -1;
147 static int hf_icmpv6_opt_naack_status = -1;
148 static int hf_icmpv6_opt_naack_supplied_ncoa = -1;
149 static int hf_icmpv6_opt_cga_pad_len = -1;
150 static int hf_icmpv6_opt_cga = -1;
151 static int hf_icmpv6_opt_cga_modifier = -1;
152 static int hf_icmpv6_opt_cga_subnet_prefix = -1;
153 static int hf_icmpv6_opt_cga_count = -1;
154 static int hf_icmpv6_opt_cga_ext_type = -1;
155 static int hf_icmpv6_opt_cga_ext_length = -1;
156 static int hf_icmpv6_opt_cga_ext_data = -1;
157 static int hf_icmpv6_opt_rsa_key_hash = -1;
158 static int hf_icmpv6_opt_digital_signature_padding = -1;
159 static int hf_icmpv6_opt_ps_key_hash = -1;
160 static int hf_icmpv6_opt_timestamp = -1;
161 static int hf_icmpv6_opt_nonce = -1;
162 static int hf_icmpv6_opt_certificate_padding = -1;
163 static int hf_icmpv6_opt_ipa_option_code = -1;
164 static int hf_icmpv6_opt_ipa_prefix_len = -1;
165 static int hf_icmpv6_opt_ipa_ipv6_address = -1;
166 static int hf_icmpv6_opt_nrpi_option_code = -1;
167 static int hf_icmpv6_opt_nrpi_prefix_len = -1;
168 static int hf_icmpv6_opt_nrpi_prefix = -1;
169 static int hf_icmpv6_opt_lla_option_code = -1;
170 static int hf_icmpv6_opt_lla_bytes = -1;
171 static int hf_icmpv6_opt_map_dist = -1;
172 static int hf_icmpv6_opt_map_pref = -1;
173 static int hf_icmpv6_opt_map_flag = -1;
174 static int hf_icmpv6_opt_map_flag_r = -1;
175 static int hf_icmpv6_opt_map_flag_reserved = -1;
176 static int hf_icmpv6_opt_map_valid_lifetime = -1;
177 static int hf_icmpv6_opt_map_global_address = -1;
178 static int hf_icmpv6_opt_route_info_flag = -1;
179 static int hf_icmpv6_opt_route_info_flag_route_preference = -1;
180 static int hf_icmpv6_opt_route_info_flag_reserved = -1;
181 static int hf_icmpv6_opt_route_lifetime = -1;
182 static int hf_icmpv6_opt_name_type = -1;
183 static int hf_icmpv6_opt_name_x501 = -1;
184 static int hf_icmpv6_opt_name_fqdn = -1;
185 static int hf_icmpv6_opt_cert_type = -1;
186 static int hf_icmpv6_x509if_Name = -1;
187 static int hf_icmpv6_x509af_Certificate = -1;
188 static int hf_icmpv6_opt_redirected_packet = -1;
189 static int hf_icmpv6_opt_mtu = -1;
190 static int hf_icmpv6_opt_nbma_shortcut_limit = -1;
191 static int hf_icmpv6_opt_advertisement_interval = -1;
192 static int hf_icmpv6_opt_home_agent_preference = -1;
193 static int hf_icmpv6_opt_home_agent_lifetime = -1;
194 static int hf_icmpv6_opt_ipv6_address = -1;
195 static int hf_icmpv6_opt_reserved = -1;
196 static int hf_icmpv6_opt_padding = -1;
197 static int hf_icmpv6_opt_rdnss_lifetime = -1;
198 static int hf_icmpv6_opt_rdnss = -1;
199 static int hf_icmpv6_opt_efo = -1;
200 static int hf_icmpv6_opt_efo_m = -1;
201 static int hf_icmpv6_opt_efo_o = -1;
202 static int hf_icmpv6_opt_efo_h = -1;
203 static int hf_icmpv6_opt_efo_prf = -1;
204 static int hf_icmpv6_opt_efo_p = -1;
205 static int hf_icmpv6_opt_efo_rsv = -1;
206 static int hf_icmpv6_opt_hkr_pad_length = -1;
207 static int hf_icmpv6_opt_hkr_at = -1;
208 static int hf_icmpv6_opt_hkr_reserved = -1;
209 static int hf_icmpv6_opt_hkr_encryption_public_key = -1;
210 static int hf_icmpv6_opt_hkr_padding = -1;
211 static int hf_icmpv6_opt_hkr_lifetime = -1;
212 static int hf_icmpv6_opt_hkr_encrypted_handover_key = -1;
213 static int hf_icmpv6_opt_hai_option_code = -1;
214 static int hf_icmpv6_opt_hai_length = -1;
215 static int hf_icmpv6_opt_hai_value = -1;
216 static int hf_icmpv6_opt_mn_option_code = -1;
217 static int hf_icmpv6_opt_mn_length = -1;
218 static int hf_icmpv6_opt_mn_value = -1;
219 static int hf_icmpv6_opt_dnssl_lifetime = -1;
220 static int hf_icmpv6_opt_dnssl = -1;
221 
222 static int hf_icmpv6_opt_aro_status = -1;
223 static int hf_icmpv6_opt_aro_registration_lifetime = -1;
224 static int hf_icmpv6_opt_aro_eui64 = -1;
225 static int hf_icmpv6_opt_6co_context_length = -1;
226 static int hf_icmpv6_opt_6co_flag = -1;
227 static int hf_icmpv6_opt_6co_flag_c = -1;
228 static int hf_icmpv6_opt_6co_flag_cid = -1;
229 static int hf_icmpv6_opt_6co_flag_reserved = -1;
230 static int hf_icmpv6_opt_6co_valid_lifetime = -1;
231 static int hf_icmpv6_opt_6co_context_prefix  = -1;
232 static int hf_icmpv6_opt_abro_version_low = -1;
233 static int hf_icmpv6_opt_abro_version_high = -1;
234 static int hf_icmpv6_opt_abro_valid_lifetime = -1;
235 static int hf_icmpv6_opt_abro_6lbr_address = -1;
236 static int hf_icmpv6_opt_6cio_unassigned1 = -1;
237 static int hf_icmpv6_opt_6cio_flag_g = -1;
238 static int hf_icmpv6_opt_6cio_unassigned2 = -1;
239 
240 static int hf_icmpv6_opt_captive_portal = -1;
241 
242 static int hf_icmpv6_opt_pref64_scaled_lifetime = -1;
243 static int hf_icmpv6_opt_pref64_plc = -1;
244 static int hf_icmpv6_opt_pref64_prefix = -1;
245 /* RFC 2710: Multicast Listener Discovery for IPv6 */
246 static int hf_icmpv6_mld_mrd = -1;
247 static int hf_icmpv6_mld_multicast_address = -1;
248 
249 /* RFC 2894: Router Renumbering for IPv6 */
250 static int hf_icmpv6_rr_sequencenumber = -1;
251 static int hf_icmpv6_rr_segmentnumber = -1;
252 static int hf_icmpv6_rr_flag = -1;
253 static int hf_icmpv6_rr_flag_t = -1;
254 static int hf_icmpv6_rr_flag_r = -1;
255 static int hf_icmpv6_rr_flag_a = -1;
256 static int hf_icmpv6_rr_flag_s = -1;
257 static int hf_icmpv6_rr_flag_p = -1;
258 static int hf_icmpv6_rr_flag_rsv = -1;
259 static int hf_icmpv6_rr_maxdelay = -1;
260 static int hf_icmpv6_rr_pco_mp_part = -1;
261 static int hf_icmpv6_rr_pco_mp_opcode = -1;
262 static int hf_icmpv6_rr_pco_mp_oplength = -1;
263 static int hf_icmpv6_rr_pco_mp_ordinal = -1;
264 static int hf_icmpv6_rr_pco_mp_matchlen = -1;
265 static int hf_icmpv6_rr_pco_mp_minlen = -1;
266 static int hf_icmpv6_rr_pco_mp_maxlen = -1;
267 static int hf_icmpv6_rr_pco_mp_matchprefix = -1;
268 static int hf_icmpv6_rr_pco_up_part = -1;
269 static int hf_icmpv6_rr_pco_up_uselen = -1;
270 static int hf_icmpv6_rr_pco_up_keeplen = -1;
271 static int hf_icmpv6_rr_pco_up_flagmask = -1;
272 static int hf_icmpv6_rr_pco_up_flagmask_l = -1;
273 static int hf_icmpv6_rr_pco_up_flagmask_a = -1;
274 static int hf_icmpv6_rr_pco_up_flagmask_reserved = -1;
275 static int hf_icmpv6_rr_pco_up_raflags = -1;
276 static int hf_icmpv6_rr_pco_up_raflags_l = -1;
277 static int hf_icmpv6_rr_pco_up_raflags_a = -1;
278 static int hf_icmpv6_rr_pco_up_raflags_reserved = -1;
279 static int hf_icmpv6_rr_pco_up_validlifetime = -1;
280 static int hf_icmpv6_rr_pco_up_preferredlifetime = -1;
281 static int hf_icmpv6_rr_pco_up_flag = -1;
282 static int hf_icmpv6_rr_pco_up_flag_v = -1;
283 static int hf_icmpv6_rr_pco_up_flag_p = -1;
284 static int hf_icmpv6_rr_pco_up_flag_reserved = -1;
285 static int hf_icmpv6_rr_pco_up_useprefix = -1;
286 static int hf_icmpv6_rr_rm = -1;
287 static int hf_icmpv6_rr_rm_flag = -1;
288 static int hf_icmpv6_rr_rm_flag_b = -1;
289 static int hf_icmpv6_rr_rm_flag_f = -1;
290 static int hf_icmpv6_rr_rm_flag_reserved = -1;
291 static int hf_icmpv6_rr_rm_ordinal = -1;
292 static int hf_icmpv6_rr_rm_matchedlen = -1;
293 static int hf_icmpv6_rr_rm_interfaceindex = -1;
294 static int hf_icmpv6_rr_rm_matchedprefix = -1;
295 
296 /* RFC 3810: Multicast Listener Discovery Version 2 (MLDv2) for IPv6 */
297 static int hf_icmpv6_mld_mrc = -1;
298 static int hf_icmpv6_mld_flag = -1;
299 static int hf_icmpv6_mld_flag_s = -1;
300 static int hf_icmpv6_mld_flag_qrv = -1;
301 static int hf_icmpv6_mld_flag_rsv = -1;
302 static int hf_icmpv6_mld_qqi = -1;
303 static int hf_icmpv6_mld_nb_sources = -1;
304 static int hf_icmpv6_mld_source_address = -1;
305 static int hf_icmpv6_mldr_nb_mcast_records = -1;
306 static int hf_icmpv6_mldr_mar = -1;
307 static int hf_icmpv6_mldr_mar_record_type = -1;
308 static int hf_icmpv6_mldr_mar_aux_data_len = -1;
309 static int hf_icmpv6_mldr_mar_nb_sources = -1;
310 static int hf_icmpv6_mldr_mar_multicast_address = -1;
311 static int hf_icmpv6_mldr_mar_source_address = -1;
312 static int hf_icmpv6_mldr_mar_auxiliary_data = -1;
313 
314 /* RFC3775/6275: Mobility Support in IPv6 */
315 static int hf_icmpv6_mip6_identifier = -1;
316 static int hf_icmpv6_mip6_home_agent_address = -1;
317 static int hf_icmpv6_mip6_flag = -1;
318 static int hf_icmpv6_mip6_flag_m = -1;
319 static int hf_icmpv6_mip6_flag_o = -1;
320 static int hf_icmpv6_mip6_flag_rsv = -1;
321 
322 /* RFC3971: SEcure Neighbor Discovery (SEND) */
323 static int hf_icmpv6_send_identifier = -1;
324 static int hf_icmpv6_send_all_components = -1;
325 static int hf_icmpv6_send_component = -1;
326 
327 /* RFC 4068/5268/5568: Fast Handovers for Mobile IPv6 ( Mobile IPv6 Fast Handovers ) */
328 static int hf_icmpv6_fmip6_subtype = -1;
329 static int hf_icmpv6_fmip6_hi_flag = -1;
330 static int hf_icmpv6_fmip6_hi_flag_s = -1;
331 static int hf_icmpv6_fmip6_hi_flag_u = -1;
332 static int hf_icmpv6_fmip6_hi_flag_reserved = -1;
333 static int hf_icmpv6_fmip6_identifier = -1;
334 
335 /* RFC 4286: Multicast Router Discovery */
336 static int hf_icmpv6_mcast_ra_query_interval = -1;
337 static int hf_icmpv6_mcast_ra_robustness_variable = -1;
338 
339 /* RFC 4620: IPv6 Node Information Queries */
340 static int hf_icmpv6_ni_qtype = -1;
341 static int hf_icmpv6_ni_flag = -1;
342 static int hf_icmpv6_ni_flag_g = -1;
343 static int hf_icmpv6_ni_flag_s = -1;
344 static int hf_icmpv6_ni_flag_l = -1;
345 static int hf_icmpv6_ni_flag_c = -1;
346 static int hf_icmpv6_ni_flag_a = -1;
347 static int hf_icmpv6_ni_flag_t = -1;
348 static int hf_icmpv6_ni_flag_rsv = -1;
349 static int hf_icmpv6_ni_nonce = -1;
350 static int hf_icmpv6_ni_query_subject_ipv6 = -1;
351 static int hf_icmpv6_ni_query_subject_fqdn = -1;
352 static int hf_icmpv6_ni_query_subject_ipv4 = -1;
353 static int hf_icmpv6_ni_reply_node_ttl = -1;
354 static int hf_icmpv6_ni_reply_node_name = -1;
355 static int hf_icmpv6_ni_reply_node_address = -1;
356 static int hf_icmpv6_ni_reply_ipv4_address = -1;
357 
358 /* RFC 4884: Extended ICMP */
359 static int hf_icmpv6_length = -1;
360 
361 /* RPL: RFC 6550/6997 : Routing and Discovery of P2P Routes in Low-Power and Lossy Networks. */
362 static int hf_icmpv6_rpl_dis_flag = -1;
363 static int hf_icmpv6_rpl_dio_instance = -1;
364 static int hf_icmpv6_rpl_dio_version = -1;
365 static int hf_icmpv6_rpl_dio_rank = -1;
366 static int hf_icmpv6_rpl_dio_flag = -1;
367 static int hf_icmpv6_rpl_dio_flag_g = -1;
368 static int hf_icmpv6_rpl_dio_flag_0 = -1;
369 static int hf_icmpv6_rpl_dio_flag_mop = -1;
370 static int hf_icmpv6_rpl_dio_flag_prf = -1;
371 static int hf_icmpv6_rpl_dio_dtsn = -1;
372 static int hf_icmpv6_rpl_dio_dagid = -1;
373 static int hf_icmpv6_rpl_dao_instance = -1;
374 static int hf_icmpv6_rpl_dao_flag = -1;
375 static int hf_icmpv6_rpl_dao_flag_k = -1;
376 static int hf_icmpv6_rpl_dao_flag_d = -1;
377 static int hf_icmpv6_rpl_dao_flag_rsv = -1;
378 static int hf_icmpv6_rpl_dao_sequence = -1;
379 static int hf_icmpv6_rpl_dao_dodagid = -1;
380 static int hf_icmpv6_rpl_daoack_instance = -1;
381 static int hf_icmpv6_rpl_daoack_flag = -1;
382 static int hf_icmpv6_rpl_daoack_flag_d = -1;
383 static int hf_icmpv6_rpl_daoack_flag_rsv = -1;
384 static int hf_icmpv6_rpl_daoack_sequence = -1;
385 static int hf_icmpv6_rpl_daoack_status = -1;
386 static int hf_icmpv6_rpl_daoack_dodagid = -1;
387 static int hf_icmpv6_rpl_cc_instance = -1;
388 static int hf_icmpv6_rpl_cc_flag = -1;
389 static int hf_icmpv6_rpl_cc_flag_r = -1;
390 static int hf_icmpv6_rpl_cc_flag_rsv = -1;
391 static int hf_icmpv6_rpl_cc_nonce = -1;
392 static int hf_icmpv6_rpl_cc_dodagid = -1;
393 static int hf_icmpv6_rpl_cc_destination_counter = -1;
394 static int hf_icmpv6_rpl_secure_flag = -1;
395 static int hf_icmpv6_rpl_secure_flag_t = -1;
396 static int hf_icmpv6_rpl_secure_flag_rsv = -1;
397 static int hf_icmpv6_rpl_secure_algorithm = -1;
398 static int hf_icmpv6_rpl_secure_kim = -1;
399 static int hf_icmpv6_rpl_secure_lvl = -1;
400 static int hf_icmpv6_rpl_secure_rsv = -1;
401 static int hf_icmpv6_rpl_secure_counter = -1;
402 static int hf_icmpv6_rpl_secure_key_source = -1;
403 static int hf_icmpv6_rpl_secure_key_index = -1;
404 static int hf_icmpv6_rpl_opt = -1;
405 static int hf_icmpv6_rpl_opt_type = -1;
406 static int hf_icmpv6_rpl_opt_length = -1;
407 static int hf_icmpv6_rpl_opt_reserved = -1;
408 static int hf_icmpv6_rpl_opt_padn = -1;
409 static int hf_icmpv6_rpl_opt_metric_type = -1;
410 static int hf_icmpv6_rpl_opt_metric_flags = -1;
411 static int hf_icmpv6_rpl_opt_metric_reserved = -1;
412 static int hf_icmpv6_rpl_opt_metric_flag_p = -1;
413 static int hf_icmpv6_rpl_opt_metric_flag_c = -1;
414 static int hf_icmpv6_rpl_opt_metric_flag_o = -1;
415 static int hf_icmpv6_rpl_opt_metric_flag_r = -1;
416 static int hf_icmpv6_rpl_opt_metric_a = -1;
417 static int hf_icmpv6_rpl_opt_metric_prec = -1;
418 static int hf_icmpv6_rpl_opt_metric_len = -1;
419 static int hf_icmpv6_rpl_opt_metric_nsa_object = -1;
420 static int hf_icmpv6_rpl_opt_metric_nsa_object_reserved = -1;
421 static int hf_icmpv6_rpl_opt_metric_nsa_object_flags = -1;
422 static int hf_icmpv6_rpl_opt_metric_nsa_object_flag_a = -1;
423 static int hf_icmpv6_rpl_opt_metric_nsa_object_flag_o = -1;
424 static int hf_icmpv6_rpl_opt_metric_nsa_object_opttlv_object = -1;
425 static int hf_icmpv6_rpl_opt_metric_nsa_object_opttlv_object_type = -1;
426 static int hf_icmpv6_rpl_opt_metric_nsa_object_opttlv_object_length = -1;
427 static int hf_icmpv6_rpl_opt_metric_nsa_object_opttlv_object_data = -1;
428 static int hf_icmpv6_rpl_opt_metric_ne_object = -1;
429 static int hf_icmpv6_rpl_opt_metric_ne_object_flags = -1;
430 static int hf_icmpv6_rpl_opt_metric_ne_object_flag_i = -1;
431 static int hf_icmpv6_rpl_opt_metric_ne_object_type = -1;
432 static int hf_icmpv6_rpl_opt_metric_ne_object_flag_e = -1;
433 static int hf_icmpv6_rpl_opt_metric_ne_object_energy = -1;
434 static int hf_icmpv6_rpl_opt_metric_hp_object = -1;
435 static int hf_icmpv6_rpl_opt_metric_hp_object_reserved = -1;
436 static int hf_icmpv6_rpl_opt_metric_hp_object_flags = -1;
437 static int hf_icmpv6_rpl_opt_metric_hp_object_hp = -1;
438 static int hf_icmpv6_rpl_opt_metric_lt_object_lt = -1;
439 static int hf_icmpv6_rpl_opt_metric_ll_object_ll = -1;
440 static int hf_icmpv6_rpl_opt_metric_lql_object = -1;
441 static int hf_icmpv6_rpl_opt_metric_lql_object_res = -1;
442 static int hf_icmpv6_rpl_opt_metric_lql_object_val = -1;
443 static int hf_icmpv6_rpl_opt_metric_lql_object_counter = -1;
444 static int hf_icmpv6_rpl_opt_metric_etx_object_etx = -1;
445 static int hf_icmpv6_rpl_opt_metric_lc_object = -1;
446 static int hf_icmpv6_rpl_opt_metric_lc_object_res = -1;
447 static int hf_icmpv6_rpl_opt_metric_lc_object_lc = -1;
448 static int hf_icmpv6_rpl_opt_metric_lc_object_counter = -1;
449 static int hf_icmpv6_rpl_opt_metric_lc_object_reserved = -1;
450 static int hf_icmpv6_rpl_opt_metric_lc_object_flag_i = -1;
451 static int hf_icmpv6_rpl_opt_route_prefix_length = -1;
452 static int hf_icmpv6_rpl_opt_route_flag = -1;
453 static int hf_icmpv6_rpl_opt_route_pref = -1;
454 static int hf_icmpv6_rpl_opt_route_reserved = -1;
455 static int hf_icmpv6_rpl_opt_route_lifetime = -1;
456 static int hf_icmpv6_rpl_opt_route_prefix = -1;
457 static int hf_icmpv6_rpl_opt_config_flag = -1;
458 static int hf_icmpv6_rpl_opt_config_reserved = -1;
459 static int hf_icmpv6_rpl_opt_config_auth = -1;
460 static int hf_icmpv6_rpl_opt_config_pcs = -1;
461 static int hf_icmpv6_rpl_opt_config_doublings = -1;
462 static int hf_icmpv6_rpl_opt_config_min_interval = -1;
463 static int hf_icmpv6_rpl_opt_config_redundancy = -1;
464 static int hf_icmpv6_rpl_opt_config_rank_incr = -1;
465 static int hf_icmpv6_rpl_opt_config_hop_rank_inc = -1;
466 static int hf_icmpv6_rpl_opt_config_ocp = -1;
467 static int hf_icmpv6_rpl_opt_config_rsv = -1;
468 static int hf_icmpv6_rpl_opt_config_def_lifetime = -1;
469 static int hf_icmpv6_rpl_opt_config_lifetime_unit = -1;
470 static int hf_icmpv6_rpl_opt_target_flag = -1;
471 static int hf_icmpv6_rpl_opt_target_prefix_length = -1;
472 static int hf_icmpv6_rpl_opt_target_prefix = -1;
473 static int hf_icmpv6_rpl_opt_transit_flag = -1;
474 static int hf_icmpv6_rpl_opt_transit_flag_e = -1;
475 static int hf_icmpv6_rpl_opt_transit_flag_rsv = -1;
476 static int hf_icmpv6_rpl_opt_transit_pathseq = -1;
477 static int hf_icmpv6_rpl_opt_transit_pathctl = -1;
478 static int hf_icmpv6_rpl_opt_transit_pathlifetime = -1;
479 static int hf_icmpv6_rpl_opt_transit_parent = -1;
480 static int hf_icmpv6_rpl_opt_solicited_instance = -1;
481 static int hf_icmpv6_rpl_opt_solicited_flag = -1;
482 static int hf_icmpv6_rpl_opt_solicited_flag_v = -1;
483 static int hf_icmpv6_rpl_opt_solicited_flag_i = -1;
484 static int hf_icmpv6_rpl_opt_solicited_flag_d = -1;
485 static int hf_icmpv6_rpl_opt_solicited_flag_rsv = -1;
486 static int hf_icmpv6_rpl_opt_solicited_dodagid = -1;
487 static int hf_icmpv6_rpl_opt_solicited_version = -1;
488 static int hf_icmpv6_rpl_opt_prefix = -1;
489 static int hf_icmpv6_rpl_opt_prefix_flag = -1;
490 static int hf_icmpv6_rpl_opt_prefix_flag_l = -1;
491 static int hf_icmpv6_rpl_opt_prefix_flag_a = -1;
492 static int hf_icmpv6_rpl_opt_prefix_flag_r = -1;
493 static int hf_icmpv6_rpl_opt_prefix_flag_rsv = -1;
494 static int hf_icmpv6_rpl_opt_prefix_vlifetime = -1;
495 static int hf_icmpv6_rpl_opt_prefix_plifetime = -1;
496 static int hf_icmpv6_rpl_opt_prefix_length = -1;
497 static int hf_icmpv6_rpl_opt_targetdesc = -1;
498 static int hf_icmpv6_rpl_opt_route_discovery_flag = -1;
499 static int hf_icmpv6_rpl_opt_route_discovery_reply = -1;
500 static int hf_icmpv6_rpl_opt_route_discovery_hop_by_hop = -1;
501 static int hf_icmpv6_rpl_opt_route_discovery_num_of_routes = -1;
502 static int hf_icmpv6_rpl_opt_route_discovery_compr = -1;
503 static int hf_icmpv6_rpl_opt_route_discovery_lifetime = -1;
504 static int hf_icmpv6_rpl_opt_route_discovery_nh = -1;
505 static int hf_icmpv6_rpl_opt_route_discovery_maxrank = -1;
506 static int hf_icmpv6_rpl_opt_route_discovery_target_addr = -1;
507 static int hf_icmpv6_rpl_opt_route_discovery_addr_vec = -1;
508 static int hf_icmpv6_rpl_opt_route_discovery_addr_vec_addr = -1;
509 static int hf_icmpv6_rpl_p2p_dro_instance = -1;
510 static int hf_icmpv6_rpl_p2p_dro_version = -1;
511 static int hf_icmpv6_rpl_p2p_dro_flag = -1;
512 static int hf_icmpv6_rpl_p2p_dro_flag_stop = -1;
513 static int hf_icmpv6_rpl_p2p_dro_flag_ack = -1;
514 static int hf_icmpv6_rpl_p2p_dro_flag_seq = -1;
515 static int hf_icmpv6_rpl_p2p_dro_flag_reserved = -1;
516 static int hf_icmpv6_rpl_p2p_dro_dagid = -1;
517 static int hf_icmpv6_rpl_p2p_droack_flag = -1;
518 static int hf_icmpv6_rpl_p2p_droack_flag_seq = -1;
519 static int hf_icmpv6_rpl_p2p_droack_flag_reserved = -1;
520 
521 /* RFC6743 Locator Update (156) */
522 static int hf_icmpv6_ilnp_nb_locs = -1;
523 static int hf_icmpv6_ilnp_locator = -1;
524 static int hf_icmpv6_ilnp_preference = -1;
525 static int hf_icmpv6_ilnp_lifetime = -1;
526 
527 static int hf_icmpv6_da_status = -1;
528 static int hf_icmpv6_da_rsv = -1;
529 static int hf_icmpv6_da_lifetime = -1;
530 static int hf_icmpv6_da_eui64 = -1;
531 static int hf_icmpv6_da_raddr = -1;
532 
533 static heur_dissector_list_t icmpv6_heur_subdissector_list;
534 static int icmpv6_tap = -1;
535 
536 /* RFC 7731 MPL (159) */
537 static int hf_icmpv6_mpl_seed_info_min_sequence = -1;
538 static int hf_icmpv6_mpl_seed_info_bm_len = -1;
539 static int hf_icmpv6_mpl_seed_info_s = -1;
540 static int hf_icmpv6_mpl_seed_info_seed_id = -1;
541 static int hf_icmpv6_mpl_seed_info_sequence = -1;
542 
543 /* Extended Echo - Probe  (RFC8335)*/
544 static int hf_icmpv6_ext_echo_seq_num = -1;
545 static int hf_icmpv6_ext_echo_req_reserved = -1;
546 static int hf_icmpv6_ext_echo_req_local = -1;
547 static int hf_icmpv6_ext_echo_rsp_state = -1;
548 static int hf_icmpv6_ext_echo_rsp_reserved = -1;
549 static int hf_icmpv6_ext_echo_rsp_active = -1;
550 static int hf_icmpv6_ext_echo_rsp_ipv4 = -1;
551 static int hf_icmpv6_ext_echo_rsp_ipv6 = -1;
552 
553 /* Conversation related data */
554 static int hf_icmpv6_resp_in = -1;
555 static int hf_icmpv6_resp_to = -1;
556 static int hf_icmpv6_no_resp = -1;
557 static int hf_icmpv6_resptime = -1;
558 
559 typedef struct _icmpv6_conv_info_t {
560     wmem_tree_t *unmatched_pdus;
561     wmem_tree_t *matched_pdus;
562 } icmpv6_conv_info_t;
563 
564 static icmp_transaction_t *transaction_start(packet_info *pinfo, proto_tree *tree, guint32 *key);
565 static icmp_transaction_t *transaction_end(packet_info *pinfo, proto_tree *tree, guint32 *key);
566 
567 static gint ett_icmpv6 = -1;
568 static gint ett_icmpv6_opt = -1;
569 static gint ett_icmpv6_mar = -1;
570 static gint ett_icmpv6_flag_prefix = -1;
571 static gint ett_icmpv6_flag_map = -1;
572 static gint ett_icmpv6_flag_route_info = -1;
573 static gint ett_icmpv6_flag_6lowpan = -1;
574 static gint ett_icmpv6_flag_efo = -1;
575 static gint ett_icmpv6_rpl_opt = -1;
576 static gint ett_icmpv6_rpl_metric_type = -1;
577 static gint ett_icmpv6_rpl_metric_flags = -1;
578 static gint ett_icmpv6_rpl_metric_nsa_object = -1;
579 static gint ett_icmpv6_rpl_metric_nsa_object_tlv_type = -1;
580 static gint ett_icmpv6_rpl_metric_ne_object = -1;
581 static gint ett_icmpv6_rpl_metric_hp_object = -1;
582 static gint ett_icmpv6_rpl_metric_lql_object = -1;
583 static gint ett_icmpv6_rpl_metric_lc_object = -1;
584 static gint ett_icmpv6_rpl_flag_routing = -1;
585 static gint ett_icmpv6_rpl_flag_config = -1;
586 static gint ett_icmpv6_rpl_flag_transit = -1;
587 static gint ett_icmpv6_rpl_flag_solicited = -1;
588 static gint ett_icmpv6_rpl_flag_prefix = -1;
589 static gint ett_icmpv6_rpl_route_discovery_flag = -1;
590 static gint ett_icmpv6_rpl_route_discovery_addr_vec = -1;
591 static gint ett_icmpv6_rpl_p2p_dro_flag = -1;
592 static gint ett_icmpv6_rpl_p2p_droack_flag = -1;
593 static gint ett_icmpv6_flag_ni = -1;
594 static gint ett_icmpv6_flag_rr = -1;
595 static gint ett_icmpv6_rr_mp = -1;
596 static gint ett_icmpv6_rr_up = -1;
597 static gint ett_icmpv6_rr_up_flag_mask = -1;
598 static gint ett_icmpv6_rr_up_flag_ra = -1;
599 static gint ett_icmpv6_rr_up_flag = -1;
600 static gint ett_icmpv6_rr_rm = -1;
601 static gint ett_icmpv6_rr_rm_flag = -1;
602 static gint ett_icmpv6_flag_mld = -1;
603 static gint ett_icmpv6_flag_ra = -1;
604 static gint ett_icmpv6_flag_na = -1;
605 static gint ett_icmpv6_flag_mip6 = -1;
606 static gint ett_icmpv6_flag_fmip6 = -1;
607 static gint ett_icmpv6_flag_secure = -1;
608 static gint ett_icmpv6_flag_rpl_dio = -1;
609 static gint ett_icmpv6_flag_rpl_dao = -1;
610 static gint ett_icmpv6_flag_rpl_daoack = -1;
611 static gint ett_icmpv6_flag_rpl_cc = -1;
612 static gint ett_icmpv6_opt_name = -1;
613 static gint ett_icmpv6_cga_param_name = -1;
614 static gint ett_icmpv6_mpl_seed_info = -1;
615 static gint ett_icmpv6_mpl_seed_info_bm = -1;
616 
617 static expert_field ei_icmpv6_invalid_option_length = EI_INIT;
618 static expert_field ei_icmpv6_undecoded_option = EI_INIT;
619 static expert_field ei_icmpv6_unknown_data = EI_INIT;
620 static expert_field ei_icmpv6_undecoded_rpl_option = EI_INIT;
621 static expert_field ei_icmpv6_undecoded_type = EI_INIT;
622 static expert_field ei_icmpv6_rr_pco_mp_matchlen = EI_INIT;
623 static expert_field ei_icmpv6_rr_pco_mp_matchedlen = EI_INIT;
624 static expert_field ei_icmpv6_checksum = EI_INIT;
625 static expert_field ei_icmpv6_resp_not_found = EI_INIT;
626 static expert_field ei_icmpv6_rpl_unknown_metric = EI_INIT;
627 static expert_field ei_icmpv6_rpl_p2p_hop_by_hop = EI_INIT;
628 static expert_field ei_icmpv6_rpl_p2p_num_of_routes = EI_INIT;
629 static expert_field ei_icmpv6_rpl_p2p_dro_rdo_zero = EI_INIT;
630 static expert_field ei_icmpv6_rpl_p2p_dro_zero = EI_INIT;
631 
632 static dissector_handle_t icmpv6_handle;
633 
634 static dissector_handle_t ipv6_handle;
635 static dissector_handle_t icmp_extension_handle;
636 
637 #define ICMP6_DST_UNREACH                 1
638 #define ICMP6_PACKET_TOO_BIG              2
639 #define ICMP6_TIME_EXCEEDED               3
640 #define ICMP6_PARAM_PROB                  4
641 #define ICMP6_ECHO_REQUEST              128
642 #define ICMP6_ECHO_REPLY                129
643 #define ICMP6_MEMBERSHIP_QUERY          130
644 #define ICMP6_MEMBERSHIP_REPORT         131
645 #define ICMP6_MEMBERSHIP_REDUCTION      132
646 #define ICMP6_ND_ROUTER_SOLICIT         133
647 #define ICMP6_ND_ROUTER_ADVERT          134
648 #define ICMP6_ND_NEIGHBOR_SOLICIT       135
649 #define ICMP6_ND_NEIGHBOR_ADVERT        136
650 #define ICMP6_ND_REDIRECT               137
651 #define ICMP6_ROUTER_RENUMBERING        138
652 #define ICMP6_NI_QUERY                  139
653 #define ICMP6_NI_REPLY                  140
654 #define ICMP6_IND_SOLICIT               141
655 #define ICMP6_IND_ADVERT                142
656 #define ICMP6_MLDV2_REPORT              143
657 #define ICMP6_MIP6_DHAAD_REQUEST        144
658 #define ICMP6_MIP6_DHAAD_REPLY          145
659 #define ICMP6_MIP6_MPS                  146
660 #define ICMP6_MIP6_MPA                  147
661 #define ICMP6_CERT_PATH_SOL             148
662 #define ICMP6_CERT_PATH_AD              149
663 #define ICMP6_EXPERIMENTAL_MOBILITY     150
664 #define ICMP6_MCAST_ROUTER_ADVERT       151
665 #define ICMP6_MCAST_ROUTER_SOLICIT      152
666 #define ICMP6_MCAST_ROUTER_TERM         153
667 #define ICMP6_FMIPV6_MESSAGES           154
668 #define ICMP6_RPL_CONTROL               155
669 #define ICMP6_ILNPV6                    156
670 #define ICMP6_6LOWPANND_DAR             157
671 #define ICMP6_6LOWPANND_DAC             158
672 #define ICMP6_MPL_CONTROL               159
673 #define ICMP6_EXTECHO                   160
674 #define ICMP6_EXTECHOREPLY              161
675 
676 
677 static const value_string icmpv6_type_val[] = {
678     { ICMP6_DST_UNREACH,           "Destination Unreachable" },                         /* [RFC4443] */
679     { ICMP6_PACKET_TOO_BIG,        "Packet Too Big" },                                  /* [RFC4443] */
680     { ICMP6_TIME_EXCEEDED,         "Time Exceeded" },                                   /* [RFC4443] */
681     { ICMP6_PARAM_PROB,            "Parameter Problem" },                               /* [RFC4443] */
682     { 100,                         "Private experimentation" },                         /* [RFC4443] */
683     { 101,                         "Private experimentation" },                         /* [RFC4443] */
684     { 127,                         "Reserved for expansion of ICMPv6 error messages" }, /* [RFC4443] */
685     { ICMP6_ECHO_REQUEST,          "Echo (ping) request" },                             /* [RFC4443] */
686     { ICMP6_ECHO_REPLY,            "Echo (ping) reply" },                               /* [RFC4443] */
687     { ICMP6_MEMBERSHIP_QUERY,      "Multicast Listener Query" },                        /* [RFC2710] */
688     { ICMP6_MEMBERSHIP_REPORT,     "Multicast Listener Report" },                       /* [RFC2710] */
689     { ICMP6_MEMBERSHIP_REDUCTION,  "Multicast Listener Done" },                         /* [RFC2710] */
690     { ICMP6_ND_ROUTER_SOLICIT,     "Router Solicitation" },                             /* [RFC4861] */
691     { ICMP6_ND_ROUTER_ADVERT,      "Router Advertisement" },                            /* [RFC4861] */
692     { ICMP6_ND_NEIGHBOR_SOLICIT,   "Neighbor Solicitation" },                           /* [RFC4861] */
693     { ICMP6_ND_NEIGHBOR_ADVERT,    "Neighbor Advertisement" },                          /* [RFC4861] */
694     { ICMP6_ND_REDIRECT,           "Redirect" },                                        /* [RFC4861] */
695     { ICMP6_ROUTER_RENUMBERING,    "Router Renumbering" },                              /* [RFC2894] */
696     { ICMP6_NI_QUERY,              "Node Information Query" },                          /* [RFC4620] */
697     { ICMP6_NI_REPLY,              "Node Information Reply" },                          /* [RFC4620] */
698     { ICMP6_IND_SOLICIT,           "Inverse Neighbor Discovery Solicitation" },         /* [RFC3122] */
699     { ICMP6_IND_ADVERT,            "Inverse Neighbor Discovery Advertisement" },        /* [RFC3122] */
700     { ICMP6_MLDV2_REPORT,          "Multicast Listener Report Message v2" },            /* [RFC3810] */
701     { ICMP6_MIP6_DHAAD_REQUEST,    "Home Agent Address Discovery Request" },            /* [RFC6275] */
702     { ICMP6_MIP6_DHAAD_REPLY,      "Home Agent Address Discovery Reply" },              /* [RFC6275] */
703     { ICMP6_MIP6_MPS,              "Mobile Prefix Solicitation" },                      /* [RFC6275] */
704     { ICMP6_MIP6_MPA,              "Mobile Prefix Advertisement" },                     /* [RFC6275] */
705     { ICMP6_CERT_PATH_SOL,         "Certification Path Solicitation" },                 /* [RFC3971] */
706     { ICMP6_CERT_PATH_AD,          "Certification Path Advertisement" },                /* [RFC3971] */
707     { ICMP6_EXPERIMENTAL_MOBILITY, "Experimental Mobility" },                           /* [RFC4065] */
708     { ICMP6_MCAST_ROUTER_ADVERT,   "Multicast Router Advertisement" },                  /* [RFC4286] */
709     { ICMP6_MCAST_ROUTER_SOLICIT,  "Multicast Router Solicitation" },                   /* [RFC4286] */
710     { ICMP6_MCAST_ROUTER_TERM,     "Multicast Router Termination" },                    /* [RFC4286] */
711     { ICMP6_FMIPV6_MESSAGES,       "FMIPv6" },                                          /* [RFC5568] */
712     { ICMP6_RPL_CONTROL,           "RPL Control" },                                     /* [RFC6550] */
713     { ICMP6_ILNPV6,                "Locator Update"},                                   /* [RFC6743] */
714     { ICMP6_6LOWPANND_DAR,         "Duplicate Address Request"},                        /* [RFC6775] */
715     { ICMP6_6LOWPANND_DAC,         "Duplicate Address Confirmation"},                   /* [RFC6775] */
716     { ICMP6_MPL_CONTROL,           "MPL Control Message"},                              /* [RFC7731] */
717     { ICMP6_EXTECHO,               "Extended Echo request"},                            /* [RFC8335] */
718     { ICMP6_EXTECHOREPLY,          "Extended Echo reply"},                              /* [RFC8335] */
719     { 200,                         "Private experimentation" },                         /* [RFC4443] */
720     { 201,                         "Private experimentation" },                         /* [RFC4443] */
721     { 255,                         "Reserved for expansion of ICMPv6 informational messages" }, /* [RFC4443] */
722     { 0, NULL }
723 };
724 
725 #define ICMP6_DST_UNREACH_NOROUTE               0       /* no route to destination */
726 #define ICMP6_DST_UNREACH_ADMIN                 1       /* administratively prohibited */
727 #define ICMP6_DST_UNREACH_NOTNEIGHBOR           2       /* not a neighbor(obsolete) */
728 #define ICMP6_DST_UNREACH_BEYONDSCOPE           2       /* beyond scope of source address */
729 #define ICMP6_DST_UNREACH_ADDR                  3       /* address unreachable */
730 #define ICMP6_DST_UNREACH_NOPORT                4       /* port unreachable */
731 #define ICMP6_DST_UNREACH_INGR_EGR              5       /* source address failed ingress/egress policy */
732 #define ICMP6_DST_UNREACH_REJECT                6       /* reject route to destination */
733 #define ICMP6_DST_UNREACH_ERROR                 7       /* error in Source Routing Header */
734 
735 static const value_string icmpv6_unreach_code_val[] = {
736     { ICMP6_DST_UNREACH_NOROUTE,     "no route to destination" },
737     { ICMP6_DST_UNREACH_ADMIN,       "Administratively prohibited" },
738     { ICMP6_DST_UNREACH_BEYONDSCOPE, "Beyond scope of source address" },
739     { ICMP6_DST_UNREACH_ADDR,        "Address unreachable" },
740     { ICMP6_DST_UNREACH_NOPORT,      "Port unreachable" },
741     { ICMP6_DST_UNREACH_INGR_EGR,    "Source address failed ingress/egress policy" },
742     { ICMP6_DST_UNREACH_REJECT,      "Reject route to destination" },
743     { ICMP6_DST_UNREACH_ERROR,       "Error in Source Routing Header" }, /* [RFC6550] [RFC6554] */
744     { 0, NULL }
745 };
746 
747 #define ICMP6_TIME_EXCEED_TRANSIT       0       /* ttl==0 in transit */
748 #define ICMP6_TIME_EXCEED_REASSEMBLY    1       /* ttl==0 in reass */
749 
750 static const value_string icmpv6_timeex_code_val[] = {
751     { ICMP6_TIME_EXCEED_TRANSIT,    "hop limit exceeded in transit" },
752     { ICMP6_TIME_EXCEED_REASSEMBLY, "fragment reassembly time exceeded" },
753     { 0, NULL }
754 };
755 
756 #define ICMP6_PARAMPROB_HEADER                  0       /* erroneous header field */
757 #define ICMP6_PARAMPROB_NEXTHEADER              1       /* unrecognized next header */
758 #define ICMP6_PARAMPROB_OPTION                  2       /* unrecognized option */
759 #define ICMP6_PARAMPROB_FIRSTFRAG               3       /* IPv6 First Fragment has incomplete IPv6 Header Chain [RFC 7112] */
760 
761 static const value_string icmpv6_paramprob_code_val[] = {
762     { ICMP6_PARAMPROB_HEADER,     "erroneous header field encountered" },
763     { ICMP6_PARAMPROB_NEXTHEADER, "unrecognized Next Header type encountered" },
764     { ICMP6_PARAMPROB_OPTION,     "unrecognized IPv6 option encountered" },
765     { ICMP6_PARAMPROB_FIRSTFRAG,  "IPv6 First Fragment has incomplete IPv6 Header Chain" },
766     { 0, NULL }
767 };
768 
769 
770 /* RFC2894 - Router Renumbering for IPv6 */
771 
772 #define ICMP6_ROUTER_RENUMBERING_COMMAND          0     /* rr command */
773 #define ICMP6_ROUTER_RENUMBERING_RESULT           1     /* rr result */
774 #define ICMP6_ROUTER_RENUMBERING_SEQNUM_RESET   255     /* rr seq num reset */
775 
776 static const value_string icmpv6_rr_code_val[] = {
777     { ICMP6_ROUTER_RENUMBERING_COMMAND,      "Command" },
778     { ICMP6_ROUTER_RENUMBERING_RESULT,       "Result" },
779     { ICMP6_ROUTER_RENUMBERING_SEQNUM_RESET, "Sequence number reset" },
780     { 0, NULL }
781 };
782 
783 #define RR_FLAG_T       0x80
784 #define RR_FLAG_R       0x40
785 #define RR_FLAG_A       0x20
786 #define RR_FLAG_S       0x10
787 #define RR_FLAG_P       0x08
788 #define RR_FLAG_RSV     0x07
789 
790 static const value_string rr_pco_mp_opcode_val[] = {
791     { 1,    "Add" },
792     { 2,    "Change" },
793     { 3,    "Set Global" },
794     { 0,    NULL }
795 };
796 
797 
798 /* RFC3810 - Multicast Listener Discovery Version 2 (MLDv2) for IPv6 */
799 
800 #define MLDV2_PACKET_MINLEN 28
801 
802 #define MLD_FLAG_S      0x08
803 #define MLD_FLAG_QRV    0x07
804 #define MLD_FLAG_RSV    0xF0
805 
806 static const value_string mldr_record_type_val[] = {
807     { 1, "Include" },
808     { 2, "Exclude" },
809     { 3, "Changed to include" },
810     { 4, "Changed to exclude" },
811     { 5, "Allow new sources" },
812     { 6, "Block old sources" },
813     { 0, NULL }
814 };
815 
816 /* RFC 4068/5268/5568: Fast Handovers for Mobile IPv6 ( Mobile IPv6 Fast Handovers ) */
817 
818 #define FMIP6_SUBTYPE_RTSOLPR   2
819 #define FMIP6_SUBTYPE_PRRTADV   3
820 #define FMIP6_SUBTYPE_HI        4
821 #define FMIP6_SUBTYPE_HACK      5
822 
823 static const value_string fmip6_subtype_val[] = {
824     { FMIP6_SUBTYPE_RTSOLPR,    "Router Solicitation for Proxy Advertisement" },
825     { FMIP6_SUBTYPE_PRRTADV,    "Proxy Router Advertisement" },
826     { FMIP6_SUBTYPE_HI,         "Handover Initiate" },
827     { FMIP6_SUBTYPE_HACK,       "Handover Acknowledge" },
828     { 0,                        NULL }
829 };
830 
831 static const value_string fmip6_prrtadv_code_val[] = {
832     { 0,   "MN should use AP-ID, AR-info tuple" },
833     { 1,   "Network Initiated Handover trigger" },
834     { 2,   "No new router information" },
835     { 3,   "Limited new router information" },
836     { 4,   "Unsolicited" },
837     { 0,    NULL }
838 };
839 
840 static const value_string fmip6_hi_code_val[] = {
841     { 0,    "FBU sent from previous link" },
842     { 1,    "FBU sent from new link" },
843     { 0,    NULL }
844 };
845 
846 static const value_string fmip6_hack_code_val[] = {
847     { 0,    "Handover Accepted, NCoA valid" },
848     { 1,    "Handover Accepted, NCoA not valid" },
849     { 2,    "Handover Accepted, NCoA in use" },
850     { 3,    "Handover Accepted, NCoA assigned" },
851     { 4,    "Handover Accepted, NCoA not assigned" },
852     { 128,  "Handover Not Accepted, reason unspecified" },
853     { 129,  "Administratively prohibited" },
854     { 130,  "Insufficient resources" },
855     { 0,    NULL }
856 };
857 
858 #define FMIP6_HI_FLAG_S     0x80
859 #define FMIP6_HI_FLAG_U     0x40
860 #define FMIP6_HI_FLAG_RSV   0x3F
861 
862 /* RFC 4620 - IPv6 Node Information Queries */
863 
864 #define ICMP6_NI_SUBJ_IPV6      0   /* Query Subject is an IPv6 address */
865 #define ICMP6_NI_SUBJ_FQDN      1   /* Query Subject is a Domain name */
866 #define ICMP6_NI_SUBJ_IPV4      2   /* Query Subject is an IPv4 address */
867 
868 #define ICMP6_NI_SUCCESS        0   /* node information successful reply */
869 #define ICMP6_NI_REFUSED        1   /* node information request is refused */
870 #define ICMP6_NI_UNKNOWN        2   /* unknown Qtype */
871 
872 #define NI_QTYPE_NOOP           0   /* NOOP  */
873 #define NI_QTYPE_SUPTYPES       1   /* Supported Qtypes (Obso) */
874 #define NI_QTYPE_NODENAME       2   /* Node Name */
875 #define NI_QTYPE_NODEADDR       3   /* Node Addresses */
876 #define NI_QTYPE_IPV4ADDR       4   /* IPv4 Addresses */
877 
878 static const value_string ni_query_code_val[] = {
879     { ICMP6_NI_SUBJ_IPV6,   "Query subject = IPv6 addresses" },
880     { ICMP6_NI_SUBJ_FQDN,   "Query subject = DNS name or empty" },
881     { ICMP6_NI_SUBJ_IPV4,   "Query subject = IPv4 addresses" },
882     { 0, NULL }
883 };
884 
885 static const value_string ni_reply_code_val[] = {
886     { ICMP6_NI_SUCCESS,   "Successful" },
887     { ICMP6_NI_REFUSED,   "Refused" },
888     { ICMP6_NI_UNKNOWN,   "Unknown query type" },
889     { 0, NULL }
890 };
891 static const value_string ni_qtype_val[] = {
892     { NI_QTYPE_NOOP,            "NOOP" },
893     { NI_QTYPE_SUPTYPES,        "Supported query types (Obsolete)" },
894     { NI_QTYPE_NODENAME,        "Node Name" },
895     { NI_QTYPE_NODEADDR,        "Node addresses" },
896     { NI_QTYPE_IPV4ADDR,        "IPv4 node addresses" },
897     { 0,                        NULL }
898 };
899 
900 #define NI_FLAG_G       0x0020
901 #define NI_FLAG_S       0x0010
902 #define NI_FLAG_L       0x0008
903 #define NI_FLAG_C       0x0004
904 #define NI_FLAG_A       0x0002
905 #define NI_FLAG_T       0x0001
906 #define NI_FLAG_RSV     0xFFC0
907 
908 static const true_false_string tfs_ni_flag_a = {
909     "All unicast address",
910     "Unicast addresses on the queried interface"
911 };
912 
913 #define ND_OPT_SOURCE_LINKADDR           1
914 #define ND_OPT_TARGET_LINKADDR           2
915 #define ND_OPT_PREFIX_INFORMATION        3
916 #define ND_OPT_REDIRECTED_HEADER         4
917 #define ND_OPT_MTU                       5
918 #define ND_OPT_NBMA                      6
919 #define ND_OPT_ADVINTERVAL               7
920 #define ND_OPT_HOMEAGENT_INFO            8
921 #define ND_OPT_SOURCE_ADDRLIST           9
922 #define ND_OPT_TARGET_ADDRLIST          10
923 #define ND_OPT_CGA                      11
924 #define ND_OPT_RSA                      12
925 #define ND_OPT_TIMESTAMP                13
926 #define ND_OPT_NONCE                    14
927 #define ND_OPT_TRUST_ANCHOR             15
928 #define ND_OPT_CERTIFICATE              16
929 #define ND_OPT_IP_ADDRESS_PREFIX        17
930 #define ND_OPT_NEW_ROUTER_PREFIX_INFO   18
931 #define ND_OPT_LINK_LAYER_ADDRESS       19
932 #define ND_OPT_NEIGHBOR_ADV_ACK         20
933 #define ND_OPT_MAP                      23
934 #define ND_OPT_ROUTE_INFO               24
935 #define ND_OPT_RECURSIVE_DNS_SERVER     25
936 #define ND_OPT_FLAGS_EXTENSION          26
937 #define ND_OPT_HANDOVER_KEY_REQUEST     27
938 #define ND_OPT_HANDOVER_KEY_REPLY       28
939 #define ND_OPT_HANDOVER_ASSIST_INFO     29
940 #define ND_OPT_MOBILE_NODE_ID           30
941 #define ND_OPT_DNS_SEARCH_LIST          31
942 #define ND_OPT_PROXY_SIGNATURE          32
943 #define ND_OPT_ADDR_REGISTRATION        33
944 #define ND_OPT_6LOWPAN_CONTEXT          34
945 #define ND_OPT_AUTH_BORDER_ROUTER       35
946 #define ND_OPT_6CIO                     36
947 #define ND_OPT_CAPPORT                  37
948 #define ND_OPT_PREF64                   38
949 
950 static const value_string option_vals[] = {
951 /*  1 */   { ND_OPT_SOURCE_LINKADDR,           "Source link-layer address" },
952 /*  2 */   { ND_OPT_TARGET_LINKADDR,           "Target link-layer address" },
953 /*  3 */   { ND_OPT_PREFIX_INFORMATION,        "Prefix information" },
954 /*  4 */   { ND_OPT_REDIRECTED_HEADER,         "Redirected header" },
955 /*  5 */   { ND_OPT_MTU,                       "MTU" },
956 /*  6 */   { ND_OPT_NBMA,                      "NBMA Shortcut Limit Option" },             /* [RFC2491] */
957 /*  7 */   { ND_OPT_ADVINTERVAL,               "Advertisement Interval" },                 /* [RFC6275] */
958 /*  8 */   { ND_OPT_HOMEAGENT_INFO,            "Home Agent Information" },                 /* [RFC6275] */
959 /*  9 */   { ND_OPT_SOURCE_ADDRLIST,           "Source Address List" },                    /* [RFC3122] */
960 /* 10 */   { ND_OPT_TARGET_ADDRLIST,           "Target Address List" },                    /* [RFC3122] */
961 /* 11 */   { ND_OPT_CGA,                       "CGA" },                                    /* [RFC3971] */
962 /* 12 */   { ND_OPT_RSA,                       "RSA Signature" },                          /* [RFC3971] */
963 /* 13 */   { ND_OPT_TIMESTAMP,                 "Timestamp" },                              /* [RFC3971] */
964 /* 14 */   { ND_OPT_NONCE,                     "Nonce" },                                  /* [RFC3971] */
965 /* 15 */   { ND_OPT_TRUST_ANCHOR,              "Trust Anchor" },                           /* [RFC3971] */
966 /* 16 */   { ND_OPT_CERTIFICATE,               "Certificate" },                            /* [RFC3971] */
967 /* 17 */   { ND_OPT_IP_ADDRESS_PREFIX,         "IP Address/Prefix Option" },               /* [RFC5568] */
968 /* 18 */   { ND_OPT_NEW_ROUTER_PREFIX_INFO,    "New Router Prefix Information" },          /* [RFC4068] OBSO */
969 /* 19 */   { ND_OPT_LINK_LAYER_ADDRESS,        "Link-layer Address" },                     /* [RFC5568] */
970 /* 20 */   { ND_OPT_NEIGHBOR_ADV_ACK,          "Neighbor Advertisement Acknowledgment" },  /* [RFC5568] */
971 /* 21-22   Unassigned */
972 /* 23 */   { ND_OPT_MAP,                       "MAP" },                                    /* [RFC4140] */
973 /* 24 */   { ND_OPT_ROUTE_INFO,                "Route Information" },                      /* [RFC4191] */
974 /* 25 */   { ND_OPT_RECURSIVE_DNS_SERVER,      "Recursive DNS Server" },                   /* [RFC6106] */
975 /* 26 */   { ND_OPT_FLAGS_EXTENSION,           "RA Flags Extension" },                     /* [RFC5175] */
976 /* 27 */   { ND_OPT_HANDOVER_KEY_REQUEST,      "Handover Key Request" },                   /* [RFC5269] */
977 /* 28 */   { ND_OPT_HANDOVER_KEY_REPLY,        "Handover Key Reply" },                     /* [RFC5269] */
978 /* 29 */   { ND_OPT_HANDOVER_ASSIST_INFO,      "Handover Assist Information" },            /* [RFC5271] */
979 /* 30 */   { ND_OPT_MOBILE_NODE_ID,            "Mobile Node Identifier Option" },          /* [RFC5271] */
980 /* 31 */   { ND_OPT_DNS_SEARCH_LIST,           "DNS Search List Option" },                 /* [RFC6106] */
981 /* 32 */   { ND_OPT_PROXY_SIGNATURE,           "Proxy Signature (PS)" },                   /* [RFC6496] */
982 /* 33 */   { ND_OPT_ADDR_REGISTRATION,         "Address Registration Option" },            /* [RFC6775] */
983 /* 34 */   { ND_OPT_6LOWPAN_CONTEXT,           "6LoWPAN Context Option" },                 /* [RFC6775] */
984 /* 35 */   { ND_OPT_AUTH_BORDER_ROUTER,        "Authoritative Border Router" },            /* [RFC6775] */
985 /* 36 */   { ND_OPT_6CIO,                      "6LoWPAN Capability Indication Option" },   /* [RFC7400] */
986 /* 37 */   { ND_OPT_CAPPORT,                   "DHCP Captive-Portal" },                    /* [RFC7710] */
987 /* 38 */   { ND_OPT_PREF64,                    "PREF64 Option" },                          /* [RFC8781] */
988 /* 39-137  Unassigned */
989    { 138,                              "CARD Request" },                           /* [RFC4065] */
990    { 139,                              "CARD Reply" },                             /* [RFC4065] */
991 /* 140-252 Unassigned */
992    { 253,                              "RFC3692-style Experiment 1" },             /* [RFC4727] */
993    { 254,                              "RFC3692-style Experiment 2" },             /* [RFC4727] */
994    { 0,                                NULL }
995 };
996 
997 #define ND_RA_FLAG_M    0x80
998 #define ND_RA_FLAG_O    0x40
999 #define ND_RA_FLAG_H    0x20
1000 #define ND_RA_FLAG_PRF  0x18
1001 #define ND_RA_FLAG_P    0x04
1002 #define ND_RA_FLAG_RSV  0x02
1003 
1004 #define ND_NA_FLAG_R    0x80000000
1005 #define ND_NA_FLAG_S    0x40000000
1006 #define ND_NA_FLAG_O    0x20000000
1007 #define ND_NA_FLAG_RSV  0x1FFFFFFF
1008 
1009 static const value_string nd_flag_router_pref[] = {
1010     { 0, "Medium" },
1011     { 1, "High" },
1012     { 2, "Reserved" },
1013     { 3, "Low" },
1014     { 0, NULL}
1015 };
1016 
1017 static const value_string nd_opt_ipa_option_code_val[] = {
1018     { 1, "Old Care-of Address" },
1019     { 2, "New Care-of Address" },
1020     { 3, "NAR's IP address" },
1021     { 4, "NAR's Prefix (sent in PrRtAdv)" },
1022     { 0, NULL }
1023 };
1024 
1025 static const value_string nd_opt_lla_option_code_val[] = {
1026     { 0, "Wildcard" },
1027     { 1, "Link-layer Address of the New Access Point" },
1028     { 2, "Link-layer Address of the MN" },
1029     { 3, "Link-layer Address of the NAR" },
1030     { 4, "Link-layer Address of the source" },
1031     { 5, "The AP belongs to the current interface of the router" },
1032     { 6, "No prefix information available" },
1033     { 7, "No fast handovers support available" },
1034     { 0, NULL }
1035 };
1036 
1037 static const value_string nd_opt_hai_option_code_val[] = {
1038     { 1, "Access Network Identifier (AN ID)" },
1039     { 2, "Sector ID" },
1040     { 0, NULL }
1041 };
1042 
1043 static const value_string nd_opt_mn_option_code_val[] = {
1044     { 1, "NAI" },
1045     { 2, "IMSI" },
1046     { 0, NULL }
1047 };
1048 static const value_string nd_opt_naack_status_val[] = {
1049     { 1,    "New CoA is invalid, perform address configuration" },
1050     { 2,    "New CoA is invalid, use the supplied CoA" },
1051     { 3,    "NCoA is invalid, use NAR's IP address as NCoA in FBU" },
1052     { 4,    "PCoA supplied, do not send FBU" },
1053     { 128,  "LLA is unrecognized" },
1054     { 0,    NULL }
1055 };
1056 
1057 #define ND_OPT_6CO_FLAG_C        0x10
1058 #define ND_OPT_6CO_FLAG_CID      0x0F
1059 #define ND_OPT_6CO_FLAG_RESERVED 0xE0
1060 
1061 static const value_string nd_opt_6lowpannd_status_val[] = {
1062     { 0, "Success" },
1063     { 1, "Duplicate Exists" },
1064     { 2, "Neighbor Cache Full" },
1065     { 0, NULL }
1066 };
1067 
1068 static const value_string icmpv6_option_name_type_vals[] = {
1069     { 1,    "DER Encoded X.501 Name" },
1070     { 2,    "FQDN" },
1071     { 3,    "SHA-1 Subject Key Identifier (SKI)" },
1072     { 4,    "SHA-224 Subject Key Identifier (SKI)" },
1073     { 5,    "SHA-256 Subject Key Identifier (SKI)" },
1074     { 6,    "SHA-384 Subject Key Identifier (SKI)" },
1075     { 7,    "SHA-512 Subject Key Identifier (SKI)" },
1076     { 253,  "Reserved for Experimental Use" },
1077     { 254,  "Reserved for Experimental Use" },
1078     { 255,  "Reserved" },
1079     { 0,    NULL }
1080 };
1081 
1082 static const value_string icmpv6_option_cert_type_vals[] = {
1083     { 1,    "X.509v3 Certificate" },
1084     { 0,    NULL }
1085 };
1086 
1087 /* RFC 4191: Default Router Preferences and More-Specific Routes  */
1088 
1089 #define ND_RA_FLAG_RTPREF_MASK  0x18 /* 00011000 */
1090 #define ND_RA_FLAG_RESERV_MASK  0xE7 /* 11100111 */
1091 
1092 /* RFC 5075/5175 : IPv6 Router Advertisement Flags Option */
1093 #define FLAGS_EO_M      0x8000
1094 #define FLAGS_EO_O      0x4000
1095 #define FLAGS_EO_H      0x2000
1096 #define FLAGS_EO_PRF    0x1800
1097 #define FLAGS_EO_P      0x0400
1098 #define FLAGS_EO_RSV    0x02FF
1099 
1100 
1101 
1102 /* RPL : RFC 6550 : Routing over Low-Power and Lossy Networks. */
1103 /* RPL ICMPv6 Codes */
1104 #define ICMP6_RPL_DIS           0x00   /* DODAG Information Solicitation */
1105 #define ICMP6_RPL_DIO           0x01   /* DODAG Information Object */
1106 #define ICMP6_RPL_DAO           0x02   /* Destination Advertisement Object */
1107 #define ICMP6_RPL_DAOACK        0x03   /* Destination Advertisement Object Ack */
1108 #define ICMP6_RPL_P2P_DRO       0x04   /* P2P Discovery Reply Object */
1109 #define ICMP6_RPL_P2P_DROACK    0x05   /* P2P Discovery Reply Object Acknowledgement */
1110 #define ICMP6_RPL_SDIS          0x80   /* Secure DODAG Information Solicitation */
1111 #define ICMP6_RPL_SDIO          0x81   /* Secure DODAG Information Object */
1112 #define ICMP6_RPL_SDAO          0x82   /* Secure Destination Advertisement Object */
1113 #define ICMP6_RPL_SDAOACK       0x83   /* Secure Destination Advertisement Object Ack */
1114 #define ICMP6_RPL_P2P_SDRO      0x84   /* Secure P2P Discovery Reply Object */
1115 #define ICMP6_RPL_P2P_SDROACK   0x85   /* Secure P2P Discovery Reply Object Acknowledgement */
1116 #define ICMP6_RPL_CC            0x8A   /* Consistency Check */
1117 
1118 
1119 /* RPL DIO Flags */
1120 #define RPL_DIO_FLAG_G           0x80
1121 #define RPL_DIO_FLAG_0           0x40
1122 #define RPL_DIO_FLAG_MOP         0x38
1123 #define RPL_DIO_FLAG_PRF         0x07
1124 
1125 /* RPL DAO Flags */
1126 #define RPL_DAO_FLAG_K                  0x80
1127 #define RPL_DAO_FLAG_D                  0x40
1128 #define RPL_DAO_FLAG_RESERVED           0x3F
1129 
1130 /* RPL DAO ACK Flags */
1131 #define RPL_DAOACK_FLAG_D               0x80
1132 #define RPL_DAOACK_FLAG_RESERVED        0x7F
1133 
1134 /* RPL CC Flags */
1135 #define RPL_CC_FLAG_R               0x80
1136 #define RPL_CC_FLAG_RESERVED        0x7F
1137 
1138 /* RPL Secure */
1139 #define ICMP6_RPL_SECURE    0x80
1140 
1141 #define RPL_SECURE_FLAG_T   0x80
1142 #define RPL_SECURE_FLAG_RSV 0x7F
1143 
1144 #define RPL_SECURE_LVL      0x07
1145 #define RPL_SECURE_KIM      0xC0
1146 #define RPL_SECURE_RSV      0x38
1147 
1148 /* RPL P2P DRO Flags */
1149 #define RPL_P2P_DRO_FLAG_S      0x8000
1150 #define RPL_P2P_DRO_FLAG_A      0x4000
1151 #define RPL_P2P_DRO_FLAG_SEQ    0x3000
1152 #define RPL_P2P_DRO_FLAG_RSV    0x0FFF
1153 
1154 /* RPL P2P DROACK Flags */
1155 #define RPL_P2P_DROACK_FLAG_SEQ    0xc000
1156 #define RPL_P2P_DROACK_FLAG_RSV    0x3FFF
1157 
1158 /* RPL Option Bitfields */
1159 #define RPL_OPT_PREFIX_FLAG_L           0x80
1160 #define RPL_OPT_PREFIX_FLAG_A           0x40
1161 #define RPL_OPT_PREFIX_FLAG_R           0x20
1162 #define RPL_OPT_PREFIX_FLAG_RSV         0x1F
1163 #define RPL_OPT_ROUTE_PREFERENCE        0x18
1164 #define RPL_OPT_ROUTE_RESERVED          0xE7
1165 #define RPL_OPT_CONFIG_FLAG_AUTH        0x08
1166 #define RPL_OPT_CONFIG_FLAG_PCS         0x07
1167 #define RPL_OPT_CONFIG_FLAG_RESERVED    0xF0
1168 #define RPL_OPT_TRANSIT_FLAG_E          0x80
1169 #define RPL_OPT_TRANSIT_FLAG_RSV        0x7F
1170 #define RPL_OPT_SOLICITED_FLAG_V        0x80
1171 #define RPL_OPT_SOLICITED_FLAG_I        0x40
1172 #define RPL_OPT_SOLICITED_FLAG_D        0x20
1173 #define RPL_OPT_SOLICITED_FLAG_RSV      0x1F
1174 #define RPL_OPT_ROUTE_DISCOVERY_R       0x80
1175 #define RPL_OPT_ROUTE_DISCOVERY_H       0x40
1176 #define RPL_OPT_ROUTE_DISCOVERY_N       0x30
1177 #define RPL_OPT_ROUTE_DISCOVERY_COMPR   0x0F
1178 #define RPL_OPT_ROUTE_DISCOVERY_L       0xC0
1179 #define RPL_OPT_ROUTE_DISCOVERY_MR_NH   0x3F
1180 
1181 /* RPL Metric Bitfields */
1182 #define RPL_METRIC_RESERVED              0xF800
1183 #define RPL_METRIC_FLAG_P                0x0400
1184 #define RPL_METRIC_FLAG_C                0x0200
1185 #define RPL_METRIC_FLAG_O                0x0100
1186 #define RPL_METRIC_FLAG_R                0x0080
1187 #define RPL_METRIC_A                     0x0070
1188 #define RPL_METRIC_PREC                  0x000F
1189 #define RPL_METRIC_NSA_OBJECT_RESERVED   0xFF00
1190 #define RPL_METRIC_NSA_OBJECT_FLAGS      0x00FC
1191 #define RPL_METRIC_NSA_OBJECT_FLAG_A     0x0002
1192 #define RPL_METRIC_NSA_OBJECT_FLAG_O     0x0001
1193 #define RPL_METRIC_NE_OBJECT_FLAGS       0xF000
1194 #define RPL_METRIC_NE_OBJECT_FLAG_I      0x0800
1195 #define RPL_METRIC_NE_OBJECT_TYPE        0x0600
1196 #define RPL_METRIC_NE_OBJECT_FLAG_E      0x0100
1197 #define RPL_METRIC_NE_OBJECT_ENERGY      0x00FF
1198 #define RPL_METRIC_HP_OBJECT_RESERVED    0xF000
1199 #define RPL_METRIC_HP_OBJECT_FLAGS       0x0F00
1200 #define RPL_METRIC_HP_OBJECT_HP          0x00FF
1201 #define RPL_METRIC_LQL_OBJECT_RES        0xFF
1202 #define RPL_METRIC_LQL_OBJECT_VAL        0xE0
1203 #define RPL_METRIC_LQL_OBJECT_COUNTER    0x1F
1204 #define RPL_METRIC_LC_OBJECT_RES         0xFF
1205 #define RPL_METRIC_LC_OBJECT_LC          0xFFC0
1206 #define RPL_METRIC_LC_OBJECT_COUNTER     0x003F
1207 #define RPL_METRIC_LC_OBJECT_RESERVED    0x003E
1208 #define RPL_METRIC_LC_OBJECT_FLAG_I      0x0001
1209 
1210 static const value_string rpl_dio_map_val[] = {
1211     { 0, "No Downward routes maintained by RPL" },
1212     { 1, "Non-Storing Mode of Operation" },
1213     { 2, "Storing Mode of Operation with no multicast support" },
1214     { 3, "Storing Mode of Operation with multicast support" },
1215     { 4, "P2P Route Discovery Mode of Operation" },
1216     { 0, NULL }
1217 };
1218 static const value_string rpl_code_val[] = {
1219     { ICMP6_RPL_DIS,        "DODAG Information Solicitation" },
1220     { ICMP6_RPL_DIO,        "DODAG Information Object" },
1221     { ICMP6_RPL_DAO,        "Destination Advertisement Object" },
1222     { ICMP6_RPL_DAOACK,     "Destination Advertisement Object Acknowledgment" },
1223     { ICMP6_RPL_SDIS,       "Secure DODAG Information Solicitation" },
1224     { ICMP6_RPL_SDIO,       "Secure DODAG Information Object" },
1225     { ICMP6_RPL_SDAO,       "Secure Destination Advertisement Object" },
1226     { ICMP6_RPL_SDAOACK,    "Secure Destination Advertisement Object Acknowledgment" },
1227     { ICMP6_RPL_CC,         "Consistency Check" },
1228     { ICMP6_RPL_P2P_DRO,    "P2P Discovery Reply Object" },
1229     { ICMP6_RPL_P2P_SDRO,   "P2P Secure Discovery Reply Object" },
1230     { ICMP6_RPL_P2P_DROACK, "P2P Discovery Reply Object Acknowledgement" },
1231     { ICMP6_RPL_P2P_SDROACK,"P2P Secure Discovery Reply Object Acknowledgement" },
1232     { 0, NULL }
1233 };
1234 
1235 static const value_string rpl_secure_algorithm_vals[] = {
1236     { 0, "Encryption: CCM with AES-128 / Signature: RSA with SHA-256" },
1237     { 0, NULL }
1238 };
1239 
1240 /* RPL Option Types */
1241 /* Pending IANA Assignment */
1242 #define RPL_OPT_PAD1            0   /* 1-byte padding */
1243 #define RPL_OPT_PADN            1   /* n-byte padding */
1244 #define RPL_OPT_METRIC          2   /* DAG metric container */
1245 #define RPL_OPT_ROUTING         3   /* Routing Information */
1246 #define RPL_OPT_CONFIG          4   /* DAG configuration */
1247 #define RPL_OPT_TARGET          5   /* RPL Target */
1248 #define RPL_OPT_TRANSIT         6   /* Transit */
1249 #define RPL_OPT_SOLICITED       7   /* Solicited Information */
1250 #define RPL_OPT_PREFIX          8   /* Destination prefix */
1251 #define RPL_OPT_TARGETDESC      9   /* RPL Target Descriptor */
1252 #define RPL_OPT_ROUTE_DISCOVERY 10  /* P2P Route Discovery */
1253 
1254 static const value_string rpl_option_vals[] = {
1255     { RPL_OPT_PAD1,             "1-byte padding" },
1256     { RPL_OPT_PADN,             "n-byte padding" },
1257     { RPL_OPT_METRIC,           "DAG Metric container" },
1258     { RPL_OPT_ROUTING,          "Routing Information"},
1259     { RPL_OPT_CONFIG,           "DODAG configuration" },
1260     { RPL_OPT_TARGET,           "RPL Target" },
1261     { RPL_OPT_TRANSIT,          "Transit Information" },
1262     { RPL_OPT_SOLICITED,        "Solicited Information"},
1263     { RPL_OPT_PREFIX,           "Prefix Information"},
1264     { RPL_OPT_TARGETDESC,       "RPL Target Descriptor"},
1265     { RPL_OPT_ROUTE_DISCOVERY,  "P2P Route Discovery"},
1266     { 0, NULL }
1267 };
1268 
1269 /* RPL Metric Types */
1270 /* RFC 6551 */
1271 #define RPL_METRIC_NSA 1  /* Node State and Attribute */
1272 #define RPL_METRIC_NE  2  /* Node Energy */
1273 #define RPL_METRIC_HP  3  /* Hop Count */
1274 #define RPL_METRIC_LT  4  /* Link Throughput */
1275 #define RPL_METRIC_LL  5  /* Link Latency */
1276 #define RPL_METRIC_LQL 6  /* Link Quality Level */
1277 #define RPL_METRIC_ETX 7  /* Link ETX */
1278 #define RPL_METRIC_LC  8  /* Link Color */
1279 
1280 static const value_string rpl_metric_vals[] = {
1281   { RPL_METRIC_NSA,  "Node State and Attribute" },
1282   { RPL_METRIC_NE,   "Node Energy" },
1283   { RPL_METRIC_HP,   "Hop Count" },
1284   { RPL_METRIC_LT,   "Link Throughput" },
1285   { RPL_METRIC_LL,   "Link Latency" },
1286   { RPL_METRIC_LQL,  "Link Quality Level" },
1287   { RPL_METRIC_ETX,  "Link ETX" },
1288   { RPL_METRIC_LC,   "Link Color" },
1289   { 0, NULL }
1290 };
1291 
1292 /* RFC 7400 */
1293 #define ND_OPT_6CIO_FLAG_G          0x0001
1294 #define ND_OPT_6CIO_FLAG_UNASSIGNED 0xFFFE
1295 
1296 /* RFC 7731 */
1297 #define MPL_SEED_INFO_BM_LEN        0xFC
1298 #define MPL_SEED_INFO_S             0x03
1299 static const value_string mpl_seed_id_lengths[] = {
1300     { 0, "0 bit, not included in MPL Seed Info" },
1301     { 1, "16 bits" },
1302     { 2, "64 bits" },
1303     { 3, "128 bits" },
1304     { 0, NULL}
1305 };
1306 static const guint8 mpl_seed_id_code_to_length[] = { 0, 2, 8, 16 }; /* bytes */
1307 
1308 static const value_string unique_infinity[] = {
1309     { 0xffffffff, "Infinity" },
1310     { 0, NULL}
1311 };
1312 
1313 static const value_string dnssl_infinity[] = {
1314     { 0, "DNSSL domain name MUST no longer be used" },
1315     { 0xffffffff, "Infinity" },
1316     { 0, NULL}
1317 };
1318 
1319 static const value_string rdnss_infinity[] = {
1320     { 0, "RDNSS address MUST no longer be used" },
1321     { 0xffffffff, "Infinity" },
1322     { 0, NULL}
1323 };
1324 
1325 static const value_string ext_echo_req_code_str[] = {
1326     { 0, "No error"},
1327     { 0, NULL}
1328 };
1329 
1330 static const value_string ext_echo_reply_code_str[] = {
1331     { 0, "No error"},
1332     { 1, "Malformed Query"},
1333     { 2, "No Such Interface"},
1334     { 3, "No Such Table Entry"},
1335     { 4, "Multiple Interfaces Satisfy Query"},
1336     { 0, NULL}
1337     };
1338 
1339 static const value_string ext_echo_reply_state_str[] = {
1340     { 0, "Reserved"},
1341     { 1, "Incomplete"},
1342     { 2, "Reachable"},
1343     { 3, "Stale"},
1344     { 4, "Delay"},
1345     { 5, "Probe"},
1346     { 6, "Failed"},
1347     { 0, NULL}
1348     };
1349 
1350 
1351 /* RFC 8781 */
1352 #define ND_OPT_PREF64_SL          0xFFF8
1353 #define ND_OPT_PREF64_PLC         0x0007
1354 
1355 static const value_string pref64_plc_str[] = {
1356     { 0, "96 bits prefix length"},
1357     { 1, "64 bits prefix length"},
1358     { 2, "56 bits prefix length"},
1359     { 3, "48 bits prefix length"},
1360     { 4, "40 bits prefix length"},
1361     { 5, "32 bits prefix length"},
1362     { 0, NULL}
1363     };
1364 
1365 /* whenever a ICMPv6 packet is seen by the tap listener */
1366 /* Add a new frame into the graph */
1367 static tap_packet_status
icmpv6_seq_analysis_packet(void * ptr,packet_info * pinfo,epan_dissect_t * edt _U_,const void * dummy _U_)1368 icmpv6_seq_analysis_packet( void *ptr, packet_info *pinfo, epan_dissect_t *edt _U_, const void *dummy _U_)
1369 {
1370     seq_analysis_info_t *sainfo = (seq_analysis_info_t *) ptr;
1371     seq_analysis_item_t *sai = sequence_analysis_create_sai_with_addresses(pinfo, sainfo);
1372 
1373     if (!sai)
1374         return TAP_PACKET_DONT_REDRAW;
1375 
1376     sai->frame_number = pinfo->num;
1377 
1378     sequence_analysis_use_color_filter(pinfo, sai);
1379 
1380     sai->port_src=pinfo->srcport;
1381     sai->port_dst=pinfo->destport;
1382 
1383     sequence_analysis_use_col_info_as_label_comment(pinfo, sai);
1384 
1385     if (pinfo->ptype == PT_NONE) {
1386         icmp_info_t *p_icmp_info = (icmp_info_t *)p_get_proto_data(wmem_file_scope(), pinfo, proto_icmpv6, 0);
1387 
1388         if (p_icmp_info != NULL) {
1389             sai->port_src = 0;
1390             sai->port_dst = p_icmp_info->type * 256 + p_icmp_info->code;
1391         }
1392     }
1393 
1394     sai->line_style = 1;
1395     sai->conv_num = 0;
1396     sai->display = TRUE;
1397 
1398     g_queue_push_tail(sainfo->items, sai);
1399 
1400     return TAP_PACKET_REDRAW;
1401 }
1402 
1403 
1404 static int
dissect_contained_icmpv6(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree)1405 dissect_contained_icmpv6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1406 {
1407     gboolean  save_in_error_pkt;
1408     gint offset;
1409 
1410     /* Save the current value of the "we're inside an error packet"
1411        flag, and set that flag; subdissectors may treat packets
1412        that are the payload of error packets differently from
1413        "real" packets. */
1414     save_in_error_pkt = pinfo->flags.in_error_pkt;
1415     pinfo->flags.in_error_pkt = TRUE;
1416 
1417     /* tiny sanity check */
1418     if ((tvb_get_guint8(tvb, 0) & 0xf0) == 0x60) {
1419         /* The contained packet is an IPv6 datagram; dissect it. */
1420         offset = call_dissector(ipv6_handle, tvb, pinfo, tree);
1421     } else {
1422         offset = call_data_dissector(tvb, pinfo, tree);
1423     }
1424 
1425     /* Restore the "we're inside an error packet" flag. */
1426     pinfo->flags.in_error_pkt = save_in_error_pkt;
1427 
1428     return offset;
1429 }
1430 
1431 
1432 /* ======================================================================= */
_find_or_create_conversation(packet_info * pinfo)1433 static conversation_t *_find_or_create_conversation(packet_info *pinfo)
1434 {
1435     conversation_t *conv = NULL;
1436 
1437     /* Have we seen this conversation before? */
1438     conv = find_conversation(pinfo->num, &pinfo->src, &pinfo->dst,
1439         conversation_pt_to_endpoint_type(pinfo->ptype), 0, 0, 0);
1440     if (conv == NULL) {
1441         /* No, this is a new conversation. */
1442         conv = conversation_new(pinfo->num, &pinfo->src, &pinfo->dst,
1443             conversation_pt_to_endpoint_type(pinfo->ptype), 0, 0, 0);
1444     }
1445     return conv;
1446 }
1447 
1448 /* ======================================================================= */
1449 /*
1450     Note: We are tracking conversations via these keys:
1451 
1452     0                   1                   2                   3
1453     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1454    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1455    |                             |G|            Checksum           |
1456    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1457    |           Identifier          |        Sequence Number        |
1458    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1459    |                            VLAN ID                            |
1460    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1461 */
transaction_start(packet_info * pinfo,proto_tree * tree,guint32 * key)1462 static icmp_transaction_t *transaction_start(packet_info *pinfo, proto_tree *tree, guint32 *key)
1463 {
1464     conversation_t     *conversation;
1465     icmpv6_conv_info_t *icmpv6_info;
1466     icmp_transaction_t *icmpv6_trans;
1467     wmem_tree_key_t     icmpv6_key[3];
1468     proto_item         *it;
1469 
1470     /* Handle the conversation tracking */
1471     conversation = _find_or_create_conversation(pinfo);
1472     icmpv6_info = (icmpv6_conv_info_t *)conversation_get_proto_data(conversation, proto_icmpv6);
1473     if (icmpv6_info == NULL) {
1474         icmpv6_info = wmem_new(wmem_file_scope(), icmpv6_conv_info_t);
1475         icmpv6_info->unmatched_pdus = wmem_tree_new(wmem_file_scope());
1476         icmpv6_info->matched_pdus = wmem_tree_new(wmem_file_scope());
1477         conversation_add_proto_data(conversation, proto_icmpv6, icmpv6_info);
1478     }
1479 
1480     if (!PINFO_FD_VISITED(pinfo)) {
1481         /*
1482          * This is a new request, create a new transaction structure and map it
1483          * to the unmatched table.
1484          */
1485         icmpv6_key[0].length = 3;
1486         icmpv6_key[0].key = key;
1487         icmpv6_key[1].length = 0;
1488         icmpv6_key[1].key = NULL;
1489 
1490         icmpv6_trans = wmem_new(wmem_file_scope(), icmp_transaction_t);
1491         icmpv6_trans->rqst_frame = pinfo->num;
1492         icmpv6_trans->resp_frame = 0;
1493         icmpv6_trans->rqst_time = pinfo->abs_ts;
1494         nstime_set_zero(&icmpv6_trans->resp_time);
1495         wmem_tree_insert32_array(icmpv6_info->unmatched_pdus, icmpv6_key, (void *)icmpv6_trans);
1496     } else {
1497         /* Already visited this frame */
1498         guint32 frame_num = pinfo->num;
1499 
1500         icmpv6_key[0].length = 3;
1501         icmpv6_key[0].key = key;
1502         icmpv6_key[1].length = 1;
1503         icmpv6_key[1].key = &frame_num;
1504         icmpv6_key[2].length = 0;
1505         icmpv6_key[2].key = NULL;
1506 
1507         icmpv6_trans = (icmp_transaction_t *)wmem_tree_lookup32_array(icmpv6_info->matched_pdus, icmpv6_key);
1508     }
1509 
1510     if (icmpv6_trans == NULL) {
1511         if (pinfo->dst.type == AT_IPv6 &&
1512                     in6_addr_is_multicast((const ws_in6_addr *)pinfo->dst.data)) {
1513             /* XXX We should support multicast echo requests, but we don't currently */
1514             /* Note the multicast destination and skip transaction tracking */
1515             col_append_str(pinfo->cinfo, COL_INFO, " (multicast)");
1516         } else if (PINFO_FD_VISITED(pinfo)) {
1517             /* No response found - add field and expert info */
1518             it = proto_tree_add_item(tree, hf_icmpv6_no_resp, NULL, 0, 0,
1519                                      ENC_NA);
1520             proto_item_set_generated(it);
1521 
1522             col_append_fstr(pinfo->cinfo, COL_INFO, " (no response found!)");
1523 
1524             /* Expert info.  TODO: add to _icmp_transaction_t type and sequence number
1525                so can report here (and in taps) */
1526             expert_add_info_format(pinfo, it, &ei_icmpv6_resp_not_found,
1527                                    "No response seen to ICMPv6 request in frame %u",
1528                                    pinfo->num);
1529         }
1530 
1531         return NULL;
1532     }
1533 
1534     /* Print state tracking in the tree */
1535     if (icmpv6_trans->resp_frame) {
1536         if (tree) {
1537             it = proto_tree_add_uint(tree, hf_icmpv6_resp_in, NULL, 0, 0,
1538                 icmpv6_trans->resp_frame);
1539             proto_item_set_generated(it);
1540         }
1541         col_append_frame_number(pinfo, COL_INFO, " (reply in %d)", icmpv6_trans->resp_frame);
1542     }
1543 
1544     return icmpv6_trans;
1545 
1546 } /* transaction_start() */
1547 
1548 /* ======================================================================= */
transaction_end(packet_info * pinfo,proto_tree * tree,guint32 * key)1549 static icmp_transaction_t *transaction_end(packet_info *pinfo, proto_tree *tree, guint32 *key)
1550 {
1551     conversation_t     *conversation;
1552     icmpv6_conv_info_t *icmpv6_info;
1553     icmp_transaction_t *icmpv6_trans;
1554     wmem_tree_key_t     icmpv6_key[3];
1555     proto_item         *it;
1556     nstime_t            ns;
1557     double resp_time;
1558 
1559     conversation = find_conversation(pinfo->num, &pinfo->src, &pinfo->dst,
1560         conversation_pt_to_endpoint_type(pinfo->ptype), 0, 0, 0);
1561     if (conversation == NULL)
1562         return NULL;
1563 
1564     icmpv6_info = (icmpv6_conv_info_t *)conversation_get_proto_data(conversation, proto_icmpv6);
1565     if (icmpv6_info == NULL)
1566         return NULL;
1567 
1568     if (!PINFO_FD_VISITED(pinfo)) {
1569         guint32 frame_num;
1570 
1571         icmpv6_key[0].length = 3;
1572         icmpv6_key[0].key = key;
1573         icmpv6_key[1].length = 0;
1574         icmpv6_key[1].key = NULL;
1575 
1576         icmpv6_trans = (icmp_transaction_t *)wmem_tree_lookup32_array(icmpv6_info->unmatched_pdus, icmpv6_key);
1577         if (icmpv6_trans == NULL)
1578             return NULL;
1579 
1580         /* we have already seen this response, or an identical one */
1581         if (icmpv6_trans->resp_frame != 0)
1582             return NULL;
1583 
1584         icmpv6_trans->resp_frame = pinfo->num;
1585 
1586         /*
1587          * we found a match.  Add entries to the matched table for both
1588          * request and reply frames
1589          */
1590         icmpv6_key[0].length = 3;
1591         icmpv6_key[0].key = key;
1592         icmpv6_key[1].length = 1;
1593         icmpv6_key[1].key = &frame_num;
1594         icmpv6_key[2].length = 0;
1595         icmpv6_key[2].key = NULL;
1596 
1597         frame_num = icmpv6_trans->rqst_frame;
1598         wmem_tree_insert32_array(icmpv6_info->matched_pdus, icmpv6_key, (void *)icmpv6_trans);
1599 
1600         frame_num = icmpv6_trans->resp_frame;
1601         wmem_tree_insert32_array(icmpv6_info->matched_pdus, icmpv6_key, (void *)icmpv6_trans);
1602     } else {
1603         /* Already visited this frame */
1604         guint32 frame_num = pinfo->num;
1605 
1606         icmpv6_key[0].length = 3;
1607         icmpv6_key[0].key = key;
1608         icmpv6_key[1].length = 1;
1609         icmpv6_key[1].key = &frame_num;
1610         icmpv6_key[2].length = 0;
1611         icmpv6_key[2].key = NULL;
1612 
1613         icmpv6_trans = (icmp_transaction_t *)wmem_tree_lookup32_array(icmpv6_info->matched_pdus, icmpv6_key);
1614         if (icmpv6_trans == NULL)
1615             return NULL;
1616     }
1617 
1618     /* Print state tracking in the tree */
1619     if (tree) {
1620         it = proto_tree_add_uint(tree, hf_icmpv6_resp_to, NULL, 0, 0,
1621             icmpv6_trans->rqst_frame);
1622         proto_item_set_generated(it);
1623     }
1624 
1625     nstime_delta(&ns, &pinfo->abs_ts, &icmpv6_trans->rqst_time);
1626     icmpv6_trans->resp_time = ns;
1627     if (tree) {
1628         resp_time = nstime_to_msec(&ns);
1629         it = proto_tree_add_double_format_value(tree, hf_icmpv6_resptime, NULL,
1630             0, 0, resp_time, "%.3f ms", resp_time);
1631         proto_item_set_generated(it);
1632     }
1633 
1634     col_append_frame_number(pinfo, COL_INFO, " (request in %d)",
1635         icmpv6_trans->rqst_frame);
1636 
1637     return icmpv6_trans;
1638 
1639 } /* transaction_end() */
1640 
1641 static int
dissect_icmpv6_nd_opt(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree)1642 dissect_icmpv6_nd_opt(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
1643 {
1644     proto_tree *icmp6opt_tree;
1645     proto_item *ti, *ti_opt, *ti_opt_len;
1646     guint8      opt_type;
1647     int         opt_len;
1648     int         opt_offset;
1649     tvbuff_t   *opt_tvb;
1650     guint       used_bytes;
1651 
1652     while ((int)tvb_reported_length(tvb) > offset) {
1653         /* there are more options */
1654 
1655         /* ICMPv6 Option */
1656         opt_len = tvb_get_guint8(tvb, offset + 1) * 8;
1657         ti = proto_tree_add_item(tree, hf_icmpv6_opt, tvb, offset, opt_len, ENC_NA);
1658         icmp6opt_tree = proto_item_add_subtree(ti, ett_icmpv6_opt);
1659         opt_offset = offset;
1660 
1661         /* Option type */
1662         proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_type, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
1663         opt_type = tvb_get_guint8(tvb, opt_offset);
1664         opt_offset += 1;
1665 
1666         /* Add option name to option root label */
1667         proto_item_append_text(ti, " (%s", val_to_str(opt_type, option_vals, "Unknown %d"));
1668 
1669         /* Option length */
1670         ti_opt_len = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_length, tvb,opt_offset, 1, ENC_BIG_ENDIAN);
1671         opt_offset += 1;
1672 
1673         /* Add length value in bytes */
1674         proto_item_append_text(ti_opt_len, " (%i bytes)", opt_len);
1675 
1676         if(opt_len == 0){
1677             expert_add_info_format(pinfo, ti_opt_len, &ei_icmpv6_invalid_option_length, "Invalid option length (Zero)");
1678             return opt_offset;
1679         }
1680 
1681         /* decode... */
1682         switch (opt_type) {
1683             case ND_OPT_SOURCE_LINKADDR: /* Source Link-layer Address (1) */
1684             {
1685                 const gchar *link_str;
1686                 /* if the opt len is 8, the Link Addr is MAC Address */
1687                 if(opt_len == 8){
1688                     proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_linkaddr_mac, tvb, opt_offset, 6, ENC_NA);
1689                     ti_opt = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_src_linkaddr_mac, tvb, opt_offset, 6, ENC_NA);
1690                     proto_item_set_hidden(ti_opt);
1691 
1692                     link_str = tvb_ether_to_str(pinfo->pool, tvb, opt_offset);
1693                     col_append_fstr(pinfo->cinfo, COL_INFO, " from %s", link_str);
1694                     proto_item_append_text(ti, " : %s", link_str);
1695                 /* if the opt len is 16 and the 6 last bytes is 0n the Link Addr is EUI64 Address */
1696                 }else if(opt_len == 16 && tvb_get_ntohl(tvb, opt_offset + 8) == 0 && tvb_get_ntohs(tvb, opt_offset + 12) == 0){
1697                     proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_linkaddr_eui64, tvb, opt_offset, 8, ENC_BIG_ENDIAN);
1698                     ti_opt = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_src_linkaddr_eui64, tvb, opt_offset, 8, ENC_BIG_ENDIAN);
1699                     proto_item_set_hidden(ti_opt);
1700                     ti_opt = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_linkaddr, tvb, opt_offset, 8, ENC_NA);
1701                     proto_item_set_hidden(ti_opt);
1702                     ti_opt = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_src_linkaddr, tvb, opt_offset, 8, ENC_NA);
1703                     proto_item_set_hidden(ti_opt);
1704 
1705                     /* Padding: 6 bytes */
1706                     proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_padding, tvb, opt_offset + 8, 6, ENC_NA);
1707 
1708                     link_str = tvb_eui64_to_str(pinfo->pool, tvb, opt_offset);
1709                     col_append_fstr(pinfo->cinfo, COL_INFO, " from %s", link_str);
1710                     proto_item_append_text(ti, " : %s", link_str);
1711                 }else{
1712                     proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_linkaddr, tvb, opt_offset, opt_len-2, ENC_NA);
1713                     ti_opt = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_src_linkaddr, tvb, opt_offset, opt_len-2, ENC_NA);
1714                     proto_item_set_hidden(ti_opt);
1715                 }
1716                 opt_offset += opt_len;
1717 
1718                 break;
1719             }
1720             case ND_OPT_TARGET_LINKADDR: /* Target Link-layer Address (2) */
1721             {
1722                 const gchar *link_str;
1723                 /* if the opt len is 8, the Link Addr is MAC Address */
1724                 if(opt_len == 8){
1725                     proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_linkaddr_mac, tvb, opt_offset, 6, ENC_NA);
1726                     ti_opt = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_target_linkaddr_mac, tvb, opt_offset, 6, ENC_NA);
1727                     proto_item_set_hidden(ti_opt);
1728 
1729                     link_str = tvb_ether_to_str(pinfo->pool, tvb, opt_offset);
1730                     col_append_fstr(pinfo->cinfo, COL_INFO, " is at %s", link_str);
1731                     proto_item_append_text(ti, " : %s", link_str);
1732 
1733                 /* if the opt len is 16 and the 6 last bytes is 0n the Link Addr is EUI64 Address */
1734                 }else if(opt_len == 16 && tvb_get_ntohl(tvb, opt_offset + 8) == 0 && tvb_get_ntohs(tvb, opt_offset + 12) == 0){
1735                     proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_linkaddr_eui64, tvb, opt_offset, 8, ENC_BIG_ENDIAN);
1736                     ti_opt = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_target_linkaddr_eui64, tvb, opt_offset, 8, ENC_BIG_ENDIAN);
1737                     proto_item_set_hidden(ti_opt);
1738 
1739                     /* Padding: 6 bytes */
1740                     proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_padding, tvb, opt_offset + 8, 6, ENC_NA);
1741 
1742                     link_str = tvb_eui64_to_str(pinfo->pool, tvb, opt_offset);
1743                     col_append_fstr(pinfo->cinfo, COL_INFO, " from %s", link_str);
1744                     proto_item_append_text(ti, " : %s", link_str);
1745                 }else{
1746                     proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_linkaddr, tvb, opt_offset, opt_len-2, ENC_NA);
1747                     ti_opt = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_target_linkaddr, tvb, opt_offset, opt_len-2, ENC_NA);
1748                     proto_item_set_hidden(ti_opt);
1749                 }
1750                 opt_offset += opt_len;
1751                 break;
1752             }
1753             case ND_OPT_PREFIX_INFORMATION: /* Prefix Information (3) */
1754             {
1755                 static int * const prefix_flag[] = {
1756                     &hf_icmpv6_opt_prefix_flag_l,
1757                     &hf_icmpv6_opt_prefix_flag_a,
1758                     &hf_icmpv6_opt_prefix_flag_r,
1759                     &hf_icmpv6_opt_prefix_flag_reserved,
1760                     NULL
1761                 };
1762 
1763                 guint8 prefix_len;
1764                 /* RFC 4861 */
1765 
1766                 /* Prefix Length */
1767                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_prefix_len, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
1768                 prefix_len = tvb_get_guint8(tvb, opt_offset);
1769                 opt_offset += 1;
1770 
1771                 /* Flags */
1772                 proto_tree_add_bitmask(icmp6opt_tree, tvb, opt_offset, hf_icmpv6_opt_prefix_flag, ett_icmpv6_flag_prefix, prefix_flag, ENC_BIG_ENDIAN);
1773                 opt_offset += 1;
1774 
1775                 /* Prefix Valid Lifetime */
1776                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_prefix_valid_lifetime, tvb, opt_offset, 4, ENC_BIG_ENDIAN);
1777                 opt_offset += 4;
1778 
1779                 /* Prefix Preferred Lifetime */
1780                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_prefix_preferred_lifetime, tvb, opt_offset, 4, ENC_BIG_ENDIAN);
1781                 opt_offset += 4;
1782 
1783                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_reserved, tvb, opt_offset, 4, ENC_NA);
1784                 opt_offset += 4;
1785 
1786                 /* Prefix */
1787                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_prefix, tvb, opt_offset, 16, ENC_NA);
1788                 proto_item_append_text(ti, " : %s/%d", tvb_ip6_to_str(pinfo->pool, tvb, opt_offset), prefix_len);
1789                 opt_offset += 16;
1790 
1791                 break;
1792             }
1793             case ND_OPT_REDIRECTED_HEADER: /* Redirected Header (4) */
1794 
1795                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_reserved, tvb, opt_offset, 6, ENC_NA);
1796                 opt_offset += 6;
1797 
1798                 if (opt_len > 8) {
1799                     proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_redirected_packet, tvb, opt_offset, opt_len - 8, ENC_NA);
1800                     opt_tvb = tvb_new_subset_length(tvb, opt_offset, opt_len - 8);
1801                     opt_offset += dissect_contained_icmpv6(opt_tvb, pinfo, icmp6opt_tree);
1802                 }
1803                 break;
1804             case ND_OPT_MTU: /* MTU (5) */
1805 
1806                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_reserved, tvb, opt_offset, 2, ENC_NA);
1807                 opt_offset += 2;
1808 
1809                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_mtu, tvb, opt_offset, 4, ENC_BIG_ENDIAN);
1810                 proto_item_append_text(ti, " : %d", tvb_get_ntohl(tvb, opt_offset));
1811                 opt_offset += 4;
1812                 break;
1813             case ND_OPT_NBMA: /* NBMA Shortcut Limit Option (6) */
1814 
1815                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_nbma_shortcut_limit, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
1816                 proto_item_append_text(ti, " : %d", tvb_get_guint8(tvb, opt_offset));
1817 
1818                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_reserved, tvb, opt_offset, 1, ENC_NA);
1819                 opt_offset += 1;
1820 
1821                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_reserved, tvb, opt_offset, 4, ENC_NA);
1822                 opt_offset += 4;
1823 
1824                 break;
1825             case ND_OPT_ADVINTERVAL: /* Advertisement Interval Option (7) */
1826 
1827                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_reserved, tvb, opt_offset, 2, ENC_NA);
1828                 opt_offset += 2;
1829 
1830                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_advertisement_interval, tvb, opt_offset, 4, ENC_BIG_ENDIAN);
1831                 proto_item_append_text(ti, " : %d", tvb_get_ntohl(tvb, opt_offset));
1832                 opt_offset += 4;
1833 
1834                 break;
1835             case ND_OPT_HOMEAGENT_INFO: /* Home Agent Information Option (8) */
1836             {
1837 
1838                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_reserved, tvb, opt_offset, 2, ENC_NA);
1839                 opt_offset += 2;
1840 
1841                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_home_agent_preference, tvb, opt_offset, 2, ENC_BIG_ENDIAN);
1842                 opt_offset += 2;
1843 
1844                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_home_agent_lifetime, tvb, opt_offset, 2, ENC_BIG_ENDIAN);
1845                 opt_offset += 2;
1846                 break;
1847             }
1848             case  ND_OPT_SOURCE_ADDRLIST: /* Source Address List (9) */
1849             case  ND_OPT_TARGET_ADDRLIST: /* Target Address List (10)*/
1850             {
1851                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_reserved, tvb, opt_offset, 6, ENC_NA);
1852                 opt_offset += 6;
1853 
1854                 while(opt_offset < (offset + opt_len) ) {
1855                     proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_ipv6_address, tvb, opt_offset, 16, ENC_NA);
1856                     proto_item_append_text(ti, " %s", tvb_ip6_to_str(pinfo->pool, tvb, opt_offset));
1857                     opt_offset += 16;
1858                 }
1859                 break;
1860             }
1861             case ND_OPT_CGA: /* CGA Option (11) */
1862             {
1863                 proto_tree *cga_tree;
1864                 proto_item *cga_item;
1865                 guint16 ext_data_len;
1866                 guint8 padd_length;
1867                 int par_len;
1868                 asn1_ctx_t asn1_ctx;
1869 
1870                 /* Pad Length */
1871                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_cga_pad_len, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
1872                 padd_length = tvb_get_guint8(tvb, opt_offset);
1873                 opt_offset += 1;
1874 
1875                 /* Reserved 8 bits */
1876 
1877                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_reserved, tvb, opt_offset, 1, ENC_NA);
1878                 opt_offset += 1;
1879 
1880                 /* CGA Parameters A variable-length field containing the CGA Parameters data
1881                  * structure described in Section 4 of
1882                  * "Cryptographically Generated Addresses (CGA)", RFC3972.
1883                  */
1884                 par_len = opt_len -4 -padd_length;
1885                 cga_item = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_cga, tvb, opt_offset, par_len, ENC_NA);
1886                 par_len += opt_offset;
1887 
1888                 cga_tree = proto_item_add_subtree(cga_item, ett_icmpv6_cga_param_name);
1889                 proto_tree_add_item(cga_tree, hf_icmpv6_opt_cga_modifier, tvb, opt_offset, 16, ENC_NA);
1890                 opt_offset += 16;
1891 
1892                 proto_tree_add_item(cga_tree, hf_icmpv6_opt_cga_subnet_prefix, tvb, opt_offset, 8, ENC_NA);
1893                 opt_offset += 8;
1894 
1895                 proto_tree_add_item(cga_tree ,hf_icmpv6_opt_cga_count, tvb, opt_offset, 1, ENC_NA);
1896                 opt_offset += 1;
1897 
1898                 asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo);
1899                 opt_offset = dissect_x509af_SubjectPublicKeyInfo(FALSE, tvb, opt_offset, &asn1_ctx, cga_tree, -1);
1900 
1901                 /* Process RFC 4581*/
1902                 while (opt_offset < par_len) {
1903                     proto_tree_add_item(cga_tree, hf_icmpv6_opt_cga_ext_type, tvb, opt_offset, 2, ENC_BIG_ENDIAN);
1904                     opt_offset += 2;
1905 
1906                     ext_data_len = tvb_get_ntohs(tvb, opt_offset);
1907                     proto_tree_add_item(cga_tree, hf_icmpv6_opt_cga_ext_length, tvb, opt_offset, 2, ENC_BIG_ENDIAN);
1908                     opt_offset += 2;
1909 
1910                     proto_tree_add_item(cga_tree, hf_icmpv6_opt_cga_ext_data, tvb, opt_offset, ext_data_len, ENC_NA);
1911                     opt_offset += ext_data_len;
1912                 }
1913 
1914                 /* Padding */
1915                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_padding, tvb, opt_offset, padd_length, ENC_NA);
1916                 opt_offset += padd_length;
1917                 break;
1918             }
1919             case ND_OPT_RSA: /* RSA Signature Option (12) */
1920             {
1921                 int par_len;
1922                 /*5.2.  RSA Signature Option */
1923                 /* Reserved, A 16-bit field reserved for future use. */
1924                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_reserved, tvb, opt_offset, 2, ENC_NA);
1925                 opt_offset = opt_offset + 2;
1926 
1927                 /* Key Hash
1928                  * A 128-bit field containing the most significant (leftmost) 128
1929                  * bits of a SHA-1 [14] hash of the public key used for constructing
1930                  * the signature.
1931                  */
1932                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_rsa_key_hash, tvb, opt_offset, 16, ENC_NA);
1933                 opt_offset = opt_offset + 16;
1934 
1935                 /* Digital Signature */
1936                 par_len = opt_len - 20;
1937                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_digital_signature_padding , tvb, opt_offset, par_len, ENC_NA);
1938                 opt_offset += par_len;
1939 
1940                 /* Padding */
1941                 /* TODO: Calculate padding length and exclude from the signature */
1942                 break;
1943             }
1944             case ND_OPT_TIMESTAMP: /* Timestamp Option (13) */
1945                 /* Reserved A 48-bit field reserved for future use. */
1946                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_reserved, tvb, opt_offset, 6, ENC_NA);
1947                 opt_offset += 6;
1948 
1949                 /* Timestamp
1950                  * A 64-bit unsigned integer field containing a timestamp.  The value
1951                  * indicates the number of seconds since January 1, 1970, 00:00 UTC,
1952                  * by using a fixed point format.  In this format, the integer number
1953                  * of seconds is contained in the first 48 bits of the field, and the
1954                  * remaining 16 bits indicate the number of 1/64K fractions of a
1955                  * second.
1956                  */
1957                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_timestamp, tvb, opt_offset, 8, ENC_TIME_RFC_3971|ENC_BIG_ENDIAN);
1958                 opt_offset += 8;
1959                 break;
1960             case ND_OPT_NONCE: /* Nonce option (14) */
1961 
1962                 /* 5.3.2.  Nonce Option */
1963                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_nonce, tvb, opt_offset, opt_len - 2, ENC_NA);
1964                 opt_offset += opt_len -2;
1965                 break;
1966             case ND_OPT_TRUST_ANCHOR: /* Trust Anchor Option (15) */
1967             {
1968                 proto_tree *name_tree;
1969                 proto_item *name_item;
1970                 guint8 name_type;
1971                 guint8 padd_length;
1972                 int par_len;
1973                 asn1_ctx_t asn1_ctx;
1974 
1975                 /* Name Type */
1976                 name_type = tvb_get_guint8(tvb, opt_offset);
1977                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_name_type, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
1978                 opt_offset += 1;
1979 
1980                 /* Pad Length */
1981                 padd_length = tvb_get_guint8(tvb, opt_offset);
1982                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_cga_pad_len, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
1983                 opt_offset += 1;
1984 
1985                 par_len = opt_len - 4 - padd_length;
1986 
1987                 switch (name_type){
1988                     case 1:
1989                         /* DER Encoded X.501 Name */
1990                         name_item = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_name_x501, tvb, opt_offset, par_len, ENC_NA);
1991                         name_tree = proto_item_add_subtree(name_item, ett_icmpv6_opt_name);
1992                         asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo);
1993                         dissect_x509if_Name(FALSE, tvb, opt_offset, &asn1_ctx, name_tree, hf_icmpv6_x509if_Name);
1994                         break;
1995                     case 2:
1996                         /* FQDN */
1997                         proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_name_fqdn, tvb, opt_offset, par_len, ENC_ASCII|ENC_NA);
1998                         break;
1999                     default:
2000                         break;
2001                 }
2002                 opt_offset += par_len;
2003 
2004                 /* Padding */
2005                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_padding, tvb, opt_offset, padd_length, ENC_NA);
2006                 opt_offset += padd_length;
2007 
2008                 break;
2009             }
2010             case ND_OPT_CERTIFICATE: /* Certificate Option (16) */
2011             {
2012                 guint8 cert_type;
2013                 guint8 padd_length;
2014                 asn1_ctx_t asn1_ctx;
2015 
2016                 /* Cert Type */
2017                 cert_type = tvb_get_guint8(tvb, opt_offset);
2018                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_cert_type, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
2019                 opt_offset += 1;
2020 
2021                 /* Reserved */
2022                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_reserved, tvb, opt_offset, 1, ENC_NA);
2023                 opt_offset += 1;
2024 
2025                 /* Certificate */
2026 
2027                 if(cert_type == 1){
2028                     asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo);
2029                     opt_offset = dissect_x509af_Certificate(FALSE, tvb, opt_offset, &asn1_ctx, icmp6opt_tree, hf_icmpv6_x509af_Certificate);
2030                     padd_length = opt_len - (opt_offset - offset);
2031                     /* Padding */
2032                     proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_padding, tvb, opt_offset, padd_length, ENC_NA);
2033                     opt_offset += padd_length;
2034                 }else{
2035                     padd_length = opt_len - 4;
2036                     proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_certificate_padding, tvb, opt_offset, padd_length, ENC_NA);
2037                     opt_offset += padd_length;
2038                 }
2039                 break;
2040 
2041             }
2042             case ND_OPT_IP_ADDRESS_PREFIX: /* IP Address/Prefix Option (17) */
2043             {
2044                 guint8 prefix_len;
2045 
2046                 /* Option-code */
2047                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_ipa_option_code, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
2048                 opt_offset += 1;
2049 
2050                 /* Prefix Len */
2051                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_ipa_prefix_len, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
2052                 prefix_len = tvb_get_guint8(tvb, opt_offset);
2053                 opt_offset += 1;
2054 
2055                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_reserved, tvb, opt_offset, 4, ENC_NA);
2056                 opt_offset += 4;
2057 
2058                 /* IPv6 Address */
2059                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_ipa_ipv6_address, tvb, opt_offset, 16, ENC_NA);
2060                 proto_item_append_text(ti, " %s/%d", tvb_ip6_to_str(pinfo->pool, tvb, opt_offset), prefix_len);
2061                 opt_offset += 16;
2062 
2063                 break;
2064             }
2065             case ND_OPT_NEW_ROUTER_PREFIX_INFO: /* New Router Prefix Information Option (18) OBSO... */
2066             {
2067 
2068                 guint8 prefix_len;
2069 
2070                 /* Option-code */
2071                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_nrpi_option_code, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
2072                 opt_offset += 1;
2073 
2074                 /* Prefix Len */
2075                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_nrpi_prefix_len, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
2076                 prefix_len = tvb_get_guint8(tvb, opt_offset);
2077                 opt_offset += 1;
2078 
2079                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_reserved, tvb, opt_offset, 4, ENC_NA);
2080                 opt_offset += 4;
2081 
2082                 /* Prefix */
2083                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_nrpi_prefix, tvb, opt_offset, 16, ENC_NA);
2084                 proto_item_append_text(ti, " %s/%d", tvb_ip6_to_str(pinfo->pool, tvb, opt_offset), prefix_len);
2085                 opt_offset += 16;
2086 
2087                 break;
2088             }
2089             case ND_OPT_LINK_LAYER_ADDRESS: /* Link-layer Address Option (19) */
2090             {
2091                 /* Option-Code */
2092                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_lla_option_code, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
2093                 opt_offset += 1;
2094 
2095                 /* Link Layer Address */
2096                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_lla_bytes, tvb, opt_offset, opt_len-3, ENC_NA);
2097                 opt_offset += opt_len - 3;
2098                 break;
2099             }
2100 
2101             case ND_OPT_NEIGHBOR_ADV_ACK: /* Neighbor Advertisement Acknowledgment Option (20) */
2102             {
2103                 guint8 status;
2104 
2105                 /* Option-Code */
2106                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_naack_option_code, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
2107                 opt_offset += 1;
2108 
2109                 /* Status */
2110                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_naack_status, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
2111                 status = tvb_get_guint8(tvb, opt_offset);
2112                 opt_offset += 1;
2113 
2114                 if(status == 2){
2115                     proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_naack_supplied_ncoa, tvb, opt_offset, 16, ENC_NA);
2116                     opt_offset += 16;
2117                 }else{
2118                     proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_reserved, tvb, opt_offset, opt_len - 4, ENC_NA);
2119                     opt_offset += opt_len - 4;
2120                 }
2121                 break;
2122             }
2123             case ND_OPT_MAP: /* MAP Option (23) */
2124             {
2125                 static int * const map_flags[] = {
2126                     &hf_icmpv6_opt_map_flag_r,
2127                     &hf_icmpv6_opt_map_flag_reserved,
2128                     NULL
2129                 };
2130 
2131                 /* Dist */
2132                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_map_dist, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
2133 
2134                 /* Pref */
2135                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_map_pref, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
2136                 opt_offset += 1;
2137 
2138                 /* Flags */
2139                 proto_tree_add_bitmask(icmp6opt_tree, tvb, opt_offset, hf_icmpv6_opt_map_flag, ett_icmpv6_flag_map, map_flags, ENC_BIG_ENDIAN);
2140                 opt_offset += 1;
2141 
2142                 /* Valid Lifetime */
2143                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_map_valid_lifetime, tvb, opt_offset, 4, ENC_BIG_ENDIAN);
2144                 opt_offset += 4;
2145 
2146                 /* Global Address */
2147                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_map_global_address, tvb, opt_offset, 16, ENC_NA);
2148                 opt_offset += 16;
2149                 break;
2150             }
2151             case ND_OPT_ROUTE_INFO: /* Route Information Option (24) */
2152             {
2153                 /* RFC 4191 */
2154                 guint8 prefix_len;
2155                 guint8 route_preference;
2156                 ws_in6_addr prefix;
2157                 address prefix_addr;
2158                 static int * const route_flags[] = {
2159                     &hf_icmpv6_opt_route_info_flag_route_preference,
2160                     &hf_icmpv6_opt_route_info_flag_reserved,
2161                     NULL
2162                 };
2163 
2164                 /* Prefix Len */
2165                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_prefix_len, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
2166                 prefix_len = tvb_get_guint8(tvb, opt_offset);
2167                 opt_offset += 1;
2168 
2169                 /* Flags */
2170                 proto_tree_add_bitmask(icmp6opt_tree, tvb, opt_offset, hf_icmpv6_opt_route_info_flag, ett_icmpv6_flag_route_info, route_flags, ENC_BIG_ENDIAN);
2171 
2172                 route_preference = tvb_get_guint8(tvb, opt_offset);
2173                 route_preference = (route_preference & ND_RA_FLAG_RTPREF_MASK) >> 3;
2174                 proto_item_append_text(ti, " : %s", val_to_str(route_preference, nd_flag_router_pref, "Unknown %d") );
2175                 opt_offset += 1;
2176 
2177                 /* Route Lifetime */
2178                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_route_lifetime, tvb, opt_offset, 4, ENC_BIG_ENDIAN);
2179                 opt_offset += 4;
2180 
2181                 /* Prefix */
2182                 switch(opt_len){
2183                     case 8: /* Default Option Length without prefix */
2184                         proto_item_append_text(ti, " ::/%d", prefix_len);
2185                         break;
2186                     case 16:
2187                         memset(&prefix, 0, sizeof(prefix));
2188                         tvb_memcpy(tvb, (guint8 *)&prefix.bytes, opt_offset, 8);
2189                         proto_tree_add_ipv6(icmp6opt_tree, hf_icmpv6_opt_prefix, tvb, opt_offset, 8, &prefix);
2190                         set_address(&prefix_addr, AT_IPv6, 16, prefix.bytes);
2191                         proto_item_append_text(ti, " %s/%d", address_to_str(pinfo->pool, &prefix_addr), prefix_len);
2192                         opt_offset += 8;
2193                         break;
2194                     case 24:
2195                         proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_prefix, tvb, opt_offset, 16, ENC_NA);
2196                         proto_item_append_text(ti, " %s/%d", tvb_ip6_to_str(pinfo->pool, tvb, opt_offset), prefix_len);
2197                         opt_offset += 16;
2198                         break;
2199                     default:
2200                         expert_add_info(pinfo, ti_opt_len, &ei_icmpv6_invalid_option_length);
2201                         break;
2202                 }
2203                 break;
2204 
2205             }
2206 
2207             case ND_OPT_RECURSIVE_DNS_SERVER: /* Recursive DNS Server Option (25) */
2208             {
2209                 /* Reserved */
2210                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_reserved, tvb, opt_offset, 2, ENC_NA);
2211                 opt_offset += 2;
2212 
2213                 /* RDNSS Lifetime */
2214                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_rdnss_lifetime, tvb, opt_offset, 4, ENC_BIG_ENDIAN);
2215                 opt_offset += 4;
2216 
2217                 while(opt_offset < (offset + opt_len) ) {
2218                     proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_rdnss, tvb, opt_offset, 16, ENC_NA);
2219                     proto_item_append_text(ti, " %s", tvb_ip6_to_str(pinfo->pool, tvb, opt_offset));
2220                     opt_offset += 16;
2221 
2222                 }
2223                 break;
2224             }
2225             case ND_OPT_FLAGS_EXTENSION: /* RA Flags Extension Option (26) */
2226             {
2227                 static int * const extension_flags[] = {
2228                     &hf_icmpv6_opt_efo_m,
2229                     &hf_icmpv6_opt_efo_o,
2230                     &hf_icmpv6_opt_efo_h,
2231                     &hf_icmpv6_opt_efo_prf,
2232                     &hf_icmpv6_opt_efo_p,
2233                     &hf_icmpv6_opt_efo_rsv,
2234                     NULL
2235                 };
2236 
2237                 proto_tree_add_bitmask(icmp6opt_tree, tvb, opt_offset, hf_icmpv6_opt_efo, ett_icmpv6_flag_efo, extension_flags, ENC_BIG_ENDIAN);
2238                 opt_offset += 2;
2239 
2240                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_reserved, tvb, opt_offset, 4, ENC_NA);
2241                 opt_offset += 4;
2242                 break;
2243             }
2244             case ND_OPT_HANDOVER_KEY_REQUEST: /* Handover Key Request Option (27) */
2245             {
2246                 int par_len;
2247                 guint padd_length;
2248 
2249                 /* Pad Length */
2250                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_hkr_pad_length, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
2251                 padd_length = tvb_get_guint8(tvb, opt_offset);
2252                 opt_offset += 1;
2253 
2254                 /* AT */
2255                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_hkr_at, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
2256 
2257                 /* Reserved */
2258                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_hkr_reserved, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
2259                 opt_offset += 1;
2260 
2261                 /* Handover Key Encryption Public Key */
2262                 par_len = opt_len-4-padd_length;
2263                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_hkr_encryption_public_key, tvb, opt_offset, par_len, ENC_NA);
2264                 opt_offset += par_len;
2265 
2266                 /* Padding */
2267                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_hkr_padding, tvb, opt_offset, padd_length, ENC_NA);
2268                 opt_offset += 1;
2269                 break;
2270             }
2271             case ND_OPT_HANDOVER_KEY_REPLY: /* Handover Key Reply Option (28) */
2272             {
2273                 int par_len;
2274                 guint padd_length;
2275 
2276                 /* Pad Length */
2277                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_hkr_pad_length, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
2278                 padd_length = tvb_get_guint8(tvb, opt_offset);
2279                 opt_offset += 1;
2280 
2281                 /* AT */
2282                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_hkr_at, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
2283 
2284                 /* Reserved */
2285                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_hkr_reserved, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
2286                 opt_offset += 1;
2287 
2288                 /* Lifetime */
2289                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_hkr_lifetime, tvb, opt_offset, 2, ENC_BIG_ENDIAN);
2290                 opt_offset += 2;
2291 
2292                 /* Encrypted Handover Key */
2293                 par_len = opt_len-6-padd_length;
2294                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_hkr_encrypted_handover_key, tvb, opt_offset, par_len, ENC_NA);
2295                 opt_offset += par_len;
2296 
2297                 /* Padding */
2298                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_hkr_padding, tvb, opt_offset, padd_length, ENC_NA);
2299                 opt_offset += 1;
2300                 break;
2301             }
2302             case ND_OPT_HANDOVER_ASSIST_INFO: /* Handover Assist Information Option (29) */
2303             {
2304                 guint8 hai_len;
2305                 int padd_length;
2306                 /* Option-Code */
2307                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_hai_option_code, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
2308                 opt_offset += 1;
2309 
2310                 /* HAI Length */
2311                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_hai_length, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
2312                 hai_len = tvb_get_guint8(tvb, opt_offset);
2313                 opt_offset += 1;
2314 
2315                 /* HAI Value */
2316                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_hai_value, tvb, opt_offset, hai_len, ENC_NA);
2317                 opt_offset += hai_len;
2318 
2319                 /* Padding... */
2320                 padd_length = opt_len - opt_offset;
2321                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_padding, tvb, opt_offset, padd_length, ENC_NA);
2322                 opt_offset += padd_length;
2323 
2324                 break;
2325             }
2326             case ND_OPT_MOBILE_NODE_ID: /* Mobile Node Identifier Option (30) */
2327             {
2328                 guint8 mn_len;
2329                 int padd_length;
2330                 /* Option-Code */
2331                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_mn_option_code, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
2332                 opt_offset += 1;
2333 
2334                 /* MN Length */
2335                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_mn_length, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
2336                 mn_len = tvb_get_guint8(tvb, opt_offset);
2337                 opt_offset += 1;
2338 
2339                 /* MN Value */
2340                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_mn_value, tvb, opt_offset, mn_len, ENC_NA);
2341                 opt_offset += mn_len;
2342 
2343                 /* Padding... */
2344                 padd_length = opt_len - opt_offset;
2345                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_padding, tvb, opt_offset, padd_length, ENC_NA);
2346                 opt_offset += padd_length;
2347 
2348                 break;
2349             }
2350             case ND_OPT_DNS_SEARCH_LIST: /* DNS Search List Option (31) */
2351             {
2352                 int dnssl_len;
2353                 const gchar *dnssl_name;
2354 
2355                 /* Reserved */
2356                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_reserved, tvb, opt_offset, 2, ENC_NA);
2357                 opt_offset += 2;
2358 
2359                 /* DNSSL Lifetime */
2360                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_dnssl_lifetime, tvb, opt_offset, 4, ENC_BIG_ENDIAN);
2361                 opt_offset += 4;
2362                 while(opt_offset < (offset + opt_len) ) {
2363 
2364                     if(tvb_get_guint8(tvb, opt_offset) == 0){
2365                         /* Padding... */
2366                         int padd_length = (offset + opt_len) - opt_offset;
2367                         proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_padding, tvb, opt_offset, padd_length, ENC_NA);
2368                         opt_offset += padd_length;
2369                         break;
2370                     }
2371                     used_bytes = get_dns_name(tvb, opt_offset, 0, opt_offset, &dnssl_name, &dnssl_len);
2372                     proto_tree_add_string(icmp6opt_tree, hf_icmpv6_opt_dnssl, tvb, opt_offset, used_bytes, format_text(pinfo->pool, dnssl_name, dnssl_len));
2373                     proto_item_append_text(ti, " %s", dnssl_name);
2374                     opt_offset += used_bytes;
2375 
2376                 }
2377                 break;
2378             }
2379             case ND_OPT_PROXY_SIGNATURE: /* Proxy Signature Option (32) */
2380             {
2381                 int par_len;
2382 
2383                 /* Reserved */
2384                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_reserved, tvb, opt_offset, 2, ENC_NA);
2385                 opt_offset +=  2;
2386 
2387                 /* Key Hash
2388                  * A 128-bit field containing the most significant (leftmost) 128
2389                  * bits of a SHA-1 [14] hash of the public key used for constructing
2390                  * the signature.
2391                  */
2392                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_ps_key_hash, tvb, opt_offset, 16, ENC_NA);
2393                 opt_offset += 16;
2394 
2395                 /* Digital Signature */
2396                 par_len = opt_len - 20;
2397                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_digital_signature_padding , tvb, opt_offset, par_len, ENC_NA);
2398                 opt_offset += par_len;
2399                 /* Padding */
2400                 /* TODO: Calculate padding length and exclude from the signature */
2401                 break;
2402             }
2403             case ND_OPT_ADDR_REGISTRATION: /* Address Registration (TBD1 Pending IANA...) */
2404             {
2405                 /* 6lowpan-ND */
2406                 guint8 status;
2407 
2408                 /* Status */
2409                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_aro_status, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
2410                 status = tvb_get_guint8(tvb, opt_offset);
2411                 opt_offset += 1;
2412 
2413                 /* Reserved */
2414                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_reserved, tvb, opt_offset, 3, ENC_NA);
2415                 opt_offset += 3;
2416 
2417                 /* Lifetime */
2418                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_aro_registration_lifetime, tvb, opt_offset, 2, ENC_BIG_ENDIAN);
2419                 opt_offset += 2;
2420 
2421                 /* EUI-64 */
2422                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_aro_eui64, tvb, opt_offset, 8, ENC_BIG_ENDIAN);
2423                 proto_item_append_text(ti, " : Register %s %s", tvb_eui64_to_str(pinfo->pool, tvb, opt_offset), val_to_str(status, nd_opt_6lowpannd_status_val, "Unknown %d"));
2424                 opt_offset += 8;
2425 
2426             }
2427             break;
2428             case ND_OPT_6LOWPAN_CONTEXT: /* 6LoWPAN Context (TBD2 Pending IANA...) */
2429             {
2430                 ieee802154_hints_t *hints;
2431                 /* 6lowpan-ND */
2432                 guint8 context_id;
2433                 guint8 context_len;
2434                 ws_in6_addr context_prefix;
2435                 address context_prefix_addr;
2436                 static int * const _6lowpan_context_flags[] = {
2437                     &hf_icmpv6_opt_6co_flag_c,
2438                     &hf_icmpv6_opt_6co_flag_cid,
2439                     &hf_icmpv6_opt_6co_flag_reserved,
2440                     NULL
2441                 };
2442 
2443                 /* Context Length */
2444                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_6co_context_length, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
2445                 context_len = tvb_get_guint8(tvb, opt_offset);
2446                 opt_offset += 1;
2447 
2448                 /*  Flags & CID */
2449                 context_id = tvb_get_guint8(tvb, opt_offset) & ND_OPT_6CO_FLAG_CID;
2450                 proto_tree_add_bitmask(icmp6opt_tree, tvb, opt_offset, hf_icmpv6_opt_6co_flag, ett_icmpv6_flag_6lowpan, _6lowpan_context_flags, ENC_BIG_ENDIAN);
2451                 opt_offset += 1;
2452 
2453                 /* Reserved */
2454                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_reserved, tvb, opt_offset, 2, ENC_NA);
2455                 opt_offset += 2;
2456 
2457                 /* Lifetime */
2458                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_6co_valid_lifetime, tvb, opt_offset, 2, ENC_BIG_ENDIAN);
2459                 opt_offset += 2;
2460 
2461                 /* Context */
2462                 memset(&context_prefix.bytes, 0, sizeof(context_prefix));
2463                 switch(opt_len){
2464                     case 8: /* Default Option Length without context prefix */
2465                         proto_item_append_text(ti, " ::/%d", context_len);
2466                         break;
2467                     case 16:
2468                         tvb_memcpy(tvb, (guint8 *)&context_prefix.bytes, opt_offset, 8);
2469                         proto_tree_add_ipv6(icmp6opt_tree, hf_icmpv6_opt_6co_context_prefix, tvb, opt_offset, 8, &context_prefix);
2470                         set_address(&context_prefix_addr, AT_IPv6, 16, context_prefix.bytes);
2471                         proto_item_append_text(ti, " %s/%d", address_to_str(pinfo->pool, &context_prefix_addr), context_len);
2472                         opt_offset += 8;
2473                         break;
2474                     case 24:
2475                         tvb_memcpy(tvb, (guint8 *)&context_prefix.bytes, opt_offset, 16);
2476                         proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_6co_context_prefix, tvb, opt_offset, 16, ENC_NA);
2477                         proto_item_append_text(ti, " %s/%d", tvb_ip6_to_str(pinfo->pool, tvb, opt_offset), context_len);
2478                         opt_offset += 16;
2479                         break;
2480                     default:
2481                         expert_add_info(pinfo, ti_opt_len, &ei_icmpv6_invalid_option_length);
2482                         break;
2483                 }
2484                 /* Update the 6LoWPAN dissectors with new context information. */
2485                 hints = (ieee802154_hints_t *)p_get_proto_data(wmem_file_scope(), pinfo,
2486                         proto_get_id_by_filter_name(IEEE802154_PROTOABBREV_WPAN), 0);
2487                 if ((opt_len <= 24) && hints) {
2488                     lowpan_context_insert(context_id, hints->src_pan, context_len, &context_prefix, pinfo->num);
2489                 }
2490             }
2491             break;
2492             case ND_OPT_AUTH_BORDER_ROUTER: /* Authoritative Border Router (33) */
2493             {
2494                 guint32 version_low, version_high, valid_lifetime;
2495 
2496                 /* Version low*/
2497                 proto_tree_add_item_ret_uint(icmp6opt_tree, hf_icmpv6_opt_abro_version_low, tvb, opt_offset, 2, ENC_BIG_ENDIAN, &version_low);
2498                 opt_offset += 2;
2499 
2500                 /* Version high */
2501                 proto_tree_add_item_ret_uint(icmp6opt_tree, hf_icmpv6_opt_abro_version_high, tvb, opt_offset, 2, ENC_BIG_ENDIAN, &version_high);
2502                 opt_offset += 2;
2503 
2504                 /* Valid lifetime */
2505                 proto_tree_add_item_ret_uint(icmp6opt_tree, hf_icmpv6_opt_abro_valid_lifetime, tvb, opt_offset, 2, ENC_BIG_ENDIAN, &valid_lifetime);
2506                 opt_offset += 2;
2507 
2508                 /* 6LBR Address */
2509                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_abro_6lbr_address, tvb, opt_offset, 16, ENC_NA);
2510                 proto_item_append_text(ti, " : Version %d.%d, Valid Lifetime : %d, 6LBR : %s", version_high, version_low, valid_lifetime, tvb_ip6_to_str(pinfo->pool, tvb, opt_offset));
2511                 opt_offset += 16;
2512 
2513             }
2514             break;
2515             case ND_OPT_6CIO: /* 6LoWPAN Capability Indication Option (35) */
2516             {
2517 
2518                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_6cio_unassigned1, tvb, opt_offset, 2, ENC_BIG_ENDIAN);
2519                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_6cio_flag_g, tvb, opt_offset, 2, ENC_BIG_ENDIAN);
2520                 opt_offset += 2;
2521 
2522                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_6cio_unassigned2, tvb, opt_offset, 4, ENC_BIG_ENDIAN);
2523                 opt_offset += 4;
2524 
2525 
2526             }
2527             break;
2528             case ND_OPT_CAPPORT: /* DHCP Captive-Portal Option (37) */
2529             {
2530                 proto_item *ti_cp;
2531 
2532                 ti_cp = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_captive_portal, tvb, opt_offset, opt_len-2, ENC_ASCII|ENC_NA);
2533                 proto_item_set_url(ti_cp);
2534                 opt_offset += opt_len - 2;
2535 
2536             }
2537             break;
2538             case ND_OPT_PREF64: /* PREF64 Option (38) */
2539             {
2540                 ws_in6_addr prefix;
2541                 guint32 plc;
2542 
2543                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_pref64_scaled_lifetime, tvb, opt_offset, 2, ENC_BIG_ENDIAN);
2544                 proto_tree_add_item_ret_uint(icmp6opt_tree, hf_icmpv6_opt_pref64_plc, tvb, opt_offset, 2, ENC_BIG_ENDIAN, &plc);
2545                 opt_offset += 2;
2546 
2547                 /* Prefix */
2548                 memset(&prefix.bytes, 0, sizeof(prefix));
2549                 switch(plc){
2550                     case 0: /* 96 bits prefix length */
2551                         tvb_memcpy(tvb, (guint8 *)&prefix.bytes, opt_offset, 12);
2552                         proto_tree_add_ipv6(icmp6opt_tree, hf_icmpv6_opt_pref64_prefix, tvb, opt_offset, 12, &prefix);
2553                         opt_offset += 12;
2554                         break;
2555                     case 1: /* 64 bits prefix length */
2556                         tvb_memcpy(tvb, (guint8 *)&prefix.bytes, opt_offset, 8);
2557                         proto_tree_add_ipv6(icmp6opt_tree, hf_icmpv6_opt_pref64_prefix, tvb, opt_offset, 8, &prefix);
2558                         opt_offset += 8;
2559                         break;
2560                     case 2: /* 56 bits prefix length */
2561                         tvb_memcpy(tvb, (guint8 *)&prefix.bytes, opt_offset, 7);
2562                         proto_tree_add_ipv6(icmp6opt_tree, hf_icmpv6_opt_pref64_prefix, tvb, opt_offset, 7, &prefix);
2563                         opt_offset += 7;
2564                         break;
2565                     case 3: /* 48 bits prefix length */
2566                         tvb_memcpy(tvb, (guint8 *)&prefix.bytes, opt_offset, 6);
2567                         proto_tree_add_ipv6(icmp6opt_tree, hf_icmpv6_opt_pref64_prefix, tvb, opt_offset, 6, &prefix);
2568                         opt_offset += 6;
2569                         break;
2570                     case 4: /* 40 bits prefix length */
2571                         tvb_memcpy(tvb, (guint8 *)&prefix.bytes, opt_offset, 5);
2572                         proto_tree_add_ipv6(icmp6opt_tree, hf_icmpv6_opt_pref64_prefix, tvb, opt_offset, 5, &prefix);
2573                         opt_offset += 5;
2574                         break;
2575                     case 5: /* 32 bits prefix length */
2576                         tvb_memcpy(tvb, (guint8 *)&prefix.bytes, opt_offset, 4);
2577                         proto_tree_add_ipv6(icmp6opt_tree, hf_icmpv6_opt_pref64_prefix, tvb, opt_offset, 4, &prefix);
2578                         opt_offset += 4;
2579                         break;
2580                     default:
2581                         expert_add_info(pinfo, ti_opt_len, &ei_icmpv6_invalid_option_length);
2582                         break;
2583                 }
2584             }
2585             break;
2586             default :
2587                 expert_add_info_format(pinfo, ti, &ei_icmpv6_undecoded_option,
2588                                        "Dissector for ICMPv6 Option (%d)"
2589                                        " code not implemented, Contact Wireshark developers"
2590                                        " if you want this supported", opt_type);
2591                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_data, tvb, opt_offset, opt_len-2, ENC_NA);
2592                 opt_offset += opt_len - 2;
2593                 break;
2594 
2595         } /* switch (opt_type) */
2596 
2597         offset += opt_len;
2598 
2599         if(offset > opt_offset){
2600             ti_opt = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_unknown_data, tvb, opt_offset, offset - opt_offset, ENC_NA);
2601             expert_add_info(pinfo, ti_opt, &ei_icmpv6_unknown_data);
2602         }
2603         /* Close the ) to option root label */
2604         proto_item_append_text(ti, ")");
2605     }
2606     return offset;
2607 }
2608 
2609 
2610 /* RPL: RFC 6550/6997 : Routing and Discovery of P2P Routes in Low-Power and Lossy Networks. */
2611 static int
dissect_icmpv6_rpl_opt(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,guint8 icmp6_code)2612 dissect_icmpv6_rpl_opt(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, guint8 icmp6_code)
2613 {
2614     proto_tree *icmp6opt_tree, *flag_tree;
2615     proto_item *ti, *ti_opt, *ti_opt_len, *ti_opt_reply, *ti_opt_hop_by_hop, *ti_opt_num_of_routes,
2616                *ti_opt_lifetime, *ti_opt_mr_nh = NULL;
2617     guint8      opt_type;
2618     int         opt_len;
2619     int         opt_offset;
2620 
2621     while ((int)tvb_reported_length(tvb) > offset) {
2622         /* there are more options */
2623 
2624         /* ICMPv6 RPL Option */
2625         ti = proto_tree_add_item(tree, hf_icmpv6_rpl_opt, tvb, offset, 1, ENC_NA);
2626         icmp6opt_tree = proto_item_add_subtree(ti, ett_icmpv6_rpl_opt);
2627         opt_offset = offset;
2628 
2629         /* Option type */
2630         proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_type, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
2631         opt_type = tvb_get_guint8(tvb, opt_offset);
2632         opt_offset += 1;
2633 
2634         /* Add option name to option root label */
2635         proto_item_append_text(ti, " (%s", val_to_str(opt_type, rpl_option_vals, "Unknown %d"));
2636 
2637         /* The Pad1 option is a special case, and contains no data. */
2638         if (opt_type == RPL_OPT_PAD1) {
2639             offset += 1;
2640             proto_item_append_text(ti, ")");
2641             continue;
2642         }
2643 
2644         /* Option length */
2645         ti_opt_len = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_length, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
2646         opt_len = tvb_get_guint8(tvb, opt_offset);
2647         proto_item_set_len(ti, opt_len + 2);
2648         opt_offset += 1;
2649 
2650         /* decode... */
2651         switch (opt_type) {
2652             case RPL_OPT_PADN:
2653                 /* n-byte padding */
2654                 ti_opt = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_padn, tvb, opt_offset, opt_len, ENC_NA);
2655                 proto_item_append_text(ti_opt, " (Length : %i bytes)", opt_len);
2656                 opt_offset += opt_len;
2657                 break;
2658             case RPL_OPT_METRIC: {
2659                 /* DAG metric container */
2660                 /* See RFC 6551 for formatting. */
2661 
2662                 proto_tree *metric_constraint_tree;
2663                 proto_item *ti_metric_constraint;
2664                 guint8 metric_constraint_type;
2665                 gint metric_len;
2666 
2667                 while (opt_offset < offset + opt_len) {
2668                     static int * const rpl_metric_flags[] = {
2669                         &hf_icmpv6_rpl_opt_metric_reserved,
2670                         &hf_icmpv6_rpl_opt_metric_flag_p,
2671                         &hf_icmpv6_rpl_opt_metric_flag_c,
2672                         &hf_icmpv6_rpl_opt_metric_flag_o,
2673                         &hf_icmpv6_rpl_opt_metric_flag_r,
2674                         &hf_icmpv6_rpl_opt_metric_a,
2675                         &hf_icmpv6_rpl_opt_metric_prec,
2676                         NULL
2677                     };
2678                     guint16 metric_constraint_flags;
2679 
2680                     /* Metric/Constraint type */
2681                     metric_constraint_type = tvb_get_guint8(tvb, opt_offset);
2682                     ti_metric_constraint = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_metric_type, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
2683                     metric_constraint_tree = proto_item_add_subtree(ti_metric_constraint, ett_icmpv6_rpl_metric_type);
2684                     opt_offset += 1;
2685 
2686                     /* Flags */
2687                     proto_tree_add_bitmask(metric_constraint_tree, tvb, opt_offset, hf_icmpv6_rpl_opt_metric_flags, ett_icmpv6_rpl_metric_flags, rpl_metric_flags, ENC_BIG_ENDIAN);
2688                     metric_constraint_flags = tvb_get_guint16(tvb, opt_offset, ENC_BIG_ENDIAN);
2689                     opt_offset += 2;
2690 
2691                     /* Metric length */
2692                     metric_len = tvb_get_guint8(tvb, opt_offset);
2693                     proto_tree_add_item(metric_constraint_tree, hf_icmpv6_rpl_opt_metric_len, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
2694                     proto_item_set_len(ti_metric_constraint, metric_len + 4);
2695                     opt_offset += 1;
2696 
2697                     /* Metric/Constraint Type */
2698                     switch(metric_constraint_type) {
2699                         case RPL_METRIC_NSA: /* Node State and Attribute Object */
2700                             {
2701                             static int * const metric_nsa_flags[] = {
2702                                 &hf_icmpv6_rpl_opt_metric_nsa_object_reserved,
2703                                 &hf_icmpv6_rpl_opt_metric_nsa_object_flags,
2704                                 &hf_icmpv6_rpl_opt_metric_nsa_object_flag_a,
2705                                 &hf_icmpv6_rpl_opt_metric_nsa_object_flag_o,
2706                                 NULL
2707                             };
2708 
2709                             proto_item *ti_metric_nsa_object =  proto_tree_add_bitmask(metric_constraint_tree, tvb, opt_offset, hf_icmpv6_rpl_opt_metric_nsa_object,
2710                                                     ett_icmpv6_rpl_metric_nsa_object, metric_nsa_flags, ENC_BIG_ENDIAN);
2711                             proto_item_set_len(ti_metric_nsa_object, 2);
2712                             opt_offset += 2;
2713                             metric_len -= 2;
2714 
2715 
2716                             while(metric_len > 0){
2717                               /* TLV */
2718                               tvb_get_guint8(tvb, opt_offset);
2719                               proto_item *ti_metric_nsa_tlv = proto_tree_add_item(metric_constraint_tree, hf_icmpv6_rpl_opt_metric_nsa_object_opttlv_object, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
2720                               proto_tree * metric_nsa_tlv_tree = proto_item_add_subtree(ti_metric_nsa_tlv, ett_icmpv6_rpl_metric_nsa_object_tlv_type);
2721 
2722                               /* TLV type */
2723                               proto_tree_add_item(metric_nsa_tlv_tree, hf_icmpv6_rpl_opt_metric_nsa_object_opttlv_object_type, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
2724                               opt_offset += 1;
2725                               metric_len -= 1;
2726 
2727                               /* TLV length */
2728                               gint nsa_tlv_len = tvb_get_guint8(tvb, opt_offset);
2729                               proto_tree_add_item(metric_nsa_tlv_tree, hf_icmpv6_rpl_opt_metric_nsa_object_opttlv_object_length, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
2730                               proto_item_set_len(ti_metric_nsa_tlv, nsa_tlv_len + 2);
2731                               opt_offset += 1;
2732                               metric_len -= 1;
2733 
2734                               /* TLV data */
2735                               proto_tree_add_item(metric_nsa_tlv_tree, hf_icmpv6_rpl_opt_metric_nsa_object_opttlv_object_data, tvb, opt_offset, nsa_tlv_len, ENC_NA);
2736                               opt_offset += nsa_tlv_len;
2737                               metric_len -= nsa_tlv_len;
2738                             }
2739                             break;
2740                             }
2741                         case RPL_METRIC_NE: /* Node Energy */
2742                             {
2743                             static int * const metric_ne_flags[] = {
2744                                 &hf_icmpv6_rpl_opt_metric_ne_object_flags,
2745                                 &hf_icmpv6_rpl_opt_metric_ne_object_flag_i,
2746                                 &hf_icmpv6_rpl_opt_metric_ne_object_type,
2747                                 &hf_icmpv6_rpl_opt_metric_ne_object_flag_e,
2748                                 &hf_icmpv6_rpl_opt_metric_ne_object_energy,
2749                                 NULL
2750                             };
2751 
2752                             for (; metric_len > 0; metric_len -= 2) {
2753                                 proto_tree_add_bitmask(metric_constraint_tree, tvb, opt_offset, hf_icmpv6_rpl_opt_metric_ne_object,
2754                                                     ett_icmpv6_rpl_metric_ne_object, metric_ne_flags, ENC_BIG_ENDIAN);
2755                                 opt_offset += 2;
2756                             }
2757                             break;
2758                             }
2759                         case RPL_METRIC_HP: /* Hop Count Object */
2760                             {
2761                             static int * const metric_hp_flags[] = {
2762                                 &hf_icmpv6_rpl_opt_metric_hp_object_reserved,
2763                                 &hf_icmpv6_rpl_opt_metric_hp_object_flags,
2764                                 &hf_icmpv6_rpl_opt_metric_hp_object_hp,
2765                                 NULL
2766                             };
2767                             proto_tree_add_bitmask(metric_constraint_tree, tvb, opt_offset, hf_icmpv6_rpl_opt_metric_hp_object,
2768                                                     ett_icmpv6_rpl_metric_hp_object, metric_hp_flags, ENC_BIG_ENDIAN);
2769                             opt_offset += 2;
2770                             break;
2771                             }
2772                         case RPL_METRIC_LT: /* Link Throughput Object */
2773                             for (; metric_len > 0; metric_len -= 4) {
2774                                 proto_tree_add_item(metric_constraint_tree, hf_icmpv6_rpl_opt_metric_lt_object_lt, tvb, opt_offset, 4, ENC_BIG_ENDIAN);
2775                                 opt_offset += 4;
2776                             }
2777                             break;
2778                         case RPL_METRIC_LL: /* Link Latency Object */
2779                             for (; metric_len > 0; metric_len -= 4) {
2780                                 proto_tree_add_item(metric_constraint_tree, hf_icmpv6_rpl_opt_metric_ll_object_ll, tvb, opt_offset, 4, ENC_BIG_ENDIAN);
2781                                 opt_offset += 4;
2782                             }
2783                             break;
2784                         case RPL_METRIC_LQL: /* Link Quality Level Object */
2785                             {
2786                             static int * const metric_lql_flags[] = {
2787                                 &hf_icmpv6_rpl_opt_metric_lql_object_val,
2788                                 &hf_icmpv6_rpl_opt_metric_lql_object_counter,
2789                                 NULL
2790                             };
2791 
2792                             proto_tree_add_item(metric_constraint_tree, hf_icmpv6_rpl_opt_metric_lql_object_res, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
2793                             opt_offset += 1;
2794                             metric_len -= 1;
2795                             for (; metric_len > 0; metric_len -= 1) {
2796                                 proto_tree_add_bitmask(metric_constraint_tree, tvb, opt_offset, hf_icmpv6_rpl_opt_metric_lql_object,
2797                                                     ett_icmpv6_rpl_metric_lql_object, metric_lql_flags, ENC_BIG_ENDIAN);
2798                                 opt_offset += 1;
2799                             }
2800                             break;
2801                             }
2802                         case RPL_METRIC_ETX: /* ETX Object */
2803                             for (; metric_len > 0; metric_len -= 2) {
2804                                 proto_tree_add_item(metric_constraint_tree, hf_icmpv6_rpl_opt_metric_etx_object_etx, tvb, opt_offset, 2, ENC_BIG_ENDIAN);
2805                                 opt_offset += 2;
2806                             }
2807                             break;
2808                         case RPL_METRIC_LC: /* Link Color Object */
2809                             proto_tree_add_item(metric_constraint_tree, hf_icmpv6_rpl_opt_metric_lc_object_res, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
2810                             opt_offset += 1;
2811                             metric_len -= 1;
2812                             for (; metric_len > 0; metric_len -= 2) {
2813                                 ti_opt = proto_tree_add_item(metric_constraint_tree, hf_icmpv6_rpl_opt_metric_lc_object, tvb, opt_offset, 2, ENC_NA);
2814                                 flag_tree = proto_item_add_subtree(ti_opt, ett_icmpv6_rpl_metric_lc_object);
2815                                 proto_tree_add_item(flag_tree, hf_icmpv6_rpl_opt_metric_lc_object_lc, tvb, opt_offset, 2, ENC_NA);
2816                                 if (metric_constraint_flags & RPL_METRIC_FLAG_C) {
2817                                     proto_tree_add_item(flag_tree, hf_icmpv6_rpl_opt_metric_lc_object_reserved, tvb, opt_offset, 2, ENC_BIG_ENDIAN);
2818                                     proto_tree_add_item(flag_tree, hf_icmpv6_rpl_opt_metric_lc_object_flag_i, tvb, opt_offset, 2, ENC_BIG_ENDIAN);
2819                                 } else if (metric_constraint_flags & RPL_METRIC_FLAG_R) {
2820                                     proto_tree_add_item(flag_tree, hf_icmpv6_rpl_opt_metric_lc_object_counter, tvb, opt_offset, 2, ENC_BIG_ENDIAN);
2821                                 } else {
2822                                     expert_add_info(pinfo, ti_opt, &ei_icmpv6_rpl_unknown_metric);
2823                                 }
2824                                 opt_offset += 2;
2825                             }
2826                             break;
2827                         default:
2828                             expert_add_info(pinfo, ti_opt_len, &ei_icmpv6_rpl_unknown_metric);
2829                             break;
2830                     }
2831                 }
2832                 break;
2833             }
2834             case RPL_OPT_ROUTING: {
2835                 guint8 prefix_len;
2836                 ws_in6_addr prefix;
2837                 address prefix_addr;
2838                 static int * const rpl_flags[] = {
2839                     &hf_icmpv6_rpl_opt_route_pref,
2840                     &hf_icmpv6_rpl_opt_route_reserved,
2841                     NULL
2842                 };
2843 
2844                 /* Prefix length */
2845                 prefix_len = tvb_get_guint8(tvb, opt_offset);
2846                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_route_prefix_length, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
2847                 opt_offset +=1;
2848 
2849                 /* Flags */
2850                 proto_tree_add_bitmask(icmp6opt_tree, tvb, opt_offset, hf_icmpv6_rpl_opt_route_flag,
2851                                     ett_icmpv6_rpl_flag_routing, rpl_flags, ENC_BIG_ENDIAN);
2852                 opt_offset +=1;
2853 
2854                 /* Prefix lifetime. */
2855                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_route_lifetime, tvb, opt_offset, 4, ENC_BIG_ENDIAN);
2856                 opt_offset += 4;
2857 
2858                 switch(opt_len){
2859                     case 6: /* Default Option Length without prefix */
2860                         proto_item_append_text(ti, " ::/%d", prefix_len);
2861                         break;
2862                     case 14:
2863                         memset(&prefix, 0, sizeof(prefix));
2864                         tvb_memcpy(tvb, (guint8 *)&prefix.bytes, opt_offset, 8);
2865                         proto_tree_add_ipv6(icmp6opt_tree, hf_icmpv6_rpl_opt_route_prefix, tvb, opt_offset, 8, &prefix);
2866                         set_address(&prefix_addr, AT_IPv6, 16, prefix.bytes);
2867                         proto_item_append_text(ti, " %s/%d", address_to_str(pinfo->pool, &prefix_addr), prefix_len);
2868                         opt_offset += 8;
2869                         break;
2870                     case 22:
2871                         proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_route_prefix, tvb, opt_offset, 16, ENC_NA);
2872                         proto_item_append_text(ti, " %s/%d", tvb_ip6_to_str(pinfo->pool, tvb, opt_offset), prefix_len);
2873                         opt_offset += 16;
2874                         break;
2875                     default:
2876                         expert_add_info(pinfo, ti_opt_len, &ei_icmpv6_invalid_option_length);
2877                         break;
2878                 }
2879                 break;
2880             }
2881             case RPL_OPT_CONFIG: {
2882                 static int * const rpl_config_flags[] = {
2883                     &hf_icmpv6_rpl_opt_config_reserved,
2884                     &hf_icmpv6_rpl_opt_config_auth,
2885                     &hf_icmpv6_rpl_opt_config_pcs,
2886                     NULL
2887                 };
2888 
2889                 /* Flags */
2890                 proto_tree_add_bitmask(icmp6opt_tree, tvb, opt_offset, hf_icmpv6_rpl_opt_config_flag,
2891                                     ett_icmpv6_rpl_flag_config, rpl_config_flags, ENC_BIG_ENDIAN);
2892                 opt_offset += 1;
2893 
2894                 /* DIOIntervalDoublings */
2895                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_config_doublings, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
2896                 opt_offset += 1;
2897 
2898                 /* DIOIntervalMin */
2899                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_config_min_interval, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
2900                 opt_offset += 1;
2901 
2902                 /* DIORedundancyConstant */
2903                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_config_redundancy, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
2904                 opt_offset += 1;
2905 
2906                 /* MaxRankIncrease */
2907                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_config_rank_incr, tvb, opt_offset, 2, ENC_BIG_ENDIAN);
2908                 opt_offset += 2;
2909 
2910                 /* MinHopRankInc */
2911                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_config_hop_rank_inc, tvb, opt_offset, 2, ENC_BIG_ENDIAN);
2912                 opt_offset += 2;
2913 
2914                 /* OCP */
2915                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_config_ocp, tvb, opt_offset, 2, ENC_BIG_ENDIAN);
2916                 opt_offset += 2;
2917 
2918                 /* Reserved */
2919                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_config_rsv, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
2920                 opt_offset += 1;
2921 
2922                 /* Default Lifetime */
2923                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_config_def_lifetime, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
2924                 opt_offset += 1;
2925 
2926                 /* Lifetime Unit */
2927                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_config_lifetime_unit, tvb, opt_offset, 2, ENC_BIG_ENDIAN);
2928                 opt_offset += 2;
2929                 break;
2930             }
2931             case RPL_OPT_TARGET: {
2932                 guint8              prefix_len;
2933                 ws_in6_addr   target_prefix;
2934                 address target_prefix_addr;
2935 
2936                 /* Flag */
2937                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_target_flag, tvb, opt_offset, 1, ENC_NA);
2938                 opt_offset += 1;
2939 
2940                 /* Prefix length */
2941                 prefix_len = tvb_get_guint8(tvb, opt_offset);
2942                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_target_prefix_length, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
2943                 opt_offset += 1;
2944 
2945                 /* Target Prefix */
2946 
2947                 switch(opt_len){
2948                     case 2: /* Default Option Length without prefix */
2949                         proto_item_append_text(ti, " ::/%d", prefix_len);
2950                         break;
2951                     case 10:
2952                         memset(&target_prefix, 0, sizeof(target_prefix));
2953                         tvb_memcpy(tvb, (guint8 *)&target_prefix.bytes, opt_offset, 8);
2954                         proto_tree_add_ipv6(icmp6opt_tree, hf_icmpv6_rpl_opt_target_prefix, tvb, opt_offset, 8, &target_prefix);
2955                         set_address(&target_prefix_addr, AT_IPv6, 16, target_prefix.bytes);
2956                         proto_item_append_text(ti, " %s/%d", address_to_str(pinfo->pool, &target_prefix_addr), prefix_len);
2957                         opt_offset += 8;
2958                         break;
2959                     case 18:
2960                         proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_target_prefix, tvb, opt_offset, 16, ENC_NA);
2961                         proto_item_append_text(ti, " %s/%d", tvb_ip6_to_str(pinfo->pool, tvb, opt_offset), prefix_len);
2962                         opt_offset += 16;
2963                         break;
2964                     default:
2965                         expert_add_info(pinfo, ti_opt_len, &ei_icmpv6_invalid_option_length);
2966                         break;
2967                 }
2968                 break;
2969             }
2970             case RPL_OPT_TRANSIT: {
2971                 static int * const rpl_transit_flags[] = {
2972                     &hf_icmpv6_rpl_opt_transit_flag_e,
2973                     &hf_icmpv6_rpl_opt_transit_flag_rsv,
2974                     NULL
2975                 };
2976 
2977                 /* Flags */
2978                 proto_tree_add_bitmask(icmp6opt_tree, tvb, opt_offset, hf_icmpv6_rpl_opt_transit_flag,
2979                                     ett_icmpv6_rpl_flag_transit, rpl_transit_flags, ENC_BIG_ENDIAN);
2980                 opt_offset += 1;
2981 
2982                 /* Path Control */
2983                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_transit_pathctl, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
2984                 opt_offset += 1;
2985 
2986                 /* Path Sequence */
2987                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_transit_pathseq, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
2988                 opt_offset += 1;
2989 
2990                 /* Path Lifetime */
2991                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_transit_pathlifetime, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
2992                 opt_offset += 1;
2993 
2994                 /* Option contains parent */
2995                 if(opt_len > 4)
2996                 {
2997                     proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_transit_parent, tvb, opt_offset, 16, ENC_NA);
2998                     proto_item_append_text(ti, " %s", tvb_ip6_to_str(pinfo->pool, tvb, opt_offset));
2999                     opt_offset += 16;
3000                 }
3001 
3002                 break;
3003             }
3004             case RPL_OPT_SOLICITED: {
3005                 static int * const rpl_solicited_flags[] = {
3006                     &hf_icmpv6_rpl_opt_solicited_flag_v,
3007                     &hf_icmpv6_rpl_opt_solicited_flag_i,
3008                     &hf_icmpv6_rpl_opt_solicited_flag_d,
3009                     &hf_icmpv6_rpl_opt_solicited_flag_rsv,
3010                     NULL
3011                 };
3012 
3013                 /*Instance ID */
3014                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_solicited_instance, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
3015                 opt_offset += 1;
3016 
3017                 /* Flags */
3018                 proto_tree_add_bitmask(icmp6opt_tree, tvb, opt_offset, hf_icmpv6_rpl_opt_solicited_flag,
3019                                     ett_icmpv6_rpl_flag_solicited, rpl_solicited_flags, ENC_BIG_ENDIAN);
3020                 opt_offset += 1;
3021 
3022                 /* DODAG ID */
3023                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_solicited_dodagid, tvb, opt_offset, 16, ENC_NA);
3024                 opt_offset += 16;
3025 
3026                 /* Version Number */
3027                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_solicited_version, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
3028                 opt_offset += 1;
3029 
3030                 break;
3031             }
3032             case RPL_OPT_PREFIX: {
3033                 /* Destination prefix option. */
3034                 guint32              prefix_len;
3035                 static int * const rpl_prefix_flags[] = {
3036                     &hf_icmpv6_rpl_opt_prefix_flag_l,
3037                     &hf_icmpv6_rpl_opt_prefix_flag_a,
3038                     &hf_icmpv6_rpl_opt_prefix_flag_r,
3039                     &hf_icmpv6_rpl_opt_prefix_flag_rsv,
3040                     NULL
3041                 };
3042 
3043                 /* Prefix length */
3044                 proto_tree_add_item_ret_uint(icmp6opt_tree, hf_icmpv6_rpl_opt_prefix_length, tvb, opt_offset, 1, ENC_BIG_ENDIAN, &prefix_len);
3045                 opt_offset +=1;
3046 
3047                 /* Flags */
3048                 proto_tree_add_bitmask(icmp6opt_tree, tvb, opt_offset, hf_icmpv6_rpl_opt_prefix_flag,
3049                                     ett_icmpv6_rpl_flag_prefix, rpl_prefix_flags, ENC_BIG_ENDIAN);
3050                 opt_offset += 1;
3051 
3052                 /* Valid lifetime. */
3053                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_prefix_vlifetime, tvb, opt_offset, 4, ENC_BIG_ENDIAN);
3054                 opt_offset += 4;
3055 
3056                 /* Preferred Lifetime */
3057                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_prefix_plifetime, tvb, opt_offset, 4, ENC_BIG_ENDIAN);
3058                 opt_offset += 4;
3059 
3060                 /* 4 reserved bytes. */
3061                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_reserved, tvb, opt_offset, 4, ENC_NA);
3062                 opt_offset += 4;
3063 
3064                 /* Prefix */
3065                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_prefix, tvb, opt_offset, 16, ENC_NA);
3066                 proto_item_append_text(ti, " %s/%d", tvb_ip6_to_str(pinfo->pool, tvb, opt_offset), prefix_len);
3067                 opt_offset += 16;
3068 
3069                 break;
3070             }
3071 
3072             case RPL_OPT_TARGETDESC: {
3073 
3074                 /* Descriptor */
3075                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_targetdesc, tvb, opt_offset, 4, ENC_BIG_ENDIAN);
3076                 opt_offset += 4;
3077                 break;
3078             }
3079 
3080             case RPL_OPT_ROUTE_DISCOVERY: {
3081                 int num_of_addr = 0;
3082                 guint8 flags = 0, compr = 0, addr_len = 0, lt_mr_nh = 0;
3083                 guint8 addr[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
3084 
3085                 /* Flags */
3086                 ti_opt = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_route_discovery_flag, tvb, opt_offset, 1, ENC_NA);
3087                 flag_tree = proto_item_add_subtree(ti_opt, ett_icmpv6_rpl_route_discovery_flag);
3088 
3089                 flags = tvb_get_guint8(tvb, opt_offset);
3090                 compr = flags & RPL_OPT_ROUTE_DISCOVERY_COMPR;
3091 
3092                 /* Reply */
3093                 ti_opt_reply = proto_tree_add_item(flag_tree, hf_icmpv6_rpl_opt_route_discovery_reply, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
3094 
3095                 /* Hop-by-Hop */
3096                 ti_opt_hop_by_hop = proto_tree_add_item(flag_tree, hf_icmpv6_rpl_opt_route_discovery_hop_by_hop, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
3097 
3098                 /* Num of Source Routes */
3099                 ti_opt_num_of_routes = proto_tree_add_item(flag_tree, hf_icmpv6_rpl_opt_route_discovery_num_of_routes, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
3100 
3101                 /* Compr */
3102                 proto_tree_add_item(flag_tree, hf_icmpv6_rpl_opt_route_discovery_compr, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
3103                 opt_offset +=1;
3104 
3105                 /* Lifetime / MaxRank / NH */
3106                 lt_mr_nh = tvb_get_guint8(tvb, opt_offset);
3107                 ti_opt_lifetime = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_route_discovery_lifetime, tvb, opt_offset, 1, ENC_NA);
3108 
3109                 if ((icmp6_code == ICMP6_RPL_P2P_DRO) || (icmp6_code == ICMP6_RPL_P2P_SDRO)) {
3110                     proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_route_discovery_nh, tvb, opt_offset, 1, ENC_NA);
3111                 } else {
3112                     ti_opt_mr_nh = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_route_discovery_maxrank, tvb, opt_offset, 1, ENC_NA);
3113                 }
3114 
3115                 opt_offset +=1;
3116 
3117                 /* add expert and auxiliary info */
3118                 switch (icmp6_code) {
3119                     case ICMP6_RPL_P2P_SDRO:
3120                     case ICMP6_RPL_P2P_DRO:
3121 
3122                         if (flags & RPL_OPT_ROUTE_DISCOVERY_R) {
3123                             expert_add_info(pinfo, ti_opt_reply, &ei_icmpv6_rpl_p2p_dro_rdo_zero);
3124                         }
3125 
3126                         if (flags & RPL_OPT_ROUTE_DISCOVERY_N) {
3127                             expert_add_info(pinfo, ti_opt_num_of_routes, &ei_icmpv6_rpl_p2p_dro_rdo_zero);
3128                         }
3129 
3130                         if (lt_mr_nh & RPL_OPT_ROUTE_DISCOVERY_L) {
3131                             expert_add_info(pinfo, ti_opt_lifetime, &ei_icmpv6_rpl_p2p_dro_rdo_zero);
3132                         }
3133 
3134                         break;
3135                     default:
3136 
3137                         if (flags & RPL_OPT_ROUTE_DISCOVERY_H) {
3138                             if (!(flags & RPL_OPT_ROUTE_DISCOVERY_R)) {
3139                                 expert_add_info(pinfo, ti_opt_hop_by_hop, &ei_icmpv6_rpl_p2p_hop_by_hop);
3140                             }
3141 
3142                             if (flags & RPL_OPT_ROUTE_DISCOVERY_N) {
3143                                 expert_add_info(pinfo, ti_opt_num_of_routes, &ei_icmpv6_rpl_p2p_num_of_routes);
3144                             }
3145                         }
3146 
3147                         proto_item_append_text(ti_opt_lifetime, " (%u sec)", pow4(guint32, (lt_mr_nh & RPL_OPT_ROUTE_DISCOVERY_L) >> 6));
3148 
3149                         if (!(lt_mr_nh & RPL_OPT_ROUTE_DISCOVERY_MR_NH)) {
3150                             proto_item_append_text(ti_opt_mr_nh, " (Infinity)");
3151                         }
3152 
3153                         break;
3154                 }
3155 
3156                 /* TargetAddr */
3157                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_route_discovery_target_addr, tvb, opt_offset, 16, ENC_NA);
3158                 opt_offset +=16;
3159 
3160                 addr_len = (16 - compr);
3161                 num_of_addr = (opt_len - 18) / addr_len;
3162 
3163                 /* Address Vector */
3164                 ti_opt = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_route_discovery_addr_vec, tvb, opt_offset, (opt_len - 18), ENC_NA);
3165                 flag_tree = proto_item_add_subtree(ti_opt, ett_icmpv6_rpl_route_discovery_addr_vec);
3166 
3167                 proto_item_append_text(flag_tree, " (%d Address%s)", num_of_addr, num_of_addr != 1 ? "es" : "");
3168 
3169                 while (num_of_addr--) {
3170                     memset(addr, 0, sizeof(addr));
3171                     tvb_memcpy(tvb, addr + compr, opt_offset, addr_len);
3172                     proto_tree_add_ipv6(flag_tree, hf_icmpv6_rpl_opt_route_discovery_addr_vec_addr, tvb, opt_offset, addr_len, (ws_in6_addr *)addr);
3173                     opt_offset += addr_len;
3174                 }
3175 
3176                 break;
3177             }
3178             default :
3179                 expert_add_info_format(pinfo, ti, &ei_icmpv6_undecoded_rpl_option,
3180                                        "Dissector for ICMPv6 RPL Option"
3181                                        " (%d) code not implemented, Contact"
3182                                        " Wireshark developers if you want this supported", opt_type);
3183                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_data, tvb, opt_offset, opt_len, ENC_NA);
3184                 opt_offset += opt_len;
3185                 break;
3186         } /* switch (opt_type) */
3187 
3188         offset += opt_len + 2;
3189 
3190         if(offset > opt_offset){
3191             ti_opt = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_unknown_data, tvb, opt_offset, offset - opt_offset, ENC_NA);
3192             expert_add_info(pinfo, ti_opt, &ei_icmpv6_unknown_data);
3193         }
3194 
3195         /* Close the ) to option root label */
3196         proto_item_append_text(ti, ")");
3197     } /* while */
3198     return offset;
3199 }
3200 
3201 static int
dissect_rpl_control(tvbuff_t * tvb,int rpl_offset,packet_info * pinfo _U_,proto_tree * icmp6_tree,guint8 icmp6_type _U_,guint8 icmp6_code)3202 dissect_rpl_control(tvbuff_t *tvb, int rpl_offset, packet_info *pinfo _U_, proto_tree *icmp6_tree, guint8 icmp6_type _U_, guint8 icmp6_code)
3203 {
3204     proto_item *ti;
3205 
3206     /* Secure RPL ? (ICMP Code start to 0x8x) */
3207     if(icmp6_code & ICMP6_RPL_SECURE)
3208     {
3209         guint8 kim, lvl;
3210         static int * const rpl_secure_flags[] = {
3211             &hf_icmpv6_rpl_secure_flag_t,
3212             &hf_icmpv6_rpl_secure_flag_rsv,
3213             NULL
3214         };
3215         static int * const rpl_secure_flags2[] = {
3216             &hf_icmpv6_rpl_secure_kim,
3217             &hf_icmpv6_rpl_secure_lvl,
3218             &hf_icmpv6_rpl_secure_rsv,
3219             NULL
3220         };
3221 
3222         /* Flags */
3223         proto_tree_add_bitmask(icmp6_tree, tvb, rpl_offset, hf_icmpv6_rpl_secure_flag,
3224                             ett_icmpv6_flag_secure, rpl_secure_flags, ENC_BIG_ENDIAN);
3225         rpl_offset += 1;
3226 
3227         /* Algorithm */
3228         proto_tree_add_item(icmp6_tree, hf_icmpv6_rpl_secure_algorithm, tvb, rpl_offset, 1, ENC_BIG_ENDIAN);
3229         rpl_offset += 1;
3230 
3231         /* KIM & LVL */
3232         proto_tree_add_bitmask(icmp6_tree, tvb, rpl_offset, hf_icmpv6_rpl_secure_flag,
3233                             ett_icmpv6_flag_secure, rpl_secure_flags2, ENC_BIG_ENDIAN);
3234         kim = tvb_get_guint8(tvb, rpl_offset) & RPL_SECURE_KIM >> 6;
3235         lvl = tvb_get_guint8(tvb, rpl_offset) & RPL_SECURE_LVL;
3236         rpl_offset += 1;
3237 
3238         /* Flags */
3239         proto_tree_add_item(icmp6_tree, hf_icmpv6_rpl_secure_flag, tvb, rpl_offset, 1, ENC_BIG_ENDIAN);
3240         rpl_offset += 1;
3241 
3242         /* Counter */
3243         proto_tree_add_item(icmp6_tree, hf_icmpv6_rpl_secure_counter, tvb, rpl_offset, 4, ENC_BIG_ENDIAN);
3244         rpl_offset += 4;
3245 
3246         /*  Key Identifier */
3247         switch(kim){
3248             case 0:
3249             {
3250                 proto_tree_add_item(icmp6_tree, hf_icmpv6_rpl_secure_key_index, tvb, rpl_offset, 1, ENC_BIG_ENDIAN);
3251                 rpl_offset += 1;
3252                 break;
3253             }
3254             case 1:
3255             {
3256                 /* No Key Identifier */
3257                 break;
3258             }
3259             case 2:
3260             {
3261                 proto_tree_add_item(icmp6_tree, hf_icmpv6_rpl_secure_key_source, tvb, rpl_offset, 8, ENC_NA);
3262                 rpl_offset += 8;
3263                 proto_tree_add_item(icmp6_tree, hf_icmpv6_rpl_secure_key_index, tvb, rpl_offset, 1, ENC_BIG_ENDIAN);
3264                 rpl_offset += 1;
3265                 break;
3266             }
3267             case 3:
3268             {
3269                 if(lvl == 1 || lvl == 3)
3270                 {
3271                     proto_tree_add_item(icmp6_tree, hf_icmpv6_rpl_secure_key_source, tvb, rpl_offset, 8, ENC_NA);
3272                     rpl_offset += 8;
3273                     proto_tree_add_item(icmp6_tree, hf_icmpv6_rpl_secure_key_index, tvb, rpl_offset, 1, ENC_BIG_ENDIAN);
3274                     rpl_offset += 1;
3275                 }
3276                 break;
3277             }
3278 
3279         }
3280 
3281     }
3282     switch(icmp6_code){
3283         case ICMP6_RPL_DIS: /* DODAG Information Solicitation (0) */
3284         case ICMP6_RPL_SDIS: /* Secure DODAG Information Solicitation (128) */
3285         {
3286             /* Flags */
3287             proto_tree_add_item(icmp6_tree, hf_icmpv6_rpl_dis_flag, tvb, rpl_offset, 1, ENC_BIG_ENDIAN);
3288             rpl_offset += 1;
3289 
3290             /* Reserved */
3291             proto_tree_add_item(icmp6_tree, hf_icmpv6_reserved, tvb, rpl_offset, 1, ENC_NA);
3292             rpl_offset += 1;
3293 
3294             /* RPL Options */
3295             rpl_offset = dissect_icmpv6_rpl_opt(tvb, rpl_offset, pinfo, icmp6_tree, icmp6_code);
3296             break;
3297         }
3298         case ICMP6_RPL_DIO: /* DODAG Information Object (1) */
3299         case ICMP6_RPL_SDIO: /* Secure DODAG Information Object (129) */
3300         {
3301             static int * const rpl_dio_flags[] = {
3302                 &hf_icmpv6_rpl_dio_flag_g,
3303                 &hf_icmpv6_rpl_dio_flag_0,
3304                 &hf_icmpv6_rpl_dio_flag_mop,
3305                 &hf_icmpv6_rpl_dio_flag_prf,
3306                 NULL
3307             };
3308 
3309             /* RPLInstanceID */
3310             proto_tree_add_item(icmp6_tree, hf_icmpv6_rpl_dio_instance, tvb, rpl_offset, 1, ENC_BIG_ENDIAN);
3311             rpl_offset += 1;
3312 
3313             /* Version Number */
3314             proto_tree_add_item(icmp6_tree, hf_icmpv6_rpl_dio_version, tvb, rpl_offset, 1, ENC_BIG_ENDIAN);
3315             rpl_offset += 1;
3316 
3317             /* Rank */
3318             proto_tree_add_item(icmp6_tree, hf_icmpv6_rpl_dio_rank, tvb, rpl_offset, 2, ENC_BIG_ENDIAN);
3319             rpl_offset += 2;
3320 
3321             /* Flags */
3322             proto_tree_add_bitmask(icmp6_tree, tvb, rpl_offset, hf_icmpv6_rpl_dio_flag,
3323                                 ett_icmpv6_flag_rpl_dio, rpl_dio_flags, ENC_BIG_ENDIAN);
3324             rpl_offset += 1;
3325 
3326             /* Destination Advertisement Trigger Sequence Number (DTSN) */
3327             proto_tree_add_item(icmp6_tree, hf_icmpv6_rpl_dio_dtsn, tvb, rpl_offset, 1, ENC_BIG_ENDIAN);
3328             rpl_offset += 1;
3329 
3330             /* Flags */
3331             proto_tree_add_item(icmp6_tree, hf_icmpv6_rpl_dio_flag, tvb, rpl_offset, 1, ENC_BIG_ENDIAN);
3332             rpl_offset += 1;
3333 
3334             /* Reserved */
3335             proto_tree_add_item(icmp6_tree, hf_icmpv6_reserved, tvb, rpl_offset, 1, ENC_NA);
3336             rpl_offset += 1;
3337 
3338             /* DODAGID */
3339             proto_tree_add_item(icmp6_tree, hf_icmpv6_rpl_dio_dagid, tvb, rpl_offset, 16, ENC_NA);
3340             rpl_offset += 16;
3341 
3342             /* RPL Options */
3343             rpl_offset = dissect_icmpv6_rpl_opt(tvb, rpl_offset, pinfo, icmp6_tree, icmp6_code);
3344             break;
3345         }
3346         case ICMP6_RPL_DAO: /* Destination Advertisement Object (2) */
3347         case ICMP6_RPL_SDAO: /* Secure Destination Advertisement Object (130) */
3348         {
3349             guint8 flags;
3350             static int * const rpl_dao_flags[] = {
3351                 &hf_icmpv6_rpl_dao_flag_k,
3352                 &hf_icmpv6_rpl_dao_flag_d,
3353                 &hf_icmpv6_rpl_dao_flag_rsv,
3354                 NULL
3355             };
3356 
3357             /* DAO Instance */
3358             proto_tree_add_item(icmp6_tree, hf_icmpv6_rpl_dao_instance, tvb, rpl_offset, 1, ENC_BIG_ENDIAN);
3359             rpl_offset += 1;
3360 
3361             /* Flags */
3362             proto_tree_add_bitmask(icmp6_tree, tvb, rpl_offset, hf_icmpv6_rpl_dao_flag,
3363                                 ett_icmpv6_flag_rpl_dao, rpl_dao_flags, ENC_BIG_ENDIAN);
3364             flags = tvb_get_guint8(tvb, rpl_offset);
3365             rpl_offset += 1;
3366 
3367             /* Reserved */
3368             proto_tree_add_item(icmp6_tree, hf_icmpv6_reserved, tvb, rpl_offset, 1, ENC_NA);
3369             rpl_offset += 1;
3370 
3371             /* Sequence */
3372             proto_tree_add_item(icmp6_tree, hf_icmpv6_rpl_dao_sequence, tvb, rpl_offset, 1, ENC_BIG_ENDIAN);
3373             rpl_offset += 1;
3374 
3375             /* DODAGID */
3376             if(flags & RPL_DAO_FLAG_D)
3377             {
3378                 proto_tree_add_item(icmp6_tree, hf_icmpv6_rpl_dao_dodagid, tvb, rpl_offset, 16, ENC_NA);
3379                 rpl_offset += 16;
3380             }
3381             /* Options */
3382             rpl_offset = dissect_icmpv6_rpl_opt(tvb, rpl_offset, pinfo, icmp6_tree, icmp6_code);
3383             break;
3384         }
3385         case ICMP6_RPL_DAOACK: /* Destination Advertisement Object Acknowledgment (3) */
3386         case ICMP6_RPL_SDAOACK: /* Secure Destination Advertisement Object Acknowledgment (131) */
3387         {
3388             guint8 flags;
3389             static int * const rpl_daoack_flags[] = {
3390                 &hf_icmpv6_rpl_daoack_flag_d,
3391                 &hf_icmpv6_rpl_daoack_flag_rsv,
3392                 NULL
3393             };
3394 
3395             /* DAO Instance */
3396             proto_tree_add_item(icmp6_tree, hf_icmpv6_rpl_daoack_instance, tvb, rpl_offset, 1, ENC_BIG_ENDIAN);
3397             rpl_offset += 1;
3398 
3399             /* Flags */
3400             proto_tree_add_bitmask(icmp6_tree, tvb, rpl_offset, hf_icmpv6_rpl_daoack_flag,
3401                                 ett_icmpv6_flag_rpl_daoack, rpl_daoack_flags, ENC_BIG_ENDIAN);
3402             flags = tvb_get_guint8(tvb, rpl_offset);
3403             rpl_offset += 1;
3404 
3405             /* DAO Sequence */
3406             proto_tree_add_item(icmp6_tree, hf_icmpv6_rpl_daoack_sequence, tvb, rpl_offset, 1, ENC_BIG_ENDIAN);
3407             rpl_offset += 1;
3408 
3409             /* Status */
3410             proto_tree_add_item(icmp6_tree, hf_icmpv6_rpl_daoack_status, tvb, rpl_offset, 1, ENC_BIG_ENDIAN);
3411             rpl_offset += 1;
3412 
3413             /* DODAGID */
3414             if(flags & RPL_DAOACK_FLAG_D)
3415             {
3416                 proto_tree_add_item(icmp6_tree, hf_icmpv6_rpl_daoack_dodagid, tvb, rpl_offset, 16, ENC_NA);
3417                 rpl_offset += 16;
3418             }
3419 
3420             /* Options */
3421             rpl_offset = dissect_icmpv6_rpl_opt(tvb, rpl_offset, pinfo, icmp6_tree, icmp6_code);
3422             break;
3423         }
3424        case ICMP6_RPL_CC:
3425        {
3426             static int * const rpl_cc_flags[] = {
3427                 &hf_icmpv6_rpl_cc_flag_r,
3428                 &hf_icmpv6_rpl_cc_flag_rsv,
3429                 NULL
3430             };
3431 
3432             /* CC Instance */
3433             proto_tree_add_item(icmp6_tree, hf_icmpv6_rpl_cc_instance, tvb, rpl_offset, 1, ENC_BIG_ENDIAN);
3434             rpl_offset += 1;
3435 
3436             /* Flags */
3437             proto_tree_add_bitmask(icmp6_tree, tvb, rpl_offset, hf_icmpv6_rpl_cc_flag,
3438                                 ett_icmpv6_flag_rpl_cc, rpl_cc_flags, ENC_BIG_ENDIAN);
3439             rpl_offset += 1;
3440 
3441             /* CC Nonce */
3442             proto_tree_add_item(icmp6_tree, hf_icmpv6_rpl_cc_nonce, tvb, rpl_offset, 2, ENC_BIG_ENDIAN);
3443             rpl_offset += 2;
3444 
3445             /* DODAGID */
3446             proto_tree_add_item(icmp6_tree, hf_icmpv6_rpl_cc_dodagid, tvb, rpl_offset, 16, ENC_NA);
3447             rpl_offset += 16;
3448 
3449             /* Destination Counter */
3450             proto_tree_add_item(icmp6_tree, hf_icmpv6_rpl_cc_destination_counter, tvb, rpl_offset, 4, ENC_BIG_ENDIAN);
3451             rpl_offset += 4;
3452 
3453             /* Options */
3454             rpl_offset = dissect_icmpv6_rpl_opt(tvb, rpl_offset, pinfo, icmp6_tree, icmp6_code);
3455             break;
3456        }
3457         case ICMP6_RPL_P2P_DRO: /* P2P Discovery Reply Object (0x4) */
3458         case ICMP6_RPL_P2P_SDRO: /* Secure P2P Discovery Reply Object (0x84) */
3459         {
3460             static int * const rpl_p2p_dro_flags[] = {
3461                 &hf_icmpv6_rpl_p2p_dro_flag_stop,
3462                 &hf_icmpv6_rpl_p2p_dro_flag_ack,
3463                 &hf_icmpv6_rpl_p2p_dro_flag_seq,
3464                 &hf_icmpv6_rpl_p2p_dro_flag_reserved,
3465                 NULL
3466             };
3467 
3468             /* RPLInstanceID */
3469             proto_tree_add_item(icmp6_tree, hf_icmpv6_rpl_p2p_dro_instance, tvb, rpl_offset, 1, ENC_BIG_ENDIAN);
3470             rpl_offset += 1;
3471 
3472             /* Version Number */
3473             ti = proto_tree_add_item(icmp6_tree, hf_icmpv6_rpl_p2p_dro_version, tvb, rpl_offset, 1, ENC_BIG_ENDIAN);
3474             if (tvb_get_guint8(tvb, rpl_offset)) {
3475                 expert_add_info(pinfo, ti, &ei_icmpv6_rpl_p2p_dro_zero);
3476             }
3477             rpl_offset += 1;
3478 
3479             /* Flags */
3480             proto_tree_add_bitmask(icmp6_tree, tvb, rpl_offset, hf_icmpv6_rpl_p2p_dro_flag,
3481                                 ett_icmpv6_rpl_p2p_dro_flag, rpl_p2p_dro_flags, ENC_BIG_ENDIAN);
3482             rpl_offset += 2;
3483 
3484             /* DODAGID */
3485             proto_tree_add_item(icmp6_tree, hf_icmpv6_rpl_p2p_dro_dagid, tvb, rpl_offset, 16, ENC_NA);
3486             rpl_offset += 16;
3487 
3488             /* RPL Options */
3489             rpl_offset = dissect_icmpv6_rpl_opt(tvb, rpl_offset, pinfo, icmp6_tree, icmp6_code);
3490             break;
3491         }
3492         case ICMP6_RPL_P2P_DROACK:  /* P2P Discovery Reply Object Acknowledgement (0x5) */
3493         case ICMP6_RPL_P2P_SDROACK: /* Secure P2P Discovery Reply Object Acknowledgement (0x85) */
3494         {
3495             static int * const rpl_p2p_droack_flags[] = {
3496                 &hf_icmpv6_rpl_p2p_droack_flag_seq,
3497                 &hf_icmpv6_rpl_p2p_droack_flag_reserved,
3498                 NULL
3499             };
3500 
3501             /* RPLInstanceID */
3502             proto_tree_add_item(icmp6_tree, hf_icmpv6_rpl_p2p_dro_instance, tvb, rpl_offset, 1, ENC_BIG_ENDIAN);
3503             rpl_offset += 1;
3504 
3505             /* Version Number */
3506             ti = proto_tree_add_item(icmp6_tree, hf_icmpv6_rpl_p2p_dro_version, tvb, rpl_offset, 1, ENC_BIG_ENDIAN);
3507             if (tvb_get_guint8(tvb, rpl_offset)) {
3508                 expert_add_info(pinfo, ti, &ei_icmpv6_rpl_p2p_dro_zero);
3509             }
3510             rpl_offset += 1;
3511 
3512             /* Flags */
3513             proto_tree_add_bitmask(icmp6_tree, tvb, rpl_offset, hf_icmpv6_rpl_p2p_droack_flag,
3514                                 ett_icmpv6_rpl_p2p_droack_flag, rpl_p2p_droack_flags, ENC_BIG_ENDIAN);
3515             rpl_offset += 2;
3516 
3517             /* DODAGID */
3518             proto_tree_add_item(icmp6_tree, hf_icmpv6_rpl_p2p_dro_dagid, tvb, rpl_offset, 16, ENC_NA);
3519             rpl_offset += 16;
3520             break;
3521         }
3522 
3523     }
3524     return rpl_offset;
3525 }
3526 /* RFC 4620 - IPv6 Node Information Queries */
3527 
3528 static int
dissect_nodeinfo(tvbuff_t * tvb,int ni_offset,packet_info * pinfo _U_,proto_tree * tree,guint8 icmp6_type,guint8 icmp6_code)3529 dissect_nodeinfo(tvbuff_t *tvb, int ni_offset, packet_info *pinfo _U_, proto_tree *tree, guint8 icmp6_type, guint8 icmp6_code)
3530 {
3531     guint16     qtype;
3532     guint       used_bytes;
3533     static int * const ni_flags[] = {
3534         &hf_icmpv6_ni_flag_g,
3535         &hf_icmpv6_ni_flag_s,
3536         &hf_icmpv6_ni_flag_l,
3537         &hf_icmpv6_ni_flag_c,
3538         &hf_icmpv6_ni_flag_a,
3539         &hf_icmpv6_ni_flag_t,
3540         &hf_icmpv6_ni_flag_rsv,
3541         NULL
3542     };
3543 
3544     /* Qtype */
3545     proto_tree_add_item(tree, hf_icmpv6_ni_qtype, tvb, ni_offset, 2, ENC_BIG_ENDIAN);
3546     qtype = tvb_get_ntohs(tvb, ni_offset);
3547     ni_offset += 2;
3548 
3549     /* Flags */
3550     proto_tree_add_bitmask(tree, tvb, ni_offset, hf_icmpv6_ni_flag,
3551                         ett_icmpv6_flag_ni, ni_flags, ENC_BIG_ENDIAN);
3552     ni_offset += 2;
3553 
3554     /* Nonce */
3555     proto_tree_add_item(tree, hf_icmpv6_ni_nonce, tvb, ni_offset, 8, ENC_BIG_ENDIAN);
3556     ni_offset += 8;
3557 
3558     /* Data ? */
3559     if(tvb_reported_length_remaining(tvb, ni_offset) == 0){
3560         return ni_offset;
3561     }
3562 
3563     if(icmp6_type == ICMP6_NI_QUERY){
3564         switch(icmp6_code){
3565             case ICMP6_NI_SUBJ_IPV6: {
3566                 proto_tree_add_item(tree, hf_icmpv6_ni_query_subject_ipv6, tvb, ni_offset, 16, ENC_NA);
3567                 ni_offset += 16;
3568                 break;
3569             }
3570             case ICMP6_NI_SUBJ_FQDN: {
3571                 int fqdn_len;
3572                 const gchar *fqdn_name;
3573                 used_bytes = get_dns_name(tvb, ni_offset, 0, ni_offset, &fqdn_name, &fqdn_len);
3574                 proto_tree_add_string(tree, hf_icmpv6_ni_query_subject_fqdn, tvb, ni_offset, used_bytes,
3575                     format_text(pinfo->pool, fqdn_name, fqdn_len));
3576                 ni_offset += used_bytes;
3577                 break;
3578             }
3579             case ICMP6_NI_SUBJ_IPV4: {
3580                 proto_tree_add_item(tree, hf_icmpv6_ni_query_subject_ipv4, tvb, ni_offset, 4, ENC_BIG_ENDIAN);
3581                 ni_offset += 4;
3582                 break;
3583             }
3584         }
3585     } else { /* It is ICMP6_NI_REPLY */
3586         switch(qtype){
3587             case NI_QTYPE_NOOP:
3588                 break;
3589             case NI_QTYPE_NODENAME: {
3590                 int node_name_len;
3591                 const gchar *node_name;
3592                 /* TTL */
3593                 proto_tree_add_item(tree, hf_icmpv6_ni_reply_node_ttl, tvb, ni_offset, 4, ENC_BIG_ENDIAN);
3594                 ni_offset += 4;
3595                 /* Data ? */
3596                 if(tvb_reported_length_remaining(tvb, ni_offset) == 0){
3597                     return ni_offset;
3598                 }
3599                 while(ni_offset < (int)tvb_reported_length(tvb) ) {
3600 
3601                     if(tvb_get_guint8(tvb, ni_offset) == 0){ /* if Zero there is padding, skip the loop */
3602                         break;
3603                     }
3604                     /* Node Name */
3605                     used_bytes = get_dns_name(tvb, ni_offset, 0, ni_offset, &node_name, &node_name_len);
3606                     proto_tree_add_string(tree, hf_icmpv6_ni_reply_node_name, tvb, ni_offset, used_bytes,
3607                         format_text(pinfo->pool, node_name, node_name_len));
3608                     ni_offset += used_bytes;
3609                 }
3610                 break;
3611             }
3612             case NI_QTYPE_NODEADDR: {
3613                 while(ni_offset < (int)tvb_reported_length(tvb) ) {
3614                     /* TTL */
3615                     proto_tree_add_item(tree, hf_icmpv6_ni_reply_node_ttl, tvb, ni_offset, 4, ENC_BIG_ENDIAN);
3616                     ni_offset += 4;
3617                     /* Node Addresses */
3618                     proto_tree_add_item(tree, hf_icmpv6_ni_reply_node_address, tvb, ni_offset, 16, ENC_NA);
3619                     ni_offset += 16;
3620                 }
3621                 break;
3622             }
3623             case NI_QTYPE_IPV4ADDR: {
3624                 while(ni_offset < (int)tvb_reported_length(tvb) ) {
3625                     /* TTL */
3626                     proto_tree_add_item(tree, hf_icmpv6_ni_reply_node_ttl, tvb, ni_offset, 4, ENC_BIG_ENDIAN);
3627                     ni_offset += 4;
3628                     /* IPv4 Address */
3629                     proto_tree_add_item(tree, hf_icmpv6_ni_reply_ipv4_address, tvb, ni_offset, 4, ENC_BIG_ENDIAN);
3630                     ni_offset += 4;
3631                 }
3632                 break;
3633             }
3634         }
3635     }
3636     return ni_offset;
3637 }
3638 /* RFC 2894 - Router Renumbering for IPv6 */
3639 
3640 static int
dissect_rrenum(tvbuff_t * tvb,int rr_offset,packet_info * pinfo _U_,proto_tree * tree,guint8 icmp6_type _U_,guint8 icmp6_code)3641 dissect_rrenum(tvbuff_t *tvb, int rr_offset, packet_info *pinfo _U_, proto_tree *tree, guint8 icmp6_type _U_, guint8 icmp6_code)
3642 {
3643     proto_tree *mp_tree, *up_tree, *rm_tree;
3644     proto_item *ti,        *ti_mp,   *ti_up,   *ti_rm;
3645     static int * const rr_flags[] = {
3646         &hf_icmpv6_rr_flag_t,
3647         &hf_icmpv6_rr_flag_r,
3648         &hf_icmpv6_rr_flag_a,
3649         &hf_icmpv6_rr_flag_s,
3650         &hf_icmpv6_rr_flag_p,
3651         &hf_icmpv6_rr_flag_rsv,
3652         NULL
3653     };
3654 
3655     /* Sequence Number */
3656     proto_tree_add_item(tree, hf_icmpv6_rr_sequencenumber, tvb, rr_offset, 4, ENC_BIG_ENDIAN);
3657     rr_offset += 4;
3658 
3659     /* Segment Number */
3660     proto_tree_add_item(tree, hf_icmpv6_rr_segmentnumber, tvb, rr_offset, 1, ENC_BIG_ENDIAN);
3661     rr_offset += 1;
3662 
3663     /* Flags */
3664     proto_tree_add_bitmask(tree, tvb, rr_offset, hf_icmpv6_rr_flag,
3665                         ett_icmpv6_flag_rr, rr_flags, ENC_BIG_ENDIAN);
3666     rr_offset += 1;
3667 
3668     /* Max Delay */
3669     proto_tree_add_item(tree, hf_icmpv6_rr_maxdelay, tvb, rr_offset, 2, ENC_BIG_ENDIAN);
3670     rr_offset += 2;
3671 
3672     /* Reserved */
3673     proto_tree_add_item(tree, hf_icmpv6_reserved, tvb, rr_offset, 4, ENC_NA);
3674     rr_offset += 4;
3675 
3676     /* Data ? */
3677     if(tvb_reported_length_remaining(tvb, rr_offset) == 0){
3678         return rr_offset;
3679     }
3680 
3681     if(icmp6_code == ICMP6_ROUTER_RENUMBERING_COMMAND){
3682         /* Match-Prefix Part */
3683         guint8 opcode, matchlen, minlen, maxlen;
3684 
3685         ti_mp = proto_tree_add_item(tree, hf_icmpv6_rr_pco_mp_part, tvb, rr_offset, 24, ENC_NA);
3686         mp_tree = proto_item_add_subtree(ti_mp, ett_icmpv6_rr_mp);
3687 
3688         /* OpCode */
3689         proto_tree_add_item(mp_tree, hf_icmpv6_rr_pco_mp_opcode, tvb, rr_offset, 1, ENC_BIG_ENDIAN);
3690         opcode = tvb_get_guint8(tvb, rr_offset);
3691         rr_offset += 1;
3692 
3693         /* OpLength */
3694         proto_tree_add_item(mp_tree, hf_icmpv6_rr_pco_mp_oplength, tvb, rr_offset, 1, ENC_BIG_ENDIAN);
3695         rr_offset += 1;
3696 
3697         /* Ordinal */
3698         proto_tree_add_item(mp_tree, hf_icmpv6_rr_pco_mp_ordinal, tvb, rr_offset, 1, ENC_BIG_ENDIAN);
3699         rr_offset += 1;
3700 
3701         /* MatchLen  */
3702         ti = proto_tree_add_item(mp_tree, hf_icmpv6_rr_pco_mp_matchlen, tvb, rr_offset, 1, ENC_BIG_ENDIAN);
3703         matchlen = tvb_get_guint8(tvb, rr_offset);
3704         if (matchlen > 128) {
3705             expert_add_info(pinfo, ti, &ei_icmpv6_rr_pco_mp_matchlen);
3706         }
3707         rr_offset += 1;
3708 
3709         /* MinLen  */
3710         proto_tree_add_item(mp_tree, hf_icmpv6_rr_pco_mp_minlen, tvb, rr_offset, 1, ENC_BIG_ENDIAN);
3711         minlen = tvb_get_guint8(tvb, rr_offset);
3712         rr_offset += 1;
3713 
3714         /* MaxLen  */
3715         proto_tree_add_item(mp_tree, hf_icmpv6_rr_pco_mp_maxlen, tvb, rr_offset, 1, ENC_BIG_ENDIAN);
3716         maxlen = tvb_get_guint8(tvb, rr_offset);
3717         rr_offset += 1;
3718 
3719         /* Reserved  */
3720         proto_tree_add_item(mp_tree, hf_icmpv6_reserved, tvb, rr_offset, 2, ENC_NA);
3721         rr_offset += 2;
3722 
3723         /* Match Prefix  */
3724         proto_tree_add_item(mp_tree, hf_icmpv6_rr_pco_mp_matchprefix, tvb, rr_offset, 16, ENC_NA);
3725 
3726         /* Add Info (Prefix, Length...) to Match Prefix Part label */
3727         proto_item_append_text(ti_mp, ": %s %s/%u (%u-%u)", val_to_str(opcode, rr_pco_mp_opcode_val, "Unknown %d"), tvb_ip6_to_str(pinfo->pool, tvb, rr_offset), matchlen, minlen, maxlen);
3728         rr_offset += 16;
3729 
3730         while ((int)tvb_reported_length(tvb) > rr_offset) {
3731             /* Use-Prefix Part */
3732             guint8 uselen, keeplen;
3733             static int * const mask_flags[] = {
3734                 &hf_icmpv6_rr_pco_up_flagmask_l,
3735                 &hf_icmpv6_rr_pco_up_flagmask_a,
3736                 &hf_icmpv6_rr_pco_up_flagmask_reserved,
3737                 NULL
3738             };
3739             static int * const ra_flags[] = {
3740                 &hf_icmpv6_rr_pco_up_raflags_l,
3741                 &hf_icmpv6_rr_pco_up_raflags_a,
3742                 &hf_icmpv6_rr_pco_up_raflags_reserved,
3743                 NULL
3744             };
3745             static int * const up_flags[] = {
3746                 &hf_icmpv6_rr_pco_up_flag_v,
3747                 &hf_icmpv6_rr_pco_up_flag_p,
3748                 &hf_icmpv6_rr_pco_up_flag_reserved,
3749                 NULL
3750             };
3751 
3752             ti_up = proto_tree_add_item(tree, hf_icmpv6_rr_pco_up_part, tvb, rr_offset, 32, ENC_NA);
3753             up_tree = proto_item_add_subtree(ti_up, ett_icmpv6_rr_up);
3754 
3755             /* UseLen */
3756             proto_tree_add_item(up_tree, hf_icmpv6_rr_pco_up_uselen, tvb, rr_offset, 1, ENC_BIG_ENDIAN);
3757             uselen = tvb_get_guint8(tvb, rr_offset);
3758             rr_offset += 1;
3759 
3760             /* KeepLen */
3761             proto_tree_add_item(up_tree, hf_icmpv6_rr_pco_up_keeplen, tvb, rr_offset, 1, ENC_BIG_ENDIAN);
3762             keeplen = tvb_get_guint8(tvb, rr_offset);
3763             rr_offset += 1;
3764 
3765             /* FlagMask */
3766             proto_tree_add_bitmask(up_tree, tvb, rr_offset, hf_icmpv6_rr_pco_up_flagmask, ett_icmpv6_rr_up_flag_mask, mask_flags, ENC_BIG_ENDIAN);
3767             rr_offset += 1;
3768 
3769             /* RaFlags */
3770             proto_tree_add_bitmask(up_tree, tvb, rr_offset, hf_icmpv6_rr_pco_up_raflags, ett_icmpv6_rr_up_flag_ra, ra_flags, ENC_BIG_ENDIAN);
3771             rr_offset += 1;
3772 
3773             /* Valid Lifetime */
3774             proto_tree_add_item(up_tree, hf_icmpv6_rr_pco_up_validlifetime, tvb, rr_offset, 4, ENC_BIG_ENDIAN);
3775             rr_offset += 4;
3776 
3777             /* Preferred Lifetime */
3778             proto_tree_add_item(up_tree, hf_icmpv6_rr_pco_up_preferredlifetime, tvb, rr_offset, 4, ENC_BIG_ENDIAN);
3779             rr_offset += 4;
3780 
3781             /* Flags */
3782             proto_tree_add_bitmask(up_tree, tvb, rr_offset, hf_icmpv6_rr_pco_up_flag, ett_icmpv6_rr_up_flag, up_flags, ENC_BIG_ENDIAN);
3783             rr_offset += 4;
3784 
3785             /* UsePrefix */
3786             proto_tree_add_item(up_tree, hf_icmpv6_rr_pco_up_useprefix, tvb, rr_offset, 16, ENC_NA);
3787 
3788             /* Add Info (Prefix, Length...) to Use Prefix Part label */
3789             proto_item_append_text(ti_up, ": %s/%u (keep %u)", tvb_ip6_to_str(pinfo->pool, tvb, rr_offset), uselen, keeplen);
3790             rr_offset += 16;
3791         }
3792 
3793     }else if(icmp6_code == ICMP6_ROUTER_RENUMBERING_RESULT){
3794         while ((int)tvb_reported_length(tvb) > rr_offset) {
3795         guint8 matchlen;
3796         guint32 interfaceindex;
3797         static int * const rm_flags[] = {
3798             &hf_icmpv6_rr_rm_flag_reserved,
3799             &hf_icmpv6_rr_rm_flag_b,
3800             &hf_icmpv6_rr_rm_flag_f,
3801             NULL
3802         };
3803         /* Result Message */
3804 
3805         ti_rm = proto_tree_add_item(tree, hf_icmpv6_rr_rm, tvb, rr_offset, 24, ENC_NA);
3806         rm_tree = proto_item_add_subtree(ti_rm, ett_icmpv6_rr_rm);
3807 
3808         /* Flags */
3809         proto_tree_add_bitmask(rm_tree, tvb, rr_offset, hf_icmpv6_rr_rm_flag, ett_icmpv6_rr_rm_flag, rm_flags, ENC_BIG_ENDIAN);
3810         rr_offset +=2;
3811 
3812         /* Ordinal */
3813         proto_tree_add_item(rm_tree, hf_icmpv6_rr_rm_ordinal, tvb, rr_offset, 1, ENC_BIG_ENDIAN);
3814         rr_offset +=1;
3815 
3816         /* MatchLen */
3817         ti = proto_tree_add_item(rm_tree, hf_icmpv6_rr_rm_matchedlen, tvb, rr_offset, 1, ENC_BIG_ENDIAN);
3818         matchlen = tvb_get_guint8(tvb, rr_offset);
3819         if (matchlen > 128) {
3820             expert_add_info(pinfo, ti, &ei_icmpv6_rr_pco_mp_matchedlen);
3821         }
3822         rr_offset +=1;
3823 
3824         /* InterfaceIndex */
3825         proto_tree_add_item(rm_tree, hf_icmpv6_rr_rm_interfaceindex, tvb, rr_offset, 4, ENC_BIG_ENDIAN);
3826         interfaceindex = tvb_get_ntohl(tvb, rr_offset);
3827         rr_offset +=4;
3828 
3829         /* MatchedPrefix */
3830         proto_tree_add_item(rm_tree, hf_icmpv6_rr_rm_matchedprefix, tvb, rr_offset, 16, ENC_NA);
3831 
3832         /* Add Info (Prefix, Length...) to Use Resultant Message label */
3833         proto_item_append_text(ti_rm, ": %s/%u (interface %u)", tvb_ip6_to_str(pinfo->pool, tvb, rr_offset), matchlen, interfaceindex);
3834         rr_offset +=16;
3835         }
3836     }
3837     return rr_offset;
3838 }
3839 
3840 
3841 static int
dissect_mldrv2(tvbuff_t * tvb,guint32 offset,packet_info * pinfo _U_,proto_tree * tree)3842 dissect_mldrv2( tvbuff_t *tvb, guint32 offset, packet_info *pinfo _U_, proto_tree *tree )
3843 {
3844     proto_tree *mar_tree;
3845     proto_item *ti_mar;
3846     int         mldr_offset = offset;
3847 
3848     /* Reserved */
3849     proto_tree_add_item(tree, hf_icmpv6_reserved, tvb, mldr_offset, 2, ENC_NA );
3850     mldr_offset += 2;
3851 
3852     /* Nr of Mcast Address Records (M) */
3853     proto_tree_add_item(tree, hf_icmpv6_mldr_nb_mcast_records, tvb, mldr_offset, 2, ENC_BIG_ENDIAN );
3854     mldr_offset += 2;
3855 
3856     /* Multicast Address Record */
3857     while(mldr_offset < (int)tvb_reported_length(tvb) ) {
3858         guint8 aux_data_len, record_type;
3859         guint16 i, nb_sources;
3860 
3861         ti_mar = proto_tree_add_item(tree, hf_icmpv6_mldr_mar, tvb, mldr_offset, -1, ENC_NA);
3862         mar_tree = proto_item_add_subtree(ti_mar, ett_icmpv6_mar);
3863 
3864         /* Record Type */
3865         proto_tree_add_item(mar_tree, hf_icmpv6_mldr_mar_record_type, tvb, mldr_offset, 1, ENC_BIG_ENDIAN);
3866         record_type = tvb_get_guint8(tvb, mldr_offset);
3867         mldr_offset += 1;
3868 
3869         /* Aux Data Len */
3870         proto_tree_add_item(mar_tree, hf_icmpv6_mldr_mar_aux_data_len, tvb, mldr_offset, 1, ENC_BIG_ENDIAN);
3871         aux_data_len = tvb_get_guint8(tvb, mldr_offset);
3872         mldr_offset += 1;
3873 
3874         /* Number of Sources (N) */
3875         proto_tree_add_item(mar_tree, hf_icmpv6_mldr_mar_nb_sources, tvb, mldr_offset, 2, ENC_BIG_ENDIAN);
3876         nb_sources = tvb_get_ntohs(tvb, mldr_offset);
3877         mldr_offset += 2;
3878 
3879         /* Multicast Address */
3880         proto_tree_add_item(mar_tree, hf_icmpv6_mldr_mar_multicast_address, tvb, mldr_offset, 16, ENC_NA);
3881         proto_item_append_text(ti_mar, " %s: %s", val_to_str(record_type, mldr_record_type_val,"Unknown Record Type (%d)"), tvb_ip6_to_str(pinfo->pool, tvb, mldr_offset));
3882         mldr_offset += 16;
3883 
3884         /* Source Address */
3885         for (i=0; i < nb_sources; i++){
3886             proto_tree_add_item(mar_tree, hf_icmpv6_mldr_mar_source_address, tvb, mldr_offset, 16, ENC_NA);
3887             mldr_offset += 16;
3888         }
3889 
3890         /* Auxiliary Data ? */
3891         if(aux_data_len)
3892         {
3893             proto_tree_add_item(mar_tree, hf_icmpv6_mldr_mar_auxiliary_data, tvb, mldr_offset, aux_data_len * 4, ENC_NA);
3894             mldr_offset += aux_data_len * 4;
3895         }
3896 
3897         /* Multicast Address Record Length */
3898         proto_item_set_len(ti_mar, 4 + 16 + (16 * nb_sources) + (aux_data_len * 4));
3899 
3900     }
3901     return mldr_offset;
3902 }
3903 
3904 static int
dissect_mpl_control(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,guint8 type _U_,guint8 code)3905 dissect_mpl_control(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, guint8 type _U_, guint8 code)
3906 {
3907     proto_tree *seed_info_tree, *bm_tree;
3908     proto_item *ti;
3909     const gint length_of_fixed_part = 2;
3910     int body_offset = offset;
3911     guint8 min_seqno, bm_len, s;
3912     gint remaining, id_len = 0;
3913     guint16 seed_info_index = 0;
3914     gchar *seed_id = NULL;
3915     int i, j;
3916     guint8 b;
3917 
3918     if (code != 0) {
3919         /* code must be 0 */
3920         ti = proto_tree_add_item(tree, hf_icmpv6_unknown_data, tvb, body_offset, 1, ENC_NA);
3921         expert_add_info_format(pinfo, ti, &ei_icmpv6_unknown_data, "Code must be 0");
3922         return body_offset;
3923     }
3924 
3925     remaining = tvb_captured_length_remaining(tvb, body_offset);
3926     while (remaining >= length_of_fixed_part) {
3927         seed_info_index++;
3928 
3929         seed_info_tree = proto_tree_add_subtree_format(tree, tvb, body_offset, length_of_fixed_part, ett_icmpv6_mpl_seed_info, NULL,
3930                                                        "MPL Seed Info: [%u]", seed_info_index);
3931 
3932         min_seqno = tvb_get_guint8(tvb, body_offset);
3933         proto_tree_add_item(seed_info_tree, hf_icmpv6_mpl_seed_info_min_sequence, tvb, body_offset, 1, ENC_BIG_ENDIAN);
3934         body_offset++;
3935 
3936         bm_len = tvb_get_guint8(tvb, body_offset) >> 2;
3937         s = tvb_get_guint8(tvb, body_offset) & 0x03;
3938         proto_tree_add_item(seed_info_tree, hf_icmpv6_mpl_seed_info_bm_len, tvb, body_offset, 1, ENC_BIG_ENDIAN);
3939         proto_tree_add_item(seed_info_tree, hf_icmpv6_mpl_seed_info_s, tvb, body_offset, 1, ENC_BIG_ENDIAN);
3940         body_offset++;
3941 
3942         id_len = mpl_seed_id_code_to_length[s];
3943         if ((remaining - length_of_fixed_part) < id_len) {
3944             /* Invalid length; remaining data is too short for Seed ID */
3945             ti = proto_tree_add_item(seed_info_tree, hf_icmpv6_unknown_data, tvb, body_offset,
3946                                      remaining - length_of_fixed_part, ENC_NA);
3947             expert_add_info_format(pinfo, ti, &ei_icmpv6_unknown_data,
3948                                    "Remaining data, %u bytes, is too short for Seed ID of %u bytes",
3949                                    remaining - length_of_fixed_part, id_len);
3950             return remaining - length_of_fixed_part;
3951         }
3952         switch (s) {
3953             case 0:
3954                 seed_id = address_to_str(pinfo->pool, &pinfo->src);
3955                 break;
3956             case 1:
3957                 seed_id = wmem_strdup_printf(pinfo->pool, "%04x", tvb_get_ntohs(tvb, body_offset));
3958                 break;
3959             case 2:
3960                 seed_id = tvb_eui64_to_str(pinfo->pool, tvb, body_offset);
3961                 break;
3962             case 3:
3963                 seed_id = tvb_ip6_to_str(pinfo->pool, tvb, body_offset);
3964                 break;
3965             default:
3966                 /* not reached */
3967                 break;
3968         }
3969         proto_tree_add_string(seed_info_tree, hf_icmpv6_mpl_seed_info_seed_id, tvb, body_offset, id_len, seed_id);
3970         body_offset += id_len;
3971 
3972         if((remaining - length_of_fixed_part - id_len) < bm_len) {
3973             /* Invalid length; remaining data is too short for Buffered Messages */
3974             ti = proto_tree_add_item(seed_info_tree, hf_icmpv6_unknown_data, tvb, body_offset,
3975                                      remaining - length_of_fixed_part - id_len, ENC_NA);
3976             expert_add_info_format(pinfo, ti, &ei_icmpv6_unknown_data,
3977                                    "Remaining data, %u bytes, is too short for Buffered Messages of %u bytes",
3978                                    remaining - length_of_fixed_part - id_len, bm_len);
3979             return body_offset - length_of_fixed_part - id_len;
3980         }
3981 
3982         if (bm_len > 0) {
3983             bm_tree = proto_tree_add_subtree_format(seed_info_tree, tvb, body_offset, bm_len, ett_icmpv6_mpl_seed_info_bm, NULL,
3984                                                     "Buffered Messages");
3985             for (i = 0; i < bm_len; i++) {
3986                 b = tvb_get_guint8(tvb, body_offset + i);
3987                 for (j = 0; j < 8; j++) {
3988                     if (b & (0x80 >> j)) {
3989                         /* From RFC 1982: s' = (s + n) modulo (2 ^ SERIAL_BITS), where SERIAL_BITS is 8 */
3990                         proto_tree_add_uint(bm_tree, hf_icmpv6_mpl_seed_info_sequence, tvb, body_offset + i, 1, (min_seqno + 8 * i + j) % 0x100);
3991                     }
3992                 }
3993             }
3994         }
3995         body_offset += bm_len;
3996 
3997         remaining = tvb_captured_length_remaining(tvb, body_offset);
3998     }
3999 
4000     if (remaining != 0) {
4001         /* Invalid length; there is remaining data after dissectin MPL Control Message */
4002         ti = proto_tree_add_item(tree, hf_icmpv6_unknown_data, tvb, body_offset, body_offset - offset, ENC_NA);
4003         expert_add_info_format(pinfo, ti, &ei_icmpv6_unknown_data,
4004                                "%u bytes data is left after dissecting MPL Control Message", remaining);
4005     }
4006 
4007     return body_offset;
4008 }
4009 
4010 static gboolean
capture_icmpv6(const guchar * pd _U_,int offset _U_,int len _U_,capture_packet_info_t * cpinfo,const union wtap_pseudo_header * pseudo_header _U_)4011 capture_icmpv6(const guchar *pd _U_, int offset _U_, int len _U_, capture_packet_info_t *cpinfo, const union wtap_pseudo_header *pseudo_header _U_)
4012 {
4013     capture_dissector_increment_count(cpinfo, proto_icmpv6);
4014     return TRUE;
4015 }
4016 
4017 static int
dissect_icmpv6(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data)4018 dissect_icmpv6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
4019 {
4020     proto_tree         *icmp6_tree = NULL;
4021     proto_item         *ti         = NULL, *checksum_item = NULL, *code_item = NULL;
4022     const char         *code_name  = NULL;
4023     guint               length     = 0, reported_length;
4024     vec_t               cksum_vec[4];
4025     guint32             phdr[2];
4026     guint16             cksum;
4027     int                 offset;
4028     tvbuff_t           *next_tvb;
4029     guint8              icmp6_type, icmp6_code;
4030     icmp_transaction_t *trans      = NULL;
4031     ws_ip6 *iph = WS_IP6_PTR(data);
4032 
4033     col_set_str(pinfo->cinfo, COL_PROTOCOL, "ICMPv6");
4034     col_clear(pinfo->cinfo, COL_INFO);
4035 
4036     offset = 0;
4037 
4038     if (tree) {
4039         ti = proto_tree_add_item(tree, proto_icmpv6, tvb, offset, -1, ENC_NA);
4040         icmp6_tree = proto_item_add_subtree(ti, ett_icmpv6);
4041 
4042         /* Type */
4043         proto_tree_add_item(icmp6_tree, hf_icmpv6_type, tvb, offset, 1, ENC_BIG_ENDIAN);
4044     }
4045     icmp6_type = tvb_get_guint8(tvb, offset);
4046     offset += 1;
4047 
4048     col_add_str(pinfo->cinfo, COL_INFO, val_to_str(icmp6_type, icmpv6_type_val, "Unknown (%d)"));
4049 
4050     if (tree)
4051         code_item = proto_tree_add_item(icmp6_tree, hf_icmpv6_code, tvb, offset, 1, ENC_BIG_ENDIAN);
4052 
4053     icmp6_code = tvb_get_guint8(tvb, offset);
4054     offset += 1;
4055 
4056     switch (icmp6_type) {
4057         case ICMP6_DST_UNREACH:
4058             code_name = val_to_str_const(icmp6_code, icmpv6_unreach_code_val, "Unknown");
4059             break;
4060         case ICMP6_TIME_EXCEEDED:
4061             code_name = val_to_str(icmp6_code, icmpv6_timeex_code_val, "Unknown (%d)");
4062             break;
4063         case ICMP6_PARAM_PROB:
4064             code_name = val_to_str(icmp6_code, icmpv6_paramprob_code_val, "Unknown (%d)");
4065             break;
4066         case ICMP6_ROUTER_RENUMBERING:
4067             code_name = val_to_str(icmp6_code, icmpv6_rr_code_val, "Unknown (%d)");
4068             break;
4069         case ICMP6_NI_QUERY:
4070             code_name = val_to_str(icmp6_code, ni_query_code_val, "Unknown (%d)");
4071             break;
4072         case ICMP6_NI_REPLY:
4073             code_name = val_to_str(icmp6_code, ni_reply_code_val, "Unknown (%d)");
4074             break;
4075         case ICMP6_RPL_CONTROL:
4076             code_name = val_to_str(icmp6_code, rpl_code_val, "Unknown (%d)");
4077             break;
4078         case ICMP6_EXTECHO:
4079             code_name = val_to_str(icmp6_code, ext_echo_req_code_str, "Unknown (%d)");
4080             break;
4081         case ICMP6_EXTECHOREPLY:
4082             code_name = val_to_str(icmp6_code, ext_echo_reply_code_str, "Unknown (%d)");
4083             break;
4084     }
4085 
4086     if (code_name)
4087         col_append_fstr(pinfo->cinfo, COL_INFO, " (%s)", code_name);
4088 
4089     /* RFC 4380
4090      * 2.7.   Teredo UDP Port
4091      * 5.2.9. Direct IPv6 Connectivity Test  */
4092     if (pinfo->destport == 3544 && icmp6_type == ICMP6_ECHO_REQUEST) {
4093         col_set_str(pinfo->cinfo, COL_PROTOCOL, "Teredo");
4094         col_set_str(pinfo->cinfo, COL_INFO, "Direct IPv6 Connectivity Test");
4095     }
4096 
4097     if (code_name)
4098         proto_item_append_text(code_item, " (%s)", code_name);
4099 
4100     cksum = tvb_get_ntohs(tvb, offset);
4101     length = tvb_captured_length(tvb);
4102     reported_length = tvb_reported_length(tvb);
4103     if (!pinfo->fragmented && length >= reported_length && !pinfo->flags.in_error_pkt) {
4104         /* The packet isn't part of a fragmented datagram, isn't truncated,
4105          * and we aren't in an ICMP error packet, so we can checksum it.
4106          */
4107 
4108         /* Set up the fields of the pseudo-header. */
4109         SET_CKSUM_VEC_PTR(cksum_vec[0], (const guint8 *)pinfo->src.data, pinfo->src.len);
4110         SET_CKSUM_VEC_PTR(cksum_vec[1], (const guint8 *)pinfo->dst.data, pinfo->dst.len);
4111         phdr[0] = g_htonl(reported_length);
4112         phdr[1] = g_htonl(IP_PROTO_ICMPV6);
4113         SET_CKSUM_VEC_PTR(cksum_vec[2], (const guint8 *)&phdr, 8);
4114         SET_CKSUM_VEC_TVB(cksum_vec[3], tvb, 0, reported_length);
4115 
4116         proto_tree_add_checksum(icmp6_tree, tvb, 2, hf_icmpv6_checksum, hf_icmpv6_checksum_status, &ei_icmpv6_checksum, pinfo, in_cksum(cksum_vec, 4),
4117                                 ENC_BIG_ENDIAN, PROTO_CHECKSUM_VERIFY|PROTO_CHECKSUM_IN_CKSUM);
4118     } else {
4119         checksum_item = proto_tree_add_checksum(icmp6_tree, tvb, 2, hf_icmpv6_checksum, hf_icmpv6_checksum_status, &ei_icmpv6_checksum, pinfo, 0,
4120                                                 ENC_BIG_ENDIAN, PROTO_CHECKSUM_NO_FLAGS);
4121         proto_item_append_text(checksum_item, " [%s]",
4122             pinfo->flags.in_error_pkt ? "in ICMP error packet" : "fragmented datagram");
4123     }
4124     offset += 2;
4125 
4126     if (icmp6_type == ICMP6_ECHO_REQUEST || icmp6_type == ICMP6_ECHO_REPLY) {
4127         guint16 identifier, sequence;
4128 
4129         /* Identifier */
4130         proto_tree_add_item(icmp6_tree, hf_icmpv6_echo_identifier, tvb, offset, 2, ENC_BIG_ENDIAN);
4131         identifier = tvb_get_ntohs(tvb, offset);
4132         offset += 2;
4133 
4134         /* Sequence Number */
4135         if (tree)
4136             proto_tree_add_item(icmp6_tree, hf_icmpv6_echo_sequence_number, tvb, offset, 2, ENC_BIG_ENDIAN);
4137         sequence = tvb_get_ntohs(tvb, offset);
4138         offset += 2;
4139 
4140         col_append_fstr(pinfo->cinfo, COL_INFO, " id=0x%04x, seq=%u",
4141             identifier, sequence);
4142         if (iph != NULL) {
4143             col_append_fstr(pinfo->cinfo, COL_INFO, ", hop limit=%u",
4144                             iph->ip6_hop);
4145         }
4146 
4147         if (pinfo->destport == 3544 && icmp6_type == ICMP6_ECHO_REQUEST) {
4148             /* RFC 4380
4149              * 2.7.   Teredo UDP Port
4150              * 5.2.9. Direct IPv6 Connectivity Test
4151              *
4152              * TODO: Clarify the nonce:  The RFC states, "(It is recommended to
4153              * use a random number [the nonce] at least 64 bits long.)"
4154              *
4155              * Shouldn't the nonce be at least 8 then?  Why not just use (-1),
4156              * as it could really be any length, couldn't it?
4157              */
4158             proto_tree_add_item(icmp6_tree, hf_icmpv6_nonce, tvb, offset, 4, ENC_NA);
4159             offset += 4;
4160         } else {
4161             if (!pinfo->flags.in_error_pkt) {
4162                 guint32 conv_key[3];
4163 
4164                 conv_key[1] = (guint32)((identifier << 16) | sequence);
4165                 conv_key[2] = prefs.strict_conversation_tracking_heuristics ? pinfo->vlan_id : 0;
4166 
4167                 if (icmp6_type == ICMP6_ECHO_REQUEST) {
4168                     conv_key[0] = (guint32)cksum;
4169                     if (conv_key[0] == 0xffff)
4170                         conv_key[0] = 0;
4171                     if (pinfo->flags.in_gre_pkt && prefs.strict_conversation_tracking_heuristics)
4172                         conv_key[0] |= 0x00010000; /* set a bit for "in GRE" */
4173                     trans = transaction_start(pinfo, icmp6_tree, conv_key);
4174                 } else { /* ICMP6_ECHO_REPLY */
4175                     guint16 tmp[2];
4176 
4177                     tmp[0] = ~cksum;
4178                     tmp[1] = ~0x0100; /* The difference between echo request & reply */
4179                     SET_CKSUM_VEC_PTR(cksum_vec[0], (guint8 *)tmp, sizeof(tmp));
4180                     conv_key[0] = in_cksum(cksum_vec, 1);
4181                     if (pinfo->flags.in_gre_pkt && prefs.strict_conversation_tracking_heuristics)
4182                         conv_key[0] |= 0x00010000; /* set a bit for "in GRE" */
4183                     trans = transaction_end(pinfo, icmp6_tree, conv_key);
4184                 }
4185             }
4186             heur_dtbl_entry_t *hdtbl_entry;
4187             next_tvb = tvb_new_subset_remaining(tvb, offset);
4188             gboolean result = dissector_try_heuristic(icmpv6_heur_subdissector_list, next_tvb, pinfo, tree, &hdtbl_entry, NULL);
4189             if (!result) {
4190                 offset += call_data_dissector(next_tvb, pinfo, icmp6_tree);
4191             }
4192             else {
4193                 offset += tvb_reported_length(next_tvb);
4194             }
4195         }
4196     }
4197 
4198     if (1) { /* There are expert infos buried in here so always execute */
4199         /* decode... */
4200         /* FIXME: The following messages MUST have a TTL^WHop-Limit of 255:
4201                 133-137, 141-142, 148-149. Detect this and add expert items. */
4202         switch (icmp6_type) {
4203             case ICMP6_DST_UNREACH: /* Destination Unreachable (1) */
4204             case ICMP6_TIME_EXCEEDED: /* Time Exceeded (3) */
4205             {
4206                 char orig_datagram_length = tvb_get_guint8(tvb, offset);
4207                 if (orig_datagram_length) {
4208                   /* RFC 4884 Original datagram length */
4209                   proto_tree_add_item(icmp6_tree, hf_icmpv6_length, tvb, offset, 1, ENC_NA);
4210                   offset += 1;
4211                   proto_tree_add_item(icmp6_tree, hf_icmpv6_reserved, tvb, offset, 3, ENC_NA);
4212                   offset += 3;
4213                 } else {
4214                   /* Reserved */
4215                   proto_tree_add_item(icmp6_tree, hf_icmpv6_reserved, tvb, offset, 4, ENC_NA);
4216                   offset += 4;
4217                 }
4218 
4219                 next_tvb = tvb_new_subset_remaining(tvb, offset);
4220                 int contained_len = dissect_contained_icmpv6(next_tvb, pinfo, icmp6_tree);
4221                 if (orig_datagram_length) {
4222                   offset += 8 * orig_datagram_length;
4223                   tvbuff_t * extension_tvb = tvb_new_subset_remaining(tvb, offset);
4224                   offset += call_dissector(icmp_extension_handle, extension_tvb, pinfo, icmp6_tree);
4225                 } else {
4226                   offset += contained_len;
4227                 }
4228                 break;
4229             }
4230             case ICMP6_PACKET_TOO_BIG: /* Packet Too Big (2) */
4231                 /* MTU */
4232                 proto_tree_add_item(icmp6_tree, hf_icmpv6_mtu, tvb, offset, 4, ENC_BIG_ENDIAN);
4233                 offset += 4;
4234 
4235                 next_tvb = tvb_new_subset_remaining(tvb, offset);
4236                 offset += dissect_contained_icmpv6(next_tvb, pinfo, icmp6_tree);
4237                 break;
4238             case ICMP6_PARAM_PROB: /* Parameter Problem (4) */
4239                 /* MTU */
4240                 proto_tree_add_item(icmp6_tree, hf_icmpv6_pointer, tvb, offset, 4, ENC_BIG_ENDIAN);
4241                 offset += 4;
4242 
4243                 next_tvb = tvb_new_subset_remaining(tvb, offset);
4244                 offset += dissect_contained_icmpv6(next_tvb, pinfo, icmp6_tree);
4245                 break;
4246             case ICMP6_ECHO_REQUEST:    /* Echo Request (128) */
4247             case ICMP6_ECHO_REPLY:      /* Echo Reply (129) */
4248                 /* Already handled above */
4249                 break;
4250             case ICMP6_MEMBERSHIP_QUERY: /* Multicast Listener Query (130) */
4251             case ICMP6_MEMBERSHIP_REPORT: /* Multicast Listener Report (131) */
4252             case ICMP6_MEMBERSHIP_REDUCTION: /* Multicast Listener Done (132) */
4253             {
4254                 /* It is MLDv2 packet ? (the min length for a MLDv2 packet is 28) */
4255                 if ((icmp6_type == ICMP6_MEMBERSHIP_QUERY) && (length >= MLDV2_PACKET_MINLEN)) {
4256                     guint32 mrc;
4257                     guint16 qqi, i, nb_sources;
4258                     static int * const mld_flags[] = {
4259                         &hf_icmpv6_mld_flag_s,
4260                         &hf_icmpv6_mld_flag_qrv,
4261                         &hf_icmpv6_mld_flag_rsv,
4262                         NULL
4263                     };
4264 
4265                     /* Maximum Response Code */
4266                     mrc = tvb_get_ntohs(tvb, offset);
4267                     if (mrc >= 32768){
4268                         mrc = ((mrc & 0x0fff) | 0x1000) << (((mrc & 0x7000) >> 12) + 3);
4269                     }
4270                     proto_tree_add_uint(icmp6_tree, hf_icmpv6_mld_mrc, tvb, offset, 2, mrc);
4271                     offset += 2;
4272 
4273                     /* Reserved */
4274                     proto_tree_add_item(icmp6_tree, hf_icmpv6_reserved, tvb, offset, 2, ENC_NA);
4275                     offset += 2;
4276 
4277                     /* Multicast Address */
4278                     proto_tree_add_item(icmp6_tree, hf_icmpv6_mld_multicast_address, tvb, offset, 16, ENC_NA);
4279                     offset += 16;
4280 
4281                     /* Flag */
4282                     proto_tree_add_bitmask(icmp6_tree, tvb, offset, hf_icmpv6_mld_flag, ett_icmpv6_flag_mld, mld_flags, ENC_BIG_ENDIAN);
4283                     offset += 1;
4284 
4285                     /* QQI */
4286                     qqi = tvb_get_guint8(tvb, offset);
4287                     if (qqi >= 128){
4288                         qqi = ((qqi & 0x0f) | 0x10) << (((qqi & 0x70) >> 4) + 3);
4289                     }
4290                     proto_tree_add_uint(icmp6_tree, hf_icmpv6_mld_qqi, tvb, offset, 1, qqi);
4291                     offset += 1;
4292 
4293                     /* Number of Sources */
4294                     proto_tree_add_item(icmp6_tree, hf_icmpv6_mld_nb_sources, tvb, offset, 2, ENC_BIG_ENDIAN);
4295                     nb_sources = tvb_get_ntohs(tvb, offset);
4296                     offset += 2;
4297 
4298                     /* Source Address */
4299                     for (i=0; i < nb_sources; i++){
4300                         proto_tree_add_item(icmp6_tree, hf_icmpv6_mld_source_address, tvb, offset, 16, ENC_NA);
4301                         offset += 16;
4302                     }
4303 
4304                 }else{ /* It is a MLDv1 Packet */
4305 
4306                     proto_tree_add_item(icmp6_tree, hf_icmpv6_mld_mrd, tvb, offset, 2, ENC_BIG_ENDIAN);
4307                     offset += 2;
4308 
4309                     /* Reserved */
4310                     proto_tree_add_item(icmp6_tree, hf_icmpv6_reserved, tvb, offset, 2, ENC_NA);
4311                     offset += 2;
4312 
4313                     /* Multicast Address */
4314                     proto_tree_add_item(icmp6_tree, hf_icmpv6_mld_multicast_address, tvb, offset, 16, ENC_NA);
4315                     offset += 16;
4316                 }
4317                 break;
4318             }
4319             case ICMP6_ND_ROUTER_SOLICIT: /* Router Solicitation (133) */
4320             {
4321                 /* Reserved */
4322                 proto_tree_add_item(icmp6_tree, hf_icmpv6_reserved, tvb, offset, 4, ENC_NA);
4323                 offset += 4;
4324 
4325                 /* Show options */
4326                 offset = dissect_icmpv6_nd_opt(tvb, offset, pinfo, icmp6_tree);
4327                 break;
4328             }
4329             case ICMP6_ND_ROUTER_ADVERT: /* Router Advertisement (134) */
4330             {
4331                 static int * const nd_ra_flags[] = {
4332                     &hf_icmpv6_nd_ra_flag_m,
4333                     &hf_icmpv6_nd_ra_flag_o,
4334                     &hf_icmpv6_nd_ra_flag_h,
4335                     &hf_icmpv6_nd_ra_flag_prf,
4336                     &hf_icmpv6_nd_ra_flag_p,
4337                     &hf_icmpv6_nd_ra_flag_rsv,
4338                     NULL
4339                 };
4340 
4341                 /* Current hop limit */
4342                 proto_tree_add_item(icmp6_tree, hf_icmpv6_nd_ra_cur_hop_limit, tvb, offset, 1, ENC_BIG_ENDIAN);
4343                 offset += 1;
4344 
4345                 /* Flags */
4346                 proto_tree_add_bitmask(icmp6_tree, tvb, offset, hf_icmpv6_nd_ra_flag, ett_icmpv6_flag_ra, nd_ra_flags, ENC_BIG_ENDIAN);
4347                 offset += 1;
4348 
4349                 /* Router lifetime */
4350                 proto_tree_add_item(icmp6_tree, hf_icmpv6_nd_ra_router_lifetime, tvb, offset, 2, ENC_BIG_ENDIAN);
4351                 offset += 2;
4352 
4353                 /* Reachable time */
4354                 proto_tree_add_item(icmp6_tree, hf_icmpv6_nd_ra_reachable_time, tvb, offset, 4, ENC_BIG_ENDIAN);
4355                 offset += 4;
4356 
4357                 /* Retrans timer */
4358                 proto_tree_add_item(icmp6_tree, hf_icmpv6_nd_ra_retrans_timer, tvb, offset, 4, ENC_BIG_ENDIAN);
4359                 offset += 4;
4360 
4361                 /* Show options */
4362                 offset = dissect_icmpv6_nd_opt(tvb, offset, pinfo, icmp6_tree);
4363                 break;
4364             }
4365             case ICMP6_ND_NEIGHBOR_SOLICIT: /* Neighbor Solicitation (135) */
4366             {
4367                 /* Reserved */
4368                 proto_tree_add_item(icmp6_tree, hf_icmpv6_reserved, tvb, offset, 4, ENC_NA);
4369                 offset += 4;
4370 
4371                 /* Target Address */
4372                 proto_tree_add_item(icmp6_tree, hf_icmpv6_nd_ns_target_address, tvb, offset, 16, ENC_NA);
4373                 col_append_fstr(pinfo->cinfo, COL_INFO, " for %s", tvb_ip6_to_str(pinfo->pool, tvb, offset));
4374 
4375                 offset += 16;
4376 
4377                 /* Show options */
4378                 offset = dissect_icmpv6_nd_opt(tvb, offset, pinfo, icmp6_tree);
4379                 break;
4380             }
4381             case ICMP6_ND_NEIGHBOR_ADVERT: /* Neighbor Advertisement (136) */
4382             {
4383                 guint32 na_flags;
4384                 wmem_strbuf_t *flags_strbuf = wmem_strbuf_new_label(pinfo->pool);
4385                 static int * const nd_na_flags[] = {
4386                     &hf_icmpv6_nd_na_flag_r,
4387                     &hf_icmpv6_nd_na_flag_s,
4388                     &hf_icmpv6_nd_na_flag_o,
4389                     &hf_icmpv6_nd_na_flag_rsv,
4390                     NULL
4391                 };
4392 
4393                 /* Flags */
4394                 proto_tree_add_bitmask(icmp6_tree, tvb, offset, hf_icmpv6_nd_na_flag, ett_icmpv6_flag_na, nd_na_flags, ENC_BIG_ENDIAN);
4395                 na_flags = tvb_get_ntohl(tvb, offset);
4396                 offset += 4;
4397 
4398                 /* Target Address */
4399                 proto_tree_add_item(icmp6_tree, hf_icmpv6_nd_na_target_address, tvb, offset, 16, ENC_NA);
4400 
4401 
4402                 if (na_flags & ND_NA_FLAG_R) {
4403                     wmem_strbuf_append(flags_strbuf, "rtr, ");
4404                 }
4405                 if (na_flags & ND_NA_FLAG_S) {
4406                     wmem_strbuf_append(flags_strbuf, "sol, ");
4407                 }
4408                 if (na_flags & ND_NA_FLAG_O) {
4409                     wmem_strbuf_append(flags_strbuf, "ovr, ");
4410                 }
4411                 if (wmem_strbuf_get_len(flags_strbuf) > 2) {
4412                     wmem_strbuf_truncate(flags_strbuf, wmem_strbuf_get_len(flags_strbuf) - 2);
4413                 } else {
4414                     wmem_strbuf_truncate(flags_strbuf, 0);
4415                     wmem_strbuf_append(flags_strbuf, "none");
4416                 }
4417 
4418                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s (%s)", tvb_ip6_to_str(pinfo->pool, tvb, offset), wmem_strbuf_get_str(flags_strbuf));
4419                 offset += 16;
4420 
4421                 /* Show options */
4422                 offset = dissect_icmpv6_nd_opt(tvb, offset, pinfo, icmp6_tree);
4423                 break;
4424             }
4425             case ICMP6_ND_REDIRECT: /* Redirect Message (137) */
4426             {
4427                 /* Reserved */
4428                 proto_tree_add_item(icmp6_tree, hf_icmpv6_reserved, tvb, offset, 4, ENC_NA);
4429                 offset += 4;
4430 
4431                 /* Target Address */
4432                 proto_tree_add_item(icmp6_tree, hf_icmpv6_nd_rd_target_address, tvb, offset, 16, ENC_NA);
4433                 offset += 16;
4434 
4435                 /* Destination Address */
4436                 proto_tree_add_item(icmp6_tree, hf_icmpv6_nd_rd_destination_address, tvb, offset, 16, ENC_NA);
4437                 offset += 16;
4438 
4439                 /* Show options */
4440                 offset = dissect_icmpv6_nd_opt(tvb, offset, pinfo, icmp6_tree);
4441                 break;
4442             }
4443             case ICMP6_ROUTER_RENUMBERING: /* Router Renumbering (138) */
4444             {
4445                 offset = dissect_rrenum(tvb, offset, pinfo, icmp6_tree, icmp6_type, icmp6_code);
4446                 break;
4447             }
4448             case ICMP6_NI_QUERY: /* ICMP Node Information Query (139) */
4449             case ICMP6_NI_REPLY: /* ICMP Node Information Response (140) */
4450             {
4451                 offset = dissect_nodeinfo(tvb, offset, pinfo, icmp6_tree, icmp6_type, icmp6_code);
4452                 break;
4453             }
4454             case ICMP6_IND_SOLICIT: /* Inverse Neighbor Discovery Solicitation Message (141) */
4455             case ICMP6_IND_ADVERT: /* Inverse Neighbor Discovery Advertisement Message (142) */
4456             {
4457                 /* Reserved */
4458                 proto_tree_add_item(icmp6_tree, hf_icmpv6_reserved, tvb, offset, 4, ENC_NA);
4459                 offset += 4;
4460 
4461                 /* Show options */
4462                 offset = dissect_icmpv6_nd_opt(tvb, offset, pinfo, icmp6_tree);
4463                 break;
4464             }
4465             case ICMP6_MLDV2_REPORT: /* Version 2 Multicast Listener Report (143) */
4466             {
4467                 offset = dissect_mldrv2( tvb, offset, pinfo, icmp6_tree );
4468                 break;
4469             }
4470             case ICMP6_MIP6_DHAAD_REQUEST: /* Home Agent Address Discovery Request Message (144) */
4471             {
4472                 /* Identifier */
4473                 proto_tree_add_item(icmp6_tree, hf_icmpv6_mip6_identifier, tvb, offset, 2, ENC_BIG_ENDIAN);
4474                 offset += 2;
4475 
4476                 /* Reserved */
4477                 proto_tree_add_item(icmp6_tree, hf_icmpv6_reserved, tvb, offset, 2, ENC_NA);
4478                 offset += 2;
4479 
4480                 break;
4481             }
4482             case ICMP6_MIP6_DHAAD_REPLY: /* Home Agent Address Discovery Reply Message (145) */
4483             {
4484                 /* Identifier */
4485                 proto_tree_add_item(icmp6_tree, hf_icmpv6_mip6_identifier, tvb, offset, 2, ENC_BIG_ENDIAN);
4486                 offset += 2;
4487 
4488                 /* Reserved */
4489                 proto_tree_add_item(icmp6_tree, hf_icmpv6_reserved, tvb, offset, 2, ENC_NA);
4490                 offset += 2;
4491 
4492                 /* Show all Home Agent Addresses */
4493                 while((int)length > offset)
4494                 {
4495                     proto_tree_add_item(icmp6_tree, hf_icmpv6_mip6_home_agent_address, tvb, offset, 16, ENC_NA);
4496                     offset += 16;
4497                 }
4498                 break;
4499             }
4500             case ICMP6_MIP6_MPS: /* Mobile Prefix Solicitation (146) */
4501             {
4502                 /* Identifier */
4503                 proto_tree_add_item(icmp6_tree, hf_icmpv6_mip6_identifier, tvb, offset, 2, ENC_BIG_ENDIAN);
4504                 offset += 2;
4505 
4506                 /* Reserved */
4507                 proto_tree_add_item(icmp6_tree, hf_icmpv6_reserved, tvb, offset, 2, ENC_NA);
4508                 offset += 2;
4509                 break;
4510             }
4511             case ICMP6_MIP6_MPA: /* Mobile Prefix Advertisement (147) */
4512             {
4513                 static int * const mip6_flags[] = {
4514                     &hf_icmpv6_mip6_flag_m,
4515                     &hf_icmpv6_mip6_flag_o,
4516                     &hf_icmpv6_mip6_flag_rsv,
4517                     NULL
4518                 };
4519 
4520                 /* Identifier */
4521                 proto_tree_add_item(icmp6_tree, hf_icmpv6_mip6_identifier, tvb, offset, 2, ENC_BIG_ENDIAN);
4522                 offset += 2;
4523 
4524                 /* Flags */
4525                 proto_tree_add_bitmask(icmp6_tree, tvb, offset, hf_icmpv6_mip6_flag, ett_icmpv6_flag_mip6, mip6_flags, ENC_BIG_ENDIAN);
4526                 offset += 2;
4527 
4528                 /* Show options */
4529                 offset = dissect_icmpv6_nd_opt(tvb, offset, pinfo, icmp6_tree);
4530                 break;
4531             }
4532             case ICMP6_CERT_PATH_SOL: /* Certification Path Solicitation Message (148) */
4533             {
4534 
4535                 /* Identifier */
4536                 proto_tree_add_item(icmp6_tree, hf_icmpv6_send_identifier, tvb, offset, 2, ENC_BIG_ENDIAN);
4537                 offset += 2;
4538 
4539                 /* Component  */
4540                 proto_tree_add_item(icmp6_tree, hf_icmpv6_send_component, tvb, offset, 2, ENC_BIG_ENDIAN);
4541                 offset += 2;
4542 
4543                 /* Show options */
4544                 offset = dissect_icmpv6_nd_opt(tvb, offset, pinfo, icmp6_tree);
4545                 break;
4546             }
4547             case ICMP6_CERT_PATH_AD: /* Certification Path Advertisement Message (149) */
4548             {
4549 
4550                 /* Identifier */
4551                 proto_tree_add_item(icmp6_tree, hf_icmpv6_send_identifier, tvb, offset, 2, ENC_BIG_ENDIAN);
4552                 offset += 2;
4553 
4554                 /* All Components */
4555                 proto_tree_add_item(icmp6_tree, hf_icmpv6_send_all_components, tvb, offset, 2, ENC_BIG_ENDIAN);
4556                 offset += 2;
4557 
4558                 /* Component  */
4559                 proto_tree_add_item(icmp6_tree, hf_icmpv6_send_component, tvb, offset, 2, ENC_BIG_ENDIAN);
4560                 offset += 2;
4561 
4562                 /* Reserved */
4563                 proto_tree_add_item(icmp6_tree, hf_icmpv6_reserved, tvb, offset, 2, ENC_NA);
4564                 offset += 2;
4565 
4566                 /* Show options */
4567                 offset = dissect_icmpv6_nd_opt(tvb, offset, pinfo, icmp6_tree);
4568                 break;
4569             }
4570             case ICMP6_EXPERIMENTAL_MOBILITY: /* ICMP messages utilized by experimental mobility protocols (150) */
4571             case ICMP6_FMIPV6_MESSAGES:  /* FMIPv6 Messages (154)*/
4572             {
4573                 guint8 subtype;
4574 
4575                 /* Subtype */
4576                 proto_tree_add_item(icmp6_tree, hf_icmpv6_fmip6_subtype, tvb, offset, 1, ENC_BIG_ENDIAN);
4577                 subtype = tvb_get_guint8(tvb, offset);
4578                 col_append_fstr(pinfo->cinfo, COL_INFO, " (%s)", val_to_str(subtype, fmip6_subtype_val, "Unknown (%d)"));
4579                 offset += 1;
4580 
4581                 switch(subtype){
4582                     case FMIP6_SUBTYPE_RTSOLPR:
4583                     {
4584                         /* Reserved */
4585                         proto_tree_add_item(icmp6_tree, hf_icmpv6_reserved, tvb, offset, 1, ENC_NA);
4586                     }
4587                     break;
4588                     case FMIP6_SUBTYPE_PRRTADV:
4589                     {
4590                         proto_item_append_text(code_item, " (%s)", val_to_str(icmp6_code, fmip6_prrtadv_code_val, "Unknown %d") );
4591                         /* Reserved */
4592                         proto_tree_add_item(icmp6_tree, hf_icmpv6_reserved, tvb, offset, 1, ENC_NA);
4593                     }
4594                     break;
4595                     case FMIP6_SUBTYPE_HI:
4596                     {
4597                         static int * const fmip6_hi_flags[] = {
4598                             &hf_icmpv6_fmip6_hi_flag_s,
4599                             &hf_icmpv6_fmip6_hi_flag_u,
4600                             &hf_icmpv6_fmip6_hi_flag_reserved,
4601                             NULL
4602                         };
4603 
4604                         proto_item_append_text(code_item, " (%s)", val_to_str(icmp6_code, fmip6_hi_code_val, "Unknown %d") );
4605                         /* Flags */
4606                         proto_tree_add_bitmask(icmp6_tree, tvb, offset, hf_icmpv6_fmip6_hi_flag, ett_icmpv6_flag_fmip6, fmip6_hi_flags, ENC_BIG_ENDIAN);
4607                     }
4608                     break;
4609                     case FMIP6_SUBTYPE_HACK:
4610                     {
4611                         proto_item_append_text(code_item, " (%s)", val_to_str(icmp6_code, fmip6_hack_code_val, "Unknown %d") );
4612                         /* Reserved */
4613                         proto_tree_add_item(icmp6_tree, hf_icmpv6_reserved, tvb, offset, 1, ENC_NA);
4614                     }
4615                     break;
4616                 }
4617                 offset +=1;
4618 
4619                 /* Identifier */
4620                 proto_tree_add_item(icmp6_tree, hf_icmpv6_fmip6_identifier, tvb, offset, 2, ENC_BIG_ENDIAN);
4621                 offset += 2;
4622 
4623                 /* Show options */
4624                 offset = dissect_icmpv6_nd_opt(tvb, offset, pinfo, icmp6_tree);
4625                 break;
4626             }
4627             case ICMP6_MCAST_ROUTER_ADVERT: /* Multicast Router Advertisement (151) */
4628             {
4629                 /* Query Interval */
4630                 proto_tree_add_item(icmp6_tree, hf_icmpv6_mcast_ra_query_interval, tvb, offset, 2, ENC_BIG_ENDIAN);
4631                 offset += 2;
4632 
4633                 /* Robustness Variable */
4634                 proto_tree_add_item(icmp6_tree, hf_icmpv6_mcast_ra_robustness_variable, tvb, offset, 2, ENC_BIG_ENDIAN);
4635                 offset += 2;
4636             }
4637             case ICMP6_MCAST_ROUTER_SOLICIT: /* Multicast Router Solicitation (152) */
4638             case ICMP6_MCAST_ROUTER_TERM: /* Multicast Router Termination (153) */
4639             {
4640                 /* No Action... */
4641                 break;
4642             }
4643             case ICMP6_RPL_CONTROL: /* RPL Control (155) */
4644             {
4645                 /* RPL: RFC 6550 : Routing over Low-Power and Lossy Networks. */
4646                 offset = dissect_rpl_control(tvb, offset, pinfo, icmp6_tree, icmp6_type, icmp6_code);
4647                 break;
4648             }
4649             case ICMP6_ILNPV6: /* Locator Update (156) */
4650             {
4651                 guint8 nb_locs, i;
4652                 /* Number of locs */
4653                 proto_tree_add_item(icmp6_tree, hf_icmpv6_ilnp_nb_locs, tvb, offset, 1, ENC_BIG_ENDIAN);
4654                 nb_locs = tvb_get_guint8(tvb, offset);
4655                 offset += 1;
4656 
4657                 /* Reserved */
4658                 proto_tree_add_item(icmp6_tree, hf_icmpv6_reserved, tvb, offset, 1, ENC_NA);
4659                 offset += 1;
4660 
4661                 /* Reserved */
4662                 proto_tree_add_item(icmp6_tree, hf_icmpv6_reserved, tvb, offset, 2, ENC_NA);
4663                 offset += 2;
4664 
4665                 /* Locator / Preference / Lifetime */
4666                 for (i=0; i < nb_locs; i++){
4667                     proto_tree_add_item(icmp6_tree, hf_icmpv6_ilnp_locator, tvb, offset, 8, ENC_NA);
4668                     offset += 8;
4669 
4670                     proto_tree_add_item(icmp6_tree, hf_icmpv6_ilnp_preference, tvb, offset, 2, ENC_NA);
4671                     offset += 2;
4672 
4673                     proto_tree_add_item(icmp6_tree, hf_icmpv6_ilnp_lifetime, tvb, offset, 2, ENC_NA);
4674                     offset += 2;
4675 
4676                 }
4677                 break;
4678             }
4679             case ICMP6_6LOWPANND_DAR:
4680             case ICMP6_6LOWPANND_DAC:
4681             {
4682                 /* Status */
4683                 proto_tree_add_item(icmp6_tree, hf_icmpv6_da_status, tvb, offset, 1, ENC_BIG_ENDIAN);
4684                 offset += 1;
4685 
4686                 /* Reserved */
4687                 proto_tree_add_item(icmp6_tree, hf_icmpv6_da_rsv, tvb, offset, 1, ENC_BIG_ENDIAN);
4688                 offset += 1;
4689 
4690                 /* Lifetime */
4691                 proto_tree_add_item(icmp6_tree, hf_icmpv6_da_lifetime, tvb, offset, 2, ENC_BIG_ENDIAN);
4692                 offset += 2;
4693 
4694                 /* EUI-64 */
4695                 proto_tree_add_item(icmp6_tree, hf_icmpv6_da_eui64, tvb, offset, 8, ENC_BIG_ENDIAN);
4696                 offset += 8;
4697 
4698                 /* Address */
4699                 proto_tree_add_item(icmp6_tree, hf_icmpv6_da_raddr, tvb, offset, 16, ENC_NA);
4700                 offset += 16;
4701                 break;
4702             }
4703             case ICMP6_MPL_CONTROL: /* MPL Control (159) */
4704             {
4705                 /* RFC 7731: Multicast Protocol for Low-Power and Lossy Networks (MPL) */
4706                 offset = dissect_mpl_control(tvb, offset, pinfo, icmp6_tree, icmp6_type, icmp6_code);
4707                 break;
4708             }
4709 
4710             case ICMP6_EXTECHO: /* Extended Echo - Probe - (RFC8335) */
4711             {
4712                 proto_tree_add_item(icmp6_tree, hf_icmpv6_echo_identifier, tvb, offset, 2,
4713                                     ENC_BIG_ENDIAN);
4714                 offset += 2;
4715                 proto_tree_add_item(icmp6_tree, hf_icmpv6_ext_echo_seq_num, tvb, offset, 1,
4716                                     ENC_BIG_ENDIAN);
4717                 offset += 1;
4718                 proto_tree_add_item(icmp6_tree, hf_icmpv6_ext_echo_req_reserved, tvb, offset, 1,
4719                                     ENC_BIG_ENDIAN);
4720                 proto_tree_add_item(icmp6_tree, hf_icmpv6_ext_echo_req_local, tvb, offset, 1,
4721                                     ENC_BIG_ENDIAN);
4722                 offset += 1;
4723 
4724                 tvbuff_t * extension_tvb = tvb_new_subset_remaining(tvb, offset);
4725                 offset += call_dissector(icmp_extension_handle, extension_tvb, pinfo, icmp6_tree);
4726                 break;
4727             }
4728 
4729             case ICMP6_EXTECHOREPLY:
4730             {
4731                 proto_tree_add_item(icmp6_tree, hf_icmpv6_echo_identifier, tvb, offset, 2,
4732                                     ENC_BIG_ENDIAN);
4733                 offset += 2;
4734                 proto_tree_add_item(icmp6_tree, hf_icmpv6_ext_echo_seq_num, tvb, offset, 1,
4735                                     ENC_BIG_ENDIAN);
4736                 offset += 1;
4737                 proto_tree_add_item(icmp6_tree, hf_icmpv6_ext_echo_rsp_state, tvb, offset, 1,
4738                                     ENC_BIG_ENDIAN);
4739                 proto_tree_add_item(icmp6_tree, hf_icmpv6_ext_echo_rsp_reserved, tvb, offset, 1,
4740                                     ENC_BIG_ENDIAN);
4741                 proto_tree_add_item(icmp6_tree, hf_icmpv6_ext_echo_rsp_active, tvb, offset, 1,
4742                                     ENC_BIG_ENDIAN);
4743                 proto_tree_add_item(icmp6_tree, hf_icmpv6_ext_echo_rsp_ipv4, tvb, offset, 1,
4744                                     ENC_BIG_ENDIAN);
4745                 proto_tree_add_item(icmp6_tree, hf_icmpv6_ext_echo_rsp_ipv6, tvb, offset, 1,
4746                                     ENC_BIG_ENDIAN);
4747                 offset += 1;
4748                 break;
4749             }
4750 
4751             default:
4752                 expert_add_info_format(pinfo, ti, &ei_icmpv6_undecoded_type,
4753                                        "Dissector for ICMPv6 Type (%d)"
4754                                        " code not implemented, Contact Wireshark"
4755                                        " developers if you want this supported", icmp6_type);
4756                 proto_tree_add_item(icmp6_tree, hf_icmpv6_data, tvb, offset, -1, ENC_NA);
4757                 break;
4758         } /* switch (icmp6_type) */
4759     } /* if (1) */
4760 
4761     if (!PINFO_FD_VISITED(pinfo)) {
4762         icmp_info_t *p_icmp_info = wmem_new(wmem_file_scope(), icmp_info_t);
4763         p_icmp_info->type = icmp6_type;
4764         p_icmp_info->code = icmp6_code;
4765         p_add_proto_data(wmem_file_scope(), pinfo, proto_icmpv6, 0, p_icmp_info);
4766     }
4767 
4768     if (trans)
4769         tap_queue_packet(icmpv6_tap, pinfo, trans);
4770 
4771     return offset;
4772 }
4773 
4774 void
proto_register_icmpv6(void)4775 proto_register_icmpv6(void)
4776 {
4777     static hf_register_info hf[] = {
4778         { &hf_icmpv6_type,
4779           { "Type", "icmpv6.type", FT_UINT8, BASE_DEC, VALS(icmpv6_type_val), 0x0,
4780             "Indicates the type of the message", HFILL }},
4781         { &hf_icmpv6_code,
4782           { "Code", "icmpv6.code", FT_UINT8, BASE_DEC, NULL, 0x0,
4783             "Depends on the message type.  It is used to create an additional level of message granularity", HFILL }},
4784         { &hf_icmpv6_checksum,
4785           { "Checksum", "icmpv6.checksum", FT_UINT16, BASE_HEX, NULL, 0x0,
4786             "Used to detect data corruption in the ICMPv6 message and parts of the IPv6 header", HFILL }},
4787         { &hf_icmpv6_checksum_status,
4788           { "Checksum Status", "icmpv6.checksum.status", FT_UINT8, BASE_NONE, VALS(proto_checksum_vals), 0x0,
4789             NULL, HFILL }},
4790         { &hf_icmpv6_reserved,
4791           { "Reserved", "icmpv6.reserved", FT_BYTES, BASE_NONE, NULL, 0x0,
4792             "Must be Zero", HFILL }},
4793         { &hf_icmpv6_data,
4794           { "Data", "icmpv6.data", FT_BYTES, BASE_NONE, NULL, 0x0,
4795             NULL, HFILL }},
4796         { &hf_icmpv6_unknown_data,
4797           { "Unknown Data", "icmpv6.unknown_data", FT_BYTES, BASE_NONE, NULL, 0x0,
4798             "Not interpreted Data", HFILL }},
4799         { &hf_icmpv6_mtu,
4800           { "MTU", "icmpv6.mtu", FT_UINT32, BASE_DEC, NULL, 0x0,
4801             "The Maximum Transmission Unit of the next-hop link", HFILL }},
4802         { &hf_icmpv6_pointer,
4803           { "Pointer", "icmpv6.pointer", FT_UINT32, BASE_DEC, NULL, 0x0,
4804             "Identifies the octet offset within the invoking packet where the error was detected", HFILL }},
4805         { &hf_icmpv6_echo_identifier,
4806           { "Identifier", "icmpv6.echo.identifier", FT_UINT16, BASE_HEX, NULL, 0x0,
4807             "An identifier to aid in matching with Request and Reply", HFILL }},
4808         { &hf_icmpv6_echo_sequence_number,
4809           { "Sequence", "icmpv6.echo.sequence_number", FT_UINT16, BASE_DEC, NULL, 0x0,
4810             "A sequence number to aid in matching Echo Replies to this Echo Request", HFILL }},
4811         { &hf_icmpv6_nonce,
4812           { "Nonce", "icmpv6.nonce", FT_BYTES, BASE_NONE, NULL, 0x0,
4813             NULL, HFILL }},
4814         /* RFC 2461/4861 : Neighbor Discovery for IP version 6 (IPv6) */
4815         { &hf_icmpv6_nd_ra_cur_hop_limit,
4816           { "Cur hop limit", "icmpv6.nd.ra.cur_hop_limit", FT_UINT8, BASE_DEC, NULL, 0x0,
4817             "The default value that should be placed in the Hop Count field of the IP header for outgoing IP packets", HFILL }},
4818         { &hf_icmpv6_nd_ra_flag,
4819           { "Flags", "icmpv6.nd.ra.flag", FT_UINT8, BASE_HEX, NULL, 0x0,
4820             NULL, HFILL }},
4821         { &hf_icmpv6_nd_ra_flag_m,
4822           { "Managed address configuration", "icmpv6.nd.ra.flag.m", FT_BOOLEAN, 8, TFS(&tfs_set_notset), ND_RA_FLAG_M,
4823             "When set, it indicates that addresses are available via DHCPv6", HFILL }},
4824         { &hf_icmpv6_nd_ra_flag_o,
4825           { "Other configuration", "icmpv6.nd.ra.flag.o", FT_BOOLEAN, 8, TFS(&tfs_set_notset), ND_RA_FLAG_O,
4826             "When set, it indicates that other configuration information is available via DHCPv6", HFILL }},
4827         { &hf_icmpv6_nd_ra_flag_h,
4828           { "Home Agent", "icmpv6.nd.ra.flag.h", FT_BOOLEAN, 8, TFS(&tfs_set_notset), ND_RA_FLAG_H,
4829             "When set, it indicate that the router sending this Router Advertisement is also functioning as a Mobile IPv6 home agent on this link", HFILL }},
4830         { &hf_icmpv6_nd_ra_flag_prf,
4831           { "Prf (Default Router Preference)", "icmpv6.nd.ra.flag.prf", FT_UINT8, BASE_DEC, VALS(nd_flag_router_pref), ND_RA_FLAG_PRF,
4832             "Indicates whether to prefer this router over other default routers", HFILL }},
4833         { &hf_icmpv6_nd_ra_flag_p,
4834           { "Proxy", "icmpv6.nd.ra.flag.p", FT_BOOLEAN, 8, TFS(&tfs_set_notset), ND_RA_FLAG_P,
4835            NULL, HFILL }},
4836         { &hf_icmpv6_nd_ra_flag_rsv,
4837           { "Reserved", "icmpv6.nd.ra.flag.rsv", FT_UINT8, BASE_DEC, NULL, ND_RA_FLAG_RSV,
4838             "Must be Zero", HFILL }},
4839         { &hf_icmpv6_nd_ra_router_lifetime,
4840           { "Router lifetime (s)", "icmpv6.nd.ra.router_lifetime", FT_UINT16, BASE_DEC, NULL, 0x0,
4841             "The lifetime associated with the default router", HFILL }},
4842         { &hf_icmpv6_nd_ra_reachable_time,
4843           { "Reachable time (ms)", "icmpv6.nd.ra.reachable_time", FT_UINT32, BASE_DEC, NULL, 0x0,
4844             "The time that a node assumes a neighbor is reachable after having received a reachability confirmation", HFILL }},
4845         { &hf_icmpv6_nd_ra_retrans_timer,
4846           { "Retrans timer (ms)", "icmpv6.nd.ra.retrans_timer", FT_UINT32, BASE_DEC, NULL, 0x0,
4847             "The time between retransmitted Neighbor Solicitation messages", HFILL }},
4848         { &hf_icmpv6_nd_ns_target_address,
4849           { "Target Address", "icmpv6.nd.ns.target_address", FT_IPv6, BASE_NONE, NULL, 0x0,
4850             "The IP address of the target of the solicitation", HFILL }},
4851         { &hf_icmpv6_nd_na_flag,
4852           { "Flags", "icmpv6.nd.na.flag", FT_UINT32, BASE_HEX, NULL, 0x0,
4853             NULL, HFILL }},
4854         { &hf_icmpv6_nd_na_flag_r,
4855           { "Router", "icmpv6.nd.na.flag.r", FT_BOOLEAN, 32, TFS(&tfs_set_notset), ND_NA_FLAG_R,
4856             "When set, it indicates that the sender is a router", HFILL }},
4857         { &hf_icmpv6_nd_na_flag_s,
4858           { "Solicited", "icmpv6.nd.na.flag.s", FT_BOOLEAN, 32, TFS(&tfs_set_notset), ND_NA_FLAG_S,
4859             "When set, it indicates that the advertisement was sent in response to a Neighbor Solicitation from the Destination address", HFILL }},
4860         { &hf_icmpv6_nd_na_flag_o,
4861           { "Override", "icmpv6.nd.na.flag.o", FT_BOOLEAN, 32, TFS(&tfs_set_notset), ND_NA_FLAG_O,
4862             "When set, it indicates that the advertisement should override an existing cache entry and update the cached link-layer address", HFILL }},
4863         { &hf_icmpv6_nd_na_flag_rsv,
4864           { "Reserved", "icmpv6.nd.na.flag.rsv", FT_UINT32, BASE_DEC, NULL, ND_NA_FLAG_RSV,
4865             "Must be Zero", HFILL }},
4866         { &hf_icmpv6_nd_na_target_address,
4867           { "Target Address", "icmpv6.nd.na.target_address", FT_IPv6, BASE_NONE, NULL, 0x0,
4868             "the Target Address field in the Neighbor Solicitation message that prompted this advertisement", HFILL }},
4869         { &hf_icmpv6_nd_rd_target_address,
4870           { "Target Address", "icmpv6.nd.rd.target_address", FT_IPv6, BASE_NONE, NULL, 0x0,
4871             "An IP address that is a better first hop to use for the ICMP Destination Address", HFILL }},
4872         { &hf_icmpv6_nd_rd_destination_address,
4873           { "Destination Address", "icmpv6.rd.na.destination_address", FT_IPv6, BASE_NONE, NULL, 0x0,
4874             "The IP address of the destination that is redirected to the target", HFILL }},
4875         { &hf_icmpv6_opt,
4876           { "ICMPv6 Option", "icmpv6.opt", FT_NONE, BASE_NONE, NULL, 0x0,
4877             "Option", HFILL }},
4878         { &hf_icmpv6_opt_type,
4879           { "Type", "icmpv6.opt.type", FT_UINT8, BASE_DEC, VALS(option_vals), 0x0,
4880             "Options type", HFILL }},
4881         { &hf_icmpv6_opt_length,
4882           { "Length", "icmpv6.opt.length", FT_UINT8, BASE_DEC, NULL, 0x0,
4883             "The length (in units of 8 bytes) of the option (including the Type and Length fields)", HFILL }},
4884         { &hf_icmpv6_opt_reserved,
4885           { "Reserved", "icmpv6.opt.reserved", FT_NONE, BASE_NONE, NULL, 0x0,
4886             "Reserved (Must be 0)", HFILL }},
4887         { &hf_icmpv6_opt_padding,
4888           { "Padding", "icmpv6.opt.padding", FT_NONE, BASE_NONE, NULL, 0x0,
4889             "Padding (Must be 0)", HFILL }},
4890         { &hf_icmpv6_opt_linkaddr,
4891           { "Link-layer address", "icmpv6.opt.linkaddr", FT_BYTES, BASE_NONE, NULL, 0x0,
4892             NULL, HFILL }},
4893        { &hf_icmpv6_opt_src_linkaddr,
4894           { "Source Link-layer address", "icmpv6.opt.src_linkaddr", FT_BYTES, BASE_NONE, NULL, 0x0,
4895             NULL, HFILL }},
4896        { &hf_icmpv6_opt_target_linkaddr,
4897           { "Target Link-layer address", "icmpv6.opt.target_linkaddr", FT_BYTES, BASE_NONE, NULL, 0x0,
4898             NULL, HFILL }},
4899         { &hf_icmpv6_opt_linkaddr_mac,
4900           { "Link-layer address", "icmpv6.opt.linkaddr", FT_ETHER, BASE_NONE, NULL, 0x0,
4901             NULL, HFILL }},
4902        { &hf_icmpv6_opt_src_linkaddr_mac,
4903           { "Source Link-layer address", "icmpv6.opt.src_linkaddr", FT_ETHER, BASE_NONE, NULL, 0x0,
4904             NULL, HFILL }},
4905        { &hf_icmpv6_opt_target_linkaddr_mac,
4906           { "Target Link-layer address", "icmpv6.opt.target_linkaddr", FT_ETHER, BASE_NONE, NULL, 0x0,
4907             NULL, HFILL }},
4908         { &hf_icmpv6_opt_linkaddr_eui64,
4909           { "Link-layer address", "icmpv6.opt.linkaddr_eui64", FT_EUI64, BASE_NONE, NULL, 0x0,
4910             NULL, HFILL }},
4911        { &hf_icmpv6_opt_src_linkaddr_eui64,
4912           { "Source Link-layer address", "icmpv6.opt.src_linkaddr_eui64", FT_EUI64, BASE_NONE, NULL, 0x0,
4913             NULL, HFILL }},
4914        { &hf_icmpv6_opt_target_linkaddr_eui64,
4915           { "Target Link-layer address", "icmpv6.opt.target_linkaddr_eui64", FT_EUI64, BASE_NONE, NULL, 0x0,
4916             NULL, HFILL }},
4917         { &hf_icmpv6_opt_prefix_len,
4918           { "Prefix Length", "icmpv6.opt.prefix.length", FT_UINT8, BASE_DEC, NULL, 0x0,
4919             "The number of leading bits in the Prefix that are valid", HFILL }},
4920         { &hf_icmpv6_opt_prefix_flag,
4921           { "Flag", "icmpv6.opt.prefix.flag", FT_UINT8, BASE_HEX, NULL, 0x00,
4922             NULL, HFILL }},
4923         { &hf_icmpv6_opt_prefix_flag_l,
4924           { "On-link flag(L)", "icmpv6.opt.prefix.flag.l", FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x80,
4925             "When set, indicates that this prefix can be used for on-link determination", HFILL }},
4926         { &hf_icmpv6_opt_prefix_flag_a,
4927           { "Autonomous address-configuration flag(A)", "icmpv6.opt.prefix.flag.a", FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x40,
4928             "When set indicates that this prefix can be used for stateless address configuration", HFILL }},
4929         { &hf_icmpv6_opt_prefix_flag_r,
4930           { "Router address flag(R)", "icmpv6.opt.prefix.flag.r", FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x20,
4931             "When set indicates that the Prefix field contains a complete IP address assigned to the sending router", HFILL }},
4932         { &hf_icmpv6_opt_prefix_flag_reserved,
4933           { "Reserved", "icmpv6.opt.prefix.flag.reserved", FT_UINT8, BASE_DEC, NULL, 0x1f,
4934             NULL, HFILL }},
4935         { &hf_icmpv6_opt_prefix_valid_lifetime,
4936           { "Valid Lifetime", "icmpv6.opt.prefix.valid_lifetime", FT_UINT32, BASE_DEC|BASE_SPECIAL_VALS, VALS(unique_infinity), 0x00,
4937             "The length of time in seconds that the prefix is valid for the purpose of on-link determination", HFILL }},
4938         { &hf_icmpv6_opt_prefix_preferred_lifetime,
4939           { "Preferred Lifetime", "icmpv6.opt.prefix.preferred_lifetime", FT_UINT32, BASE_DEC|BASE_SPECIAL_VALS, VALS(unique_infinity), 0x00,
4940             "The length of time in seconds that addresses generated from the prefix via stateless address autoconfiguration remain preferred", HFILL }},
4941         { &hf_icmpv6_opt_prefix,
4942           { "Prefix", "icmpv6.opt.prefix", FT_IPv6, BASE_NONE, NULL, 0x00,
4943             "An IP address or a prefix of an IP address", HFILL }},
4944         { &hf_icmpv6_opt_cga_pad_len,
4945           { "Pad Length", "icmpv6.opt.cga.pad_length", FT_UINT8, BASE_DEC, NULL, 0x0,
4946             "Pad Length (in bytes)", HFILL }},
4947         { &hf_icmpv6_opt_cga,
4948           { "CGA", "icmpv6.opt.cga", FT_BYTES, BASE_NONE, NULL, 0x0,
4949             NULL, HFILL }},
4950         { &hf_icmpv6_opt_cga_modifier,
4951           { "Modifier", "icmpv6.opt.cga.modifier", FT_BYTES, BASE_NONE, NULL, 0x0,
4952             NULL, HFILL }},
4953         { &hf_icmpv6_opt_cga_subnet_prefix,
4954           { "Subnet Prefix", "icmpv6.opt.cga.subnet_prefix", FT_BYTES, BASE_NONE, NULL, 0x0,
4955             NULL, HFILL }},
4956         { &hf_icmpv6_opt_cga_count,
4957           { "Count", "icmpv6.opt.cga.count", FT_BYTES, BASE_NONE, NULL, 0x0,
4958             NULL, HFILL }},
4959         { &hf_icmpv6_opt_cga_ext_type,
4960           { "Ext Type", "icmpv6.opt.cga.ext_type", FT_UINT16, BASE_DEC, NULL, 0x0,
4961             NULL, HFILL }},
4962         { &hf_icmpv6_opt_cga_ext_length,
4963           { "Ext Length", "icmpv6.opt.cga.ext_length", FT_UINT16, BASE_DEC, NULL, 0x0,
4964             NULL, HFILL }},
4965         { &hf_icmpv6_opt_cga_ext_data,
4966           { "Ext Data", "icmpv6.opt.cga.ext_data", FT_BYTES, BASE_NONE, NULL, 0x0,
4967             NULL, HFILL }},
4968         { &hf_icmpv6_opt_rsa_key_hash,
4969           { "Key Hash", "icmpv6.opt.rsa.key_hash", FT_BYTES, BASE_NONE, NULL, 0x0,
4970             NULL, HFILL }},
4971         { &hf_icmpv6_opt_digital_signature_padding,
4972           { "Digital Signature and Padding", "icmpv6.opt.digital_signature_padding", FT_NONE, BASE_NONE, NULL, 0x0,
4973             "TO DO FIX ME !!", HFILL }},
4974         { &hf_icmpv6_opt_ps_key_hash,
4975           { "Key Hash", "icmpv6.opt.ps.key_hash", FT_BYTES, BASE_NONE, NULL, 0x0,
4976             NULL, HFILL }},
4977         { &hf_icmpv6_opt_timestamp,
4978           { "Timestamp", "icmpv6.opt.timestamp", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x0,
4979             "The value indicates the number of seconds since January 1, 1970, 00:00 UTC", HFILL }},
4980         { &hf_icmpv6_opt_nonce,
4981           { "Nonce", "icmpv6.opt.nonce", FT_BYTES, BASE_NONE, NULL, 0x0,
4982             "A field containing a random number selected by the sender of the solicitation message", HFILL }},
4983         { &hf_icmpv6_opt_certificate_padding,
4984           { "Certificate and Padding", "icmpv6.opt.certificate_padding", FT_NONE, BASE_NONE, NULL, 0x0,
4985             NULL, HFILL }},
4986         { &hf_icmpv6_opt_ipa_option_code,
4987           { "Option-code", "icmpv6.opt.ipa.option_code", FT_UINT8, BASE_DEC, VALS(nd_opt_ipa_option_code_val), 0x00,
4988             NULL, HFILL }},
4989         { &hf_icmpv6_opt_ipa_prefix_len,
4990           { "Prefix Length", "icmpv6.opt.ipa.prefix_len", FT_UINT8, BASE_DEC, NULL, 0x00,
4991             "That indicates the length of the IPv6 Address Prefix", HFILL }},
4992         { &hf_icmpv6_opt_ipa_ipv6_address,
4993           { "IPv6 Address", "icmpv6.opt.ipa.ipv6_address", FT_IPv6, BASE_NONE, NULL, 0x00,
4994             "The IP address/prefix defined by the Option-Code field", HFILL }},
4995         { &hf_icmpv6_opt_nrpi_option_code,
4996           { "Option-code", "icmpv6.opt.nrpi.option_code", FT_UINT8, BASE_DEC, NULL, 0x00,
4997             NULL, HFILL }},
4998         { &hf_icmpv6_opt_nrpi_prefix_len,
4999           { "Prefix Length", "icmpv6.opt.nrpi.prefix_len", FT_UINT8, BASE_DEC, NULL, 0x00,
5000             "The number of leading bits in the Prefix that are valid", HFILL }},
5001         { &hf_icmpv6_opt_nrpi_prefix,
5002           { "Prefix", "icmpv6.opt.nrpi.prefix", FT_IPv6, BASE_NONE, NULL, 0x00,
5003             "An IP address or a prefix of an IP address", HFILL }},
5004         { &hf_icmpv6_opt_lla_option_code,
5005           { "Option-code", "icmpv6.opt.lla.option_code", FT_UINT8, BASE_DEC, VALS(nd_opt_lla_option_code_val), 0x00,
5006             NULL, HFILL }},
5007         { &hf_icmpv6_opt_lla_bytes,
5008           { "Link-Layer Address", "icmpv6.opt.lla.bytes", FT_BYTES, BASE_NONE, NULL, 0x00,
5009             "(in Bytes Format)", HFILL }},
5010         { &hf_icmpv6_opt_naack_option_code,
5011           { "Option-Code", "icmpv6.opt.naack.option_code", FT_UINT8, BASE_DEC, NULL, 0x00,
5012             NULL, HFILL }},
5013         { &hf_icmpv6_opt_naack_status,
5014           { "Status", "icmpv6.opt.naack.status", FT_UINT8, BASE_DEC, VALS(nd_opt_naack_status_val), 0x00,
5015             "Indicating the disposition of the Unsolicited Neighbor Advertisement message", HFILL }},
5016         { &hf_icmpv6_opt_naack_supplied_ncoa,
5017           { "Supplied NCoA", "icmpv6.opt.naack.supplied_ncoa", FT_IPv6, BASE_NONE, NULL, 0x00,
5018             NULL, HFILL }},
5019         { &hf_icmpv6_opt_map_dist,
5020           { "Distance", "icmpv6.opt.map.distance", FT_UINT8, BASE_DEC, NULL, 0xF0,
5021             "Identifying the distance between MAP and the receiver of the advertisement (in the number of hops)", HFILL }},
5022         { &hf_icmpv6_opt_map_pref,
5023           { "Preference", "icmpv6.opt.map.preference", FT_UINT8, BASE_DEC, NULL, 0x0F,
5024             "Used as an indicator of operator preference (Highest is better)", HFILL }},
5025         { &hf_icmpv6_opt_map_flag,
5026           { "Flag", "icmpv6.opt.map.flag", FT_UINT8, BASE_HEX, NULL, 0x00,
5027             NULL, HFILL }},
5028         { &hf_icmpv6_opt_map_flag_r,
5029           { "RCoA Flag", "icmpv6.opt.map.flag.r", FT_BOOLEAN, 8, NULL, 0x80,
5030             "It indicates that the mobile node is allocated the RCoA by the MAP", HFILL }},
5031         { &hf_icmpv6_opt_map_flag_reserved,
5032           { "Reserved", "icmpv6.opt.map.flag.reserved", FT_UINT8, BASE_DEC, NULL, 0x7F,
5033             "Must be 0", HFILL }},
5034         { &hf_icmpv6_opt_map_valid_lifetime,
5035           { "Valid Lifetime", "icmpv6.opt.map.valid_lifetime", FT_UINT32, BASE_DEC, NULL, 0x0,
5036             "This value indicates the validity of the MAP's address and the RCoA.", HFILL }},
5037         { &hf_icmpv6_opt_map_global_address,
5038           { "Global Address", "icmpv6.opt.map.global_address", FT_IPv6, BASE_NONE, NULL, 0x0,
5039             "One of the MAP's global addresses", HFILL }},
5040         { &hf_icmpv6_opt_route_info_flag,
5041           { "Flag", "icmpv6.opt.route_info.flag", FT_UINT8, BASE_HEX, NULL, 0x00,
5042             NULL, HFILL }},
5043         { &hf_icmpv6_opt_route_info_flag_route_preference,
5044           { "Route Preference", "icmpv6.opt.route_info.flag.route_preference", FT_UINT8, BASE_DEC, VALS(nd_flag_router_pref), ND_RA_FLAG_RTPREF_MASK,
5045             "The Route Preference indicates whether to prefer the router associated with this prefix over others", HFILL }},
5046         { &hf_icmpv6_opt_route_info_flag_reserved,
5047           { "Reserved", "icmpv6.opt.route_info.flag.reserved", FT_UINT8, BASE_DEC, NULL, ND_RA_FLAG_RESERV_MASK,
5048             "Must be 0", HFILL }},
5049         { &hf_icmpv6_opt_route_lifetime,
5050           { "Route Lifetime", "icmpv6.opt.route_lifetime", FT_UINT32, BASE_DEC|BASE_SPECIAL_VALS, VALS(unique_infinity), 0x00,
5051             "The length of time in seconds that the prefix is valid for the purpose of route determination", HFILL }},
5052         { &hf_icmpv6_opt_name_type,
5053           { "Name Type", "icmpv6.opt.name_type", FT_UINT8, BASE_DEC, VALS(icmpv6_option_name_type_vals), 0x0,
5054             NULL, HFILL }},
5055         { &hf_icmpv6_opt_name_x501,
5056           { "DER Encoded X.501 Name", "icmpv6.opt.name_x501", FT_BYTES, BASE_NONE, NULL, 0x0,
5057             NULL, HFILL }},
5058         { &hf_icmpv6_opt_name_fqdn,
5059           { "FQDN", "icmpv6.opt.name_type.fqdn", FT_STRING, BASE_NONE, NULL, 0x0,
5060             NULL, HFILL }},
5061         { &hf_icmpv6_opt_cert_type,
5062           { "Cert Type", "icmpv6.opt.name_type", FT_UINT8, BASE_DEC, VALS(icmpv6_option_cert_type_vals), 0x0,
5063             NULL, HFILL }},
5064         /* RFC3971:  SEcure Neighbor Discovery (SEND) */
5065         { &hf_icmpv6_send_identifier,
5066           { "Identifier", "icmpv6.send.identifier", FT_UINT16, BASE_DEC, NULL, 0x0,
5067             "An identifier to aid in matching with Request and Reply", HFILL }},
5068         { &hf_icmpv6_send_all_components,
5069           { "All Components", "icmpv6.send.all_components", FT_UINT16, BASE_DEC, NULL, 0x0,
5070             "Inform the receiver of the number of certificates in the entire path", HFILL }},
5071         { &hf_icmpv6_send_component,
5072           { "Component", "icmpv6.send.component", FT_UINT16, BASE_DEC, NULL, 0x0,
5073             "If the field is set to 65,535 if the sender seeks to retrieve all certificates", HFILL }},
5074 
5075         { &hf_icmpv6_x509if_Name,
5076           { "Name", "icmpv6.x509_Name", FT_UINT32, BASE_DEC, VALS(x509if_Name_vals), 0x0,
5077             NULL, HFILL }},
5078         { &hf_icmpv6_x509af_Certificate,
5079           { "Certificate", "icmpv6.x509_Certificate", FT_NONE, BASE_NONE, NULL, 0x0,
5080             NULL, HFILL }},
5081         { &hf_icmpv6_opt_redirected_packet,
5082           { "Redirected Packet", "icmpv6.opt.redirected_packet", FT_NONE, BASE_NONE, NULL, 0x0,
5083             NULL, HFILL }},
5084         { &hf_icmpv6_opt_mtu,
5085           { "MTU", "icmpv6.opt.mtu", FT_UINT32, BASE_DEC, NULL, 0x0,
5086             "The recommended MTU for the link", HFILL }},
5087         { &hf_icmpv6_opt_nbma_shortcut_limit,
5088           { "Shortcut Limit", "icmpv6.opt.nbma.shortcut_limit", FT_UINT8, BASE_DEC, NULL, 0x0,
5089             "Hop limit for shortcut attempt", HFILL }},
5090         { &hf_icmpv6_opt_advertisement_interval,
5091           { "Advertisement Interval", "icmpv6.opt.advertisement_interval", FT_UINT32, BASE_DEC, NULL, 0x0,
5092             "The maximum time (in milliseconds) between successive unsolicited Router Advertisement messages sent by this router on this network interface", HFILL }},
5093         { &hf_icmpv6_opt_home_agent_preference,
5094           { "Home Agent Preference", "icmpv6.opt.home_agent_preference", FT_UINT16, BASE_DEC, NULL, 0x0,
5095             "The preference for the home agent sending this Router Advertisement", HFILL }},
5096         { &hf_icmpv6_opt_home_agent_lifetime,
5097           { "Home Agent Preference", "icmpv6.opt.home_agent_lifetime", FT_UINT16, BASE_DEC, NULL, 0x0,
5098             "The lifetime associated with the home agent in units of seconds.", HFILL }},
5099         { &hf_icmpv6_opt_ipv6_address,
5100           { "IPv6 Address", "icmpv6.opt.ipv6_address", FT_IPv6, BASE_NONE, NULL, 0x0,
5101             "IPv6 addresses of the interface", HFILL }},
5102         { &hf_icmpv6_opt_rdnss_lifetime,
5103           { "Lifetime", "icmpv6.opt.rdnss.lifetime", FT_UINT32, BASE_DEC|BASE_SPECIAL_VALS, VALS(rdnss_infinity), 0x0,
5104             NULL, HFILL }},
5105         { &hf_icmpv6_opt_rdnss,
5106           { "Recursive DNS Servers", "icmpv6.opt.rdnss", FT_IPv6, BASE_NONE, NULL, 0x0,
5107             NULL, HFILL }},
5108         { &hf_icmpv6_opt_efo,
5109           { "Flags Expansion Option", "icmpv6.opt.efo", FT_UINT16, BASE_HEX, NULL, 0x0,
5110             NULL, HFILL }},
5111         { &hf_icmpv6_opt_efo_m,
5112           { "Managed address configuration", "icmpv6.opt.efo.m", FT_BOOLEAN, 16, TFS(&tfs_set_notset), FLAGS_EO_M,
5113             "When set, it indicates that addresses are available via DHCPv6", HFILL }},
5114         { &hf_icmpv6_opt_efo_o,
5115           { "Other configuration", "icmpv6.opt.efo.o", FT_BOOLEAN, 16, TFS(&tfs_set_notset), FLAGS_EO_O,
5116             "When set, it indicates that other configuration information is available via DHCPv6", HFILL }},
5117         { &hf_icmpv6_opt_efo_h,
5118           { "Home Agent", "icmpv6.opt.efo.h", FT_BOOLEAN, 16, TFS(&tfs_set_notset), FLAGS_EO_H,
5119             "When set, it indicate that the router sending this Router Advertisement is also functioning as a Mobile IPv6 home agent on this link", HFILL }},
5120         { &hf_icmpv6_opt_efo_prf,
5121           { "Prf (Default Router Preference)", "icmpv6.opt.efo.prf", FT_UINT16, BASE_DEC, VALS(nd_flag_router_pref), FLAGS_EO_PRF,
5122             "Indicates whether to prefer this router over other default routers", HFILL }},
5123         { &hf_icmpv6_opt_efo_p,
5124           { "Proxy", "icmpv6.opt.efo.p", FT_BOOLEAN, 16, TFS(&tfs_set_notset), FLAGS_EO_P,
5125            NULL, HFILL }},
5126         { &hf_icmpv6_opt_efo_rsv,
5127           { "Reserved", "icmpv6.opt.efo.rsv", FT_UINT16, BASE_DEC, NULL, FLAGS_EO_RSV,
5128             "Must be Zero", HFILL }},
5129         { &hf_icmpv6_opt_hkr_pad_length,
5130           { "Pad Length", "icmpv6.opt.hkr.pad_length", FT_UINT8, BASE_DEC, NULL, 0x0,
5131             "The number of padding octets beyond the end of the Handover Key", HFILL }},
5132         { &hf_icmpv6_opt_hkr_at,
5133           { "AT", "icmpv6.opt.hkr.at", FT_UINT8, BASE_DEC, NULL, 0xF0,
5134             "The algorithm type field describing the algorithm used by FMIPv6 to calculate the authenticator", HFILL }},
5135         { &hf_icmpv6_opt_hkr_reserved,
5136           { "Reserved", "icmpv6.opt.hkr.reserved", FT_UINT8, BASE_DEC, NULL, 0x0F,
5137             "Reserved (Must be Zero)", HFILL }},
5138         { &hf_icmpv6_opt_hkr_encryption_public_key,
5139           { "Handover Key Encryption Public Key", "icmpv6.opt.hkr.encryption_public_key", FT_BYTES, BASE_NONE, NULL, 0x0,
5140             NULL, HFILL }},
5141         { &hf_icmpv6_opt_hkr_padding,
5142           { "Padding", "icmpv6.opt.hkr.padding", FT_BYTES, BASE_NONE, NULL, 0x0,
5143             "A variable-length field making the option length a multiple of 8", HFILL }},
5144         { &hf_icmpv6_opt_hkr_lifetime,
5145           { "Padding", "icmpv6.opt.hkr.lifetime", FT_UINT16, BASE_DEC, NULL, 0x0,
5146             "Lifetime of the handover key (in seconds)", HFILL }},
5147         { &hf_icmpv6_opt_hkr_encrypted_handover_key,
5148           { "Encrypted Handover Key", "icmpv6.opt.hkr.encrypted_handover_key", FT_BYTES, BASE_NONE, NULL, 0x0,
5149             "The shared handover key, encrypted with the MN's handover key encryption public key", HFILL }},
5150         { &hf_icmpv6_opt_hai_option_code,
5151           { "Option-Code", "icmpv6.opt.hai.option_code", FT_UINT8, BASE_DEC, VALS(nd_opt_hai_option_code_val), 0x0,
5152             NULL, HFILL }},
5153         { &hf_icmpv6_opt_hai_length,
5154           { "HAI-Length", "icmpv6.opt.hai.length", FT_UINT8, BASE_DEC, NULL, 0x0,
5155             "The size of the HAI-Value field in octets", HFILL }},
5156         { &hf_icmpv6_opt_hai_value,
5157           { "HAI-Value", "icmpv6.opt.hai.value", FT_BYTES, BASE_NONE, NULL, 0x0,
5158             "The value specified by the Option-Code", HFILL }},
5159         { &hf_icmpv6_opt_mn_option_code,
5160           { "Option-Code", "icmpv6.opt.mn.option_code", FT_UINT8, BASE_DEC, VALS(nd_opt_mn_option_code_val), 0x0,
5161             NULL, HFILL }},
5162         { &hf_icmpv6_opt_mn_length,
5163           { "MN-Length", "icmpv6.opt.mn.length", FT_UINT8, BASE_DEC, NULL, 0x0,
5164             "The size of the MN-Value field in octets", HFILL }},
5165         { &hf_icmpv6_opt_mn_value,
5166           { "MN-Value", "icmpv6.opt.mn.value", FT_BYTES, BASE_NONE, NULL, 0x0,
5167             "The value specified by the Option-Code", HFILL }},
5168         { &hf_icmpv6_opt_dnssl_lifetime,
5169           { "Lifetime", "icmpv6.opt.dnssl.lifetime", FT_UINT32, BASE_DEC|BASE_SPECIAL_VALS, VALS(dnssl_infinity), 0x0,
5170             NULL, HFILL }},
5171         { &hf_icmpv6_opt_dnssl,
5172           { "Domain Names", "icmpv6.opt.dnssl", FT_STRING, BASE_NONE, NULL, 0x0,
5173             NULL, HFILL }},
5174         { &hf_icmpv6_opt_aro_status,
5175           { "Status", "icmpv6.opt.aro.status", FT_UINT8, BASE_DEC, VALS(nd_opt_6lowpannd_status_val), 0x00,
5176             "Indicates the status of a registration in the NA response", HFILL }},
5177         { &hf_icmpv6_opt_aro_registration_lifetime,
5178           { "Registration  Lifetime", "icmpv6.opt.aro.registration_lifetime", FT_UINT16, BASE_DEC, NULL, 0x00,
5179             "The amount of time (in a unit of 60 seconds) that the router should retain the Neighbor Cache entry", HFILL }},
5180         { &hf_icmpv6_opt_aro_eui64,
5181           { "EUI-64", "icmpv6.opt.aro.eui64", FT_EUI64, BASE_NONE, NULL, 0x00,
5182             "This field is used to uniquely identify the interface of the registered address", HFILL }},
5183         { &hf_icmpv6_opt_6co_context_length,
5184           { "Context Length", "icmpv6.opt.6co.context_length", FT_UINT8, BASE_DEC, NULL, 0x00,
5185             "The number of leading bits in the Context Prefix field that are valid", HFILL }},
5186         { &hf_icmpv6_opt_6co_flag,
5187           { "Flag", "icmpv6.opt.6co.flag", FT_UINT8, BASE_HEX, NULL, 0x00,
5188             NULL, HFILL }},
5189         { &hf_icmpv6_opt_6co_flag_c,
5190           { "Compression Flag", "icmpv6.opt.6co.flag.c", FT_BOOLEAN, 8, TFS(&tfs_set_notset), ND_OPT_6CO_FLAG_C,
5191             "This flag indicates if the context is valid for use in compression", HFILL }},
5192         { &hf_icmpv6_opt_6co_flag_cid,
5193           { "CID", "icmpv6.opt.6co.flag.cid", FT_UINT8, BASE_DEC, NULL, ND_OPT_6CO_FLAG_CID,
5194             "Context Identifier for this prefix information", HFILL }},
5195         { &hf_icmpv6_opt_6co_flag_reserved,
5196           { "Reserved", "icmpv6.opt.6co.flag.reserved", FT_UINT8, BASE_DEC, NULL, ND_OPT_6CO_FLAG_RESERVED,
5197             "Must be zero", HFILL }},
5198         { &hf_icmpv6_opt_6co_valid_lifetime,
5199           { "Lifetime", "icmpv6.opt.6co.valid_lifetime", FT_UINT16, BASE_DEC, NULL, 0x00,
5200             "The length of time in a unit of 60 seconds that the context is valid for the purpose of header compression or decompression", HFILL }},
5201         { &hf_icmpv6_opt_6co_context_prefix,
5202           { "Context Prefix", "icmpv6.opt.6co.context_prefix", FT_IPv6, BASE_NONE, NULL, 0x00,
5203             "The IPv6 prefix or address corresponding to the Context ID (CID) field", HFILL }},
5204         { &hf_icmpv6_opt_abro_version_low,
5205           { "Version Low", "icmpv6.opt.abro.version_low", FT_UINT16, BASE_DEC, NULL, 0x00,
5206             "The version number low (the least significant 16 bits) corresponding to this set of information contained in the RA message", HFILL }},
5207         { &hf_icmpv6_opt_abro_version_high,
5208           { "Version", "icmpv6.opt.abro.version_high", FT_UINT16, BASE_DEC, NULL, 0x00,
5209             "The version number high (most significant 16 bits) corresponding to this set of information contained in the RA message", HFILL }},
5210         { &hf_icmpv6_opt_abro_valid_lifetime,
5211           { "Valid Lifetime", "icmpv6.opt.abro.valid_lifetime", FT_UINT16, BASE_DEC, NULL, 0x00,
5212             "The length of time in a unit of 60 seconds (relative to the time the packet is received) that this set of border router information is valid.", HFILL }},
5213         { &hf_icmpv6_opt_abro_6lbr_address,
5214           { "6LBR Address", "icmpv6.opt.abro.6lbr_address", FT_IPv6, BASE_NONE, NULL, 0x00,
5215             "IPv6 address of the 6LBR that is the origin of the included version number", HFILL }},
5216         { &hf_icmpv6_opt_6cio_unassigned1,
5217           { "Unassigned", "icmpv6.opt.6cio.unassigned1", FT_UINT16, BASE_HEX, NULL, ND_OPT_6CIO_FLAG_UNASSIGNED,
5218             NULL, HFILL }},
5219         { &hf_icmpv6_opt_6cio_flag_g,
5220           { "G", "icmpv6.opt.6cio.flag_g", FT_UINT16, BASE_HEX, NULL, ND_OPT_6CIO_FLAG_G,
5221             NULL, HFILL }},
5222         { &hf_icmpv6_opt_6cio_unassigned2,
5223           { "Unassigned", "icmpv6.opt.6cio.unassigned2", FT_UINT32, BASE_HEX, NULL, 0x00,
5224             NULL, HFILL }},
5225 
5226         { &hf_icmpv6_opt_captive_portal,
5227            { "Captive Portal", "icmpv6.opt.captive_portal", FT_STRING, BASE_NONE, NULL, 0x00,
5228              "The contact URI for the captive portal that the user should connect to", HFILL }},
5229 
5230         { &hf_icmpv6_opt_pref64_scaled_lifetime,
5231           { "Scaled Lifetime", "icmpv6.opt.pref64.scaled_lifetime", FT_UINT16, BASE_DEC, NULL, ND_OPT_PREF64_SL,
5232             "The maximum time in units of 8 seconds over which this NAT64 prefix MAY be used", HFILL }},
5233         { &hf_icmpv6_opt_pref64_plc,
5234           { "PLC (Prefix Length Code)", "icmpv6.opt.pref64.plc", FT_UINT16, BASE_HEX, VALS(pref64_plc_str), ND_OPT_PREF64_PLC,
5235             "This field encodes the NAT64 Prefix Length", HFILL }},
5236         { &hf_icmpv6_opt_pref64_prefix,
5237           { "Prefix", "icmpv6.opt.pref64.prefix", FT_IPv6, BASE_NONE, NULL, 0x00,
5238             "NAT64 Prefix", HFILL }},
5239 
5240         /* RFC2710:  Multicast Listener Discovery for IPv6 */
5241         { &hf_icmpv6_mld_mrd,
5242           { "Maximum Response Delay [ms]", "icmpv6.mld.maximum_response_delay", FT_UINT16, BASE_DEC, NULL, 0x0,
5243             "Specifies the maximum allowed delay before sending a responding Report, in units of milliseconds", HFILL }},
5244         { &hf_icmpv6_mld_multicast_address,
5245           { "Multicast Address", "icmpv6.mld.multicast_address", FT_IPv6, BASE_NONE, NULL, 0x0,
5246             "Specific IPv6 multicast address", HFILL }},
5247         /* RFC 2894: Router Renumbering for IPv6 */
5248         { &hf_icmpv6_rr_sequencenumber,
5249            { "Sequence Number", "icmpv6.rr.sequence_number", FT_UINT32, BASE_DEC, NULL, 0x0,
5250              "The sequence number MUST be non-decreasing between Sequence Number Resets", HFILL }},
5251         { &hf_icmpv6_rr_segmentnumber,
5252            { "Segment Number", "icmpv6.rr.segment_number", FT_UINT8, BASE_DEC, NULL, 0x0,
5253              "Enumerates different valid RR messages having the same Sequence Number", HFILL }},
5254         { &hf_icmpv6_rr_flag,
5255            { "Flags", "icmpv6.rr.flag", FT_UINT8, BASE_HEX, NULL, 0x0,
5256              "Five are defined and three bits are reserved", HFILL }},
5257         { &hf_icmpv6_rr_flag_t,
5258            { "Test Command", "icmpv6.rr.flag.t", FT_BOOLEAN, 8, TFS(&tfs_set_notset), RR_FLAG_T,
5259              "Indicates a Test message: processing is to be simulated and no configuration changes are to be made", HFILL }},
5260         { &hf_icmpv6_rr_flag_r,
5261            { "Result requested", "icmpv6.rr.flag.r", FT_BOOLEAN, 8, TFS(&tfs_set_notset), RR_FLAG_R,
5262              "Indicates that the router send a Result message upon completion of processing the Command message", HFILL }},
5263         { &hf_icmpv6_rr_flag_a,
5264            { "All Interfaces", "icmpv6.rr.flag.a", FT_BOOLEAN, 8, TFS(&tfs_set_notset), RR_FLAG_A,
5265              "Indicates that the Command be applied to all interfaces regardless of administrative shutdown status", HFILL }},
5266         { &hf_icmpv6_rr_flag_s,
5267            { "Site-specific", "icmpv6.rr.flag.s", FT_BOOLEAN, 8, TFS(&tfs_set_notset), RR_FLAG_S,
5268              "Indicates that the Command be applied only to interfaces which belong to the same site as the interface to which the Command is addressed", HFILL }},
5269         { &hf_icmpv6_rr_flag_p,
5270            { "Processed previously", "icmpv6.rr.flag.p", FT_BOOLEAN, 8, TFS(&tfs_set_notset), RR_FLAG_P,
5271              "Indicates that the Command message was previously processed (and is not a Test) and the responding router is not processing it again", HFILL }},
5272         { &hf_icmpv6_rr_flag_rsv,
5273            { "Reserved", "icmpv6.rr.flag.rsv", FT_UINT8, BASE_DEC, NULL, RR_FLAG_RSV,
5274              "Must be Zero", HFILL }},
5275         { &hf_icmpv6_rr_maxdelay,
5276            { "Max Delay", "icmpv6.rr.maxdelay", FT_UINT16, BASE_DEC, NULL, 0x0,
5277              "Specifying the maximum time (in milliseconds) by which a router MUST delay sending any reply to this Command", HFILL }},
5278 
5279         { &hf_icmpv6_rr_pco_mp_part,
5280            { "Match-Prefix Part", "icmpv6.rr.pco.mp", FT_NONE, BASE_NONE, NULL, 0x0,
5281              NULL, HFILL }},
5282         { &hf_icmpv6_rr_pco_mp_opcode,
5283            { "OpCode", "icmpv6.rr.pco.mp.opcode", FT_UINT8, BASE_DEC, VALS(rr_pco_mp_opcode_val), 0x0,
5284              "Specifying the operation to be performed when the associated MatchPrefix matches an interface's prefix or address", HFILL }},
5285         { &hf_icmpv6_rr_pco_mp_oplength,
5286            { "OpLength", "icmpv6.rr.pco.mp.oplength", FT_UINT8, BASE_DEC, NULL, 0x0,
5287              "The total length of this Prefix Control Operation (in units of 8 octets)", HFILL }},
5288         { &hf_icmpv6_rr_pco_mp_ordinal,
5289            { "Ordinal", "icmpv6.rr.pco.mp.ordinal", FT_UINT8, BASE_HEX, NULL, 0x0,
5290              "The value is otherwise unconstrained", HFILL }},
5291         { &hf_icmpv6_rr_pco_mp_matchlen,
5292            { "MatchLen", "icmpv6.rr.pco.mp.matchlen", FT_UINT8, BASE_DEC, NULL, 0x0,
5293              "Between 0 and 128 inclusive specifying the number of initial bits of MatchPrefix which are significant in matching", HFILL }},
5294         { &hf_icmpv6_rr_pco_mp_minlen,
5295            { "MinLen", "icmpv6.rr.pco.mp.minlen", FT_UINT8, BASE_DEC, NULL, 0x0,
5296              "Specifying the minimum length which any configured prefix must have in order to be eligible for testing against the MatchPrefix", HFILL }},
5297         { &hf_icmpv6_rr_pco_mp_maxlen,
5298            { "MaxLen", "icmpv6.rr.pco.mp.maxlen", FT_UINT8, BASE_DEC, NULL, 0x0,
5299              "Specifying the maximum length which any configured prefix must have in order to be eligible for testing against the MatchPrefix", HFILL }},
5300         { &hf_icmpv6_rr_pco_mp_matchprefix,
5301            { "MatchPrefix", "icmpv6.rr.pco.mp.matchprefix", FT_IPv6, BASE_NONE, NULL, 0x0,
5302              "The 128-bit prefix to be compared with each interface's prefix or address", HFILL }},
5303         { &hf_icmpv6_rr_pco_up_part,
5304            { "Use-Prefix Part", "icmpv6.rr.pco.up", FT_NONE, BASE_NONE, NULL, 0x0,
5305              NULL, HFILL }},
5306         { &hf_icmpv6_rr_pco_up_uselen,
5307            { "UseLen", "icmpv6.rr.pco.up.uselen", FT_UINT8, BASE_DEC, NULL, 0x0,
5308              "specifying the number of initial bits of UsePrefix to use in creating a new prefix for an interface", HFILL }},
5309         { &hf_icmpv6_rr_pco_up_keeplen,
5310            { "KeepLen", "icmpv6.rr.pco.up.keeplen", FT_UINT8, BASE_DEC, NULL, 0x0,
5311              "Specifying the number of bits of the prefix or address which matched the associated Match-Prefix which should be retained in the new prefix", HFILL }},
5312         { &hf_icmpv6_rr_pco_up_flagmask,
5313            { "FlagMask", "icmpv6.rr.pco.up.flagmask", FT_UINT8, BASE_HEX, NULL, 0x0,
5314              "A 1 bit in any position means that the corresponding flag bit in a Router Advertisement (RA) Prefix Information Option for the New Prefix should be set from the RAFlags field in this Use-Prefix Part", HFILL }},
5315 
5316         { &hf_icmpv6_rr_pco_up_flagmask_l,
5317           { "On-link flag(L)", "icmpv6.rr.pco.up.flagmask.l", FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x80,
5318             "When set, indicates the On-link (L) flag bit in a Router Advertisement (RA) Prefix Information Option for the New Prefix should be set from the RAFlags field in this Use-Prefix Part", HFILL }},
5319         { &hf_icmpv6_rr_pco_up_flagmask_a,
5320           { "Autonomous address-configuration flag(A)", "icmpv6.rr.pco.up.flagmask.a", FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x40,
5321             "When set, indicates the Autonomous address-configuration (A) flag bit in a Router Advertisement (RA) Prefix Information Option for the New Prefix should be set from the RAFlags field in this Use-Prefix Part", HFILL }},
5322         { &hf_icmpv6_rr_pco_up_flagmask_reserved,
5323           { "Reserved", "icmpv6.rr.pco.up.flagmask.reserved", FT_UINT8, BASE_DEC, NULL, 0x3f,
5324             NULL, HFILL }},
5325         { &hf_icmpv6_rr_pco_up_raflags,
5326            { "RAFlags", "icmpv6.rr.pco.up.raflags", FT_UINT8, BASE_HEX, NULL, 0x0,
5327              "Under control of the FlagMask field, may be used to initialize the flags in Router Advertisement Prefix Information Options  which advertise the New Prefix", HFILL }},
5328         { &hf_icmpv6_rr_pco_up_raflags_l,
5329           { "On-link flag(L)", "icmpv6.rr.pco.up.flagmask.l", FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x80,
5330             "When set, indicates that this prefix can be used for on-link determination", HFILL }},
5331         { &hf_icmpv6_rr_pco_up_raflags_a,
5332           { "Autonomous address-configuration flag(A)", "icmpv6.rr.pco.up.flagmask.a", FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x40,
5333             "When set indicates that this prefix can be used for stateless address configuration", HFILL }},
5334         { &hf_icmpv6_rr_pco_up_raflags_reserved,
5335           { "Reserved", "icmpv6.rr.pco.up.flagmask.reserved", FT_UINT8, BASE_DEC, NULL, 0x3f,
5336             NULL, HFILL }},
5337         { &hf_icmpv6_rr_pco_up_validlifetime,
5338            { "Valid Lifetime", "icmpv6.rr.pco.up.validlifetime", FT_UINT32, BASE_DEC|BASE_SPECIAL_VALS, VALS(unique_infinity), 0x0,
5339              "The number of seconds for which the New Prefix will be valid", HFILL }},
5340         { &hf_icmpv6_rr_pco_up_preferredlifetime,
5341            { "Preferred Lifetime", "icmpv6.rr.pco.up.preferredlifetime", FT_UINT32, BASE_DEC|BASE_SPECIAL_VALS, VALS(unique_infinity), 0x0,
5342              "The number of seconds for which the New Prefix will be preferred", HFILL }},
5343         { &hf_icmpv6_rr_pco_up_flag,
5344            { "Flags", "icmpv6.rr.pco.up.flag", FT_UINT32, BASE_HEX, NULL, 0x0,
5345              NULL, HFILL }},
5346         { &hf_icmpv6_rr_pco_up_flag_v,
5347           { "Decrement valid lifetime", "icmpv6.rr.pco.up.flag.v", FT_BOOLEAN, 32, TFS(&tfs_set_notset), 0x80000000,
5348             "When set, indicating that the valid lifetime of the New Prefix MUST be effectively decremented in real time", HFILL }},
5349         { &hf_icmpv6_rr_pco_up_flag_p,
5350           { "Decrement preferred lifetime", "icmpv6.rr.pco.up.flag.p", FT_BOOLEAN, 32, TFS(&tfs_set_notset), 0x40000000,
5351             "When set, indicating that the preferred lifetime of the New Prefix MUST be effectively decremented in real time", HFILL }},
5352         { &hf_icmpv6_rr_pco_up_flag_reserved,
5353           { "Reserved", "icmpv6.rr.pco.up.flag.reserved", FT_UINT32, BASE_DEC, NULL, 0x3FFFFFFF,
5354             NULL, HFILL }},
5355         { &hf_icmpv6_rr_pco_up_useprefix,
5356            { "UsePrefix", "icmpv6.rr.pco.up.useprefix", FT_IPv6, BASE_NONE, NULL, 0x0,
5357              "The 128-bit Use-prefix which either becomes or is used in forming (if KeepLen is nonzero) the New Prefix", HFILL }},
5358         { &hf_icmpv6_rr_rm,
5359            { "Result Message", "icmpv6.rr.rm", FT_NONE, BASE_NONE, NULL, 0x0,
5360              NULL, HFILL }},
5361         { &hf_icmpv6_rr_rm_flag,
5362            { "Flags", "icmpv6.rr.rm.flag", FT_UINT16, BASE_HEX, NULL, 0x0,
5363              NULL, HFILL }},
5364         { &hf_icmpv6_rr_rm_flag_b,
5365           { "Bounds", "icmpv6.rr.rm.flag.b", FT_BOOLEAN, 16, TFS(&tfs_set_notset), 0x0002,
5366             "When set, indicates that one or more fields in the associated PCO were out of bounds", HFILL }},
5367         { &hf_icmpv6_rr_rm_flag_f,
5368           { "Forbidden", "icmpv6.rr.rm.flag.f", FT_BOOLEAN, 16, TFS(&tfs_set_notset), 0x0001,
5369             "When set, indicates that one or more Use-Prefix parts from the associated PCO were not honored by the router because of attempted formation of a forbidden prefix format, such as a multicast or loopback address", HFILL }},
5370         { &hf_icmpv6_rr_rm_flag_reserved,
5371           { "Reserved", "icmpv6.rr.rm.flag.reserved", FT_UINT16, BASE_DEC, NULL, 0xFFFC,
5372             "Must be Zero", HFILL }},
5373         { &hf_icmpv6_rr_rm_ordinal,
5374            { "Ordinal", "icmpv6.rr.rm.ordinal", FT_UINT8, BASE_HEX, NULL, 0x0,
5375              "The value is otherwise unconstrained", HFILL }},
5376         { &hf_icmpv6_rr_rm_matchedlen,
5377            { "MatchedLen", "icmpv6.rr.rm.matchedlen", FT_UINT8, BASE_DEC, NULL, 0x0,
5378              "The length of the Matched Prefix", HFILL }},
5379         { &hf_icmpv6_rr_rm_interfaceindex,
5380            { "InterfaceIndex", "icmpv6.rr.rm.interfaceindex", FT_UINT32, BASE_DEC, NULL, 0x0,
5381              "The router's numeric designation of the interface on which the MatchedPrefix was configured", HFILL }},
5382         { &hf_icmpv6_rr_rm_matchedprefix,
5383            { "MatchedPrefix", "icmpv6.rr.rm.matchedprefix", FT_IPv6, BASE_NONE, NULL, 0x0,
5384              "The 128 Bits MatchedPrefix", HFILL }},
5385 
5386         /* RFC3775/6275: Mobility Support in IPv6 */
5387         { &hf_icmpv6_mip6_identifier,
5388           { "Identifier", "icmpv6.mip6.identifier", FT_UINT16, BASE_DEC_HEX, NULL, 0x0,
5389             "An identifier to aid in matching with Request and Reply", HFILL }},
5390         { &hf_icmpv6_mip6_home_agent_address,
5391           { "Home Agent Address", "icmpv6.mip6.home_agent_address", FT_IPv6, BASE_NONE, NULL, 0x0,
5392             "A list of addresses of home agents on the home link for the mobile node", HFILL }},
5393         { &hf_icmpv6_mip6_flag,
5394           { "Flags", "icmpv6.mip6.flag", FT_UINT16, BASE_HEX, NULL, 0x0,
5395             NULL, HFILL }},
5396         { &hf_icmpv6_mip6_flag_m,
5397           { "Managed address configuration", "icmpv6.mip6.flag.m", FT_BOOLEAN, 16, TFS(&tfs_set_notset), FLAGS_EO_M,
5398             "When set, it indicates that addresses are available via DHCPv6", HFILL }},
5399         { &hf_icmpv6_mip6_flag_o,
5400           { "Other configuration", "icmpv6.mip6.flag.o", FT_BOOLEAN, 16, TFS(&tfs_set_notset), FLAGS_EO_O,
5401             "When set, it indicates that other configuration information is available via DHCPv6", HFILL }},
5402         { &hf_icmpv6_mip6_flag_rsv,
5403           { "Reserved", "icmpv6.mip6.flag.rsv", FT_UINT16, BASE_DEC, NULL, 0x3FFF,
5404             "Must be Zero", HFILL }},
5405 
5406         /* RFC3810: Multicast Listener Discovery Version 2 (MLDv2) for IPv6 */
5407         { &hf_icmpv6_mld_mrc,
5408           { "Maximum Response Code", "icmpv6.mld.maximum_response_code", FT_UINT16, BASE_DEC, NULL, 0x0,
5409             "Specifies the maximum allowed delay before sending a responding Report", HFILL }},
5410        { &hf_icmpv6_mld_flag,
5411           { "Flags", "icmpv6.mld.flag", FT_UINT8, BASE_HEX, NULL, 0x0,
5412             NULL, HFILL }},
5413        { &hf_icmpv6_mld_flag_s,
5414           { "Suppress Router-Side Processing", "icmpv6.mld.flag.s", FT_BOOLEAN, 8, NULL, MLD_FLAG_S,
5415             "Indicates to any receiving multicast routers that they have to suppress the normal timer updates they perform upon hearing a Query", HFILL }},
5416        { &hf_icmpv6_mld_flag_qrv,
5417           { "QRV (Querier's Robustness Variable)", "icmpv6.mld.flag.qrv", FT_UINT8, BASE_DEC, NULL, MLD_FLAG_QRV,
5418             "Contains the RV (Robustness Variable) value used by the Querier", HFILL }},
5419        { &hf_icmpv6_mld_flag_rsv,
5420           { "Reserved", "icmpv6.mld.flag.reserved", FT_UINT8, BASE_DEC, NULL, MLD_FLAG_RSV,
5421             "Must Be Zero", HFILL }},
5422        { &hf_icmpv6_mld_qqi,
5423           { "QQIC (Querier's Query Interval Code)", "icmpv6.mld.qqi", FT_UINT8, BASE_DEC, NULL, 0x0,
5424             "Specifies the QI (Query Interval) used by the Querier", HFILL }},
5425        { &hf_icmpv6_mld_nb_sources,
5426           { "Number of Sources", "icmpv6.mld.nb_sources", FT_UINT16, BASE_DEC, NULL, 0x0,
5427             "Specifies how many source addresses are present in the Query", HFILL }},
5428        { &hf_icmpv6_mld_source_address,
5429           { "Source Address", "icmpv6.mld.source_address", FT_IPv6, BASE_NONE, NULL, 0x0,
5430             "The Source Address fields are a vector of unicast addresses", HFILL }},
5431         { &hf_icmpv6_mldr_nb_mcast_records,
5432           { "Number of Multicast Address Records", "icmpv6.mldr.nb_mcast_records", FT_UINT16, BASE_DEC, NULL, 0x0,
5433             "Specifies how many Multicast Address Records are present in this Report", HFILL }},
5434         { &hf_icmpv6_mldr_mar,
5435           { "Multicast Address Record", "icmpv6.mldr.mar", FT_NONE, BASE_NONE, NULL, 0x0,
5436             "Each Multicast Address Record is a block of fields that contain information on the sender listening to a single multicast address on the interface from which the Report is sent", HFILL }},
5437         { &hf_icmpv6_mldr_mar_record_type,
5438           { "Record Type", "icmpv6.mldr.mar.record_type", FT_UINT8, BASE_DEC, VALS(mldr_record_type_val), 0x0,
5439             "It specifies the type of the Multicast Address Record", HFILL }},
5440         { &hf_icmpv6_mldr_mar_aux_data_len,
5441           { "Aux Data Len", "icmpv6.mldr.mar.aux_data_len", FT_UINT8, BASE_DEC, NULL, 0x0,
5442             "The Aux Data Len field contains the length (in units of 32-bit words) of the Auxiliary Data Field in this Multicast Address Record", HFILL }},
5443         { &hf_icmpv6_mldr_mar_nb_sources,
5444           { "Number of Sources", "icmpv6.mldr.mar.nb_sources", FT_UINT16, BASE_DEC, NULL, 0x0,
5445             "The Number of Sources field specifies how many source addresses are present in this Multicast Address Record", HFILL }},
5446         { &hf_icmpv6_mldr_mar_multicast_address,
5447           { "Multicast Address", "icmpv6.mldr.mar.multicast_address", FT_IPv6, BASE_NONE, NULL, 0x0,
5448             "The Multicast Address field contains the multicast address to which this Multicast Address Record pertains", HFILL }},
5449         { &hf_icmpv6_mldr_mar_source_address,
5450           { "Source Address", "icmpv6.mldr.mar.source_address", FT_IPv6, BASE_NONE, NULL, 0x0,
5451             "The Source Address fields are a vector of unicast addresses", HFILL }},
5452         { &hf_icmpv6_mldr_mar_auxiliary_data,
5453           { "Auxiliary Data", "icmpv6.mldr.mar.auxiliary_data", FT_BYTES, BASE_NONE, NULL, 0x0,
5454             "Contains additional information that pertain to this Multicast Address Record", HFILL }},
5455         /* RFC 4068/5268/5568: Fast Handovers for Mobile IPv6 ( Mobile IPv6 Fast Handovers ) */
5456         { &hf_icmpv6_fmip6_subtype,
5457            { "Subtype", "icmpv6.fmip6.subtype", FT_UINT8, BASE_DEC, VALS(fmip6_subtype_val), 0x0,
5458              "Designates the Subtype of information", HFILL }},
5459         { &hf_icmpv6_fmip6_hi_flag,
5460           { "Flag", "icmpv6.fmip6.hi.flag", FT_UINT8, BASE_HEX, NULL, 0x00,
5461             NULL, HFILL }},
5462         { &hf_icmpv6_fmip6_hi_flag_s,
5463           { "Assigned address configuration", "icmpv6.fmip6.hi.flag.s", FT_BOOLEAN, 8, TFS(&tfs_set_notset), FMIP6_HI_FLAG_S,
5464             "When set, this message requests a new CoA to be returned by the destination", HFILL }},
5465         { &hf_icmpv6_fmip6_hi_flag_u,
5466           { "Buffer", "icmpv6.fmip6.hi.flag.a", FT_BOOLEAN, 8, TFS(&tfs_set_notset), FMIP6_HI_FLAG_U,
5467             "When set, the destination SHOULD buffer any packets toward the node indicated in the options of this message", HFILL }},
5468         { &hf_icmpv6_fmip6_hi_flag_reserved,
5469           { "Reserved", "icmpv6.fmip6.hi.flag.reserved", FT_UINT8, BASE_DEC, NULL, FMIP6_HI_FLAG_RSV,
5470             NULL, HFILL }},
5471         { &hf_icmpv6_fmip6_identifier,
5472           { "Identifier", "icmpv6.fmip6.identifier", FT_UINT16, BASE_DEC_HEX, NULL, 0x0,
5473             "An identifier to aid in matching with Request and Reply", HFILL }},
5474 
5475         /* RFC 4286: Multicast Router Discovery */
5476         { &hf_icmpv6_mcast_ra_query_interval,
5477           { "Query Interval", "icmpv6.mcast_ra.query_interval", FT_UINT16, BASE_DEC, NULL, 0x0,
5478             "The Query Interval value (in seconds) in use by MLD on the interface.", HFILL }},
5479         { &hf_icmpv6_mcast_ra_robustness_variable,
5480           { "Robustness Variable", "icmpv6.mcast_ra.robustness_variable", FT_UINT16, BASE_DEC, NULL, 0x0,
5481             "The Robustness Variable in use by MLD on the advertising interface", HFILL }},
5482 
5483         /* RFC 4620: IPv6 Node Information Queries */
5484         { &hf_icmpv6_ni_qtype,
5485            { "Qtype", "icmpv6.ni.qtype", FT_UINT16, BASE_DEC, VALS(ni_qtype_val), 0x0,
5486              "Designates the type of information", HFILL }},
5487         { &hf_icmpv6_ni_flag,
5488            { "Flags", "icmpv6.ni.flag", FT_UINT16, BASE_HEX, NULL, 0x0,
5489              "Qtype-specific flags that may be defined for certain Query types and their Replies", HFILL }},
5490         { &hf_icmpv6_ni_flag_g,
5491            { "Global-scope addresses", "icmpv6.ni.flag.g", FT_BOOLEAN, 16, TFS(&tfs_set_notset), NI_FLAG_G,
5492              "Global-scope addresses are requested", HFILL }},
5493         { &hf_icmpv6_ni_flag_s,
5494            { "Site-local addresses", "icmpv6.ni.flag.s", FT_BOOLEAN, 16, TFS(&tfs_set_notset), NI_FLAG_S,
5495              "Site-local addresses are requested", HFILL }},
5496         { &hf_icmpv6_ni_flag_l,
5497            { "Link-local addresses", "icmpv6.ni.flag.l", FT_BOOLEAN, 16, TFS(&tfs_set_notset), NI_FLAG_L,
5498              "Link-local addresses are requested", HFILL }},
5499         { &hf_icmpv6_ni_flag_c,
5500            { "Compression", "icmpv6.ni.flag.c", FT_BOOLEAN, 16, TFS(&tfs_set_notset), NI_FLAG_C,
5501              "IPv4-compatible (now deprecated) and IPv4-mapped addresses are requested", HFILL }},
5502         { &hf_icmpv6_ni_flag_a,
5503            { "Unicast Addresses", "icmpv6.ni.flag.a", FT_BOOLEAN, 16, TFS(&tfs_ni_flag_a), NI_FLAG_A,
5504              "Responder's unicast addresses", HFILL }},
5505         { &hf_icmpv6_ni_flag_t,
5506            { "Truncated", "icmpv6.ni.flag.t", FT_BOOLEAN, 16, TFS(&tfs_set_notset), NI_FLAG_T,
5507              "Defined in a Reply only, indicates that the set of addresses is incomplete for space reasons", HFILL }},
5508         { &hf_icmpv6_ni_flag_rsv,
5509            { "Reserved", "icmpv6.ni.flag.rsv", FT_UINT16, BASE_HEX, NULL, NI_FLAG_RSV,
5510              "Must be Zero", HFILL }},
5511         { &hf_icmpv6_ni_nonce,
5512            { "Nonce", "icmpv6.ni.nonce", FT_UINT64, BASE_HEX, NULL, 0x0,
5513              "An opaque 64-bit field", HFILL }},
5514         { &hf_icmpv6_ni_query_subject_ipv6,
5515            { "IPv6 subject address", "icmpv6.ni.query.subject_ipv6", FT_IPv6, BASE_NONE, NULL, 0x0,
5516              NULL, HFILL }},
5517         { &hf_icmpv6_ni_query_subject_fqdn,
5518            { "FQDN subject", "icmpv6.ni.query.subject_fqdn", FT_STRING, BASE_NONE, NULL, 0x0,
5519              NULL, HFILL }},
5520         { &hf_icmpv6_ni_query_subject_ipv4,
5521            { "IPv4 subject address", "icmpv6.ni.query.subject_ipv4", FT_IPv4, BASE_NONE, NULL, 0x0,
5522              NULL, HFILL }},
5523         { &hf_icmpv6_ni_reply_node_ttl,
5524            { "TTL", "icmpv6.ni.reply.node_ttl", FT_UINT32, BASE_DEC, NULL, 0x0,
5525              NULL, HFILL }},
5526         { &hf_icmpv6_ni_reply_node_name,
5527            { "Name Node", "icmpv6.ni.reply.node_name", FT_STRING, BASE_NONE, NULL, 0x0,
5528              NULL, HFILL }},
5529         { &hf_icmpv6_ni_reply_node_address,
5530            { "IPv6 Node address", "icmpv6.ni.reply.node_address", FT_IPv6, BASE_NONE, NULL, 0x0,
5531              NULL, HFILL }},
5532         { &hf_icmpv6_ni_reply_ipv4_address,
5533            { "IPv4 Node address", "icmpv6.ni.reply.ipv4_address", FT_IPv4, BASE_NONE, NULL, 0x0,
5534              NULL, HFILL }},
5535 
5536         /* RFC 4884: Extended ICMP */
5537         { &hf_icmpv6_length,
5538           { "Length of original datagram", "icmpv6.length", FT_UINT8, BASE_DEC, NULL, 0x0,
5539             "The length of the original datagram", HFILL }},
5540 
5541         /* RPL: RFC 6550 : Routing over Low-Power and Lossy Networks. */
5542         { &hf_icmpv6_rpl_dis_flag,
5543            { "Flags", "icmpv6.rpl.dis.flags", FT_UINT8, BASE_DEC, NULL, 0x0,
5544              "8-bit unused field reserved for flags", HFILL }},
5545         { &hf_icmpv6_rpl_dio_instance,
5546            { "RPLInstanceID", "icmpv6.rpl.dio.instance", FT_UINT8, BASE_DEC, NULL, 0x0,
5547              "Set by the DODAG root that indicates which RPL Instance the DODAG is part of", HFILL }},
5548         { &hf_icmpv6_rpl_dio_version,
5549            { "Version", "icmpv6.rpl.dio.version", FT_UINT8, BASE_DEC, NULL, 0x0,
5550              "Set by the DODAG root to the DODAGVersionNumber", HFILL }},
5551         { &hf_icmpv6_rpl_dio_rank,
5552            { "Rank", "icmpv6.rpl.dio.rank", FT_UINT16, BASE_DEC, NULL, 0x0,
5553              "Indicating the DODAG rank of the node sending the DIO message", HFILL }},
5554         { &hf_icmpv6_rpl_dio_flag,
5555            { "Flags", "icmpv6.rpl.dio.flag", FT_UINT8, BASE_HEX, NULL, 0x0,
5556              NULL, HFILL }},
5557         { &hf_icmpv6_rpl_dio_flag_g,
5558            { "Grounded (G)", "icmpv6.rpl.dio.flag.g", FT_BOOLEAN, 8, NULL, RPL_DIO_FLAG_G,
5559              "Indicates whether the DODAG advertised can satisfy the application-defined goal", HFILL }},
5560         { &hf_icmpv6_rpl_dio_flag_0,
5561            { "Zero", "icmpv6.rpl.dio.flag.0", FT_BOOLEAN, 8, NULL, RPL_DIO_FLAG_0,
5562              NULL, HFILL }},
5563         { &hf_icmpv6_rpl_dio_flag_mop,
5564            { "Mode of Operation (MOP)", "icmpv6.rpl.dio.flag.mop", FT_UINT8, BASE_HEX, VALS(rpl_dio_map_val), RPL_DIO_FLAG_MOP,
5565              "Identifies the mode of operation of the RPL Instance as administratively provisioned at and distributed by the DODAG Root", HFILL }},
5566         { &hf_icmpv6_rpl_dio_flag_prf,
5567            { "DODAG Preference", "icmpv6.rpl.dio.flag.preference", FT_UINT8, BASE_DEC, NULL, RPL_DIO_FLAG_PRF,
5568              "Defines how preferable the root of this DODAG is compared to other DODAG roots within the instance", HFILL }},
5569         { &hf_icmpv6_rpl_dio_dtsn,
5570            { "Destination Advertisement Trigger Sequence Number (DTSN)", "icmpv6.rpl.dio.dtsn", FT_UINT8, BASE_DEC, NULL, 0x0,
5571              "The DTSN is used as part of the procedure to maintain downward routes.", HFILL }},
5572         { &hf_icmpv6_rpl_dio_dagid,
5573            { "DODAGID", "icmpv6.rpl.dio.dagid", FT_IPv6, BASE_NONE, NULL, 0x0,
5574              "IPv6 address set by a DODAG root which uniquely identifies a DODAG", HFILL }},
5575         { &hf_icmpv6_rpl_dao_instance,
5576            { "RPLInstanceID", "icmpv6.rpl.dao.instance", FT_UINT8, BASE_DEC, NULL, 0x0,
5577              "Indicating the topology instance associated with the DODAG as learned from the DIO", HFILL }},
5578         { &hf_icmpv6_rpl_dao_flag,
5579            { "Flags", "icmpv6.rpl.dao.flag", FT_UINT8, BASE_HEX, NULL, 0x0,
5580              NULL, HFILL }},
5581         { &hf_icmpv6_rpl_dao_flag_k,
5582            { "DAO-ACK Request (K)", "icmpv6.rpl.dao.flag.k", FT_BOOLEAN, 8, NULL, RPL_DAO_FLAG_K,
5583              "Indicates that the recipient is expected to send a DAO-ACK back", HFILL }},
5584         { &hf_icmpv6_rpl_dao_flag_d,
5585            { "DODAGID Present (D)", "icmpv6.rpl.dao.flag.d", FT_BOOLEAN, 8, NULL, RPL_DAO_FLAG_D,
5586              "Indicates that the DODAGID field is present", HFILL }},
5587         { &hf_icmpv6_rpl_dao_flag_rsv,
5588            { "Reserved", "icmpv6.rpl.dao.flag.rsv", FT_UINT8, BASE_DEC, NULL, RPL_DAO_FLAG_RESERVED,
5589              "Must be zero", HFILL }},
5590         { &hf_icmpv6_rpl_dao_sequence,
5591            { "DAO Sequence", "icmpv6.rpl.dao.sequence", FT_UINT8, BASE_DEC, NULL, 0x0,
5592              "Incremented at each unique DAO message from a node and echoed in the DAO-ACK message", HFILL }},
5593         { &hf_icmpv6_rpl_dao_dodagid,
5594            { "DODAGID", "icmpv6.rpl.dao.dodagid", FT_IPv6, BASE_NONE, NULL, 0x0,
5595              "IPv6 address set by a DODAG root which uniquely identifies a DODAG", HFILL }},
5596         { &hf_icmpv6_rpl_daoack_instance,
5597            { "RPLInstanceID", "icmpv6.rpl.daoack.instance", FT_UINT8, BASE_DEC, NULL, 0x0,
5598              "Indicating the topology instance associated with the DODAG, as learned from the DIO", HFILL }},
5599         { &hf_icmpv6_rpl_daoack_flag,
5600            { "Flag", "icmpv6.rpl.daoack.flag", FT_UINT8, BASE_HEX, NULL, 0x0,
5601              NULL, HFILL }},
5602         { &hf_icmpv6_rpl_daoack_flag_d,
5603            { "DODAGID Present (D)", "icmpv6.rpl.daoack.flag.d", FT_BOOLEAN, 8, NULL, RPL_DAOACK_FLAG_D,
5604              "Indicates that the DODAGID field is present", HFILL }},
5605         { &hf_icmpv6_rpl_daoack_flag_rsv,
5606            { "Reserved", "icmpv6.rpl.daoack.flag.rsv", FT_UINT8, BASE_DEC, NULL, RPL_DAOACK_FLAG_RESERVED,
5607              "Must be zero", HFILL }},
5608         { &hf_icmpv6_rpl_daoack_sequence,
5609            { "DAO-ACK Sequence", "icmpv6.rpl.daoack.sequence", FT_UINT8, BASE_DEC, NULL, 0x0,
5610              "Incremented at each DAO message from a node, and echoed in the DAO-ACK by the recipient", HFILL }},
5611         { &hf_icmpv6_rpl_daoack_status,
5612            { "Status", "icmpv6.rpl.daoack.status", FT_UINT8, BASE_DEC, NULL, 0x0,
5613              "Indicates the completion", HFILL }},
5614         { &hf_icmpv6_rpl_daoack_dodagid,
5615            { "DODAGID", "icmpv6.rpl.daoack.dodagid", FT_IPv6, BASE_NONE, NULL, 0x0,
5616              "IPv6 address integer set by a DODAG root which uniquely identifies a DODAG", HFILL }},
5617         { &hf_icmpv6_rpl_cc_instance,
5618            { "RPLInstanceID", "icmpv6.rpl.cc.instance", FT_UINT8, BASE_DEC, NULL, 0x0,
5619              "Indicating the topology instance associated with the DODAG, as learned from the DIO", HFILL }},
5620         { &hf_icmpv6_rpl_cc_flag,
5621            { "Flag", "icmpv6.rpl.cc.flag", FT_UINT8, BASE_HEX, NULL, 0x0,
5622              NULL, HFILL }},
5623         { &hf_icmpv6_rpl_cc_flag_r,
5624            { "Response (R)", "icmpv6.rpl.cc.flag.r", FT_BOOLEAN, 8, NULL, RPL_CC_FLAG_R,
5625              "Indicates whether the CC message is a response", HFILL }},
5626         { &hf_icmpv6_rpl_cc_flag_rsv,
5627            { "Reserved", "icmpv6.rpl.cc.flag.rsv", FT_UINT8, BASE_DEC, NULL, RPL_CC_FLAG_RESERVED,
5628              "Must be zero", HFILL }},
5629         { &hf_icmpv6_rpl_cc_nonce,
5630            { "CC Nonce", "icmpv6.rpl.cc.nonce", FT_UINT16, BASE_HEX, NULL, 0x0,
5631              "The corresponding CC response includes the same CC nonce value as the request, as learned from the DIO", HFILL }},
5632         { &hf_icmpv6_rpl_cc_dodagid,
5633            { "DODAGID", "icmpv6.rpl.cc.dodagid", FT_IPv6, BASE_NONE, NULL, 0x0,
5634              "IPv6 address integer set by a DODAG root which uniquely identifies a DODAG", HFILL }},
5635         { &hf_icmpv6_rpl_cc_destination_counter,
5636            { "Destination Counter", "icmpv6.rpl.cc.destination_counter", FT_UINT32, BASE_DEC, NULL, 0x0,
5637              "Indicating the sender's estimate of the destination's current security Counter value", HFILL }},
5638         { &hf_icmpv6_rpl_secure_flag,
5639            { "Flags", "icmpv6.rpl.secure.flag", FT_UINT8, BASE_HEX, NULL, 0x0,
5640              NULL, HFILL }},
5641         { &hf_icmpv6_rpl_secure_flag_t,
5642            { "Counter is Time (T)", "icmpv6.rpl.secure.flag.t", FT_BOOLEAN, 8, NULL, RPL_SECURE_FLAG_T,
5643              "If it is set then the Counter field is a timestamp", HFILL }},
5644         { &hf_icmpv6_rpl_secure_flag_rsv,
5645            { "Reserved", "icmpv6.rpl.secure.flag.rsv", FT_UINT8, BASE_DEC, NULL, RPL_SECURE_FLAG_RSV,
5646              "Must be zero", HFILL }},
5647         { &hf_icmpv6_rpl_secure_algorithm,
5648            { "Algorithm", "icmpv6.rpl.secure.algorithm", FT_UINT8, BASE_DEC, VALS(rpl_secure_algorithm_vals), 0x0,
5649              "The Security Algorithm field specifies the encryption, MAC, and signature scheme the network uses", HFILL }},
5650         { &hf_icmpv6_rpl_secure_kim,
5651            { "Key Identifier Mode (KIM)", "icmpv6.rpl.secure.kim", FT_UINT8, BASE_DEC, NULL, RPL_SECURE_KIM,
5652              "That indicates whether the key used for packet protection is determined implicitly or explicitly and indicates the particular representation of the Key Identifier field", HFILL }},
5653         { &hf_icmpv6_rpl_secure_lvl,
5654            { "Security Level (LVL)", "icmpv6.rpl.secure.lvl", FT_UINT8, BASE_DEC, NULL, RPL_SECURE_LVL,
5655              "Indicates the provided packet protection", HFILL }},
5656         { &hf_icmpv6_rpl_secure_rsv,
5657            { "Reserved", "icmpv6.rpl.secure.rsv", FT_UINT8, BASE_DEC, NULL, RPL_SECURE_RSV,
5658              "Must be zero", HFILL }},
5659         { &hf_icmpv6_rpl_secure_counter,
5660            { "Counter", "icmpv6.rpl.secure.counter", FT_UINT32, BASE_DEC, NULL, 0x0,
5661              "Indicates the non-repeating 4-octet value used to construct the cryptographic mechanism that implements packet protection and allows for the provision of semantic security", HFILL }},
5662         { &hf_icmpv6_rpl_secure_key_source,
5663            { "Key Source", "icmpv6.rpl.secure.key.source", FT_BYTES, BASE_NONE, NULL, 0x0,
5664              "Indicates the logical identifier of the originator of a group key", HFILL }},
5665         { &hf_icmpv6_rpl_secure_key_index,
5666            { "Key Source", "icmpv6.rpl.secure.key.index", FT_UINT8, BASE_DEC, NULL, 0x0,
5667              "Allows unique identification of different keys with the same originator", HFILL }},
5668         { &hf_icmpv6_rpl_opt,
5669           { "ICMPv6 RPL Option", "icmpv6.opt", FT_NONE, BASE_NONE, NULL, 0x0,
5670             "Option", HFILL }},
5671         { &hf_icmpv6_rpl_opt_type,
5672           { "Type", "icmpv6.rpl.opt.type", FT_UINT8, BASE_DEC, VALS(rpl_option_vals), 0x0,
5673             "Options type", HFILL }},
5674         { &hf_icmpv6_rpl_opt_length,
5675           { "Length", "icmpv6.rpl.opt.length", FT_UINT8, BASE_DEC, NULL, 0x0,
5676             "The length of the option in octets excluding the Type and Length fields", HFILL }},
5677         { &hf_icmpv6_rpl_opt_reserved,
5678           { "Reserved", "icmpv6.rpl.opt.reserved", FT_NONE, BASE_NONE, NULL, 0x0,
5679             "Reserved (Must be 0)", HFILL }},
5680         { &hf_icmpv6_rpl_opt_padn,
5681           { "Paddn", "icmpv6.rpl.opt.padn", FT_NONE, BASE_NONE, NULL, 0x0,
5682             "Padding (Must be 0)", HFILL }},
5683         { &hf_icmpv6_rpl_opt_metric_type,
5684           { "Routing Metric/Constraint Type", "icmpv6.rpl.opt.metric.type", FT_UINT8, BASE_DEC, VALS(rpl_metric_vals), 0x0,
5685             "The Routing Metric/Constraint Type field uniquely identifies each Routing Metric/Constraint object. RFC 6551", HFILL }},
5686         { &hf_icmpv6_rpl_opt_metric_flags,
5687           { "Flags","icmpv6.rpl.opt.metric.flags", FT_UINT16, BASE_HEX, NULL, 0x0,
5688             NULL, HFILL }},
5689         { &hf_icmpv6_rpl_opt_metric_reserved,
5690           { "Reserved Flags","icmpv6.rpl.opt.metric.reserved", FT_UINT16, BASE_HEX, NULL, RPL_METRIC_RESERVED,
5691             "Reserved (Must be Zero)", HFILL }},
5692         { &hf_icmpv6_rpl_opt_metric_flag_p,
5693           { "Flag P","icmpv6.rpl.opt.metric.flag.p", FT_BOOLEAN, 16, TFS(&tfs_set_notset), RPL_METRIC_FLAG_P,
5694             "Only used for recorded metrics.  When cleared, all nodes along the path successfully recorded the corresponding metric. When set, this indicates that one or several nodes along the path could not record the metric", HFILL }},
5695         { &hf_icmpv6_rpl_opt_metric_flag_c,
5696           { "Flag C","icmpv6.rpl.opt.metric.flag.c", FT_BOOLEAN, 16, TFS(&tfs_set_notset), RPL_METRIC_FLAG_C,
5697             "When set, this indicates that the object refers to a routing constraint. When cleared, the object refers to a routing metric.", HFILL }},
5698         { &hf_icmpv6_rpl_opt_metric_flag_o,
5699           { "Flag O","icmpv6.rpl.opt.metric.flag.o", FT_BOOLEAN, 16, TFS(&tfs_set_notset), RPL_METRIC_FLAG_O,
5700             "Used exclusively for routing constraints. When set, this indicates that the constraint is optional. When cleared, the constraint is mandatory.", HFILL }},
5701         { &hf_icmpv6_rpl_opt_metric_flag_r,
5702           { "Flag R","icmpv6.rpl.opt.metric.flag.r", FT_BOOLEAN, 16, TFS(&tfs_set_notset), RPL_METRIC_FLAG_R,
5703             "Only relevant for a routing metric. When set, this indicates that the routing metric is recorded along the path. When cleared, the routing metric is aggregated", HFILL }},
5704         { &hf_icmpv6_rpl_opt_metric_a,
5705           { "A Field","icmpv6.rpl.opt.metric.flag.a", FT_UINT16, BASE_HEX, NULL, RPL_METRIC_A,
5706             "Only relevant for metrics, it indicates whether the aggregated routing metric is additive, is multiplicative, reports a maximum, or reports a minimum", HFILL }},
5707         { &hf_icmpv6_rpl_opt_metric_prec,
5708           { "Precedence field","icmpv6.rpl.opt.metric.prec", FT_UINT16, BASE_HEX, NULL, RPL_METRIC_PREC,
5709             "It indicates the precedence of this Routing Metric/Constraint object relative to other objects in the container", HFILL }},
5710         { &hf_icmpv6_rpl_opt_metric_len,
5711           { "Metric Length", "icmpv6.rpl.opt.metric.length", FT_UINT8, BASE_DEC, NULL, 0x0,
5712             "The length of the object body, expressed in bytes.", HFILL }},
5713         { &hf_icmpv6_rpl_opt_metric_nsa_object,
5714           { "Node State and Attribute Object","icmpv6.rpl.opt.metric.nsa.object", FT_UINT16, BASE_HEX, NULL, 0x0,
5715             NULL, HFILL }},
5716         { &hf_icmpv6_rpl_opt_metric_nsa_object_reserved,
5717           { "Reserved field","icmpv6.rpl.opt.metric.nsa.object.reserved", FT_UINT16, BASE_HEX, NULL, RPL_METRIC_NSA_OBJECT_RESERVED,
5718             "Reserved (Must be Zero)", HFILL }},
5719         { &hf_icmpv6_rpl_opt_metric_nsa_object_flags,
5720           { "Flags","icmpv6.rpl.opt.metric.nsa.object.flags", FT_UINT16, BASE_HEX, NULL, RPL_METRIC_NSA_OBJECT_FLAGS,
5721             "Unspecified flags (Must be Zero)", HFILL }},
5722         { &hf_icmpv6_rpl_opt_metric_nsa_object_flag_a,
5723           { "Flag A", "icmpv6.rpl.opt.metric.nsa.object.flag.a", FT_BOOLEAN, 16, TFS(&tfs_set_notset), RPL_METRIC_NSA_OBJECT_FLAG_A,
5724             "When set, this indicates that the node can act as a traffic aggregator.", HFILL }},
5725         { &hf_icmpv6_rpl_opt_metric_nsa_object_flag_o,
5726           { "Flag O", "icmpv6.rpl.opt.metric.nsa.object.flag.o", FT_BOOLEAN, 16, TFS(&tfs_set_notset), RPL_METRIC_NSA_OBJECT_FLAG_O,
5727             "When set, this indicates that the node is overloaded and may not be able to process traffic.", HFILL }},
5728         { &hf_icmpv6_rpl_opt_metric_nsa_object_opttlv_object,
5729           { "Node State and Attribute Optional TLV", "icmpv6.rpl.opt.metric.nsa.object.opttlv.object", FT_UINT8, BASE_DEC, NULL, 0x0,
5730             "Optional TLV.", HFILL }},
5731         { &hf_icmpv6_rpl_opt_metric_nsa_object_opttlv_object_type,
5732           { "Node State and Attribute Optional TLV Type", "icmpv6.rpl.opt.metric.nsa.object.opttlv.object.type", FT_UINT8, BASE_DEC, NULL, 0x0,
5733             "Optional TLV type.", HFILL }},
5734         { &hf_icmpv6_rpl_opt_metric_nsa_object_opttlv_object_length,
5735           { "Node State and Attribute Optional TLV Length", "icmpv6.rpl.opt.metric.nsa.object.opttlv.object.length", FT_UINT8, BASE_DEC, NULL, 0x0,
5736             "The length of the option in octets excluding the Type and Length fields", HFILL }},
5737         { &hf_icmpv6_rpl_opt_metric_nsa_object_opttlv_object_data,
5738           { "Raw Data", "icmpv6.rpl.opt.metric.nsa.object.opttlv.object.data", FT_BYTES, BASE_NONE, NULL, 0x0,
5739             "The raw data in the TLV", HFILL }},
5740         { &hf_icmpv6_rpl_opt_metric_ne_object,
5741           { "Node Energy Object","icmpv6.rpl.opt.metric.ne.object", FT_UINT16, BASE_HEX, NULL, 0x0,
5742             NULL, HFILL }},
5743         { &hf_icmpv6_rpl_opt_metric_ne_object_flags,
5744           { "Flags field","icmpv6.rpl.opt.metric.ne.object.flags", FT_UINT16, BASE_HEX, NULL, RPL_METRIC_NE_OBJECT_FLAGS,
5745             "Unspecified flags (Must be Zero)", HFILL }},
5746         { &hf_icmpv6_rpl_opt_metric_ne_object_flag_i,
5747           { "Flag I","icmpv6.rpl.opt.metric.ne.object.flag.i", FT_BOOLEAN, 16, TFS(&tfs_set_notset), RPL_METRIC_NE_OBJECT_FLAG_I,
5748             "Only relevant when the node type is used as a constraint. When set, this indicates that nodes of the type specified in the node type field MUST be included", HFILL }},
5749         { &hf_icmpv6_rpl_opt_metric_ne_object_type,
5750           { "Type", "icmpv6.rpl.opt.metric.ne.object.type", FT_UINT16, BASE_HEX, NULL, RPL_METRIC_NE_OBJECT_TYPE,
5751             "T=0 designates a mains-powered node, T=1 a battery-powered node, and T=2 a node powered by an energy scavenger.", HFILL }},
5752         { &hf_icmpv6_rpl_opt_metric_ne_object_flag_e,
5753           { "Flag E", "icmpv6.rpl.opt.metric.ne.object.flag.e", FT_BOOLEAN, 16, TFS(&tfs_set_notset), RPL_METRIC_NE_OBJECT_FLAG_E,
5754             "When the 'E' bit is set for a metric, the estimated percentage of remaining energy on the node is indicated in the Energy 8-bit field. When cleared, the estimated percentage of remaining energy is not provided. When the 'E' bit is set for a constraint, the E_E field defines a threshold for the inclusion/exclusion: if an inclusion, nodes with values higher than the threshold are to be included; if an exclusion, nodes with values lower than the threshold are to be excluded.", HFILL }},
5755         { &hf_icmpv6_rpl_opt_metric_ne_object_energy,
5756           { "Energy", "icmpv6.rpl.opt.metric.ne.object.energy", FT_UINT16, BASE_HEX, NULL, RPL_METRIC_NE_OBJECT_ENERGY,
5757             "8-bit unsigned integer field indicating an estimated percentage of remaining energy. The Energy field is only relevant when the 'E' flag is set, and it MUST be set to 0 when the 'E' flag is cleared.", HFILL }},
5758         { &hf_icmpv6_rpl_opt_metric_hp_object,
5759           { "Hop Count Object","icmpv6.rpl.opt.metric.hp.object", FT_UINT16, BASE_HEX, NULL, 0x0,
5760             NULL, HFILL }},
5761         { &hf_icmpv6_rpl_opt_metric_hp_object_reserved,
5762           { "Reserved field","icmpv6.rpl.opt.metric.hp.object.reserved", FT_UINT16, BASE_HEX, NULL, RPL_METRIC_HP_OBJECT_RESERVED,
5763             "Reserved (Must be Zero)", HFILL }},
5764         { &hf_icmpv6_rpl_opt_metric_hp_object_flags,
5765           { "Flags","icmpv6.rpl.opt.metric.hp.object.flags", FT_UINT16, BASE_HEX, NULL, RPL_METRIC_HP_OBJECT_FLAGS,
5766             "Reserved (Must be Zero)", HFILL }},
5767         { &hf_icmpv6_rpl_opt_metric_hp_object_hp,
5768           { "Hop Count", "icmpv6.rpl.opt.metric.hp.object.hp", FT_UINT16, BASE_DEC, NULL, RPL_METRIC_HP_OBJECT_HP,
5769             "When used as a constraint, the DAG root indicates the maximum number of hops that a path may traverse. When used as a metric, each visited node simply increments the Hop Count field.", HFILL }},
5770         { &hf_icmpv6_rpl_opt_metric_lt_object_lt,
5771           { "Link Throughput", "icmpv6.rpl.opt.metric.lt.object.lt", FT_UINT32, BASE_DEC, NULL, 0x0,
5772             "The Throughput metric is the effective bit rate of a link.", HFILL }},
5773         { &hf_icmpv6_rpl_opt_metric_ll_object_ll,
5774           { "Link Latency", "icmpv6.rpl.opt.metric.ll.object.ll", FT_UINT32, BASE_DEC, NULL, 0x0,
5775             "The Latency is encoded in 32 bits in unsigned integer format, expressed in microseconds.", HFILL }},
5776         { &hf_icmpv6_rpl_opt_metric_lql_object,
5777           { "Link Quality Level Object","icmpv6.rpl.opt.metric.lql.object", FT_UINT8, BASE_HEX, NULL, 0x0,
5778             NULL, HFILL }},
5779         { &hf_icmpv6_rpl_opt_metric_lql_object_res,
5780           { "Reserved field","icmpv6.rpl.opt.metric.lql.object.res", FT_UINT8, BASE_HEX, NULL, RPL_METRIC_LQL_OBJECT_RES,
5781             "Reserved (Must be Zero)", HFILL }},
5782         { &hf_icmpv6_rpl_opt_metric_lql_object_val,
5783           { "Val(ue)","icmpv6.rpl.opt.metric.lql.object.val", FT_UINT8, BASE_HEX, NULL, RPL_METRIC_LQL_OBJECT_VAL,
5784             "LQL value from 0 to 7 where 0 means undetermined and 1 indicates the highest link quality.", HFILL }},
5785         { &hf_icmpv6_rpl_opt_metric_lql_object_counter,
5786           { "Counter", "icmpv6.rpl.opt.metric.lql.object.counter", FT_UINT8, BASE_DEC, NULL, RPL_METRIC_LQL_OBJECT_COUNTER,
5787             "The Counter represents the number of links with that value.", HFILL }},
5788         { &hf_icmpv6_rpl_opt_metric_etx_object_etx,
5789           { "ETX", "icmpv6.rpl.opt.metric.etx.object.etx", FT_UINT16, BASE_DEC, NULL, 0x0,
5790             "The ETX metric is the number of transmissions a node expects to make to a destination in order to successfully deliver a packet.", HFILL }},
5791         { &hf_icmpv6_rpl_opt_metric_lc_object,
5792           { "Link Color Object","icmpv6.rpl.opt.metric.lc.object", FT_NONE, BASE_NONE, NULL, 0x0,
5793             NULL, HFILL }},
5794         { &hf_icmpv6_rpl_opt_metric_lc_object_res,
5795           { "Reserved field","icmpv6.rpl.opt.metric.lc.object.res", FT_UINT8, BASE_HEX, NULL, RPL_METRIC_LC_OBJECT_RES,
5796             "Reserved (Must be Zero)", HFILL }},
5797         { &hf_icmpv6_rpl_opt_metric_lc_object_lc,
5798           { "Link Color","icmpv6.rpl.opt.metric.lc.object.lc", FT_UINT16, BASE_HEX, NULL, RPL_METRIC_LC_OBJECT_LC,
5799             "The Link Color (LC) object is an administrative 10-bit link constraint used to avoid or attract specific links for specific traffic types.", HFILL }},
5800         { &hf_icmpv6_rpl_opt_metric_lc_object_counter,
5801           { "Counter", "icmpv6.rpl.opt.metric.lc.object.counter", FT_UINT16, BASE_DEC, NULL, RPL_METRIC_LC_OBJECT_COUNTER,
5802             "The Counter is used to compress the information where the number of links for each Link Color is reported.", HFILL }},
5803         { &hf_icmpv6_rpl_opt_metric_lc_object_reserved,
5804           { "Reserved", "icmpv6.rpl.opt.metric.lc.object.reserved", FT_UINT16, BASE_DEC, NULL, RPL_METRIC_LC_OBJECT_RESERVED,
5805             "Reserved (Must be Zero).", HFILL }},
5806         { &hf_icmpv6_rpl_opt_metric_lc_object_flag_i,
5807           { "Flag I", "icmpv6.rpl.opt.metric.lc.object.flag.i", FT_UINT16, BASE_DEC, NULL, RPL_METRIC_LC_OBJECT_FLAG_I,
5808             "The 'I' bit is only relevant when the Link Color is used as a constraint. When set, this indicates that links with the specified color must be included.", HFILL }},
5809         { &hf_icmpv6_rpl_opt_route_prefix_length,
5810            { "Prefix Length", "icmpv6.rpl.opt.route.prefix_length", FT_UINT8, BASE_DEC, NULL, 0x0,
5811              "The number of leading bits in the Prefix that are valid", HFILL }},
5812         { &hf_icmpv6_rpl_opt_route_flag,
5813            { "Flag","icmpv6.rpl.opt.route.flag", FT_UINT8, BASE_HEX, NULL, 0x0,
5814              NULL, HFILL }},
5815         { &hf_icmpv6_rpl_opt_route_pref,
5816            { "Preference","icmpv6.rpl.opt.route.pref", FT_UINT8, BASE_DEC, VALS(nd_flag_router_pref), RPL_OPT_ROUTE_PREFERENCE,
5817              "The Route Preference indicates whether to prefer the router associated with this prefix over others, when multiple identical prefixes (for different routers) have been received", HFILL }},
5818         { &hf_icmpv6_rpl_opt_route_reserved,
5819            { "Reserved","icmpv6.rpl.opt.route.reserved", FT_UINT8, BASE_DEC, NULL, RPL_OPT_ROUTE_RESERVED,
5820              "Reserved (Must be Zero)", HFILL }},
5821         { &hf_icmpv6_rpl_opt_route_lifetime,
5822            { "Route Lifetime", "icmpv6.rpl.opt.route.lifetime", FT_UINT32, BASE_DEC|BASE_SPECIAL_VALS, VALS(unique_infinity), 0x0,
5823              "The length of time in seconds (relative to the time the packet is sent) that the prefix is valid for route determination", HFILL }},
5824         { &hf_icmpv6_rpl_opt_route_prefix,
5825            { "Prefix", "icmpv6.rpl.opt.route.prefix", FT_IPv6, BASE_NONE, NULL, 0x0,
5826              "Variable-length field containing an IP address or a prefix of an IPv6 address", HFILL }},
5827         { &hf_icmpv6_rpl_opt_config_flag,
5828            { "Flag","icmpv6.rpl.opt.config.flag", FT_UINT8, BASE_HEX, NULL, 0x0,
5829              NULL, HFILL }},
5830         { &hf_icmpv6_rpl_opt_config_reserved,
5831            { "Reserved","icmpv6.rpl.opt.config.reserved", FT_UINT8, BASE_DEC, NULL, RPL_OPT_CONFIG_FLAG_RESERVED,
5832              "Must be Zero", HFILL }},
5833         { &hf_icmpv6_rpl_opt_config_auth,
5834            { "Authentication Enabled","icmpv6.rpl.opt.config.auth", FT_BOOLEAN, 8, TFS(&tfs_set_notset), RPL_OPT_CONFIG_FLAG_AUTH,
5835              "One bit flag describing the security mode of the network", HFILL }},
5836         { &hf_icmpv6_rpl_opt_config_pcs,
5837            { "Path Control Size", "icmpv6.rpl.opt.config.pcs", FT_UINT8, BASE_DEC, NULL, RPL_OPT_CONFIG_FLAG_PCS,
5838              "Used to configure the number of bits that may be allocated to the Path Control field", HFILL }},
5839         { &hf_icmpv6_rpl_opt_config_doublings,
5840            { "DIOIntervalDoublings","icmpv6.rpl.opt.config.interval_double", FT_UINT8, BASE_DEC, NULL, 0x0,
5841              "Used to configure Imax of the DIO trickle timer", HFILL }},
5842         { &hf_icmpv6_rpl_opt_config_min_interval,
5843            { "DIOIntervalMin", "icmpv6.rpl.opt.config.interval_min", FT_UINT16, BASE_DEC, NULL, 0x0,
5844              "Used to configure Imin of the DIO trickle timer", HFILL }},
5845         { &hf_icmpv6_rpl_opt_config_redundancy,
5846            { "DIORedundancyConstant", "icmpv6.rpl.opt.config.redundancy", FT_UINT8, BASE_DEC, NULL, 0x0,
5847              "Used to configure k of the DIO trickle timer", HFILL }},
5848         { &hf_icmpv6_rpl_opt_config_rank_incr,
5849            { "MaxRankInc", "icmpv6.rpl.opt.config.max_rank_inc", FT_UINT16, BASE_DEC, NULL, 0x0,
5850              "Used to configure DAGMaxRankIncrease", HFILL }},
5851         { &hf_icmpv6_rpl_opt_config_hop_rank_inc,
5852            { "MinHopRankInc", "icmpv6.rpl.opt.config.min_hop_rank_inc", FT_UINT16, BASE_DEC, NULL, 0x0,
5853               "Used to configure MinHopRankIncrease", HFILL }},
5854         { &hf_icmpv6_rpl_opt_config_ocp,
5855            { "OCP (Objective Code Point)","icmpv6.rpl.opt.config.ocp", FT_UINT16, BASE_DEC, NULL, 0x0,
5856               "The OCP field identifies the OF and is managed by the IANA", HFILL }},
5857         { &hf_icmpv6_rpl_opt_config_rsv,
5858            { "Reserved", "icmpv6.rpl.opt.config.rsv", FT_UINT8, BASE_DEC, NULL, 0x0,
5859               NULL, HFILL }},
5860         { &hf_icmpv6_rpl_opt_config_def_lifetime,
5861            { "Default Lifetime", "icmpv6.rpl.opt.config.def_lifetime", FT_UINT8, BASE_DEC, NULL, 0x0,
5862               "This is the lifetime that is used as default for all RPL routes", HFILL }},
5863         { &hf_icmpv6_rpl_opt_config_lifetime_unit,
5864            { "Lifetime Unit", "icmpv6.rpl.opt.config.lifetime_unit", FT_UINT16, BASE_DEC, NULL, 0x0,
5865               "Provides the unit in seconds that is used to express route lifetimes in RPL", HFILL }},
5866         { &hf_icmpv6_rpl_opt_target_flag,
5867            { "Reserved", "icmpv6.rpl.opt.target.flag", FT_NONE, BASE_NONE, NULL, 0x0,
5868               "Unused field reserved for flags", HFILL }},
5869         { &hf_icmpv6_rpl_opt_target_prefix_length,
5870            { "Target Length", "icmpv6.rpl.opt.target.prefix_length", FT_UINT8, BASE_DEC, NULL, 0x0,
5871               "Number of valid leading bits in the IPv6 Prefix", HFILL }},
5872         { &hf_icmpv6_rpl_opt_target_prefix,
5873            { "Target", "icmpv6.rpl.opt.target.prefix", FT_IPv6, BASE_NONE, NULL, 0x0,
5874               "Identifying an IPv6 destination address, prefix, or multicast group", HFILL }},
5875         { &hf_icmpv6_rpl_opt_transit_flag,
5876            { "Flags", "icmpv6.rpl.opt.transit.flag", FT_UINT8, BASE_HEX, NULL, 0x0,
5877              NULL, HFILL }},
5878          { &hf_icmpv6_rpl_opt_transit_flag_e,
5879            { "External", "icmpv6.rpl.opt.transit.flag.e", FT_BOOLEAN, 8, TFS(&tfs_set_notset), RPL_OPT_TRANSIT_FLAG_E,
5880              "Indicate that the parent router redistributes external targets into the RPL network", HFILL }},
5881          { &hf_icmpv6_rpl_opt_transit_flag_rsv,
5882            { "Reserved", "icmpv6.rpl.opt.transit.flag.rsv", FT_UINT8, BASE_DEC, NULL, RPL_OPT_TRANSIT_FLAG_RSV,
5883              "Must be Zero", HFILL }},
5884         { &hf_icmpv6_rpl_opt_transit_pathctl,
5885            { "Path Control", "icmpv6.rpl.opt.transit.pathctl", FT_UINT8, BASE_DEC, NULL, 0x0,
5886               "Limits the number of DAO-Parents to which a DAO message advertising connectivity", HFILL }},
5887         { &hf_icmpv6_rpl_opt_transit_pathseq,
5888            { "Path Sequence", "icmpv6.rpl.opt.transit.pathseq", FT_UINT8, BASE_DEC, NULL, 0x0,
5889               "Increments the Path Sequence each time it issues a RPL Target option with updated information", HFILL }},
5890         { &hf_icmpv6_rpl_opt_transit_pathlifetime,
5891            { "Path Lifetime", "icmpv6.rpl.opt.transit.pathlifetime", FT_UINT8, BASE_DEC, NULL, 0x0,
5892               "The length of time in Lifetime Units that the prefix is valid for route determination", HFILL }},
5893         { &hf_icmpv6_rpl_opt_transit_parent,
5894            { "Parent Address", "icmpv6.rpl.opt.transit.parent", FT_IPv6, BASE_NONE, NULL, 0x0,
5895               "IPv6 Address of the DODAG Parent of the node originally issuing the Transit Information Option", HFILL }},
5896         { &hf_icmpv6_rpl_opt_solicited_instance,
5897            { "Instance", "icmpv6.rpl.opt.solicited.instance", FT_UINT8, BASE_DEC, NULL, 0x0,
5898               "Containing the RPLInstanceID that is being solicited when valid", HFILL }},
5899         { &hf_icmpv6_rpl_opt_solicited_flag,
5900            { "Flag", "icmpv6.rpl.opt.solicited.flag", FT_UINT8, BASE_HEX, NULL, 0x0,
5901               NULL, HFILL }},
5902         { &hf_icmpv6_rpl_opt_solicited_flag_v,
5903            { "Version predicate", "icmpv6.rpl.opt.solicited.flag.v", FT_BOOLEAN, 8, TFS(&tfs_true_false), RPL_OPT_SOLICITED_FLAG_V,
5904               "The Version predicate is true if the receiver's DODAGVersionNumber matches the requested Version Number", HFILL }},
5905         { &hf_icmpv6_rpl_opt_solicited_flag_i,
5906            { "InstanceID predicate","icmpv6.rpl.opt.solicited.flag.i", FT_BOOLEAN, 8, TFS(&tfs_true_false), RPL_OPT_SOLICITED_FLAG_I,
5907               "The InstanceID predicate is true when the RPL node's current RPLInstanceID matches the requested RPLInstanceID", HFILL }},
5908         { &hf_icmpv6_rpl_opt_solicited_flag_d,
5909            { "DODAGID predicate", "icmpv6.rpl.opt.solicited.flag.d", FT_BOOLEAN, 8, TFS(&tfs_true_false), RPL_OPT_SOLICITED_FLAG_D,
5910               "The DODAGID predicate is true if the RPL node's parent set has the same DODAGID as the DODAGID field", HFILL }},
5911          { &hf_icmpv6_rpl_opt_solicited_flag_rsv,
5912            { "Reserved", "icmpv6.rpl.opt.solicited.flag.rsv", FT_UINT8, BASE_DEC, NULL, RPL_OPT_SOLICITED_FLAG_RSV,
5913              "Must be Zero", HFILL }},
5914         { &hf_icmpv6_rpl_opt_solicited_dodagid,
5915            { "DODAGID", "icmpv6.rpl.opt.solicited.dodagid", FT_IPv6, BASE_NONE, NULL, 0x0,
5916               "the DODAGID that is being solicited when valid", HFILL }},
5917         { &hf_icmpv6_rpl_opt_solicited_version,
5918            { "Version", "icmpv6.rpl.opt.solicited.version", FT_UINT8, BASE_DEC, NULL, 0x0,
5919               "the value of  DODAGVersionNumber that is being solicited when valid", HFILL }},
5920 
5921         { &hf_icmpv6_rpl_opt_prefix_length,
5922            { "Prefix Length", "icmpv6.rpl.opt.prefix.length", FT_UINT8, BASE_DEC, NULL, 0x0,
5923              "The number of leading bits in the Prefix that are valid", HFILL }},
5924         { &hf_icmpv6_rpl_opt_prefix_flag,
5925            { "Flag", "icmpv6.rpl.opt.prefix.flag", FT_UINT8, BASE_HEX, NULL, 0x0,
5926              NULL, HFILL }},
5927         { &hf_icmpv6_rpl_opt_prefix_flag_l,
5928            { "On Link", "icmpv6.rpl.opt.prefix.flag.l", FT_BOOLEAN, 8, TFS(&tfs_set_notset), RPL_OPT_PREFIX_FLAG_L,
5929              "When set, indicates that this prefix can be used for on-link determination", HFILL }},
5930         { &hf_icmpv6_rpl_opt_prefix_flag_a,
5931            { "Auto Address Config","icmpv6.rpl.opt.config.flag.a", FT_BOOLEAN, 8, TFS(&tfs_set_notset), RPL_OPT_PREFIX_FLAG_A,
5932              "When set indicates that this prefix can be used for stateless address configuration", HFILL }},
5933         { &hf_icmpv6_rpl_opt_prefix_flag_r,
5934            { "Router Address", "icmpv6.rpl.opt.config.flag.r", FT_BOOLEAN, 8, TFS(&tfs_set_notset), RPL_OPT_PREFIX_FLAG_R,
5935              "When set, indicates that the Prefix field contains a complete IPv6 address assigned to the sending router that can be used as parent in a target option", HFILL }},
5936         { &hf_icmpv6_rpl_opt_prefix_flag_rsv,
5937            { "Reserved", "icmpv6.rpl.opt.config.flag.rsv", FT_UINT8, BASE_DEC, NULL, RPL_OPT_PREFIX_FLAG_RSV,
5938              "Must Be Zero", HFILL }},
5939         { &hf_icmpv6_rpl_opt_prefix_vlifetime,
5940            { "Valid Lifetime", "icmpv6.rpl.opt.prefix.valid_lifetime", FT_UINT32, BASE_DEC|BASE_SPECIAL_VALS, VALS(unique_infinity), 0x0,
5941              "The length of time in seconds that the prefix is valid for the purpose of on-link determination", HFILL }},
5942         { &hf_icmpv6_rpl_opt_prefix_plifetime,
5943            { "Preferred Lifetime", "icmpv6.rpl.opt.prefix.preferred_lifetime", FT_UINT32, BASE_DEC|BASE_SPECIAL_VALS, VALS(unique_infinity), 0x0,
5944              "The length of time in seconds that addresses generated from the prefix via stateless address autoconfiguration remain preferred", HFILL }},
5945         { &hf_icmpv6_rpl_opt_prefix,
5946            { "Destination Prefix", "icmpv6.rpl.opt.prefix", FT_IPv6, BASE_NONE, NULL, 0x0,
5947              "An IPv6 address or a prefix of an IPv6 address", HFILL }},
5948         { &hf_icmpv6_rpl_opt_targetdesc,
5949            { "Descriptor", "icmpv6.rpl.opt.targetdesc.descriptor", FT_UINT32, BASE_HEX, NULL, 0x0,
5950              "Opaque Data", HFILL }},
5951 
5952         { &hf_icmpv6_rpl_opt_route_discovery_flag,
5953            { "Flags", "icmpv6.rpl.opt.routediscovery.flag", FT_NONE, BASE_NONE, NULL, 0x0,
5954              "NULL", HFILL }},
5955         { &hf_icmpv6_rpl_opt_route_discovery_reply,
5956            { "Reply", "icmpv6.rpl.opt.routediscovery.flag.reply", FT_BOOLEAN, 8, TFS(&tfs_yes_no), RPL_OPT_ROUTE_DISCOVERY_R,
5957              "The Origin sets this flag to one to allow the Target(s) to send P2P-DRO messages back to the Origin", HFILL }},
5958         { &hf_icmpv6_rpl_opt_route_discovery_hop_by_hop,
5959            { "Hop-by-Hop", "icmpv6.rpl.opt.routediscovery.flag.hopbyhop", FT_BOOLEAN, 8, TFS(&tfs_yes_no), RPL_OPT_ROUTE_DISCOVERY_H,
5960              "The Origin sets this flag to one if it desires Hop-by-hop Routes and to zero if it desires Source Routes.", HFILL }},
5961         { &hf_icmpv6_rpl_opt_route_discovery_num_of_routes,
5962            { "Number of Routes", "icmpv6.rpl.opt.routediscovery.flag.numofroutes", FT_UINT8, BASE_DEC, NULL, RPL_OPT_ROUTE_DISCOVERY_N,
5963              "This value plus one indicates the number of Source Routes that each Target should convey to the Origin", HFILL }},
5964         { &hf_icmpv6_rpl_opt_route_discovery_compr,
5965            { "Compr", "icmpv6.rpl.opt.routediscovery.flag.compr", FT_UINT8, BASE_DEC, NULL, RPL_OPT_ROUTE_DISCOVERY_COMPR,
5966              "Number of prefix octets that are elided from the Target field and Address vector", HFILL }},
5967         { &hf_icmpv6_rpl_opt_route_discovery_lifetime,
5968            { "Lifetime", "icmpv6.rpl.opt.routediscovery.lifetime", FT_UINT8, BASE_DEC, NULL, RPL_OPT_ROUTE_DISCOVERY_L,
5969              "Lifetime of the temporary DODAG", HFILL }},
5970         { &hf_icmpv6_rpl_opt_route_discovery_maxrank,
5971            { "MaxRank", "icmpv6.rpl.opt.routediscovery.maxrank", FT_UINT8, BASE_DEC, NULL, RPL_OPT_ROUTE_DISCOVERY_MR_NH,
5972              "Upper limit of the integer portion of the rank when used inside a DIO", HFILL }},
5973         { &hf_icmpv6_rpl_opt_route_discovery_nh,
5974            { "NH", "icmpv6.rpl.opt.routediscovery.nh", FT_UINT8, BASE_DEC, NULL, RPL_OPT_ROUTE_DISCOVERY_MR_NH,
5975              "Index of the next-hop (NH) address inside the Address vector", HFILL }},
5976         { &hf_icmpv6_rpl_opt_route_discovery_target_addr,
5977            { "Target Address", "icmpv6.rpl.opt.routediscovery.targetaddr", FT_IPv6, BASE_NONE, NULL, 0x0,
5978              "An IPv6 address of the Target after eliding Compr number of prefix octets", HFILL }},
5979         { &hf_icmpv6_rpl_opt_route_discovery_addr_vec,
5980            { "Address Vector", "icmpv6.rpl.opt.routediscovery.addr_vec", FT_NONE, BASE_NONE, NULL, 0x0,
5981              "NULL", HFILL }},
5982         { &hf_icmpv6_rpl_opt_route_discovery_addr_vec_addr,
5983           { "Address", "icmpv6.rpl.opt.routediscovery.addrvec.addr", FT_IPv6, BASE_NONE, NULL, 0x0,
5984             NULL, HFILL }},
5985         { &hf_icmpv6_rpl_p2p_dro_instance,
5986            { "RPLInstanceID", "icmpv6.rpl.p2p.dro.instance", FT_UINT8, BASE_DEC, NULL, 0x0,
5987              "Set by the DODAG root that indicates which RPL Instance the DODAG is part of", HFILL }},
5988         { &hf_icmpv6_rpl_p2p_dro_version,
5989            { "Version", "icmpv6.rpl.p2p.dro.version", FT_UINT8, BASE_DEC, NULL, 0x0,
5990              "Set by the DODAG root to the DODAGVersionNumber", HFILL }},
5991         { &hf_icmpv6_rpl_p2p_dro_flag,
5992            { "Flags", "icmpv6.rpl.p2p.dro.flag", FT_UINT16, BASE_HEX, NULL, 0x0,
5993              "NULL", HFILL }},
5994         { &hf_icmpv6_rpl_p2p_dro_flag_stop,
5995            { "Stop", "icmpv6.rpl.p2p.dro.flag.stop", FT_BOOLEAN, 16, TFS(&tfs_yes_no), RPL_P2P_DRO_FLAG_S,
5996              "Indicates that the P2P-RPL route discovery is over", HFILL }},
5997         { &hf_icmpv6_rpl_p2p_dro_flag_ack,
5998            { "Ack", "icmpv6.rpl.p2p.dro.flag.ack", FT_BOOLEAN, 16, TFS(&tfs_yes_no), RPL_P2P_DRO_FLAG_A,
5999              "Indicates that the Origin MUST unicast a P2P-DRO-ACK message to the Target", HFILL }},
6000         { &hf_icmpv6_rpl_p2p_dro_flag_seq,
6001            { "Seq", "icmpv6.rpl.p2p.dro.flag.seq", FT_UINT16, BASE_DEC, NULL, RPL_P2P_DRO_FLAG_SEQ,
6002              "Indicates the sequence number for the P2P-DRO", HFILL }},
6003         { &hf_icmpv6_rpl_p2p_dro_flag_reserved,
6004            { "Reserved", "icmpv6.rpl.p2p.dro.flag.reserved", FT_UINT16, BASE_DEC, NULL, RPL_P2P_DRO_FLAG_RSV,
6005              NULL, HFILL }},
6006         { &hf_icmpv6_rpl_p2p_dro_dagid,
6007            { "DODAGID", "icmpv6.rpl.p2p.dro.dagid", FT_IPv6, BASE_NONE, NULL, 0x0,
6008              "IPv6 address set by a DODAG root which uniquely identifies a DODAG", HFILL }},
6009         { &hf_icmpv6_rpl_p2p_droack_flag,
6010            { "Flags", "icmpv6.rpl.p2p.droack.flag", FT_UINT16, BASE_HEX, NULL, 0x0,
6011              "NULL", HFILL }},
6012         { &hf_icmpv6_rpl_p2p_droack_flag_seq,
6013            { "Seq", "icmpv6.rpl.p2p.droack.flag.seq", FT_UINT16, BASE_DEC, NULL, RPL_P2P_DROACK_FLAG_SEQ,
6014              "Indicates the sequence number for the P2P-DRO", HFILL }},
6015         { &hf_icmpv6_rpl_p2p_droack_flag_reserved,
6016            { "Reserved", "icmpv6.rpl.p2p.droack.flag.reserved", FT_UINT16, BASE_DEC, NULL, RPL_P2P_DROACK_FLAG_RSV,
6017              NULL, HFILL }},
6018 
6019         /* RFC6743 Locator Update (156) */
6020 
6021         { &hf_icmpv6_ilnp_nb_locs,
6022           { "Num of Locs", "icmpv6.ilnp.nb_locs", FT_UINT8, BASE_DEC, NULL, 0x0,
6023             "The number of 64-bit Locator values that are advertised in this message", HFILL }},
6024         { &hf_icmpv6_ilnp_locator,
6025           { "Locator", "icmpv6.ilnp.nb_locator", FT_UINT64, BASE_HEX, NULL, 0x0,
6026             "The 64-bit Locator values currently valid for the sending ILNPv6 node", HFILL }},
6027         { &hf_icmpv6_ilnp_preference,
6028           { "Preference", "icmpv6.ilnp.nb_preference", FT_UINT32, BASE_DEC, NULL, 0x0,
6029             "The preferability of each Locator relative to other valid Locator values", HFILL }},
6030         { &hf_icmpv6_ilnp_lifetime,
6031           { "Lifetime", "icmpv6.ilnp.nb_lifetime", FT_UINT32, BASE_DEC, NULL, 0x0,
6032             "The maximum number of seconds that this particular Locator may be considered valid", HFILL }},
6033 
6034         /* 6lowpan-nd: Neighbour Discovery for 6LoWPAN Networks */
6035         { &hf_icmpv6_da_status,
6036           { "Status", "icmpv6.6lowpannd.da.status", FT_UINT8, BASE_DEC, VALS(nd_opt_6lowpannd_status_val), 0x0,
6037             "Indicates the status of a registration in the DAC", HFILL }},
6038         { &hf_icmpv6_da_rsv,
6039           { "Reserved", "icmpv6.6lowpannd.da.rsv", FT_UINT8, BASE_DEC, NULL, 0x0,
6040             "Must be Zero", HFILL }},
6041         { &hf_icmpv6_da_lifetime,
6042           { "Lifetime", "icmpv6.6lowpannd.da.lifetime", FT_UINT16, BASE_DEC, NULL, 0x0,
6043             "The amount of time in a unit of 60 seconds that the router should retain the Neighbor Cache entry for the sender of the NS that includes this option", HFILL }},
6044         { &hf_icmpv6_da_eui64,
6045           { "EUI-64", "icmpv6.6lowpannd.da.eui64", FT_EUI64, BASE_NONE, NULL, 0x0,
6046             "This field is used to uniquely identify the interface of the registered address by including the EUI-64 identifier", HFILL }},
6047         { &hf_icmpv6_da_raddr,
6048           { "Registered Address", "icmpv6.6lowpannd.da.reg_addr", FT_IPv6, BASE_NONE, NULL, 0x0,
6049             "Carries the host address, which was contained in the IPv6 Source field in the NS that contained the ARO option sent by the host", HFILL }},
6050 
6051         /* Extended Echo - Probe - RFC8335 */
6052         { &hf_icmpv6_ext_echo_seq_num,
6053          { "Sequence number", "icmpv6.ext.echo.seq", FT_UINT8, BASE_DEC_HEX, NULL, 0x0,
6054            NULL, HFILL}},
6055         { &hf_icmpv6_ext_echo_req_reserved,
6056          { "Reserved", "icmpv6.ext.echo.req.res", FT_UINT8, BASE_HEX, NULL, 0xFE,
6057            NULL, HFILL}},
6058         { &hf_icmpv6_ext_echo_req_local,
6059          { "Local bit", "icmpv6.ext.echo.req.local", FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x01,
6060            NULL, HFILL}},
6061         { &hf_icmpv6_ext_echo_rsp_state,
6062          { "State", "icmpv6.ext.echo.rsp.state", FT_UINT8, BASE_DEC, VALS(ext_echo_reply_state_str), 0xE0,
6063            NULL, HFILL}},
6064         { &hf_icmpv6_ext_echo_rsp_reserved,
6065          { "Reserved", "icmpv6.ext.echo.rsp.res", FT_UINT8, BASE_HEX, NULL, 0x18,
6066            NULL, HFILL}},
6067         { &hf_icmpv6_ext_echo_rsp_active,
6068          { "Active bit", "icmpv6.ext.echo.rsp.active", FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x04,
6069            NULL, HFILL}},
6070         { &hf_icmpv6_ext_echo_rsp_ipv4,
6071          { "IPv4 bit", "icmpv6.ext.echo.rsp.ipv4", FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x02,
6072            NULL, HFILL}},
6073         { &hf_icmpv6_ext_echo_rsp_ipv6,
6074          { "IPv6 bit", "icmpv6.ext.echo.rsp.ipv6", FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x01,
6075            NULL, HFILL}},
6076 
6077         /* Conversation-related [generated] header fields */
6078         { &hf_icmpv6_resp_in,
6079             { "Response In", "icmpv6.resp_in", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
6080               "The response to this request is in this frame", HFILL }},
6081         {&hf_icmpv6_no_resp,
6082             {"No response seen", "icmpv6.no_resp", FT_NONE, BASE_NONE, NULL, 0x0,
6083              "No corresponding response frame was seen", HFILL}},
6084         { &hf_icmpv6_resp_to,
6085             { "Response To", "icmpv6.resp_to", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
6086               "This is the response to the request in this frame", HFILL }},
6087         { &hf_icmpv6_resptime,
6088             { "Response Time", "icmpv6.resptime", FT_DOUBLE, BASE_NONE, NULL, 0x0,
6089               "The time between the request and the response, in ms.", HFILL }},
6090 
6091         /* RFC 7731: Multicast Protocol for Low-Power and Lossy Networks (MPL) */
6092         { &hf_icmpv6_mpl_seed_info_min_sequence,
6093             { "MinSequence", "icmpv6.mpl.seed_info.min_sequence", FT_UINT8, BASE_DEC, NULL, 0x0,
6094               "The lower-bound sequence number for the MPL Seed.", HFILL }},
6095         { &hf_icmpv6_mpl_seed_info_bm_len,
6096             { "Buffered Messages Length", "icmpv6.mpl.seed_info.bm_len", FT_UINT8, BASE_DEC, NULL, MPL_SEED_INFO_BM_LEN,
6097               "The The size of buffered-mpl-messages in octets.", HFILL }},
6098         { &hf_icmpv6_mpl_seed_info_s,
6099             { "Seed ID Length", "icmpv6.mpl.seed_info.s", FT_UINT8, BASE_DEC, VALS(mpl_seed_id_lengths), MPL_SEED_INFO_S,
6100               "The length of the seed-id.", HFILL }},
6101         { &hf_icmpv6_mpl_seed_info_seed_id,
6102             { "Seed ID", "icmpv6.mpl.seed_info.seed_id", FT_STRING, BASE_NONE, NULL, 0x0,
6103               NULL, HFILL }},
6104         { &hf_icmpv6_mpl_seed_info_sequence,
6105             { "Sequence", "icmpv6.mpl.seed_info.sequence", FT_UINT8, BASE_DEC, NULL, 0x0,
6106               NULL, HFILL }}
6107 
6108     };
6109 
6110     static gint *ett[] = {
6111         &ett_icmpv6,
6112         &ett_icmpv6_opt,
6113         &ett_icmpv6_mar,
6114         &ett_icmpv6_flag_prefix,
6115         &ett_icmpv6_flag_map,
6116         &ett_icmpv6_flag_route_info,
6117         &ett_icmpv6_flag_6lowpan,
6118         &ett_icmpv6_flag_efo,
6119         &ett_icmpv6_rpl_opt,
6120         &ett_icmpv6_rpl_metric_type,
6121         &ett_icmpv6_rpl_metric_flags,
6122         &ett_icmpv6_rpl_metric_nsa_object,
6123         &ett_icmpv6_rpl_metric_nsa_object_tlv_type,
6124         &ett_icmpv6_rpl_metric_ne_object,
6125         &ett_icmpv6_rpl_metric_hp_object,
6126         &ett_icmpv6_rpl_metric_lql_object,
6127         &ett_icmpv6_rpl_metric_lc_object,
6128         &ett_icmpv6_rpl_flag_routing,
6129         &ett_icmpv6_rpl_flag_config,
6130         &ett_icmpv6_rpl_flag_transit,
6131         &ett_icmpv6_rpl_flag_solicited,
6132         &ett_icmpv6_rpl_flag_prefix,
6133         &ett_icmpv6_rpl_route_discovery_flag,
6134         &ett_icmpv6_rpl_route_discovery_addr_vec,
6135         &ett_icmpv6_rpl_p2p_dro_flag,
6136         &ett_icmpv6_rpl_p2p_droack_flag,
6137         &ett_icmpv6_flag_ni,
6138         &ett_icmpv6_flag_rr,
6139         &ett_icmpv6_rr_mp,
6140         &ett_icmpv6_rr_up,
6141         &ett_icmpv6_rr_up_flag_mask,
6142         &ett_icmpv6_rr_up_flag_ra,
6143         &ett_icmpv6_rr_up_flag,
6144         &ett_icmpv6_rr_rm,
6145         &ett_icmpv6_rr_rm_flag,
6146         &ett_icmpv6_flag_mld,
6147         &ett_icmpv6_flag_ra,
6148         &ett_icmpv6_flag_na,
6149         &ett_icmpv6_flag_mip6,
6150         &ett_icmpv6_flag_fmip6,
6151         &ett_icmpv6_flag_secure,
6152         &ett_icmpv6_flag_rpl_dio,
6153         &ett_icmpv6_flag_rpl_dao,
6154         &ett_icmpv6_flag_rpl_daoack,
6155         &ett_icmpv6_flag_rpl_cc,
6156         &ett_icmpv6_opt_name,
6157         &ett_icmpv6_cga_param_name,
6158         &ett_icmpv6_mpl_seed_info,
6159         &ett_icmpv6_mpl_seed_info_bm
6160     };
6161 
6162     static ei_register_info ei[] = {
6163         { &ei_icmpv6_invalid_option_length, { "icmpv6.invalid_option_length", PI_MALFORMED, PI_ERROR, "Invalid Option Length", EXPFILL }},
6164         { &ei_icmpv6_undecoded_option, { "icmpv6.undecoded.option", PI_UNDECODED, PI_NOTE, "Undecoded option", EXPFILL }},
6165         { &ei_icmpv6_unknown_data, { "icmpv6.unknown_data.expert", PI_MALFORMED, PI_ERROR, "Unknown Data (not interpreted)", EXPFILL }},
6166         { &ei_icmpv6_undecoded_rpl_option, { "icmpv6.undecoded.rpl_option", PI_UNDECODED, PI_NOTE, "Undecoded RPL Option", EXPFILL }},
6167         { &ei_icmpv6_undecoded_type, { "icmpv6.undecoded.type", PI_UNDECODED, PI_NOTE, "Undecoded type", EXPFILL }},
6168         { &ei_icmpv6_rr_pco_mp_matchlen, { "icmpv6.rr.pco.mp.matchlen.gt128", PI_PROTOCOL, PI_WARN, "MatchLen is greater than 128", EXPFILL }},
6169         { &ei_icmpv6_rr_pco_mp_matchedlen, { "icmpv6.rr.pco.mp.matchedlen.gt128", PI_PROTOCOL, PI_WARN, "MatchedLen is greater than 128", EXPFILL }},
6170         { &ei_icmpv6_checksum, { "icmpv6.checksum_bad.expert", PI_CHECKSUM, PI_WARN, "Bad checksum", EXPFILL }},
6171         { &ei_icmpv6_resp_not_found, { "icmpv6.resp_not_found", PI_SEQUENCE, PI_WARN, "Response not found", EXPFILL }},
6172         { &ei_icmpv6_rpl_unknown_metric, { "icmpv6.rpl.unknown.metric", PI_UNDECODED, PI_NOTE, "Unknown RPL metric/constraint type", EXPFILL }},
6173         { &ei_icmpv6_rpl_p2p_hop_by_hop, { "icmpv6.rpl.p2p.hop_by_hop", PI_PROTOCOL, PI_WARN, "Reply MUST be set to one in order to establish a Hop-by-Hop Route", EXPFILL }},
6174         { &ei_icmpv6_rpl_p2p_num_of_routes, { "icmpv6.rpl.p2p.num_of_routes", PI_PROTOCOL, PI_WARN, "This field MUST be set to zero when Hop-by-Hop Routes are being discovered", EXPFILL }},
6175         { &ei_icmpv6_rpl_p2p_dro_rdo_zero, { "icmpv6.rpl.p2p.dro.rdo.zero", PI_PROTOCOL, PI_WARN, "This field MUST be set to zero when the P2P-RDO is included in a P2P-DRO", EXPFILL }},
6176         { &ei_icmpv6_rpl_p2p_dro_zero, { "icmpv6.rpl.p2p.dro.zero", PI_PROTOCOL, PI_WARN, "This field MUST be set to zero", EXPFILL }},
6177     };
6178 
6179     expert_module_t* expert_icmpv6;
6180 
6181     proto_icmpv6 = proto_register_protocol("Internet Control Message Protocol v6",
6182                                            "ICMPv6", "icmpv6");
6183     proto_register_field_array(proto_icmpv6, hf, array_length(hf));
6184     proto_register_subtree_array(ett, array_length(ett));
6185     expert_icmpv6 = expert_register_protocol(proto_icmpv6);
6186     expert_register_field_array(expert_icmpv6, ei, array_length(ei));
6187 
6188     register_seq_analysis("icmpv6", "ICMPv6 Flows", proto_icmpv6, NULL, TL_REQUIRES_COLUMNS, icmpv6_seq_analysis_packet);
6189     icmpv6_handle = register_dissector("icmpv6", dissect_icmpv6, proto_icmpv6);
6190     icmpv6_heur_subdissector_list = register_heur_dissector_list("icmpv6", proto_icmpv6);
6191     icmpv6_tap = register_tap("icmpv6");
6192 }
6193 
6194 void
proto_reg_handoff_icmpv6(void)6195 proto_reg_handoff_icmpv6(void)
6196 {
6197     capture_dissector_handle_t icmpv6_cap_handle;
6198 
6199     dissector_add_uint("ip.proto", IP_PROTO_ICMPV6, icmpv6_handle);
6200     icmpv6_cap_handle = create_capture_dissector_handle(capture_icmpv6, proto_icmpv6);
6201     capture_dissector_add_uint("ip.proto", IP_PROTO_ICMPV6, icmpv6_cap_handle);
6202 
6203     /*
6204      * Get a handle for the IPv6 dissector.
6205      */
6206     ipv6_handle = find_dissector_add_dependency("ipv6", proto_icmpv6);
6207     icmp_extension_handle = find_dissector("icmp_extension");
6208 }
6209 
6210 /*
6211  * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
6212  *
6213  * Local variables:
6214  * c-basic-offset: 4
6215  * tab-width: 8
6216  * indent-tabs-mode: nil
6217  * End:
6218  *
6219  * vi: set shiftwidth=4 tabstop=8 expandtab:
6220  * :indentSize=4:tabSize=8:noTabs=true:
6221  */
6222