Add GeoIP IPv6 database support. Tested with GeoIP 1.4.7, but older
[obnox/wireshark/wip.git] / epan / dissectors / packet-ipv6.c
1 /* packet-ipv6.c
2  * Routines for IPv6 packet disassembly
3  *
4  * $Id$
5  *
6  * Wireshark - Network traffic analyzer
7  * By Gerald Combs <gerald@wireshark.org>
8  * Copyright 1998 Gerald Combs
9  *
10  * SHIM6 support added by Matthijs Mekking <matthijs@NLnetLabs.nl>
11  *
12  * MobileIPv6 support added by Tomislav Borosa <tomislav.borosa@siemens.hr>
13  *
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.
18  *
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.
23  *
24  * You should have received a copy of the GNU General Public License
25  * along with this program; if not, write to the Free Software
26  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
27  */
28
29 #ifdef HAVE_CONFIG_H
30 # include "config.h"
31 #endif
32
33 #include <math.h>
34 #include <glib.h>
35 #include <epan/packet.h>
36 #include <epan/ip_opts.h>
37 #include <epan/addr_resolv.h>
38 #include <epan/prefs.h>
39 #include <epan/reassemble.h>
40 #include <epan/ipproto.h>
41 #include <epan/ipv6-utils.h>
42 #include <epan/etypes.h>
43 #include <epan/ppptypes.h>
44 #include <epan/aftypes.h>
45 #include <epan/nlpid.h>
46 #include <epan/arcnet_pids.h>
47 #include <epan/in_cksum.h>
48 #include <epan/expert.h>
49 #include <epan/emem.h>
50 #include <epan/tap.h>
51 #include "packet-ipsec.h"
52 #include "packet-ipv6.h"
53
54 #ifdef HAVE_GEOIP_V6
55 #include "GeoIP.h"
56 #include <epan/geoip_db.h>
57 #endif /* HAVE_GEOIP_V6 */
58
59 /*
60  * NOTE: ipv6.nxt is not very useful as we will have chained header.
61  * now testing ipv6.final, but it raises SEGV.
62 #define TEST_FINALHDR
63  */
64
65 /* Differentiated Services Field. See RFCs 2474, 2597 and 2598. */
66 #define IPDSFIELD_DSCP_MASK     0xFC
67 #define IPDSFIELD_ECN_MASK     0x03
68 #define IPDSFIELD_DSCP_SHIFT    2
69 #define IPDSFIELD_DSCP(dsfield) (((dsfield)&IPDSFIELD_DSCP_MASK)>>IPDSFIELD_DSCP_SHIFT)
70 #define IPDSFIELD_ECN(dsfield)  ((dsfield)&IPDSFIELD_ECN_MASK)
71 #define IPDSFIELD_DSCP_DEFAULT  0x00
72 #define IPDSFIELD_DSCP_CS1      0x08
73 #define IPDSFIELD_DSCP_CS2      0x10
74 #define IPDSFIELD_DSCP_CS3      0x18
75 #define IPDSFIELD_DSCP_CS4      0x20
76 #define IPDSFIELD_DSCP_CS5      0x28
77 #define IPDSFIELD_DSCP_CS6      0x30
78 #define IPDSFIELD_DSCP_CS7      0x38
79 #define IPDSFIELD_DSCP_AF11     0x0A
80 #define IPDSFIELD_DSCP_AF12     0x0C
81 #define IPDSFIELD_DSCP_AF13     0x0E
82 #define IPDSFIELD_DSCP_AF21     0x12
83 #define IPDSFIELD_DSCP_AF22     0x14
84 #define IPDSFIELD_DSCP_AF23     0x16
85 #define IPDSFIELD_DSCP_AF31     0x1A
86 #define IPDSFIELD_DSCP_AF32     0x1C
87 #define IPDSFIELD_DSCP_AF33     0x1E
88 #define IPDSFIELD_DSCP_AF41     0x22
89 #define IPDSFIELD_DSCP_AF42     0x24
90 #define IPDSFIELD_DSCP_AF43     0x26
91 #define IPDSFIELD_DSCP_EF       0x2E
92 #define IPDSFIELD_ECT_MASK      0x02
93 #define IPDSFIELD_CE_MASK       0x01
94
95 /* RPL Routing header */
96 #define IP6RRPL_BITMASK_CMPRI     0xF0000000
97 #define IP6RRPL_BITMASK_CMPRE     0x0F000000
98 #define IP6RRPL_BITMASK_PAD       0x00F00000
99 #define IP6RRPL_BITMASK_RESERVED  0x000FFFFF
100
101 static int ipv6_tap = -1;
102
103 static int proto_ipv6             = -1;
104 static int hf_ipv6_version        = -1;
105 static int hf_ip_version      = -1;
106 static int hf_ipv6_class          = -1;
107 static int hf_ipv6_flow           = -1;
108 static int hf_ipv6_plen           = -1;
109 static int hf_ipv6_nxt            = -1;
110 static int hf_ipv6_hlim           = -1;
111 static int hf_ipv6_src            = -1;
112 static int hf_ipv6_src_host       = -1;
113 static int hf_ipv6_src_sa_mac     = -1;
114 static int hf_ipv6_src_isatap_ipv4              = -1;
115 static int hf_ipv6_src_6to4_gateway_ipv4        = -1;
116 static int hf_ipv6_src_6to4_sla_id              = -1;
117 static int hf_ipv6_src_teredo_server_ipv4       = -1;
118 static int hf_ipv6_src_teredo_port              = -1;
119 static int hf_ipv6_src_teredo_client_ipv4       = -1;
120 static int hf_ipv6_dst            = -1;
121 static int hf_ipv6_dst_host       = -1;
122 static int hf_ipv6_dst_sa_mac     = -1;
123 static int hf_ipv6_dst_isatap_ipv4        = -1;
124 static int hf_ipv6_dst_6to4_gateway_ipv4        = -1;
125 static int hf_ipv6_dst_6to4_sla_id              = -1;
126 static int hf_ipv6_dst_teredo_server_ipv4       = -1;
127 static int hf_ipv6_dst_teredo_port              = -1;
128 static int hf_ipv6_dst_teredo_client_ipv4       = -1;
129 static int hf_ipv6_addr           = -1;
130 static int hf_ipv6_host           = -1;
131 static int hf_ipv6_sa_mac         = -1;
132 static int hf_ipv6_isatap_ipv4    = -1;
133 static int hf_ipv6_6to4_gateway_ipv4            = -1;
134 static int hf_ipv6_6to4_sla_id                  = -1;
135 static int hf_ipv6_teredo_server_ipv4           = -1;
136 static int hf_ipv6_teredo_port                  = -1;
137 static int hf_ipv6_teredo_client_ipv4           = -1;
138 static int hf_ipv6_opt_pad1       = -1;
139 static int hf_ipv6_opt_padn       = -1;
140 static int hf_ipv6_dst_opt        = -1;
141 static int hf_ipv6_hop_opt        = -1;
142 static int hf_ipv6_unk_hdr        = -1;
143 static int hf_ipv6_routing_hdr_opt        = -1;
144 static int hf_ipv6_routing_hdr_type       = -1;
145 static int hf_ipv6_routing_hdr_left       = -1;
146 static int hf_ipv6_routing_hdr_addr       = -1;
147 #ifdef TEST_FINALHDR
148 static int hf_ipv6_final          = -1;
149 #endif
150 static int hf_ipv6_frag_offset                = -1;
151 static int hf_ipv6_frag_more                  = -1;
152 static int hf_ipv6_frag_id                    = -1;
153 static int hf_ipv6_fragments                  = -1;
154 static int hf_ipv6_fragment                   = -1;
155 static int hf_ipv6_fragment_overlap           = -1;
156 static int hf_ipv6_fragment_overlap_conflict  = -1;
157 static int hf_ipv6_fragment_multiple_tails    = -1;
158 static int hf_ipv6_fragment_too_long_fragment = -1;
159 static int hf_ipv6_fragment_error             = -1;
160 static int hf_ipv6_fragment_count             = -1;
161 static int hf_ipv6_reassembled_in             = -1;
162 static int hf_ipv6_reassembled_length         = -1;
163
164 static int hf_ipv6_mipv6_type                 = -1;
165 static int hf_ipv6_mipv6_length               = -1;
166 static int hf_ipv6_mipv6_home_address         = -1;
167
168 static int hf_ipv6_routing_hdr_rpl_cmprI  = -1;
169 static int hf_ipv6_routing_hdr_rpl_cmprE  = -1;
170 static int hf_ipv6_routing_hdr_rpl_pad    = -1;
171 static int hf_ipv6_routing_hdr_rpl_reserved = -1;
172 static int hf_ipv6_routing_hdr_rpl_segments = -1;
173 static int hf_ipv6_routing_hdr_rpl_addr = -1;
174 static int hf_ipv6_routing_hdr_rpl_fulladdr = -1;
175
176 static int hf_ipv6_shim6              = -1;
177 static int hf_ipv6_shim6_nxt          = -1;
178 static int hf_ipv6_shim6_len          = -1;
179 static int hf_ipv6_shim6_p            = -1;
180 /* context tag is 49 bits, cannot be used for filter yet */
181 static int hf_ipv6_shim6_ct           = -1;
182 static int hf_ipv6_shim6_type         = -1;
183 static int hf_ipv6_shim6_proto        = -1;
184 static int hf_ipv6_shim6_checksum     = -1;
185 static int hf_ipv6_shim6_checksum_bad = -1;
186 static int hf_ipv6_shim6_checksum_good= -1;
187 static int hf_ipv6_shim6_inonce       = -1; /* also for request nonce */
188 static int hf_ipv6_shim6_rnonce       = -1;
189 static int hf_ipv6_shim6_precvd       = -1;
190 static int hf_ipv6_shim6_psent        = -1;
191 static int hf_ipv6_shim6_psrc         = -1;
192 static int hf_ipv6_shim6_pdst         = -1;
193 static int hf_ipv6_shim6_pnonce       = -1;
194 static int hf_ipv6_shim6_pdata        = -1;
195 static int hf_ipv6_shim6_sulid        = -1;
196 static int hf_ipv6_shim6_rulid        = -1;
197 static int hf_ipv6_shim6_reap         = -1;
198 static int hf_ipv6_shim6_opt_type     = -1;
199 static int hf_ipv6_shim6_opt_len      = -1;
200 static int hf_ipv6_shim6_opt_total_len= -1;
201 static int hf_ipv6_shim6_opt_loc_verif_methods = -1;
202 static int hf_ipv6_shim6_opt_critical = -1;
203 static int hf_ipv6_shim6_opt_loclist  = -1;
204 static int hf_ipv6_shim6_locator      = -1;
205 static int hf_ipv6_shim6_loc_flag     = -1;
206 static int hf_ipv6_shim6_loc_prio     = -1;
207 static int hf_ipv6_shim6_loc_weight   = -1;
208 static int hf_ipv6_shim6_opt_locnum   = -1;
209 static int hf_ipv6_shim6_opt_elemlen  = -1;
210 static int hf_ipv6_shim6_opt_fii      = -1;
211 static int hf_ipv6_traffic_class_dscp = -1;
212 static int hf_ipv6_traffic_class_ect  = -1;
213 static int hf_ipv6_traffic_class_ce   = -1;
214
215 #ifdef HAVE_GEOIP_V6
216 static int hf_geoip_country = -1;
217 static int hf_geoip_city = -1;
218 static int hf_geoip_org = -1;
219 static int hf_geoip_isp = -1;
220 static int hf_geoip_asnum = -1;
221 static int hf_geoip_lat = -1;
222 static int hf_geoip_lon = -1;
223 static int hf_geoip_src_country = -1;
224 static int hf_geoip_src_city = -1;
225 static int hf_geoip_src_org = -1;
226 static int hf_geoip_src_isp = -1;
227 static int hf_geoip_src_asnum = -1;
228 static int hf_geoip_src_lat = -1;
229 static int hf_geoip_src_lon = -1;
230 static int hf_geoip_dst_country = -1;
231 static int hf_geoip_dst_city = -1;
232 static int hf_geoip_dst_org = -1;
233 static int hf_geoip_dst_isp = -1;
234 static int hf_geoip_dst_asnum = -1;
235 static int hf_geoip_dst_lat = -1;
236 static int hf_geoip_dst_lon = -1;
237 #endif /* HAVE_GEOIP_V6 */
238
239 static gint ett_ipv6                      = -1;
240 static gint ett_ipv6_version    = -1;
241 static gint ett_ipv6_shim6                = -1;
242 static gint ett_ipv6_shim6_option         = -1;
243 static gint ett_ipv6_shim6_locators       = -1;
244 static gint ett_ipv6_shim6_verif_methods  = -1;
245 static gint ett_ipv6_shim6_loc_pref       = -1;
246 static gint ett_ipv6_shim6_probes_sent    = -1;
247 static gint ett_ipv6_shim6_probe_sent     = -1;
248 static gint ett_ipv6_shim6_probes_rcvd    = -1;
249 static gint ett_ipv6_shim6_probe_rcvd     = -1;
250 static gint ett_ipv6_shim6_cksum          = -1;
251 static gint ett_ipv6_fragments            = -1;
252 static gint ett_ipv6_fragment             = -1;
253 static gint ett_ipv6_traffic_class        = -1;
254
255 #ifdef HAVE_GEOIP_V6
256 static gint ett_geoip_info = -1;
257 #endif /* HAVE_GEOIP_V6 */
258
259
260 static const fragment_items ipv6_frag_items = {
261         &ett_ipv6_fragment,
262         &ett_ipv6_fragments,
263         &hf_ipv6_fragments,
264         &hf_ipv6_fragment,
265         &hf_ipv6_fragment_overlap,
266         &hf_ipv6_fragment_overlap_conflict,
267         &hf_ipv6_fragment_multiple_tails,
268         &hf_ipv6_fragment_too_long_fragment,
269         &hf_ipv6_fragment_error,
270         &hf_ipv6_fragment_count,
271         &hf_ipv6_reassembled_in,
272         &hf_ipv6_reassembled_length,
273         "IPv6 fragments"
274 };
275
276 static dissector_handle_t data_handle;
277
278 static dissector_table_t ip_dissector_table;
279
280 /* Reassemble fragmented datagrams */
281 static gboolean ipv6_reassemble = TRUE;
282
283 /* Place IPv6 summary in proto tree */
284 static gboolean ipv6_summary_in_tree = TRUE;
285
286 #ifdef HAVE_GEOIP_V6
287 /* Look up addresses in GeoIP */
288 static gboolean ipv6_use_geoip = FALSE;
289 #endif /* HAVE_GEOIP_V6 */
290
291 #ifndef offsetof
292 #define offsetof(type, member)  ((size_t)(&((type *)0)->member))
293 #endif
294
295 /*
296  * defragmentation of IPv6
297  */
298 static GHashTable *ipv6_fragment_table = NULL;
299 static GHashTable *ipv6_reassembled_table = NULL;
300
301 void
302 capture_ipv6(const guchar *pd, int offset, int len, packet_counts *ld)
303 {
304   guint8 nxt;
305   int advance;
306
307   if (!BYTES_ARE_IN_FRAME(offset, len, 4+4+16+16)) {
308     ld->other++;
309     return;
310   }
311   nxt = pd[offset+6];           /* get the "next header" value */
312   offset += 4+4+16+16;          /* skip past the IPv6 header */
313
314 again:
315    switch (nxt) {
316    case IP_PROTO_HOPOPTS:
317    case IP_PROTO_ROUTING:
318    case IP_PROTO_DSTOPTS:
319      if (!BYTES_ARE_IN_FRAME(offset, len, 2)) {
320        ld->other++;
321        return;
322      }
323      nxt = pd[offset];
324      advance = (pd[offset+1] + 1) << 3;
325      if (!BYTES_ARE_IN_FRAME(offset, len, advance)) {
326        ld->other++;
327        return;
328      }
329      offset += advance;
330      goto again;
331    case IP_PROTO_FRAGMENT:
332      if (!BYTES_ARE_IN_FRAME(offset, len, 2)) {
333        ld->other++;
334        return;
335      }
336      nxt = pd[offset];
337      advance = 8;
338      if (!BYTES_ARE_IN_FRAME(offset, len, advance)) {
339        ld->other++;
340        return;
341      }
342      offset += advance;
343      goto again;
344    case IP_PROTO_AH:
345      if (!BYTES_ARE_IN_FRAME(offset, len, 2)) {
346        ld->other++;
347        return;
348      }
349      nxt = pd[offset];
350      advance = 8 + ((pd[offset+1] - 1) << 2);
351      if (!BYTES_ARE_IN_FRAME(offset, len, advance)) {
352        ld->other++;
353        return;
354      }
355      offset += advance;
356      goto again;
357    case IP_PROTO_SHIM6:
358    case IP_PROTO_SHIM6_OLD:
359      if (!BYTES_ARE_IN_FRAME(offset, len, 2)) {
360        ld->other++;
361        return;
362      }
363      nxt = pd[offset];
364      advance = (pd[offset+1] + 1) << 3;
365      if (!BYTES_ARE_IN_FRAME(offset, len, advance)) {
366        ld->other++;
367        return;
368      }
369      offset += advance;
370      goto again;
371    }
372
373   switch(nxt) {
374     case IP_PROTO_SCTP:
375       ld->sctp++;
376       break;
377     case IP_PROTO_TCP:
378       ld->tcp++;
379       break;
380     case IP_PROTO_UDP:
381     case IP_PROTO_UDPLITE:
382       ld->udp++;
383       break;
384     case IP_PROTO_ICMP:
385     case IP_PROTO_ICMPV6:       /* XXX - separate counters? */
386       ld->icmp++;
387       break;
388     case IP_PROTO_OSPF:
389       ld->ospf++;
390       break;
391     case IP_PROTO_GRE:
392       ld->gre++;
393       break;
394     case IP_PROTO_VINES:
395       ld->vines++;
396       break;
397     default:
398       ld->other++;
399   }
400 }
401
402 #ifdef HAVE_GEOIP_V6
403 static void
404 add_geoip_info(proto_tree *tree, tvbuff_t *tvb, gint offset, struct e_in6_addr src, struct e_in6_addr dst)
405 {
406   guint dbnum, num_dbs;
407   int geoip_hf, geoip_src_hf, geoip_dst_hf;
408   const char *geoip_src_str, *geoip_dst_str;
409   proto_item *geoip_info_item;
410   proto_tree *geoip_info_tree;
411   proto_item *item;
412   guint item_cnt;
413
414   num_dbs = geoip_db_num_dbs();
415
416   geoip_info_item = proto_tree_add_text(tree, tvb, offset + IP6H_SRC, 16, "Source GeoIP: ");
417   geoip_info_tree = proto_item_add_subtree(geoip_info_item, ett_geoip_info);
418   PROTO_ITEM_SET_GENERATED(geoip_info_item);
419   item_cnt = 0;
420
421   for (dbnum = 0; dbnum < num_dbs; dbnum++) {
422     geoip_src_str = geoip_db_lookup_ipv6(dbnum, src, NULL);
423
424     switch (geoip_db_type(dbnum)) {
425       case GEOIP_COUNTRY_EDITION_V6:
426         geoip_hf = hf_geoip_country;
427         geoip_src_hf = hf_geoip_src_country;
428         break;
429 #if NUM_DB_TYPES > 31
430       case GEOIP_CITY_EDITION_REV0_V6:
431         geoip_hf = hf_geoip_city;
432         geoip_src_hf = hf_geoip_src_city;
433         break;
434       case GEOIP_CITY_EDITION_REV1_V6:
435         geoip_hf = hf_geoip_city;
436         geoip_src_hf = hf_geoip_src_city;
437         break;
438       case GEOIP_ORG_EDITION_V6:
439         geoip_hf = hf_geoip_org;
440         geoip_src_hf = hf_geoip_src_org;
441         break;
442       case GEOIP_ISP_EDITION_V6:
443         geoip_hf = hf_geoip_isp;
444         geoip_src_hf = hf_geoip_src_isp;
445         break;
446       case GEOIP_ASNUM_EDITION_V6:
447         geoip_hf = hf_geoip_asnum;
448         geoip_src_hf = hf_geoip_src_asnum;
449         break;
450 #endif /* DB_NUM_TYPES */
451       case WS_LAT_FAKE_EDITION:
452         geoip_hf = hf_geoip_lat;
453         geoip_src_hf = hf_geoip_src_lat;
454         break;
455       case WS_LON_FAKE_EDITION:
456         geoip_hf = hf_geoip_lon;
457         geoip_src_hf = hf_geoip_src_lon;
458         break;
459       default:
460         continue;
461         break;
462     }
463
464     if (geoip_src_str) {
465       item = proto_tree_add_string_format_value(geoip_info_tree, geoip_src_hf, tvb,
466         offset + IP6H_SRC, 16, geoip_src_str, "%s", geoip_src_str);
467       PROTO_ITEM_SET_GENERATED(item);
468       item  = proto_tree_add_string_format_value(geoip_info_tree, geoip_hf, tvb,
469         offset + IP6H_SRC, 16, geoip_src_str, "%s", geoip_src_str);
470       PROTO_ITEM_SET_GENERATED(item);
471       PROTO_ITEM_SET_HIDDEN(item);
472
473       item_cnt++;
474       proto_item_append_text(geoip_info_item, "%s%s", plurality(item_cnt, "", ", "), geoip_src_str);
475     }
476   }
477
478   if (item_cnt == 0)
479     proto_item_append_text(geoip_info_item, "Unknown");
480
481   geoip_info_item = proto_tree_add_text(tree, tvb, offset + IP6H_DST, 16, "Destination GeoIP: ");
482   geoip_info_tree = proto_item_add_subtree(geoip_info_item, ett_geoip_info);
483   PROTO_ITEM_SET_GENERATED(geoip_info_item);
484   item_cnt = 0;
485
486   for (dbnum = 0; dbnum < num_dbs; dbnum++) {
487     geoip_dst_str = geoip_db_lookup_ipv6(dbnum, dst, NULL);
488
489     switch (geoip_db_type(dbnum)) {
490       case GEOIP_COUNTRY_EDITION:
491         geoip_hf = hf_geoip_country;
492         geoip_dst_hf = hf_geoip_dst_country;
493         break;
494 #if NUM_DB_TYPES > 31
495       case GEOIP_CITY_EDITION_REV0:
496         geoip_hf = hf_geoip_city;
497         geoip_dst_hf = hf_geoip_dst_city;
498         break;
499       case GEOIP_CITY_EDITION_REV1:
500         geoip_hf = hf_geoip_city;
501         geoip_dst_hf = hf_geoip_dst_city;
502         break;
503       case GEOIP_ORG_EDITION:
504         geoip_hf = hf_geoip_org;
505         geoip_dst_hf = hf_geoip_dst_org;
506         break;
507       case GEOIP_ISP_EDITION:
508         geoip_hf = hf_geoip_isp;
509         geoip_dst_hf = hf_geoip_dst_isp;
510         break;
511       case GEOIP_ASNUM_EDITION:
512         geoip_hf = hf_geoip_asnum;
513         geoip_dst_hf = hf_geoip_dst_asnum;
514         break;
515 #endif /* DB_NUM_TYPES */
516       case WS_LAT_FAKE_EDITION:
517         geoip_hf = hf_geoip_lat;
518         geoip_dst_hf = hf_geoip_dst_lat;
519         break;
520       case WS_LON_FAKE_EDITION:
521         geoip_hf = hf_geoip_lon;
522         geoip_dst_hf = hf_geoip_dst_lon;
523         break;
524       default:
525         continue;
526         break;
527     }
528
529     if (geoip_dst_str) {
530       item = proto_tree_add_string_format_value(geoip_info_tree, geoip_dst_hf, tvb,
531         offset + IP6H_DST, 16, geoip_dst_str, "%s", geoip_dst_str);
532       PROTO_ITEM_SET_GENERATED(item);
533       item  = proto_tree_add_string_format_value(geoip_info_tree, geoip_hf, tvb,
534         offset + IP6H_DST, 16, geoip_dst_str, "%s", geoip_dst_str);
535       PROTO_ITEM_SET_GENERATED(item);
536       PROTO_ITEM_SET_HIDDEN(item);
537
538       item_cnt++;
539       proto_item_append_text(geoip_info_item, "%s%s", plurality(item_cnt, "", ", "), geoip_dst_str);
540     }
541   }
542
543   if (item_cnt == 0)
544     proto_item_append_text(geoip_info_item, "Unknown");
545 }
546 #endif /* HAVE_GEOIP_V6 */
547
548 static void
549 ipv6_reassemble_init(void)
550 {
551   fragment_table_init(&ipv6_fragment_table);
552   reassembled_table_init(&ipv6_reassembled_table);
553 }
554
555 enum {
556   IPv6_RT_HEADER_SOURCE_ROUTING=0,
557   IPv6_RT_HEADER_NIMROD,
558   IPv6_RT_HEADER_MobileIP,
559   IPv6_RT_HEADER_RPL=4,
560 };
561
562 /* Routeing Header Types */
563 static const value_string routing_header_type[] = {
564   { IPv6_RT_HEADER_SOURCE_ROUTING, "IPv6 Source Routing" },
565   { IPv6_RT_HEADER_NIMROD, "Nimrod" },
566   { IPv6_RT_HEADER_MobileIP, "Mobile IP" },
567   { IPv6_RT_HEADER_RPL, "RPL" },
568   { 0, NULL }
569 };
570
571 static int
572 dissect_routing6(tvbuff_t *tvb, int offset, proto_tree *tree, packet_info *pinfo) {
573     struct ip6_rthdr rt;
574     guint len, seg_left;
575     proto_tree *rthdr_tree;
576     proto_item *ti;
577     guint8 buf[sizeof(struct ip6_rthdr0) + sizeof(struct e_in6_addr) * 23];
578
579     tvb_memcpy(tvb, (guint8 *)&rt, offset, sizeof(rt));
580     len = (rt.ip6r_len + 1) << 3;
581
582     if (tree) {
583         /* !!! specify length */
584       ti = proto_tree_add_uint_format(tree, hf_ipv6_routing_hdr_opt, tvb,
585                       offset, len, rt.ip6r_type,
586                       "Routing Header, Type : %s (%u)",
587                       val_to_str(rt.ip6r_type, routing_header_type, "Unknown"),
588                       rt.ip6r_type);
589       rthdr_tree = proto_item_add_subtree(ti, ett_ipv6);
590
591         proto_tree_add_text(rthdr_tree, tvb,
592             offset + offsetof(struct ip6_rthdr, ip6r_nxt), 1,
593             "Next header: %s (0x%02x)", ipprotostr(rt.ip6r_nxt), rt.ip6r_nxt);
594
595         proto_tree_add_text(rthdr_tree, tvb,
596             offset + offsetof(struct ip6_rthdr, ip6r_len), 1,
597             "Length: %u (%d bytes)", rt.ip6r_len, len);
598
599         proto_tree_add_item(rthdr_tree, hf_ipv6_routing_hdr_type, tvb,
600                   offset + offsetof(struct ip6_rthdr, ip6r_type), 1, FALSE);
601
602         proto_tree_add_item(rthdr_tree, hf_ipv6_routing_hdr_left, tvb,
603                   offset + offsetof(struct ip6_rthdr, ip6r_segleft), 1, FALSE);
604
605         seg_left = tvb_get_guint8(tvb, offset + offsetof(struct ip6_rthdr, ip6r_segleft));
606
607         if (rt.ip6r_type == IPv6_RT_HEADER_SOURCE_ROUTING && len <= sizeof(buf)) {
608             struct e_in6_addr *a;
609             int n;
610             struct ip6_rthdr0 *rt0;
611
612             tvb_memcpy(tvb, buf, offset, len);
613             rt0 = (struct ip6_rthdr0 *)buf;
614
615             for (a = rt0->ip6r0_addr, n = 0;
616                     a < (struct e_in6_addr *)(buf + len); a++, n++) {
617
618               proto_tree_add_item(rthdr_tree, hf_ipv6_routing_hdr_addr, tvb,
619                               offset + offsetof(struct ip6_rthdr0, ip6r0_addr)
620                                      + n * sizeof(struct e_in6_addr),
621                               sizeof(struct e_in6_addr), FALSE);
622               if (seg_left)
623                   SET_ADDRESS(&pinfo->dst, AT_IPv6, 16, tvb_get_ptr(tvb,
624                               offset + offsetof(struct ip6_rthdr0, ip6r0_addr)
625                                      + n * sizeof(struct e_in6_addr), 16));
626             }
627         }
628         if (rt.ip6r_type == IPv6_RT_HEADER_MobileIP) {
629           proto_tree_add_item(rthdr_tree, hf_ipv6_mipv6_home_address, tvb,
630                               offset + 8, 16, FALSE);
631           SET_ADDRESS(&pinfo->dst, AT_IPv6, 16, tvb_get_ptr(tvb, offset + 8, 16));
632         }
633     if (rt.ip6r_type == IPv6_RT_HEADER_RPL) {
634         guint8 cmprI;
635         guint8 cmprE;
636         guint8 pad;
637         gint segments;
638
639         /* IPv6 destination address used for elided bytes */
640         struct e_in6_addr dstAddr;
641         offset += 4;
642         memcpy((guint8 *)&dstAddr, (guint8 *)pinfo->dst.data, pinfo->dst.len);
643
644         proto_tree_add_item(rthdr_tree, hf_ipv6_routing_hdr_rpl_cmprI, tvb, offset, 4, FALSE);
645         proto_tree_add_item(rthdr_tree, hf_ipv6_routing_hdr_rpl_cmprE, tvb, offset, 4, FALSE);
646         proto_tree_add_item(rthdr_tree, hf_ipv6_routing_hdr_rpl_pad, tvb, offset, 4, FALSE);
647         proto_tree_add_item(rthdr_tree, hf_ipv6_routing_hdr_rpl_reserved, tvb, offset, 4, FALSE);
648
649         cmprI = tvb_get_guint8(tvb, offset) & 0xF0;
650         cmprE = tvb_get_guint8(tvb, offset) & 0x0F;
651         pad   = tvb_get_guint8(tvb, offset + 1) & 0xF0;
652
653         /* Shift bytes over */
654         cmprI >>= 4;
655         pad >>= 4;
656
657         /* from draft-ietf-6man-rpl-routing-header-03:
658         n = (((Hdr Ext Len * 8) - Pad - (16 - CmprE)) / (16 - CmprI)) + 1 */
659         segments = (((rt.ip6r_len * 8) - pad - (16 - cmprE)) / (16 - cmprI)) + 1;
660         ti = proto_tree_add_int(rthdr_tree, hf_ipv6_routing_hdr_rpl_segments, tvb, offset, 2, segments);
661         PROTO_ITEM_SET_GENERATED(ti);
662
663         if ((segments < 0) || (segments > 136)) {
664             expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_ERROR, "Calculated total segments is invalid, 0 < %d < 136 fails", segments);
665         } else {
666
667             offset += 4;
668
669             /* We use cmprI for internal (e.g.: not last) address for how many bytes to elide, so actual bytes present = 16-CmprI */
670             while(segments > 1) {
671                 struct e_in6_addr addr;
672
673                 proto_tree_add_item(rthdr_tree, hf_ipv6_routing_hdr_rpl_addr, tvb, offset, (16-cmprI), ENC_NA);
674                 /* Display Full Address */
675                 memcpy((guint8 *)&addr, (guint8 *)&dstAddr, sizeof(dstAddr));
676                 tvb_memcpy(tvb, (guint8 *)&addr + cmprI, offset, (16-cmprI));
677                 ti = proto_tree_add_ipv6(rthdr_tree, hf_ipv6_routing_hdr_rpl_fulladdr, tvb, offset, (16-cmprI), (guint8 *)&addr);
678                 PROTO_ITEM_SET_GENERATED(ti);
679                 offset += (16-cmprI);
680                 segments--;
681             }
682
683             /* We use cmprE for last address for how many bytes to elide, so actual bytes present = 16-CmprE */
684             if (segments == 1) {
685                 struct e_in6_addr addr;
686
687                 proto_tree_add_item(rthdr_tree, hf_ipv6_routing_hdr_rpl_addr, tvb, offset, (16-cmprI), ENC_NA);
688                 /* Display Full Address */
689                 memcpy((guint8 *)&addr, (guint8 *)&dstAddr, sizeof(dstAddr));
690                 tvb_memcpy(tvb, (guint8 *)&addr + cmprE, offset, (16-cmprE));
691                 ti = proto_tree_add_ipv6(rthdr_tree, hf_ipv6_routing_hdr_rpl_fulladdr, tvb, offset, (16-cmprE), (guint8 *)&addr);
692                 PROTO_ITEM_SET_GENERATED(ti);
693                 offset += (16-cmprE);
694             }
695
696         }
697
698     }
699     }
700
701     return len;
702 }
703
704 static int
705 dissect_frag6(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree,
706     guint16 *offlg, guint32 *ident) {
707     struct ip6_frag frag;
708     int len;
709     proto_item *ti;
710     proto_tree *rthdr_tree;
711
712     tvb_memcpy(tvb, (guint8 *)&frag, offset, sizeof(frag));
713     len = sizeof(frag);
714     frag.ip6f_offlg = g_ntohs(frag.ip6f_offlg);
715     frag.ip6f_ident = g_ntohl(frag.ip6f_ident);
716     *offlg = frag.ip6f_offlg;
717     *ident = frag.ip6f_ident;
718     if (check_col(pinfo->cinfo, COL_INFO)) {
719         col_add_fstr(pinfo->cinfo, COL_INFO,
720             "IPv6 fragment (nxt=%s (0x%02x) off=%u id=0x%x)",
721             ipprotostr(frag.ip6f_nxt), frag.ip6f_nxt,
722             frag.ip6f_offlg & IP6F_OFF_MASK, frag.ip6f_ident);
723     }
724     if (tree) {
725            ti = proto_tree_add_text(tree, tvb, offset, len,
726                            "Fragmentation Header");
727            rthdr_tree = proto_item_add_subtree(ti, ett_ipv6);
728
729            proto_tree_add_text(rthdr_tree, tvb,
730                          offset + offsetof(struct ip6_frag, ip6f_nxt), 1,
731                          "Next header: %s (0x%02x)",
732                          ipprotostr(frag.ip6f_nxt), frag.ip6f_nxt);
733
734 #if 0
735            proto_tree_add_text(rthdr_tree, tvb,
736                          offset + offsetof(struct ip6_frag, ip6f_reserved), 1,
737                          "Reserved: %u",
738                          frag.ip6f_reserved);
739 #endif
740
741            proto_tree_add_item(rthdr_tree, hf_ipv6_frag_offset, tvb,
742                     offset + offsetof(struct ip6_frag, ip6f_offlg), 2, FALSE);
743
744            proto_tree_add_item(rthdr_tree, hf_ipv6_frag_more, tvb,
745                     offset + offsetof(struct ip6_frag, ip6f_offlg), 2, FALSE);
746
747            proto_tree_add_item(rthdr_tree, hf_ipv6_frag_id, tvb,
748                     offset + offsetof(struct ip6_frag, ip6f_ident), 4, FALSE);
749     }
750     return len;
751 }
752
753 static int
754 dissect_mipv6_hoa(tvbuff_t *tvb, proto_tree *dstopt_tree, int offset, packet_info *pinfo)
755 {
756     int len = 0;
757
758     proto_tree_add_uint_format(dstopt_tree, hf_ipv6_mipv6_type, tvb,
759         offset + len, 1,
760         tvb_get_guint8(tvb, offset + len),
761         "Option Type: %u (0x%02x) - Home Address Option",
762         tvb_get_guint8(tvb, offset + len),
763         tvb_get_guint8(tvb, offset + len));
764     len += 1;
765
766     proto_tree_add_uint(dstopt_tree, hf_ipv6_mipv6_length, tvb, offset + len,
767         1, tvb_get_guint8(tvb, offset + len));
768     len += 1;
769
770     proto_tree_add_item(dstopt_tree, hf_ipv6_mipv6_home_address, tvb,
771                         offset + len, 16, ENC_NA);
772     SET_ADDRESS(&pinfo->src, AT_IPv6, 16, tvb_get_ptr(tvb, offset + len, 16));
773     len += 16;
774     return len;
775 }
776
777 static const value_string rtalertvals[] = {
778     { IP6OPT_RTALERT_MLD, "MLD" },
779     { IP6OPT_RTALERT_RSVP, "RSVP" },
780     { 0, NULL }
781 };
782
783 /* Like "dissect_ip_tcp_options()", but assumes the length of an option
784    *doesn't* include the type and length bytes. */
785 void
786 dissect_ipv6_options(tvbuff_t *tvb, int offset, guint length,
787                         const ip_tcp_opt *opttab, int nopts, int eol,
788                         packet_info *pinfo, proto_tree *opt_tree)
789 {
790   guchar            opt;
791   const ip_tcp_opt *optp;
792   opt_len_type      len_type;
793   unsigned int      optlen;
794   const char       *name;
795   char              name_str[7+1+1+2+2+1+1];    /* "Unknown (0x%02x)" */
796   void            (*dissect)(const struct ip_tcp_opt *, tvbuff_t *,
797                                 int, guint, packet_info *, proto_tree *);
798   guint             len;
799
800   while (length > 0) {
801     opt = tvb_get_guint8(tvb, offset);
802     for (optp = &opttab[0]; optp < &opttab[nopts]; optp++) {
803       if (optp->optcode == opt)
804         break;
805     }
806     if (optp == &opttab[nopts]) {
807       /* We assume that the only NO_LENGTH options are Pad1 options,
808          so that we can treat unknown options as VARIABLE_LENGTH with a
809          minimum of 0, and at least be able to move on to the next option
810          by using the length in the option. */
811       optp = NULL;      /* indicate that we don't know this option */
812       len_type = VARIABLE_LENGTH;
813       optlen = 0;
814       g_snprintf(name_str, sizeof name_str, "Unknown (0x%02x)", opt);
815       name = name_str;
816       dissect = NULL;
817     } else {
818       len_type = optp->len_type;
819       optlen = optp->optlen;
820       name = optp->name;
821       dissect = optp->dissect;
822     }
823     --length;      /* account for type byte */
824     if (len_type != NO_LENGTH) {
825       /* Option has a length. Is it in the packet? */
826       if (length == 0) {
827         /* Bogus - packet must at least include option code byte and
828            length byte! */
829         proto_tree_add_text(opt_tree, tvb, offset,      1,
830               "%s (length byte past end of options)", name);
831         return;
832       }
833       len = tvb_get_guint8(tvb, offset + 1);  /* total including type, len */
834       --length;    /* account for length byte */
835       if (len > length) {
836         /* Bogus - option goes past the end of the header. */
837         proto_tree_add_text(opt_tree, tvb, offset,      length,
838               "%s (option length = %u byte%s says option goes past end of options)",
839               name, len, plurality(len, "", "s"));
840         return;
841       } else if (len_type == FIXED_LENGTH && len != optlen) {
842         /* Bogus - option length isn't what it's supposed to be for this
843            option. */
844         proto_tree_add_text(opt_tree, tvb, offset,      2 + len,
845               "%s (with option length = %u byte%s; should be %u)", name,
846               len, plurality(len, "", "s"), optlen);
847         return;
848       } else if (len_type == VARIABLE_LENGTH && len < optlen) {
849         /* Bogus - option length is less than what it's supposed to be for
850            this option. */
851         proto_tree_add_text(opt_tree, tvb, offset,      2 + len,
852               "%s (with option length = %u byte%s; should be >= %u)", name,
853               len, plurality(len, "", "s"), optlen);
854         return;
855       } else {
856         if (optp == NULL) {
857           proto_tree_add_text(opt_tree, tvb, offset,    2 + len, "%s (%u byte%s)",
858                                 name, len, plurality(len, "", "s"));
859         } else {
860           if (dissect != NULL) {
861             /* Option has a dissector. */
862             (*dissect)(optp, tvb, offset,          2 + len, pinfo, opt_tree);
863           } else {
864             /* Option has no data, hence no dissector. */
865             proto_tree_add_text(opt_tree, tvb, offset,  2 + len, "%s", name);
866           }
867         }
868         offset += 2 + len;
869       }
870       length -= len;
871     } else {
872       proto_tree_add_text(opt_tree, tvb, offset,      1, "%s", name);
873       offset += 1;
874     }
875     if (opt == eol)
876       break;
877   }
878 }
879
880 static int
881 dissect_unknown_option(tvbuff_t *tvb, int offset, proto_tree *tree)
882 {
883     struct ip6_ext ext;
884     int len;
885     proto_tree *unkopt_tree;
886     proto_item *ti;
887
888     tvb_memcpy(tvb, (guint8 *)&ext, offset, sizeof(ext));
889     len = (ext.ip6e_len + 1) << 3;
890
891     if (tree) {
892         /* !!! specify length */
893         ti = proto_tree_add_item(tree, hf_ipv6_unk_hdr, tvb, offset, len, ENC_NA);
894
895         unkopt_tree = proto_item_add_subtree(ti, ett_ipv6);
896
897         proto_tree_add_text(unkopt_tree, tvb,
898             offset + offsetof(struct ip6_ext, ip6e_nxt), 1,
899             "Next header: %s (0x%02x)", ipprotostr(ext.ip6e_nxt), ext.ip6e_nxt);
900
901         proto_tree_add_text(unkopt_tree, tvb,
902             offset + offsetof(struct ip6_ext, ip6e_len), 1,
903             "Length: %u (%d bytes)", ext.ip6e_len, len);
904     }
905     return len;
906 }
907
908 static int
909 dissect_opts(tvbuff_t *tvb, int offset, proto_tree *tree, packet_info * pinfo, const int hf_option_item)
910 {
911     struct ip6_ext ext;
912     int len;
913     proto_tree *dstopt_tree;
914     proto_item *ti;
915     gint p;
916     guint8 tmp;
917     int mip_offset = 0, delta = 0;
918
919     tvb_memcpy(tvb, (guint8 *)&ext, offset, sizeof(ext));
920     len = (ext.ip6e_len + 1) << 3;
921
922     if (tree) {
923         /* !!! specify length */
924         ti = proto_tree_add_item(tree, hf_option_item, tvb, offset, len, FALSE);
925
926         dstopt_tree = proto_item_add_subtree(ti, ett_ipv6);
927
928         proto_tree_add_text(dstopt_tree, tvb,
929             offset + offsetof(struct ip6_ext, ip6e_nxt), 1,
930             "Next header: %s (0x%02x)", ipprotostr(ext.ip6e_nxt), ext.ip6e_nxt);
931
932         proto_tree_add_text(dstopt_tree, tvb,
933             offset + offsetof(struct ip6_ext, ip6e_len), 1,
934             "Length: %u (%d bytes)", ext.ip6e_len, len);
935
936         mip_offset = offset;
937         mip_offset += 2;
938
939         p = offset + 2;
940
941         while (p < offset + len) {
942             switch (tvb_get_guint8(tvb, p)) {
943             case IP6OPT_PAD1:
944                 proto_tree_add_item(dstopt_tree, hf_ipv6_opt_pad1, tvb, p, 1, ENC_NA);
945                 p++;
946                 mip_offset++;
947                 break;
948             case IP6OPT_PADN:
949                 /* RFC 2460 states :
950                  * "The PadN option is used to insert two or more octets of
951                  * padding into the Options area of a header.  For N octets of
952                  * padding, the Opt Data Len field contains the value N-2, and
953                  * the Option Data consists of N-2 zero-valued octets."
954                  */
955                 tmp = tvb_get_guint8(tvb, p + 1);
956                 proto_tree_add_uint_format(dstopt_tree, hf_ipv6_opt_padn, tvb,
957                                             p, tmp + 2, tmp + 2,
958                                             "PadN: %u bytes", tmp + 2);
959                 p += tmp + 2;
960                 mip_offset += tvb_get_guint8(tvb, mip_offset + 1) + 2;
961                 break;
962             case IP6OPT_JUMBO:
963                 tmp = tvb_get_guint8(tvb, p + 1);
964                 if (tmp == 4) {
965                     proto_tree_add_text(dstopt_tree, tvb, p, tmp + 2,
966                         "Jumbo payload: %u (%u bytes)",
967                         tvb_get_ntohl(tvb, p + 2), tmp + 2);
968                 } else {
969                     ti = proto_tree_add_text(dstopt_tree, tvb, p, tmp + 2,
970                         "Jumbo payload: Invalid length (%u bytes)",  tmp);
971                     expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_ERROR,
972                         "Jumbo payload: Invalid length (%u bytes)", tmp);
973                 }
974                 p += tmp + 2;
975                 mip_offset += tvb_get_guint8(tvb, mip_offset+1)+2;
976                 break;
977             case IP6OPT_RTALERT:
978               {
979                 tmp = tvb_get_guint8(tvb, p + 1);
980                 if (tmp == 2) {
981                     proto_tree_add_text(dstopt_tree, tvb, p , tmp + 2,
982                             "Router alert: %s (%u bytes)",
983                             val_to_str(tvb_get_ntohs(tvb, p + 2),
984                                         rtalertvals, "Unknown"),
985                             tmp + 2);
986                 } else {
987                     ti = proto_tree_add_text(dstopt_tree, tvb, p , tmp + 2,
988                             "Router alert: Invalid Length (%u bytes)",
989                             tmp + 2);
990                     expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_ERROR,
991                             "Router alert: Invalid Length (%u bytes)",
992                             tmp + 2);
993                 }
994
995                 p += tmp + 2;
996                 mip_offset += tvb_get_guint8(tvb, mip_offset + 1) + 2;
997                 break;
998               }
999             case IP6OPT_HOME_ADDRESS:
1000                 delta = dissect_mipv6_hoa(tvb, dstopt_tree, mip_offset, pinfo);
1001                 p += delta;
1002                 mip_offset += delta;
1003                 break;
1004             default:
1005                 p = offset + len;
1006                 break;
1007             }
1008         }
1009
1010         /* decode... */
1011     }
1012     return len;
1013 }
1014
1015 static int
1016 dissect_hopopts(tvbuff_t *tvb, int offset, proto_tree *tree, packet_info * pinfo)
1017 {
1018     return dissect_opts(tvb, offset, tree, pinfo, hf_ipv6_hop_opt);
1019 }
1020
1021 static int
1022 dissect_dstopts(tvbuff_t *tvb, int offset, proto_tree *tree, packet_info * pinfo)
1023 {
1024     return dissect_opts(tvb, offset, tree, pinfo, hf_ipv6_dst_opt);
1025 }
1026
1027 /* START SHIM6 PART */
1028 static guint16 shim_checksum(const guint8 *ptr, int len)
1029 {
1030         vec_t cksum_vec[1];
1031
1032         cksum_vec[0].ptr = ptr;
1033         cksum_vec[0].len = len;
1034         return in_cksum(&cksum_vec[0], 1);
1035 }
1036
1037 static int
1038 dissect_shim_hex(tvbuff_t *tvb, int offset, int len, const char *itemname, guint8 bitmask, proto_tree *tree)
1039 {
1040     proto_item *ti;
1041     int count;
1042     gint p;
1043
1044     p = offset;
1045
1046     ti = proto_tree_add_text(tree, tvb, offset, len, "%s", itemname);
1047
1048     proto_item_append_text(ti, " 0x%02x", tvb_get_guint8(tvb, p) & bitmask);
1049     for (count=1; count<len; count++)
1050       proto_item_append_text(ti, "%02x", tvb_get_guint8(tvb, p+count));
1051
1052     return len;
1053 }
1054
1055 static const value_string shimoptvals[] = {
1056     { SHIM6_OPT_RESPVAL,  "Responder Validator Option" },
1057     { SHIM6_OPT_LOCLIST,  "Locator List Option" },
1058     { SHIM6_OPT_LOCPREF,  "Locator Preferences Option" },
1059     { SHIM6_OPT_CGAPDM,   "CGA Parameter Data Structure Option" },
1060     { SHIM6_OPT_CGASIG,   "CGA Signature Option" },
1061     { SHIM6_OPT_ULIDPAIR, "ULID Pair Option" },
1062     { SHIM6_OPT_FII,      "Forked Instance Identifier Option" },
1063     { 0, NULL }
1064 };
1065
1066 static const value_string shimverifmethods[] = {
1067     { SHIM6_VERIF_HBA, "HBA" },
1068     { SHIM6_VERIF_CGA, "CGA" },
1069     { 0, NULL }
1070 };
1071
1072 static const value_string shimflags[] _U_ = {
1073     { SHIM6_FLAG_BROKEN,    "BROKEN" },
1074     { SHIM6_FLAG_TEMPORARY, "TEMPORARY" },
1075     { 0, NULL }
1076 };
1077
1078 static const value_string shimreapstates[] = {
1079     { SHIM6_REAP_OPERATIONAL, "Operational" },
1080     { SHIM6_REAP_EXPLORING,   "Exploring" },
1081     { SHIM6_REAP_INBOUNDOK,   "InboundOK" },
1082     { 0, NULL }
1083 };
1084
1085 static const value_string shim6_protocol[] = {
1086   { 0, "SHIM6" },
1087   { 1, "HIP" },
1088   { 0, NULL }
1089 };
1090
1091 static const value_string dscp_vals[] = {
1092                   { IPDSFIELD_DSCP_DEFAULT, "Default"               },
1093                   { IPDSFIELD_DSCP_CS1,     "Class Selector 1"      },
1094                   { IPDSFIELD_DSCP_CS2,     "Class Selector 2"      },
1095                   { IPDSFIELD_DSCP_CS3,     "Class Selector 3"      },
1096                   { IPDSFIELD_DSCP_CS4,     "Class Selector 4"      },
1097                   { IPDSFIELD_DSCP_CS5,     "Class Selector 5"      },
1098                   { IPDSFIELD_DSCP_CS6,     "Class Selector 6"      },
1099                   { IPDSFIELD_DSCP_CS7,     "Class Selector 7"      },
1100                   { IPDSFIELD_DSCP_AF11,    "Assured Forwarding 11" },
1101                   { IPDSFIELD_DSCP_AF12,    "Assured Forwarding 12" },
1102                   { IPDSFIELD_DSCP_AF13,    "Assured Forwarding 13" },
1103                   { IPDSFIELD_DSCP_AF21,    "Assured Forwarding 21" },
1104                   { IPDSFIELD_DSCP_AF22,    "Assured Forwarding 22" },
1105                   { IPDSFIELD_DSCP_AF23,    "Assured Forwarding 23" },
1106                   { IPDSFIELD_DSCP_AF31,    "Assured Forwarding 31" },
1107                   { IPDSFIELD_DSCP_AF32,    "Assured Forwarding 32" },
1108                   { IPDSFIELD_DSCP_AF33,    "Assured Forwarding 33" },
1109                   { IPDSFIELD_DSCP_AF41,    "Assured Forwarding 41" },
1110                   { IPDSFIELD_DSCP_AF42,    "Assured Forwarding 42" },
1111                   { IPDSFIELD_DSCP_AF43,    "Assured Forwarding 43" },
1112                   { IPDSFIELD_DSCP_EF,      "Expedited Forwarding"  },
1113                   { 0,                      NULL                    } };
1114
1115 static void
1116 dissect_shim6_opt_loclist(proto_tree * opt_tree, tvbuff_t * tvb, gint *offset)
1117 {
1118   proto_item * it;
1119   proto_tree * subtree;
1120   guint count;
1121   guint optlen;
1122   int p = *offset;
1123
1124   proto_tree_add_item(opt_tree, hf_ipv6_shim6_opt_loclist, tvb, p, 4, FALSE);
1125   p += 4;
1126
1127   optlen = tvb_get_guint8(tvb, p);
1128   proto_tree_add_item(opt_tree, hf_ipv6_shim6_opt_locnum, tvb, p, 1, FALSE);
1129   p++;
1130
1131   /* Verification Methods */
1132   it = proto_tree_add_text(opt_tree, tvb, p, optlen,
1133                             "Locator Verification Methods");
1134   subtree = proto_item_add_subtree(it, ett_ipv6_shim6_verif_methods);
1135
1136   for (count=0; count < optlen; count++)
1137     proto_tree_add_item(subtree, hf_ipv6_shim6_opt_loc_verif_methods, tvb,
1138                             p+count, 1, FALSE);
1139   p += optlen;
1140
1141   /* Padding, included in length field */
1142   if ((7 - optlen % 8) > 0) {
1143       proto_tree_add_text(opt_tree, tvb, p, (7 - optlen % 8), "Padding");
1144       p += (7 - optlen % 8);
1145   }
1146
1147   /* Locators */
1148   it = proto_tree_add_text(opt_tree, tvb, p, 16 * optlen, "Locators");
1149   subtree = proto_item_add_subtree(it, ett_ipv6_shim6_locators);
1150
1151   for (count=0; count < optlen; count++) {
1152       proto_tree_add_item(subtree, hf_ipv6_shim6_locator, tvb, p, 16, FALSE);
1153       p += 16;
1154   }
1155   *offset = p;
1156 }
1157
1158 static void
1159 dissect_shim6_opt_loc_pref(proto_tree * opt_tree, tvbuff_t * tvb, gint *offset, gint len, packet_info *pinfo)
1160 {
1161   proto_tree * subtree;
1162   proto_item * it;
1163
1164   gint p;
1165   gint optlen;
1166   gint count;
1167
1168   p = *offset;
1169
1170   proto_tree_add_item(opt_tree, hf_ipv6_shim6_opt_loclist, tvb, p, 4, FALSE);
1171   p += 4;
1172
1173   optlen = tvb_get_guint8(tvb, p);
1174   proto_tree_add_item(opt_tree, hf_ipv6_shim6_opt_elemlen, tvb, p, 1, FALSE);
1175
1176   if (optlen < 1 || optlen > 3) {
1177     it = proto_tree_add_text(opt_tree, tvb, p, 1,
1178       "Invalid element length: %u",  optlen);
1179     expert_add_info_format(pinfo, it, PI_MALFORMED, PI_ERROR,
1180       "Invalid element length: %u", optlen);
1181     return;
1182   }
1183
1184   p++;
1185
1186   /* Locator Preferences */
1187   count = 1;
1188   while (p < len) {
1189     it = proto_tree_add_text(opt_tree, tvb, p, optlen, "Locator Preferences %u", count);
1190     subtree = proto_item_add_subtree(it, ett_ipv6_shim6_loc_pref);
1191
1192     /* Flags */
1193     if (optlen >= 1)
1194       proto_tree_add_item(subtree, hf_ipv6_shim6_loc_flag, tvb, p, 1, FALSE);
1195     /* Priority */
1196     if (optlen >= 2)
1197       proto_tree_add_item(subtree, hf_ipv6_shim6_loc_prio, tvb, p+1, 1, FALSE);
1198     /* Weight */
1199     if (optlen >= 3)
1200       proto_tree_add_item(subtree, hf_ipv6_shim6_loc_weight, tvb, p+2, 1, FALSE);
1201     /*
1202      * Shim6 Draft 08 doesn't specify the format when the Element length is
1203      * more than three, except that any such formats MUST be defined so that
1204      * the first three octets are the same as in the above case, that is, a
1205      * of a 1 octet flags field followed by a 1 octet priority field, and a
1206      * 1 octet weight field.
1207      */
1208     p += optlen;
1209     count++;
1210   }
1211   *offset = p;
1212 }
1213
1214
1215 static int
1216 dissect_shimopts(tvbuff_t *tvb, int offset, proto_tree *tree, packet_info *pinfo)
1217 {
1218     int len, total_len;
1219     gint p;
1220     gint padding;
1221     proto_tree *opt_tree;
1222     proto_item *ti;
1223     const gchar *ctype;
1224
1225
1226     p = offset;
1227
1228     p += 4;
1229
1230     len = tvb_get_ntohs(tvb, offset+2);
1231     padding = 7 - ((len + 3) % 8);
1232     total_len = 4 + len + padding;
1233
1234     if (tree)
1235     {
1236         /* Option Type */
1237         ctype = val_to_str( (tvb_get_ntohs(tvb, offset) & SHIM6_BITMASK_OPT_TYPE) >> 1, shimoptvals, "Unknown Option Type");
1238         ti = proto_tree_add_text(tree, tvb, offset, total_len, "%s", ctype);
1239         opt_tree = proto_item_add_subtree(ti, ett_ipv6_shim6_option);
1240
1241         proto_tree_add_item(opt_tree, hf_ipv6_shim6_opt_type, tvb, offset, 2, FALSE);
1242
1243         /* Critical */
1244         proto_tree_add_item(opt_tree, hf_ipv6_shim6_opt_critical, tvb, offset+1, 1, FALSE);
1245
1246         /* Content Length */
1247         proto_tree_add_item(opt_tree, hf_ipv6_shim6_opt_len, tvb, offset + 2, 2, FALSE);
1248         ti = proto_tree_add_uint_format(opt_tree, hf_ipv6_shim6_opt_total_len, tvb, offset+2, 2,
1249             total_len, "Total Length: %u", total_len);
1250         PROTO_ITEM_SET_GENERATED(ti);
1251
1252         /* Option Type Specific */
1253         switch (tvb_get_ntohs(tvb, offset) >> 1)
1254         {
1255             case SHIM6_OPT_RESPVAL:
1256                 p += dissect_shim_hex(tvb, p, len, "Validator:", 0xff, opt_tree);
1257                 if (total_len-(len+4) > 0)
1258                     proto_tree_add_text(opt_tree, tvb, p, total_len-(len+4), "Padding");
1259                 break;
1260             case SHIM6_OPT_LOCLIST:
1261                 dissect_shim6_opt_loclist(opt_tree, tvb, &p);
1262                 break;
1263             case SHIM6_OPT_LOCPREF:
1264                 dissect_shim6_opt_loc_pref(opt_tree, tvb, &p, offset+len+4, pinfo);
1265                 if (total_len-(len+4) > 0)
1266                   proto_tree_add_text(opt_tree, tvb, p, total_len-(len+4), "Padding");
1267                 break;
1268             case SHIM6_OPT_CGAPDM:
1269                 p += dissect_shim_hex(tvb, p, len, "CGA Parameter Data Structure:", 0xff, opt_tree);
1270                 if (total_len-(len+4) > 0)
1271                     proto_tree_add_text(opt_tree, tvb, p, total_len-(len+4), "Padding");
1272                 break;
1273             case SHIM6_OPT_CGASIG:
1274                 p += dissect_shim_hex(tvb, p, len, "CGA Signature:", 0xff, opt_tree);
1275                 if (total_len-(len+4) > 0)
1276                     proto_tree_add_text(opt_tree, tvb, p, total_len-(len+4), "Padding");
1277                 break;
1278             case SHIM6_OPT_ULIDPAIR:
1279                 proto_tree_add_text(opt_tree, tvb, p, 4, "Reserved");
1280                 p += 4;
1281                 proto_tree_add_item(opt_tree, hf_ipv6_shim6_sulid, tvb, p, 16, FALSE);
1282                 p += 16;
1283                 proto_tree_add_item(opt_tree, hf_ipv6_shim6_rulid, tvb, p, 16, FALSE);
1284                 p += 16;
1285                 break;
1286             case SHIM6_OPT_FII:
1287                 proto_tree_add_item(opt_tree, hf_ipv6_shim6_opt_fii, tvb, p, 4, FALSE);
1288                 p += 4;
1289                 break;
1290             default:
1291                 break;
1292         }
1293     }
1294     return total_len;
1295 }
1296
1297 static void
1298 dissect_shim6_ct(proto_tree * shim_tree, gint hf_item, tvbuff_t * tvb, gint offset, const guchar * label)
1299 {
1300   guint8 tmp[6];
1301   guchar * ct_str;
1302
1303   tmp[0] = tvb_get_guint8(tvb, offset++);
1304   tmp[1] = tvb_get_guint8(tvb, offset++);
1305   tmp[2] = tvb_get_guint8(tvb, offset++);
1306   tmp[3] = tvb_get_guint8(tvb, offset++);
1307   tmp[4] = tvb_get_guint8(tvb, offset++);
1308   tmp[5] = tvb_get_guint8(tvb, offset++);
1309
1310   ct_str = ep_strdup_printf("%s: %02X %02X %02X %02X %02X %02X", label,
1311                               tmp[0] & SHIM6_BITMASK_CT, tmp[1], tmp[2],
1312                               tmp[3], tmp[4], tmp[5]
1313                             );
1314   proto_tree_add_none_format(shim_tree, hf_item, tvb, offset - 6, 6, "%s", ct_str);
1315 }
1316
1317 static void
1318 dissect_shim6_probes(proto_tree * shim_tree, tvbuff_t * tvb, gint offset,
1319                      const guchar * label, guint nbr_probe,
1320                      gboolean probes_rcvd)
1321 {
1322   proto_tree * probes_tree;
1323   proto_tree * probe_tree;
1324   proto_item * it;
1325   gint ett_probes;
1326   gint ett_probe;
1327   guint count;
1328
1329   if (probes_rcvd) {
1330     ett_probes = ett_ipv6_shim6_probes_rcvd;
1331     ett_probe = ett_ipv6_shim6_probe_rcvd;
1332   } else {
1333     ett_probes = ett_ipv6_shim6_probes_sent;
1334     ett_probe = ett_ipv6_shim6_probe_sent;
1335   }
1336   it = proto_tree_add_text(shim_tree, tvb, offset, 40 * nbr_probe, "%s", label);
1337   probes_tree = proto_item_add_subtree(it, ett_probes);
1338
1339   for (count=0; count < nbr_probe; count++) {
1340     it = proto_tree_add_text(probes_tree, tvb, offset, 40, "Probe %u", count+1);
1341     probe_tree = proto_item_add_subtree(it, ett_probe);
1342
1343     proto_tree_add_item(probe_tree, hf_ipv6_shim6_psrc, tvb, offset, 16, FALSE);
1344     offset += 16;
1345     proto_tree_add_item(probe_tree, hf_ipv6_shim6_pdst, tvb, offset, 16, FALSE);
1346     offset += 16;
1347
1348     proto_tree_add_item(probe_tree, hf_ipv6_shim6_pnonce, tvb, offset, 4, FALSE);
1349     offset += 4;
1350
1351     proto_tree_add_item(probe_tree, hf_ipv6_shim6_pdata, tvb, offset, 4, FALSE);
1352     offset += 4;
1353   }
1354 }
1355
1356 /* Dissect SHIM6 data: control messages */
1357 static int
1358 dissect_shimctrl(tvbuff_t *tvb, gint offset, guint type, proto_tree *shim_tree)
1359 {
1360   gint p;
1361   guint8 tmp;
1362   const gchar *sta;
1363   guint probes_sent;
1364   guint probes_rcvd;
1365
1366     p = offset;
1367
1368     switch (type)
1369     {
1370         case SHIM6_TYPE_I1:
1371             dissect_shim6_ct(shim_tree, hf_ipv6_shim6_ct, tvb, p, "Initiator Context Tag");
1372             p += 6;
1373             proto_tree_add_item(shim_tree, hf_ipv6_shim6_inonce, tvb, p, 4, FALSE);
1374             p += 4;
1375             break;
1376         case SHIM6_TYPE_R1:
1377             proto_tree_add_text(shim_tree, tvb, p, 2, "Reserved2");
1378             p += 2;
1379             proto_tree_add_item(shim_tree, hf_ipv6_shim6_inonce, tvb, p, 4, FALSE);
1380             p += 4;
1381             proto_tree_add_item(shim_tree, hf_ipv6_shim6_rnonce, tvb, p, 4, FALSE);
1382             p += 4;
1383             break;
1384         case SHIM6_TYPE_I2:
1385             dissect_shim6_ct(shim_tree, hf_ipv6_shim6_ct, tvb, p, "Initiator Context Tag");
1386             p += 6;
1387             proto_tree_add_item(shim_tree, hf_ipv6_shim6_inonce, tvb, p, 4, FALSE);
1388             p += 4;
1389             proto_tree_add_item(shim_tree, hf_ipv6_shim6_rnonce, tvb, p, 4, FALSE);
1390             p += 4;
1391             proto_tree_add_text(shim_tree, tvb, p, 4, "Reserved2");
1392             p += 4;
1393             break;
1394         case SHIM6_TYPE_R2:
1395             dissect_shim6_ct(shim_tree, hf_ipv6_shim6_ct, tvb, p, "Responder Context Tag");
1396             p += 6;
1397             proto_tree_add_item(shim_tree, hf_ipv6_shim6_inonce, tvb, p, 4, FALSE);
1398             p += 4;
1399             break;
1400         case SHIM6_TYPE_R1BIS:
1401             dissect_shim6_ct(shim_tree, hf_ipv6_shim6_ct, tvb, p, "Packet Context Tag");
1402             p += 6;
1403             proto_tree_add_item(shim_tree, hf_ipv6_shim6_rnonce, tvb, p, 4, FALSE);
1404             p += 4;
1405             break;
1406         case SHIM6_TYPE_I2BIS:
1407             dissect_shim6_ct(shim_tree, hf_ipv6_shim6_ct, tvb, p, "Initiator Context Tag");
1408             p += 6;
1409             proto_tree_add_item(shim_tree, hf_ipv6_shim6_inonce, tvb, p, 4, FALSE);
1410             p += 4;
1411             proto_tree_add_item(shim_tree, hf_ipv6_shim6_rnonce, tvb, p, 4, FALSE);
1412             p += 4;
1413             proto_tree_add_text(shim_tree, tvb, p, 6, "Reserved2");
1414             p += 6;
1415             dissect_shim6_ct(shim_tree, hf_ipv6_shim6_ct, tvb, p, "Initiator Context Tag");
1416             p += 6;
1417             break;
1418         case SHIM6_TYPE_UPD_REQ:
1419         case SHIM6_TYPE_UPD_ACK:
1420             dissect_shim6_ct(shim_tree, hf_ipv6_shim6_ct, tvb, p, "Receiver Context Tag");
1421             p += 6;
1422             proto_tree_add_item(shim_tree, hf_ipv6_shim6_rnonce, tvb, p, 4, FALSE);
1423             p += 4;
1424             break;
1425         case SHIM6_TYPE_KEEPALIVE:
1426             dissect_shim6_ct(shim_tree, hf_ipv6_shim6_ct, tvb, p, "Receiver Context Tag");
1427             p += 6;
1428             proto_tree_add_text(shim_tree, tvb, p, 4, "Reserved2");
1429             p += 4;
1430             break;
1431         case SHIM6_TYPE_PROBE:
1432             dissect_shim6_ct(shim_tree, hf_ipv6_shim6_ct, tvb, p, "Receiver Context Tag");
1433             p += 6;
1434
1435             tmp = tvb_get_guint8(tvb, p);
1436             probes_sent = tmp & SHIM6_BITMASK_PSENT;
1437             probes_rcvd = (tmp & SHIM6_BITMASK_PRECVD) >> 4;
1438
1439             proto_tree_add_uint_format(shim_tree, hf_ipv6_shim6_psent, tvb,
1440                                         p, 1, probes_sent,
1441                                         "Probes Sent: %u", probes_sent);
1442             proto_tree_add_uint_format(shim_tree, hf_ipv6_shim6_precvd, tvb,
1443                                         p, 1, probes_rcvd,
1444                                         "Probes Received: %u", probes_rcvd);
1445             p++;
1446
1447             sta = val_to_str((tvb_get_guint8(tvb, p) & SHIM6_BITMASK_STA) >> 6,
1448                                         shimreapstates, "Unknown REAP State");
1449             proto_tree_add_uint_format(shim_tree, hf_ipv6_shim6_reap, tvb,
1450                 p, 1, (tvb_get_guint8(tvb, p) & SHIM6_BITMASK_STA) >> 6,
1451                 "REAP State: %s", sta);
1452
1453             proto_tree_add_text(shim_tree, tvb, p, 3, "Reserved2");
1454             p += 3;
1455
1456             /* Probes Sent */
1457             if (probes_sent) {
1458               dissect_shim6_probes(shim_tree, tvb, p, "Probes Sent",
1459                                                           probes_sent, FALSE);
1460               p += 40 * probes_sent;
1461             }
1462
1463            /* Probes Received */
1464             if (probes_rcvd) {
1465               dissect_shim6_probes(shim_tree, tvb, p, "Probes Received",
1466                                                           probes_rcvd, TRUE);
1467               p += 40 * probes_rcvd;
1468             }
1469            break;
1470         default:
1471            break;
1472     }
1473     return p-offset;
1474 }
1475
1476 /* Dissect SHIM6 data: payload, common part, options */
1477 static const value_string shimctrlvals[] = {
1478     { SHIM6_TYPE_I1,        "I1" },
1479     { SHIM6_TYPE_R1,        "R1" },
1480     { SHIM6_TYPE_I2,        "I2" },
1481     { SHIM6_TYPE_R2,        "R2" },
1482     { SHIM6_TYPE_R1BIS,     "R1bis" },
1483     { SHIM6_TYPE_I2BIS,     "I2bis" },
1484     { SHIM6_TYPE_UPD_REQ,   "Update Request" },
1485     { SHIM6_TYPE_UPD_ACK,   "Update Acknowledgement" },
1486     { SHIM6_TYPE_KEEPALIVE, "Keepalive" },
1487     { SHIM6_TYPE_PROBE,     "Probe" },
1488     { 0, NULL }
1489 };
1490
1491 static void ipv6_shim6_checkum_additional_info(tvbuff_t * tvb, packet_info * pinfo,
1492     proto_item * it_cksum, int offset, gboolean is_cksum_correct)
1493 {
1494         proto_tree * checksum_tree;
1495         proto_item * item;
1496
1497         checksum_tree = proto_item_add_subtree(it_cksum, ett_ipv6_shim6_cksum);
1498         item = proto_tree_add_boolean(checksum_tree, hf_ipv6_shim6_checksum_good, tvb,
1499            offset, 2, is_cksum_correct);
1500         PROTO_ITEM_SET_GENERATED(item);
1501         item = proto_tree_add_boolean(checksum_tree, hf_ipv6_shim6_checksum_bad, tvb,
1502            offset, 2, !is_cksum_correct);
1503         PROTO_ITEM_SET_GENERATED(item);
1504         if (!is_cksum_correct) {
1505           expert_add_info_format(pinfo, item, PI_CHECKSUM, PI_ERROR, "Bad checksum");
1506           col_append_str(pinfo->cinfo, COL_INFO, " [Shim6 CHECKSUM INCORRECT]");
1507         }
1508 }
1509
1510 static int
1511 dissect_shim6(tvbuff_t *tvb, int offset, proto_tree *tree, packet_info * pinfo)
1512 {
1513     struct ip6_shim shim;
1514     int len;
1515     gint p;
1516     proto_tree *shim_tree;
1517     proto_item *ti;
1518     guint8 tmp[5];
1519
1520     tvb_memcpy(tvb, (guint8 *)&shim, offset, sizeof(shim));
1521     len = (shim.ip6s_len + 1) << 3;
1522
1523     if (tree)
1524     {
1525         ti = proto_tree_add_item(tree, hf_ipv6_shim6, tvb, offset, len, ENC_NA);
1526         shim_tree = proto_item_add_subtree(ti, ett_ipv6_shim6);
1527
1528         /* Next Header */
1529         proto_tree_add_uint_format(shim_tree, hf_ipv6_shim6_nxt, tvb,
1530             offset + offsetof(struct ip6_shim, ip6s_nxt), 1, shim.ip6s_nxt,
1531             "Next header: %s (0x%02x)", ipprotostr(shim.ip6s_nxt), shim.ip6s_nxt);
1532
1533         /* Header Extension Length */
1534         proto_tree_add_uint_format(shim_tree, hf_ipv6_shim6_len, tvb,
1535             offset + offsetof(struct ip6_shim, ip6s_len), 1, shim.ip6s_len,
1536             "Header Ext Length: %u (%d bytes)", shim.ip6s_len, len);
1537
1538         /* P Field */
1539         proto_tree_add_item(shim_tree, hf_ipv6_shim6_p, tvb,
1540                               offset + offsetof(struct ip6_shim, ip6s_p), 1, FALSE);
1541
1542         /* skip the first 2 bytes (nxt hdr, hdr ext len, p+7bits) */
1543         p = offset + 3;
1544
1545         if (shim.ip6s_p & SHIM6_BITMASK_P)
1546         {
1547             tmp[0] = tvb_get_guint8(tvb, p++);
1548             tmp[1] = tvb_get_guint8(tvb, p++);
1549             tmp[2] = tvb_get_guint8(tvb, p++);
1550             tmp[3] = tvb_get_guint8(tvb, p++);
1551             tmp[4] = tvb_get_guint8(tvb, p++);
1552
1553             /* Payload Extension Header */
1554             proto_tree_add_none_format(shim_tree, hf_ipv6_shim6_ct, tvb,
1555                 offset + offsetof(struct ip6_shim, ip6s_p), 6,
1556                 "Receiver Context Tag: %02x %02x %02x %02x %02x %02x",
1557                 shim.ip6s_p & SHIM6_BITMASK_CT, tmp[0], tmp[1], tmp[2], tmp[3], tmp[4]);
1558         }
1559         else
1560         {
1561             /* Control Message */
1562             guint16 csum;
1563             int advance;
1564
1565             /* Message Type */
1566             proto_tree_add_item(shim_tree, hf_ipv6_shim6_type, tvb,
1567                                 offset + offsetof(struct ip6_shim, ip6s_p), 1,
1568                                 FALSE
1569                                 );
1570
1571             /* Protocol bit (Must be zero for SHIM6) */
1572             proto_tree_add_item(shim_tree, hf_ipv6_shim6_proto, tvb, p, 1, FALSE);
1573             p++;
1574
1575             /* Checksum */
1576             csum = shim_checksum(tvb_get_ptr(tvb, offset, len), len);
1577
1578             if (csum == 0) {
1579                 ti = proto_tree_add_uint_format(shim_tree, hf_ipv6_shim6_checksum, tvb, p, 2,
1580                     tvb_get_ntohs(tvb, p), "Checksum: 0x%04x [correct]", tvb_get_ntohs(tvb, p));
1581                 ipv6_shim6_checkum_additional_info(tvb, pinfo, ti, p, TRUE);
1582             } else {
1583                 ti = proto_tree_add_uint_format(shim_tree, hf_ipv6_shim6_checksum, tvb, p, 2,
1584                     tvb_get_ntohs(tvb, p), "Checksum: 0x%04x [incorrect: should be 0x%04x]",
1585                     tvb_get_ntohs(tvb, p), in_cksum_shouldbe(tvb_get_ntohs(tvb, p), csum));
1586                 ipv6_shim6_checkum_additional_info(tvb, pinfo, ti, p, FALSE);
1587             }
1588             p += 2;
1589
1590             /* Type specific data */
1591             advance = dissect_shimctrl(tvb, p, shim.ip6s_p & SHIM6_BITMASK_TYPE, shim_tree);
1592             p += advance;
1593
1594             /* Options */
1595             while (p < offset+len) {
1596               p += dissect_shimopts(tvb, p, shim_tree, pinfo);
1597             }
1598         }
1599     }
1600     return len;
1601 }
1602
1603 /* END SHIM6 PART */
1604
1605 static void
1606 dissect_ipv6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1607 {
1608   proto_tree *ipv6_tree = NULL;
1609   proto_item *ipv6_item = NULL, *ti;
1610   guint8 nxt;
1611   guint8 stype=0;
1612   int advance;
1613   int poffset;
1614   guint16 plen;
1615   gboolean hopopts, routing, frag, ah, shim6, dstopts;
1616   guint16 offlg;
1617   guint32 ident;
1618   int offset;
1619   fragment_data *ipfd_head;
1620   tvbuff_t   *next_tvb;
1621   gboolean update_col_info = TRUE;
1622   gboolean save_fragmented = FALSE;
1623   const char *sep = "IPv6 ";
1624   guint8 *mac_addr;
1625
1626   struct ip6_hdr ipv6;
1627
1628   col_set_str(pinfo->cinfo, COL_PROTOCOL, "IPv6");
1629   col_clear(pinfo->cinfo, COL_INFO);
1630
1631   offset = 0;
1632   tvb_memcpy(tvb, (guint8 *)&ipv6, offset, sizeof(ipv6));
1633
1634   /* Get extension header and payload length */
1635   plen = g_ntohs(ipv6.ip6_plen);
1636
1637   /* Adjust the length of this tvbuff to include only the IPv6 datagram. */
1638   set_actual_length(tvb, plen + sizeof (struct ip6_hdr));
1639
1640   SET_ADDRESS(&pinfo->net_src, AT_IPv6, 16, tvb_get_ptr(tvb, offset + IP6H_SRC, 16));
1641   SET_ADDRESS(&pinfo->src, AT_IPv6, 16, tvb_get_ptr(tvb, offset + IP6H_SRC, 16));
1642   SET_ADDRESS(&pinfo->net_dst, AT_IPv6, 16, tvb_get_ptr(tvb, offset + IP6H_DST, 16));
1643   SET_ADDRESS(&pinfo->dst, AT_IPv6, 16, tvb_get_ptr(tvb, offset + IP6H_DST, 16));
1644
1645   if (tree) {
1646     proto_tree* pt;
1647     proto_item* pi;
1648     proto_tree *ipv6_tc_tree;
1649     proto_item *ipv6_tc;
1650     const char *name;
1651
1652     ipv6_item = proto_tree_add_item(tree, proto_ipv6, tvb, offset, -1, FALSE);
1653     ipv6_tree = proto_item_add_subtree(ipv6_item, ett_ipv6);
1654
1655     /* !!! warning: (4-bit) version, (6-bit) DSCP, (1-bit) ECN-ECT, (1-bit) ECN-CE and (20-bit) Flow */
1656     pi = proto_tree_add_item(ipv6_tree, hf_ipv6_version, tvb,
1657                         offset + offsetof(struct ip6_hdr, ip6_vfc), 1, FALSE);
1658         pt = proto_item_add_subtree(pi,ett_ipv6_version);
1659     pi = proto_tree_add_item(pt, hf_ip_version, tvb,
1660                                                 offset + offsetof(struct ip6_hdr, ip6_vfc), 1, FALSE);
1661         PROTO_ITEM_SET_GENERATED(pi);
1662
1663     ipv6_tc = proto_tree_add_item(ipv6_tree, hf_ipv6_class, tvb,
1664                         offset + offsetof(struct ip6_hdr, ip6_flow), 4, FALSE);
1665
1666     ipv6_tc_tree = proto_item_add_subtree(ipv6_tc, ett_ipv6_traffic_class);
1667
1668     proto_tree_add_item(ipv6_tc_tree, hf_ipv6_traffic_class_dscp, tvb,
1669                         offset + offsetof(struct ip6_hdr, ip6_flow), 4, FALSE);
1670
1671     proto_tree_add_item(ipv6_tc_tree, hf_ipv6_traffic_class_ect, tvb,
1672                         offset + offsetof(struct ip6_hdr, ip6_flow), 4, FALSE);
1673
1674     proto_tree_add_item(ipv6_tc_tree, hf_ipv6_traffic_class_ce, tvb,
1675                         offset + offsetof(struct ip6_hdr, ip6_flow), 4, FALSE);
1676
1677     proto_tree_add_item(ipv6_tree, hf_ipv6_flow, tvb,
1678                         offset + offsetof(struct ip6_hdr, ip6_flow), 4, FALSE);
1679
1680     proto_tree_add_item(ipv6_tree, hf_ipv6_plen, tvb,
1681                         offset + offsetof(struct ip6_hdr, ip6_plen), 2, FALSE);
1682
1683     proto_tree_add_uint_format(ipv6_tree, hf_ipv6_nxt, tvb,
1684                 offset + offsetof(struct ip6_hdr, ip6_nxt), 1,
1685                 ipv6.ip6_nxt,
1686                 "Next header: %s (0x%02x)",
1687                 ipprotostr(ipv6.ip6_nxt), ipv6.ip6_nxt);
1688
1689     proto_tree_add_item(ipv6_tree, hf_ipv6_hlim, tvb,
1690                         offset + offsetof(struct ip6_hdr, ip6_hlim), 1, FALSE);
1691
1692     /* Add the different items for the source address */
1693     proto_tree_add_item(ipv6_tree, hf_ipv6_src, tvb,
1694                         offset + offsetof(struct ip6_hdr, ip6_src), 16, FALSE);
1695     ti = proto_tree_add_ipv6(ipv6_tree, hf_ipv6_addr, tvb,
1696                               offset + offsetof(struct ip6_hdr, ip6_src),
1697                               16, (guint8 *)&ipv6.ip6_src);
1698     PROTO_ITEM_SET_HIDDEN(ti);
1699     name = get_addr_name(&pinfo->src);
1700     if (ipv6_summary_in_tree) {
1701       proto_item_append_text(ipv6_item, ", Src: %s (%s)", name, ip6_to_str(&ipv6.ip6_src));
1702     }
1703     ti = proto_tree_add_string(ipv6_tree, hf_ipv6_src_host, tvb,
1704                               offset + offsetof(struct ip6_hdr, ip6_src),
1705                               16, name);
1706     PROTO_ITEM_SET_GENERATED(ti);
1707     PROTO_ITEM_SET_HIDDEN(ti);
1708     ti = proto_tree_add_string(ipv6_tree, hf_ipv6_host, tvb,
1709                               offset + offsetof(struct ip6_hdr, ip6_src),
1710                               16, name);
1711     PROTO_ITEM_SET_GENERATED(ti);
1712     PROTO_ITEM_SET_HIDDEN(ti);
1713
1714     /* Extract embedded (IPv6 and MAC) address information */
1715     if (tvb_get_ntohs(tvb, offset + IP6H_SRC) == 0x2002) { /* RFC 3056 section 2 */
1716       ti = proto_tree_add_item(ipv6_tree, hf_ipv6_src_6to4_gateway_ipv4, tvb,
1717                                 offset + IP6H_SRC + 2, 4, FALSE);
1718       PROTO_ITEM_SET_GENERATED(ti);
1719       ti = proto_tree_add_item(ipv6_tree, hf_ipv6_src_6to4_sla_id, tvb,
1720                                 offset + IP6H_SRC + 6, 2, FALSE);
1721       PROTO_ITEM_SET_GENERATED(ti);
1722       ti = proto_tree_add_item(ipv6_tree, hf_ipv6_6to4_gateway_ipv4, tvb,
1723                                 offset + IP6H_SRC + 2, 4, FALSE);
1724       PROTO_ITEM_SET_GENERATED(ti);
1725       PROTO_ITEM_SET_HIDDEN(ti);
1726       ti = proto_tree_add_item(ipv6_tree, hf_ipv6_6to4_sla_id, tvb,
1727                                 offset + IP6H_SRC + 6, 2, FALSE);
1728       PROTO_ITEM_SET_GENERATED(ti);
1729       PROTO_ITEM_SET_HIDDEN(ti);
1730     } else if (tvb_get_ntohl(tvb, offset + IP6H_SRC) == 0x20010000) { /* RFC 4380 section 4 */
1731       guint16 mapped_port = tvb_get_ntohs(tvb, offset + IP6H_SRC + 10) ^ 0xffff;
1732       guint32 client_v4 = tvb_get_ipv4(tvb, offset + IP6H_SRC + 12) ^ 0xffffffff;
1733
1734       ti = proto_tree_add_item(ipv6_tree, hf_ipv6_src_teredo_server_ipv4, tvb,
1735                                 offset + IP6H_SRC + 4, 4, FALSE);
1736       PROTO_ITEM_SET_GENERATED(ti);
1737       ti = proto_tree_add_uint(ipv6_tree, hf_ipv6_src_teredo_port, tvb,
1738                                 offset + IP6H_SRC + 10, 2, mapped_port);
1739       PROTO_ITEM_SET_GENERATED(ti);
1740       ti = proto_tree_add_ipv4(ipv6_tree, hf_ipv6_src_teredo_client_ipv4, tvb,
1741                                 offset + IP6H_SRC + 12, 4, client_v4);
1742       PROTO_ITEM_SET_GENERATED(ti);
1743       ti = proto_tree_add_item(ipv6_tree, hf_ipv6_teredo_server_ipv4, tvb,
1744                                 offset + IP6H_SRC + 4, 4, FALSE);
1745       PROTO_ITEM_SET_GENERATED(ti);
1746       PROTO_ITEM_SET_HIDDEN(ti);
1747       ti = proto_tree_add_uint(ipv6_tree, hf_ipv6_teredo_port, tvb,
1748                                 offset + IP6H_SRC + 10, 2, mapped_port);
1749       PROTO_ITEM_SET_GENERATED(ti);
1750       PROTO_ITEM_SET_HIDDEN(ti);
1751       ti = proto_tree_add_ipv4(ipv6_tree, hf_ipv6_teredo_client_ipv4, tvb,
1752                                 offset + IP6H_SRC + 12, 4, client_v4);
1753       PROTO_ITEM_SET_GENERATED(ti);
1754       PROTO_ITEM_SET_HIDDEN(ti);
1755     }
1756
1757     if (tvb_get_guint8(tvb, offset + IP6H_SRC + 8) & 0x02 && tvb_get_ntohs(tvb, offset + IP6H_SRC + 11) == 0xfffe) {  /* RFC 4291 appendix A */
1758       mac_addr = ep_alloc(6);
1759       tvb_memcpy(tvb, mac_addr, offset + IP6H_SRC + 8, 3);
1760       tvb_memcpy(tvb, mac_addr+3, offset+ IP6H_SRC + 13, 3);
1761       mac_addr[0] &= ~0x02;
1762       ti = proto_tree_add_ether(ipv6_tree, hf_ipv6_src_sa_mac, tvb,
1763                                 offset + IP6H_SRC + 8, 6, mac_addr);
1764       PROTO_ITEM_SET_GENERATED(ti);
1765       ti = proto_tree_add_ether(ipv6_tree, hf_ipv6_sa_mac, tvb,
1766                                 offset + IP6H_SRC + 8, 6, mac_addr);
1767       PROTO_ITEM_SET_GENERATED(ti);
1768       PROTO_ITEM_SET_HIDDEN(ti);
1769     } else if ((tvb_get_ntohl(tvb, offset + IP6H_SRC + 8) & 0xfcffffff) == 0x00005efe) { /* RFC 5214 section 6.1 */
1770       ti = proto_tree_add_item(ipv6_tree, hf_ipv6_src_isatap_ipv4, tvb,
1771                                 offset + IP6H_SRC + 12, 4, FALSE);
1772       PROTO_ITEM_SET_GENERATED(ti);
1773       ti = proto_tree_add_item(ipv6_tree, hf_ipv6_isatap_ipv4, tvb,
1774                                 offset + IP6H_SRC + 12, 4, FALSE);
1775       PROTO_ITEM_SET_GENERATED(ti);
1776       PROTO_ITEM_SET_HIDDEN(ti);
1777     }
1778
1779     /* Add different items for the destination address */
1780     proto_tree_add_item(ipv6_tree, hf_ipv6_dst, tvb,
1781                         offset + offsetof(struct ip6_hdr, ip6_dst), 16, FALSE);
1782     ti = proto_tree_add_ipv6(ipv6_tree, hf_ipv6_addr, tvb,
1783                               offset + offsetof(struct ip6_hdr, ip6_dst),
1784                               16, (guint8 *)&ipv6.ip6_dst);
1785     PROTO_ITEM_SET_HIDDEN(ti);
1786     name = get_addr_name(&pinfo->dst);
1787     if (ipv6_summary_in_tree) {
1788       proto_item_append_text(ipv6_item, ", Dst: %s (%s)", name, ip6_to_str(&ipv6.ip6_dst));
1789     }
1790     ti = proto_tree_add_string(ipv6_tree, hf_ipv6_dst_host, tvb,
1791                               offset + offsetof(struct ip6_hdr, ip6_dst),
1792                               16, name);
1793     PROTO_ITEM_SET_GENERATED(ti);
1794     PROTO_ITEM_SET_HIDDEN(ti);
1795     ti = proto_tree_add_string(ipv6_tree, hf_ipv6_host, tvb,
1796                               offset + offsetof(struct ip6_hdr, ip6_dst),
1797                               16, name);
1798     PROTO_ITEM_SET_GENERATED(ti);
1799     PROTO_ITEM_SET_HIDDEN(ti);
1800
1801     /* Extract embedded (IPv6 and MAC) address information */
1802     if (tvb_get_ntohs(tvb, offset + IP6H_DST) == 0x2002) { /* RFC 3056 section 2 */
1803       ti = proto_tree_add_item(ipv6_tree, hf_ipv6_dst_6to4_gateway_ipv4, tvb,
1804                                 offset + IP6H_DST + 2, 4, FALSE);
1805       PROTO_ITEM_SET_GENERATED(ti);
1806       ti = proto_tree_add_item(ipv6_tree, hf_ipv6_dst_6to4_sla_id, tvb,
1807                                 offset + IP6H_DST + 6, 2, FALSE);
1808       PROTO_ITEM_SET_GENERATED(ti);
1809       ti = proto_tree_add_item(ipv6_tree, hf_ipv6_6to4_gateway_ipv4, tvb,
1810                                 offset + IP6H_DST + 2, 4, FALSE);
1811       PROTO_ITEM_SET_GENERATED(ti);
1812       PROTO_ITEM_SET_HIDDEN(ti);
1813       ti = proto_tree_add_item(ipv6_tree, hf_ipv6_6to4_sla_id, tvb,
1814                                 offset + IP6H_DST + 6, 2, FALSE);
1815       PROTO_ITEM_SET_GENERATED(ti);
1816       PROTO_ITEM_SET_HIDDEN(ti);
1817     } else if (tvb_get_ntohl(tvb, offset + IP6H_DST) == 0x20010000) { /* RFC 4380 section 4 */
1818       guint16 mapped_port = tvb_get_ntohs(tvb, offset + IP6H_DST + 10) ^ 0xffff;
1819       guint32 client_v4 = tvb_get_ipv4(tvb, offset + IP6H_DST + 12) ^ 0xffffffff;
1820
1821       ti = proto_tree_add_item(ipv6_tree, hf_ipv6_dst_teredo_server_ipv4, tvb,
1822                                 offset + IP6H_DST + 4, 4, FALSE);
1823       PROTO_ITEM_SET_GENERATED(ti);
1824       ti = proto_tree_add_uint(ipv6_tree, hf_ipv6_dst_teredo_port, tvb,
1825                                 offset + IP6H_DST + 10, 2, mapped_port);
1826       PROTO_ITEM_SET_GENERATED(ti);
1827       ti = proto_tree_add_ipv4(ipv6_tree, hf_ipv6_dst_teredo_client_ipv4, tvb,
1828                                 offset + IP6H_DST + 12, 4, client_v4);
1829       PROTO_ITEM_SET_GENERATED(ti);
1830       ti = proto_tree_add_item(ipv6_tree, hf_ipv6_teredo_server_ipv4, tvb,
1831                                 offset + IP6H_DST + 4, 4, FALSE);
1832       PROTO_ITEM_SET_GENERATED(ti);
1833       PROTO_ITEM_SET_HIDDEN(ti);
1834       ti = proto_tree_add_uint(ipv6_tree, hf_ipv6_teredo_port, tvb,
1835                                 offset + IP6H_DST + 10, 2, mapped_port);
1836       PROTO_ITEM_SET_GENERATED(ti);
1837       PROTO_ITEM_SET_HIDDEN(ti);
1838       ti = proto_tree_add_ipv4(ipv6_tree, hf_ipv6_teredo_client_ipv4, tvb,
1839                                 offset + IP6H_DST + 12, 4, client_v4);
1840       PROTO_ITEM_SET_GENERATED(ti);
1841       PROTO_ITEM_SET_HIDDEN(ti);
1842     }
1843
1844     if (tvb_get_guint8(tvb, offset + IP6H_DST + 8) & 0x02 && tvb_get_ntohs(tvb, offset + IP6H_DST + 11) == 0xfffe) { /* RFC 4291 appendix A */
1845       mac_addr = ep_alloc(6);
1846       tvb_memcpy(tvb, mac_addr, offset + IP6H_DST + 8, 3);
1847       tvb_memcpy(tvb, mac_addr+3, offset+ IP6H_DST + 13, 3);
1848       mac_addr[0] &= ~0x02;
1849       ti = proto_tree_add_ether(ipv6_tree, hf_ipv6_dst_sa_mac, tvb,
1850                                 offset + IP6H_DST + 8, 6, mac_addr);
1851       PROTO_ITEM_SET_GENERATED(ti);
1852       ti = proto_tree_add_ether(ipv6_tree, hf_ipv6_sa_mac, tvb,
1853                                 offset + IP6H_DST + 8, 6, mac_addr);
1854       PROTO_ITEM_SET_GENERATED(ti);
1855       PROTO_ITEM_SET_HIDDEN(ti);
1856     } else if ((tvb_get_ntohl(tvb, offset + IP6H_DST + 8) & 0xfcffffff) == 0x00005efe) { /* RFC 5214 section 6.1 */
1857       ti = proto_tree_add_item(ipv6_tree, hf_ipv6_dst_isatap_ipv4, tvb,
1858                                 offset + IP6H_DST + 12, 4, FALSE);
1859       PROTO_ITEM_SET_GENERATED(ti);
1860       ti = proto_tree_add_item(ipv6_tree, hf_ipv6_isatap_ipv4, tvb,
1861                                 offset + IP6H_DST + 12, 4, FALSE);
1862       PROTO_ITEM_SET_GENERATED(ti);
1863       PROTO_ITEM_SET_HIDDEN(ti);
1864     }
1865   }
1866
1867 #ifdef HAVE_GEOIP
1868   if (tree && ipv6_use_geoip) {
1869     add_geoip_info(ipv6_tree, tvb, offset, ipv6.ip6_src, ipv6.ip6_dst);
1870   }
1871 #endif
1872
1873   /* start of the new header (could be a extension header) */
1874   poffset = offset + offsetof(struct ip6_hdr, ip6_nxt);
1875   nxt = tvb_get_guint8(tvb, poffset);
1876   offset += sizeof(struct ip6_hdr);
1877   offlg = 0;
1878   ident = 0;
1879
1880 /* start out assuming this isn't fragmented, and has none of the other
1881    non-final headers */
1882   hopopts = FALSE;
1883   routing = FALSE;
1884   frag = FALSE;
1885   ah = FALSE;
1886   shim6 = FALSE;
1887   dstopts = FALSE;
1888
1889 again:
1890    switch (nxt) {
1891
1892    case IP_PROTO_HOPOPTS:
1893       hopopts = TRUE;
1894       advance = dissect_hopopts(tvb, offset, ipv6_tree, pinfo);
1895       nxt = tvb_get_guint8(tvb, offset);
1896       poffset = offset;
1897       offset += advance;
1898       plen -= advance;
1899       goto again;
1900
1901     case IP_PROTO_ROUTING:
1902       routing = TRUE;
1903       advance = dissect_routing6(tvb, offset, ipv6_tree, pinfo);
1904       nxt = tvb_get_guint8(tvb, offset);
1905       poffset = offset;
1906       offset += advance;
1907       plen -= advance;
1908       goto again;
1909
1910     case IP_PROTO_FRAGMENT:
1911       advance = dissect_frag6(tvb, offset, pinfo, ipv6_tree,
1912           &offlg, &ident);
1913       nxt = tvb_get_guint8(tvb, offset);
1914       poffset = offset;
1915       offset += advance;
1916       plen -= advance;
1917       frag = offlg & (IP6F_OFF_MASK | IP6F_MORE_FRAG);
1918       save_fragmented |= frag;
1919       if (ipv6_reassemble && frag && tvb_bytes_exist(tvb, offset, plen)) {
1920         ipfd_head = fragment_add_check(tvb, offset, pinfo, ident,
1921         ipv6_fragment_table,
1922         ipv6_reassembled_table,
1923           offlg & IP6F_OFF_MASK,
1924           plen,
1925           offlg & IP6F_MORE_FRAG);
1926         next_tvb = process_reassembled_data(tvb, offset, pinfo, "Reassembled IPv6",
1927         ipfd_head, &ipv6_frag_items, &update_col_info, ipv6_tree);
1928         if (next_tvb) {  /* Process post-fragment headers after reassembly... */
1929           offset= 0;
1930           offlg = 0;
1931           frag = FALSE;
1932           tvb = next_tvb;
1933           goto again;
1934         }
1935       }
1936       if (!(offlg & IP6F_OFF_MASK)) /*...or in the first fragment */
1937         goto again;
1938       break;
1939
1940     case IP_PROTO_AH:
1941       ah = TRUE;
1942       advance = dissect_ah_header(tvb_new_subset_remaining(tvb, offset),
1943                                   pinfo, ipv6_tree, NULL, NULL);
1944       nxt = tvb_get_guint8(tvb, offset);
1945       poffset = offset;
1946       offset += advance;
1947       plen -= advance;
1948       goto again;
1949
1950     case IP_PROTO_SHIM6:
1951     case IP_PROTO_SHIM6_OLD:
1952       shim6 = TRUE;
1953       advance = dissect_shim6(tvb, offset, ipv6_tree, pinfo);
1954       nxt = tvb_get_guint8(tvb, offset);
1955       stype = tvb_get_guint8(tvb, offset+2);
1956       poffset = offset;
1957       offset += advance;
1958       plen -= advance;
1959       goto again;
1960
1961     case IP_PROTO_DSTOPTS:
1962       dstopts = TRUE;
1963       advance = dissect_dstopts(tvb, offset, ipv6_tree, pinfo);
1964       nxt = tvb_get_guint8(tvb, offset);
1965       poffset = offset;
1966       offset += advance;
1967       plen -= advance;
1968       goto again;
1969
1970     case IP_PROTO_NONE:
1971       break;
1972
1973     default:
1974       /* Since we did not recognize this IPv6 option, check
1975        * whether it is a known protocol. If not, then it
1976        * is an unknown IPv6 option
1977        */
1978       if (!dissector_get_uint_handle(ip_dissector_table, nxt)) {
1979         advance = dissect_unknown_option(tvb, offset, ipv6_tree);
1980         nxt = tvb_get_guint8(tvb, offset);
1981         poffset = offset;
1982         offset += advance;
1983         plen -= advance;
1984         goto again;
1985       }
1986     }
1987
1988 #ifdef TEST_FINALHDR
1989   ti = proto_tree_add_uint(ipv6_tree, hf_ipv6_final, tvb, poffset, 1, nxt);
1990   PROTO_ITEM_SET_HIDDEN(ti);
1991 #endif
1992
1993   proto_item_set_len (ipv6_item, offset);
1994   tap_queue_packet(ipv6_tap, pinfo, &ipv6);
1995
1996   /* collect packet info */
1997   pinfo->ipproto = nxt;
1998   pinfo->iplen = sizeof(ipv6) + plen + offset;
1999   pinfo->iphdrlen = offset;
2000
2001   if (offlg & IP6F_OFF_MASK || (ipv6_reassemble && offlg & IP6F_MORE_FRAG)) {
2002     /* Not the first fragment, or the first when we are reassembling and there are more. */
2003     /* Don't dissect it; just show this as a fragment. */
2004     /* COL_INFO was filled in by "dissect_frag6()" */
2005     call_dissector(data_handle, tvb_new_subset_remaining(tvb, offset), pinfo, tree);
2006     return;
2007   } else {
2008     /* First fragment, not fragmented, or already reassembled.  Dissect what we have here. */
2009
2010     /* Get a tvbuff for the payload. */
2011     next_tvb = tvb_new_subset_remaining(tvb, offset);
2012
2013     /*
2014      * If this is the first fragment, but not the only fragment,
2015      * tell the next protocol that.
2016      */
2017     if (offlg & IP6F_MORE_FRAG)
2018       pinfo->fragmented = TRUE;
2019     else
2020       pinfo->fragmented = FALSE;
2021   }
2022
2023
2024   /* do lookup with the subdissector table */
2025   if (!dissector_try_uint(ip_dissector_table, nxt, next_tvb, pinfo, tree)) {
2026     /* Unknown protocol.
2027        Handle "no next header" specially. */
2028     if (nxt == IP_PROTO_NONE) {
2029       if (check_col(pinfo->cinfo, COL_INFO)) {
2030         /* If we had an Authentication Header, the AH dissector already
2031            put something in the Info column; leave it there. */
2032         if (!ah) {
2033           if (hopopts || routing || dstopts || shim6) {
2034             if (hopopts) {
2035               col_append_fstr(pinfo->cinfo, COL_INFO, "%shop-by-hop options",
2036                              sep);
2037               sep = ", ";
2038             }
2039             if (routing) {
2040               col_append_fstr(pinfo->cinfo, COL_INFO, "%srouting", sep);
2041               sep = ", ";
2042             }
2043             if (dstopts) {
2044               col_append_fstr(pinfo->cinfo, COL_INFO, "%sdestination options",
2045                               sep);
2046             }
2047             if (shim6) {
2048               if (stype & SHIM6_BITMASK_P) {
2049                 col_append_str(pinfo->cinfo, COL_INFO, "Shim6 (Payload)");
2050               }
2051               else {
2052                 col_append_fstr(pinfo->cinfo, COL_INFO, "Shim6 (%s)",
2053                    val_to_str(stype & SHIM6_BITMASK_TYPE, shimctrlvals, "Unknown"));
2054               }
2055             }
2056           } else
2057             col_set_str(pinfo->cinfo, COL_INFO, "IPv6 no next header");
2058         }
2059       }
2060     } else {
2061       if (check_col(pinfo->cinfo, COL_INFO))
2062         col_add_fstr(pinfo->cinfo, COL_INFO, "%s (0x%02x)", ipprotostr(nxt),nxt);
2063     }
2064     call_dissector(data_handle, next_tvb, pinfo, tree);
2065   }
2066   pinfo->fragmented = save_fragmented;
2067 }
2068
2069 void
2070 proto_register_ipv6(void)
2071 {
2072   static hf_register_info hf[] = {
2073     { &hf_ipv6_version,
2074       { "Version",              "ipv6.version",
2075                                 FT_UINT8, BASE_DEC, NULL, 0xF0, NULL, HFILL }},
2076     { &hf_ip_version,
2077       { "This field makes the filter \"ip.version == 6\" possible",             "ip.version",
2078                                 FT_UINT8, BASE_DEC, NULL, 0xF0, NULL, HFILL }},
2079     { &hf_ipv6_class,
2080       { "Traffic class",        "ipv6.class",
2081                                 FT_UINT32, BASE_HEX, NULL, 0x0FF00000, NULL, HFILL }},
2082     { &hf_ipv6_flow,
2083       { "Flowlabel",            "ipv6.flow",
2084                                 FT_UINT32, BASE_HEX, NULL, 0x000FFFFF, NULL, HFILL }},
2085     { &hf_ipv6_plen,
2086       { "Payload length",       "ipv6.plen",
2087                                 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
2088     { &hf_ipv6_nxt,
2089       { "Next header",          "ipv6.nxt",
2090                                 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2091     { &hf_ipv6_hlim,
2092       { "Hop limit",            "ipv6.hlim",
2093                                 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
2094     { &hf_ipv6_src,
2095       { "Source",               "ipv6.src",
2096                                 FT_IPv6, BASE_NONE, NULL, 0x0,
2097                                 "Source IPv6 Address", HFILL }},
2098     { &hf_ipv6_src_host,
2099       { "Source Host",          "ipv6.src_host",
2100                                 FT_STRING, BASE_NONE, NULL, 0x0,
2101                                 "Source IPv6 Host", HFILL }},
2102     { &hf_ipv6_src_sa_mac,
2103       { "Source SA MAC",                "ipv6.src_sa_mac",
2104                                 FT_ETHER, BASE_NONE, NULL, 0x0,
2105                                 "Source IPv6 Stateless Autoconfiguration MAC Address", HFILL }},
2106     { &hf_ipv6_src_isatap_ipv4,
2107       { "Source ISATAP IPv4",           "ipv6.src_isatap_ipv4",
2108                                 FT_IPv4, BASE_NONE, NULL, 0x0,
2109                                 "Source IPv6 ISATAP Encapsulated IPv4 Address", HFILL }},
2110     { &hf_ipv6_src_6to4_gateway_ipv4,
2111       { "Source 6to4 Gateway IPv4",             "ipv6.src_6to4_gw_ipv4",
2112                                 FT_IPv4, BASE_NONE, NULL, 0x0,
2113                                 "Source IPv6 6to4 Gateway IPv4 Address", HFILL }},
2114     { &hf_ipv6_src_6to4_sla_id,
2115       { "Source 6to4 SLA ID",           "ipv6.src_6to4_sla_id",
2116                                 FT_UINT16, BASE_DEC, NULL, 0x0,
2117                                 "Source IPv6 6to4 SLA ID", HFILL }},
2118     { &hf_ipv6_src_teredo_server_ipv4,
2119       { "Source Teredo Server IPv4",            "ipv6.src_ts_ipv4",
2120                                 FT_IPv4, BASE_NONE, NULL, 0x0,
2121                                 "Source IPv6 Teredo Server Encapsulated IPv4 Address", HFILL }},
2122     { &hf_ipv6_src_teredo_port,
2123       { "Source Teredo Port",           "ipv6.src_tc_port",
2124                                 FT_UINT16, BASE_DEC, NULL, 0x0,
2125                                 "Source IPv6 Teredo Client Mapped Port", HFILL }},
2126     { &hf_ipv6_src_teredo_client_ipv4,
2127       { "Source Teredo Client IPv4",            "ipv6.src_tc_ipv4",
2128                                 FT_IPv4, BASE_NONE, NULL, 0x0,
2129                                 "Source IPv6 Teredo Client Encapsulated IPv4 Address", HFILL }},
2130     { &hf_ipv6_dst,
2131       { "Destination",          "ipv6.dst",
2132                                 FT_IPv6, BASE_NONE, NULL, 0x0,
2133                                 "Destination IPv6 Address", HFILL }},
2134     { &hf_ipv6_dst_host,
2135       { "Destination Host",     "ipv6.dst_host",
2136                                 FT_STRING, BASE_NONE, NULL, 0x0,
2137                                 "Destination IPv6 Host", HFILL }},
2138     { &hf_ipv6_dst_sa_mac,
2139       { "Destination SA MAC",           "ipv6.dst_sa_mac",
2140                                 FT_ETHER, BASE_NONE, NULL, 0x0,
2141                                 "Destination IPv6 Stateless Autoconfiguration MAC Address", HFILL }},
2142     { &hf_ipv6_dst_isatap_ipv4,
2143       { "Destination ISATAP IPv4",              "ipv6.dst_isatap_ipv4",
2144                                 FT_IPv4, BASE_NONE, NULL, 0x0,
2145                                 "Destination IPv6 ISATAP Encapsulated IPv4 Address", HFILL }},
2146     { &hf_ipv6_dst_6to4_gateway_ipv4,
2147       { "Destination 6to4 Gateway IPv4",                "ipv6.dst_6to4_gw_ipv4",
2148                                 FT_IPv4, BASE_NONE, NULL, 0x0,
2149                                 "Destination IPv6 6to4 Gateway IPv4 Address", HFILL }},
2150     { &hf_ipv6_dst_6to4_sla_id,
2151       { "Destination 6to4 SLA ID",              "ipv6.dst_6to4_sla_id",
2152                                 FT_UINT16, BASE_DEC, NULL, 0x0,
2153                                 "Destination IPv6 6to4 SLA ID", HFILL }},
2154     { &hf_ipv6_dst_teredo_server_ipv4,
2155       { "Destination Teredo Server IPv4",               "ipv6.dst_ts_ipv4",
2156                                 FT_IPv4, BASE_NONE, NULL, 0x0,
2157                                 "Destination IPv6 Teredo Server Encapsulated IPv4 Address", HFILL }},
2158     { &hf_ipv6_dst_teredo_port,
2159       { "Destination Teredo Port",              "ipv6.dst_tc_port",
2160                                 FT_UINT16, BASE_DEC, NULL, 0x0,
2161                                 "Destination IPv6 Teredo Client Mapped Port", HFILL }},
2162     { &hf_ipv6_dst_teredo_client_ipv4,
2163       { "Destination Teredo Client IPv4",               "ipv6.dst_tc_ipv4",
2164                                 FT_IPv4, BASE_NONE, NULL, 0x0,
2165                                 "Destination IPv6 Teredo Client Encapsulated IPv4 Address", HFILL }},
2166     { &hf_ipv6_addr,
2167       { "Address",              "ipv6.addr",
2168                                 FT_IPv6, BASE_NONE, NULL, 0x0,
2169                                 "Source or Destination IPv6 Address", HFILL }},
2170     { &hf_ipv6_host,
2171       { "Host",                 "ipv6.host",
2172                                 FT_STRING, BASE_NONE, NULL, 0x0,
2173                                 "IPv6 Host", HFILL }},
2174
2175     { &hf_ipv6_sa_mac,
2176       { "SA MAC",               "ipv6.sa_mac",
2177                                 FT_ETHER, BASE_NONE, NULL, 0x0,
2178                                 "IPv6 Stateless Autoconfiguration MAC Address", HFILL }},
2179     { &hf_ipv6_isatap_ipv4,
2180       { "ISATAP IPv4",          "ipv6.isatap_ipv4",
2181                                 FT_IPv4, BASE_NONE, NULL, 0x0,
2182                                 "IPv6 ISATAP Encapsulated IPv4 Address", HFILL }},
2183     { &hf_ipv6_6to4_gateway_ipv4,
2184       { "6to4 Gateway IPv4",            "ipv6.6to4_gw_ipv4",
2185                                 FT_IPv4, BASE_NONE, NULL, 0x0,
2186                                 "IPv6 6to4 Gateway IPv4 Address", HFILL }},
2187     { &hf_ipv6_6to4_sla_id,
2188       { "6to4 SLA ID",          "ipv6.6to4_sla_id",
2189                                 FT_UINT16, BASE_DEC, NULL, 0x0,
2190                                 "IPv6 6to4 SLA ID", HFILL }},
2191     { &hf_ipv6_teredo_server_ipv4,
2192       { "Teredo Server IPv4",           "ipv6.ts_ipv4",
2193                                 FT_IPv4, BASE_NONE, NULL, 0x0,
2194                                 "IPv6 Teredo Server Encapsulated IPv4 Address", HFILL }},
2195     { &hf_ipv6_teredo_port,
2196       { "Teredo Port",          "ipv6.tc_port",
2197                                 FT_UINT16, BASE_DEC, NULL, 0x0,
2198                                 "IPv6 Teredo Client Mapped Port", HFILL }},
2199     { &hf_ipv6_teredo_client_ipv4,
2200       { "Teredo Client IPv4",           "ipv6.tc_ipv4",
2201                                 FT_IPv4, BASE_NONE, NULL, 0x0,
2202                                 "IPv6 Teredo Client Encapsulated IPv4 Address", HFILL }},
2203 #ifdef HAVE_GEOIP_V6
2204     { &hf_geoip_country,
2205       { "Source or Destination GeoIP Country", "ipv6.geoip.country", FT_STRING, BASE_NONE, NULL, 0x0,
2206             NULL, HFILL }},
2207     { &hf_geoip_city,
2208       { "Source or Destination GeoIP City", "ipv6.geoip.city", FT_STRING, BASE_NONE, NULL, 0x0,
2209             NULL, HFILL }},
2210     { &hf_geoip_org,
2211       { "Source or Destination GeoIP Organization", "ipv6.geoip.org", FT_STRING, BASE_NONE, NULL, 0x0,
2212             NULL, HFILL }},
2213     { &hf_geoip_isp,
2214       { "Source or Destination GeoIP ISP", "ipv6.geoip.isp", FT_STRING, BASE_NONE, NULL, 0x0,
2215             NULL, HFILL }},
2216     { &hf_geoip_asnum,
2217       { "Source or Destination GeoIP AS Number", "ipv6.geoip.asnum", FT_STRING, BASE_NONE, NULL, 0x0,
2218             NULL, HFILL }},
2219     { &hf_geoip_lat,
2220       { "Source or Destination GeoIP Latitude", "ipv6.geoip.lat", FT_STRING, BASE_NONE, NULL, 0x0,
2221             NULL, HFILL }},
2222     { &hf_geoip_lon,
2223       { "Source or Destination GeoIP Longitude", "ipv6.geoip.lon", FT_STRING, BASE_NONE, NULL, 0x0,
2224             NULL, HFILL }},
2225     { &hf_geoip_src_country,
2226       { "Source GeoIP Country", "ipv6.geoip.src_country", FT_STRING, BASE_NONE, NULL, 0x0,
2227             NULL, HFILL }},
2228     { &hf_geoip_src_city,
2229       { "Source GeoIP City", "ipv6.geoip.src_city", FT_STRING, BASE_NONE, NULL, 0x0,
2230             NULL, HFILL }},
2231     { &hf_geoip_src_org,
2232       { "Source GeoIP Organization", "ipv6.geoip.src_org", FT_STRING, BASE_NONE, NULL, 0x0,
2233             NULL, HFILL }},
2234     { &hf_geoip_src_isp,
2235       { "Source GeoIP ISP", "ipv6.geoip.src_isp", FT_STRING, BASE_NONE, NULL, 0x0,
2236             NULL, HFILL }},
2237     { &hf_geoip_src_asnum,
2238       { "Source GeoIP AS Number", "ipv6.geoip.src_asnum", FT_STRING, BASE_NONE, NULL, 0x0,
2239             NULL, HFILL }},
2240     { &hf_geoip_src_lat,
2241       { "Source GeoIP Latitude", "ipv6.geoip.src_lat", FT_STRING, BASE_NONE, NULL, 0x0,
2242             NULL, HFILL }},
2243     { &hf_geoip_src_lon,
2244       { "Source GeoIP Longitude", "ipv6.geoip.src_lon", FT_STRING, BASE_NONE, NULL, 0x0,
2245             NULL, HFILL }},
2246     { &hf_geoip_dst_country,
2247       { "Destination GeoIP Country", "ipv6.geoip.dst_country", FT_STRING, BASE_NONE, NULL, 0x0,
2248             NULL, HFILL }},
2249     { &hf_geoip_dst_city,
2250       { "Destination GeoIP City", "ipv6.geoip.dst_city", FT_STRING, BASE_NONE, NULL, 0x0,
2251             NULL, HFILL }},
2252     { &hf_geoip_dst_org,
2253       { "Destination GeoIP Organization", "ipv6.geoip.dst_org", FT_STRING, BASE_NONE, NULL, 0x0,
2254             NULL, HFILL }},
2255     { &hf_geoip_dst_isp,
2256       { "Destination GeoIP ISP", "ipv6.geoip.dst_isp", FT_STRING, BASE_NONE, NULL, 0x0,
2257             NULL, HFILL }},
2258     { &hf_geoip_dst_asnum,
2259       { "Destination GeoIP AS Number", "ipv6.geoip.dst_asnum", FT_STRING, BASE_NONE, NULL, 0x0,
2260             NULL, HFILL }},
2261     { &hf_geoip_dst_lat,
2262       { "Destination GeoIP Latitude", "ipv6.geoip.dst_lat", FT_STRING, BASE_NONE, NULL, 0x0,
2263             NULL, HFILL }},
2264     { &hf_geoip_dst_lon,
2265       { "Destination GeoIP Longitude", "ipv6.geoip.dst_lon", FT_STRING, BASE_NONE, NULL, 0x0,
2266             NULL, HFILL }},
2267 #endif /* HAVE_GEOIP_V6 */
2268
2269
2270     { &hf_ipv6_opt_pad1,
2271       { "Pad1",                 "ipv6.opt.pad1",
2272                                 FT_NONE, BASE_NONE, NULL, 0x0,
2273                                 "Pad1 Option", HFILL }},
2274     { &hf_ipv6_opt_padn,
2275       { "PadN",                 "ipv6.opt.padn",
2276                                 FT_UINT8, BASE_DEC, NULL, 0x0,
2277                                 "PadN Option", HFILL }},
2278     { &hf_ipv6_dst_opt,
2279       { "Destination Option",   "ipv6.dst_opt",
2280                                 FT_NONE, BASE_NONE, NULL, 0x0,
2281                                 NULL, HFILL }},
2282     { &hf_ipv6_hop_opt,
2283       { "Hop-by-Hop Option",    "ipv6.hop_opt",
2284                                 FT_NONE, BASE_NONE, NULL, 0x0,
2285                                 NULL, HFILL }},
2286     { &hf_ipv6_unk_hdr,
2287       { "Unknown Extension Header",     "ipv6.unknown_hdr",
2288                                 FT_NONE, BASE_NONE, NULL, 0x0,
2289                                 NULL, HFILL }},
2290     { &hf_ipv6_routing_hdr_opt,
2291       { "Routing Header, Type","ipv6.routing_hdr",
2292                                 FT_UINT8, BASE_DEC, NULL, 0x0,
2293                                 "Routing Header Option", HFILL }},
2294     { &hf_ipv6_routing_hdr_type,
2295       { "Type",                 "ipv6.routing_hdr.type",
2296                                 FT_UINT8, BASE_DEC, VALS(routing_header_type), 0x0,
2297                                 "Routeing Header Type", HFILL }},
2298     { &hf_ipv6_routing_hdr_left,
2299       { "Left Segments",        "ipv6.routing_hdr.left",
2300                                 FT_UINT8, BASE_DEC, NULL, 0x0,
2301                                 "Routing Header Left Segments", HFILL }},
2302     { &hf_ipv6_routing_hdr_addr,
2303       { "Address",              "ipv6.routing_hdr.addr",
2304                                 FT_IPv6, BASE_NONE, NULL, 0x0,
2305                                 "Routing Header Address", HFILL }},
2306     { &hf_ipv6_frag_offset,
2307       { "Offset",               "ipv6.fragment.offset",
2308                                 FT_UINT16, BASE_DEC_HEX, NULL, IP6F_OFF_MASK,
2309                                 "Fragment Offset", HFILL }},
2310     { &hf_ipv6_frag_more,
2311       { "More Fragment",        "ipv6.fragment.more",
2312                                 FT_BOOLEAN, 16, TFS(&tfs_yes_no), IP6F_MORE_FRAG,
2313                                 "More Fragments", HFILL }},
2314     { &hf_ipv6_frag_id,
2315       { "Identification",       "ipv6.framgent.id",
2316                                 FT_UINT32, BASE_HEX, NULL, 0x0,
2317                                 "Fragment Identification", HFILL }},
2318     { &hf_ipv6_fragment_overlap,
2319       { "Fragment overlap",     "ipv6.fragment.overlap",
2320                                 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2321                                 "Fragment overlaps with other fragments", HFILL }},
2322
2323     { &hf_ipv6_fragment_overlap_conflict,
2324       { "Conflicting data in fragment overlap", "ipv6.fragment.overlap.conflict",
2325                                 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2326                                 "Overlapping fragments contained conflicting data", HFILL }},
2327
2328     { &hf_ipv6_fragment_multiple_tails,
2329       { "Multiple tail fragments found", "ipv6.fragment.multipletails",
2330                                 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2331                                 "Several tails were found when defragmenting the packet", HFILL }},
2332
2333     { &hf_ipv6_fragment_too_long_fragment,
2334       { "Fragment too long",    "ipv6.fragment.toolongfragment",
2335                                 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2336                                 "Fragment contained data past end of packet", HFILL }},
2337
2338     { &hf_ipv6_fragment_error,
2339       { "Defragmentation error", "ipv6.fragment.error",
2340                                 FT_FRAMENUM, BASE_NONE, NULL, 0x0,
2341                                 "Defragmentation error due to illegal fragments", HFILL }},
2342
2343     { &hf_ipv6_fragment_count,
2344       { "Fragment count", "ipv6.fragment.count",
2345                                 FT_UINT32, BASE_DEC, NULL, 0x0,
2346                                 NULL, HFILL }},
2347
2348     { &hf_ipv6_fragment,
2349       { "IPv6 Fragment",        "ipv6.fragment",
2350                                 FT_FRAMENUM, BASE_NONE, NULL, 0x0,
2351                                 NULL, HFILL }},
2352
2353     { &hf_ipv6_fragments,
2354       { "IPv6 Fragments",       "ipv6.fragments",
2355                                 FT_NONE, BASE_NONE, NULL, 0x0,
2356                                 NULL, HFILL }},
2357
2358     { &hf_ipv6_reassembled_in,
2359       { "Reassembled IPv6 in frame", "ipv6.reassembled_in",
2360                                 FT_FRAMENUM, BASE_NONE, NULL, 0x0,
2361                                 "This IPv6 packet is reassembled in this frame", HFILL }},
2362
2363     { &hf_ipv6_reassembled_length,
2364       { "Reassembled IPv6 length", "ipv6.reassembled.length",
2365                                 FT_UINT32, BASE_DEC, NULL, 0x0,
2366                                 "The total length of the reassembled payload", HFILL }},
2367
2368     /* RPL Routing Header */
2369     { &hf_ipv6_routing_hdr_rpl_cmprI,
2370       { "Compressed Internal Octets (CmprI)", "ipv6.routing_hdr.rpl.cmprI",
2371         FT_UINT32, BASE_DEC, NULL, IP6RRPL_BITMASK_CMPRI,
2372         "Elided octets from all but last segment", HFILL }},
2373
2374     { &hf_ipv6_routing_hdr_rpl_cmprE,
2375       { "Compressed Final Octets (CmprE)", "ipv6.routing_hdr.rpl.cmprE",
2376         FT_UINT32, BASE_DEC, NULL, IP6RRPL_BITMASK_CMPRE,
2377         "Elided octets from last segment address", HFILL }},
2378
2379     { &hf_ipv6_routing_hdr_rpl_pad,
2380       { "Padding Bytes", "ipv6.routing_hdr.rpl.pad",
2381         FT_UINT32, BASE_DEC, NULL, IP6RRPL_BITMASK_PAD,
2382         NULL, HFILL }},
2383
2384     { &hf_ipv6_routing_hdr_rpl_reserved,
2385       { "Reserved", "ipv6.routing_hdr.rpl.reserved",
2386         FT_UINT32, BASE_DEC, NULL, IP6RRPL_BITMASK_RESERVED,
2387         "Must be Zero", HFILL }},
2388
2389     { &hf_ipv6_routing_hdr_rpl_segments,
2390       { "Total Segments", "ipv6.routing_hdr.rpl.segments",
2391         FT_INT32, BASE_DEC, NULL, 0,
2392         NULL, HFILL }},
2393
2394     { &hf_ipv6_routing_hdr_rpl_addr,
2395       { "Address", "ipv6.routing_hdr.rpl.address",
2396         FT_BYTES, BASE_NONE, NULL, 0,
2397         NULL, HFILL }},
2398
2399     { &hf_ipv6_routing_hdr_rpl_fulladdr,
2400       { "Full Address", "ipv6.routing_hdr.rpl.full_address",
2401         FT_IPv6, BASE_NONE, NULL, 0,
2402         "Uncompressed IPv6 Address", HFILL }},
2403
2404     /* Mobile IPv6 */
2405     { &hf_ipv6_mipv6_type,
2406       { "Option Type",          "ipv6.mipv6_type",
2407                                 FT_UINT8, BASE_DEC, NULL, 0x0,
2408                                 NULL, HFILL }},
2409     { &hf_ipv6_mipv6_length,
2410       { "Option Length",        "ipv6.mipv6_length",
2411                                 FT_UINT8, BASE_DEC, NULL, 0x0,
2412                                 NULL, HFILL }},
2413     { &hf_ipv6_mipv6_home_address,
2414       { "Home Address", "ipv6.mipv6_home_address",
2415                                 FT_IPv6, BASE_NONE, NULL, 0x0,
2416                                 NULL, HFILL }},
2417
2418     /* SHIM6 */
2419     { &hf_ipv6_shim6,
2420       { "SHIM6",                "ipv6.shim6",
2421                                 FT_NONE, BASE_NONE, NULL, 0x0,
2422                                 NULL, HFILL }},
2423
2424     { &hf_ipv6_shim6_nxt,
2425       { "Next Header",          "ipv6.shim6.nxt",
2426                                 FT_UINT8, BASE_DEC, NULL, 0x0,
2427                                 NULL, HFILL }},
2428
2429     { &hf_ipv6_shim6_len,
2430       { "Header Ext Length",    "ipv6.shim6.len",
2431                                 FT_UINT8, BASE_DEC, NULL, 0x0,
2432                                 NULL, HFILL }},
2433
2434     { &hf_ipv6_shim6_p,
2435       { "P Bit",                "ipv6.shim6.p",
2436                                 FT_BOOLEAN, 8, NULL, SHIM6_BITMASK_P,
2437                                 NULL, HFILL }},
2438
2439     { &hf_ipv6_shim6_ct,
2440       { "Context Tag",          "ipv6.shim6.ct",
2441                                 FT_NONE, BASE_NONE, NULL, 0x0,
2442                                 NULL, HFILL }},
2443
2444     { &hf_ipv6_shim6_type,
2445       { "Message Type",         "ipv6.shim6.type",
2446                                 FT_UINT8, BASE_DEC,
2447                                 VALS(shimctrlvals), SHIM6_BITMASK_TYPE,
2448                                 NULL, HFILL }},
2449
2450     { &hf_ipv6_shim6_proto,
2451       { "Protocol",             "ipv6.shim6.proto",
2452                                 FT_UINT8, BASE_DEC,
2453                                 VALS(shim6_protocol), SHIM6_BITMASK_PROTOCOL,
2454                                 NULL, HFILL }},
2455
2456     { &hf_ipv6_shim6_checksum,
2457       { "Checksum",             "ipv6.shim6.checksum",
2458                                 FT_UINT16, BASE_HEX, NULL, 0x0,
2459                                 "Shim6 Checksum", HFILL }},
2460     { &hf_ipv6_shim6_checksum_bad,
2461       { "Bad Checksum",         "ipv6.shim6.checksum_bad",
2462                                 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2463                                 "Shim6 Bad Checksum", HFILL }},
2464
2465     { &hf_ipv6_shim6_checksum_good,
2466       { "Good Checksum",                "ipv6.shim6.checksum_good",
2467                                 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2468                                 NULL, HFILL }},
2469
2470     { &hf_ipv6_shim6_inonce,
2471       { "Initiator Nonce",      "ipv6.shim6.inonce",
2472                                 FT_UINT32, BASE_DEC_HEX, NULL, 0x0,
2473                                 NULL, HFILL }},
2474
2475     { &hf_ipv6_shim6_rnonce,
2476       { "Responder Nonce",      "ipv6.shim6.rnonce",
2477                                 FT_UINT32, BASE_DEC_HEX, NULL, 0x0,
2478                                 NULL, HFILL }},
2479
2480     { &hf_ipv6_shim6_precvd,
2481       { "Probes Received",      "ipv6.shim6.precvd",
2482                                 FT_UINT8, BASE_DEC, NULL, 0x0,
2483                                 NULL, HFILL }},
2484
2485     { &hf_ipv6_shim6_psent,
2486       { "Probes Sent",          "ipv6.shim6.psent",
2487                                 FT_UINT8, BASE_DEC, NULL, 0x0,
2488                                 NULL, HFILL }},
2489
2490     { &hf_ipv6_shim6_psrc,
2491       { "Source Address",       "ipv6.shim6.psrc",
2492                                 FT_IPv6, BASE_NONE, NULL, 0x0,
2493                                 "Shim6 Probe Source Address", HFILL }},
2494
2495     { &hf_ipv6_shim6_pdst,
2496       { "Destination Address",  "ipv6.shim6.pdst",
2497                                 FT_IPv6, BASE_NONE, NULL, 0x0,
2498                                 "Shim6 Probe Destination Address", HFILL }},
2499
2500     { &hf_ipv6_shim6_pnonce,
2501       { "Nonce",                "ipv6.shim6.pnonce",
2502                                 FT_UINT32, BASE_DEC_HEX, NULL, 0x0,
2503                                 "Shim6 Probe Nonce", HFILL }},
2504
2505     { &hf_ipv6_shim6_pdata,
2506       { "Data",                 "ipv6.shim6.pdata",
2507                                 FT_UINT32, BASE_HEX, NULL, 0x0,
2508                                 "Shim6 Probe Data", HFILL }},
2509
2510     { &hf_ipv6_shim6_sulid,
2511       { "Sender ULID",          "ipv6.shim6.sulid",
2512                                 FT_IPv6, BASE_NONE, NULL, 0x0,
2513                                 "Shim6 Sender ULID", HFILL }},
2514
2515     { &hf_ipv6_shim6_rulid,
2516       { "Receiver ULID",        "ipv6.shim6.rulid",
2517                                 FT_IPv6, BASE_NONE, NULL, 0x0,
2518                                 "Shim6 Receiver ULID", HFILL }},
2519
2520     { &hf_ipv6_shim6_reap,
2521       { "REAP State",           "ipv6.shim6.reap",
2522                                 FT_UINT8, BASE_DEC, NULL, 0x0,
2523                                 NULL, HFILL }},
2524
2525     { &hf_ipv6_shim6_opt_type,
2526       { "Option Type",          "ipv6.shim6.opt.type",
2527                                 FT_UINT16, BASE_DEC,
2528                                 VALS(shimoptvals), SHIM6_BITMASK_OPT_TYPE,
2529                                 "Shim6 Option Type", HFILL }},
2530
2531     { &hf_ipv6_shim6_opt_critical,
2532       { "Option Critical Bit",  "ipv6.shim6.opt.critical",
2533                                 FT_BOOLEAN, 8,
2534                                 TFS(&tfs_yes_no),
2535                                 SHIM6_BITMASK_CRITICAL,
2536                                 "TRUE : option is critical, FALSE: option is not critical",
2537                                 HFILL }},
2538
2539     { &hf_ipv6_shim6_opt_len,
2540       { "Content Length",       "ipv6.shim6.opt.len",
2541                                 FT_UINT16, BASE_DEC, NULL, 0x0,
2542                                 "Content Length Option", HFILL }},
2543
2544     { &hf_ipv6_shim6_opt_total_len,
2545       { "Total Length",         "ipv6.shim6.opt.total_len",
2546                                 FT_UINT16, BASE_DEC, NULL, 0x0,
2547                                 "Total Option Length", HFILL }},
2548
2549     { &hf_ipv6_shim6_opt_loc_verif_methods,
2550       { "Verification Method",  "ipv6.shim6.opt.verif_method",
2551                                 FT_UINT8, BASE_DEC,
2552                                 VALS(shimverifmethods), 0x0,
2553                                 "Locator Verification Method", HFILL }},
2554
2555     { &hf_ipv6_shim6_opt_loclist,
2556       { "Locator List Generation", "ipv6.shim6.opt.loclist",
2557                                 FT_UINT32, BASE_DEC_HEX, NULL, 0x0,
2558                                 NULL, HFILL }},
2559
2560     { &hf_ipv6_shim6_locator,
2561       { "Locator",              "ipv6.shim6.locator",
2562                                 FT_IPv6, BASE_NONE, NULL, 0x0,
2563                                 "Shim6 Locator", HFILL }},
2564
2565     { &hf_ipv6_shim6_opt_locnum,
2566       { "Num Locators",         "ipv6.shim6.opt.locnum",
2567                                 FT_UINT8, BASE_DEC, NULL, 0x0,
2568                                 "Number of Locators in Locator List", HFILL }},
2569
2570     { &hf_ipv6_shim6_opt_elemlen,
2571       { "Element Length",       "ipv6.shim6.opt.elemlen",
2572                                 FT_UINT8, BASE_DEC, NULL, 0x0,
2573                                 "Length of Elements in Locator Preferences Option", HFILL }},
2574     { &hf_ipv6_shim6_loc_flag,
2575       { "Flags",                "ipv6.shim6.loc.flags",
2576                                 FT_UINT8, BASE_DEC, NULL, 0x0,
2577                                 "Locator Preferences Flags", HFILL }},
2578
2579     { &hf_ipv6_shim6_loc_prio,
2580       { "Priority",             "ipv6.shim6.loc.prio",
2581                                 FT_UINT8, BASE_DEC, NULL, 0x0,
2582                                 "Locator Preferences Priority", HFILL }},
2583
2584     { &hf_ipv6_shim6_loc_weight,
2585       { "Weight",               "ipv6.shim6.loc.weight",
2586                                 FT_UINT8, BASE_DEC, NULL, 0x0,
2587                                 "Locator Preferences Weight", HFILL }},
2588
2589     { &hf_ipv6_shim6_opt_fii,
2590       { "Forked Instance Identifier", "ipv6.shim6.opt.fii",
2591                                 FT_UINT32, BASE_DEC_HEX, NULL, 0x0,
2592                                 NULL, HFILL }},
2593
2594 #ifdef TEST_FINALHDR
2595     { &hf_ipv6_final,
2596       { "Final next header",    "ipv6.final",
2597                                 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2598 #endif
2599
2600     { &hf_ipv6_traffic_class_dscp,
2601       { "Differentiated Services Field",        "ipv6.traffic_class.dscp",
2602                                 FT_UINT32, BASE_HEX, VALS(dscp_vals), 0x0FC00000, NULL, HFILL }},
2603
2604     { &hf_ipv6_traffic_class_ect,
2605       { "ECN-Capable Transport (ECT)", "ipv6.traffic_class.ect",
2606                                 FT_BOOLEAN, 32, TFS(&tfs_set_notset), 0x0200000, NULL, HFILL }},
2607
2608     { &hf_ipv6_traffic_class_ce,
2609       { "ECN-CE",               "ipv6.traffic_class.ce",
2610                                 FT_BOOLEAN, 32, TFS(&tfs_set_notset), 0x0100000, NULL, HFILL }},
2611   };
2612   static gint *ett[] = {
2613     &ett_ipv6,
2614     &ett_ipv6_version,
2615     &ett_ipv6_shim6,
2616     &ett_ipv6_shim6_option,
2617     &ett_ipv6_shim6_locators,
2618     &ett_ipv6_shim6_verif_methods,
2619     &ett_ipv6_shim6_loc_pref,
2620     &ett_ipv6_shim6_probes_sent,
2621     &ett_ipv6_shim6_probes_rcvd,
2622     &ett_ipv6_shim6_probe_sent,
2623     &ett_ipv6_shim6_probe_rcvd,
2624     &ett_ipv6_shim6_cksum,
2625     &ett_ipv6_fragments,
2626     &ett_ipv6_fragment,
2627     &ett_ipv6_traffic_class,
2628 #ifdef HAVE_GEOIP_V6
2629     &ett_geoip_info
2630 #endif /* HAVE_GEOIP_V6 */
2631   };
2632   module_t *ipv6_module;
2633
2634   proto_ipv6 = proto_register_protocol("Internet Protocol Version 6", "IPv6", "ipv6");
2635   proto_register_field_array(proto_ipv6, hf, array_length(hf));
2636   proto_register_subtree_array(ett, array_length(ett));
2637
2638   /* Register configuration options */
2639   ipv6_module = prefs_register_protocol(proto_ipv6, NULL);
2640   prefs_register_bool_preference(ipv6_module, "defragment",
2641         "Reassemble fragmented IPv6 datagrams",
2642         "Whether fragmented IPv6 datagrams should be reassembled",
2643         &ipv6_reassemble);
2644   prefs_register_bool_preference(ipv6_module, "summary_in_tree",
2645         "Show IPv6 summary in protocol tree",
2646         "Whether the IPv6 summary line should be shown in the protocol tree",
2647         &ipv6_summary_in_tree);
2648 #ifdef HAVE_GEOIP_V6
2649         prefs_register_bool_preference(ipv6_module, "use_geoip" ,
2650                   "Enable GeoIP lookups",
2651                   "Whether to look up IPv6 addresses in each GeoIP database we have loaded",
2652                   &ipv6_use_geoip);
2653 #endif /* HAVE_GEOIP_V6 */
2654
2655   register_dissector("ipv6", dissect_ipv6, proto_ipv6);
2656   register_init_routine(ipv6_reassemble_init);
2657   ipv6_tap = register_tap("ipv6");
2658 }
2659
2660 void
2661 proto_reg_handoff_ipv6(void)
2662 {
2663   dissector_handle_t ipv6_handle;
2664
2665   data_handle = find_dissector("data");
2666   ipv6_handle = find_dissector("ipv6");
2667   dissector_add_uint("ethertype", ETHERTYPE_IPv6, ipv6_handle);
2668   dissector_add_uint("ppp.protocol", PPP_IPV6, ipv6_handle);
2669   dissector_add_uint("ppp.protocol", ETHERTYPE_IPv6, ipv6_handle);
2670   dissector_add_uint("gre.proto", ETHERTYPE_IPv6, ipv6_handle);
2671   dissector_add_uint("ip.proto", IP_PROTO_IPV6, ipv6_handle);
2672   dissector_add_uint("null.type", BSD_AF_INET6_BSD, ipv6_handle);
2673   dissector_add_uint("null.type", BSD_AF_INET6_FREEBSD, ipv6_handle);
2674   dissector_add_uint("null.type", BSD_AF_INET6_DARWIN, ipv6_handle);
2675   dissector_add_uint("chdlctype", ETHERTYPE_IPv6, ipv6_handle);
2676   dissector_add_uint("fr.ietf", NLPID_IP6, ipv6_handle);
2677   dissector_add_uint("osinl.excl", NLPID_IP6, ipv6_handle);
2678   dissector_add_uint("x.25.spi", NLPID_IP6, ipv6_handle);
2679   dissector_add_uint("arcnet.protocol_id", ARCNET_PROTO_IPv6, ipv6_handle);
2680
2681   ip_dissector_table = find_dissector_table("ip.proto");
2682 }