epan/dissectors/pidl/samr/samr.cnf cnf_dissect_lsa_BinaryString => lsarpc_dissect_str...
[wireshark-sm.git] / epan / dissectors / packet-ipv6.c
blob3e5817d24b9f553164b2d46707bf5b45c7950938
1 /* packet-ipv6.c
2 * Routines for IPv6 packet disassembly
4 * Wireshark - Network traffic analyzer
5 * By Gerald Combs <gerald@wireshark.org>
6 * Copyright 1998 Gerald Combs
8 * SHIM6 support added by Matthijs Mekking <matthijs@NLnetLabs.nl>
10 * MobileIPv6 support added by Tomislav Borosa <tomislav.borosa@siemens.hr>
12 * Added support for new IPv6 Hop by Hop PMTU Option <bob.hinden@gmail.com>
14 * SPDX-License-Identifier: GPL-2.0-or-later
17 #include "config.h"
19 #include <math.h>
20 #include <epan/packet.h>
21 #include <epan/capture_dissectors.h>
22 #include <epan/expert.h>
23 #include <epan/ip_opts.h>
24 #include <epan/addr_resolv.h>
25 #include <epan/maxmind_db.h>
26 #include <epan/prefs.h>
27 #include <epan/uat.h>
28 #include <epan/conversation_table.h>
29 #include <epan/conversation_filter.h>
30 #include <epan/reassemble.h>
31 #include <epan/ipproto.h>
32 #include <epan/etypes.h>
33 #include <epan/ppptypes.h>
34 #include <epan/aftypes.h>
35 #include <epan/nlpid.h>
36 #include <epan/arcnet_pids.h>
37 #include <epan/decode_as.h>
38 #include <epan/proto_data.h>
39 #include <epan/to_str.h>
40 #include <epan/exported_pdu.h>
41 #include <epan/exceptions.h>
42 #include <epan/iana-ip.h>
43 #include <epan/tfs.h>
44 #include <epan/unit_strings.h>
46 #include <wiretap/erf_record.h>
47 #include "packet-ip.h"
48 #include "packet-juniper.h"
49 #include "packet-sflow.h"
50 #include "packet-vxlan.h"
51 #include "packet-mpls.h"
52 #include "packet-nsh.h"
54 void proto_register_ipv6(void);
55 void proto_reg_handoff_ipv6(void);
57 /* Offsets of fields within an IPv6 header. */
58 #define IP6H_CTL_VFC 0
59 #define IP6H_CTL_FLOW 0
60 #define IP6H_CTL_PLEN 4
61 #define IP6H_CTL_NXT 6
62 #define IP6H_CTL_HLIM 7
63 #define IP6H_SRC 8
64 #define IP6H_DST 24
66 /* Option types and related macros */
67 #define IP6OPT_PAD1 0x00 /* 00 0 00000 = 0 */
68 #define IP6OPT_PADN 0x01 /* 00 0 00001 = 1 */
69 #define IP6OPT_TEL 0x04 /* 00 0 00100 = 4 */
70 #define IP6OPT_RTALERT 0x05 /* 00 0 00101 = 5 */
71 #define IP6OPT_CALIPSO 0x07 /* 00 0 00111 = 7 */
72 #define IP6OPT_SMF_DPD 0x08 /* 00 0 01000 = 8 */
73 #define IP6OPT_PDM 0x0F /* 00 0 01111 = 15 */
74 #define IP6OPT_APN6 0x13 /* 00 0 10011 = 19 */
75 #define IP6OPT_EXP_1E 0x1E /* 00 0 11110 = 30 */
76 #define IP6OPT_RPL 0x23 /* 00 1 00011 = 35 */
77 #define IP6OPT_QUICKSTART 0x26 /* 00 1 00110 = 38 */
78 #define IP6OPT_PMTU 0x30 /* 00 1 10000 = 48 */
79 #define IP6OPT_IOAM 0x31 /* 00 1 10001 = 49 */
80 #define IP6OPT_EXP_3E 0x3E /* 00 1 11110 = 62 */
81 #define IP6OPT_TPF 0x41 /* 01 0 00001 = 65 */
82 #define IP6OPT_EXP_5E 0x5E /* 01 0 11110 = 94 */
83 #define IP6OPT_RPL_OLD 0x63 /* 01 1 00011 = 99 */ /* DEPRECATED */
84 #define IP6OPT_MPL 0x6D /* 01 1 01101 = 109 */
85 #define IP6OPT_EXP_7E 0x7E /* 01 1 11110 = 126 */
86 #define IP6OPT_ENDI 0x8A /* 10 0 01010 = 138 */ /* DEPRECATED */
87 #define IP6OPT_ILNP_NONCE 0x8B /* 10 0 01011 = 139 */
88 #define IP6OPT_LIO 0x8C /* 10 0 01100 = 140 */
89 #define IP6OPT_EXP_9E 0x9E /* 10 0 11110 = 158 */
90 #define IP6OPT_EXP_BE 0xBE /* 10 1 11110 = 190 */
91 #define IP6OPT_JUMBO 0xC2 /* 11 0 00010 = 194 */
92 #define IP6OPT_HOME_ADDRESS 0xC9 /* 11 0 01001 = 201 */
93 #define IP6OPT_EXP_DE 0xDE /* 11 0 11110 = 222 */
94 #define IP6OPT_IP_DFF 0xEE /* 11 1 01110 = 238 */
95 #define IP6OPT_EXP_FE 0xFE /* 11 1 11110 = 254 */
97 #define IP6OPT_RTALERT_MLD 0 /* Datagram contains MLD msg */
98 #define IP6OPT_RTALERT_RSVP 1 /* Datagram contains RSVP msg */
99 #define IP6OPT_RTALERT_ACTNET 2 /* Datagram contains ACTNET msg */
101 /* RPL Routing header */
102 #define IP6RRPL_BITMASK_CMPRI 0xF0000000
103 #define IP6RRPL_BITMASK_CMPRE 0x0F000000
104 #define IP6RRPL_BITMASK_PAD 0x00F00000
105 #define IP6RRPL_BITMASK_RESERVED 0x000FFFFF
107 /* IOAM Option-Types */
108 #define IP6IOAM_PRE_TRACE 0 /* Pre-allocated Trace */
109 #define IP6IOAM_INC_TRACE 1 /* Incremental Trace */
110 #define IP6IOAM_POT 2 /* Proof of Transit */
111 #define IP6IOAM_E2E 3 /* Edge to Edge */
112 #define IP6IOAM_DEX 4 /* Direct Export */
114 /* IOAM Trace Types */
115 #define IP6IOAM_TRACE_MASK_BIT0 (1 << 23) /* Hop_lim + Node ID */
116 #define IP6IOAM_TRACE_MASK_BIT1 (1 << 22) /* Ingress and Egress IDs */
117 #define IP6IOAM_TRACE_MASK_BIT2 (1 << 21) /* Timestamp seconds */
118 #define IP6IOAM_TRACE_MASK_BIT3 (1 << 20) /* Timestamp fraction */
119 #define IP6IOAM_TRACE_MASK_BIT4 (1 << 19) /* Transit delay */
120 #define IP6IOAM_TRACE_MASK_BIT5 (1 << 18) /* IOAM-Namespace data */
121 #define IP6IOAM_TRACE_MASK_BIT6 (1 << 17) /* Queue depth */
122 #define IP6IOAM_TRACE_MASK_BIT7 (1 << 16) /* Checksum complement */
123 #define IP6IOAM_TRACE_MASK_BIT8 (1 << 15) /* (wide) Hop_lim + Node ID */
124 #define IP6IOAM_TRACE_MASK_BIT9 (1 << 14) /* (wide) Ingress and Egress IDs */
125 #define IP6IOAM_TRACE_MASK_BIT10 (1 << 13) /* (wide) IOAM-Namespace data */
126 #define IP6IOAM_TRACE_MASK_BIT11 (1 << 12) /* Buffer occupancy */
127 #define IP6IOAM_TRACE_MASK_BIT12 (1 << 11) /* Undefined */
128 #define IP6IOAM_TRACE_MASK_BIT13 (1 << 10) /* Undefined */
129 #define IP6IOAM_TRACE_MASK_BIT14 (1 << 9) /* Undefined */
130 #define IP6IOAM_TRACE_MASK_BIT15 (1 << 8) /* Undefined */
131 #define IP6IOAM_TRACE_MASK_BIT16 (1 << 7) /* Undefined */
132 #define IP6IOAM_TRACE_MASK_BIT17 (1 << 6) /* Undefined */
133 #define IP6IOAM_TRACE_MASK_BIT18 (1 << 5) /* Undefined */
134 #define IP6IOAM_TRACE_MASK_BIT19 (1 << 4) /* Undefined */
135 #define IP6IOAM_TRACE_MASK_BIT20 (1 << 3) /* Undefined */
136 #define IP6IOAM_TRACE_MASK_BIT21 (1 << 2) /* Undefined */
137 #define IP6IOAM_TRACE_MASK_BIT22 (1 << 1) /* Opaque state snapshot */
139 /* Protocol specific data indices */
140 #define IPV6_PROTO_VALUE 1
141 #define IPV6_PROTO_PINFO 2
143 static int ipv6_tap;
145 static int exported_pdu_tap;
147 static int proto_ipv6;
148 static int proto_ipv6_hopopts;
149 static int proto_ipv6_routing;
150 static int proto_ipv6_fraghdr;
151 static int proto_ipv6_dstopts;
153 static int proto_ipv6_routing_rt0;
154 static int proto_ipv6_routing_mipv6;
155 static int proto_ipv6_routing_rpl;
156 static int proto_ipv6_routing_srh;
157 static int proto_ipv6_routing_crh;
159 static int hf_ipv6_version;
160 static int hf_ip_version;
161 static int hf_ipv6_tclass;
162 static int hf_ipv6_tclass_dscp;
163 static int hf_ipv6_tclass_ecn;
164 static int hf_ipv6_flow;
165 static int hf_ipv6_stream;
166 static int hf_ipv6_plen;
167 static int hf_ipv6_nxt;
168 static int hf_ipv6_hlim;
169 static int hf_ipv6_src;
170 static int hf_ipv6_src_addr_space;
171 static int hf_ipv6_src_multicast_flags;
172 static int hf_ipv6_src_multicast_flags_reserved;
173 static int hf_ipv6_src_multicast_flags_transient;
174 static int hf_ipv6_src_multicast_flags_network_prefix;
175 static int hf_ipv6_src_multicast_flags_embed_rp;
176 static int hf_ipv6_src_special_purpose;
177 static int hf_ipv6_src_special_purpose_source;
178 static int hf_ipv6_src_special_purpose_destination;
179 static int hf_ipv6_src_special_purpose_forwardable;
180 static int hf_ipv6_src_special_purpose_global;
181 static int hf_ipv6_src_special_purpose_reserved;
182 static int hf_ipv6_src_multicast_scope;
183 static int hf_ipv6_src_host;
184 static int hf_ipv6_src_slaac_mac;
185 static int hf_ipv6_src_isatap_ipv4;
186 static int hf_ipv6_src_6to4_gateway_ipv4;
187 static int hf_ipv6_src_6to4_sla_id;
188 static int hf_ipv6_src_teredo_server_ipv4;
189 static int hf_ipv6_src_teredo_port;
190 static int hf_ipv6_src_teredo_client_ipv4;
191 static int hf_ipv6_src_embed_ipv4;
192 static int hf_ipv6_dst;
193 static int hf_ipv6_dst_addr_space;
194 static int hf_ipv6_dst_multicast_flags;
195 static int hf_ipv6_dst_multicast_flags_reserved;
196 static int hf_ipv6_dst_multicast_flags_transient;
197 static int hf_ipv6_dst_multicast_flags_network_prefix;
198 static int hf_ipv6_dst_multicast_flags_embed_rp;
199 static int hf_ipv6_dst_multicast_scope;
200 static int hf_ipv6_dst_special_purpose;
201 static int hf_ipv6_dst_special_purpose_source;
202 static int hf_ipv6_dst_special_purpose_destination;
203 static int hf_ipv6_dst_special_purpose_forwardable;
204 static int hf_ipv6_dst_special_purpose_global;
205 static int hf_ipv6_dst_special_purpose_reserved;
206 static int hf_ipv6_dst_host;
207 static int hf_ipv6_dst_slaac_mac;
208 static int hf_ipv6_dst_isatap_ipv4;
209 static int hf_ipv6_dst_6to4_gateway_ipv4;
210 static int hf_ipv6_dst_6to4_sla_id;
211 static int hf_ipv6_dst_teredo_server_ipv4;
212 static int hf_ipv6_dst_teredo_port;
213 static int hf_ipv6_dst_teredo_client_ipv4;
214 static int hf_ipv6_dst_embed_ipv4;
215 static int hf_ipv6_addr;
216 static int hf_ipv6_addr_space;
217 static int hf_ipv6_multicast_flags;
218 static int hf_ipv6_multicast_flags_reserved;
219 static int hf_ipv6_multicast_flags_transient;
220 static int hf_ipv6_multicast_flags_network_prefix;
221 static int hf_ipv6_multicast_flags_embed_rp;
222 static int hf_ipv6_multicast_scope;
223 static int hf_ipv6_addr_special_purpose;
224 static int hf_ipv6_addr_special_purpose_source;
225 static int hf_ipv6_addr_special_purpose_destination;
226 static int hf_ipv6_addr_special_purpose_forwardable;
227 static int hf_ipv6_addr_special_purpose_global;
228 static int hf_ipv6_addr_special_purpose_reserved;
229 static int hf_ipv6_host;
230 static int hf_ipv6_slaac_mac;
231 static int hf_ipv6_isatap_ipv4;
232 static int hf_ipv6_6to4_gateway_ipv4;
233 static int hf_ipv6_6to4_sla_id;
234 static int hf_ipv6_teredo_server_ipv4;
235 static int hf_ipv6_teredo_port;
236 static int hf_ipv6_teredo_client_ipv4;
237 static int hf_ipv6_embed_ipv4_prefix;
238 static int hf_ipv6_embed_ipv4;
239 static int hf_ipv6_embed_ipv4_u;
240 static int hf_ipv6_embed_ipv4_suffix;
241 static int hf_ipv6_opt;
242 static int hf_ipv6_opt_type;
243 static int hf_ipv6_opt_type_action;
244 static int hf_ipv6_opt_type_change;
245 static int hf_ipv6_opt_type_rest;
246 static int hf_ipv6_opt_length;
247 static int hf_ipv6_opt_pad1;
248 static int hf_ipv6_opt_padn;
249 static int hf_ipv6_opt_tel;
250 static int hf_ipv6_opt_rtalert;
251 static int hf_ipv6_opt_pmtu_min;
252 static int hf_ipv6_opt_pmtu_rtn;
253 static int hf_ipv6_opt_pmtu_rtn_flag;
254 static int hf_ipv6_opt_apn_id_type;
255 static int hf_ipv6_opt_apn_flags;
256 static int hf_ipv6_opt_apn_param_type;
257 static int hf_ipv6_opt_apn_id_part1;
258 static int hf_ipv6_opt_apn_id_part2;
259 static int hf_ipv6_opt_apn_id_part3;
260 static int hf_ipv6_opt_apn_id_part4;
261 static int hf_ipv6_opt_jumbo;
262 static int hf_ipv6_opt_calipso_doi;
263 static int hf_ipv6_opt_calipso_cmpt_length;
264 static int hf_ipv6_opt_calipso_sens_level;
265 static int hf_ipv6_opt_calipso_checksum;
266 static int hf_ipv6_opt_calipso_cmpt_bitmap;
267 static int hf_ipv6_opt_smf_dpd_hash_bit;
268 static int hf_ipv6_opt_smf_dpd_tid_type;
269 static int hf_ipv6_opt_smf_dpd_tid_len;
270 static int hf_ipv6_opt_smf_dpd_tagger_id;
271 static int hf_ipv6_opt_smf_dpd_ident;
272 static int hf_ipv6_opt_smf_dpd_hav;
273 static int hf_ipv6_opt_pdm_scale_dtlr;
274 static int hf_ipv6_opt_pdm_scale_dtls;
275 static int hf_ipv6_opt_pdm_psn_this_pkt;
276 static int hf_ipv6_opt_pdm_psn_last_recv;
277 static int hf_ipv6_opt_pdm_delta_last_recv;
278 static int hf_ipv6_opt_pdm_delta_last_sent;
279 static int hf_ipv6_opt_qs_func;
280 static int hf_ipv6_opt_qs_rate;
281 static int hf_ipv6_opt_qs_ttl;
282 static int hf_ipv6_opt_qs_ttl_diff;
283 static int hf_ipv6_opt_qs_unused;
284 static int hf_ipv6_opt_qs_nonce;
285 static int hf_ipv6_opt_qs_reserved;
286 static int hf_ipv6_opt_ioam_rsv;
287 static int hf_ipv6_opt_ioam_opt_type;
288 static int hf_ipv6_opt_ioam_trace_ns;
289 static int hf_ipv6_opt_ioam_trace_nodelen;
290 static int hf_ipv6_opt_ioam_trace_flags;
291 static int hf_ipv6_opt_ioam_trace_flag_o;
292 static int hf_ipv6_opt_ioam_trace_flag_l;
293 static int hf_ipv6_opt_ioam_trace_flag_a;
294 static int hf_ipv6_opt_ioam_trace_flag_rsv;
295 static int hf_ipv6_opt_ioam_trace_remlen;
296 static int hf_ipv6_opt_ioam_trace_type;
297 static int hf_ipv6_opt_ioam_trace_type_bit0;
298 static int hf_ipv6_opt_ioam_trace_type_bit1;
299 static int hf_ipv6_opt_ioam_trace_type_bit2;
300 static int hf_ipv6_opt_ioam_trace_type_bit3;
301 static int hf_ipv6_opt_ioam_trace_type_bit4;
302 static int hf_ipv6_opt_ioam_trace_type_bit5;
303 static int hf_ipv6_opt_ioam_trace_type_bit6;
304 static int hf_ipv6_opt_ioam_trace_type_bit7;
305 static int hf_ipv6_opt_ioam_trace_type_bit8;
306 static int hf_ipv6_opt_ioam_trace_type_bit9;
307 static int hf_ipv6_opt_ioam_trace_type_bit10;
308 static int hf_ipv6_opt_ioam_trace_type_bit11;
309 static int hf_ipv6_opt_ioam_trace_type_undef;
310 static int hf_ipv6_opt_ioam_trace_type_bit22;
311 static int hf_ipv6_opt_ioam_trace_type_rsv;
312 static int hf_ipv6_opt_ioam_trace_rsv;
313 static int hf_ipv6_opt_ioam_trace_free_space;
314 static int hf_ipv6_opt_ioam_trace_node_hlim;
315 static int hf_ipv6_opt_ioam_trace_node_id;
316 static int hf_ipv6_opt_ioam_trace_node_iif;
317 static int hf_ipv6_opt_ioam_trace_node_eif;
318 static int hf_ipv6_opt_ioam_trace_node_tss;
319 static int hf_ipv6_opt_ioam_trace_node_tsf;
320 static int hf_ipv6_opt_ioam_trace_node_trdelay;
321 static int hf_ipv6_opt_ioam_trace_node_nsdata;
322 static int hf_ipv6_opt_ioam_trace_node_qdepth;
323 static int hf_ipv6_opt_ioam_trace_node_csum;
324 static int hf_ipv6_opt_ioam_trace_node_id_wide;
325 static int hf_ipv6_opt_ioam_trace_node_iif_wide;
326 static int hf_ipv6_opt_ioam_trace_node_eif_wide;
327 static int hf_ipv6_opt_ioam_trace_node_nsdata_wide;
328 static int hf_ipv6_opt_ioam_trace_node_bufoccup;
329 static int hf_ipv6_opt_ioam_trace_node_undefined;
330 static int hf_ipv6_opt_ioam_trace_node_oss_len;
331 static int hf_ipv6_opt_ioam_trace_node_oss_scid;
332 static int hf_ipv6_opt_ioam_trace_node_oss_data;
333 static int hf_ipv6_opt_ioam_dex_ns;
334 static int hf_ipv6_opt_ioam_dex_flags;
335 static int hf_ipv6_opt_ioam_dex_extflags;
336 static int hf_ipv6_opt_ioam_dex_extflag_flag_rsv;
337 static int hf_ipv6_opt_ioam_dex_extflag_flag_seqnum;
338 static int hf_ipv6_opt_ioam_dex_extflag_flag_flowid;
339 static int hf_ipv6_opt_ioam_dex_extflag_seqnum;
340 static int hf_ipv6_opt_ioam_dex_extflag_flowid;
341 static int hf_ipv6_opt_ioam_dex_rsv;
342 static int hf_ipv6_opt_tpf_information;
343 static int hf_ipv6_opt_mipv6_home_address;
344 static int hf_ipv6_opt_rpl_flag;
345 static int hf_ipv6_opt_rpl_flag_o;
346 static int hf_ipv6_opt_rpl_flag_r;
347 static int hf_ipv6_opt_rpl_flag_f;
348 static int hf_ipv6_opt_rpl_flag_rsv;
349 static int hf_ipv6_opt_rpl_instance_id;
350 static int hf_ipv6_opt_rpl_senderrank;
351 static int hf_ipv6_opt_ilnp_nonce;
352 static int hf_ipv6_opt_lio_len;
353 static int hf_ipv6_opt_lio_id;
354 static int hf_ipv6_opt_mpl_flag;
355 static int hf_ipv6_opt_mpl_flag_s;
356 static int hf_ipv6_opt_mpl_flag_m;
357 static int hf_ipv6_opt_mpl_flag_v;
358 static int hf_ipv6_opt_mpl_flag_rsv;
359 static int hf_ipv6_opt_mpl_sequence;
360 static int hf_ipv6_opt_mpl_seed_id;
361 static int hf_ipv6_opt_dff_flags;
362 static int hf_ipv6_opt_dff_flag_ver;
363 static int hf_ipv6_opt_dff_flag_dup;
364 static int hf_ipv6_opt_dff_flag_ret;
365 static int hf_ipv6_opt_dff_flag_rsv;
366 static int hf_ipv6_opt_dff_seqnum;
367 static int hf_ipv6_opt_experimental;
368 static int hf_ipv6_opt_unknown_data;
369 static int hf_ipv6_opt_unknown;
370 static int hf_ipv6_dstopts_nxt;
371 static int hf_ipv6_dstopts_len;
372 static int hf_ipv6_dstopts_len_oct;
373 static int hf_ipv6_hopopts_nxt;
374 static int hf_ipv6_hopopts_len;
375 static int hf_ipv6_hopopts_len_oct;
376 static int hf_ipv6_routing_nxt;
377 static int hf_ipv6_routing_len;
378 static int hf_ipv6_routing_len_oct;
379 static int hf_ipv6_routing_type;
380 static int hf_ipv6_routing_segleft;
381 static int hf_ipv6_routing_unknown_data;
382 static int hf_ipv6_fraghdr_nxt;
383 static int hf_ipv6_fraghdr_reserved_octet;
384 static int hf_ipv6_fraghdr_offset;
385 static int hf_ipv6_fraghdr_reserved_bits;
386 static int hf_ipv6_fraghdr_more;
387 static int hf_ipv6_fraghdr_ident;
388 static int hf_ipv6_fragment;
389 static int hf_ipv6_fragment_overlap;
390 static int hf_ipv6_fragment_overlap_conflict;
391 static int hf_ipv6_fragment_multiple_tails;
392 static int hf_ipv6_fragment_too_long_fragment;
393 static int hf_ipv6_fragment_error;
394 static int hf_ipv6_fragment_count;
395 static int hf_ipv6_fragments;
396 static int hf_ipv6_reassembled_in;
397 static int hf_ipv6_reassembled_length;
398 static int hf_ipv6_reassembled_data;
400 static int hf_ipv6_routing_src_reserved;
401 static int hf_ipv6_routing_src_addr;
403 static int hf_ipv6_routing_mipv6_reserved;
404 static int hf_ipv6_routing_mipv6_home_address;
406 static int hf_ipv6_routing_rpl_cmprI;
407 static int hf_ipv6_routing_rpl_cmprE;
408 static int hf_ipv6_routing_rpl_pad;
409 static int hf_ipv6_routing_rpl_reserved;
410 static int hf_ipv6_routing_rpl_addr_count;
411 static int hf_ipv6_routing_rpl_addr;
412 static int hf_ipv6_routing_rpl_fulladdr;
414 static int hf_ipv6_routing_srh_last_entry;
415 static int hf_ipv6_routing_srh_flags;
416 static int hf_ipv6_routing_srh_tag;
417 static int hf_ipv6_routing_srh_addr;
419 static int hf_ipv6_routing_crh16_current_sid;
420 static int hf_ipv6_routing_crh32_current_sid;
421 static int hf_ipv6_routing_crh16_segment_id;
422 static int hf_ipv6_routing_crh32_segment_id;
424 struct ipv6_addr_info_s {
425 int *hf_addr;
426 int *hf_addr_space;
427 int *hf_multicast_flags;
428 int *const *hf_multicast_flags_bits;
429 int *hf_multicast_scope;
430 int *hf_special_purpose;
431 int *hf_special_purpose_source;
432 int *hf_special_purpose_destination;
433 int *hf_special_purpose_forwardable;
434 int *hf_special_purpose_global;
435 int *hf_special_purpose_reserved;
436 int *hf_host;
439 static int *const ipv6_src_multicast_flags_bits[5] = {
440 &hf_ipv6_src_multicast_flags_reserved,
441 &hf_ipv6_src_multicast_flags_embed_rp,
442 &hf_ipv6_src_multicast_flags_network_prefix,
443 &hf_ipv6_src_multicast_flags_transient,
444 NULL
447 static struct ipv6_addr_info_s ipv6_src_info = {
448 &hf_ipv6_src,
449 &hf_ipv6_src_addr_space,
450 &hf_ipv6_src_multicast_flags,
451 ipv6_src_multicast_flags_bits,
452 &hf_ipv6_src_multicast_scope,
453 &hf_ipv6_src_special_purpose,
454 &hf_ipv6_src_special_purpose_source,
455 &hf_ipv6_src_special_purpose_destination,
456 &hf_ipv6_src_special_purpose_forwardable,
457 &hf_ipv6_src_special_purpose_global,
458 &hf_ipv6_src_special_purpose_reserved,
459 &hf_ipv6_src_host,
462 static int *const ipv6_dst_multicast_flags_bits[5] = {
463 &hf_ipv6_dst_multicast_flags_reserved,
464 &hf_ipv6_dst_multicast_flags_embed_rp,
465 &hf_ipv6_dst_multicast_flags_network_prefix,
466 &hf_ipv6_dst_multicast_flags_transient,
467 NULL
470 static struct ipv6_addr_info_s ipv6_dst_info = {
471 &hf_ipv6_dst,
472 &hf_ipv6_dst_addr_space,
473 &hf_ipv6_dst_multicast_flags,
474 ipv6_dst_multicast_flags_bits,
475 &hf_ipv6_dst_multicast_scope,
476 &hf_ipv6_dst_special_purpose,
477 &hf_ipv6_dst_special_purpose_source,
478 &hf_ipv6_dst_special_purpose_destination,
479 &hf_ipv6_dst_special_purpose_forwardable,
480 &hf_ipv6_dst_special_purpose_global,
481 &hf_ipv6_dst_special_purpose_reserved,
482 &hf_ipv6_dst_host,
485 static int hf_geoip_country;
486 static int hf_geoip_country_iso;
487 static int hf_geoip_city;
488 static int hf_geoip_as_number;
489 static int hf_geoip_as_org;
490 static int hf_geoip_latitude;
491 static int hf_geoip_longitude;
492 static int hf_geoip_src_summary;
493 static int hf_geoip_src_country;
494 static int hf_geoip_src_country_iso;
495 static int hf_geoip_src_city;
496 static int hf_geoip_src_as_number;
497 static int hf_geoip_src_as_org;
498 static int hf_geoip_src_latitude;
499 static int hf_geoip_src_longitude;
500 static int hf_geoip_dst_summary;
501 static int hf_geoip_dst_country;
502 static int hf_geoip_dst_country_iso;
503 static int hf_geoip_dst_city;
504 static int hf_geoip_dst_as_number;
505 static int hf_geoip_dst_as_org;
506 static int hf_geoip_dst_latitude;
507 static int hf_geoip_dst_longitude;
509 static int ett_ipv6_proto;
510 static int ett_ipv6_detail;
511 static int ett_ipv6_detail_special_purpose;
512 static int ett_ipv6_multicast_flags;
513 static int ett_ipv6_traffic_class;
514 static int ett_ipv6_opt;
515 static int ett_ipv6_opt_type;
516 static int ett_ipv6_opt_rpl;
517 static int ett_ipv6_opt_mpl;
518 static int ett_ipv6_opt_dff_flags;
519 static int ett_ipv6_opt_ioam_trace_flags;
520 static int ett_ipv6_opt_ioam_trace_types;
521 static int ett_ipv6_opt_ioam_dex_extflags;
522 static int ett_ipv6_hopopts_proto;
523 static int ett_ipv6_fraghdr_proto;
524 static int ett_ipv6_routing_proto;
525 static int ett_ipv6_routing_srh_vect;
526 static int ett_ipv6_fragments;
527 static int ett_ipv6_fragment;
528 static int ett_ipv6_dstopts_proto;
530 static int ett_geoip_info;
532 static uint32_t ipv6_stream_count;
534 static expert_field ei_ipv6_routing_invalid_length;
535 static expert_field ei_ipv6_routing_invalid_segleft;
536 static expert_field ei_ipv6_routing_undecoded;
537 static expert_field ei_ipv6_dst_addr_not_unspecified;
538 static expert_field ei_ipv6_src_addr_not_multicast;
539 static expert_field ei_ipv6_dst_addr_not_multicast;
540 static expert_field ei_ipv6_src_route_list_mult_inst_same_addr;
541 static expert_field ei_ipv6_src_route_list_src_addr;
542 static expert_field ei_ipv6_src_route_list_dst_addr;
543 static expert_field ei_ipv6_src_route_list_multicast_addr;
544 static expert_field ei_ipv6_routing_rpl_cmpri_cmpre_pad;
545 static expert_field ei_ipv6_routing_rpl_addr_count_ge0;
546 static expert_field ei_ipv6_routing_rpl_reserved;
547 static expert_field ei_ipv6_routing_deprecated;
548 static expert_field ei_ipv6_opt_jumbo_missing;
549 static expert_field ei_ipv6_opt_jumbo_prohibited;
550 static expert_field ei_ipv6_opt_jumbo_truncated;
551 static expert_field ei_ipv6_opt_jumbo_fragment;
552 static expert_field ei_ipv6_opt_invalid_len;
553 static expert_field ei_ipv6_opt_apn_invalid_id_type;
554 static expert_field ei_ipv6_opt_unknown_data;
555 static expert_field ei_ipv6_opt_deprecated;
556 static expert_field ei_ipv6_opt_mpl_ipv6_src_seed_id;
557 static expert_field ei_ipv6_hopopts_not_first;
558 static expert_field ei_ipv6_plen_exceeds_framing;
559 static expert_field ei_ipv6_plen_zero;
560 static expert_field ei_ipv6_bogus_ipv6_version;
561 static expert_field ei_ipv6_invalid_header;
562 static expert_field ei_ipv6_opt_header_mismatch;
563 static expert_field ei_ipv6_opt_ioam_invalid_nodelen;
564 static expert_field ei_ipv6_opt_ioam_invalid_remlen;
565 static expert_field ei_ipv6_opt_ioam_invalid_trace_type;
566 static expert_field ei_ipv6_embed_ipv4_u_value;
568 static dissector_handle_t ipv6_handle;
570 /* Reassemble fragmented datagrams */
571 static bool ipv6_reassemble = true;
573 /* Place IPv6 summary in proto tree */
574 static bool ipv6_summary_in_tree = true;
576 /* Show expanded information about IPv6 address */
577 static bool ipv6_address_detail = true;
579 /* Perform strict RFC adherence checking */
580 static bool g_ipv6_rpl_srh_strict_rfc_checking;
582 /* Use heuristics to determine subdissector */
583 static bool try_heuristic_first;
585 /* Display IPv6 extension headers under the root tree */
586 static bool ipv6_exthdr_under_root;
588 /* Hide extension header generated field for length */
589 static bool ipv6_exthdr_hide_len_oct_field;
591 /* Assume TSO and correct zero-length IP packets */
592 static bool ipv6_tso_supported;
594 /* Assign unique ID numbers to each IPv6 conversation. This increases
595 * resource US because of having to lookup and create conversations
596 * (which aren't otherwise needed.)
598 static bool ipv6_track_conv_id = true;
600 #define set_address_ipv6(dst, src_ip6) \
601 set_address((dst), AT_IPv6, IPv6_ADDR_SIZE, (src_ip6))
603 #define set_address_ipv6_tvb(dst, tvb, offset) \
604 set_address_tvb((dst), AT_IPv6, IPv6_ADDR_SIZE, (tvb), (offset))
606 #define alloc_address_wmem_ipv6(scope, dst, src_ip6) \
607 alloc_address_wmem((scope), (dst), AT_IPv6, IPv6_ADDR_SIZE, (src_ip6))
609 #define alloc_address_tvb_ipv6(scope, dst, tvb, offset) \
610 alloc_address_tvb((scope), (dst), AT_IPv6, IPv6_ADDR_SIZE, (tvb), (offset))
612 extern const ws_in6_addr *tvb_get_ptr_ipv6(tvbuff_t tvb, int offset);
613 #define tvb_get_ptr_ipv6(tvb, offset) \
614 ((const ws_in6_addr *)tvb_get_ptr(tvb, offset, IPv6_ADDR_SIZE))
616 ipv6_pinfo_t *p_get_ipv6_pinfo(packet_info *pinfo)
618 return (ipv6_pinfo_t *)p_get_proto_data(pinfo->pool, pinfo, proto_ipv6, IPV6_PROTO_PINFO);
621 /* Return tree pointer (for tree root preference) */
622 proto_tree *p_ipv6_pinfo_select_root(packet_info *pinfo, proto_tree *tree)
624 ipv6_pinfo_t *p;
626 if ((p = p_get_ipv6_pinfo(pinfo)) != NULL && p->ipv6_tree != NULL)
627 return p->ipv6_tree;
628 return tree;
631 ipv6_pinfo_t *p_ipv6_pinfo_add_len(packet_info *pinfo, int exthdr_len)
633 ipv6_pinfo_t *p;
635 if ((p = p_get_ipv6_pinfo(pinfo)) == NULL)
636 return NULL;
638 p->frag_plen -= exthdr_len;
639 p->ipv6_item_len += exthdr_len;
640 return p;
643 static void p_add_ipv6_nxt(packet_info *pinfo, uint8_t nxt)
645 uint8_t *ptr;
647 ptr = (uint8_t *)wmem_memdup(pinfo->pool, &nxt, sizeof(uint8_t));
648 p_add_proto_data(pinfo->pool, pinfo, proto_ipv6,
649 (pinfo->curr_layer_num<<8) | IPV6_PROTO_VALUE, ptr);
652 static uint8_t *p_get_ipv6_nxt(packet_info *pinfo)
654 return (uint8_t *)p_get_proto_data(pinfo->pool, pinfo, proto_ipv6,
655 (pinfo->curr_layer_num<<8) | IPV6_PROTO_VALUE);
658 static void *ipv6_value(packet_info *pinfo)
660 uint8_t *nxt = p_get_ipv6_nxt(pinfo);
662 if (nxt == NULL) {
663 return GUINT_TO_POINTER(255); /* Reserved IP Protocol */
665 return GUINT_TO_POINTER((unsigned)*nxt);
668 static void ipv6_prompt(packet_info *pinfo, char *result)
670 void *value = ipv6_value(pinfo);
672 snprintf(result, MAX_DECODE_AS_PROMPT_LEN, "IP protocol %u as", GPOINTER_TO_UINT(value));
675 static const char* ipv6_conv_get_filter_type(conv_item_t* conv, conv_filter_type_e filter)
677 if ((filter == CONV_FT_SRC_ADDRESS) && (conv->src_address.type == AT_IPv6))
678 return "ipv6.src";
680 if ((filter == CONV_FT_DST_ADDRESS) && (conv->dst_address.type == AT_IPv6))
681 return "ipv6.dst";
683 if ((filter == CONV_FT_ANY_ADDRESS) && (conv->src_address.type == AT_IPv6))
684 return "ipv6.addr";
686 return CONV_FILTER_INVALID;
689 static ct_dissector_info_t ipv6_ct_dissector_info = {&ipv6_conv_get_filter_type};
691 static tap_packet_status
692 ipv6_conversation_packet(void *pct, packet_info *pinfo, epan_dissect_t *edt _U_, const void *vip, tap_flags_t flags)
694 conv_hash_t *hash = (conv_hash_t*) pct;
695 hash->flags = flags;
697 const ipv6_tap_info_t *ip6 = (const ipv6_tap_info_t *)vip;
699 if (!ipv6_track_conv_id) {
700 add_conversation_table_data(hash, &ip6->ip6_src, &ip6->ip6_dst, 0, 0,
701 1, pinfo->fd->pkt_len, &pinfo->rel_ts, &pinfo->abs_ts,
702 &ipv6_ct_dissector_info, CONVERSATION_IPV6);
703 } else {
704 add_conversation_table_data_with_conv_id(hash, &ip6->ip6_src, &ip6->ip6_dst, 0, 0,
705 (conv_id_t)ip6->ip6_stream, 1, pinfo->fd->pkt_len,
706 &pinfo->rel_ts, &pinfo->abs_ts, &ipv6_ct_dissector_info, CONVERSATION_IPV6);
709 return TAP_PACKET_REDRAW;
712 static const char* ipv6_endpoint_get_filter_type(endpoint_item_t* endpoint, conv_filter_type_e filter)
714 if ((filter == CONV_FT_ANY_ADDRESS) && (endpoint->myaddress.type == AT_IPv6))
715 return "ipv6.addr";
717 return CONV_FILTER_INVALID;
720 static et_dissector_info_t ipv6_endpoint_dissector_info = {&ipv6_endpoint_get_filter_type};
722 static tap_packet_status
723 ipv6_endpoint_packet(void *pit, packet_info *pinfo, epan_dissect_t *edt _U_, const void *vip, tap_flags_t flags)
725 conv_hash_t *hash = (conv_hash_t*) pit;
726 hash->flags = flags;
728 const ipv6_tap_info_t *ip6 = (const ipv6_tap_info_t *)vip;
730 add_endpoint_table_data(hash, &ip6->ip6_src, 0, true, 1,
731 pinfo->fd->pkt_len, &ipv6_endpoint_dissector_info, ENDPOINT_NONE);
732 add_endpoint_table_data(hash, &ip6->ip6_dst, 0, false, 1,
733 pinfo->fd->pkt_len, &ipv6_endpoint_dissector_info, ENDPOINT_NONE);
735 return TAP_PACKET_REDRAW;
738 static bool
739 ipv6_filter_valid(packet_info *pinfo, void *user_data _U_)
741 return proto_is_frame_protocol(pinfo->layers, "ipv6");
744 static char*
745 ipv6_build_filter(packet_info *pinfo, void *user_data _U_)
747 return ws_strdup_printf("ipv6.addr eq %s and ipv6.addr eq %s",
748 address_to_str(pinfo->pool, &pinfo->net_src),
749 address_to_str(pinfo->pool, &pinfo->net_dst));
753 /* UAT for providing a list of NAT64 prefixes */
755 struct nat64_prefix_data {
756 char *ipaddr;
757 uint8_t prefix_len;
758 uint32_t prefix_wildcard_len;
762 static uat_t *nat64_prefix_uat;
763 static struct nat64_prefix_data *nat64_prefix_uats;
764 static unsigned number_of_nat64_prefix;
767 UAT_CSTRING_CB_DEF(nat64_prefix_uats, ipaddr, struct nat64_prefix_data)
769 static bool
770 nat64_prefix_uat_fld_ip_chk_cb(void *r _U_, const char *ipaddr, unsigned len _U_, const void *u1 _U_, const void *u2 _U_, char **err)
772 /* Check for a valid IPv6 address */
773 ws_in6_addr addr;
775 if (ws_inet_pton6(ipaddr, &addr)) {
776 *err = NULL;
777 return true;
780 *err = ws_strdup_printf("No valid IPv6 address given.");
781 return false;
784 static const value_string nat64_prefix_length_vals[] =
786 { 32, "32" },
787 { 40, "40" },
788 { 48, "48" },
789 { 56, "56" },
790 { 64, "64" },
791 { 96, "96" },
792 { 0, NULL }
795 UAT_VS_DEF(nat64_prefix_uats, prefix_len, struct nat64_prefix_data, uint8_t, 96, "96")
797 static const value_string nat64_prefix_wildcard_length_vals[] =
799 { 0, "0" },
800 { 8, "8" },
801 { 16, "16" },
802 { 32, "32" },
803 { 64, "64" },
804 { 0, NULL }
807 UAT_VS_DEF(nat64_prefix_uats, prefix_wildcard_len, struct nat64_prefix_data, uint8_t, 0, "0")
810 static void
811 nat64_prefix_free_cb(void *data)
813 struct nat64_prefix_data *h = (struct nat64_prefix_data *)data;
815 g_free(h->ipaddr);
818 static void *
819 nat64_prefix_copy_cb(void *dst_, const void *src_, size_t len _U_)
821 const struct nat64_prefix_data *src = (const struct nat64_prefix_data *)src_;
822 struct nat64_prefix_data *dst = (struct nat64_prefix_data *)dst_;
824 dst->ipaddr = g_strdup(src->ipaddr);
825 dst->prefix_len = src->prefix_len;
826 dst->prefix_wildcard_len = src->prefix_wildcard_len;
828 return dst;
832 static int
833 ipv6_previous_layer_id(packet_info *pinfo)
835 wmem_list_frame_t *layer;
837 layer = wmem_list_tail(pinfo->layers);
838 DISSECTOR_ASSERT(layer);
839 layer = wmem_list_frame_prev(layer);
840 if (layer != NULL) {
841 return GPOINTER_TO_INT(wmem_list_frame_data(layer));
843 return -1;
846 static const fragment_items ipv6_frag_items = {
847 &ett_ipv6_fragment,
848 &ett_ipv6_fragments,
849 &hf_ipv6_fragments,
850 &hf_ipv6_fragment,
851 &hf_ipv6_fragment_overlap,
852 &hf_ipv6_fragment_overlap_conflict,
853 &hf_ipv6_fragment_multiple_tails,
854 &hf_ipv6_fragment_too_long_fragment,
855 &hf_ipv6_fragment_error,
856 &hf_ipv6_fragment_count,
857 &hf_ipv6_reassembled_in,
858 &hf_ipv6_reassembled_length,
859 &hf_ipv6_reassembled_data,
860 "IPv6 fragments"
863 static dissector_table_t ip_dissector_table;
864 static dissector_table_t ipv6_routing_dissector_table;
867 * defragmentation of IPv6
869 static reassembly_table ipv6_reassembly_table;
871 /* http://www.iana.org/assignments/ipv6-parameters (last updated 2015-07-07) */
872 static const value_string ipv6_opt_type_vals[] = {
873 { IP6OPT_PAD1, "Pad1" },
874 { IP6OPT_PADN, "PadN" },
875 { IP6OPT_TEL, "Tunnel Encapsulation Limit" },
876 { IP6OPT_RTALERT, "Router Alert" },
877 { IP6OPT_CALIPSO, "CALIPSO" },
878 { IP6OPT_SMF_DPD, "SMF_DPD" },
879 { IP6OPT_PDM, "Performance and Diagnostic Metrics" },
880 { IP6OPT_APN6, "Application-Aware IPv6 Networking (APN6)" },
881 { IP6OPT_EXP_1E, "Experimental (0x1E)" },
882 { IP6OPT_RPL, "RPL Option" },
883 { IP6OPT_QUICKSTART, "Quick-Start" },
884 { IP6OPT_PMTU, "Path MTU Option" },
885 { IP6OPT_IOAM, "IOAM Option" },
886 { IP6OPT_EXP_3E, "Experimental (0x3E)" },
887 { IP6OPT_TPF, "Tunnel Payload Forwarding (TPF) Information" },
888 { IP6OPT_EXP_5E, "Experimental (0x5E)" },
889 { IP6OPT_RPL_OLD, "RPL Option (deprecated)" },
890 { IP6OPT_MPL, "MPL Option" },
891 { IP6OPT_EXP_7E, "Experimental (0x7E)" },
892 { IP6OPT_ENDI, "Endpoint Identification" },
893 { IP6OPT_ILNP_NONCE, "ILNP Nonce" },
894 { IP6OPT_LIO, "Line-Identification Option" },
895 { IP6OPT_EXP_9E, "Experimental (0x9E)" },
896 { IP6OPT_EXP_BE, "Experimental (0xBE)" },
897 { IP6OPT_JUMBO, "Jumbo Payload" },
898 { IP6OPT_HOME_ADDRESS, "Home Address" },
899 { IP6OPT_EXP_DE, "Experimental (0xDE)" },
900 { IP6OPT_IP_DFF, "IP_DFF" },
901 { IP6OPT_EXP_FE, "Experimental (0xFE)" },
902 { 0, NULL }
904 static value_string_ext ipv6_opt_type_vals_ext = VALUE_STRING_EXT_INIT(ipv6_opt_type_vals);
906 static const value_string ipv6_opt_rtalert_vals[] = {
907 { IP6OPT_RTALERT_MLD, "MLD" },
908 { IP6OPT_RTALERT_RSVP, "RSVP" },
909 { IP6OPT_RTALERT_ACTNET, "Active Network" },
910 { 0, NULL }
913 enum {
914 IP6OPT_SMF_DPD_NULL = 0,
915 IP6OPT_SMF_DPD_DFLT,
916 IP6OPT_SMF_DPD_IPv4,
917 IP6OPT_SMF_DPD_IPv6
920 static const value_string ipv6_opt_smf_dpd_tidty_vals[] = {
921 { IP6OPT_SMF_DPD_NULL, "NULL" },
922 { IP6OPT_SMF_DPD_DFLT, "DEFAULT" },
923 { IP6OPT_SMF_DPD_IPv4, "IPv4" },
924 { IP6OPT_SMF_DPD_IPv6, "IPv6" },
925 { 0, NULL }
928 enum {
929 IPv6_OPT_ACTION_SKIP = 0,
930 IPv6_OPT_ACTION_DISC,
931 IPv6_OPT_ACTION_ICMP,
932 IPv6_OPT_ACTION_MCST,
935 static const value_string ipv6_opt_type_action_vals[] = {
936 { IPv6_OPT_ACTION_SKIP, "Skip and continue" },
937 { IPv6_OPT_ACTION_DISC, "Discard" },
938 { IPv6_OPT_ACTION_ICMP, "Discard and send ICMP Parameter Problem" },
939 { IPv6_OPT_ACTION_MCST, "Discard and send ICMP if not multicast" },
940 { 0, NULL }
943 enum {
944 IPv6_OPT_HDR_HBH = 0,
945 IPv6_OPT_HDR_DST,
946 IPv6_OPT_HDR_ANY
949 static const int _ipv6_opt_type_hdr[][2] = {
950 { IP6OPT_TEL, IPv6_OPT_HDR_DST },
951 { IP6OPT_RTALERT, IPv6_OPT_HDR_HBH },
952 { IP6OPT_PMTU, IPv6_OPT_HDR_HBH },
953 { IP6OPT_APN6, IPv6_OPT_HDR_ANY },
954 { IP6OPT_CALIPSO, IPv6_OPT_HDR_HBH },
955 { IP6OPT_SMF_DPD, IPv6_OPT_HDR_HBH },
956 { IP6OPT_PDM, IPv6_OPT_HDR_DST },
957 { IP6OPT_RPL, IPv6_OPT_HDR_HBH },
958 { IP6OPT_QUICKSTART, IPv6_OPT_HDR_HBH },
959 { IP6OPT_IOAM, IPv6_OPT_HDR_HBH },
960 { IP6OPT_TPF, IPv6_OPT_HDR_DST },
961 { IP6OPT_RPL_OLD, IPv6_OPT_HDR_HBH },
962 { IP6OPT_MPL, IPv6_OPT_HDR_HBH },
963 { IP6OPT_ILNP_NONCE, IPv6_OPT_HDR_DST },
964 { IP6OPT_LIO, IPv6_OPT_HDR_DST },
965 { IP6OPT_JUMBO, IPv6_OPT_HDR_HBH },
966 { IP6OPT_HOME_ADDRESS, IPv6_OPT_HDR_DST },
967 { IP6OPT_IP_DFF, IPv6_OPT_HDR_HBH },
968 { 0, IPv6_OPT_HDR_ANY }
971 static inline int
972 ipv6_opt_type_hdr(int type)
974 static const int (*p)[2] = _ipv6_opt_type_hdr;
976 for (; (*p)[1] != IPv6_OPT_HDR_ANY; p++) {
977 if ((*p)[0] == type) {
978 return (*p)[1];
981 return IPv6_OPT_HDR_ANY;
984 enum {
985 IPv6_RT_HEADER_SOURCE_ROUTING = 0, /* DEPRECATED */
986 IPv6_RT_HEADER_NIMROD = 1, /* DEPRECATED */
987 IPv6_RT_HEADER_MOBILE_IP = 2,
988 IPv6_RT_HEADER_RPL = 3,
989 IPv6_RT_HEADER_SEGMENT_ROUTING = 4,
990 IPv6_RT_HEADER_COMPACT_16 = 5,
991 IPv6_RT_HEADER_COMPACT_32 = 6,
992 IPv6_RT_HEADER_EXP1 = 253,
993 IPv6_RT_HEADER_EXP2 = 254
996 /* Routing Header Types */
997 static const value_string routing_header_type[] = {
998 { IPv6_RT_HEADER_SOURCE_ROUTING, "Source Route" },
999 { IPv6_RT_HEADER_NIMROD, "Nimrod" },
1000 { IPv6_RT_HEADER_MOBILE_IP, "Type 2 Routing" },
1001 { IPv6_RT_HEADER_RPL, "RPL Source Route" },
1002 { IPv6_RT_HEADER_SEGMENT_ROUTING, "Segment Routing" },
1003 { IPv6_RT_HEADER_COMPACT_16, "Compact Routing Header 16" },
1004 { IPv6_RT_HEADER_COMPACT_32, "Compact Routing Header 32" },
1005 { IPv6_RT_HEADER_EXP1, "Experiment 1" },
1006 { IPv6_RT_HEADER_EXP2, "Experiment 2" },
1007 { 0, NULL }
1010 static const value_string mpl_seed_id_len_vals[] = {
1011 { 0, "0" },
1012 { 1, "16-bit unsigned integer" },
1013 { 2, "64-bit unsigned integer" },
1014 { 3, "128-bit unsigned integer" },
1015 { 0, NULL }
1018 static const value_string ipv6_multicast_scope_vals[] = {
1019 { 0x0, "Reserved" },
1020 { 0x1, "Interface-Local scope" },
1021 { 0x2, "Link-Local scope" },
1022 { 0x3, "Realm-Local scope" },
1023 { 0x4, "Admin-Local scope" },
1024 { 0x5, "Site-Local scope" },
1025 { 0x6, "Unassigned" },
1026 { 0x7, "Unassigned" },
1027 { 0x8, "Organization-Local scope" },
1028 { 0x9, "Unassigned" },
1029 { 0xA, "Unassigned" },
1030 { 0xB, "Unassigned" },
1031 { 0xC, "Unassigned" },
1032 { 0xD, "Unassigned" },
1033 { 0xE, "Global scope" },
1034 { 0xF, "Reserved" },
1035 { 0, NULL }
1038 #define APN_ID_32BIT 1
1039 #define APN_ID_64BIT 2
1040 #define APN_ID_128BIT 3
1041 static const value_string apn_id_type_strs[] = {
1042 { 0, "Invalid" },
1043 { APN_ID_32BIT, "32-bit" },
1044 { APN_ID_64BIT, "64-bit" },
1045 { APN_ID_128BIT, "128-bit" },
1046 { 0, NULL }
1049 static bool
1050 capture_ipv6(const unsigned char *pd, int offset, int len, capture_packet_info_t *cpinfo, const union wtap_pseudo_header *pseudo_header)
1052 uint8_t nxt;
1054 if (!BYTES_ARE_IN_FRAME(offset, len, IPv6_HDR_SIZE))
1055 return false;
1057 capture_dissector_increment_count(cpinfo, proto_ipv6);
1059 nxt = pd[offset+6]; /* get the "next header" value */
1060 offset += IPv6_HDR_SIZE; /* skip past the IPv6 header */
1062 return try_capture_dissector("ip.proto", nxt, pd, offset, len, cpinfo, pseudo_header);
1065 static bool
1066 capture_ipv6_exthdr(const unsigned char *pd, int offset, int len, capture_packet_info_t *cpinfo, const union wtap_pseudo_header *pseudo_header)
1068 uint8_t nxt;
1069 int advance;
1071 if (!BYTES_ARE_IN_FRAME(offset, len, 2))
1072 return false;
1073 nxt = pd[offset];
1074 switch (nxt) {
1075 case IP_PROTO_FRAGMENT:
1076 advance = IPv6_FRAGMENT_HDR_SIZE;
1077 break;
1078 default:
1079 advance = (pd[offset+1] + 1) << 3;
1080 break;
1082 if (!BYTES_ARE_IN_FRAME(offset, len, advance))
1083 return false;
1084 offset += advance;
1086 return try_capture_dissector("ip.proto", nxt, pd, offset, len, cpinfo, pseudo_header);
1089 static void
1090 add_geoip_info_entry(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, int offset, const ws_in6_addr *ip6, bool isdst)
1092 const mmdb_lookup_t *lookup = maxmind_db_lookup_ipv6(ip6);
1093 if (!lookup->found) return;
1095 wmem_strbuf_t *summary = wmem_strbuf_new(pinfo->pool, "");
1096 if (lookup->city) {
1097 wmem_strbuf_append(summary, lookup->city);
1099 if (lookup->country_iso) {
1100 if (wmem_strbuf_get_len(summary) > 0) wmem_strbuf_append(summary, ", ");
1101 wmem_strbuf_append(summary, lookup->country_iso);
1102 } else if (lookup->country) {
1103 if (wmem_strbuf_get_len(summary) > 0) wmem_strbuf_append(summary, ", ");
1104 wmem_strbuf_append(summary, lookup->country);
1106 if (lookup->as_number > 0) {
1107 if (wmem_strbuf_get_len(summary) > 0) wmem_strbuf_append(summary, ", ");
1108 wmem_strbuf_append_printf(summary, "ASN %u", lookup->as_number);
1110 if (lookup->as_org) {
1111 if (wmem_strbuf_get_len(summary) > 0) wmem_strbuf_append(summary, ", ");
1112 wmem_strbuf_append(summary, lookup->as_org);
1115 int addr_offset = offset + (isdst ? IP6H_DST : IP6H_SRC);
1116 int dir_hf = isdst ? hf_geoip_dst_summary : hf_geoip_src_summary;
1117 proto_item *geoip_info_item = proto_tree_add_string(tree, dir_hf, tvb, addr_offset, 16, wmem_strbuf_finalize(summary));
1118 proto_item_set_generated(geoip_info_item);
1119 proto_tree *geoip_info_tree = proto_item_add_subtree(geoip_info_item, ett_geoip_info);
1121 proto_item *item;
1123 if (lookup->city) {
1124 dir_hf = isdst ? hf_geoip_dst_city : hf_geoip_src_city;
1125 item = proto_tree_add_string(geoip_info_tree, dir_hf, tvb, addr_offset, 16, lookup->city);
1126 proto_item_set_generated(item);
1127 item = proto_tree_add_string(geoip_info_tree, hf_geoip_city, tvb, addr_offset, 16, lookup->city);
1128 proto_item_set_generated(item);
1131 if (lookup->country) {
1132 dir_hf = isdst ? hf_geoip_dst_country : hf_geoip_src_country;
1133 item = proto_tree_add_string(geoip_info_tree, dir_hf, tvb, addr_offset, 16, lookup->country);
1134 proto_item_set_generated(item);
1135 item = proto_tree_add_string(geoip_info_tree, hf_geoip_country, tvb, addr_offset, 16, lookup->country);
1136 proto_item_set_generated(item);
1139 if (lookup->country_iso) {
1140 dir_hf = isdst ? hf_geoip_dst_country_iso : hf_geoip_src_country_iso;
1141 item = proto_tree_add_string(geoip_info_tree, dir_hf, tvb, addr_offset, 16, lookup->country_iso);
1142 proto_item_set_generated(item);
1143 item = proto_tree_add_string(geoip_info_tree, hf_geoip_country_iso, tvb, addr_offset, 16, lookup->country_iso);
1144 proto_item_set_generated(item);
1147 if (lookup->as_number > 0) {
1148 dir_hf = isdst ? hf_geoip_dst_as_number : hf_geoip_src_as_number;
1149 item = proto_tree_add_uint(geoip_info_tree, dir_hf, tvb, addr_offset, 16, lookup->as_number);
1150 proto_item_set_generated(item);
1151 item = proto_tree_add_uint(geoip_info_tree, hf_geoip_as_number, tvb, addr_offset, 16, lookup->as_number);
1152 proto_item_set_generated(item);
1155 if (lookup->as_org) {
1156 dir_hf = isdst ? hf_geoip_dst_as_org : hf_geoip_src_as_org;
1157 item = proto_tree_add_string(geoip_info_tree, dir_hf, tvb, addr_offset, 16, lookup->as_org);
1158 proto_item_set_generated(item);
1159 item = proto_tree_add_string(geoip_info_tree, hf_geoip_as_org, tvb, addr_offset, 16, lookup->as_org);
1160 proto_item_set_generated(item);
1163 if (lookup->latitude >= -90.0 && lookup->latitude <= 90.0) {
1164 dir_hf = isdst ? hf_geoip_dst_latitude : hf_geoip_src_latitude;
1165 item = proto_tree_add_double(geoip_info_tree, dir_hf, tvb, addr_offset, 16, lookup->latitude);
1166 proto_item_set_generated(item);
1167 item = proto_tree_add_double(geoip_info_tree, hf_geoip_latitude, tvb, addr_offset, 16, lookup->latitude);
1168 proto_item_set_generated(item);
1171 if (lookup->longitude >= -180.0 && lookup->longitude <= 180.0) {
1172 dir_hf = isdst ? hf_geoip_dst_longitude : hf_geoip_src_longitude;
1173 item = proto_tree_add_double(geoip_info_tree, dir_hf, tvb, addr_offset, 16, lookup->longitude);
1174 proto_item_set_generated(item);
1175 item = proto_tree_add_double(geoip_info_tree, hf_geoip_longitude, tvb, addr_offset, 16, lookup->longitude);
1176 proto_item_set_generated(item);
1180 static void
1181 add_geoip_info(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, int offset, const ws_in6_addr *src, const ws_in6_addr *dst)
1183 add_geoip_info_entry(tree, pinfo, tvb, offset, src, false);
1184 add_geoip_info_entry(tree, pinfo, tvb, offset, dst, true);
1187 /* Returns true if reassembled */
1188 static bool
1189 ipv6_reassemble_do(tvbuff_t **tvb_ptr, int *offset_ptr, packet_info *pinfo, proto_tree *ipv6_tree,
1190 uint32_t plen, uint16_t frag_off, bool frag_flg, uint32_t frag_ident,
1191 bool *show_data_ptr)
1193 fragment_head *ipfd_head;
1194 tvbuff_t *next_tvb;
1195 bool update_col_info = true;
1197 pinfo->fragmented = true;
1198 *show_data_ptr = true;
1199 if (!ipv6_reassemble) {
1200 /* not reassembling */
1201 if (frag_off == 0) {
1202 /* first fragment */
1203 *show_data_ptr = false;
1205 return false;
1208 /* reassembling */
1209 if (tvb_bytes_exist(*tvb_ptr, *offset_ptr, plen)) {
1210 ipfd_head = fragment_add_check(&ipv6_reassembly_table,
1211 *tvb_ptr, *offset_ptr, pinfo, frag_ident, NULL,
1212 frag_off, plen, frag_flg);
1213 next_tvb = process_reassembled_data(*tvb_ptr, *offset_ptr, pinfo, "Reassembled IPv6",
1214 ipfd_head, &ipv6_frag_items, &update_col_info, ipv6_tree);
1215 if (next_tvb) {
1216 /* Process post-fragment headers after reassembly */
1217 *offset_ptr = 0;
1218 *tvb_ptr = next_tvb;
1219 pinfo->fragmented = false;
1220 *show_data_ptr = false;
1221 return true;
1224 return false;
1227 static proto_item *
1228 _proto_tree_add_ipv6_vector_address(proto_tree *tree, packet_info *pinfo, int hfindex, tvbuff_t *tvb, int start,
1229 int length, const ws_in6_addr *value_ptr, int idx)
1231 address addr;
1232 char *str;
1234 set_address_ipv6(&addr, value_ptr);
1235 str = address_with_resolution_to_str(pinfo->pool, &addr);
1236 return proto_tree_add_ipv6_format(tree, hfindex, tvb, start, length,
1237 value_ptr, "Address[%d]: %s", idx, str);
1240 /* IPv6 Source Routing Header (Type 0) */
1241 static int
1242 dissect_routing6_rt0(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
1244 struct ws_rthdr *rt = (struct ws_rthdr *)data;
1245 proto_item *ti;
1246 int offset = 0;
1247 int idx;
1248 int rt0_addr_count;
1249 const ws_in6_addr *addr = NULL;
1251 proto_tree_add_item(tree, hf_ipv6_routing_src_reserved, tvb, offset, 4, ENC_NA);
1252 offset += 4;
1254 if (rt->hdr.ip6r_len % 2 != 0) {
1255 expert_add_info_format(pinfo, rt->ti_len, &ei_ipv6_routing_invalid_length,
1256 "IPv6 Routing Header extension header length must not be odd");
1258 rt0_addr_count = rt->hdr.ip6r_len / 2;
1259 if (rt->hdr.ip6r_segleft > rt0_addr_count) {
1260 expert_add_info_format(pinfo, rt->ti_segleft, &ei_ipv6_routing_invalid_segleft,
1261 "IPv6 Type 0 Routing Header segments left field must not exceed address count (%u)", rt0_addr_count);
1264 for (idx = 1; idx <= rt0_addr_count; idx++) {
1265 addr = tvb_get_ptr_ipv6(tvb, offset);
1266 ti = _proto_tree_add_ipv6_vector_address(tree, pinfo, hf_ipv6_routing_src_addr, tvb,
1267 offset, IPv6_ADDR_SIZE, addr, idx);
1268 offset += IPv6_ADDR_SIZE;
1269 if (in6_addr_is_multicast(addr)) {
1270 expert_add_info(pinfo, ti, &ei_ipv6_src_route_list_multicast_addr);
1274 if (addr != NULL && pinfo->dst.type == AT_IPv6 && rt->hdr.ip6r_segleft > 0) {
1275 alloc_address_wmem_ipv6(pinfo->pool, &pinfo->dst, addr);
1278 expert_add_info(pinfo, rt->ti_type, &ei_ipv6_routing_deprecated);
1279 return tvb_captured_length(tvb);
1282 /* Mobile IPv6 Routing Header (Type 2) */
1283 static int
1284 dissect_routing6_mipv6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
1286 struct ws_rthdr *rt = (struct ws_rthdr *)data;
1287 proto_item *ti;
1288 int offset = 0;
1289 const ws_in6_addr *addr;
1291 proto_tree_add_item(tree, hf_ipv6_routing_mipv6_reserved, tvb, offset, 4, ENC_NA);
1292 offset += 4;
1294 if (rt->hdr.ip6r_len != 2) {
1295 expert_add_info_format(pinfo, rt->ti_len, &ei_ipv6_routing_invalid_length,
1296 "IPv6 Type 2 Routing Header extension header length must equal 2");
1298 if (rt->hdr.ip6r_segleft != 1) {
1299 expert_add_info_format(pinfo, rt->ti_segleft, &ei_ipv6_routing_invalid_segleft,
1300 "IPv6 Type 2 Routing Header segments left field must equal 1");
1303 addr = tvb_get_ptr_ipv6(tvb, offset);
1304 ti = _proto_tree_add_ipv6_vector_address(tree, pinfo, hf_ipv6_routing_mipv6_home_address, tvb,
1305 offset, IPv6_ADDR_SIZE, addr, 1);
1306 if (in6_addr_is_multicast(addr)) {
1307 expert_add_info(pinfo, ti, &ei_ipv6_src_route_list_multicast_addr);
1310 if (pinfo->dst.type == AT_IPv6 && rt->hdr.ip6r_segleft > 0) {
1311 alloc_address_wmem_ipv6(pinfo->pool, &pinfo->dst, addr);
1314 return tvb_captured_length(tvb);
1317 /* RPL Source Routing Header (Type 3) */
1318 static int
1319 dissect_routing6_rpl(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
1321 struct ws_rthdr *rt = (struct ws_rthdr *)data;
1322 proto_item *ti;
1323 int offset = 0;
1324 uint8_t cmprI, cmprE, cmprX, pad;
1325 uint32_t reserved;
1326 int idx;
1327 int rpl_addr_count;
1328 ws_in6_addr rpl_fulladdr;
1329 const ws_in6_addr *ip6_dst_addr, *ip6_src_addr;
1330 wmem_array_t *rpl_addr_vector = NULL;
1331 unsigned i;
1333 /* Must be IPv6 addresses */
1334 if ((pinfo->dst.type != AT_IPv6) || (pinfo->src.type != AT_IPv6))
1335 return 0;
1337 /* IPv6 destination address used for elided bytes */
1338 ip6_dst_addr = (const ws_in6_addr *)pinfo->dst.data;
1339 /* IPv6 source address used for strict checking */
1340 ip6_src_addr = (const ws_in6_addr *)pinfo->src.data;
1342 /* from RFC6554: Multicast addresses MUST NOT appear in the IPv6 Destination Address field */
1343 if (in6_addr_is_multicast(ip6_dst_addr)) {
1344 expert_add_info(pinfo, proto_tree_get_parent(tree), &ei_ipv6_dst_addr_not_multicast);
1347 proto_tree_add_item(tree, hf_ipv6_routing_rpl_cmprI, tvb, offset, 4, ENC_BIG_ENDIAN);
1348 proto_tree_add_item(tree, hf_ipv6_routing_rpl_cmprE, tvb, offset, 4, ENC_BIG_ENDIAN);
1349 ti = proto_tree_add_item(tree, hf_ipv6_routing_rpl_pad, tvb, offset, 4, ENC_BIG_ENDIAN);
1351 cmprI = tvb_get_uint8(tvb, offset) & 0xF0;
1352 cmprE = tvb_get_uint8(tvb, offset) & 0x0F;
1353 pad = tvb_get_uint8(tvb, offset + 1) & 0xF0;
1355 /* Shift bytes over */
1356 cmprI >>= 4;
1357 pad >>= 4;
1359 /* from RFC6554: when CmprI and CmprE are both 0, Pad MUST carry a value of 0 */
1360 if (cmprI == 0 && cmprE == 0 && pad != 0) {
1361 expert_add_info_format(pinfo, ti, &ei_ipv6_routing_rpl_cmpri_cmpre_pad, "When cmprI equals 0 and cmprE equals 0, pad MUST equal 0 but instead was %d", pad);
1364 ti = proto_tree_add_item(tree, hf_ipv6_routing_rpl_reserved, tvb, offset, 4, ENC_BIG_ENDIAN);
1365 reserved = tvb_get_bits32(tvb, ((offset + 1) * 8) + 4, 20, ENC_BIG_ENDIAN);
1367 if (reserved != 0) {
1368 expert_add_info_format(pinfo, ti, &ei_ipv6_routing_rpl_reserved, "Reserved field must equal 0 but instead was %d", reserved);
1371 /* From RFC6554:
1372 * n = (((Hdr Ext Len * 8) - Pad - (16 - CmprE)) / (16 - CmprI)) + 1
1374 rpl_addr_count = 0;
1375 if (rt->hdr.ip6r_len > 0) {
1376 rpl_addr_count = (((rt->hdr.ip6r_len * 8) - pad - (16 - cmprE)) / (16 - cmprI)) + 1;
1378 ti = proto_tree_add_int(tree, hf_ipv6_routing_rpl_addr_count, tvb, offset, 2, rpl_addr_count);
1379 proto_item_set_generated(ti);
1380 if (rpl_addr_count < 0) {
1381 /* This error should always be reported */
1382 expert_add_info_format(pinfo, ti, &ei_ipv6_routing_rpl_addr_count_ge0, "Calculated total address count must be greater than or equal to 0, instead was %d", rpl_addr_count);
1384 else if (rt->hdr.ip6r_segleft > (unsigned)rpl_addr_count) {
1385 expert_add_info_format(pinfo, rt->ti_segleft, &ei_ipv6_routing_invalid_segleft,
1386 "IPv6 RPL Routing Header segments left field must not exceed address count (%d)", rpl_addr_count);
1389 if (rpl_addr_count > 0) {
1390 offset += 4;
1392 if (g_ipv6_rpl_srh_strict_rfc_checking)
1393 rpl_addr_vector = wmem_array_sized_new(pinfo->pool, IPv6_ADDR_SIZE, rpl_addr_count);
1395 /* We use cmprI for internal (e.g.: not last) address for how many bytes to elide, so actual bytes present = 16-CmprI */
1396 for (idx = 1; idx <= rpl_addr_count; idx++) {
1397 if (idx == rpl_addr_count)
1398 cmprX = 16 - cmprE;
1399 else
1400 cmprX = 16 - cmprI;
1401 proto_tree_add_item(tree, hf_ipv6_routing_rpl_addr, tvb, offset, cmprX, ENC_NA);
1402 /* Display Full Address */
1403 memcpy(&rpl_fulladdr, ip6_dst_addr, IPv6_ADDR_SIZE);
1404 tvb_memcpy(tvb, &rpl_fulladdr.bytes[16-cmprX], offset, cmprX);
1405 ti = _proto_tree_add_ipv6_vector_address(tree, pinfo, hf_ipv6_routing_rpl_fulladdr, tvb,
1406 offset, cmprX, &rpl_fulladdr, idx);
1407 proto_item_set_generated(ti);
1408 offset += cmprX;
1410 /* IPv6 Source and Destination addresses of the encapsulating datagram (MUST) not appear in the SRH*/
1411 if (memcmp(&rpl_fulladdr, ip6_src_addr, IPv6_ADDR_SIZE) == 0) {
1412 expert_add_info(pinfo, ti, &ei_ipv6_src_route_list_src_addr);
1414 if (memcmp(&rpl_fulladdr, ip6_dst_addr, IPv6_ADDR_SIZE) == 0) {
1415 expert_add_info(pinfo, ti, &ei_ipv6_src_route_list_dst_addr);
1418 /* Multicast addresses MUST NOT appear in the in SRH */
1419 if (in6_addr_is_multicast(&rpl_fulladdr)) {
1420 expert_add_info(pinfo, ti, &ei_ipv6_src_route_list_multicast_addr);
1423 if (g_ipv6_rpl_srh_strict_rfc_checking) {
1424 /* from RFC6554: */
1425 /* The SRH MUST NOT specify a path that visits a node more than once. */
1426 /* To do this, we will just check the current 'addr' against the previous addresses */
1427 for (i = 0; i < wmem_array_get_count(rpl_addr_vector); i++) {
1428 /* Compare the addresses */
1429 if (memcmp(&rpl_fulladdr, wmem_array_index(rpl_addr_vector, i), IPv6_ADDR_SIZE) == 0) {
1430 /* Found a previous that is the same */
1431 expert_add_info(pinfo, ti, &ei_ipv6_src_route_list_mult_inst_same_addr);
1432 break;
1435 wmem_array_append(rpl_addr_vector, &rpl_fulladdr, 1);
1438 if (pinfo->dst.type == AT_IPv6 && rt->hdr.ip6r_segleft > 0) {
1439 alloc_address_wmem_ipv6(pinfo->pool, &pinfo->dst, &rpl_fulladdr);
1444 return tvb_captured_length(tvb);
1447 /* Segment Routing Header (Type 4) */
1448 static int
1449 dissect_routing6_srh(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
1451 struct ws_rthdr *rt = (struct ws_rthdr *)data;
1452 int offset = 0;
1453 int addr_offset;
1454 uint32_t last_entry, addr_count;
1456 proto_tree_add_item_ret_uint(tree, hf_ipv6_routing_srh_last_entry,
1457 tvb, offset, 1, ENC_BIG_ENDIAN,
1458 &last_entry);
1459 addr_count = last_entry + 1;
1460 offset += 1;
1462 proto_tree_add_item(tree, hf_ipv6_routing_srh_flags, tvb, offset, 1, ENC_BIG_ENDIAN);
1463 offset += 1;
1465 proto_tree_add_item(tree, hf_ipv6_routing_srh_tag, tvb, offset, 2, ENC_NA);
1466 offset += 2;
1468 if (rt->hdr.ip6r_segleft > addr_count) {
1469 expert_add_info_format(pinfo, rt->ti_segleft, &ei_ipv6_routing_invalid_segleft,
1470 "IPv6 Type 4 Routing Header segments left field must not exceed address count (%u)", addr_count);
1473 if (pinfo->dst.type == AT_IPv6 && rt->hdr.ip6r_segleft > 0) {
1474 alloc_address_wmem_ipv6(pinfo->pool, &pinfo->dst, tvb_get_ptr_ipv6(tvb, offset));
1477 for (unsigned i = 0; i < addr_count; i++) {
1478 addr_offset = offset + i * IPv6_ADDR_SIZE;
1479 _proto_tree_add_ipv6_vector_address(tree, pinfo, hf_ipv6_routing_srh_addr, tvb,
1480 addr_offset, IPv6_ADDR_SIZE, tvb_get_ptr_ipv6(tvb, addr_offset), i);
1483 /* TODO: dissect TLVs */
1485 return tvb_captured_length(tvb);
1488 /* Compact Routing Header 16 (Type 5) and Compact Routing Header 32 (Type 6).
1489 https://tools.ietf.org/html/draft-bonica-6man-comp-rtg-hdr-23. */
1490 static int dissect_routing6_crh(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, void* data)
1492 int offset, minimum_crh_length;
1493 int sid;
1495 unsigned sid_count;
1496 unsigned octets_per_sid;
1497 unsigned sids_beyond_first_word;
1498 unsigned sids_per_word;
1499 struct ws_rthdr* rt = (struct ws_rthdr*)data;
1500 bool is_crh16 = rt->hdr.ip6r_type == IPv6_RT_HEADER_COMPACT_16;
1501 uint8_t segments_left = rt->hdr.ip6r_segleft;
1503 /* Compute the minimum CRH length measured in 8-octet units, not including
1504 the first 8 octets */
1505 minimum_crh_length = -1;
1506 switch (rt->hdr.ip6r_type) {
1507 case IPv6_RT_HEADER_COMPACT_16:
1508 octets_per_sid = 2;
1509 sids_per_word = 4;
1510 sid_count = rt->hdr.ip6r_len * 4 + 2;
1511 if (segments_left <= 2)
1512 minimum_crh_length = 0;
1513 sids_beyond_first_word = segments_left - 2;
1514 break;
1515 case IPv6_RT_HEADER_COMPACT_32:
1516 octets_per_sid = 4;
1517 sids_per_word = 2;
1518 sid_count = rt->hdr.ip6r_len * 2 + 1;
1519 if (segments_left <= 1)
1520 minimum_crh_length = 0;
1521 sids_beyond_first_word = segments_left - 1;
1522 break;
1523 default:
1524 DISSECTOR_ASSERT_NOT_REACHED();
1526 if (minimum_crh_length) {
1527 minimum_crh_length = sids_beyond_first_word / sids_per_word;
1528 if (sids_beyond_first_word % sids_per_word)
1529 minimum_crh_length++;
1531 if (minimum_crh_length > rt->hdr.ip6r_len) {
1532 expert_add_info_format(pinfo, rt->ti_len, &ei_ipv6_routing_invalid_length,
1533 "IPv6 Compact Routing Header minimum length must not exceed header length (%u)",
1534 rt->hdr.ip6r_len);
1537 offset = 0;
1538 if (is_crh16) {
1539 proto_item* current_sid_item = proto_tree_add_item(tree, hf_ipv6_routing_crh16_current_sid,
1540 tvb, offset + (octets_per_sid * segments_left), octets_per_sid, ENC_BIG_ENDIAN);
1541 proto_item_set_generated(current_sid_item);
1542 } else {
1543 proto_item* current_sid_item = proto_tree_add_item(tree, hf_ipv6_routing_crh32_current_sid,
1544 tvb, offset + (octets_per_sid * segments_left), octets_per_sid, ENC_BIG_ENDIAN);
1545 proto_item_set_generated(current_sid_item);
1547 sid = is_crh16 ? tvb_get_uint16(tvb, offset, ENC_BIG_ENDIAN)
1548 : tvb_get_uint32(tvb, offset, ENC_BIG_ENDIAN);
1549 proto_tree* segment_ids
1550 = proto_tree_add_subtree(tree, tvb, 0, -1, 0, NULL, "Segment Identifiers");
1551 for (unsigned i = 0; i < sid_count && sid; i++) {
1552 if (is_crh16) {
1553 proto_tree_add_uint_format(segment_ids, hf_ipv6_routing_crh16_segment_id, tvb, offset,
1554 octets_per_sid, sid, "SID[%d] = %d", i, sid);
1555 } else {
1556 proto_tree_add_uint_format(segment_ids, hf_ipv6_routing_crh32_segment_id, tvb, offset,
1557 octets_per_sid, sid, "SID[%d] = %d", i, sid);
1559 offset += octets_per_sid;
1560 sid = is_crh16 ? tvb_get_uint16(tvb, offset, ENC_BIG_ENDIAN)
1561 : tvb_get_uint32(tvb, offset, ENC_BIG_ENDIAN);
1564 return tvb_captured_length(tvb);
1568 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1569 | Next Header | Hdr Ext Len | Routing Type | Segments Left |
1570 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1573 . type-specific data .
1576 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1578 static int
1579 dissect_routing6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) {
1580 struct ws_rthdr rt;
1581 unsigned nxt, hdr_len, total_len;
1582 proto_tree *rt_tree, *root_tree;
1583 proto_item *pi, *ti, *ti_hdr_len, *ti_type, *ti_segs;
1584 int offset = 0;
1585 tvbuff_t *next_tvb;
1586 int type, type_len;
1587 dissector_handle_t type_dissector;
1589 col_append_sep_str(pinfo->cinfo, COL_INFO, " , ", "IPv6 routing");
1591 root_tree = p_ipv6_pinfo_select_root(pinfo, tree);
1593 pi = proto_tree_add_item(root_tree, proto_ipv6_routing, tvb, offset, -1, ENC_NA);
1594 rt_tree = proto_item_add_subtree(pi, ett_ipv6_routing_proto);
1596 proto_tree_add_item(rt_tree, hf_ipv6_routing_nxt, tvb, offset, 1, ENC_BIG_ENDIAN);
1597 nxt = tvb_get_uint8(tvb, offset);
1598 offset += 1;
1600 ti_hdr_len = proto_tree_add_item(rt_tree, hf_ipv6_routing_len, tvb, offset, 1, ENC_BIG_ENDIAN);
1601 hdr_len = tvb_get_uint8(tvb, offset);
1603 Hdr Ext Len 8-bit unsigned integer. Length of the Routing
1604 header in 8-octet units, not including the
1605 first 8 octets.
1607 total_len = (hdr_len + 1) * 8;
1608 type_len = total_len - 4;
1610 proto_item_set_len(pi, total_len);
1611 ti = proto_tree_add_uint(rt_tree, hf_ipv6_routing_len_oct, tvb, offset, 1, total_len);
1612 proto_item_set_generated(ti);
1613 if (ipv6_exthdr_hide_len_oct_field) {
1614 proto_item_set_hidden(ti);
1615 proto_item_append_text(ti_hdr_len, " (%d bytes)", total_len);
1617 p_ipv6_pinfo_add_len(pinfo, total_len);
1618 offset += 1;
1620 ti_type = proto_tree_add_item(rt_tree, hf_ipv6_routing_type, tvb, offset, 1, ENC_BIG_ENDIAN);
1621 type = tvb_get_uint8(tvb, offset);
1622 proto_item_append_text(pi, " (%s)", val_to_str(type, routing_header_type, "Unknown type %u"));
1623 offset += 1;
1625 ti_segs = proto_tree_add_item(rt_tree, hf_ipv6_routing_segleft, tvb, offset, 1, ENC_BIG_ENDIAN);
1626 offset += 1;
1628 type_dissector = dissector_get_uint_handle(ipv6_routing_dissector_table, type);
1629 if (type_dissector != NULL) {
1630 tvb_memcpy(tvb, &(rt.hdr), 0, 4);
1631 rt.ti_len = ti_hdr_len;
1632 rt.ti_type = ti_type;
1633 rt.ti_segleft = ti_segs;
1634 call_dissector_with_data(type_dissector, tvb_new_subset_length(tvb, offset, type_len), pinfo, rt_tree, &rt);
1636 else {
1637 /* Unknown Routing Header Type */
1638 ti = proto_tree_add_item(rt_tree, hf_ipv6_routing_unknown_data, tvb, offset, type_len, ENC_NA);
1639 expert_add_info(pinfo, ti, &ei_ipv6_routing_undecoded);
1642 p_add_ipv6_nxt(pinfo, nxt);
1644 next_tvb = tvb_new_subset_remaining(tvb, total_len);
1645 ipv6_dissect_next(nxt, next_tvb, pinfo, tree, (ws_ip6 *)data);
1646 return tvb_captured_length(tvb);
1649 static int
1650 dissect_fraghdr(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) {
1651 proto_item *pi, *ti;
1652 proto_tree *frag_tree, *root_tree;
1653 uint8_t nxt;
1654 uint16_t offlg;
1655 uint16_t frag_off;
1656 bool frag_flg;
1657 uint32_t frag_ident;
1658 int offset = 0;
1659 ipv6_pinfo_t *ipv6_pinfo;
1660 bool show_data = false;
1661 bool reassembled;
1662 tvbuff_t *next_tvb;
1664 nxt = tvb_get_uint8(tvb, offset);
1665 offlg = tvb_get_ntohs(tvb, offset + 2);
1666 frag_off = offlg & IP6F_OFF_MASK; /* offset in bytes */
1667 frag_flg = offlg & IP6F_MORE_FRAG;
1668 frag_ident = tvb_get_ntohl(tvb, offset + 4);
1669 col_add_fstr(pinfo->cinfo, COL_INFO, "IPv6 fragment (off=%u more=%s ident=0x%08x nxt=%u)",
1670 frag_off, frag_flg ? "y" : "n", frag_ident, nxt);
1672 root_tree = p_ipv6_pinfo_select_root(pinfo, tree);
1673 ipv6_pinfo = p_ipv6_pinfo_add_len(pinfo, IPv6_FRAGMENT_HDR_SIZE);
1675 /* IPv6 Fragmentation Header has fixed length of 8 bytes */
1676 pi = proto_tree_add_item(root_tree, proto_ipv6_fraghdr, tvb, offset, IPv6_FRAGMENT_HDR_SIZE, ENC_NA);
1677 if (ipv6_pinfo != NULL && ipv6_pinfo->jumbo_plen != 0) {
1678 expert_add_info(pinfo, pi, &ei_ipv6_opt_jumbo_fragment);
1681 frag_tree = proto_item_add_subtree(pi, ett_ipv6_fraghdr_proto);
1683 proto_tree_add_item(frag_tree, hf_ipv6_fraghdr_nxt, tvb, offset, 1, ENC_BIG_ENDIAN);
1684 offset += 1;
1686 proto_tree_add_item(frag_tree, hf_ipv6_fraghdr_reserved_octet, tvb, offset, 1, ENC_BIG_ENDIAN);
1687 offset += 1;
1689 ti = proto_tree_add_item(frag_tree, hf_ipv6_fraghdr_offset, tvb, offset, 2, ENC_BIG_ENDIAN);
1690 proto_item_append_text(ti, " (%d bytes)", frag_off);
1692 proto_tree_add_item(frag_tree, hf_ipv6_fraghdr_reserved_bits, tvb, offset, 2, ENC_BIG_ENDIAN);
1694 proto_tree_add_item(frag_tree, hf_ipv6_fraghdr_more, tvb, offset, 2, ENC_BIG_ENDIAN);
1695 offset += 2;
1697 proto_tree_add_item(frag_tree, hf_ipv6_fraghdr_ident, tvb, offset, 4, ENC_BIG_ENDIAN);
1698 offset += 4;
1700 if (ipv6_pinfo != NULL && ipv6_pinfo->frag_plen > 0) {
1701 if ((frag_off != 0) || frag_flg) {
1702 reassembled = ipv6_reassemble_do(&tvb, &offset, pinfo, root_tree, ipv6_pinfo->frag_plen,
1703 frag_off, frag_flg, frag_ident, &show_data);
1704 if (show_data) {
1705 next_tvb = tvb_new_subset_remaining(tvb, offset);
1706 call_data_dissector(next_tvb, pinfo, tree);
1707 return tvb_captured_length(tvb);
1709 if (reassembled) {
1710 ipv6_pinfo->frag_plen = 0;
1711 next_tvb = tvb_new_subset_remaining(tvb, offset);
1712 ipv6_dissect_next(nxt, next_tvb, pinfo, tree, (ws_ip6 *)data);
1713 return tvb_captured_length(tvb);
1718 p_add_ipv6_nxt(pinfo, nxt);
1720 next_tvb = tvb_new_subset_remaining(tvb, offset);
1721 ipv6_dissect_next(nxt, next_tvb, pinfo, tree, (ws_ip6 *)data);
1722 return tvb_captured_length(tvb);
1725 struct opt_proto_item {
1726 proto_item *type, *len;
1730 * Jumbo Payload Option
1732 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1733 | Option Type | Opt Data Len |
1734 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1735 | Jumbo Payload Length |
1736 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1738 static int
1739 dissect_opt_jumbo(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *opt_tree,
1740 struct opt_proto_item *opt_ti, uint8_t opt_len)
1742 proto_item *pi = proto_tree_get_parent(opt_tree);
1743 proto_item *ti;
1744 uint32_t jumbo_plen = 0;
1745 ipv6_pinfo_t *ipv6_pinfo = p_get_ipv6_pinfo(pinfo);
1747 if (opt_len != 4) {
1748 expert_add_info_format(pinfo, opt_ti->len, &ei_ipv6_opt_invalid_len,
1749 "Jumbo Payload: Invalid length (%u bytes)", opt_len);
1751 ti = proto_tree_add_item_ret_uint(opt_tree, hf_ipv6_opt_jumbo, tvb, offset, 4, ENC_BIG_ENDIAN, &jumbo_plen);
1752 offset += 4;
1754 if (ipv6_pinfo != NULL && ipv6_pinfo->ip6_plen != 0) {
1755 expert_add_info(pinfo, pi, &ei_ipv6_opt_jumbo_prohibited);
1757 if (jumbo_plen < 65536) {
1758 expert_add_info(pinfo, ti, &ei_ipv6_opt_jumbo_truncated);
1761 return offset;
1765 * RPL Option
1767 0 1 2 3
1768 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1769 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1770 | Option Type | Opt Data Len |
1771 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1772 |O|R|F|0|0|0|0|0| RPLInstanceID | SenderRank |
1773 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1774 | (sub-TLVs) |
1775 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1777 static int
1778 dissect_opt_rpl(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *opt_tree,
1779 struct opt_proto_item *opt_ti, uint8_t opt_len)
1781 static int * const rpl_flags[] = {
1782 &hf_ipv6_opt_rpl_flag_o,
1783 &hf_ipv6_opt_rpl_flag_r,
1784 &hf_ipv6_opt_rpl_flag_f,
1785 &hf_ipv6_opt_rpl_flag_rsv,
1786 NULL
1789 if (opt_len < 4) {
1790 expert_add_info_format(pinfo, opt_ti->len, &ei_ipv6_opt_invalid_len,
1791 "RPL Option: Invalid length (%u bytes)", opt_len);
1793 proto_tree_add_bitmask(opt_tree, tvb, offset, hf_ipv6_opt_rpl_flag, ett_ipv6_opt_rpl, rpl_flags, ENC_NA);
1794 offset += 1;
1795 proto_tree_add_item(opt_tree, hf_ipv6_opt_rpl_instance_id, tvb, offset, 1, ENC_NA);
1796 offset += 1;
1797 proto_tree_add_item(opt_tree, hf_ipv6_opt_rpl_senderrank, tvb, offset, 2, ENC_BIG_ENDIAN);
1798 offset += 2;
1800 /* TODO: Add dissection of sub-TLVs */
1802 return offset;
1806 * Tunnel Encapsulation Limit Option
1808 Option Type Opt Data Len Opt Data Len
1809 0 1 2 3 4 5 6 7
1810 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1811 |0 0 0 0 0 1 0 0| 1 | Tun Encap Lim |
1812 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1814 static int
1815 dissect_opt_tel(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *opt_tree,
1816 struct opt_proto_item *opt_ti, uint8_t opt_len)
1818 if (opt_len != 1) {
1819 expert_add_info_format(pinfo, opt_ti->len, &ei_ipv6_opt_invalid_len,
1820 "Tunnel Encapsulation Limit: Invalid length (%u bytes)", opt_len);
1822 proto_tree_add_item(opt_tree, hf_ipv6_opt_tel, tvb, offset, 1, ENC_BIG_ENDIAN);
1823 offset += 1;
1825 return offset;
1829 * IPv6 Minimum Path MTU Hop by Hop Option
1832 Option Option Option
1833 Type Data Len Data
1834 +--------+--------+--------+--------+---------+-------+-+
1835 |BBCTTTTT|00000100| Min-PMTU | Rtn-PMTU |R|
1836 +--------+--------+--------+--------+---------+-------+-+
1838 Option Type:
1840 BB 00 Skip over this option and continue processing.
1842 C 1 Option data can change en route to the packet's final
1843 destination.
1845 TTTTT 10000 Option Type assigned from IANA [IANA-HBH].
1847 Length: 4 The size of the each value field in Option Data
1848 field supports Path MTU values from 0 to 65,535 octets.
1850 Min-PMTU: n 16-bits. The minimum PMTU in octets, reflecting the
1851 smallest link MTU that the packet experienced across
1852 the path. This is called the Reported PMTU. A value
1853 less than the IPv6 minimum link MTU [RFC8200]
1854 should be ignored.
1856 Rtn-PMTU: n 15-bits. The returned minimum PMTU, carrying the 15
1857 most significant bits of the latest received Min-PMTU
1858 field. The value zero means that no Reported MTU is
1859 being returned.
1861 R n 1-bit. R-Flag. Set by the source to signal that
1862 the destination should include the received
1863 Reported PMTU in Rtn-PMTU field.
1865 [IANA-HBH]
1866 "Destination Options and Hop-by-Hop Options",
1867 <https://www.iana.org/assignments/ipv6-parameters/
1868 ipv6-parameters.xhtml#ipv6-parameters-2>
1870 static int
1871 dissect_opt_pmtu(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *opt_tree,
1872 struct opt_proto_item *opt_ti, uint8_t opt_len)
1874 uint16_t val;
1876 if (opt_len != 4) {
1877 expert_add_info_format(pinfo, opt_ti->len, &ei_ipv6_opt_invalid_len,
1878 "PMTU Option: Invalid Length (%u bytes)", opt_len);
1881 proto_tree_add_item(opt_tree, hf_ipv6_opt_pmtu_min, tvb, offset, 2, ENC_BIG_ENDIAN);
1882 offset += 2;
1883 val = tvb_get_ntohs(tvb, offset);
1884 proto_tree_add_uint(opt_tree, hf_ipv6_opt_pmtu_rtn, tvb, offset, 2, val & 0xFFFE);
1885 offset += 1;
1886 proto_tree_add_boolean(opt_tree, hf_ipv6_opt_pmtu_rtn_flag, tvb, offset, 1, val & 0x0001);
1887 offset += 1;
1889 return offset;
1893 * IETF APN6
1895 * Application-Aware IPv6 Networking (APN6)
1897 * https://datatracker.ietf.org/wg/apn/about/
1898 * https://datatracker.ietf.org/doc/draft-li-apn-header/
1899 * https://datatracker.ietf.org/doc/draft-li-apn-ipv6-encap/
1901 * 0 1 2 3
1902 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1903 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1904 | APN-ID-Type | Flags | APN-Para-Type |
1905 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1906 | APN-ID |
1907 | (32-bit/64-bit/128-bit) |
1908 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1909 * */
1910 static int
1911 dissect_opt_apn6(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *opt_tree,
1912 struct opt_proto_item *opt_ti, uint8_t opt_len)
1914 if (opt_len < 8) {
1915 expert_add_info_format(pinfo, opt_ti->len, &ei_ipv6_opt_invalid_len,
1916 "APN6 Option: Invalid Length (%u bytes) for basic APN header and shortest APN ID(32-bit)", opt_len);
1919 uint32_t parsed_offset = 0; // offset is for DOH header; parsed_offset is for APN option.
1920 proto_tree *sub_tree = proto_tree_add_subtree(opt_tree, tvb, offset, opt_len, 0, NULL, "APN Header");
1922 uint8_t apn_id_type = tvb_get_uint8(tvb, offset);
1923 proto_item *apn_id_type_i = proto_tree_add_item(sub_tree, hf_ipv6_opt_apn_id_type, tvb, offset, 1, ENC_BIG_ENDIAN);
1925 offset++;
1926 parsed_offset++;
1928 if (apn_id_type < APN_ID_32BIT || apn_id_type > APN_ID_128BIT) {
1929 expert_add_info_format(pinfo, apn_id_type_i, &ei_ipv6_opt_apn_invalid_id_type,
1930 "APN6 Option: Invalid APN ID Type (%u)", apn_id_type);
1934 proto_tree_add_item(sub_tree, hf_ipv6_opt_apn_flags, tvb, offset, 1, ENC_BIG_ENDIAN);
1935 offset++;
1936 parsed_offset++;
1938 proto_tree_add_item(sub_tree, hf_ipv6_opt_apn_param_type, tvb, offset, 2, ENC_BIG_ENDIAN);
1939 offset += 2;
1940 parsed_offset += 2;
1943 if (apn_id_type >= APN_ID_32BIT) {
1944 proto_tree_add_item(sub_tree, hf_ipv6_opt_apn_id_part1, tvb, offset, 4, ENC_BIG_ENDIAN);
1945 offset += 4;
1946 parsed_offset += 4;
1948 if (apn_id_type >= APN_ID_64BIT) {
1949 if (opt_len - parsed_offset < 4) {
1950 expert_add_info_format(pinfo, opt_ti->len, &ei_ipv6_opt_invalid_len,
1951 "APN6 Option: Invalid Length (%u bytes) for 64-bit APN ID, parsed offset %u",
1952 opt_len, parsed_offset);
1954 proto_tree_add_item(sub_tree, hf_ipv6_opt_apn_id_part2, tvb, offset, 4, ENC_BIG_ENDIAN);
1955 offset += 4;
1956 parsed_offset += 4;
1958 if (apn_id_type >= APN_ID_128BIT) {
1959 if (opt_len - parsed_offset < 8) {
1960 expert_add_info_format(pinfo, opt_ti->len, &ei_ipv6_opt_invalid_len,
1961 "APN6 Option: Invalid Length (%u bytes) for 128-bit APN ID, parsed offset %u",
1962 opt_len, parsed_offset);
1965 proto_tree_add_item(sub_tree, hf_ipv6_opt_apn_id_part3, tvb, offset, 4, ENC_BIG_ENDIAN);
1966 offset += 4;
1968 proto_tree_add_item(sub_tree, hf_ipv6_opt_apn_id_part4, tvb, offset, 4, ENC_BIG_ENDIAN);
1969 offset += 4;
1972 return offset;
1977 * IPv6 Router Alert Option
1979 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1980 |0 0 0|0 0 1 0 1|0 0 0 0 0 0 1 0| Value (2 octets) |
1981 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1982 length = 2
1984 static int
1985 dissect_opt_rtalert(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *opt_tree,
1986 struct opt_proto_item *opt_ti, uint8_t opt_len)
1988 if (opt_len != 2) {
1989 expert_add_info_format(pinfo, opt_ti->len, &ei_ipv6_opt_invalid_len,
1990 "Router alert: Invalid Length (%u bytes)", opt_len);
1992 proto_tree_add_item(opt_tree, hf_ipv6_opt_rtalert, tvb, offset, 2, ENC_BIG_ENDIAN);
1993 offset += 2;
1995 return offset;
1999 * Quick-Start Option for IPv6
2001 0 1 2 3
2002 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
2003 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2004 | Option | Length=6 | Func. | Rate | Not Used |
2005 | | | 1000 | Report| |
2006 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2007 | QS Nonce | R |
2008 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2010 static int
2011 dissect_opt_quickstart(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *opt_tree,
2012 struct opt_proto_item *opt_ti, uint8_t opt_len, ws_ip6 *iph)
2014 proto_item *pi = proto_tree_get_parent(opt_tree);
2015 proto_item *ti;
2016 uint8_t command, function, rate;
2017 uint32_t qs_ttl = 0;
2019 if (opt_len != 6) {
2020 expert_add_info_format(pinfo, opt_ti->len, &ei_ipv6_opt_invalid_len,
2021 "Quick-Start: Invalid Length (%u bytes)", opt_len);
2024 command = tvb_get_uint8(tvb, offset);
2025 function = command >> 4;
2026 rate = command & QS_RATE_MASK;
2028 proto_tree_add_item(opt_tree, hf_ipv6_opt_qs_func, tvb, offset, 1, ENC_BIG_ENDIAN);
2030 switch (function) {
2031 case QS_RATE_REQUEST:
2032 proto_tree_add_item(opt_tree, hf_ipv6_opt_qs_rate, tvb, offset, 1, ENC_BIG_ENDIAN);
2033 offset += 1;
2034 proto_tree_add_item_ret_uint(opt_tree, hf_ipv6_opt_qs_ttl, tvb, offset, 1, ENC_BIG_ENDIAN, &qs_ttl);
2035 proto_item_append_text(pi, ", %s, QS TTL %u",
2036 val_to_str_ext(rate, &qs_rate_vals_ext, "Unknown (%u)"),
2037 qs_ttl);
2038 if (iph != NULL) {
2039 uint8_t ttl_diff;
2041 ttl_diff = (iph->ip6_hop - qs_ttl) % 256;
2042 ti = proto_tree_add_uint(opt_tree, hf_ipv6_opt_qs_ttl_diff, tvb, offset, 1, ttl_diff);
2043 proto_item_set_generated(ti);
2044 proto_item_append_text(pi, ", QS TTL diff %u", ttl_diff);
2046 offset += 1;
2047 proto_tree_add_item(opt_tree, hf_ipv6_opt_qs_nonce, tvb, offset, 4, ENC_BIG_ENDIAN);
2048 proto_tree_add_item(opt_tree, hf_ipv6_opt_qs_reserved, tvb, offset, 4, ENC_BIG_ENDIAN);
2049 offset += 4;
2050 break;
2051 case QS_RATE_REPORT:
2052 proto_tree_add_item(opt_tree, hf_ipv6_opt_qs_rate, tvb, offset, 1, ENC_BIG_ENDIAN);
2053 proto_item_append_text(pi, ", %s", val_to_str_ext(rate, &qs_rate_vals_ext, "Unknown (%u)"));
2054 offset += 1;
2055 proto_tree_add_item(opt_tree, hf_ipv6_opt_qs_unused, tvb, offset, 1, ENC_BIG_ENDIAN);
2056 offset += 1;
2057 proto_tree_add_item(opt_tree, hf_ipv6_opt_qs_nonce, tvb, offset, 4, ENC_BIG_ENDIAN);
2058 proto_tree_add_item(opt_tree, hf_ipv6_opt_qs_reserved, tvb, offset, 4, ENC_BIG_ENDIAN);
2059 offset += 4;
2060 break;
2061 default:
2062 break;
2065 return offset;
2068 static const value_string ipv6_ioam_opt_types[] = {
2069 { IP6IOAM_PRE_TRACE, "Pre-allocated Trace" },
2070 { IP6IOAM_INC_TRACE, "Incremental Trace" },
2071 { IP6IOAM_POT, "Proof of Transit" },
2072 { IP6IOAM_E2E, "Edge to Edge" },
2073 { IP6IOAM_DEX, "Direct Export" },
2074 { 0, NULL}
2077 static int
2078 dissect_opt_ioam_trace_node(tvbuff_t *tvb, int offset,
2079 proto_tree *opt_tree, uint32_t trace_type)
2081 proto_tree* sub_tree;
2083 if (trace_type & IP6IOAM_TRACE_MASK_BIT0) {
2084 sub_tree = proto_tree_add_subtree(opt_tree, tvb, offset, 4, 0, NULL,
2085 "Hop_Lim and Node ID (short)");
2086 proto_tree_add_item(sub_tree, hf_ipv6_opt_ioam_trace_node_hlim,
2087 tvb, offset, 1, ENC_NA);
2088 proto_tree_add_item(sub_tree, hf_ipv6_opt_ioam_trace_node_id,
2089 tvb, offset + 1, 3, ENC_BIG_ENDIAN);
2090 offset += 4;
2093 if (trace_type & IP6IOAM_TRACE_MASK_BIT1) {
2094 sub_tree = proto_tree_add_subtree(opt_tree, tvb, offset, 4, 0, NULL,
2095 "Ingress and Egress IDs (short)");
2096 proto_tree_add_item(sub_tree, hf_ipv6_opt_ioam_trace_node_iif,
2097 tvb, offset, 2, ENC_BIG_ENDIAN);
2098 proto_tree_add_item(sub_tree, hf_ipv6_opt_ioam_trace_node_eif,
2099 tvb, offset + 2, 2, ENC_BIG_ENDIAN);
2100 offset += 4;
2103 if (trace_type & IP6IOAM_TRACE_MASK_BIT2) {
2104 proto_tree_add_item(opt_tree, hf_ipv6_opt_ioam_trace_node_tss,
2105 tvb, offset, 4, ENC_BIG_ENDIAN);
2106 offset += 4;
2109 if (trace_type & IP6IOAM_TRACE_MASK_BIT3) {
2110 proto_tree_add_item(opt_tree, hf_ipv6_opt_ioam_trace_node_tsf,
2111 tvb, offset, 4, ENC_BIG_ENDIAN);
2112 offset += 4;
2115 if (trace_type & IP6IOAM_TRACE_MASK_BIT4) {
2116 proto_tree_add_item(opt_tree, hf_ipv6_opt_ioam_trace_node_trdelay,
2117 tvb, offset, 4, ENC_BIG_ENDIAN);
2118 offset += 4;
2121 if (trace_type & IP6IOAM_TRACE_MASK_BIT5) {
2122 proto_tree_add_item(opt_tree, hf_ipv6_opt_ioam_trace_node_nsdata,
2123 tvb, offset, 4, ENC_BIG_ENDIAN);
2124 offset += 4;
2127 if (trace_type & IP6IOAM_TRACE_MASK_BIT6) {
2128 proto_tree_add_item(opt_tree, hf_ipv6_opt_ioam_trace_node_qdepth,
2129 tvb, offset, 4, ENC_BIG_ENDIAN);
2130 offset += 4;
2133 if (trace_type & IP6IOAM_TRACE_MASK_BIT7) {
2134 proto_tree_add_item(opt_tree, hf_ipv6_opt_ioam_trace_node_csum,
2135 tvb, offset, 4, ENC_BIG_ENDIAN);
2136 offset += 4;
2139 if (trace_type & IP6IOAM_TRACE_MASK_BIT8) {
2140 sub_tree = proto_tree_add_subtree(opt_tree, tvb, offset, 8, 0, NULL,
2141 "Hop_Lim and Node ID (wide)");
2142 proto_tree_add_item(sub_tree, hf_ipv6_opt_ioam_trace_node_hlim,
2143 tvb, offset, 1, ENC_NA);
2144 proto_tree_add_item(sub_tree, hf_ipv6_opt_ioam_trace_node_id_wide,
2145 tvb, offset + 1, 7, ENC_BIG_ENDIAN);
2146 offset += 8;
2149 if (trace_type & IP6IOAM_TRACE_MASK_BIT9) {
2150 sub_tree = proto_tree_add_subtree(opt_tree, tvb, offset, 8, 0, NULL,
2151 "Ingress and Egress IDs (wide)");
2152 proto_tree_add_item(sub_tree, hf_ipv6_opt_ioam_trace_node_iif_wide,
2153 tvb, offset, 4, ENC_BIG_ENDIAN);
2154 proto_tree_add_item(sub_tree, hf_ipv6_opt_ioam_trace_node_eif_wide,
2155 tvb, offset + 4, 4, ENC_BIG_ENDIAN);
2156 offset += 8;
2159 if (trace_type & IP6IOAM_TRACE_MASK_BIT10) {
2160 proto_tree_add_item(opt_tree, hf_ipv6_opt_ioam_trace_node_nsdata_wide,
2161 tvb, offset, 8, ENC_BIG_ENDIAN);
2162 offset += 8;
2165 if (trace_type & IP6IOAM_TRACE_MASK_BIT11) {
2166 proto_tree_add_item(opt_tree, hf_ipv6_opt_ioam_trace_node_bufoccup,
2167 tvb, offset, 4, ENC_BIG_ENDIAN);
2168 offset += 4;
2171 if (trace_type & IP6IOAM_TRACE_MASK_BIT12) {
2172 proto_tree_add_item(opt_tree, hf_ipv6_opt_ioam_trace_node_undefined,
2173 tvb, offset, 4, ENC_BIG_ENDIAN);
2174 offset += 4;
2177 if (trace_type & IP6IOAM_TRACE_MASK_BIT13) {
2178 proto_tree_add_item(opt_tree, hf_ipv6_opt_ioam_trace_node_undefined,
2179 tvb, offset, 4, ENC_BIG_ENDIAN);
2180 offset += 4;
2183 if (trace_type & IP6IOAM_TRACE_MASK_BIT14) {
2184 proto_tree_add_item(opt_tree, hf_ipv6_opt_ioam_trace_node_undefined,
2185 tvb, offset, 4, ENC_BIG_ENDIAN);
2186 offset += 4;
2189 if (trace_type & IP6IOAM_TRACE_MASK_BIT15) {
2190 proto_tree_add_item(opt_tree, hf_ipv6_opt_ioam_trace_node_undefined,
2191 tvb, offset, 4, ENC_BIG_ENDIAN);
2192 offset += 4;
2195 if (trace_type & IP6IOAM_TRACE_MASK_BIT16) {
2196 proto_tree_add_item(opt_tree, hf_ipv6_opt_ioam_trace_node_undefined,
2197 tvb, offset, 4, ENC_BIG_ENDIAN);
2198 offset += 4;
2201 if (trace_type & IP6IOAM_TRACE_MASK_BIT17) {
2202 proto_tree_add_item(opt_tree, hf_ipv6_opt_ioam_trace_node_undefined,
2203 tvb, offset, 4, ENC_BIG_ENDIAN);
2204 offset += 4;
2207 if (trace_type & IP6IOAM_TRACE_MASK_BIT18) {
2208 proto_tree_add_item(opt_tree, hf_ipv6_opt_ioam_trace_node_undefined,
2209 tvb, offset, 4, ENC_BIG_ENDIAN);
2210 offset += 4;
2213 if (trace_type & IP6IOAM_TRACE_MASK_BIT19) {
2214 proto_tree_add_item(opt_tree, hf_ipv6_opt_ioam_trace_node_undefined,
2215 tvb, offset, 4, ENC_BIG_ENDIAN);
2216 offset += 4;
2219 if (trace_type & IP6IOAM_TRACE_MASK_BIT20) {
2220 proto_tree_add_item(opt_tree, hf_ipv6_opt_ioam_trace_node_undefined,
2221 tvb, offset, 4, ENC_BIG_ENDIAN);
2222 offset += 4;
2225 if (trace_type & IP6IOAM_TRACE_MASK_BIT21) {
2226 proto_tree_add_item(opt_tree, hf_ipv6_opt_ioam_trace_node_undefined,
2227 tvb, offset, 4, ENC_BIG_ENDIAN);
2228 offset += 4;
2231 return offset;
2235 * IOAM Trace Option Header
2237 0 1 2 3
2238 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
2239 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2240 | Namespace-ID | NodeLen | Flags | RemainingLen|
2241 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2242 | IOAM-Trace-Type | Reserved |
2243 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+<-+
2244 | | |
2245 | node data list [0] | |
2246 | | |
2247 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ D
2248 | | a
2249 | node data list [1] | t
2250 | | a
2251 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2252 ~ ........ ~ S
2253 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ p
2254 | | a
2255 | node data list [n-1] | c
2256 | | e
2257 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
2258 | | |
2259 | node data list [n] | |
2260 | | |
2261 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+<-+
2263 static int
2264 dissect_opt_ioam_trace(tvbuff_t *tvb, int offset, packet_info *pinfo,
2265 proto_tree *opt_tree, struct opt_proto_item *opt_ti, uint8_t opt_len)
2267 proto_item *ti;
2268 uint32_t trace_type, oss_scid;
2269 uint16_t len;
2270 uint8_t remlen, nodelen, oss_len, i = 0;
2271 int new_offset;
2273 static int * const ioam_trace_flags[] = {
2274 &hf_ipv6_opt_ioam_trace_flag_o,
2275 &hf_ipv6_opt_ioam_trace_flag_l,
2276 &hf_ipv6_opt_ioam_trace_flag_a,
2277 &hf_ipv6_opt_ioam_trace_flag_rsv,
2278 NULL
2281 static int * const ioam_trace_types[] = {
2282 &hf_ipv6_opt_ioam_trace_type_bit0,
2283 &hf_ipv6_opt_ioam_trace_type_bit1,
2284 &hf_ipv6_opt_ioam_trace_type_bit2,
2285 &hf_ipv6_opt_ioam_trace_type_bit3,
2286 &hf_ipv6_opt_ioam_trace_type_bit4,
2287 &hf_ipv6_opt_ioam_trace_type_bit5,
2288 &hf_ipv6_opt_ioam_trace_type_bit6,
2289 &hf_ipv6_opt_ioam_trace_type_bit7,
2290 &hf_ipv6_opt_ioam_trace_type_bit8,
2291 &hf_ipv6_opt_ioam_trace_type_bit9,
2292 &hf_ipv6_opt_ioam_trace_type_bit10,
2293 &hf_ipv6_opt_ioam_trace_type_bit11,
2294 &hf_ipv6_opt_ioam_trace_type_undef,
2295 &hf_ipv6_opt_ioam_trace_type_bit22,
2296 &hf_ipv6_opt_ioam_trace_type_rsv,
2297 NULL
2300 if (opt_len < 10) {
2301 expert_add_info_format(pinfo, opt_ti->len, &ei_ipv6_opt_invalid_len,
2302 "IOAM Option: Invalid length (%u bytes)", opt_len);
2305 proto_tree_add_item(opt_tree, hf_ipv6_opt_ioam_trace_ns, tvb, offset, 2, ENC_BIG_ENDIAN);
2306 offset += 2;
2308 nodelen = tvb_get_bits8(tvb, offset * 8, 5);
2309 proto_tree_add_bits_item(opt_tree, hf_ipv6_opt_ioam_trace_nodelen, tvb,
2310 offset * 8, 5, ENC_BIG_ENDIAN);
2312 proto_tree_add_bitmask(opt_tree, tvb, offset, hf_ipv6_opt_ioam_trace_flags,
2313 ett_ipv6_opt_ioam_trace_flags, ioam_trace_flags, ENC_NA);
2315 remlen = tvb_get_bits8(tvb, offset * 8 + 9, 7);
2316 ti = proto_tree_add_bits_item(opt_tree, hf_ipv6_opt_ioam_trace_remlen, tvb,
2317 offset * 8 + 9, 7, ENC_BIG_ENDIAN);
2318 if (remlen * 4 > opt_len - 10) {
2319 expert_add_info_format(pinfo, ti, &ei_ipv6_opt_ioam_invalid_remlen,
2320 "IOAM RemLen: Invalid length (%u bytes)", remlen * 4);
2323 offset += 2;
2325 trace_type = tvb_get_bits32(tvb, offset * 8, 24, ENC_BIG_ENDIAN);
2326 ti = proto_tree_add_bitmask(opt_tree, tvb, offset, hf_ipv6_opt_ioam_trace_type,
2327 ett_ipv6_opt_ioam_trace_types, ioam_trace_types, ENC_BIG_ENDIAN);
2328 proto_tree_add_item(opt_tree, hf_ipv6_opt_ioam_trace_rsv, tvb, offset + 3, 1, ENC_NA);
2329 offset += 4;
2331 /* node data list parsing starts here */
2332 if (!nodelen && trace_type != IP6IOAM_TRACE_MASK_BIT22) {
2333 expert_add_info(pinfo, ti, &ei_ipv6_opt_ioam_invalid_nodelen);
2334 return offset;
2336 if (remlen * 4 > opt_len - 10)
2337 return offset;
2339 proto_tree* trace_tree
2340 = proto_tree_add_subtree(opt_tree, tvb, offset, opt_len - 10, 0, NULL, "Trace Data");
2342 if (remlen) {
2343 proto_tree_add_item(trace_tree, hf_ipv6_opt_ioam_trace_free_space, tvb,
2344 offset, remlen * 4, ENC_NA);
2345 offset += remlen * 4;
2348 len = opt_len - 10 - remlen * 4;
2349 while (len && len >= nodelen * 4) {
2350 proto_tree* node_tree
2351 = proto_tree_add_subtree_format(trace_tree, tvb, offset,
2352 nodelen * 4, 0, NULL, "Node %u", ++i);
2354 new_offset = dissect_opt_ioam_trace_node(tvb, offset, node_tree, trace_type);
2355 if (new_offset - offset != nodelen * 4) {
2356 expert_add_info(pinfo, ti, &ei_ipv6_opt_ioam_invalid_trace_type);
2357 return offset;
2360 offset = new_offset;
2361 len -= nodelen * 4;
2363 /* Opaque State Snapshot */
2364 if (trace_type & IP6IOAM_TRACE_MASK_BIT22) {
2365 if (len < 4) {
2366 expert_add_info_format(pinfo, opt_ti->len, &ei_ipv6_opt_invalid_len,
2367 "IOAM Option: Invalid length (%u bytes)", opt_len);
2368 return offset;
2371 oss_len = tvb_get_uint8(tvb, offset);
2373 proto_tree* oss_tree
2374 = proto_tree_add_subtree(node_tree, tvb, offset, (oss_len + 1) * 4,
2375 0, NULL, "Opaque State Snapshot");
2376 proto_tree_add_item(oss_tree, hf_ipv6_opt_ioam_trace_node_oss_len,
2377 tvb, offset, 1, ENC_NA);
2378 proto_tree_add_item_ret_uint(oss_tree, hf_ipv6_opt_ioam_trace_node_oss_scid,
2379 tvb, offset + 1, 3, ENC_BIG_ENDIAN, &oss_scid);
2380 offset += 4;
2382 len -= 4;
2383 if (len < oss_len * 4) {
2384 expert_add_info_format(pinfo, opt_ti->len, &ei_ipv6_opt_invalid_len,
2385 "IOAM Option: Invalid length (%u bytes)", opt_len);
2386 return offset;
2389 if (oss_len > 0) {
2390 proto_tree_add_item(oss_tree, hf_ipv6_opt_ioam_trace_node_oss_data,
2391 tvb, offset, oss_len * 4, ENC_NA);
2393 len -= oss_len * 4;
2394 offset += oss_len * 4;
2399 if (len) {
2400 expert_add_info_format(pinfo, opt_ti->len, &ei_ipv6_opt_invalid_len,
2401 "IOAM Option: Invalid length (%u bytes)", opt_len);
2404 return offset;
2408 * IOAM Direct Export Option Header
2410 0 1 2 3
2411 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
2412 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2413 | Namespace-ID | Flags |Extension-Flags|
2414 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2415 | IOAM-Trace-Type | Reserved |
2416 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2417 | Flow ID (Optional) |
2418 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2419 | Sequence Number (Optional) |
2420 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2422 static int
2423 dissect_opt_ioam_dex(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *opt_tree,
2424 struct opt_proto_item *opt_ti, uint8_t opt_len)
2426 uint8_t extflags;
2428 static int * const ioam_dex_extflags[] = {
2429 &hf_ipv6_opt_ioam_dex_extflag_flag_rsv,
2430 &hf_ipv6_opt_ioam_dex_extflag_flag_seqnum,
2431 &hf_ipv6_opt_ioam_dex_extflag_flag_flowid,
2432 NULL
2435 static int * const ioam_dex_trace_types[] = {
2436 &hf_ipv6_opt_ioam_trace_type_bit0,
2437 &hf_ipv6_opt_ioam_trace_type_bit1,
2438 &hf_ipv6_opt_ioam_trace_type_bit2,
2439 &hf_ipv6_opt_ioam_trace_type_bit3,
2440 &hf_ipv6_opt_ioam_trace_type_bit4,
2441 &hf_ipv6_opt_ioam_trace_type_bit5,
2442 &hf_ipv6_opt_ioam_trace_type_bit6,
2443 &hf_ipv6_opt_ioam_trace_type_bit7,
2444 &hf_ipv6_opt_ioam_trace_type_bit8,
2445 &hf_ipv6_opt_ioam_trace_type_bit9,
2446 &hf_ipv6_opt_ioam_trace_type_bit10,
2447 &hf_ipv6_opt_ioam_trace_type_bit11,
2448 &hf_ipv6_opt_ioam_trace_type_undef,
2449 &hf_ipv6_opt_ioam_trace_type_bit22,
2450 &hf_ipv6_opt_ioam_trace_type_rsv,
2451 NULL
2454 if (opt_len < 10) {
2455 expert_add_info_format(pinfo, opt_ti->len, &ei_ipv6_opt_invalid_len,
2456 "IOAM Option: Invalid length (%u bytes)", opt_len);
2459 proto_tree_add_item(opt_tree, hf_ipv6_opt_ioam_dex_ns, tvb, offset, 2, ENC_BIG_ENDIAN);
2460 offset += 2;
2462 proto_tree_add_item(opt_tree, hf_ipv6_opt_ioam_dex_flags, tvb, offset, 1, ENC_NA);
2463 offset++;
2465 extflags = tvb_get_bits8(tvb, offset*8, 8);
2466 proto_tree_add_bitmask(opt_tree, tvb, offset, hf_ipv6_opt_ioam_dex_extflags,
2467 ett_ipv6_opt_ioam_dex_extflags, ioam_dex_extflags, ENC_NA);
2468 offset++;
2470 proto_tree_add_bitmask(opt_tree, tvb, offset, hf_ipv6_opt_ioam_trace_type,
2471 ett_ipv6_opt_ioam_trace_types, ioam_dex_trace_types, ENC_BIG_ENDIAN);
2472 proto_tree_add_item(opt_tree, hf_ipv6_opt_ioam_trace_rsv, tvb, offset + 3, 1, ENC_NA);
2473 offset += 4;
2475 if (extflags & 0x2) {
2476 proto_tree_add_item(opt_tree, hf_ipv6_opt_ioam_dex_extflag_flowid, tvb, offset, 4, ENC_NA);
2477 offset+=4;
2480 if (extflags & 0x1) {
2481 proto_tree_add_item(opt_tree, hf_ipv6_opt_ioam_dex_extflag_seqnum, tvb, offset, 4, ENC_NA);
2482 offset+=4;
2485 return offset;
2489 * IOAM Option Header
2491 0 1 2 3
2492 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
2493 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2494 | Option Type | Opt Data Len | Reserved | IOAM Type |
2495 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2497 static int
2498 dissect_opt_ioam(tvbuff_t *tvb, int offset, packet_info *pinfo,
2499 proto_tree *opt_tree, struct opt_proto_item *opt_ti, uint8_t opt_len)
2501 uint32_t opt_type;
2503 if (opt_len < 2) {
2504 expert_add_info_format(pinfo, opt_ti->len, &ei_ipv6_opt_invalid_len,
2505 "IOAM Option: Invalid length (%u bytes)", opt_len);
2508 proto_tree_add_item(opt_tree, hf_ipv6_opt_ioam_rsv, tvb, offset, 1, ENC_NA);
2509 proto_tree_add_item_ret_uint(opt_tree, hf_ipv6_opt_ioam_opt_type, tvb,
2510 offset + 1, 1, ENC_NA, &opt_type);
2511 offset += 2;
2513 proto_tree* opt_type_tree
2514 = proto_tree_add_subtree(opt_tree, tvb, offset, opt_len - 2, 0, NULL,
2515 val_to_str_const(opt_type, ipv6_ioam_opt_types,
2516 "Unknown Option-Type"));
2518 switch (opt_type) {
2519 case IP6IOAM_PRE_TRACE:
2520 case IP6IOAM_INC_TRACE:
2521 offset = dissect_opt_ioam_trace(tvb, offset, pinfo, opt_type_tree, opt_ti, opt_len);
2522 break;
2523 case IP6IOAM_POT:
2524 break;
2525 case IP6IOAM_E2E:
2526 break;
2527 case IP6IOAM_DEX:
2528 offset = dissect_opt_ioam_dex(tvb, offset, pinfo, opt_type_tree, opt_ti, opt_len);
2531 return offset;
2535 * Tunnel Payload Forwarding Option for IPv6
2537 0 1 2 3
2538 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
2539 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2540 | Option Type | Option Length |
2541 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2542 | TPF Information |
2543 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2545 static int
2546 dissect_opt_tpf(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *opt_tree,
2547 struct opt_proto_item *opt_ti, uint8_t opt_len)
2549 if (opt_len != 4) {
2550 expert_add_info_format(pinfo, opt_ti->len, &ei_ipv6_opt_invalid_len,
2551 "TPF: Invalid Length (%u bytes)", opt_len);
2553 proto_tree_add_item(opt_tree, hf_ipv6_opt_tpf_information, tvb, offset, 4, ENC_BIG_ENDIAN);
2554 offset += 4;
2556 return offset;
2560 ------------------------------------------------------------
2561 | Next Header | Hdr Ext Len | Option Type | Option Length|
2562 +-------------+---------------+-------------+--------------+
2563 | CALIPSO Domain of Interpretation |
2564 +-------------+---------------+-------------+--------------+
2565 | Cmpt Length | Sens Level | Checksum (CRC-16) |
2566 +-------------+---------------+-------------+--------------+
2567 | Compartment Bitmap (Optional; variable length) |
2568 +-------------+---------------+-------------+--------------+
2570 static int
2571 dissect_opt_calipso(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *opt_tree,
2572 struct opt_proto_item *opt_ti, uint8_t opt_len)
2574 uint32_t cmpt_length = 0;
2576 if (opt_len < 8) {
2577 expert_add_info_format(pinfo, opt_ti->len, &ei_ipv6_opt_invalid_len,
2578 "CALIPSO: Invalid Length (%u bytes)", opt_len);
2581 proto_tree_add_item(opt_tree, hf_ipv6_opt_calipso_doi, tvb,
2582 offset, 4, ENC_BIG_ENDIAN);
2583 offset += 4;
2585 proto_tree_add_item_ret_uint(opt_tree, hf_ipv6_opt_calipso_cmpt_length, tvb,
2586 offset, 1, ENC_BIG_ENDIAN, &cmpt_length);
2587 offset += 1;
2589 proto_tree_add_item(opt_tree, hf_ipv6_opt_calipso_sens_level, tvb,
2590 offset, 1, ENC_BIG_ENDIAN);
2591 offset += 1;
2593 proto_tree_add_checksum(opt_tree, tvb, offset, hf_ipv6_opt_calipso_checksum, -1,
2594 NULL, pinfo, 0, ENC_BIG_ENDIAN, PROTO_CHECKSUM_NO_FLAGS);
2595 offset += 2;
2597 proto_tree_add_item(opt_tree, hf_ipv6_opt_calipso_cmpt_bitmap, tvb,
2598 offset, cmpt_length*4, ENC_NA);
2599 offset += cmpt_length*4;
2601 return offset;
2605 * IPv6 SMF_DPD Option Header
2607 0 1 2 3
2608 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
2609 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2610 ... |0|0|0| 01000 | Opt. Data Len |
2611 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2612 |0|TidTy| TidLen| TaggerId (optional) ... |
2613 +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2614 | | Identifier ...
2615 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2617 Figure 3: IPv6 SMF_DPD Option Header in I-DPD mode
2619 0 1 2 3
2620 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
2621 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2622 ... |0|0|0| OptType | Opt. Data Len |
2623 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2624 |1| Hash Assist Value (HAV) ...
2625 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2627 Figure 4: IPv6 SMF_DPD Option Header in H-DPD Mode
2629 static int
2630 dissect_opt_smf_dpd(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *opt_tree,
2631 struct opt_proto_item *opt_ti _U_, uint8_t opt_len)
2633 uint8_t hash_tid;
2634 uint8_t tid_len;
2635 int ident_len;
2637 proto_tree_add_item(opt_tree, hf_ipv6_opt_smf_dpd_hash_bit, tvb, offset, 1, ENC_BIG_ENDIAN);
2638 hash_tid = tvb_get_uint8(tvb, offset);
2640 if (hash_tid & 0x80) {
2641 /* H-DPD Mode */
2642 proto_tree_add_item(opt_tree, hf_ipv6_opt_smf_dpd_hav, tvb, offset, opt_len, ENC_NA);
2643 return offset + opt_len;
2646 /* I-DPD Mode */
2647 proto_tree_add_item(opt_tree, hf_ipv6_opt_smf_dpd_tid_type, tvb, offset, 1, ENC_BIG_ENDIAN);
2648 proto_tree_add_item(opt_tree, hf_ipv6_opt_smf_dpd_tid_len, tvb, offset, 1, ENC_BIG_ENDIAN);
2649 offset += 1;
2650 ident_len = opt_len - 1;
2651 if (hash_tid & 0x70) {
2652 tid_len = (hash_tid & 0x0f) + 1;
2653 proto_tree_add_item(opt_tree, hf_ipv6_opt_smf_dpd_tagger_id, tvb, offset, tid_len, ENC_NA);
2654 offset += tid_len;
2655 ident_len -= tid_len;
2657 if (ident_len > 0) {
2658 proto_tree_add_item(opt_tree, hf_ipv6_opt_smf_dpd_ident, tvb, offset, ident_len, ENC_NA);
2659 offset += ident_len;
2662 return offset;
2666 * Performance and Diagnostic Metrics Destination Option (ietf-ippm-6man-pdm-option-13)
2668 0 1 2 3
2669 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
2670 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2671 | Option Type | Option Length | ScaleDTLR | ScaleDTLS |
2672 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2673 | PSN This Packet | PSN Last Received |
2674 |-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2675 | Delta Time Last Received | Delta Time Last Sent |
2676 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2678 static int
2679 dissect_opt_pdm(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *opt_tree,
2680 struct opt_proto_item *opt_ti _U_, uint8_t opt_len)
2682 if (opt_len != 10) {
2683 expert_add_info_format(pinfo, opt_ti->len, &ei_ipv6_opt_invalid_len,
2684 "PDM: Invalid length (%u bytes)", opt_len);
2686 proto_tree_add_item(opt_tree, hf_ipv6_opt_pdm_scale_dtlr, tvb, offset, 1, ENC_BIG_ENDIAN);
2687 offset += 1;
2688 proto_tree_add_item(opt_tree, hf_ipv6_opt_pdm_scale_dtls, tvb, offset, 1, ENC_BIG_ENDIAN);
2689 offset += 1;
2690 proto_tree_add_item(opt_tree, hf_ipv6_opt_pdm_psn_this_pkt, tvb, offset, 2, ENC_BIG_ENDIAN);
2691 offset += 2;
2692 proto_tree_add_item(opt_tree, hf_ipv6_opt_pdm_psn_last_recv, tvb, offset, 2, ENC_BIG_ENDIAN);
2693 offset += 2;
2694 proto_tree_add_item(opt_tree, hf_ipv6_opt_pdm_delta_last_recv, tvb, offset, 2, ENC_BIG_ENDIAN);
2695 offset += 2;
2696 proto_tree_add_item(opt_tree, hf_ipv6_opt_pdm_delta_last_sent, tvb, offset, 2, ENC_BIG_ENDIAN);
2697 offset += 2;
2699 return offset;
2703 * Home Address Option
2705 0 1 2 3
2706 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
2707 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2708 | Option Type | Option Length |
2709 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2713 + Home Address +
2717 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2719 static int
2720 dissect_opt_home_address(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *opt_tree,
2721 struct opt_proto_item *opt_ti, uint8_t opt_len)
2723 if (opt_len != 16) {
2724 expert_add_info_format(pinfo, opt_ti->len, &ei_ipv6_opt_invalid_len,
2725 "Home Address: Invalid length (%u bytes)", opt_len);
2727 proto_tree_add_item(opt_tree, hf_ipv6_opt_mipv6_home_address, tvb, offset, IPv6_ADDR_SIZE, ENC_NA);
2728 alloc_address_tvb_ipv6(pinfo->pool, &pinfo->src, tvb, offset);
2729 offset += IPv6_ADDR_SIZE;
2731 return offset;
2735 * ILNP Nonce Option
2738 0 1 2 3
2739 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
2740 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2741 | Next Header | Hdr Ext Len | Option Type | Option Length |
2742 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2743 / Nonce Value /
2744 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2746 static int
2747 dissect_opt_ilnp_nonce(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *opt_tree,
2748 struct opt_proto_item *opt_ti _U_, uint8_t opt_len)
2750 proto_tree_add_item(opt_tree, hf_ipv6_opt_ilnp_nonce, tvb, offset, opt_len, ENC_NA);
2751 offset += opt_len;
2753 return offset;
2757 * Line-Identification Option
2759 0 1 2 3
2760 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
2761 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2762 | Option Type | Option Length |
2763 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2764 | LineIDLen | Line ID...
2765 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2767 static int
2768 dissect_opt_lio(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *opt_tree,
2769 struct opt_proto_item *opt_ti _U_, uint8_t opt_len)
2771 uint32_t lid_len = 0;
2773 proto_tree_add_item_ret_uint(opt_tree, hf_ipv6_opt_lio_len, tvb, offset, 1, ENC_BIG_ENDIAN, &lid_len);
2774 offset += 1;
2776 if (lid_len + 1 > opt_len) {
2777 /* XXX Add expert info */
2778 lid_len = opt_len - 1;
2780 proto_tree_add_item(opt_tree, hf_ipv6_opt_lio_id, tvb, offset, lid_len, ENC_BIG_ENDIAN|ENC_ASCII);
2781 offset += lid_len;
2783 return offset;
2787 * MPL Option
2789 0 1 2 3
2790 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
2791 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2792 | Option Type | Opt Data Len |
2793 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2794 | S |M|V| rsv | sequence | seed-id (optional) |
2795 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2797 static int
2798 dissect_opt_mpl(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *opt_tree,
2799 struct opt_proto_item *opt_ti _U_, uint8_t opt_len _U_)
2801 static int * const mpl_flags[] = {
2802 &hf_ipv6_opt_mpl_flag_s,
2803 &hf_ipv6_opt_mpl_flag_m,
2804 &hf_ipv6_opt_mpl_flag_v,
2805 &hf_ipv6_opt_mpl_flag_rsv,
2806 NULL
2808 static const uint8_t seed_id_len_arr[4] = {0, 2, 8, 16};
2809 uint8_t seed_id_len;
2811 proto_tree_add_bitmask(opt_tree, tvb, offset, hf_ipv6_opt_mpl_flag, ett_ipv6_opt_mpl, mpl_flags, ENC_NA);
2812 seed_id_len = seed_id_len_arr[tvb_get_uint8(tvb, offset) >> 6];
2813 offset +=1;
2815 proto_tree_add_item(opt_tree, hf_ipv6_opt_mpl_sequence, tvb, offset, 1, ENC_NA);
2816 offset +=1;
2817 if (seed_id_len > 0) {
2818 proto_tree_add_item(opt_tree, hf_ipv6_opt_mpl_seed_id, tvb, offset, seed_id_len, ENC_NA);
2819 offset += seed_id_len;
2821 else {
2822 expert_add_info(pinfo, opt_ti->type, &ei_ipv6_opt_mpl_ipv6_src_seed_id);
2825 return offset;
2829 * IPv6 DFF Header
2831 1 2 3
2832 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
2833 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2834 | Next Header | Hdr Ext Len | OptTypeDFF | OptDataLenDFF |
2835 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2836 |VER|D|R|0|0|0|0| Sequence Number | Pad1 |
2837 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2839 static int
2840 dissect_opt_dff(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *opt_tree,
2841 struct opt_proto_item *opt_ti, uint8_t opt_len)
2843 static int * const dff_flags[] = {
2844 &hf_ipv6_opt_dff_flag_ver,
2845 &hf_ipv6_opt_dff_flag_dup,
2846 &hf_ipv6_opt_dff_flag_ret,
2847 &hf_ipv6_opt_dff_flag_rsv,
2848 NULL
2851 /* Option length is 3 octets */
2852 /* http://www.rfc-editor.org/errata_search.php?eid=3937 */
2853 if (opt_len != 3) {
2854 expert_add_info_format(pinfo, opt_ti->len, &ei_ipv6_opt_invalid_len,
2855 "IPv6 DFF: Invalid length (%u bytes)", opt_len);
2857 proto_tree_add_bitmask(opt_tree, tvb, offset, hf_ipv6_opt_dff_flags,
2858 ett_ipv6_opt_dff_flags, dff_flags, ENC_NA);
2859 offset += 1;
2860 proto_tree_add_item(opt_tree, hf_ipv6_opt_dff_seqnum, tvb, offset, 2, ENC_BIG_ENDIAN);
2861 offset += 2;
2863 return offset;
2866 static int
2867 dissect_opt_unknown(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *opt_tree,
2868 struct opt_proto_item *opt_ti _U_, uint8_t opt_len)
2870 proto_item *ti;
2872 ti = proto_tree_add_item(opt_tree, hf_ipv6_opt_unknown, tvb,
2873 offset, opt_len, ENC_NA);
2874 expert_add_info(pinfo, ti, &ei_ipv6_opt_unknown_data);
2876 return offset + opt_len;
2879 static int
2880 dissect_opts(tvbuff_t *tvb, int offset, proto_tree *tree, packet_info *pinfo, ws_ip6 *iph, const int exthdr_proto)
2882 int len, offset_end;
2883 uint8_t nxt;
2884 proto_tree *exthdr_tree, *opt_tree, *opt_type_tree, *root_tree;
2885 proto_item *pi, *ti, *ti_len;
2886 int hf_exthdr_item_nxt, hf_exthdr_item_len, hf_exthdr_item_len_oct;
2887 int ett_exthdr_proto;
2888 uint8_t opt_type, opt_len, opt_start;
2889 int opt_hdr_type;
2890 const char *opt_name;
2891 bool hopopts;
2892 struct opt_proto_item opt_ti;
2893 tvbuff_t *next_tvb;
2895 hopopts = (exthdr_proto == proto_ipv6_hopopts);
2897 nxt = tvb_get_uint8(tvb, offset);
2898 len = (tvb_get_uint8(tvb, offset + 1) + 1) << 3;
2899 offset_end = offset + len;
2901 root_tree = p_ipv6_pinfo_select_root(pinfo, tree);
2902 p_ipv6_pinfo_add_len(pinfo, len);
2904 /* !!! specify length */
2905 ti = proto_tree_add_item(root_tree, exthdr_proto, tvb, offset, len, ENC_NA);
2907 if (hopopts && ipv6_previous_layer_id(pinfo) != proto_ipv6) {
2908 /* IPv6 Hop-by-Hop must appear immediately after IPv6 header (RFC 2460) */
2909 expert_add_info(pinfo, ti, &ei_ipv6_hopopts_not_first);
2912 if (exthdr_proto == proto_ipv6_hopopts) {
2913 hf_exthdr_item_nxt = hf_ipv6_hopopts_nxt;
2914 hf_exthdr_item_len = hf_ipv6_hopopts_len;
2915 hf_exthdr_item_len_oct = hf_ipv6_hopopts_len_oct;
2916 ett_exthdr_proto = ett_ipv6_hopopts_proto;
2917 } else if (exthdr_proto == proto_ipv6_dstopts) {
2918 hf_exthdr_item_nxt = hf_ipv6_dstopts_nxt;
2919 hf_exthdr_item_len = hf_ipv6_dstopts_len;
2920 hf_exthdr_item_len_oct = hf_ipv6_dstopts_len_oct;
2921 ett_exthdr_proto = ett_ipv6_dstopts_proto;
2922 } else {
2923 DISSECTOR_ASSERT_NOT_REACHED();
2926 exthdr_tree = proto_item_add_subtree(ti, ett_exthdr_proto);
2928 proto_tree_add_item(exthdr_tree, hf_exthdr_item_nxt, tvb, offset, 1, ENC_BIG_ENDIAN);
2929 offset += 1;
2931 ti_len = proto_tree_add_item(exthdr_tree, hf_exthdr_item_len, tvb, offset, 1, ENC_BIG_ENDIAN);
2932 ti = proto_tree_add_uint(exthdr_tree, hf_exthdr_item_len_oct, tvb, offset, 1, len);
2933 proto_item_set_generated(ti);
2934 if (ipv6_exthdr_hide_len_oct_field) {
2935 proto_item_set_hidden(ti);
2936 proto_item_append_text(ti_len, " (%d bytes)", len);
2938 offset += 1;
2940 while (offset < offset_end) {
2941 /* there are more options */
2943 opt_type = tvb_get_uint8(tvb, offset);
2944 opt_len = tvb_get_uint8(tvb, offset + 1);
2945 opt_name = val_to_str_ext(opt_type, &ipv6_opt_type_vals_ext, "Unknown IPv6 Option (%u)");
2947 pi = proto_tree_add_none_format(exthdr_tree, hf_ipv6_opt, tvb, offset, 2 + opt_len,
2948 "%s", opt_name);
2949 opt_tree = proto_item_add_subtree(pi, ett_ipv6_opt);
2951 opt_ti.type = proto_tree_add_item(opt_tree, hf_ipv6_opt_type, tvb, offset, 1, ENC_BIG_ENDIAN);
2953 if (opt_type == IP6OPT_PAD1) {
2954 /* The Pad1 option is a special case, and contains no data. */
2955 proto_tree_add_item(opt_tree, hf_ipv6_opt_pad1, tvb, offset, 1, ENC_NA);
2956 offset += 1;
2957 continue;
2960 if ((opt_hdr_type = ipv6_opt_type_hdr(opt_type)) != IPv6_OPT_HDR_ANY) {
2961 if (hopopts && (opt_hdr_type == IPv6_OPT_HDR_DST)) {
2962 expert_add_info_format(pinfo, opt_ti.type, &ei_ipv6_opt_header_mismatch,
2963 "%s must use a destination options header", opt_name);
2965 else if (!hopopts && (opt_hdr_type == IPv6_OPT_HDR_HBH)) {
2966 expert_add_info_format(pinfo, opt_ti.type, &ei_ipv6_opt_header_mismatch,
2967 "%s must use a hop-by-hop options header", opt_name);
2971 opt_type_tree = proto_item_add_subtree(opt_ti.type, ett_ipv6_opt_type);
2972 proto_tree_add_item(opt_type_tree, hf_ipv6_opt_type_action, tvb, offset, 1, ENC_BIG_ENDIAN);
2973 proto_tree_add_item(opt_type_tree, hf_ipv6_opt_type_change, tvb, offset, 1, ENC_BIG_ENDIAN);
2974 proto_tree_add_item(opt_type_tree, hf_ipv6_opt_type_rest, tvb, offset, 1, ENC_BIG_ENDIAN);
2975 offset += 1;
2977 opt_ti.len = proto_tree_add_item(opt_tree, hf_ipv6_opt_length, tvb, offset, 1, ENC_BIG_ENDIAN);
2978 offset += 1;
2980 if (opt_type == IP6OPT_PADN) {
2981 /* RFC 2460 states :
2982 * "The PadN option is used to insert two or more octets of
2983 * padding into the Options area of a header. For N octets of
2984 * padding, the Opt Data Len field contains the value N-2, and
2985 * the Option Data consists of N-2 zero-valued octets."
2987 proto_tree_add_item(opt_tree, hf_ipv6_opt_padn, tvb, offset, opt_len, ENC_NA);
2988 offset += opt_len;
2989 continue;
2992 opt_start = offset;
2993 switch (opt_type) {
2994 case IP6OPT_JUMBO:
2995 offset = dissect_opt_jumbo(tvb, offset, pinfo, opt_tree, &opt_ti, opt_len);
2996 break;
2997 case IP6OPT_RPL:
2998 case IP6OPT_RPL_OLD:
2999 offset = dissect_opt_rpl(tvb, offset, pinfo, opt_tree, &opt_ti, opt_len);
3000 break;
3001 case IP6OPT_TEL:
3002 offset = dissect_opt_tel(tvb, offset, pinfo, opt_tree, &opt_ti, opt_len);
3003 break;
3004 case IP6OPT_RTALERT:
3005 offset = dissect_opt_rtalert(tvb, offset, pinfo, opt_tree, &opt_ti, opt_len);
3006 break;
3007 case IP6OPT_PMTU:
3008 offset = dissect_opt_pmtu(tvb, offset, pinfo, opt_tree, &opt_ti, opt_len);
3009 break;
3010 case IP6OPT_APN6:
3011 offset = dissect_opt_apn6(tvb, offset, pinfo, opt_tree, &opt_ti, opt_len);
3012 break;
3013 case IP6OPT_QUICKSTART:
3014 offset = dissect_opt_quickstart(tvb, offset, pinfo, opt_tree, &opt_ti, opt_len, iph);
3015 break;
3016 case IP6OPT_IOAM:
3017 offset = dissect_opt_ioam(tvb, offset, pinfo, opt_tree, &opt_ti, opt_len);
3018 break;
3019 case IP6OPT_TPF:
3020 offset = dissect_opt_tpf(tvb, offset, pinfo, opt_tree, &opt_ti, opt_len);
3021 break;
3022 case IP6OPT_CALIPSO:
3023 offset = dissect_opt_calipso(tvb, offset, pinfo, opt_tree, &opt_ti, opt_len);
3024 break;
3025 case IP6OPT_SMF_DPD:
3026 offset = dissect_opt_smf_dpd(tvb, offset, pinfo, opt_tree, &opt_ti, opt_len);
3027 break;
3028 case IP6OPT_PDM:
3029 offset = dissect_opt_pdm(tvb, offset, pinfo, opt_tree, &opt_ti, opt_len);
3030 break;
3031 case IP6OPT_HOME_ADDRESS:
3032 offset = dissect_opt_home_address(tvb, offset, pinfo, opt_tree, &opt_ti, opt_len);
3033 break;
3034 case IP6OPT_ILNP_NONCE:
3035 offset = dissect_opt_ilnp_nonce(tvb, offset, pinfo, opt_tree, &opt_ti, opt_len);
3036 break;
3037 case IP6OPT_LIO:
3038 offset = dissect_opt_lio(tvb, offset, pinfo, opt_tree, &opt_ti, opt_len);
3039 break;
3040 case IP6OPT_MPL:
3041 offset = dissect_opt_mpl(tvb, offset, pinfo, opt_tree, &opt_ti, opt_len);
3042 break;
3043 case IP6OPT_IP_DFF:
3044 offset = dissect_opt_dff(tvb, offset, pinfo, opt_tree, &opt_ti, opt_len);
3045 break;
3046 case IP6OPT_ENDI:
3047 offset = dissect_opt_unknown(tvb, offset, pinfo, opt_tree, &opt_ti, opt_len);
3048 expert_add_info(pinfo, opt_ti.type, &ei_ipv6_opt_deprecated);
3049 break;
3050 case IP6OPT_EXP_1E:
3051 case IP6OPT_EXP_3E:
3052 case IP6OPT_EXP_5E:
3053 case IP6OPT_EXP_7E:
3054 case IP6OPT_EXP_9E:
3055 case IP6OPT_EXP_BE:
3056 case IP6OPT_EXP_DE:
3057 case IP6OPT_EXP_FE:
3058 proto_tree_add_item(opt_tree, hf_ipv6_opt_experimental, tvb,
3059 offset, opt_len, ENC_NA);
3060 offset += opt_len;
3061 break;
3062 default:
3063 offset = dissect_opt_unknown(tvb, offset, pinfo, opt_tree, &opt_ti, opt_len);
3064 break;
3066 if (offset < opt_start + opt_len) {
3067 ti = proto_tree_add_item(opt_tree, hf_ipv6_opt_unknown_data, tvb,
3068 offset, opt_start + opt_len - offset, ENC_NA);
3069 expert_add_info(pinfo, ti, &ei_ipv6_opt_unknown_data);
3070 offset = opt_start + opt_len;
3074 p_add_ipv6_nxt(pinfo, nxt);
3076 next_tvb = tvb_new_subset_remaining(tvb, len);
3077 ipv6_dissect_next(nxt, next_tvb, pinfo, tree, iph);
3078 return tvb_captured_length(tvb);
3081 static int
3082 dissect_hopopts(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
3084 col_append_sep_str(pinfo->cinfo, COL_INFO, " , ", "IPv6 hop-by-hop options");
3086 return dissect_opts(tvb, 0, tree, pinfo, (ws_ip6 *)data, proto_ipv6_hopopts);
3089 static int
3090 dissect_dstopts(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
3092 col_append_sep_str(pinfo->cinfo, COL_INFO, " , ", "IPv6 destination options");
3094 return dissect_opts(tvb, 0, tree, pinfo, (ws_ip6 *)data, proto_ipv6_dstopts);
3097 /* return value is > UINT16_MAX, else zero */
3098 /* tvb + offset contains the Hbh header */
3099 static uint32_t
3100 ipv6_get_jumbo_plen(tvbuff_t *tvb, int offset)
3102 int offset_end, hdr_len;
3103 int opt_type, opt_len;
3104 uint32_t jumbo_plen;
3106 if (!tvb_bytes_exist(tvb, offset, 2)) {
3107 return 0;
3109 hdr_len = (tvb_get_uint8(tvb, offset + 1) + 1) * 8;
3110 offset_end = offset + hdr_len;
3111 offset +=2;
3113 while (offset < offset_end && tvb_bytes_exist(tvb, offset, 6)) {
3114 opt_type = tvb_get_uint8(tvb, offset);
3115 offset += 1;
3116 if (opt_type == IP6OPT_PAD1) {
3117 continue;
3119 opt_len = tvb_get_uint8(tvb, offset);
3120 offset += 1;
3121 if (opt_type == IP6OPT_JUMBO && opt_len == 4) {
3122 jumbo_plen = tvb_get_uint32(tvb, offset, ENC_BIG_ENDIAN);
3123 if (jumbo_plen > UINT16_MAX) {
3124 return jumbo_plen;
3126 return 0;
3128 offset += opt_len;
3130 return 0;
3133 static void
3134 add_ipv6_address_detail(packet_info *pinfo, proto_item *vis, proto_item *invis,
3135 tvbuff_t *tvb, int offset, struct ipv6_addr_info_s *addr_info)
3137 proto_item *ti;
3138 proto_tree *vtree; /* visible tree */
3139 proto_tree *itree; /* invisible tree */
3141 vtree = proto_item_add_subtree(vis, ett_ipv6_detail);
3142 itree = proto_item_add_subtree(invis, ett_ipv6_detail);
3145 * Internet Protocol Version 6 Address Space
3146 * https://www.iana.org/assignments/ipv6-address-space/ipv6-address-space.xhtml
3148 if (tvb_get_uint8(tvb, offset) == 0xFF) {
3149 /* RFC 4291 section 2.4: multicast prefix */
3150 ti = proto_tree_add_string(vtree, *addr_info->hf_addr_space, tvb, offset, 1, "Multicast");
3151 proto_item_set_generated(ti);
3152 if (addr_info == &ipv6_src_info) {
3153 /* "Shouldn't" see this one as a source */
3154 expert_add_info(pinfo, ti, &ei_ipv6_src_addr_not_multicast);
3157 ti = proto_tree_add_string(itree, hf_ipv6_addr_space, tvb, offset, 1, "Multicast");
3158 proto_item_set_generated(ti);
3161 * Multicast address scope and flags.
3163 * RFC 4291 Section 2.7:
3164 * https://www.rfc-editor.org/rfc/rfc4291#section-2.7
3166 * RFC 7346:
3167 * https://www.rfc-editor.org/rfc/rfc7346.html
3169 * IANA Registry:
3170 * https://www.iana.org/assignments/ipv6-multicast-addresses/ipv6-multicast-addresses.xhtml#ipv6-scope
3173 static int *const hf_ipv6_multicast_flags_bits[] = {
3174 &hf_ipv6_multicast_flags_reserved,
3175 &hf_ipv6_multicast_flags_embed_rp,
3176 &hf_ipv6_multicast_flags_network_prefix,
3177 &hf_ipv6_multicast_flags_transient,
3178 NULL
3181 /* Add multicast address flags. */
3182 ti = proto_tree_add_bitmask(vtree, tvb, offset, *addr_info->hf_multicast_flags,
3183 ett_ipv6_multicast_flags, addr_info->hf_multicast_flags_bits, ENC_BIG_ENDIAN);
3184 proto_item_set_generated(ti);
3185 ti = proto_tree_add_bitmask(itree, tvb, offset, hf_ipv6_multicast_flags,
3186 ett_ipv6_multicast_flags, hf_ipv6_multicast_flags_bits, ENC_BIG_ENDIAN);
3187 proto_item_set_generated(ti);
3189 /* Add multicast address scope. */
3190 ti = proto_tree_add_item(vtree, *addr_info->hf_multicast_scope, tvb, offset, 2, ENC_BIG_ENDIAN);
3191 proto_item_set_generated(ti);
3192 ti = proto_tree_add_item(itree, hf_ipv6_multicast_scope, tvb, offset, 2, ENC_BIG_ENDIAN);
3193 proto_item_set_generated(ti);
3195 else if ((tvb_get_ntohs(tvb, offset) & 0xFFC0) == 0xFE80) {
3196 ti = proto_tree_add_string(vtree, *addr_info->hf_addr_space, tvb, offset, 2, "Link-Local Unicast");
3197 proto_item_set_generated(ti);
3198 ti = proto_tree_add_string(itree, hf_ipv6_addr_space, tvb, offset, 2, "Link-Local Unicast");
3199 proto_item_set_generated(ti);
3201 else if ((tvb_get_uint8(tvb, offset) & 0x30) == 0x20) {
3202 ti = proto_tree_add_string(vtree, *addr_info->hf_addr_space, tvb, offset, 2, "Global Unicast");
3203 proto_item_set_generated(ti);
3204 ti = proto_tree_add_string(itree, hf_ipv6_addr_space, tvb, offset, 2, "Global Unicast");
3205 proto_item_set_generated(ti);
3207 else if ((tvb_get_uint8(tvb, offset) & 0xFE) == 0xFC) {
3208 ti = proto_tree_add_string(vtree, *addr_info->hf_addr_space, tvb, offset, 2, "Unique Local Unicast");
3209 proto_item_set_generated(ti);
3210 ti = proto_tree_add_string(itree, hf_ipv6_addr_space, tvb, offset, 2, "Unique Local Unicast");
3211 proto_item_set_generated(ti);
3213 else {
3214 ti = proto_tree_add_string(vtree, *addr_info->hf_addr_space, tvb, offset, 2, "Reserved by IETF");
3215 proto_item_set_generated(ti);
3216 ti = proto_tree_add_string(itree, hf_ipv6_addr_space, tvb, offset, 2, "Reserved by IETF");
3217 proto_item_set_generated(ti);
3220 /* Check for IPv6 address special-purpose ranges. */
3221 const ws_in6_addr *addr = tvb_get_ptr_ipv6(tvb, offset);
3222 const struct ws_iana_ip_special_block *block;
3223 proto_tree *vtree2;
3224 proto_tree *itree2;
3226 if ((block = ws_iana_ipv6_special_block_lookup(addr)) != NULL) {
3227 ti = proto_tree_add_string(vtree, *addr_info->hf_special_purpose, tvb, offset, IPv6_ADDR_SIZE, block->name);
3228 proto_item_set_generated(ti);
3229 vtree2 = proto_item_add_subtree(ti, ett_ipv6_detail_special_purpose);
3231 ti = proto_tree_add_string(itree, hf_ipv6_addr_special_purpose, tvb, offset, IPv6_ADDR_SIZE, block->name);
3232 proto_item_set_generated(ti);
3233 itree2 = proto_item_add_subtree(ti, ett_ipv6_detail_special_purpose);
3235 if (block->source >= 0) {
3236 ti = proto_tree_add_boolean(vtree2, *addr_info->hf_special_purpose_source, tvb, offset, IPv6_ADDR_SIZE, block->source);
3237 proto_item_set_generated(ti);
3238 ti = proto_tree_add_boolean(itree2, hf_ipv6_addr_special_purpose_source, tvb, offset, IPv6_ADDR_SIZE, block->source);
3239 proto_item_set_generated(ti);
3241 if (block->destination >= 0) {
3242 ti = proto_tree_add_boolean(vtree2, *addr_info->hf_special_purpose_destination, tvb, offset, IPv6_ADDR_SIZE, block->destination);
3243 proto_item_set_generated(ti);
3244 ti = proto_tree_add_boolean(itree2, hf_ipv6_addr_special_purpose_destination, tvb, offset, IPv6_ADDR_SIZE, block->destination);
3245 proto_item_set_generated(ti);
3247 if (block->forwardable >= 0) {
3248 ti = proto_tree_add_boolean(vtree2, *addr_info->hf_special_purpose_forwardable, tvb, offset, IPv6_ADDR_SIZE, block->forwardable);
3249 proto_item_set_generated(ti);
3250 ti = proto_tree_add_boolean(itree2, hf_ipv6_addr_special_purpose_forwardable, tvb, offset, IPv6_ADDR_SIZE, block->forwardable);
3251 proto_item_set_generated(ti);
3253 if (block->global >= 0) {
3254 ti = proto_tree_add_boolean(vtree2, *addr_info->hf_special_purpose_global, tvb, offset, IPv6_ADDR_SIZE, block->global);
3255 proto_item_set_generated(ti);
3256 ti = proto_tree_add_boolean(itree2, hf_ipv6_addr_special_purpose_global, tvb, offset, IPv6_ADDR_SIZE, block->global);
3257 proto_item_set_generated(ti);
3259 if (block->reserved >= 0) {
3260 ti = proto_tree_add_boolean(vtree2, *addr_info->hf_special_purpose_reserved, tvb, offset, IPv6_ADDR_SIZE, block->reserved);
3261 proto_item_set_generated(ti);
3262 ti = proto_tree_add_boolean(itree2, hf_ipv6_addr_special_purpose_reserved, tvb, offset, IPv6_ADDR_SIZE, block->reserved);
3263 proto_item_set_generated(ti);
3268 static void
3269 add_ipv6_address(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset,
3270 struct ipv6_addr_info_s *addr_info)
3272 ws_in6_addr addr;
3273 const char *name;
3274 proto_item *ti, *vis, *invis;
3276 vis = proto_tree_add_item(tree, *addr_info->hf_addr, tvb, offset, IPv6_ADDR_SIZE, ENC_NA);
3277 invis = proto_tree_add_item(tree, hf_ipv6_addr, tvb, offset, IPv6_ADDR_SIZE, ENC_NA);
3278 proto_item_set_hidden(invis);
3280 if (ipv6_address_detail) {
3281 add_ipv6_address_detail(pinfo, vis, invis, tvb, offset, addr_info);
3284 if (!proto_field_is_referenced(tree, *addr_info->hf_host) &&
3285 !proto_field_is_referenced(tree, hf_ipv6_host)) {
3287 return;
3290 tvb_get_ipv6(tvb, offset, &addr);
3291 name = get_hostname6_wmem(pinfo->pool, &addr);
3292 ti = proto_tree_add_string(tree, *addr_info->hf_host, tvb, offset, IPv6_ADDR_SIZE, name);
3293 proto_item_set_generated(ti);
3294 proto_item_set_hidden(ti);
3295 ti = proto_tree_add_string(tree, hf_ipv6_host, tvb, offset, IPv6_ADDR_SIZE, name);
3296 proto_item_set_generated(ti);
3297 proto_item_set_hidden(ti);
3300 #define ADDRESS_SET_GENERATED_HIDDEN(ti) \
3301 G_STMT_START { \
3302 proto_item_set_generated(ti); \
3303 if (i > 0) proto_item_set_hidden(ti); \
3304 } G_STMT_END
3306 /* RFC 3056 section 2 */
3307 static void
3308 add_ipv6_address_6to4(proto_tree *tree, tvbuff_t *tvb, int offset,
3309 int hf_gateway, int hf_sla_id)
3311 if (tvb_get_ntohs(tvb, offset) != 0x2002)
3312 return;
3314 struct { int gateway, sla_id; } hf[2] = {
3315 { hf_gateway, hf_sla_id},
3316 { hf_ipv6_6to4_gateway_ipv4, hf_ipv6_6to4_sla_id}
3318 proto_item *ti;
3319 for (int i = 0; i < 2; i++) {
3320 ti = proto_tree_add_item(tree, hf[i].gateway, tvb, offset + 2, 4, ENC_BIG_ENDIAN);
3321 ADDRESS_SET_GENERATED_HIDDEN(ti);
3322 ti = proto_tree_add_item(tree, hf[i].sla_id, tvb, offset + 6, 2, ENC_BIG_ENDIAN);
3323 ADDRESS_SET_GENERATED_HIDDEN(ti);
3327 /* RFC 4380 section 4 */
3328 static void
3329 add_ipv6_address_teredo(proto_tree *tree, tvbuff_t *tvb, int offset,
3330 int hf_server, int hf_port, int hf_client)
3332 if (tvb_get_ntohl(tvb, offset) != 0x20010000)
3333 return;
3335 uint16_t mapped_port = tvb_get_ntohs(tvb, offset + 10) ^ 0xffff;
3336 uint32_t client_v4 = tvb_get_ipv4(tvb, offset + 12) ^ 0xffffffff;
3338 struct { int server, port, client; } hf[2] = {
3339 { hf_server, hf_port, hf_client },
3340 { hf_ipv6_teredo_server_ipv4, hf_ipv6_teredo_port, hf_ipv6_teredo_client_ipv4 }
3342 proto_item *ti;
3343 for (int i = 0; i < 2; i++) {
3344 ti = proto_tree_add_item(tree, hf[i].server, tvb, offset + 4, 4, ENC_BIG_ENDIAN);
3345 ADDRESS_SET_GENERATED_HIDDEN(ti);
3346 ti = proto_tree_add_uint(tree, hf[i].port, tvb, offset + 10, 2, mapped_port);
3347 ADDRESS_SET_GENERATED_HIDDEN(ti);
3348 ti = proto_tree_add_ipv4(tree, hf[i].client, tvb, offset + 12, 4, client_v4);
3349 ADDRESS_SET_GENERATED_HIDDEN(ti);
3353 /* RFC 4291 appendix A */
3354 static void
3355 add_ipv6_address_slaac(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset, int hf_slaac)
3357 if (!(tvb_get_uint8(tvb, offset + 8) & 0x02) ||
3358 !(tvb_get_ntohs(tvb, offset + 11) == 0xfffe)) {
3359 return;
3362 uint8_t *mac_addr = (uint8_t *)wmem_alloc(pinfo->pool, 6);
3363 tvb_memcpy(tvb, mac_addr, offset + 8, 3);
3364 tvb_memcpy(tvb, mac_addr+3, offset + 13, 3);
3365 mac_addr[0] &= ~0x02;
3367 struct { int mac; } hf[2] = {
3368 { hf_slaac },
3369 { hf_ipv6_slaac_mac }
3371 proto_item *ti;
3372 for (int i = 0; i < 2; i++) {
3373 ti = proto_tree_add_ether(tree, hf[i].mac, tvb, offset + 8, 8, mac_addr);
3374 ADDRESS_SET_GENERATED_HIDDEN(ti);
3378 /* RFC 5214 section 6.1 */
3379 static void
3380 add_ipv6_address_isatap(proto_tree *tree, tvbuff_t *tvb, int offset, int hf_isatap)
3382 if ((tvb_get_ntohl(tvb, offset + 8) & 0xfcffffff) != 0x00005efe)
3383 return;
3385 struct { int ipv4; } hf[2] = {
3386 { hf_isatap },
3387 { hf_ipv6_isatap_ipv4 }
3389 proto_item *ti;
3390 for (int i = 0; i < 2; i++) {
3391 ti = proto_tree_add_item(tree, hf[i].ipv4, tvb, offset + 12, 4, ENC_BIG_ENDIAN);
3392 ADDRESS_SET_GENERATED_HIDDEN(ti);
3396 /* RFC 6052 */
3397 static void
3398 add_ipv6_address_embed_ipv4(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset, int hf_embed)
3400 /* Section 2.1: Well-Known Prefix for IPv4-Embedded IPv6 Address: 64:FF9B::/96 */
3401 static const uint8_t well_known_prefix[] = {
3402 0x00, 0x64, 0xFF, 0x9B,
3403 0x00, 0x00, 0x00, 0x00,
3404 0x00, 0x00, 0x00, 0x00
3407 ws_in6_addr ipv6_addr;
3408 ws_in4_addr ipv4_addr;
3409 int ipv4_prefix;
3410 int ipv4_offset;
3411 bool ipv6_embed_ipv4 = false;
3413 if (tvb_memeql(tvb, offset, well_known_prefix, sizeof well_known_prefix) == 0) {
3414 ipv4_addr = tvb_get_bits32(tvb, (offset * 8) + 96, 32, ENC_BIG_ENDIAN);
3415 ipv4_prefix = 96;
3416 ipv4_offset = 96;
3417 ipv6_embed_ipv4 = true;
3418 } else {
3419 for (size_t j = 0; j < number_of_nat64_prefix; j++) {
3420 if (nat64_prefix_uats[j].prefix_len <= nat64_prefix_uats[j].prefix_wildcard_len) {
3421 continue;
3424 if (ws_inet_pton6(nat64_prefix_uats[j].ipaddr, &ipv6_addr)) {
3425 if (tvb_memeql(tvb, offset, (const uint8_t *)&ipv6_addr,
3426 (nat64_prefix_uats[j].prefix_len - nat64_prefix_uats[j].prefix_wildcard_len) / 8) == 0) {
3427 switch (nat64_prefix_uats[j].prefix_len)
3429 case 32:
3430 ipv4_addr = tvb_get_bits32(tvb, (offset * 8) + 32, 32, ENC_BIG_ENDIAN);
3431 break;
3432 case 40:
3433 ipv4_addr = tvb_get_bits32(tvb, (offset * 8) + 40, 24, ENC_BIG_ENDIAN) << 8;
3434 ipv4_addr |= tvb_get_bits32(tvb, (offset * 8) + 72, 8, ENC_BIG_ENDIAN);
3435 break;
3436 case 48:
3437 ipv4_addr = tvb_get_bits32(tvb, (offset * 8) + 48, 16, ENC_BIG_ENDIAN) << 16;
3438 ipv4_addr |= tvb_get_bits32(tvb, (offset * 8) + 72, 16, ENC_BIG_ENDIAN);
3439 break;
3440 case 56:
3441 ipv4_addr = tvb_get_bits32(tvb, (offset * 8) + 56, 8, ENC_BIG_ENDIAN) << 24;
3442 ipv4_addr |= tvb_get_bits32(tvb, (offset * 8) + 72, 24, ENC_BIG_ENDIAN);
3443 break;
3444 case 64:
3445 ipv4_addr = tvb_get_bits32(tvb, (offset * 8) + 72, 32, ENC_BIG_ENDIAN);
3446 break;
3447 case 96:
3448 ipv4_addr = tvb_get_bits32(tvb, (offset * 8) + 96, 32, ENC_BIG_ENDIAN);
3449 break;
3450 default:
3451 DISSECTOR_ASSERT_NOT_REACHED();
3454 ipv4_prefix = nat64_prefix_uats[j].prefix_len;
3455 if (ipv4_prefix != 64) {
3456 ipv4_offset = ipv4_prefix;
3457 } else {
3458 ipv4_offset = 72;
3460 ipv6_embed_ipv4 = true;
3461 break;
3467 if (ipv6_embed_ipv4) {
3468 proto_item *ti;
3470 // The prefix
3471 ti = proto_tree_add_item(tree, hf_ipv6_embed_ipv4_prefix, tvb, offset, ipv4_prefix / 8, ENC_NA);
3472 proto_item_set_generated(ti);
3474 // Majority of IPv4 address is after u-field
3475 if (ipv4_prefix >= 56) {
3476 if (ipv4_prefix < 96) {
3477 ti = proto_tree_add_item(tree, hf_ipv6_embed_ipv4_u, tvb, offset + 8, 1, ENC_NA);
3478 proto_item_set_generated(ti);
3480 if (tvb_get_uint8(tvb, offset + 8)) {
3481 expert_add_info(pinfo, ti, &ei_ipv6_embed_ipv4_u_value);
3485 // IPv4 embedded address
3486 ipv4_addr = g_ntohl(ipv4_addr);
3487 ti = proto_tree_add_ipv4(tree, hf_embed, tvb,
3488 offset + (ipv4_offset / 8),
3489 (ipv4_offset > 32 && ipv4_offset < 64) ? 5 : 4, ipv4_addr);
3490 proto_item_set_generated(ti);
3492 ti = proto_tree_add_ipv4(tree, hf_ipv6_embed_ipv4, tvb,
3493 offset + (ipv4_offset / 8),
3494 (ipv4_offset > 32 && ipv4_offset < 64) ? 5 : 4, ipv4_addr);
3495 proto_item_set_generated(ti);
3497 // Majority of IPv4 address is before u-field
3498 if (ipv4_prefix < 56) {
3499 ti = proto_tree_add_item(tree, hf_ipv6_embed_ipv4_u, tvb, offset + 8, 1, ENC_NA);
3500 proto_item_set_generated(ti);
3501 if (tvb_get_uint8(tvb, offset + 8)) {
3502 expert_add_info(pinfo, ti, &ei_ipv6_embed_ipv4_u_value);
3506 // Suffix, if present
3507 if (ipv4_prefix < 96) {
3508 ti = proto_tree_add_item(tree, hf_ipv6_embed_ipv4_suffix, tvb,
3509 offset + ((72 + ipv4_prefix - 32) / 8),
3510 (56 - (ipv4_prefix - 32)) / 8,
3511 ENC_NA);
3512 proto_item_set_generated(ti);
3517 static void
3518 export_pdu(tvbuff_t *tvb, packet_info *pinfo)
3520 if (have_tap_listener(exported_pdu_tap)) {
3521 exp_pdu_data_t *exp_pdu_data = wmem_new0(pinfo->pool, exp_pdu_data_t);
3523 exp_pdu_data->tvb_captured_length = tvb_captured_length(tvb);
3524 exp_pdu_data->tvb_reported_length = tvb_reported_length(tvb);
3525 exp_pdu_data->pdu_tvb = tvb;
3526 tap_queue_packet(exported_pdu_tap, pinfo, exp_pdu_data);
3530 static struct ipv6_analysis *
3531 init_ipv6_conversation_data(packet_info *pinfo)
3533 struct ipv6_analysis *ipv6d;
3535 /* Initialize the ip protocol data structure to add to the ip conversation */
3536 ipv6d=wmem_new0(wmem_file_scope(), struct ipv6_analysis);
3538 ipv6d->initial_frame = pinfo->num;
3539 ipv6d->stream = 0;
3540 ipv6d->stream = ipv6_stream_count++;
3542 return ipv6d;
3545 struct ipv6_analysis *
3546 get_ipv6_conversation_data(conversation_t *conv, packet_info *pinfo)
3548 struct ipv6_analysis *ipv6d;
3550 /* Did the caller supply the conversation pointer? */
3551 if( conv==NULL ) {
3552 return NULL;
3555 /* Get the data for this conversation */
3556 ipv6d=(struct ipv6_analysis *)conversation_get_proto_data(conv, proto_ipv6);
3558 if (!ipv6d) {
3559 ipv6d = init_ipv6_conversation_data(pinfo);
3560 conversation_add_proto_data(conv, proto_ipv6, ipv6d);
3563 if (!ipv6d) {
3564 return NULL;
3567 return ipv6d;
3570 static int
3571 dissect_ipv6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
3573 proto_tree *ipv6_tree, *pt;
3574 proto_item *ipv6_item, *ti, *pi;
3575 proto_item *ti_ipv6_plen = NULL, *ti_ipv6_version;
3576 uint8_t ip6_tcls, ip6_nxt, ip6_hlim;
3577 uint32_t ip6_flow;
3578 const ws_in6_addr *ip6_src, *ip6_dst;
3579 uint32_t ip6_plen = 0, jumbo_plen = 0;
3580 uint32_t plen;
3581 int offset;
3582 unsigned reported_plen;
3583 tvbuff_t *next_tvb;
3584 bool save_fragmented;
3585 int version;
3586 ws_ip6 *iph;
3587 struct ipv6_analysis *ipv6d=NULL;
3589 offset = 0;
3591 iph = wmem_new0(pinfo->pool, ws_ip6);
3593 col_set_str(pinfo->cinfo, COL_PROTOCOL, "IPv6");
3594 col_clear(pinfo->cinfo, COL_INFO);
3596 ipv6_item = proto_tree_add_item(tree, proto_ipv6, tvb, offset, IPv6_HDR_SIZE, ENC_NA);
3597 ipv6_tree = proto_item_add_subtree(ipv6_item, ett_ipv6_proto);
3600 /* Validate IP version (6) */
3601 version = tvb_get_bits8(tvb, (offset + IP6H_CTL_VFC) * 8, 4);
3602 ti_ipv6_version = proto_tree_add_bits_item(ipv6_tree, hf_ipv6_version, tvb,
3603 (offset + IP6H_CTL_VFC) * 8, 4, ENC_BIG_ENDIAN);
3604 pi = proto_tree_add_item(ipv6_tree, hf_ip_version, tvb,
3605 offset + IP6H_CTL_VFC, 1, ENC_BIG_ENDIAN);
3606 proto_item_append_text(pi, " [This field makes the filter match on \"ip.version == 6\" possible]");
3607 proto_item_set_hidden(pi);
3608 if (version != 6) {
3609 col_add_fstr(pinfo->cinfo, COL_INFO,
3610 "Bogus IPv6 version (%u, must be 6)", version);
3611 expert_add_info_format(pinfo, ti_ipv6_version, &ei_ipv6_bogus_ipv6_version, "Bogus IPv6 version");
3612 return offset + IP6H_CTL_VFC;
3615 /* Validate header size (40 bytes) */
3616 if (tvb_reported_length(tvb) < IPv6_HDR_SIZE) {
3617 col_add_fstr(pinfo->cinfo, COL_INFO,
3618 "Invalid IPv6 header (%u bytes, need exactly 40)",
3619 tvb_reported_length(tvb));
3620 expert_add_info_format(pinfo, ipv6_item, &ei_ipv6_invalid_header,
3621 "IPv6 header must be exactly 40 bytes");
3624 /* !!! warning: (4-bit) version, (6-bit) DSCP, (2-bit) ECN and (20-bit) Flow */
3625 ti = proto_tree_add_item(ipv6_tree, hf_ipv6_tclass, tvb,
3626 offset + IP6H_CTL_VFC, 4, ENC_BIG_ENDIAN);
3627 ip6_tcls = tvb_get_bits8(tvb, (offset + IP6H_CTL_VFC) * 8 + 4, 8);
3628 proto_item_append_text(ti, " (DSCP: %s, ECN: %s)",
3629 val_to_str_ext_const(IPDSFIELD_DSCP(ip6_tcls), &dscp_short_vals_ext, "Unknown"),
3630 val_to_str_ext_const(IPDSFIELD_ECN(ip6_tcls), &ecn_short_vals_ext, "Unknown"));
3632 pt = proto_item_add_subtree(ti, ett_ipv6_traffic_class);
3633 proto_tree_add_item(pt, hf_ipv6_tclass_dscp, tvb,
3634 offset + IP6H_CTL_VFC, 4, ENC_BIG_ENDIAN);
3635 proto_tree_add_item(pt, hf_ipv6_tclass_ecn, tvb,
3636 offset + IP6H_CTL_VFC, 4, ENC_BIG_ENDIAN);
3638 /* Set DSCP column */
3639 col_add_str(pinfo->cinfo, COL_DSCP_VALUE,
3640 val_to_str_ext(IPDSFIELD_DSCP(ip6_tcls), &dscp_short_vals_ext, "%u"));
3642 proto_tree_add_item_ret_uint(ipv6_tree, hf_ipv6_flow, tvb,
3643 offset + IP6H_CTL_FLOW + 1, 3, ENC_BIG_ENDIAN, &ip6_flow);
3645 ip6_plen = tvb_get_uint16(tvb, offset + IP6H_CTL_PLEN, ENC_BIG_ENDIAN);
3647 ip6_nxt = tvb_get_uint8(tvb, offset + IP6H_CTL_NXT);
3649 if (ipv6_tso_supported && ip6_plen == 0 &&
3650 ip6_nxt != IP_PROTO_HOPOPTS && ip6_nxt != IP_PROTO_NONE) {
3651 ip6_plen = tvb_reported_length(tvb) - IPv6_HDR_SIZE;
3652 pi = proto_tree_add_uint_format_value(ipv6_tree, hf_ipv6_plen, tvb,
3653 offset + IP6H_CTL_PLEN, 2, ip6_plen,
3654 "%u bytes (reported as 0, presumed to be because "
3655 "of \"TCP segmentation offload\" (TSO))",
3656 ip6_plen);
3657 proto_item_set_generated(pi);
3658 } else {
3659 ti_ipv6_plen = proto_tree_add_item(ipv6_tree, hf_ipv6_plen, tvb,
3660 offset + IP6H_CTL_PLEN, 2, ENC_BIG_ENDIAN);
3661 if (ip6_plen == 0 && ip6_nxt != IP_PROTO_HOPOPTS && ip6_nxt != IP_PROTO_NONE) {
3662 expert_add_info(pinfo, ti_ipv6_plen, &ei_ipv6_plen_zero);
3666 proto_tree_add_item(ipv6_tree, hf_ipv6_nxt, tvb, offset + IP6H_CTL_NXT, 1, ENC_NA);
3668 proto_tree_add_item(ipv6_tree, hf_ipv6_hlim, tvb,
3669 offset + IP6H_CTL_HLIM, 1, ENC_BIG_ENDIAN);
3670 ip6_hlim = tvb_get_uint8(tvb, offset + IP6H_CTL_HLIM);
3672 /* Source address */
3673 add_ipv6_address(pinfo, ipv6_tree, tvb, offset + IP6H_SRC, &ipv6_src_info);
3674 ip6_src = tvb_get_ptr_ipv6(tvb, offset + IP6H_SRC);
3675 alloc_address_wmem_ipv6(pinfo->pool, &pinfo->net_src, ip6_src);
3676 copy_address_shallow(&pinfo->src, &pinfo->net_src);
3678 /* Destination address */
3679 add_ipv6_address(pinfo, ipv6_tree, tvb, offset + IP6H_DST, &ipv6_dst_info);
3680 ip6_dst = tvb_get_ptr_ipv6(tvb, offset + IP6H_DST);
3681 alloc_address_wmem_ipv6(pinfo->pool, &pinfo->net_dst, ip6_dst);
3682 copy_address_shallow(&pinfo->dst, &pinfo->net_dst);
3684 if (tree) {
3685 if (ipv6_summary_in_tree) {
3686 proto_item_append_text(ipv6_item, ", Src: %s, Dst: %s",
3687 address_with_resolution_to_str(pinfo->pool, &pinfo->src),
3688 address_with_resolution_to_str(pinfo->pool, &pinfo->dst));
3691 /* Add the different items for the address */
3692 add_ipv6_address_6to4(ipv6_tree, tvb, offset + IP6H_SRC,
3693 hf_ipv6_src_6to4_gateway_ipv4, hf_ipv6_src_6to4_sla_id);
3694 add_ipv6_address_6to4(ipv6_tree, tvb, offset + IP6H_DST,
3695 hf_ipv6_dst_6to4_gateway_ipv4, hf_ipv6_dst_6to4_sla_id);
3697 add_ipv6_address_teredo(ipv6_tree, tvb, offset + IP6H_SRC,
3698 hf_ipv6_src_teredo_server_ipv4, hf_ipv6_src_teredo_port, hf_ipv6_src_teredo_client_ipv4);
3699 add_ipv6_address_teredo(ipv6_tree, tvb, offset + IP6H_DST,
3700 hf_ipv6_dst_teredo_server_ipv4, hf_ipv6_dst_teredo_port, hf_ipv6_dst_teredo_client_ipv4);
3702 add_ipv6_address_slaac(pinfo, ipv6_tree, tvb, offset + IP6H_SRC, hf_ipv6_src_slaac_mac);
3703 add_ipv6_address_slaac(pinfo, ipv6_tree, tvb, offset + IP6H_DST, hf_ipv6_dst_slaac_mac);
3705 add_ipv6_address_isatap(ipv6_tree, tvb, offset + IP6H_SRC, hf_ipv6_src_isatap_ipv4);
3706 add_ipv6_address_isatap(ipv6_tree, tvb, offset + IP6H_DST, hf_ipv6_dst_isatap_ipv4);
3708 add_ipv6_address_embed_ipv4(pinfo, ipv6_tree, tvb, offset + IP6H_SRC, hf_ipv6_src_embed_ipv4);
3709 add_ipv6_address_embed_ipv4(pinfo, ipv6_tree, tvb, offset + IP6H_DST, hf_ipv6_dst_embed_ipv4);
3711 if (gbl_resolv_flags.maxmind_geoip) {
3712 add_geoip_info(ipv6_tree, pinfo, tvb, offset, ip6_src, ip6_dst);
3716 /* Increment offset to point to next header (may be an extension header) */
3717 offset += IPv6_HDR_SIZE;
3719 /* Check for Jumbo option */
3720 plen = ip6_plen;
3721 if (plen == 0 && ip6_nxt == IP_PROTO_HOPOPTS) {
3722 jumbo_plen = ipv6_get_jumbo_plen(tvb, offset);
3723 if (jumbo_plen != 0) {
3724 proto_item_append_text(ti_ipv6_plen, " (Jumbogram)");
3725 plen = jumbo_plen;
3726 } else {
3727 /* IPv6 length zero is invalid if there is a hop-by-hop header without jumbo option */
3728 col_set_str(pinfo->cinfo, COL_INFO, "Invalid IPv6 payload length");
3729 expert_add_info(pinfo, ti_ipv6_plen, &ei_ipv6_opt_jumbo_missing);
3733 reported_plen = tvb_reported_length(tvb) - IPv6_HDR_SIZE;
3734 if (!pinfo->flags.in_error_pkt && plen > reported_plen) {
3735 expert_add_info_format(pinfo, ti_ipv6_plen, &ei_ipv6_plen_exceeds_framing,
3736 "IPv6 payload length exceeds framing length (%d bytes)", reported_plen);
3740 if (ipv6_track_conv_id) {
3741 /* conversation management */
3742 conversation_t *conv;
3744 /* find (and extend) an existing conversation, or create a new one */
3745 conv = find_conversation_strat(pinfo, CONVERSATION_IPV6, NO_PORT_X);
3746 if(!conv) {
3747 conv=conversation_new_strat(pinfo, CONVERSATION_IPV6, NO_PORTS);
3749 else {
3751 * while not strictly necessary because there is only 1
3752 * conversation between 2 IPs, we still move the last frame
3753 * indicator as being a usual practice.
3755 if (!(pinfo->fd->visited)) {
3756 if (pinfo->num > conv->last_frame) {
3757 conv->last_frame = pinfo->num;
3762 ipv6d = get_ipv6_conversation_data(conv, pinfo);
3763 if(ipv6d) {
3764 iph->ip6_stream = ipv6d->stream;
3766 ipv6_item = proto_tree_add_uint(ipv6_tree, hf_ipv6_stream, tvb, 0, 0, ipv6d->stream);
3767 proto_item_set_generated(ipv6_item);
3771 /* Fill in IP header fields for subdissectors */
3772 iph->ip6_ver = 6;
3773 iph->ip6_tc = ip6_tcls;
3774 iph->ip6_flw = ip6_flow;
3775 iph->ip6_len = plen;
3776 iph->ip6_nxt = ip6_nxt;
3777 iph->ip6_hop = ip6_hlim;
3778 alloc_address_wmem_ipv6(pinfo->pool, &iph->ip6_src, ip6_src);
3779 alloc_address_wmem_ipv6(pinfo->pool, &iph->ip6_dst, ip6_dst);
3781 /* Shared state between IPv6 header and extensions. */
3782 ipv6_pinfo_t *ipv6_pinfo = wmem_new0(pinfo->pool, ipv6_pinfo_t);
3783 ipv6_pinfo->ip6_plen = ip6_plen;
3784 ipv6_pinfo->jumbo_plen = jumbo_plen;
3785 ipv6_pinfo->frag_plen = ip6_plen; /* updated by extension header dissectors, if any */
3786 if (!ipv6_exthdr_under_root) {
3787 ipv6_pinfo->ipv6_tree = ipv6_tree;
3788 ipv6_pinfo->ipv6_item_len = IPv6_HDR_SIZE;
3790 p_add_proto_data(pinfo->pool, pinfo, proto_ipv6, IPV6_PROTO_PINFO, ipv6_pinfo);
3792 /* Adjust the length of this tvbuff to include only the IPv6 datagram. */
3793 set_actual_length(tvb, IPv6_HDR_SIZE + plen);
3794 /* Only export after adjusting the length */
3795 export_pdu(tvb, pinfo);
3796 save_fragmented = pinfo->fragmented;
3798 p_add_ipv6_nxt(pinfo, ip6_nxt);
3800 next_tvb = tvb_new_subset_remaining(tvb, offset);
3801 TRY {
3802 ipv6_dissect_next(ip6_nxt, next_tvb, pinfo, tree, iph);
3804 FINALLY {
3805 /* If we need to extend the length due to an ext header and haven't
3806 * yet, do so now. This might be due to an exception or unreassembled
3807 * fragments.
3808 * XXX: What about the tap? We want to tap if we haven't yet, but
3809 * if we always tapped here we would send to the tap in reverse order
3810 * for IP-in-IP.
3812 if (ipv6_pinfo != NULL && ipv6_pinfo->ipv6_tree != NULL) {
3813 /* Set IPv6 Header length */
3814 proto_item_set_len(proto_tree_get_parent(ipv6_pinfo->ipv6_tree), ipv6_pinfo->ipv6_item_len);
3815 ipv6_pinfo->ipv6_tree = NULL;
3818 ENDTRY;
3820 pinfo->fragmented = save_fragmented;
3821 return tvb_captured_length(tvb);
3824 void
3825 ipv6_dissect_next(unsigned nxt, tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, ws_ip6 *iph)
3827 dissector_handle_t nxt_handle;
3828 ipv6_pinfo_t *ipv6_pinfo = p_get_ipv6_pinfo(pinfo);
3830 /* https://www.iana.org/assignments/ipv6-parameters/ipv6-parameters.xhtml#extension-header */
3832 switch (nxt) {
3833 case IP_PROTO_HOPOPTS:
3834 case IP_PROTO_ROUTING:
3835 case IP_PROTO_FRAGMENT:
3836 //case IP_PROTO_ESP: Even though ESP is technically an extension header,
3837 // we treat it as a payload container.
3838 case IP_PROTO_AH:
3839 case IP_PROTO_DSTOPTS:
3840 case IP_PROTO_MIPV6:
3841 //case IP_PROTO_HIP: Even though HIP is technically an extension header, the only defined
3842 // next header is IP_NONE. Also the HIP dissector is not ready for this.
3843 case IP_PROTO_SHIM6:
3844 nxt_handle = dissector_get_uint_handle(ip_dissector_table, nxt);
3845 break;
3846 default:
3847 nxt_handle = NULL;
3848 break;
3850 if (nxt_handle != NULL) {
3851 call_dissector_with_data(nxt_handle, tvb, pinfo, tree, iph);
3852 return;
3856 * Done with extension header chain
3859 if (ipv6_pinfo != NULL && ipv6_pinfo->ipv6_tree != NULL) {
3860 /* Set IPv6 Header length */
3861 proto_item_set_len(proto_tree_get_parent(ipv6_pinfo->ipv6_tree), ipv6_pinfo->ipv6_item_len);
3862 ipv6_pinfo->ipv6_tree = NULL;
3865 if (iph != NULL && iph->ip6_ver == 6) {
3866 iph->ip6_nxt = nxt; /* upper-layer protocol more useful */
3867 tap_queue_packet(ipv6_tap, pinfo, iph);
3870 if (nxt == IP_PROTO_NONE) {
3871 col_set_str(pinfo->cinfo, COL_INFO, "IPv6 no next header");
3872 call_data_dissector(tvb, pinfo, tree);
3873 return;
3876 if (ip_try_dissect(try_heuristic_first, nxt, tvb, pinfo, tree, iph)) {
3877 return;
3880 /* Unknown protocol. */
3881 col_add_fstr(pinfo->cinfo, COL_INFO, "Unknown IP Protocol: %s (%u)", ipprotostr(nxt), nxt);
3882 call_data_dissector(tvb, pinfo, tree);
3885 static void
3886 ipv6_init(void)
3888 ipv6_stream_count = 0;
3891 void
3892 proto_register_ipv6(void)
3894 static hf_register_info hf_ipv6[] = {
3895 { &hf_ipv6_version,
3896 { "Version", "ipv6.version",
3897 FT_UINT8, BASE_DEC, NULL, 0x00,
3898 NULL, HFILL }
3900 { &hf_ip_version,
3901 { "Version", "ip.version",
3902 FT_UINT8, BASE_DEC, NULL, 0xF0,
3903 NULL, HFILL }
3905 { &hf_ipv6_tclass,
3906 { "Traffic Class", "ipv6.tclass",
3907 FT_UINT32, BASE_HEX, NULL, 0x0FF00000,
3908 NULL, HFILL }
3910 { &hf_ipv6_tclass_dscp,
3911 { "Differentiated Services Codepoint", "ipv6.tclass.dscp",
3912 FT_UINT32, BASE_DEC | BASE_EXT_STRING, &dscp_vals_ext, 0x0FC00000,
3913 NULL, HFILL }
3915 { &hf_ipv6_tclass_ecn,
3916 { "Explicit Congestion Notification", "ipv6.tclass.ecn",
3917 FT_UINT32, BASE_DEC | BASE_EXT_STRING, &ecn_vals_ext, 0x00300000,
3918 NULL, HFILL }
3920 { &hf_ipv6_flow,
3921 { "Flow Label", "ipv6.flow",
3922 FT_UINT24, BASE_HEX, NULL, 0x0FFFFF,
3923 NULL, HFILL }
3925 { &hf_ipv6_plen,
3926 { "Payload Length", "ipv6.plen",
3927 FT_UINT16, BASE_DEC, NULL, 0x0,
3928 NULL, HFILL }
3930 { &hf_ipv6_nxt,
3931 { "Next Header", "ipv6.nxt",
3932 FT_UINT8, BASE_DEC | BASE_EXT_STRING, &ipproto_val_ext, 0x0,
3933 NULL, HFILL }
3935 { &hf_ipv6_hlim,
3936 { "Hop Limit", "ipv6.hlim",
3937 FT_UINT8, BASE_DEC, NULL, 0x0,
3938 NULL, HFILL }
3940 { &hf_ipv6_src,
3941 { "Source Address", "ipv6.src",
3942 FT_IPv6, BASE_NONE, NULL, 0x0,
3943 "Source IPv6 Address", HFILL }
3945 { &hf_ipv6_src_addr_space,
3946 { "Address Space", "ipv6.src_addr_space",
3947 FT_STRING, BASE_NONE, NULL, 0x0,
3948 "Source IPv6 Address Space", HFILL }
3950 { &hf_ipv6_src_multicast_flags,
3951 { "Multicast Flags", "ipv6.src_multicast_flags",
3952 FT_UINT16, BASE_HEX, NULL, 0x00F0,
3953 "Source Address Multicast Flags", HFILL }
3955 { &hf_ipv6_src_multicast_flags_transient,
3956 { "Transient", "ipv6.src_multicast_flags.transient",
3957 FT_BOOLEAN, 16, NULL, 0x0010,
3958 "Source Address Transient Multicast Flag", HFILL }
3960 { &hf_ipv6_src_multicast_flags_network_prefix,
3961 { "Network Prefix", "ipv6.src_multicast_flags.network_prefix",
3962 FT_BOOLEAN, 16, NULL, 0x0020,
3963 "Source Address Network Prefix Multicast Flag", HFILL }
3965 { &hf_ipv6_src_multicast_flags_embed_rp,
3966 { "Rendezvous Point (RP)", "ipv6.src_multicast_flags.embed_rp",
3967 FT_BOOLEAN, 16, NULL, 0x0040,
3968 "Source Address Rendezvous Point (RP) Multicast Flag", HFILL }
3970 { &hf_ipv6_src_multicast_flags_reserved,
3971 { "Reserved", "ipv6.src_multicast_flags.reserved",
3972 FT_UINT16, BASE_DEC, NULL, 0x0080,
3973 "Source Address Reserved Multicast Flag", HFILL }
3975 { &hf_ipv6_src_multicast_scope,
3976 { "Multicast Scope", "ipv6.src_multicast_scope",
3977 FT_UINT16, BASE_HEX, VALS(ipv6_multicast_scope_vals), 0x000F,
3978 "Source Address Multicast Scope", HFILL }
3980 { &hf_ipv6_src_special_purpose,
3981 { "Special-Purpose Allocation", "ipv6.src_special_purpose",
3982 FT_STRING, BASE_NONE, NULL, 0x0,
3983 "Source Address Special-Purpose Allocation", HFILL }
3985 { &hf_ipv6_src_special_purpose_source,
3986 { "Source", "ipv6.src_special_purpose_source",
3987 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3988 "Whether an address from the allocated special-purpose address "
3989 "block is valid when used as the source address of an IP datagram", HFILL }
3991 { &hf_ipv6_src_special_purpose_destination,
3992 { "Destination", "ipv6.src_special_purpose_destination",
3993 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3994 "Whether an address from the allocated special-purpose address "
3995 "block is valid when used as the destination address of an IP datagram", HFILL }
3997 { &hf_ipv6_src_special_purpose_forwardable,
3998 { "Forwardable", "ipv6.src_special_purpose_forwardable",
3999 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
4000 "Whether a router may forward an IP datagram whose destination "
4001 "address is drawn from the allocated special-purpose address block", HFILL }
4003 { &hf_ipv6_src_special_purpose_global,
4004 { "Globally Reachable", "ipv6.src_special_purpose_global",
4005 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
4006 "Whether an IP datagram whose destination address is drawn "
4007 "from the allocated special-purpose address block is "
4008 "forwardable beyond a specified administrative domain", HFILL }
4010 { &hf_ipv6_src_special_purpose_reserved,
4011 { "Reserved-by-Protocol", "ipv6.src_special_purpose_reserved",
4012 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
4013 "Whether the special-purpose address block is reserved by IP itself", HFILL }
4015 { &hf_ipv6_src_host,
4016 { "Source Host", "ipv6.src_host",
4017 FT_STRING, BASE_NONE, NULL, 0x0,
4018 "Source IPv6 Host", HFILL }
4020 { &hf_ipv6_src_slaac_mac,
4021 { "Source SLAAC MAC", "ipv6.src_slaac_mac",
4022 FT_ETHER, BASE_NONE, NULL, 0x0,
4023 "Source IPv6 Stateless Address Autoconfiguration (SLAAC) 48-bit MAC Identifier", HFILL }
4025 { &hf_ipv6_src_isatap_ipv4,
4026 { "Source ISATAP IPv4", "ipv6.src_isatap_ipv4",
4027 FT_IPv4, BASE_NONE, NULL, 0x0,
4028 "Source IPv6 ISATAP Encapsulated IPv4 Address", HFILL }
4030 { &hf_ipv6_src_6to4_gateway_ipv4,
4031 { "Source 6to4 Gateway IPv4", "ipv6.src_6to4_gw_ipv4",
4032 FT_IPv4, BASE_NONE, NULL, 0x0,
4033 "Source IPv6 6to4 Gateway IPv4 Address", HFILL }
4035 { &hf_ipv6_src_6to4_sla_id,
4036 { "Source 6to4 SLA ID", "ipv6.src_6to4_sla_id",
4037 FT_UINT16, BASE_DEC, NULL, 0x0,
4038 "Source IPv6 6to4 SLA ID", HFILL }
4040 { &hf_ipv6_src_teredo_server_ipv4,
4041 { "Source Teredo Server IPv4", "ipv6.src_ts_ipv4",
4042 FT_IPv4, BASE_NONE, NULL, 0x0,
4043 "Source IPv6 Teredo Server Encapsulated IPv4 Address", HFILL }
4045 { &hf_ipv6_src_teredo_port,
4046 { "Source Teredo Port", "ipv6.src_tc_port",
4047 FT_UINT16, BASE_DEC, NULL, 0x0,
4048 "Source IPv6 Teredo Client Mapped Port", HFILL }
4050 { &hf_ipv6_src_teredo_client_ipv4,
4051 { "Source Teredo Client IPv4", "ipv6.src_tc_ipv4",
4052 FT_IPv4, BASE_NONE, NULL, 0x0,
4053 "Source IPv6 Teredo Client Encapsulated IPv4 Address", HFILL }
4055 { &hf_ipv6_src_embed_ipv4,
4056 { "Source Embedded IPv4", "ipv6.src_embed_ipv4",
4057 FT_IPv4, BASE_NONE, NULL, 0x0,
4058 "Source IPv4-Embedded IPv6 Address", HFILL }
4060 { &hf_ipv6_dst,
4061 { "Destination Address", "ipv6.dst",
4062 FT_IPv6, BASE_NONE, NULL, 0x0,
4063 "Destination IPv6 Address", HFILL }
4065 { &hf_ipv6_dst_addr_space,
4066 { "Address Space", "ipv6.dst_addr_space",
4067 FT_STRING, BASE_NONE, NULL, 0x0,
4068 "Destination IPv6 Address Space", HFILL }
4070 { &hf_ipv6_dst_multicast_flags,
4071 { "Multicast Flags", "ipv6.dst_multicast_flags",
4072 FT_UINT16, BASE_HEX, NULL, 0x00F0,
4073 "Destination Address Multicast Flags", HFILL }
4075 { &hf_ipv6_dst_multicast_flags_transient,
4076 { "Transient", "ipv6.dst_multicast_flags.transient",
4077 FT_BOOLEAN, 16, NULL, 0x0010,
4078 "Destination Address Transient Multicast Flag", HFILL }
4080 { &hf_ipv6_dst_multicast_flags_network_prefix,
4081 { "Network Prefix", "ipv6.dst_multicast_flags.network_prefix",
4082 FT_BOOLEAN, 16, NULL, 0x0020,
4083 "Destination Address Network Prefix Multicast Flag", HFILL }
4085 { &hf_ipv6_dst_multicast_flags_embed_rp,
4086 { "Rendezvous Point (RP)", "ipv6.dst_multicast_flags.embed_rp",
4087 FT_BOOLEAN, 16, NULL, 0x0040,
4088 "Destination Address Rendezvous Point (RP) Multicast Flag", HFILL }
4090 { &hf_ipv6_dst_multicast_flags_reserved,
4091 { "Reserved", "ipv6.dst_multicast_flags.reserved",
4092 FT_UINT16, BASE_DEC, NULL, 0x0080,
4093 "Destination Address Reserved Multicast Flag", HFILL }
4095 { &hf_ipv6_dst_multicast_scope,
4096 { "Multicast Scope", "ipv6.dst_multicast_scope",
4097 FT_UINT16, BASE_HEX, VALS(ipv6_multicast_scope_vals), 0x000F,
4098 "Destination Address Multicast Scope", HFILL }
4100 { &hf_ipv6_dst_special_purpose,
4101 { "Special-Purpose Allocation", "ipv6.dst_special_purpose",
4102 FT_STRING, BASE_NONE, NULL, 0x0,
4103 "Destination Address Special-Purpose Allocation", HFILL }
4105 { &hf_ipv6_dst_special_purpose_source,
4106 { "Source", "ipv6.dst_special_purpose_source",
4107 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
4108 "Whether an address from the allocated special-purpose address "
4109 "block is valid when used as the source address of an IP datagram", HFILL }
4111 { &hf_ipv6_dst_special_purpose_destination,
4112 { "Destination", "ipv6.dst_special_purpose_destination",
4113 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
4114 "Whether an address from the allocated special-purpose address "
4115 "block is valid when used as the destination address of an IP datagram", HFILL }
4117 { &hf_ipv6_dst_special_purpose_forwardable,
4118 { "Forwardable", "ipv6.dst_special_purpose_forwardable",
4119 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
4120 "Whether a router may forward an IP datagram whose destination "
4121 "address is drawn from the allocated special-purpose address block", HFILL }
4123 { &hf_ipv6_dst_special_purpose_global,
4124 { "Globally Reachable", "ipv6.dst_special_purpose_global",
4125 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
4126 "Whether an IP datagram whose destination address is drawn "
4127 "from the allocated special-purpose address block is "
4128 "forwardable beyond a specified administrative domain", HFILL }
4130 { &hf_ipv6_dst_special_purpose_reserved,
4131 { "Reserved-by-Protocol", "ipv6.dst_special_purpose_reserved",
4132 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
4133 "Whether the special-purpose address block is reserved by IP itself", HFILL }
4135 { &hf_ipv6_dst_host,
4136 { "Destination Host", "ipv6.dst_host",
4137 FT_STRING, BASE_NONE, NULL, 0x0,
4138 "Destination IPv6 Host", HFILL }
4140 { &hf_ipv6_dst_slaac_mac,
4141 { "Destination SLAAC MAC", "ipv6.dst_slaac_mac",
4142 FT_ETHER, BASE_NONE, NULL, 0x0,
4143 "Destination IPv6 Stateless Address Autoconfiguration (SLAAC) 48-bit MAC Identifier", HFILL }
4145 { &hf_ipv6_dst_isatap_ipv4,
4146 { "Destination ISATAP IPv4", "ipv6.dst_isatap_ipv4",
4147 FT_IPv4, BASE_NONE, NULL, 0x0,
4148 "Destination IPv6 ISATAP Encapsulated IPv4 Address", HFILL }
4150 { &hf_ipv6_dst_6to4_gateway_ipv4,
4151 { "Destination 6to4 Gateway IPv4", "ipv6.dst_6to4_gw_ipv4",
4152 FT_IPv4, BASE_NONE, NULL, 0x0,
4153 "Destination IPv6 6to4 Gateway IPv4 Address", HFILL }
4155 { &hf_ipv6_dst_6to4_sla_id,
4156 { "Destination 6to4 SLA ID", "ipv6.dst_6to4_sla_id",
4157 FT_UINT16, BASE_DEC, NULL, 0x0,
4158 "Destination IPv6 6to4 SLA ID", HFILL }
4160 { &hf_ipv6_dst_teredo_server_ipv4,
4161 { "Destination Teredo Server IPv4", "ipv6.dst_ts_ipv4",
4162 FT_IPv4, BASE_NONE, NULL, 0x0,
4163 "Destination IPv6 Teredo Server Encapsulated IPv4 Address", HFILL }
4165 { &hf_ipv6_dst_teredo_port,
4166 { "Destination Teredo Port", "ipv6.dst_tc_port",
4167 FT_UINT16, BASE_DEC, NULL, 0x0,
4168 "Destination IPv6 Teredo Client Mapped Port", HFILL }
4170 { &hf_ipv6_dst_teredo_client_ipv4,
4171 { "Destination Teredo Client IPv4", "ipv6.dst_tc_ipv4",
4172 FT_IPv4, BASE_NONE, NULL, 0x0,
4173 "Destination IPv6 Teredo Client Encapsulated IPv4 Address", HFILL }
4175 { &hf_ipv6_dst_embed_ipv4,
4176 { "Destination Embedded IPv4", "ipv6.dst_embed_ipv4",
4177 FT_IPv4, BASE_NONE, NULL, 0x0,
4178 "Destination IPv4-Embedded IPv6 Address", HFILL }
4180 { &hf_ipv6_addr,
4181 { "Source or Destination Address", "ipv6.addr",
4182 FT_IPv6, BASE_NONE, NULL, 0x0,
4183 NULL, HFILL }
4185 { &hf_ipv6_addr_space,
4186 { "Address Space", "ipv6.addr_space",
4187 FT_STRING, BASE_NONE, NULL, 0x0,
4188 "Source or Destination Address Space", HFILL }
4190 { &hf_ipv6_multicast_flags,
4191 { "Multicast Flags", "ipv6.multicast_flags",
4192 FT_UINT16, BASE_HEX, NULL, 0x00F0,
4193 "Source or Destination Address Multicast Flags", HFILL }
4195 { &hf_ipv6_multicast_flags_transient,
4196 { "Transient", "ipv6.multicast_flags.transient",
4197 FT_BOOLEAN, 16, NULL, 0x0010,
4198 "Source or Destination Address Transient Multicast Flag", HFILL }
4200 { &hf_ipv6_multicast_flags_network_prefix,
4201 { "Network Prefix", "ipv6.multicast_flags.network_prefix",
4202 FT_BOOLEAN, 16, NULL, 0x0020,
4203 "Source or Destination Address Network Prefix Multicast Flag", HFILL }
4205 { &hf_ipv6_multicast_flags_embed_rp,
4206 { "Rendezvous Point (RP)", "ipv6.multicast_flags.embed_rp",
4207 FT_BOOLEAN, 16, NULL, 0x0040,
4208 "Source or Destination Address Rendezvous Point (RP) Multicast Flag", HFILL }
4210 { &hf_ipv6_multicast_flags_reserved,
4211 { "Reserved", "ipv6.multicast_flags.reserved",
4212 FT_UINT16, BASE_DEC, NULL, 0x0080,
4213 "Source or Destination Address Reserved Multicast Flag", HFILL }
4215 { &hf_ipv6_multicast_scope,
4216 { "Multicast Scope", "ipv6.multicast_scope",
4217 FT_UINT16, BASE_HEX, VALS(ipv6_multicast_scope_vals), 0x000F,
4218 "Source or Destination Address Multicast Scope", HFILL }
4220 { &hf_ipv6_addr_special_purpose,
4221 { "Special-Purpose Allocation", "ipv6.addr_special_purpose",
4222 FT_STRING, BASE_NONE, NULL, 0x0,
4223 "Source or Destination Address Special-Purpose Allocation", HFILL }
4225 { &hf_ipv6_addr_special_purpose_source,
4226 { "Source", "ipv6.addr_special_purpose_source",
4227 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
4228 "Whether an address from the allocated special-purpose address "
4229 "block is valid when used as the source address of an IP datagram", HFILL }
4231 { &hf_ipv6_addr_special_purpose_destination,
4232 { "Destination", "ipv6.addr_special_purpose_destination",
4233 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
4234 "Whether an address from the allocated special-purpose address "
4235 "block is valid when used as the destination address of an IP datagram", HFILL }
4237 { &hf_ipv6_addr_special_purpose_forwardable,
4238 { "Forwardable", "ipv6.addr_special_purpose_forwardable",
4239 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
4240 "Whether a router may forward an IP datagram whose destination "
4241 "address is drawn from the allocated special-purpose address block", HFILL }
4243 { &hf_ipv6_addr_special_purpose_global,
4244 { "Globally Reachable", "ipv6.addr_special_purpose_global",
4245 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
4246 "Whether an IP datagram whose destination address is drawn "
4247 "from the allocated special-purpose address block is "
4248 "forwardable beyond a specified administrative domain", HFILL }
4250 { &hf_ipv6_addr_special_purpose_reserved,
4251 { "Reserved-by-Protocol", "ipv6.addr_special_purpose_reserved",
4252 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
4253 "Whether the special-purpose address block is reserved by IP itself", HFILL }
4255 { &hf_ipv6_host,
4256 { "Source or Destination Host", "ipv6.host",
4257 FT_STRING, BASE_NONE, NULL, 0x0,
4258 NULL, HFILL }
4260 { &hf_ipv6_slaac_mac,
4261 { "SLAAC MAC", "ipv6.slaac_mac",
4262 FT_ETHER, BASE_NONE, NULL, 0x0,
4263 "IPv6 Stateless Address Autoconfiguration (SLAAC) 48-bit MAC Identifier", HFILL }
4265 { &hf_ipv6_isatap_ipv4,
4266 { "ISATAP IPv4", "ipv6.isatap_ipv4",
4267 FT_IPv4, BASE_NONE, NULL, 0x0,
4268 "IPv6 ISATAP Encapsulated IPv4 Address", HFILL }
4270 { &hf_ipv6_6to4_gateway_ipv4,
4271 { "6to4 Gateway IPv4", "ipv6.6to4_gw_ipv4",
4272 FT_IPv4, BASE_NONE, NULL, 0x0,
4273 "IPv6 6to4 Gateway IPv4 Address", HFILL }
4275 { &hf_ipv6_6to4_sla_id,
4276 { "6to4 SLA ID", "ipv6.6to4_sla_id",
4277 FT_UINT16, BASE_DEC, NULL, 0x0,
4278 "IPv6 6to4 SLA ID", HFILL }
4280 { &hf_ipv6_teredo_server_ipv4,
4281 { "Teredo Server IPv4", "ipv6.ts_ipv4",
4282 FT_IPv4, BASE_NONE, NULL, 0x0,
4283 "IPv6 Teredo Server Encapsulated IPv4 Address", HFILL }
4285 { &hf_ipv6_teredo_port,
4286 { "Teredo Port", "ipv6.tc_port",
4287 FT_UINT16, BASE_DEC, NULL, 0x0,
4288 "IPv6 Teredo Client Mapped Port", HFILL }
4290 { &hf_ipv6_teredo_client_ipv4,
4291 { "Teredo Client IPv4", "ipv6.tc_ipv4",
4292 FT_IPv4, BASE_NONE, NULL, 0x0,
4293 "IPv6 Teredo Client Encapsulated IPv4 Address", HFILL }
4295 { &hf_ipv6_embed_ipv4_prefix,
4296 { "Embedded IPv4 Prefix", "ipv6.embed_ipv4_prefix",
4297 FT_BYTES, BASE_NONE, NULL, 0x0,
4298 "IPv4-Embedded IPv6 Address Prefix", HFILL }
4300 { &hf_ipv6_embed_ipv4,
4301 { "Embedded IPv4", "ipv6.embed_ipv4",
4302 FT_IPv4, BASE_NONE, NULL, 0x0,
4303 "IPv4-Embedded IPv6 Address", HFILL }
4305 { &hf_ipv6_embed_ipv4_u,
4306 { "Embedded IPv4 u field", "ipv6.embed_ipv4_u",
4307 FT_BYTES, BASE_NONE, NULL, 0x0,
4308 "IPv4-Embedded IPv6 Address u field", HFILL }
4310 { &hf_ipv6_embed_ipv4_suffix,
4311 { "Embedded IPv4 Suffix", "ipv6.embed_ipv4_suffix",
4312 FT_BYTES, BASE_NONE, NULL, 0x0,
4313 "IPv4-Embedded IPv6 Address Suffix", HFILL }
4316 { &hf_ipv6_stream,
4317 { "Stream index", "ipv6.stream",
4318 FT_UINT32, BASE_DEC, NULL, 0x0,
4319 NULL, HFILL }
4322 { &hf_geoip_country,
4323 { "Source or Destination GeoIP Country", "ipv6.geoip.country",
4324 FT_STRING, BASE_NONE, NULL, 0x0,
4325 NULL, HFILL }
4327 { &hf_geoip_country_iso,
4328 { "Source or Destination GeoIP ISO Two Letter Country Code", "ipv6.geoip.country_iso",
4329 FT_STRING, BASE_NONE, NULL, 0x0,
4330 NULL, HFILL }
4332 { &hf_geoip_city,
4333 { "Source or Destination GeoIP City", "ipv6.geoip.city",
4334 FT_STRING, BASE_NONE, NULL, 0x0,
4335 NULL, HFILL }
4337 { &hf_geoip_as_number,
4338 { "Source or Destination GeoIP AS Number", "ipv6.geoip.asnum",
4339 FT_UINT32, BASE_DEC, NULL, 0x0,
4340 NULL, HFILL }
4342 { &hf_geoip_as_org,
4343 { "Source or Destination GeoIP AS Organization", "ipv6.geoip.org",
4344 FT_STRING, BASE_NONE, NULL, 0x0,
4345 NULL, HFILL }
4347 { &hf_geoip_latitude,
4348 { "Source or Destination GeoIP Latitude", "ipv6.geoip.lat",
4349 FT_DOUBLE, BASE_NONE, NULL, 0x0,
4350 NULL, HFILL }
4352 { &hf_geoip_longitude,
4353 { "Source or Destination GeoIP Longitude", "ipv6.geoip.lon",
4354 FT_DOUBLE, BASE_NONE, NULL, 0x0,
4355 NULL, HFILL }
4357 { &hf_geoip_src_summary,
4358 { "Source GeoIP", "ipv6.geoip.src_summary",
4359 FT_STRING, BASE_NONE, NULL, 0x0,
4360 NULL, HFILL }
4362 { &hf_geoip_src_country,
4363 { "Source GeoIP Country", "ipv6.geoip.src_country",
4364 FT_STRING, BASE_NONE, NULL, 0x0,
4365 NULL, HFILL }
4367 { &hf_geoip_src_country_iso,
4368 { "Source GeoIP ISO Two Letter Country Code", "ipv6.geoip.src_country_iso",
4369 FT_STRING, BASE_NONE, NULL, 0x0,
4370 NULL, HFILL }
4372 { &hf_geoip_src_city,
4373 { "Source GeoIP City", "ipv6.geoip.src_city",
4374 FT_STRING, BASE_NONE, NULL, 0x0,
4375 NULL, HFILL }
4377 { &hf_geoip_src_as_number,
4378 { "Source GeoIP AS Number", "ipv6.geoip.src_asnum",
4379 FT_UINT32, BASE_DEC, NULL, 0x0,
4380 NULL, HFILL }
4382 { &hf_geoip_src_as_org,
4383 { "Source GeoIP AS Organization", "ipv6.geoip.src_org",
4384 FT_STRING, BASE_NONE, NULL, 0x0,
4385 NULL, HFILL }
4387 { &hf_geoip_src_latitude,
4388 { "Source GeoIP Latitude", "ipv6.geoip.src_lat",
4389 FT_DOUBLE, BASE_NONE, NULL, 0x0,
4390 NULL, HFILL }
4392 { &hf_geoip_src_longitude,
4393 { "Source GeoIP Longitude", "ipv6.geoip.src_lon",
4394 FT_DOUBLE, BASE_NONE, NULL, 0x0,
4395 NULL, HFILL }
4397 { &hf_geoip_dst_summary,
4398 { "Destination GeoIP", "ipv6.geoip.dst_summary",
4399 FT_STRING, BASE_NONE, NULL, 0x0,
4400 NULL, HFILL }
4402 { &hf_geoip_dst_country,
4403 { "Destination GeoIP Country", "ipv6.geoip.dst_country",
4404 FT_STRING, BASE_NONE, NULL, 0x0,
4405 NULL, HFILL }
4407 { &hf_geoip_dst_country_iso,
4408 { "Destination GeoIP ISO Two Letter Country Code", "ipv6.geoip.dst_country_iso",
4409 FT_STRING, BASE_NONE, NULL, 0x0,
4410 NULL, HFILL }
4412 { &hf_geoip_dst_city,
4413 { "Destination GeoIP City", "ipv6.geoip.dst_city",
4414 FT_STRING, BASE_NONE, NULL, 0x0,
4415 NULL, HFILL }
4417 { &hf_geoip_dst_as_number,
4418 { "Destination GeoIP AS Number", "ipv6.geoip.dst_asnum",
4419 FT_UINT32, BASE_DEC, NULL, 0x0,
4420 NULL, HFILL }
4422 { &hf_geoip_dst_as_org,
4423 { "Destination GeoIP AS Organization", "ipv6.geoip.dst_org",
4424 FT_STRING, BASE_NONE, NULL, 0x0,
4425 NULL, HFILL }
4427 { &hf_geoip_dst_latitude,
4428 { "Destination GeoIP Latitude", "ipv6.geoip.dst_lat",
4429 FT_DOUBLE, BASE_NONE, NULL, 0x0,
4430 NULL, HFILL }
4432 { &hf_geoip_dst_longitude,
4433 { "Destination GeoIP Longitude", "ipv6.geoip.dst_lon",
4434 FT_DOUBLE, BASE_NONE, NULL, 0x0,
4435 NULL, HFILL }
4438 { &hf_ipv6_opt,
4439 { "IPv6 Option", "ipv6.opt",
4440 FT_NONE, BASE_NONE, NULL, 0x0,
4441 NULL, HFILL }
4443 { &hf_ipv6_opt_type,
4444 { "Type", "ipv6.opt.type",
4445 FT_UINT8, BASE_HEX | BASE_EXT_STRING, &ipv6_opt_type_vals_ext, 0x0,
4446 "Option type", HFILL }
4448 { &hf_ipv6_opt_type_action,
4449 { "Action", "ipv6.opt.type.action",
4450 FT_UINT8, BASE_DEC, VALS(ipv6_opt_type_action_vals), 0xC0,
4451 "Action for unrecognized option type", HFILL }
4453 { &hf_ipv6_opt_type_change,
4454 { "May Change", "ipv6.opt.type.change",
4455 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x20,
4456 "Whether the option data may change en-route", HFILL }
4458 { &hf_ipv6_opt_type_rest,
4459 { "Low-Order Bits", "ipv6.opt.type.rest",
4460 FT_UINT8, BASE_HEX, NULL, 0x1F,
4461 "Remaining low-order bits", HFILL }
4463 { &hf_ipv6_opt_length,
4464 { "Length", "ipv6.opt.length",
4465 FT_UINT8, BASE_DEC, NULL, 0x0,
4466 "Option length in octets", HFILL }
4468 { &hf_ipv6_opt_pad1,
4469 { "Pad1", "ipv6.opt.pad1",
4470 FT_NONE, BASE_NONE, NULL, 0x0,
4471 "Pad1 Option", HFILL }
4473 { &hf_ipv6_opt_padn,
4474 { "PadN", "ipv6.opt.padn",
4475 FT_BYTES, BASE_NONE|BASE_ALLOW_ZERO, NULL, 0x0,
4476 "PadN Option", HFILL }
4478 { &hf_ipv6_opt_pmtu_min,
4479 { "Minimum Reported PMTU", "ipv6.opt.pmtu.min",
4480 FT_UINT16, BASE_DEC, NULL, 0x0,
4481 "The minimum reported PMTU in octets", HFILL }
4483 { &hf_ipv6_opt_pmtu_rtn,
4484 { "Return Minimum PMTU", "ipv6.opt.pmtu.rtn",
4485 FT_UINT16, BASE_DEC, NULL, 0x0,
4486 "The Return Min-PMTU in octets", HFILL }
4488 { &hf_ipv6_opt_pmtu_rtn_flag,
4489 { "Return Flag", "ipv6.opt.pmtu.r_flag",
4490 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
4491 "Destination should include the received reported PMTU", HFILL }
4493 { &hf_ipv6_opt_apn_id_type,
4494 { "ID Type", "ipv6.opt.apn.id.type",
4495 FT_UINT8, BASE_DEC, VALS(apn_id_type_strs), 0x0,
4496 "The type of the APN ID", HFILL }
4498 { &hf_ipv6_opt_apn_flags,
4499 { "Flags", "ipv6.opt.apn.flags",
4500 FT_UINT8, BASE_HEX, NULL, 0x0,
4501 "Flags for advanced processing", HFILL }
4503 { &hf_ipv6_opt_apn_param_type,
4504 { "Parameters Types", "ipv6.opt.apn.param.type",
4505 FT_UINT16, BASE_HEX, NULL, 0x0,
4506 "Bitmap to identify the existence of APN Parameters", HFILL }
4508 { &hf_ipv6_opt_apn_id_part1,
4509 { "ID Part1", "ipv6.opt.apn.id.part1",
4510 FT_UINT32, BASE_HEX, NULL, 0x0,
4511 "The first 32-bit of the APN ID", HFILL }
4513 { &hf_ipv6_opt_apn_id_part2,
4514 { "ID Part2", "ipv6.opt.apn.id.part2",
4515 FT_UINT32, BASE_HEX, NULL, 0x0,
4516 "The second 32-bit of the APN ID", HFILL }
4518 { &hf_ipv6_opt_apn_id_part3,
4519 { "ID Part3", "ipv6.opt.apn.id.part3",
4520 FT_UINT32, BASE_HEX, NULL, 0x0,
4521 "The third 32-bit of the APN ID", HFILL }
4523 { &hf_ipv6_opt_apn_id_part4,
4524 { "ID Part4", "ipv6.opt.apn.id.part4",
4525 FT_UINT32, BASE_HEX, NULL, 0x0,
4526 "The last 32-bit of the APN ID", HFILL }
4528 { &hf_ipv6_opt_rtalert,
4529 { "Router Alert", "ipv6.opt.router_alert",
4530 FT_UINT16, BASE_DEC, VALS(ipv6_opt_rtalert_vals), 0x0,
4531 "Router Alert Option", HFILL }
4533 { &hf_ipv6_opt_tel,
4534 { "Tunnel Encapsulation Limit", "ipv6.opt.tel",
4535 FT_UINT8, BASE_DEC, NULL, 0x0,
4536 "How many further levels of encapsulation are permitted", HFILL }
4538 { &hf_ipv6_opt_jumbo,
4539 { "Payload Length", "ipv6.opt.jumbo",
4540 FT_UINT32, BASE_DEC, NULL, 0x0,
4541 "IPv6 (Jumbo) Payload Length", HFILL }
4543 { &hf_ipv6_opt_calipso_doi,
4544 { "CALIPSO Domain of Interpretation", "ipv6.opt.calipso.doi",
4545 FT_UINT32, BASE_DEC, NULL, 0x0,
4546 NULL, HFILL }
4548 { &hf_ipv6_opt_calipso_cmpt_length,
4549 { "Compartment Length", "ipv6.opt.calipso.cmpt.length",
4550 FT_UINT8, BASE_DEC, NULL, 0x0,
4551 NULL, HFILL }
4553 { &hf_ipv6_opt_calipso_sens_level,
4554 { "Sensitivity Level", "ipv6.opt.calipso.sens_level",
4555 FT_UINT8, BASE_DEC, NULL, 0x0,
4556 NULL, HFILL }
4558 { &hf_ipv6_opt_calipso_checksum,
4559 { "Checksum", "ipv6.opt.calipso.checksum",
4560 FT_UINT16, BASE_HEX, NULL, 0x0,
4561 NULL, HFILL }
4563 { &hf_ipv6_opt_calipso_cmpt_bitmap,
4564 { "Compartment Bitmap", "ipv6.opt.calipso.cmpt_bitmap",
4565 FT_BYTES, BASE_NONE, NULL, 0x0,
4566 NULL, HFILL }
4568 { &hf_ipv6_opt_smf_dpd_hash_bit,
4569 { "H-bit", "ipv6.opt.smf_dpd.hash_bit",
4570 FT_BOOLEAN, 8, NULL, 0x80,
4571 "Hash indicator", HFILL }
4573 { &hf_ipv6_opt_smf_dpd_tid_type,
4574 { "TaggerID Type", "ipv6.opt.smf_dpd.tid_type",
4575 FT_UINT8, BASE_DEC, VALS(ipv6_opt_smf_dpd_tidty_vals), 0x70,
4576 NULL, HFILL }
4578 { &hf_ipv6_opt_smf_dpd_tid_len,
4579 { "TaggerID Length", "ipv6.opt.smf_dpd.tid_len",
4580 FT_UINT8, BASE_DEC, NULL, 0x0F,
4581 NULL, HFILL }
4583 { &hf_ipv6_opt_smf_dpd_tagger_id,
4584 { "TaggerID", "ipv6.opt.smf_dpd.tagger_id",
4585 FT_BYTES, BASE_NONE, NULL, 0x0,
4586 NULL, HFILL }
4588 { &hf_ipv6_opt_smf_dpd_ident,
4589 { "Identifier", "ipv6.opt.smf_dpd.ident",
4590 FT_BYTES, BASE_NONE, NULL, 0x0,
4591 NULL, HFILL }
4593 { &hf_ipv6_opt_smf_dpd_hav,
4594 { "Hash Assist Value", "ipv6.opt.smf_dpd.hav",
4595 FT_BYTES, BASE_NONE, NULL, 0x0,
4596 NULL, HFILL }
4598 { &hf_ipv6_opt_pdm_scale_dtlr,
4599 { "Scale DTLR", "ipv6.opt.pdm.scale_dtlr",
4600 FT_UINT8, BASE_DEC, NULL, 0x0,
4601 "Scale for Delta Time Last Received", HFILL }
4603 { &hf_ipv6_opt_pdm_scale_dtls,
4604 { "Scale DTLS", "ipv6.opt.pdm.scale_dtls",
4605 FT_UINT8, BASE_DEC, NULL, 0x0,
4606 "Scale for Delta Time Last Sent", HFILL }
4608 { &hf_ipv6_opt_pdm_psn_this_pkt,
4609 { "PSN This Packet", "ipv6.opt.pdm.psn_this_pkt",
4610 FT_UINT16, BASE_DEC, NULL, 0x0,
4611 "Packet Sequence Number This Packet", HFILL }
4613 { &hf_ipv6_opt_pdm_psn_last_recv,
4614 { "PSN Last Received", "ipv6.opt.pdm.psn_last_recv",
4615 FT_UINT16, BASE_DEC, NULL, 0x0,
4616 "Packet Sequence Number Last Received", HFILL }
4618 { &hf_ipv6_opt_pdm_delta_last_recv,
4619 { "Delta Time Last Received", "ipv6.opt.pdm.delta_last_recv",
4620 FT_UINT16, BASE_DEC, NULL, 0x0,
4621 NULL, HFILL }
4623 { &hf_ipv6_opt_pdm_delta_last_sent,
4624 { "Delta Time Last Sent", "ipv6.opt.pdm.delta_last_sent",
4625 FT_UINT16, BASE_DEC, NULL, 0x0,
4626 NULL, HFILL }
4628 { &hf_ipv6_opt_qs_func,
4629 { "Function", "ipv6.opt.qs_func",
4630 FT_UINT8, BASE_DEC, VALS(qs_func_vals), QS_FUNC_MASK,
4631 NULL, HFILL }
4633 { &hf_ipv6_opt_qs_rate,
4634 { "Rate", "ipv6.opt.qs_rate",
4635 FT_UINT8, BASE_DEC | BASE_EXT_STRING, &qs_rate_vals_ext, QS_RATE_MASK,
4636 NULL, HFILL }
4638 { &hf_ipv6_opt_qs_ttl,
4639 { "QS TTL", "ipv6.opt.qs_ttl",
4640 FT_UINT8, BASE_DEC, NULL, 0x0,
4641 NULL, HFILL }
4643 { &hf_ipv6_opt_qs_ttl_diff,
4644 { "TTL Diff", "ipv6.opt.qs_ttl_diff",
4645 FT_UINT8, BASE_DEC, NULL, 0x0,
4646 NULL, HFILL }
4648 { &hf_ipv6_opt_qs_unused,
4649 { "Not Used", "ipv6.opt.qs_unused",
4650 FT_UINT8, BASE_DEC, NULL, 0x0,
4651 NULL, HFILL }
4653 { &hf_ipv6_opt_qs_nonce,
4654 { "QS Nonce", "ipv6.opt.qs_nonce",
4655 FT_UINT32, BASE_HEX, NULL, 0xFFFFFFFC,
4656 NULL, HFILL }
4658 { &hf_ipv6_opt_qs_reserved,
4659 { "Reserved", "ipv6.opt.qs_reserved",
4660 FT_UINT32, BASE_HEX, NULL, 0x0003,
4661 NULL, HFILL }
4663 { &hf_ipv6_opt_ioam_rsv,
4664 { "Reserved", "ipv6.opt.ioam.rsv",
4665 FT_UINT8, BASE_DEC, NULL, 0x0,
4666 "Reserved (must be zero)", HFILL }
4668 { &hf_ipv6_opt_ioam_opt_type,
4669 { "Option-Type", "ipv6.opt.ioam.opt_type",
4670 FT_UINT8, BASE_DEC, VALS(ipv6_ioam_opt_types), 0x0,
4671 NULL, HFILL }
4673 { &hf_ipv6_opt_ioam_trace_ns,
4674 { "Namespace ID", "ipv6.opt.ioam.trace.ns",
4675 FT_UINT16, BASE_DEC, NULL, 0x0,
4676 NULL, HFILL }
4678 { &hf_ipv6_opt_ioam_trace_nodelen,
4679 { "Node Length", "ipv6.opt.ioam.trace.nodelen",
4680 FT_UINT8, BASE_DEC, NULL, 0x0,
4681 NULL, HFILL }
4683 { &hf_ipv6_opt_ioam_trace_flags,
4684 { "Flags", "ipv6.opt.ioam.trace.flags",
4685 FT_UINT16, BASE_HEX, NULL, 0x0780,
4686 NULL, HFILL }
4688 { &hf_ipv6_opt_ioam_trace_flag_o,
4689 { "Overflow", "ipv6.opt.ioam.trace.flag.o",
4690 FT_BOOLEAN, 16, NULL, 0x0400,
4691 "Not enough free space", HFILL }
4693 { &hf_ipv6_opt_ioam_trace_flag_l,
4694 { "Loopback", "ipv6.opt.ioam.trace.flag.l",
4695 FT_BOOLEAN, 16, NULL, 0x0200,
4696 "Send a copy of the packet back towards the source", HFILL }
4698 { &hf_ipv6_opt_ioam_trace_flag_a,
4699 { "Active", "ipv6.opt.ioam.trace.flag.a",
4700 FT_BOOLEAN, 16, NULL, 0x0100,
4701 "Active measurement packet", HFILL }
4703 { &hf_ipv6_opt_ioam_trace_flag_rsv,
4704 { "Reserved", "ipv6.opt.ioam.trace.flag.rsv",
4705 FT_BOOLEAN, 16, NULL, 0x0080,
4706 "Reserved (must be zero)", HFILL }
4708 { &hf_ipv6_opt_ioam_trace_remlen,
4709 { "Remaining Length", "ipv6.opt.ioam.trace.remlen",
4710 FT_UINT8, BASE_DEC, NULL, 0x0,
4711 NULL, HFILL }
4713 { &hf_ipv6_opt_ioam_trace_type,
4714 { "Trace Type", "ipv6.opt.ioam.trace.type",
4715 FT_UINT24, BASE_HEX, NULL, 0x0,
4716 NULL, HFILL }
4718 { &hf_ipv6_opt_ioam_trace_type_bit0,
4719 { "Hop_Lim and Node ID (short)", "ipv6.opt.ioam.trace.type.bit0",
4720 FT_BOOLEAN, 24, NULL, 0x800000,
4721 NULL, HFILL }
4723 { &hf_ipv6_opt_ioam_trace_type_bit1,
4724 { "Ingress and Egress IDs (short)", "ipv6.opt.ioam.trace.type.bit1",
4725 FT_BOOLEAN, 24, NULL, 0x400000,
4726 NULL, HFILL }
4728 { &hf_ipv6_opt_ioam_trace_type_bit2,
4729 { "Timestamp seconds", "ipv6.opt.ioam.trace.type.bit2",
4730 FT_BOOLEAN, 24, NULL, 0x200000,
4731 NULL, HFILL }
4733 { &hf_ipv6_opt_ioam_trace_type_bit3,
4734 { "Timestamp fraction", "ipv6.opt.ioam.trace.type.bit3",
4735 FT_BOOLEAN, 24, NULL, 0x100000,
4736 NULL, HFILL }
4738 { &hf_ipv6_opt_ioam_trace_type_bit4,
4739 { "Transit delay", "ipv6.opt.ioam.trace.type.bit4",
4740 FT_BOOLEAN, 24, NULL, 0x080000,
4741 NULL, HFILL }
4743 { &hf_ipv6_opt_ioam_trace_type_bit5,
4744 { "IOAM-Namespace specific data (short)", "ipv6.opt.ioam.trace.type.bit5",
4745 FT_BOOLEAN, 24, NULL, 0x040000,
4746 NULL, HFILL }
4748 { &hf_ipv6_opt_ioam_trace_type_bit6,
4749 { "Queue depth", "ipv6.opt.ioam.trace.type.bit6",
4750 FT_BOOLEAN, 24, NULL, 0x020000,
4751 NULL, HFILL }
4753 { &hf_ipv6_opt_ioam_trace_type_bit7,
4754 { "Checksum complement", "ipv6.opt.ioam.trace.type.bit7",
4755 FT_BOOLEAN, 24, NULL, 0x010000,
4756 NULL, HFILL }
4758 { &hf_ipv6_opt_ioam_trace_type_bit8,
4759 { "Hop_Lim and Node ID (wide)", "ipv6.opt.ioam.trace.type.bit8",
4760 FT_BOOLEAN, 24, NULL, 0x008000,
4761 NULL, HFILL }
4763 { &hf_ipv6_opt_ioam_trace_type_bit9,
4764 { "Ingress and Egress IDs (wide)", "ipv6.opt.ioam.trace.type.bit9",
4765 FT_BOOLEAN, 24, NULL, 0x004000,
4766 NULL, HFILL }
4768 { &hf_ipv6_opt_ioam_trace_type_bit10,
4769 { "IOAM-Namespace specific data (wide)", "ipv6.opt.ioam.trace.type.bit10",
4770 FT_BOOLEAN, 24, NULL, 0x002000,
4771 NULL, HFILL }
4773 { &hf_ipv6_opt_ioam_trace_type_bit11,
4774 { "Buffer occupancy", "ipv6.opt.ioam.trace.type.bit11",
4775 FT_BOOLEAN, 24, NULL, 0x001000,
4776 NULL, HFILL }
4778 { &hf_ipv6_opt_ioam_trace_type_undef,
4779 { "Undefined", "ipv6.opt.ioam.trace.type.undef",
4780 FT_BOOLEAN, 24, NULL, 0x000ffc,
4781 NULL, HFILL }
4783 { &hf_ipv6_opt_ioam_trace_type_bit22,
4784 { "Opaque State Snapshot", "ipv6.opt.ioam.trace.type.bit22",
4785 FT_BOOLEAN, 24, NULL, 0x000002,
4786 NULL, HFILL }
4788 { &hf_ipv6_opt_ioam_trace_type_rsv,
4789 { "Reserved", "ipv6.opt.ioam.trace.type.rsv",
4790 FT_BOOLEAN, 24, NULL, 0x000001,
4791 NULL, HFILL }
4793 { &hf_ipv6_opt_ioam_trace_rsv,
4794 { "Reserved", "ipv6.opt.ioam.trace.rsv",
4795 FT_UINT8, BASE_DEC, NULL, 0x0,
4796 "Reserved (must be zero)", HFILL }
4798 { &hf_ipv6_opt_ioam_trace_free_space,
4799 { "Free space", "ipv6.opt.ioam.trace.free_space",
4800 FT_BYTES, BASE_NONE, NULL, 0x0,
4801 NULL, HFILL }
4803 { &hf_ipv6_opt_ioam_trace_node_hlim,
4804 { "Hop Limit", "ipv6.opt.ioam.trace.node.hlim",
4805 FT_UINT8, BASE_DEC, NULL, 0x0,
4806 NULL, HFILL }
4808 { &hf_ipv6_opt_ioam_trace_node_id,
4809 { "ID", "ipv6.opt.ioam.trace.node.id",
4810 FT_UINT24, BASE_HEX, NULL, 0x0,
4811 NULL, HFILL }
4813 { &hf_ipv6_opt_ioam_trace_node_iif,
4814 { "Ingress ID", "ipv6.opt.ioam.trace.node.iif",
4815 FT_UINT16, BASE_HEX, NULL, 0x0,
4816 NULL, HFILL }
4818 { &hf_ipv6_opt_ioam_trace_node_eif,
4819 { "Egress ID", "ipv6.opt.ioam.trace.node.eif",
4820 FT_UINT16, BASE_HEX, NULL, 0x0,
4821 NULL, HFILL }
4823 { &hf_ipv6_opt_ioam_trace_node_tss,
4824 { "Timestamp Seconds", "ipv6.opt.ioam.trace.node.tss",
4825 FT_UINT32, BASE_HEX, NULL, 0x0,
4826 NULL, HFILL }
4828 { &hf_ipv6_opt_ioam_trace_node_tsf,
4829 { "Timestamp Fraction", "ipv6.opt.ioam.trace.node.tsf",
4830 FT_UINT32, BASE_HEX, NULL, 0x0,
4831 NULL, HFILL }
4833 { &hf_ipv6_opt_ioam_trace_node_trdelay,
4834 { "Transit Delay", "ipv6.opt.ioam.trace.node.trdelay",
4835 FT_UINT32, BASE_HEX, NULL, 0x0,
4836 NULL, HFILL }
4838 { &hf_ipv6_opt_ioam_trace_node_nsdata,
4839 { "Namespace Data (short)", "ipv6.opt.ioam.trace.node.nsdata",
4840 FT_UINT32, BASE_HEX, NULL, 0x0,
4841 NULL, HFILL }
4843 { &hf_ipv6_opt_ioam_trace_node_qdepth,
4844 { "Queue Depth", "ipv6.opt.ioam.trace.node.qdepth",
4845 FT_UINT32, BASE_HEX, NULL, 0x0,
4846 NULL, HFILL }
4848 { &hf_ipv6_opt_ioam_trace_node_csum,
4849 { "Checksum Complement", "ipv6.opt.ioam.trace.node.csum",
4850 FT_UINT32, BASE_HEX, NULL, 0x0,
4851 NULL, HFILL }
4853 { &hf_ipv6_opt_ioam_trace_node_id_wide,
4854 { "ID", "ipv6.opt.ioam.trace.node.id_wide",
4855 FT_UINT56, BASE_HEX, NULL, 0x0,
4856 NULL, HFILL }
4858 { &hf_ipv6_opt_ioam_trace_node_iif_wide,
4859 { "Ingress ID", "ipv6.opt.ioam.trace.node.iif_wide",
4860 FT_UINT32, BASE_HEX, NULL, 0x0,
4861 NULL, HFILL }
4863 { &hf_ipv6_opt_ioam_trace_node_eif_wide,
4864 { "Egress ID", "ipv6.opt.ioam.trace.node.eif_wide",
4865 FT_UINT32, BASE_HEX, NULL, 0x0,
4866 NULL, HFILL }
4868 { &hf_ipv6_opt_ioam_trace_node_nsdata_wide,
4869 { "Namespace Data (wide)", "ipv6.opt.ioam.trace.node.nsdata_wide",
4870 FT_UINT64, BASE_HEX, NULL, 0x0,
4871 NULL, HFILL }
4873 { &hf_ipv6_opt_ioam_trace_node_bufoccup,
4874 { "Buffer Occupancy", "ipv6.opt.ioam.trace.node.bufoccup",
4875 FT_UINT32, BASE_HEX, NULL, 0x0,
4876 NULL, HFILL }
4878 { &hf_ipv6_opt_ioam_trace_node_undefined,
4879 { "Undefined bit", "ipv6.opt.ioam.trace.node.undefined",
4880 FT_UINT32, BASE_HEX, NULL, 0x0,
4881 NULL, HFILL }
4883 { &hf_ipv6_opt_ioam_trace_node_oss_len,
4884 { "Length", "ipv6.opt.ioam.trace.node.oss.len",
4885 FT_UINT8, BASE_DEC, NULL, 0x0,
4886 NULL, HFILL }
4888 { &hf_ipv6_opt_ioam_trace_node_oss_scid,
4889 { "Schema ID", "ipv6.opt.ioam.trace.node.oss.scid",
4890 FT_UINT24, BASE_HEX, NULL, 0x0,
4891 NULL, HFILL }
4893 { &hf_ipv6_opt_ioam_trace_node_oss_data,
4894 { "Data", "ipv6.opt.ioam.trace.node.oss.data",
4895 FT_BYTES, BASE_NONE, NULL, 0x0,
4896 NULL, HFILL }
4898 { &hf_ipv6_opt_ioam_dex_ns,
4899 { "Namespace ID", "ipv6.opt.ioam.dex.ns",
4900 FT_UINT16, BASE_DEC, NULL, 0x0,
4901 NULL, HFILL }
4903 { &hf_ipv6_opt_ioam_dex_flags,
4904 { "Flags", "ipv6.opt.ioam.dex.flags",
4905 FT_UINT8, BASE_DEC, NULL, 0x0,
4906 NULL, HFILL }
4908 { &hf_ipv6_opt_ioam_dex_extflags,
4909 { "Extension Flags", "ipv6.opt.ioam.dex.extflags",
4910 FT_UINT8, BASE_DEC, NULL, 0x0,
4911 NULL, HFILL }
4913 { &hf_ipv6_opt_ioam_dex_extflag_flag_seqnum,
4914 { "Sequence Number", "ipv6.opt.ioam.dex.extflag.flag.seqnum",
4915 FT_BOOLEAN, 8, NULL, 0x2,
4916 NULL, HFILL }
4918 { &hf_ipv6_opt_ioam_dex_extflag_flag_flowid,
4919 { "Flow ID", "ipv6.opt.ioam.dex.extflag.flag.flowid",
4920 FT_BOOLEAN, 8, NULL, 0x1,
4921 NULL, HFILL }
4923 { &hf_ipv6_opt_ioam_dex_extflag_flag_rsv,
4924 { "Reserved", "ipv6.opt.ioam.trace.type.rsv",
4925 FT_BOOLEAN, 8, NULL, 0xFC,
4926 NULL, HFILL }
4928 { &hf_ipv6_opt_ioam_dex_extflag_flowid,
4929 { "Flow ID", "ipv6.opt.ioam.dex.extflag.flowid",
4930 FT_UINT32, BASE_DEC, NULL, 0x0,
4931 NULL, HFILL }
4933 { &hf_ipv6_opt_ioam_dex_extflag_seqnum,
4934 { "Sequence Number", "ipv6.opt.ioam.dex.extflag.seqnum",
4935 FT_UINT32, BASE_DEC, NULL, 0x0,
4936 NULL, HFILL }
4938 { &hf_ipv6_opt_ioam_dex_rsv,
4939 { "Reserved", "ipv6.opt.ioam.dex.rsv",
4940 FT_UINT8, BASE_DEC, NULL, 0x0,
4941 NULL, HFILL }
4943 { &hf_ipv6_opt_tpf_information,
4944 { "TPF Information", "ipv6.opt.tpf_information",
4945 FT_UINT32, BASE_HEX, NULL, 0x0,
4946 "Tunnel Payload Forwarding Information", HFILL }
4948 { &hf_ipv6_opt_mipv6_home_address,
4949 { "MIPv6 Home Address", "ipv6.opt.mipv6.home_address",
4950 FT_IPv6, BASE_NONE, NULL, 0x0,
4951 NULL, HFILL }
4953 { &hf_ipv6_opt_rpl_flag,
4954 { "Flag", "ipv6.opt.rpl.flag",
4955 FT_UINT8, BASE_HEX, NULL, 0x0,
4956 NULL, HFILL }
4958 { &hf_ipv6_opt_rpl_flag_o,
4959 { "Down", "ipv6.opt.rpl.flag.o",
4960 FT_BOOLEAN, 8, NULL, 0x80,
4961 "The packet is expected to progress Up or Down", HFILL }
4963 { &hf_ipv6_opt_rpl_flag_r,
4964 { "Rank Error", "ipv6.opt.rpl.flag.r",
4965 FT_BOOLEAN, 8, NULL, 0x40,
4966 "Whether a rank error was detected", HFILL }
4968 { &hf_ipv6_opt_rpl_flag_f,
4969 { "Forwarding Error", "ipv6.opt.rpl.flag.f",
4970 FT_BOOLEAN, 8, NULL, 0x20,
4971 "Set if the node cannot forward the packet further towards the destination", HFILL }
4973 { &hf_ipv6_opt_rpl_flag_rsv,
4974 { "Reserved", "ipv6.opt.rpl.flag.rsv",
4975 FT_UINT8, BASE_HEX, NULL, 0x1F,
4976 "Reserved (must be zero)", HFILL }
4978 { &hf_ipv6_opt_rpl_instance_id,
4979 { "RPLInstanceID", "ipv6.opt.rpl.instance_id",
4980 FT_UINT8, BASE_HEX, NULL, 0x0,
4981 "The DODAG instance along which the packet is sent", HFILL }
4983 { &hf_ipv6_opt_rpl_senderrank,
4984 { "Sender Rank", "ipv6.opt.rpl.sender_rank",
4985 FT_UINT16, BASE_HEX, NULL, 0x0,
4986 "Set to zero by the source and to DAGRank(rank) by a router that forwards inside the RPL network", HFILL }
4988 { &hf_ipv6_opt_ilnp_nonce,
4989 { "ILNP Nonce", "ipv6.opt.ilnp_nonce",
4990 FT_BYTES, BASE_NONE, NULL, 0x0,
4991 NULL, HFILL }
4993 { &hf_ipv6_opt_lio_len,
4994 { "LineIDLen", "ipv6.opt.lio.length",
4995 FT_UINT8, BASE_DEC, NULL, 0x0,
4996 NULL, HFILL }
4998 { &hf_ipv6_opt_lio_id,
4999 { "Line ID", "ipv6.opt.lio.line_id",
5000 FT_STRING, BASE_NONE, NULL, 0x0,
5001 NULL, HFILL }
5003 { &hf_ipv6_opt_mpl_flag,
5004 { "Flag", "ipv6.opt.mpl.flag",
5005 FT_UINT8, BASE_HEX, NULL, 0x0,
5006 NULL, HFILL }
5008 { &hf_ipv6_opt_mpl_flag_s,
5009 { "Seed ID Length", "ipv6.opt.mpl.flag.s",
5010 FT_UINT8, BASE_DEC, VALS(mpl_seed_id_len_vals), 0xC0,
5011 "Identifies the length of Seed ID", HFILL }
5013 { &hf_ipv6_opt_mpl_flag_m,
5014 { "Largest Sequence", "ipv6.opt.mpl.flag.m",
5015 FT_BOOLEAN, 8, NULL, 0x20,
5016 "Indicates Sequence is known to be the largest sequence number", HFILL }
5018 { &hf_ipv6_opt_mpl_flag_v,
5019 { "Version", "ipv6.opt.mpl.flag.v",
5020 FT_BOOLEAN, 8, NULL, 0x10,
5021 "0 indicates this option conforms to RFC<TBC>", HFILL }
5023 { &hf_ipv6_opt_mpl_flag_rsv,
5024 { "Reserved", "ipv6.opt.mpl.flag.rsv",
5025 FT_UINT8, BASE_HEX, NULL, 0x0F,
5026 "Reserved (must be zero)", HFILL }
5028 { &hf_ipv6_opt_mpl_sequence,
5029 { "Sequence", "ipv6.opt.mpl.sequence",
5030 FT_UINT8, BASE_HEX, NULL, 0x0,
5031 "Identifies relative ordering of MPL Data Messages from the MPL Seed identified by Seed ID", HFILL }
5033 { &hf_ipv6_opt_mpl_seed_id,
5034 { "Seed ID", "ipv6.opt.mpl.seed_id",
5035 FT_BYTES, BASE_NONE, NULL, 0x0,
5036 "Uniquely identifies the MPL Seed that initiated dissemination of the MPL Data Message", HFILL }
5038 { &hf_ipv6_opt_dff_flags,
5039 { "Flags", "ipv6.opt.dff.flags",
5040 FT_UINT8, BASE_HEX, NULL, 0x0,
5041 NULL, HFILL }
5043 { &hf_ipv6_opt_dff_flag_ver,
5044 { "Version (VER)", "ipv6.opt.dff.flag.ver",
5045 FT_UINT8, BASE_DEC, NULL, 0xC0,
5046 "The version of DFF that is used", HFILL }
5048 { &hf_ipv6_opt_dff_flag_dup,
5049 { "Duplicate (DUP)", "ipv6.opt.dff.flag.dup",
5050 FT_BOOLEAN, 8, NULL, 0x20,
5051 "Indicates the packet is being retransmitted", HFILL }
5053 { &hf_ipv6_opt_dff_flag_ret,
5054 { "Return (RET)", "ipv6.opt.dff.flag.ret",
5055 FT_BOOLEAN, 8, NULL, 0x10,
5056 "Must be set to 1 prior to sending the packet back to the Previous Hop", HFILL }
5058 { &hf_ipv6_opt_dff_flag_rsv,
5059 { "Reserved", "ipv6.opt.dff.flag.rsv",
5060 FT_UINT8, BASE_HEX, NULL, 0x0F,
5061 "Reserved (must be zero)", HFILL }
5063 { &hf_ipv6_opt_dff_seqnum,
5064 { "Sequence Number", "ipv6.opt.dff.sequence_number",
5065 FT_UINT16, BASE_DEC_HEX, NULL, 0x0,
5066 NULL, HFILL }
5068 { &hf_ipv6_opt_experimental,
5069 { "Experimental Option", "ipv6.opt.experimental",
5070 FT_BYTES, BASE_NONE, NULL, 0x0,
5071 NULL, HFILL }
5073 { &hf_ipv6_opt_unknown_data,
5074 { "Unknown Data", "ipv6.opt_unknown_data",
5075 FT_BYTES, BASE_NONE, NULL, 0x0,
5076 "Not interpreted data", HFILL }
5078 { &hf_ipv6_opt_unknown,
5079 { "Unknown Option Payload", "ipv6.opt.unknown",
5080 FT_BYTES, BASE_NONE, NULL, 0x0,
5081 NULL, HFILL }
5083 { &hf_ipv6_fragment,
5084 { "IPv6 Fragment", "ipv6.fragment",
5085 FT_FRAMENUM, BASE_NONE, NULL, 0x0,
5086 NULL, HFILL }
5088 { &hf_ipv6_fragment_overlap,
5089 { "Fragment overlap", "ipv6.fragment.overlap",
5090 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
5091 "Fragment overlaps with other fragments", HFILL }
5093 { &hf_ipv6_fragment_overlap_conflict,
5094 { "Conflicting data in fragment overlap", "ipv6.fragment.overlap.conflict",
5095 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
5096 "Overlapping fragments contained conflicting data", HFILL }
5098 { &hf_ipv6_fragment_multiple_tails,
5099 { "Multiple tail fragments found", "ipv6.fragment.multipletails",
5100 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
5101 "Several tails were found when defragmenting the packet", HFILL }
5103 { &hf_ipv6_fragment_too_long_fragment,
5104 { "Fragment too long", "ipv6.fragment.toolongfragment",
5105 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
5106 "Fragment contained data past end of packet", HFILL }
5108 { &hf_ipv6_fragment_error,
5109 { "Defragmentation error", "ipv6.fragment.error",
5110 FT_FRAMENUM, BASE_NONE, NULL, 0x0,
5111 "Defragmentation error due to illegal fragments", HFILL }
5113 { &hf_ipv6_fragment_count,
5114 { "Fragment count", "ipv6.fragment.count",
5115 FT_UINT32, BASE_DEC, NULL, 0x0,
5116 NULL, HFILL }
5118 { &hf_ipv6_fragments,
5119 { "IPv6 Fragments", "ipv6.fragments",
5120 FT_NONE, BASE_NONE, NULL, 0x0,
5121 NULL, HFILL }
5123 { &hf_ipv6_reassembled_in,
5124 { "Reassembled IPv6 in frame", "ipv6.reassembled.in",
5125 FT_FRAMENUM, BASE_NONE, NULL, 0x0,
5126 "This IPv6 packet is reassembled in this frame", HFILL }
5128 { &hf_ipv6_reassembled_length,
5129 { "Reassembled IPv6 length", "ipv6.reassembled.length",
5130 FT_UINT32, BASE_DEC, NULL, 0x0,
5131 "The total length of the reassembled payload", HFILL }
5133 { &hf_ipv6_reassembled_data,
5134 { "Reassembled IPv6 data", "ipv6.reassembled.data",
5135 FT_BYTES, BASE_NONE, NULL, 0x0,
5136 "The reassembled payload", HFILL }
5140 static hf_register_info hf_ipv6_hopopts[] = {
5141 { &hf_ipv6_hopopts_nxt,
5142 { "Next Header", "ipv6.hopopts.nxt",
5143 FT_UINT8, BASE_DEC | BASE_EXT_STRING, &ipproto_val_ext, 0x0,
5144 NULL, HFILL }
5146 { &hf_ipv6_hopopts_len,
5147 { "Length", "ipv6.hopopts.len",
5148 FT_UINT8, BASE_DEC, NULL, 0x0,
5149 "Extension header length in 8-octet words (minus 1)", HFILL }
5151 { &hf_ipv6_hopopts_len_oct,
5152 { "Length", "ipv6.hopopts.len_oct",
5153 FT_UINT16, BASE_DEC|BASE_UNIT_STRING, UNS(&units_byte_bytes), 0x0,
5154 "Extension header length in octets", HFILL }
5158 static hf_register_info hf_ipv6_dstopts[] = {
5159 { &hf_ipv6_dstopts_nxt,
5160 { "Next Header", "ipv6.dstopts.nxt",
5161 FT_UINT8, BASE_DEC | BASE_EXT_STRING, &ipproto_val_ext, 0x0,
5162 NULL, HFILL }
5164 { &hf_ipv6_dstopts_len,
5165 { "Length", "ipv6.dstopts.len",
5166 FT_UINT8, BASE_DEC, NULL, 0x0,
5167 "Extension header length in 8-octet words (minus 1)", HFILL }
5169 { &hf_ipv6_dstopts_len_oct,
5170 { "Length", "ipv6.dstopts.len_oct",
5171 FT_UINT16, BASE_DEC|BASE_UNIT_STRING, UNS(&units_byte_bytes), 0x0,
5172 "Extension header length in octets", HFILL }
5176 static hf_register_info hf_ipv6_routing[] = {
5178 /* IPv6 Routing Header */
5179 { &hf_ipv6_routing_nxt,
5180 { "Next Header", "ipv6.routing.nxt",
5181 FT_UINT8, BASE_DEC | BASE_EXT_STRING, &ipproto_val_ext, 0x0,
5182 NULL, HFILL }
5184 { &hf_ipv6_routing_len,
5185 { "Length", "ipv6.routing.len",
5186 FT_UINT8, BASE_DEC, NULL, 0x0,
5187 "Extension header length in 8-octet words (minus 1)", HFILL }
5189 { &hf_ipv6_routing_len_oct,
5190 { "Length", "ipv6.routing.len_oct",
5191 FT_UINT16, BASE_DEC|BASE_UNIT_STRING, UNS(&units_byte_bytes), 0x0,
5192 "Extension header length in octets", HFILL }
5194 { &hf_ipv6_routing_type,
5195 { "Type", "ipv6.routing.type",
5196 FT_UINT8, BASE_DEC, VALS(routing_header_type), 0x0,
5197 "Routing Header Type", HFILL }
5199 { &hf_ipv6_routing_segleft,
5200 { "Segments Left", "ipv6.routing.segleft",
5201 FT_UINT8, BASE_DEC, NULL, 0x0,
5202 "Routing Header Segments Left", HFILL }
5204 { &hf_ipv6_routing_unknown_data,
5205 { "Type-Specific Data", "ipv6.routing.unknown_data",
5206 FT_BYTES, BASE_NONE, NULL, 0x0,
5207 "Unknown routing header type-specific data", HFILL }
5210 /* Source Routing Header */
5211 { &hf_ipv6_routing_src_reserved,
5212 { "Reserved", "ipv6.routing.src.reserved",
5213 FT_BYTES, BASE_NONE, NULL, 0x0,
5214 "Must be zero", HFILL }
5216 { &hf_ipv6_routing_src_addr,
5217 { "Address", "ipv6.routing.src.addr",
5218 FT_IPv6, BASE_NONE, NULL, 0x0,
5219 "Source Routing Header Address", HFILL }},
5221 /* Mobile IPv6 */
5222 { &hf_ipv6_routing_mipv6_reserved,
5223 { "Reserved", "ipv6.routing.mipv6.reserved",
5224 FT_BYTES, BASE_NONE, NULL, 0x0,
5225 "Must be zero", HFILL }
5227 { &hf_ipv6_routing_mipv6_home_address,
5228 { "Home Address", "ipv6.routing.mipv6.home_address",
5229 FT_IPv6, BASE_NONE, NULL, 0x0,
5230 NULL, HFILL }
5233 /* RPL Routing Header */
5234 { &hf_ipv6_routing_rpl_cmprI,
5235 { "Compressed Internal Octets (CmprI)", "ipv6.routing.rpl.cmprI",
5236 FT_UINT32, BASE_DEC, NULL, IP6RRPL_BITMASK_CMPRI,
5237 "Elided octets from all but last segment", HFILL }
5239 { &hf_ipv6_routing_rpl_cmprE,
5240 { "Compressed Final Octets (CmprE)", "ipv6.routing.rpl.cmprE",
5241 FT_UINT32, BASE_DEC, NULL, IP6RRPL_BITMASK_CMPRE,
5242 "Elided octets from last segment address", HFILL }
5244 { &hf_ipv6_routing_rpl_pad,
5245 { "Padding Bytes", "ipv6.routing.rpl.pad",
5246 FT_UINT32, BASE_DEC, NULL, IP6RRPL_BITMASK_PAD,
5247 NULL, HFILL }
5249 { &hf_ipv6_routing_rpl_reserved,
5250 { "Reserved", "ipv6.routing.rpl.reserved",
5251 FT_UINT32, BASE_DEC, NULL, IP6RRPL_BITMASK_RESERVED,
5252 "Must be zero", HFILL }
5254 { &hf_ipv6_routing_rpl_addr_count,
5255 { "Total Address Count", "ipv6.routing.rpl.addr_count",
5256 FT_INT32, BASE_DEC, NULL, 0,
5257 NULL, HFILL }
5259 { &hf_ipv6_routing_rpl_addr,
5260 { "Address", "ipv6.routing.rpl.address",
5261 FT_BYTES, BASE_NONE, NULL, 0,
5262 NULL, HFILL }
5264 { &hf_ipv6_routing_rpl_fulladdr,
5265 { "Full Address", "ipv6.routing.rpl.full_address",
5266 FT_IPv6, BASE_NONE, NULL, 0,
5267 "Uncompressed IPv6 Address", HFILL }
5270 /* Segment Routing Header */
5271 { &hf_ipv6_routing_srh_last_entry,
5272 { "Last Entry", "ipv6.routing.srh.last_entry",
5273 FT_UINT8, BASE_DEC, NULL, 0x0,
5274 "Index (zero based) of the last element of the Segment List", HFILL }
5276 { &hf_ipv6_routing_srh_flags,
5277 { "Flags", "ipv6.routing.srh.flags",
5278 FT_UINT8, BASE_HEX, NULL, 0x0,
5279 "Unused, 8 bits of flags", HFILL }
5281 { &hf_ipv6_routing_srh_tag,
5282 { "Tag", "ipv6.routing.srh.tag",
5283 FT_BYTES, BASE_NONE, NULL, 0x0,
5284 "Tag a packet as part of a class or group of packets", HFILL }
5286 { &hf_ipv6_routing_srh_addr,
5287 { "Address", "ipv6.routing.srh.addr",
5288 FT_IPv6, BASE_NONE, NULL, 0x0,
5289 "Segment address", HFILL }
5292 /* Compact Routing Header */
5293 { &hf_ipv6_routing_crh16_current_sid,
5294 { "Current SID", "ipv6.routing.crh16.current_sid",
5295 FT_UINT16, BASE_DEC, NULL, 0x0,
5296 "Value of the current Segment ID", HFILL }
5298 { &hf_ipv6_routing_crh32_current_sid,
5299 { "Current SID", "ipv6.routing.crh32.current_sid",
5300 FT_UINT32, BASE_DEC, NULL, 0x0,
5301 "Value of the current Segment ID", HFILL }
5303 { &hf_ipv6_routing_crh16_segment_id,
5304 { "Segment ID", "ipv6.routing.crh16.sid",
5305 FT_UINT16, BASE_DEC, NULL, 0x0,
5306 "Segment address", HFILL }
5308 { &hf_ipv6_routing_crh32_segment_id,
5309 { "Segment ID", "ipv6.routing.crh32.sid",
5310 FT_UINT32, BASE_DEC, NULL, 0x0,
5311 "Segment address", HFILL }
5315 static hf_register_info hf_ipv6_fraghdr[] = {
5316 { &hf_ipv6_fraghdr_nxt,
5317 { "Next header", "ipv6.fraghdr.nxt",
5318 FT_UINT8, BASE_DEC | BASE_EXT_STRING, &ipproto_val_ext, 0x0,
5319 NULL, HFILL }
5321 { &hf_ipv6_fraghdr_reserved_octet,
5322 { "Reserved octet", "ipv6.fraghdr.reserved_octet",
5323 FT_UINT8, BASE_HEX, NULL, 0x0,
5324 "Should always be 0", HFILL }
5326 { &hf_ipv6_fraghdr_offset,
5327 { "Offset", "ipv6.fraghdr.offset",
5328 FT_UINT16, BASE_DEC, NULL, IP6F_OFF_MASK,
5329 "Fragment Offset", HFILL }
5331 { &hf_ipv6_fraghdr_reserved_bits,
5332 { "Reserved bits", "ipv6.fraghdr.reserved_bits",
5333 FT_UINT16, BASE_DEC, NULL, IP6F_RESERVED_MASK,
5334 NULL, HFILL }
5336 { &hf_ipv6_fraghdr_more,
5337 { "More Fragments", "ipv6.fraghdr.more",
5338 FT_BOOLEAN, 16, TFS(&tfs_yes_no), IP6F_MORE_FRAG,
5339 NULL, HFILL }
5341 { &hf_ipv6_fraghdr_ident,
5342 { "Identification", "ipv6.fraghdr.ident",
5343 FT_UINT32, BASE_HEX, NULL, 0x0,
5344 "Fragment Identification", HFILL }
5348 static int *ett_ipv6[] = {
5349 &ett_ipv6_proto,
5350 &ett_ipv6_detail,
5351 &ett_ipv6_detail_special_purpose,
5352 &ett_ipv6_multicast_flags,
5353 &ett_ipv6_traffic_class,
5354 &ett_geoip_info,
5355 &ett_ipv6_opt,
5356 &ett_ipv6_opt_type,
5357 &ett_ipv6_opt_rpl,
5358 &ett_ipv6_opt_mpl,
5359 &ett_ipv6_opt_dff_flags,
5360 &ett_ipv6_opt_ioam_trace_flags,
5361 &ett_ipv6_opt_ioam_trace_types,
5362 &ett_ipv6_fragment,
5363 &ett_ipv6_fragments
5366 static int *ett_ipv6_hopopts[] = {
5367 &ett_ipv6_hopopts_proto
5370 static int *ett_ipv6_routing[] = {
5371 &ett_ipv6_routing_proto,
5372 &ett_ipv6_routing_srh_vect
5375 static int *ett_ipv6_fraghdr[] = {
5376 &ett_ipv6_fraghdr_proto
5379 static int *ett_ipv6_dstopts[] = {
5380 &ett_ipv6_dstopts_proto
5383 static ei_register_info ei_ipv6[] = {
5384 { &ei_ipv6_opt_jumbo_missing,
5385 { "ipv6.opt.jumbo.missing", PI_MALFORMED, PI_ERROR,
5386 "IPv6 payload length equals 0 and Hop-By-Hop present and Jumbo Payload option missing", EXPFILL }
5388 { &ei_ipv6_opt_jumbo_prohibited,
5389 { "ipv6.opt.jumbo.prohibited", PI_PROTOCOL, PI_WARN,
5390 "When IPv6 payload length does not equal 0 a Jumbo Payload option must not be present", EXPFILL }
5392 { &ei_ipv6_opt_jumbo_truncated,
5393 { "ipv6.opt.jumbo.truncated", PI_PROTOCOL, PI_WARN,
5394 "Jumbo Payload option present and jumbo length < 65536", EXPFILL }
5396 { &ei_ipv6_opt_jumbo_fragment,
5397 { "ipv6.opt.jumbo.fragment", PI_PROTOCOL, PI_WARN,
5398 "Jumbo Payload option cannot be used with a fragment header", EXPFILL }
5400 { &ei_ipv6_opt_invalid_len,
5401 { "ipv6.opt.invalid_len", PI_MALFORMED, PI_ERROR,
5402 "Invalid IPv6 option length", EXPFILL }
5404 { &ei_ipv6_opt_apn_invalid_id_type,
5405 { "ipv6.opt.apn.invalid.id_type", PI_MALFORMED, PI_ERROR,
5406 "Invalid APN ID Type", EXPFILL }
5408 { &ei_ipv6_opt_unknown_data,
5409 { "ipv6.opt.unknown_data.expert", PI_UNDECODED, PI_NOTE,
5410 "Unknown Data (not interpreted)", EXPFILL }
5412 { &ei_ipv6_plen_exceeds_framing,
5413 { "ipv6.plen_exceeds_framing", PI_PROTOCOL, PI_WARN,
5414 "IPv6 payload length does not match expected framing length", EXPFILL }
5416 { &ei_ipv6_plen_zero,
5417 { "ipv6.plen_zero", PI_PROTOCOL, PI_CHAT,
5418 "IPv6 payload length equals 0 (maybe because of \"TCP segmentation offload\" (TSO))", EXPFILL }
5420 { &ei_ipv6_bogus_ipv6_version,
5421 { "ipv6.bogus_ipv6_version", PI_MALFORMED, PI_ERROR,
5422 "Bogus IP version", EXPFILL }
5424 { &ei_ipv6_invalid_header,
5425 { "ipv6.invalid_header", PI_MALFORMED, PI_ERROR,
5426 "Invalid IPv6 header", EXPFILL }
5428 { &ei_ipv6_opt_header_mismatch,
5429 { "ipv6.opt.header_mismatch", PI_PROTOCOL, PI_WARN,
5430 "Wrong options extension header for type", EXPFILL }
5432 { &ei_ipv6_opt_deprecated,
5433 { "ipv6.opt.deprecated", PI_DEPRECATED, PI_NOTE,
5434 "Option type is deprecated", EXPFILL }
5436 { &ei_ipv6_opt_mpl_ipv6_src_seed_id,
5437 { "ipv6.opt.mpl.ipv6_src_seed_id", PI_PROTOCOL, PI_COMMENT,
5438 "Seed ID is the IPv6 Source Address", EXPFILL }
5440 { &ei_ipv6_opt_ioam_invalid_nodelen,
5441 { "ipv6.opt.ioam.trace.invalid_nodelen", PI_PROTOCOL, PI_ERROR,
5442 "Invalid \"NodeLen\" value: cannot be 0", EXPFILL }
5444 { &ei_ipv6_opt_ioam_invalid_remlen,
5445 { "ipv6.opt.ioam.trace.invalid_remlen", PI_PROTOCOL, PI_ERROR,
5446 "Invalid \"RemLen\" value", EXPFILL }
5448 { &ei_ipv6_opt_ioam_invalid_trace_type,
5449 { "ipv6.opt.ioam.trace.invalid_type", PI_PROTOCOL, PI_ERROR,
5450 "Mismatch between Trace Type and NodeLen", EXPFILL }
5452 { &ei_ipv6_embed_ipv4_u_value,
5453 { "ipv6.embed_ipv4.u.nonzero", PI_PROTOCOL, PI_WARN,
5454 "IPv4-Embedded IPv6 address bit 64 to 71 must be zero", EXPFILL }
5456 { &ei_ipv6_dst_addr_not_unspecified,
5457 { "ipv6.addr.not_unspecified", PI_PROTOCOL, PI_WARN,
5458 "Unspecified address cannot appear as a destination", EXPFILL }
5462 static ei_register_info ei_ipv6_hopopts[] = {
5463 { &ei_ipv6_hopopts_not_first,
5464 { "ipv6.hopopts.not_first", PI_PROTOCOL, PI_ERROR,
5465 "IPv6 Hop-by-Hop extension header must appear immediately after IPv6 header", EXPFILL }
5469 static ei_register_info ei_ipv6_routing[] = {
5470 { &ei_ipv6_src_addr_not_multicast,
5471 { "ipv6.src_addr.not_multicast", PI_PROTOCOL, PI_WARN,
5472 "Source address must not be a multicast address", EXPFILL }
5474 { &ei_ipv6_dst_addr_not_multicast,
5475 { "ipv6.dst_addr.not_multicast", PI_PROTOCOL, PI_WARN,
5476 "Destination address must not be a multicast address", EXPFILL }
5478 { &ei_ipv6_src_route_list_mult_inst_same_addr,
5479 { "ipv6.src_route_list.mult_inst_same_addr", PI_PROTOCOL, PI_WARN,
5480 "Multiple instances of the same address must not appear in the source route list", EXPFILL }
5482 { &ei_ipv6_src_route_list_src_addr,
5483 { "ipv6.src_route_list.src_addr", PI_PROTOCOL, PI_WARN,
5484 "Source address must not appear in the source route list", EXPFILL }
5486 { &ei_ipv6_src_route_list_dst_addr,
5487 { "ipv6.src_route_list.dst_addr", PI_PROTOCOL, PI_WARN,
5488 "Destination address must not appear in the source route list", EXPFILL }
5490 { &ei_ipv6_src_route_list_multicast_addr,
5491 { "ipv6.src_route_list.multicast_addr", PI_PROTOCOL, PI_WARN,
5492 "Multicast addresses must not appear in the source route list", EXPFILL }
5494 { &ei_ipv6_routing_rpl_cmpri_cmpre_pad,
5495 { "ipv6.routing.rpl.cmprI_cmprE_pad", PI_PROTOCOL, PI_WARN,
5496 "When cmprI equals 0 and cmprE equals 0, pad MUST equal 0 but instead was X", EXPFILL }
5498 { &ei_ipv6_routing_rpl_addr_count_ge0,
5499 { "ipv6.routing.rpl.addr_count_ge0", PI_MALFORMED, PI_ERROR,
5500 "Calculated total address count must be greater than or equal to 0, instead was X", EXPFILL }
5502 { &ei_ipv6_routing_rpl_reserved,
5503 { "ipv6.routing.rpl.reserved_not0", PI_PROTOCOL, PI_NOTE,
5504 "Reserved field must equal 0 but instead was X", EXPFILL }
5506 { &ei_ipv6_routing_invalid_length,
5507 { "ipv6.routing.invalid_length", PI_MALFORMED, PI_ERROR,
5508 "Invalid IPv6 Routing header length", EXPFILL }
5510 { &ei_ipv6_routing_invalid_segleft,
5511 { "ipv6.routing.invalid_segleft", PI_PROTOCOL, PI_WARN,
5512 "IPv6 Routing Header segments left field must not exceed address count", EXPFILL }
5514 { &ei_ipv6_routing_undecoded,
5515 { "ipv6.routing.undecoded", PI_UNDECODED, PI_NOTE,
5516 "Undecoded IPv6 routing header field", EXPFILL }
5518 { &ei_ipv6_routing_deprecated,
5519 { "ipv6.routing.deprecated", PI_DEPRECATED, PI_NOTE,
5520 "Routing header type is deprecated", EXPFILL }
5524 /* Decode As handling */
5525 static build_valid_func ipv6_da_build_value[1] = {ipv6_value};
5526 static decode_as_value_t ipv6_da_values = {ipv6_prompt, 1, ipv6_da_build_value};
5528 static decode_as_t ipv6_da = {"ipv6", "ip.proto", 1, 0, &ipv6_da_values, NULL, NULL,
5529 decode_as_default_populate_list, decode_as_default_reset, decode_as_default_change, NULL};
5531 static decode_as_t ipv6_hopopts_da = {"ipv6.hopopts", "ip.proto", 1, 0, &ipv6_da_values, NULL, NULL,
5532 decode_as_default_populate_list, decode_as_default_reset, decode_as_default_change, NULL};
5534 static decode_as_t ipv6_routing_da = {"ipv6.routing", "ip.proto", 1, 0, &ipv6_da_values, NULL, NULL,
5535 decode_as_default_populate_list, decode_as_default_reset, decode_as_default_change, NULL};
5537 static decode_as_t ipv6_fraghdr_da = {"ipv6.fraghdr", "ip.proto", 1, 0, &ipv6_da_values, NULL, NULL,
5538 decode_as_default_populate_list, decode_as_default_reset, decode_as_default_change, NULL};
5540 static decode_as_t ipv6_dstopts_da = {"ipv6.dstopts", "ip.proto", 1, 0, &ipv6_da_values, NULL, NULL,
5541 decode_as_default_populate_list, decode_as_default_reset, decode_as_default_change, NULL};
5543 module_t *ipv6_module;
5544 expert_module_t* expert_ipv6;
5545 expert_module_t* expert_ipv6_hopopts;
5546 expert_module_t* expert_ipv6_routing;
5548 proto_ipv6 = proto_register_protocol("Internet Protocol Version 6", "IPv6", "ipv6");
5549 proto_register_field_array(proto_ipv6, hf_ipv6, array_length(hf_ipv6));
5550 proto_register_subtree_array(ett_ipv6, array_length(ett_ipv6));
5551 expert_ipv6 = expert_register_protocol(proto_ipv6);
5552 expert_register_field_array(expert_ipv6, ei_ipv6, array_length(ei_ipv6));
5554 proto_ipv6_hopopts = proto_register_protocol("IPv6 Hop-by-Hop Option", "IPv6 Hop-by-Hop", "ipv6.hopopts");
5555 proto_register_field_array(proto_ipv6_hopopts, hf_ipv6_hopopts, array_length(hf_ipv6_hopopts));
5556 proto_register_subtree_array(ett_ipv6_hopopts, array_length(ett_ipv6_hopopts));
5557 expert_ipv6_hopopts = expert_register_protocol(proto_ipv6_hopopts);
5558 expert_register_field_array(expert_ipv6_hopopts, ei_ipv6_hopopts, array_length(ei_ipv6_hopopts));
5560 proto_ipv6_routing = proto_register_protocol("Routing Header for IPv6", "IPv6 Routing", "ipv6.routing");
5561 proto_register_field_array(proto_ipv6_routing, hf_ipv6_routing, array_length(hf_ipv6_routing));
5562 proto_register_subtree_array(ett_ipv6_routing, array_length(ett_ipv6_routing));
5563 expert_ipv6_routing = expert_register_protocol(proto_ipv6_routing);
5564 expert_register_field_array(expert_ipv6_routing, ei_ipv6_routing, array_length(ei_ipv6_routing));
5566 ipv6_routing_dissector_table = register_dissector_table("ipv6.routing.type", "IPv6 Routing Type",
5567 proto_ipv6_routing, FT_UINT8, BASE_DEC);
5569 proto_ipv6_routing_rt0 = proto_register_protocol_in_name_only("IPv6 Routing Type - Source Route", "Source Route", "ipv6.routing.type.rt0", proto_ipv6, FT_BYTES);
5570 proto_ipv6_routing_mipv6 = proto_register_protocol_in_name_only("IPv6 Routing Type - Type 2", "Type 2", "ipv6.routing.type.mipv6", proto_ipv6, FT_BYTES);
5571 proto_ipv6_routing_rpl = proto_register_protocol_in_name_only("IPv6 Routing Type - RPL Source Route", "RPL Source Route", "ipv6.routing.type.mipv6", proto_ipv6, FT_BYTES);
5572 proto_ipv6_routing_srh = proto_register_protocol_in_name_only("IPv6 Routing Types - Segment Routing", "Segment Routing", "ipv6.routing.type.srh", proto_ipv6, FT_BYTES);
5573 proto_ipv6_routing_crh = proto_register_protocol_in_name_only("IPv6 Routing Types - Compact Routing", "Compact Routing", "ipv6.routing.type.crh", proto_ipv6, FT_BYTES);
5575 proto_ipv6_fraghdr = proto_register_protocol("Fragment Header for IPv6", "IPv6 Fragment", "ipv6.fraghdr");
5576 proto_register_field_array(proto_ipv6_fraghdr, hf_ipv6_fraghdr, array_length(hf_ipv6_fraghdr));
5577 proto_register_subtree_array(ett_ipv6_fraghdr, array_length(ett_ipv6_fraghdr));
5579 proto_ipv6_dstopts = proto_register_protocol("Destination Options for IPv6", "IPv6 Destination", "ipv6.dstopts");
5580 proto_register_field_array(proto_ipv6_dstopts, hf_ipv6_dstopts, array_length(hf_ipv6_dstopts));
5581 proto_register_subtree_array(ett_ipv6_dstopts, array_length(ett_ipv6_dstopts));
5583 /* Register configuration options */
5584 ipv6_module = prefs_register_protocol(proto_ipv6, NULL);
5585 prefs_register_bool_preference(ipv6_module, "defragment",
5586 "Reassemble fragmented IPv6 datagrams",
5587 "Whether fragmented IPv6 datagrams should be reassembled",
5588 &ipv6_reassemble);
5589 prefs_register_bool_preference(ipv6_module, "summary_in_tree",
5590 "Show IPv6 summary in protocol tree",
5591 "Whether the IPv6 summary line should be shown in the protocol tree",
5592 &ipv6_summary_in_tree);
5593 prefs_register_bool_preference(ipv6_module, "address_detail" ,
5594 "Show details about IPv6 addresses",
5595 "Whether to show extended information about IPv6 addresses",
5596 &ipv6_address_detail);
5598 prefs_register_obsolete_preference(ipv6_module, "use_geoip");
5600 /* RPL Strict Header Checking */
5601 prefs_register_bool_preference(ipv6_module, "perform_strict_rpl_srh_rfc_checking",
5602 "Perform strict checking for RPL Source Routing Headers (RFC 6554)",
5603 "Check that all RPL Source Routed packets conform to RFC 6554 and do not visit a node more than once",
5604 &g_ipv6_rpl_srh_strict_rfc_checking);
5606 prefs_register_bool_preference(ipv6_module, "try_heuristic_first",
5607 "Try heuristic sub-dissectors first",
5608 "Try to decode a packet using an heuristic sub-dissector before using a sub-dissector registered to a specific port",
5609 &try_heuristic_first);
5611 prefs_register_bool_preference(ipv6_module, "exthdr_under_root_protocol_tree",
5612 "Display IPv6 extension headers under the root protocol tree",
5613 "Whether to display IPv6 extension headers as a separate protocol or a sub-protocol of the IPv6 packet",
5614 &ipv6_exthdr_under_root);
5616 prefs_register_bool_preference(ipv6_module, "exthdr_hide_len_oct_field",
5617 "Use a single field for IPv6 extension header length",
5618 "If enabled the Length field in octets will be hidden",
5619 &ipv6_exthdr_hide_len_oct_field);
5621 prefs_register_bool_preference(ipv6_module, "tso_support",
5622 "Support packet-capture from IPv6 TSO-enabled hardware",
5623 "Whether to correct for TSO-enabled (TCP segmentation offload) hardware "
5624 "captures, such as spoofing the IPv6 packet length", &ipv6_tso_supported);
5626 prefs_register_static_text_preference(ipv6_module, "text_use_geoip" ,
5627 "IP geolocation settings can be changed in the Name Resolution preferences",
5628 "IP geolocation settings can be changed in the Name Resolution preferences");
5630 prefs_register_bool_preference(ipv6_module, "conv_id",
5631 "Assign IPv6 conversation IDs",
5632 "Whether to assign unique numbers to each IPv6 conversation (increases resource consumption)",
5633 &ipv6_track_conv_id);
5635 static uat_field_t nat64_uats_flds[] = {
5636 UAT_FLD_CSTRING_OTHER(nat64_prefix_uats, ipaddr, "NAT64 Prefix", nat64_prefix_uat_fld_ip_chk_cb, "IPv6 prefix address"),
5637 UAT_FLD_VS(nat64_prefix_uats, prefix_len, "Prefix length", nat64_prefix_length_vals, "IPv6 prefix address length"),
5638 UAT_FLD_VS(nat64_prefix_uats, prefix_wildcard_len, "Prefix wildcard length", nat64_prefix_wildcard_length_vals, "IPv6 prefix address wildcard length"),
5639 UAT_END_FIELDS
5642 nat64_prefix_uat = uat_new("NAT64 Network-Specific Prefixes",
5643 sizeof(struct nat64_prefix_data),
5644 "NAT64_NSP_list", /* filename */
5645 true, /* from_profile */
5646 &nat64_prefix_uats, /* data_ptr */
5647 &number_of_nat64_prefix, /* numitems_ptr */
5648 UAT_AFFECTS_DISSECTION,
5649 NULL,
5650 nat64_prefix_copy_cb,
5651 NULL,
5652 nat64_prefix_free_cb,
5653 NULL,
5654 NULL,
5655 nat64_uats_flds);
5657 prefs_register_uat_preference(ipv6_module, "nat64_prefixes",
5658 "NAT64 Prefixes",
5659 "A list of IPv6 prefixes used for NAT64s",
5660 nat64_prefix_uat);
5662 register_init_routine(ipv6_init);
5664 ipv6_handle = register_dissector("ipv6", dissect_ipv6, proto_ipv6);
5665 reassembly_table_register(&ipv6_reassembly_table,
5666 &addresses_reassembly_table_functions);
5667 ipv6_tap = register_tap("ipv6");
5669 register_decode_as(&ipv6_da);
5670 register_decode_as(&ipv6_hopopts_da);
5671 register_decode_as(&ipv6_routing_da);
5672 register_decode_as(&ipv6_fraghdr_da);
5673 register_decode_as(&ipv6_dstopts_da);
5675 register_conversation_table(proto_ipv6, true, ipv6_conversation_packet, ipv6_endpoint_packet);
5676 register_conversation_filter("ipv6", "IPv6", ipv6_filter_valid, ipv6_build_filter, NULL);
5678 register_capture_dissector("ipv6", capture_ipv6, proto_ipv6);
5681 void
5682 proto_reg_handoff_ipv6(void)
5684 dissector_handle_t ipv6_hopopts_handle;
5685 dissector_handle_t ipv6_routing_handle;
5686 dissector_handle_t ipv6_fraghdr_handle;
5687 dissector_handle_t ipv6_dstopts_handle;
5688 capture_dissector_handle_t ipv6_cap_handle;
5689 capture_dissector_handle_t ipv6_ext_cap_handle;
5690 dissector_handle_t h;
5692 dissector_add_uint("ethertype", ETHERTYPE_IPv6, ipv6_handle);
5693 dissector_add_uint("erf.types.type", ERF_TYPE_IPV6, ipv6_handle);
5694 dissector_add_uint("ppp.protocol", PPP_IPV6, ipv6_handle);
5695 dissector_add_uint("ppp.protocol", ETHERTYPE_IPv6, ipv6_handle);
5696 dissector_add_uint("gre.proto", ETHERTYPE_IPv6, ipv6_handle);
5697 dissector_add_uint("ip.proto", IP_PROTO_IPV6, ipv6_handle);
5698 dissector_add_uint("null.type", BSD_AF_INET6_BSD, ipv6_handle);
5699 dissector_add_uint("null.type", BSD_AF_INET6_FREEBSD, ipv6_handle);
5700 dissector_add_uint("null.type", BSD_AF_INET6_DARWIN, ipv6_handle);
5701 dissector_add_uint("chdlc.protocol", ETHERTYPE_IPv6, ipv6_handle);
5702 dissector_add_uint("fr.nlpid", NLPID_IP6, ipv6_handle);
5703 dissector_add_uint("osinl.excl", NLPID_IP6, ipv6_handle);
5704 dissector_add_uint("x.25.spi", NLPID_IP6, ipv6_handle);
5705 dissector_add_uint("arcnet.protocol_id", ARCNET_PROTO_IPv6, ipv6_handle);
5706 dissector_add_uint("juniper.proto", JUNIPER_PROTO_IP6, ipv6_handle);
5707 dissector_add_uint("juniper.proto", JUNIPER_PROTO_MPLS_IP6, ipv6_handle);
5708 dissector_add_uint("pwach.channel_type", PW_ACH_TYPE_IPV6, ipv6_handle);
5709 dissector_add_uint("mcc.proto", PW_ACH_TYPE_IPV6, ipv6_handle);
5710 dissector_add_uint("sflow_245.header_protocol", SFLOW_245_HEADER_IPv6, ipv6_handle);
5711 dissector_add_uint("wtap_encap", WTAP_ENCAP_RAW_IP6, ipv6_handle);
5712 dissector_add_uint("enc", BSD_AF_INET6_BSD, ipv6_handle);
5713 dissector_add_uint("vxlan.next_proto", VXLAN_IPV6, ipv6_handle);
5714 dissector_add_uint("nsh.next_proto", NSH_IPV6, ipv6_handle);
5716 dissector_add_for_decode_as_with_preference("udp.port", ipv6_handle);
5718 ipv6_hopopts_handle = create_dissector_handle(dissect_hopopts, proto_ipv6_hopopts);
5719 dissector_add_uint("ip.proto", IP_PROTO_HOPOPTS, ipv6_hopopts_handle);
5721 ipv6_routing_handle = create_dissector_handle(dissect_routing6, proto_ipv6_routing);
5722 dissector_add_uint("ip.proto", IP_PROTO_ROUTING, ipv6_routing_handle);
5724 ipv6_fraghdr_handle = create_dissector_handle(dissect_fraghdr, proto_ipv6_fraghdr);
5725 dissector_add_uint("ip.proto", IP_PROTO_FRAGMENT, ipv6_fraghdr_handle);
5727 ipv6_dstopts_handle = create_dissector_handle(dissect_dstopts, proto_ipv6_dstopts);
5728 dissector_add_uint("ip.proto", IP_PROTO_DSTOPTS, ipv6_dstopts_handle);
5730 ip_dissector_table = find_dissector_table("ip.proto");
5732 ipv6_cap_handle = find_capture_dissector("ipv6");
5733 capture_dissector_add_uint("ethertype", ETHERTYPE_IPv6, ipv6_cap_handle);
5734 capture_dissector_add_uint("enc", BSD_AF_INET6_BSD, ipv6_cap_handle);
5735 capture_dissector_add_uint("null.bsd", BSD_AF_INET6_BSD, ipv6_cap_handle);
5736 capture_dissector_add_uint("null.bsd", BSD_AF_INET6_FREEBSD, ipv6_cap_handle);
5737 capture_dissector_add_uint("null.bsd", BSD_AF_INET6_DARWIN, ipv6_cap_handle);
5738 capture_dissector_add_uint("fr.nlpid", NLPID_IP6, ipv6_cap_handle);
5740 ipv6_ext_cap_handle = create_capture_dissector_handle(capture_ipv6_exthdr, proto_ipv6_hopopts);
5741 capture_dissector_add_uint("ip.proto", IP_PROTO_HOPOPTS, ipv6_ext_cap_handle);
5742 ipv6_ext_cap_handle = create_capture_dissector_handle(capture_ipv6_exthdr, proto_ipv6_routing);
5743 capture_dissector_add_uint("ip.proto", IP_PROTO_ROUTING, ipv6_ext_cap_handle);
5744 ipv6_ext_cap_handle = create_capture_dissector_handle(capture_ipv6_exthdr, proto_ipv6_fraghdr);
5745 capture_dissector_add_uint("ip.proto", IP_PROTO_FRAGMENT, ipv6_ext_cap_handle);
5746 ipv6_ext_cap_handle = create_capture_dissector_handle(capture_ipv6_exthdr, proto_ipv6_dstopts);
5747 capture_dissector_add_uint("ip.proto", IP_PROTO_DSTOPTS, ipv6_ext_cap_handle);
5749 h = create_dissector_handle(dissect_routing6_rt0, proto_ipv6_routing_rt0);
5750 dissector_add_uint("ipv6.routing.type", IPv6_RT_HEADER_SOURCE_ROUTING, h);
5751 h = create_dissector_handle(dissect_routing6_mipv6, proto_ipv6_routing_mipv6);
5752 dissector_add_uint("ipv6.routing.type", IPv6_RT_HEADER_MOBILE_IP, h);
5753 h = create_dissector_handle(dissect_routing6_rpl, proto_ipv6_routing_rpl);
5754 dissector_add_uint("ipv6.routing.type", IPv6_RT_HEADER_RPL, h);
5755 h = create_dissector_handle(dissect_routing6_srh, proto_ipv6_routing_srh);
5756 dissector_add_uint("ipv6.routing.type", IPv6_RT_HEADER_SEGMENT_ROUTING, h);
5757 h = create_dissector_handle(dissect_routing6_crh, proto_ipv6_routing_crh);
5758 dissector_add_uint("ipv6.routing.type", IPv6_RT_HEADER_COMPACT_16, h);
5759 dissector_add_uint("ipv6.routing.type", IPv6_RT_HEADER_COMPACT_32, h);
5761 exported_pdu_tap = find_tap_id("IP");
5765 * Editor modelines
5767 * Local Variables:
5768 * c-basic-offset: 4
5769 * tab-width: 8
5770 * indent-tabs-mode: nil
5771 * End:
5773 * ex: set shiftwidth=4 tabstop=8 expandtab:
5774 * :indentSize=4:tabSize=8:noTabs=true: