987bbefa004f8921faa4c5212d2aef7d4fe8d3bd
[obnox/wireshark/wip.git] / epan / dissectors / packet-icmpv6.c
1 /* packet-icmpv6.c
2  * Routines for ICMPv6 packet disassembly
3  *
4  * $Id$
5  *
6  * Wireshark - Network traffic analyzer
7  * By Gerald Combs <gerald@wireshark.org>
8  * Copyright 1998 Gerald Combs
9  *
10  * MobileIPv6 support added by Tomislav Borosa <tomislav.borosa@siemens.hr>
11  * Copyright 2006, Nicolas DICHTEL - 6WIND - <nicolas.dichtel@6wind.com>
12  *
13  * HMIPv6 support added by Martti Kuparinen <martti.kuparinen@iki.fi>
14  *
15  * FMIPv6 support added by Martin Andre <andre@clarinet.u-strasbg.fr>
16  *
17  * RPL support added by Colin O'Flynn & Owen Kirby.
18  *
19  * Enhance ICMPv6 dissector by Alexis La Goutte
20  *
21  * This program is free software; you can redistribute it and/or
22  * modify it under the terms of the GNU General Public License
23  * as published by the Free Software Foundation; either version 2
24  * of the License, or (at your option) any later version.
25  *
26  * This program is distributed in the hope that it will be useful,
27  * but WITHOUT ANY WARRANTY; without even the implied warranty of
28  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
29  * GNU General Public License for more details.
30  *
31  * You should have received a copy of the GNU General Public License
32  * along with this program; if not, write to the Free Software
33  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
34  */
35
36 #ifdef HAVE_CONFIG_H
37 # include "config.h"
38 #endif
39
40 #include <string.h>
41
42 #include <glib.h>
43
44 #include <epan/packet.h>
45 #include <epan/in_cksum.h>
46 #include <epan/addr_resolv.h>
47 #include <epan/ipproto.h>
48 #include <epan/asn1.h>
49 #include <epan/strutil.h>
50 #include <epan/expert.h>
51 #include <epan/conversation.h>
52 #include <epan/emem.h>
53 #include <epan/tap.h>
54
55 #include "packet-ber.h"
56 #include "packet-dns.h"
57 #include "packet-x509af.h"
58 #include "packet-x509if.h"
59 #include "packet-icmp.h"    /* same transaction_t used both both v4 and v6 */
60
61 /*
62  * The information used comes from:
63  * RFC 1885/2463/4443: Internet Control Message Protocol (ICMPv6) for the Internet Protocol Version 6 (IPv6) Specification
64  * RFC 2461/4861: Neighbor Discovery for IP Version 6 (IPv6)
65  * RFC 2491: IPv6 over Non-Broadcast Multiple Access (NBMA) networks
66  * RFC 2710: Multicast Listener Discovery for IPv6
67  * RFC 2894: Router Renumbering for IPv6
68  * RFC 3122: Extensions to IPv6 Neighbor Discovery for Inverse Discovery Specification
69  * RFC 3775/6275: Mobility Support in IPv6
70  * RFC 3810: Multicast Listener Discovery Version 2 (MLDv2) for IPv6
71  * RFC 3971: SEcure Neighbor Discovery (SEND)
72  * RFC 4065: Instructions for Seamoby and Experimental Mobility Protocol IANA Allocations
73  * RFC 4068/5268/5568: Fast Handovers for Mobile IPv6 (Mobile IPv6 Fast Handovers)
74  * RFC 4140/5380: Hierarchical Mobile IPv6 Mobility Management (HMIPv6)
75  * RFC 4191: Default Router Preferences and More-Specific Routes
76  * RFC 4286: Multicast Router Discovery
77  * RFC 4620: IPv6 Node Information Queries
78  * RFC 5006/6106: IPv6 Router Advertisement Options for DNS Configuration
79  * RFC 5075/5175: IPv6 Router Advertisement Flags Option
80  * RFC 5269: Distributing a Symmetric Fast Mobile IPv6 (FMIPv6) Handover Key Using SEcure Neighbor Discovery (SEND)
81  * RFC 5271: Mobile IPv6 Fast Handovers for 3G CDMA Networks
82  * RFC 6275: Mobility Support in IPv6
83  * draft-ieft-roll-rpl-19.txt: RPL: IPv6 Routing Protocol for Low power and Lossy Networks
84  * draft-ietf-csi-proxy-send-05: Secure Proxy ND Support for SEND
85  * draft-ietf-6lowpan-nd-18: Neighbor Discovery Optimization for Low Power and Lossy Networks (6LoWPAN)
86  * http://www.iana.org/assignments/icmpv6-parameters (last updated 2011-04-08)
87  */
88
89 static int proto_icmpv6 = -1;
90 static int hf_icmpv6_type = -1;
91 static int hf_icmpv6_code = -1;
92 static int hf_icmpv6_checksum = -1;
93 static int hf_icmpv6_checksum_bad = -1;
94 static int hf_icmpv6_reserved = -1;
95 static int hf_icmpv6_data = -1;
96 static int hf_icmpv6_unknown_data = -1;
97 static int hf_icmpv6_mtu = -1;
98 static int hf_icmpv6_pointer = -1;
99 static int hf_icmpv6_echo_identifier = -1;
100 static int hf_icmpv6_echo_sequence_number = -1;
101 static int hf_icmpv6_nonce = -1;
102
103 /* RFC 2461/4861 : Neighbor Discovery for IP version 6 (IPv6) */
104 static int hf_icmpv6_nd_ra_cur_hop_limit = -1;
105 static int hf_icmpv6_nd_ra_flag = -1;
106 static int hf_icmpv6_nd_ra_flag_m = -1;
107 static int hf_icmpv6_nd_ra_flag_o = -1;
108 static int hf_icmpv6_nd_ra_flag_h = -1;
109 static int hf_icmpv6_nd_ra_flag_prf = -1;
110 static int hf_icmpv6_nd_ra_flag_p = -1;
111 static int hf_icmpv6_nd_ra_flag_rsv = -1;
112 static int hf_icmpv6_nd_ra_router_lifetime = -1;
113 static int hf_icmpv6_nd_ra_reachable_time = -1;
114 static int hf_icmpv6_nd_ra_retrans_timer = -1;
115 static int hf_icmpv6_nd_ns_target_address = -1;
116 static int hf_icmpv6_nd_na_flag = -1;
117 static int hf_icmpv6_nd_na_flag_r = -1;
118 static int hf_icmpv6_nd_na_flag_s = -1;
119 static int hf_icmpv6_nd_na_flag_o = -1;
120 static int hf_icmpv6_nd_na_flag_rsv = -1;
121 static int hf_icmpv6_nd_na_target_address = -1;
122 static int hf_icmpv6_nd_rd_target_address = -1;
123 static int hf_icmpv6_nd_rd_destination_address = -1;
124
125 /* ND Options */
126 static int hf_icmpv6_opt = -1;
127 static int hf_icmpv6_opt_type = -1;
128 static int hf_icmpv6_opt_length = -1;
129 static int hf_icmpv6_opt_linkaddr_mac = -1;
130 static int hf_icmpv6_opt_src_linkaddr_mac = -1;
131 static int hf_icmpv6_opt_target_linkaddr_mac = -1;
132 static int hf_icmpv6_opt_linkaddr = -1;
133 static int hf_icmpv6_opt_src_linkaddr = -1;
134 static int hf_icmpv6_opt_target_linkaddr = -1;
135 static int hf_icmpv6_opt_linkaddr_eui64 = -1;
136 static int hf_icmpv6_opt_src_linkaddr_eui64 = -1;
137 static int hf_icmpv6_opt_target_linkaddr_eui64 = -1;
138 static int hf_icmpv6_opt_prefix_len = -1;
139 static int hf_icmpv6_opt_prefix_flag = -1;
140 static int hf_icmpv6_opt_prefix_flag_l = -1;
141 static int hf_icmpv6_opt_prefix_flag_a = -1;
142 static int hf_icmpv6_opt_prefix_flag_r = -1;
143 static int hf_icmpv6_opt_prefix_flag_reserved = -1;
144 static int hf_icmpv6_opt_prefix_valid_lifetime = -1;
145 static int hf_icmpv6_opt_prefix_preferred_lifetime = -1;
146 static int hf_icmpv6_opt_prefix = -1;
147 static int hf_icmpv6_opt_naack_option_code = -1;
148 static int hf_icmpv6_opt_naack_status = -1;
149 static int hf_icmpv6_opt_naack_supplied_ncoa = -1;
150 static int hf_icmpv6_opt_cga_pad_len = -1;
151 static int hf_icmpv6_opt_cga = -1;
152 static int hf_icmpv6_opt_cga_modifier = -1;
153 static int hf_icmpv6_opt_cga_subnet_prefix = -1;
154 static int hf_icmpv6_opt_cga_count = -1;
155 static int hf_icmpv6_opt_cga_ext_type = -1;
156 static int hf_icmpv6_opt_cga_ext_length = -1;
157 static int hf_icmpv6_opt_cga_ext_data = -1;
158 static int hf_icmpv6_opt_rsa_key_hash = -1;
159 static int hf_icmpv6_opt_digital_signature_padding = -1;
160 static int hf_icmpv6_opt_ps_key_hash = -1;
161 static int hf_icmpv6_opt_timestamp = -1;
162 static int hf_icmpv6_opt_nonce = -1;
163 static int hf_icmpv6_opt_certificate_padding = -1;
164 static int hf_icmpv6_opt_ipa_option_code = -1;
165 static int hf_icmpv6_opt_ipa_prefix_len = -1;
166 static int hf_icmpv6_opt_ipa_ipv6_address = -1;
167 static int hf_icmpv6_opt_nrpi_option_code = -1;
168 static int hf_icmpv6_opt_nrpi_prefix_len = -1;
169 static int hf_icmpv6_opt_nrpi_prefix = -1;
170 static int hf_icmpv6_opt_lla_option_code = -1;
171 static int hf_icmpv6_opt_lla_bytes = -1;
172 static int hf_icmpv6_opt_map_dist = -1;
173 static int hf_icmpv6_opt_map_pref = -1;
174 static int hf_icmpv6_opt_map_flag = -1;
175 static int hf_icmpv6_opt_map_flag_r = -1;
176 static int hf_icmpv6_opt_map_flag_reserved = -1;
177 static int hf_icmpv6_opt_map_valid_lifetime = -1;
178 static int hf_icmpv6_opt_map_global_address = -1;
179 static int hf_icmpv6_opt_route_info_flag = -1;
180 static int hf_icmpv6_opt_route_info_flag_route_preference = -1;
181 static int hf_icmpv6_opt_route_info_flag_reserved = -1;
182 static int hf_icmpv6_opt_route_lifetime = -1;
183 static int hf_icmpv6_opt_name_type = -1;
184 static int hf_icmpv6_opt_name_x501 = -1;
185 static int hf_icmpv6_opt_name_fqdn = -1;
186 static int hf_icmpv6_opt_cert_type = -1;
187 static int hf_icmpv6_x509if_Name = -1;
188 static int hf_icmpv6_x509af_Certificate = -1;
189 static int hf_icmpv6_opt_redirected_packet = -1;
190 static int hf_icmpv6_opt_mtu = -1;
191 static int hf_icmpv6_opt_nbma_shortcut_limit = -1;
192 static int hf_icmpv6_opt_advertisement_interval = -1;
193 static int hf_icmpv6_opt_home_agent_preference = -1;
194 static int hf_icmpv6_opt_home_agent_lifetime = -1;
195 static int hf_icmpv6_opt_ipv6_address = -1;
196 static int hf_icmpv6_opt_reserved = -1;
197 static int hf_icmpv6_opt_padding = -1;
198 static int hf_icmpv6_opt_rdnss_lifetime = -1;
199 static int hf_icmpv6_opt_rdnss = -1;
200 static int hf_icmpv6_opt_efo = -1;
201 static int hf_icmpv6_opt_efo_m = -1;
202 static int hf_icmpv6_opt_efo_o = -1;
203 static int hf_icmpv6_opt_efo_h = -1;
204 static int hf_icmpv6_opt_efo_prf = -1;
205 static int hf_icmpv6_opt_efo_p = -1;
206 static int hf_icmpv6_opt_efo_rsv = -1;
207 static int hf_icmpv6_opt_hkr_pad_length = -1;
208 static int hf_icmpv6_opt_hkr_at = -1;
209 static int hf_icmpv6_opt_hkr_reserved = -1;
210 static int hf_icmpv6_opt_hkr_encryption_public_key = -1;
211 static int hf_icmpv6_opt_hkr_padding = -1;
212 static int hf_icmpv6_opt_hkr_lifetime = -1;
213 static int hf_icmpv6_opt_hkr_encrypted_handover_key = -1;
214 static int hf_icmpv6_opt_hai_option_code = -1;
215 static int hf_icmpv6_opt_hai_length = -1;
216 static int hf_icmpv6_opt_hai_value = -1;
217 static int hf_icmpv6_opt_mn_option_code = -1;
218 static int hf_icmpv6_opt_mn_length = -1;
219 static int hf_icmpv6_opt_mn_value = -1;
220 static int hf_icmpv6_opt_dnssl_lifetime = -1;
221 static int hf_icmpv6_opt_dnssl = -1;
222
223 static int hf_icmpv6_opt_aro_status = -1;
224 static int hf_icmpv6_opt_aro_registration_lifetime = -1;
225 static int hf_icmpv6_opt_aro_eui64 = -1;
226 static int hf_icmpv6_opt_6co_context_length = -1;
227 static int hf_icmpv6_opt_6co_flag = -1;
228 static int hf_icmpv6_opt_6co_flag_c = -1;
229 static int hf_icmpv6_opt_6co_flag_cid = -1;
230 static int hf_icmpv6_opt_6co_flag_reserved = -1;
231 static int hf_icmpv6_opt_6co_valid_lifetime = -1;
232 static int hf_icmpv6_opt_6co_context_prefix  = -1;
233 static int hf_icmpv6_opt_abro_version = -1;
234 static int hf_icmpv6_opt_abro_6lbr_address = -1;
235
236
237 /* RFC 2710: Multicast Listener Discovery for IPv6 */
238 static int hf_icmpv6_mld_mrd = -1;
239 static int hf_icmpv6_mld_multicast_address = -1;
240
241 /* RFC 2894: Router Renumbering for IPv6 */
242 static int hf_icmpv6_rr_sequencenumber = -1;
243 static int hf_icmpv6_rr_segmentnumber = -1;
244 static int hf_icmpv6_rr_flag = -1;
245 static int hf_icmpv6_rr_flag_t = -1;
246 static int hf_icmpv6_rr_flag_r = -1;
247 static int hf_icmpv6_rr_flag_a = -1;
248 static int hf_icmpv6_rr_flag_s = -1;
249 static int hf_icmpv6_rr_flag_p = -1;
250 static int hf_icmpv6_rr_flag_rsv = -1;
251 static int hf_icmpv6_rr_maxdelay = -1;
252 static int hf_icmpv6_rr_pco_mp_part = -1;
253 static int hf_icmpv6_rr_pco_mp_opcode = -1;
254 static int hf_icmpv6_rr_pco_mp_oplength = -1;
255 static int hf_icmpv6_rr_pco_mp_ordinal = -1;
256 static int hf_icmpv6_rr_pco_mp_matchlen = -1;
257 static int hf_icmpv6_rr_pco_mp_minlen = -1;
258 static int hf_icmpv6_rr_pco_mp_maxlen = -1;
259 static int hf_icmpv6_rr_pco_mp_matchprefix = -1;
260 static int hf_icmpv6_rr_pco_up_part = -1;
261 static int hf_icmpv6_rr_pco_up_uselen = -1;
262 static int hf_icmpv6_rr_pco_up_keeplen = -1;
263 static int hf_icmpv6_rr_pco_up_flagmask = -1;
264 static int hf_icmpv6_rr_pco_up_flagmask_l = -1;
265 static int hf_icmpv6_rr_pco_up_flagmask_a = -1;
266 static int hf_icmpv6_rr_pco_up_flagmask_reserved = -1;
267 static int hf_icmpv6_rr_pco_up_raflags = -1;
268 static int hf_icmpv6_rr_pco_up_raflags_l = -1;
269 static int hf_icmpv6_rr_pco_up_raflags_a = -1;
270 static int hf_icmpv6_rr_pco_up_raflags_reserved = -1;
271 static int hf_icmpv6_rr_pco_up_validlifetime = -1;
272 static int hf_icmpv6_rr_pco_up_preferredlifetime = -1;
273 static int hf_icmpv6_rr_pco_up_flag = -1;
274 static int hf_icmpv6_rr_pco_up_flag_v = -1;
275 static int hf_icmpv6_rr_pco_up_flag_p = -1;
276 static int hf_icmpv6_rr_pco_up_flag_reserved = -1;
277 static int hf_icmpv6_rr_pco_up_useprefix = -1;
278 static int hf_icmpv6_rr_rm = -1;
279 static int hf_icmpv6_rr_rm_flag = -1;
280 static int hf_icmpv6_rr_rm_flag_b = -1;
281 static int hf_icmpv6_rr_rm_flag_f = -1;
282 static int hf_icmpv6_rr_rm_flag_reserved = -1;
283 static int hf_icmpv6_rr_rm_ordinal = -1;
284 static int hf_icmpv6_rr_rm_matchedlen = -1;
285 static int hf_icmpv6_rr_rm_interfaceindex = -1;
286 static int hf_icmpv6_rr_rm_matchedprefix = -1;
287
288 /* RFC 3810: Multicast Listener Discovery Version 2 (MLDv2) for IPv6 */
289 static int hf_icmpv6_mld_mrc = -1;
290 static int hf_icmpv6_mld_flag = -1;
291 static int hf_icmpv6_mld_flag_s = -1;
292 static int hf_icmpv6_mld_flag_qrv = -1;
293 static int hf_icmpv6_mld_flag_rsv = -1;
294 static int hf_icmpv6_mld_qqi = -1;
295 static int hf_icmpv6_mld_nb_sources = -1;
296 static int hf_icmpv6_mld_source_address = -1;
297 static int hf_icmpv6_mldr_nb_mcast_records = -1;
298 static int hf_icmpv6_mldr_mar = -1;
299 static int hf_icmpv6_mldr_mar_record_type = -1;
300 static int hf_icmpv6_mldr_mar_aux_data_len = -1;
301 static int hf_icmpv6_mldr_mar_nb_sources = -1;
302 static int hf_icmpv6_mldr_mar_multicast_address = -1;
303 static int hf_icmpv6_mldr_mar_source_address = -1;
304 static int hf_icmpv6_mldr_mar_auxiliary_data = -1;
305
306 /* RFC3775/6275: Mobility Support in IPv6 */
307 static int hf_icmpv6_mip6_identifier = -1;
308 static int hf_icmpv6_mip6_home_agent_address = -1;
309 static int hf_icmpv6_mip6_flag = -1;
310 static int hf_icmpv6_mip6_flag_m = -1;
311 static int hf_icmpv6_mip6_flag_o = -1;
312 static int hf_icmpv6_mip6_flag_rsv = -1;
313
314 /* RFC3971: SEcure Neighbor Discovery (SEND) */
315 static int hf_icmpv6_send_identifier = -1;
316 static int hf_icmpv6_send_all_components = -1;
317 static int hf_icmpv6_send_component = -1;
318
319 /* RFC 4068/5268/5568: Fast Handovers for Mobile IPv6 ( Mobile IPv6 Fast Handovers ) */
320 static int hf_icmpv6_fmip6_subtype = -1;
321 static int hf_icmpv6_fmip6_hi_flag = -1;
322 static int hf_icmpv6_fmip6_hi_flag_s = -1;
323 static int hf_icmpv6_fmip6_hi_flag_u = -1;
324 static int hf_icmpv6_fmip6_hi_flag_reserved = -1;
325 static int hf_icmpv6_fmip6_identifier = -1;
326
327 /* RFC 4286: Multicast Router Discovery */
328 static int hf_icmpv6_mcast_ra_query_interval = -1;
329 static int hf_icmpv6_mcast_ra_robustness_variable = -1;
330
331 /* RFC 4620: IPv6 Node Information Queries */
332 static int hf_icmpv6_ni_qtype = -1;
333 static int hf_icmpv6_ni_flag = -1;
334 static int hf_icmpv6_ni_flag_g = -1;
335 static int hf_icmpv6_ni_flag_s = -1;
336 static int hf_icmpv6_ni_flag_l = -1;
337 static int hf_icmpv6_ni_flag_c = -1;
338 static int hf_icmpv6_ni_flag_a = -1;
339 static int hf_icmpv6_ni_flag_t = -1;
340 static int hf_icmpv6_ni_flag_rsv = -1;
341 static int hf_icmpv6_ni_nonce = -1;
342 static int hf_icmpv6_ni_query_subject_ipv6 = -1;
343 static int hf_icmpv6_ni_query_subject_fqdn = -1;
344 static int hf_icmpv6_ni_query_subject_ipv4 = -1;
345 static int hf_icmpv6_ni_reply_node_ttl = -1;
346 static int hf_icmpv6_ni_reply_node_name = -1;
347 static int hf_icmpv6_ni_reply_node_address = -1;
348 static int hf_icmpv6_ni_reply_ipv4_address = -1;
349
350 /* RPL: draft-ietf-roll-rpl-19.txt: Routing over Low-Power and Lossy Networks. */
351 static int hf_icmpv6_rpl_dis_flag = -1;
352 static int hf_icmpv6_rpl_dio_instance = -1;
353 static int hf_icmpv6_rpl_dio_version = -1;
354 static int hf_icmpv6_rpl_dio_rank = -1;
355 static int hf_icmpv6_rpl_dio_flag = -1;
356 static int hf_icmpv6_rpl_dio_flag_g = -1;
357 static int hf_icmpv6_rpl_dio_flag_0 = -1;
358 static int hf_icmpv6_rpl_dio_flag_mop = -1;
359 static int hf_icmpv6_rpl_dio_flag_prf = -1;
360 static int hf_icmpv6_rpl_dio_dtsn = -1;
361 static int hf_icmpv6_rpl_dio_dagid = -1;
362 static int hf_icmpv6_rpl_dao_instance = -1;
363 static int hf_icmpv6_rpl_dao_flag = -1;
364 static int hf_icmpv6_rpl_dao_flag_k = -1;
365 static int hf_icmpv6_rpl_dao_flag_d = -1;
366 static int hf_icmpv6_rpl_dao_flag_rsv = -1;
367 static int hf_icmpv6_rpl_dao_sequence = -1;
368 static int hf_icmpv6_rpl_dao_dodagid = -1;
369 static int hf_icmpv6_rpl_daoack_instance = -1;
370 static int hf_icmpv6_rpl_daoack_flag = -1;
371 static int hf_icmpv6_rpl_daoack_flag_d = -1;
372 static int hf_icmpv6_rpl_daoack_flag_rsv = -1;
373 static int hf_icmpv6_rpl_daoack_sequence = -1;
374 static int hf_icmpv6_rpl_daoack_status = -1;
375 static int hf_icmpv6_rpl_daoack_dodagid = -1;
376 static int hf_icmpv6_rpl_cc_instance = -1;
377 static int hf_icmpv6_rpl_cc_flag = -1;
378 static int hf_icmpv6_rpl_cc_flag_r = -1;
379 static int hf_icmpv6_rpl_cc_flag_rsv = -1;
380 static int hf_icmpv6_rpl_cc_nonce = -1;
381 static int hf_icmpv6_rpl_cc_dodagid = -1;
382 static int hf_icmpv6_rpl_cc_destination_counter = -1;
383 static int hf_icmpv6_rpl_secure_flag = -1;
384 static int hf_icmpv6_rpl_secure_flag_t = -1;
385 static int hf_icmpv6_rpl_secure_flag_rsv = -1;
386 static int hf_icmpv6_rpl_secure_algorithm = -1;
387 static int hf_icmpv6_rpl_secure_algorithm_encryption = -1;
388 static int hf_icmpv6_rpl_secure_algorithm_signature = -1;
389 static int hf_icmpv6_rpl_secure_kim = -1;
390 static int hf_icmpv6_rpl_secure_lvl = -1;
391 static int hf_icmpv6_rpl_secure_rsv = -1;
392 static int hf_icmpv6_rpl_secure_counter = -1;
393 static int hf_icmpv6_rpl_secure_key_source = -1;
394 static int hf_icmpv6_rpl_secure_key_index = -1;
395 static int hf_icmpv6_rpl_opt = -1;
396 static int hf_icmpv6_rpl_opt_type = -1;
397 static int hf_icmpv6_rpl_opt_length = -1;
398 static int hf_icmpv6_rpl_opt_reserved = -1;
399 static int hf_icmpv6_rpl_opt_padn = -1;
400 static int hf_icmpv6_rpl_opt_route_prefix_length = -1;
401 static int hf_icmpv6_rpl_opt_route_flag = -1;
402 static int hf_icmpv6_rpl_opt_route_pref = -1;
403 static int hf_icmpv6_rpl_opt_route_reserved = -1;
404 static int hf_icmpv6_rpl_opt_route_lifetime = -1;
405 static int hf_icmpv6_rpl_opt_route_prefix = -1;
406 static int hf_icmpv6_rpl_opt_config_flag = -1;
407 static int hf_icmpv6_rpl_opt_config_reserved = -1;
408 static int hf_icmpv6_rpl_opt_config_auth = -1;
409 static int hf_icmpv6_rpl_opt_config_pcs = -1;
410 static int hf_icmpv6_rpl_opt_config_doublings = -1;
411 static int hf_icmpv6_rpl_opt_config_min_interval = -1;
412 static int hf_icmpv6_rpl_opt_config_redundancy = -1;
413 static int hf_icmpv6_rpl_opt_config_rank_incr = -1;
414 static int hf_icmpv6_rpl_opt_config_hop_rank_inc = -1;
415 static int hf_icmpv6_rpl_opt_config_ocp = -1;
416 static int hf_icmpv6_rpl_opt_config_rsv = -1;
417 static int hf_icmpv6_rpl_opt_config_def_lifetime = -1;
418 static int hf_icmpv6_rpl_opt_config_lifetime_unit = -1;
419 static int hf_icmpv6_rpl_opt_target_flag = -1;
420 static int hf_icmpv6_rpl_opt_target_prefix_length = -1;
421 static int hf_icmpv6_rpl_opt_target_prefix = -1;
422 static int hf_icmpv6_rpl_opt_transit_flag = -1;
423 static int hf_icmpv6_rpl_opt_transit_flag_e = -1;
424 static int hf_icmpv6_rpl_opt_transit_flag_rsv = -1;
425 static int hf_icmpv6_rpl_opt_transit_pathseq = -1;
426 static int hf_icmpv6_rpl_opt_transit_pathctl = -1;
427 static int hf_icmpv6_rpl_opt_transit_pathlifetime = -1;
428 static int hf_icmpv6_rpl_opt_transit_parent = -1;
429 static int hf_icmpv6_rpl_opt_solicited_instance = -1;
430 static int hf_icmpv6_rpl_opt_solicited_flag = -1;
431 static int hf_icmpv6_rpl_opt_solicited_flag_v = -1;
432 static int hf_icmpv6_rpl_opt_solicited_flag_i = -1;
433 static int hf_icmpv6_rpl_opt_solicited_flag_d = -1;
434 static int hf_icmpv6_rpl_opt_solicited_flag_rsv = -1;
435 static int hf_icmpv6_rpl_opt_solicited_dodagid = -1;
436 static int hf_icmpv6_rpl_opt_solicited_version = -1;
437 static int hf_icmpv6_rpl_opt_prefix = -1;
438 static int hf_icmpv6_rpl_opt_prefix_flag = -1;
439 static int hf_icmpv6_rpl_opt_prefix_flag_l = -1;
440 static int hf_icmpv6_rpl_opt_prefix_flag_a = -1;
441 static int hf_icmpv6_rpl_opt_prefix_flag_r = -1;
442 static int hf_icmpv6_rpl_opt_prefix_flag_rsv = -1;
443 static int hf_icmpv6_rpl_opt_prefix_vlifetime = -1;
444 static int hf_icmpv6_rpl_opt_prefix_plifetime = -1;
445 static int hf_icmpv6_rpl_opt_prefix_length = -1;
446 static int hf_icmpv6_rpl_opt_targetdesc = -1;
447
448 static int hf_icmpv6_da_status = -1;
449 static int hf_icmpv6_da_rsv = -1;
450 static int hf_icmpv6_da_lifetime = -1;
451 static int hf_icmpv6_da_eui64 = -1;
452 static int hf_icmpv6_da_raddr = -1;
453
454 static int icmpv6_tap = -1;
455
456 /* Conversation related data */
457 static int hf_icmpv6_resp_in = -1;
458 static int hf_icmpv6_resp_to = -1;
459 static int hf_icmpv6_resptime = -1;
460
461 typedef struct _icmpv6_conv_info_t {
462     emem_tree_t *pdus;
463 } icmpv6_conv_info_t;
464
465 static icmp_transaction_t *transaction_start(packet_info *pinfo, proto_tree *tree, guint32 *key);
466 static icmp_transaction_t *transaction_end(packet_info *pinfo, proto_tree *tree, guint32 *key);
467
468 static gint ett_icmpv6 = -1;
469 static gint ett_icmpv6_opt = -1;
470 static gint ett_icmpv6_mar = -1;
471 static gint ett_icmpv6_flag_prefix = -1;
472 static gint ett_icmpv6_flag_map = -1;
473 static gint ett_icmpv6_flag_route_info = -1;
474 static gint ett_icmpv6_flag_6lowpan = -1;
475 static gint ett_icmpv6_flag_efo = -1;
476 static gint ett_icmpv6_rpl_opt = -1;
477 static gint ett_icmpv6_rpl_flag_routing = -1;
478 static gint ett_icmpv6_rpl_flag_config = -1;
479 static gint ett_icmpv6_rpl_flag_transit = -1;
480 static gint ett_icmpv6_rpl_flag_solicited = -1;
481 static gint ett_icmpv6_rpl_flag_prefix = -1;
482 static gint ett_icmpv6_flag_ni = -1;
483 static gint ett_icmpv6_flag_rr = -1;
484 static gint ett_icmpv6_rr_mp = -1;
485 static gint ett_icmpv6_rr_up = -1;
486 static gint ett_icmpv6_rr_up_flag_mask = -1;
487 static gint ett_icmpv6_rr_up_flag_ra = -1;
488 static gint ett_icmpv6_rr_up_flag = -1;
489 static gint ett_icmpv6_rr_rm = -1;
490 static gint ett_icmpv6_rr_rm_flag = -1;
491 static gint ett_icmpv6_flag_mld = -1;
492 static gint ett_icmpv6_flag_ra = -1;
493 static gint ett_icmpv6_flag_na = -1;
494 static gint ett_icmpv6_flag_mip6 = -1;
495 static gint ett_icmpv6_flag_fmip6 = -1;
496 static gint ett_icmpv6_flag_secure = -1;
497 static gint ett_icmpv6_flag_rpl_dio = -1;
498 static gint ett_icmpv6_flag_rpl_dao = -1;
499 static gint ett_icmpv6_flag_rpl_daoack = -1;
500 static gint ett_icmpv6_flag_rpl_cc = -1;
501 static gint ett_icmpv6_opt_name = -1;
502 static gint ett_icmpv6_cga_param_name = -1;
503
504 static dissector_handle_t ipv6_handle;
505 static dissector_handle_t data_handle;
506
507 #define ICMP6_DST_UNREACH                 1
508 #define ICMP6_PACKET_TOO_BIG              2
509 #define ICMP6_TIME_EXCEEDED               3
510 #define ICMP6_PARAM_PROB                  4
511 #define ICMP6_ECHO_REQUEST              128
512 #define ICMP6_ECHO_REPLY                129
513 #define ICMP6_MEMBERSHIP_QUERY          130
514 #define ICMP6_MEMBERSHIP_REPORT         131
515 #define ICMP6_MEMBERSHIP_REDUCTION      132
516 #define ICMP6_ND_ROUTER_SOLICIT         133
517 #define ICMP6_ND_ROUTER_ADVERT          134
518 #define ICMP6_ND_NEIGHBOR_SOLICIT       135
519 #define ICMP6_ND_NEIGHBOR_ADVERT        136
520 #define ICMP6_ND_REDIRECT               137
521 #define ICMP6_ROUTER_RENUMBERING        138
522 #define ICMP6_NI_QUERY                  139
523 #define ICMP6_NI_REPLY                  140
524 #define ICMP6_IND_SOLICIT               141
525 #define ICMP6_IND_ADVERT                142
526 #define ICMP6_MLDV2_REPORT              143
527 #define ICMP6_MIP6_DHAAD_REQUEST        144
528 #define ICMP6_MIP6_DHAAD_REPLY          145
529 #define ICMP6_MIP6_MPS                  146
530 #define ICMP6_MIP6_MPA                  147
531 #define ICMP6_CERT_PATH_SOL             148
532 #define ICMP6_CERT_PATH_AD              149
533 #define ICMP6_EXPERIMENTAL_MOBILITY     150
534 #define ICMP6_MCAST_ROUTER_ADVERT       151
535 #define ICMP6_MCAST_ROUTER_SOLICIT      152
536 #define ICMP6_MCAST_ROUTER_TERM         153
537 #define ICMP6_FMIPV6_MESSAGES           154
538 #define ICMP6_RPL_CONTROL               155
539 #define ICMP6_6LOWPANND_DAR             156 /* Pending IANA assignment */
540 #define ICMP6_6LOWPANND_DAC             157 /* Pending IANA assignment */
541
542
543 static const value_string icmpv6_type_val[] = {
544     { ICMP6_DST_UNREACH,           "Destination Unreachable" },                         /* [RFC4443] */
545     { ICMP6_PACKET_TOO_BIG,        "Packet Too Big" },                                  /* [RFC4443] */
546     { ICMP6_TIME_EXCEEDED,         "Time Exceeded" },                                   /* [RFC4443] */
547     { ICMP6_PARAM_PROB,            "Parameter Problem" },                               /* [RFC4443] */
548     { 100,                         "Private experimentation" },                         /* [RFC4443] */
549     { 101,                         "Private experimentation" },                         /* [RFC4443] */
550     { 127,                         "Reserved for expansion of ICMPv6 error messages" }, /* [RFC4443] */
551     { ICMP6_ECHO_REQUEST,          "Echo (ping) request" },                             /* [RFC4443] */
552     { ICMP6_ECHO_REPLY,            "Echo (ping) reply" },                               /* [RFC4443] */
553     { ICMP6_MEMBERSHIP_QUERY,      "Multicast Listener Query" },                        /* [RFC2710] */
554     { ICMP6_MEMBERSHIP_REPORT,     "Multicast Listener Report" },                       /* [RFC2710] */
555     { ICMP6_MEMBERSHIP_REDUCTION,  "Multicast Listener Done" },                         /* [RFC2710] */
556     { ICMP6_ND_ROUTER_SOLICIT,     "Router Solicitation" },                             /* [RFC4861] */
557     { ICMP6_ND_ROUTER_ADVERT,      "Router Advertisement" },                            /* [RFC4861] */
558     { ICMP6_ND_NEIGHBOR_SOLICIT,   "Neighbor Solicitation" },                           /* [RFC4861] */
559     { ICMP6_ND_NEIGHBOR_ADVERT,    "Neighbor Advertisement" },                          /* [RFC4861] */
560     { ICMP6_ND_REDIRECT,           "Redirect" },                                        /* [RFC4861] */
561     { ICMP6_ROUTER_RENUMBERING,    "Router Renumbering" },                              /* [RFC2894] */
562     { ICMP6_NI_QUERY,              "Node Information Query" },                          /* [RFC4620] */
563     { ICMP6_NI_REPLY,              "Node Information Reply" },                          /* [RFC4620] */
564     { ICMP6_IND_SOLICIT,           "Inverse Neighbor Discovery Solicitation" },         /* [RFC3122] */
565     { ICMP6_IND_ADVERT,            "Inverse Neighbor Discovery Advertisement" },        /* [RFC3122] */
566     { ICMP6_MLDV2_REPORT,          "Multicast Listener Report Message v2" },            /* [RFC3810] */
567     { ICMP6_MIP6_DHAAD_REQUEST,    "Home Agent Address Discovery Request" },            /* [RFC6275] */
568     { ICMP6_MIP6_DHAAD_REPLY,      "Home Agent Address Discovery Reply" },              /* [RFC6275] */
569     { ICMP6_MIP6_MPS,              "Mobile Prefix Solicitation" },                      /* [RFC6275] */
570     { ICMP6_MIP6_MPA,              "Mobile Prefix Advertisement" },                     /* [RFC6275] */
571     { ICMP6_CERT_PATH_SOL,         "Certification Path Solicitation" },                 /* [RFC3971] */
572     { ICMP6_CERT_PATH_AD,          "Certification Path Advertisement" },                /* [RFC3971] */
573     { ICMP6_EXPERIMENTAL_MOBILITY, "Experimental Mobility" },                           /* [RFC4065] */
574     { ICMP6_MCAST_ROUTER_ADVERT,   "Multicast Router Advertisement" },                  /* [RFC4286] */
575     { ICMP6_MCAST_ROUTER_SOLICIT,  "Multicast Router Solicitation" },                   /* [RFC4286] */
576     { ICMP6_MCAST_ROUTER_TERM,     "Multicast Router Termination" },                    /* [RFC4286] */
577     { ICMP6_FMIPV6_MESSAGES,       "FMIPv6" },                                          /* [RFC5568] */
578     { ICMP6_RPL_CONTROL,           "RPL Control" },                                     /* draft-ieft-roll-rpl-19.txt Pending IANA */
579     { ICMP6_6LOWPANND_DAR,         "Duplicate Address Request"},                        /* draft-ietf-6lowpan-nd-18.txt Pending IANA */
580     { ICMP6_6LOWPANND_DAC,         "Duplicate Address Confirmation"},                   /* draft-ietf-6lowpan-nd-18.txt Pending IANA */
581     { 200,                         "Private experimentation" },                         /* [RFC4443] */
582     { 201,                         "Private experimentation" },                         /* [RFC4443] */
583     { 255,                         "Reserved for expansion of ICMPv6 informational messages" }, /* [RFC4443] */
584     { 0, NULL }
585 };
586
587 #define ICMP6_DST_UNREACH_NOROUTE               0       /* no route to destination */
588 #define ICMP6_DST_UNREACH_ADMIN                 1       /* administratively prohibited */
589 #define ICMP6_DST_UNREACH_NOTNEIGHBOR           2       /* not a neighbor(obsolete) */
590 #define ICMP6_DST_UNREACH_BEYONDSCOPE           2       /* beyond scope of source address */
591 #define ICMP6_DST_UNREACH_ADDR                  3       /* address unreachable */
592 #define ICMP6_DST_UNREACH_NOPORT                4       /* port unreachable */
593 #define ICMP6_DST_UNREACH_INGR_EGR              5       /* source address failed ingress/egress policy */
594 #define ICMP6_DST_UNREACH_REJECT                6       /* reject route to destination */
595 #define ICMP6_DST_UNREACH_ERROR                 7       /* error in Source Routing Header */
596
597 static const value_string icmpv6_unreach_code_val[] = {
598     { ICMP6_DST_UNREACH_NOROUTE,     "no route to destination" },
599     { ICMP6_DST_UNREACH_ADMIN,       "Administratively prohibited" },
600     { ICMP6_DST_UNREACH_BEYONDSCOPE, "Beyond scope of source address" },
601     { ICMP6_DST_UNREACH_ADDR,        "Address unreachable" },
602     { ICMP6_DST_UNREACH_NOPORT,      "Port unreachable" },
603     { ICMP6_DST_UNREACH_INGR_EGR,    "Source address failed ingress/egress policy" },
604     { ICMP6_DST_UNREACH_REJECT,      "Reject route to destination" },
605     { ICMP6_DST_UNREACH_ERROR,       "Error in Source Routing Header" }, /* [draft-ieft-roll-rpl-19.txt] */
606     { 0, NULL }
607 };
608
609 #define ICMP6_TIME_EXCEED_TRANSIT       0       /* ttl==0 in transit */
610 #define ICMP6_TIME_EXCEED_REASSEMBLY    1       /* ttl==0 in reass */
611
612 static const value_string icmpv6_timeex_code_val[] = {
613     { ICMP6_TIME_EXCEED_TRANSIT,    "hop limit exceeded in transit" },
614     { ICMP6_TIME_EXCEED_REASSEMBLY, "fragment reassembly time exceeded" },
615     { 0, NULL }
616 };
617
618 #define ICMP6_PARAMPROB_HEADER                  0       /* erroneous header field */
619 #define ICMP6_PARAMPROB_NEXTHEADER              1       /* unrecognized next header */
620 #define ICMP6_PARAMPROB_OPTION                  2       /* unrecognized option */
621
622 static const value_string icmpv6_paramprob_code_val[] = {
623     { ICMP6_PARAMPROB_HEADER,     "erroneous header field encountered" },
624     { ICMP6_PARAMPROB_NEXTHEADER, "unrecognized Next Header type encountered" },
625     { ICMP6_PARAMPROB_OPTION,     "unrecognized IPv6 option encountered" },
626     { 0, NULL }
627 };
628
629
630 /* RFC2894 - Router Renumbering for IPv6 */
631
632 #define ICMP6_ROUTER_RENUMBERING_COMMAND          0     /* rr command */
633 #define ICMP6_ROUTER_RENUMBERING_RESULT           1     /* rr result */
634 #define ICMP6_ROUTER_RENUMBERING_SEQNUM_RESET   255     /* rr seq num reset */
635
636 static const value_string icmpv6_rr_code_val[] = {
637     { ICMP6_ROUTER_RENUMBERING_COMMAND,      "Command" },
638     { ICMP6_ROUTER_RENUMBERING_RESULT,       "Result" },
639     { ICMP6_ROUTER_RENUMBERING_SEQNUM_RESET, "Sequence number reset" },
640     { 0, NULL }
641 };
642
643 #define RR_FLAG_T       0x80
644 #define RR_FLAG_R       0x40
645 #define RR_FLAG_A       0x20
646 #define RR_FLAG_S       0x10
647 #define RR_FLAG_P       0x08
648 #define RR_FLAG_RSV     0x07
649
650 static const value_string rr_pco_mp_opcode_val[] = {
651     { 1,    "Add" },
652     { 2,    "Change" },
653     { 3,    "Set Global" },
654     { 0,    NULL }
655 };
656
657
658 /* RFC3810 - Multicast Listener Discovery Version 2 (MLDv2) for IPv6 */
659
660 #define MLDV2_PACKET_MINLEN 28
661
662 #define MLD_FLAG_S      0x08
663 #define MLD_FLAG_QRV    0x07
664 #define MLD_FLAG_RSV    0xF0
665
666 static const value_string mldr_record_type_val[] = {
667     { 1, "Include" },
668     { 2, "Exclude" },
669     { 3, "Changed to include" },
670     { 4, "Changed to exclude" },
671     { 5, "Allow new sources" },
672     { 6, "Block old sources" },
673     { 0, NULL }
674 };
675
676 /* RFC 4068/5268/5568: Fast Handovers for Mobile IPv6 ( Mobile IPv6 Fast Handovers ) */
677
678 #define FMIP6_SUBTYPE_RTSOLPR   2
679 #define FMIP6_SUBTYPE_PRRTADV   3
680 #define FMIP6_SUBTYPE_HI        4
681 #define FMIP6_SUBTYPE_HACK      5
682
683 static const value_string fmip6_subtype_val[] = {
684     { FMIP6_SUBTYPE_RTSOLPR,    "Router Solicitation for Proxy Advertisement" },
685     { FMIP6_SUBTYPE_PRRTADV,    "Proxy Router Advertisement" },
686     { FMIP6_SUBTYPE_HI,         "Handover Initiate" },
687     { FMIP6_SUBTYPE_HACK,       "Handover Acknowledge" },
688     { 0,                        NULL }
689 };
690
691 static const value_string fmip6_prrtadv_code_val[] = {
692     { 0,   "MN should use AP-ID, AR-info tuple" },
693     { 1,   "Network Initiated Handover trigger" },
694     { 2,   "No new router information" },
695     { 3,   "Limited new router information" },
696     { 4,   "Unsolicited" },
697     { 0,    NULL }
698 };
699
700 static const value_string fmip6_hi_code_val[] = {
701     { 0,    "FBU sent from previous link" },
702     { 1,    "FBU sent from new link" },
703     { 0,    NULL }
704 };
705
706 static const value_string fmip6_hack_code_val[] = {
707     { 0,    "Handover Accepted, NCoA valid" },
708     { 1,    "Handover Accepted, NCoA not valid" },
709     { 2,    "Handover Accepted, NCoA in use" },
710     { 3,    "Handover Accepted, NCoA assigned" },
711     { 4,    "Handover Accepted, NCoA not assigned" },
712     { 128,  "Handover Not Accepted, reason unspecified" },
713     { 129,  "Administratively prohibited" },
714     { 130,  "Insufficient resources" },
715     { 0,    NULL }
716 };
717
718 #define FMIP6_HI_FLAG_S     0x80
719 #define FMIP6_HI_FLAG_U     0x40
720 #define FMIP6_HI_FLAG_RSV   0x3F
721
722 /* RFC 4620 - IPv6 Node Information Queries */
723
724 #define ICMP6_NI_SUBJ_IPV6      0   /* Query Subject is an IPv6 address */
725 #define ICMP6_NI_SUBJ_FQDN      1   /* Query Subject is a Domain name */
726 #define ICMP6_NI_SUBJ_IPV4      2   /* Query Subject is an IPv4 address */
727
728 #define ICMP6_NI_SUCCESS        0   /* node information successful reply */
729 #define ICMP6_NI_REFUSED        1   /* node information request is refused */
730 #define ICMP6_NI_UNKNOWN        2   /* unknown Qtype */
731
732 #define NI_QTYPE_NOOP           0   /* NOOP  */
733 #define NI_QTYPE_SUPTYPES       1   /* Supported Qtypes (Obso) */
734 #define NI_QTYPE_NODENAME       2   /* Node Name */
735 #define NI_QTYPE_NODEADDR       3   /* Node Addresses */
736 #define NI_QTYPE_IPV4ADDR       4   /* IPv4 Addresses */
737
738 static const value_string ni_query_code_val[] = {
739     { ICMP6_NI_SUBJ_IPV6,   "Query subject = IPv6 addresses" },
740     { ICMP6_NI_SUBJ_FQDN,   "Query subject = DNS name or empty" },
741     { ICMP6_NI_SUBJ_IPV4,   "Query subject = IPv4 addresses" },
742     { 0, NULL }
743 };
744
745 static const value_string ni_reply_code_val[] = {
746     { ICMP6_NI_SUCCESS,   "Successful" },
747     { ICMP6_NI_REFUSED,   "Refused" },
748     { ICMP6_NI_UNKNOWN,   "Unknown query type" },
749     { 0, NULL }
750 };
751 static const value_string ni_qtype_val[] = {
752     { NI_QTYPE_NOOP,            "NOOP" },
753     { NI_QTYPE_SUPTYPES,        "Supported query types (Obsolete)" },
754     { NI_QTYPE_NODENAME,        "Node Name" },
755     { NI_QTYPE_NODEADDR,        "Node addresses" },
756     { NI_QTYPE_IPV4ADDR,        "IPv4 node addresses" },
757     { 0,                        NULL }
758 };
759
760 #define NI_FLAG_G       0x0020
761 #define NI_FLAG_S       0x0010
762 #define NI_FLAG_L       0x0008
763 #define NI_FLAG_C       0x0004
764 #define NI_FLAG_A       0x0002
765 #define NI_FLAG_T       0x0001
766 #define NI_FLAG_RSV     0xFFC0
767
768 static const true_false_string tfs_ni_flag_a = {
769     "All unicast address",
770     "Unicast addresses on the queried interface"
771 };
772
773 #define ND_OPT_SOURCE_LINKADDR           1
774 #define ND_OPT_TARGET_LINKADDR           2
775 #define ND_OPT_PREFIX_INFORMATION        3
776 #define ND_OPT_REDIRECTED_HEADER         4
777 #define ND_OPT_MTU                       5
778 #define ND_OPT_NBMA                      6
779 #define ND_OPT_ADVINTERVAL               7
780 #define ND_OPT_HOMEAGENT_INFO            8
781 #define ND_OPT_SOURCE_ADDRLIST           9
782 #define ND_OPT_TARGET_ADDRLIST          10
783 #define ND_OPT_CGA                      11
784 #define ND_OPT_RSA                      12
785 #define ND_OPT_TIMESTAMP                13
786 #define ND_OPT_NONCE                    14
787 #define ND_OPT_TRUST_ANCHOR             15
788 #define ND_OPT_CERTIFICATE              16
789 #define ND_OPT_IP_ADDRESS_PREFIX        17
790 #define ND_OPT_NEW_ROUTER_PREFIX_INFO   18
791 #define ND_OPT_LINK_LAYER_ADDRESS       19
792 #define ND_OPT_NEIGHBOR_ADV_ACK         20
793 #define ND_OPT_MAP                      23
794 #define ND_OPT_ROUTE_INFO               24
795 #define ND_OPT_RECURSIVE_DNS_SERVER     25
796 #define ND_OPT_FLAGS_EXTENSION          26
797 #define ND_OPT_HANDOVER_KEY_REQUEST     27
798 #define ND_OPT_HANDOVER_KEY_REPLY       28
799 #define ND_OPT_HANDOVER_ASSIST_INFO     29
800 #define ND_OPT_MOBILE_NODE_ID           30
801 #define ND_OPT_DNS_SEARCH_LIST          31
802 #define ND_OPT_PROXY_SIGNATURE          32
803 /* draft-6lowpan-nd types, pending IANA assignment */
804 #define ND_OPT_ADDR_REGISTRATION        131 /* Conflit with RFC6106.. */
805 #define ND_OPT_6LOWPAN_CONTEXT          132 /* Conflit with draft-ietf-csi-proxy-send-05.txt.. */
806 #define ND_OPT_AUTH_BORDER_ROUTER       33
807
808 static const value_string option_vals[] = {
809 /*  1 */   { ND_OPT_SOURCE_LINKADDR,           "Source link-layer address" },
810 /*  2 */   { ND_OPT_TARGET_LINKADDR,           "Target link-layer address" },
811 /*  3 */   { ND_OPT_PREFIX_INFORMATION,        "Prefix information" },
812 /*  4 */   { ND_OPT_REDIRECTED_HEADER,         "Redirected header" },
813 /*  5 */   { ND_OPT_MTU,                       "MTU" },
814 /*  6 */   { ND_OPT_NBMA,                      "NBMA Shortcut Limit Option" },             /* [RFC2491] */
815 /*  7 */   { ND_OPT_ADVINTERVAL,               "Advertisement Interval" },                 /* [RFC6275] */
816 /*  8 */   { ND_OPT_HOMEAGENT_INFO,            "Home Agent Information" },                 /* [RFC6275] */
817 /*  9 */   { ND_OPT_SOURCE_ADDRLIST,           "Source Address List" },                    /* [RFC3122] */
818 /* 10 */   { ND_OPT_TARGET_ADDRLIST,           "Target Address List" },                    /* [RFC3122] */
819 /* 11 */   { ND_OPT_CGA,                       "CGA" },                                    /* [RFC3971] */
820 /* 12 */   { ND_OPT_RSA,                       "RSA Signature" },                          /* [RFC3971] */
821 /* 13 */   { ND_OPT_TIMESTAMP,                 "Timestamp" },                              /* [RFC3971] */
822 /* 14 */   { ND_OPT_NONCE,                     "Nonce" },                                  /* [RFC3971] */
823 /* 15 */   { ND_OPT_TRUST_ANCHOR,              "Trust Anchor" },                           /* [RFC3971] */
824 /* 16 */   { ND_OPT_CERTIFICATE,               "Certificate" },                            /* [RFC3971] */
825 /* 17 */   { ND_OPT_IP_ADDRESS_PREFIX,         "IP Address/Prefix Option" },               /* [RFC5568] */
826 /* 18 */   { ND_OPT_NEW_ROUTER_PREFIX_INFO,    "New Router Prefix Information" },          /* [RFC4068] OBSO */
827 /* 19 */   { ND_OPT_LINK_LAYER_ADDRESS,        "Link-layer Address" },                     /* [RFC5568] */
828 /* 20 */   { ND_OPT_NEIGHBOR_ADV_ACK,          "Neighbor Advertisement Acknowledgment" },  /* [RFC5568] */
829 /* 21-22   Unassigned */
830 /* 23 */   { ND_OPT_MAP,                       "MAP" },                                    /* [RFC4140] */
831 /* 24 */   { ND_OPT_ROUTE_INFO,                "Route Information" },                      /* [RFC4191] */
832 /* 25 */   { ND_OPT_RECURSIVE_DNS_SERVER,      "Recursive DNS Server" },                   /* [RFC6106] */
833 /* 26 */   { ND_OPT_FLAGS_EXTENSION,           "RA Flags Extension" },                     /* [RFC5175] */
834 /* 27 */   { ND_OPT_HANDOVER_KEY_REQUEST,      "Handover Key Request" },                   /* [RFC5269] */
835 /* 28 */   { ND_OPT_HANDOVER_KEY_REPLY,        "Handover Key Reply" },                     /* [RFC5269] */
836 /* 29 */   { ND_OPT_HANDOVER_ASSIST_INFO,      "Handover Assist Information" },            /* [RFC5271] */
837 /* 30 */   { ND_OPT_MOBILE_NODE_ID,            "Mobile Node Identifier Option" },          /* [RFC5271] */
838 /* 31 */   { ND_OPT_DNS_SEARCH_LIST,           "DNS Search List Option" },                 /* [RFC6106] */
839 /* 32 */   { ND_OPT_PROXY_SIGNATURE,           "Proxy Signature (PS)" },                   /* [draft-ietf-csi-proxy-send-05.txt] */
840 /* 31 */   { ND_OPT_ADDR_REGISTRATION,         "Address Registration Option" },            /* [draft-ietf-6lowpan-nd-18.txt] */
841 /* 32 */   { ND_OPT_6LOWPAN_CONTEXT,           "6LoWPAN Context Option" },                 /* [draft-ietf-6lowpan-nd-18.txt] */
842 /* 33 */   { ND_OPT_AUTH_BORDER_ROUTER,        "Authorative Border Router" },              /* [draft-ietf-6lowpan-nd-18.txt] */
843 /* 34-137  Unassigned */
844    { 138,                              "CARD Request" },                           /* [RFC4065] */
845    { 139,                              "CARD Reply" },                             /* [RFC4065] */
846 /* 140-252 Unassigned */
847    { 253,                              "RFC3692-style Experiment 1" },             /* [RFC4727] */
848    { 254,                              "RFC3692-style Experiment 2" },             /* [RFC4727] */
849    { 0,                                NULL }
850 };
851
852 #define ND_RA_FLAG_M    0x80
853 #define ND_RA_FLAG_O    0x40
854 #define ND_RA_FLAG_H    0x20
855 #define ND_RA_FLAG_PRF  0x18
856 #define ND_RA_FLAG_P    0x04
857 #define ND_RA_FLAG_RSV  0x02
858
859 #define ND_NA_FLAG_R    0x80000000
860 #define ND_NA_FLAG_S    0x40000000
861 #define ND_NA_FLAG_O    0x20000000
862 #define ND_NA_FLAG_RSV  0x1FFFFFFF
863
864 static const value_string nd_flag_router_pref[] = {
865     { 1, "High" },
866     { 0, "Medium" },
867     { 3, "Low" },
868     { 2, "Reserved" },
869     { 0, NULL}
870 };
871
872 static const value_string nd_opt_ipa_option_code_val[] = {
873     { 1, "Old Care-of Address" },
874     { 2, "New Care-of Address" },
875     { 3, "NAR's IP address" },
876     { 4, "NAR's Prefix (sent in PrRtAdv)" },
877     { 0, NULL }
878 };
879
880 static const value_string nd_opt_lla_option_code_val[] = {
881     { 0, "Wildcard" },
882     { 1, "Link-layer Address of the New Access Point" },
883     { 2, "Link-layer Address of the MN" },
884     { 3, "Link-layer Address of the NAR" },
885     { 4, "Link-layer Address of the source" },
886     { 5, "The AP belongs to the current interface of the router" },
887     { 6, "No prefix information available" },
888     { 7, "No fast handovers support available" },
889     { 0, NULL }
890 };
891
892 static const value_string nd_opt_hai_option_code_val[] = {
893     { 1, "Access Network Identifier (AN ID)" },
894     { 2, "Sector ID" },
895     { 0, NULL }
896 };
897
898 static const value_string nd_opt_mn_option_code_val[] = {
899     { 1, "NAI" },
900     { 2, "IMSI" },
901     { 0, NULL }
902 };
903 static const value_string nd_opt_naack_status_val[] = {
904     { 1,    "New CoA is invalid, perform address configuration" },
905     { 2,    "New CoA is invalid, use the supplied CoA" },
906     { 3,    "NCoA is invalid, use NAR's IP address as NCoA in FBU" },
907     { 4,    "PCoA supplied, do not send FBU" },
908     { 128,  "LLA is unrecognized" },
909     { 0,    NULL }
910 };
911
912 #define ND_OPT_6CO_FLAG_C        0x10
913 #define ND_OPT_6CO_FLAG_CID      0x0F
914 #define ND_OPT_6CO_FLAG_RESERVED 0xE0
915
916 static const value_string nd_opt_6lowpannd_status_val[] = {
917     { 0, "Success" },
918     { 1, "Duplicate Exists" },
919     { 2, "Neighbor Cache Full" },
920     { 0, NULL }
921 };
922
923 static const value_string icmpv6_option_name_type_vals[] = {
924     { 1,    "DER Encoded X.501 Name" },
925     { 2,    "FQDN" },
926     { 3,    "SHA-1 Subject Key Identifier (SKI)" },
927     { 4,    "SHA-224 Subject Key Identifier (SKI)" },
928     { 5,    "SHA-256 Subject Key Identifier (SKI)" },
929     { 6,    "SHA-384 Subject Key Identifier (SKI)" },
930     { 7,    "SHA-512 Subject Key Identifier (SKI)" },
931     { 253,  "Reserved for Experimental Use" },
932     { 254,  "Reserved for Experimental Use" },
933     { 255,  "Reserved" },
934     { 0,    NULL }
935 };
936
937 static const value_string icmpv6_option_cert_type_vals[] = {
938     { 1,    "X.509v3 Certificate" },
939     { 0,    NULL }
940 };
941
942 /* RFC 4191: Default Router Preferences and More-Specific Routes  */
943
944 #define ND_RA_FLAG_RTPREF_MASK  0x18 /* 00011000 */
945 #define ND_RA_FLAG_RESERV_MASK  0xE7 /* 11100111 */
946
947 /* RFC 5075/5175 : IPv6 Router Advertisement Flags Option */
948 #define FLAGS_EO_M      0x8000
949 #define FLAGS_EO_O      0x4000
950 #define FLAGS_EO_H      0x2000
951 #define FLAGS_EO_PRF    0x1800
952 #define FLAGS_EO_P      0x0400
953 #define FLAGS_EO_RSV    0x02FF
954
955
956
957 /* RPL: draft-ietf-roll-rpl-19.txt: Routing over Low-Power and Lossy Networks. */
958 /* Pending IANA Assignment */
959 /* RPL ICMPv6 Codes */
960 #define ICMP6_RPL_DIS       0x00   /* DODAG Information Solicitation */
961 #define ICMP6_RPL_DIO       0x01   /* DODAG Information Object */
962 #define ICMP6_RPL_DAO       0x02   /* Destination Advertisement Object */
963 #define ICMP6_RPL_DAOACK    0x03   /* Destination Advertisement Object Ack */
964 #define ICMP6_RPL_SDIS      0x80   /* Secure DODAG Information Solicitation */
965 #define ICMP6_RPL_SDIO      0x81   /* Secure DODAG Information Object */
966 #define ICMP6_RPL_SDAO      0x82   /* Secure Destination Advertisement Object */
967 #define ICMP6_RPL_SDAOACK   0x83   /* Secure Destination Advertisement Object Ack */
968 #define ICMP6_RPL_CC        0x8A   /* Consistency Check */
969
970
971 /* RPL DIO Flags */
972 #define RPL_DIO_FLAG_G           0x80
973 #define RPL_DIO_FLAG_0           0x40
974 #define RPL_DIO_FLAG_MOP         0x38
975 #define RPL_DIO_FLAG_PRF         0x07
976
977 /* RPL DAO Flags */
978 #define RPL_DAO_FLAG_K                  0x80
979 #define RPL_DAO_FLAG_D                  0x40
980 #define RPL_DAO_FLAG_RESERVED           0x3F
981
982 /* RPL DAO ACK Flags */
983 #define RPL_DAOACK_FLAG_D               0x80
984 #define RPL_DAOACK_FLAG_RESERVED        0x7F
985
986 /* RPL CC Flags */
987 #define RPL_CC_FLAG_R               0x80
988 #define RPL_CC_FLAG_RESERVED        0x7F
989
990 /* RPL Secure */
991 #define ICMP6_RPL_SECURE    0x80
992
993 #define RPL_SECURE_FLAG_T   0x80
994 #define RPL_SECURE_FLAG_RSV 0x7F
995
996 #define RPL_SECURE_LVL      0x07
997 #define RPL_SECURE_KIM      0xC0
998 #define RPL_SECURE_RSV      0x38
999
1000 /* RPL Option Bitfields */
1001 #define RPL_OPT_PREFIX_FLAG_L           0x80
1002 #define RPL_OPT_PREFIX_FLAG_A           0x40
1003 #define RPL_OPT_PREFIX_FLAG_R           0x20
1004 #define RPL_OPT_PREFIX_FLAG_RSV         0x1F
1005 #define RPL_OPT_ROUTE_PREFERENCE        0x18
1006 #define RPL_OPT_ROUTE_RESERVED          0xE7
1007 #define RPL_OPT_CONFIG_FLAG_AUTH        0x08
1008 #define RPL_OPT_CONFIG_FLAG_PCS         0x07
1009 #define RPL_OPT_CONFIG_FLAG_RESERVED    0xF0
1010 #define RPL_OPT_TRANSIT_FLAG_E          0x80
1011 #define RPL_OPT_TRANSIT_FLAG_RSV        0x7F
1012 #define RPL_OPT_SOLICITED_FLAG_V        0x80
1013 #define RPL_OPT_SOLICITED_FLAG_I        0x40
1014 #define RPL_OPT_SOLICITED_FLAG_D        0x20
1015 #define RPL_OPT_SOLICITED_FLAG_RSV      0x1F
1016
1017 static const value_string rpl_dio_map_val[] = {
1018     { 0, "No downward routes maintained by RPL" },
1019     { 1, "Non storing mode" },
1020     { 2, "Storing without multicast support" },
1021     { 3, "Storing with multicast support" },
1022     { 0, NULL }
1023 };
1024 static const value_string rpl_code_val[] = {
1025     { ICMP6_RPL_DIS,    "DODAG Information Solicitation" },
1026     { ICMP6_RPL_DIO,    "DODAG Information Object" },
1027     { ICMP6_RPL_DAO,    "Destination Advertisement Object" },
1028     { ICMP6_RPL_DAOACK, "Destination Advertisement Object Acknowledgement" },
1029     { ICMP6_RPL_SDIS,   "Secure DODAG Information Solicitation" },
1030     { ICMP6_RPL_SDIO,   "Secure DODAG Information Object" },
1031     { ICMP6_RPL_SDAO,   "Secure Destination Advertisement Object" },
1032     { ICMP6_RPL_SDAOACK,"Secure Destination Advertisement Object Acknowledgement" },
1033     { ICMP6_RPL_CC,     "Consistency Check" },
1034     { 0, NULL }
1035 };
1036
1037 static const value_string rpl_secure_algorithm_encryption_val[] = {
1038     { 0, "CCM with AES-128" },
1039     { 0, NULL }
1040 };
1041
1042 static const value_string rpl_secure_algorithm_signature_val[] = {
1043     { 0, "RSA with SHA-256" },
1044     { 0, NULL }
1045 };
1046 /* RPL Option Types */
1047 /* Pending IANA Assignment */
1048 #define RPL_OPT_PAD1        0   /* 1-byte padding */
1049 #define RPL_OPT_PADN        1   /* n-byte padding */
1050 #define RPL_OPT_METRIC      2   /* DAG metric container */
1051 #define RPL_OPT_ROUTING     3   /* Routing Information */
1052 #define RPL_OPT_CONFIG      4   /* DAG configuration */
1053 #define RPL_OPT_TARGET      5   /* RPL Target */
1054 #define RPL_OPT_TRANSIT     6   /* Transit */
1055 #define RPL_OPT_SOLICITED   7   /* Solicited Information */
1056 #define RPL_OPT_PREFIX      8   /* Destination prefix */
1057 #define RPL_OPT_TARGETDESC  9   /* RPL Target Descriptor */
1058
1059 static const value_string rpl_option_vals[] = {
1060     { RPL_OPT_PAD1,       "1-byte padding" },
1061     { RPL_OPT_PADN,       "n-byte padding" },
1062     { RPL_OPT_METRIC,     "Metric container" },
1063     { RPL_OPT_ROUTING,    "Routing"},
1064     { RPL_OPT_CONFIG,     "DODAG configuration" },
1065     { RPL_OPT_TARGET,     "RPL Target" },
1066     { RPL_OPT_TRANSIT,    "Transit Information" },
1067     { RPL_OPT_SOLICITED,  "Solicited Information"},
1068     { RPL_OPT_PREFIX,     "Prefix Information"},
1069     { RPL_OPT_TARGETDESC, "RPL Target Descriptor"},
1070     { 0, NULL }
1071 };
1072
1073
1074
1075 static int
1076 dissect_contained_icmpv6(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
1077 {
1078     gboolean save_in_error_pkt;
1079     tvbuff_t *next_tvb;
1080
1081     /* Save the current value of the "we're inside an error packet"
1082        flag, and set that flag; subdissectors may treat packets
1083        that are the payload of error packets differently from
1084        "real" packets. */
1085     save_in_error_pkt = pinfo->flags.in_error_pkt;
1086     pinfo->flags.in_error_pkt = TRUE;
1087
1088     next_tvb = tvb_new_subset_remaining(tvb, offset);
1089
1090     /* tiny sanity check */
1091     if ((tvb_get_guint8(tvb, offset) & 0xf0) == 0x60) {
1092         /* The contained packet is an IPv6 datagram; dissect it. */
1093         offset += call_dissector(ipv6_handle, next_tvb, pinfo, tree);
1094     } else
1095         offset += call_dissector(data_handle, next_tvb, pinfo, tree);
1096
1097     /* Restore the "we're inside an error packet" flag. */
1098     pinfo->flags.in_error_pkt = save_in_error_pkt;
1099
1100     return offset;
1101 }
1102
1103
1104 /* ======================================================================= */
1105 static conversation_t *_find_or_create_conversation(packet_info *pinfo)
1106 {
1107     conversation_t *conv = NULL;
1108
1109     /* Have we seen this conversation before? */
1110     conv = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst,
1111         pinfo->ptype, 0, 0, 0);
1112     if ( conv == NULL )
1113     {
1114         /* No, this is a new conversation. */
1115         conv = conversation_new(pinfo->fd->num, &pinfo->src, &pinfo->dst,
1116             pinfo->ptype, 0, 0, 0);
1117     }
1118     return (conv);
1119 }
1120
1121 /* ======================================================================= */
1122 static icmp_transaction_t *transaction_start(packet_info *pinfo, proto_tree *tree, guint32 *key)
1123 {
1124     conversation_t *conversation;
1125     icmpv6_conv_info_t *icmpv6_info;
1126     icmp_transaction_t *icmpv6_trans;
1127     emem_tree_key_t icmpv6_key[2];
1128     proto_item *it;
1129
1130     /* Handle the conversation tracking */
1131     conversation = _find_or_create_conversation(pinfo);
1132     icmpv6_info = conversation_get_proto_data(conversation, proto_icmpv6);
1133     if ( icmpv6_info == NULL )
1134     {
1135         icmpv6_info = se_alloc(sizeof(icmpv6_conv_info_t));
1136         icmpv6_info->pdus = se_tree_create_non_persistent(
1137             EMEM_TREE_TYPE_RED_BLACK, "icmpv6_pdus");
1138         conversation_add_proto_data(conversation, proto_icmpv6, icmpv6_info);
1139     }
1140
1141     icmpv6_key[0].length = 2;
1142     icmpv6_key[0].key = key;
1143     icmpv6_key[1].length = 0;
1144     icmpv6_key[1].key = NULL;
1145     if ( !PINFO_FD_VISITED(pinfo) )
1146     {
1147         icmpv6_trans = se_alloc(sizeof(icmp_transaction_t));
1148         icmpv6_trans->rqst_frame = PINFO_FD_NUM(pinfo);
1149         icmpv6_trans->resp_frame = 0;
1150         icmpv6_trans->rqst_time = pinfo->fd->abs_ts;
1151         icmpv6_trans->resp_time = 0.0;
1152         se_tree_insert32_array(icmpv6_info->pdus, icmpv6_key, (void *)icmpv6_trans);
1153     }
1154     else /* Already visited this frame */
1155         icmpv6_trans = se_tree_lookup32_array(icmpv6_info->pdus, icmpv6_key);
1156
1157     if ( icmpv6_trans == NULL )
1158         return (NULL);
1159
1160     /* Print state tracking in the tree */
1161     if ( tree && icmpv6_trans->resp_frame &&
1162         (icmpv6_trans->rqst_frame == PINFO_FD_NUM(pinfo)) )
1163     {
1164         it = proto_tree_add_uint(tree, hf_icmpv6_resp_in, NULL, 0, 0,
1165             icmpv6_trans->resp_frame);
1166         PROTO_ITEM_SET_GENERATED(it);
1167     }
1168
1169     return (icmpv6_trans);
1170
1171 } /* transaction_start() */
1172
1173 /* ======================================================================= */
1174 static icmp_transaction_t *transaction_end(packet_info *pinfo, proto_tree *tree, guint32 *key)
1175 {
1176     conversation_t *conversation;
1177     icmpv6_conv_info_t *icmpv6_info;
1178     icmp_transaction_t *icmpv6_trans;
1179     emem_tree_key_t icmpv6_key[2];
1180     proto_item *it;
1181     nstime_t ns;
1182
1183     conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst,
1184         pinfo->ptype, 0, 0, 0);
1185     if ( conversation == NULL )
1186         return (NULL);
1187
1188     icmpv6_info = conversation_get_proto_data(conversation, proto_icmpv6);
1189     if ( icmpv6_info == NULL )
1190         return (NULL);
1191
1192     icmpv6_key[0].length = 2;
1193     icmpv6_key[0].key = key;
1194     icmpv6_key[1].length = 0;
1195     icmpv6_key[1].key = NULL;
1196     icmpv6_trans = se_tree_lookup32_array(icmpv6_info->pdus, icmpv6_key);
1197     if ( icmpv6_trans == NULL )
1198         return (NULL);
1199
1200     /* Print state tracking in the tree */
1201     if ( icmpv6_trans->rqst_frame &&
1202         (icmpv6_trans->rqst_frame < PINFO_FD_NUM(pinfo)) &&
1203         ((icmpv6_trans->resp_frame == 0) ||
1204         (icmpv6_trans->resp_frame == PINFO_FD_NUM(pinfo))) )
1205     {
1206         icmpv6_trans->resp_frame = PINFO_FD_NUM(pinfo);
1207         if ( tree )
1208         {
1209             it = proto_tree_add_uint(tree, hf_icmpv6_resp_to, NULL, 0, 0,
1210                 icmpv6_trans->rqst_frame);
1211             PROTO_ITEM_SET_GENERATED(it);
1212         }
1213
1214         nstime_delta(&ns, &pinfo->fd->abs_ts, &icmpv6_trans->rqst_time);
1215         icmpv6_trans->resp_time = nstime_to_msec(&ns);
1216         if ( tree )
1217         {
1218             it = proto_tree_add_double_format_value(tree, hf_icmpv6_resptime, NULL,
1219                 0, 0, icmpv6_trans->resp_time, "%.3f ms", icmpv6_trans->resp_time);
1220             PROTO_ITEM_SET_GENERATED(it);
1221         }
1222     }
1223
1224     return (icmpv6_trans);
1225
1226 } /* transaction_end() */
1227
1228 static int
1229 dissect_icmpv6_nd_opt(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
1230 {
1231     proto_tree *icmp6opt_tree, *flag_tree;
1232     proto_item *ti, *ti_opt, *ti_opt_len;
1233     guint8 opt_type;
1234     int opt_len;
1235     int opt_offset;
1236
1237     while ((int)tvb_reported_length(tvb) > offset) {
1238         /* there are more options */
1239
1240         /* ICMPv6 Option */
1241         opt_len = tvb_get_guint8(tvb, offset + 1) * 8;
1242         ti = proto_tree_add_item(tree, hf_icmpv6_opt, tvb, offset, opt_len, ENC_NA);
1243         icmp6opt_tree = proto_item_add_subtree(ti, ett_icmpv6_opt);
1244         opt_offset = offset;
1245
1246         /* Option type */
1247         proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_type, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
1248         opt_type = tvb_get_guint8(tvb, opt_offset);
1249         opt_offset += 1;
1250
1251         /* Add option name to option root label */
1252         proto_item_append_text(ti, " (%s", val_to_str(opt_type, option_vals, "Unknown %d"));
1253
1254         /* Option length */
1255         ti_opt_len = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_length, tvb,opt_offset, 1, ENC_BIG_ENDIAN);
1256         opt_offset += 1;
1257
1258         /* Add length value in bytes */
1259         proto_item_append_text(ti_opt_len, " (%i bytes)", opt_len);
1260
1261         if(opt_len == 0){
1262             expert_add_info_format(pinfo, ti_opt_len, PI_MALFORMED, PI_ERROR, "Invalid option length (Zero)");
1263             return opt_offset;
1264         }
1265
1266         /* decode... */
1267         switch (opt_type) {
1268             case ND_OPT_SOURCE_LINKADDR: /* Source Link-layer Address (1) */
1269             {
1270                 const gchar *link_str;
1271                 /* if the opt len is 8, the Link Addr is MAC Address */
1272                 if(opt_len == 8){
1273                     proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_linkaddr_mac, tvb, opt_offset, 6, ENC_NA);
1274                     ti_opt = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_src_linkaddr_mac, tvb, opt_offset, 6, ENC_NA);
1275                     PROTO_ITEM_SET_HIDDEN(ti_opt);
1276
1277                     link_str = tvb_ether_to_str(tvb, opt_offset);
1278                     col_append_fstr(pinfo->cinfo, COL_INFO, " from %s", link_str);
1279                     proto_item_append_text(ti, " : %s", link_str);
1280                 /* if the opt len is 16 and the 6 last bytes is 0n the Link Addr is EUI64 Address */
1281                 }else if(opt_len == 16 && tvb_get_ntohl(tvb, opt_offset + 8) == 0 && tvb_get_ntohs(tvb, opt_offset + 12) == 0){
1282                     proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_linkaddr_eui64, tvb, opt_offset, 8, ENC_BIG_ENDIAN);
1283                     ti_opt = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_src_linkaddr_eui64, tvb, opt_offset, 8, ENC_BIG_ENDIAN);
1284                     PROTO_ITEM_SET_HIDDEN(ti_opt);
1285
1286                     /* Padding: 6 bytes */
1287                     proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_padding, tvb, opt_offset + 8, 6, ENC_NA);
1288
1289                     link_str = tvb_eui64_to_str(tvb, opt_offset, ENC_BIG_ENDIAN);
1290                     col_append_fstr(pinfo->cinfo, COL_INFO, " from %s", link_str);
1291                     proto_item_append_text(ti, " : %s", link_str);
1292                 }else{
1293                     proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_linkaddr, tvb, opt_offset, opt_len-2, ENC_NA);
1294                     ti_opt = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_src_linkaddr, tvb, opt_offset, opt_len-2, ENC_NA);
1295                     PROTO_ITEM_SET_HIDDEN(ti_opt);
1296                 }
1297                 opt_offset += opt_len;
1298
1299                 break;
1300             }
1301             case ND_OPT_TARGET_LINKADDR: /* Target Link-layer Address (2) */
1302             {
1303                 const gchar *link_str;
1304                 /* if the opt len is 8, the Link Addr is MAC Address */
1305                 if(opt_len == 8){
1306                     proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_linkaddr_mac, tvb, opt_offset, 6, ENC_NA);
1307                     ti_opt = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_target_linkaddr_mac, tvb, opt_offset, 6, ENC_NA);
1308                     PROTO_ITEM_SET_HIDDEN(ti_opt);
1309
1310                     link_str = tvb_ether_to_str(tvb, opt_offset);
1311                     col_append_fstr(pinfo->cinfo, COL_INFO, " is at %s", link_str);
1312                     proto_item_append_text(ti, " : %s", link_str);
1313
1314                 /* if the opt len is 16 and the 6 last bytes is 0n the Link Addr is EUI64 Address */
1315                 }else if(opt_len == 16 && tvb_get_ntohl(tvb, opt_offset + 8) == 0 && tvb_get_ntohs(tvb, opt_offset + 12) == 0){
1316                     proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_linkaddr_eui64, tvb, opt_offset, 8, ENC_BIG_ENDIAN);
1317                     ti_opt = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_target_linkaddr_eui64, tvb, opt_offset, 8, ENC_BIG_ENDIAN);
1318                     PROTO_ITEM_SET_HIDDEN(ti_opt);
1319
1320                     /* Padding: 6 bytes */
1321                     proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_padding, tvb, opt_offset + 8, 6, ENC_NA);
1322
1323                     link_str = tvb_eui64_to_str(tvb, opt_offset, ENC_BIG_ENDIAN);
1324                     col_append_fstr(pinfo->cinfo, COL_INFO, " from %s", link_str);
1325                     proto_item_append_text(ti, " : %s", link_str);
1326                 }else{
1327                     proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_linkaddr, tvb, opt_offset, opt_len-2, ENC_NA);
1328                     ti_opt = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_target_linkaddr, tvb, opt_offset, opt_len-2, ENC_NA);
1329                     PROTO_ITEM_SET_HIDDEN(ti_opt);
1330                 }
1331                 opt_offset += opt_len;
1332                 break;
1333             }
1334             case ND_OPT_PREFIX_INFORMATION: /* Prefix Information (3) */
1335             {
1336                 guint8 prefix_len;
1337                 /* RFC 4861 */
1338
1339                 /* Prefix Length */
1340                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_prefix_len, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
1341                 prefix_len = tvb_get_guint8(tvb, opt_offset);
1342                 opt_offset += 1;
1343
1344                 /* Flags */
1345                 ti_opt = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_prefix_flag, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
1346                 flag_tree = proto_item_add_subtree(ti_opt, ett_icmpv6_flag_prefix);
1347
1348                 proto_tree_add_item(flag_tree, hf_icmpv6_opt_prefix_flag_l, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
1349                 proto_tree_add_item(flag_tree, hf_icmpv6_opt_prefix_flag_a, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
1350                 proto_tree_add_item(flag_tree, hf_icmpv6_opt_prefix_flag_r, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
1351                 proto_tree_add_item(flag_tree, hf_icmpv6_opt_prefix_flag_reserved, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
1352                 opt_offset += 1;
1353
1354                 /* Prefix Valid Lifetime */
1355                 ti_opt = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_prefix_valid_lifetime, tvb, opt_offset, 4, ENC_BIG_ENDIAN);
1356
1357                 switch(tvb_get_ntohl(tvb, opt_offset)){
1358                     case 0xffffffff:
1359                         proto_item_append_text(ti_opt, " (Infinity)");
1360                         break;
1361                     default:
1362                         break;
1363                 }
1364                 opt_offset += 4;
1365
1366                 /* Prefix Preferred Lifetime */
1367                 ti_opt = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_prefix_preferred_lifetime, tvb, opt_offset, 4, ENC_BIG_ENDIAN);
1368
1369                 switch(tvb_get_ntohl(tvb, opt_offset)){
1370                     case 0xffffffff:
1371                         proto_item_append_text(ti_opt, " (Infinity)");
1372                         break;
1373                     default:
1374                         break;
1375                 }
1376                 opt_offset += 4;
1377
1378                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_reserved, tvb, opt_offset, 4, ENC_NA);
1379                 opt_offset += 4;
1380
1381                 /* Prefix */
1382                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_prefix, tvb, opt_offset, 16, ENC_NA);
1383                 proto_item_append_text(ti, " : %s/%d", tvb_ip6_to_str(tvb, opt_offset), prefix_len);
1384                 opt_offset += 16;
1385
1386                 break;
1387             }
1388             case ND_OPT_REDIRECTED_HEADER: /* Redirected Header (4) */
1389
1390                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_reserved, tvb, opt_offset, 6, ENC_NA);
1391                 opt_offset += 6;
1392
1393                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_redirected_packet, tvb, opt_offset, -1, ENC_NA);
1394
1395                 offset = dissect_contained_icmpv6(tvb, opt_offset, pinfo, icmp6opt_tree);
1396                 break;
1397             case ND_OPT_MTU: /* MTU (5) */
1398
1399                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_reserved, tvb, opt_offset, 2, ENC_NA);
1400                 opt_offset += 2;
1401
1402                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_mtu, tvb, opt_offset, 4, ENC_BIG_ENDIAN);
1403                 proto_item_append_text(ti, " : %d", tvb_get_ntohl(tvb, opt_offset));
1404                 opt_offset += 4;
1405                 break;
1406             case ND_OPT_NBMA: /* NBMA Shortcut Limit Option (6) */
1407
1408                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_nbma_shortcut_limit, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
1409                 proto_item_append_text(ti, " : %d", tvb_get_guint8(tvb, opt_offset));
1410
1411                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_reserved, tvb, opt_offset, 1, ENC_NA);
1412                 opt_offset += 1;
1413
1414                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_reserved, tvb, opt_offset, 4, ENC_NA);
1415                 opt_offset += 4;
1416
1417                 break;
1418             case ND_OPT_ADVINTERVAL: /* Advertisement Interval Option (7) */
1419
1420                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_reserved, tvb, opt_offset, 2, ENC_NA);
1421                 opt_offset += 2;
1422
1423                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_advertisement_interval, tvb, opt_offset, 4, ENC_BIG_ENDIAN);
1424                 proto_item_append_text(ti, " : %d", tvb_get_ntohl(tvb, opt_offset));
1425                 opt_offset += 4;
1426
1427                 break;
1428             case ND_OPT_HOMEAGENT_INFO: /* Home Agent Information Option (8) */
1429             {
1430
1431                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_reserved, tvb, opt_offset, 2, ENC_NA);
1432                 opt_offset += 2;
1433
1434                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_home_agent_preference, tvb, opt_offset, 2, ENC_BIG_ENDIAN);
1435                 opt_offset += 2;
1436
1437                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_home_agent_lifetime, tvb, opt_offset, 2, ENC_BIG_ENDIAN);
1438                 opt_offset += 2;
1439                 break;
1440             }
1441             case  ND_OPT_SOURCE_ADDRLIST: /* Source Address List (9) */
1442             case  ND_OPT_TARGET_ADDRLIST: /* Target Address List (10)*/
1443             {
1444                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_reserved, tvb, opt_offset, 6, ENC_NA);
1445                 opt_offset += 6;
1446
1447                 while(opt_offset < (offset + opt_len) ) {
1448                     proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_ipv6_address, tvb, opt_offset, 16, ENC_NA);
1449                     proto_item_append_text(ti, " %s", tvb_ip6_to_str(tvb, opt_offset));
1450                     opt_offset += 16;
1451                 }
1452                 break;
1453             }
1454             case ND_OPT_CGA: /* CGA Option (11) */
1455             {
1456                 proto_tree *cga_tree;
1457                 proto_item *cga_item;
1458                 guint16 ext_data_len;
1459                 guint8 padd_length;
1460                 int par_len;
1461                 asn1_ctx_t asn1_ctx;
1462
1463                 /* Pad Length */
1464                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_cga_pad_len, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
1465                 padd_length = tvb_get_guint8(tvb, opt_offset);
1466                 opt_offset += 1;
1467
1468                 /* Reserved 8 bits */
1469
1470                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_reserved, tvb, opt_offset, 1, ENC_NA);
1471                 opt_offset += 1;
1472
1473                 /* CGA Parameters A variable-length field containing the CGA Parameters data
1474                  * structure described in Section 4 of
1475                  * "Cryptographically Generated Addresses (CGA)", RFC3972.
1476                  */
1477                 par_len = opt_len -4 -padd_length;
1478                 cga_item = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_cga, tvb, opt_offset, par_len, ENC_NA);
1479                 par_len += opt_offset;
1480
1481                 cga_tree = proto_item_add_subtree(cga_item, ett_icmpv6_cga_param_name);
1482                 proto_tree_add_item(cga_tree, hf_icmpv6_opt_cga_modifier, tvb, opt_offset, 16, ENC_NA);
1483                 opt_offset += 16;
1484
1485                 proto_tree_add_item(cga_tree, hf_icmpv6_opt_cga_subnet_prefix, tvb, opt_offset, 8, ENC_NA);
1486                 opt_offset += 8;
1487
1488                 proto_tree_add_item(cga_tree ,hf_icmpv6_opt_cga_count, tvb, opt_offset, 1, ENC_NA);
1489                 opt_offset += 1;
1490
1491                 asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo);
1492                 opt_offset = dissect_x509af_SubjectPublicKeyInfo(FALSE, tvb, opt_offset, &asn1_ctx, cga_tree, -1);
1493
1494                 /* Process RFC 4581*/
1495                 while (opt_offset < par_len) {
1496                     proto_tree_add_item(cga_tree, hf_icmpv6_opt_cga_ext_type, tvb, opt_offset, 2, ENC_BIG_ENDIAN);
1497                     opt_offset += 2;
1498
1499                     ext_data_len = tvb_get_ntohs(tvb, opt_offset);
1500                     proto_tree_add_item(cga_tree, hf_icmpv6_opt_cga_ext_length, tvb, opt_offset, 2, ENC_BIG_ENDIAN);
1501                     opt_offset += 2;
1502
1503                     proto_tree_add_item(cga_tree, hf_icmpv6_opt_cga_ext_data, tvb, opt_offset, ext_data_len, ENC_NA);
1504                     opt_offset += ext_data_len;
1505                 }
1506
1507                 /* Padding */
1508                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_padding, tvb, opt_offset, padd_length, ENC_NA);
1509                 opt_offset += padd_length;
1510                 break;
1511             }
1512             case ND_OPT_RSA: /* RSA Signature Option (12) */
1513             {
1514                 int par_len;
1515                 /*5.2.  RSA Signature Option */
1516                 /* Reserved, A 16-bit field reserved for future use. */
1517                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_reserved, tvb, opt_offset, 2, ENC_NA);
1518                 opt_offset = opt_offset + 2;
1519
1520                 /* Key Hash
1521                  * A 128-bit field containing the most significant (leftmost) 128
1522                  * bits of a SHA-1 [14] hash of the public key used for constructing
1523                  * the signature.
1524                  */
1525                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_rsa_key_hash, tvb, opt_offset, 16, ENC_NA);
1526                 opt_offset = opt_offset + 16;
1527
1528                 /* Digital Signature */
1529                 par_len = opt_len - 20;
1530                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_digital_signature_padding , tvb, opt_offset, par_len, ENC_NA);
1531                 opt_offset += par_len;
1532
1533                 /* Padding */
1534                 /* TODO: Calculate padding length and exlude from the signature */
1535                 break;
1536             }
1537             case ND_OPT_TIMESTAMP: /* Timestamp Option (13) */
1538                 /* Reserved A 48-bit field reserved for future use. */
1539                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_reserved, tvb, opt_offset, 6, ENC_NA);
1540                 opt_offset += 6;
1541
1542                 /* Timestamp
1543                  * A 64-bit unsigned integer field containing a timestamp.  The value
1544                  * indicates the number of seconds since January 1, 1970, 00:00 UTC,
1545                  * by using a fixed point format.  In this format, the integer number
1546                  * of seconds is contained in the first 48 bits of the field, and the
1547                  * remaining 16 bits indicate the number of 1/64K fractions of a
1548                  * second.
1549                  */
1550                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_timestamp, tvb, opt_offset + 2, 4, ENC_TIME_TIMESPEC|ENC_BIG_ENDIAN);
1551                 opt_offset += 8;
1552                 break;
1553             case ND_OPT_NONCE: /* Nonce option (14) */
1554
1555                 /* 5.3.2.  Nonce Option */
1556                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_nonce, tvb, opt_offset, opt_len - 2, ENC_NA);
1557                 opt_offset += opt_len -2;
1558                 break;
1559             case ND_OPT_TRUST_ANCHOR: /* Trust Anchor Option (15) */
1560             {
1561                 proto_tree *name_tree;
1562                 proto_item *name_item;
1563                 guint8 name_type;
1564                 guint8 padd_length;
1565                 int par_len;
1566                 asn1_ctx_t asn1_ctx;
1567
1568                 /* Name Type */
1569                 name_type = tvb_get_guint8(tvb, opt_offset);
1570                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_name_type, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
1571                 opt_offset += 1;
1572
1573                 /* Pad Length */
1574                 padd_length = tvb_get_guint8(tvb, opt_offset);
1575                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_cga_pad_len, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
1576                 opt_offset += 1;
1577
1578                 par_len = opt_len - 4 - padd_length;
1579
1580                 switch (name_type){
1581                     case 1:
1582                         /* DER Encoded X.501 Name */
1583                         name_item = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_name_x501, tvb, opt_offset, par_len, ENC_NA);
1584                         name_tree = proto_item_add_subtree(name_item, ett_icmpv6_opt_name);
1585                         asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo);
1586                         dissect_x509if_Name(FALSE, tvb, opt_offset, &asn1_ctx, name_tree, hf_icmpv6_x509if_Name);
1587                         break;
1588                     case 2:
1589                         /* FQDN */
1590                         proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_name_fqdn, tvb, opt_offset, par_len, ENC_ASCII|ENC_NA);
1591                         break;
1592                     default:
1593                         break;
1594                 }
1595                 opt_offset += par_len;
1596
1597                 /* Padding */
1598                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_padding, tvb, opt_offset, padd_length, ENC_NA);
1599                 opt_offset += padd_length;
1600
1601                 break;
1602             }
1603             case ND_OPT_CERTIFICATE: /* Certificate Option (16) */
1604             {
1605                 guint8 cert_type;
1606                 guint8 padd_length;
1607                 asn1_ctx_t asn1_ctx;
1608
1609                 /* Cert Type */
1610                 cert_type = tvb_get_guint8(tvb, opt_offset);
1611                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_cert_type, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
1612                 opt_offset += 1;
1613
1614                 /* Reserved */
1615                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_reserved, tvb, opt_offset, 1, ENC_NA);
1616                 opt_offset += 1;
1617
1618                 /* Certificate */
1619
1620                 if(cert_type == 1){
1621                     asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo);
1622                     opt_offset = dissect_x509af_Certificate(FALSE, tvb, opt_offset, &asn1_ctx, icmp6opt_tree, hf_icmpv6_x509af_Certificate);
1623                     padd_length = opt_len - (opt_offset - offset);
1624                     /* Padding */
1625                     proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_padding, tvb, opt_offset, padd_length, ENC_NA);
1626                     opt_offset += padd_length;
1627                 }else{
1628                     padd_length = opt_len - 4;
1629                     proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_certificate_padding, tvb, opt_offset, padd_length, ENC_NA);
1630                     opt_offset += padd_length;
1631                 }
1632                 break;
1633
1634             }
1635             case ND_OPT_IP_ADDRESS_PREFIX: /* IP Address/Prefix Option (17) */
1636             {
1637                 guint8 prefix_len;
1638
1639                 /* Option-code */
1640                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_ipa_option_code, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
1641                 opt_offset += 1;
1642
1643                 /* Prefix Len */
1644                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_ipa_prefix_len, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
1645                 prefix_len = tvb_get_guint8(tvb, opt_offset);
1646                 opt_offset += 1;
1647
1648                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_reserved, tvb, opt_offset, 4, ENC_NA);
1649                 opt_offset += 4;
1650
1651                 /* IPv6 Address */
1652                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_ipa_ipv6_address, tvb, opt_offset, 16, ENC_NA);
1653                 proto_item_append_text(ti, " %s/%d", tvb_ip6_to_str(tvb, opt_offset), prefix_len);
1654                 opt_offset += 16;
1655
1656                 break;
1657             }
1658             case ND_OPT_NEW_ROUTER_PREFIX_INFO: /* New Router Prefix Information Option (18) OBSO... */
1659             {
1660
1661                 guint8 prefix_len;
1662
1663                 /* Option-code */
1664                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_nrpi_option_code, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
1665                 opt_offset += 1;
1666
1667                 /* Prefix Len */
1668                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_nrpi_prefix_len, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
1669                 prefix_len = tvb_get_guint8(tvb, opt_offset);
1670                 opt_offset += 1;
1671
1672                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_reserved, tvb, opt_offset, 4, ENC_NA);
1673                 opt_offset += 4;
1674
1675                 /* Prefix */
1676                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_nrpi_prefix, tvb, opt_offset, 16, ENC_NA);
1677                 proto_item_append_text(ti, " %s/%d", tvb_ip6_to_str(tvb, opt_offset), prefix_len);
1678                 opt_offset += 16;
1679
1680                 break;
1681             }
1682             case ND_OPT_LINK_LAYER_ADDRESS: /* Link-layer Address Option (19) */
1683             {
1684                 /* Option-Code */
1685                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_lla_option_code, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
1686                 opt_offset += 1;
1687
1688                 /* Link Layer Address */
1689                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_lla_bytes, tvb, opt_offset, opt_len-3, ENC_NA);
1690                 opt_offset += opt_len - 3;
1691                 break;
1692             }
1693
1694             case ND_OPT_NEIGHBOR_ADV_ACK: /* Neighbor Advertisement Acknowledgment Option (20) */
1695             {
1696                 guint8 status;
1697
1698                 /* Option-Code */
1699                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_naack_option_code, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
1700                 opt_offset += 1;
1701
1702                 /* Status */
1703                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_naack_status, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
1704                 status = tvb_get_guint8(tvb, opt_offset);
1705                 opt_offset += 1;
1706
1707                 if(status == 2){
1708                     proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_naack_supplied_ncoa, tvb, opt_offset, 16, ENC_NA);
1709                     opt_offset += 16;
1710                 }else{
1711                     proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_reserved, tvb, opt_offset, opt_len - 4, ENC_NA);
1712                     opt_offset += opt_len - 4;
1713                 }
1714                 break;
1715             }
1716             case ND_OPT_MAP: /* MAP Option (23) */
1717             {
1718
1719                 /* Dist */
1720                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_map_dist, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
1721
1722                 /* Pref */
1723                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_map_pref, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
1724                 opt_offset += 1;
1725
1726                 /* Flags */
1727                 ti_opt = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_map_flag, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
1728                 flag_tree = proto_item_add_subtree(ti_opt, ett_icmpv6_flag_map);
1729
1730                 proto_tree_add_item(flag_tree, hf_icmpv6_opt_map_flag_r, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
1731                 proto_tree_add_item(flag_tree, hf_icmpv6_opt_map_flag_reserved, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
1732                 opt_offset += 1;
1733
1734                 /* Valid Lifetime */
1735                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_map_valid_lifetime, tvb, opt_offset, 4, ENC_BIG_ENDIAN);
1736                 opt_offset += 4;
1737
1738                 /* Global Address */
1739                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_map_global_address, tvb, opt_offset, 16, ENC_NA);
1740                 opt_offset += 16;
1741                 break;
1742             }
1743             case ND_OPT_ROUTE_INFO: /* Route Information Option (24) */
1744             {
1745                 /* RFC 4191 */
1746                 guint8 prefix_len;
1747                 guint8 route_preference;
1748                 struct e_in6_addr prefix;
1749
1750                 /* Prefix Len */
1751                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_prefix_len, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
1752                 prefix_len = tvb_get_guint8(tvb, opt_offset);
1753                 opt_offset += 1;
1754
1755                 /* Flags */
1756                 ti_opt = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_route_info_flag, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
1757                 flag_tree = proto_item_add_subtree(ti_opt, ett_icmpv6_flag_route_info);
1758
1759                 proto_tree_add_item(flag_tree, hf_icmpv6_opt_route_info_flag_route_preference, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
1760                 proto_tree_add_item(flag_tree, hf_icmpv6_opt_route_info_flag_reserved, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
1761
1762                 route_preference = tvb_get_guint8(tvb, opt_offset);
1763                 route_preference = (route_preference & ND_RA_FLAG_RTPREF_MASK) >> 3;
1764                 proto_item_append_text(ti, " : %s", val_to_str(route_preference, nd_flag_router_pref, "Unknown %d") );
1765                 opt_offset += 1;
1766
1767                 /* Route Lifetime */
1768                 ti_opt = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_route_lifetime, tvb, opt_offset, 4, ENC_BIG_ENDIAN);
1769
1770                 switch(tvb_get_ntohl(tvb, opt_offset)){
1771                     case 0xffffffff:
1772                         proto_item_append_text(ti_opt, " (Infinity)");
1773                         break;
1774                     default:
1775                         break;
1776                 }
1777                 opt_offset += 4;
1778
1779                 /* Prefix */
1780                 switch(opt_len){
1781                     case 8: /* Default Option Length without prefix */
1782                         proto_item_append_text(ti, " ::/%d", prefix_len);
1783                         break;
1784                     case 16:
1785                         memset(&prefix, 0, sizeof(prefix));
1786                         tvb_memcpy(tvb, (guint8 *)&prefix.bytes, opt_offset, 8);
1787                         proto_tree_add_ipv6(icmp6opt_tree, hf_icmpv6_opt_prefix, tvb, opt_offset, 8, prefix.bytes);
1788                         proto_item_append_text(ti, " %s/%d", ip6_to_str(&prefix), prefix_len);
1789                         opt_offset += 8;
1790                         break;
1791                     case 24:
1792                         proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_prefix, tvb, opt_offset, 16, ENC_NA);
1793                         proto_item_append_text(ti, " %s/%d", tvb_ip6_to_str(tvb, opt_offset), prefix_len);
1794                         opt_offset += 16;
1795                         break;
1796                     default:
1797                         expert_add_info_format(pinfo, ti_opt_len, PI_MALFORMED, PI_ERROR, "Invalid Option Length");
1798                         break;
1799                 }
1800                 break;
1801
1802             }
1803
1804             case ND_OPT_RECURSIVE_DNS_SERVER: /* Recursive DNS Server Option (25) */
1805             {
1806                 /* Reserved */
1807                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_reserved, tvb, opt_offset, 2, ENC_NA);
1808                 opt_offset += 2;
1809
1810                 /* RDNSS Lifetime */
1811                 ti_opt = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_rdnss_lifetime, tvb, opt_offset, 4, ENC_BIG_ENDIAN);
1812                 /* A value of all one bits (0xffffffff) represents infinity.  A value of
1813                  * zero means that the RDNSS address MUST no longer be used.
1814                  */
1815                 switch(tvb_get_ntohl(tvb, opt_offset)){
1816                     case 0:
1817                         proto_item_append_text(ti_opt, " (RDNSS address MUST no longer be used)");
1818                         break;
1819                     case 0xffffffff:
1820                         proto_item_append_text(ti_opt, " (Infinity)");
1821                         break;
1822                     default:
1823                         break;
1824                 }
1825                 opt_offset += 4;
1826
1827                 while(opt_offset < (offset + opt_len) ) {
1828                     proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_rdnss, tvb, opt_offset, 16, ENC_NA);
1829                     proto_item_append_text(ti, " %s", tvb_ip6_to_str(tvb, opt_offset));
1830                     opt_offset += 16;
1831
1832                 }
1833                 break;
1834             }
1835             case ND_OPT_FLAGS_EXTENSION: /* RA Flags Extension Option (26) */
1836             {
1837                 ti_opt = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_efo, tvb, opt_offset, 6, ENC_NA);
1838                 flag_tree = proto_item_add_subtree(ti_opt, ett_icmpv6_flag_efo);
1839
1840                 proto_tree_add_item(flag_tree, hf_icmpv6_opt_efo_m, tvb, opt_offset, 2, ENC_BIG_ENDIAN);
1841                 proto_tree_add_item(flag_tree, hf_icmpv6_opt_efo_o, tvb, opt_offset, 2, ENC_BIG_ENDIAN);
1842                 proto_tree_add_item(flag_tree, hf_icmpv6_opt_efo_h, tvb, opt_offset, 2, ENC_BIG_ENDIAN);
1843                 proto_tree_add_item(flag_tree, hf_icmpv6_opt_efo_prf, tvb, opt_offset, 2, ENC_BIG_ENDIAN);
1844                 proto_tree_add_item(flag_tree, hf_icmpv6_opt_efo_p, tvb, opt_offset, 2, ENC_BIG_ENDIAN);
1845                 proto_tree_add_item(flag_tree, hf_icmpv6_opt_efo_rsv, tvb, opt_offset, 2, ENC_BIG_ENDIAN);
1846                 opt_offset += 2;
1847
1848                 proto_tree_add_item(flag_tree, hf_icmpv6_opt_reserved, tvb, opt_offset, 4, ENC_NA);
1849                 opt_offset += 4;
1850                 break;
1851             }
1852             case ND_OPT_HANDOVER_KEY_REQUEST: /* Handover Key Request Option (27) */
1853             {
1854                 int par_len;
1855                 guint padd_length;
1856
1857                 /* Pad Length */
1858                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_hkr_pad_length, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
1859                 padd_length = tvb_get_guint8(tvb, opt_offset);
1860                 opt_offset += 1;
1861
1862                 /* AT */
1863                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_hkr_at, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
1864
1865                 /* Reserved */
1866                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_hkr_reserved, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
1867                 opt_offset += 1;
1868
1869                 /* Handover Key Encryption Public Key */
1870                 par_len = opt_len-4-padd_length;
1871                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_hkr_encryption_public_key, tvb, opt_offset, par_len, ENC_NA);
1872                 opt_offset += par_len;
1873
1874                 /* Padding */
1875                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_hkr_padding, tvb, opt_offset, padd_length, ENC_NA);
1876                 opt_offset += 1;
1877                 break;
1878             }
1879             case ND_OPT_HANDOVER_KEY_REPLY: /* Handover Key Reply Option (28) */
1880             {
1881                 int par_len;
1882                 guint padd_length;
1883
1884                 /* Pad Length */
1885                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_hkr_pad_length, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
1886                 padd_length = tvb_get_guint8(tvb, opt_offset);
1887                 opt_offset += 1;
1888
1889                 /* AT */
1890                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_hkr_at, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
1891
1892                 /* Reserved */
1893                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_hkr_reserved, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
1894                 opt_offset += 1;
1895
1896                 /* Lifetime */
1897                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_hkr_lifetime, tvb, opt_offset, 2, ENC_BIG_ENDIAN);
1898                 opt_offset += 2;
1899
1900                 /* Encrypted Handover Key */
1901                 par_len = opt_len-6-padd_length;
1902                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_hkr_encrypted_handover_key, tvb, opt_offset, par_len, ENC_NA);
1903                 opt_offset += par_len;
1904
1905                 /* Padding */
1906                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_hkr_padding, tvb, opt_offset, padd_length, ENC_NA);
1907                 opt_offset += 1;
1908                 break;
1909             }
1910             case ND_OPT_HANDOVER_ASSIST_INFO: /* Handover Assist Information Option (29) */
1911             {
1912                 guint8 hai_len;
1913                 int padd_length;
1914                 /* Option-Code */
1915                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_hai_option_code, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
1916                 opt_offset += 1;
1917
1918                 /* HAI Length */
1919                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_hai_length, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
1920                 hai_len = tvb_get_guint8(tvb, opt_offset);
1921                 opt_offset += 1;
1922
1923                 /* HAI Value */
1924                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_hai_value, tvb, opt_offset, hai_len, ENC_NA);
1925                 opt_offset += hai_len;
1926
1927                 /* Padding... */
1928                 padd_length = opt_len - opt_offset;
1929                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_padding, tvb, opt_offset, padd_length, ENC_NA);
1930                 opt_offset += padd_length;
1931
1932                 break;
1933             }
1934             case ND_OPT_MOBILE_NODE_ID: /* Mobile Node Identifier Option (30) */
1935             {
1936                 guint8 mn_len;
1937                 int padd_length;
1938                 /* Option-Code */
1939                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_mn_option_code, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
1940                 opt_offset += 1;
1941
1942                 /* MN Length */
1943                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_mn_length, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
1944                 mn_len = tvb_get_guint8(tvb, opt_offset);
1945                 opt_offset += 1;
1946
1947                 /* MN Value */
1948                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_mn_value, tvb, opt_offset, mn_len, ENC_NA);
1949                 opt_offset += mn_len;
1950
1951                 /* Padding... */
1952                 padd_length = opt_len - opt_offset;
1953                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_padding, tvb, opt_offset, padd_length, ENC_NA);
1954                 opt_offset += padd_length;
1955
1956                 break;
1957             }
1958             case ND_OPT_DNS_SEARCH_LIST: /* DNS Search List Option (31) */
1959             {
1960                 int dnssl_len;
1961                 const guchar *dnssl_name;
1962
1963                 /* Reserved */
1964                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_reserved, tvb, opt_offset, 2, ENC_NA);
1965                 opt_offset += 2;
1966
1967                 /* DNSSL Lifetime */
1968                 ti_opt = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_dnssl_lifetime, tvb, opt_offset, 4, ENC_BIG_ENDIAN);
1969                 switch(tvb_get_ntohl(tvb, opt_offset)){
1970                     case 0:
1971                         proto_item_append_text(ti_opt, " (DNSSL domain name MUST no longer be used)");
1972                         break;
1973                     case 0xffffffff:
1974                         proto_item_append_text(ti_opt, " (Infinity)");
1975                         break;
1976                     default:
1977                         break;
1978                 }
1979                 opt_offset += 4;
1980                 while(opt_offset < (offset + opt_len) ) {
1981
1982                     if(tvb_get_guint8(tvb, opt_offset) == 0){
1983                         /* Padding... */
1984                         int padd_length = (offset + opt_len) - opt_offset;
1985                         proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_padding, tvb, opt_offset, padd_length, FALSE);
1986                         opt_offset += padd_length;
1987                         break;
1988                     }
1989                     dnssl_len = get_dns_name(tvb, opt_offset, 0, opt_offset, &dnssl_name);
1990                     proto_tree_add_string(icmp6opt_tree, hf_icmpv6_opt_dnssl, tvb, opt_offset, dnssl_len, dnssl_name);
1991                     proto_item_append_text(ti, " %s", dnssl_name);
1992                     opt_offset += dnssl_len;
1993
1994                 }
1995                 break;
1996             }
1997             case ND_OPT_PROXY_SIGNATURE: /* Proxy Signature Option (32) */
1998             {
1999                 int par_len;
2000
2001                 /* Reserved */
2002                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_reserved, tvb, opt_offset, 2, ENC_NA);
2003                 opt_offset +=  2;
2004
2005                 /* Key Hash
2006                  * A 128-bit field containing the most significant (leftmost) 128
2007                  * bits of a SHA-1 [14] hash of the public key used for constructing
2008                  * the signature.
2009                  */
2010                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_ps_key_hash, tvb, opt_offset, 16, ENC_NA);
2011                 opt_offset += 16;
2012
2013                 /* Digital Signature */
2014                 par_len = opt_len - 20;
2015                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_digital_signature_padding , tvb, opt_offset, par_len, ENC_NA);
2016                 opt_offset += par_len;
2017                 /* Padding */
2018                 /* TODO: Calculate padding length and exlude from the signature */
2019                 break;
2020             }
2021             case ND_OPT_ADDR_REGISTRATION: /* Address Registration (TBD1 Pending IANA...) */
2022             {
2023                 /* 6lowpan-ND */
2024                 guint8 status;
2025
2026                 /* Status */
2027                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_aro_status, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
2028                 status = tvb_get_guint8(tvb, opt_offset);
2029                 opt_offset += 1;
2030
2031                 /* Reserved */
2032                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_reserved, tvb, opt_offset, 3, ENC_NA);
2033                 opt_offset += 3;
2034
2035                 /* Lifetime */
2036                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_aro_registration_lifetime, tvb, opt_offset, 2, ENC_BIG_ENDIAN);
2037                 opt_offset += 2;
2038
2039                 /* EUI-64 */
2040                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_aro_eui64, tvb, opt_offset, 8, ENC_BIG_ENDIAN);
2041                 proto_item_append_text(ti, " : Register %s %s", tvb_eui64_to_str(tvb, opt_offset, FALSE), val_to_str(status, nd_opt_6lowpannd_status_val, "Unknown %d"));
2042                 opt_offset += 8;
2043
2044             }
2045             break;
2046             case ND_OPT_6LOWPAN_CONTEXT: /* 6LoWPAN Context (TBD2 Pending IANA...) */
2047             {
2048                 /* 6lowpan-ND */
2049                 guint8 context_len;
2050                 struct e_in6_addr context_prefix;
2051
2052                 /* Context Length */
2053                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_6co_context_length, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
2054                 context_len = tvb_get_guint8(tvb, opt_offset);
2055                 opt_offset += 1;
2056
2057                 /*  Flags & CID */
2058                 ti_opt = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_6co_flag, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
2059                 flag_tree = proto_item_add_subtree(ti_opt, ett_icmpv6_flag_6lowpan);
2060                 proto_tree_add_item(flag_tree, hf_icmpv6_opt_6co_flag_c, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
2061                 proto_tree_add_item(flag_tree, hf_icmpv6_opt_6co_flag_cid, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
2062                 proto_tree_add_item(flag_tree, hf_icmpv6_opt_6co_flag_reserved, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
2063                 opt_offset += 1;
2064
2065                 /* Reserved */
2066                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_reserved, tvb, opt_offset, 2, ENC_NA);
2067                 opt_offset += 2;
2068
2069                 /* Lifetime */
2070                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_6co_valid_lifetime, tvb, opt_offset, 2, ENC_BIG_ENDIAN);
2071                 opt_offset += 2;
2072
2073                 /* Context */
2074                 switch(opt_len){
2075                     case 8: /* Default Option Length without context prefix */
2076                         proto_item_append_text(ti, " ::/%d", context_len);
2077                         break;
2078                     case 16:
2079                         memset(&context_prefix, 0, sizeof(context_prefix));
2080                         tvb_memcpy(tvb, (guint8 *)&context_prefix.bytes, opt_offset, 8);
2081                         proto_tree_add_ipv6(icmp6opt_tree, hf_icmpv6_opt_6co_context_prefix, tvb, opt_offset, 8, context_prefix.bytes);
2082                         proto_item_append_text(ti, " %s/%d", ip6_to_str(&context_prefix), context_len);
2083                         opt_offset += 8;
2084                         break;
2085                     case 24:
2086                         proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_6co_context_prefix, tvb, opt_offset, 16, ENC_NA);
2087                         proto_item_append_text(ti, " %s/%d", tvb_ip6_to_str(tvb, opt_offset), context_len);
2088                         opt_offset += 16;
2089                         break;
2090                     default:
2091                         expert_add_info_format(pinfo, ti_opt_len, PI_MALFORMED, PI_ERROR, "Invalid Option Length");
2092                         break;
2093                 }
2094             }
2095             break;
2096             case ND_OPT_AUTH_BORDER_ROUTER: /* Authoritative Border Router (33) */
2097             {
2098                 guint16 version;
2099
2100                 /* Version */
2101                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_abro_version, tvb, opt_offset, 2, ENC_BIG_ENDIAN);
2102                 version = tvb_get_ntohs(tvb, opt_offset);
2103                 opt_offset += 2;
2104
2105                 /* Reserved */
2106                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_reserved, tvb, opt_offset, 4, ENC_NA);
2107                 opt_offset += 4;
2108
2109                 /* 6LBR Address */
2110                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_abro_6lbr_address, tvb, opt_offset, 16, ENC_NA);
2111                 proto_item_append_text(ti, " : Version %d, 6LBR : %s", version, tvb_ip6_to_str(tvb, opt_offset));
2112                 opt_offset += 16;
2113
2114             }
2115             break;
2116
2117             default :
2118                 expert_add_info_format(pinfo, ti, PI_UNDECODED, PI_NOTE,
2119                                        "Dissector for ICMPv6 Option (%d)"
2120                                        " code not implemented, Contact Wireshark developers"
2121                                        " if you want this supported", opt_type);
2122                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_data, tvb, opt_offset, opt_len, ENC_NA);
2123                 opt_offset += opt_len;
2124                 break;
2125
2126         } /* switch (opt_type) */
2127
2128         offset += opt_len;
2129
2130         if(offset > opt_offset){
2131             ti_opt = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_unknown_data, tvb, opt_offset, offset - opt_offset, ENC_NA);
2132             expert_add_info_format(pinfo, ti_opt, PI_MALFORMED, PI_ERROR, "Unknown Data (not interpreted)");
2133         }
2134         /* Close the ) to option root label */
2135         proto_item_append_text(ti, ")");
2136     }
2137     return offset;
2138 }
2139
2140
2141 /* RPL: draft-ietf-roll-rpl-19.txt: Routing over Low-Power and Lossy Networks. */
2142 static int
2143 dissect_icmpv6_rpl_opt(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
2144 {
2145     proto_tree *icmp6opt_tree, *flag_tree;
2146     proto_item *ti, *ti_opt, *ti_opt_len;
2147     guint8 opt_type;
2148     int opt_len;
2149     int opt_offset;
2150
2151     while ((int)tvb_reported_length(tvb) > offset) {
2152         /* there are more options */
2153
2154         /* ICMPv6 RPL Option */
2155         ti = proto_tree_add_item(tree, hf_icmpv6_rpl_opt, tvb, offset, 1, ENC_NA);
2156         icmp6opt_tree = proto_item_add_subtree(ti, ett_icmpv6_rpl_opt);
2157         opt_offset = offset;
2158
2159         /* Option type */
2160         proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_type, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
2161         opt_type = tvb_get_guint8(tvb, opt_offset);
2162         opt_offset += 1;
2163
2164         /* Add option name to option root label */
2165         proto_item_append_text(ti, " (%s", val_to_str(opt_type, rpl_option_vals, "Unknown %d"));
2166
2167         /* The Pad1 option is a special case, and contains no data. */
2168         if (opt_type == RPL_OPT_PAD1) {
2169             offset += 1;
2170             proto_item_append_text(ti, ")");
2171             continue;
2172         }
2173
2174         /* Option length */
2175         ti_opt_len = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_length, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
2176         opt_len = tvb_get_guint8(tvb, opt_offset);
2177         proto_item_set_len(ti, opt_len + 2);
2178         opt_offset += 1;
2179
2180         /* decode... */
2181         switch (opt_type) {
2182             case RPL_OPT_PADN:
2183                 /* n-byte padding */
2184                 ti_opt = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_padn, tvb, opt_offset, opt_len, ENC_NA);
2185                 proto_item_append_text(ti_opt, " (Length : %i bytes)", opt_len);
2186                 opt_offset += opt_len;
2187                 break;
2188
2189             case RPL_OPT_METRIC:
2190                 /* DAG metric container */
2191                 /* See draft-ietf-roll-routing-metrics for formatting. */
2192                 break;
2193             case RPL_OPT_ROUTING: {
2194                 guint8 prefix_len;
2195                 struct e_in6_addr prefix;
2196
2197                 /* Prefix length */
2198                 prefix_len = tvb_get_guint8(tvb, opt_offset);
2199                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_route_prefix_length, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
2200                 opt_offset +=1;
2201
2202                 /* Flags */
2203                 ti_opt = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_route_flag, tvb, opt_offset, 1, ENC_NA);
2204                 flag_tree = proto_item_add_subtree(ti_opt, ett_icmpv6_rpl_flag_routing);
2205
2206                 proto_tree_add_item(flag_tree, hf_icmpv6_rpl_opt_route_pref, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
2207                 proto_tree_add_item(flag_tree, hf_icmpv6_rpl_opt_route_reserved, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
2208                 opt_offset +=1;
2209
2210                 /* Prefix lifetime. */
2211                 ti_opt = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_route_lifetime, tvb, opt_offset, 4, ENC_BIG_ENDIAN);
2212
2213                 switch(tvb_get_ntohl(tvb, opt_offset)){
2214                     case 0xffffffff:
2215                         proto_item_append_text(ti_opt, " (Infinity)");
2216                         break;
2217                     default:
2218                         break;
2219                 }
2220                 opt_offset += 4;
2221
2222                 switch(opt_len){
2223                     case 6: /* Default Option Length without prefix */
2224                         proto_item_append_text(ti, " ::/%d", prefix_len);
2225                         break;
2226                     case 14:
2227                         memset(&prefix, 0, sizeof(prefix));
2228                         tvb_memcpy(tvb, (guint8 *)&prefix.bytes, opt_offset, 8);
2229                         proto_tree_add_ipv6(icmp6opt_tree, hf_icmpv6_rpl_opt_route_prefix, tvb, opt_offset, 8, prefix.bytes);
2230                         proto_item_append_text(ti, " %s/%d", ip6_to_str(&prefix), prefix_len);
2231                         opt_offset += 8;
2232                         break;
2233                     case 22:
2234                         proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_route_prefix, tvb, opt_offset, 16, ENC_NA);
2235                         proto_item_append_text(ti, " %s/%d", tvb_ip6_to_str(tvb, opt_offset), prefix_len);
2236                         opt_offset += 16;
2237                         break;
2238                     default:
2239                         expert_add_info_format(pinfo, ti_opt_len, PI_MALFORMED, PI_ERROR, "Invalid Option Length");
2240                         break;
2241                 }
2242                 break;
2243             }
2244             case RPL_OPT_CONFIG: {
2245
2246                 /* Flags */
2247                 ti_opt = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_config_flag, tvb, opt_offset, 1, ENC_NA);
2248                 flag_tree = proto_item_add_subtree(ti_opt, ett_icmpv6_rpl_flag_config);
2249
2250                 proto_tree_add_item(flag_tree, hf_icmpv6_rpl_opt_config_reserved, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
2251                 proto_tree_add_item(flag_tree, hf_icmpv6_rpl_opt_config_auth, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
2252                 proto_tree_add_item(flag_tree, hf_icmpv6_rpl_opt_config_pcs, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
2253                 opt_offset += 1;
2254
2255                 /* DIOIntervalDoublings */
2256                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_config_doublings, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
2257                 opt_offset += 1;
2258
2259                 /* DIOIntervalMin */
2260                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_config_min_interval, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
2261                 opt_offset += 1;
2262
2263                 /* DIORedundancyConstant */
2264                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_config_redundancy, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
2265                 opt_offset += 1;
2266
2267                 /* MaxRankIncrease */
2268                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_config_rank_incr, tvb, opt_offset, 2, ENC_BIG_ENDIAN);
2269                 opt_offset += 2;
2270
2271                 /* MinHopRankInc */
2272                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_config_hop_rank_inc, tvb, opt_offset, 2, ENC_BIG_ENDIAN);
2273                 opt_offset += 2;
2274
2275                 /* OCP */
2276                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_config_ocp, tvb, opt_offset, 2, ENC_BIG_ENDIAN);
2277                 opt_offset += 2;
2278
2279                 /* Reserved */
2280                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_config_rsv, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
2281                 opt_offset += 1;
2282
2283                 /* Default Lifetime */
2284                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_config_def_lifetime, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
2285                 opt_offset += 1;
2286
2287                 /* Lifetime Unit */
2288                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_config_lifetime_unit, tvb, opt_offset, 2, ENC_BIG_ENDIAN);
2289                 opt_offset += 2;
2290                 break;
2291             }
2292             case RPL_OPT_TARGET: {
2293                 guint8              prefix_len;
2294                 struct e_in6_addr   target_prefix;
2295
2296                 /* Flag */
2297                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_target_flag, tvb, opt_offset, 1, ENC_NA);
2298                 opt_offset += 1;
2299
2300                 /* Prefix length */
2301                 prefix_len = tvb_get_guint8(tvb, opt_offset);
2302                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_target_prefix_length, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
2303                 opt_offset += 1;
2304
2305                 /* Target Prefix */
2306
2307                 switch(opt_len){
2308                     case 2: /* Default Option Length without prefix */
2309                         proto_item_append_text(ti, " ::/%d", prefix_len);
2310                         break;
2311                     case 10:
2312                         memset(&target_prefix, 0, sizeof(target_prefix));
2313                         tvb_memcpy(tvb, (guint8 *)&target_prefix.bytes, opt_offset, 8);
2314                         proto_tree_add_ipv6(icmp6opt_tree, hf_icmpv6_rpl_opt_target_prefix, tvb, opt_offset, 8, target_prefix.bytes);
2315                         proto_item_append_text(ti, " %s/%d", ip6_to_str(&target_prefix), prefix_len);
2316                         opt_offset += 8;
2317                         break;
2318                     case 18:
2319                         proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_target_prefix, tvb, opt_offset, 16, ENC_NA);
2320                         proto_item_append_text(ti, " %s/%d", tvb_ip6_to_str(tvb, opt_offset), prefix_len);
2321                         opt_offset += 16;
2322                         break;
2323                     default:
2324                         expert_add_info_format(pinfo, ti_opt_len, PI_MALFORMED, PI_ERROR, "Invalid Option Length");
2325                         break;
2326                 }
2327                 break;
2328             }
2329             case RPL_OPT_TRANSIT: {
2330                 /* Flags */
2331                 ti_opt = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_transit_flag, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
2332                 flag_tree = proto_item_add_subtree(ti_opt, ett_icmpv6_rpl_flag_transit);
2333
2334                 proto_tree_add_item(flag_tree, hf_icmpv6_rpl_opt_transit_flag_e, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
2335                 proto_tree_add_item(flag_tree, hf_icmpv6_rpl_opt_transit_flag_rsv, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
2336                 opt_offset += 1;
2337
2338                 /* Path Control */
2339                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_transit_pathctl, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
2340                 opt_offset += 1;
2341
2342                 /* Path Sequence */
2343                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_transit_pathseq, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
2344                 opt_offset += 1;
2345
2346                 /* Path Lifetime */
2347                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_transit_pathlifetime, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
2348                 opt_offset += 1;
2349
2350                 /* Option contains parent */
2351                 if(opt_len > 4)
2352                 {
2353                     proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_transit_parent, tvb, opt_offset, 16, ENC_NA);
2354                     proto_item_append_text(ti, " %s", tvb_ip6_to_str(tvb, opt_offset));
2355                     opt_offset += 16;
2356                 }
2357
2358                 break;
2359             }
2360             case RPL_OPT_SOLICITED: {
2361
2362                 /*Instance ID */
2363                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_solicited_instance, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
2364                 opt_offset += 1;
2365
2366                 /* Flags */
2367                 ti_opt = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_solicited_flag, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
2368                 flag_tree = proto_item_add_subtree(ti_opt, ett_icmpv6_rpl_flag_solicited);
2369
2370                 proto_tree_add_item(flag_tree, hf_icmpv6_rpl_opt_solicited_flag_v, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
2371                 proto_tree_add_item(flag_tree, hf_icmpv6_rpl_opt_solicited_flag_i, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
2372                 proto_tree_add_item(flag_tree, hf_icmpv6_rpl_opt_solicited_flag_d, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
2373                 proto_tree_add_item(flag_tree, hf_icmpv6_rpl_opt_solicited_flag_rsv, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
2374                 opt_offset += 1;
2375
2376                 /* DODAG ID */
2377                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_solicited_dodagid, tvb, opt_offset, 16, ENC_NA);
2378                 opt_offset += 16;
2379
2380                 /* Version Number */
2381                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_solicited_version, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
2382                 opt_offset += 1;
2383
2384                 break;
2385             }
2386             case RPL_OPT_PREFIX: {
2387                 /* Destination prefix option. */
2388                 guint8              prefix_len;
2389
2390                 /* Prefix length */
2391                 prefix_len = tvb_get_guint8(tvb, opt_offset);
2392                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_prefix_length, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
2393                 opt_offset +=1;
2394
2395                 /* Flags */
2396                 ti_opt = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_prefix_flag, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
2397                 flag_tree = proto_item_add_subtree(ti_opt, ett_icmpv6_rpl_flag_prefix);
2398
2399                 proto_tree_add_item(flag_tree, hf_icmpv6_rpl_opt_prefix_flag_l, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
2400                 proto_tree_add_item(flag_tree, hf_icmpv6_rpl_opt_prefix_flag_a, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
2401                 proto_tree_add_item(flag_tree, hf_icmpv6_rpl_opt_prefix_flag_r, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
2402                 proto_tree_add_item(flag_tree, hf_icmpv6_rpl_opt_prefix_flag_rsv, tvb, opt_offset, 1, ENC_BIG_ENDIAN);
2403                 opt_offset += 1;
2404
2405                 /* Valid lifetime. */
2406                 ti_opt = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_prefix_vlifetime, tvb, opt_offset, 4, ENC_BIG_ENDIAN);
2407                 switch(tvb_get_ntohl(tvb, opt_offset)){
2408                     case 0xffffffff:
2409                         proto_item_append_text(ti_opt, " (Infinity)");
2410                         break;
2411                     default:
2412                         break;
2413                 }
2414                 opt_offset += 4;
2415
2416                 /* Preferrred Lifetime */
2417                 ti_opt = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_prefix_plifetime, tvb, opt_offset, 4, ENC_BIG_ENDIAN);
2418                 switch(tvb_get_ntohl(tvb, opt_offset)){
2419                     case 0xffffffff:
2420                         proto_item_append_text(ti_opt, " (Infinity)");
2421                         break;
2422                     default:
2423                         break;
2424                 }
2425                 opt_offset += 4;
2426
2427                 /* 4 reserved bytes. */
2428                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_reserved, tvb, opt_offset, 4, ENC_NA);
2429                 opt_offset += 4;
2430
2431                 /* Prefix */
2432                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_prefix, tvb, opt_offset, 16, ENC_NA);
2433                 proto_item_append_text(ti, " %s/%d", tvb_ip6_to_str(tvb, opt_offset), prefix_len);
2434                 opt_offset += 16;
2435
2436                 break;
2437             }
2438
2439             case RPL_OPT_TARGETDESC: {
2440
2441                 /* Descriptor */
2442                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_targetdesc, tvb, opt_offset, 4, ENC_BIG_ENDIAN);
2443                 opt_offset += 4;
2444                 break;
2445             }
2446             default :
2447                 expert_add_info_format(pinfo, ti, PI_UNDECODED, PI_NOTE,
2448                                        "Dissector for ICMPv6 RPL Option"
2449                                        " (%d) code not implemented, Contact"
2450                                        " Wireshark developers if you want this supported", opt_type);
2451                 proto_tree_add_item(icmp6opt_tree, hf_icmpv6_data, tvb, opt_offset, opt_len, ENC_NA);
2452                 opt_offset += opt_len;
2453                 break;
2454         } /* switch (opt_type) */
2455
2456         offset += opt_len + 2;
2457
2458         if(offset > opt_offset){
2459             ti_opt = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_unknown_data, tvb, opt_offset, offset - opt_offset, ENC_NA);
2460             expert_add_info_format(pinfo, ti_opt, PI_MALFORMED, PI_ERROR, "Unknown Data (not interpreted)");
2461         }
2462
2463         /* Close the ) to option root label */
2464         proto_item_append_text(ti, ")");
2465     } /* while */
2466     return offset;
2467 }
2468
2469 static int
2470 dissect_rpl_control(tvbuff_t *tvb, int rpl_offset, packet_info *pinfo _U_, proto_tree *icmp6_tree, guint8 icmp6_type _U_, guint8 icmp6_code)
2471 {
2472     proto_tree *flag_tree;
2473     proto_item *ti;
2474
2475     /* Secure RPL ? (ICMP Code start to 0x8x) */
2476     if(icmp6_code & ICMP6_RPL_SECURE)
2477     {
2478         guint8 kim, lvl;
2479
2480         /* Flags */
2481         ti = proto_tree_add_item(icmp6_tree, hf_icmpv6_rpl_secure_flag, tvb, rpl_offset, 1, ENC_BIG_ENDIAN);
2482         flag_tree = proto_item_add_subtree(ti, ett_icmpv6_flag_secure);
2483         proto_tree_add_item(flag_tree, hf_icmpv6_rpl_secure_flag_t, tvb, rpl_offset, 1, ENC_BIG_ENDIAN);
2484         proto_tree_add_item(flag_tree, hf_icmpv6_rpl_secure_flag_rsv, tvb, rpl_offset, 1, ENC_BIG_ENDIAN);
2485         rpl_offset += 1;
2486
2487         /* Algorithm */
2488         ti = proto_tree_add_item(icmp6_tree, hf_icmpv6_rpl_secure_algorithm, tvb, rpl_offset, 1, ENC_BIG_ENDIAN);
2489         flag_tree = proto_item_add_subtree(ti, ett_icmpv6_flag_secure);
2490         proto_tree_add_item(flag_tree, hf_icmpv6_rpl_secure_algorithm_encryption, tvb, rpl_offset, 1, ENC_BIG_ENDIAN);
2491         proto_tree_add_item(flag_tree, hf_icmpv6_rpl_secure_algorithm_signature, tvb, rpl_offset, 1, ENC_BIG_ENDIAN);
2492         rpl_offset += 1;
2493
2494         /* KIM & LVL */
2495         ti = proto_tree_add_item(icmp6_tree, hf_icmpv6_rpl_secure_flag, tvb, rpl_offset, 1, ENC_BIG_ENDIAN);
2496         flag_tree = proto_item_add_subtree(ti, ett_icmpv6_flag_secure);
2497         proto_tree_add_item(flag_tree, hf_icmpv6_rpl_secure_kim, tvb, rpl_offset, 1, ENC_BIG_ENDIAN);
2498         proto_tree_add_item(flag_tree, hf_icmpv6_rpl_secure_lvl, tvb, rpl_offset, 1, ENC_BIG_ENDIAN);
2499         proto_tree_add_item(flag_tree, hf_icmpv6_rpl_secure_rsv, tvb, rpl_offset, 1, ENC_BIG_ENDIAN);
2500         kim = tvb_get_guint8(tvb, rpl_offset) & RPL_SECURE_KIM >> 6;
2501         lvl = tvb_get_guint8(tvb, rpl_offset) & RPL_SECURE_LVL;
2502         rpl_offset += 1;
2503
2504         /* Flags */
2505         proto_tree_add_item(icmp6_tree, hf_icmpv6_rpl_secure_flag, tvb, rpl_offset, 1, ENC_BIG_ENDIAN);
2506         rpl_offset += 1;
2507
2508         /* Counter */
2509         proto_tree_add_item(icmp6_tree, hf_icmpv6_rpl_secure_counter, tvb, rpl_offset, 4, ENC_BIG_ENDIAN);
2510         rpl_offset += 4;
2511
2512         /*  Key Identifier */
2513         switch(kim){
2514             case 0:
2515             {
2516                 proto_tree_add_item(icmp6_tree, hf_icmpv6_rpl_secure_key_index, tvb, rpl_offset, 1, ENC_BIG_ENDIAN);
2517                 rpl_offset += 1;
2518                 break;
2519             }
2520             case 1:
2521             {
2522                 /* No Key Identifier */
2523                 break;
2524             }
2525             case 2:
2526             {
2527                 proto_tree_add_item(icmp6_tree, hf_icmpv6_rpl_secure_key_source, tvb, rpl_offset, 8, ENC_NA);
2528                 rpl_offset += 8;
2529                 proto_tree_add_item(icmp6_tree, hf_icmpv6_rpl_secure_key_index, tvb, rpl_offset, 1, ENC_BIG_ENDIAN);
2530                 rpl_offset += 1;
2531                 break;
2532             }
2533             case 3:
2534             {
2535                 if(lvl == 1 || lvl == 3)
2536                 {
2537                     proto_tree_add_item(icmp6_tree, hf_icmpv6_rpl_secure_key_source, tvb, rpl_offset, 8, ENC_NA);
2538                     rpl_offset += 8;
2539                     proto_tree_add_item(icmp6_tree, hf_icmpv6_rpl_secure_key_index, tvb, rpl_offset, 1, ENC_BIG_ENDIAN);
2540                     rpl_offset += 1;
2541                 }
2542                 break;
2543             }
2544
2545         }
2546
2547     }
2548     switch(icmp6_code){
2549         case ICMP6_RPL_DIS: /* DODAG Information Solicitation (0) */
2550         case ICMP6_RPL_SDIS: /* Secure DODAG Information Solicitation (128) */
2551         {
2552             /* Flags */
2553             proto_tree_add_item(icmp6_tree, hf_icmpv6_rpl_dis_flag, tvb, rpl_offset, 1, ENC_BIG_ENDIAN);
2554             rpl_offset += 1;
2555
2556             /* Reserved */
2557             proto_tree_add_item(icmp6_tree, hf_icmpv6_reserved, tvb, rpl_offset, 1, ENC_NA);
2558             rpl_offset += 1;
2559
2560             /* RPL Options */
2561             rpl_offset = dissect_icmpv6_rpl_opt(tvb, rpl_offset, pinfo, icmp6_tree);
2562             break;
2563         }
2564         case ICMP6_RPL_DIO: /* DODAG Information Object (1) */
2565         case ICMP6_RPL_SDIO: /* Secure DODAG Information Object (129) */
2566         {
2567             /* RPLInstanceID */
2568             proto_tree_add_item(icmp6_tree, hf_icmpv6_rpl_dio_instance, tvb, rpl_offset, 1, ENC_BIG_ENDIAN);
2569             rpl_offset += 1;
2570
2571             /* Version Number */
2572             proto_tree_add_item(icmp6_tree, hf_icmpv6_rpl_dio_version, tvb, rpl_offset, 1, ENC_BIG_ENDIAN);
2573             rpl_offset += 1;
2574
2575             /* Rank */
2576             proto_tree_add_item(icmp6_tree, hf_icmpv6_rpl_dio_rank, tvb, rpl_offset, 2, ENC_BIG_ENDIAN);
2577             rpl_offset += 2;
2578
2579             /* Flags */
2580             ti = proto_tree_add_item(icmp6_tree, hf_icmpv6_rpl_dio_flag, tvb, rpl_offset, 1, ENC_BIG_ENDIAN);
2581             flag_tree = proto_item_add_subtree(ti, ett_icmpv6_flag_rpl_dio);
2582             proto_tree_add_item(flag_tree, hf_icmpv6_rpl_dio_flag_g, tvb, rpl_offset, 1, ENC_BIG_ENDIAN);
2583             proto_tree_add_item(flag_tree, hf_icmpv6_rpl_dio_flag_0, tvb, rpl_offset, 1, ENC_BIG_ENDIAN);
2584             proto_tree_add_item(flag_tree, hf_icmpv6_rpl_dio_flag_mop, tvb, rpl_offset, 1, ENC_BIG_ENDIAN);
2585             proto_tree_add_item(flag_tree, hf_icmpv6_rpl_dio_flag_prf, tvb, rpl_offset, 1, ENC_BIG_ENDIAN);
2586             rpl_offset += 1;
2587
2588             /* Destination Advertisement Trigger Sequence Number (DTSN) */
2589             proto_tree_add_item(icmp6_tree, hf_icmpv6_rpl_dio_dtsn, tvb, rpl_offset, 1, ENC_BIG_ENDIAN);
2590             rpl_offset += 1;
2591
2592             /* Flags */
2593             proto_tree_add_item(icmp6_tree, hf_icmpv6_rpl_dio_flag, tvb, rpl_offset, 1, ENC_BIG_ENDIAN);
2594             rpl_offset += 1;
2595
2596             /* Reserved */
2597             proto_tree_add_item(icmp6_tree, hf_icmpv6_reserved, tvb, rpl_offset, 1, ENC_NA);
2598             rpl_offset += 1;
2599
2600             /* DODAGID */
2601             proto_tree_add_item(icmp6_tree, hf_icmpv6_rpl_dio_dagid, tvb, rpl_offset, 16, ENC_NA);
2602             rpl_offset += 16;
2603
2604             /* RPL Options */
2605             rpl_offset = dissect_icmpv6_rpl_opt(tvb, rpl_offset, pinfo, icmp6_tree);
2606             break;
2607         }
2608         case ICMP6_RPL_DAO: /* Destination Advertisement Object (2) */
2609         case ICMP6_RPL_SDAO: /* Secure Destination Advertisement Object (130) */
2610         {
2611             guint8 flags;
2612
2613             /* DAO Instance */
2614             proto_tree_add_item(icmp6_tree, hf_icmpv6_rpl_dao_instance, tvb, rpl_offset, 1, ENC_BIG_ENDIAN);
2615             rpl_offset += 1;
2616
2617             /* Flags */
2618             ti = proto_tree_add_item(icmp6_tree, hf_icmpv6_rpl_dao_flag, tvb, rpl_offset, 1, ENC_BIG_ENDIAN);
2619             flag_tree = proto_item_add_subtree(ti, ett_icmpv6_flag_rpl_dao);
2620             proto_tree_add_item(flag_tree, hf_icmpv6_rpl_dao_flag_k, tvb, rpl_offset, 1, ENC_BIG_ENDIAN);
2621             proto_tree_add_item(flag_tree, hf_icmpv6_rpl_dao_flag_d, tvb, rpl_offset, 1, ENC_BIG_ENDIAN);
2622             proto_tree_add_item(flag_tree, hf_icmpv6_rpl_dao_flag_rsv, tvb, rpl_offset, 1, ENC_BIG_ENDIAN);
2623             flags = tvb_get_guint8(tvb, rpl_offset);
2624             rpl_offset += 1;
2625
2626             /* Reserved */
2627             proto_tree_add_item(icmp6_tree, hf_icmpv6_reserved, tvb, rpl_offset, 1, ENC_NA);
2628             rpl_offset += 1;
2629
2630             /* Sequence */
2631             proto_tree_add_item(icmp6_tree, hf_icmpv6_rpl_dao_sequence, tvb, rpl_offset, 1, ENC_BIG_ENDIAN);
2632             rpl_offset += 1;
2633
2634             /* DODAGID */
2635             if(flags & RPL_DAO_FLAG_D)
2636             {
2637                 proto_tree_add_item(icmp6_tree, hf_icmpv6_rpl_dao_dodagid, tvb, rpl_offset, 16, ENC_NA);
2638                 rpl_offset += 16;
2639             }
2640             /* Options */
2641             rpl_offset = dissect_icmpv6_rpl_opt(tvb, rpl_offset, pinfo, icmp6_tree);
2642             break;
2643         }
2644         case ICMP6_RPL_DAOACK: /* Destination Advertisement Object Acknowledgment (3) */
2645         case ICMP6_RPL_SDAOACK: /* Secure Destination Advertisement Object Acknowledgment (131) */
2646         {
2647             guint8 flags;
2648
2649             /* DAO Instance */
2650             proto_tree_add_item(icmp6_tree, hf_icmpv6_rpl_daoack_instance, tvb, rpl_offset, 1, ENC_BIG_ENDIAN);
2651             rpl_offset += 1;
2652
2653             /* Flags */
2654             ti = proto_tree_add_item(icmp6_tree, hf_icmpv6_rpl_daoack_flag, tvb, rpl_offset, 1, ENC_BIG_ENDIAN);
2655             flag_tree = proto_item_add_subtree(ti, ett_icmpv6_flag_rpl_daoack);
2656             proto_tree_add_item(flag_tree, hf_icmpv6_rpl_daoack_flag_d, tvb, rpl_offset, 1, ENC_BIG_ENDIAN);
2657             proto_tree_add_item(flag_tree, hf_icmpv6_rpl_daoack_flag_rsv, tvb, rpl_offset, 1, ENC_BIG_ENDIAN);
2658             flags = tvb_get_guint8(tvb, rpl_offset);
2659             rpl_offset += 1;
2660
2661             /* DAO Sequence */
2662             proto_tree_add_item(icmp6_tree, hf_icmpv6_rpl_daoack_sequence, tvb, rpl_offset, 1, ENC_BIG_ENDIAN);
2663             rpl_offset += 1;
2664
2665             /* Status */
2666             proto_tree_add_item(icmp6_tree, hf_icmpv6_rpl_daoack_status, tvb, rpl_offset, 1, ENC_BIG_ENDIAN);
2667             rpl_offset += 1;
2668
2669             /* DODAGID */
2670             if(flags & RPL_DAOACK_FLAG_D)
2671             {
2672                 proto_tree_add_item(icmp6_tree, hf_icmpv6_rpl_daoack_dodagid, tvb, rpl_offset, 16, ENC_NA);
2673                 rpl_offset += 16;
2674             }
2675
2676             /* Options */
2677             rpl_offset = dissect_icmpv6_rpl_opt(tvb, rpl_offset, pinfo, icmp6_tree);
2678             break;
2679         }
2680        case ICMP6_RPL_CC:
2681        {
2682             /* CC Instance */
2683             proto_tree_add_item(icmp6_tree, hf_icmpv6_rpl_cc_instance, tvb, rpl_offset, 1, ENC_BIG_ENDIAN);
2684             rpl_offset += 1;
2685
2686             /* Flags */
2687             ti = proto_tree_add_item(icmp6_tree, hf_icmpv6_rpl_cc_flag, tvb, rpl_offset, 1, ENC_BIG_ENDIAN);
2688             flag_tree = proto_item_add_subtree(ti, ett_icmpv6_flag_rpl_cc);
2689             proto_tree_add_item(flag_tree, hf_icmpv6_rpl_cc_flag_r, tvb, rpl_offset, 1, ENC_BIG_ENDIAN);
2690             proto_tree_add_item(flag_tree, hf_icmpv6_rpl_cc_flag_rsv, tvb, rpl_offset, 1, ENC_BIG_ENDIAN);
2691             rpl_offset += 1;
2692
2693             /* CC Nonce */
2694             proto_tree_add_item(icmp6_tree, hf_icmpv6_rpl_cc_nonce, tvb, rpl_offset, 2, ENC_BIG_ENDIAN);
2695             rpl_offset += 2;
2696
2697             /* DODAGID */
2698             proto_tree_add_item(icmp6_tree, hf_icmpv6_rpl_cc_dodagid, tvb, rpl_offset, 16, ENC_NA);
2699             rpl_offset += 16;
2700
2701             /* Destination Counter */
2702             proto_tree_add_item(icmp6_tree, hf_icmpv6_rpl_cc_destination_counter, tvb, rpl_offset, 4, ENC_BIG_ENDIAN);
2703             rpl_offset += 4;
2704
2705             /* Options */
2706             rpl_offset = dissect_icmpv6_rpl_opt(tvb, rpl_offset, pinfo, icmp6_tree);
2707             break;
2708        }
2709
2710     }
2711     return rpl_offset;
2712 }
2713 /* RFC 4620 - IPv6 Node Information Queries */
2714
2715 static int
2716 dissect_nodeinfo(tvbuff_t *tvb, int ni_offset, packet_info *pinfo _U_, proto_tree *tree, guint8 icmp6_type, guint8 icmp6_code)
2717 {
2718     proto_tree *flag_tree;
2719     proto_item *ti;
2720     guint16 qtype;
2721
2722     /* Qtype */
2723     proto_tree_add_item(tree, hf_icmpv6_ni_qtype, tvb, ni_offset, 2, ENC_BIG_ENDIAN);
2724     qtype = tvb_get_ntohs(tvb, ni_offset);
2725     ni_offset += 2;
2726
2727     /* Flags */
2728     ti = proto_tree_add_item(tree, hf_icmpv6_ni_flag, tvb, ni_offset, 2, ENC_BIG_ENDIAN);
2729     flag_tree = proto_item_add_subtree(ti, ett_icmpv6_flag_ni);
2730     proto_tree_add_item(flag_tree, hf_icmpv6_ni_flag_g, tvb, ni_offset, 2, ENC_BIG_ENDIAN);
2731     proto_tree_add_item(flag_tree, hf_icmpv6_ni_flag_s, tvb, ni_offset, 2, ENC_BIG_ENDIAN);
2732     proto_tree_add_item(flag_tree, hf_icmpv6_ni_flag_l, tvb, ni_offset, 2, ENC_BIG_ENDIAN);
2733     proto_tree_add_item(flag_tree, hf_icmpv6_ni_flag_c, tvb, ni_offset, 2, ENC_BIG_ENDIAN);
2734     proto_tree_add_item(flag_tree, hf_icmpv6_ni_flag_a, tvb, ni_offset, 2, ENC_BIG_ENDIAN);
2735     proto_tree_add_item(flag_tree, hf_icmpv6_ni_flag_t, tvb, ni_offset, 2, ENC_BIG_ENDIAN);
2736     proto_tree_add_item(flag_tree, hf_icmpv6_ni_flag_rsv, tvb, ni_offset, 2, ENC_BIG_ENDIAN);
2737     ni_offset += 2;
2738
2739     /* Nonce */
2740     proto_tree_add_item(tree, hf_icmpv6_ni_nonce, tvb, ni_offset, 8, ENC_BIG_ENDIAN);
2741     ni_offset += 8;
2742
2743     /* Data ? */
2744     if(tvb_reported_length_remaining(tvb, ni_offset) == 0){
2745         return ni_offset;
2746     }
2747
2748     if(icmp6_type == ICMP6_NI_QUERY){
2749         switch(icmp6_code){
2750             case ICMP6_NI_SUBJ_IPV6: {
2751                 proto_tree_add_item(tree, hf_icmpv6_ni_query_subject_ipv6, tvb, ni_offset, 16, ENC_NA);
2752                 ni_offset += 16;
2753                 break;
2754             }
2755             case ICMP6_NI_SUBJ_FQDN: {
2756                 int fqdn_len;
2757                 const guchar *fqdn_name;
2758                 fqdn_len = get_dns_name(tvb, ni_offset, 0, ni_offset, &fqdn_name);
2759                 proto_tree_add_string(tree, hf_icmpv6_ni_query_subject_fqdn, tvb, ni_offset, fqdn_len, fqdn_name);
2760                 ni_offset += fqdn_len;
2761                 break;
2762             }
2763             case ICMP6_NI_SUBJ_IPV4: {
2764                 proto_tree_add_item(tree, hf_icmpv6_ni_query_subject_ipv4, tvb, ni_offset, 4, ENC_BIG_ENDIAN);
2765                 ni_offset += 4;
2766                 break;
2767             }
2768         }
2769     } else { /* It is ICMP6_NI_REPLY */
2770         switch(qtype){
2771             case NI_QTYPE_NOOP:
2772                 break;
2773             case NI_QTYPE_NODENAME: {
2774                 int node_len;
2775                 const guchar *node_name;
2776                 /* TTL */
2777                 proto_tree_add_item(tree, hf_icmpv6_ni_reply_node_ttl, tvb, ni_offset, 4, ENC_BIG_ENDIAN);
2778                 ni_offset += 4;
2779                 /* Data ? */
2780                 if(tvb_reported_length_remaining(tvb, ni_offset) == 0){
2781                     return ni_offset;
2782                 }
2783                 while(ni_offset < (int)tvb_reported_length(tvb) ) {
2784
2785                     if(tvb_get_guint8(tvb, ni_offset) == 0){ /* if Zero there is padding, skip the loop */
2786                         break;
2787                     }
2788                     /* Node Name */
2789                     node_len = get_dns_name(tvb, ni_offset, 0, ni_offset, &node_name);
2790                     proto_tree_add_string(tree, hf_icmpv6_ni_reply_node_name, tvb, ni_offset, node_len, node_name);
2791                     ni_offset += node_len;
2792                 }
2793                 break;
2794             }
2795             case NI_QTYPE_NODEADDR: {
2796                 while(ni_offset < (int)tvb_reported_length(tvb) ) {
2797                     /* TTL */
2798                     proto_tree_add_item(tree, hf_icmpv6_ni_reply_node_ttl, tvb, ni_offset, 4, ENC_BIG_ENDIAN);
2799                     ni_offset += 4;
2800                     /* Node Addresses */
2801                     proto_tree_add_item(tree, hf_icmpv6_ni_reply_node_address, tvb, ni_offset, 16, ENC_NA);
2802                     ni_offset += 16;
2803                 }
2804                 break;
2805             }
2806             case NI_QTYPE_IPV4ADDR: {
2807                 while(ni_offset < (int)tvb_reported_length(tvb) ) {
2808                     /* TTL */
2809                     proto_tree_add_item(tree, hf_icmpv6_ni_reply_node_ttl, tvb, ni_offset, 4, ENC_BIG_ENDIAN);
2810                     ni_offset += 4;
2811                     /* IPv4 Address */
2812                     proto_tree_add_item(tree, hf_icmpv6_ni_reply_ipv4_address, tvb, ni_offset, 4, ENC_BIG_ENDIAN);
2813                     ni_offset += 4;
2814                 }
2815                 break;
2816             }
2817         }
2818     }
2819     return ni_offset;
2820 }
2821 /* RFC 2894 - Router Renumbering for IPv6 */
2822
2823 static int
2824 dissect_rrenum(tvbuff_t *tvb, int rr_offset, packet_info *pinfo _U_, proto_tree *tree, guint8 icmp6_type _U_, guint8 icmp6_code)
2825 {
2826     proto_tree *flag_tree, *mp_tree, *up_tree, *rm_tree;
2827     proto_item *ti, *ti_mp, *ti_up, *ti_rm;
2828
2829     /* Sequence Number */
2830     proto_tree_add_item(tree, hf_icmpv6_rr_sequencenumber, tvb, rr_offset, 4, ENC_BIG_ENDIAN);
2831     rr_offset += 4;
2832
2833     /* Segment Number */
2834     proto_tree_add_item(tree, hf_icmpv6_rr_segmentnumber, tvb, rr_offset, 1, ENC_BIG_ENDIAN);
2835     rr_offset += 1;
2836
2837     /* Flags */
2838     ti = proto_tree_add_item(tree, hf_icmpv6_rr_flag, tvb, rr_offset, 1, ENC_BIG_ENDIAN);
2839     flag_tree = proto_item_add_subtree(ti, ett_icmpv6_flag_rr);
2840     proto_tree_add_item(flag_tree, hf_icmpv6_rr_flag_t, tvb, rr_offset, 1, ENC_BIG_ENDIAN);
2841     proto_tree_add_item(flag_tree, hf_icmpv6_rr_flag_r, tvb, rr_offset, 1, ENC_BIG_ENDIAN);
2842     proto_tree_add_item(flag_tree, hf_icmpv6_rr_flag_a, tvb, rr_offset, 1, ENC_BIG_ENDIAN);
2843     proto_tree_add_item(flag_tree, hf_icmpv6_rr_flag_s, tvb, rr_offset, 1, ENC_BIG_ENDIAN);
2844     proto_tree_add_item(flag_tree, hf_icmpv6_rr_flag_p, tvb, rr_offset, 1, ENC_BIG_ENDIAN);
2845     proto_tree_add_item(flag_tree, hf_icmpv6_rr_flag_rsv, tvb, rr_offset, 1, ENC_BIG_ENDIAN);
2846     rr_offset += 1;
2847
2848     /* Max Delay */
2849     proto_tree_add_item(tree, hf_icmpv6_rr_maxdelay, tvb, rr_offset, 2, ENC_BIG_ENDIAN);
2850     rr_offset += 2;
2851
2852     /* Reserved */
2853     proto_tree_add_item(tree, hf_icmpv6_reserved, tvb, rr_offset, 4, ENC_NA);
2854     rr_offset += 4;
2855
2856     /* Data ? */
2857     if(tvb_reported_length_remaining(tvb, rr_offset) == 0){
2858         return rr_offset;
2859     }
2860
2861     if(icmp6_code == ICMP6_ROUTER_RENUMBERING_COMMAND){
2862         /* Match-Prefix Part */
2863         guint8 opcode, matchlen, minlen, maxlen;
2864
2865         ti_mp = proto_tree_add_item(tree, hf_icmpv6_rr_pco_mp_part, tvb, rr_offset, 24, ENC_NA);
2866         mp_tree = proto_item_add_subtree(ti_mp, ett_icmpv6_rr_mp);
2867
2868         /* OpCode */
2869         proto_tree_add_item(mp_tree, hf_icmpv6_rr_pco_mp_opcode, tvb, rr_offset, 1, ENC_BIG_ENDIAN);
2870         opcode = tvb_get_guint8(tvb, rr_offset);
2871         rr_offset += 1;
2872
2873         /* OpLength */
2874         proto_tree_add_item(mp_tree, hf_icmpv6_rr_pco_mp_oplength, tvb, rr_offset, 1, ENC_BIG_ENDIAN);
2875         rr_offset += 1;
2876
2877         /* Ordinal */
2878         proto_tree_add_item(mp_tree, hf_icmpv6_rr_pco_mp_ordinal, tvb, rr_offset, 1, ENC_BIG_ENDIAN);
2879         rr_offset += 1;
2880
2881         /* MatchLen  */
2882         proto_tree_add_item(mp_tree, hf_icmpv6_rr_pco_mp_matchlen, tvb, rr_offset, 1, ENC_BIG_ENDIAN);
2883         matchlen = tvb_get_guint8(tvb, rr_offset);
2884         if (matchlen > 128) {
2885             expert_add_info_format(pinfo, ti, PI_PROTOCOL, PI_WARN,
2886                 "MatchLen is greater than 128");
2887         }
2888         rr_offset += 1;
2889
2890         /* MinLen  */
2891         proto_tree_add_item(mp_tree, hf_icmpv6_rr_pco_mp_minlen, tvb, rr_offset, 1, ENC_BIG_ENDIAN);
2892         minlen = tvb_get_guint8(tvb, rr_offset);
2893         rr_offset += 1;
2894
2895         /* MaxLen  */
2896         proto_tree_add_item(mp_tree, hf_icmpv6_rr_pco_mp_maxlen, tvb, rr_offset, 1, ENC_BIG_ENDIAN);
2897         maxlen = tvb_get_guint8(tvb, rr_offset);
2898         rr_offset += 1;
2899
2900         /* Reserved  */
2901         proto_tree_add_item(mp_tree, hf_icmpv6_reserved, tvb, rr_offset, 2, ENC_NA);
2902         rr_offset += 2;
2903
2904         /* Match Prefix  */
2905         proto_tree_add_item(mp_tree, hf_icmpv6_rr_pco_mp_matchprefix, tvb, rr_offset, 16, ENC_NA);
2906
2907         /* Add Info (Prefix, Length...) to Match Prefix Part label */
2908         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(tvb, rr_offset), matchlen, minlen, maxlen);
2909         rr_offset += 16;
2910
2911         while ((int)tvb_reported_length(tvb) > rr_offset) {
2912             /* Use-Prefix Part */
2913             guint8 uselen, keeplen;
2914
2915             ti_up = proto_tree_add_item(tree, hf_icmpv6_rr_pco_up_part, tvb, rr_offset, 32, ENC_NA);
2916             up_tree = proto_item_add_subtree(ti_up, ett_icmpv6_rr_up);
2917
2918             /* UseLen */
2919             proto_tree_add_item(up_tree, hf_icmpv6_rr_pco_up_uselen, tvb, rr_offset, 1, ENC_BIG_ENDIAN);
2920             uselen = tvb_get_guint8(tvb, rr_offset);
2921             rr_offset += 1;
2922
2923             /* KeepLen */
2924             proto_tree_add_item(up_tree, hf_icmpv6_rr_pco_up_keeplen, tvb, rr_offset, 1, ENC_BIG_ENDIAN);
2925             keeplen = tvb_get_guint8(tvb, rr_offset);
2926             rr_offset += 1;
2927
2928             /* FlagMask */
2929             ti = proto_tree_add_item(up_tree, hf_icmpv6_rr_pco_up_flagmask, tvb, rr_offset, 1, ENC_BIG_ENDIAN);
2930             flag_tree = proto_item_add_subtree(ti, ett_icmpv6_rr_up_flag_mask);
2931             proto_tree_add_item(flag_tree, hf_icmpv6_rr_pco_up_flagmask_l, tvb, rr_offset, 1, ENC_BIG_ENDIAN);
2932             proto_tree_add_item(flag_tree, hf_icmpv6_rr_pco_up_flagmask_a, tvb, rr_offset, 1, ENC_BIG_ENDIAN);
2933             proto_tree_add_item(flag_tree, hf_icmpv6_rr_pco_up_flagmask_reserved, tvb, rr_offset, 1, ENC_BIG_ENDIAN);
2934             rr_offset += 1;
2935
2936             /* RaFlags */
2937             ti = proto_tree_add_item(up_tree, hf_icmpv6_rr_pco_up_raflags, tvb, rr_offset, 1, ENC_BIG_ENDIAN);
2938             flag_tree = proto_item_add_subtree(ti, ett_icmpv6_rr_up_flag_ra);
2939             proto_tree_add_item(flag_tree, hf_icmpv6_rr_pco_up_raflags_l, tvb, rr_offset, 1, ENC_BIG_ENDIAN);
2940             proto_tree_add_item(flag_tree, hf_icmpv6_rr_pco_up_raflags_a, tvb, rr_offset, 1, ENC_BIG_ENDIAN);
2941             proto_tree_add_item(flag_tree, hf_icmpv6_rr_pco_up_raflags_reserved, tvb, rr_offset, 1, ENC_BIG_ENDIAN);
2942             rr_offset += 1;
2943
2944             /* Valid Lifetime */
2945             ti = proto_tree_add_item(up_tree, hf_icmpv6_rr_pco_up_validlifetime, tvb, rr_offset, 4, ENC_BIG_ENDIAN);
2946             switch(tvb_get_ntohl(tvb, rr_offset)){
2947                 case 0xffffffff:
2948                     proto_item_append_text(ti, " (Infinity)");
2949                 break;
2950                 default:
2951                 break;
2952             }
2953             rr_offset += 4;
2954
2955             /* Preferred Lifetime */
2956             ti = proto_tree_add_item(up_tree, hf_icmpv6_rr_pco_up_preferredlifetime, tvb, rr_offset, 4, ENC_BIG_ENDIAN);
2957             switch(tvb_get_ntohl(tvb, rr_offset)){
2958                 case 0xffffffff:
2959                     proto_item_append_text(ti, " (Infinity)");
2960                 break;
2961                 default:
2962                 break;
2963             }
2964             rr_offset += 4;
2965
2966             /* Flags */
2967             ti = proto_tree_add_item(up_tree, hf_icmpv6_rr_pco_up_flag, tvb, rr_offset, 4, ENC_BIG_ENDIAN);
2968             flag_tree = proto_item_add_subtree(ti, ett_icmpv6_rr_up_flag);
2969             proto_tree_add_item(flag_tree, hf_icmpv6_rr_pco_up_flag_v, tvb, rr_offset, 4, ENC_BIG_ENDIAN);
2970             proto_tree_add_item(flag_tree, hf_icmpv6_rr_pco_up_flag_p, tvb, rr_offset, 4, ENC_BIG_ENDIAN);
2971             proto_tree_add_item(flag_tree, hf_icmpv6_rr_pco_up_flag_reserved, tvb, rr_offset, 4, ENC_BIG_ENDIAN);
2972             rr_offset += 4;
2973
2974             /* UsePrefix */
2975             proto_tree_add_item(up_tree, hf_icmpv6_rr_pco_up_useprefix, tvb, rr_offset, 16, ENC_NA);
2976             rr_offset += 16;
2977
2978             /* Add Info (Prefix, Length...) to Use Prefix Part label */
2979             proto_item_append_text(ti_up, ": %s/%u (keep %u)", tvb_ip6_to_str(tvb, rr_offset), uselen, keeplen);
2980         }
2981
2982     }else if(icmp6_code == ICMP6_ROUTER_RENUMBERING_RESULT){
2983         while ((int)tvb_reported_length(tvb) > rr_offset) {
2984         guint8 matchlen;
2985         guint32 interfaceindex;
2986         /* Result Message */
2987
2988         ti_rm = proto_tree_add_item(tree, hf_icmpv6_rr_rm, tvb, rr_offset, 24, ENC_NA);
2989         rm_tree = proto_item_add_subtree(ti_rm, ett_icmpv6_rr_rm);
2990
2991         /* Flags */
2992         ti = proto_tree_add_item(rm_tree, hf_icmpv6_rr_rm_flag, tvb, rr_offset, 2, ENC_BIG_ENDIAN);
2993         flag_tree = proto_item_add_subtree(ti, ett_icmpv6_rr_rm_flag);
2994         proto_tree_add_item(flag_tree, hf_icmpv6_rr_rm_flag_reserved, tvb, rr_offset, 2, ENC_BIG_ENDIAN);
2995         proto_tree_add_item(flag_tree, hf_icmpv6_rr_rm_flag_b, tvb, rr_offset, 2, ENC_BIG_ENDIAN);
2996         proto_tree_add_item(flag_tree, hf_icmpv6_rr_rm_flag_f, tvb, rr_offset, 2, ENC_BIG_ENDIAN);
2997         rr_offset +=2;
2998
2999         /* Ordinal */
3000         proto_tree_add_item(rm_tree, hf_icmpv6_rr_rm_ordinal, tvb, rr_offset, 1, ENC_BIG_ENDIAN);
3001         rr_offset +=1;
3002
3003         /* MatchLen */
3004         ti = proto_tree_add_item(rm_tree, hf_icmpv6_rr_rm_matchedlen, tvb, rr_offset, 1, ENC_BIG_ENDIAN);
3005         matchlen = tvb_get_guint8(tvb, rr_offset);
3006         if (matchlen > 128) {
3007             expert_add_info_format(pinfo, ti, PI_PROTOCOL, PI_WARN,
3008                 "MatchedLen is greater than 128");
3009         }
3010         rr_offset +=1;
3011
3012         /* InterfaceIndex */
3013         proto_tree_add_item(rm_tree, hf_icmpv6_rr_rm_interfaceindex, tvb, rr_offset, 4, ENC_BIG_ENDIAN);
3014         interfaceindex = tvb_get_ntohl(tvb, rr_offset);
3015         rr_offset +=4;
3016
3017         /* MatchedPrefix */
3018         proto_tree_add_item(rm_tree, hf_icmpv6_rr_rm_matchedprefix, tvb, rr_offset, 16, ENC_NA);
3019
3020         /* Add Info (Prefix, Length...) to Use Resultant Message label */
3021         proto_item_append_text(ti_rm, ": %s/%u (interface %u)", tvb_ip6_to_str(tvb, rr_offset), matchlen, interfaceindex);
3022         rr_offset +=16;
3023         }
3024     }
3025     return rr_offset;
3026 }
3027
3028
3029 static int
3030 dissect_mldrv2( tvbuff_t *tvb, guint32 offset, packet_info *pinfo _U_, proto_tree *tree )
3031 {
3032     proto_tree *mar_tree;
3033     proto_item *ti_mar;
3034     int mldr_offset = offset;
3035
3036     /* Reserved */
3037     proto_tree_add_item(tree, hf_icmpv6_reserved, tvb, mldr_offset, 2, ENC_NA );
3038     mldr_offset += 2;
3039
3040     /* Nr of Mcast Address Records (M) */
3041     proto_tree_add_item(tree, hf_icmpv6_mldr_nb_mcast_records, tvb, mldr_offset, 2, ENC_BIG_ENDIAN );
3042     mldr_offset += 2;
3043
3044     /* Multicast Address Record */
3045     while(mldr_offset < (int)tvb_reported_length(tvb) ) {
3046         guint8 aux_data_len, record_type;
3047         guint16 i, nb_sources;
3048         struct e_in6_addr multicast_address;
3049
3050         ti_mar = proto_tree_add_item(tree, hf_icmpv6_mldr_mar, tvb, mldr_offset, -1, ENC_NA);
3051         mar_tree = proto_item_add_subtree(ti_mar, ett_icmpv6_mar);
3052
3053         /* Record Type */
3054         proto_tree_add_item(mar_tree, hf_icmpv6_mldr_mar_record_type, tvb, mldr_offset, 1, ENC_BIG_ENDIAN);
3055         record_type = tvb_get_guint8(tvb, mldr_offset);
3056         mldr_offset += 1;
3057
3058         /* Aux Data Len */
3059         proto_tree_add_item(mar_tree, hf_icmpv6_mldr_mar_aux_data_len, tvb, mldr_offset, 1, ENC_BIG_ENDIAN);
3060         aux_data_len = tvb_get_guint8(tvb, mldr_offset);
3061         mldr_offset += 1;
3062
3063         /* Number of Sources (N) */
3064         proto_tree_add_item(mar_tree, hf_icmpv6_mldr_mar_nb_sources, tvb, mldr_offset, 2, ENC_BIG_ENDIAN);
3065         nb_sources = tvb_get_ntohs(tvb, mldr_offset);
3066         mldr_offset += 2;
3067
3068         /* Multicast Address */
3069         proto_tree_add_item(mar_tree, hf_icmpv6_mldr_mar_multicast_address, tvb, mldr_offset, 16, ENC_NA);
3070         tvb_get_ipv6(tvb, mldr_offset, &multicast_address);
3071         mldr_offset += 16;
3072
3073         /* Source Address */
3074         for (i=1; i <= nb_sources; i++){
3075             proto_tree_add_item(mar_tree, hf_icmpv6_mldr_mar_source_address, tvb, mldr_offset, 16, ENC_NA);
3076             mldr_offset += 16;
3077         }
3078
3079         /* Auxiliary Data ? */
3080         if(aux_data_len)
3081         {
3082             proto_tree_add_item(mar_tree, hf_icmpv6_mldr_mar_auxiliary_data, tvb, mldr_offset, aux_data_len * 4, ENC_NA);
3083             mldr_offset += aux_data_len * 4;
3084         }
3085
3086         /* Multicast Address Record Length */
3087         proto_item_set_len(ti_mar, 4 + 16 + (16 * nb_sources) + (aux_data_len * 4));
3088         proto_item_append_text(ti_mar, " %s: %s", val_to_str(record_type, mldr_record_type_val,"Unknown Record Type (%d)"), ip6_to_str(&multicast_address));
3089
3090     }
3091     return mldr_offset;
3092 }
3093
3094
3095 static int
3096 dissect_icmpv6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
3097 {
3098     proto_tree *icmp6_tree = NULL, *flag_tree = NULL;
3099     proto_item *ti = NULL, *hidden_item, *checksum_item = NULL, *code_item = NULL, *ti_flag = NULL;
3100     const char *code_name = NULL;
3101     guint length = 0, reported_length;
3102     vec_t cksum_vec[4];
3103     guint32 phdr[2];
3104     guint16 cksum, computed_cksum;
3105     int offset;
3106     tvbuff_t *next_tvb;
3107     guint8 icmp6_type, icmp6_code;
3108     icmp_transaction_t *trans = NULL;
3109
3110     col_set_str(pinfo->cinfo, COL_PROTOCOL, "ICMPv6");
3111     col_clear(pinfo->cinfo, COL_INFO);
3112
3113     offset = 0;
3114
3115     if (tree) {
3116         ti = proto_tree_add_item(tree, proto_icmpv6, tvb, offset, -1, ENC_NA);
3117         icmp6_tree = proto_item_add_subtree(ti, ett_icmpv6);
3118
3119         /* Type */
3120         proto_tree_add_item(icmp6_tree, hf_icmpv6_type, tvb, offset, 1, ENC_BIG_ENDIAN);
3121     }
3122     icmp6_type = tvb_get_guint8(tvb, offset);
3123     offset += 1;
3124
3125     col_add_str(pinfo->cinfo, COL_INFO, val_to_str(icmp6_type, icmpv6_type_val, "Unknown (%d)"));
3126
3127     if (tree)
3128         code_item = proto_tree_add_item(icmp6_tree, hf_icmpv6_code, tvb, offset, 1, ENC_BIG_ENDIAN);
3129
3130     icmp6_code = tvb_get_guint8(tvb, offset);
3131     offset += 1;
3132
3133     switch (icmp6_type) {
3134         case ICMP6_DST_UNREACH:
3135             code_name = val_to_str(icmp6_code, icmpv6_unreach_code_val, "Unknown");
3136             break;
3137         case ICMP6_TIME_EXCEEDED:
3138             code_name = val_to_str(icmp6_code, icmpv6_timeex_code_val, "Unknown (%d)");
3139             break;
3140         case ICMP6_PARAM_PROB:
3141             code_name = val_to_str(icmp6_code, icmpv6_paramprob_code_val, "Unknown (%d)");
3142             break;
3143         case ICMP6_ROUTER_RENUMBERING:
3144             code_name = val_to_str(icmp6_code, icmpv6_rr_code_val, "Unknown (%d)");
3145             break;
3146         case ICMP6_NI_QUERY:
3147             code_name = val_to_str(icmp6_code, ni_query_code_val, "Unknown (%d)");
3148             break;
3149         case ICMP6_NI_REPLY:
3150             code_name = val_to_str(icmp6_code, ni_reply_code_val, "Unknown (%d)");
3151             break;
3152         case ICMP6_RPL_CONTROL:
3153             code_name = val_to_str(icmp6_code, rpl_code_val, "Unknown (%d)");
3154             break;
3155     }
3156
3157     if (code_name)
3158         col_append_fstr(pinfo->cinfo, COL_INFO, " (%s)", code_name);
3159
3160     /* RFC 4380
3161      * 2.7.   Teredo UDP Port
3162      * 5.2.9. Direct IPv6 Connectivity Test  */
3163     if (pinfo->destport == 3544 && icmp6_type == ICMP6_ECHO_REQUEST) {
3164         col_set_str(pinfo->cinfo, COL_PROTOCOL, "Teredo");
3165         col_set_str(pinfo->cinfo, COL_INFO, "Direct IPv6 Connectivity Test");
3166     }
3167
3168     if (tree) {
3169         if (code_name)
3170             proto_item_append_text(code_item, " (%s)", code_name);
3171         checksum_item = proto_tree_add_item(icmp6_tree, hf_icmpv6_checksum, tvb, offset, 2, ENC_BIG_ENDIAN);
3172     }
3173
3174     cksum = tvb_get_ntohs(tvb, offset);
3175
3176     if (1) { /* There's an expert info in here so always execute */
3177         length = tvb_length(tvb);
3178         reported_length = tvb_reported_length(tvb);
3179         if (!pinfo->fragmented && length >= reported_length) {
3180             /* The packet isn't part of a fragmented datagram and isn't
3181                truncated, so we can checksum it. */
3182
3183             /* Set up the fields of the pseudo-header. */
3184             cksum_vec[0].ptr = pinfo->src.data;
3185             cksum_vec[0].len = pinfo->src.len;
3186             cksum_vec[1].ptr = pinfo->dst.data;
3187             cksum_vec[1].len = pinfo->dst.len;
3188             cksum_vec[2].ptr = (const guint8 *)&phdr;
3189             phdr[0] = g_htonl(reported_length);
3190             phdr[1] = g_htonl(IP_PROTO_ICMPV6);
3191             cksum_vec[2].len = 8;
3192             cksum_vec[3].len = reported_length;
3193             cksum_vec[3].ptr = tvb_get_ptr(tvb, 0, cksum_vec[3].len);
3194             computed_cksum = in_cksum(cksum_vec, 4);
3195
3196             if (computed_cksum == 0) {
3197                 proto_item_append_text(checksum_item, " [correct]");
3198             } else {
3199                 hidden_item = proto_tree_add_boolean(icmp6_tree, hf_icmpv6_checksum_bad, tvb, offset, 2, TRUE);
3200
3201                 PROTO_ITEM_SET_GENERATED(hidden_item);
3202                 proto_item_append_text(checksum_item, " [incorrect, should be 0x%04x]", in_cksum_shouldbe(cksum, computed_cksum));
3203                 expert_add_info_format(pinfo, checksum_item, PI_CHECKSUM, PI_WARN,
3204                                        "ICMPv6 Checksum Incorrect, should be 0x%04x", in_cksum_shouldbe(cksum, computed_cksum));
3205             }
3206         }
3207     }
3208     offset += 2;
3209
3210     if (icmp6_type == ICMP6_ECHO_REQUEST || icmp6_type == ICMP6_ECHO_REPLY) {
3211         guint16 identifier, sequence;
3212
3213         /* Identifier */
3214         if (tree)
3215             proto_tree_add_item(icmp6_tree, hf_icmpv6_echo_identifier, tvb, offset, 2, ENC_BIG_ENDIAN);
3216         identifier = tvb_get_ntohs(tvb, offset);
3217         offset += 2;
3218
3219         /* Sequence Number */
3220         if (tree)
3221             proto_tree_add_item(icmp6_tree, hf_icmpv6_echo_sequence_number, tvb, offset, 2, ENC_BIG_ENDIAN);
3222         sequence = tvb_get_ntohs(tvb, offset);
3223         offset += 2;
3224
3225         col_append_fstr(pinfo->cinfo, COL_INFO, " id=0x%04x, seq=%u", identifier, sequence);
3226
3227         if (pinfo->destport == 3544 && icmp6_type == ICMP6_ECHO_REQUEST) {
3228             /* RFC 4380
3229              * 2.7.   Teredo UDP Port
3230              * 5.2.9. Direct IPv6 Connectivity Test
3231              *
3232              * TODO: Clarify the nonce:  The RFC states, "(It is recommended to
3233              * use a random number [the nonce] at least 64 bits long.)"
3234              *
3235              * Shouldn't the nonce be at least 8 then?  Why not just use (-1),
3236              * as it could really be any length, couldn't it?
3237              */
3238             if (tree)
3239                 proto_tree_add_item(icmp6_tree, hf_icmpv6_nonce, tvb, offset, 4, ENC_NA);
3240             offset += 4;
3241         } else {
3242             if (!pinfo->flags.in_error_pkt) {
3243                 guint32 conv_key[2];
3244
3245                 conv_key[1] = (guint32)((identifier << 16) | sequence);
3246
3247                 if (icmp6_type == ICMP6_ECHO_REQUEST) {
3248                     conv_key[0] = (guint32)cksum;
3249                     if (pinfo->flags.in_gre_pkt)
3250                         conv_key[0] |= 0x00010000; /* set a bit for "in GRE" */
3251                     trans = transaction_start(pinfo, icmp6_tree, conv_key);
3252                 } else { /* ICMP6_ECHO_REPLY */
3253                     guint16 tmp[2];
3254
3255                     tmp[0] = ~cksum;
3256                     tmp[1] = ~0x0100; /* The difference between echo request & reply */
3257                     cksum_vec[0].len = sizeof(tmp);
3258                     cksum_vec[0].ptr = (guint8 *)tmp;
3259                     conv_key[0] = in_cksum(cksum_vec, 1);
3260                     if (pinfo->flags.in_gre_pkt)
3261                         conv_key[0] |= 0x00010000; /* set a bit for "in GRE" */
3262                     trans = transaction_end(pinfo, icmp6_tree, conv_key);
3263                 }
3264             }
3265             next_tvb = tvb_new_subset(tvb, offset, -1, -1);
3266             offset += call_dissector(data_handle, next_tvb, pinfo, icmp6_tree);
3267         }
3268     }
3269
3270     if (1) { /* There are expert infos buried in here so always execute */
3271         /* decode... */
3272         switch (icmp6_type) {
3273             case ICMP6_DST_UNREACH: /* Destination Unreachable (1) */
3274             case ICMP6_TIME_EXCEEDED: /* Time Exceeded (3) */
3275                 /* Reserved */
3276                 proto_tree_add_item(icmp6_tree, hf_icmpv6_reserved, tvb, offset, 4, ENC_NA);
3277                 offset += 4;
3278
3279                 offset = dissect_contained_icmpv6(tvb, offset, pinfo, icmp6_tree);
3280                 break;
3281             case ICMP6_PACKET_TOO_BIG: /* Packet Too Big (2) */
3282                 /* MTU */
3283                 proto_tree_add_item(icmp6_tree, hf_icmpv6_mtu, tvb, offset, 4, ENC_BIG_ENDIAN);
3284                 offset += 4;
3285
3286                 offset = dissect_contained_icmpv6(tvb, offset, pinfo, icmp6_tree);
3287                 break;
3288             case ICMP6_PARAM_PROB: /* Parameter Problem (4) */
3289                 /* MTU */
3290                 proto_tree_add_item(icmp6_tree, hf_icmpv6_pointer, tvb, offset, 4, ENC_BIG_ENDIAN);
3291                 offset += 4;
3292
3293                 offset = dissect_contained_icmpv6(tvb, offset, pinfo, icmp6_tree);
3294                 break;
3295             case ICMP6_ECHO_REQUEST:    /* Echo Request (128) */
3296             case ICMP6_ECHO_REPLY:      /* Echo Reply (129) */
3297                 /* Already handled above */
3298                 break;
3299             case ICMP6_MEMBERSHIP_QUERY: /* Multicast Listener Query (130) */
3300             case ICMP6_MEMBERSHIP_REPORT: /* Multicast Listener Report (131) */
3301             case ICMP6_MEMBERSHIP_REDUCTION: /* Multicast Listener Done (132) */
3302             {
3303                 /* It is MLDv2 packet ? (the min length for a MLDv2 packet is 28) */
3304                 if ((icmp6_type == ICMP6_MEMBERSHIP_QUERY) && (length >= MLDV2_PACKET_MINLEN)) {
3305                     guint32 mrc;
3306                     guint16 qqi, i, nb_sources;
3307
3308                     /* Maximum Response Code */
3309                     mrc = tvb_get_ntohs(tvb, offset);
3310                     if (mrc >= 32768){
3311                         mrc = ((mrc & 0x0fff) | 0x1000) << (((mrc & 0x7000) >> 12) + 3);
3312                     }
3313                     proto_tree_add_uint(icmp6_tree, hf_icmpv6_mld_mrc, tvb, offset, 2, mrc);
3314                     offset += 2;
3315
3316                     /* Reserved */
3317                     proto_tree_add_item(icmp6_tree, hf_icmpv6_reserved, tvb, offset, 2, ENC_NA);
3318                     offset += 2;
3319
3320                     /* Multicast Address */
3321                     proto_tree_add_item(icmp6_tree, hf_icmpv6_mld_multicast_address, tvb, offset, 16, ENC_NA);
3322                     offset += 16;
3323
3324                     /* Flag */
3325                     ti_flag = proto_tree_add_item(icmp6_tree, hf_icmpv6_mld_flag, tvb, offset, 1, ENC_BIG_ENDIAN);
3326                     flag_tree = proto_item_add_subtree(ti_flag, ett_icmpv6_flag_mld);
3327                     proto_tree_add_item(flag_tree, hf_icmpv6_mld_flag_s, tvb, offset, 1, ENC_BIG_ENDIAN);
3328                     proto_tree_add_item(flag_tree, hf_icmpv6_mld_flag_qrv, tvb, offset, 1, ENC_BIG_ENDIAN);
3329                     proto_tree_add_item(flag_tree, hf_icmpv6_mld_flag_rsv, tvb, offset, 1, ENC_BIG_ENDIAN);
3330                     offset += 1;
3331
3332                     /* QQI */
3333                     qqi = tvb_get_guint8(tvb, offset);
3334                     if (qqi >= 128){
3335                         qqi = ((qqi & 0x0f) | 0x10) << (((qqi & 0x70) >> 4) + 3);
3336                     }
3337                     proto_tree_add_uint(icmp6_tree, hf_icmpv6_mld_qqi, tvb, offset, 1, qqi);
3338                     offset += 1;
3339
3340                     /* Number of Sources */
3341                     proto_tree_add_item(icmp6_tree, hf_icmpv6_mld_nb_sources, tvb, offset, 2, ENC_BIG_ENDIAN);
3342                     nb_sources = tvb_get_ntohs(tvb, offset);
3343                     offset += 2;
3344
3345                     /* Source Address */
3346                     for (i=1; i <= nb_sources; i++){
3347                         proto_tree_add_item(icmp6_tree, hf_icmpv6_mld_source_address, tvb, offset, 16, ENC_NA);
3348                         offset += 16;
3349                     }
3350
3351                 }else{ /* It is a MLDv1 Packet */
3352
3353                     proto_tree_add_item(icmp6_tree, hf_icmpv6_mld_mrd, tvb, offset, 2, ENC_BIG_ENDIAN);
3354                     offset += 2;
3355
3356                     /* Reserved */
3357                     proto_tree_add_item(icmp6_tree, hf_icmpv6_reserved, tvb, offset, 2, ENC_NA);
3358                     offset += 2;
3359
3360                     /* Multicast Address */
3361                     proto_tree_add_item(icmp6_tree, hf_icmpv6_mld_multicast_address, tvb, offset, 16, ENC_NA);
3362                     offset += 16;
3363                 }
3364                 break;
3365             }
3366             case ICMP6_ND_ROUTER_SOLICIT: /* Router Solicitation (133) */
3367             {
3368                 /* Reserved */
3369                 proto_tree_add_item(icmp6_tree, hf_icmpv6_reserved, tvb, offset, 4, ENC_NA);
3370                 offset += 4;
3371
3372                 /* Show options */
3373                 offset = dissect_icmpv6_nd_opt(tvb, offset, pinfo, icmp6_tree);
3374                 break;
3375             }
3376             case ICMP6_ND_ROUTER_ADVERT: /* Router Advertisement (134) */
3377             {
3378
3379                 /* Current hop limit */
3380                 proto_tree_add_item(icmp6_tree, hf_icmpv6_nd_ra_cur_hop_limit, tvb, offset, 1, ENC_BIG_ENDIAN);
3381                 offset += 1;
3382
3383                 /* Flags */
3384                 ti_flag = proto_tree_add_item(icmp6_tree, hf_icmpv6_nd_ra_flag, tvb, offset, 1, ENC_BIG_ENDIAN);
3385                 flag_tree = proto_item_add_subtree(ti_flag, ett_icmpv6_flag_ra);
3386
3387                 proto_tree_add_item(flag_tree, hf_icmpv6_nd_ra_flag_m, tvb, offset, 1, ENC_BIG_ENDIAN);
3388                 proto_tree_add_item(flag_tree, hf_icmpv6_nd_ra_flag_o, tvb, offset, 1, ENC_BIG_ENDIAN);
3389                 proto_tree_add_item(flag_tree, hf_icmpv6_nd_ra_flag_h, tvb, offset, 1, ENC_BIG_ENDIAN);
3390                 proto_tree_add_item(flag_tree, hf_icmpv6_nd_ra_flag_prf, tvb, offset, 1, ENC_BIG_ENDIAN);
3391                 proto_tree_add_item(flag_tree, hf_icmpv6_nd_ra_flag_p, tvb, offset, 1, ENC_BIG_ENDIAN);
3392                 proto_tree_add_item(flag_tree, hf_icmpv6_nd_ra_flag_rsv, tvb, offset, 1, ENC_BIG_ENDIAN);
3393                 offset += 1;
3394
3395                 /* Router lifetime */
3396                 proto_tree_add_item(icmp6_tree, hf_icmpv6_nd_ra_router_lifetime, tvb, offset, 2, ENC_BIG_ENDIAN);
3397                 offset += 2;
3398
3399                 /* Reachable time */
3400                 proto_tree_add_item(icmp6_tree, hf_icmpv6_nd_ra_reachable_time, tvb, offset, 4, ENC_BIG_ENDIAN);
3401                 offset += 4;
3402
3403                 /* Retrans timer */
3404                 proto_tree_add_item(icmp6_tree, hf_icmpv6_nd_ra_retrans_timer, tvb, offset, 4, ENC_BIG_ENDIAN);
3405                 offset += 4;
3406
3407                 /* Show options */
3408                 offset = dissect_icmpv6_nd_opt(tvb, offset, pinfo, icmp6_tree);
3409                 break;
3410             }
3411             case ICMP6_ND_NEIGHBOR_SOLICIT: /* Neighbor Solicitation (135) */
3412             {
3413                 /* Reserved */
3414                 proto_tree_add_item(icmp6_tree, hf_icmpv6_reserved, tvb, offset, 4, ENC_NA);
3415                 offset += 4;
3416
3417                 /* Target Address */
3418                 proto_tree_add_item(icmp6_tree, hf_icmpv6_nd_ns_target_address, tvb, offset, 16, ENC_NA);
3419                 col_append_fstr(pinfo->cinfo, COL_INFO, " for %s", tvb_ip6_to_str(tvb, offset));
3420
3421                 offset += 16;
3422
3423                 /* Show options */
3424                 offset = dissect_icmpv6_nd_opt(tvb, offset, pinfo, icmp6_tree);
3425                 break;
3426             }
3427             case ICMP6_ND_NEIGHBOR_ADVERT: /* Neighbor Advertisement (136) */
3428             {
3429                 guint32 na_flags;
3430                 emem_strbuf_t *flags_strbuf = ep_strbuf_new_label("");
3431
3432                 /* Flags */
3433                 ti_flag = proto_tree_add_item(icmp6_tree, hf_icmpv6_nd_na_flag, tvb, offset, 4, ENC_BIG_ENDIAN);
3434                 flag_tree = proto_item_add_subtree(ti_flag, ett_icmpv6_flag_na);
3435                 proto_tree_add_item(flag_tree, hf_icmpv6_nd_na_flag_r, tvb, offset, 4, ENC_BIG_ENDIAN);
3436                 proto_tree_add_item(flag_tree, hf_icmpv6_nd_na_flag_s, tvb, offset, 4, ENC_BIG_ENDIAN);
3437                 proto_tree_add_item(flag_tree, hf_icmpv6_nd_na_flag_o, tvb, offset, 4, ENC_BIG_ENDIAN);
3438                 proto_tree_add_item(flag_tree, hf_icmpv6_nd_na_flag_rsv, tvb, offset, 4, ENC_BIG_ENDIAN);
3439                 na_flags = tvb_get_ntohl(tvb, offset);
3440                 offset += 4;
3441
3442                 /* Target Address */
3443                 proto_tree_add_item(icmp6_tree, hf_icmpv6_nd_na_target_address, tvb, offset, 16, ENC_NA);
3444
3445
3446                 if (na_flags & ND_NA_FLAG_R) {
3447                     ep_strbuf_append(flags_strbuf, "rtr, ");
3448                 }
3449                 if (na_flags & ND_NA_FLAG_S) {
3450                     ep_strbuf_append(flags_strbuf, "sol, ");
3451                 }
3452                 if (na_flags & ND_NA_FLAG_O) {
3453                     ep_strbuf_append(flags_strbuf, "ovr, ");
3454                 }
3455                 if (flags_strbuf->len > 2) {
3456                     ep_strbuf_truncate(flags_strbuf, flags_strbuf->len - 2);
3457                 } else {
3458                     ep_strbuf_printf(flags_strbuf, "none");
3459                 }
3460
3461                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s (%s)", tvb_ip6_to_str(tvb, offset), flags_strbuf->str);
3462                 offset += 16;
3463
3464                 /* Show options */
3465                 offset = dissect_icmpv6_nd_opt(tvb, offset, pinfo, icmp6_tree);
3466                 break;
3467             }
3468             case ICMP6_ND_REDIRECT: /* Redirect Message (137) */
3469             {
3470                 /* Reserved */
3471                 proto_tree_add_item(icmp6_tree, hf_icmpv6_reserved, tvb, offset, 4, ENC_NA);
3472                 offset += 4;
3473
3474                 /* Target Address */
3475                 proto_tree_add_item(icmp6_tree, hf_icmpv6_nd_rd_target_address, tvb, offset, 16, ENC_NA);
3476                 offset += 16;
3477
3478                 /* Destination Address */
3479                 proto_tree_add_item(icmp6_tree, hf_icmpv6_nd_rd_destination_address, tvb, offset, 16, ENC_NA);
3480                 offset += 16;
3481
3482                 /* Show options */
3483                 offset = dissect_icmpv6_nd_opt(tvb, offset, pinfo, icmp6_tree);
3484                 break;
3485             }
3486             case ICMP6_ROUTER_RENUMBERING: /* Router Renumbering (138) */
3487             {
3488                 offset = dissect_rrenum(tvb, offset, pinfo, icmp6_tree, icmp6_type, icmp6_code);
3489                 break;
3490             }
3491             case ICMP6_NI_QUERY: /* ICMP Node Information Query (139) */
3492             case ICMP6_NI_REPLY: /* ICMP Node Information Response (140) */
3493             {
3494                 offset = dissect_nodeinfo(tvb, offset, pinfo, icmp6_tree, icmp6_type, icmp6_code);
3495                 break;
3496             }
3497             case ICMP6_IND_SOLICIT: /* Inverse Neighbor Discovery Solicitation Message (141) */
3498             case ICMP6_IND_ADVERT: /* Inverse Neighbor Discovery Advertisement Message (142) */
3499             {
3500                 /* Reserved */
3501                 proto_tree_add_item(icmp6_tree, hf_icmpv6_reserved, tvb, offset, 4, ENC_NA);
3502                 offset += 4;
3503
3504                 /* Show options */
3505                 offset = dissect_icmpv6_nd_opt(tvb, offset, pinfo, icmp6_tree);
3506                 break;
3507             }
3508             case ICMP6_MLDV2_REPORT: /* Version 2 Multicast Listener Report (143) */
3509             {
3510                 offset = dissect_mldrv2( tvb, offset, pinfo, icmp6_tree );
3511                 break;
3512             }
3513             case ICMP6_MIP6_DHAAD_REQUEST: /* Home Agent Address Discovery Request Message (144) */
3514             {
3515                 /* Identifier */
3516                 proto_tree_add_item(icmp6_tree, hf_icmpv6_mip6_identifier, tvb, offset, 2, ENC_BIG_ENDIAN);
3517                 offset += 2;
3518
3519                 /* Reserved */
3520                 proto_tree_add_item(icmp6_tree, hf_icmpv6_reserved, tvb, offset, 2, ENC_NA);
3521                 offset += 2;
3522
3523                 break;
3524             }
3525             case ICMP6_MIP6_DHAAD_REPLY: /* Home Agent Address Discovery Reply Message (145) */
3526             {
3527                 /* Identifier */
3528                 proto_tree_add_item(icmp6_tree, hf_icmpv6_mip6_identifier, tvb, offset, 2, ENC_BIG_ENDIAN);
3529                 offset += 2;
3530
3531                 /* Reserved */
3532                 proto_tree_add_item(icmp6_tree, hf_icmpv6_reserved, tvb, offset, 2, ENC_NA);
3533                 offset += 2;
3534
3535                 /* Show all Home Agent Addresses */
3536                 while((int)length > offset)
3537                 {
3538                     proto_tree_add_item(icmp6_tree, hf_icmpv6_mip6_home_agent_address, tvb, offset, 16, ENC_NA);
3539                     offset += 16;
3540                 }
3541                 break;
3542             }
3543             case ICMP6_MIP6_MPS: /* Mobile Prefix Solicitation (146) */
3544             {
3545                 /* Identifier */
3546                 proto_tree_add_item(icmp6_tree, hf_icmpv6_mip6_identifier, tvb, offset, 2, ENC_BIG_ENDIAN);
3547                 offset += 2;
3548
3549                 /* Reserved */
3550                 proto_tree_add_item(icmp6_tree, hf_icmpv6_reserved, tvb, offset, 2, ENC_NA);
3551                 offset += 2;
3552                 break;
3553             }
3554             case ICMP6_MIP6_MPA: /* Mobile Prefix Advertisement (147) */
3555             {
3556                 /* Identifier */
3557                 proto_tree_add_item(icmp6_tree, hf_icmpv6_mip6_identifier, tvb, offset, 2, ENC_BIG_ENDIAN);
3558                 offset += 2;
3559
3560                 /* Flag */
3561                 ti_flag = proto_tree_add_item(icmp6_tree, hf_icmpv6_mip6_flag, tvb,offset, 6, ENC_NA);
3562                 flag_tree = proto_item_add_subtree(ti_flag, ett_icmpv6_flag_mip6);
3563                 proto_tree_add_item(flag_tree, hf_icmpv6_mip6_flag_m, tvb, offset, 2, ENC_BIG_ENDIAN);
3564                 proto_tree_add_item(flag_tree, hf_icmpv6_mip6_flag_o, tvb, offset, 2, ENC_BIG_ENDIAN);
3565                 proto_tree_add_item(flag_tree, hf_icmpv6_mip6_flag_rsv, tvb, offset, 2, ENC_BIG_ENDIAN);
3566                 offset += 2;
3567
3568                 /* Show options */
3569                 offset = dissect_icmpv6_nd_opt(tvb, offset, pinfo, icmp6_tree);
3570                 break;
3571             }
3572             case ICMP6_CERT_PATH_SOL: /* Certification Path Solicitation Message (148) */
3573             {
3574
3575                 /* Identifier */
3576                 proto_tree_add_item(icmp6_tree, hf_icmpv6_send_identifier, tvb, offset, 2, ENC_BIG_ENDIAN);
3577                 offset += 2;
3578
3579                 /* Component  */
3580                 proto_tree_add_item(icmp6_tree, hf_icmpv6_send_component, tvb, offset, 2, ENC_BIG_ENDIAN);
3581                 offset += 2;
3582
3583                 /* Show options */
3584                 offset = dissect_icmpv6_nd_opt(tvb, offset, pinfo, icmp6_tree);
3585                 break;
3586             }
3587             case ICMP6_CERT_PATH_AD: /* Certification Path Advertisement Message (149) */
3588             {
3589
3590                 /* Identifier */
3591                 proto_tree_add_item(icmp6_tree, hf_icmpv6_send_identifier, tvb, offset, 2, ENC_BIG_ENDIAN);
3592                 offset += 2;
3593
3594                 /* All Components */
3595                 proto_tree_add_item(icmp6_tree, hf_icmpv6_send_all_components, tvb, offset, 2, ENC_BIG_ENDIAN);
3596                 offset += 2;
3597
3598                 /* Component  */
3599                 proto_tree_add_item(icmp6_tree, hf_icmpv6_send_component, tvb, offset, 2, ENC_BIG_ENDIAN);
3600                 offset += 2;
3601
3602                 /* Reserved */
3603                 proto_tree_add_item(icmp6_tree, hf_icmpv6_reserved, tvb, offset, 2, ENC_NA);
3604                 offset += 2;
3605
3606                 /* Show options */
3607                 offset = dissect_icmpv6_nd_opt(tvb, offset, pinfo, icmp6_tree);
3608                 break;
3609             }
3610             case ICMP6_EXPERIMENTAL_MOBILITY: /* ICMP messages utilized by experimental mobility protocols (150) */
3611             case ICMP6_FMIPV6_MESSAGES:  /* FMIPv6 Messages (154)*/
3612             {
3613                 guint8 subtype;
3614
3615                 /* Subtype */
3616                 proto_tree_add_item(icmp6_tree, hf_icmpv6_fmip6_subtype, tvb, offset, 1, ENC_BIG_ENDIAN);
3617                 subtype = tvb_get_guint8(tvb, offset);
3618                 col_append_fstr(pinfo->cinfo, COL_INFO, " (%s)", val_to_str(subtype, fmip6_subtype_val, "Unknown (%d)"));
3619                 offset += 1;
3620
3621                 switch(subtype){
3622                     case FMIP6_SUBTYPE_RTSOLPR:
3623                     {
3624                         /* Reserved */
3625                         proto_tree_add_item(icmp6_tree, hf_icmpv6_reserved, tvb, offset, 1, ENC_NA);
3626                     }
3627                     break;
3628                     case FMIP6_SUBTYPE_PRRTADV:
3629                     {
3630                         proto_item_append_text(code_item, " (%s)", val_to_str(icmp6_code, fmip6_prrtadv_code_val, "Unknown %d") );
3631                         /* Reserved */
3632                         proto_tree_add_item(icmp6_tree, hf_icmpv6_reserved, tvb, offset, 1, ENC_NA);
3633                     }
3634                     break;
3635                     case FMIP6_SUBTYPE_HI:
3636                     {
3637                         proto_item_append_text(code_item, " (%s)", val_to_str(icmp6_code, fmip6_hi_code_val, "Unknown %d") );
3638                         /* Flags */
3639                         ti_flag = proto_tree_add_item(icmp6_tree, hf_icmpv6_fmip6_hi_flag, tvb, offset, 1, ENC_BIG_ENDIAN);
3640                         flag_tree = proto_item_add_subtree(ti_flag, ett_icmpv6_flag_fmip6);
3641
3642                         proto_tree_add_item(flag_tree, hf_icmpv6_fmip6_hi_flag_s, tvb, offset, 1, ENC_BIG_ENDIAN);
3643                         proto_tree_add_item(flag_tree, hf_icmpv6_fmip6_hi_flag_u, tvb, offset, 1, ENC_BIG_ENDIAN);
3644                         proto_tree_add_item(flag_tree, hf_icmpv6_fmip6_hi_flag_reserved, tvb, offset, 1, ENC_BIG_ENDIAN);
3645                     }
3646                     break;
3647                     case FMIP6_SUBTYPE_HACK:
3648                     {
3649                         proto_item_append_text(code_item, " (%s)", val_to_str(icmp6_code, fmip6_hack_code_val, "Unknown %d") );
3650                         /* Reserved */
3651                         proto_tree_add_item(icmp6_tree, hf_icmpv6_reserved, tvb, offset, 1, ENC_NA);
3652                     }
3653                     break;
3654                 }
3655                 offset +=1;
3656
3657                 /* Identifier */
3658                 proto_tree_add_item(icmp6_tree, hf_icmpv6_fmip6_identifier, tvb, offset, 2, ENC_BIG_ENDIAN);
3659                 offset += 2;
3660
3661                 /* Show options */
3662                 offset = dissect_icmpv6_nd_opt(tvb, offset, pinfo, icmp6_tree);
3663                 break;
3664             }
3665             case ICMP6_MCAST_ROUTER_ADVERT: /* Multicast Router Advertisement (151) */
3666             {
3667                 /* Query Interval */
3668                 proto_tree_add_item(icmp6_tree, hf_icmpv6_mcast_ra_query_interval, tvb, offset, 2, ENC_BIG_ENDIAN);
3669                 offset += 2;
3670
3671                 /* Robustness Variable */
3672                 proto_tree_add_item(icmp6_tree, hf_icmpv6_mcast_ra_robustness_variable, tvb, offset, 2, ENC_BIG_ENDIAN);
3673                 offset += 2;
3674             }
3675             case ICMP6_MCAST_ROUTER_SOLICIT: /* Multicast Router Solicitation (152) */
3676             case ICMP6_MCAST_ROUTER_TERM: /* Multicast Router Termination (153) */
3677             {
3678                 /* No Action... */
3679                 break;
3680             }
3681             case ICMP6_RPL_CONTROL: /* RPL Control (155) */
3682             {
3683                 /* RPL: draft-ietf-roll-rpl-19.txt: Routing over Low-Power and Lossy Networks. */
3684                 offset = dissect_rpl_control(tvb, offset, pinfo, icmp6_tree, icmp6_type, icmp6_code);
3685                 break;
3686             }
3687
3688             case ICMP6_6LOWPANND_DAR:
3689             case ICMP6_6LOWPANND_DAC:
3690             {
3691                 /* Status */
3692                 proto_tree_add_item(icmp6_tree, hf_icmpv6_da_status, tvb, offset, 1, ENC_BIG_ENDIAN);
3693                 offset += 1;
3694
3695                 /* Reserved */
3696                 proto_tree_add_item(icmp6_tree, hf_icmpv6_da_rsv, tvb, offset, 1, ENC_BIG_ENDIAN);
3697                 offset += 1;
3698
3699                 /* Lifetime */
3700                 proto_tree_add_item(icmp6_tree, hf_icmpv6_da_lifetime, tvb, offset, 2, ENC_BIG_ENDIAN);
3701                 offset += 2;
3702
3703                 /* EUI-64 */
3704                 proto_tree_add_item(icmp6_tree, hf_icmpv6_da_eui64, tvb, offset, 8, ENC_BIG_ENDIAN);
3705                 offset += 8;
3706
3707                 /* Address */
3708                 proto_tree_add_item(icmp6_tree, hf_icmpv6_da_raddr, tvb, offset, 16, ENC_NA);
3709                 offset += 16;
3710                 break;
3711             }
3712             default:
3713                 expert_add_info_format(pinfo, ti, PI_UNDECODED, PI_NOTE,
3714                                        "Dissector for ICMPv6 Type (%d)"
3715                                        " code not implemented, Contact Wireshark"
3716                                        " developers if you want this supported", icmp6_type);
3717                 proto_tree_add_item(icmp6_tree, hf_icmpv6_data, tvb, offset, -1, ENC_NA);
3718                 break;
3719         } /* switch (icmp6_type) */
3720     } /* if (1) */
3721
3722     if (trans)
3723         tap_queue_packet(icmpv6_tap, pinfo, trans);
3724
3725     return offset;
3726 }
3727
3728 void
3729 proto_register_icmpv6(void)
3730 {
3731     static hf_register_info hf[] = {
3732         { &hf_icmpv6_type,
3733           { "Type", "icmpv6.type", FT_UINT8, BASE_DEC, VALS(icmpv6_type_val), 0x0,
3734             "Indicates the type of the message", HFILL }},
3735         { &hf_icmpv6_code,
3736           { "Code", "icmpv6.code", FT_UINT8, BASE_DEC, NULL, 0x0,
3737             "Depends on the message type.  It is used to create an additional level of message granularity", HFILL }},
3738         { &hf_icmpv6_checksum,
3739           { "Checksum", "icmpv6.checksum", FT_UINT16, BASE_HEX, NULL, 0x0,
3740             "Used to detect data corruption in the ICMPv6 message and parts of the IPv6 header", HFILL }},
3741         { &hf_icmpv6_checksum_bad,
3742           { "Bad Checksum", "icmpv6.checksum_bad", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3743             NULL, HFILL }},
3744         { &hf_icmpv6_reserved,
3745           { "Reserved", "icmpv6.reserved", FT_BYTES, BASE_NONE, NULL, 0x0,
3746             "Must be Zero", HFILL }},
3747         { &hf_icmpv6_data,
3748           { "Data", "icmpv6.data", FT_BYTES, BASE_NONE, NULL, 0x0,
3749             NULL, HFILL }},
3750         { &hf_icmpv6_unknown_data,
3751           { "Unknown Data", "icmpv6.unknown_data", FT_BYTES, BASE_NONE, NULL, 0x0,
3752             "Not interpreted Data", HFILL }},
3753         { &hf_icmpv6_mtu,
3754           { "MTU", "icmpv6.mtu", FT_UINT32, BASE_DEC, NULL, 0x0,
3755             "The Maximum Transmission Unit of the next-hop link", HFILL }},
3756         { &hf_icmpv6_pointer,
3757           { "Pointer", "icmpv6.pointer", FT_UINT32, BASE_DEC, NULL, 0x0,
3758             "Identifies the octet offset within the invoking packet where the error was detected", HFILL }},
3759         { &hf_icmpv6_echo_identifier,
3760           { "Identifier", "icmpv6.echo.identifier", FT_UINT16, BASE_HEX, NULL, 0x0,
3761             "An identifier to aid in matching with Request and Reply", HFILL }},
3762         { &hf_icmpv6_echo_sequence_number,
3763           { "Sequence", "icmpv6.echo.sequence_number", FT_UINT16, BASE_DEC, NULL, 0x0,
3764             "A sequence number to aid in matching Echo Replies to this Echo Request", HFILL }},
3765         { &hf_icmpv6_nonce,
3766           { "Nonce", "icmpv6.nonce", FT_BYTES, BASE_NONE, NULL, 0x0,
3767             NULL, HFILL }},
3768         /* RFC 2461/4861 : Neighbor Discovery for IP version 6 (IPv6) */
3769         { &hf_icmpv6_nd_ra_cur_hop_limit,
3770           { "Cur hop limit", "icmpv6.nd.ra.cur_hop_limit", FT_UINT8, BASE_DEC, NULL, 0x0,
3771             "The default value that should be placed in the Hop Count field of the IP header for outgoing IP packets", HFILL }},
3772         { &hf_icmpv6_nd_ra_flag,
3773           { "Flags", "icmpv6.nd.ra.flag", FT_UINT8, BASE_HEX, NULL, 0x0,
3774             NULL, HFILL }},
3775         { &hf_icmpv6_nd_ra_flag_m,
3776           { "Managed address configuration", "icmpv6.nd.ra.flag.m", FT_BOOLEAN, 8, TFS(&tfs_set_notset), ND_RA_FLAG_M,
3777             "When set, it indicates that addresses are available via DHCPv6", HFILL }},
3778         { &hf_icmpv6_nd_ra_flag_o,
3779           { "Other configuration", "icmpv6.nd.ra.flag.o", FT_BOOLEAN, 8, TFS(&tfs_set_notset), ND_RA_FLAG_O,
3780             "When set, it indicates that other configuration information is available via DHCPv6", HFILL }},
3781         { &hf_icmpv6_nd_ra_flag_h,
3782           { "Home Agent", "icmpv6.nd.ra.flag.h", FT_BOOLEAN, 8, TFS(&tfs_set_notset), ND_RA_FLAG_H,
3783             "When set, it indicate that the router sending this Router Advertisement is also functioning as a Mobile IPv6 home agent on this link", HFILL }},
3784         { &hf_icmpv6_nd_ra_flag_prf,
3785           { "Prf (Default Router Preference)", "icmpv6.nd.ra.flag.prf", FT_UINT8, BASE_DEC, VALS(nd_flag_router_pref), ND_RA_FLAG_PRF,
3786             "Indicates whether to prefer this router over other default routers", HFILL }},
3787         { &hf_icmpv6_nd_ra_flag_p,
3788           { "Proxy", "icmpv6.nd.ra.flag.p", FT_BOOLEAN, 8, TFS(&tfs_set_notset), ND_RA_FLAG_P,
3789            NULL, HFILL }},
3790         { &hf_icmpv6_nd_ra_flag_rsv,
3791           { "Reserved", "icmpv6.nd.ra.flag.rsv", FT_UINT8, BASE_DEC, NULL, ND_RA_FLAG_RSV,
3792             "Must be Zero", HFILL }},
3793         { &hf_icmpv6_nd_ra_router_lifetime,
3794           { "Router lifetime (s)", "icmpv6.nd.ra.router_lifetime", FT_UINT16, BASE_DEC, NULL, 0x0,
3795             "The lifetime associated with the default router", HFILL }},
3796         { &hf_icmpv6_nd_ra_reachable_time,
3797           { "Reachable time (ms)", "icmpv6.nd.ra.reachable_time", FT_UINT32, BASE_DEC, NULL, 0x0,
3798             "The time that a node assumes a neighbor is reachable after having received a reachability confirmation", HFILL }},
3799         { &hf_icmpv6_nd_ra_retrans_timer,
3800           { "Retrans timer (ms)", "icmpv6.nd.ra.retrans_timer", FT_UINT32, BASE_DEC, NULL, 0x0,
3801             "The time between retransmitted Neighbor Solicitation messages", HFILL }},
3802         { &hf_icmpv6_nd_ns_target_address,
3803           { "Target Address", "icmpv6.nd.ns.target_address", FT_IPv6, BASE_NONE, NULL, 0x0,
3804             "The IP address of the target of the solicitation", HFILL }},
3805         { &hf_icmpv6_nd_na_flag,
3806           { "Flags", "icmpv6.nd.na.flag", FT_UINT32, BASE_HEX, NULL, 0x0,
3807             NULL, HFILL }},
3808         { &hf_icmpv6_nd_na_flag_r,
3809           { "Router", "icmpv6.nd.na.flag.r", FT_BOOLEAN, 32, TFS(&tfs_set_notset), ND_NA_FLAG_R,
3810             "When set, it indicates that the sender is a router", HFILL }},
3811         { &hf_icmpv6_nd_na_flag_s,
3812           { "Solicited", "icmpv6.nd.na.flag.s", FT_BOOLEAN, 32, TFS(&tfs_set_notset), ND_NA_FLAG_S,
3813             "When set, it indicates that the advertisement was sent in response to a Neighbor Solicitation from the Destination address", HFILL }},
3814         { &hf_icmpv6_nd_na_flag_o,
3815           { "Override", "icmpv6.nd.na.flag.o", FT_BOOLEAN, 32, TFS(&tfs_set_notset), ND_NA_FLAG_O,
3816             "When set, it indicates that the advertisement should override an existing cache entry and update the cached link-layer address", HFILL }},
3817         { &hf_icmpv6_nd_na_flag_rsv,
3818           { "Reserved", "icmpv6.nd.na.flag.rsv", FT_UINT32, BASE_DEC, NULL, ND_NA_FLAG_RSV,
3819             "Must be Zero", HFILL }},
3820         { &hf_icmpv6_nd_na_target_address,
3821           { "Target Address", "icmpv6.nd.na.target_address", FT_IPv6, BASE_NONE, NULL, 0x0,
3822             "the Target Address field in the Neighbor Solicitation message that prompted this advertisement", HFILL }},
3823         { &hf_icmpv6_nd_rd_target_address,
3824           { "Target Address", "icmpv6.nd.rd.target_address", FT_IPv6, BASE_NONE, NULL, 0x0,
3825             "An IP address that is a better first hop to use for the ICMP Destination Address", HFILL }},
3826         { &hf_icmpv6_nd_rd_destination_address,
3827           { "Destination Address", "icmpv6.rd.na.destination_address", FT_IPv6, BASE_NONE, NULL, 0x0,
3828             "The IP address of the destination that is redirected to the target", HFILL }},
3829         { &hf_icmpv6_opt,
3830           { "ICMPv6 Option", "icmpv6.opt", FT_NONE, BASE_NONE, NULL, 0x0,
3831             "Option", HFILL }},
3832         { &hf_icmpv6_opt_type,
3833           { "Type", "icmpv6.opt.type", FT_UINT8, BASE_DEC, VALS(option_vals), 0x0,
3834             "Options type", HFILL }},
3835         { &hf_icmpv6_opt_length,
3836           { "Length", "icmpv6.opt.length", FT_UINT8, BASE_DEC, NULL, 0x0,
3837             "The length (in units of 8 bytes) of the option (including the Type and Length fields)", HFILL }},
3838         { &hf_icmpv6_opt_reserved,
3839           { "Reserved", "icmpv6.opt.reserved", FT_NONE, BASE_NONE, NULL, 0x0,
3840             "Reserved (Must be 0)", HFILL }},
3841         { &hf_icmpv6_opt_padding,
3842           { "Padding", "icmpv6.opt.padding", FT_NONE, BASE_NONE, NULL, 0x0,
3843             "Padding (Must be 0)", HFILL }},
3844         { &hf_icmpv6_opt_linkaddr,
3845           { "Link-layer address", "icmpv6.opt.linkaddr", FT_BYTES, BASE_NONE, NULL, 0x0,
3846             NULL, HFILL }},
3847        { &hf_icmpv6_opt_src_linkaddr,
3848           { "Source Link-layer address", "icmpv6.opt.src_linkaddr", FT_BYTES, BASE_NONE, NULL, 0x0,
3849             NULL, HFILL }},
3850        { &hf_icmpv6_opt_target_linkaddr,
3851           { "Target Link-layer address", "icmpv6.opt.target_linkaddr", FT_BYTES, BASE_NONE, NULL, 0x0,
3852             NULL, HFILL }},
3853         { &hf_icmpv6_opt_linkaddr_mac,
3854           { "Link-layer address", "icmpv6.opt.linkaddr", FT_ETHER, BASE_NONE, NULL, 0x0,
3855             NULL, HFILL }},
3856        { &hf_icmpv6_opt_src_linkaddr_mac,
3857           { "Source Link-layer address", "icmpv6.opt.src_linkaddr", FT_ETHER, BASE_NONE, NULL, 0x0,
3858             NULL, HFILL }},
3859        { &hf_icmpv6_opt_target_linkaddr_mac,
3860           { "Target Link-layer address", "icmpv6.opt.target_linkaddr", FT_ETHER, BASE_NONE, NULL, 0x0,
3861             NULL, HFILL }},
3862         { &hf_icmpv6_opt_linkaddr_eui64,
3863           { "Link-layer address", "icmpv6.opt.linkaddr", FT_EUI64, BASE_NONE, NULL, 0x0,
3864             NULL, HFILL }},
3865        { &hf_icmpv6_opt_src_linkaddr_eui64,
3866           { "Source Link-layer address", "icmpv6.opt.src_linkaddr", FT_EUI64, BASE_NONE, NULL, 0x0,
3867             NULL, HFILL }},
3868        { &hf_icmpv6_opt_target_linkaddr_eui64,
3869           { "Target Link-layer address", "icmpv6.opt.target_linkaddr", FT_EUI64, BASE_NONE, NULL, 0x0,
3870             NULL, HFILL }},
3871         { &hf_icmpv6_opt_prefix_len,
3872           { "Prefix Length", "icmpv6.opt.prefix.length", FT_UINT8, BASE_DEC, NULL, 0x0,
3873             "The number of leading bits in the Prefix that are valid", HFILL }},
3874         { &hf_icmpv6_opt_prefix_flag,
3875           { "Flag", "icmpv6.opt.prefix.flag", FT_UINT8, BASE_HEX, NULL, 0x00,
3876             NULL, HFILL }},
3877         { &hf_icmpv6_opt_prefix_flag_l,
3878           { "On-link flag(L)", "icmpv6.opt.prefix.flag.l", FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x80,
3879             "When set, indicates that this prefix can be used for on-link determination", HFILL }},
3880         { &hf_icmpv6_opt_prefix_flag_a,
3881           { "Autonomous address-configuration flag(A)", "icmpv6.opt.prefix.flag.a", FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x40,
3882             "When set indicates that this prefix can be used for stateless address configuration", HFILL }},
3883         { &hf_icmpv6_opt_prefix_flag_r,
3884           { "Router address flag(R)", "icmpv6.opt.prefix.flag.r", FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x20,
3885             "When set indicates that the Prefix field contains a complete IP address assigned to the sending router", HFILL }},
3886         { &hf_icmpv6_opt_prefix_flag_reserved,
3887           { "Reserved", "icmpv6.opt.prefix.flag.reserved", FT_UINT8, BASE_DEC, NULL, 0x1f,
3888             NULL, HFILL }},
3889         { &hf_icmpv6_opt_prefix_valid_lifetime,
3890           { "Valid Lifetime", "icmpv6.opt.prefix.valid_lifetime", FT_UINT32, BASE_DEC, NULL, 0x00,
3891             "The length of time in seconds that the prefix is valid for the purpose of on-link determination", HFILL }},
3892         { &hf_icmpv6_opt_prefix_preferred_lifetime,
3893           { "Preferred Lifetime", "icmpv6.opt.prefix.preferred_lifetime", FT_UINT32, BASE_DEC, NULL, 0x00,
3894             "The length of time in seconds that addresses generated from the prefix via stateless address autoconfiguration remain preferred", HFILL }},
3895         { &hf_icmpv6_opt_prefix,
3896           { "Prefix", "icmpv6.opt.prefix", FT_IPv6, BASE_NONE, NULL, 0x00,
3897             "An IP address or a prefix of an IP address", HFILL }},
3898         { &hf_icmpv6_opt_cga_pad_len,
3899           { "Pad Length", "icmpv6.opt.cga.pad_length", FT_UINT8, BASE_DEC, NULL, 0x0,
3900             "Pad Length (in bytes)", HFILL }},
3901         { &hf_icmpv6_opt_cga,
3902           { "CGA", "icmpv6.opt.cga", FT_BYTES, BASE_NONE, NULL, 0x0,
3903             NULL, HFILL }},
3904         { &hf_icmpv6_opt_cga_modifier,
3905           { "Modifier", "icmpv6.opt.cga.modifier", FT_BYTES, BASE_NONE, NULL, 0x0,
3906             NULL, HFILL }},
3907         { &hf_icmpv6_opt_cga_subnet_prefix,
3908           { "Subnet Prefix", "icmpv6.opt.cga.subnet_prefix", FT_BYTES, BASE_NONE, NULL, 0x0,
3909             NULL, HFILL }},
3910         { &hf_icmpv6_opt_cga_count,
3911           { "Count", "icmpv6.opt.cga.count", FT_BYTES, BASE_NONE, NULL, 0x0,
3912             NULL, HFILL }},
3913         { &hf_icmpv6_opt_cga_ext_type,
3914           { "Ext Type", "icmpv6.opt.cga.ext_type", FT_UINT16, BASE_DEC, NULL, 0x0,
3915             NULL, HFILL }},
3916         { &hf_icmpv6_opt_cga_ext_length,
3917           { "Ext Length", "icmpv6.opt.cga.ext_length", FT_UINT16, BASE_DEC, NULL, 0x0,
3918             NULL, HFILL }},
3919         { &hf_icmpv6_opt_cga_ext_data,
3920           { "Ext Data", "icmpv6.opt.cga.ext_length", FT_BYTES, BASE_NONE, NULL, 0x0,
3921             NULL, HFILL }},
3922         { &hf_icmpv6_opt_rsa_key_hash,
3923           { "Key Hash", "icmpv6.opt.rsa.key_hash", FT_BYTES, BASE_NONE, NULL, 0x0,
3924             NULL, HFILL }},
3925         { &hf_icmpv6_opt_digital_signature_padding,
3926           { "Digital Signature and Padding", "icmpv6.opt.digital_signature_padding", FT_NONE, BASE_NONE, NULL, 0x0,
3927             "TO DO FIX ME !!", HFILL }},
3928         { &hf_icmpv6_opt_ps_key_hash,
3929           { "Key Hash", "icmpv6.opt.ps.key_hash", FT_BYTES, BASE_NONE, NULL, 0x0,
3930             NULL, HFILL }},
3931         { &hf_icmpv6_opt_timestamp,
3932           { "Timestamp", "icmpv6.opt.timestamp", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x0,
3933             "The value indicates the number of seconds since January 1, 1970, 00:00 UTC", HFILL }},
3934         { &hf_icmpv6_opt_nonce,
3935           { "Nonce", "icmpv6.opt.nonce", FT_BYTES, BASE_NONE, NULL, 0x0,
3936             "A field containing a random number selected by the sender of the solicitation message", HFILL }},
3937         { &hf_icmpv6_opt_certificate_padding,
3938           { "Certificat and Padding", "icmpv6.opt.certificate_padding", FT_NONE, BASE_NONE, NULL, 0x0,
3939             NULL, HFILL }},
3940         { &hf_icmpv6_opt_ipa_option_code,
3941           { "Option-code", "icmpv6.opt.ipa.option_code", FT_UINT8, BASE_DEC, VALS(nd_opt_ipa_option_code_val), 0x00,
3942             NULL, HFILL }},
3943         { &hf_icmpv6_opt_ipa_prefix_len,
3944           { "Prefix Length", "icmpv6.opt.ipa.prefix_len", FT_UINT8, BASE_DEC, NULL, 0x00,
3945             "That indicates the length of the IPv6 Address Prefix", HFILL }},
3946         { &hf_icmpv6_opt_ipa_ipv6_address,
3947           { "IPv6 Address", "icmpv6.opt.ipa.ipv6_address", FT_IPv6, BASE_NONE, NULL, 0x00,
3948             "The IP address/prefix defined by the Option-Code field", HFILL }},
3949         { &hf_icmpv6_opt_nrpi_option_code,
3950           { "Option-code", "icmpv6.opt.nrpi.option_code", FT_UINT8, BASE_DEC, NULL, 0x00,
3951             NULL, HFILL }},
3952         { &hf_icmpv6_opt_nrpi_prefix_len,
3953           { "Prefix Length", "icmpv6.opt.nrpi.prefix_len", FT_UINT8, BASE_DEC, NULL, 0x00,
3954             "The number of leading bits in the Prefix that are valid", HFILL }},
3955         { &hf_icmpv6_opt_nrpi_prefix,
3956           { "Prefix", "icmpv6.opt.nrpi.prefix", FT_IPv6, BASE_NONE, NULL, 0x00,
3957             "An IP address or a prefix of an IP address", HFILL }},
3958         { &hf_icmpv6_opt_lla_option_code,
3959           { "Option-code", "icmpv6.opt.lla.option_code", FT_UINT8, BASE_DEC, VALS(nd_opt_lla_option_code_val), 0x00,
3960             NULL, HFILL }},
3961         { &hf_icmpv6_opt_lla_bytes,
3962           { "Link-Layer Address", "icmpv6.opt.lla.bytes", FT_BYTES, BASE_NONE, NULL, 0x00,
3963             "(in Bytes Format)", HFILL }},
3964         { &hf_icmpv6_opt_naack_option_code,
3965           { "Option-Code", "icmpv6.opt.naack.option_code", FT_UINT8, BASE_DEC, NULL, 0x00,
3966             NULL, HFILL }},
3967         { &hf_icmpv6_opt_naack_status,
3968           { "Status", "icmpv6.opt.naack.status", FT_UINT8, BASE_DEC, VALS(nd_opt_naack_status_val), 0x00,
3969             "Indicating the disposition of the Unsolicited Neighbor Advertisement message", HFILL }},
3970         { &hf_icmpv6_opt_naack_supplied_ncoa,
3971           { "Supplied NCoA", "icmpv6.opt.naack.supplied_ncoa", FT_IPv6, BASE_NONE, NULL, 0x00,
3972             NULL, HFILL }},
3973         { &hf_icmpv6_opt_map_dist,
3974           { "Distance", "icmpv6.opt.map.distance", FT_UINT8, BASE_DEC, NULL, 0xF0,
3975             "Identifying the distance between MAP and the receiver of the advertisement (in the number of hops)", HFILL }},
3976         { &hf_icmpv6_opt_map_pref,
3977           { "Preference", "icmpv6.opt.map.preference", FT_UINT8, BASE_DEC, NULL, 0x0F,
3978             "Used as an indicator of operator preference (Highest is better)", HFILL }},
3979         { &hf_icmpv6_opt_map_flag,
3980           { "Flag", "icmpv6.opt.map.flag", FT_UINT8, BASE_HEX, NULL, 0x00,
3981             NULL, HFILL }},
3982         { &hf_icmpv6_opt_map_flag_r,
3983           { "RCoA Flag", "icmpv6.opt.map.flag.r", FT_BOOLEAN, 8, NULL, 0x80,
3984             "It indicates that the mobile node is allocated the RCoA by the MAP", HFILL }},
3985         { &hf_icmpv6_opt_map_flag_reserved,
3986           { "Reserved", "icmpv6.opt.map.flag.reserved", FT_UINT8, BASE_DEC, NULL, 0x7F,
3987             "Must be 0", HFILL }},
3988         { &hf_icmpv6_opt_map_valid_lifetime,
3989           { "Valid Lifetime", "icmpv6.opt.map.valid_lifetime", FT_UINT32, BASE_DEC, NULL, 0x0,
3990             "This value indicates the validity of the MAP's address and the RCoA.", HFILL }},
3991         { &hf_icmpv6_opt_map_global_address,
3992           { "Global Address", "icmpv6.opt.map.global_address", FT_IPv6, BASE_NONE, NULL, 0x0,
3993             "TOne of the MAP's global addresses", HFILL }},
3994         { &hf_icmpv6_opt_route_info_flag,
3995           { "Flag", "icmpv6.opt.route_info.flag", FT_UINT8, BASE_HEX, NULL, 0x00,
3996             NULL, HFILL }},
3997         { &hf_icmpv6_opt_route_info_flag_route_preference,
3998           { "Route Preference", "icmpv6.opt.route_info.flag.route_preference", FT_UINT8, BASE_DEC, VALS(nd_flag_router_pref), ND_RA_FLAG_RTPREF_MASK,
3999             "The Route Preference indicates whether to prefer the router associated with this prefix over others", HFILL }},
4000         { &hf_icmpv6_opt_route_info_flag_reserved,
4001           { "Reserved", "icmpv6.opt.route_info.flag.reserved", FT_UINT8, BASE_DEC, NULL, ND_RA_FLAG_RESERV_MASK,
4002             "Must be 0", HFILL }},
4003         { &hf_icmpv6_opt_route_lifetime,
4004           { "Route Lifetime", "icmpv6.opt.route_lifetime", FT_UINT32, BASE_DEC, NULL, 0x00,
4005             "The length of time in seconds that the prefix is valid for the purpose of route determination", HFILL }},
4006         { &hf_icmpv6_opt_name_type,
4007           { "Name Type", "icmpv6.opt.name_type", FT_UINT8, BASE_DEC, VALS(icmpv6_option_name_type_vals), 0x0,
4008             NULL, HFILL }},
4009         { &hf_icmpv6_opt_name_x501,
4010           { "DER Encoded X.501 Name", "icmpv6.opt.name_x501", FT_BYTES, BASE_NONE, NULL, 0x0,
4011             NULL, HFILL }},
4012         { &hf_icmpv6_opt_name_fqdn,
4013           { "FQDN", "icmpv6.opt.name_type.fqdn", FT_STRING, BASE_NONE, NULL, 0x0,
4014             NULL, HFILL }},
4015         { &hf_icmpv6_opt_cert_type,
4016           { "Cert Type", "icmpv6.opt.name_type", FT_UINT8, BASE_DEC, VALS(icmpv6_option_cert_type_vals), 0x0,
4017             NULL, HFILL }},
4018         /* RFC3971:  SEcure Neighbor Discovery (SEND) */
4019         { &hf_icmpv6_send_identifier,
4020           { "Identifier", "icmpv6.send.identifier", FT_UINT16, BASE_DEC, NULL, 0x0,
4021             "An identifier to aid in matching with Request and Reply", HFILL }},
4022         { &hf_icmpv6_send_all_components,
4023           { "All Components", "icmpv6.send.all_components", FT_UINT16, BASE_DEC, NULL, 0x0,
4024             "Inform the receiver of the number of certificates in the entire path", HFILL }},
4025         { &hf_icmpv6_send_component,
4026           { "Component", "icmpv6.send.component", FT_UINT16, BASE_DEC, NULL, 0x0,
4027             "If the field is set to 65,535 if the sender seeks to retrieve all certificates", HFILL }},
4028
4029         { &hf_icmpv6_x509if_Name,
4030           { "Name", "icmpv6.x509_Name", FT_UINT32, BASE_DEC, VALS(x509if_Name_vals), 0x0,
4031             NULL, HFILL }},
4032         { &hf_icmpv6_x509af_Certificate,
4033           { "Certificate", "icmpv6.x509_Certificate", FT_NONE, BASE_NONE, NULL, 0x0,
4034             NULL, HFILL }},
4035         { &hf_icmpv6_opt_redirected_packet,
4036           { "Redirected Packet", "icmpv6.opt.redirected_packet", FT_NONE, BASE_NONE, NULL, 0x0,
4037             NULL, HFILL }},
4038         { &hf_icmpv6_opt_mtu,
4039           { "MTU", "icmpv6.opt.mtu", FT_UINT32, BASE_DEC, NULL, 0x0,
4040             "The recommended MTU for the link", HFILL }},
4041         { &hf_icmpv6_opt_nbma_shortcut_limit,
4042           { "Shortcut Limit", "icmpv6.opt.nbma.shortcut_limit", FT_UINT8, BASE_DEC, NULL, 0x0,
4043             "Hop limit for shortcut attempt", HFILL }},
4044         { &hf_icmpv6_opt_advertisement_interval,
4045           { "Advertisement Interval", "icmpv6.opt.advertisement_interval", FT_UINT32, BASE_DEC, NULL, 0x0,
4046             "The maximum time (in milliseconds) between successive unsolicited Router Advertisement messages sent by this router on this network interface", HFILL }},
4047         { &hf_icmpv6_opt_home_agent_preference,
4048           { "Home Agent Preference", "icmpv6.opt.home_agent_preference", FT_UINT16, BASE_DEC, NULL, 0x0,
4049             "The preference for the home agent sending this Router Advertisement", HFILL }},
4050         { &hf_icmpv6_opt_home_agent_lifetime,
4051           { "Home Agent Preference", "icmpv6.opt.home_agent_lifetime", FT_UINT16, BASE_DEC, NULL, 0x0,
4052             "The lifetime associated with the home agent in units of seconds.", HFILL }},
4053         { &hf_icmpv6_opt_ipv6_address,
4054           { "IPv6 Address", "icmpv6.opt.ipv6_address", FT_IPv6, BASE_NONE, NULL, 0x0,
4055             "IPv6 addresses of the interface", HFILL }},
4056         { &hf_icmpv6_opt_rdnss_lifetime,
4057           { "Lifetime", "icmpv6.opt.rdnss.lifetime", FT_UINT32, BASE_DEC, NULL, 0x0,
4058             NULL, HFILL }},
4059         { &hf_icmpv6_opt_rdnss,
4060           { "Recursive DNS Servers", "icmpv6.opt.rdnss", FT_IPv6, BASE_NONE, NULL, 0x0,
4061             NULL, HFILL }},
4062         { &hf_icmpv6_opt_efo,
4063           { "Flags Expansion Option", "icmpv6.opt.efo", FT_NONE, BASE_NONE, NULL, 0x0,
4064             NULL, HFILL }},
4065         { &hf_icmpv6_opt_efo_m,
4066           { "Managed address configuration", "icmpv6.opt.efo.m", FT_BOOLEAN, 16, TFS(&tfs_set_notset), FLAGS_EO_M,
4067             "When set, it indicates that addresses are available via DHCPv6", HFILL }},
4068         { &hf_icmpv6_opt_efo_o,
4069           { "Other configuration", "icmpv6.opt.efo.o", FT_BOOLEAN, 16, TFS(&tfs_set_notset), FLAGS_EO_O,
4070             "When set, it indicates that other configuration information is available via DHCPv6", HFILL }},
4071         { &hf_icmpv6_opt_efo_h,
4072           { "Home Agent", "icmpv6.opt.efo.h", FT_BOOLEAN, 16, TFS(&tfs_set_notset), FLAGS_EO_H,
4073             "When set, it indicate that the router sending this Router Advertisement is also functioning as a Mobile IPv6 home agent on this link", HFILL }},
4074         { &hf_icmpv6_opt_efo_prf,
4075           { "Prf (Default Router Preference)", "icmpv6.opt.efo.prf", FT_UINT16, BASE_DEC, VALS(nd_flag_router_pref), FLAGS_EO_PRF,
4076             "Indicates whether to prefer this router over other default routers", HFILL }},
4077         { &hf_icmpv6_opt_efo_p,
4078           { "Proxy", "icmpv6.opt.efo.p", FT_BOOLEAN, 16, TFS(&tfs_set_notset), FLAGS_EO_P,
4079            NULL, HFILL }},
4080         { &hf_icmpv6_opt_efo_rsv,
4081           { "Reserved", "icmpv6.opt.efo.rsv", FT_UINT16, BASE_DEC, NULL, FLAGS_EO_RSV,
4082             "Must be Zero", HFILL }},
4083         { &hf_icmpv6_opt_hkr_pad_length,
4084           { "Pad Length", "icmpv6.opt.hkr.pad_length", FT_UINT8, BASE_DEC, NULL, 0x0,
4085             "The number of padding octets beyond the end of the Handover Key", HFILL }},
4086         { &hf_icmpv6_opt_hkr_at,
4087           { "AT", "icmpv6.opt.hkr.at", FT_UINT8, BASE_DEC, NULL, 0xF0,
4088             "The algorithm type field describing the algorithm used by FMIPv6 to calculate the authenticator", HFILL }},
4089         { &hf_icmpv6_opt_hkr_reserved,
4090           { "Reserved", "icmpv6.opt.hkr.reserved", FT_UINT8, BASE_DEC, NULL, 0x0F,
4091             "Reserved (Must be Zero)", HFILL }},
4092         { &hf_icmpv6_opt_hkr_encryption_public_key,
4093           { "Handover Key Encryption Public Key", "icmpv6.opt.hkr.encryption_public_key", FT_BYTES, BASE_NONE, NULL, 0x0,
4094             NULL, HFILL }},
4095         { &hf_icmpv6_opt_hkr_padding,
4096           { "Padding", "icmpv6.opt.hkr.padding", FT_BYTES, BASE_NONE, NULL, 0x0,
4097             "A variable-length field making the option length a multiple of 8", HFILL }},
4098         { &hf_icmpv6_opt_hkr_lifetime,
4099           { "Padding", "icmpv6.opt.hkr.lifetime", FT_UINT16, BASE_DEC, NULL, 0x0,
4100             "Lifetime of the handover key (in seconds)", HFILL }},
4101         { &hf_icmpv6_opt_hkr_encrypted_handover_key,
4102           { "Encrypted Handover Key", "icmpv6.opt.hkr.encrypted_handover_key", FT_BYTES, BASE_NONE, NULL, 0x0,
4103             "The shared handover key, encrypted with the MN's handover key encryption public key", HFILL }},
4104         { &hf_icmpv6_opt_hai_option_code,
4105           { "Option-Code", "icmpv6.opt.hai.option_code", FT_UINT8, BASE_DEC, VALS(nd_opt_hai_option_code_val), 0x0,
4106             NULL, HFILL }},
4107         { &hf_icmpv6_opt_hai_length,
4108           { "HAI-Length", "icmpv6.opt.hai.length", FT_UINT8, BASE_DEC, NULL, 0x0,
4109             "The size of the HAI-Value field in octets", HFILL }},
4110         { &hf_icmpv6_opt_hai_value,
4111           { "HAI-Value", "icmpv6.opt.hai.value", FT_BYTES, BASE_NONE, NULL, 0x0,
4112             "The value specified by the Option-Code", HFILL }},
4113         { &hf_icmpv6_opt_mn_option_code,
4114           { "Option-Code", "icmpv6.opt.mn.option_code", FT_UINT8, BASE_DEC, VALS(nd_opt_mn_option_code_val), 0x0,
4115             NULL, HFILL }},
4116         { &hf_icmpv6_opt_mn_length,
4117           { "MN-Length", "icmpv6.opt.mn.length", FT_UINT8, BASE_DEC, NULL, 0x0,
4118             "The size of the MN-Value field in octets", HFILL }},
4119         { &hf_icmpv6_opt_mn_value,
4120           { "MN-Value", "icmpv6.opt.mn.value", FT_BYTES, BASE_NONE, NULL, 0x0,
4121             "The value specified by the Option-Code", HFILL }},
4122         { &hf_icmpv6_opt_dnssl_lifetime,
4123           { "Lifetime", "icmpv6.opt.dnssl.lifetime", FT_UINT32, BASE_DEC, NULL, 0x0,
4124             NULL, HFILL }},
4125         { &hf_icmpv6_opt_dnssl,
4126           { "Domain Names", "icmpv6.opt.dnssl", FT_STRING, BASE_NONE, NULL, 0x0,
4127             NULL, HFILL }},
4128         { &hf_icmpv6_opt_aro_status,
4129           { "Status", "icmpv6.opt.aro.status", FT_UINT8, BASE_DEC, VALS(nd_opt_6lowpannd_status_val), 0x00,
4130             "Indicates the status of a registration in the NA response", HFILL }},
4131         { &hf_icmpv6_opt_aro_registration_lifetime,
4132           { "Registration  Lifetime", "icmpv6.opt.aro.registration_lifetime", FT_UINT16, BASE_DEC, NULL, 0x00,
4133             "The amount of time (in a unit of 60 seconds) that the router should retain the Neighbor Cache entry", HFILL }},
4134         { &hf_icmpv6_opt_aro_eui64,
4135           { "EUI-64", "icmpv6.opt.aro.eui64", FT_EUI64, BASE_NONE, NULL, 0x00,
4136             "This field is used to uniquely identify the interface of the registered address", HFILL }},
4137         { &hf_icmpv6_opt_6co_context_length,
4138           { "Context Length", "icmpv6.opt.6co.context_length", FT_UINT8, BASE_DEC, NULL, 0x00,
4139             "The number of leading bits in the Context Prefix field that are valid", HFILL }},
4140         { &hf_icmpv6_opt_6co_flag,
4141           { "Flag", "icmpv6.opt.6co.flag", FT_UINT8, BASE_HEX, NULL, 0x00,
4142             NULL, HFILL }},
4143         { &hf_icmpv6_opt_6co_flag_c,
4144           { "Compression Flag", "icmpv6.opt.6co.flag.c", FT_BOOLEAN, 8, TFS(&tfs_set_notset), ND_OPT_6CO_FLAG_C,
4145             "This flag indicates if the context is valid for use in compression", HFILL }},
4146         { &hf_icmpv6_opt_6co_flag_cid,
4147           { "CID", "icmpv6.opt.6co.flag.cid", FT_UINT8, BASE_DEC, NULL, ND_OPT_6CO_FLAG_CID,
4148             "Context Identifier for this prefix information", HFILL }},
4149         { &hf_icmpv6_opt_6co_flag_reserved,
4150           { "Reserved", "icmpv6.opt.6co.flag.reserved", FT_UINT8, BASE_DEC, NULL, ND_OPT_6CO_FLAG_RESERVED,
4151             "Must be zero", HFILL }},
4152         { &hf_icmpv6_opt_6co_valid_lifetime,
4153           { "Lifetime", "icmpv6.opt.6co.valid_lifetime", FT_UINT16, BASE_DEC, NULL, 0x00,
4154             "The length of time in a unit of 60 seconds that the context is valid for the purpose of header compression or decompression", HFILL }},
4155         { &hf_icmpv6_opt_6co_context_prefix,
4156           { "Context Prefix", "icmpv6.opt.6co.context_prefix", FT_IPv6, BASE_NONE, NULL, 0x00,
4157             "The IPv6 prefix or address corresponding to the Context ID (CID) field", HFILL }},
4158         { &hf_icmpv6_opt_abro_version,
4159           { "Version", "icmpv6.opt.abro.version", FT_UINT16, BASE_DEC, NULL, 0x00,
4160             "The version number corresponding to this set of information contained in the RA message", HFILL }},
4161         { &hf_icmpv6_opt_abro_6lbr_address,
4162           { "6LBR Address", "icmpv6.opt.abro.6lbr_address", FT_IPv6, BASE_NONE, NULL, 0x00,
4163             "IPv6 address of the 6LBR that is the origin of the included version number", HFILL }},
4164
4165         /* RFC2710:  Multicast Listener Discovery for IPv6 */
4166         { &hf_icmpv6_mld_mrd,
4167           { "Maximum Response Delay [ms]", "icmpv6.mld.maximum_response_delay", FT_UINT16, BASE_DEC, NULL, 0x0,
4168             "Specifies the maximum allowed delay before sending a responding Report, in units of milliseconds", HFILL }},
4169         { &hf_icmpv6_mld_multicast_address,
4170           { "Multicast Address", "icmpv6.mld.multicast_address", FT_IPv6, BASE_NONE, NULL, 0x0,
4171             "Specific IPv6 multicast address", HFILL }},
4172         /* RFC 2894: Router Renumbering for IPv6 */
4173         { &hf_icmpv6_rr_sequencenumber,
4174            { "Sequence Number", "icmpv6.rr.sequence_number", FT_UINT32, BASE_DEC, NULL, 0x0,
4175              "The sequence number MUST be non-decreasing between Sequence Number Resets", HFILL }},
4176         { &hf_icmpv6_rr_segmentnumber,
4177            { "Segment Number", "icmpv6.rr.segment_number", FT_UINT8, BASE_DEC, NULL, 0x0,
4178              "Enumerates different valid RR messages having the same Sequence Number", HFILL }},
4179         { &hf_icmpv6_rr_flag,
4180            { "Flags", "icmpv6.rr.flag", FT_UINT8, BASE_HEX, NULL, 0x0,
4181              "Five are defined and three bits are reserved", HFILL }},
4182         { &hf_icmpv6_rr_flag_t,
4183            { "Test Command", "icmpv6.rr.flag.t", FT_BOOLEAN, 8, TFS(&tfs_set_notset), RR_FLAG_T,
4184              "Indicates a Test message: processing is to be simulated and no configuration changes are to be made", HFILL }},
4185         { &hf_icmpv6_rr_flag_r,
4186            { "Result requested", "icmpv6.rr.flag.r", FT_BOOLEAN, 8, TFS(&tfs_set_notset), RR_FLAG_R,
4187              "Indicates that the router send a Result message upon completion of processing the Command message", HFILL }},
4188         { &hf_icmpv6_rr_flag_a,
4189            { "All Interfaces", "icmpv6.rr.flag.a", FT_BOOLEAN, 8, TFS(&tfs_set_notset), RR_FLAG_A,
4190              "Indicates that the Command be applied to all interfaces regardless of administrative shutdown status", HFILL }},
4191         { &hf_icmpv6_rr_flag_s,
4192            { "Site-specific", "icmpv6.rr.flag.s", FT_BOOLEAN, 8, TFS(&tfs_set_notset), RR_FLAG_S,
4193              "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 }},
4194         { &hf_icmpv6_rr_flag_p,
4195            { "Processed previously", "icmpv6.rr.flag.p", FT_BOOLEAN, 8, TFS(&tfs_set_notset), RR_FLAG_P,
4196              "Indicates that the Command message was previously processed (and is not a Test) and the responding router is not processing it again", HFILL }},
4197         { &hf_icmpv6_rr_flag_rsv,
4198            { "Reserved", "icmpv6.rr.flag.rsv", FT_UINT8, BASE_DEC, NULL, RR_FLAG_RSV,
4199              "Must be Zero", HFILL }},
4200         { &hf_icmpv6_rr_maxdelay,
4201            { "Max Delay", "icmpv6.rr.maxdelay", FT_UINT16, BASE_DEC, NULL, 0x0,
4202              "Specifying the maximum time (in milliseconds) by which a router MUST delay sending any reply to this Command", HFILL }},
4203
4204         { &hf_icmpv6_rr_pco_mp_part,
4205            { "Match-Prefix Part", "icmpv6.rr.pco.mp", FT_NONE, BASE_NONE, NULL, 0x0,
4206              NULL, HFILL }},
4207         { &hf_icmpv6_rr_pco_mp_opcode,
4208            { "OpCode", "icmpv6.rr.pco.mp.opcode", FT_UINT8, BASE_DEC, VALS(rr_pco_mp_opcode_val), 0x0,
4209              "Specifying the operation to be performed when the associated MatchPrefix matches an interface's prefix or address", HFILL }},
4210         { &hf_icmpv6_rr_pco_mp_oplength,
4211            { "OpLength", "icmpv6.rr.pco.mp.oplength", FT_UINT8, BASE_DEC, NULL, 0x0,
4212              "The total length of this Prefix Control Operation (in units of 8 octets)", HFILL }},
4213         { &hf_icmpv6_rr_pco_mp_ordinal,
4214            { "Ordinal", "icmpv6.rr.pco.mp.ordinal", FT_UINT8, BASE_HEX, NULL, 0x0,
4215              "The value is otherwise unconstrained", HFILL }},
4216         { &hf_icmpv6_rr_pco_mp_matchlen,
4217            { "MatchLen", "icmpv6.rr.pco.mp.matchlen", FT_UINT8, BASE_DEC, NULL, 0x0,
4218              "Between 0 and 128 inclusive specifying the number of initial bits of MatchPrefix which are significant in matching", HFILL }},
4219         { &hf_icmpv6_rr_pco_mp_minlen,
4220            { "MinLen", "icmpv6.rr.pco.mp.minlen", FT_UINT8, BASE_DEC, NULL, 0x0,
4221              "Specifying the minimum length which any configured prefix must have in order to be eligible for testing against the MatchPrefix", HFILL }},
4222         { &hf_icmpv6_rr_pco_mp_maxlen,
4223            { "MaxLen", "icmpv6.rr.pco.mp.maxlen", FT_UINT8, BASE_DEC, NULL, 0x0,
4224              "Specifying the maximum length which any configured prefix must have in order to be eligible for testing against the MatchPrefix", HFILL }},
4225         { &hf_icmpv6_rr_pco_mp_matchprefix,
4226            { "MatchPrefix", "icmpv6.rr.pco.mp.matchprefix", FT_IPv6, BASE_NONE, NULL, 0x0,
4227              "The 128-bit prefix to be compared with each interface's prefix or address", HFILL }},
4228         { &hf_icmpv6_rr_pco_up_part,
4229            { "Use-Prefix Part", "icmpv6.rr.pco.up", FT_NONE, BASE_NONE, NULL, 0x0,
4230              NULL, HFILL }},
4231         { &hf_icmpv6_rr_pco_up_uselen,
4232            { "UseLen", "icmpv6.rr.pco.up.uselen", FT_UINT8, BASE_DEC, NULL, 0x0,
4233              "specifying the number of initial bits of UsePrefix to use in creating a new prefix for an interface", HFILL }},
4234         { &hf_icmpv6_rr_pco_up_keeplen,
4235            { "KeepLen", "icmpv6.rr.pco.up.keeplen", FT_UINT8, BASE_DEC, NULL, 0x0,
4236              "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 }},
4237         { &hf_icmpv6_rr_pco_up_flagmask,
4238            { "FlagMask", "icmpv6.rr.pco.up.flagmask", FT_UINT8, BASE_HEX, NULL, 0x0,
4239              "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 }},
4240
4241         { &hf_icmpv6_rr_pco_up_flagmask_l,
4242           { "On-link flag(L)", "icmpv6.rr.pco.up.flagmask.l", FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x80,
4243             "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 }},
4244         { &hf_icmpv6_rr_pco_up_flagmask_a,
4245           { "Autonomous address-configuration flag(A)", "icmpv6.rr.pco.up.flagmask.a", FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x40,
4246             "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 }},
4247         { &hf_icmpv6_rr_pco_up_flagmask_reserved,
4248           { "Reserved", "icmpv6.rr.pco.up.flagmask.reserved", FT_UINT8, BASE_DEC, NULL, 0x3f,
4249             NULL, HFILL }},
4250         { &hf_icmpv6_rr_pco_up_raflags,
4251            { "RAFlags", "icmpv6.rr.pco.up.raflags", FT_UINT8, BASE_HEX, NULL, 0x0,
4252              "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 }},
4253         { &hf_icmpv6_rr_pco_up_raflags_l,
4254           { "On-link flag(L)", "icmpv6.rr.pco.up.flagmask.l", FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x80,
4255             "When set, indicates that this prefix can be used for on-link determination", HFILL }},
4256         { &hf_icmpv6_rr_pco_up_raflags_a,
4257           { "Autonomous address-configuration flag(A)", "icmpv6.rr.pco.up.flagmask.a", FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x40,
4258             "When set indicates that this prefix can be used for stateless address configuration", HFILL }},
4259         { &hf_icmpv6_rr_pco_up_raflags_reserved,
4260           { "Reserved", "icmpv6.rr.pco.up.flagmask.reserved", FT_UINT8, BASE_DEC, NULL, 0x3f,
4261             NULL, HFILL }},
4262         { &hf_icmpv6_rr_pco_up_validlifetime,
4263            { "Valid Lifetime", "icmpv6.rr.pco.up.validlifetime", FT_UINT32, BASE_DEC, NULL, 0x0,
4264              "The number of seconds for which the New Prefix will be valid", HFILL }},
4265         { &hf_icmpv6_rr_pco_up_preferredlifetime,
4266            { "Preferred Lifetime", "icmpv6.rr.pco.up.preferredlifetime", FT_UINT32, BASE_DEC, NULL, 0x0,
4267              "The number of seconds for which the New Prefix will be preferred", HFILL }},
4268         { &hf_icmpv6_rr_pco_up_flag,
4269            { "Flags", "icmpv6.rr.pco.up.flag", FT_UINT32, BASE_HEX, NULL, 0x0,
4270              NULL, HFILL }},
4271         { &hf_icmpv6_rr_pco_up_flag_v,
4272           { "Decrement valid lifetime", "icmpv6.rr.pco.up.flag.v", FT_BOOLEAN, 32, TFS(&tfs_set_notset), 0x80000000,
4273             "When set, indicating that the valid lifetime of the New Prefix MUST be effectively decremented in real time", HFILL }},
4274         { &hf_icmpv6_rr_pco_up_flag_p,
4275           { "Decrement preferred lifetime", "icmpv6.rr.pco.up.flag.p", FT_BOOLEAN, 32, TFS(&tfs_set_notset), 0x40000000,
4276             "When set, indicating that the preferred lifetime of the New Prefix MUST be effectively decremented in real time", HFILL }},
4277         { &hf_icmpv6_rr_pco_up_flag_reserved,
4278           { "Reserved", "icmpv6.rr.pco.up.flag.reserved", FT_UINT32, BASE_DEC, NULL, 0x3FFFFFFF,
4279             NULL, HFILL }},
4280         { &hf_icmpv6_rr_pco_up_useprefix,
4281            { "UsePrefix", "icmpv6.rr.pco.up.useprefix", FT_IPv6, BASE_NONE, NULL, 0x0,
4282              "The 128-bit Use-prefix which either becomes or is used in forming (if KeepLen is nonzero) the New Prefix", HFILL }},
4283         { &hf_icmpv6_rr_rm,
4284            { "Result Message", "icmpv6.rr.rm", FT_NONE, BASE_NONE, NULL, 0x0,
4285              NULL, HFILL }},
4286         { &hf_icmpv6_rr_rm_flag,
4287            { "Flags", "icmpv6.rr.rm.flag", FT_UINT16, BASE_HEX, NULL, 0x0,
4288              NULL, HFILL }},
4289         { &hf_icmpv6_rr_rm_flag_b,
4290           { "Bounds", "icmpv6.rr.rm.flag.b", FT_BOOLEAN, 16, TFS(&tfs_set_notset), 0x0002,
4291             "When set, indicates that one or more fields in the associated PCO were out of bounds", HFILL }},
4292         { &hf_icmpv6_rr_rm_flag_f,
4293           { "Forbidden", "icmpv6.rr.rm.flag.f", FT_BOOLEAN, 16, TFS(&tfs_set_notset), 0x0001,
4294             "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 }},
4295         { &hf_icmpv6_rr_rm_flag_reserved,
4296           { "Reserved", "icmpv6.rr.rm.flag.reserved", FT_UINT16, BASE_DEC, NULL, 0xFFFC,
4297             "Must be Zero", HFILL }},
4298         { &hf_icmpv6_rr_rm_ordinal,
4299            { "Ordinal", "icmpv6.rr.rm.ordinal", FT_UINT8, BASE_HEX, NULL, 0x0,
4300              "The value is otherwise unconstrained", HFILL }},
4301         { &hf_icmpv6_rr_rm_matchedlen,
4302            { "MatchedLen", "icmpv6.rr.rm.matchedlen", FT_UINT8, BASE_DEC, NULL, 0x0,
4303              "The length of the Matched Prefix", HFILL }},
4304         { &hf_icmpv6_rr_rm_interfaceindex,
4305            { "InterfaceIndex", "icmpv6.rr.rm.interfaceindex", FT_UINT32, BASE_DEC, NULL, 0x0,
4306              "The router's numeric designation of the interface on which the MatchedPrefix was configured", HFILL }},
4307         { &hf_icmpv6_rr_rm_matchedprefix,
4308            { "MatchedPrefix", "icmpv6.rr.rm.matchedprefix", FT_IPv6, BASE_NONE, NULL, 0x0,
4309              "The 128 Bits MatchedPrefix", HFILL }},
4310
4311         /* RFC3775/6275: Mobility Support in IPv6 */
4312         { &hf_icmpv6_mip6_identifier,
4313           { "Identifier", "icmpv6.mip6.identifier", FT_UINT16, BASE_DEC_HEX, NULL, 0x0,
4314             "An identifier to aid in matching with Request and Reply", HFILL }},
4315         { &hf_icmpv6_mip6_home_agent_address,
4316           { "Home Agent Address", "icmpv6.mip6.home_agent_address", FT_IPv6, BASE_NONE, NULL, 0x0,
4317             "A list of addresses of home agents on the home link for the mobile node", HFILL }},
4318         { &hf_icmpv6_mip6_flag,
4319           { "Flags", "icmpv6.mip6.flag", FT_NONE, BASE_NONE, NULL, 0x0,
4320             NULL, HFILL }},
4321         { &hf_icmpv6_mip6_flag_m,
4322           { "Managed address configuration", "icmpv6.mip6.flag.m", FT_BOOLEAN, 16, TFS(&tfs_set_notset), FLAGS_EO_M,
4323             "When set, it indicates that addresses are available via DHCPv6", HFILL }},
4324         { &hf_icmpv6_mip6_flag_o,
4325           { "Other configuration", "icmpv6.mip6.flag.o", FT_BOOLEAN, 16, TFS(&tfs_set_notset), FLAGS_EO_O,
4326             "When set, it indicates that other configuration information is available via DHCPv6", HFILL }},
4327         { &hf_icmpv6_mip6_flag_rsv,
4328           { "Reserved", "icmpv6.mip6.flag.rsv", FT_UINT16, BASE_DEC, NULL, 0x2FFF,
4329             "Must be Zero", HFILL }},
4330
4331         /* RFC3810: Multicast Listener Discovery Version 2 (MLDv2) for IPv6 */
4332         { &hf_icmpv6_mld_mrc,
4333           { "Maximum Response Code", "icmpv6.mld.maximum_response_code", FT_UINT16, BASE_DEC, NULL, 0x0,
4334             "Specifies the maximum allowed delay before sending a responding Report", HFILL }},
4335        { &hf_icmpv6_mld_flag,
4336           { "Flags", "icmpv6.mld.flag", FT_UINT8, BASE_HEX, NULL, 0x0,
4337             NULL, HFILL }},
4338        { &hf_icmpv6_mld_flag_s,
4339           { "Suppress Router-Side Processing", "icmpv6.mld.flag.s", FT_BOOLEAN, 8, NULL, MLD_FLAG_S,
4340             "Indicates to any receiving multicast routers that they have to suppress the normal timer updates they perform upon hearing a Query", HFILL }},
4341        { &hf_icmpv6_mld_flag_qrv,
4342           { "QRV (Querier's Robustness Variable)", "icmpv6.mld.flag.qrv", FT_UINT8, BASE_DEC, NULL, MLD_FLAG_QRV,
4343             "Contains the RV (Robustness Variable) value used by the Querier", HFILL }},
4344        { &hf_icmpv6_mld_flag_rsv,
4345           { "Reserved", "icmpv6.mld.flag.reserved", FT_UINT8, BASE_DEC, NULL, MLD_FLAG_RSV,
4346             "Must Be Zero", HFILL }},
4347        { &hf_icmpv6_mld_qqi,
4348           { "QQIC (Querier's Query Interval Code)", "icmpv6.mld.qqi", FT_UINT8, BASE_DEC, NULL, 0x0,
4349             "Specifies the QI (Query Interval) used by the Querier", HFILL }},
4350        { &hf_icmpv6_mld_nb_sources,
4351           { "Number of Sources", "icmpv6.mld.nb_sources", FT_UINT16, BASE_DEC, NULL, 0x0,
4352             "Specifies how many source addresses are present in the Query", HFILL }},
4353        { &hf_icmpv6_mld_source_address,
4354           { "Source Address", "icmpv6.mld.source_address", FT_IPv6, BASE_NONE, NULL, 0x0,
4355             "The Source Address fields are a vector of unicast addresses", HFILL }},
4356         { &hf_icmpv6_mldr_nb_mcast_records,
4357           { "Number of Multicast Address Records", "icmpv6.mldr.nb_mcast_records", FT_UINT16, BASE_DEC, NULL, 0x0,
4358             "Specifies how many Multicast Address Records are present in this Report", HFILL }},
4359         { &hf_icmpv6_mldr_mar,
4360           { "Multicast Address Record", "icmpv6.mldr.mar", FT_NONE, BASE_NONE, NULL, 0x0,
4361             "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 }},
4362         { &hf_icmpv6_mldr_mar_record_type,
4363           { "Record Type", "icmpv6.mldr.mar.record_type", FT_UINT8, BASE_DEC, VALS(mldr_record_type_val), 0x0,
4364             "It specifies the type of the Multicast Address Record", HFILL }},
4365         { &hf_icmpv6_mldr_mar_aux_data_len,
4366           { "Aux Data Len", "icmpv6.mldr.mar.aux_data_len", FT_UINT8, BASE_DEC, NULL, 0x0,
4367             "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 }},
4368         { &hf_icmpv6_mldr_mar_nb_sources,
4369           { "Number of Sources", "icmpv6.mldr.mar.nb_sources", FT_UINT16, BASE_DEC, NULL, 0x0,
4370             "The Number of Sources field specifies how many source addresses are present in this Multicast Address Record", HFILL }},
4371         { &hf_icmpv6_mldr_mar_multicast_address,
4372           { "Multicast Address", "icmpv6.mldr.mar.multicast_address", FT_IPv6, BASE_NONE, NULL, 0x0,
4373             "The Multicast Address field contains the multicast address to which this Multicast Address Record pertains", HFILL }},
4374         { &hf_icmpv6_mldr_mar_source_address,
4375           { "Source Address", "icmpv6.mldr.mar.source_address", FT_IPv6, BASE_NONE, NULL, 0x0,
4376             "The Source Address fields are a vector of unicast addresses", HFILL }},
4377         { &hf_icmpv6_mldr_mar_auxiliary_data,
4378           { "Auxiliary Data", "icmpv6.mldr.mar.auxiliary_data", FT_BYTES, BASE_NONE, NULL, 0x0,
4379             "Contains additional information that pertain to this Multicast Address Record", HFILL }},
4380         /* RFC 4068/5268/5568: Fast Handovers for Mobile IPv6 ( Mobile IPv6 Fast Handovers ) */
4381         { &hf_icmpv6_fmip6_subtype,
4382            { "Subtype", "icmpv6.fmip6.subtype", FT_UINT8, BASE_DEC, VALS(fmip6_subtype_val), 0x0,
4383              "Designates the Subtype of information", HFILL }},
4384         { &hf_icmpv6_fmip6_hi_flag,
4385           { "Flag", "icmpv6.fmip6.hi.flag", FT_UINT8, BASE_HEX, NULL, 0x00,
4386             NULL, HFILL }},
4387         { &hf_icmpv6_fmip6_hi_flag_s,
4388           { "Assigned address configuration", "icmpv6.fmip6.hi.flag.s", FT_BOOLEAN, 8, TFS(&tfs_set_notset), FMIP6_HI_FLAG_S,
4389             "When set, this message requests a new CoA to be returned by the destination", HFILL }},
4390         { &hf_icmpv6_fmip6_hi_flag_u,
4391           { "Buffer", "icmpv6.fmip6.hi.flag.a", FT_BOOLEAN, 8, TFS(&tfs_set_notset), FMIP6_HI_FLAG_U,
4392             "When set, the destination SHOULD buffer any packets toward the node indicated in the options of this message", HFILL }},
4393         { &hf_icmpv6_fmip6_hi_flag_reserved,
4394           { "Reserved", "icmpv6.fmip6.hi.flag.reserved", FT_UINT8, BASE_DEC, NULL, FMIP6_HI_FLAG_RSV,
4395             NULL, HFILL }},
4396         { &hf_icmpv6_fmip6_identifier,
4397           { "Identifier", "icmpv6.fmip6.identifier", FT_UINT16, BASE_DEC_HEX, NULL, 0x0,
4398             "An identifier to aid in matching with Request and Reply", HFILL }},
4399
4400         /* RFC 4286: Multicast Router Discovery */
4401         { &hf_icmpv6_mcast_ra_query_interval,
4402           { "Query Interval", "icmpv6.mcast_ra.query_interval", FT_UINT16, BASE_DEC, NULL, 0x0,
4403             "The Query Interval value (in seconds) in use by MLD on the interface.", HFILL }},
4404         { &hf_icmpv6_mcast_ra_robustness_variable,
4405           { "Robustness Variable", "icmpv6.mcast_ra.robustness_variable", FT_UINT16, BASE_DEC, NULL, 0x0,
4406             "The Robustness Variable in use by MLD on the advertising interface", HFILL }},
4407
4408         /* RFC 4620: IPv6 Node Information Queries */
4409         { &hf_icmpv6_ni_qtype,
4410            { "Qtype", "icmpv6.ni.qtype", FT_UINT16, BASE_DEC, VALS(ni_qtype_val), 0x0,
4411              "Designates the type of information", HFILL }},
4412         { &hf_icmpv6_ni_flag,
4413            { "Flags", "icmpv6.ni.flag", FT_UINT16, BASE_HEX, NULL, 0x0,
4414              "Qtype-specific flags that may be defined for certain Query types and their Replies", HFILL }},
4415         { &hf_icmpv6_ni_flag_g,
4416            { "Global-scope addresses", "icmpv6.ni.flag.g", FT_BOOLEAN, 16, TFS(&tfs_set_notset), NI_FLAG_G,
4417              "Global-scope addresses are requested", HFILL }},
4418         { &hf_icmpv6_ni_flag_s,
4419            { "Site-local addresses", "icmpv6.ni.flag.s", FT_BOOLEAN, 16, TFS(&tfs_set_notset), NI_FLAG_S,
4420              "Site-local addresses are requested", HFILL }},
4421         { &hf_icmpv6_ni_flag_l,
4422            { "Link-local addresses", "icmpv6.ni.flag.l", FT_BOOLEAN, 16, TFS(&tfs_set_notset), NI_FLAG_L,
4423              "Link-local addresses are requested", HFILL }},
4424         { &hf_icmpv6_ni_flag_c,
4425            { "Compression", "icmpv6.ni.flag.c", FT_BOOLEAN, 16, TFS(&tfs_set_notset), NI_FLAG_C,
4426              "IPv4-compatible (now deprecated) and IPv4-mapped addresses are requested", HFILL }},
4427         { &hf_icmpv6_ni_flag_a,
4428            { "Unicast Addresses", "icmpv6.ni.flag.a", FT_BOOLEAN, 16, TFS(&tfs_ni_flag_a), NI_FLAG_A,
4429              "Responder's unicast addresses", HFILL }},
4430         { &hf_icmpv6_ni_flag_t,
4431            { "Truncated", "icmpv6.ni.flag.t", FT_BOOLEAN, 16, TFS(&tfs_set_notset), NI_FLAG_T,
4432              "Defined in a Reply only, indicates that the set of addresses is incomplete for space reasons", HFILL }},
4433         { &hf_icmpv6_ni_flag_rsv,
4434            { "Reserved", "icmpv6.ni.flag.rsv", FT_UINT16, BASE_HEX, NULL, NI_FLAG_RSV,
4435              "Must be Zero", HFILL }},
4436         { &hf_icmpv6_ni_nonce,
4437            { "Nonce", "icmpv6.ni.nonce", FT_UINT64, BASE_HEX, NULL, 0x0,
4438              "An opaque 64-bit field", HFILL }},
4439         { &hf_icmpv6_ni_query_subject_ipv6,
4440            { "IPv6 subject address", "icmpv6.ni.query.subject_ipv6", FT_IPv6, BASE_NONE, NULL, 0x0,
4441              NULL, HFILL }},
4442         { &hf_icmpv6_ni_query_subject_fqdn,
4443            { "FQDN subject", "icmpv6.ni.query.subject_fqdn", FT_STRING, BASE_NONE, NULL, 0x0,
4444              NULL, HFILL }},
4445         { &hf_icmpv6_ni_query_subject_ipv4,
4446            { "IPv4 subject address", "icmpv6.ni.query.subject_ipv4", FT_IPv4, BASE_NONE, NULL, 0x0,
4447              NULL, HFILL }},
4448         { &hf_icmpv6_ni_reply_node_ttl,
4449            { "TTL", "icmpv6.ni.query.subject_ipv4", FT_UINT32, BASE_DEC, NULL, 0x0,
4450              NULL, HFILL }},
4451         { &hf_icmpv6_ni_reply_node_name,
4452            { "Name Node", "icmpv6.ni.query.node_name", FT_STRING, BASE_NONE, NULL, 0x0,
4453              NULL, HFILL }},
4454         { &hf_icmpv6_ni_reply_node_address,
4455            { "IPv6 Node address", "icmpv6.ni.query.node_address", FT_IPv6, BASE_NONE, NULL, 0x0,
4456              NULL, HFILL }},
4457         { &hf_icmpv6_ni_reply_ipv4_address,
4458            { "IPv4 Node address", "icmpv6.ni.query.ipv4_address", FT_IPv4, BASE_NONE, NULL, 0x0,
4459              NULL, HFILL }},
4460
4461         /* RPL: draft-ietf-roll-rpl-19.txt: Routing over Low-Power and Lossy Networks. */
4462         { &hf_icmpv6_rpl_dis_flag,
4463            { "Flags", "icmpv6.rpl.dis.flags", FT_UINT8, BASE_DEC, NULL, 0x0,
4464              "8-bit unused field reserved for flags", HFILL }},
4465         { &hf_icmpv6_rpl_dio_instance,
4466            { "RPLInstanceID", "icmpv6.rpl.dio.instance", FT_UINT8, BASE_DEC, NULL, 0x0,
4467              "Set by the DODAG root that indicates which RPL Instance the DODAG is part of", HFILL }},
4468         { &hf_icmpv6_rpl_dio_version,
4469            { "Version", "icmpv6.rpl.dio.version", FT_UINT8, BASE_DEC, NULL, 0x0,
4470              "Set by the DODAG root to the DODAGVersionNumber", HFILL }},
4471         { &hf_icmpv6_rpl_dio_rank,
4472            { "Rank", "icmpv6.rpl.dio.rank", FT_UINT16, BASE_DEC, NULL, 0x0,
4473              "Indicating the DODAG rank of the node sending the DIO message", HFILL }},
4474         { &hf_icmpv6_rpl_dio_flag,
4475            { "Flags", "icmpv6.rpl.dio.flag", FT_UINT8, BASE_HEX, NULL, 0x0,
4476              NULL, HFILL }},
4477         { &hf_icmpv6_rpl_dio_flag_g,
4478            { "Grounded (G)", "icmpv6.rpl.dio.flag.g", FT_BOOLEAN, 8, NULL, RPL_DIO_FLAG_G,
4479              "Indicates whether the DODAG advertised can satisfy the application-defined goal", HFILL }},
4480         { &hf_icmpv6_rpl_dio_flag_0,
4481            { "Zero", "icmpv6.rpl.dio.flag.0", FT_BOOLEAN, 8, NULL, RPL_DIO_FLAG_0,
4482              NULL, HFILL }},
4483         { &hf_icmpv6_rpl_dio_flag_mop,
4484            { "Mode of Operation (MOP)", "icmpv6.rpl.dio.flag.mop", FT_UINT8, BASE_HEX, VALS(rpl_dio_map_val), RPL_DIO_FLAG_MOP,
4485              "Identifies the mode of operation of the RPL Instance as administratively provisioned at and distributed by the DODAG Root", HFILL }},
4486         { &hf_icmpv6_rpl_dio_flag_prf,
4487            { "DODAG Preference", "icmpv6.rpl.dio.flag.preference", FT_UINT8, BASE_DEC, NULL, RPL_DIO_FLAG_PRF,
4488              "Defines how preferable the root of this DODAG is compared to other DODAG roots within the instance", HFILL }},
4489         { &hf_icmpv6_rpl_dio_dtsn,
4490            { "Destination Advertisement Trigger Sequence Number (DTSN)", "icmpv6.rpl.dio.dtsn", FT_UINT8, BASE_DEC, NULL, 0x0,
4491              "The DTSN is used as part of the procedure to maintain downward routes.", HFILL }},
4492         { &hf_icmpv6_rpl_dio_dagid,
4493            { "DODAGID", "icmpv6.rpl.dio.dagid", FT_IPv6, BASE_NONE, NULL, 0x0,
4494              "IPv6 address set by a DODAG root which uniquely identifies a DODAG", HFILL }},
4495         { &hf_icmpv6_rpl_dao_instance,
4496            { "RPLInstanceID", "icmpv6.rpl.dao.instance", FT_UINT8, BASE_DEC, NULL, 0x0,
4497              "Indicating the topology instance associated with the DODAG as learned from the DIO", HFILL }},
4498         { &hf_icmpv6_rpl_dao_flag,
4499            { "Flags", "icmpv6.rpl.dao.flag", FT_UINT8, BASE_HEX, NULL, 0x0,
4500              NULL, HFILL }},
4501         { &hf_icmpv6_rpl_dao_flag_k,
4502            { "DAO-ACK Request (K)", "icmpv6.rpl.dao.flag.k", FT_BOOLEAN, 8, NULL, RPL_DAO_FLAG_K,
4503              "Indicates that the recipient is expected to send a DAO-ACK back", HFILL }},
4504         { &hf_icmpv6_rpl_dao_flag_d,
4505            { "DODAGID Present (D)", "icmpv6.rpl.dao.flag.d", FT_BOOLEAN, 8, NULL, RPL_DAO_FLAG_D,
4506              "Indicates that the DODAGID field is present", HFILL }},
4507         { &hf_icmpv6_rpl_dao_flag_rsv,
4508            { "Reserved", "icmpv6.rpl.dao.flag.rsv", FT_UINT8, BASE_DEC, NULL, RPL_DAO_FLAG_RESERVED,
4509              "Must be zero", HFILL }},
4510         { &hf_icmpv6_rpl_dao_sequence,
4511            { "DAO Sequence", "icmpv6.rpl.dao.sequence", FT_UINT8, BASE_DEC, NULL, 0x0,
4512              "Incremented at each unique DAO message from a node and echoed in the DAO-ACK message", HFILL }},
4513         { &hf_icmpv6_rpl_dao_dodagid,
4514            { "DODAGID", "icmpv6.rpl.dao.dodagid", FT_IPv6, BASE_NONE, NULL, 0x0,
4515              "IPv6 address set by a DODAG root which uniquely identifies a DODAG", HFILL }},
4516         { &hf_icmpv6_rpl_daoack_instance,
4517            { "RPLInstanceID", "icmpv6.rpl.daoack.instance", FT_UINT8, BASE_DEC, NULL, 0x0,
4518              "Indicating the topology instance associated with the DODAG, as learned from the DIO", HFILL }},
4519         { &hf_icmpv6_rpl_daoack_flag,
4520            { "Flag", "icmpv6.rpl.daoack.flag", FT_UINT8, BASE_HEX, NULL, 0x0,
4521              NULL, HFILL }},
4522         { &hf_icmpv6_rpl_daoack_flag_d,
4523            { "DODAGID Present (D)", "icmpv6.rpl.daoack.flag.d", FT_BOOLEAN, 8, NULL, RPL_DAOACK_FLAG_D,
4524              "Indicates that the DODAGID field is present", HFILL }},
4525         { &hf_icmpv6_rpl_daoack_flag_rsv,
4526            { "Reserved", "icmpv6.rpl.daoack.flag.rsv", FT_UINT8, BASE_DEC, NULL, RPL_DAOACK_FLAG_RESERVED,
4527              "Must be zero", HFILL }},
4528         { &hf_icmpv6_rpl_daoack_sequence,
4529            { "DAO-ACK Sequence", "icmpv6.rpl.daoack.sequence", FT_UINT8, BASE_DEC, NULL, 0x0,
4530              "Incremented at each DAO message from a node, and echoed in the DAO-ACK by the recipient", HFILL }},
4531         { &hf_icmpv6_rpl_daoack_status,
4532            { "Status", "icmpv6.rpl.daoack.status", FT_UINT8, BASE_DEC, NULL, 0x0,
4533              "Indicates the completion", HFILL }},
4534         { &hf_icmpv6_rpl_daoack_dodagid,
4535            { "DODAGID", "icmpv6.rpl.daoack.dodagid", FT_IPv6, BASE_NONE, NULL, 0x0,
4536              "IPv6 address integer set by a DODAG root which uniquely identifies a DODAG", HFILL }},
4537         { &hf_icmpv6_rpl_cc_instance,
4538            { "RPLInstanceID", "icmpv6.rpl.cc.instance", FT_UINT8, BASE_DEC, NULL, 0x0,
4539              "Indicating the topology instance associated with the DODAG, as learned from the DIO", HFILL }},
4540         { &hf_icmpv6_rpl_cc_flag,
4541            { "Flag", "icmpv6.rpl.cc.flag", FT_UINT8, BASE_HEX, NULL, 0x0,
4542              NULL, HFILL }},
4543         { &hf_icmpv6_rpl_cc_flag_r,
4544            { "Reponse (R)", "icmpv6.rpl.cc.flag.r", FT_BOOLEAN, 8, NULL, RPL_CC_FLAG_R,
4545              "Indicates whether the CC message is a response", HFILL }},
4546         { &hf_icmpv6_rpl_cc_flag_rsv,
4547            { "Reserved", "icmpv6.rpl.cc.flag.rsv", FT_UINT8, BASE_DEC, NULL, RPL_CC_FLAG_RESERVED,
4548              "Must be zero", HFILL }},
4549         { &hf_icmpv6_rpl_cc_nonce,
4550            { "CC Nonce", "icmpv6.rpl.cc.nonce", FT_UINT16, BASE_HEX, NULL, 0x0,
4551              "The corresponding CC response includes the same CC nonce value as the request, as learned from the DIO", HFILL }},
4552         { &hf_icmpv6_rpl_cc_dodagid,
4553            { "DODAGID", "icmpv6.rpl.cc.dodagid", FT_IPv6, BASE_NONE, NULL, 0x0,
4554              "IPv6 address integer set by a DODAG root which uniquely identifies a DODAG", HFILL }},
4555         { &hf_icmpv6_rpl_cc_destination_counter,
4556            { "Destination Counter", "icmpv6.rpl.cc.destination_counter", FT_UINT32, BASE_DEC, NULL, 0x0,
4557              "Indicating the sender's estimate of the destination's current security Counter value", HFILL }},
4558         { &hf_icmpv6_rpl_secure_flag,
4559            { "Flags", "icmpv6.rpl.secure.flag", FT_UINT8, BASE_HEX, NULL, 0x0,
4560              NULL, HFILL }},
4561         { &hf_icmpv6_rpl_secure_flag_t,
4562            { "Counter is Time (T)", "icmpv6.rpl.secure.flag.t", FT_BOOLEAN, 8, NULL, RPL_SECURE_FLAG_T,
4563              "If it is set then the Counter field is a timestamp", HFILL }},
4564         { &hf_icmpv6_rpl_secure_flag_rsv,
4565            { "Reserved", "icmpv6.rpl.secure.flag.rsv", FT_UINT8, BASE_DEC, NULL, RPL_SECURE_FLAG_RSV,
4566              "Must be zero", HFILL }},
4567         { &hf_icmpv6_rpl_secure_algorithm,
4568            { "Algorithm", "icmpv6.rpl.secure.algorithm", FT_UINT8, BASE_DEC, NULL, 0x0,
4569              "The Security Algorithm field specifies the encryption, MAC, and signature scheme the network uses", HFILL }},
4570         { &hf_icmpv6_rpl_secure_algorithm_encryption,
4571            { "Algorithm (Encryption)", "icmpv6.rpl.secure.algorithm.encryption", FT_UINT8, BASE_DEC, VALS(rpl_secure_algorithm_encryption_val), 0x0,
4572              NULL, HFILL }},
4573         { &hf_icmpv6_rpl_secure_algorithm_signature,
4574            { "Algorithm (Signature)", "icmpv6.rpl.secure.algorithm.signature", FT_UINT8, BASE_DEC, VALS(rpl_secure_algorithm_signature_val), 0x0,
4575              NULL, HFILL }},
4576         { &hf_icmpv6_rpl_secure_kim,
4577            { "Key Identifier Mode (KIM)", "icmpv6.rpl.secure.kim", FT_UINT8, BASE_DEC, NULL, RPL_SECURE_KIM,
4578              "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 }},
4579         { &hf_icmpv6_rpl_secure_lvl,
4580            { "Security Level (LVL)", "icmpv6.rpl.secure.lvl", FT_UINT8, BASE_DEC, NULL, RPL_SECURE_LVL,
4581              "Indicates the provided packet protection", HFILL }},
4582         { &hf_icmpv6_rpl_secure_rsv,
4583            { "Reserved", "icmpv6.rpl.secure.rsv", FT_UINT8, BASE_DEC, NULL, RPL_SECURE_RSV,
4584              "Must be zero", HFILL }},
4585         { &hf_icmpv6_rpl_secure_counter,
4586            { "Counter", "icmpv6.rpl.secure.counter", FT_UINT32, BASE_DEC, NULL, 0x0,
4587              "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 }},
4588         { &hf_icmpv6_rpl_secure_key_source,
4589            { "Key Source", "icmpv6.rpl.secure.key.source", FT_BYTES, BASE_NONE, NULL, 0x0,
4590              "Indicates the logical identifier of the originator of a group key", HFILL }},
4591         { &hf_icmpv6_rpl_secure_key_index,
4592            { "Key Source", "icmpv6.rpl.secure.key.index", FT_UINT8, BASE_DEC, NULL, 0x0,
4593              "Allows unique identification of different keys with the same originator", HFILL }},
4594         { &hf_icmpv6_rpl_opt,
4595           { "ICMPv6 RPL Option", "icmpv6.opt", FT_NONE, BASE_NONE, NULL, 0x0,
4596             "Option", HFILL }},
4597         { &hf_icmpv6_rpl_opt_type,
4598           { "Type", "icmpv6.rpl.opt.type", FT_UINT8, BASE_DEC, VALS(rpl_option_vals), 0x0,
4599             "Options type", HFILL }},
4600         { &hf_icmpv6_rpl_opt_length,
4601           { "Length", "icmpv6.rpl.opt.length", FT_UINT8, BASE_DEC, NULL, 0x0,
4602             "The length of the option in octets excluding the Type and Length fields", HFILL }},
4603         { &hf_icmpv6_rpl_opt_reserved,
4604           { "Reserved", "icmpv6.rpl.opt.reserved", FT_NONE, BASE_NONE, NULL, 0x0,
4605             "Reserved (Must be 0)", HFILL }},
4606         { &hf_icmpv6_rpl_opt_padn,
4607           { "Paddn", "icmpv6.rpl.opt.padn", FT_NONE, BASE_NONE, NULL, 0x0,
4608             "Padding (Must be 0)", HFILL }},
4609         { &hf_icmpv6_rpl_opt_route_prefix_length,
4610            { "Prefix Length", "icmpv6.rpl.opt.route.prefix_length", FT_UINT8, BASE_DEC, NULL, 0x0,
4611              "The number of leading bits in the Prefix that are valid", HFILL }},
4612         { &hf_icmpv6_rpl_opt_route_flag,
4613            { "Flag","icmpv6.rpl.opt.route.flag", FT_NONE, BASE_NONE, NULL, 0x0,
4614              NULL, HFILL }},
4615         { &hf_icmpv6_rpl_opt_route_pref,
4616            { "Preference","icmpv6.rpl.opt.route.pref", FT_UINT8, BASE_DEC, VALS(nd_flag_router_pref), RPL_OPT_ROUTE_PREFERENCE,
4617              "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 }},
4618         { &hf_icmpv6_rpl_opt_route_reserved,
4619            { "Reserved","icmpv6.rpl.opt.route.reserved", FT_UINT8, BASE_DEC, NULL, RPL_OPT_ROUTE_RESERVED,
4620              "Reserved (Must be Zero)", HFILL }},
4621         { &hf_icmpv6_rpl_opt_route_lifetime,
4622            { "Route Lifetime", "icmpv6.rpl.opt.route.lifetime", FT_UINT32, BASE_DEC, NULL, 0x0,
4623              "The length of time in seconds (relative to the time the packet is sent) that the prefix is valid for route determination", HFILL }},
4624         { &hf_icmpv6_rpl_opt_route_prefix,
4625            { "Prefix", "icmpv6.rpl.opt.route.prefix", FT_IPv6, BASE_NONE, NULL, 0x0,
4626              "Variable-length field containing an IP address or a prefix of an IPv6 address", HFILL }},
4627         { &hf_icmpv6_rpl_opt_config_flag,
4628            { "Flag","icmpv6.rpl.opt.config.flag", FT_NONE, BASE_NONE, NULL, 0x0,
4629              NULL, HFILL }},
4630         { &hf_icmpv6_rpl_opt_config_reserved,
4631            { "Reserved","icmpv6.rpl.opt.config.reserved", FT_UINT8, BASE_DEC, NULL, RPL_OPT_CONFIG_FLAG_RESERVED,
4632              "Must be Zero", HFILL }},
4633         { &hf_icmpv6_rpl_opt_config_auth,
4634            { "Authentication Enabled","icmpv6.rpl.opt.config.auth", FT_BOOLEAN, 8, TFS(&tfs_set_notset), RPL_OPT_CONFIG_FLAG_AUTH,
4635              "One bit flag describing the security mode of the network", HFILL }},
4636         { &hf_icmpv6_rpl_opt_config_pcs,
4637            { "Path Control Size", "icmpv6.rpl.opt.config.pcs", FT_UINT8, BASE_DEC, NULL, RPL_OPT_CONFIG_FLAG_PCS,
4638              "Used to configure the number of bits that may be allocated to the Path Control field", HFILL }},
4639         { &hf_icmpv6_rpl_opt_config_doublings,
4640            { "DIOIntervalDoublings","icmpv6.rpl.opt.config.interval_double", FT_UINT8, BASE_DEC, NULL, 0x0,
4641              "Used to configure Imax of the DIO trickle timer", HFILL }},
4642         { &hf_icmpv6_rpl_opt_config_min_interval,
4643            { "DIOIntervalMin", "icmpv6.rpl.opt.config.interval_min", FT_UINT16, BASE_DEC, NULL, 0x0,
4644              "Used to configure Imin of the DIO trickle timer", HFILL }},
4645         { &hf_icmpv6_rpl_opt_config_redundancy,
4646            { "DIORedundancyConstant", "icmpv6.rpl.opt.config.redundancy", FT_UINT8, BASE_DEC, NULL, 0x0,
4647              "Used to configure k of the DIO trickle timer", HFILL }},
4648         { &hf_icmpv6_rpl_opt_config_rank_incr,
4649            { "MaxRankInc", "icmpv6.rpl.opt.config.max_rank_inc", FT_UINT16, BASE_DEC, NULL, 0x0,
4650              "Used to configure DAGMaxRankIncrease", HFILL }},
4651         { &hf_icmpv6_rpl_opt_config_hop_rank_inc,
4652            { "MinHopRankInc", "icmpv6.rpl.opt.config.min_hop_rank_inc", FT_UINT16, BASE_DEC, NULL, 0x0,
4653               "Used to configure MinHopRankIncrease", HFILL }},
4654         { &hf_icmpv6_rpl_opt_config_ocp,
4655            { "OCP (Objective Code Point)","icmpv6.rpl.opt.config.ocp", FT_UINT16, BASE_DEC, NULL, 0x0,
4656               "The OCP field identifies the OF and is managed by the IANA", HFILL }},
4657         { &hf_icmpv6_rpl_opt_config_rsv,
4658            { "Reserved", "icmpv6.rpl.opt.config.rsv", FT_UINT8, BASE_DEC, NULL, 0x0,
4659               NULL, HFILL }},
4660         { &hf_icmpv6_rpl_opt_config_def_lifetime,
4661            { "Default Lifetime", "icmpv6.rpl.opt.config.def_lifetime", FT_UINT8, BASE_DEC, NULL, 0x0,
4662               "This is the lifetime that is used as default for all RPL routes", HFILL }},
4663         { &hf_icmpv6_rpl_opt_config_lifetime_unit,
4664            { "Lifetime Unit", "icmpv6.rpl.opt.config.lifetime_unit", FT_UINT16, BASE_DEC, NULL, 0x0,
4665               "Provides the unit in seconds that is used to express route lifetimes in RPL", HFILL }},
4666         { &hf_icmpv6_rpl_opt_target_flag,
4667            { "Reserved", "icmpv6.rpl.opt.target.flag", FT_NONE, BASE_NONE, NULL, 0x0,
4668               "Unused field reserved for flags", HFILL }},
4669         { &hf_icmpv6_rpl_opt_target_prefix_length,
4670            { "Target Length", "icmpv6.rpl.opt.target.prefix_length", FT_UINT8, BASE_DEC, NULL, 0x0,
4671               "Number of valid leading bits in the IPv6 Prefix", HFILL }},
4672         { &hf_icmpv6_rpl_opt_target_prefix,
4673            { "Target", "icmpv6.rpl.opt.target.prefix", FT_IPv6, BASE_NONE, NULL, 0x0,
4674               "Identifying an IPv6 destination address, prefix, or multicast group", HFILL }},
4675         { &hf_icmpv6_rpl_opt_transit_flag,
4676            { "Flags", "icmpv6.rpl.opt.transit.flag", FT_UINT8, BASE_HEX, NULL, 0x0,
4677              NULL, HFILL }},
4678          { &hf_icmpv6_rpl_opt_transit_flag_e,
4679            { "External", "icmpv6.rpl.opt.transit.flag.e", FT_BOOLEAN, 8, TFS(&tfs_set_notset), RPL_OPT_TRANSIT_FLAG_E,
4680              "Indicate that the parent router redistributes external targets into the RPL network", HFILL }},
4681          { &hf_icmpv6_rpl_opt_transit_flag_rsv,
4682            { "Reserved", "icmpv6.rpl.opt.transit.flag.rsv", FT_UINT8, BASE_DEC, NULL, RPL_OPT_TRANSIT_FLAG_RSV,
4683              "Must be Zero", HFILL }},
4684         { &hf_icmpv6_rpl_opt_transit_pathctl,
4685            { "Path Control", "icmpv6.rpl.opt.transit.pathctl", FT_UINT8, BASE_DEC, NULL, 0x0,
4686               "Limits the number of DAO-Parents to which a DAO message advertising connectivity", HFILL }},
4687         { &hf_icmpv6_rpl_opt_transit_pathseq,
4688            { "Path Sequence", "icmpv6.rpl.opt.transit.pathseq", FT_UINT8, BASE_DEC, NULL, 0x0,
4689               "Increments the Path Sequence each time it issues a RPL Target option with updated information", HFILL }},
4690         { &hf_icmpv6_rpl_opt_transit_pathlifetime,
4691            { "Path Lifetime", "icmpv6.rpl.opt.transit.pathlifetime", FT_UINT8, BASE_DEC, NULL, 0x0,
4692               "The length of time in Lifetime Units that the prefix is valid for route determination", HFILL }},
4693         { &hf_icmpv6_rpl_opt_transit_parent,
4694            { "Parent Address", "icmpv6.rpl.opt.transit.parent", FT_IPv6, BASE_NONE, NULL, 0x0,
4695               "IPv6 Address of the DODAG Parent of the node originally issuing the Transit Information Option", HFILL }},
4696         { &hf_icmpv6_rpl_opt_solicited_instance,
4697            { "Instance", "icmpv6.rpl.opt.solicited.instance", FT_UINT8, BASE_DEC, NULL, 0x0,
4698               "Containing the RPLInstanceID that is being solicited when valid", HFILL }},
4699         { &hf_icmpv6_rpl_opt_solicited_flag,
4700            { "Flag", "icmpv6.rpl.opt.solicited.flag", FT_UINT8, BASE_HEX, NULL, 0x0,
4701               NULL, HFILL }},
4702         { &hf_icmpv6_rpl_opt_solicited_flag_v,
4703            { "Version predicate", "icmpv6.rpl.opt.solicited.flag.v", FT_BOOLEAN, 8, TFS(&tfs_true_false), RPL_OPT_SOLICITED_FLAG_V,
4704               "The Version predicate is true if the receiver's DODAGVersionNumber matches the requested Version Number", HFILL }},
4705         { &hf_icmpv6_rpl_opt_solicited_flag_i,
4706            { "InstanceID predicate","icmpv6.rpl.opt.solicited.flag.i", FT_BOOLEAN, 8, TFS(&tfs_true_false), RPL_OPT_SOLICITED_FLAG_I,
4707               "The InstanceID predicate is true when the RPL node's current RPLInstanceID matches the requested RPLInstanceID", HFILL }},
4708         { &hf_icmpv6_rpl_opt_solicited_flag_d,
4709            { "DODAGID predicate", "icmpv6.rpl.opt.solicited.flag.d", FT_BOOLEAN, 8, TFS(&tfs_true_false), RPL_OPT_SOLICITED_FLAG_D,
4710               "The DODAGID predicate is true if the RPL node's parent set has the same DODAGID as the DODAGID field", HFILL }},
4711          { &hf_icmpv6_rpl_opt_solicited_flag_rsv,
4712            { "Reserved", "icmpv6.rpl.opt.solicited.flag.rsv", FT_UINT8, BASE_DEC, NULL, RPL_OPT_SOLICITED_FLAG_RSV,
4713              "Must be Zero", HFILL }},
4714         { &hf_icmpv6_rpl_opt_solicited_dodagid,
4715            { "DODAGID", "icmpv6.rpl.opt.solicited.dodagid", FT_IPv6, BASE_NONE, NULL, 0x0,
4716               "the DODAGID that is being solicited when valid", HFILL }},
4717         { &hf_icmpv6_rpl_opt_solicited_version,
4718            { "Version", "icmpv6.rpl.opt.solicited.version", FT_UINT8, BASE_DEC, NULL, 0x0,
4719               "the value of  DODAGVersionNumber that is being solicited when valid", HFILL }},
4720
4721         { &hf_icmpv6_rpl_opt_prefix_length,
4722            { "Prefix Length", "icmpv6.rpl.opt.prefix.length", FT_UINT8, BASE_DEC, NULL, 0x0,
4723              "The number of leading bits in the Prefix that are valid", HFILL }},
4724         { &hf_icmpv6_rpl_opt_prefix_flag,
4725            { "Flag", "icmpv6.rpl.opt.prefix.flag", FT_UINT8, BASE_HEX, NULL, 0x0,
4726              NULL, HFILL }},
4727         { &hf_icmpv6_rpl_opt_prefix_flag_l,
4728            { "On Link", "icmpv6.rpl.opt.prefix.flag.l", FT_BOOLEAN, 8, TFS(&tfs_set_notset), RPL_OPT_PREFIX_FLAG_L,
4729              "When set, indicates that this prefix can be used for on-link determination", HFILL }},
4730         { &hf_icmpv6_rpl_opt_prefix_flag_a,
4731            { "Auto Address Config","icmpv6.rpl.opt.config.flag.a", FT_BOOLEAN, 8, TFS(&tfs_set_notset), RPL_OPT_PREFIX_FLAG_A,
4732              "When set indicates that this prefix can be used for stateless address configuration", HFILL }},
4733         { &hf_icmpv6_rpl_opt_prefix_flag_r,
4734            { "Router Address", "icmpv6.rpl.opt.config.flag.r", FT_BOOLEAN, 8, TFS(&tfs_set_notset), RPL_OPT_PREFIX_FLAG_R,
4735              "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 }},
4736         { &hf_icmpv6_rpl_opt_prefix_flag_rsv,
4737            { "Reserved", "icmpv6.rpl.opt.config.flag.rsv", FT_UINT8, BASE_DEC, NULL, RPL_OPT_PREFIX_FLAG_RSV,
4738              "Must Be Zero", HFILL }},
4739         { &hf_icmpv6_rpl_opt_prefix_vlifetime,
4740            { "Valid Lifetime", "icmpv6.rpl.opt.prefix.valid_lifetime", FT_UINT32, BASE_DEC, NULL, 0x0,
4741              "The length of time in seconds that the prefix is valid for the purpose of on-link determination", HFILL }},
4742         { &hf_icmpv6_rpl_opt_prefix_plifetime,
4743            { "Preferred Lifetime", "icmpv6.rpl.opt.prefix.preferred_lifetime", FT_UINT32, BASE_DEC, NULL, 0x0,
4744              "The length of time in seconds that addresses generated from the prefix via stateless address autoconfiguration remain preferred", HFILL }},
4745         { &hf_icmpv6_rpl_opt_prefix,
4746            { "Destination Prefix", "icmpv6.rpl.opt.prefix", FT_IPv6, BASE_NONE, NULL, 0x0,
4747              "An IPv6 address or a prefix of an IPv6 address", HFILL }},
4748         { &hf_icmpv6_rpl_opt_targetdesc,
4749            { "Descriptor", "icmpv6.rpl.opt.targetdesc.descriptor", FT_UINT32, BASE_HEX, NULL, 0x0,
4750              "Opaque Data", HFILL }},
4751
4752         /* 6lowpan-nd: Neighbour Discovery for 6LoWPAN Networks */
4753         { &hf_icmpv6_da_status,
4754           { "Status", "icmpv6.6lowpannd.da.status", FT_UINT8, BASE_DEC, VALS(nd_opt_6lowpannd_status_val), 0x0,
4755             "Indicates the status of a registration in the DAC", HFILL }},
4756         { &hf_icmpv6_da_rsv,
4757           { "Reserved", "icmpv6.6lowpannd.da.rsv", FT_UINT8, BASE_DEC, NULL, 0x0,
4758             "Must be Zero", HFILL }},
4759         { &hf_icmpv6_da_lifetime,
4760           { "Lifetime", "icmpv6.6lowpannd.da.lifetime", FT_UINT16, BASE_DEC, NULL, 0x0,
4761             "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 }},
4762         { &hf_icmpv6_da_eui64,
4763           { "EUI-64", "icmpv6.6lowpannd.da.eui64", FT_EUI64, BASE_NONE, NULL, 0x0,
4764             "This field is used to uniquely identify the interface of the registered address by including the EUI-64 identifier", HFILL }},
4765         { &hf_icmpv6_da_raddr,
4766           { "Registered Address", "icmpv6.6lowpannd.da.reg_addr", FT_IPv6, BASE_NONE, NULL, 0x0,
4767             "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 }},
4768
4769         /* Conversation-related [generated] header fields */
4770         { &hf_icmpv6_resp_in,
4771             { "Response In", "icmpv6.resp_in", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
4772               "The response to this request is in this frame", HFILL }},
4773         { &hf_icmpv6_resp_to,
4774             { "Response To", "icmpv6.resp_to", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
4775               "This is the response to the request in this frame", HFILL }},
4776         { &hf_icmpv6_resptime,
4777             { "Response Time", "icmpv6.resptime", FT_DOUBLE, BASE_NONE, NULL, 0x0,
4778               "The time between the request and the response, in ms.", HFILL }}
4779     };
4780
4781     static gint *ett[] = {
4782         &ett_icmpv6,
4783         &ett_icmpv6_opt,
4784         &ett_icmpv6_mar,
4785         &ett_icmpv6_flag_prefix,
4786         &ett_icmpv6_flag_map,
4787         &ett_icmpv6_flag_route_info,
4788         &ett_icmpv6_flag_6lowpan,
4789         &ett_icmpv6_flag_efo,
4790         &ett_icmpv6_rpl_opt,
4791         &ett_icmpv6_rpl_flag_routing,
4792         &ett_icmpv6_rpl_flag_config,
4793         &ett_icmpv6_rpl_flag_transit,
4794         &ett_icmpv6_rpl_flag_solicited,
4795         &ett_icmpv6_rpl_flag_prefix,
4796         &ett_icmpv6_flag_ni,
4797         &ett_icmpv6_flag_rr,
4798         &ett_icmpv6_rr_mp,
4799         &ett_icmpv6_rr_up,
4800         &ett_icmpv6_rr_up_flag_mask,
4801         &ett_icmpv6_rr_up_flag_ra,
4802         &ett_icmpv6_rr_up_flag,
4803         &ett_icmpv6_rr_rm,
4804         &ett_icmpv6_rr_rm_flag,
4805         &ett_icmpv6_flag_mld,
4806         &ett_icmpv6_flag_ra,
4807         &ett_icmpv6_flag_na,
4808         &ett_icmpv6_flag_mip6,
4809         &ett_icmpv6_flag_fmip6,
4810         &ett_icmpv6_flag_secure,
4811         &ett_icmpv6_flag_rpl_dio,
4812         &ett_icmpv6_flag_rpl_dao,
4813         &ett_icmpv6_flag_rpl_daoack,
4814         &ett_icmpv6_flag_rpl_cc,
4815         &ett_icmpv6_opt_name,
4816         &ett_icmpv6_cga_param_name
4817     };
4818
4819     proto_icmpv6 = proto_register_protocol("Internet Control Message Protocol v6",
4820                                            "ICMPv6", "icmpv6");
4821     proto_register_field_array(proto_icmpv6, hf, array_length(hf));
4822     proto_register_subtree_array(ett, array_length(ett));
4823
4824     new_register_dissector("icmpv6", dissect_icmpv6, proto_icmpv6);
4825     icmpv6_tap = register_tap("icmpv6");
4826 }
4827
4828 void
4829 proto_reg_handoff_icmpv6(void)
4830 {
4831     dissector_handle_t icmpv6_handle;
4832
4833     icmpv6_handle = new_create_dissector_handle(dissect_icmpv6, proto_icmpv6);
4834     dissector_add_uint("ip.proto", IP_PROTO_ICMPV6, icmpv6_handle);
4835
4836     /*
4837      * Get a handle for the IPv6 dissector.
4838      */
4839     ipv6_handle = find_dissector("ipv6");
4840     data_handle = find_dissector("data");
4841 }
4842
4843 /*
4844  * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
4845  *
4846  * Local variables:
4847  * c-basic-offset: 4
4848  * tab-width: 8
4849  * indent-tabs-mode: nil
4850  * End:
4851  *
4852  * vi: set shiftwidth=4 tabstop=8 expandtab:
4853  * :indentSize=4:tabSize=8:noTabs=true:
4854  */