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 <epan/ip_opts.h>
37 #include <epan/addr_resolv.h>
38 #include <epan/prefs.h>
39 #include <epan/reassemble.h>
40 #include <epan/ipproto.h>
41 #include <epan/ipv6-utils.h>
42 #include <epan/etypes.h>
43 #include <epan/ppptypes.h>
44 #include <epan/aftypes.h>
45 #include <epan/nlpid.h>
46 #include <epan/arcnet_pids.h>
47 #include <epan/in_cksum.h>
48 #include <epan/expert.h>
49 #include <epan/emem.h>
51 #include "packet-ipsec.h"
52 #include "packet-ipv6.h"
56 #include <epan/geoip_db.h>
57 #endif /* HAVE_GEOIP_V6 */
60 * NOTE: ipv6.nxt is not very useful as we will have chained header.
61 * now testing ipv6.final, but it raises SEGV.
65 /* Differentiated Services Field. See RFCs 2474, 2597 and 2598. */
66 #define IPDSFIELD_DSCP_MASK 0xFC
67 #define IPDSFIELD_ECN_MASK 0x03
68 #define IPDSFIELD_DSCP_SHIFT 2
69 #define IPDSFIELD_DSCP(dsfield) (((dsfield)&IPDSFIELD_DSCP_MASK)>>IPDSFIELD_DSCP_SHIFT)
70 #define IPDSFIELD_ECN(dsfield) ((dsfield)&IPDSFIELD_ECN_MASK)
71 #define IPDSFIELD_DSCP_DEFAULT 0x00
72 #define IPDSFIELD_DSCP_CS1 0x08
73 #define IPDSFIELD_DSCP_CS2 0x10
74 #define IPDSFIELD_DSCP_CS3 0x18
75 #define IPDSFIELD_DSCP_CS4 0x20
76 #define IPDSFIELD_DSCP_CS5 0x28
77 #define IPDSFIELD_DSCP_CS6 0x30
78 #define IPDSFIELD_DSCP_CS7 0x38
79 #define IPDSFIELD_DSCP_AF11 0x0A
80 #define IPDSFIELD_DSCP_AF12 0x0C
81 #define IPDSFIELD_DSCP_AF13 0x0E
82 #define IPDSFIELD_DSCP_AF21 0x12
83 #define IPDSFIELD_DSCP_AF22 0x14
84 #define IPDSFIELD_DSCP_AF23 0x16
85 #define IPDSFIELD_DSCP_AF31 0x1A
86 #define IPDSFIELD_DSCP_AF32 0x1C
87 #define IPDSFIELD_DSCP_AF33 0x1E
88 #define IPDSFIELD_DSCP_AF41 0x22
89 #define IPDSFIELD_DSCP_AF42 0x24
90 #define IPDSFIELD_DSCP_AF43 0x26
91 #define IPDSFIELD_DSCP_EF 0x2E
92 #define IPDSFIELD_ECT_MASK 0x02
93 #define IPDSFIELD_CE_MASK 0x01
95 /* RPL Routing header */
96 #define IP6RRPL_BITMASK_CMPRI 0xF0000000
97 #define IP6RRPL_BITMASK_CMPRE 0x0F000000
98 #define IP6RRPL_BITMASK_PAD 0x00F00000
99 #define IP6RRPL_BITMASK_RESERVED 0x000FFFFF
101 static int ipv6_tap = -1;
103 static int proto_ipv6 = -1;
104 static int hf_ipv6_version = -1;
105 static int hf_ip_version = -1;
106 static int hf_ipv6_class = -1;
107 static int hf_ipv6_flow = -1;
108 static int hf_ipv6_plen = -1;
109 static int hf_ipv6_nxt = -1;
110 static int hf_ipv6_hlim = -1;
111 static int hf_ipv6_src = -1;
112 static int hf_ipv6_src_host = -1;
113 static int hf_ipv6_src_sa_mac = -1;
114 static int hf_ipv6_src_isatap_ipv4 = -1;
115 static int hf_ipv6_src_6to4_gateway_ipv4 = -1;
116 static int hf_ipv6_src_6to4_sla_id = -1;
117 static int hf_ipv6_src_teredo_server_ipv4 = -1;
118 static int hf_ipv6_src_teredo_port = -1;
119 static int hf_ipv6_src_teredo_client_ipv4 = -1;
120 static int hf_ipv6_dst = -1;
121 static int hf_ipv6_dst_host = -1;
122 static int hf_ipv6_dst_sa_mac = -1;
123 static int hf_ipv6_dst_isatap_ipv4 = -1;
124 static int hf_ipv6_dst_6to4_gateway_ipv4 = -1;
125 static int hf_ipv6_dst_6to4_sla_id = -1;
126 static int hf_ipv6_dst_teredo_server_ipv4 = -1;
127 static int hf_ipv6_dst_teredo_port = -1;
128 static int hf_ipv6_dst_teredo_client_ipv4 = -1;
129 static int hf_ipv6_addr = -1;
130 static int hf_ipv6_host = -1;
131 static int hf_ipv6_sa_mac = -1;
132 static int hf_ipv6_isatap_ipv4 = -1;
133 static int hf_ipv6_6to4_gateway_ipv4 = -1;
134 static int hf_ipv6_6to4_sla_id = -1;
135 static int hf_ipv6_teredo_server_ipv4 = -1;
136 static int hf_ipv6_teredo_port = -1;
137 static int hf_ipv6_teredo_client_ipv4 = -1;
138 static int hf_ipv6_opt_pad1 = -1;
139 static int hf_ipv6_opt_padn = -1;
140 static int hf_ipv6_dst_opt = -1;
141 static int hf_ipv6_hop_opt = -1;
142 static int hf_ipv6_unk_hdr = -1;
143 static int hf_ipv6_routing_hdr_opt = -1;
144 static int hf_ipv6_routing_hdr_type = -1;
145 static int hf_ipv6_routing_hdr_left = -1;
146 static int hf_ipv6_routing_hdr_addr = -1;
148 static int hf_ipv6_final = -1;
150 static int hf_ipv6_frag_offset = -1;
151 static int hf_ipv6_frag_more = -1;
152 static int hf_ipv6_frag_id = -1;
153 static int hf_ipv6_fragments = -1;
154 static int hf_ipv6_fragment = -1;
155 static int hf_ipv6_fragment_overlap = -1;
156 static int hf_ipv6_fragment_overlap_conflict = -1;
157 static int hf_ipv6_fragment_multiple_tails = -1;
158 static int hf_ipv6_fragment_too_long_fragment = -1;
159 static int hf_ipv6_fragment_error = -1;
160 static int hf_ipv6_fragment_count = -1;
161 static int hf_ipv6_reassembled_in = -1;
162 static int hf_ipv6_reassembled_length = -1;
164 static int hf_ipv6_mipv6_type = -1;
165 static int hf_ipv6_mipv6_length = -1;
166 static int hf_ipv6_mipv6_home_address = -1;
168 static int hf_ipv6_routing_hdr_rpl_cmprI = -1;
169 static int hf_ipv6_routing_hdr_rpl_cmprE = -1;
170 static int hf_ipv6_routing_hdr_rpl_pad = -1;
171 static int hf_ipv6_routing_hdr_rpl_reserved = -1;
172 static int hf_ipv6_routing_hdr_rpl_segments = -1;
173 static int hf_ipv6_routing_hdr_rpl_addr = -1;
174 static int hf_ipv6_routing_hdr_rpl_fulladdr = -1;
176 static int hf_ipv6_shim6 = -1;
177 static int hf_ipv6_shim6_nxt = -1;
178 static int hf_ipv6_shim6_len = -1;
179 static int hf_ipv6_shim6_p = -1;
180 /* context tag is 49 bits, cannot be used for filter yet */
181 static int hf_ipv6_shim6_ct = -1;
182 static int hf_ipv6_shim6_type = -1;
183 static int hf_ipv6_shim6_proto = -1;
184 static int hf_ipv6_shim6_checksum = -1;
185 static int hf_ipv6_shim6_checksum_bad = -1;
186 static int hf_ipv6_shim6_checksum_good= -1;
187 static int hf_ipv6_shim6_inonce = -1; /* also for request nonce */
188 static int hf_ipv6_shim6_rnonce = -1;
189 static int hf_ipv6_shim6_precvd = -1;
190 static int hf_ipv6_shim6_psent = -1;
191 static int hf_ipv6_shim6_psrc = -1;
192 static int hf_ipv6_shim6_pdst = -1;
193 static int hf_ipv6_shim6_pnonce = -1;
194 static int hf_ipv6_shim6_pdata = -1;
195 static int hf_ipv6_shim6_sulid = -1;
196 static int hf_ipv6_shim6_rulid = -1;
197 static int hf_ipv6_shim6_reap = -1;
198 static int hf_ipv6_shim6_opt_type = -1;
199 static int hf_ipv6_shim6_opt_len = -1;
200 static int hf_ipv6_shim6_opt_total_len= -1;
201 static int hf_ipv6_shim6_opt_loc_verif_methods = -1;
202 static int hf_ipv6_shim6_opt_critical = -1;
203 static int hf_ipv6_shim6_opt_loclist = -1;
204 static int hf_ipv6_shim6_locator = -1;
205 static int hf_ipv6_shim6_loc_flag = -1;
206 static int hf_ipv6_shim6_loc_prio = -1;
207 static int hf_ipv6_shim6_loc_weight = -1;
208 static int hf_ipv6_shim6_opt_locnum = -1;
209 static int hf_ipv6_shim6_opt_elemlen = -1;
210 static int hf_ipv6_shim6_opt_fii = -1;
211 static int hf_ipv6_traffic_class_dscp = -1;
212 static int hf_ipv6_traffic_class_ect = -1;
213 static int hf_ipv6_traffic_class_ce = -1;
216 static int hf_geoip_country = -1;
217 static int hf_geoip_city = -1;
218 static int hf_geoip_org = -1;
219 static int hf_geoip_isp = -1;
220 static int hf_geoip_asnum = -1;
221 static int hf_geoip_lat = -1;
222 static int hf_geoip_lon = -1;
223 static int hf_geoip_src_country = -1;
224 static int hf_geoip_src_city = -1;
225 static int hf_geoip_src_org = -1;
226 static int hf_geoip_src_isp = -1;
227 static int hf_geoip_src_asnum = -1;
228 static int hf_geoip_src_lat = -1;
229 static int hf_geoip_src_lon = -1;
230 static int hf_geoip_dst_country = -1;
231 static int hf_geoip_dst_city = -1;
232 static int hf_geoip_dst_org = -1;
233 static int hf_geoip_dst_isp = -1;
234 static int hf_geoip_dst_asnum = -1;
235 static int hf_geoip_dst_lat = -1;
236 static int hf_geoip_dst_lon = -1;
237 #endif /* HAVE_GEOIP_V6 */
239 static gint ett_ipv6 = -1;
240 static gint ett_ipv6_version = -1;
241 static gint ett_ipv6_shim6 = -1;
242 static gint ett_ipv6_shim6_option = -1;
243 static gint ett_ipv6_shim6_locators = -1;
244 static gint ett_ipv6_shim6_verif_methods = -1;
245 static gint ett_ipv6_shim6_loc_pref = -1;
246 static gint ett_ipv6_shim6_probes_sent = -1;
247 static gint ett_ipv6_shim6_probe_sent = -1;
248 static gint ett_ipv6_shim6_probes_rcvd = -1;
249 static gint ett_ipv6_shim6_probe_rcvd = -1;
250 static gint ett_ipv6_shim6_cksum = -1;
251 static gint ett_ipv6_fragments = -1;
252 static gint ett_ipv6_fragment = -1;
253 static gint ett_ipv6_traffic_class = -1;
256 static gint ett_geoip_info = -1;
257 #endif /* HAVE_GEOIP_V6 */
260 static const fragment_items ipv6_frag_items = {
265 &hf_ipv6_fragment_overlap,
266 &hf_ipv6_fragment_overlap_conflict,
267 &hf_ipv6_fragment_multiple_tails,
268 &hf_ipv6_fragment_too_long_fragment,
269 &hf_ipv6_fragment_error,
270 &hf_ipv6_fragment_count,
271 &hf_ipv6_reassembled_in,
272 &hf_ipv6_reassembled_length,
276 static dissector_handle_t data_handle;
278 static dissector_table_t ip_dissector_table;
280 /* Reassemble fragmented datagrams */
281 static gboolean ipv6_reassemble = TRUE;
283 /* Place IPv6 summary in proto tree */
284 static gboolean ipv6_summary_in_tree = TRUE;
287 /* Look up addresses in GeoIP */
288 static gboolean ipv6_use_geoip = FALSE;
289 #endif /* HAVE_GEOIP_V6 */
292 #define offsetof(type, member) ((size_t)(&((type *)0)->member))
296 * defragmentation of IPv6
298 static GHashTable *ipv6_fragment_table = NULL;
299 static GHashTable *ipv6_reassembled_table = NULL;
302 capture_ipv6(const guchar *pd, int offset, int len, packet_counts *ld)
307 if (!BYTES_ARE_IN_FRAME(offset, len, 4+4+16+16)) {
311 nxt = pd[offset+6]; /* get the "next header" value */
312 offset += 4+4+16+16; /* skip past the IPv6 header */
316 case IP_PROTO_HOPOPTS:
317 case IP_PROTO_ROUTING:
318 case IP_PROTO_DSTOPTS:
319 if (!BYTES_ARE_IN_FRAME(offset, len, 2)) {
324 advance = (pd[offset+1] + 1) << 3;
325 if (!BYTES_ARE_IN_FRAME(offset, len, advance)) {
331 case IP_PROTO_FRAGMENT:
332 if (!BYTES_ARE_IN_FRAME(offset, len, 2)) {
338 if (!BYTES_ARE_IN_FRAME(offset, len, advance)) {
345 if (!BYTES_ARE_IN_FRAME(offset, len, 2)) {
350 advance = 8 + ((pd[offset+1] - 1) << 2);
351 if (!BYTES_ARE_IN_FRAME(offset, len, advance)) {
358 case IP_PROTO_SHIM6_OLD:
359 if (!BYTES_ARE_IN_FRAME(offset, len, 2)) {
364 advance = (pd[offset+1] + 1) << 3;
365 if (!BYTES_ARE_IN_FRAME(offset, len, advance)) {
381 case IP_PROTO_UDPLITE:
385 case IP_PROTO_ICMPV6: /* XXX - separate counters? */
404 add_geoip_info(proto_tree *tree, tvbuff_t *tvb, gint offset, struct e_in6_addr src, struct e_in6_addr dst)
406 guint dbnum, num_dbs;
407 int geoip_hf, geoip_src_hf, geoip_dst_hf;
408 const char *geoip_src_str, *geoip_dst_str;
409 proto_item *geoip_info_item;
410 proto_tree *geoip_info_tree;
414 num_dbs = geoip_db_num_dbs();
416 geoip_info_item = proto_tree_add_text(tree, tvb, offset + IP6H_SRC, 16, "Source GeoIP: ");
417 geoip_info_tree = proto_item_add_subtree(geoip_info_item, ett_geoip_info);
418 PROTO_ITEM_SET_GENERATED(geoip_info_item);
421 for (dbnum = 0; dbnum < num_dbs; dbnum++) {
422 geoip_src_str = geoip_db_lookup_ipv6(dbnum, src, NULL);
424 switch (geoip_db_type(dbnum)) {
425 case GEOIP_COUNTRY_EDITION_V6:
426 geoip_hf = hf_geoip_country;
427 geoip_src_hf = hf_geoip_src_country;
429 #if NUM_DB_TYPES > 31
430 case GEOIP_CITY_EDITION_REV0_V6:
431 geoip_hf = hf_geoip_city;
432 geoip_src_hf = hf_geoip_src_city;
434 case GEOIP_CITY_EDITION_REV1_V6:
435 geoip_hf = hf_geoip_city;
436 geoip_src_hf = hf_geoip_src_city;
438 case GEOIP_ORG_EDITION_V6:
439 geoip_hf = hf_geoip_org;
440 geoip_src_hf = hf_geoip_src_org;
442 case GEOIP_ISP_EDITION_V6:
443 geoip_hf = hf_geoip_isp;
444 geoip_src_hf = hf_geoip_src_isp;
446 case GEOIP_ASNUM_EDITION_V6:
447 geoip_hf = hf_geoip_asnum;
448 geoip_src_hf = hf_geoip_src_asnum;
450 #endif /* DB_NUM_TYPES */
451 case WS_LAT_FAKE_EDITION:
452 geoip_hf = hf_geoip_lat;
453 geoip_src_hf = hf_geoip_src_lat;
455 case WS_LON_FAKE_EDITION:
456 geoip_hf = hf_geoip_lon;
457 geoip_src_hf = hf_geoip_src_lon;
465 item = proto_tree_add_string_format_value(geoip_info_tree, geoip_src_hf, tvb,
466 offset + IP6H_SRC, 16, geoip_src_str, "%s", geoip_src_str);
467 PROTO_ITEM_SET_GENERATED(item);
468 item = proto_tree_add_string_format_value(geoip_info_tree, geoip_hf, tvb,
469 offset + IP6H_SRC, 16, geoip_src_str, "%s", geoip_src_str);
470 PROTO_ITEM_SET_GENERATED(item);
471 PROTO_ITEM_SET_HIDDEN(item);
474 proto_item_append_text(geoip_info_item, "%s%s", plurality(item_cnt, "", ", "), geoip_src_str);
479 proto_item_append_text(geoip_info_item, "Unknown");
481 geoip_info_item = proto_tree_add_text(tree, tvb, offset + IP6H_DST, 16, "Destination GeoIP: ");
482 geoip_info_tree = proto_item_add_subtree(geoip_info_item, ett_geoip_info);
483 PROTO_ITEM_SET_GENERATED(geoip_info_item);
486 for (dbnum = 0; dbnum < num_dbs; dbnum++) {
487 geoip_dst_str = geoip_db_lookup_ipv6(dbnum, dst, NULL);
489 switch (geoip_db_type(dbnum)) {
490 case GEOIP_COUNTRY_EDITION:
491 geoip_hf = hf_geoip_country;
492 geoip_dst_hf = hf_geoip_dst_country;
494 #if NUM_DB_TYPES > 31
495 case GEOIP_CITY_EDITION_REV0:
496 geoip_hf = hf_geoip_city;
497 geoip_dst_hf = hf_geoip_dst_city;
499 case GEOIP_CITY_EDITION_REV1:
500 geoip_hf = hf_geoip_city;
501 geoip_dst_hf = hf_geoip_dst_city;
503 case GEOIP_ORG_EDITION:
504 geoip_hf = hf_geoip_org;
505 geoip_dst_hf = hf_geoip_dst_org;
507 case GEOIP_ISP_EDITION:
508 geoip_hf = hf_geoip_isp;
509 geoip_dst_hf = hf_geoip_dst_isp;
511 case GEOIP_ASNUM_EDITION:
512 geoip_hf = hf_geoip_asnum;
513 geoip_dst_hf = hf_geoip_dst_asnum;
515 #endif /* DB_NUM_TYPES */
516 case WS_LAT_FAKE_EDITION:
517 geoip_hf = hf_geoip_lat;
518 geoip_dst_hf = hf_geoip_dst_lat;
520 case WS_LON_FAKE_EDITION:
521 geoip_hf = hf_geoip_lon;
522 geoip_dst_hf = hf_geoip_dst_lon;
530 item = proto_tree_add_string_format_value(geoip_info_tree, geoip_dst_hf, tvb,
531 offset + IP6H_DST, 16, geoip_dst_str, "%s", geoip_dst_str);
532 PROTO_ITEM_SET_GENERATED(item);
533 item = proto_tree_add_string_format_value(geoip_info_tree, geoip_hf, tvb,
534 offset + IP6H_DST, 16, geoip_dst_str, "%s", geoip_dst_str);
535 PROTO_ITEM_SET_GENERATED(item);
536 PROTO_ITEM_SET_HIDDEN(item);
539 proto_item_append_text(geoip_info_item, "%s%s", plurality(item_cnt, "", ", "), geoip_dst_str);
544 proto_item_append_text(geoip_info_item, "Unknown");
546 #endif /* HAVE_GEOIP_V6 */
549 ipv6_reassemble_init(void)
551 fragment_table_init(&ipv6_fragment_table);
552 reassembled_table_init(&ipv6_reassembled_table);
556 IPv6_RT_HEADER_SOURCE_ROUTING=0,
557 IPv6_RT_HEADER_NIMROD,
558 IPv6_RT_HEADER_MobileIP,
559 IPv6_RT_HEADER_RPL=4,
562 /* Routeing Header Types */
563 static const value_string routing_header_type[] = {
564 { IPv6_RT_HEADER_SOURCE_ROUTING, "IPv6 Source Routing" },
565 { IPv6_RT_HEADER_NIMROD, "Nimrod" },
566 { IPv6_RT_HEADER_MobileIP, "Mobile IP" },
567 { IPv6_RT_HEADER_RPL, "RPL" },
572 dissect_routing6(tvbuff_t *tvb, int offset, proto_tree *tree, packet_info *pinfo) {
575 proto_tree *rthdr_tree;
577 guint8 buf[sizeof(struct ip6_rthdr0) + sizeof(struct e_in6_addr) * 23];
579 tvb_memcpy(tvb, (guint8 *)&rt, offset, sizeof(rt));
580 len = (rt.ip6r_len + 1) << 3;
583 /* !!! specify length */
584 ti = proto_tree_add_uint_format(tree, hf_ipv6_routing_hdr_opt, tvb,
585 offset, len, rt.ip6r_type,
586 "Routing Header, Type : %s (%u)",
587 val_to_str(rt.ip6r_type, routing_header_type, "Unknown"),
589 rthdr_tree = proto_item_add_subtree(ti, ett_ipv6);
591 proto_tree_add_text(rthdr_tree, tvb,
592 offset + offsetof(struct ip6_rthdr, ip6r_nxt), 1,
593 "Next header: %s (0x%02x)", ipprotostr(rt.ip6r_nxt), rt.ip6r_nxt);
595 proto_tree_add_text(rthdr_tree, tvb,
596 offset + offsetof(struct ip6_rthdr, ip6r_len), 1,
597 "Length: %u (%d bytes)", rt.ip6r_len, len);
599 proto_tree_add_item(rthdr_tree, hf_ipv6_routing_hdr_type, tvb,
600 offset + offsetof(struct ip6_rthdr, ip6r_type), 1, FALSE);
602 proto_tree_add_item(rthdr_tree, hf_ipv6_routing_hdr_left, tvb,
603 offset + offsetof(struct ip6_rthdr, ip6r_segleft), 1, FALSE);
605 seg_left = tvb_get_guint8(tvb, offset + offsetof(struct ip6_rthdr, ip6r_segleft));
607 if (rt.ip6r_type == IPv6_RT_HEADER_SOURCE_ROUTING && len <= sizeof(buf)) {
608 struct e_in6_addr *a;
610 struct ip6_rthdr0 *rt0;
612 tvb_memcpy(tvb, buf, offset, len);
613 rt0 = (struct ip6_rthdr0 *)buf;
615 for (a = rt0->ip6r0_addr, n = 0;
616 a < (struct e_in6_addr *)(buf + len); a++, n++) {
618 proto_tree_add_item(rthdr_tree, hf_ipv6_routing_hdr_addr, tvb,
619 offset + offsetof(struct ip6_rthdr0, ip6r0_addr)
620 + n * sizeof(struct e_in6_addr),
621 sizeof(struct e_in6_addr), FALSE);
623 SET_ADDRESS(&pinfo->dst, AT_IPv6, 16, tvb_get_ptr(tvb,
624 offset + offsetof(struct ip6_rthdr0, ip6r0_addr)
625 + n * sizeof(struct e_in6_addr), 16));
628 if (rt.ip6r_type == IPv6_RT_HEADER_MobileIP) {
629 proto_tree_add_item(rthdr_tree, hf_ipv6_mipv6_home_address, tvb,
630 offset + 8, 16, FALSE);
631 SET_ADDRESS(&pinfo->dst, AT_IPv6, 16, tvb_get_ptr(tvb, offset + 8, 16));
633 if (rt.ip6r_type == IPv6_RT_HEADER_RPL) {
639 /* IPv6 destination address used for elided bytes */
640 struct e_in6_addr dstAddr;
642 memcpy((guint8 *)&dstAddr, (guint8 *)pinfo->dst.data, pinfo->dst.len);
644 proto_tree_add_item(rthdr_tree, hf_ipv6_routing_hdr_rpl_cmprI, tvb, offset, 4, FALSE);
645 proto_tree_add_item(rthdr_tree, hf_ipv6_routing_hdr_rpl_cmprE, tvb, offset, 4, FALSE);
646 proto_tree_add_item(rthdr_tree, hf_ipv6_routing_hdr_rpl_pad, tvb, offset, 4, FALSE);
647 proto_tree_add_item(rthdr_tree, hf_ipv6_routing_hdr_rpl_reserved, tvb, offset, 4, FALSE);
649 cmprI = tvb_get_guint8(tvb, offset) & 0xF0;
650 cmprE = tvb_get_guint8(tvb, offset) & 0x0F;
651 pad = tvb_get_guint8(tvb, offset + 1) & 0xF0;
653 /* Shift bytes over */
657 /* from draft-ietf-6man-rpl-routing-header-03:
658 n = (((Hdr Ext Len * 8) - Pad - (16 - CmprE)) / (16 - CmprI)) + 1 */
659 segments = (((rt.ip6r_len * 8) - pad - (16 - cmprE)) / (16 - cmprI)) + 1;
660 ti = proto_tree_add_int(rthdr_tree, hf_ipv6_routing_hdr_rpl_segments, tvb, offset, 2, segments);
661 PROTO_ITEM_SET_GENERATED(ti);
663 if ((segments < 0) || (segments > 136)) {
664 expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_ERROR, "Calculated total segments is invalid, 0 < %d < 136 fails", segments);
669 /* We use cmprI for internal (e.g.: not last) address for how many bytes to elide, so actual bytes present = 16-CmprI */
670 while(segments > 1) {
671 struct e_in6_addr addr;
673 proto_tree_add_item(rthdr_tree, hf_ipv6_routing_hdr_rpl_addr, tvb, offset, (16-cmprI), ENC_NA);
674 /* Display Full Address */
675 memcpy((guint8 *)&addr, (guint8 *)&dstAddr, sizeof(dstAddr));
676 tvb_memcpy(tvb, (guint8 *)&addr + cmprI, offset, (16-cmprI));
677 ti = proto_tree_add_ipv6(rthdr_tree, hf_ipv6_routing_hdr_rpl_fulladdr, tvb, offset, (16-cmprI), (guint8 *)&addr);
678 PROTO_ITEM_SET_GENERATED(ti);
679 offset += (16-cmprI);
683 /* We use cmprE for last address for how many bytes to elide, so actual bytes present = 16-CmprE */
685 struct e_in6_addr addr;
687 proto_tree_add_item(rthdr_tree, hf_ipv6_routing_hdr_rpl_addr, tvb, offset, (16-cmprI), ENC_NA);
688 /* Display Full Address */
689 memcpy((guint8 *)&addr, (guint8 *)&dstAddr, sizeof(dstAddr));
690 tvb_memcpy(tvb, (guint8 *)&addr + cmprE, offset, (16-cmprE));
691 ti = proto_tree_add_ipv6(rthdr_tree, hf_ipv6_routing_hdr_rpl_fulladdr, tvb, offset, (16-cmprE), (guint8 *)&addr);
692 PROTO_ITEM_SET_GENERATED(ti);
693 offset += (16-cmprE);
705 dissect_frag6(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree,
706 guint16 *offlg, guint32 *ident) {
707 struct ip6_frag frag;
710 proto_tree *rthdr_tree;
712 tvb_memcpy(tvb, (guint8 *)&frag, offset, sizeof(frag));
714 frag.ip6f_offlg = g_ntohs(frag.ip6f_offlg);
715 frag.ip6f_ident = g_ntohl(frag.ip6f_ident);
716 *offlg = frag.ip6f_offlg;
717 *ident = frag.ip6f_ident;
718 if (check_col(pinfo->cinfo, COL_INFO)) {
719 col_add_fstr(pinfo->cinfo, COL_INFO,
720 "IPv6 fragment (nxt=%s (0x%02x) off=%u id=0x%x)",
721 ipprotostr(frag.ip6f_nxt), frag.ip6f_nxt,
722 frag.ip6f_offlg & IP6F_OFF_MASK, frag.ip6f_ident);
725 ti = proto_tree_add_text(tree, tvb, offset, len,
726 "Fragmentation Header");
727 rthdr_tree = proto_item_add_subtree(ti, ett_ipv6);
729 proto_tree_add_text(rthdr_tree, tvb,
730 offset + offsetof(struct ip6_frag, ip6f_nxt), 1,
731 "Next header: %s (0x%02x)",
732 ipprotostr(frag.ip6f_nxt), frag.ip6f_nxt);
735 proto_tree_add_text(rthdr_tree, tvb,
736 offset + offsetof(struct ip6_frag, ip6f_reserved), 1,
741 proto_tree_add_item(rthdr_tree, hf_ipv6_frag_offset, tvb,
742 offset + offsetof(struct ip6_frag, ip6f_offlg), 2, FALSE);
744 proto_tree_add_item(rthdr_tree, hf_ipv6_frag_more, tvb,
745 offset + offsetof(struct ip6_frag, ip6f_offlg), 2, FALSE);
747 proto_tree_add_item(rthdr_tree, hf_ipv6_frag_id, tvb,
748 offset + offsetof(struct ip6_frag, ip6f_ident), 4, FALSE);
754 dissect_mipv6_hoa(tvbuff_t *tvb, proto_tree *dstopt_tree, int offset, packet_info *pinfo)
758 proto_tree_add_uint_format(dstopt_tree, hf_ipv6_mipv6_type, tvb,
760 tvb_get_guint8(tvb, offset + len),
761 "Option Type: %u (0x%02x) - Home Address Option",
762 tvb_get_guint8(tvb, offset + len),
763 tvb_get_guint8(tvb, offset + len));
766 proto_tree_add_uint(dstopt_tree, hf_ipv6_mipv6_length, tvb, offset + len,
767 1, tvb_get_guint8(tvb, offset + len));
770 proto_tree_add_item(dstopt_tree, hf_ipv6_mipv6_home_address, tvb,
771 offset + len, 16, ENC_NA);
772 SET_ADDRESS(&pinfo->src, AT_IPv6, 16, tvb_get_ptr(tvb, offset + len, 16));
777 static const value_string rtalertvals[] = {
778 { IP6OPT_RTALERT_MLD, "MLD" },
779 { IP6OPT_RTALERT_RSVP, "RSVP" },
783 /* Like "dissect_ip_tcp_options()", but assumes the length of an option
784 *doesn't* include the type and length bytes. */
786 dissect_ipv6_options(tvbuff_t *tvb, int offset, guint length,
787 const ip_tcp_opt *opttab, int nopts, int eol,
788 packet_info *pinfo, proto_tree *opt_tree)
791 const ip_tcp_opt *optp;
792 opt_len_type len_type;
795 char name_str[7+1+1+2+2+1+1]; /* "Unknown (0x%02x)" */
796 void (*dissect)(const struct ip_tcp_opt *, tvbuff_t *,
797 int, guint, packet_info *, proto_tree *);
801 opt = tvb_get_guint8(tvb, offset);
802 for (optp = &opttab[0]; optp < &opttab[nopts]; optp++) {
803 if (optp->optcode == opt)
806 if (optp == &opttab[nopts]) {
807 /* We assume that the only NO_LENGTH options are Pad1 options,
808 so that we can treat unknown options as VARIABLE_LENGTH with a
809 minimum of 0, and at least be able to move on to the next option
810 by using the length in the option. */
811 optp = NULL; /* indicate that we don't know this option */
812 len_type = VARIABLE_LENGTH;
814 g_snprintf(name_str, sizeof name_str, "Unknown (0x%02x)", opt);
818 len_type = optp->len_type;
819 optlen = optp->optlen;
821 dissect = optp->dissect;
823 --length; /* account for type byte */
824 if (len_type != NO_LENGTH) {
825 /* Option has a length. Is it in the packet? */
827 /* Bogus - packet must at least include option code byte and
829 proto_tree_add_text(opt_tree, tvb, offset, 1,
830 "%s (length byte past end of options)", name);
833 len = tvb_get_guint8(tvb, offset + 1); /* total including type, len */
834 --length; /* account for length byte */
836 /* Bogus - option goes past the end of the header. */
837 proto_tree_add_text(opt_tree, tvb, offset, length,
838 "%s (option length = %u byte%s says option goes past end of options)",
839 name, len, plurality(len, "", "s"));
841 } else if (len_type == FIXED_LENGTH && len != optlen) {
842 /* Bogus - option length isn't what it's supposed to be for this
844 proto_tree_add_text(opt_tree, tvb, offset, 2 + len,
845 "%s (with option length = %u byte%s; should be %u)", name,
846 len, plurality(len, "", "s"), optlen);
848 } else if (len_type == VARIABLE_LENGTH && len < optlen) {
849 /* Bogus - option length is less than what it's supposed to be for
851 proto_tree_add_text(opt_tree, tvb, offset, 2 + len,
852 "%s (with option length = %u byte%s; should be >= %u)", name,
853 len, plurality(len, "", "s"), optlen);
857 proto_tree_add_text(opt_tree, tvb, offset, 2 + len, "%s (%u byte%s)",
858 name, len, plurality(len, "", "s"));
860 if (dissect != NULL) {
861 /* Option has a dissector. */
862 (*dissect)(optp, tvb, offset, 2 + len, pinfo, opt_tree);
864 /* Option has no data, hence no dissector. */
865 proto_tree_add_text(opt_tree, tvb, offset, 2 + len, "%s", name);
872 proto_tree_add_text(opt_tree, tvb, offset, 1, "%s", name);
881 dissect_unknown_option(tvbuff_t *tvb, int offset, proto_tree *tree)
885 proto_tree *unkopt_tree;
888 tvb_memcpy(tvb, (guint8 *)&ext, offset, sizeof(ext));
889 len = (ext.ip6e_len + 1) << 3;
892 /* !!! specify length */
893 ti = proto_tree_add_item(tree, hf_ipv6_unk_hdr, tvb, offset, len, ENC_NA);
895 unkopt_tree = proto_item_add_subtree(ti, ett_ipv6);
897 proto_tree_add_text(unkopt_tree, tvb,
898 offset + offsetof(struct ip6_ext, ip6e_nxt), 1,
899 "Next header: %s (0x%02x)", ipprotostr(ext.ip6e_nxt), ext.ip6e_nxt);
901 proto_tree_add_text(unkopt_tree, tvb,
902 offset + offsetof(struct ip6_ext, ip6e_len), 1,
903 "Length: %u (%d bytes)", ext.ip6e_len, len);
909 dissect_opts(tvbuff_t *tvb, int offset, proto_tree *tree, packet_info * pinfo, const int hf_option_item)
913 proto_tree *dstopt_tree;
917 int mip_offset = 0, delta = 0;
919 tvb_memcpy(tvb, (guint8 *)&ext, offset, sizeof(ext));
920 len = (ext.ip6e_len + 1) << 3;
923 /* !!! specify length */
924 ti = proto_tree_add_item(tree, hf_option_item, tvb, offset, len, FALSE);
926 dstopt_tree = proto_item_add_subtree(ti, ett_ipv6);
928 proto_tree_add_text(dstopt_tree, tvb,
929 offset + offsetof(struct ip6_ext, ip6e_nxt), 1,
930 "Next header: %s (0x%02x)", ipprotostr(ext.ip6e_nxt), ext.ip6e_nxt);
932 proto_tree_add_text(dstopt_tree, tvb,
933 offset + offsetof(struct ip6_ext, ip6e_len), 1,
934 "Length: %u (%d bytes)", ext.ip6e_len, len);
941 while (p < offset + len) {
942 switch (tvb_get_guint8(tvb, p)) {
944 proto_tree_add_item(dstopt_tree, hf_ipv6_opt_pad1, tvb, p, 1, ENC_NA);
950 * "The PadN option is used to insert two or more octets of
951 * padding into the Options area of a header. For N octets of
952 * padding, the Opt Data Len field contains the value N-2, and
953 * the Option Data consists of N-2 zero-valued octets."
955 tmp = tvb_get_guint8(tvb, p + 1);
956 proto_tree_add_uint_format(dstopt_tree, hf_ipv6_opt_padn, tvb,
958 "PadN: %u bytes", tmp + 2);
960 mip_offset += tvb_get_guint8(tvb, mip_offset + 1) + 2;
963 tmp = tvb_get_guint8(tvb, p + 1);
965 proto_tree_add_text(dstopt_tree, tvb, p, tmp + 2,
966 "Jumbo payload: %u (%u bytes)",
967 tvb_get_ntohl(tvb, p + 2), tmp + 2);
969 ti = proto_tree_add_text(dstopt_tree, tvb, p, tmp + 2,
970 "Jumbo payload: Invalid length (%u bytes)", tmp);
971 expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_ERROR,
972 "Jumbo payload: Invalid length (%u bytes)", tmp);
975 mip_offset += tvb_get_guint8(tvb, mip_offset+1)+2;
979 tmp = tvb_get_guint8(tvb, p + 1);
981 proto_tree_add_text(dstopt_tree, tvb, p , tmp + 2,
982 "Router alert: %s (%u bytes)",
983 val_to_str(tvb_get_ntohs(tvb, p + 2),
984 rtalertvals, "Unknown"),
987 ti = proto_tree_add_text(dstopt_tree, tvb, p , tmp + 2,
988 "Router alert: Invalid Length (%u bytes)",
990 expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_ERROR,
991 "Router alert: Invalid Length (%u bytes)",
996 mip_offset += tvb_get_guint8(tvb, mip_offset + 1) + 2;
999 case IP6OPT_HOME_ADDRESS:
1000 delta = dissect_mipv6_hoa(tvb, dstopt_tree, mip_offset, pinfo);
1002 mip_offset += delta;
1016 dissect_hopopts(tvbuff_t *tvb, int offset, proto_tree *tree, packet_info * pinfo)
1018 return dissect_opts(tvb, offset, tree, pinfo, hf_ipv6_hop_opt);
1022 dissect_dstopts(tvbuff_t *tvb, int offset, proto_tree *tree, packet_info * pinfo)
1024 return dissect_opts(tvb, offset, tree, pinfo, hf_ipv6_dst_opt);
1027 /* START SHIM6 PART */
1028 static guint16 shim_checksum(const guint8 *ptr, int len)
1032 cksum_vec[0].ptr = ptr;
1033 cksum_vec[0].len = len;
1034 return in_cksum(&cksum_vec[0], 1);
1038 dissect_shim_hex(tvbuff_t *tvb, int offset, int len, const char *itemname, guint8 bitmask, proto_tree *tree)
1046 ti = proto_tree_add_text(tree, tvb, offset, len, "%s", itemname);
1048 proto_item_append_text(ti, " 0x%02x", tvb_get_guint8(tvb, p) & bitmask);
1049 for (count=1; count<len; count++)
1050 proto_item_append_text(ti, "%02x", tvb_get_guint8(tvb, p+count));
1055 static const value_string shimoptvals[] = {
1056 { SHIM6_OPT_RESPVAL, "Responder Validator Option" },
1057 { SHIM6_OPT_LOCLIST, "Locator List Option" },
1058 { SHIM6_OPT_LOCPREF, "Locator Preferences Option" },
1059 { SHIM6_OPT_CGAPDM, "CGA Parameter Data Structure Option" },
1060 { SHIM6_OPT_CGASIG, "CGA Signature Option" },
1061 { SHIM6_OPT_ULIDPAIR, "ULID Pair Option" },
1062 { SHIM6_OPT_FII, "Forked Instance Identifier Option" },
1066 static const value_string shimverifmethods[] = {
1067 { SHIM6_VERIF_HBA, "HBA" },
1068 { SHIM6_VERIF_CGA, "CGA" },
1072 static const value_string shimflags[] _U_ = {
1073 { SHIM6_FLAG_BROKEN, "BROKEN" },
1074 { SHIM6_FLAG_TEMPORARY, "TEMPORARY" },
1078 static const value_string shimreapstates[] = {
1079 { SHIM6_REAP_OPERATIONAL, "Operational" },
1080 { SHIM6_REAP_EXPLORING, "Exploring" },
1081 { SHIM6_REAP_INBOUNDOK, "InboundOK" },
1085 static const value_string shim6_protocol[] = {
1091 static const value_string dscp_vals[] = {
1092 { IPDSFIELD_DSCP_DEFAULT, "Default" },
1093 { IPDSFIELD_DSCP_CS1, "Class Selector 1" },
1094 { IPDSFIELD_DSCP_CS2, "Class Selector 2" },
1095 { IPDSFIELD_DSCP_CS3, "Class Selector 3" },
1096 { IPDSFIELD_DSCP_CS4, "Class Selector 4" },
1097 { IPDSFIELD_DSCP_CS5, "Class Selector 5" },
1098 { IPDSFIELD_DSCP_CS6, "Class Selector 6" },
1099 { IPDSFIELD_DSCP_CS7, "Class Selector 7" },
1100 { IPDSFIELD_DSCP_AF11, "Assured Forwarding 11" },
1101 { IPDSFIELD_DSCP_AF12, "Assured Forwarding 12" },
1102 { IPDSFIELD_DSCP_AF13, "Assured Forwarding 13" },
1103 { IPDSFIELD_DSCP_AF21, "Assured Forwarding 21" },
1104 { IPDSFIELD_DSCP_AF22, "Assured Forwarding 22" },
1105 { IPDSFIELD_DSCP_AF23, "Assured Forwarding 23" },
1106 { IPDSFIELD_DSCP_AF31, "Assured Forwarding 31" },
1107 { IPDSFIELD_DSCP_AF32, "Assured Forwarding 32" },
1108 { IPDSFIELD_DSCP_AF33, "Assured Forwarding 33" },
1109 { IPDSFIELD_DSCP_AF41, "Assured Forwarding 41" },
1110 { IPDSFIELD_DSCP_AF42, "Assured Forwarding 42" },
1111 { IPDSFIELD_DSCP_AF43, "Assured Forwarding 43" },
1112 { IPDSFIELD_DSCP_EF, "Expedited Forwarding" },
1116 dissect_shim6_opt_loclist(proto_tree * opt_tree, tvbuff_t * tvb, gint *offset)
1119 proto_tree * subtree;
1124 proto_tree_add_item(opt_tree, hf_ipv6_shim6_opt_loclist, tvb, p, 4, FALSE);
1127 optlen = tvb_get_guint8(tvb, p);
1128 proto_tree_add_item(opt_tree, hf_ipv6_shim6_opt_locnum, tvb, p, 1, FALSE);
1131 /* Verification Methods */
1132 it = proto_tree_add_text(opt_tree, tvb, p, optlen,
1133 "Locator Verification Methods");
1134 subtree = proto_item_add_subtree(it, ett_ipv6_shim6_verif_methods);
1136 for (count=0; count < optlen; count++)
1137 proto_tree_add_item(subtree, hf_ipv6_shim6_opt_loc_verif_methods, tvb,
1141 /* Padding, included in length field */
1142 if ((7 - optlen % 8) > 0) {
1143 proto_tree_add_text(opt_tree, tvb, p, (7 - optlen % 8), "Padding");
1144 p += (7 - optlen % 8);
1148 it = proto_tree_add_text(opt_tree, tvb, p, 16 * optlen, "Locators");
1149 subtree = proto_item_add_subtree(it, ett_ipv6_shim6_locators);
1151 for (count=0; count < optlen; count++) {
1152 proto_tree_add_item(subtree, hf_ipv6_shim6_locator, tvb, p, 16, FALSE);
1159 dissect_shim6_opt_loc_pref(proto_tree * opt_tree, tvbuff_t * tvb, gint *offset, gint len, packet_info *pinfo)
1161 proto_tree * subtree;
1170 proto_tree_add_item(opt_tree, hf_ipv6_shim6_opt_loclist, tvb, p, 4, FALSE);
1173 optlen = tvb_get_guint8(tvb, p);
1174 proto_tree_add_item(opt_tree, hf_ipv6_shim6_opt_elemlen, tvb, p, 1, FALSE);
1176 if (optlen < 1 || optlen > 3) {
1177 it = proto_tree_add_text(opt_tree, tvb, p, 1,
1178 "Invalid element length: %u", optlen);
1179 expert_add_info_format(pinfo, it, PI_MALFORMED, PI_ERROR,
1180 "Invalid element length: %u", optlen);
1186 /* Locator Preferences */
1189 it = proto_tree_add_text(opt_tree, tvb, p, optlen, "Locator Preferences %u", count);
1190 subtree = proto_item_add_subtree(it, ett_ipv6_shim6_loc_pref);
1194 proto_tree_add_item(subtree, hf_ipv6_shim6_loc_flag, tvb, p, 1, FALSE);
1197 proto_tree_add_item(subtree, hf_ipv6_shim6_loc_prio, tvb, p+1, 1, FALSE);
1200 proto_tree_add_item(subtree, hf_ipv6_shim6_loc_weight, tvb, p+2, 1, FALSE);
1202 * Shim6 Draft 08 doesn't specify the format when the Element length is
1203 * more than three, except that any such formats MUST be defined so that
1204 * the first three octets are the same as in the above case, that is, a
1205 * of a 1 octet flags field followed by a 1 octet priority field, and a
1206 * 1 octet weight field.
1216 dissect_shimopts(tvbuff_t *tvb, int offset, proto_tree *tree, packet_info *pinfo)
1221 proto_tree *opt_tree;
1230 len = tvb_get_ntohs(tvb, offset+2);
1231 padding = 7 - ((len + 3) % 8);
1232 total_len = 4 + len + padding;
1237 ctype = val_to_str( (tvb_get_ntohs(tvb, offset) & SHIM6_BITMASK_OPT_TYPE) >> 1, shimoptvals, "Unknown Option Type");
1238 ti = proto_tree_add_text(tree, tvb, offset, total_len, "%s", ctype);
1239 opt_tree = proto_item_add_subtree(ti, ett_ipv6_shim6_option);
1241 proto_tree_add_item(opt_tree, hf_ipv6_shim6_opt_type, tvb, offset, 2, FALSE);
1244 proto_tree_add_item(opt_tree, hf_ipv6_shim6_opt_critical, tvb, offset+1, 1, FALSE);
1246 /* Content Length */
1247 proto_tree_add_item(opt_tree, hf_ipv6_shim6_opt_len, tvb, offset + 2, 2, FALSE);
1248 ti = proto_tree_add_uint_format(opt_tree, hf_ipv6_shim6_opt_total_len, tvb, offset+2, 2,
1249 total_len, "Total Length: %u", total_len);
1250 PROTO_ITEM_SET_GENERATED(ti);
1252 /* Option Type Specific */
1253 switch (tvb_get_ntohs(tvb, offset) >> 1)
1255 case SHIM6_OPT_RESPVAL:
1256 p += dissect_shim_hex(tvb, p, len, "Validator:", 0xff, opt_tree);
1257 if (total_len-(len+4) > 0)
1258 proto_tree_add_text(opt_tree, tvb, p, total_len-(len+4), "Padding");
1260 case SHIM6_OPT_LOCLIST:
1261 dissect_shim6_opt_loclist(opt_tree, tvb, &p);
1263 case SHIM6_OPT_LOCPREF:
1264 dissect_shim6_opt_loc_pref(opt_tree, tvb, &p, offset+len+4, pinfo);
1265 if (total_len-(len+4) > 0)
1266 proto_tree_add_text(opt_tree, tvb, p, total_len-(len+4), "Padding");
1268 case SHIM6_OPT_CGAPDM:
1269 p += dissect_shim_hex(tvb, p, len, "CGA Parameter Data Structure:", 0xff, opt_tree);
1270 if (total_len-(len+4) > 0)
1271 proto_tree_add_text(opt_tree, tvb, p, total_len-(len+4), "Padding");
1273 case SHIM6_OPT_CGASIG:
1274 p += dissect_shim_hex(tvb, p, len, "CGA Signature:", 0xff, opt_tree);
1275 if (total_len-(len+4) > 0)
1276 proto_tree_add_text(opt_tree, tvb, p, total_len-(len+4), "Padding");
1278 case SHIM6_OPT_ULIDPAIR:
1279 proto_tree_add_text(opt_tree, tvb, p, 4, "Reserved");
1281 proto_tree_add_item(opt_tree, hf_ipv6_shim6_sulid, tvb, p, 16, FALSE);
1283 proto_tree_add_item(opt_tree, hf_ipv6_shim6_rulid, tvb, p, 16, FALSE);
1287 proto_tree_add_item(opt_tree, hf_ipv6_shim6_opt_fii, tvb, p, 4, FALSE);
1298 dissect_shim6_ct(proto_tree * shim_tree, gint hf_item, tvbuff_t * tvb, gint offset, const guchar * label)
1303 tmp[0] = tvb_get_guint8(tvb, offset++);
1304 tmp[1] = tvb_get_guint8(tvb, offset++);
1305 tmp[2] = tvb_get_guint8(tvb, offset++);
1306 tmp[3] = tvb_get_guint8(tvb, offset++);
1307 tmp[4] = tvb_get_guint8(tvb, offset++);
1308 tmp[5] = tvb_get_guint8(tvb, offset++);
1310 ct_str = ep_strdup_printf("%s: %02X %02X %02X %02X %02X %02X", label,
1311 tmp[0] & SHIM6_BITMASK_CT, tmp[1], tmp[2],
1312 tmp[3], tmp[4], tmp[5]
1314 proto_tree_add_none_format(shim_tree, hf_item, tvb, offset - 6, 6, "%s", ct_str);
1318 dissect_shim6_probes(proto_tree * shim_tree, tvbuff_t * tvb, gint offset,
1319 const guchar * label, guint nbr_probe,
1320 gboolean probes_rcvd)
1322 proto_tree * probes_tree;
1323 proto_tree * probe_tree;
1330 ett_probes = ett_ipv6_shim6_probes_rcvd;
1331 ett_probe = ett_ipv6_shim6_probe_rcvd;
1333 ett_probes = ett_ipv6_shim6_probes_sent;
1334 ett_probe = ett_ipv6_shim6_probe_sent;
1336 it = proto_tree_add_text(shim_tree, tvb, offset, 40 * nbr_probe, "%s", label);
1337 probes_tree = proto_item_add_subtree(it, ett_probes);
1339 for (count=0; count < nbr_probe; count++) {
1340 it = proto_tree_add_text(probes_tree, tvb, offset, 40, "Probe %u", count+1);
1341 probe_tree = proto_item_add_subtree(it, ett_probe);
1343 proto_tree_add_item(probe_tree, hf_ipv6_shim6_psrc, tvb, offset, 16, FALSE);
1345 proto_tree_add_item(probe_tree, hf_ipv6_shim6_pdst, tvb, offset, 16, FALSE);
1348 proto_tree_add_item(probe_tree, hf_ipv6_shim6_pnonce, tvb, offset, 4, FALSE);
1351 proto_tree_add_item(probe_tree, hf_ipv6_shim6_pdata, tvb, offset, 4, FALSE);
1356 /* Dissect SHIM6 data: control messages */
1358 dissect_shimctrl(tvbuff_t *tvb, gint offset, guint type, proto_tree *shim_tree)
1371 dissect_shim6_ct(shim_tree, hf_ipv6_shim6_ct, tvb, p, "Initiator Context Tag");
1373 proto_tree_add_item(shim_tree, hf_ipv6_shim6_inonce, tvb, p, 4, FALSE);
1377 proto_tree_add_text(shim_tree, tvb, p, 2, "Reserved2");
1379 proto_tree_add_item(shim_tree, hf_ipv6_shim6_inonce, tvb, p, 4, FALSE);
1381 proto_tree_add_item(shim_tree, hf_ipv6_shim6_rnonce, tvb, p, 4, FALSE);
1385 dissect_shim6_ct(shim_tree, hf_ipv6_shim6_ct, tvb, p, "Initiator Context Tag");
1387 proto_tree_add_item(shim_tree, hf_ipv6_shim6_inonce, tvb, p, 4, FALSE);
1389 proto_tree_add_item(shim_tree, hf_ipv6_shim6_rnonce, tvb, p, 4, FALSE);
1391 proto_tree_add_text(shim_tree, tvb, p, 4, "Reserved2");
1395 dissect_shim6_ct(shim_tree, hf_ipv6_shim6_ct, tvb, p, "Responder Context Tag");
1397 proto_tree_add_item(shim_tree, hf_ipv6_shim6_inonce, tvb, p, 4, FALSE);
1400 case SHIM6_TYPE_R1BIS:
1401 dissect_shim6_ct(shim_tree, hf_ipv6_shim6_ct, tvb, p, "Packet Context Tag");
1403 proto_tree_add_item(shim_tree, hf_ipv6_shim6_rnonce, tvb, p, 4, FALSE);
1406 case SHIM6_TYPE_I2BIS:
1407 dissect_shim6_ct(shim_tree, hf_ipv6_shim6_ct, tvb, p, "Initiator Context Tag");
1409 proto_tree_add_item(shim_tree, hf_ipv6_shim6_inonce, tvb, p, 4, FALSE);
1411 proto_tree_add_item(shim_tree, hf_ipv6_shim6_rnonce, tvb, p, 4, FALSE);
1413 proto_tree_add_text(shim_tree, tvb, p, 6, "Reserved2");
1415 dissect_shim6_ct(shim_tree, hf_ipv6_shim6_ct, tvb, p, "Initiator Context Tag");
1418 case SHIM6_TYPE_UPD_REQ:
1419 case SHIM6_TYPE_UPD_ACK:
1420 dissect_shim6_ct(shim_tree, hf_ipv6_shim6_ct, tvb, p, "Receiver Context Tag");
1422 proto_tree_add_item(shim_tree, hf_ipv6_shim6_rnonce, tvb, p, 4, FALSE);
1425 case SHIM6_TYPE_KEEPALIVE:
1426 dissect_shim6_ct(shim_tree, hf_ipv6_shim6_ct, tvb, p, "Receiver Context Tag");
1428 proto_tree_add_text(shim_tree, tvb, p, 4, "Reserved2");
1431 case SHIM6_TYPE_PROBE:
1432 dissect_shim6_ct(shim_tree, hf_ipv6_shim6_ct, tvb, p, "Receiver Context Tag");
1435 tmp = tvb_get_guint8(tvb, p);
1436 probes_sent = tmp & SHIM6_BITMASK_PSENT;
1437 probes_rcvd = (tmp & SHIM6_BITMASK_PRECVD) >> 4;
1439 proto_tree_add_uint_format(shim_tree, hf_ipv6_shim6_psent, tvb,
1441 "Probes Sent: %u", probes_sent);
1442 proto_tree_add_uint_format(shim_tree, hf_ipv6_shim6_precvd, tvb,
1444 "Probes Received: %u", probes_rcvd);
1447 sta = val_to_str((tvb_get_guint8(tvb, p) & SHIM6_BITMASK_STA) >> 6,
1448 shimreapstates, "Unknown REAP State");
1449 proto_tree_add_uint_format(shim_tree, hf_ipv6_shim6_reap, tvb,
1450 p, 1, (tvb_get_guint8(tvb, p) & SHIM6_BITMASK_STA) >> 6,
1451 "REAP State: %s", sta);
1453 proto_tree_add_text(shim_tree, tvb, p, 3, "Reserved2");
1458 dissect_shim6_probes(shim_tree, tvb, p, "Probes Sent",
1459 probes_sent, FALSE);
1460 p += 40 * probes_sent;
1463 /* Probes Received */
1465 dissect_shim6_probes(shim_tree, tvb, p, "Probes Received",
1467 p += 40 * probes_rcvd;
1476 /* Dissect SHIM6 data: payload, common part, options */
1477 static const value_string shimctrlvals[] = {
1478 { SHIM6_TYPE_I1, "I1" },
1479 { SHIM6_TYPE_R1, "R1" },
1480 { SHIM6_TYPE_I2, "I2" },
1481 { SHIM6_TYPE_R2, "R2" },
1482 { SHIM6_TYPE_R1BIS, "R1bis" },
1483 { SHIM6_TYPE_I2BIS, "I2bis" },
1484 { SHIM6_TYPE_UPD_REQ, "Update Request" },
1485 { SHIM6_TYPE_UPD_ACK, "Update Acknowledgement" },
1486 { SHIM6_TYPE_KEEPALIVE, "Keepalive" },
1487 { SHIM6_TYPE_PROBE, "Probe" },
1491 static void ipv6_shim6_checkum_additional_info(tvbuff_t * tvb, packet_info * pinfo,
1492 proto_item * it_cksum, int offset, gboolean is_cksum_correct)
1494 proto_tree * checksum_tree;
1497 checksum_tree = proto_item_add_subtree(it_cksum, ett_ipv6_shim6_cksum);
1498 item = proto_tree_add_boolean(checksum_tree, hf_ipv6_shim6_checksum_good, tvb,
1499 offset, 2, is_cksum_correct);
1500 PROTO_ITEM_SET_GENERATED(item);
1501 item = proto_tree_add_boolean(checksum_tree, hf_ipv6_shim6_checksum_bad, tvb,
1502 offset, 2, !is_cksum_correct);
1503 PROTO_ITEM_SET_GENERATED(item);
1504 if (!is_cksum_correct) {
1505 expert_add_info_format(pinfo, item, PI_CHECKSUM, PI_ERROR, "Bad checksum");
1506 col_append_str(pinfo->cinfo, COL_INFO, " [Shim6 CHECKSUM INCORRECT]");
1511 dissect_shim6(tvbuff_t *tvb, int offset, proto_tree *tree, packet_info * pinfo)
1513 struct ip6_shim shim;
1516 proto_tree *shim_tree;
1520 tvb_memcpy(tvb, (guint8 *)&shim, offset, sizeof(shim));
1521 len = (shim.ip6s_len + 1) << 3;
1525 ti = proto_tree_add_item(tree, hf_ipv6_shim6, tvb, offset, len, ENC_NA);
1526 shim_tree = proto_item_add_subtree(ti, ett_ipv6_shim6);
1529 proto_tree_add_uint_format(shim_tree, hf_ipv6_shim6_nxt, tvb,
1530 offset + offsetof(struct ip6_shim, ip6s_nxt), 1, shim.ip6s_nxt,
1531 "Next header: %s (0x%02x)", ipprotostr(shim.ip6s_nxt), shim.ip6s_nxt);
1533 /* Header Extension Length */
1534 proto_tree_add_uint_format(shim_tree, hf_ipv6_shim6_len, tvb,
1535 offset + offsetof(struct ip6_shim, ip6s_len), 1, shim.ip6s_len,
1536 "Header Ext Length: %u (%d bytes)", shim.ip6s_len, len);
1539 proto_tree_add_item(shim_tree, hf_ipv6_shim6_p, tvb,
1540 offset + offsetof(struct ip6_shim, ip6s_p), 1, FALSE);
1542 /* skip the first 2 bytes (nxt hdr, hdr ext len, p+7bits) */
1545 if (shim.ip6s_p & SHIM6_BITMASK_P)
1547 tmp[0] = tvb_get_guint8(tvb, p++);
1548 tmp[1] = tvb_get_guint8(tvb, p++);
1549 tmp[2] = tvb_get_guint8(tvb, p++);
1550 tmp[3] = tvb_get_guint8(tvb, p++);
1551 tmp[4] = tvb_get_guint8(tvb, p++);
1553 /* Payload Extension Header */
1554 proto_tree_add_none_format(shim_tree, hf_ipv6_shim6_ct, tvb,
1555 offset + offsetof(struct ip6_shim, ip6s_p), 6,
1556 "Receiver Context Tag: %02x %02x %02x %02x %02x %02x",
1557 shim.ip6s_p & SHIM6_BITMASK_CT, tmp[0], tmp[1], tmp[2], tmp[3], tmp[4]);
1561 /* Control Message */
1566 proto_tree_add_item(shim_tree, hf_ipv6_shim6_type, tvb,
1567 offset + offsetof(struct ip6_shim, ip6s_p), 1,
1571 /* Protocol bit (Must be zero for SHIM6) */
1572 proto_tree_add_item(shim_tree, hf_ipv6_shim6_proto, tvb, p, 1, FALSE);
1576 csum = shim_checksum(tvb_get_ptr(tvb, offset, len), len);
1579 ti = proto_tree_add_uint_format(shim_tree, hf_ipv6_shim6_checksum, tvb, p, 2,
1580 tvb_get_ntohs(tvb, p), "Checksum: 0x%04x [correct]", tvb_get_ntohs(tvb, p));
1581 ipv6_shim6_checkum_additional_info(tvb, pinfo, ti, p, TRUE);
1583 ti = proto_tree_add_uint_format(shim_tree, hf_ipv6_shim6_checksum, tvb, p, 2,
1584 tvb_get_ntohs(tvb, p), "Checksum: 0x%04x [incorrect: should be 0x%04x]",
1585 tvb_get_ntohs(tvb, p), in_cksum_shouldbe(tvb_get_ntohs(tvb, p), csum));
1586 ipv6_shim6_checkum_additional_info(tvb, pinfo, ti, p, FALSE);
1590 /* Type specific data */
1591 advance = dissect_shimctrl(tvb, p, shim.ip6s_p & SHIM6_BITMASK_TYPE, shim_tree);
1595 while (p < offset+len) {
1596 p += dissect_shimopts(tvb, p, shim_tree, pinfo);
1603 /* END SHIM6 PART */
1606 dissect_ipv6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1608 proto_tree *ipv6_tree = NULL;
1609 proto_item *ipv6_item = NULL, *ti;
1615 gboolean hopopts, routing, frag, ah, shim6, dstopts;
1619 fragment_data *ipfd_head;
1621 gboolean update_col_info = TRUE;
1622 gboolean save_fragmented = FALSE;
1623 const char *sep = "IPv6 ";
1626 struct ip6_hdr ipv6;
1628 col_set_str(pinfo->cinfo, COL_PROTOCOL, "IPv6");
1629 col_clear(pinfo->cinfo, COL_INFO);
1632 tvb_memcpy(tvb, (guint8 *)&ipv6, offset, sizeof(ipv6));
1634 /* Get extension header and payload length */
1635 plen = g_ntohs(ipv6.ip6_plen);
1637 /* Adjust the length of this tvbuff to include only the IPv6 datagram. */
1638 set_actual_length(tvb, plen + sizeof (struct ip6_hdr));
1640 SET_ADDRESS(&pinfo->net_src, AT_IPv6, 16, tvb_get_ptr(tvb, offset + IP6H_SRC, 16));
1641 SET_ADDRESS(&pinfo->src, AT_IPv6, 16, tvb_get_ptr(tvb, offset + IP6H_SRC, 16));
1642 SET_ADDRESS(&pinfo->net_dst, AT_IPv6, 16, tvb_get_ptr(tvb, offset + IP6H_DST, 16));
1643 SET_ADDRESS(&pinfo->dst, AT_IPv6, 16, tvb_get_ptr(tvb, offset + IP6H_DST, 16));
1648 proto_tree *ipv6_tc_tree;
1649 proto_item *ipv6_tc;
1652 ipv6_item = proto_tree_add_item(tree, proto_ipv6, tvb, offset, -1, FALSE);
1653 ipv6_tree = proto_item_add_subtree(ipv6_item, ett_ipv6);
1655 /* !!! warning: (4-bit) version, (6-bit) DSCP, (1-bit) ECN-ECT, (1-bit) ECN-CE and (20-bit) Flow */
1656 pi = proto_tree_add_item(ipv6_tree, hf_ipv6_version, tvb,
1657 offset + offsetof(struct ip6_hdr, ip6_vfc), 1, FALSE);
1658 pt = proto_item_add_subtree(pi,ett_ipv6_version);
1659 pi = proto_tree_add_item(pt, hf_ip_version, tvb,
1660 offset + offsetof(struct ip6_hdr, ip6_vfc), 1, FALSE);
1661 PROTO_ITEM_SET_GENERATED(pi);
1663 ipv6_tc = proto_tree_add_item(ipv6_tree, hf_ipv6_class, tvb,
1664 offset + offsetof(struct ip6_hdr, ip6_flow), 4, FALSE);
1666 ipv6_tc_tree = proto_item_add_subtree(ipv6_tc, ett_ipv6_traffic_class);
1668 proto_tree_add_item(ipv6_tc_tree, hf_ipv6_traffic_class_dscp, tvb,
1669 offset + offsetof(struct ip6_hdr, ip6_flow), 4, FALSE);
1671 proto_tree_add_item(ipv6_tc_tree, hf_ipv6_traffic_class_ect, tvb,
1672 offset + offsetof(struct ip6_hdr, ip6_flow), 4, FALSE);
1674 proto_tree_add_item(ipv6_tc_tree, hf_ipv6_traffic_class_ce, tvb,
1675 offset + offsetof(struct ip6_hdr, ip6_flow), 4, FALSE);
1677 proto_tree_add_item(ipv6_tree, hf_ipv6_flow, tvb,
1678 offset + offsetof(struct ip6_hdr, ip6_flow), 4, FALSE);
1680 proto_tree_add_item(ipv6_tree, hf_ipv6_plen, tvb,
1681 offset + offsetof(struct ip6_hdr, ip6_plen), 2, FALSE);
1683 proto_tree_add_uint_format(ipv6_tree, hf_ipv6_nxt, tvb,
1684 offset + offsetof(struct ip6_hdr, ip6_nxt), 1,
1686 "Next header: %s (0x%02x)",
1687 ipprotostr(ipv6.ip6_nxt), ipv6.ip6_nxt);
1689 proto_tree_add_item(ipv6_tree, hf_ipv6_hlim, tvb,
1690 offset + offsetof(struct ip6_hdr, ip6_hlim), 1, FALSE);
1692 /* Add the different items for the source address */
1693 proto_tree_add_item(ipv6_tree, hf_ipv6_src, tvb,
1694 offset + offsetof(struct ip6_hdr, ip6_src), 16, FALSE);
1695 ti = proto_tree_add_ipv6(ipv6_tree, hf_ipv6_addr, tvb,
1696 offset + offsetof(struct ip6_hdr, ip6_src),
1697 16, (guint8 *)&ipv6.ip6_src);
1698 PROTO_ITEM_SET_HIDDEN(ti);
1699 name = get_addr_name(&pinfo->src);
1700 if (ipv6_summary_in_tree) {
1701 proto_item_append_text(ipv6_item, ", Src: %s (%s)", name, ip6_to_str(&ipv6.ip6_src));
1703 ti = proto_tree_add_string(ipv6_tree, hf_ipv6_src_host, tvb,
1704 offset + offsetof(struct ip6_hdr, ip6_src),
1706 PROTO_ITEM_SET_GENERATED(ti);
1707 PROTO_ITEM_SET_HIDDEN(ti);
1708 ti = proto_tree_add_string(ipv6_tree, hf_ipv6_host, tvb,
1709 offset + offsetof(struct ip6_hdr, ip6_src),
1711 PROTO_ITEM_SET_GENERATED(ti);
1712 PROTO_ITEM_SET_HIDDEN(ti);
1714 /* Extract embedded (IPv6 and MAC) address information */
1715 if (tvb_get_ntohs(tvb, offset + IP6H_SRC) == 0x2002) { /* RFC 3056 section 2 */
1716 ti = proto_tree_add_item(ipv6_tree, hf_ipv6_src_6to4_gateway_ipv4, tvb,
1717 offset + IP6H_SRC + 2, 4, FALSE);
1718 PROTO_ITEM_SET_GENERATED(ti);
1719 ti = proto_tree_add_item(ipv6_tree, hf_ipv6_src_6to4_sla_id, tvb,
1720 offset + IP6H_SRC + 6, 2, FALSE);
1721 PROTO_ITEM_SET_GENERATED(ti);
1722 ti = proto_tree_add_item(ipv6_tree, hf_ipv6_6to4_gateway_ipv4, tvb,
1723 offset + IP6H_SRC + 2, 4, FALSE);
1724 PROTO_ITEM_SET_GENERATED(ti);
1725 PROTO_ITEM_SET_HIDDEN(ti);
1726 ti = proto_tree_add_item(ipv6_tree, hf_ipv6_6to4_sla_id, tvb,
1727 offset + IP6H_SRC + 6, 2, FALSE);
1728 PROTO_ITEM_SET_GENERATED(ti);
1729 PROTO_ITEM_SET_HIDDEN(ti);
1730 } else if (tvb_get_ntohl(tvb, offset + IP6H_SRC) == 0x20010000) { /* RFC 4380 section 4 */
1731 guint16 mapped_port = tvb_get_ntohs(tvb, offset + IP6H_SRC + 10) ^ 0xffff;
1732 guint32 client_v4 = tvb_get_ipv4(tvb, offset + IP6H_SRC + 12) ^ 0xffffffff;
1734 ti = proto_tree_add_item(ipv6_tree, hf_ipv6_src_teredo_server_ipv4, tvb,
1735 offset + IP6H_SRC + 4, 4, FALSE);
1736 PROTO_ITEM_SET_GENERATED(ti);
1737 ti = proto_tree_add_uint(ipv6_tree, hf_ipv6_src_teredo_port, tvb,
1738 offset + IP6H_SRC + 10, 2, mapped_port);
1739 PROTO_ITEM_SET_GENERATED(ti);
1740 ti = proto_tree_add_ipv4(ipv6_tree, hf_ipv6_src_teredo_client_ipv4, tvb,
1741 offset + IP6H_SRC + 12, 4, client_v4);
1742 PROTO_ITEM_SET_GENERATED(ti);
1743 ti = proto_tree_add_item(ipv6_tree, hf_ipv6_teredo_server_ipv4, tvb,
1744 offset + IP6H_SRC + 4, 4, FALSE);
1745 PROTO_ITEM_SET_GENERATED(ti);
1746 PROTO_ITEM_SET_HIDDEN(ti);
1747 ti = proto_tree_add_uint(ipv6_tree, hf_ipv6_teredo_port, tvb,
1748 offset + IP6H_SRC + 10, 2, mapped_port);
1749 PROTO_ITEM_SET_GENERATED(ti);
1750 PROTO_ITEM_SET_HIDDEN(ti);
1751 ti = proto_tree_add_ipv4(ipv6_tree, hf_ipv6_teredo_client_ipv4, tvb,
1752 offset + IP6H_SRC + 12, 4, client_v4);
1753 PROTO_ITEM_SET_GENERATED(ti);
1754 PROTO_ITEM_SET_HIDDEN(ti);
1757 if (tvb_get_guint8(tvb, offset + IP6H_SRC + 8) & 0x02 && tvb_get_ntohs(tvb, offset + IP6H_SRC + 11) == 0xfffe) { /* RFC 4291 appendix A */
1758 mac_addr = ep_alloc(6);
1759 tvb_memcpy(tvb, mac_addr, offset + IP6H_SRC + 8, 3);
1760 tvb_memcpy(tvb, mac_addr+3, offset+ IP6H_SRC + 13, 3);
1761 mac_addr[0] &= ~0x02;
1762 ti = proto_tree_add_ether(ipv6_tree, hf_ipv6_src_sa_mac, tvb,
1763 offset + IP6H_SRC + 8, 6, mac_addr);
1764 PROTO_ITEM_SET_GENERATED(ti);
1765 ti = proto_tree_add_ether(ipv6_tree, hf_ipv6_sa_mac, tvb,
1766 offset + IP6H_SRC + 8, 6, mac_addr);
1767 PROTO_ITEM_SET_GENERATED(ti);
1768 PROTO_ITEM_SET_HIDDEN(ti);
1769 } else if ((tvb_get_ntohl(tvb, offset + IP6H_SRC + 8) & 0xfcffffff) == 0x00005efe) { /* RFC 5214 section 6.1 */
1770 ti = proto_tree_add_item(ipv6_tree, hf_ipv6_src_isatap_ipv4, tvb,
1771 offset + IP6H_SRC + 12, 4, FALSE);
1772 PROTO_ITEM_SET_GENERATED(ti);
1773 ti = proto_tree_add_item(ipv6_tree, hf_ipv6_isatap_ipv4, tvb,
1774 offset + IP6H_SRC + 12, 4, FALSE);
1775 PROTO_ITEM_SET_GENERATED(ti);
1776 PROTO_ITEM_SET_HIDDEN(ti);
1779 /* Add different items for the destination address */
1780 proto_tree_add_item(ipv6_tree, hf_ipv6_dst, tvb,
1781 offset + offsetof(struct ip6_hdr, ip6_dst), 16, FALSE);
1782 ti = proto_tree_add_ipv6(ipv6_tree, hf_ipv6_addr, tvb,
1783 offset + offsetof(struct ip6_hdr, ip6_dst),
1784 16, (guint8 *)&ipv6.ip6_dst);
1785 PROTO_ITEM_SET_HIDDEN(ti);
1786 name = get_addr_name(&pinfo->dst);
1787 if (ipv6_summary_in_tree) {
1788 proto_item_append_text(ipv6_item, ", Dst: %s (%s)", name, ip6_to_str(&ipv6.ip6_dst));
1790 ti = proto_tree_add_string(ipv6_tree, hf_ipv6_dst_host, tvb,
1791 offset + offsetof(struct ip6_hdr, ip6_dst),
1793 PROTO_ITEM_SET_GENERATED(ti);
1794 PROTO_ITEM_SET_HIDDEN(ti);
1795 ti = proto_tree_add_string(ipv6_tree, hf_ipv6_host, tvb,
1796 offset + offsetof(struct ip6_hdr, ip6_dst),
1798 PROTO_ITEM_SET_GENERATED(ti);
1799 PROTO_ITEM_SET_HIDDEN(ti);
1801 /* Extract embedded (IPv6 and MAC) address information */
1802 if (tvb_get_ntohs(tvb, offset + IP6H_DST) == 0x2002) { /* RFC 3056 section 2 */
1803 ti = proto_tree_add_item(ipv6_tree, hf_ipv6_dst_6to4_gateway_ipv4, tvb,
1804 offset + IP6H_DST + 2, 4, FALSE);
1805 PROTO_ITEM_SET_GENERATED(ti);
1806 ti = proto_tree_add_item(ipv6_tree, hf_ipv6_dst_6to4_sla_id, tvb,
1807 offset + IP6H_DST + 6, 2, FALSE);
1808 PROTO_ITEM_SET_GENERATED(ti);
1809 ti = proto_tree_add_item(ipv6_tree, hf_ipv6_6to4_gateway_ipv4, tvb,
1810 offset + IP6H_DST + 2, 4, FALSE);
1811 PROTO_ITEM_SET_GENERATED(ti);
1812 PROTO_ITEM_SET_HIDDEN(ti);
1813 ti = proto_tree_add_item(ipv6_tree, hf_ipv6_6to4_sla_id, tvb,
1814 offset + IP6H_DST + 6, 2, FALSE);
1815 PROTO_ITEM_SET_GENERATED(ti);
1816 PROTO_ITEM_SET_HIDDEN(ti);
1817 } else if (tvb_get_ntohl(tvb, offset + IP6H_DST) == 0x20010000) { /* RFC 4380 section 4 */
1818 guint16 mapped_port = tvb_get_ntohs(tvb, offset + IP6H_DST + 10) ^ 0xffff;
1819 guint32 client_v4 = tvb_get_ipv4(tvb, offset + IP6H_DST + 12) ^ 0xffffffff;
1821 ti = proto_tree_add_item(ipv6_tree, hf_ipv6_dst_teredo_server_ipv4, tvb,
1822 offset + IP6H_DST + 4, 4, FALSE);
1823 PROTO_ITEM_SET_GENERATED(ti);
1824 ti = proto_tree_add_uint(ipv6_tree, hf_ipv6_dst_teredo_port, tvb,
1825 offset + IP6H_DST + 10, 2, mapped_port);
1826 PROTO_ITEM_SET_GENERATED(ti);
1827 ti = proto_tree_add_ipv4(ipv6_tree, hf_ipv6_dst_teredo_client_ipv4, tvb,
1828 offset + IP6H_DST + 12, 4, client_v4);
1829 PROTO_ITEM_SET_GENERATED(ti);
1830 ti = proto_tree_add_item(ipv6_tree, hf_ipv6_teredo_server_ipv4, tvb,
1831 offset + IP6H_DST + 4, 4, FALSE);
1832 PROTO_ITEM_SET_GENERATED(ti);
1833 PROTO_ITEM_SET_HIDDEN(ti);
1834 ti = proto_tree_add_uint(ipv6_tree, hf_ipv6_teredo_port, tvb,
1835 offset + IP6H_DST + 10, 2, mapped_port);
1836 PROTO_ITEM_SET_GENERATED(ti);
1837 PROTO_ITEM_SET_HIDDEN(ti);
1838 ti = proto_tree_add_ipv4(ipv6_tree, hf_ipv6_teredo_client_ipv4, tvb,
1839 offset + IP6H_DST + 12, 4, client_v4);
1840 PROTO_ITEM_SET_GENERATED(ti);
1841 PROTO_ITEM_SET_HIDDEN(ti);
1844 if (tvb_get_guint8(tvb, offset + IP6H_DST + 8) & 0x02 && tvb_get_ntohs(tvb, offset + IP6H_DST + 11) == 0xfffe) { /* RFC 4291 appendix A */
1845 mac_addr = ep_alloc(6);
1846 tvb_memcpy(tvb, mac_addr, offset + IP6H_DST + 8, 3);
1847 tvb_memcpy(tvb, mac_addr+3, offset+ IP6H_DST + 13, 3);
1848 mac_addr[0] &= ~0x02;
1849 ti = proto_tree_add_ether(ipv6_tree, hf_ipv6_dst_sa_mac, tvb,
1850 offset + IP6H_DST + 8, 6, mac_addr);
1851 PROTO_ITEM_SET_GENERATED(ti);
1852 ti = proto_tree_add_ether(ipv6_tree, hf_ipv6_sa_mac, tvb,
1853 offset + IP6H_DST + 8, 6, mac_addr);
1854 PROTO_ITEM_SET_GENERATED(ti);
1855 PROTO_ITEM_SET_HIDDEN(ti);
1856 } else if ((tvb_get_ntohl(tvb, offset + IP6H_DST + 8) & 0xfcffffff) == 0x00005efe) { /* RFC 5214 section 6.1 */
1857 ti = proto_tree_add_item(ipv6_tree, hf_ipv6_dst_isatap_ipv4, tvb,
1858 offset + IP6H_DST + 12, 4, FALSE);
1859 PROTO_ITEM_SET_GENERATED(ti);
1860 ti = proto_tree_add_item(ipv6_tree, hf_ipv6_isatap_ipv4, tvb,
1861 offset + IP6H_DST + 12, 4, FALSE);
1862 PROTO_ITEM_SET_GENERATED(ti);
1863 PROTO_ITEM_SET_HIDDEN(ti);
1868 if (tree && ipv6_use_geoip) {
1869 add_geoip_info(ipv6_tree, tvb, offset, ipv6.ip6_src, ipv6.ip6_dst);
1873 /* start of the new header (could be a extension header) */
1874 poffset = offset + offsetof(struct ip6_hdr, ip6_nxt);
1875 nxt = tvb_get_guint8(tvb, poffset);
1876 offset += sizeof(struct ip6_hdr);
1880 /* start out assuming this isn't fragmented, and has none of the other
1881 non-final headers */
1892 case IP_PROTO_HOPOPTS:
1894 advance = dissect_hopopts(tvb, offset, ipv6_tree, pinfo);
1895 nxt = tvb_get_guint8(tvb, offset);
1901 case IP_PROTO_ROUTING:
1903 advance = dissect_routing6(tvb, offset, ipv6_tree, pinfo);
1904 nxt = tvb_get_guint8(tvb, offset);
1910 case IP_PROTO_FRAGMENT:
1911 advance = dissect_frag6(tvb, offset, pinfo, ipv6_tree,
1913 nxt = tvb_get_guint8(tvb, offset);
1917 frag = offlg & (IP6F_OFF_MASK | IP6F_MORE_FRAG);
1918 save_fragmented |= frag;
1919 if (ipv6_reassemble && frag && tvb_bytes_exist(tvb, offset, plen)) {
1920 ipfd_head = fragment_add_check(tvb, offset, pinfo, ident,
1921 ipv6_fragment_table,
1922 ipv6_reassembled_table,
1923 offlg & IP6F_OFF_MASK,
1925 offlg & IP6F_MORE_FRAG);
1926 next_tvb = process_reassembled_data(tvb, offset, pinfo, "Reassembled IPv6",
1927 ipfd_head, &ipv6_frag_items, &update_col_info, ipv6_tree);
1928 if (next_tvb) { /* Process post-fragment headers after reassembly... */
1936 if (!(offlg & IP6F_OFF_MASK)) /*...or in the first fragment */
1942 advance = dissect_ah_header(tvb_new_subset_remaining(tvb, offset),
1943 pinfo, ipv6_tree, NULL, NULL);
1944 nxt = tvb_get_guint8(tvb, offset);
1950 case IP_PROTO_SHIM6:
1951 case IP_PROTO_SHIM6_OLD:
1953 advance = dissect_shim6(tvb, offset, ipv6_tree, pinfo);
1954 nxt = tvb_get_guint8(tvb, offset);
1955 stype = tvb_get_guint8(tvb, offset+2);
1961 case IP_PROTO_DSTOPTS:
1963 advance = dissect_dstopts(tvb, offset, ipv6_tree, pinfo);
1964 nxt = tvb_get_guint8(tvb, offset);
1974 /* Since we did not recognize this IPv6 option, check
1975 * whether it is a known protocol. If not, then it
1976 * is an unknown IPv6 option
1978 if (!dissector_get_uint_handle(ip_dissector_table, nxt)) {
1979 advance = dissect_unknown_option(tvb, offset, ipv6_tree);
1980 nxt = tvb_get_guint8(tvb, offset);
1988 #ifdef TEST_FINALHDR
1989 ti = proto_tree_add_uint(ipv6_tree, hf_ipv6_final, tvb, poffset, 1, nxt);
1990 PROTO_ITEM_SET_HIDDEN(ti);
1993 proto_item_set_len (ipv6_item, offset);
1994 tap_queue_packet(ipv6_tap, pinfo, &ipv6);
1996 /* collect packet info */
1997 pinfo->ipproto = nxt;
1998 pinfo->iplen = sizeof(ipv6) + plen + offset;
1999 pinfo->iphdrlen = offset;
2001 if (offlg & IP6F_OFF_MASK || (ipv6_reassemble && offlg & IP6F_MORE_FRAG)) {
2002 /* Not the first fragment, or the first when we are reassembling and there are more. */
2003 /* Don't dissect it; just show this as a fragment. */
2004 /* COL_INFO was filled in by "dissect_frag6()" */
2005 call_dissector(data_handle, tvb_new_subset_remaining(tvb, offset), pinfo, tree);
2008 /* First fragment, not fragmented, or already reassembled. Dissect what we have here. */
2010 /* Get a tvbuff for the payload. */
2011 next_tvb = tvb_new_subset_remaining(tvb, offset);
2014 * If this is the first fragment, but not the only fragment,
2015 * tell the next protocol that.
2017 if (offlg & IP6F_MORE_FRAG)
2018 pinfo->fragmented = TRUE;
2020 pinfo->fragmented = FALSE;
2024 /* do lookup with the subdissector table */
2025 if (!dissector_try_uint(ip_dissector_table, nxt, next_tvb, pinfo, tree)) {
2026 /* Unknown protocol.
2027 Handle "no next header" specially. */
2028 if (nxt == IP_PROTO_NONE) {
2029 if (check_col(pinfo->cinfo, COL_INFO)) {
2030 /* If we had an Authentication Header, the AH dissector already
2031 put something in the Info column; leave it there. */
2033 if (hopopts || routing || dstopts || shim6) {
2035 col_append_fstr(pinfo->cinfo, COL_INFO, "%shop-by-hop options",
2040 col_append_fstr(pinfo->cinfo, COL_INFO, "%srouting", sep);
2044 col_append_fstr(pinfo->cinfo, COL_INFO, "%sdestination options",
2048 if (stype & SHIM6_BITMASK_P) {
2049 col_append_str(pinfo->cinfo, COL_INFO, "Shim6 (Payload)");
2052 col_append_fstr(pinfo->cinfo, COL_INFO, "Shim6 (%s)",
2053 val_to_str(stype & SHIM6_BITMASK_TYPE, shimctrlvals, "Unknown"));
2057 col_set_str(pinfo->cinfo, COL_INFO, "IPv6 no next header");
2061 if (check_col(pinfo->cinfo, COL_INFO))
2062 col_add_fstr(pinfo->cinfo, COL_INFO, "%s (0x%02x)", ipprotostr(nxt),nxt);
2064 call_dissector(data_handle, next_tvb, pinfo, tree);
2066 pinfo->fragmented = save_fragmented;
2070 proto_register_ipv6(void)
2072 static hf_register_info hf[] = {
2074 { "Version", "ipv6.version",
2075 FT_UINT8, BASE_DEC, NULL, 0xF0, NULL, HFILL }},
2077 { "This field makes the filter \"ip.version == 6\" possible", "ip.version",
2078 FT_UINT8, BASE_DEC, NULL, 0xF0, NULL, HFILL }},
2080 { "Traffic class", "ipv6.class",
2081 FT_UINT32, BASE_HEX, NULL, 0x0FF00000, NULL, HFILL }},
2083 { "Flowlabel", "ipv6.flow",
2084 FT_UINT32, BASE_HEX, NULL, 0x000FFFFF, NULL, HFILL }},
2086 { "Payload length", "ipv6.plen",
2087 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
2089 { "Next header", "ipv6.nxt",
2090 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2092 { "Hop limit", "ipv6.hlim",
2093 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
2095 { "Source", "ipv6.src",
2096 FT_IPv6, BASE_NONE, NULL, 0x0,
2097 "Source IPv6 Address", HFILL }},
2098 { &hf_ipv6_src_host,
2099 { "Source Host", "ipv6.src_host",
2100 FT_STRING, BASE_NONE, NULL, 0x0,
2101 "Source IPv6 Host", HFILL }},
2102 { &hf_ipv6_src_sa_mac,
2103 { "Source SA MAC", "ipv6.src_sa_mac",
2104 FT_ETHER, BASE_NONE, NULL, 0x0,
2105 "Source IPv6 Stateless Autoconfiguration MAC Address", HFILL }},
2106 { &hf_ipv6_src_isatap_ipv4,
2107 { "Source ISATAP IPv4", "ipv6.src_isatap_ipv4",
2108 FT_IPv4, BASE_NONE, NULL, 0x0,
2109 "Source IPv6 ISATAP Encapsulated IPv4 Address", HFILL }},
2110 { &hf_ipv6_src_6to4_gateway_ipv4,
2111 { "Source 6to4 Gateway IPv4", "ipv6.src_6to4_gw_ipv4",
2112 FT_IPv4, BASE_NONE, NULL, 0x0,
2113 "Source IPv6 6to4 Gateway IPv4 Address", HFILL }},
2114 { &hf_ipv6_src_6to4_sla_id,
2115 { "Source 6to4 SLA ID", "ipv6.src_6to4_sla_id",
2116 FT_UINT16, BASE_DEC, NULL, 0x0,
2117 "Source IPv6 6to4 SLA ID", HFILL }},
2118 { &hf_ipv6_src_teredo_server_ipv4,
2119 { "Source Teredo Server IPv4", "ipv6.src_ts_ipv4",
2120 FT_IPv4, BASE_NONE, NULL, 0x0,
2121 "Source IPv6 Teredo Server Encapsulated IPv4 Address", HFILL }},
2122 { &hf_ipv6_src_teredo_port,
2123 { "Source Teredo Port", "ipv6.src_tc_port",
2124 FT_UINT16, BASE_DEC, NULL, 0x0,
2125 "Source IPv6 Teredo Client Mapped Port", HFILL }},
2126 { &hf_ipv6_src_teredo_client_ipv4,
2127 { "Source Teredo Client IPv4", "ipv6.src_tc_ipv4",
2128 FT_IPv4, BASE_NONE, NULL, 0x0,
2129 "Source IPv6 Teredo Client Encapsulated IPv4 Address", HFILL }},
2131 { "Destination", "ipv6.dst",
2132 FT_IPv6, BASE_NONE, NULL, 0x0,
2133 "Destination IPv6 Address", HFILL }},
2134 { &hf_ipv6_dst_host,
2135 { "Destination Host", "ipv6.dst_host",
2136 FT_STRING, BASE_NONE, NULL, 0x0,
2137 "Destination IPv6 Host", HFILL }},
2138 { &hf_ipv6_dst_sa_mac,
2139 { "Destination SA MAC", "ipv6.dst_sa_mac",
2140 FT_ETHER, BASE_NONE, NULL, 0x0,
2141 "Destination IPv6 Stateless Autoconfiguration MAC Address", HFILL }},
2142 { &hf_ipv6_dst_isatap_ipv4,
2143 { "Destination ISATAP IPv4", "ipv6.dst_isatap_ipv4",
2144 FT_IPv4, BASE_NONE, NULL, 0x0,
2145 "Destination IPv6 ISATAP Encapsulated IPv4 Address", HFILL }},
2146 { &hf_ipv6_dst_6to4_gateway_ipv4,
2147 { "Destination 6to4 Gateway IPv4", "ipv6.dst_6to4_gw_ipv4",
2148 FT_IPv4, BASE_NONE, NULL, 0x0,
2149 "Destination IPv6 6to4 Gateway IPv4 Address", HFILL }},
2150 { &hf_ipv6_dst_6to4_sla_id,
2151 { "Destination 6to4 SLA ID", "ipv6.dst_6to4_sla_id",
2152 FT_UINT16, BASE_DEC, NULL, 0x0,
2153 "Destination IPv6 6to4 SLA ID", HFILL }},
2154 { &hf_ipv6_dst_teredo_server_ipv4,
2155 { "Destination Teredo Server IPv4", "ipv6.dst_ts_ipv4",
2156 FT_IPv4, BASE_NONE, NULL, 0x0,
2157 "Destination IPv6 Teredo Server Encapsulated IPv4 Address", HFILL }},
2158 { &hf_ipv6_dst_teredo_port,
2159 { "Destination Teredo Port", "ipv6.dst_tc_port",
2160 FT_UINT16, BASE_DEC, NULL, 0x0,
2161 "Destination IPv6 Teredo Client Mapped Port", HFILL }},
2162 { &hf_ipv6_dst_teredo_client_ipv4,
2163 { "Destination Teredo Client IPv4", "ipv6.dst_tc_ipv4",
2164 FT_IPv4, BASE_NONE, NULL, 0x0,
2165 "Destination IPv6 Teredo Client Encapsulated IPv4 Address", HFILL }},
2167 { "Address", "ipv6.addr",
2168 FT_IPv6, BASE_NONE, NULL, 0x0,
2169 "Source or Destination IPv6 Address", HFILL }},
2171 { "Host", "ipv6.host",
2172 FT_STRING, BASE_NONE, NULL, 0x0,
2173 "IPv6 Host", HFILL }},
2176 { "SA MAC", "ipv6.sa_mac",
2177 FT_ETHER, BASE_NONE, NULL, 0x0,
2178 "IPv6 Stateless Autoconfiguration MAC Address", HFILL }},
2179 { &hf_ipv6_isatap_ipv4,
2180 { "ISATAP IPv4", "ipv6.isatap_ipv4",
2181 FT_IPv4, BASE_NONE, NULL, 0x0,
2182 "IPv6 ISATAP Encapsulated IPv4 Address", HFILL }},
2183 { &hf_ipv6_6to4_gateway_ipv4,
2184 { "6to4 Gateway IPv4", "ipv6.6to4_gw_ipv4",
2185 FT_IPv4, BASE_NONE, NULL, 0x0,
2186 "IPv6 6to4 Gateway IPv4 Address", HFILL }},
2187 { &hf_ipv6_6to4_sla_id,
2188 { "6to4 SLA ID", "ipv6.6to4_sla_id",
2189 FT_UINT16, BASE_DEC, NULL, 0x0,
2190 "IPv6 6to4 SLA ID", HFILL }},
2191 { &hf_ipv6_teredo_server_ipv4,
2192 { "Teredo Server IPv4", "ipv6.ts_ipv4",
2193 FT_IPv4, BASE_NONE, NULL, 0x0,
2194 "IPv6 Teredo Server Encapsulated IPv4 Address", HFILL }},
2195 { &hf_ipv6_teredo_port,
2196 { "Teredo Port", "ipv6.tc_port",
2197 FT_UINT16, BASE_DEC, NULL, 0x0,
2198 "IPv6 Teredo Client Mapped Port", HFILL }},
2199 { &hf_ipv6_teredo_client_ipv4,
2200 { "Teredo Client IPv4", "ipv6.tc_ipv4",
2201 FT_IPv4, BASE_NONE, NULL, 0x0,
2202 "IPv6 Teredo Client Encapsulated IPv4 Address", HFILL }},
2203 #ifdef HAVE_GEOIP_V6
2204 { &hf_geoip_country,
2205 { "Source or Destination GeoIP Country", "ipv6.geoip.country", FT_STRING, BASE_NONE, NULL, 0x0,
2208 { "Source or Destination GeoIP City", "ipv6.geoip.city", FT_STRING, BASE_NONE, NULL, 0x0,
2211 { "Source or Destination GeoIP Organization", "ipv6.geoip.org", FT_STRING, BASE_NONE, NULL, 0x0,
2214 { "Source or Destination GeoIP ISP", "ipv6.geoip.isp", FT_STRING, BASE_NONE, NULL, 0x0,
2217 { "Source or Destination GeoIP AS Number", "ipv6.geoip.asnum", FT_STRING, BASE_NONE, NULL, 0x0,
2220 { "Source or Destination GeoIP Latitude", "ipv6.geoip.lat", FT_STRING, BASE_NONE, NULL, 0x0,
2223 { "Source or Destination GeoIP Longitude", "ipv6.geoip.lon", FT_STRING, BASE_NONE, NULL, 0x0,
2225 { &hf_geoip_src_country,
2226 { "Source GeoIP Country", "ipv6.geoip.src_country", FT_STRING, BASE_NONE, NULL, 0x0,
2228 { &hf_geoip_src_city,
2229 { "Source GeoIP City", "ipv6.geoip.src_city", FT_STRING, BASE_NONE, NULL, 0x0,
2231 { &hf_geoip_src_org,
2232 { "Source GeoIP Organization", "ipv6.geoip.src_org", FT_STRING, BASE_NONE, NULL, 0x0,
2234 { &hf_geoip_src_isp,
2235 { "Source GeoIP ISP", "ipv6.geoip.src_isp", FT_STRING, BASE_NONE, NULL, 0x0,
2237 { &hf_geoip_src_asnum,
2238 { "Source GeoIP AS Number", "ipv6.geoip.src_asnum", FT_STRING, BASE_NONE, NULL, 0x0,
2240 { &hf_geoip_src_lat,
2241 { "Source GeoIP Latitude", "ipv6.geoip.src_lat", FT_STRING, BASE_NONE, NULL, 0x0,
2243 { &hf_geoip_src_lon,
2244 { "Source GeoIP Longitude", "ipv6.geoip.src_lon", FT_STRING, BASE_NONE, NULL, 0x0,
2246 { &hf_geoip_dst_country,
2247 { "Destination GeoIP Country", "ipv6.geoip.dst_country", FT_STRING, BASE_NONE, NULL, 0x0,
2249 { &hf_geoip_dst_city,
2250 { "Destination GeoIP City", "ipv6.geoip.dst_city", FT_STRING, BASE_NONE, NULL, 0x0,
2252 { &hf_geoip_dst_org,
2253 { "Destination GeoIP Organization", "ipv6.geoip.dst_org", FT_STRING, BASE_NONE, NULL, 0x0,
2255 { &hf_geoip_dst_isp,
2256 { "Destination GeoIP ISP", "ipv6.geoip.dst_isp", FT_STRING, BASE_NONE, NULL, 0x0,
2258 { &hf_geoip_dst_asnum,
2259 { "Destination GeoIP AS Number", "ipv6.geoip.dst_asnum", FT_STRING, BASE_NONE, NULL, 0x0,
2261 { &hf_geoip_dst_lat,
2262 { "Destination GeoIP Latitude", "ipv6.geoip.dst_lat", FT_STRING, BASE_NONE, NULL, 0x0,
2264 { &hf_geoip_dst_lon,
2265 { "Destination GeoIP Longitude", "ipv6.geoip.dst_lon", FT_STRING, BASE_NONE, NULL, 0x0,
2267 #endif /* HAVE_GEOIP_V6 */
2270 { &hf_ipv6_opt_pad1,
2271 { "Pad1", "ipv6.opt.pad1",
2272 FT_NONE, BASE_NONE, NULL, 0x0,
2273 "Pad1 Option", HFILL }},
2274 { &hf_ipv6_opt_padn,
2275 { "PadN", "ipv6.opt.padn",
2276 FT_UINT8, BASE_DEC, NULL, 0x0,
2277 "PadN Option", HFILL }},
2279 { "Destination Option", "ipv6.dst_opt",
2280 FT_NONE, BASE_NONE, NULL, 0x0,
2283 { "Hop-by-Hop Option", "ipv6.hop_opt",
2284 FT_NONE, BASE_NONE, NULL, 0x0,
2287 { "Unknown Extension Header", "ipv6.unknown_hdr",
2288 FT_NONE, BASE_NONE, NULL, 0x0,
2290 { &hf_ipv6_routing_hdr_opt,
2291 { "Routing Header, Type","ipv6.routing_hdr",
2292 FT_UINT8, BASE_DEC, NULL, 0x0,
2293 "Routing Header Option", HFILL }},
2294 { &hf_ipv6_routing_hdr_type,
2295 { "Type", "ipv6.routing_hdr.type",
2296 FT_UINT8, BASE_DEC, VALS(routing_header_type), 0x0,
2297 "Routeing Header Type", HFILL }},
2298 { &hf_ipv6_routing_hdr_left,
2299 { "Left Segments", "ipv6.routing_hdr.left",
2300 FT_UINT8, BASE_DEC, NULL, 0x0,
2301 "Routing Header Left Segments", HFILL }},
2302 { &hf_ipv6_routing_hdr_addr,
2303 { "Address", "ipv6.routing_hdr.addr",
2304 FT_IPv6, BASE_NONE, NULL, 0x0,
2305 "Routing Header Address", HFILL }},
2306 { &hf_ipv6_frag_offset,
2307 { "Offset", "ipv6.fragment.offset",
2308 FT_UINT16, BASE_DEC_HEX, NULL, IP6F_OFF_MASK,
2309 "Fragment Offset", HFILL }},
2310 { &hf_ipv6_frag_more,
2311 { "More Fragment", "ipv6.fragment.more",
2312 FT_BOOLEAN, 16, TFS(&tfs_yes_no), IP6F_MORE_FRAG,
2313 "More Fragments", HFILL }},
2315 { "Identification", "ipv6.framgent.id",
2316 FT_UINT32, BASE_HEX, NULL, 0x0,
2317 "Fragment Identification", HFILL }},
2318 { &hf_ipv6_fragment_overlap,
2319 { "Fragment overlap", "ipv6.fragment.overlap",
2320 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2321 "Fragment overlaps with other fragments", HFILL }},
2323 { &hf_ipv6_fragment_overlap_conflict,
2324 { "Conflicting data in fragment overlap", "ipv6.fragment.overlap.conflict",
2325 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2326 "Overlapping fragments contained conflicting data", HFILL }},
2328 { &hf_ipv6_fragment_multiple_tails,
2329 { "Multiple tail fragments found", "ipv6.fragment.multipletails",
2330 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2331 "Several tails were found when defragmenting the packet", HFILL }},
2333 { &hf_ipv6_fragment_too_long_fragment,
2334 { "Fragment too long", "ipv6.fragment.toolongfragment",
2335 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2336 "Fragment contained data past end of packet", HFILL }},
2338 { &hf_ipv6_fragment_error,
2339 { "Defragmentation error", "ipv6.fragment.error",
2340 FT_FRAMENUM, BASE_NONE, NULL, 0x0,
2341 "Defragmentation error due to illegal fragments", HFILL }},
2343 { &hf_ipv6_fragment_count,
2344 { "Fragment count", "ipv6.fragment.count",
2345 FT_UINT32, BASE_DEC, NULL, 0x0,
2348 { &hf_ipv6_fragment,
2349 { "IPv6 Fragment", "ipv6.fragment",
2350 FT_FRAMENUM, BASE_NONE, NULL, 0x0,
2353 { &hf_ipv6_fragments,
2354 { "IPv6 Fragments", "ipv6.fragments",
2355 FT_NONE, BASE_NONE, NULL, 0x0,
2358 { &hf_ipv6_reassembled_in,
2359 { "Reassembled IPv6 in frame", "ipv6.reassembled_in",
2360 FT_FRAMENUM, BASE_NONE, NULL, 0x0,
2361 "This IPv6 packet is reassembled in this frame", HFILL }},
2363 { &hf_ipv6_reassembled_length,
2364 { "Reassembled IPv6 length", "ipv6.reassembled.length",
2365 FT_UINT32, BASE_DEC, NULL, 0x0,
2366 "The total length of the reassembled payload", HFILL }},
2368 /* RPL Routing Header */
2369 { &hf_ipv6_routing_hdr_rpl_cmprI,
2370 { "Compressed Internal Octets (CmprI)", "ipv6.routing_hdr.rpl.cmprI",
2371 FT_UINT32, BASE_DEC, NULL, IP6RRPL_BITMASK_CMPRI,
2372 "Elided octets from all but last segment", HFILL }},
2374 { &hf_ipv6_routing_hdr_rpl_cmprE,
2375 { "Compressed Final Octets (CmprE)", "ipv6.routing_hdr.rpl.cmprE",
2376 FT_UINT32, BASE_DEC, NULL, IP6RRPL_BITMASK_CMPRE,
2377 "Elided octets from last segment address", HFILL }},
2379 { &hf_ipv6_routing_hdr_rpl_pad,
2380 { "Padding Bytes", "ipv6.routing_hdr.rpl.pad",
2381 FT_UINT32, BASE_DEC, NULL, IP6RRPL_BITMASK_PAD,
2384 { &hf_ipv6_routing_hdr_rpl_reserved,
2385 { "Reserved", "ipv6.routing_hdr.rpl.reserved",
2386 FT_UINT32, BASE_DEC, NULL, IP6RRPL_BITMASK_RESERVED,
2387 "Must be Zero", HFILL }},
2389 { &hf_ipv6_routing_hdr_rpl_segments,
2390 { "Total Segments", "ipv6.routing_hdr.rpl.segments",
2391 FT_INT32, BASE_DEC, NULL, 0,
2394 { &hf_ipv6_routing_hdr_rpl_addr,
2395 { "Address", "ipv6.routing_hdr.rpl.address",
2396 FT_BYTES, BASE_NONE, NULL, 0,
2399 { &hf_ipv6_routing_hdr_rpl_fulladdr,
2400 { "Full Address", "ipv6.routing_hdr.rpl.full_address",
2401 FT_IPv6, BASE_NONE, NULL, 0,
2402 "Uncompressed IPv6 Address", HFILL }},
2405 { &hf_ipv6_mipv6_type,
2406 { "Option Type", "ipv6.mipv6_type",
2407 FT_UINT8, BASE_DEC, NULL, 0x0,
2409 { &hf_ipv6_mipv6_length,
2410 { "Option Length", "ipv6.mipv6_length",
2411 FT_UINT8, BASE_DEC, NULL, 0x0,
2413 { &hf_ipv6_mipv6_home_address,
2414 { "Home Address", "ipv6.mipv6_home_address",
2415 FT_IPv6, BASE_NONE, NULL, 0x0,
2420 { "SHIM6", "ipv6.shim6",
2421 FT_NONE, BASE_NONE, NULL, 0x0,
2424 { &hf_ipv6_shim6_nxt,
2425 { "Next Header", "ipv6.shim6.nxt",
2426 FT_UINT8, BASE_DEC, NULL, 0x0,
2429 { &hf_ipv6_shim6_len,
2430 { "Header Ext Length", "ipv6.shim6.len",
2431 FT_UINT8, BASE_DEC, NULL, 0x0,
2435 { "P Bit", "ipv6.shim6.p",
2436 FT_BOOLEAN, 8, NULL, SHIM6_BITMASK_P,
2439 { &hf_ipv6_shim6_ct,
2440 { "Context Tag", "ipv6.shim6.ct",
2441 FT_NONE, BASE_NONE, NULL, 0x0,
2444 { &hf_ipv6_shim6_type,
2445 { "Message Type", "ipv6.shim6.type",
2447 VALS(shimctrlvals), SHIM6_BITMASK_TYPE,
2450 { &hf_ipv6_shim6_proto,
2451 { "Protocol", "ipv6.shim6.proto",
2453 VALS(shim6_protocol), SHIM6_BITMASK_PROTOCOL,
2456 { &hf_ipv6_shim6_checksum,
2457 { "Checksum", "ipv6.shim6.checksum",
2458 FT_UINT16, BASE_HEX, NULL, 0x0,
2459 "Shim6 Checksum", HFILL }},
2460 { &hf_ipv6_shim6_checksum_bad,
2461 { "Bad Checksum", "ipv6.shim6.checksum_bad",
2462 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2463 "Shim6 Bad Checksum", HFILL }},
2465 { &hf_ipv6_shim6_checksum_good,
2466 { "Good Checksum", "ipv6.shim6.checksum_good",
2467 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2470 { &hf_ipv6_shim6_inonce,
2471 { "Initiator Nonce", "ipv6.shim6.inonce",
2472 FT_UINT32, BASE_DEC_HEX, NULL, 0x0,
2475 { &hf_ipv6_shim6_rnonce,
2476 { "Responder Nonce", "ipv6.shim6.rnonce",
2477 FT_UINT32, BASE_DEC_HEX, NULL, 0x0,
2480 { &hf_ipv6_shim6_precvd,
2481 { "Probes Received", "ipv6.shim6.precvd",
2482 FT_UINT8, BASE_DEC, NULL, 0x0,
2485 { &hf_ipv6_shim6_psent,
2486 { "Probes Sent", "ipv6.shim6.psent",
2487 FT_UINT8, BASE_DEC, NULL, 0x0,
2490 { &hf_ipv6_shim6_psrc,
2491 { "Source Address", "ipv6.shim6.psrc",
2492 FT_IPv6, BASE_NONE, NULL, 0x0,
2493 "Shim6 Probe Source Address", HFILL }},
2495 { &hf_ipv6_shim6_pdst,
2496 { "Destination Address", "ipv6.shim6.pdst",
2497 FT_IPv6, BASE_NONE, NULL, 0x0,
2498 "Shim6 Probe Destination Address", HFILL }},
2500 { &hf_ipv6_shim6_pnonce,
2501 { "Nonce", "ipv6.shim6.pnonce",
2502 FT_UINT32, BASE_DEC_HEX, NULL, 0x0,
2503 "Shim6 Probe Nonce", HFILL }},
2505 { &hf_ipv6_shim6_pdata,
2506 { "Data", "ipv6.shim6.pdata",
2507 FT_UINT32, BASE_HEX, NULL, 0x0,
2508 "Shim6 Probe Data", HFILL }},
2510 { &hf_ipv6_shim6_sulid,
2511 { "Sender ULID", "ipv6.shim6.sulid",
2512 FT_IPv6, BASE_NONE, NULL, 0x0,
2513 "Shim6 Sender ULID", HFILL }},
2515 { &hf_ipv6_shim6_rulid,
2516 { "Receiver ULID", "ipv6.shim6.rulid",
2517 FT_IPv6, BASE_NONE, NULL, 0x0,
2518 "Shim6 Receiver ULID", HFILL }},
2520 { &hf_ipv6_shim6_reap,
2521 { "REAP State", "ipv6.shim6.reap",
2522 FT_UINT8, BASE_DEC, NULL, 0x0,
2525 { &hf_ipv6_shim6_opt_type,
2526 { "Option Type", "ipv6.shim6.opt.type",
2527 FT_UINT16, BASE_DEC,
2528 VALS(shimoptvals), SHIM6_BITMASK_OPT_TYPE,
2529 "Shim6 Option Type", HFILL }},
2531 { &hf_ipv6_shim6_opt_critical,
2532 { "Option Critical Bit", "ipv6.shim6.opt.critical",
2535 SHIM6_BITMASK_CRITICAL,
2536 "TRUE : option is critical, FALSE: option is not critical",
2539 { &hf_ipv6_shim6_opt_len,
2540 { "Content Length", "ipv6.shim6.opt.len",
2541 FT_UINT16, BASE_DEC, NULL, 0x0,
2542 "Content Length Option", HFILL }},
2544 { &hf_ipv6_shim6_opt_total_len,
2545 { "Total Length", "ipv6.shim6.opt.total_len",
2546 FT_UINT16, BASE_DEC, NULL, 0x0,
2547 "Total Option Length", HFILL }},
2549 { &hf_ipv6_shim6_opt_loc_verif_methods,
2550 { "Verification Method", "ipv6.shim6.opt.verif_method",
2552 VALS(shimverifmethods), 0x0,
2553 "Locator Verification Method", HFILL }},
2555 { &hf_ipv6_shim6_opt_loclist,
2556 { "Locator List Generation", "ipv6.shim6.opt.loclist",
2557 FT_UINT32, BASE_DEC_HEX, NULL, 0x0,
2560 { &hf_ipv6_shim6_locator,
2561 { "Locator", "ipv6.shim6.locator",
2562 FT_IPv6, BASE_NONE, NULL, 0x0,
2563 "Shim6 Locator", HFILL }},
2565 { &hf_ipv6_shim6_opt_locnum,
2566 { "Num Locators", "ipv6.shim6.opt.locnum",
2567 FT_UINT8, BASE_DEC, NULL, 0x0,
2568 "Number of Locators in Locator List", HFILL }},
2570 { &hf_ipv6_shim6_opt_elemlen,
2571 { "Element Length", "ipv6.shim6.opt.elemlen",
2572 FT_UINT8, BASE_DEC, NULL, 0x0,
2573 "Length of Elements in Locator Preferences Option", HFILL }},
2574 { &hf_ipv6_shim6_loc_flag,
2575 { "Flags", "ipv6.shim6.loc.flags",
2576 FT_UINT8, BASE_DEC, NULL, 0x0,
2577 "Locator Preferences Flags", HFILL }},
2579 { &hf_ipv6_shim6_loc_prio,
2580 { "Priority", "ipv6.shim6.loc.prio",
2581 FT_UINT8, BASE_DEC, NULL, 0x0,
2582 "Locator Preferences Priority", HFILL }},
2584 { &hf_ipv6_shim6_loc_weight,
2585 { "Weight", "ipv6.shim6.loc.weight",
2586 FT_UINT8, BASE_DEC, NULL, 0x0,
2587 "Locator Preferences Weight", HFILL }},
2589 { &hf_ipv6_shim6_opt_fii,
2590 { "Forked Instance Identifier", "ipv6.shim6.opt.fii",
2591 FT_UINT32, BASE_DEC_HEX, NULL, 0x0,
2594 #ifdef TEST_FINALHDR
2596 { "Final next header", "ipv6.final",
2597 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2600 { &hf_ipv6_traffic_class_dscp,
2601 { "Differentiated Services Field", "ipv6.traffic_class.dscp",
2602 FT_UINT32, BASE_HEX, VALS(dscp_vals), 0x0FC00000, NULL, HFILL }},
2604 { &hf_ipv6_traffic_class_ect,
2605 { "ECN-Capable Transport (ECT)", "ipv6.traffic_class.ect",
2606 FT_BOOLEAN, 32, TFS(&tfs_set_notset), 0x0200000, NULL, HFILL }},
2608 { &hf_ipv6_traffic_class_ce,
2609 { "ECN-CE", "ipv6.traffic_class.ce",
2610 FT_BOOLEAN, 32, TFS(&tfs_set_notset), 0x0100000, NULL, HFILL }},
2612 static gint *ett[] = {
2616 &ett_ipv6_shim6_option,
2617 &ett_ipv6_shim6_locators,
2618 &ett_ipv6_shim6_verif_methods,
2619 &ett_ipv6_shim6_loc_pref,
2620 &ett_ipv6_shim6_probes_sent,
2621 &ett_ipv6_shim6_probes_rcvd,
2622 &ett_ipv6_shim6_probe_sent,
2623 &ett_ipv6_shim6_probe_rcvd,
2624 &ett_ipv6_shim6_cksum,
2625 &ett_ipv6_fragments,
2627 &ett_ipv6_traffic_class,
2628 #ifdef HAVE_GEOIP_V6
2630 #endif /* HAVE_GEOIP_V6 */
2632 module_t *ipv6_module;
2634 proto_ipv6 = proto_register_protocol("Internet Protocol Version 6", "IPv6", "ipv6");
2635 proto_register_field_array(proto_ipv6, hf, array_length(hf));
2636 proto_register_subtree_array(ett, array_length(ett));
2638 /* Register configuration options */
2639 ipv6_module = prefs_register_protocol(proto_ipv6, NULL);
2640 prefs_register_bool_preference(ipv6_module, "defragment",
2641 "Reassemble fragmented IPv6 datagrams",
2642 "Whether fragmented IPv6 datagrams should be reassembled",
2644 prefs_register_bool_preference(ipv6_module, "summary_in_tree",
2645 "Show IPv6 summary in protocol tree",
2646 "Whether the IPv6 summary line should be shown in the protocol tree",
2647 &ipv6_summary_in_tree);
2648 #ifdef HAVE_GEOIP_V6
2649 prefs_register_bool_preference(ipv6_module, "use_geoip" ,
2650 "Enable GeoIP lookups",
2651 "Whether to look up IPv6 addresses in each GeoIP database we have loaded",
2653 #endif /* HAVE_GEOIP_V6 */
2655 register_dissector("ipv6", dissect_ipv6, proto_ipv6);
2656 register_init_routine(ipv6_reassemble_init);
2657 ipv6_tap = register_tap("ipv6");
2661 proto_reg_handoff_ipv6(void)
2663 dissector_handle_t ipv6_handle;
2665 data_handle = find_dissector("data");
2666 ipv6_handle = find_dissector("ipv6");
2667 dissector_add_uint("ethertype", ETHERTYPE_IPv6, ipv6_handle);
2668 dissector_add_uint("ppp.protocol", PPP_IPV6, ipv6_handle);
2669 dissector_add_uint("ppp.protocol", ETHERTYPE_IPv6, ipv6_handle);
2670 dissector_add_uint("gre.proto", ETHERTYPE_IPv6, ipv6_handle);
2671 dissector_add_uint("ip.proto", IP_PROTO_IPV6, ipv6_handle);
2672 dissector_add_uint("null.type", BSD_AF_INET6_BSD, ipv6_handle);
2673 dissector_add_uint("null.type", BSD_AF_INET6_FREEBSD, ipv6_handle);
2674 dissector_add_uint("null.type", BSD_AF_INET6_DARWIN, ipv6_handle);
2675 dissector_add_uint("chdlctype", ETHERTYPE_IPv6, ipv6_handle);
2676 dissector_add_uint("fr.ietf", NLPID_IP6, ipv6_handle);
2677 dissector_add_uint("osinl.excl", NLPID_IP6, ipv6_handle);
2678 dissector_add_uint("x.25.spi", NLPID_IP6, ipv6_handle);
2679 dissector_add_uint("arcnet.protocol_id", ARCNET_PROTO_IPv6, ipv6_handle);
2681 ip_dissector_table = find_dissector_table("ip.proto");