HACK: pinfo->private_data points to smb_info again
[wireshark-wip.git] / epan / dissectors / packet-ipv6.c
blob3b7ec41dba1683114d4df8f23a9048222eabccac
1 /* packet-ipv6.c
2 * Routines for IPv6 packet disassembly
4 * $Id$
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
29 #include "config.h"
31 #include <math.h>
32 #include <glib.h>
33 #include <epan/packet.h>
34 #include <epan/expert.h>
35 #include <epan/ip_opts.h>
36 #include <epan/addr_resolv.h>
37 #include <epan/prefs.h>
38 #include <epan/reassemble.h>
39 #include <epan/ipproto.h>
40 #include <epan/ipv6-utils.h>
41 #include <epan/etypes.h>
42 #include <epan/ppptypes.h>
43 #include <epan/aftypes.h>
44 #include <epan/nlpid.h>
45 #include <epan/arcnet_pids.h>
46 #include <epan/in_cksum.h>
47 #include <epan/expert.h>
48 #include <epan/wmem/wmem.h>
49 #include <epan/tap.h>
50 #include "packet-ipsec.h"
51 #include "packet-ipv6.h"
52 #include "packet-ip.h"
54 #ifdef HAVE_GEOIP_V6
55 #include <GeoIP.h>
56 #include <epan/geoip_db.h>
57 #endif /* HAVE_GEOIP_V6 */
59 /* Option types and related macros */
60 #define IP6OPT_PAD1 0x00 /* 00 0 00000 */
61 #define IP6OPT_PADN 0x01 /* 00 0 00001 */
62 #define IP6OPT_TEL 0x04 /* 00 0 00100 */
63 #define IP6OPT_RTALERT 0x05 /* 00 0 00101 */
64 #define IP6OPT_CALIPSO 0x07 /* 00 0 00111 */
65 #define IP6OPT_QUICKSTART 0x26 /* 00 1 00110 */
66 #define IP6OPT_ENDI 0x8A /* 10 0 01010 */
67 #define IP6OPT_EXP_1E 0x1E /* 00 0 11110 */
68 #define IP6OPT_EXP_3E 0x3E /* 00 1 11110 */
69 #define IP6OPT_EXP_5E 0x5E /* 01 0 11110 */
70 #define IP6OPT_RPL 0x63 /* 01 1 00011 */
71 #define IP6OPT_EXP_7E 0x7E /* 01 1 11110 */
72 #define IP6OPT_EXP_9E 0x9E /* 10 0 11110 */
73 #define IP6OPT_EXP_BE 0xBE /* 10 1 11110 */
74 #define IP6OPT_JUMBO 0xC2 /* 11 0 00010 = 194 */
75 #define IP6OPT_HOME_ADDRESS 0xC9 /* 11 0 01001 */
76 #define IP6OPT_EXP_DE 0xDE /* 11 0 11110 */
77 #define IP6OPT_EXP_FE 0xFE /* 11 1 11110 */
79 #define IP6OPT_RTALERT_MLD 0 /* Datagram contains MLD msg */
80 #define IP6OPT_RTALERT_RSVP 1 /* Datagram contains RSVP msg */
81 #define IP6OPT_RTALERT_ACTNET 2 /* Datagram contains ACTNET msg */
83 /* Differentiated Services Field. See RFCs 2474, 2597 and 2598. */
84 #define IPDSFIELD_DSCP_MASK 0xFC
85 #define IPDSFIELD_ECN_MASK 0x03
86 #define IPDSFIELD_DSCP_SHIFT 2
87 #define IPDSFIELD_DSCP(dsfield) (((dsfield)&IPDSFIELD_DSCP_MASK)>>IPDSFIELD_DSCP_SHIFT)
88 #define IPDSFIELD_ECN(dsfield) ((dsfield)&IPDSFIELD_ECN_MASK)
89 #define IPDSFIELD_DSCP_DEFAULT 0x00
90 #define IPDSFIELD_DSCP_CS1 0x08
91 #define IPDSFIELD_DSCP_CS2 0x10
92 #define IPDSFIELD_DSCP_CS3 0x18
93 #define IPDSFIELD_DSCP_CS4 0x20
94 #define IPDSFIELD_DSCP_CS5 0x28
95 #define IPDSFIELD_DSCP_CS6 0x30
96 #define IPDSFIELD_DSCP_CS7 0x38
97 #define IPDSFIELD_DSCP_AF11 0x0A
98 #define IPDSFIELD_DSCP_AF12 0x0C
99 #define IPDSFIELD_DSCP_AF13 0x0E
100 #define IPDSFIELD_DSCP_AF21 0x12
101 #define IPDSFIELD_DSCP_AF22 0x14
102 #define IPDSFIELD_DSCP_AF23 0x16
103 #define IPDSFIELD_DSCP_AF31 0x1A
104 #define IPDSFIELD_DSCP_AF32 0x1C
105 #define IPDSFIELD_DSCP_AF33 0x1E
106 #define IPDSFIELD_DSCP_AF41 0x22
107 #define IPDSFIELD_DSCP_AF42 0x24
108 #define IPDSFIELD_DSCP_AF43 0x26
109 #define IPDSFIELD_DSCP_EF 0x2E
110 #define IPDSFIELD_ECT_MASK 0x02
111 #define IPDSFIELD_CE_MASK 0x01
113 /* RPL Routing header */
114 #define IP6RRPL_BITMASK_CMPRI 0xF0000000
115 #define IP6RRPL_BITMASK_CMPRE 0x0F000000
116 #define IP6RRPL_BITMASK_PAD 0x00F00000
117 #define IP6RRPL_BITMASK_RESERVED 0x000FFFFF
119 static int ipv6_tap = -1;
121 static int proto_ipv6 = -1;
122 static int hf_ipv6_version = -1;
123 static int hf_ip_version = -1;
124 static int hf_ipv6_class = -1;
125 static int hf_ipv6_flow = -1;
126 static int hf_ipv6_plen = -1;
127 static int hf_ipv6_nxt = -1;
128 static int hf_ipv6_hlim = -1;
129 static int hf_ipv6_src = -1;
130 static int hf_ipv6_src_host = -1;
131 static int hf_ipv6_src_sa_mac = -1;
132 static int hf_ipv6_src_isatap_ipv4 = -1;
133 static int hf_ipv6_src_6to4_gateway_ipv4 = -1;
134 static int hf_ipv6_src_6to4_sla_id = -1;
135 static int hf_ipv6_src_teredo_server_ipv4 = -1;
136 static int hf_ipv6_src_teredo_port = -1;
137 static int hf_ipv6_src_teredo_client_ipv4 = -1;
138 static int hf_ipv6_dst = -1;
139 static int hf_ipv6_dst_host = -1;
140 static int hf_ipv6_dst_sa_mac = -1;
141 static int hf_ipv6_dst_isatap_ipv4 = -1;
142 static int hf_ipv6_dst_6to4_gateway_ipv4 = -1;
143 static int hf_ipv6_dst_6to4_sla_id = -1;
144 static int hf_ipv6_dst_teredo_server_ipv4 = -1;
145 static int hf_ipv6_dst_teredo_port = -1;
146 static int hf_ipv6_dst_teredo_client_ipv4 = -1;
147 static int hf_ipv6_addr = -1;
148 static int hf_ipv6_host = -1;
149 static int hf_ipv6_sa_mac = -1;
150 static int hf_ipv6_isatap_ipv4 = -1;
151 static int hf_ipv6_6to4_gateway_ipv4 = -1;
152 static int hf_ipv6_6to4_sla_id = -1;
153 static int hf_ipv6_teredo_server_ipv4 = -1;
154 static int hf_ipv6_teredo_port = -1;
155 static int hf_ipv6_teredo_client_ipv4 = -1;
156 static int hf_ipv6_opt = -1;
157 static int hf_ipv6_opt_type = -1;
158 static int hf_ipv6_opt_length = -1;
159 static int hf_ipv6_opt_pad1 = -1;
160 static int hf_ipv6_opt_padn = -1;
161 static int hf_ipv6_opt_tel = -1;
162 static int hf_ipv6_opt_rtalert = -1;
163 static int hf_ipv6_opt_jumbo = -1;
164 static int hf_ipv6_opt_calipso_doi = -1;
165 static int hf_ipv6_opt_calipso_cmpt_length = -1;
166 static int hf_ipv6_opt_calipso_sens_level = -1;
167 static int hf_ipv6_opt_calipso_checksum = -1;
168 static int hf_ipv6_opt_calipso_cmpt_bitmap = -1;
169 static int hf_ipv6_opt_qs_func = -1;
170 static int hf_ipv6_opt_qs_rate = -1;
171 static int hf_ipv6_opt_qs_ttl = -1;
172 static int hf_ipv6_opt_qs_ttl_diff = -1;
173 static int hf_ipv6_opt_qs_unused = -1;
174 static int hf_ipv6_opt_qs_nonce = -1;
175 static int hf_ipv6_opt_qs_reserved = -1;
176 static int hf_ipv6_opt_rpl_flag = -1;
177 static int hf_ipv6_opt_rpl_flag_o = -1;
178 static int hf_ipv6_opt_rpl_flag_r = -1;
179 static int hf_ipv6_opt_rpl_flag_f = -1;
180 static int hf_ipv6_opt_rpl_flag_rsv = -1;
181 static int hf_ipv6_opt_rpl_instance_id = -1;
182 static int hf_ipv6_opt_rpl_senderrank = -1;
183 static int hf_ipv6_opt_experimental = -1;
184 static int hf_ipv6_opt_unknown = -1;
185 static int hf_ipv6_dst_opt = -1;
186 static int hf_ipv6_hop_opt = -1;
187 static int hf_ipv6_unk_hdr = -1;
188 static int hf_ipv6_routing_hdr_opt = -1;
189 static int hf_ipv6_routing_hdr_type = -1;
190 static int hf_ipv6_routing_hdr_left = -1;
191 static int hf_ipv6_routing_hdr_addr = -1;
192 static int hf_ipv6_frag_nxt = -1;
193 static int hf_ipv6_frag_reserved = -1;
194 static int hf_ipv6_frag_offset = -1;
195 static int hf_ipv6_frag_reserved_bits = -1;
196 static int hf_ipv6_frag_more = -1;
197 static int hf_ipv6_frag_id = -1;
198 static int hf_ipv6_fragments = -1;
199 static int hf_ipv6_fragment = -1;
200 static int hf_ipv6_fragment_overlap = -1;
201 static int hf_ipv6_fragment_overlap_conflict = -1;
202 static int hf_ipv6_fragment_multiple_tails = -1;
203 static int hf_ipv6_fragment_too_long_fragment = -1;
204 static int hf_ipv6_fragment_error = -1;
205 static int hf_ipv6_fragment_count = -1;
206 static int hf_ipv6_reassembled_in = -1;
207 static int hf_ipv6_reassembled_length = -1;
208 static int hf_ipv6_reassembled_data = -1;
210 static int hf_ipv6_mipv6_home_address = -1;
212 static int hf_ipv6_routing_hdr_rpl_cmprI = -1;
213 static int hf_ipv6_routing_hdr_rpl_cmprE = -1;
214 static int hf_ipv6_routing_hdr_rpl_pad = -1;
215 static int hf_ipv6_routing_hdr_rpl_reserved = -1;
216 static int hf_ipv6_routing_hdr_rpl_segments = -1;
217 static int hf_ipv6_routing_hdr_rpl_addr = -1;
218 static int hf_ipv6_routing_hdr_rpl_fulladdr = -1;
220 static int hf_ipv6_shim6 = -1;
221 static int hf_ipv6_shim6_nxt = -1;
222 static int hf_ipv6_shim6_len = -1;
223 static int hf_ipv6_shim6_p = -1;
224 /* context tag is 49 bits, cannot be used for filter yet */
225 static int hf_ipv6_shim6_ct = -1;
226 static int hf_ipv6_shim6_type = -1;
227 static int hf_ipv6_shim6_proto = -1;
228 static int hf_ipv6_shim6_checksum = -1;
229 static int hf_ipv6_shim6_checksum_bad = -1;
230 static int hf_ipv6_shim6_checksum_good = -1;
231 static int hf_ipv6_shim6_inonce = -1; /* also for request nonce */
232 static int hf_ipv6_shim6_rnonce = -1;
233 static int hf_ipv6_shim6_precvd = -1;
234 static int hf_ipv6_shim6_psent = -1;
235 static int hf_ipv6_shim6_psrc = -1;
236 static int hf_ipv6_shim6_pdst = -1;
237 static int hf_ipv6_shim6_pnonce = -1;
238 static int hf_ipv6_shim6_pdata = -1;
239 static int hf_ipv6_shim6_sulid = -1;
240 static int hf_ipv6_shim6_rulid = -1;
241 static int hf_ipv6_shim6_reap = -1;
242 static int hf_ipv6_shim6_opt_type = -1;
243 static int hf_ipv6_shim6_opt_len = -1;
244 static int hf_ipv6_shim6_opt_total_len = -1;
245 static int hf_ipv6_shim6_opt_loc_verif_methods = -1;
246 static int hf_ipv6_shim6_opt_critical = -1;
247 static int hf_ipv6_shim6_opt_loclist = -1;
248 static int hf_ipv6_shim6_locator = -1;
249 static int hf_ipv6_shim6_loc_flag = -1;
250 static int hf_ipv6_shim6_loc_prio = -1;
251 static int hf_ipv6_shim6_loc_weight = -1;
252 static int hf_ipv6_shim6_opt_locnum = -1;
253 static int hf_ipv6_shim6_opt_elemlen = -1;
254 static int hf_ipv6_shim6_opt_fii = -1;
255 static int hf_ipv6_traffic_class_dscp = -1;
256 static int hf_ipv6_traffic_class_ect = -1;
257 static int hf_ipv6_traffic_class_ce = -1;
259 #ifdef HAVE_GEOIP_V6
260 static int hf_geoip_country = -1;
261 static int hf_geoip_city = -1;
262 static int hf_geoip_org = -1;
263 static int hf_geoip_isp = -1;
264 static int hf_geoip_asnum = -1;
265 static int hf_geoip_lat = -1;
266 static int hf_geoip_lon = -1;
267 static int hf_geoip_src_country = -1;
268 static int hf_geoip_src_city = -1;
269 static int hf_geoip_src_org = -1;
270 static int hf_geoip_src_isp = -1;
271 static int hf_geoip_src_asnum = -1;
272 static int hf_geoip_src_lat = -1;
273 static int hf_geoip_src_lon = -1;
274 static int hf_geoip_dst_country = -1;
275 static int hf_geoip_dst_city = -1;
276 static int hf_geoip_dst_org = -1;
277 static int hf_geoip_dst_isp = -1;
278 static int hf_geoip_dst_asnum = -1;
279 static int hf_geoip_dst_lat = -1;
280 static int hf_geoip_dst_lon = -1;
281 #endif /* HAVE_GEOIP_V6 */
283 static gint ett_ipv6 = -1;
284 static gint ett_ipv6_opt = -1;
285 static gint ett_ipv6_opt_flag = -1;
286 static gint ett_ipv6_version = -1;
287 static gint ett_ipv6_shim6 = -1;
288 static gint ett_ipv6_shim6_option = -1;
289 static gint ett_ipv6_shim6_locators = -1;
290 static gint ett_ipv6_shim6_verif_methods = -1;
291 static gint ett_ipv6_shim6_loc_pref = -1;
292 static gint ett_ipv6_shim6_probes_sent = -1;
293 static gint ett_ipv6_shim6_probe_sent = -1;
294 static gint ett_ipv6_shim6_probes_rcvd = -1;
295 static gint ett_ipv6_shim6_probe_rcvd = -1;
296 static gint ett_ipv6_shim6_cksum = -1;
297 static gint ett_ipv6_fragments = -1;
298 static gint ett_ipv6_fragment = -1;
299 static gint ett_ipv6_traffic_class = -1;
301 #ifdef HAVE_GEOIP_V6
302 static gint ett_geoip_info = -1;
303 #endif /* HAVE_GEOIP_V6 */
305 static expert_field ei_ipv6_dst_addr_not_multicast = EI_INIT;
306 static expert_field ei_ipv6_src_route_list_mult_inst_same_addr = EI_INIT;
307 static expert_field ei_ipv6_src_route_list_src_addr = EI_INIT;
308 static expert_field ei_ipv6_src_route_list_dst_addr = EI_INIT;
309 static expert_field ei_ipv6_src_route_list_multicast_addr = EI_INIT;
310 static expert_field ei_ipv6_cmpri_cmpre_pad = EI_INIT;
311 static expert_field ei_ipv6_routing_hdr_rpl_reserved = EI_INIT;
312 static expert_field ei_ipv6_opt_tel_invalid_len = EI_INIT;
313 static expert_field ei_ipv6_opt_jumbo_invalid_len = EI_INIT;
314 static expert_field ei_ipv6_opt_rtalert_invalid_len = EI_INIT;
315 static expert_field ei_ipv6_mipv6_home_address_invalid_len = EI_INIT;
316 static expert_field ei_ipv6_shim6_opt_elemlen_invalid = EI_INIT;
317 static expert_field ei_ipv6_shim6_checksum_bad = EI_INIT;
318 static expert_field ei_ipv6_routing_hdr_rpl_segments_ge0 = EI_INIT;
320 static const fragment_items ipv6_frag_items = {
321 &ett_ipv6_fragment,
322 &ett_ipv6_fragments,
323 &hf_ipv6_fragments,
324 &hf_ipv6_fragment,
325 &hf_ipv6_fragment_overlap,
326 &hf_ipv6_fragment_overlap_conflict,
327 &hf_ipv6_fragment_multiple_tails,
328 &hf_ipv6_fragment_too_long_fragment,
329 &hf_ipv6_fragment_error,
330 &hf_ipv6_fragment_count,
331 &hf_ipv6_reassembled_in,
332 &hf_ipv6_reassembled_length,
333 &hf_ipv6_reassembled_data,
334 "IPv6 fragments"
337 static dissector_handle_t data_handle;
339 static dissector_table_t ip_dissector_table;
341 /* Reassemble fragmented datagrams */
342 static gboolean ipv6_reassemble = TRUE;
344 /* Place IPv6 summary in proto tree */
345 static gboolean ipv6_summary_in_tree = TRUE;
347 #ifdef HAVE_GEOIP_V6
348 /* Look up addresses in GeoIP */
349 static gboolean ipv6_use_geoip = TRUE;
350 #endif /* HAVE_GEOIP_V6 */
352 /* Perform strict RFC adherence checking */
353 static gboolean g_ipv6_rpl_srh_strict_rfc_checking = FALSE;
355 #ifndef offsetof
356 #define offsetof(type, member) ((size_t)(&((type *)0)->member))
357 #endif
360 * defragmentation of IPv6
362 static reassembly_table ipv6_reassembly_table;
364 /* http://www.iana.org/assignments/icmpv6-parameters (last updated 2012-12-22) */
365 static const value_string ipv6_opt_vals[] = {
366 { IP6OPT_PAD1, "Pad1" },
367 { IP6OPT_PADN, "PadN" },
368 { IP6OPT_TEL, "Tunnel Encapsulation Limit" },
369 { IP6OPT_RTALERT, "Router Alert" },
370 { IP6OPT_CALIPSO, "Calipso" },
371 { IP6OPT_QUICKSTART, "Quick Start" },
372 { IP6OPT_ENDI, "Endpoint Identification" },
373 { IP6OPT_EXP_1E, "Experimental (0x1E)" },
374 { IP6OPT_EXP_3E, "Experimental (0x3E)" },
375 { IP6OPT_EXP_5E, "Experimental (0x5E)" },
376 { IP6OPT_RPL, "RPL Option" },
377 { IP6OPT_EXP_7E, "Experimental (0x7E)" },
378 { IP6OPT_EXP_9E, "Experimental (0x9E)" },
379 { IP6OPT_EXP_BE, "Experimental (0xBE)" },
380 { IP6OPT_JUMBO, "Jumbo" },
381 { IP6OPT_HOME_ADDRESS, "Home Address" },
382 { IP6OPT_EXP_DE, "Experimental (0xDE)" },
383 { IP6OPT_EXP_FE, "Experimental (0xFE)" },
384 { 0, NULL }
388 void
389 capture_ipv6(const guchar *pd, int offset, int len, packet_counts *ld)
391 guint8 nxt;
392 int advance;
394 if (!BYTES_ARE_IN_FRAME(offset, len, 4+4+16+16)) {
395 ld->other++;
396 return;
398 nxt = pd[offset+6]; /* get the "next header" value */
399 offset += 4+4+16+16; /* skip past the IPv6 header */
401 again:
402 switch (nxt) {
403 case IP_PROTO_HOPOPTS:
404 case IP_PROTO_ROUTING:
405 case IP_PROTO_DSTOPTS:
406 if (!BYTES_ARE_IN_FRAME(offset, len, 2)) {
407 ld->other++;
408 return;
410 nxt = pd[offset];
411 advance = (pd[offset+1] + 1) << 3;
412 if (!BYTES_ARE_IN_FRAME(offset, len, advance)) {
413 ld->other++;
414 return;
416 offset += advance;
417 goto again;
418 case IP_PROTO_FRAGMENT:
419 if (!BYTES_ARE_IN_FRAME(offset, len, 2)) {
420 ld->other++;
421 return;
423 nxt = pd[offset];
424 advance = 8;
425 if (!BYTES_ARE_IN_FRAME(offset, len, advance)) {
426 ld->other++;
427 return;
429 offset += advance;
430 goto again;
431 case IP_PROTO_AH:
432 if (!BYTES_ARE_IN_FRAME(offset, len, 2)) {
433 ld->other++;
434 return;
436 nxt = pd[offset];
437 advance = 8 + ((pd[offset+1] - 1) << 2);
438 if (!BYTES_ARE_IN_FRAME(offset, len, advance)) {
439 ld->other++;
440 return;
442 offset += advance;
443 goto again;
444 case IP_PROTO_SHIM6:
445 case IP_PROTO_SHIM6_OLD:
446 if (!BYTES_ARE_IN_FRAME(offset, len, 2)) {
447 ld->other++;
448 return;
450 nxt = pd[offset];
451 advance = (pd[offset+1] + 1) << 3;
452 if (!BYTES_ARE_IN_FRAME(offset, len, advance)) {
453 ld->other++;
454 return;
456 offset += advance;
457 goto again;
460 switch(nxt) {
461 case IP_PROTO_SCTP:
462 ld->sctp++;
463 break;
464 case IP_PROTO_TCP:
465 ld->tcp++;
466 break;
467 case IP_PROTO_UDP:
468 case IP_PROTO_UDPLITE:
469 ld->udp++;
470 break;
471 case IP_PROTO_ICMP:
472 case IP_PROTO_ICMPV6: /* XXX - separate counters? */
473 ld->icmp++;
474 break;
475 case IP_PROTO_OSPF:
476 ld->ospf++;
477 break;
478 case IP_PROTO_GRE:
479 ld->gre++;
480 break;
481 case IP_PROTO_VINES:
482 ld->vines++;
483 break;
484 default:
485 ld->other++;
490 * Unicast Scope
491 * Note that we must check topmost 10 bits only, not 16 bits (see RFC2373).
493 /* XXX Currently unused
494 static inline gboolean in6_is_addr_link_local(struct e_in6_addr *a) {
495 if ((a->bytes[0] == 0xfe) && ((a->bytes[1] & 0xc0) == 0x80)) {
496 return TRUE;
498 return FALSE;
501 static inline gboolean in6_is_addr_sitelocal(struct e_in6_addr *a) {
502 if ((a->bytes[0] == 0xfe) && ((a->bytes[1] & 0xc0) == 0xc0)) {
503 return TRUE;
505 return FALSE;
510 * Multicast
512 static inline gboolean in6_is_addr_multicast(struct e_in6_addr *a) {
513 if (a->bytes[0] == 0xff) {
514 return TRUE;
516 return FALSE;
519 #ifdef HAVE_GEOIP_V6
520 static void
521 add_geoip_info_entry(proto_tree *geoip_info_item, tvbuff_t *tvb, gint offset, const struct e_in6_addr *ip, int isdst)
523 proto_tree *geoip_info_tree;
525 guint num_dbs = geoip_db_num_dbs();
526 guint item_cnt = 0;
527 guint dbnum;
529 geoip_info_tree = proto_item_add_subtree(geoip_info_item, ett_geoip_info);
531 for (dbnum = 0; dbnum < num_dbs; dbnum++) {
532 const char *geoip_str = geoip_db_lookup_ipv6(dbnum, *ip, NULL);
533 int db_type = geoip_db_type(dbnum);
535 int geoip_hf, geoip_local_hf;
537 switch (db_type) {
538 case GEOIP_COUNTRY_EDITION_V6:
539 geoip_hf = hf_geoip_country;
540 geoip_local_hf = (isdst) ? hf_geoip_dst_country : hf_geoip_src_country;
541 break;
542 #if NUM_DB_TYPES > 31
543 case GEOIP_CITY_EDITION_REV0_V6:
544 case GEOIP_CITY_EDITION_REV1_V6:
545 geoip_hf = hf_geoip_city;
546 geoip_local_hf = (isdst) ? hf_geoip_dst_city : hf_geoip_src_city;
547 break;
548 case GEOIP_ORG_EDITION_V6:
549 geoip_hf = hf_geoip_org;
550 geoip_local_hf = (isdst) ? hf_geoip_dst_org : hf_geoip_src_org;
551 break;
552 case GEOIP_ISP_EDITION_V6:
553 geoip_hf = hf_geoip_isp;
554 geoip_local_hf = (isdst) ? hf_geoip_dst_isp : hf_geoip_src_isp;
555 break;
556 case GEOIP_ASNUM_EDITION_V6:
557 geoip_hf = hf_geoip_asnum;
558 geoip_local_hf = (isdst) ? hf_geoip_dst_asnum : hf_geoip_src_asnum;
559 break;
560 #endif /* DB_NUM_TYPES */
561 case WS_LAT_FAKE_EDITION:
562 geoip_hf = hf_geoip_lat;
563 geoip_local_hf = (isdst) ? hf_geoip_dst_lat : hf_geoip_src_lat;
564 break;
565 case WS_LON_FAKE_EDITION:
566 geoip_hf = hf_geoip_lon;
567 geoip_local_hf = (isdst) ? hf_geoip_dst_lon : hf_geoip_src_lon;
568 break;
569 default:
570 continue;
571 break;
574 if (geoip_str) {
575 proto_item *item;
576 if (db_type == WS_LAT_FAKE_EDITION || db_type == WS_LON_FAKE_EDITION) {
577 /* Convert latitude, longitude to double. Fix bug #5077 */
578 item = proto_tree_add_double_format_value(geoip_info_tree, geoip_local_hf, tvb,
579 offset, 16, g_ascii_strtod(geoip_str, NULL), "%s", geoip_str);
580 PROTO_ITEM_SET_GENERATED(item);
581 item = proto_tree_add_double_format_value(geoip_info_tree, geoip_hf, tvb,
582 offset, 16, g_ascii_strtod(geoip_str, NULL), "%s", geoip_str);
583 PROTO_ITEM_SET_GENERATED(item);
584 PROTO_ITEM_SET_HIDDEN(item);
585 } else {
586 item = proto_tree_add_unicode_string(geoip_info_tree, geoip_local_hf, tvb,
587 offset, 16, geoip_str);
588 PROTO_ITEM_SET_GENERATED(item);
589 item = proto_tree_add_unicode_string(geoip_info_tree, geoip_hf, tvb,
590 offset, 16, geoip_str);
591 PROTO_ITEM_SET_GENERATED(item);
592 PROTO_ITEM_SET_HIDDEN(item);
595 item_cnt++;
596 proto_item_append_text(geoip_info_item, "%s%s", plurality(item_cnt, "", ", "), geoip_str);
600 if (item_cnt == 0)
601 proto_item_append_text(geoip_info_item, "Unknown");
604 static void
605 add_geoip_info(proto_tree *tree, tvbuff_t *tvb, gint offset, const struct e_in6_addr *src, const struct e_in6_addr *dst)
607 guint num_dbs;
608 proto_item *geoip_info_item;
610 num_dbs = geoip_db_num_dbs();
611 if (num_dbs < 1)
612 return;
614 geoip_info_item = proto_tree_add_text(tree, tvb, offset + IP6H_SRC, 16, "Source GeoIP: ");
615 PROTO_ITEM_SET_GENERATED(geoip_info_item);
616 add_geoip_info_entry(geoip_info_item, tvb, offset + IP6H_SRC, src, 0);
618 geoip_info_item = proto_tree_add_text(tree, tvb, offset + IP6H_DST, 16, "Destination GeoIP: ");
619 PROTO_ITEM_SET_GENERATED(geoip_info_item);
620 add_geoip_info_entry(geoip_info_item, tvb, offset + IP6H_DST, dst, 1);
622 #endif /* HAVE_GEOIP_V6 */
624 static void
625 ipv6_reassemble_init(void)
627 reassembly_table_init(&ipv6_reassembly_table,
628 &addresses_reassembly_table_functions);
631 enum {
632 IPv6_RT_HEADER_SOURCE_ROUTING=0,
633 IPv6_RT_HEADER_NIMROD,
634 IPv6_RT_HEADER_MobileIP,
635 IPv6_RT_HEADER_RPL
638 /* Routing Header Types */
639 static const value_string routing_header_type[] = {
640 { IPv6_RT_HEADER_SOURCE_ROUTING, "IPv6 Source Routing" },
641 { IPv6_RT_HEADER_NIMROD, "Nimrod" },
642 { IPv6_RT_HEADER_MobileIP, "Mobile IP" },
643 { IPv6_RT_HEADER_RPL, "RPL" },
644 { 0, NULL }
647 static int
648 dissect_routing6(tvbuff_t *tvb, int offset, proto_tree *tree, packet_info *pinfo) {
649 struct ip6_rthdr rt;
650 guint len, seg_left;
651 proto_tree *rthdr_tree;
652 proto_item *ti;
653 guint8 buf[sizeof(struct ip6_rthdr0) + sizeof(struct e_in6_addr) * 23];
655 tvb_memcpy(tvb, (guint8 *)&rt, offset, sizeof(rt));
656 len = (rt.ip6r_len + 1) << 3;
658 /* Assigning seg_left and the if (seg_left) {} blocks of code that follow,
659 * along with any expert_add_info() calls, all need to execute when
660 * appropriate, regardless of whether the tree is NULL or not. */
661 if (1) {
662 /* !!! specify length */
663 ti = proto_tree_add_uint_format(tree, hf_ipv6_routing_hdr_opt, tvb,
664 offset, len, rt.ip6r_type,
665 "Routing Header, Type : %s (%u)",
666 val_to_str_const(rt.ip6r_type, routing_header_type, "Unknown"),
667 rt.ip6r_type);
668 rthdr_tree = proto_item_add_subtree(ti, ett_ipv6);
670 proto_tree_add_text(rthdr_tree, tvb,
671 offset + (int)offsetof(struct ip6_rthdr, ip6r_nxt), 1,
672 "Next header: %s (%u)", ipprotostr(rt.ip6r_nxt), rt.ip6r_nxt);
674 proto_tree_add_text(rthdr_tree, tvb,
675 offset + (int)offsetof(struct ip6_rthdr, ip6r_len), 1,
676 "Length: %u (%d bytes)", rt.ip6r_len, len);
678 proto_tree_add_item(rthdr_tree, hf_ipv6_routing_hdr_type, tvb,
679 offset + (int)offsetof(struct ip6_rthdr, ip6r_type), 1, ENC_BIG_ENDIAN);
681 proto_tree_add_item(rthdr_tree, hf_ipv6_routing_hdr_left, tvb,
682 offset + (int)offsetof(struct ip6_rthdr, ip6r_segleft), 1, ENC_BIG_ENDIAN);
684 seg_left = tvb_get_guint8(tvb, offset + (int)offsetof(struct ip6_rthdr, ip6r_segleft));
686 if (rt.ip6r_type == IPv6_RT_HEADER_SOURCE_ROUTING && len <= sizeof(buf)) {
687 struct e_in6_addr *a;
688 int n;
689 struct ip6_rthdr0 *rt0;
691 tvb_memcpy(tvb, buf, offset, len);
692 rt0 = (struct ip6_rthdr0 *)buf;
694 for (a = rt0->ip6r0_addr, n = 0;
695 a < (struct e_in6_addr *)(buf + len); a++, n++) {
697 proto_tree_add_item(rthdr_tree, hf_ipv6_routing_hdr_addr, tvb,
698 offset + (int)(offsetof(struct ip6_rthdr0, ip6r0_addr)
699 + n * sizeof(struct e_in6_addr)),
700 (int)sizeof(struct e_in6_addr), ENC_NA);
701 if (seg_left)
702 TVB_SET_ADDRESS(&pinfo->dst, AT_IPv6, tvb,
703 offset + (int)offsetof(struct ip6_rthdr0, ip6r0_addr) + n * (int)sizeof(struct e_in6_addr), 16);
706 if (rt.ip6r_type == IPv6_RT_HEADER_MobileIP) {
707 proto_tree_add_item(rthdr_tree, hf_ipv6_mipv6_home_address, tvb,
708 offset + 8, 16, ENC_NA);
709 if (seg_left)
710 TVB_SET_ADDRESS(&pinfo->dst, AT_IPv6, tvb, offset + 8, 16);
712 if (rt.ip6r_type == IPv6_RT_HEADER_RPL) {
713 guint8 cmprI;
714 guint8 cmprE;
715 guint8 pad;
716 guint32 reserved;
717 gint segments;
719 /* IPv6 destination address used for elided bytes */
720 struct e_in6_addr dstAddr;
721 /* IPv6 source address used for strict checking */
722 struct e_in6_addr srcAddr;
723 offset += 4;
724 memcpy((guint8 *)&dstAddr, (guint8 *)pinfo->dst.data, pinfo->dst.len);
725 memcpy((guint8 *)&srcAddr, (guint8 *)pinfo->src.data, pinfo->src.len);
727 /* from RFC6554: Multicast addresses MUST NOT appear in the IPv6 Destination Address field */
728 if(g_ipv6_rpl_srh_strict_rfc_checking && in6_is_addr_multicast(&dstAddr)){
729 expert_add_info(pinfo, ti, &ei_ipv6_dst_addr_not_multicast);
732 proto_tree_add_item(rthdr_tree, hf_ipv6_routing_hdr_rpl_cmprI, tvb, offset, 4, ENC_BIG_ENDIAN);
733 proto_tree_add_item(rthdr_tree, hf_ipv6_routing_hdr_rpl_cmprE, tvb, offset, 4, ENC_BIG_ENDIAN);
734 proto_tree_add_item(rthdr_tree, hf_ipv6_routing_hdr_rpl_pad, tvb, offset, 4, ENC_BIG_ENDIAN);
736 cmprI = tvb_get_guint8(tvb, offset) & 0xF0;
737 cmprE = tvb_get_guint8(tvb, offset) & 0x0F;
738 pad = tvb_get_guint8(tvb, offset + 1) & 0xF0;
740 /* Shift bytes over */
741 cmprI >>= 4;
742 pad >>= 4;
744 /* from RFC6554: when CmprI and CmprE are both 0, Pad MUST carry a value of 0 */
745 if(g_ipv6_rpl_srh_strict_rfc_checking && (cmprI == 0 && cmprE == 0 && pad != 0)){
746 expert_add_info_format(pinfo, ti, &ei_ipv6_cmpri_cmpre_pad, "When cmprI equals 0 and cmprE equals 0, pad MUST equal 0 but instead was %d", pad);
749 proto_tree_add_item(rthdr_tree, hf_ipv6_routing_hdr_rpl_reserved, tvb, offset, 4, ENC_BIG_ENDIAN);
750 reserved = tvb_get_bits32(tvb, ((offset + 1) * 8) + 4, 20, ENC_BIG_ENDIAN);
752 if(g_ipv6_rpl_srh_strict_rfc_checking && reserved != 0){
753 expert_add_info_format(pinfo, ti, &ei_ipv6_routing_hdr_rpl_reserved, "Reserved field must equal 0 but instead was %d", reserved);
756 /* from RFC6554:
757 n = (((Hdr Ext Len * 8) - Pad - (16 - CmprE)) / (16 - CmprI)) + 1 */
758 segments = (((rt.ip6r_len * 8) - pad - (16 - cmprE)) / (16 - cmprI)) + 1;
759 ti = proto_tree_add_int(rthdr_tree, hf_ipv6_routing_hdr_rpl_segments, tvb, offset, 2, segments);
760 PROTO_ITEM_SET_GENERATED(ti);
762 if (segments < 0) {
763 /* This error should always be reported */
764 expert_add_info_format(pinfo, ti, &ei_ipv6_routing_hdr_rpl_segments_ge0, "Calculated total segments must be greater than or equal to 0, instead was %d", segments);
765 } else {
767 offset += 4;
769 /* We use cmprI for internal (e.g.: not last) address for how many bytes to elide, so actual bytes present = 16-CmprI */
770 while(segments > 1) {
771 struct e_in6_addr addr;
773 proto_tree_add_item(rthdr_tree, hf_ipv6_routing_hdr_rpl_addr, tvb, offset, (16-cmprI), ENC_NA);
774 /* Display Full Address */
775 memcpy((guint8 *)&addr, (guint8 *)&dstAddr, sizeof(dstAddr));
776 tvb_memcpy(tvb, (guint8 *)&addr + cmprI, offset, (16-cmprI));
777 ti = proto_tree_add_ipv6(rthdr_tree, hf_ipv6_routing_hdr_rpl_fulladdr, tvb, offset, (16-cmprI), (guint8 *)&addr);
778 PROTO_ITEM_SET_GENERATED(ti);
779 offset += (16-cmprI);
780 segments--;
782 if(g_ipv6_rpl_srh_strict_rfc_checking){
783 /* from RFC6554: */
784 /* The SRH MUST NOT specify a path that visits a node more than once. */
785 /* To do this, we will just check the current 'addr' against the next addresses */
786 gint tempSegments;
787 gint tempOffset;
788 tempSegments = segments; /* Has already been decremented above */
789 tempOffset = offset; /* Has already been moved */
790 while(tempSegments > 1) {
791 struct e_in6_addr tempAddr;
792 memcpy((guint8 *)&tempAddr, (guint8 *)&dstAddr, sizeof(dstAddr));
793 tvb_memcpy(tvb, (guint8 *)&tempAddr + cmprI, tempOffset, (16-cmprI));
794 /* Compare the addresses */
795 if (memcmp(addr.bytes, tempAddr.bytes, 16) == 0) {
796 /* Found a later address that is the same */
797 expert_add_info(pinfo, ti, &ei_ipv6_src_route_list_mult_inst_same_addr);
798 break;
800 tempOffset += (16-cmprI);
801 tempSegments--;
803 if (tempSegments == 1) {
804 struct e_in6_addr tempAddr;
806 memcpy((guint8 *)&tempAddr, (guint8 *)&dstAddr, sizeof(dstAddr));
807 tvb_memcpy(tvb, (guint8 *)&tempAddr + cmprE, tempOffset, (16-cmprE));
808 /* Compare the addresses */
809 if (memcmp(addr.bytes, tempAddr.bytes, 16) == 0) {
810 /* Found a later address that is the same */
811 expert_add_info(pinfo, ti, &ei_ipv6_src_route_list_mult_inst_same_addr);
814 /* IPv6 Source and Destination addresses of the encapsulating datagram (MUST) not appear in the SRH*/
815 if (memcmp(addr.bytes, srcAddr.bytes, 16) == 0) {
816 expert_add_info(pinfo, ti, &ei_ipv6_src_route_list_src_addr);
819 if (memcmp(addr.bytes, dstAddr.bytes, 16) == 0) {
820 expert_add_info(pinfo, ti, &ei_ipv6_src_route_list_dst_addr);
823 /* Multicast addresses MUST NOT appear in the in SRH */
824 if(in6_is_addr_multicast(&addr)){
825 expert_add_info(pinfo, ti, &ei_ipv6_src_route_list_multicast_addr);
830 /* We use cmprE for last address for how many bytes to elide, so actual bytes present = 16-CmprE */
831 if (segments == 1) {
832 struct e_in6_addr addr;
834 proto_tree_add_item(rthdr_tree, hf_ipv6_routing_hdr_rpl_addr, tvb, offset, (16-cmprI), ENC_NA);
835 /* Display Full Address */
836 memcpy((guint8 *)&addr, (guint8 *)&dstAddr, sizeof(dstAddr));
837 tvb_memcpy(tvb, (guint8 *)&addr + cmprE, offset, (16-cmprE));
838 ti = proto_tree_add_ipv6(rthdr_tree, hf_ipv6_routing_hdr_rpl_fulladdr, tvb, offset, (16-cmprE), (guint8 *)&addr);
839 PROTO_ITEM_SET_GENERATED(ti);
840 /* offset += (16-cmprE); */
842 if(g_ipv6_rpl_srh_strict_rfc_checking){
843 /* IPv6 Source and Destination addresses of the encapsulating datagram (MUST) not appear in the SRH*/
844 if (memcmp(addr.bytes, srcAddr.bytes, 16) == 0) {
845 expert_add_info(pinfo, ti, &ei_ipv6_src_route_list_src_addr);
848 if (memcmp(addr.bytes, dstAddr.bytes, 16) == 0) {
849 expert_add_info(pinfo, ti, &ei_ipv6_src_route_list_dst_addr);
852 /* Multicast addresses MUST NOT appear in the in SRH */
853 if(in6_is_addr_multicast(&addr)){
854 expert_add_info(pinfo, ti, &ei_ipv6_src_route_list_multicast_addr);
862 return len;
865 static int
866 dissect_frag6(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree,
867 guint16 *offlg, guint32 *ident) {
868 struct ip6_frag frag;
869 int len;
870 proto_item *ti;
871 proto_tree *rthdr_tree;
873 tvb_memcpy(tvb, (guint8 *)&frag, offset, sizeof(frag));
874 len = sizeof(frag);
875 frag.ip6f_offlg = g_ntohs(frag.ip6f_offlg);
876 frag.ip6f_ident = g_ntohl(frag.ip6f_ident);
877 *offlg = frag.ip6f_offlg;
878 *ident = frag.ip6f_ident;
879 col_add_fstr(pinfo->cinfo, COL_INFO,
880 "IPv6 fragment (nxt=%s (%u) off=%u id=0x%x)",
881 ipprotostr(frag.ip6f_nxt), frag.ip6f_nxt,
882 (frag.ip6f_offlg & IP6F_OFF_MASK) >> IP6F_OFF_SHIFT, frag.ip6f_ident);
884 if (tree) {
885 ti = proto_tree_add_text(tree, tvb, offset, len,
886 "Fragmentation Header");
887 rthdr_tree = proto_item_add_subtree(ti, ett_ipv6);
889 proto_tree_add_item(rthdr_tree, hf_ipv6_frag_nxt, tvb,
890 offset + (int)offsetof(struct ip6_frag, ip6f_nxt), 1,
891 ENC_BIG_ENDIAN);
893 proto_tree_add_item(rthdr_tree, hf_ipv6_frag_reserved, tvb,
894 offset + (int)offsetof(struct ip6_frag, ip6f_reserved), 1,
895 ENC_BIG_ENDIAN);
897 proto_tree_add_item(rthdr_tree, hf_ipv6_frag_offset, tvb,
898 offset + (int)offsetof(struct ip6_frag, ip6f_offlg), 2, ENC_BIG_ENDIAN);
899 proto_tree_add_item(rthdr_tree, hf_ipv6_frag_reserved_bits, tvb,
900 offset + (int)offsetof(struct ip6_frag, ip6f_offlg), 2, ENC_BIG_ENDIAN);
901 proto_tree_add_item(rthdr_tree, hf_ipv6_frag_more, tvb,
902 offset + (int)offsetof(struct ip6_frag, ip6f_offlg), 2, ENC_BIG_ENDIAN);
903 proto_tree_add_item(rthdr_tree, hf_ipv6_frag_id, tvb,
904 offset + (int)offsetof(struct ip6_frag, ip6f_ident), 4, ENC_BIG_ENDIAN);
906 return len;
909 static const value_string rtalertvals[] = {
910 { IP6OPT_RTALERT_MLD, "MLD" },
911 { IP6OPT_RTALERT_RSVP, "RSVP" },
912 { IP6OPT_RTALERT_ACTNET, "Active Network" },
913 { 0, NULL }
916 static int
917 dissect_unknown_option(tvbuff_t *tvb, int offset, proto_tree *tree)
919 int len;
920 proto_tree *unkopt_tree;
921 proto_item *ti, *ti_len;
923 len = (tvb_get_guint8(tvb, offset + 1) + 1) << 3;
925 if (tree) {
926 /* !!! specify length */
927 ti = proto_tree_add_item(tree, hf_ipv6_unk_hdr, tvb, offset, len, ENC_NA);
929 unkopt_tree = proto_item_add_subtree(ti, ett_ipv6);
931 proto_tree_add_item(unkopt_tree, hf_ipv6_nxt, tvb, offset, 1, ENC_NA);
932 offset += 1;
934 ti_len = proto_tree_add_item(unkopt_tree, hf_ipv6_opt_length, tvb, offset, 1, ENC_NA);
935 proto_item_append_text(ti_len, " (%d byte%s)", len, plurality(len, "", "s"));
936 /* offset += 1; */
938 return len;
941 static int
942 dissect_opts(tvbuff_t *tvb, int offset, proto_tree *tree, packet_info * pinfo, const int hf_option_item)
944 int len;
945 int offset_end;
946 proto_tree *dstopt_tree, *opt_tree;
947 proto_item *ti, *ti_len, *ti_opt, *ti_opt_len;
948 guint8 opt_len, opt_type;
950 len = (tvb_get_guint8(tvb, offset + 1) + 1) << 3;
951 offset_end = offset + len;
953 if (tree) {
954 /* !!! specify length */
955 ti = proto_tree_add_item(tree, hf_option_item, tvb, offset, len, ENC_NA);
957 dstopt_tree = proto_item_add_subtree(ti, ett_ipv6);
959 proto_tree_add_item(dstopt_tree, hf_ipv6_nxt, tvb, offset, 1, ENC_NA);
960 offset += 1;
962 ti_len = proto_tree_add_item(dstopt_tree, hf_ipv6_opt_length, tvb, offset, 1, ENC_NA);
963 proto_item_append_text(ti_len, " (%d byte%s)", len, plurality(len, "", "s"));
964 offset += 1;
966 while (offset_end > offset) {
967 /* there are more options */
969 /* IPv6 Option */
970 ti_opt = proto_tree_add_item(dstopt_tree, hf_ipv6_opt, tvb, offset, 1, ENC_NA);
971 opt_tree = proto_item_add_subtree(ti_opt, ett_ipv6_opt);
973 /* Option type */
974 proto_tree_add_item(opt_tree, hf_ipv6_opt_type, tvb, offset, 1, ENC_BIG_ENDIAN);
975 opt_type = tvb_get_guint8(tvb, offset);
977 /* Add option name to option root label */
978 proto_item_append_text(ti_opt, " (%s", val_to_str(opt_type, ipv6_opt_vals, "Unknown %d"));
980 /* The Pad1 option is a special case, and contains no data. */
981 if (opt_type == IP6OPT_PAD1) {
982 proto_tree_add_item(opt_tree, hf_ipv6_opt_pad1, tvb, offset, 1, ENC_NA);
983 offset += 1;
984 proto_item_append_text(ti_opt, ")");
985 continue;
987 offset += 1;
989 /* Option length */
990 ti_opt_len = proto_tree_add_item(opt_tree, hf_ipv6_opt_length, tvb, offset, 1, ENC_BIG_ENDIAN);
991 opt_len = tvb_get_guint8(tvb, offset);
992 proto_item_set_len(ti_opt, opt_len + 2);
993 offset += 1;
995 switch (opt_type) {
996 case IP6OPT_PADN:
997 /* RFC 2460 states :
998 * "The PadN option is used to insert two or more octets of
999 * padding into the Options area of a header. For N octets of
1000 * padding, the Opt Data Len field contains the value N-2, and
1001 * the Option Data consists of N-2 zero-valued octets."
1003 proto_tree_add_item(opt_tree, hf_ipv6_opt_padn, tvb,
1004 offset, opt_len, ENC_NA);
1005 offset += opt_len;
1006 break;
1007 case IP6OPT_TEL:
1008 if (opt_len != 1) {
1009 expert_add_info_format(pinfo, ti_opt_len, &ei_ipv6_opt_tel_invalid_len,
1010 "Tunnel Encapsulation Limit: Invalid length (%u bytes)", opt_len);
1012 proto_tree_add_item(opt_tree, hf_ipv6_opt_tel, tvb,
1013 offset, 1, ENC_BIG_ENDIAN);
1014 offset += 1;
1015 break;
1016 case IP6OPT_JUMBO:
1017 if (opt_len != 4) {
1018 expert_add_info_format(pinfo, ti_opt_len, &ei_ipv6_opt_jumbo_invalid_len,
1019 "Jumbo payload: Invalid length (%u bytes)", opt_len);
1021 proto_tree_add_item(opt_tree, hf_ipv6_opt_jumbo, tvb,
1022 offset, 4, ENC_BIG_ENDIAN);
1023 offset += 4;
1024 break;
1025 case IP6OPT_RTALERT:
1027 if (opt_len != 2) {
1028 expert_add_info_format(pinfo, ti_opt_len, &ei_ipv6_opt_rtalert_invalid_len,
1029 "Router alert: Invalid Length (%u bytes)",
1030 opt_len + 2);
1032 proto_tree_add_item(opt_tree, hf_ipv6_opt_rtalert, tvb,
1033 offset, 2, ENC_BIG_ENDIAN);
1034 offset += 2;
1035 break;
1037 case IP6OPT_HOME_ADDRESS:
1038 if (opt_len != 16) {
1039 expert_add_info_format(pinfo, ti_opt_len, &ei_ipv6_mipv6_home_address_invalid_len,
1040 "Home Address: Invalid length (%u bytes)", opt_len);
1042 proto_tree_add_item(opt_tree, hf_ipv6_mipv6_home_address, tvb,
1043 offset, 16, ENC_NA);
1044 TVB_SET_ADDRESS(&pinfo->src, AT_IPv6, tvb, offset, 16);
1045 offset += 16;
1046 break;
1047 case IP6OPT_CALIPSO:
1049 guint8 cmpt_length;
1050 proto_tree_add_item(opt_tree, hf_ipv6_opt_calipso_doi, tvb,
1051 offset, 4, ENC_BIG_ENDIAN);
1052 offset += 4;
1053 proto_tree_add_item(opt_tree, hf_ipv6_opt_calipso_cmpt_length, tvb,
1054 offset, 1, ENC_BIG_ENDIAN);
1055 cmpt_length = tvb_get_guint8(tvb, offset);
1056 offset += 1;
1057 proto_tree_add_item(opt_tree, hf_ipv6_opt_calipso_sens_level, tvb,
1058 offset, 1, ENC_BIG_ENDIAN);
1059 offset += 1;
1060 /* Need to add Check Checksum..*/
1061 proto_tree_add_item(opt_tree, hf_ipv6_opt_calipso_checksum, tvb,
1062 offset, 2, ENC_BIG_ENDIAN);
1063 offset += 2;
1064 proto_tree_add_item(opt_tree, hf_ipv6_opt_calipso_cmpt_bitmap, tvb,
1065 offset, cmpt_length, ENC_NA);
1066 offset += cmpt_length;
1067 break;
1069 case IP6OPT_QUICKSTART:
1072 guint8 command = tvb_get_guint8(tvb, offset);
1073 guint8 function = command >> 4;
1074 guint8 rate = command & QS_RATE_MASK;
1075 guint8 ttl_diff;
1077 proto_tree_add_item(opt_tree, hf_ipv6_opt_qs_func, tvb, offset, 1, ENC_NA);
1079 if (function == QS_RATE_REQUEST) {
1080 proto_tree_add_item(opt_tree, hf_ipv6_opt_qs_rate, tvb, offset, 1, ENC_NA);
1081 offset += 1;
1082 proto_tree_add_item(opt_tree, hf_ipv6_opt_qs_ttl, tvb, offset, 1, ENC_NA);
1083 ttl_diff = (pinfo->ip_ttl - tvb_get_guint8(tvb, offset) % 256);
1084 offset += 1;
1085 ti = proto_tree_add_uint_format_value(opt_tree, hf_ipv6_opt_qs_ttl_diff,
1086 tvb, offset, 1, ttl_diff,
1087 "%u", ttl_diff);
1088 PROTO_ITEM_SET_GENERATED(ti);
1089 proto_item_append_text(ti_opt, ", %s, QS TTL %u, QS TTL diff %u",
1090 val_to_str_ext(rate, &qs_rate_vals_ext, "Unknown (%u)"),
1091 tvb_get_guint8(tvb, offset), ttl_diff);
1092 offset += 1;
1093 proto_tree_add_item(opt_tree, hf_ipv6_opt_qs_nonce, tvb, offset, 4, ENC_NA);
1094 proto_tree_add_item(opt_tree, hf_ipv6_opt_qs_reserved, tvb, offset, 4, ENC_NA);
1095 offset += 4;
1096 } else if (function == QS_RATE_REPORT) {
1097 proto_tree_add_item(opt_tree, hf_ipv6_opt_qs_rate, tvb, offset, 1, ENC_NA);
1098 offset += 1;
1099 proto_item_append_text(ti_opt, ", %s",
1100 val_to_str_ext(rate, &qs_rate_vals_ext, "Unknown (%u)"));
1101 proto_tree_add_item(opt_tree, hf_ipv6_opt_qs_unused, tvb, offset, 1, ENC_NA);
1102 offset += 1;
1103 proto_tree_add_item(opt_tree, hf_ipv6_opt_qs_nonce, tvb, offset, 4, ENC_NA);
1104 proto_tree_add_item(opt_tree, hf_ipv6_opt_qs_reserved, tvb, offset, 4, ENC_NA);
1105 offset += 4;
1109 break;
1110 case IP6OPT_RPL:
1112 proto_tree *flag_tree;
1113 proto_item *ti_flag;
1115 ti_flag = proto_tree_add_item(opt_tree, hf_ipv6_opt_rpl_flag, tvb, offset, 1, ENC_BIG_ENDIAN);
1116 flag_tree = proto_item_add_subtree(ti_flag, ett_ipv6_opt_flag);
1117 proto_tree_add_item(flag_tree, hf_ipv6_opt_rpl_flag_o, tvb, offset, 1, ENC_BIG_ENDIAN);
1118 proto_tree_add_item(flag_tree, hf_ipv6_opt_rpl_flag_r, tvb, offset, 1, ENC_BIG_ENDIAN);
1119 proto_tree_add_item(flag_tree, hf_ipv6_opt_rpl_flag_f, tvb, offset, 1, ENC_BIG_ENDIAN);
1120 proto_tree_add_item(flag_tree, hf_ipv6_opt_rpl_flag_rsv, tvb, offset, 1, ENC_BIG_ENDIAN);
1121 offset +=1;
1123 proto_tree_add_item(flag_tree, hf_ipv6_opt_rpl_instance_id, tvb, offset, 1, ENC_BIG_ENDIAN);
1124 offset +=1;
1126 proto_tree_add_item(flag_tree, hf_ipv6_opt_rpl_senderrank, tvb, offset, 2, ENC_BIG_ENDIAN);
1127 offset +=2;
1129 /* TODO: Add dissector of sub TLV */
1131 break;
1132 case IP6OPT_EXP_1E:
1133 case IP6OPT_EXP_3E:
1134 case IP6OPT_EXP_5E:
1135 case IP6OPT_EXP_7E:
1136 case IP6OPT_EXP_9E:
1137 case IP6OPT_EXP_BE:
1138 case IP6OPT_EXP_DE:
1139 case IP6OPT_EXP_FE:
1140 proto_tree_add_item(opt_tree, hf_ipv6_opt_experimental, tvb,
1141 offset, opt_len, ENC_NA);
1142 offset += opt_len;
1143 break;
1144 default:
1145 proto_tree_add_item(opt_tree, hf_ipv6_opt_unknown, tvb,
1146 offset, opt_len, ENC_NA);
1147 offset += opt_len;
1148 break;
1150 /* Close the ) to option root label */
1151 proto_item_append_text(ti_opt, ")");
1155 return len;
1158 static int
1159 dissect_hopopts(tvbuff_t *tvb, int offset, proto_tree *tree, packet_info * pinfo)
1161 return dissect_opts(tvb, offset, tree, pinfo, hf_ipv6_hop_opt);
1164 static int
1165 dissect_dstopts(tvbuff_t *tvb, int offset, proto_tree *tree, packet_info * pinfo)
1167 return dissect_opts(tvb, offset, tree, pinfo, hf_ipv6_dst_opt);
1170 /* START SHIM6 PART */
1171 static guint16 shim_checksum(const guint8 *ptr, int len)
1173 vec_t cksum_vec[1];
1175 cksum_vec[0].ptr = ptr;
1176 cksum_vec[0].len = len;
1177 return in_cksum(&cksum_vec[0], 1);
1180 static int
1181 dissect_shim_hex(tvbuff_t *tvb, int offset, int len, const char *itemname, guint8 bitmask, proto_tree *tree)
1183 proto_item *ti;
1184 int count;
1185 gint p;
1187 p = offset;
1189 ti = proto_tree_add_text(tree, tvb, offset, len, "%s", itemname);
1191 proto_item_append_text(ti, " 0x%02x", tvb_get_guint8(tvb, p) & bitmask);
1192 for (count=1; count<len; count++)
1193 proto_item_append_text(ti, "%02x", tvb_get_guint8(tvb, p+count));
1195 return len;
1198 static const value_string shimoptvals[] = {
1199 { SHIM6_OPT_RESPVAL, "Responder Validator Option" },
1200 { SHIM6_OPT_LOCLIST, "Locator List Option" },
1201 { SHIM6_OPT_LOCPREF, "Locator Preferences Option" },
1202 { SHIM6_OPT_CGAPDM, "CGA Parameter Data Structure Option" },
1203 { SHIM6_OPT_CGASIG, "CGA Signature Option" },
1204 { SHIM6_OPT_ULIDPAIR, "ULID Pair Option" },
1205 { SHIM6_OPT_FII, "Forked Instance Identifier Option" },
1206 { 0, NULL }
1209 static const value_string shimverifmethods[] = {
1210 { SHIM6_VERIF_HBA, "HBA" },
1211 { SHIM6_VERIF_CGA, "CGA" },
1212 { 0, NULL }
1215 static const value_string shimflags[] _U_ = {
1216 { SHIM6_FLAG_BROKEN, "BROKEN" },
1217 { SHIM6_FLAG_TEMPORARY, "TEMPORARY" },
1218 { 0, NULL }
1221 static const value_string shimreapstates[] = {
1222 { SHIM6_REAP_OPERATIONAL, "Operational" },
1223 { SHIM6_REAP_EXPLORING, "Exploring" },
1224 { SHIM6_REAP_INBOUNDOK, "InboundOK" },
1225 { 0, NULL }
1228 static const value_string shim6_protocol[] = {
1229 { 0, "SHIM6" },
1230 { 1, "HIP" },
1231 { 0, NULL }
1235 static void
1236 dissect_shim6_opt_loclist(proto_tree * opt_tree, tvbuff_t * tvb, gint *offset)
1238 proto_item * it;
1239 proto_tree * subtree;
1240 guint count;
1241 guint optlen;
1242 int p = *offset;
1244 proto_tree_add_item(opt_tree, hf_ipv6_shim6_opt_loclist, tvb, p, 4, ENC_BIG_ENDIAN);
1245 p += 4;
1247 optlen = tvb_get_guint8(tvb, p);
1248 proto_tree_add_item(opt_tree, hf_ipv6_shim6_opt_locnum, tvb, p, 1, ENC_BIG_ENDIAN);
1249 p++;
1251 /* Verification Methods */
1252 it = proto_tree_add_text(opt_tree, tvb, p, optlen,
1253 "Locator Verification Methods");
1254 subtree = proto_item_add_subtree(it, ett_ipv6_shim6_verif_methods);
1256 for (count=0; count < optlen; count++)
1257 proto_tree_add_item(subtree, hf_ipv6_shim6_opt_loc_verif_methods, tvb,
1258 p+count, 1, ENC_BIG_ENDIAN);
1259 p += optlen;
1261 /* Padding, included in length field */
1262 if ((7 - optlen % 8) > 0) {
1263 proto_tree_add_text(opt_tree, tvb, p, (7 - optlen % 8), "Padding");
1264 p += (7 - optlen % 8);
1267 /* Locators */
1268 it = proto_tree_add_text(opt_tree, tvb, p, 16 * optlen, "Locators");
1269 subtree = proto_item_add_subtree(it, ett_ipv6_shim6_locators);
1271 for (count=0; count < optlen; count++) {
1272 proto_tree_add_item(subtree, hf_ipv6_shim6_locator, tvb, p, 16, ENC_NA);
1273 p += 16;
1275 *offset = p;
1278 static void
1279 dissect_shim6_opt_loc_pref(proto_tree * opt_tree, tvbuff_t * tvb, gint *offset, gint len, packet_info *pinfo)
1281 proto_tree * subtree;
1282 proto_item * it;
1284 gint p;
1285 gint optlen;
1286 gint count;
1288 p = *offset;
1290 proto_tree_add_item(opt_tree, hf_ipv6_shim6_opt_loclist, tvb, p, 4, ENC_BIG_ENDIAN);
1291 p += 4;
1293 optlen = tvb_get_guint8(tvb, p);
1294 proto_tree_add_item(opt_tree, hf_ipv6_shim6_opt_elemlen, tvb, p, 1, ENC_BIG_ENDIAN);
1296 if (optlen < 1 || optlen > 3) {
1297 proto_tree_add_expert_format(opt_tree, pinfo, &ei_ipv6_shim6_opt_elemlen_invalid, tvb, p, 1,
1298 "Invalid element length: %u", optlen);
1299 return;
1302 p++;
1304 /* Locator Preferences */
1305 count = 1;
1306 while (p < len) {
1307 it = proto_tree_add_text(opt_tree, tvb, p, optlen, "Locator Preferences %u", count);
1308 subtree = proto_item_add_subtree(it, ett_ipv6_shim6_loc_pref);
1310 /* Flags */
1311 if (optlen >= 1)
1312 proto_tree_add_item(subtree, hf_ipv6_shim6_loc_flag, tvb, p, 1, ENC_BIG_ENDIAN);
1313 /* Priority */
1314 if (optlen >= 2)
1315 proto_tree_add_item(subtree, hf_ipv6_shim6_loc_prio, tvb, p+1, 1, ENC_BIG_ENDIAN);
1316 /* Weight */
1317 if (optlen >= 3)
1318 proto_tree_add_item(subtree, hf_ipv6_shim6_loc_weight, tvb, p+2, 1, ENC_BIG_ENDIAN);
1320 * Shim6 Draft 08 doesn't specify the format when the Element length is
1321 * more than three, except that any such formats MUST be defined so that
1322 * the first three octets are the same as in the above case, that is, a
1323 * of a 1 octet flags field followed by a 1 octet priority field, and a
1324 * 1 octet weight field.
1326 p += optlen;
1327 count++;
1329 *offset = p;
1333 static int
1334 dissect_shimopts(tvbuff_t *tvb, int offset, proto_tree *tree, packet_info *pinfo)
1336 int len, total_len;
1337 gint p;
1338 gint padding;
1339 proto_tree *opt_tree;
1340 proto_item *ti;
1341 const gchar *ctype;
1344 p = offset;
1346 p += 4;
1348 len = tvb_get_ntohs(tvb, offset+2);
1349 padding = 7 - ((len + 3) % 8);
1350 total_len = 4 + len + padding;
1352 if (tree)
1354 /* Option Type */
1355 ctype = val_to_str_const( (tvb_get_ntohs(tvb, offset) & SHIM6_BITMASK_OPT_TYPE) >> 1, shimoptvals, "Unknown Option Type");
1356 ti = proto_tree_add_text(tree, tvb, offset, total_len, "%s", ctype);
1357 opt_tree = proto_item_add_subtree(ti, ett_ipv6_shim6_option);
1359 proto_tree_add_item(opt_tree, hf_ipv6_shim6_opt_type, tvb, offset, 2, ENC_BIG_ENDIAN);
1361 /* Critical */
1362 proto_tree_add_item(opt_tree, hf_ipv6_shim6_opt_critical, tvb, offset+1, 1, ENC_BIG_ENDIAN);
1364 /* Content Length */
1365 proto_tree_add_item(opt_tree, hf_ipv6_shim6_opt_len, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
1366 ti = proto_tree_add_uint(opt_tree, hf_ipv6_shim6_opt_total_len, tvb, offset+2, 2, total_len);
1367 PROTO_ITEM_SET_GENERATED(ti);
1369 /* Option Type Specific */
1370 switch (tvb_get_ntohs(tvb, offset) >> 1)
1372 case SHIM6_OPT_RESPVAL:
1373 p += dissect_shim_hex(tvb, p, len, "Validator:", 0xff, opt_tree);
1374 if (total_len-(len+4) > 0)
1375 proto_tree_add_text(opt_tree, tvb, p, total_len-(len+4), "Padding");
1376 break;
1377 case SHIM6_OPT_LOCLIST:
1378 dissect_shim6_opt_loclist(opt_tree, tvb, &p);
1379 break;
1380 case SHIM6_OPT_LOCPREF:
1381 dissect_shim6_opt_loc_pref(opt_tree, tvb, &p, offset+len+4, pinfo);
1382 if (total_len-(len+4) > 0)
1383 proto_tree_add_text(opt_tree, tvb, p, total_len-(len+4), "Padding");
1384 break;
1385 case SHIM6_OPT_CGAPDM:
1386 p += dissect_shim_hex(tvb, p, len, "CGA Parameter Data Structure:", 0xff, opt_tree);
1387 if (total_len-(len+4) > 0)
1388 proto_tree_add_text(opt_tree, tvb, p, total_len-(len+4), "Padding");
1389 break;
1390 case SHIM6_OPT_CGASIG:
1391 p += dissect_shim_hex(tvb, p, len, "CGA Signature:", 0xff, opt_tree);
1392 if (total_len-(len+4) > 0)
1393 proto_tree_add_text(opt_tree, tvb, p, total_len-(len+4), "Padding");
1394 break;
1395 case SHIM6_OPT_ULIDPAIR:
1396 proto_tree_add_text(opt_tree, tvb, p, 4, "Reserved");
1397 p += 4;
1398 proto_tree_add_item(opt_tree, hf_ipv6_shim6_sulid, tvb, p, 16, ENC_NA);
1399 p += 16;
1400 proto_tree_add_item(opt_tree, hf_ipv6_shim6_rulid, tvb, p, 16, ENC_NA);
1401 p += 16;
1402 break;
1403 case SHIM6_OPT_FII:
1404 proto_tree_add_item(opt_tree, hf_ipv6_shim6_opt_fii, tvb, p, 4, ENC_BIG_ENDIAN);
1405 p += 4;
1406 break;
1407 default:
1408 break;
1411 return total_len;
1414 static void
1415 dissect_shim6_ct(proto_tree * shim_tree, gint hf_item, tvbuff_t * tvb, gint offset, const guchar * label)
1417 guint8 tmp[6];
1418 guchar * ct_str;
1420 tmp[0] = tvb_get_guint8(tvb, offset++);
1421 tmp[1] = tvb_get_guint8(tvb, offset++);
1422 tmp[2] = tvb_get_guint8(tvb, offset++);
1423 tmp[3] = tvb_get_guint8(tvb, offset++);
1424 tmp[4] = tvb_get_guint8(tvb, offset++);
1425 tmp[5] = tvb_get_guint8(tvb, offset++);
1427 ct_str = wmem_strdup_printf(wmem_packet_scope(),
1428 "%s: %02X %02X %02X %02X %02X %02X", label,
1429 tmp[0] & SHIM6_BITMASK_CT, tmp[1], tmp[2],
1430 tmp[3], tmp[4], tmp[5]
1432 proto_tree_add_none_format(shim_tree, hf_item, tvb, offset - 6, 6, "%s", ct_str);
1435 static void
1436 dissect_shim6_probes(proto_tree * shim_tree, tvbuff_t * tvb, gint offset,
1437 const guchar * label, guint nbr_probe,
1438 gboolean probes_rcvd)
1440 proto_tree * probes_tree;
1441 proto_tree * probe_tree;
1442 proto_item * it;
1443 gint ett_probes;
1444 gint ett_probe;
1445 guint count;
1447 if (probes_rcvd) {
1448 ett_probes = ett_ipv6_shim6_probes_rcvd;
1449 ett_probe = ett_ipv6_shim6_probe_rcvd;
1450 } else {
1451 ett_probes = ett_ipv6_shim6_probes_sent;
1452 ett_probe = ett_ipv6_shim6_probe_sent;
1454 it = proto_tree_add_text(shim_tree, tvb, offset, 40 * nbr_probe, "%s", label);
1455 probes_tree = proto_item_add_subtree(it, ett_probes);
1457 for (count=0; count < nbr_probe; count++) {
1458 it = proto_tree_add_text(probes_tree, tvb, offset, 40, "Probe %u", count+1);
1459 probe_tree = proto_item_add_subtree(it, ett_probe);
1461 proto_tree_add_item(probe_tree, hf_ipv6_shim6_psrc, tvb, offset, 16, ENC_NA);
1462 offset += 16;
1463 proto_tree_add_item(probe_tree, hf_ipv6_shim6_pdst, tvb, offset, 16, ENC_NA);
1464 offset += 16;
1466 proto_tree_add_item(probe_tree, hf_ipv6_shim6_pnonce, tvb, offset, 4, ENC_BIG_ENDIAN);
1467 offset += 4;
1469 proto_tree_add_item(probe_tree, hf_ipv6_shim6_pdata, tvb, offset, 4, ENC_BIG_ENDIAN);
1470 offset += 4;
1474 /* Dissect SHIM6 data: control messages */
1475 static int
1476 dissect_shimctrl(tvbuff_t *tvb, gint offset, guint type, proto_tree *shim_tree)
1478 gint p;
1479 guint8 tmp;
1480 const gchar *sta;
1481 guint probes_sent;
1482 guint probes_rcvd;
1484 p = offset;
1486 switch (type)
1488 case SHIM6_TYPE_I1:
1489 dissect_shim6_ct(shim_tree, hf_ipv6_shim6_ct, tvb, p, "Initiator Context Tag");
1490 p += 6;
1491 proto_tree_add_item(shim_tree, hf_ipv6_shim6_inonce, tvb, p, 4, ENC_BIG_ENDIAN);
1492 p += 4;
1493 break;
1494 case SHIM6_TYPE_R1:
1495 proto_tree_add_text(shim_tree, tvb, p, 2, "Reserved2");
1496 p += 2;
1497 proto_tree_add_item(shim_tree, hf_ipv6_shim6_inonce, tvb, p, 4, ENC_BIG_ENDIAN);
1498 p += 4;
1499 proto_tree_add_item(shim_tree, hf_ipv6_shim6_rnonce, tvb, p, 4, ENC_BIG_ENDIAN);
1500 p += 4;
1501 break;
1502 case SHIM6_TYPE_I2:
1503 dissect_shim6_ct(shim_tree, hf_ipv6_shim6_ct, tvb, p, "Initiator Context Tag");
1504 p += 6;
1505 proto_tree_add_item(shim_tree, hf_ipv6_shim6_inonce, tvb, p, 4, ENC_BIG_ENDIAN);
1506 p += 4;
1507 proto_tree_add_item(shim_tree, hf_ipv6_shim6_rnonce, tvb, p, 4, ENC_BIG_ENDIAN);
1508 p += 4;
1509 proto_tree_add_text(shim_tree, tvb, p, 4, "Reserved2");
1510 p += 4;
1511 break;
1512 case SHIM6_TYPE_R2:
1513 dissect_shim6_ct(shim_tree, hf_ipv6_shim6_ct, tvb, p, "Responder Context Tag");
1514 p += 6;
1515 proto_tree_add_item(shim_tree, hf_ipv6_shim6_inonce, tvb, p, 4, ENC_BIG_ENDIAN);
1516 p += 4;
1517 break;
1518 case SHIM6_TYPE_R1BIS:
1519 dissect_shim6_ct(shim_tree, hf_ipv6_shim6_ct, tvb, p, "Packet Context Tag");
1520 p += 6;
1521 proto_tree_add_item(shim_tree, hf_ipv6_shim6_rnonce, tvb, p, 4, ENC_BIG_ENDIAN);
1522 p += 4;
1523 break;
1524 case SHIM6_TYPE_I2BIS:
1525 dissect_shim6_ct(shim_tree, hf_ipv6_shim6_ct, tvb, p, "Initiator Context Tag");
1526 p += 6;
1527 proto_tree_add_item(shim_tree, hf_ipv6_shim6_inonce, tvb, p, 4, ENC_BIG_ENDIAN);
1528 p += 4;
1529 proto_tree_add_item(shim_tree, hf_ipv6_shim6_rnonce, tvb, p, 4, ENC_BIG_ENDIAN);
1530 p += 4;
1531 proto_tree_add_text(shim_tree, tvb, p, 6, "Reserved2");
1532 p += 6;
1533 dissect_shim6_ct(shim_tree, hf_ipv6_shim6_ct, tvb, p, "Initiator Context Tag");
1534 p += 6;
1535 break;
1536 case SHIM6_TYPE_UPD_REQ:
1537 case SHIM6_TYPE_UPD_ACK:
1538 dissect_shim6_ct(shim_tree, hf_ipv6_shim6_ct, tvb, p, "Receiver Context Tag");
1539 p += 6;
1540 proto_tree_add_item(shim_tree, hf_ipv6_shim6_rnonce, tvb, p, 4, ENC_BIG_ENDIAN);
1541 p += 4;
1542 break;
1543 case SHIM6_TYPE_KEEPALIVE:
1544 dissect_shim6_ct(shim_tree, hf_ipv6_shim6_ct, tvb, p, "Receiver Context Tag");
1545 p += 6;
1546 proto_tree_add_text(shim_tree, tvb, p, 4, "Reserved2");
1547 p += 4;
1548 break;
1549 case SHIM6_TYPE_PROBE:
1550 dissect_shim6_ct(shim_tree, hf_ipv6_shim6_ct, tvb, p, "Receiver Context Tag");
1551 p += 6;
1553 tmp = tvb_get_guint8(tvb, p);
1554 probes_sent = tmp & SHIM6_BITMASK_PSENT;
1555 probes_rcvd = (tmp & SHIM6_BITMASK_PRECVD) >> 4;
1556 proto_tree_add_item(shim_tree, hf_ipv6_shim6_psent, tvb,
1557 p, 1, ENC_BIG_ENDIAN);
1558 proto_tree_add_item(shim_tree, hf_ipv6_shim6_precvd, tvb,
1559 p, 1, ENC_BIG_ENDIAN);
1560 p++;
1562 sta = val_to_str_const((tvb_get_guint8(tvb, p) & SHIM6_BITMASK_STA) >> 6,
1563 shimreapstates, "Unknown REAP State");
1564 proto_tree_add_uint_format_value(shim_tree, hf_ipv6_shim6_reap, tvb,
1565 p, 1, (tvb_get_guint8(tvb, p) & SHIM6_BITMASK_STA) >> 6,
1566 "%s", sta);
1568 proto_tree_add_text(shim_tree, tvb, p, 3, "Reserved2");
1569 p += 3;
1571 /* Probes Sent */
1572 if (probes_sent) {
1573 dissect_shim6_probes(shim_tree, tvb, p, "Probes Sent",
1574 probes_sent, FALSE);
1575 p += 40 * probes_sent;
1578 /* Probes Received */
1579 if (probes_rcvd) {
1580 dissect_shim6_probes(shim_tree, tvb, p, "Probes Received",
1581 probes_rcvd, TRUE);
1582 p += 40 * probes_rcvd;
1584 break;
1585 default:
1586 break;
1588 return p-offset;
1591 /* Dissect SHIM6 data: payload, common part, options */
1592 static const value_string shimctrlvals[] = {
1593 { SHIM6_TYPE_I1, "I1" },
1594 { SHIM6_TYPE_R1, "R1" },
1595 { SHIM6_TYPE_I2, "I2" },
1596 { SHIM6_TYPE_R2, "R2" },
1597 { SHIM6_TYPE_R1BIS, "R1bis" },
1598 { SHIM6_TYPE_I2BIS, "I2bis" },
1599 { SHIM6_TYPE_UPD_REQ, "Update Request" },
1600 { SHIM6_TYPE_UPD_ACK, "Update Acknowledgment" },
1601 { SHIM6_TYPE_KEEPALIVE, "Keepalive" },
1602 { SHIM6_TYPE_PROBE, "Probe" },
1603 { 0, NULL }
1606 static void ipv6_shim6_checkum_additional_info(tvbuff_t * tvb, packet_info * pinfo,
1607 proto_item * it_cksum, int offset, gboolean is_cksum_correct)
1609 proto_tree * checksum_tree;
1610 proto_item * item;
1612 checksum_tree = proto_item_add_subtree(it_cksum, ett_ipv6_shim6_cksum);
1613 item = proto_tree_add_boolean(checksum_tree, hf_ipv6_shim6_checksum_good, tvb,
1614 offset, 2, is_cksum_correct);
1615 PROTO_ITEM_SET_GENERATED(item);
1616 item = proto_tree_add_boolean(checksum_tree, hf_ipv6_shim6_checksum_bad, tvb,
1617 offset, 2, !is_cksum_correct);
1618 PROTO_ITEM_SET_GENERATED(item);
1619 if (!is_cksum_correct) {
1620 expert_add_info(pinfo, item, &ei_ipv6_shim6_checksum_bad);
1621 col_append_str(pinfo->cinfo, COL_INFO, " [Shim6 CHECKSUM INCORRECT]");
1625 static int
1626 dissect_shim6(tvbuff_t *tvb, int offset, proto_tree *tree, packet_info * pinfo)
1628 struct ip6_shim shim;
1629 int len;
1630 gint p;
1631 proto_tree *shim_tree;
1632 proto_item *ti;
1633 guint8 tmp[5];
1635 tvb_memcpy(tvb, (guint8 *)&shim, offset, sizeof(shim));
1636 len = (shim.ip6s_len + 1) << 3;
1638 if (tree)
1640 ti = proto_tree_add_item(tree, hf_ipv6_shim6, tvb, offset, len, ENC_NA);
1641 shim_tree = proto_item_add_subtree(ti, ett_ipv6_shim6);
1643 /* Next Header */
1644 proto_tree_add_uint_format_value(shim_tree, hf_ipv6_shim6_nxt, tvb,
1645 offset + (int)offsetof(struct ip6_shim, ip6s_nxt), 1, shim.ip6s_nxt,
1646 "%s (%u)", ipprotostr(shim.ip6s_nxt), shim.ip6s_nxt);
1648 /* Header Extension Length */
1649 proto_tree_add_uint_format_value(shim_tree, hf_ipv6_shim6_len, tvb,
1650 offset + (int)offsetof(struct ip6_shim, ip6s_len), 1, shim.ip6s_len,
1651 "%u (%d bytes)", shim.ip6s_len, len);
1653 /* P Field */
1654 proto_tree_add_item(shim_tree, hf_ipv6_shim6_p, tvb,
1655 offset + (int)offsetof(struct ip6_shim, ip6s_p), 1, ENC_BIG_ENDIAN);
1657 /* skip the first 2 bytes (nxt hdr, hdr ext len, p+7bits) */
1658 p = offset + 3;
1660 if (shim.ip6s_p & SHIM6_BITMASK_P)
1662 tmp[0] = tvb_get_guint8(tvb, p++);
1663 tmp[1] = tvb_get_guint8(tvb, p++);
1664 tmp[2] = tvb_get_guint8(tvb, p++);
1665 tmp[3] = tvb_get_guint8(tvb, p++);
1666 tmp[4] = tvb_get_guint8(tvb, p++);
1668 /* Payload Extension Header */
1669 proto_tree_add_none_format(shim_tree, hf_ipv6_shim6_ct, tvb,
1670 offset + (int)offsetof(struct ip6_shim, ip6s_p), 6,
1671 "Receiver Context Tag: %02x %02x %02x %02x %02x %02x",
1672 shim.ip6s_p & SHIM6_BITMASK_CT, tmp[0], tmp[1], tmp[2], tmp[3], tmp[4]);
1674 else
1676 /* Control Message */
1677 guint16 csum;
1678 int advance;
1680 /* Message Type */
1681 proto_tree_add_item(shim_tree, hf_ipv6_shim6_type, tvb,
1682 offset + (int)offsetof(struct ip6_shim, ip6s_p), 1,
1683 ENC_BIG_ENDIAN
1686 /* Protocol bit (Must be zero for SHIM6) */
1687 proto_tree_add_item(shim_tree, hf_ipv6_shim6_proto, tvb, p, 1, ENC_BIG_ENDIAN);
1688 p++;
1690 /* Checksum */
1691 csum = shim_checksum(tvb_get_ptr(tvb, offset, len), len);
1693 if (csum == 0) {
1694 ti = proto_tree_add_uint_format_value(shim_tree, hf_ipv6_shim6_checksum, tvb, p, 2,
1695 tvb_get_ntohs(tvb, p), "0x%04x [correct]", tvb_get_ntohs(tvb, p));
1696 ipv6_shim6_checkum_additional_info(tvb, pinfo, ti, p, TRUE);
1697 } else {
1698 ti = proto_tree_add_uint_format_value(shim_tree, hf_ipv6_shim6_checksum, tvb, p, 2,
1699 tvb_get_ntohs(tvb, p), "0x%04x [incorrect: should be 0x%04x]",
1700 tvb_get_ntohs(tvb, p), in_cksum_shouldbe(tvb_get_ntohs(tvb, p), csum));
1701 ipv6_shim6_checkum_additional_info(tvb, pinfo, ti, p, FALSE);
1703 p += 2;
1705 /* Type specific data */
1706 advance = dissect_shimctrl(tvb, p, shim.ip6s_p & SHIM6_BITMASK_TYPE, shim_tree);
1707 p += advance;
1709 /* Options */
1710 while (p < offset+len) {
1711 p += dissect_shimopts(tvb, p, shim_tree, pinfo);
1715 return len;
1718 /* END SHIM6 PART */
1720 static void
1721 dissect_ipv6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1723 proto_tree *ipv6_tree = NULL;
1724 proto_item *ipv6_item = NULL, *ti;
1725 guint8 nxt;
1726 guint8 stype=0;
1727 int advance;
1728 guint16 plen;
1729 gboolean hopopts, routing, frag, ah, shim6, dstopts;
1730 guint16 offlg;
1731 guint32 ident;
1732 int offset;
1733 fragment_head *ipfd_head;
1734 tvbuff_t *next_tvb;
1735 gboolean update_col_info = TRUE;
1736 gboolean save_fragmented = FALSE;
1737 const char *sep = "IPv6 ";
1738 guint8 *mac_addr;
1740 struct ip6_hdr ipv6;
1742 col_set_str(pinfo->cinfo, COL_PROTOCOL, "IPv6");
1743 col_clear(pinfo->cinfo, COL_INFO);
1745 offset = 0;
1746 tvb_memcpy(tvb, (guint8 *)&ipv6, offset, sizeof(ipv6));
1748 /* Get extension header and payload length */
1749 plen = g_ntohs(ipv6.ip6_plen);
1751 /* Adjust the length of this tvbuff to include only the IPv6 datagram. */
1752 set_actual_length(tvb, plen + (guint)sizeof (struct ip6_hdr));
1754 TVB_SET_ADDRESS(&pinfo->net_src, AT_IPv6, tvb, offset + IP6H_SRC, 16);
1755 TVB_SET_ADDRESS(&pinfo->src, AT_IPv6, tvb, offset + IP6H_SRC, 16);
1756 TVB_SET_ADDRESS(&pinfo->net_dst, AT_IPv6, tvb, offset + IP6H_DST, 16);
1757 TVB_SET_ADDRESS(&pinfo->dst, AT_IPv6, tvb, offset + IP6H_DST, 16);
1759 if (tree) {
1760 proto_tree* pt;
1761 proto_item* pi;
1762 proto_tree *ipv6_tc_tree;
1763 proto_item *ipv6_tc;
1764 const char *name;
1766 ipv6_item = proto_tree_add_item(tree, proto_ipv6, tvb, offset, -1, ENC_NA);
1767 ipv6_tree = proto_item_add_subtree(ipv6_item, ett_ipv6);
1769 /* !!! warning: (4-bit) version, (6-bit) DSCP, (1-bit) ECN-ECT, (1-bit) ECN-CE and (20-bit) Flow */
1770 pi = proto_tree_add_item(ipv6_tree, hf_ipv6_version, tvb,
1771 offset + (int)offsetof(struct ip6_hdr, ip6_vfc), 1, ENC_BIG_ENDIAN);
1772 pt = proto_item_add_subtree(pi,ett_ipv6_version);
1773 pi = proto_tree_add_item(pt, hf_ip_version, tvb,
1774 offset + (int)offsetof(struct ip6_hdr, ip6_vfc), 1, ENC_BIG_ENDIAN);
1775 PROTO_ITEM_SET_GENERATED(pi);
1777 ipv6_tc = proto_tree_add_item(ipv6_tree, hf_ipv6_class, tvb,
1778 offset + (int)offsetof(struct ip6_hdr, ip6_flow), 4, ENC_BIG_ENDIAN);
1780 ipv6_tc_tree = proto_item_add_subtree(ipv6_tc, ett_ipv6_traffic_class);
1782 proto_tree_add_item(ipv6_tc_tree, hf_ipv6_traffic_class_dscp, tvb,
1783 offset + (int)offsetof(struct ip6_hdr, ip6_flow), 4, ENC_BIG_ENDIAN);
1784 proto_tree_add_item(ipv6_tc_tree, hf_ipv6_traffic_class_ect, tvb,
1785 offset + (int)offsetof(struct ip6_hdr, ip6_flow), 4, ENC_BIG_ENDIAN);
1787 proto_tree_add_item(ipv6_tc_tree, hf_ipv6_traffic_class_ce, tvb,
1788 offset + (int)offsetof(struct ip6_hdr, ip6_flow), 4, ENC_BIG_ENDIAN);
1790 proto_tree_add_item(ipv6_tree, hf_ipv6_flow, tvb,
1791 offset + (int)offsetof(struct ip6_hdr, ip6_flow), 4, ENC_BIG_ENDIAN);
1793 proto_tree_add_item(ipv6_tree, hf_ipv6_plen, tvb,
1794 offset + (int)offsetof(struct ip6_hdr, ip6_plen), 2, ENC_BIG_ENDIAN);
1796 proto_tree_add_uint_format_value(ipv6_tree, hf_ipv6_nxt, tvb,
1797 offset + (int)offsetof(struct ip6_hdr, ip6_nxt), 1,
1798 ipv6.ip6_nxt,
1799 "%s (%u)",
1800 ipprotostr(ipv6.ip6_nxt), ipv6.ip6_nxt);
1802 proto_tree_add_item(ipv6_tree, hf_ipv6_hlim, tvb,
1803 offset + (int)offsetof(struct ip6_hdr, ip6_hlim), 1, ENC_BIG_ENDIAN);
1804 /* Yes, there is not TTL in IPv6 Header... but it is the same of Hop Limit...*/
1805 pinfo->ip_ttl = tvb_get_guint8(tvb, offset + (int)offsetof(struct ip6_hdr, ip6_hlim));
1807 /* Add the different items for the source address */
1808 proto_tree_add_item(ipv6_tree, hf_ipv6_src, tvb,
1809 offset + (int)offsetof(struct ip6_hdr, ip6_src), 16, ENC_NA);
1810 ti = proto_tree_add_ipv6(ipv6_tree, hf_ipv6_addr, tvb,
1811 offset + (int)offsetof(struct ip6_hdr, ip6_src),
1812 16, (guint8 *)&ipv6.ip6_src);
1813 PROTO_ITEM_SET_HIDDEN(ti);
1814 name = get_addr_name(&pinfo->src);
1815 if (ipv6_summary_in_tree) {
1816 proto_item_append_text(ipv6_item, ", Src: %s (%s)", name, ip6_to_str(&ipv6.ip6_src));
1818 ti = proto_tree_add_string(ipv6_tree, hf_ipv6_src_host, tvb,
1819 offset + (int)offsetof(struct ip6_hdr, ip6_src),
1820 16, name);
1821 PROTO_ITEM_SET_GENERATED(ti);
1822 PROTO_ITEM_SET_HIDDEN(ti);
1823 ti = proto_tree_add_string(ipv6_tree, hf_ipv6_host, tvb,
1824 offset + (int)offsetof(struct ip6_hdr, ip6_src),
1825 16, name);
1826 PROTO_ITEM_SET_GENERATED(ti);
1827 PROTO_ITEM_SET_HIDDEN(ti);
1829 /* Extract embedded (IPv6 and MAC) address information */
1830 if (tvb_get_ntohs(tvb, offset + IP6H_SRC) == 0x2002) { /* RFC 3056 section 2 */
1831 ti = proto_tree_add_item(ipv6_tree, hf_ipv6_src_6to4_gateway_ipv4, tvb,
1832 offset + IP6H_SRC + 2, 4, ENC_BIG_ENDIAN);
1833 PROTO_ITEM_SET_GENERATED(ti);
1834 ti = proto_tree_add_item(ipv6_tree, hf_ipv6_src_6to4_sla_id, tvb,
1835 offset + IP6H_SRC + 6, 2, ENC_BIG_ENDIAN);
1836 PROTO_ITEM_SET_GENERATED(ti);
1837 ti = proto_tree_add_item(ipv6_tree, hf_ipv6_6to4_gateway_ipv4, tvb,
1838 offset + IP6H_SRC + 2, 4, ENC_BIG_ENDIAN);
1839 PROTO_ITEM_SET_GENERATED(ti);
1840 PROTO_ITEM_SET_HIDDEN(ti);
1841 ti = proto_tree_add_item(ipv6_tree, hf_ipv6_6to4_sla_id, tvb,
1842 offset + IP6H_SRC + 6, 2, ENC_BIG_ENDIAN);
1843 PROTO_ITEM_SET_GENERATED(ti);
1844 PROTO_ITEM_SET_HIDDEN(ti);
1845 } else if (tvb_get_ntohl(tvb, offset + IP6H_SRC) == 0x20010000) { /* RFC 4380 section 4 */
1846 guint16 mapped_port = tvb_get_ntohs(tvb, offset + IP6H_SRC + 10) ^ 0xffff;
1847 guint32 client_v4 = tvb_get_ipv4(tvb, offset + IP6H_SRC + 12) ^ 0xffffffff;
1849 ti = proto_tree_add_item(ipv6_tree, hf_ipv6_src_teredo_server_ipv4, tvb,
1850 offset + IP6H_SRC + 4, 4, ENC_BIG_ENDIAN);
1851 PROTO_ITEM_SET_GENERATED(ti);
1852 ti = proto_tree_add_uint(ipv6_tree, hf_ipv6_src_teredo_port, tvb,
1853 offset + IP6H_SRC + 10, 2, mapped_port);
1854 PROTO_ITEM_SET_GENERATED(ti);
1855 ti = proto_tree_add_ipv4(ipv6_tree, hf_ipv6_src_teredo_client_ipv4, tvb,
1856 offset + IP6H_SRC + 12, 4, client_v4);
1857 PROTO_ITEM_SET_GENERATED(ti);
1858 ti = proto_tree_add_item(ipv6_tree, hf_ipv6_teredo_server_ipv4, tvb,
1859 offset + IP6H_SRC + 4, 4, ENC_BIG_ENDIAN);
1860 PROTO_ITEM_SET_GENERATED(ti);
1861 PROTO_ITEM_SET_HIDDEN(ti);
1862 ti = proto_tree_add_uint(ipv6_tree, hf_ipv6_teredo_port, tvb,
1863 offset + IP6H_SRC + 10, 2, mapped_port);
1864 PROTO_ITEM_SET_GENERATED(ti);
1865 PROTO_ITEM_SET_HIDDEN(ti);
1866 ti = proto_tree_add_ipv4(ipv6_tree, hf_ipv6_teredo_client_ipv4, tvb,
1867 offset + IP6H_SRC + 12, 4, client_v4);
1868 PROTO_ITEM_SET_GENERATED(ti);
1869 PROTO_ITEM_SET_HIDDEN(ti);
1872 if (tvb_get_guint8(tvb, offset + IP6H_SRC + 8) & 0x02 && tvb_get_ntohs(tvb, offset + IP6H_SRC + 11) == 0xfffe) { /* RFC 4291 appendix A */
1873 mac_addr = (guint8 *)wmem_alloc(wmem_packet_scope(), 6);
1874 tvb_memcpy(tvb, mac_addr, offset + IP6H_SRC + 8, 3);
1875 tvb_memcpy(tvb, mac_addr+3, offset+ IP6H_SRC + 13, 3);
1876 mac_addr[0] &= ~0x02;
1877 ti = proto_tree_add_ether(ipv6_tree, hf_ipv6_src_sa_mac, tvb,
1878 offset + IP6H_SRC + 8, 6, mac_addr);
1879 PROTO_ITEM_SET_GENERATED(ti);
1880 ti = proto_tree_add_ether(ipv6_tree, hf_ipv6_sa_mac, tvb,
1881 offset + IP6H_SRC + 8, 6, mac_addr);
1882 PROTO_ITEM_SET_GENERATED(ti);
1883 PROTO_ITEM_SET_HIDDEN(ti);
1884 } else if ((tvb_get_ntohl(tvb, offset + IP6H_SRC + 8) & 0xfcffffff) == 0x00005efe) { /* RFC 5214 section 6.1 */
1885 ti = proto_tree_add_item(ipv6_tree, hf_ipv6_src_isatap_ipv4, tvb,
1886 offset + IP6H_SRC + 12, 4, ENC_BIG_ENDIAN);
1887 PROTO_ITEM_SET_GENERATED(ti);
1888 ti = proto_tree_add_item(ipv6_tree, hf_ipv6_isatap_ipv4, tvb,
1889 offset + IP6H_SRC + 12, 4, ENC_BIG_ENDIAN);
1890 PROTO_ITEM_SET_GENERATED(ti);
1891 PROTO_ITEM_SET_HIDDEN(ti);
1894 /* Add different items for the destination address */
1895 proto_tree_add_item(ipv6_tree, hf_ipv6_dst, tvb,
1896 offset + (int)offsetof(struct ip6_hdr, ip6_dst), 16, ENC_NA);
1897 ti = proto_tree_add_ipv6(ipv6_tree, hf_ipv6_addr, tvb,
1898 offset + (int)offsetof(struct ip6_hdr, ip6_dst),
1899 16, (guint8 *)&ipv6.ip6_dst);
1900 PROTO_ITEM_SET_HIDDEN(ti);
1901 name = get_addr_name(&pinfo->dst);
1902 if (ipv6_summary_in_tree) {
1903 proto_item_append_text(ipv6_item, ", Dst: %s (%s)", name, ip6_to_str(&ipv6.ip6_dst));
1905 ti = proto_tree_add_string(ipv6_tree, hf_ipv6_dst_host, tvb,
1906 offset + (int)offsetof(struct ip6_hdr, ip6_dst),
1907 16, name);
1908 PROTO_ITEM_SET_GENERATED(ti);
1909 PROTO_ITEM_SET_HIDDEN(ti);
1910 ti = proto_tree_add_string(ipv6_tree, hf_ipv6_host, tvb,
1911 offset + (int)offsetof(struct ip6_hdr, ip6_dst),
1912 16, name);
1913 PROTO_ITEM_SET_GENERATED(ti);
1914 PROTO_ITEM_SET_HIDDEN(ti);
1916 /* Extract embedded (IPv6 and MAC) address information */
1917 if (tvb_get_ntohs(tvb, offset + IP6H_DST) == 0x2002) { /* RFC 3056 section 2 */
1918 ti = proto_tree_add_item(ipv6_tree, hf_ipv6_dst_6to4_gateway_ipv4, tvb,
1919 offset + IP6H_DST + 2, 4, ENC_BIG_ENDIAN);
1920 PROTO_ITEM_SET_GENERATED(ti);
1921 ti = proto_tree_add_item(ipv6_tree, hf_ipv6_dst_6to4_sla_id, tvb,
1922 offset + IP6H_DST + 6, 2, ENC_BIG_ENDIAN);
1923 PROTO_ITEM_SET_GENERATED(ti);
1924 ti = proto_tree_add_item(ipv6_tree, hf_ipv6_6to4_gateway_ipv4, tvb,
1925 offset + IP6H_DST + 2, 4, ENC_BIG_ENDIAN);
1926 PROTO_ITEM_SET_GENERATED(ti);
1927 PROTO_ITEM_SET_HIDDEN(ti);
1928 ti = proto_tree_add_item(ipv6_tree, hf_ipv6_6to4_sla_id, tvb,
1929 offset + IP6H_DST + 6, 2, ENC_BIG_ENDIAN);
1930 PROTO_ITEM_SET_GENERATED(ti);
1931 PROTO_ITEM_SET_HIDDEN(ti);
1932 } else if (tvb_get_ntohl(tvb, offset + IP6H_DST) == 0x20010000) { /* RFC 4380 section 4 */
1933 guint16 mapped_port = tvb_get_ntohs(tvb, offset + IP6H_DST + 10) ^ 0xffff;
1934 guint32 client_v4 = tvb_get_ipv4(tvb, offset + IP6H_DST + 12) ^ 0xffffffff;
1936 ti = proto_tree_add_item(ipv6_tree, hf_ipv6_dst_teredo_server_ipv4, tvb,
1937 offset + IP6H_DST + 4, 4, ENC_BIG_ENDIAN);
1938 PROTO_ITEM_SET_GENERATED(ti);
1939 ti = proto_tree_add_uint(ipv6_tree, hf_ipv6_dst_teredo_port, tvb,
1940 offset + IP6H_DST + 10, 2, mapped_port);
1941 PROTO_ITEM_SET_GENERATED(ti);
1942 ti = proto_tree_add_ipv4(ipv6_tree, hf_ipv6_dst_teredo_client_ipv4, tvb,
1943 offset + IP6H_DST + 12, 4, client_v4);
1944 PROTO_ITEM_SET_GENERATED(ti);
1945 ti = proto_tree_add_item(ipv6_tree, hf_ipv6_teredo_server_ipv4, tvb,
1946 offset + IP6H_DST + 4, 4, ENC_BIG_ENDIAN);
1947 PROTO_ITEM_SET_GENERATED(ti);
1948 PROTO_ITEM_SET_HIDDEN(ti);
1949 ti = proto_tree_add_uint(ipv6_tree, hf_ipv6_teredo_port, tvb,
1950 offset + IP6H_DST + 10, 2, mapped_port);
1951 PROTO_ITEM_SET_GENERATED(ti);
1952 PROTO_ITEM_SET_HIDDEN(ti);
1953 ti = proto_tree_add_ipv4(ipv6_tree, hf_ipv6_teredo_client_ipv4, tvb,
1954 offset + IP6H_DST + 12, 4, client_v4);
1955 PROTO_ITEM_SET_GENERATED(ti);
1956 PROTO_ITEM_SET_HIDDEN(ti);
1959 if (tvb_get_guint8(tvb, offset + IP6H_DST + 8) & 0x02 && tvb_get_ntohs(tvb, offset + IP6H_DST + 11) == 0xfffe) { /* RFC 4291 appendix A */
1960 mac_addr = (guint8 *)wmem_alloc(wmem_packet_scope(), 6);
1961 tvb_memcpy(tvb, mac_addr, offset + IP6H_DST + 8, 3);
1962 tvb_memcpy(tvb, mac_addr+3, offset+ IP6H_DST + 13, 3);
1963 mac_addr[0] &= ~0x02;
1964 ti = proto_tree_add_ether(ipv6_tree, hf_ipv6_dst_sa_mac, tvb,
1965 offset + IP6H_DST + 8, 6, mac_addr);
1966 PROTO_ITEM_SET_GENERATED(ti);
1967 ti = proto_tree_add_ether(ipv6_tree, hf_ipv6_sa_mac, tvb,
1968 offset + IP6H_DST + 8, 6, mac_addr);
1969 PROTO_ITEM_SET_GENERATED(ti);
1970 PROTO_ITEM_SET_HIDDEN(ti);
1971 } else if ((tvb_get_ntohl(tvb, offset + IP6H_DST + 8) & 0xfcffffff) == 0x00005efe) { /* RFC 5214 section 6.1 */
1972 ti = proto_tree_add_item(ipv6_tree, hf_ipv6_dst_isatap_ipv4, tvb,
1973 offset + IP6H_DST + 12, 4, ENC_BIG_ENDIAN);
1974 PROTO_ITEM_SET_GENERATED(ti);
1975 ti = proto_tree_add_item(ipv6_tree, hf_ipv6_isatap_ipv4, tvb,
1976 offset + IP6H_DST + 12, 4, ENC_BIG_ENDIAN);
1977 PROTO_ITEM_SET_GENERATED(ti);
1978 PROTO_ITEM_SET_HIDDEN(ti);
1982 #ifdef HAVE_GEOIP_V6
1983 if (tree && ipv6_use_geoip) {
1984 add_geoip_info(ipv6_tree, tvb, offset, &ipv6.ip6_src, &ipv6.ip6_dst);
1986 #endif
1988 /* start of the new header (could be a extension header) */
1989 nxt = tvb_get_guint8(tvb, offset + 6);
1990 offset += (int)sizeof(struct ip6_hdr);
1991 offlg = 0;
1992 ident = 0;
1994 /* start out assuming this isn't fragmented, and has none of the other
1995 non-final headers */
1996 hopopts = FALSE;
1997 routing = FALSE;
1998 ah = FALSE;
1999 shim6 = FALSE;
2000 dstopts = FALSE;
2002 again:
2003 switch (nxt) {
2005 case IP_PROTO_HOPOPTS:
2006 hopopts = TRUE;
2007 advance = dissect_hopopts(tvb, offset, ipv6_tree, pinfo);
2008 nxt = tvb_get_guint8(tvb, offset);
2009 offset += advance;
2010 plen -= advance;
2011 goto again;
2013 case IP_PROTO_ROUTING:
2014 routing = TRUE;
2015 advance = dissect_routing6(tvb, offset, ipv6_tree, pinfo);
2016 nxt = tvb_get_guint8(tvb, offset);
2017 offset += advance;
2018 plen -= advance;
2019 goto again;
2021 case IP_PROTO_FRAGMENT:
2022 advance = dissect_frag6(tvb, offset, pinfo, ipv6_tree,
2023 &offlg, &ident);
2024 nxt = tvb_get_guint8(tvb, offset);
2025 offset += advance;
2026 plen -= advance;
2027 frag = offlg & (IP6F_OFF_MASK | IP6F_MORE_FRAG);
2028 save_fragmented |= frag;
2029 if (ipv6_reassemble && frag && tvb_bytes_exist(tvb, offset, plen)) {
2030 ipfd_head = fragment_add_check(&ipv6_reassembly_table,
2031 tvb, offset, pinfo, ident, NULL,
2032 offlg & IP6F_OFF_MASK,
2033 plen,
2034 offlg & IP6F_MORE_FRAG);
2035 next_tvb = process_reassembled_data(tvb, offset, pinfo, "Reassembled IPv6",
2036 ipfd_head, &ipv6_frag_items, &update_col_info, ipv6_tree);
2037 if (next_tvb) { /* Process post-fragment headers after reassembly... */
2038 offset= 0;
2039 offlg = 0;
2040 tvb = next_tvb;
2041 goto again;
2044 if (!(offlg & IP6F_OFF_MASK)) /*...or in the first fragment */
2045 goto again;
2046 break;
2048 case IP_PROTO_AH:
2049 ah = TRUE;
2050 advance = dissect_ah_header(tvb_new_subset_remaining(tvb, offset),
2051 pinfo, ipv6_tree, NULL, NULL);
2052 nxt = tvb_get_guint8(tvb, offset);
2053 offset += advance;
2054 plen -= advance;
2055 goto again;
2057 case IP_PROTO_SHIM6:
2058 case IP_PROTO_SHIM6_OLD:
2059 shim6 = TRUE;
2060 advance = dissect_shim6(tvb, offset, ipv6_tree, pinfo);
2061 nxt = tvb_get_guint8(tvb, offset);
2062 stype = tvb_get_guint8(tvb, offset+2);
2063 offset += advance;
2064 plen -= advance;
2065 goto again;
2067 case IP_PROTO_DSTOPTS:
2068 dstopts = TRUE;
2069 advance = dissect_dstopts(tvb, offset, ipv6_tree, pinfo);
2070 nxt = tvb_get_guint8(tvb, offset);
2071 offset += advance;
2072 plen -= advance;
2073 goto again;
2075 case IP_PROTO_NONE:
2076 break;
2078 default:
2079 /* Since we did not recognize this IPv6 option, check
2080 * whether it is a known protocol. If not, then it
2081 * is an unknown IPv6 option
2083 if (!dissector_get_uint_handle(ip_dissector_table, nxt)) {
2084 advance = dissect_unknown_option(tvb, offset, ipv6_tree);
2085 nxt = tvb_get_guint8(tvb, offset);
2086 offset += advance;
2087 plen -= advance;
2088 goto again;
2092 proto_item_set_len (ipv6_item, offset);
2094 /* collect packet info */
2095 pinfo->ipproto = nxt;
2096 tap_queue_packet(ipv6_tap, pinfo, &ipv6);
2098 if (offlg & IP6F_OFF_MASK || (ipv6_reassemble && offlg & IP6F_MORE_FRAG)) {
2099 /* Not the first fragment, or the first when we are reassembling and there are more. */
2100 /* Don't dissect it; just show this as a fragment. */
2101 /* COL_INFO was filled in by "dissect_frag6()" */
2102 call_dissector(data_handle, tvb_new_subset_remaining(tvb, offset), pinfo, tree);
2103 return;
2104 } else {
2105 /* First fragment, not fragmented, or already reassembled. Dissect what we have here. */
2107 /* Get a tvbuff for the payload. */
2108 next_tvb = tvb_new_subset_remaining(tvb, offset);
2111 * If this is the first fragment, but not the only fragment,
2112 * tell the next protocol that.
2114 if (offlg & IP6F_MORE_FRAG)
2115 pinfo->fragmented = TRUE;
2116 else
2117 pinfo->fragmented = FALSE;
2121 /* do lookup with the subdissector table */
2122 if (!dissector_try_uint(ip_dissector_table, nxt, next_tvb, pinfo, tree)) {
2123 /* Unknown protocol.
2124 Handle "no next header" specially. */
2125 if (nxt == IP_PROTO_NONE) {
2126 /* If we had an Authentication Header, the AH dissector already
2127 put something in the Info column; leave it there. */
2128 if (!ah) {
2129 if (hopopts || routing || dstopts || shim6) {
2130 if (hopopts) {
2131 col_append_fstr(pinfo->cinfo, COL_INFO, "%shop-by-hop options",
2132 sep);
2133 sep = ", ";
2135 if (routing) {
2136 col_append_fstr(pinfo->cinfo, COL_INFO, "%srouting", sep);
2137 sep = ", ";
2139 if (dstopts) {
2140 col_append_fstr(pinfo->cinfo, COL_INFO, "%sdestination options",
2141 sep);
2143 if (shim6) {
2144 if (stype & SHIM6_BITMASK_P) {
2145 col_append_str(pinfo->cinfo, COL_INFO, "Shim6 (Payload)");
2147 else {
2148 col_append_fstr(pinfo->cinfo, COL_INFO, "Shim6 (%s)",
2149 val_to_str_const(stype & SHIM6_BITMASK_TYPE, shimctrlvals, "Unknown"));
2152 } else
2153 col_set_str(pinfo->cinfo, COL_INFO, "IPv6 no next header");
2155 } else {
2156 col_add_fstr(pinfo->cinfo, COL_INFO, "%s (%u)", ipprotostr(nxt), nxt);
2158 call_dissector(data_handle, next_tvb, pinfo, tree);
2160 pinfo->fragmented = save_fragmented;
2163 void
2164 proto_register_ipv6(void)
2166 static hf_register_info hf[] = {
2167 { &hf_ipv6_version,
2168 { "Version", "ipv6.version",
2169 FT_UINT8, BASE_DEC, NULL, 0xF0, NULL, HFILL }},
2170 { &hf_ip_version,
2171 { "This field makes the filter \"ip.version == 6\" possible", "ip.version",
2172 FT_UINT8, BASE_DEC, NULL, 0xF0, NULL, HFILL }},
2173 { &hf_ipv6_class,
2174 { "Traffic class", "ipv6.class",
2175 FT_UINT32, BASE_HEX, NULL, 0x0FF00000, NULL, HFILL }},
2176 { &hf_ipv6_flow,
2177 { "Flowlabel", "ipv6.flow",
2178 FT_UINT32, BASE_HEX, NULL, 0x000FFFFF, NULL, HFILL }},
2179 { &hf_ipv6_plen,
2180 { "Payload length", "ipv6.plen",
2181 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
2182 { &hf_ipv6_nxt,
2183 { "Next header", "ipv6.nxt",
2184 FT_UINT8, BASE_DEC | BASE_EXT_STRING, &ipproto_val_ext, 0x0, NULL, HFILL }},
2185 { &hf_ipv6_hlim,
2186 { "Hop limit", "ipv6.hlim",
2187 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
2188 { &hf_ipv6_src,
2189 { "Source", "ipv6.src",
2190 FT_IPv6, BASE_NONE, NULL, 0x0,
2191 "Source IPv6 Address", HFILL }},
2192 { &hf_ipv6_src_host,
2193 { "Source Host", "ipv6.src_host",
2194 FT_STRING, BASE_NONE, NULL, 0x0,
2195 "Source IPv6 Host", HFILL }},
2196 { &hf_ipv6_src_sa_mac,
2197 { "Source SA MAC", "ipv6.src_sa_mac",
2198 FT_ETHER, BASE_NONE, NULL, 0x0,
2199 "Source IPv6 Stateless Autoconfiguration MAC Address", HFILL }},
2200 { &hf_ipv6_src_isatap_ipv4,
2201 { "Source ISATAP IPv4", "ipv6.src_isatap_ipv4",
2202 FT_IPv4, BASE_NONE, NULL, 0x0,
2203 "Source IPv6 ISATAP Encapsulated IPv4 Address", HFILL }},
2204 { &hf_ipv6_src_6to4_gateway_ipv4,
2205 { "Source 6to4 Gateway IPv4", "ipv6.src_6to4_gw_ipv4",
2206 FT_IPv4, BASE_NONE, NULL, 0x0,
2207 "Source IPv6 6to4 Gateway IPv4 Address", HFILL }},
2208 { &hf_ipv6_src_6to4_sla_id,
2209 { "Source 6to4 SLA ID", "ipv6.src_6to4_sla_id",
2210 FT_UINT16, BASE_DEC, NULL, 0x0,
2211 "Source IPv6 6to4 SLA ID", HFILL }},
2212 { &hf_ipv6_src_teredo_server_ipv4,
2213 { "Source Teredo Server IPv4", "ipv6.src_ts_ipv4",
2214 FT_IPv4, BASE_NONE, NULL, 0x0,
2215 "Source IPv6 Teredo Server Encapsulated IPv4 Address", HFILL }},
2216 { &hf_ipv6_src_teredo_port,
2217 { "Source Teredo Port", "ipv6.src_tc_port",
2218 FT_UINT16, BASE_DEC, NULL, 0x0,
2219 "Source IPv6 Teredo Client Mapped Port", HFILL }},
2220 { &hf_ipv6_src_teredo_client_ipv4,
2221 { "Source Teredo Client IPv4", "ipv6.src_tc_ipv4",
2222 FT_IPv4, BASE_NONE, NULL, 0x0,
2223 "Source IPv6 Teredo Client Encapsulated IPv4 Address", HFILL }},
2224 { &hf_ipv6_dst,
2225 { "Destination", "ipv6.dst",
2226 FT_IPv6, BASE_NONE, NULL, 0x0,
2227 "Destination IPv6 Address", HFILL }},
2228 { &hf_ipv6_dst_host,
2229 { "Destination Host", "ipv6.dst_host",
2230 FT_STRING, BASE_NONE, NULL, 0x0,
2231 "Destination IPv6 Host", HFILL }},
2232 { &hf_ipv6_dst_sa_mac,
2233 { "Destination SA MAC", "ipv6.dst_sa_mac",
2234 FT_ETHER, BASE_NONE, NULL, 0x0,
2235 "Destination IPv6 Stateless Autoconfiguration MAC Address", HFILL }},
2236 { &hf_ipv6_dst_isatap_ipv4,
2237 { "Destination ISATAP IPv4", "ipv6.dst_isatap_ipv4",
2238 FT_IPv4, BASE_NONE, NULL, 0x0,
2239 "Destination IPv6 ISATAP Encapsulated IPv4 Address", HFILL }},
2240 { &hf_ipv6_dst_6to4_gateway_ipv4,
2241 { "Destination 6to4 Gateway IPv4", "ipv6.dst_6to4_gw_ipv4",
2242 FT_IPv4, BASE_NONE, NULL, 0x0,
2243 "Destination IPv6 6to4 Gateway IPv4 Address", HFILL }},
2244 { &hf_ipv6_dst_6to4_sla_id,
2245 { "Destination 6to4 SLA ID", "ipv6.dst_6to4_sla_id",
2246 FT_UINT16, BASE_DEC, NULL, 0x0,
2247 "Destination IPv6 6to4 SLA ID", HFILL }},
2248 { &hf_ipv6_dst_teredo_server_ipv4,
2249 { "Destination Teredo Server IPv4", "ipv6.dst_ts_ipv4",
2250 FT_IPv4, BASE_NONE, NULL, 0x0,
2251 "Destination IPv6 Teredo Server Encapsulated IPv4 Address", HFILL }},
2252 { &hf_ipv6_dst_teredo_port,
2253 { "Destination Teredo Port", "ipv6.dst_tc_port",
2254 FT_UINT16, BASE_DEC, NULL, 0x0,
2255 "Destination IPv6 Teredo Client Mapped Port", HFILL }},
2256 { &hf_ipv6_dst_teredo_client_ipv4,
2257 { "Destination Teredo Client IPv4", "ipv6.dst_tc_ipv4",
2258 FT_IPv4, BASE_NONE, NULL, 0x0,
2259 "Destination IPv6 Teredo Client Encapsulated IPv4 Address", HFILL }},
2260 { &hf_ipv6_addr,
2261 { "Source or Destination Address", "ipv6.addr",
2262 FT_IPv6, BASE_NONE, NULL, 0x0,
2263 NULL, HFILL }},
2264 { &hf_ipv6_host,
2265 { "Source or Destination Host", "ipv6.host",
2266 FT_STRING, BASE_NONE, NULL, 0x0,
2267 NULL, HFILL }},
2269 { &hf_ipv6_sa_mac,
2270 { "SA MAC", "ipv6.sa_mac",
2271 FT_ETHER, BASE_NONE, NULL, 0x0,
2272 "IPv6 Stateless Autoconfiguration MAC Address", HFILL }},
2273 { &hf_ipv6_isatap_ipv4,
2274 { "ISATAP IPv4", "ipv6.isatap_ipv4",
2275 FT_IPv4, BASE_NONE, NULL, 0x0,
2276 "IPv6 ISATAP Encapsulated IPv4 Address", HFILL }},
2277 { &hf_ipv6_6to4_gateway_ipv4,
2278 { "6to4 Gateway IPv4", "ipv6.6to4_gw_ipv4",
2279 FT_IPv4, BASE_NONE, NULL, 0x0,
2280 "IPv6 6to4 Gateway IPv4 Address", HFILL }},
2281 { &hf_ipv6_6to4_sla_id,
2282 { "6to4 SLA ID", "ipv6.6to4_sla_id",
2283 FT_UINT16, BASE_DEC, NULL, 0x0,
2284 "IPv6 6to4 SLA ID", HFILL }},
2285 { &hf_ipv6_teredo_server_ipv4,
2286 { "Teredo Server IPv4", "ipv6.ts_ipv4",
2287 FT_IPv4, BASE_NONE, NULL, 0x0,
2288 "IPv6 Teredo Server Encapsulated IPv4 Address", HFILL }},
2289 { &hf_ipv6_teredo_port,
2290 { "Teredo Port", "ipv6.tc_port",
2291 FT_UINT16, BASE_DEC, NULL, 0x0,
2292 "IPv6 Teredo Client Mapped Port", HFILL }},
2293 { &hf_ipv6_teredo_client_ipv4,
2294 { "Teredo Client IPv4", "ipv6.tc_ipv4",
2295 FT_IPv4, BASE_NONE, NULL, 0x0,
2296 "IPv6 Teredo Client Encapsulated IPv4 Address", HFILL }},
2297 #ifdef HAVE_GEOIP_V6
2298 { &hf_geoip_country,
2299 { "Source or Destination GeoIP Country", "ipv6.geoip.country",
2300 FT_STRING, BASE_NONE, NULL, 0x0,
2301 NULL, HFILL }},
2302 { &hf_geoip_city,
2303 { "Source or Destination GeoIP City", "ipv6.geoip.city",
2304 FT_STRING, BASE_NONE, NULL, 0x0,
2305 NULL, HFILL }},
2306 { &hf_geoip_org,
2307 { "Source or Destination GeoIP Organization", "ipv6.geoip.org",
2308 FT_STRING, BASE_NONE, NULL, 0x0,
2309 NULL, HFILL }},
2310 { &hf_geoip_isp,
2311 { "Source or Destination GeoIP ISP", "ipv6.geoip.isp",
2312 FT_STRING, BASE_NONE, NULL, 0x0,
2313 NULL, HFILL }},
2314 { &hf_geoip_asnum,
2315 { "Source or Destination GeoIP AS Number", "ipv6.geoip.asnum",
2316 FT_STRING, BASE_NONE, NULL, 0x0,
2317 NULL, HFILL }},
2318 { &hf_geoip_lat,
2319 { "Source or Destination GeoIP Latitude", "ipv6.geoip.lat",
2320 FT_DOUBLE, BASE_NONE, NULL, 0x0,
2321 NULL, HFILL }},
2322 { &hf_geoip_lon,
2323 { "Source or Destination GeoIP Longitude", "ipv6.geoip.lon",
2324 FT_DOUBLE, BASE_NONE, NULL, 0x0,
2325 NULL, HFILL }},
2326 { &hf_geoip_src_country,
2327 { "Source GeoIP Country", "ipv6.geoip.src_country",
2328 FT_STRING, BASE_NONE, NULL, 0x0,
2329 NULL, HFILL }},
2330 { &hf_geoip_src_city,
2331 { "Source GeoIP City", "ipv6.geoip.src_city",
2332 FT_STRING, BASE_NONE, NULL, 0x0,
2333 NULL, HFILL }},
2334 { &hf_geoip_src_org,
2335 { "Source GeoIP Organization", "ipv6.geoip.src_org",
2336 FT_STRING, BASE_NONE, NULL, 0x0,
2337 NULL, HFILL }},
2338 { &hf_geoip_src_isp,
2339 { "Source GeoIP ISP", "ipv6.geoip.src_isp",
2340 FT_STRING, BASE_NONE, NULL, 0x0,
2341 NULL, HFILL }},
2342 { &hf_geoip_src_asnum,
2343 { "Source GeoIP AS Number", "ipv6.geoip.src_asnum",
2344 FT_STRING, BASE_NONE, NULL, 0x0,
2345 NULL, HFILL }},
2346 { &hf_geoip_src_lat,
2347 { "Source GeoIP Latitude", "ipv6.geoip.src_lat",
2348 FT_DOUBLE, BASE_NONE, NULL, 0x0,
2349 NULL, HFILL }},
2350 { &hf_geoip_src_lon,
2351 { "Source GeoIP Longitude", "ipv6.geoip.src_lon",
2352 FT_DOUBLE, BASE_NONE, NULL, 0x0,
2353 NULL, HFILL }},
2354 { &hf_geoip_dst_country,
2355 { "Destination GeoIP Country", "ipv6.geoip.dst_country",
2356 FT_STRING, BASE_NONE, NULL, 0x0,
2357 NULL, HFILL }},
2358 { &hf_geoip_dst_city,
2359 { "Destination GeoIP City", "ipv6.geoip.dst_city",
2360 FT_STRING, BASE_NONE, NULL, 0x0,
2361 NULL, HFILL }},
2362 { &hf_geoip_dst_org,
2363 { "Destination GeoIP Organization", "ipv6.geoip.dst_org",
2364 FT_STRING, BASE_NONE, NULL, 0x0,
2365 NULL, HFILL }},
2366 { &hf_geoip_dst_isp,
2367 { "Destination GeoIP ISP", "ipv6.geoip.dst_isp",
2368 FT_STRING, BASE_NONE, NULL, 0x0,
2369 NULL, HFILL }},
2370 { &hf_geoip_dst_asnum,
2371 { "Destination GeoIP AS Number", "ipv6.geoip.dst_asnum",
2372 FT_STRING, BASE_NONE, NULL, 0x0,
2373 NULL, HFILL }},
2374 { &hf_geoip_dst_lat,
2375 { "Destination GeoIP Latitude", "ipv6.geoip.dst_lat",
2376 FT_DOUBLE, BASE_NONE, NULL, 0x0,
2377 NULL, HFILL }},
2378 { &hf_geoip_dst_lon,
2379 { "Destination GeoIP Longitude", "ipv6.geoip.dst_lon",
2380 FT_DOUBLE, BASE_NONE, NULL, 0x0,
2381 NULL, HFILL }},
2382 #endif /* HAVE_GEOIP_V6 */
2385 { &hf_ipv6_dst_opt,
2386 { "Destination Option", "ipv6.dst_opt",
2387 FT_NONE, BASE_NONE, NULL, 0x0,
2388 NULL, HFILL }},
2389 { &hf_ipv6_hop_opt,
2390 { "Hop-by-Hop Option", "ipv6.hop_opt",
2391 FT_NONE, BASE_NONE, NULL, 0x0,
2392 NULL, HFILL }},
2393 { &hf_ipv6_unk_hdr,
2394 { "Unknown Extension Header", "ipv6.unknown_hdr",
2395 FT_NONE, BASE_NONE, NULL, 0x0,
2396 NULL, HFILL }},
2397 { &hf_ipv6_opt,
2398 { "IPv6 Option", "ipv6.opt",
2399 FT_NONE, BASE_NONE, NULL, 0x0,
2400 "Option", HFILL }},
2401 { &hf_ipv6_opt_type,
2402 { "Type", "ipv6.opt.type",
2403 FT_UINT8, BASE_DEC, VALS(ipv6_opt_vals), 0x0,
2404 "Options type", HFILL }},
2405 { &hf_ipv6_opt_length,
2406 { "Length", "ipv6.opt.length",
2407 FT_UINT8, BASE_DEC, NULL, 0x0,
2408 "Length in units of 8 octets", HFILL }},
2409 { &hf_ipv6_opt_pad1,
2410 { "Pad1", "ipv6.opt.pad1",
2411 FT_NONE, BASE_NONE, NULL, 0x0,
2412 "Pad1 Option", HFILL }},
2413 { &hf_ipv6_opt_padn,
2414 { "PadN", "ipv6.opt.padn",
2415 FT_BYTES, BASE_NONE, NULL, 0x0,
2416 "PadN Option", HFILL }},
2417 { &hf_ipv6_opt_rtalert,
2418 { "Router Alert", "ipv6.opt.router_alert",
2419 FT_UINT16, BASE_DEC, VALS(rtalertvals), 0x0,
2420 NULL, HFILL }},
2421 { &hf_ipv6_opt_tel,
2422 { "Tunnel Encapsulation Limit", "ipv6.opt.tel",
2423 FT_UINT8, BASE_DEC, NULL, 0x0,
2424 "How many further levels of encapsulation are permitted", HFILL }},
2425 { &hf_ipv6_opt_jumbo,
2426 { "Jumbo", "ipv6.opt.jumbo",
2427 FT_UINT32, BASE_DEC, NULL, 0x0,
2428 "Length of the IPv6 packet in octets", HFILL }},
2429 { &hf_ipv6_opt_calipso_doi,
2430 { "CALIPSO Domain of Interpretation","ipv6.opt.calipso.doi",
2431 FT_UINT8, BASE_DEC, NULL, 0x0,
2432 NULL, HFILL }},
2433 { &hf_ipv6_opt_calipso_cmpt_length,
2434 { "Compartment Length","ipv6.opt.calipso.cmpt.length",
2435 FT_UINT8, BASE_DEC, NULL, 0x0,
2436 NULL, HFILL }},
2437 { &hf_ipv6_opt_calipso_sens_level,
2438 { "Sensitivity Level","ipv6.opt.calipso.sens_level",
2439 FT_UINT8, BASE_DEC, NULL, 0x0,
2440 NULL, HFILL }},
2441 { &hf_ipv6_opt_calipso_checksum,
2442 { "Checksum","ipv6.opt.calipso.checksum",
2443 FT_UINT16, BASE_HEX, NULL, 0x0,
2444 NULL, HFILL }},
2445 { &hf_ipv6_opt_calipso_cmpt_bitmap,
2446 { "Compartment Bitmap","ipv6.opt.calipso.cmpt_bitmap",
2447 FT_BYTES, BASE_NONE, NULL, 0x0,
2448 NULL, HFILL }},
2449 { &hf_ipv6_opt_qs_func,
2450 { "Function", "ipv6.opt.qs_func",
2451 FT_UINT8, BASE_DEC, VALS(qs_func_vals), QS_FUNC_MASK,
2452 NULL, HFILL }},
2453 { &hf_ipv6_opt_qs_rate,
2454 { "Rate", "ipv6.opt.qs_rate",
2455 FT_UINT8, BASE_DEC | BASE_EXT_STRING, &qs_rate_vals_ext, QS_RATE_MASK,
2456 NULL, HFILL }},
2457 { &hf_ipv6_opt_qs_ttl,
2458 { "QS TTL", "ipv6.opt.qs_ttl",
2459 FT_UINT8, BASE_DEC, NULL, 0x0,
2460 NULL, HFILL }},
2461 { &hf_ipv6_opt_qs_ttl_diff,
2462 { "TTL Diff", "ipv6.opt.qs_ttl_diff",
2463 FT_UINT8, BASE_DEC, NULL, 0x0,
2464 NULL, HFILL }},
2465 { &hf_ipv6_opt_qs_unused,
2466 { "Not Used", "ipv6.opt.qs_unused",
2467 FT_UINT8, BASE_DEC, NULL, 0x0,
2468 NULL, HFILL }},
2469 { &hf_ipv6_opt_qs_nonce,
2470 { "QS Nonce", "ipv6.opt.qs_nonce",
2471 FT_UINT32, BASE_HEX, NULL, 0xFFFFFFFC,
2472 NULL, HFILL }},
2473 { &hf_ipv6_opt_qs_reserved,
2474 { "Reserved", "ipv6.opt.qs_reserved",
2475 FT_UINT32, BASE_HEX, NULL, 0x0003,
2476 NULL, HFILL }},
2477 { &hf_ipv6_opt_rpl_flag,
2478 { "Flag", "ipv6.opt.rpl.flag",
2479 FT_UINT8, BASE_DEC, NULL, 0x0,
2480 NULL, HFILL }},
2481 { &hf_ipv6_opt_rpl_flag_o,
2482 { "Down", "ipv6.opt.rpl.flag.o",
2483 FT_BOOLEAN, 8, NULL, 0x80,
2484 "The packet is expected to progress Up or Down", HFILL }},
2485 { &hf_ipv6_opt_rpl_flag_r,
2486 { "Rank Error", "ipv6.opt.rpl.flag.r",
2487 FT_BOOLEAN, 8, NULL, 0x40,
2488 "Indicating whether a rank error was detected", HFILL }},
2489 { &hf_ipv6_opt_rpl_flag_f,
2490 { "Forwarding Error", "ipv6.opt.rpl.flag.f",
2491 FT_BOOLEAN, 8, NULL, 0x20,
2492 "Indicating that this node can not forward the packet further towards the destination", HFILL }},
2493 { &hf_ipv6_opt_rpl_flag_rsv,
2494 { "Reserved", "ipv6.opt.rpl.flag.rsv",
2495 FT_UINT8, BASE_HEX, NULL, 0x1F,
2496 "Reserved (Must Be Zero)", HFILL }},
2497 { &hf_ipv6_opt_rpl_instance_id,
2498 { "RPLInstanceID", "ipv6.opt.rpl.instance_id",
2499 FT_UINT8, BASE_HEX, NULL, 0x0,
2500 "Indicating the DODAG instance along which the packet is sent", HFILL }},
2501 { &hf_ipv6_opt_rpl_senderrank,
2502 { "Sender Rank", "ipv6.opt.rpl.sender_rank",
2503 FT_UINT16, BASE_HEX, NULL, 0x0,
2504 "Set to zero by the source and to DAGRank(rank) by a router that forwards inside the RPL network", HFILL }},
2505 { &hf_ipv6_opt_experimental,
2506 { "Experimental Option","ipv6.opt.experimental",
2507 FT_BYTES, BASE_NONE, NULL, 0x0,
2508 NULL, HFILL }},
2509 { &hf_ipv6_opt_unknown,
2510 { "Unknown Option Payload","ipv6.opt.unknown",
2511 FT_BYTES, BASE_NONE, NULL, 0x0,
2512 NULL, HFILL }},
2513 { &hf_ipv6_routing_hdr_opt,
2514 { "Routing Header, Type","ipv6.routing_hdr",
2515 FT_UINT8, BASE_DEC, NULL, 0x0,
2516 "Routing Header Option", HFILL }},
2517 { &hf_ipv6_routing_hdr_type,
2518 { "Type", "ipv6.routing_hdr.type",
2519 FT_UINT8, BASE_DEC, VALS(routing_header_type), 0x0,
2520 "Routing Header Type", HFILL }},
2521 { &hf_ipv6_routing_hdr_left,
2522 { "Segments Left", "ipv6.routing_hdr.left",
2523 FT_UINT8, BASE_DEC, NULL, 0x0,
2524 "Routing Header Segments Left", HFILL }},
2525 { &hf_ipv6_routing_hdr_addr,
2526 { "Address", "ipv6.routing_hdr.addr",
2527 FT_IPv6, BASE_NONE, NULL, 0x0,
2528 "Routing Header Address", HFILL }},
2529 { &hf_ipv6_frag_nxt,
2530 { "Next header", "ipv6.fragment.nxt",
2531 FT_UINT16, BASE_DEC | BASE_EXT_STRING, &ipproto_val_ext, 0x0,
2532 "Fragment next header", HFILL }},
2533 { &hf_ipv6_frag_reserved,
2534 { "Reserved octet", "ipv6.fragment.reserved_octet",
2535 FT_UINT16, BASE_HEX, NULL, 0x0,
2536 "Should always be 0", HFILL }},
2537 { &hf_ipv6_frag_offset,
2538 { "Offset", "ipv6.fragment.offset",
2539 FT_UINT16, BASE_DEC_HEX, NULL, IP6F_OFF_MASK,
2540 "Fragment Offset", HFILL }},
2541 { &hf_ipv6_frag_reserved_bits,
2542 { "Reserved bits", "ipv6.fragment.reserved_bits",
2543 FT_UINT16, BASE_DEC_HEX, NULL, IP6F_RESERVED_MASK,
2544 NULL, HFILL }},
2545 { &hf_ipv6_frag_more,
2546 { "More Fragment", "ipv6.fragment.more",
2547 FT_BOOLEAN, 16, TFS(&tfs_yes_no), IP6F_MORE_FRAG,
2548 "More Fragments", HFILL }},
2549 { &hf_ipv6_frag_id,
2550 { "Identification", "ipv6.fragment.id",
2551 FT_UINT32, BASE_HEX, NULL, 0x0,
2552 "Fragment Identification", HFILL }},
2553 { &hf_ipv6_fragment_overlap,
2554 { "Fragment overlap", "ipv6.fragment.overlap",
2555 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2556 "Fragment overlaps with other fragments", HFILL }},
2558 { &hf_ipv6_fragment_overlap_conflict,
2559 { "Conflicting data in fragment overlap", "ipv6.fragment.overlap.conflict",
2560 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2561 "Overlapping fragments contained conflicting data", HFILL }},
2563 { &hf_ipv6_fragment_multiple_tails,
2564 { "Multiple tail fragments found", "ipv6.fragment.multipletails",
2565 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2566 "Several tails were found when defragmenting the packet", HFILL }},
2568 { &hf_ipv6_fragment_too_long_fragment,
2569 { "Fragment too long", "ipv6.fragment.toolongfragment",
2570 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2571 "Fragment contained data past end of packet", HFILL }},
2573 { &hf_ipv6_fragment_error,
2574 { "Defragmentation error", "ipv6.fragment.error",
2575 FT_FRAMENUM, BASE_NONE, NULL, 0x0,
2576 "Defragmentation error due to illegal fragments", HFILL }},
2578 { &hf_ipv6_fragment_count,
2579 { "Fragment count", "ipv6.fragment.count",
2580 FT_UINT32, BASE_DEC, NULL, 0x0,
2581 NULL, HFILL }},
2583 { &hf_ipv6_fragment,
2584 { "IPv6 Fragment", "ipv6.fragment",
2585 FT_FRAMENUM, BASE_NONE, NULL, 0x0,
2586 NULL, HFILL }},
2588 { &hf_ipv6_fragments,
2589 { "IPv6 Fragments", "ipv6.fragments",
2590 FT_NONE, BASE_NONE, NULL, 0x0,
2591 NULL, HFILL }},
2593 { &hf_ipv6_reassembled_in,
2594 { "Reassembled IPv6 in frame", "ipv6.reassembled_in",
2595 FT_FRAMENUM, BASE_NONE, NULL, 0x0,
2596 "This IPv6 packet is reassembled in this frame", HFILL }},
2598 { &hf_ipv6_reassembled_length,
2599 { "Reassembled IPv6 length", "ipv6.reassembled.length",
2600 FT_UINT32, BASE_DEC, NULL, 0x0,
2601 "The total length of the reassembled payload", HFILL }},
2603 { &hf_ipv6_reassembled_data,
2604 { "Reassembled IPv6 data", "ipv6.reassembled.data",
2605 FT_BYTES, BASE_NONE, NULL, 0x0,
2606 "The reassembled payload", HFILL }},
2607 /* RPL Routing Header */
2608 { &hf_ipv6_routing_hdr_rpl_cmprI,
2609 { "Compressed Internal Octets (CmprI)", "ipv6.routing_hdr.rpl.cmprI",
2610 FT_UINT32, BASE_DEC, NULL, IP6RRPL_BITMASK_CMPRI,
2611 "Elided octets from all but last segment", HFILL }},
2613 { &hf_ipv6_routing_hdr_rpl_cmprE,
2614 { "Compressed Final Octets (CmprE)", "ipv6.routing_hdr.rpl.cmprE",
2615 FT_UINT32, BASE_DEC, NULL, IP6RRPL_BITMASK_CMPRE,
2616 "Elided octets from last segment address", HFILL }},
2618 { &hf_ipv6_routing_hdr_rpl_pad,
2619 { "Padding Bytes", "ipv6.routing_hdr.rpl.pad",
2620 FT_UINT32, BASE_DEC, NULL, IP6RRPL_BITMASK_PAD,
2621 NULL, HFILL }},
2623 { &hf_ipv6_routing_hdr_rpl_reserved,
2624 { "Reserved", "ipv6.routing_hdr.rpl.reserved",
2625 FT_UINT32, BASE_DEC, NULL, IP6RRPL_BITMASK_RESERVED,
2626 "Must be Zero", HFILL }},
2628 { &hf_ipv6_routing_hdr_rpl_segments,
2629 { "Total Segments", "ipv6.routing_hdr.rpl.segments",
2630 FT_INT32, BASE_DEC, NULL, 0,
2631 NULL, HFILL }},
2633 { &hf_ipv6_routing_hdr_rpl_addr,
2634 { "Address", "ipv6.routing_hdr.rpl.address",
2635 FT_BYTES, BASE_NONE, NULL, 0,
2636 NULL, HFILL }},
2638 { &hf_ipv6_routing_hdr_rpl_fulladdr,
2639 { "Full Address", "ipv6.routing_hdr.rpl.full_address",
2640 FT_IPv6, BASE_NONE, NULL, 0,
2641 "Uncompressed IPv6 Address", HFILL }},
2643 /* Mobile IPv6 */
2644 { &hf_ipv6_mipv6_home_address,
2645 { "Home Address", "ipv6.mipv6_home_address",
2646 FT_IPv6, BASE_NONE, NULL, 0x0,
2647 NULL, HFILL }},
2649 /* SHIM6 */
2650 { &hf_ipv6_shim6,
2651 { "SHIM6", "ipv6.shim6",
2652 FT_NONE, BASE_NONE, NULL, 0x0,
2653 NULL, HFILL }},
2655 { &hf_ipv6_shim6_nxt,
2656 { "Next Header", "ipv6.shim6.nxt",
2657 FT_UINT8, BASE_DEC, NULL, 0x0,
2658 NULL, HFILL }},
2660 { &hf_ipv6_shim6_len,
2661 { "Header Ext Length", "ipv6.shim6.len",
2662 FT_UINT8, BASE_DEC, NULL, 0x0,
2663 NULL, HFILL }},
2665 { &hf_ipv6_shim6_p,
2666 { "P Bit", "ipv6.shim6.p",
2667 FT_BOOLEAN, 8, NULL, SHIM6_BITMASK_P,
2668 NULL, HFILL }},
2670 { &hf_ipv6_shim6_ct,
2671 { "Context Tag", "ipv6.shim6.ct",
2672 FT_NONE, BASE_NONE, NULL, 0x0,
2673 NULL, HFILL }},
2675 { &hf_ipv6_shim6_type,
2676 { "Message Type", "ipv6.shim6.type",
2677 FT_UINT8, BASE_DEC,
2678 VALS(shimctrlvals), SHIM6_BITMASK_TYPE,
2679 NULL, HFILL }},
2681 { &hf_ipv6_shim6_proto,
2682 { "Protocol", "ipv6.shim6.proto",
2683 FT_UINT8, BASE_DEC,
2684 VALS(shim6_protocol), SHIM6_BITMASK_PROTOCOL,
2685 NULL, HFILL }},
2687 { &hf_ipv6_shim6_checksum,
2688 { "Checksum", "ipv6.shim6.checksum",
2689 FT_UINT16, BASE_HEX, NULL, 0x0,
2690 "Shim6 Checksum", HFILL }},
2691 { &hf_ipv6_shim6_checksum_bad,
2692 { "Bad Checksum", "ipv6.shim6.checksum_bad",
2693 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2694 "Shim6 Bad Checksum", HFILL }},
2696 { &hf_ipv6_shim6_checksum_good,
2697 { "Good Checksum", "ipv6.shim6.checksum_good",
2698 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2699 NULL, HFILL }},
2701 { &hf_ipv6_shim6_inonce,
2702 { "Initiator Nonce", "ipv6.shim6.inonce",
2703 FT_UINT32, BASE_DEC_HEX, NULL, 0x0,
2704 NULL, HFILL }},
2706 { &hf_ipv6_shim6_rnonce,
2707 { "Responder Nonce", "ipv6.shim6.rnonce",
2708 FT_UINT32, BASE_DEC_HEX, NULL, 0x0,
2709 NULL, HFILL }},
2711 { &hf_ipv6_shim6_precvd,
2712 { "Probes Received", "ipv6.shim6.precvd",
2713 FT_UINT8, BASE_DEC, NULL, SHIM6_BITMASK_PRECVD,
2714 NULL, HFILL }},
2716 { &hf_ipv6_shim6_psent,
2717 { "Probes Sent", "ipv6.shim6.psent",
2718 FT_UINT8, BASE_DEC, NULL, SHIM6_BITMASK_PSENT,
2719 NULL, HFILL }},
2721 { &hf_ipv6_shim6_psrc,
2722 { "Source Address", "ipv6.shim6.psrc",
2723 FT_IPv6, BASE_NONE, NULL, 0x0,
2724 "Shim6 Probe Source Address", HFILL }},
2726 { &hf_ipv6_shim6_pdst,
2727 { "Destination Address", "ipv6.shim6.pdst",
2728 FT_IPv6, BASE_NONE, NULL, 0x0,
2729 "Shim6 Probe Destination Address", HFILL }},
2731 { &hf_ipv6_shim6_pnonce,
2732 { "Nonce", "ipv6.shim6.pnonce",
2733 FT_UINT32, BASE_DEC_HEX, NULL, 0x0,
2734 "Shim6 Probe Nonce", HFILL }},
2736 { &hf_ipv6_shim6_pdata,
2737 { "Data", "ipv6.shim6.pdata",
2738 FT_UINT32, BASE_HEX, NULL, 0x0,
2739 "Shim6 Probe Data", HFILL }},
2741 { &hf_ipv6_shim6_sulid,
2742 { "Sender ULID", "ipv6.shim6.sulid",
2743 FT_IPv6, BASE_NONE, NULL, 0x0,
2744 "Shim6 Sender ULID", HFILL }},
2746 { &hf_ipv6_shim6_rulid,
2747 { "Receiver ULID", "ipv6.shim6.rulid",
2748 FT_IPv6, BASE_NONE, NULL, 0x0,
2749 "Shim6 Receiver ULID", HFILL }},
2751 { &hf_ipv6_shim6_reap,
2752 { "REAP State", "ipv6.shim6.reap",
2753 FT_UINT8, BASE_DEC, NULL, 0x0,
2754 NULL, HFILL }},
2756 { &hf_ipv6_shim6_opt_type,
2757 { "Option Type", "ipv6.shim6.opt.type",
2758 FT_UINT16, BASE_DEC,
2759 VALS(shimoptvals), SHIM6_BITMASK_OPT_TYPE,
2760 "Shim6 Option Type", HFILL }},
2762 { &hf_ipv6_shim6_opt_critical,
2763 { "Option Critical Bit", "ipv6.shim6.opt.critical",
2764 FT_BOOLEAN, 8,
2765 TFS(&tfs_yes_no),
2766 SHIM6_BITMASK_CRITICAL,
2767 "TRUE : option is critical, FALSE: option is not critical",
2768 HFILL }},
2770 { &hf_ipv6_shim6_opt_len,
2771 { "Content Length", "ipv6.shim6.opt.len",
2772 FT_UINT16, BASE_DEC, NULL, 0x0,
2773 "Content Length Option", HFILL }},
2775 { &hf_ipv6_shim6_opt_total_len,
2776 { "Total Length", "ipv6.shim6.opt.total_len",
2777 FT_UINT16, BASE_DEC, NULL, 0x0,
2778 "Total Option Length", HFILL }},
2780 { &hf_ipv6_shim6_opt_loc_verif_methods,
2781 { "Verification Method", "ipv6.shim6.opt.verif_method",
2782 FT_UINT8, BASE_DEC,
2783 VALS(shimverifmethods), 0x0,
2784 "Locator Verification Method", HFILL }},
2786 { &hf_ipv6_shim6_opt_loclist,
2787 { "Locator List Generation", "ipv6.shim6.opt.loclist",
2788 FT_UINT32, BASE_DEC_HEX, NULL, 0x0,
2789 NULL, HFILL }},
2791 { &hf_ipv6_shim6_locator,
2792 { "Locator", "ipv6.shim6.locator",
2793 FT_IPv6, BASE_NONE, NULL, 0x0,
2794 "Shim6 Locator", HFILL }},
2796 { &hf_ipv6_shim6_opt_locnum,
2797 { "Num Locators", "ipv6.shim6.opt.locnum",
2798 FT_UINT8, BASE_DEC, NULL, 0x0,
2799 "Number of Locators in Locator List", HFILL }},
2801 { &hf_ipv6_shim6_opt_elemlen,
2802 { "Element Length", "ipv6.shim6.opt.elemlen",
2803 FT_UINT8, BASE_DEC, NULL, 0x0,
2804 "Length of Elements in Locator Preferences Option", HFILL }},
2805 { &hf_ipv6_shim6_loc_flag,
2806 { "Flags", "ipv6.shim6.loc.flags",
2807 FT_UINT8, BASE_DEC, NULL, 0x0,
2808 "Locator Preferences Flags", HFILL }},
2810 { &hf_ipv6_shim6_loc_prio,
2811 { "Priority", "ipv6.shim6.loc.prio",
2812 FT_UINT8, BASE_DEC, NULL, 0x0,
2813 "Locator Preferences Priority", HFILL }},
2815 { &hf_ipv6_shim6_loc_weight,
2816 { "Weight", "ipv6.shim6.loc.weight",
2817 FT_UINT8, BASE_DEC, NULL, 0x0,
2818 "Locator Preferences Weight", HFILL }},
2820 { &hf_ipv6_shim6_opt_fii,
2821 { "Forked Instance Identifier", "ipv6.shim6.opt.fii",
2822 FT_UINT32, BASE_DEC_HEX, NULL, 0x0,
2823 NULL, HFILL }},
2825 { &hf_ipv6_traffic_class_dscp,
2826 { "Differentiated Services Field", "ipv6.traffic_class.dscp",
2827 FT_UINT32, BASE_HEX | BASE_EXT_STRING, &dscp_vals_ext, 0x0FC00000, NULL, HFILL }},
2829 { &hf_ipv6_traffic_class_ect,
2830 { "ECN-Capable Transport (ECT)", "ipv6.traffic_class.ect",
2831 FT_BOOLEAN, 32, TFS(&tfs_set_notset), 0x0200000, NULL, HFILL }},
2833 { &hf_ipv6_traffic_class_ce,
2834 { "ECN-CE", "ipv6.traffic_class.ce",
2835 FT_BOOLEAN, 32, TFS(&tfs_set_notset), 0x0100000, NULL, HFILL }},
2837 static gint *ett[] = {
2838 &ett_ipv6,
2839 &ett_ipv6_opt,
2840 &ett_ipv6_opt_flag,
2841 &ett_ipv6_version,
2842 &ett_ipv6_shim6,
2843 &ett_ipv6_shim6_option,
2844 &ett_ipv6_shim6_locators,
2845 &ett_ipv6_shim6_verif_methods,
2846 &ett_ipv6_shim6_loc_pref,
2847 &ett_ipv6_shim6_probes_sent,
2848 &ett_ipv6_shim6_probes_rcvd,
2849 &ett_ipv6_shim6_probe_sent,
2850 &ett_ipv6_shim6_probe_rcvd,
2851 &ett_ipv6_shim6_cksum,
2852 &ett_ipv6_fragments,
2853 &ett_ipv6_fragment,
2854 &ett_ipv6_traffic_class,
2855 #ifdef HAVE_GEOIP_V6
2856 &ett_geoip_info
2857 #endif /* HAVE_GEOIP_V6 */
2859 static ei_register_info ei[] = {
2860 { &ei_ipv6_dst_addr_not_multicast, { "ipv6.dst_addr.not_multicast", PI_PROTOCOL, PI_WARN, "Destination address must not be a multicast address", EXPFILL }},
2861 { &ei_ipv6_src_route_list_mult_inst_same_addr, { "ipv6.src_route_list.mult_inst_same_addr", PI_PROTOCOL, PI_ERROR, "Multiple instances of the same address must not appear in the source route list", EXPFILL }},
2862 { &ei_ipv6_src_route_list_src_addr, { "ipv6.src_route_list.src_addr", PI_PROTOCOL, PI_ERROR, "Source address must not appear in the source route list", EXPFILL }},
2863 { &ei_ipv6_src_route_list_dst_addr, { "ipv6.src_route_list.dst_addr", PI_PROTOCOL, PI_ERROR, "Destination address must not appear in the source route list", EXPFILL }},
2864 { &ei_ipv6_src_route_list_multicast_addr, { "ipv6.src_route_list.multicast_addr", PI_PROTOCOL, PI_ERROR, "Multicast addresses must not appear in the source route list", EXPFILL }},
2865 { &ei_ipv6_cmpri_cmpre_pad, { "ipv6.routing_hdr.rpl.cmprI.cmprE.pad", PI_PROTOCOL, PI_WARN, "When cmprI equals 0 and cmprE equals 0, pad MUST equal 0 but instead was X", EXPFILL }},
2866 { &ei_ipv6_routing_hdr_rpl_reserved, { "ipv6.routing_hdr.rpl.reserved.not0", PI_PROTOCOL, PI_WARN, "Reserved field must equal 0 but instead was X", EXPFILL }},
2867 { &ei_ipv6_opt_tel_invalid_len, { "ipv6.opt.tel.invalid_len", PI_MALFORMED, PI_ERROR, "Tunnel Encapsulation Limit: Invalid length", EXPFILL }},
2868 { &ei_ipv6_opt_jumbo_invalid_len, { "ipv6.opt.jumbo.invalid_len", PI_MALFORMED, PI_ERROR, "Jumbo payload: Invalid length", EXPFILL }},
2869 { &ei_ipv6_opt_rtalert_invalid_len, { "ipv6.opt.router_alert.invalid_len", PI_MALFORMED, PI_ERROR, "Router alert: Invalid Length", EXPFILL }},
2870 { &ei_ipv6_mipv6_home_address_invalid_len, { "ipv6.mipv6_home_address.invalid_len", PI_MALFORMED, PI_ERROR, "Home Address: Invalid length", EXPFILL }},
2871 { &ei_ipv6_shim6_opt_elemlen_invalid, { "ipv6.shim6.opt.elemlen.invalid", PI_MALFORMED, PI_ERROR, "Invalid element length", EXPFILL }},
2872 { &ei_ipv6_shim6_checksum_bad, { "ipv6.shim6.checksum_bad.expert", PI_CHECKSUM, PI_ERROR, "Bad checksum", EXPFILL }},
2873 { &ei_ipv6_routing_hdr_rpl_segments_ge0, { "ipv6.routing_hdr.rpl.segments.ge0", PI_MALFORMED, PI_ERROR, "Calculated total segments must be greater than or equal to 0, instead was X", EXPFILL }},
2876 module_t *ipv6_module;
2877 expert_module_t* expert_ipv6;
2879 proto_ipv6 = proto_register_protocol("Internet Protocol Version 6", "IPv6", "ipv6");
2880 proto_register_field_array(proto_ipv6, hf, array_length(hf));
2881 proto_register_subtree_array(ett, array_length(ett));
2882 expert_ipv6 = expert_register_protocol(proto_ipv6);
2883 expert_register_field_array(expert_ipv6, ei, array_length(ei));
2885 /* Register configuration options */
2886 ipv6_module = prefs_register_protocol(proto_ipv6, NULL);
2887 prefs_register_bool_preference(ipv6_module, "defragment",
2888 "Reassemble fragmented IPv6 datagrams",
2889 "Whether fragmented IPv6 datagrams should be reassembled",
2890 &ipv6_reassemble);
2891 prefs_register_bool_preference(ipv6_module, "summary_in_tree",
2892 "Show IPv6 summary in protocol tree",
2893 "Whether the IPv6 summary line should be shown in the protocol tree",
2894 &ipv6_summary_in_tree);
2895 #ifdef HAVE_GEOIP_V6
2896 prefs_register_bool_preference(ipv6_module, "use_geoip" ,
2897 "Enable GeoIP lookups",
2898 "Whether to look up IPv6 addresses in each GeoIP database we have loaded",
2899 &ipv6_use_geoip);
2900 #endif /* HAVE_GEOIP_V6 */
2902 /* RPL Strict Header Checking */
2903 prefs_register_bool_preference(ipv6_module, "perform_strict_rpl_srh_rfc_checking",
2904 "Perform strict checking for adherence to the RFC for RPL Source Routing Headers (RFC 6554)",
2905 "Whether to check that all RPL Source Routing Headers adhere to RFC 6554",
2906 &g_ipv6_rpl_srh_strict_rfc_checking);
2908 register_dissector("ipv6", dissect_ipv6, proto_ipv6);
2909 register_init_routine(ipv6_reassemble_init);
2910 ipv6_tap = register_tap("ipv6");
2913 void
2914 proto_reg_handoff_ipv6(void)
2916 dissector_handle_t ipv6_handle;
2918 data_handle = find_dissector("data");
2919 ipv6_handle = find_dissector("ipv6");
2920 dissector_add_uint("ethertype", ETHERTYPE_IPv6, ipv6_handle);
2921 dissector_add_uint("ppp.protocol", PPP_IPV6, ipv6_handle);
2922 dissector_add_uint("ppp.protocol", ETHERTYPE_IPv6, ipv6_handle);
2923 dissector_add_uint("gre.proto", ETHERTYPE_IPv6, ipv6_handle);
2924 dissector_add_uint("ip.proto", IP_PROTO_IPV6, ipv6_handle);
2925 dissector_add_uint("null.type", BSD_AF_INET6_BSD, ipv6_handle);
2926 dissector_add_uint("null.type", BSD_AF_INET6_FREEBSD, ipv6_handle);
2927 dissector_add_uint("null.type", BSD_AF_INET6_DARWIN, ipv6_handle);
2928 dissector_add_uint("chdlc.protocol", ETHERTYPE_IPv6, ipv6_handle);
2929 dissector_add_uint("fr.nlpid", NLPID_IP6, ipv6_handle);
2930 dissector_add_uint("osinl.excl", NLPID_IP6, ipv6_handle);
2931 dissector_add_uint("x.25.spi", NLPID_IP6, ipv6_handle);
2932 dissector_add_uint("arcnet.protocol_id", ARCNET_PROTO_IPv6, ipv6_handle);
2934 ip_dissector_table = find_dissector_table("ip.proto");
2938 * Editor modelines
2940 * Local Variables:
2941 * c-basic-offset: 2
2942 * tab-width: 8
2943 * indent-tabs-mode: nil
2944 * End:
2946 * ex: set shiftwidth=2 tabstop=8 expandtab:
2947 * :indentSize=2:tabSize=8:noTabs=true: