2 * Routines for IPv6 packet disassembly
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * SHIM6 support added by Matthijs Mekking <matthijs@NLnetLabs.nl>
12 * MobileIPv6 support added by Tomislav Borosa <tomislav.borosa@siemens.hr>
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
35 #include <epan/packet.h>
36 #include "packet-ipsec.h"
37 #include "packet-ipv6.h"
38 #include <epan/ip_opts.h>
39 #include <epan/addr_resolv.h>
40 #include <epan/prefs.h>
41 #include <epan/reassemble.h>
42 #include <epan/ipproto.h>
43 #include <epan/ipv6-utils.h>
44 #include <epan/etypes.h>
45 #include <epan/ppptypes.h>
46 #include <epan/aftypes.h>
47 #include <epan/nlpid.h>
48 #include <epan/arcnet_pids.h>
49 #include <epan/in_cksum.h>
50 #include <epan/value_string.h>
51 #include <epan/expert.h>
52 #include <epan/emem.h>
56 * NOTE: ipv6.nxt is not very useful as we will have chained header.
57 * now testing ipv6.final, but it raises SEGV.
61 /* Differentiated Services Field. See RFCs 2474, 2597 and 2598. */
62 #define IPDSFIELD_DSCP_MASK 0xFC
63 #define IPDSFIELD_ECN_MASK 0x03
64 #define IPDSFIELD_DSCP_SHIFT 2
65 #define IPDSFIELD_DSCP(dsfield) (((dsfield)&IPDSFIELD_DSCP_MASK)>>IPDSFIELD_DSCP_SHIFT)
66 #define IPDSFIELD_ECN(dsfield) ((dsfield)&IPDSFIELD_ECN_MASK)
67 #define IPDSFIELD_DSCP_DEFAULT 0x00
68 #define IPDSFIELD_DSCP_CS1 0x08
69 #define IPDSFIELD_DSCP_CS2 0x10
70 #define IPDSFIELD_DSCP_CS3 0x18
71 #define IPDSFIELD_DSCP_CS4 0x20
72 #define IPDSFIELD_DSCP_CS5 0x28
73 #define IPDSFIELD_DSCP_CS6 0x30
74 #define IPDSFIELD_DSCP_CS7 0x38
75 #define IPDSFIELD_DSCP_AF11 0x0A
76 #define IPDSFIELD_DSCP_AF12 0x0C
77 #define IPDSFIELD_DSCP_AF13 0x0E
78 #define IPDSFIELD_DSCP_AF21 0x12
79 #define IPDSFIELD_DSCP_AF22 0x14
80 #define IPDSFIELD_DSCP_AF23 0x16
81 #define IPDSFIELD_DSCP_AF31 0x1A
82 #define IPDSFIELD_DSCP_AF32 0x1C
83 #define IPDSFIELD_DSCP_AF33 0x1E
84 #define IPDSFIELD_DSCP_AF41 0x22
85 #define IPDSFIELD_DSCP_AF42 0x24
86 #define IPDSFIELD_DSCP_AF43 0x26
87 #define IPDSFIELD_DSCP_EF 0x2E
88 #define IPDSFIELD_ECT_MASK 0x02
89 #define IPDSFIELD_CE_MASK 0x01
91 static int ipv6_tap = -1;
93 static int proto_ipv6 = -1;
94 static int hf_ipv6_version = -1;
95 static int hf_ip_version = -1;
96 static int hf_ipv6_class = -1;
97 static int hf_ipv6_flow = -1;
98 static int hf_ipv6_plen = -1;
99 static int hf_ipv6_nxt = -1;
100 static int hf_ipv6_hlim = -1;
101 static int hf_ipv6_src = -1;
102 static int hf_ipv6_src_host = -1;
103 static int hf_ipv6_dst = -1;
104 static int hf_ipv6_dst_host = -1;
105 static int hf_ipv6_addr = -1;
106 static int hf_ipv6_host = -1;
107 static int hf_ipv6_opt_pad1 = -1;
108 static int hf_ipv6_opt_padn = -1;
109 static int hf_ipv6_dst_opt = -1;
110 static int hf_ipv6_hop_opt = -1;
111 static int hf_ipv6_unk_hdr = -1;
112 static int hf_ipv6_routing_hdr_opt = -1;
113 static int hf_ipv6_routing_hdr_type = -1;
114 static int hf_ipv6_routing_hdr_left = -1;
115 static int hf_ipv6_routing_hdr_addr = -1;
117 static int hf_ipv6_final = -1;
119 static int hf_ipv6_frag_offset = -1;
120 static int hf_ipv6_frag_more = -1;
121 static int hf_ipv6_frag_id = -1;
122 static int hf_ipv6_fragments = -1;
123 static int hf_ipv6_fragment = -1;
124 static int hf_ipv6_fragment_overlap = -1;
125 static int hf_ipv6_fragment_overlap_conflict = -1;
126 static int hf_ipv6_fragment_multiple_tails = -1;
127 static int hf_ipv6_fragment_too_long_fragment = -1;
128 static int hf_ipv6_fragment_error = -1;
129 static int hf_ipv6_reassembled_in = -1;
130 static int hf_ipv6_reassembled_length = -1;
132 static int hf_ipv6_mipv6_type = -1;
133 static int hf_ipv6_mipv6_length = -1;
134 static int hf_ipv6_mipv6_home_address = -1;
136 static int hf_ipv6_shim6 = -1;
137 static int hf_ipv6_shim6_nxt = -1;
138 static int hf_ipv6_shim6_len = -1;
139 static int hf_ipv6_shim6_p = -1;
140 /* context tag is 49 bits, cannot be used for filter yet */
141 static int hf_ipv6_shim6_ct = -1;
142 static int hf_ipv6_shim6_type = -1;
143 static int hf_ipv6_shim6_proto = -1;
144 static int hf_ipv6_shim6_checksum = -1;
145 static int hf_ipv6_shim6_checksum_bad = -1;
146 static int hf_ipv6_shim6_checksum_good= -1;
147 static int hf_ipv6_shim6_inonce = -1; /* also for request nonce */
148 static int hf_ipv6_shim6_rnonce = -1;
149 static int hf_ipv6_shim6_precvd = -1;
150 static int hf_ipv6_shim6_psent = -1;
151 static int hf_ipv6_shim6_psrc = -1;
152 static int hf_ipv6_shim6_pdst = -1;
153 static int hf_ipv6_shim6_pnonce = -1;
154 static int hf_ipv6_shim6_pdata = -1;
155 static int hf_ipv6_shim6_sulid = -1;
156 static int hf_ipv6_shim6_rulid = -1;
157 static int hf_ipv6_shim6_reap = -1;
158 static int hf_ipv6_shim6_opt_type = -1;
159 static int hf_ipv6_shim6_opt_len = -1;
160 static int hf_ipv6_shim6_opt_total_len= -1;
161 static int hf_ipv6_shim6_opt_loc_verif_methods = -1;
162 static int hf_ipv6_shim6_opt_critical = -1;
163 static int hf_ipv6_shim6_opt_loclist = -1;
164 static int hf_ipv6_shim6_locator = -1;
165 static int hf_ipv6_shim6_loc_flag = -1;
166 static int hf_ipv6_shim6_loc_prio = -1;
167 static int hf_ipv6_shim6_loc_weight = -1;
168 static int hf_ipv6_shim6_opt_locnum = -1;
169 static int hf_ipv6_shim6_opt_elemlen = -1;
170 static int hf_ipv6_shim6_opt_fii = -1;
171 static int hf_ipv6_traffic_class_dscp = -1;
172 static int hf_ipv6_traffic_class_ect = -1;
173 static int hf_ipv6_traffic_class_ce = -1;
175 static gint ett_ipv6 = -1;
176 static gint ett_ipv6_version = -1;
177 static gint ett_ipv6_shim6 = -1;
178 static gint ett_ipv6_shim6_option = -1;
179 static gint ett_ipv6_shim6_locators = -1;
180 static gint ett_ipv6_shim6_verif_methods = -1;
181 static gint ett_ipv6_shim6_loc_pref = -1;
182 static gint ett_ipv6_shim6_probes_sent = -1;
183 static gint ett_ipv6_shim6_probe_sent = -1;
184 static gint ett_ipv6_shim6_probes_rcvd = -1;
185 static gint ett_ipv6_shim6_probe_rcvd = -1;
186 static gint ett_ipv6_shim6_cksum = -1;
187 static gint ett_ipv6_fragments = -1;
188 static gint ett_ipv6_fragment = -1;
189 static gint ett_ipv6_traffic_class = -1;
191 static const fragment_items ipv6_frag_items = {
196 &hf_ipv6_fragment_overlap,
197 &hf_ipv6_fragment_overlap_conflict,
198 &hf_ipv6_fragment_multiple_tails,
199 &hf_ipv6_fragment_too_long_fragment,
200 &hf_ipv6_fragment_error,
201 &hf_ipv6_reassembled_in,
202 &hf_ipv6_reassembled_length,
206 static dissector_handle_t data_handle;
208 static dissector_table_t ip_dissector_table;
210 /* Reassemble fragmented datagrams */
211 static gboolean ipv6_reassemble = TRUE;
214 #define offsetof(type, member) ((size_t)(&((type *)0)->member))
218 * defragmentation of IPv6
220 static GHashTable *ipv6_fragment_table = NULL;
221 static GHashTable *ipv6_reassembled_table = NULL;
224 capture_ipv6(const guchar *pd, int offset, int len, packet_counts *ld)
229 if (!BYTES_ARE_IN_FRAME(offset, len, 4+4+16+16)) {
233 nxt = pd[offset+6]; /* get the "next header" value */
234 offset += 4+4+16+16; /* skip past the IPv6 header */
238 case IP_PROTO_HOPOPTS:
239 case IP_PROTO_ROUTING:
240 case IP_PROTO_DSTOPTS:
241 if (!BYTES_ARE_IN_FRAME(offset, len, 2)) {
246 advance = (pd[offset+1] + 1) << 3;
247 if (!BYTES_ARE_IN_FRAME(offset, len, advance)) {
253 case IP_PROTO_FRAGMENT:
254 if (!BYTES_ARE_IN_FRAME(offset, len, 2)) {
260 if (!BYTES_ARE_IN_FRAME(offset, len, advance)) {
267 if (!BYTES_ARE_IN_FRAME(offset, len, 2)) {
272 advance = 8 + ((pd[offset+1] - 1) << 2);
273 if (!BYTES_ARE_IN_FRAME(offset, len, advance)) {
280 case IP_PROTO_SHIM6_OLD:
281 if (!BYTES_ARE_IN_FRAME(offset, len, 2)) {
286 advance = (pd[offset+1] + 1) << 3;
287 if (!BYTES_ARE_IN_FRAME(offset, len, advance)) {
303 case IP_PROTO_UDPLITE:
307 case IP_PROTO_ICMPV6: /* XXX - separate counters? */
325 ipv6_reassemble_init(void)
327 fragment_table_init(&ipv6_fragment_table);
328 reassembled_table_init(&ipv6_reassembled_table);
332 IPv6_RT_HEADER_SOURCE_ROUTING=0,
333 IPv6_RT_HEADER_NIMROD,
334 IPv6_RT_HEADER_MobileIP
337 /* Routeing Header Types */
338 static const value_string routing_header_type[] = {
339 { IPv6_RT_HEADER_SOURCE_ROUTING, "IPv6 Source Routing" },
340 { IPv6_RT_HEADER_NIMROD, "Nimrod" },
341 { IPv6_RT_HEADER_MobileIP, "Mobile IP" },
346 dissect_routing6(tvbuff_t *tvb, int offset, proto_tree *tree, packet_info *pinfo) {
349 proto_tree *rthdr_tree;
351 guint8 buf[sizeof(struct ip6_rthdr0) + sizeof(struct e_in6_addr) * 23];
353 tvb_memcpy(tvb, (guint8 *)&rt, offset, sizeof(rt));
354 len = (rt.ip6r_len + 1) << 3;
357 /* !!! specify length */
358 ti = proto_tree_add_uint_format(tree, hf_ipv6_routing_hdr_opt, tvb,
359 offset, len, rt.ip6r_type,
360 "Routing Header, Type : %s (%u)",
361 val_to_str(rt.ip6r_type, routing_header_type, "Unknown"),
363 rthdr_tree = proto_item_add_subtree(ti, ett_ipv6);
365 proto_tree_add_text(rthdr_tree, tvb,
366 offset + offsetof(struct ip6_rthdr, ip6r_nxt), 1,
367 "Next header: %s (0x%02x)", ipprotostr(rt.ip6r_nxt), rt.ip6r_nxt);
369 proto_tree_add_text(rthdr_tree, tvb,
370 offset + offsetof(struct ip6_rthdr, ip6r_len), 1,
371 "Length: %u (%d bytes)", rt.ip6r_len, len);
373 proto_tree_add_item(rthdr_tree, hf_ipv6_routing_hdr_type, tvb,
374 offset + offsetof(struct ip6_rthdr, ip6r_type), 1, FALSE);
376 proto_tree_add_item(rthdr_tree, hf_ipv6_routing_hdr_left, tvb,
377 offset + offsetof(struct ip6_rthdr, ip6r_segleft), 1, FALSE);
379 if (rt.ip6r_type == IPv6_RT_HEADER_SOURCE_ROUTING && len <= sizeof(buf)) {
380 struct e_in6_addr *a;
382 struct ip6_rthdr0 *rt0;
384 tvb_memcpy(tvb, buf, offset, len);
385 rt0 = (struct ip6_rthdr0 *)buf;
387 for (a = rt0->ip6r0_addr, n = 0;
388 a < (struct e_in6_addr *)(buf + len); a++, n++) {
390 proto_tree_add_item(rthdr_tree, hf_ipv6_routing_hdr_addr, tvb,
391 offset + offsetof(struct ip6_rthdr0, ip6r0_addr)
392 + n * sizeof(struct e_in6_addr),
393 sizeof(struct e_in6_addr), FALSE);
394 SET_ADDRESS(&pinfo->dst, AT_IPv6, 16, tvb_get_ptr(tvb,
395 offset + offsetof(struct ip6_rthdr0, ip6r0_addr)
396 + n * sizeof(struct e_in6_addr), 16));
399 if (rt.ip6r_type == IPv6_RT_HEADER_MobileIP) {
400 proto_tree_add_item(rthdr_tree, hf_ipv6_mipv6_home_address, tvb,
401 offset + 8, 16, FALSE);
402 SET_ADDRESS(&pinfo->dst, AT_IPv6, 16, tvb_get_ptr(tvb, offset + 8, 16));
410 dissect_frag6(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree,
411 guint16 *offlg, guint32 *ident) {
412 struct ip6_frag frag;
415 proto_tree *rthdr_tree;
417 tvb_memcpy(tvb, (guint8 *)&frag, offset, sizeof(frag));
419 frag.ip6f_offlg = g_ntohs(frag.ip6f_offlg);
420 frag.ip6f_ident = g_ntohl(frag.ip6f_ident);
421 *offlg = frag.ip6f_offlg;
422 *ident = frag.ip6f_ident;
423 if (check_col(pinfo->cinfo, COL_INFO)) {
424 col_add_fstr(pinfo->cinfo, COL_INFO,
425 "IPv6 fragment (nxt=%s (0x%02x) off=%u id=0x%x)",
426 ipprotostr(frag.ip6f_nxt), frag.ip6f_nxt,
427 frag.ip6f_offlg & IP6F_OFF_MASK, frag.ip6f_ident);
430 ti = proto_tree_add_text(tree, tvb, offset, len,
431 "Fragmentation Header");
432 rthdr_tree = proto_item_add_subtree(ti, ett_ipv6);
434 proto_tree_add_text(rthdr_tree, tvb,
435 offset + offsetof(struct ip6_frag, ip6f_nxt), 1,
436 "Next header: %s (0x%02x)",
437 ipprotostr(frag.ip6f_nxt), frag.ip6f_nxt);
440 proto_tree_add_text(rthdr_tree, tvb,
441 offset + offsetof(struct ip6_frag, ip6f_reserved), 1,
446 proto_tree_add_item(rthdr_tree, hf_ipv6_frag_offset, tvb,
447 offset + offsetof(struct ip6_frag, ip6f_offlg), 2, FALSE);
449 proto_tree_add_item(rthdr_tree, hf_ipv6_frag_more, tvb,
450 offset + offsetof(struct ip6_frag, ip6f_offlg), 2, FALSE);
452 proto_tree_add_item(rthdr_tree, hf_ipv6_frag_id, tvb,
453 offset + offsetof(struct ip6_frag, ip6f_ident), 4, FALSE);
459 dissect_mipv6_hoa(tvbuff_t *tvb, proto_tree *dstopt_tree, int offset, packet_info *pinfo)
463 proto_tree_add_uint_format(dstopt_tree, hf_ipv6_mipv6_type, tvb,
465 tvb_get_guint8(tvb, offset + len),
466 "Option Type: %u (0x%02x) - Home Address Option",
467 tvb_get_guint8(tvb, offset + len),
468 tvb_get_guint8(tvb, offset + len));
471 proto_tree_add_uint(dstopt_tree, hf_ipv6_mipv6_length, tvb, offset + len,
472 1, tvb_get_guint8(tvb, offset + len));
475 proto_tree_add_ipv6(dstopt_tree, hf_ipv6_mipv6_home_address, tvb,
476 offset + len, 16, tvb_get_ptr(tvb, offset + len, 16));
477 SET_ADDRESS(&pinfo->src, AT_IPv6, 16, tvb_get_ptr(tvb, offset + len, 16));
482 static const value_string rtalertvals[] = {
483 { IP6OPT_RTALERT_MLD, "MLD" },
484 { IP6OPT_RTALERT_RSVP, "RSVP" },
488 /* Like "dissect_ip_tcp_options()", but assumes the length of an option
489 *doesn't* include the type and length bytes. */
491 dissect_ipv6_options(tvbuff_t *tvb, int offset, guint length,
492 const ip_tcp_opt *opttab, int nopts, int eol,
493 packet_info *pinfo, proto_tree *opt_tree)
496 const ip_tcp_opt *optp;
497 opt_len_type len_type;
500 char name_str[7+1+1+2+2+1+1]; /* "Unknown (0x%02x)" */
501 void (*dissect)(const struct ip_tcp_opt *, tvbuff_t *,
502 int, guint, packet_info *, proto_tree *);
506 opt = tvb_get_guint8(tvb, offset);
507 for (optp = &opttab[0]; optp < &opttab[nopts]; optp++) {
508 if (optp->optcode == opt)
511 if (optp == &opttab[nopts]) {
512 /* We assume that the only NO_LENGTH options are Pad1 options,
513 so that we can treat unknown options as VARIABLE_LENGTH with a
514 minimum of 0, and at least be able to move on to the next option
515 by using the length in the option. */
516 optp = NULL; /* indicate that we don't know this option */
517 len_type = VARIABLE_LENGTH;
519 g_snprintf(name_str, sizeof name_str, "Unknown (0x%02x)", opt);
523 len_type = optp->len_type;
524 optlen = optp->optlen;
526 dissect = optp->dissect;
528 --length; /* account for type byte */
529 if (len_type != NO_LENGTH) {
530 /* Option has a length. Is it in the packet? */
532 /* Bogus - packet must at least include option code byte and
534 proto_tree_add_text(opt_tree, tvb, offset, 1,
535 "%s (length byte past end of options)", name);
538 len = tvb_get_guint8(tvb, offset + 1); /* total including type, len */
539 --length; /* account for length byte */
541 /* Bogus - option goes past the end of the header. */
542 proto_tree_add_text(opt_tree, tvb, offset, length,
543 "%s (option length = %u byte%s says option goes past end of options)",
544 name, len, plurality(len, "", "s"));
546 } else if (len_type == FIXED_LENGTH && len != optlen) {
547 /* Bogus - option length isn't what it's supposed to be for this
549 proto_tree_add_text(opt_tree, tvb, offset, 2 + len,
550 "%s (with option length = %u byte%s; should be %u)", name,
551 len, plurality(len, "", "s"), optlen);
553 } else if (len_type == VARIABLE_LENGTH && len < optlen) {
554 /* Bogus - option length is less than what it's supposed to be for
556 proto_tree_add_text(opt_tree, tvb, offset, 2 + len,
557 "%s (with option length = %u byte%s; should be >= %u)", name,
558 len, plurality(len, "", "s"), optlen);
562 proto_tree_add_text(opt_tree, tvb, offset, 2 + len, "%s (%u byte%s)",
563 name, len, plurality(len, "", "s"));
565 if (dissect != NULL) {
566 /* Option has a dissector. */
567 (*dissect)(optp, tvb, offset, 2 + len, pinfo, opt_tree);
569 /* Option has no data, hence no dissector. */
570 proto_tree_add_text(opt_tree, tvb, offset, 2 + len, "%s", name);
577 proto_tree_add_text(opt_tree, tvb, offset, 1, "%s", name);
586 dissect_unknown_option(tvbuff_t *tvb, int offset, proto_tree *tree)
590 proto_tree *unkopt_tree;
593 tvb_memcpy(tvb, (guint8 *)&ext, offset, sizeof(ext));
594 len = (ext.ip6e_len + 1) << 3;
597 /* !!! specify length */
598 ti = proto_tree_add_item(tree, hf_ipv6_unk_hdr, tvb, offset, len, FALSE);
600 unkopt_tree = proto_item_add_subtree(ti, ett_ipv6);
602 proto_tree_add_text(unkopt_tree, tvb,
603 offset + offsetof(struct ip6_ext, ip6e_nxt), 1,
604 "Next header: %s (0x%02x)", ipprotostr(ext.ip6e_nxt), ext.ip6e_nxt);
606 proto_tree_add_text(unkopt_tree, tvb,
607 offset + offsetof(struct ip6_ext, ip6e_len), 1,
608 "Length: %u (%d bytes)", ext.ip6e_len, len);
614 dissect_opts(tvbuff_t *tvb, int offset, proto_tree *tree, packet_info * pinfo, const int hf_option_item)
618 proto_tree *dstopt_tree;
622 int mip_offset = 0, delta = 0;
624 tvb_memcpy(tvb, (guint8 *)&ext, offset, sizeof(ext));
625 len = (ext.ip6e_len + 1) << 3;
628 /* !!! specify length */
629 ti = proto_tree_add_item(tree, hf_option_item, tvb, offset, len, FALSE);
631 dstopt_tree = proto_item_add_subtree(ti, ett_ipv6);
633 proto_tree_add_text(dstopt_tree, tvb,
634 offset + offsetof(struct ip6_ext, ip6e_nxt), 1,
635 "Next header: %s (0x%02x)", ipprotostr(ext.ip6e_nxt), ext.ip6e_nxt);
637 proto_tree_add_text(dstopt_tree, tvb,
638 offset + offsetof(struct ip6_ext, ip6e_len), 1,
639 "Length: %u (%d bytes)", ext.ip6e_len, len);
646 while (p < offset + len) {
647 switch (tvb_get_guint8(tvb, p)) {
649 proto_tree_add_item(dstopt_tree, hf_ipv6_opt_pad1, tvb, p, 1, FALSE);
655 * "The PadN option is used to insert two or more octets of
656 * padding into the Options area of a header. For N octets of
657 * padding, the Opt Data Len field contains the value N-2, and
658 * the Option Data consists of N-2 zero-valued octets."
660 tmp = tvb_get_guint8(tvb, p + 1);
661 proto_tree_add_uint_format(dstopt_tree, hf_ipv6_opt_padn, tvb,
663 "PadN: %u bytes", tmp + 2);
665 mip_offset += tvb_get_guint8(tvb, mip_offset + 1) + 2;
668 tmp = tvb_get_guint8(tvb, p + 1);
670 proto_tree_add_text(dstopt_tree, tvb, p, tmp + 2,
671 "Jumbo payload: %u (%u bytes)",
672 tvb_get_ntohl(tvb, p + 2), tmp + 2);
674 ti = proto_tree_add_text(dstopt_tree, tvb, p, tmp + 2,
675 "Jumbo payload: Invalid length (%u bytes)", tmp);
676 expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_ERROR,
677 "Jumbo payload: Invalid length (%u bytes)", tmp);
680 mip_offset += tvb_get_guint8(tvb, mip_offset+1)+2;
684 tmp = tvb_get_guint8(tvb, p + 1);
686 proto_tree_add_text(dstopt_tree, tvb, p , tmp + 2,
687 "Router alert: %s (%u bytes)",
688 val_to_str(tvb_get_ntohs(tvb, p + 2),
689 rtalertvals, "Unknown"),
692 ti = proto_tree_add_text(dstopt_tree, tvb, p , tmp + 2,
693 "Router alert: Invalid Length (%u bytes)",
695 expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_ERROR,
696 "Router alert: Invalid Length (%u bytes)",
701 mip_offset += tvb_get_guint8(tvb, mip_offset + 1) + 2;
704 case IP6OPT_HOME_ADDRESS:
705 delta = dissect_mipv6_hoa(tvb, dstopt_tree, mip_offset, pinfo);
721 dissect_hopopts(tvbuff_t *tvb, int offset, proto_tree *tree, packet_info * pinfo)
723 return dissect_opts(tvb, offset, tree, pinfo, hf_ipv6_hop_opt);
727 dissect_dstopts(tvbuff_t *tvb, int offset, proto_tree *tree, packet_info * pinfo)
729 return dissect_opts(tvb, offset, tree, pinfo, hf_ipv6_dst_opt);
732 /* START SHIM6 PART */
733 static guint16 shim_checksum(const guint8 *ptr, int len)
737 cksum_vec[0].ptr = ptr;
738 cksum_vec[0].len = len;
739 return in_cksum(&cksum_vec[0], 1);
743 dissect_shim_hex(tvbuff_t *tvb, int offset, int len, const char *itemname, guint8 bitmask, proto_tree *tree)
751 ti = proto_tree_add_text(tree, tvb, offset, len, "%s", itemname);
753 proto_item_append_text(ti, " 0x%02x", tvb_get_guint8(tvb, p) & bitmask);
754 for (count=1; count<len; count++)
755 proto_item_append_text(ti, "%02x", tvb_get_guint8(tvb, p+count));
760 static const value_string shimoptvals[] = {
761 { SHIM6_OPT_RESPVAL, "Responder Validator Option" },
762 { SHIM6_OPT_LOCLIST, "Locator List Option" },
763 { SHIM6_OPT_LOCPREF, "Locator Preferences Option" },
764 { SHIM6_OPT_CGAPDM, "CGA Parameter Data Structure Option" },
765 { SHIM6_OPT_CGASIG, "CGA Signature Option" },
766 { SHIM6_OPT_ULIDPAIR, "ULID Pair Option" },
767 { SHIM6_OPT_FII, "Forked Instance Identifier Option" },
771 static const value_string shimverifmethods[] = {
772 { SHIM6_VERIF_HBA, "HBA" },
773 { SHIM6_VERIF_CGA, "CGA" },
777 static const value_string shimflags[] _U_ = {
778 { SHIM6_FLAG_BROKEN, "BROKEN" },
779 { SHIM6_FLAG_TEMPORARY, "TEMPORARY" },
783 static const value_string shimreapstates[] = {
784 { SHIM6_REAP_OPERATIONAL, "Operational" },
785 { SHIM6_REAP_EXPLORING, "Exploring" },
786 { SHIM6_REAP_INBOUNDOK, "InboundOK" },
790 static const value_string shim6_protocol[] = {
796 static const value_string dscp_vals[] = {
797 { IPDSFIELD_DSCP_DEFAULT, "Default" },
798 { IPDSFIELD_DSCP_CS1, "Class Selector 1" },
799 { IPDSFIELD_DSCP_CS2, "Class Selector 2" },
800 { IPDSFIELD_DSCP_CS3, "Class Selector 3" },
801 { IPDSFIELD_DSCP_CS4, "Class Selector 4" },
802 { IPDSFIELD_DSCP_CS5, "Class Selector 5" },
803 { IPDSFIELD_DSCP_CS6, "Class Selector 6" },
804 { IPDSFIELD_DSCP_CS7, "Class Selector 7" },
805 { IPDSFIELD_DSCP_AF11, "Assured Forwarding 11" },
806 { IPDSFIELD_DSCP_AF12, "Assured Forwarding 12" },
807 { IPDSFIELD_DSCP_AF13, "Assured Forwarding 13" },
808 { IPDSFIELD_DSCP_AF21, "Assured Forwarding 21" },
809 { IPDSFIELD_DSCP_AF22, "Assured Forwarding 22" },
810 { IPDSFIELD_DSCP_AF23, "Assured Forwarding 23" },
811 { IPDSFIELD_DSCP_AF31, "Assured Forwarding 31" },
812 { IPDSFIELD_DSCP_AF32, "Assured Forwarding 32" },
813 { IPDSFIELD_DSCP_AF33, "Assured Forwarding 33" },
814 { IPDSFIELD_DSCP_AF41, "Assured Forwarding 41" },
815 { IPDSFIELD_DSCP_AF42, "Assured Forwarding 42" },
816 { IPDSFIELD_DSCP_AF43, "Assured Forwarding 43" },
817 { IPDSFIELD_DSCP_EF, "Expedited Forwarding" },
821 dissect_shim6_opt_loclist(proto_tree * opt_tree, tvbuff_t * tvb, gint *offset)
824 proto_tree * subtree;
829 proto_tree_add_item(opt_tree, hf_ipv6_shim6_opt_loclist, tvb, p, 4, FALSE);
832 optlen = tvb_get_guint8(tvb, p);
833 proto_tree_add_item(opt_tree, hf_ipv6_shim6_opt_locnum, tvb, p, 1, FALSE);
836 /* Verification Methods */
837 it = proto_tree_add_text(opt_tree, tvb, p, optlen,
838 "Locator Verification Methods");
839 subtree = proto_item_add_subtree(it, ett_ipv6_shim6_verif_methods);
841 for (count=0; count < optlen; count++)
842 proto_tree_add_item(subtree, hf_ipv6_shim6_opt_loc_verif_methods, tvb,
846 /* Padding, included in length field */
847 if ((7 - optlen % 8) > 0) {
848 proto_tree_add_text(opt_tree, tvb, p, (7 - optlen % 8), "Padding");
849 p += (7 - optlen % 8);
853 it = proto_tree_add_text(opt_tree, tvb, p, 16 * optlen, "Locators");
854 subtree = proto_item_add_subtree(it, ett_ipv6_shim6_locators);
856 for (count=0; count < optlen; count++) {
857 proto_tree_add_item(subtree, hf_ipv6_shim6_locator, tvb, p, 16, FALSE);
864 dissect_shim6_opt_loc_pref(proto_tree * opt_tree, tvbuff_t * tvb, gint *offset, gint len, packet_info *pinfo)
866 proto_tree * subtree;
875 proto_tree_add_item(opt_tree, hf_ipv6_shim6_opt_loclist, tvb, p, 4, FALSE);
878 optlen = tvb_get_guint8(tvb, p);
879 proto_tree_add_item(opt_tree, hf_ipv6_shim6_opt_elemlen, tvb, p, 1, FALSE);
881 if (optlen < 1 || optlen > 3) {
882 it = proto_tree_add_text(opt_tree, tvb, p, 1,
883 "Invalid element length: %u", optlen);
884 expert_add_info_format(pinfo, it, PI_MALFORMED, PI_ERROR,
885 "Invalid element length: %u", optlen);
891 /* Locator Preferences */
894 it = proto_tree_add_text(opt_tree, tvb, p, optlen, "Locator Preferences %u", count);
895 subtree = proto_item_add_subtree(it, ett_ipv6_shim6_loc_pref);
899 proto_tree_add_item(subtree, hf_ipv6_shim6_loc_flag, tvb, p, 1, FALSE);
902 proto_tree_add_item(subtree, hf_ipv6_shim6_loc_prio, tvb, p+1, 1, FALSE);
905 proto_tree_add_item(subtree, hf_ipv6_shim6_loc_weight, tvb, p+2, 1, FALSE);
907 * Shim6 Draft 08 doesn't specify the format when the Element length is
908 * more than three, except that any such formats MUST be defined so that
909 * the first three octets are the same as in the above case, that is, a
910 * of a 1 octet flags field followed by a 1 octet priority field, and a
911 * 1 octet weight field.
921 dissect_shimopts(tvbuff_t *tvb, int offset, proto_tree *tree, packet_info *pinfo)
926 proto_tree *opt_tree;
934 tmp[0] = tvb_get_guint8(tvb, p++);
935 tmp[1] = tvb_get_guint8(tvb, p++);
938 len = tvb_get_ntohs(tvb, offset+2);
939 padding = 7 - ((len + 3) % 8);
940 total_len = 4 + len + padding;
945 ctype = val_to_str( (tvb_get_ntohs(tvb, offset) & SHIM6_BITMASK_OPT_TYPE) >> 1, shimoptvals, "Unknown Option Type");
946 ti = proto_tree_add_text(tree, tvb, offset, total_len, "%s", ctype);
947 opt_tree = proto_item_add_subtree(ti, ett_ipv6_shim6_option);
949 proto_tree_add_item(opt_tree, hf_ipv6_shim6_opt_type, tvb, offset, 2, FALSE);
952 proto_tree_add_item(opt_tree, hf_ipv6_shim6_opt_critical, tvb, offset+1, 1, FALSE);
955 proto_tree_add_item(opt_tree, hf_ipv6_shim6_opt_len, tvb, offset + 2, 2, FALSE);
956 ti = proto_tree_add_uint_format(opt_tree, hf_ipv6_shim6_opt_total_len, tvb, offset+2, 2,
957 total_len, "Total Length: %u", total_len);
958 PROTO_ITEM_SET_GENERATED(ti);
960 /* Option Type Specific */
961 switch (tvb_get_ntohs(tvb, offset) >> 1)
963 case SHIM6_OPT_RESPVAL:
964 p += dissect_shim_hex(tvb, p, len, "Validator:", 0xff, opt_tree);
965 if (total_len-(len+4) > 0)
966 proto_tree_add_text(opt_tree, tvb, p, total_len-(len+4), "Padding");
968 case SHIM6_OPT_LOCLIST:
969 dissect_shim6_opt_loclist(opt_tree, tvb, &p);
971 case SHIM6_OPT_LOCPREF:
972 dissect_shim6_opt_loc_pref(opt_tree, tvb, &p, offset+len+4, pinfo);
973 if (total_len-(len+4) > 0)
974 proto_tree_add_text(opt_tree, tvb, p, total_len-(len+4), "Padding");
976 case SHIM6_OPT_CGAPDM:
977 p += dissect_shim_hex(tvb, p, len, "CGA Parameter Data Structure:", 0xff, opt_tree);
978 if (total_len-(len+4) > 0)
979 proto_tree_add_text(opt_tree, tvb, p, total_len-(len+4), "Padding");
981 case SHIM6_OPT_CGASIG:
982 p += dissect_shim_hex(tvb, p, len, "CGA Signature:", 0xff, opt_tree);
983 if (total_len-(len+4) > 0)
984 proto_tree_add_text(opt_tree, tvb, p, total_len-(len+4), "Padding");
986 case SHIM6_OPT_ULIDPAIR:
987 proto_tree_add_text(opt_tree, tvb, p, 4, "Reserved");
989 proto_tree_add_item(opt_tree, hf_ipv6_shim6_sulid, tvb, p, 16, FALSE);
991 proto_tree_add_item(opt_tree, hf_ipv6_shim6_rulid, tvb, p, 16, FALSE);
995 proto_tree_add_item(opt_tree, hf_ipv6_shim6_opt_fii, tvb, p, 4, FALSE);
1006 dissect_shim6_ct(proto_tree * shim_tree, gint hf_item, tvbuff_t * tvb, gint offset, const guchar * label)
1011 tmp[0] = tvb_get_guint8(tvb, offset++);
1012 tmp[1] = tvb_get_guint8(tvb, offset++);
1013 tmp[2] = tvb_get_guint8(tvb, offset++);
1014 tmp[3] = tvb_get_guint8(tvb, offset++);
1015 tmp[4] = tvb_get_guint8(tvb, offset++);
1016 tmp[5] = tvb_get_guint8(tvb, offset++);
1018 ct_str = ep_strdup_printf("%s: %02X %02X %02X %02X %02X %02X", label,
1019 tmp[0] & SHIM6_BITMASK_CT, tmp[1], tmp[2],
1020 tmp[3], tmp[4], tmp[5]
1022 proto_tree_add_none_format(shim_tree, hf_item, tvb, offset - 6, 6, "%s", ct_str);
1026 dissect_shim6_probes(proto_tree * shim_tree, tvbuff_t * tvb, gint offset,
1027 const guchar * label, guint nbr_probe,
1028 gboolean probes_rcvd)
1030 proto_tree * probes_tree;
1031 proto_tree * probe_tree;
1038 ett_probes = ett_ipv6_shim6_probes_rcvd;
1039 ett_probe = ett_ipv6_shim6_probe_rcvd;
1041 ett_probes = ett_ipv6_shim6_probes_sent;
1042 ett_probe = ett_ipv6_shim6_probe_sent;
1044 it = proto_tree_add_text(shim_tree, tvb, offset, 40 * nbr_probe, "%s", label);
1045 probes_tree = proto_item_add_subtree(it, ett_probes);
1047 for (count=0; count < nbr_probe; count++) {
1048 it = proto_tree_add_text(probes_tree, tvb, offset, 40, "Probe %u", count+1);
1049 probe_tree = proto_item_add_subtree(it, ett_probe);
1051 proto_tree_add_item(probe_tree, hf_ipv6_shim6_psrc, tvb, offset, 16, FALSE);
1053 proto_tree_add_item(probe_tree, hf_ipv6_shim6_pdst, tvb, offset, 16, FALSE);
1056 proto_tree_add_item(probe_tree, hf_ipv6_shim6_pnonce, tvb, offset, 4, FALSE);
1059 proto_tree_add_item(probe_tree, hf_ipv6_shim6_pdata, tvb, offset, 4, FALSE);
1064 /* Dissect SHIM6 data: control messages */
1066 dissect_shimctrl(tvbuff_t *tvb, gint offset, guint type, proto_tree *shim_tree)
1079 dissect_shim6_ct(shim_tree, hf_ipv6_shim6_ct, tvb, p, "Initiator Context Tag");
1081 proto_tree_add_item(shim_tree, hf_ipv6_shim6_inonce, tvb, p, 4, FALSE);
1085 proto_tree_add_text(shim_tree, tvb, p, 2, "Reserved2");
1087 proto_tree_add_item(shim_tree, hf_ipv6_shim6_inonce, tvb, p, 4, FALSE);
1089 proto_tree_add_item(shim_tree, hf_ipv6_shim6_rnonce, tvb, p, 4, FALSE);
1093 dissect_shim6_ct(shim_tree, hf_ipv6_shim6_ct, tvb, p, "Initiator Context Tag");
1095 proto_tree_add_item(shim_tree, hf_ipv6_shim6_inonce, tvb, p, 4, FALSE);
1097 proto_tree_add_item(shim_tree, hf_ipv6_shim6_rnonce, tvb, p, 4, FALSE);
1099 proto_tree_add_text(shim_tree, tvb, p, 4, "Reserved2");
1103 dissect_shim6_ct(shim_tree, hf_ipv6_shim6_ct, tvb, p, "Responder Context Tag");
1105 proto_tree_add_item(shim_tree, hf_ipv6_shim6_inonce, tvb, p, 4, FALSE);
1108 case SHIM6_TYPE_R1BIS:
1109 dissect_shim6_ct(shim_tree, hf_ipv6_shim6_ct, tvb, p, "Packet Context Tag");
1111 proto_tree_add_item(shim_tree, hf_ipv6_shim6_rnonce, tvb, p, 4, FALSE);
1114 case SHIM6_TYPE_I2BIS:
1115 dissect_shim6_ct(shim_tree, hf_ipv6_shim6_ct, tvb, p, "Initiator Context Tag");
1117 proto_tree_add_item(shim_tree, hf_ipv6_shim6_inonce, tvb, p, 4, FALSE);
1119 proto_tree_add_item(shim_tree, hf_ipv6_shim6_rnonce, tvb, p, 4, FALSE);
1121 proto_tree_add_text(shim_tree, tvb, p, 6, "Reserved2");
1123 dissect_shim6_ct(shim_tree, hf_ipv6_shim6_ct, tvb, p, "Initiator Context Tag");
1126 case SHIM6_TYPE_UPD_REQ:
1127 case SHIM6_TYPE_UPD_ACK:
1128 dissect_shim6_ct(shim_tree, hf_ipv6_shim6_ct, tvb, p, "Receiver Context Tag");
1130 proto_tree_add_item(shim_tree, hf_ipv6_shim6_rnonce, tvb, p, 4, FALSE);
1133 case SHIM6_TYPE_KEEPALIVE:
1134 dissect_shim6_ct(shim_tree, hf_ipv6_shim6_ct, tvb, p, "Receiver Context Tag");
1136 proto_tree_add_text(shim_tree, tvb, p, 4, "Reserved2");
1139 case SHIM6_TYPE_PROBE:
1140 dissect_shim6_ct(shim_tree, hf_ipv6_shim6_ct, tvb, p, "Receiver Context Tag");
1143 tmp = tvb_get_guint8(tvb, p);
1144 probes_sent = tmp & SHIM6_BITMASK_PSENT;
1145 probes_rcvd = (tmp & SHIM6_BITMASK_PRECVD) >> 4;
1147 proto_tree_add_uint_format(shim_tree, hf_ipv6_shim6_psent, tvb,
1149 "Probes Sent: %u", probes_sent);
1150 proto_tree_add_uint_format(shim_tree, hf_ipv6_shim6_precvd, tvb,
1152 "Probes Received: %u", probes_rcvd);
1155 sta = val_to_str((tvb_get_guint8(tvb, p) & SHIM6_BITMASK_STA) >> 6,
1156 shimreapstates, "Unknown REAP State");
1157 proto_tree_add_uint_format(shim_tree, hf_ipv6_shim6_reap, tvb,
1158 p, 1, (tvb_get_guint8(tvb, p) & SHIM6_BITMASK_STA) >> 6,
1159 "REAP State: %s", sta);
1161 proto_tree_add_text(shim_tree, tvb, p, 3, "Reserved2");
1166 dissect_shim6_probes(shim_tree, tvb, p, "Probes Sent",
1167 probes_sent, FALSE);
1168 p += 40 * probes_sent;
1171 /* Probes Received */
1173 dissect_shim6_probes(shim_tree, tvb, p, "Probes Received",
1175 p += 40 * probes_rcvd;
1184 /* Dissect SHIM6 data: payload, common part, options */
1185 static const value_string shimctrlvals[] = {
1186 { SHIM6_TYPE_I1, "I1" },
1187 { SHIM6_TYPE_R1, "R1" },
1188 { SHIM6_TYPE_I2, "I2" },
1189 { SHIM6_TYPE_R2, "R2" },
1190 { SHIM6_TYPE_R1BIS, "R1bis" },
1191 { SHIM6_TYPE_I2BIS, "I2bis" },
1192 { SHIM6_TYPE_UPD_REQ, "Update Request" },
1193 { SHIM6_TYPE_UPD_ACK, "Update Acknowledgement" },
1194 { SHIM6_TYPE_KEEPALIVE, "Keepalive" },
1195 { SHIM6_TYPE_PROBE, "Probe" },
1199 static void ipv6_shim6_checkum_additional_info(tvbuff_t * tvb, packet_info * pinfo,
1200 proto_item * it_cksum, int offset, gboolean is_cksum_correct)
1202 proto_tree * checksum_tree;
1205 checksum_tree = proto_item_add_subtree(it_cksum, ett_ipv6_shim6_cksum);
1206 item = proto_tree_add_boolean(checksum_tree, hf_ipv6_shim6_checksum_good, tvb,
1207 offset, 2, is_cksum_correct);
1208 PROTO_ITEM_SET_GENERATED(item);
1209 item = proto_tree_add_boolean(checksum_tree, hf_ipv6_shim6_checksum_bad, tvb,
1210 offset, 2, !is_cksum_correct);
1211 PROTO_ITEM_SET_GENERATED(item);
1212 if (!is_cksum_correct) {
1213 expert_add_info_format(pinfo, item, PI_CHECKSUM, PI_ERROR, "Bad checksum");
1214 col_append_str(pinfo->cinfo, COL_INFO, " [Shim6 CHECKSUM INCORRECT]");
1219 dissect_shim6(tvbuff_t *tvb, int offset, proto_tree *tree, packet_info * pinfo)
1221 struct ip6_shim shim;
1224 proto_tree *shim_tree;
1228 tvb_memcpy(tvb, (guint8 *)&shim, offset, sizeof(shim));
1229 len = (shim.ip6s_len + 1) << 3;
1233 ti = proto_tree_add_item(tree, hf_ipv6_shim6, tvb, offset, len, FALSE);
1234 shim_tree = proto_item_add_subtree(ti, ett_ipv6_shim6);
1237 proto_tree_add_uint_format(shim_tree, hf_ipv6_shim6_nxt, tvb,
1238 offset + offsetof(struct ip6_shim, ip6s_nxt), 1, shim.ip6s_nxt,
1239 "Next header: %s (0x%02x)", ipprotostr(shim.ip6s_nxt), shim.ip6s_nxt);
1241 /* Header Extension Length */
1242 proto_tree_add_uint_format(shim_tree, hf_ipv6_shim6_len, tvb,
1243 offset + offsetof(struct ip6_shim, ip6s_len), 1, shim.ip6s_len,
1244 "Header Ext Length: %u (%d bytes)", shim.ip6s_len, len);
1247 proto_tree_add_item(shim_tree, hf_ipv6_shim6_p, tvb,
1248 offset + offsetof(struct ip6_shim, ip6s_p), 1, FALSE);
1250 /* skip the first 2 bytes (nxt hdr, hdr ext len, p+7bits) */
1253 if (shim.ip6s_p & SHIM6_BITMASK_P)
1255 tmp[0] = tvb_get_guint8(tvb, p++);
1256 tmp[1] = tvb_get_guint8(tvb, p++);
1257 tmp[2] = tvb_get_guint8(tvb, p++);
1258 tmp[3] = tvb_get_guint8(tvb, p++);
1259 tmp[4] = tvb_get_guint8(tvb, p++);
1261 /* Payload Extension Header */
1262 proto_tree_add_none_format(shim_tree, hf_ipv6_shim6_ct, tvb,
1263 offset + offsetof(struct ip6_shim, ip6s_p), 6,
1264 "Receiver Context Tag: %02x %02x %02x %02x %02x %02x",
1265 shim.ip6s_p & SHIM6_BITMASK_CT, tmp[0], tmp[1], tmp[2], tmp[3], tmp[4]);
1269 /* Control Message */
1274 proto_tree_add_item(shim_tree, hf_ipv6_shim6_type, tvb,
1275 offset + offsetof(struct ip6_shim, ip6s_p), 1,
1279 /* Protocol bit (Must be zero for SHIM6) */
1280 proto_tree_add_item(shim_tree, hf_ipv6_shim6_proto, tvb, p, 1, FALSE);
1284 csum = shim_checksum(tvb_get_ptr(tvb, offset, len), len);
1287 ti = proto_tree_add_uint_format(shim_tree, hf_ipv6_shim6_checksum, tvb, p, 2,
1288 tvb_get_ntohs(tvb, p), "Checksum: 0x%04x [correct]", tvb_get_ntohs(tvb, p));
1289 ipv6_shim6_checkum_additional_info(tvb, pinfo, ti, p, TRUE);
1291 ti = proto_tree_add_uint_format(shim_tree, hf_ipv6_shim6_checksum, tvb, p, 2,
1292 tvb_get_ntohs(tvb, p), "Checksum: 0x%04x [incorrect: should be 0x%04x]",
1293 tvb_get_ntohs(tvb, p), in_cksum_shouldbe(tvb_get_ntohs(tvb, p), csum));
1294 ipv6_shim6_checkum_additional_info(tvb, pinfo, ti, p, FALSE);
1298 /* Type specific data */
1299 advance = dissect_shimctrl(tvb, p, shim.ip6s_p & SHIM6_BITMASK_TYPE, shim_tree);
1303 while (p < offset+len) {
1304 p += dissect_shimopts(tvb, p, shim_tree, pinfo);
1311 /* END SHIM6 PART */
1314 dissect_ipv6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1316 proto_tree *ipv6_tree = NULL;
1317 proto_item *ipv6_item = NULL, *ti;
1323 gboolean hopopts, routing, frag, ah, shim6, dstopts;
1327 fragment_data *ipfd_head;
1329 gboolean update_col_info = TRUE;
1330 gboolean save_fragmented = FALSE;
1331 const char *sep = "IPv6 ";
1333 struct ip6_hdr ipv6;
1335 col_set_str(pinfo->cinfo, COL_PROTOCOL, "IPv6");
1336 col_clear(pinfo->cinfo, COL_INFO);
1339 tvb_memcpy(tvb, (guint8 *)&ipv6, offset, sizeof(ipv6));
1341 /* Get extension header and payload length */
1342 plen = g_ntohs(ipv6.ip6_plen);
1344 /* Adjust the length of this tvbuff to include only the IPv6 datagram. */
1345 set_actual_length(tvb, plen + sizeof (struct ip6_hdr));
1347 SET_ADDRESS(&pinfo->net_src, AT_IPv6, 16, tvb_get_ptr(tvb, offset + IP6H_SRC, 16));
1348 SET_ADDRESS(&pinfo->src, AT_IPv6, 16, tvb_get_ptr(tvb, offset + IP6H_SRC, 16));
1349 SET_ADDRESS(&pinfo->net_dst, AT_IPv6, 16, tvb_get_ptr(tvb, offset + IP6H_DST, 16));
1350 SET_ADDRESS(&pinfo->dst, AT_IPv6, 16, tvb_get_ptr(tvb, offset + IP6H_DST, 16));
1355 proto_tree *ipv6_tc_tree;
1356 proto_item *ipv6_tc;
1358 ipv6_item = proto_tree_add_item(tree, proto_ipv6, tvb, offset, -1, FALSE);
1359 ipv6_tree = proto_item_add_subtree(ipv6_item, ett_ipv6);
1361 /* !!! warning: (4-bit) version, (6-bit) DSCP, (1-bit) ECN-ECT, (1-bit) ECN-CE and (20-bit) Flow */
1362 pi = proto_tree_add_item(ipv6_tree, hf_ipv6_version, tvb,
1363 offset + offsetof(struct ip6_hdr, ip6_vfc), 1, FALSE);
1364 pt = proto_item_add_subtree(pi,ett_ipv6_version);
1365 pi = proto_tree_add_item(pt, hf_ip_version, tvb,
1366 offset + offsetof(struct ip6_hdr, ip6_vfc), 1, FALSE);
1367 PROTO_ITEM_SET_GENERATED(pi);
1369 ipv6_tc = proto_tree_add_item(ipv6_tree, hf_ipv6_class, tvb,
1370 offset + offsetof(struct ip6_hdr, ip6_flow), 4, FALSE);
1372 ipv6_tc_tree = proto_item_add_subtree(ipv6_tc, ett_ipv6_traffic_class);
1374 proto_tree_add_item(ipv6_tc_tree, hf_ipv6_traffic_class_dscp, tvb,
1375 offset + offsetof(struct ip6_hdr, ip6_flow), 4, FALSE);
1377 proto_tree_add_item(ipv6_tc_tree, hf_ipv6_traffic_class_ect, tvb,
1378 offset + offsetof(struct ip6_hdr, ip6_flow), 4, FALSE);
1380 proto_tree_add_item(ipv6_tc_tree, hf_ipv6_traffic_class_ce, tvb,
1381 offset + offsetof(struct ip6_hdr, ip6_flow), 4, FALSE);
1383 proto_tree_add_item(ipv6_tree, hf_ipv6_flow, tvb,
1384 offset + offsetof(struct ip6_hdr, ip6_flow), 4, FALSE);
1386 proto_tree_add_item(ipv6_tree, hf_ipv6_plen, tvb,
1387 offset + offsetof(struct ip6_hdr, ip6_plen), 2, FALSE);
1389 proto_tree_add_uint_format(ipv6_tree, hf_ipv6_nxt, tvb,
1390 offset + offsetof(struct ip6_hdr, ip6_nxt), 1,
1392 "Next header: %s (0x%02x)",
1393 ipprotostr(ipv6.ip6_nxt), ipv6.ip6_nxt);
1395 proto_tree_add_item(ipv6_tree, hf_ipv6_hlim, tvb,
1396 offset + offsetof(struct ip6_hdr, ip6_hlim), 1, FALSE);
1398 /* Adds the different items for the source address */
1399 proto_tree_add_item(ipv6_tree, hf_ipv6_src, tvb,
1400 offset + offsetof(struct ip6_hdr, ip6_src), 16, FALSE);
1401 ti = proto_tree_add_ipv6(ipv6_tree, hf_ipv6_addr, tvb,
1402 offset + offsetof(struct ip6_hdr, ip6_src),
1403 16, (guint8 *)&ipv6.ip6_src);
1404 PROTO_ITEM_SET_HIDDEN(ti);
1405 ti = proto_tree_add_string(ipv6_tree, hf_ipv6_src_host, tvb,
1406 offset + offsetof(struct ip6_hdr, ip6_src),
1407 16, get_addr_name(&pinfo->src));
1408 PROTO_ITEM_SET_GENERATED(ti);
1409 PROTO_ITEM_SET_HIDDEN(ti);
1410 ti = proto_tree_add_string(ipv6_tree, hf_ipv6_host, tvb,
1411 offset + offsetof(struct ip6_hdr, ip6_src),
1412 16, get_addr_name(&pinfo->src));
1413 PROTO_ITEM_SET_GENERATED(ti);
1414 PROTO_ITEM_SET_HIDDEN(ti);
1416 /* Adds different items for the destination address */
1417 proto_tree_add_item(ipv6_tree, hf_ipv6_dst, tvb,
1418 offset + offsetof(struct ip6_hdr, ip6_dst), 16, FALSE);
1419 ti = proto_tree_add_ipv6(ipv6_tree, hf_ipv6_addr, tvb,
1420 offset + offsetof(struct ip6_hdr, ip6_dst),
1421 16, (guint8 *)&ipv6.ip6_dst);
1422 PROTO_ITEM_SET_HIDDEN(ti);
1423 ti = proto_tree_add_string(ipv6_tree, hf_ipv6_dst_host, tvb,
1424 offset + offsetof(struct ip6_hdr, ip6_dst),
1425 16, get_addr_name(&pinfo->dst));
1426 PROTO_ITEM_SET_GENERATED(ti);
1427 PROTO_ITEM_SET_HIDDEN(ti);
1428 ti = proto_tree_add_string(ipv6_tree, hf_ipv6_host, tvb,
1429 offset + offsetof(struct ip6_hdr, ip6_dst),
1430 16, get_addr_name(&pinfo->dst));
1431 PROTO_ITEM_SET_GENERATED(ti);
1432 PROTO_ITEM_SET_HIDDEN(ti);
1435 /* start of the new header (could be a extension header) */
1436 poffset = offset + offsetof(struct ip6_hdr, ip6_nxt);
1437 nxt = tvb_get_guint8(tvb, poffset);
1438 offset += sizeof(struct ip6_hdr);
1442 /* start out assuming this isn't fragmented, and has none of the other
1443 non-final headers */
1454 case IP_PROTO_HOPOPTS:
1456 advance = dissect_hopopts(tvb, offset, ipv6_tree, pinfo);
1457 nxt = tvb_get_guint8(tvb, offset);
1463 case IP_PROTO_ROUTING:
1465 advance = dissect_routing6(tvb, offset, ipv6_tree, pinfo);
1466 nxt = tvb_get_guint8(tvb, offset);
1472 case IP_PROTO_FRAGMENT:
1473 advance = dissect_frag6(tvb, offset, pinfo, ipv6_tree,
1475 nxt = tvb_get_guint8(tvb, offset);
1479 frag = offlg & (IP6F_OFF_MASK | IP6F_MORE_FRAG);
1480 save_fragmented |= frag;
1481 if (ipv6_reassemble && frag && tvb_bytes_exist(tvb, offset, plen)) {
1482 ipfd_head = fragment_add_check(tvb, offset, pinfo, ident,
1483 ipv6_fragment_table,
1484 ipv6_reassembled_table,
1485 offlg & IP6F_OFF_MASK,
1487 offlg & IP6F_MORE_FRAG);
1488 next_tvb = process_reassembled_data(tvb, offset, pinfo, "Reassembled IPv6",
1489 ipfd_head, &ipv6_frag_items, &update_col_info, ipv6_tree);
1490 if (next_tvb) { /* Process post-fragment headers after reassembly... */
1498 if (!(offlg & IP6F_OFF_MASK)) /*...or in the first fragment */
1504 advance = dissect_ah_header(tvb_new_subset_remaining(tvb, offset),
1505 pinfo, ipv6_tree, NULL, NULL);
1506 nxt = tvb_get_guint8(tvb, offset);
1512 case IP_PROTO_SHIM6:
1513 case IP_PROTO_SHIM6_OLD:
1515 advance = dissect_shim6(tvb, offset, ipv6_tree, pinfo);
1516 nxt = tvb_get_guint8(tvb, offset);
1517 stype = tvb_get_guint8(tvb, offset+2);
1523 case IP_PROTO_DSTOPTS:
1525 advance = dissect_dstopts(tvb, offset, ipv6_tree, pinfo);
1526 nxt = tvb_get_guint8(tvb, offset);
1536 /* Since we did not recognize this IPv6 option, check
1537 * whether it is a known protocol. If not, then it
1538 * is an unknown IPv6 option
1540 if (!dissector_get_port_handle(ip_dissector_table, nxt)) {
1541 advance = dissect_unknown_option(tvb, offset, ipv6_tree);
1542 nxt = tvb_get_guint8(tvb, offset);
1550 #ifdef TEST_FINALHDR
1551 ti = proto_tree_add_uint(ipv6_tree, hf_ipv6_final, tvb, poffset, 1, nxt);
1552 PROTO_ITEM_SET_HIDDEN(ti);
1555 proto_item_set_len (ipv6_item, offset);
1556 tap_queue_packet(ipv6_tap, pinfo, &ipv6);
1558 /* collect packet info */
1559 pinfo->ipproto = nxt;
1560 pinfo->iplen = sizeof(ipv6) + plen + offset;
1561 pinfo->iphdrlen = offset;
1563 if (offlg & IP6F_OFF_MASK || (ipv6_reassemble && offlg & IP6F_MORE_FRAG)) {
1564 /* Not the first fragment, or the first when we are reassembling and there are more. */
1565 /* Don't dissect it; just show this as a fragment. */
1566 /* COL_INFO was filled in by "dissect_frag6()" */
1567 call_dissector(data_handle, tvb_new_subset_remaining(tvb, offset), pinfo, tree);
1570 /* First fragment, not fragmented, or already reassembled. Dissect what we have here. */
1572 /* Get a tvbuff for the payload. */
1573 next_tvb = tvb_new_subset_remaining(tvb, offset);
1576 * If this is the first fragment, but not the only fragment,
1577 * tell the next protocol that.
1579 if (offlg & IP6F_MORE_FRAG)
1580 pinfo->fragmented = TRUE;
1582 pinfo->fragmented = FALSE;
1586 /* do lookup with the subdissector table */
1587 if (!dissector_try_port(ip_dissector_table, nxt, next_tvb, pinfo, tree)) {
1588 /* Unknown protocol.
1589 Handle "no next header" specially. */
1590 if (nxt == IP_PROTO_NONE) {
1591 if (check_col(pinfo->cinfo, COL_INFO)) {
1592 /* If we had an Authentication Header, the AH dissector already
1593 put something in the Info column; leave it there. */
1595 if (hopopts || routing || dstopts || shim6) {
1597 col_append_fstr(pinfo->cinfo, COL_INFO, "%shop-by-hop options",
1602 col_append_fstr(pinfo->cinfo, COL_INFO, "%srouting", sep);
1606 col_append_fstr(pinfo->cinfo, COL_INFO, "%sdestination options",
1610 if (stype & SHIM6_BITMASK_P) {
1611 col_append_str(pinfo->cinfo, COL_INFO, "Shim6 (Payload)");
1614 col_append_fstr(pinfo->cinfo, COL_INFO, "Shim6 (%s)",
1615 val_to_str(stype & SHIM6_BITMASK_TYPE, shimctrlvals, "Unknown"));
1619 col_set_str(pinfo->cinfo, COL_INFO, "IPv6 no next header");
1623 if (check_col(pinfo->cinfo, COL_INFO))
1624 col_add_fstr(pinfo->cinfo, COL_INFO, "%s (0x%02x)", ipprotostr(nxt),nxt);
1626 call_dissector(data_handle, next_tvb, pinfo, tree);
1628 pinfo->fragmented = save_fragmented;
1632 proto_register_ipv6(void)
1634 static hf_register_info hf[] = {
1636 { "Version", "ipv6.version",
1637 FT_UINT8, BASE_DEC, NULL, 0xF0, NULL, HFILL }},
1639 { "This field makes the filter \"ip.version == 6\" possible", "ip.version",
1640 FT_UINT8, BASE_DEC, NULL, 0xF0, NULL, HFILL }},
1642 { "Traffic class", "ipv6.class",
1643 FT_UINT32, BASE_HEX, NULL, 0x0FF00000, NULL, HFILL }},
1645 { "Flowlabel", "ipv6.flow",
1646 FT_UINT32, BASE_HEX, NULL, 0x000FFFFF, NULL, HFILL }},
1648 { "Payload length", "ipv6.plen",
1649 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1651 { "Next header", "ipv6.nxt",
1652 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1654 { "Hop limit", "ipv6.hlim",
1655 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1657 { "Source", "ipv6.src",
1658 FT_IPv6, BASE_NONE, NULL, 0x0,
1659 "Source IPv6 Address", HFILL }},
1660 { &hf_ipv6_src_host,
1661 { "Source Host", "ipv6.src_host",
1662 FT_STRING, BASE_NONE, NULL, 0x0,
1663 "Source IPv6 Host", HFILL }},
1665 { "Destination", "ipv6.dst",
1666 FT_IPv6, BASE_NONE, NULL, 0x0,
1667 "Destination IPv6 Address", HFILL }},
1668 { &hf_ipv6_dst_host,
1669 { "Destination Host", "ipv6.dst_host",
1670 FT_STRING, BASE_NONE, NULL, 0x0,
1671 "Destination IPv6 Host", HFILL }},
1673 { "Address", "ipv6.addr",
1674 FT_IPv6, BASE_NONE, NULL, 0x0,
1675 "Source or Destination IPv6 Address", HFILL }},
1677 { "Host", "ipv6.host",
1678 FT_STRING, BASE_NONE, NULL, 0x0,
1679 "IPv6 Host", HFILL }},
1681 { &hf_ipv6_opt_pad1,
1682 { "Pad1", "ipv6.opt.pad1",
1683 FT_NONE, BASE_NONE, NULL, 0x0,
1684 "Pad1 Option", HFILL }},
1685 { &hf_ipv6_opt_padn,
1686 { "PadN", "ipv6.opt.padn",
1687 FT_UINT8, BASE_DEC, NULL, 0x0,
1688 "PadN Option", HFILL }},
1690 { "Destination Option", "ipv6.dst_opt",
1691 FT_NONE, BASE_NONE, NULL, 0x0,
1694 { "Hop-by-Hop Option", "ipv6.hop_opt",
1695 FT_NONE, BASE_NONE, NULL, 0x0,
1698 { "Unknown Extension Header", "ipv6.unknown_hdr",
1699 FT_NONE, BASE_NONE, NULL, 0x0,
1701 { &hf_ipv6_routing_hdr_opt,
1702 { "Routing Header, Type","ipv6.routing_hdr",
1703 FT_UINT8, BASE_DEC, NULL, 0x0,
1704 "Routing Header Option", HFILL }},
1705 { &hf_ipv6_routing_hdr_type,
1706 { "Type", "ipv6.routing_hdr.type",
1707 FT_UINT8, BASE_DEC, VALS(routing_header_type), 0x0,
1708 "Routeing Header Type", HFILL }},
1709 { &hf_ipv6_routing_hdr_left,
1710 { "Left Segments", "ipv6.routing_hdr.left",
1711 FT_UINT8, BASE_DEC, NULL, 0x0,
1712 "Routing Header Left Segments", HFILL }},
1713 { &hf_ipv6_routing_hdr_addr,
1714 { "Address", "ipv6.routing_hdr.addr",
1715 FT_IPv6, BASE_NONE, NULL, 0x0,
1716 "Routing Header Address", HFILL }},
1717 { &hf_ipv6_frag_offset,
1718 { "Offset", "ipv6.fragment.offset",
1719 FT_UINT16, BASE_DEC_HEX, NULL, IP6F_OFF_MASK,
1720 "Fragment Offset", HFILL }},
1721 { &hf_ipv6_frag_more,
1722 { "More Fragment", "ipv6.fragment.more",
1723 FT_BOOLEAN, 16, TFS(&tfs_yes_no), IP6F_MORE_FRAG,
1724 "More Fragments", HFILL }},
1726 { "Identification", "ipv6.framgent.id",
1727 FT_UINT32, BASE_HEX, NULL, 0x0,
1728 "Fragment Identification", HFILL }},
1729 { &hf_ipv6_fragment_overlap,
1730 { "Fragment overlap", "ipv6.fragment.overlap",
1731 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1732 "Fragment overlaps with other fragments", HFILL }},
1734 { &hf_ipv6_fragment_overlap_conflict,
1735 { "Conflicting data in fragment overlap", "ipv6.fragment.overlap.conflict",
1736 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1737 "Overlapping fragments contained conflicting data", HFILL }},
1739 { &hf_ipv6_fragment_multiple_tails,
1740 { "Multiple tail fragments found", "ipv6.fragment.multipletails",
1741 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1742 "Several tails were found when defragmenting the packet", HFILL }},
1744 { &hf_ipv6_fragment_too_long_fragment,
1745 { "Fragment too long", "ipv6.fragment.toolongfragment",
1746 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1747 "Fragment contained data past end of packet", HFILL }},
1749 { &hf_ipv6_fragment_error,
1750 { "Defragmentation error", "ipv6.fragment.error",
1751 FT_FRAMENUM, BASE_NONE, NULL, 0x0,
1752 "Defragmentation error due to illegal fragments", HFILL }},
1754 { &hf_ipv6_fragment,
1755 { "IPv6 Fragment", "ipv6.fragment",
1756 FT_FRAMENUM, BASE_NONE, NULL, 0x0,
1759 { &hf_ipv6_fragments,
1760 { "IPv6 Fragments", "ipv6.fragments",
1761 FT_NONE, BASE_NONE, NULL, 0x0,
1764 { &hf_ipv6_reassembled_in,
1765 { "Reassembled IPv6 in frame", "ipv6.reassembled_in",
1766 FT_FRAMENUM, BASE_NONE, NULL, 0x0,
1767 "This IPv6 packet is reassembled in this frame", HFILL }},
1769 { &hf_ipv6_reassembled_length,
1770 { "Reassembled IPv6 length", "ipv6.reassembled.length",
1771 FT_UINT32, BASE_DEC, NULL, 0x0,
1772 "The total length of the reassembled payload", HFILL }},
1775 { &hf_ipv6_mipv6_type,
1776 { "Option Type", "ipv6.mipv6_type",
1777 FT_UINT8, BASE_DEC, NULL, 0x0,
1779 { &hf_ipv6_mipv6_length,
1780 { "Option Length", "ipv6.mipv6_length",
1781 FT_UINT8, BASE_DEC, NULL, 0x0,
1783 { &hf_ipv6_mipv6_home_address,
1784 { "Home Address", "ipv6.mipv6_home_address",
1785 FT_IPv6, BASE_NONE, NULL, 0x0,
1790 { "SHIM6", "ipv6.shim6",
1791 FT_NONE, BASE_NONE, NULL, 0x0,
1794 { &hf_ipv6_shim6_nxt,
1795 { "Next Header", "ipv6.shim6.nxt",
1796 FT_UINT8, BASE_DEC, NULL, 0x0,
1799 { &hf_ipv6_shim6_len,
1800 { "Header Ext Length", "ipv6.shim6.len",
1801 FT_UINT8, BASE_DEC, NULL, 0x0,
1805 { "P Bit", "ipv6.shim6.p",
1806 FT_BOOLEAN, 8, NULL, SHIM6_BITMASK_P,
1809 { &hf_ipv6_shim6_ct,
1810 { "Context Tag", "ipv6.shim6.ct",
1811 FT_NONE, BASE_NONE, NULL, 0x0,
1814 { &hf_ipv6_shim6_type,
1815 { "Message Type", "ipv6.shim6.type",
1817 VALS(shimctrlvals), SHIM6_BITMASK_TYPE,
1820 { &hf_ipv6_shim6_proto,
1821 { "Protocol", "ipv6.shim6.proto",
1823 VALS(shim6_protocol), SHIM6_BITMASK_PROTOCOL,
1826 { &hf_ipv6_shim6_checksum,
1827 { "Checksum", "ipv6.shim6.checksum",
1828 FT_UINT16, BASE_HEX, NULL, 0x0,
1829 "Shim6 Checksum", HFILL }},
1830 { &hf_ipv6_shim6_checksum_bad,
1831 { "Bad Checksum", "ipv6.shim6.checksum_bad",
1832 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1833 "Shim6 Bad Checksum", HFILL }},
1835 { &hf_ipv6_shim6_checksum_good,
1836 { "Good Checksum", "ipv6.shim6.checksum_good",
1837 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1840 { &hf_ipv6_shim6_inonce,
1841 { "Initiator Nonce", "ipv6.shim6.inonce",
1842 FT_UINT32, BASE_DEC_HEX, NULL, 0x0,
1845 { &hf_ipv6_shim6_rnonce,
1846 { "Responder Nonce", "ipv6.shim6.rnonce",
1847 FT_UINT32, BASE_DEC_HEX, NULL, 0x0,
1850 { &hf_ipv6_shim6_precvd,
1851 { "Probes Received", "ipv6.shim6.precvd",
1852 FT_UINT8, BASE_DEC, NULL, 0x0,
1855 { &hf_ipv6_shim6_psent,
1856 { "Probes Sent", "ipv6.shim6.psent",
1857 FT_UINT8, BASE_DEC, NULL, 0x0,
1860 { &hf_ipv6_shim6_psrc,
1861 { "Source Address", "ipv6.shim6.psrc",
1862 FT_IPv6, BASE_NONE, NULL, 0x0,
1863 "Shim6 Probe Source Address", HFILL }},
1865 { &hf_ipv6_shim6_pdst,
1866 { "Destination Address", "ipv6.shim6.pdst",
1867 FT_IPv6, BASE_NONE, NULL, 0x0,
1868 "Shim6 Probe Destination Address", HFILL }},
1870 { &hf_ipv6_shim6_pnonce,
1871 { "Nonce", "ipv6.shim6.pnonce",
1872 FT_UINT32, BASE_DEC_HEX, NULL, 0x0,
1873 "Shim6 Probe Nonce", HFILL }},
1875 { &hf_ipv6_shim6_pdata,
1876 { "Data", "ipv6.shim6.pdata",
1877 FT_UINT32, BASE_HEX, NULL, 0x0,
1878 "Shim6 Probe Data", HFILL }},
1880 { &hf_ipv6_shim6_sulid,
1881 { "Sender ULID", "ipv6.shim6.sulid",
1882 FT_IPv6, BASE_NONE, NULL, 0x0,
1883 "Shim6 Sender ULID", HFILL }},
1885 { &hf_ipv6_shim6_rulid,
1886 { "Receiver ULID", "ipv6.shim6.rulid",
1887 FT_IPv6, BASE_NONE, NULL, 0x0,
1888 "Shim6 Receiver ULID", HFILL }},
1890 { &hf_ipv6_shim6_reap,
1891 { "REAP State", "ipv6.shim6.reap",
1892 FT_UINT8, BASE_DEC, NULL, 0x0,
1895 { &hf_ipv6_shim6_opt_type,
1896 { "Option Type", "ipv6.shim6.opt.type",
1897 FT_UINT16, BASE_DEC,
1898 VALS(shimoptvals), SHIM6_BITMASK_OPT_TYPE,
1899 "Shim6 Option Type", HFILL }},
1901 { &hf_ipv6_shim6_opt_critical,
1902 { "Option Critical Bit", "ipv6.shim6.opt.critical",
1905 SHIM6_BITMASK_CRITICAL,
1906 "TRUE : option is critical, FALSE: option is not critical",
1909 { &hf_ipv6_shim6_opt_len,
1910 { "Content Length", "ipv6.shim6.opt.len",
1911 FT_UINT16, BASE_DEC, NULL, 0x0,
1912 "Content Length Option", HFILL }},
1914 { &hf_ipv6_shim6_opt_total_len,
1915 { "Total Length", "ipv6.shim6.opt.total_len",
1916 FT_UINT16, BASE_DEC, NULL, 0x0,
1917 "Total Option Length", HFILL }},
1919 { &hf_ipv6_shim6_opt_loc_verif_methods,
1920 { "Verification Method", "ipv6.shim6.opt.verif_method",
1922 VALS(shimverifmethods), 0x0,
1923 "Locator Verification Method", HFILL }},
1925 { &hf_ipv6_shim6_opt_loclist,
1926 { "Locator List Generation", "ipv6.shim6.opt.loclist",
1927 FT_UINT32, BASE_DEC_HEX, NULL, 0x0,
1930 { &hf_ipv6_shim6_locator,
1931 { "Locator", "ipv6.shim6.locator",
1932 FT_IPv6, BASE_NONE, NULL, 0x0,
1933 "Shim6 Locator", HFILL }},
1935 { &hf_ipv6_shim6_opt_locnum,
1936 { "Num Locators", "ipv6.shim6.opt.locnum",
1937 FT_UINT8, BASE_DEC, NULL, 0x0,
1938 "Number of Locators in Locator List", HFILL }},
1940 { &hf_ipv6_shim6_opt_elemlen,
1941 { "Element Length", "ipv6.shim6.opt.elemlen",
1942 FT_UINT8, BASE_DEC, NULL, 0x0,
1943 "Length of Elements in Locator Preferences Option", HFILL }},
1944 { &hf_ipv6_shim6_loc_flag,
1945 { "Flags", "ipv6.shim6.loc.flags",
1946 FT_UINT8, BASE_DEC, NULL, 0x0,
1947 "Locator Preferences Flags", HFILL }},
1949 { &hf_ipv6_shim6_loc_prio,
1950 { "Priority", "ipv6.shim6.loc.prio",
1951 FT_UINT8, BASE_DEC, NULL, 0x0,
1952 "Locator Preferences Priority", HFILL }},
1954 { &hf_ipv6_shim6_loc_weight,
1955 { "Weight", "ipv6.shim6.loc.weight",
1956 FT_UINT8, BASE_DEC, NULL, 0x0,
1957 "Locator Preferences Weight", HFILL }},
1959 { &hf_ipv6_shim6_opt_fii,
1960 { "Forked Instance Identifier", "ipv6.shim6.opt.fii",
1961 FT_UINT32, BASE_DEC_HEX, NULL, 0x0,
1964 #ifdef TEST_FINALHDR
1966 { "Final next header", "ipv6.final",
1967 FT_UINT8, BASE_HEX, NULL, 0x0, "", HFILL }},
1970 { &hf_ipv6_traffic_class_dscp,
1971 { "Differentiated Services Field", "ipv6.traffic_class.dscp",
1972 FT_UINT32, BASE_HEX, VALS(dscp_vals), 0x0FC00000, NULL, HFILL }},
1974 { &hf_ipv6_traffic_class_ect,
1975 { "ECN-Capable Transport (ECT)", "ipv6.traffic_class.ect",
1976 FT_BOOLEAN, 32, TFS(&tfs_set_notset), 0x0200000, NULL, HFILL }},
1978 { &hf_ipv6_traffic_class_ce,
1979 { "ECN-CE", "ipv6.traffic_class.ce",
1980 FT_BOOLEAN, 32, TFS(&tfs_set_notset), 0x0100000, NULL, HFILL }},
1982 static gint *ett[] = {
1986 &ett_ipv6_shim6_option,
1987 &ett_ipv6_shim6_locators,
1988 &ett_ipv6_shim6_verif_methods,
1989 &ett_ipv6_shim6_loc_pref,
1990 &ett_ipv6_shim6_probes_sent,
1991 &ett_ipv6_shim6_probes_rcvd,
1992 &ett_ipv6_shim6_probe_sent,
1993 &ett_ipv6_shim6_probe_rcvd,
1994 &ett_ipv6_shim6_cksum,
1995 &ett_ipv6_fragments,
1997 &ett_ipv6_traffic_class
1999 module_t *ipv6_module;
2001 proto_ipv6 = proto_register_protocol("Internet Protocol Version 6", "IPv6", "ipv6");
2002 proto_register_field_array(proto_ipv6, hf, array_length(hf));
2003 proto_register_subtree_array(ett, array_length(ett));
2005 /* Register configuration options */
2006 ipv6_module = prefs_register_protocol(proto_ipv6, NULL);
2007 prefs_register_bool_preference(ipv6_module, "defragment",
2008 "Reassemble fragmented IPv6 datagrams",
2009 "Whether fragmented IPv6 datagrams should be reassembled",
2012 register_dissector("ipv6", dissect_ipv6, proto_ipv6);
2013 register_init_routine(ipv6_reassemble_init);
2014 ipv6_tap = register_tap("ipv6");
2018 proto_reg_handoff_ipv6(void)
2020 dissector_handle_t ipv6_handle;
2022 data_handle = find_dissector("data");
2023 ipv6_handle = find_dissector("ipv6");
2024 dissector_add("ethertype", ETHERTYPE_IPv6, ipv6_handle);
2025 dissector_add("ppp.protocol", PPP_IPV6, ipv6_handle);
2026 dissector_add("ppp.protocol", ETHERTYPE_IPv6, ipv6_handle);
2027 dissector_add("gre.proto", ETHERTYPE_IPv6, ipv6_handle);
2028 dissector_add("ip.proto", IP_PROTO_IPV6, ipv6_handle);
2029 dissector_add("null.type", BSD_AF_INET6_BSD, ipv6_handle);
2030 dissector_add("null.type", BSD_AF_INET6_FREEBSD, ipv6_handle);
2031 dissector_add("null.type", BSD_AF_INET6_DARWIN, ipv6_handle);
2032 dissector_add("chdlctype", ETHERTYPE_IPv6, ipv6_handle);
2033 dissector_add("fr.ietf", NLPID_IP6, ipv6_handle);
2034 dissector_add("osinl.excl", NLPID_IP6, ipv6_handle);
2035 dissector_add("x.25.spi", NLPID_IP6, ipv6_handle);
2036 dissector_add("arcnet.protocol_id", ARCNET_PROTO_IPv6, ipv6_handle);
2038 ip_dissector_table = find_dissector_table("ip.proto");