* Prefer col_append_str instead of col_append_fstr for constant strings
[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 <string.h>
34 #include <math.h>
35 #include <stdio.h>
36 #include <glib.h>
37 #include <epan/packet.h>
38 #include "packet-ipsec.h"
39 #include "packet-ipv6.h"
40 #include <epan/ip_opts.h>
41 #include <epan/addr_resolv.h>
42 #include <epan/prefs.h>
43 #include <epan/reassemble.h>
44 #include <epan/ipproto.h>
45 #include <epan/ipv6-utils.h>
46 #include <epan/etypes.h>
47 #include <epan/ppptypes.h>
48 #include <epan/aftypes.h>
49 #include <epan/nlpid.h>
50 #include <epan/arcnet_pids.h>
51 #include <epan/in_cksum.h>
52 #include <epan/value_string.h>
53 #include <epan/expert.h>
54 #include <epan/emem.h>
55
56 /*
57  * NOTE: ipv6.nxt is not very useful as we will have chained header.
58  * now testing ipv6.final, but it raises SEGV.
59 #define TEST_FINALHDR
60  */
61
62 static int proto_ipv6             = -1;
63 static int hf_ipv6_version        = -1;
64 static int hf_ip_version      = -1;
65 static int hf_ipv6_class          = -1;
66 static int hf_ipv6_flow           = -1;
67 static int hf_ipv6_plen           = -1;
68 static int hf_ipv6_nxt            = -1;
69 static int hf_ipv6_hlim           = -1;
70 static int hf_ipv6_src            = -1;
71 static int hf_ipv6_src_host       = -1;
72 static int hf_ipv6_dst            = -1;
73 static int hf_ipv6_dst_host       = -1;
74 static int hf_ipv6_addr           = -1;
75 static int hf_ipv6_host           = -1;
76 static int hf_ipv6_opt_pad1       = -1;
77 static int hf_ipv6_opt_padn       = -1;
78 static int hf_ipv6_dst_opt        = -1;
79 static int hf_ipv6_hop_opt        = -1;
80 static int hf_ipv6_unk_hdr        = -1;
81 static int hf_ipv6_routing_hdr_opt        = -1;
82 static int hf_ipv6_routing_hdr_type       = -1;
83 static int hf_ipv6_routing_hdr_left       = -1;
84 static int hf_ipv6_routing_hdr_addr       = -1;
85 #ifdef TEST_FINALHDR
86 static int hf_ipv6_final          = -1;
87 #endif
88 static int hf_ipv6_frag_offset                = -1;
89 static int hf_ipv6_frag_more                  = -1;
90 static int hf_ipv6_frag_id                    = -1;
91 static int hf_ipv6_fragments                  = -1;
92 static int hf_ipv6_fragment                   = -1;
93 static int hf_ipv6_fragment_overlap           = -1;
94 static int hf_ipv6_fragment_overlap_conflict  = -1;
95 static int hf_ipv6_fragment_multiple_tails    = -1;
96 static int hf_ipv6_fragment_too_long_fragment = -1;
97 static int hf_ipv6_fragment_error             = -1;
98 static int hf_ipv6_reassembled_in             = -1;
99
100 static int hf_ipv6_mipv6_type                 = -1;
101 static int hf_ipv6_mipv6_length               = -1;
102 static int hf_ipv6_mipv6_home_address         = -1;
103
104 static int hf_ipv6_shim6              = -1;
105 static int hf_ipv6_shim6_nxt          = -1;
106 static int hf_ipv6_shim6_len          = -1;
107 static int hf_ipv6_shim6_p            = -1;
108 /* context tag is 49 bits, cannot be used for filter yet */
109 static int hf_ipv6_shim6_ct           = -1;
110 static int hf_ipv6_shim6_type         = -1;
111 static int hf_ipv6_shim6_proto        = -1;
112 static int hf_ipv6_shim6_checksum     = -1;
113 static int hf_ipv6_shim6_checksum_bad = -1;
114 static int hf_ipv6_shim6_checksum_good= -1;
115 static int hf_ipv6_shim6_inonce       = -1; /* also for request nonce */
116 static int hf_ipv6_shim6_rnonce       = -1;
117 static int hf_ipv6_shim6_precvd       = -1;
118 static int hf_ipv6_shim6_psent        = -1;
119 static int hf_ipv6_shim6_psrc         = -1;
120 static int hf_ipv6_shim6_pdst         = -1;
121 static int hf_ipv6_shim6_pnonce       = -1;
122 static int hf_ipv6_shim6_pdata        = -1;
123 static int hf_ipv6_shim6_sulid        = -1;
124 static int hf_ipv6_shim6_rulid        = -1;
125 static int hf_ipv6_shim6_reap         = -1;
126 static int hf_ipv6_shim6_opt_type     = -1;
127 static int hf_ipv6_shim6_opt_len      = -1;
128 static int hf_ipv6_shim6_opt_total_len= -1;
129 static int hf_ipv6_shim6_opt_loc_verif_methods = -1;
130 static int hf_ipv6_shim6_opt_critical = -1;
131 static int hf_ipv6_shim6_opt_loclist  = -1;
132 static int hf_ipv6_shim6_locator      = -1;
133 static int hf_ipv6_shim6_loc_flag     = -1;
134 static int hf_ipv6_shim6_loc_prio     = -1;
135 static int hf_ipv6_shim6_loc_weight   = -1;
136 static int hf_ipv6_shim6_opt_locnum   = -1;
137 static int hf_ipv6_shim6_opt_elemlen  = -1;
138 static int hf_ipv6_shim6_opt_fii      = -1;
139
140 static gint ett_ipv6                      = -1;
141 static gint ett_ipv6_version    = -1;
142 static gint ett_ipv6_shim6                = -1;
143 static gint ett_ipv6_shim6_option         = -1;
144 static gint ett_ipv6_shim6_locators       = -1;
145 static gint ett_ipv6_shim6_verif_methods  = -1;
146 static gint ett_ipv6_shim6_loc_pref       = -1;
147 static gint ett_ipv6_shim6_probes_sent    = -1;
148 static gint ett_ipv6_shim6_probe_sent     = -1;
149 static gint ett_ipv6_shim6_probes_rcvd    = -1;
150 static gint ett_ipv6_shim6_probe_rcvd     = -1;
151 static gint ett_ipv6_shim6_cksum          = -1;
152 static gint ett_ipv6_fragments            = -1;
153 static gint ett_ipv6_fragment             = -1;
154
155 static const fragment_items ipv6_frag_items = {
156         &ett_ipv6_fragment,
157         &ett_ipv6_fragments,
158         &hf_ipv6_fragments,
159         &hf_ipv6_fragment,
160         &hf_ipv6_fragment_overlap,
161         &hf_ipv6_fragment_overlap_conflict,
162         &hf_ipv6_fragment_multiple_tails,
163         &hf_ipv6_fragment_too_long_fragment,
164         &hf_ipv6_fragment_error,
165         &hf_ipv6_reassembled_in,
166         "fragments"
167 };
168
169 static dissector_handle_t data_handle;
170
171 static dissector_table_t ip_dissector_table;
172
173 /* Reassemble fragmented datagrams */
174 static gboolean ipv6_reassemble = TRUE;
175
176 #ifndef offsetof
177 #define offsetof(type, member)  ((size_t)(&((type *)0)->member))
178 #endif
179
180 /*
181  * defragmentation of IPv6
182  */
183 static GHashTable *ipv6_fragment_table = NULL;
184 static GHashTable *ipv6_reassembled_table = NULL;
185
186 void
187 capture_ipv6(const guchar *pd, int offset, int len, packet_counts *ld)
188 {
189   guint8 nxt;
190   int advance;
191
192   if (!BYTES_ARE_IN_FRAME(offset, len, 4+4+16+16)) {
193     ld->other++;
194     return;
195   }
196   nxt = pd[offset+6];           /* get the "next header" value */
197   offset += 4+4+16+16;          /* skip past the IPv6 header */
198
199 again:
200    switch (nxt) {
201    case IP_PROTO_HOPOPTS:
202    case IP_PROTO_ROUTING:
203    case IP_PROTO_DSTOPTS:
204      if (!BYTES_ARE_IN_FRAME(offset, len, 2)) {
205        ld->other++;
206        return;
207      }
208      nxt = pd[offset];
209      advance = (pd[offset+1] + 1) << 3;
210      if (!BYTES_ARE_IN_FRAME(offset, len, advance)) {
211        ld->other++;
212        return;
213      }
214      offset += advance;
215      goto again;
216    case IP_PROTO_FRAGMENT:
217      if (!BYTES_ARE_IN_FRAME(offset, len, 2)) {
218        ld->other++;
219        return;
220      }
221      nxt = pd[offset];
222      advance = 8;
223      if (!BYTES_ARE_IN_FRAME(offset, len, advance)) {
224        ld->other++;
225        return;
226      }
227      offset += advance;
228      goto again;
229    case IP_PROTO_AH:
230      if (!BYTES_ARE_IN_FRAME(offset, len, 2)) {
231        ld->other++;
232        return;
233      }
234      nxt = pd[offset];
235      advance = 8 + ((pd[offset+1] - 1) << 2);
236      if (!BYTES_ARE_IN_FRAME(offset, len, advance)) {
237        ld->other++;
238        return;
239      }
240      offset += advance;
241      goto again;
242    case IP_PROTO_SHIM6:
243    case IP_PROTO_SHIM6_OLD:
244      if (!BYTES_ARE_IN_FRAME(offset, len, 2)) {
245        ld->other++;
246        return;
247      }
248      nxt = pd[offset];
249      advance = (pd[offset+1] + 1) << 3;
250      if (!BYTES_ARE_IN_FRAME(offset, len, advance)) {
251        ld->other++;
252        return;
253      }
254      offset += advance;
255      goto again;
256    }
257
258   switch(nxt) {
259     case IP_PROTO_SCTP:
260       ld->sctp++;
261       break;
262     case IP_PROTO_TCP:
263       ld->tcp++;
264       break;
265     case IP_PROTO_UDP:
266     case IP_PROTO_UDPLITE:
267       ld->udp++;
268       break;
269     case IP_PROTO_ICMP:
270     case IP_PROTO_ICMPV6:       /* XXX - separate counters? */
271       ld->icmp++;
272       break;
273     case IP_PROTO_OSPF:
274       ld->ospf++;
275       break;
276     case IP_PROTO_GRE:
277       ld->gre++;
278       break;
279     case IP_PROTO_VINES:
280       ld->vines++;
281       break;
282     default:
283       ld->other++;
284   }
285 }
286
287 static void
288 ipv6_reassemble_init(void)
289 {
290   fragment_table_init(&ipv6_fragment_table);
291   reassembled_table_init(&ipv6_reassembled_table);
292 }
293
294 enum {
295   IPv6_RT_HEADER_SOURCE_ROUTING=0,
296   IPv6_RT_HEADER_NIMROD,
297   IPv6_RT_HEADER_MobileIP
298 };
299
300 /* Routeing Header Types */
301 static const value_string routing_header_type[] = {
302   { IPv6_RT_HEADER_SOURCE_ROUTING, "IPv6 Source Routing" },
303   { IPv6_RT_HEADER_NIMROD, "Nimrod" },
304   { IPv6_RT_HEADER_MobileIP, "Mobile IP" },
305   { 0, NULL }
306 };
307
308 static int
309 dissect_routing6(tvbuff_t *tvb, int offset, proto_tree *tree, packet_info *pinfo) {
310     struct ip6_rthdr rt;
311     guint len;
312     proto_tree *rthdr_tree;
313     proto_item *ti;
314     guint8 buf[sizeof(struct ip6_rthdr0) + sizeof(struct e_in6_addr) * 23];
315
316     tvb_memcpy(tvb, (guint8 *)&rt, offset, sizeof(rt));
317     len = (rt.ip6r_len + 1) << 3;
318
319     if (tree) {
320         /* !!! specify length */
321       ti = proto_tree_add_uint_format(tree, hf_ipv6_routing_hdr_opt, tvb,
322                       offset, len, rt.ip6r_type,
323                       "Routing Header, Type : %s (%u)",
324                       val_to_str(rt.ip6r_type, routing_header_type, "Unknown"),
325                       rt.ip6r_type);
326       rthdr_tree = proto_item_add_subtree(ti, ett_ipv6);
327
328         proto_tree_add_text(rthdr_tree, tvb,
329             offset + offsetof(struct ip6_rthdr, ip6r_nxt), 1,
330             "Next header: %s (0x%02x)", ipprotostr(rt.ip6r_nxt), rt.ip6r_nxt);
331
332         proto_tree_add_text(rthdr_tree, tvb,
333             offset + offsetof(struct ip6_rthdr, ip6r_len), 1,
334             "Length: %u (%d bytes)", rt.ip6r_len, len);
335
336         proto_tree_add_item(rthdr_tree, hf_ipv6_routing_hdr_type, tvb,
337                   offset + offsetof(struct ip6_rthdr, ip6r_type), 1, FALSE);
338
339         proto_tree_add_item(rthdr_tree, hf_ipv6_routing_hdr_left, tvb,
340                   offset + offsetof(struct ip6_rthdr, ip6r_segleft), 1, FALSE);
341
342         if (rt.ip6r_type == IPv6_RT_HEADER_SOURCE_ROUTING && len <= sizeof(buf)) {
343             struct e_in6_addr *a;
344             int n;
345             struct ip6_rthdr0 *rt0;
346
347             tvb_memcpy(tvb, buf, offset, len);
348             rt0 = (struct ip6_rthdr0 *)buf;
349
350             for (a = rt0->ip6r0_addr, n = 0;
351                     a < (struct e_in6_addr *)(buf + len); a++, n++) {
352
353               proto_tree_add_item(rthdr_tree, hf_ipv6_routing_hdr_addr, tvb,
354                               offset + offsetof(struct ip6_rthdr0, ip6r0_addr)
355                                      + n * sizeof(struct e_in6_addr),
356                               sizeof(struct e_in6_addr), FALSE);
357               SET_ADDRESS(&pinfo->dst, AT_IPv6, 16, tvb_get_ptr(tvb,
358                               offset + offsetof(struct ip6_rthdr0, ip6r0_addr)
359                                      + n * sizeof(struct e_in6_addr), 16));
360             }
361         }
362         if (rt.ip6r_type == IPv6_RT_HEADER_MobileIP) {
363           proto_tree_add_item(rthdr_tree, hf_ipv6_mipv6_home_address, tvb,
364                               offset + 8, 16, FALSE);
365           SET_ADDRESS(&pinfo->dst, AT_IPv6, 16, tvb_get_ptr(tvb, offset + 8, 16));
366         }
367     }
368
369     return len;
370 }
371
372 static int
373 dissect_frag6(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree,
374     guint16 *offlg, guint32 *ident) {
375     struct ip6_frag frag;
376     int len;
377     proto_item *ti;
378     proto_tree *rthdr_tree;
379
380     tvb_memcpy(tvb, (guint8 *)&frag, offset, sizeof(frag));
381     len = sizeof(frag);
382     frag.ip6f_offlg = g_ntohs(frag.ip6f_offlg);
383     frag.ip6f_ident = g_ntohl(frag.ip6f_ident);
384     *offlg = frag.ip6f_offlg;
385     *ident = frag.ip6f_ident;
386     if (check_col(pinfo->cinfo, COL_INFO)) {
387         col_add_fstr(pinfo->cinfo, COL_INFO,
388             "IPv6 fragment (nxt=%s (0x%02x) off=%u id=0x%x)",
389             ipprotostr(frag.ip6f_nxt), frag.ip6f_nxt,
390             frag.ip6f_offlg & IP6F_OFF_MASK, frag.ip6f_ident);
391     }
392     if (tree) {
393            ti = proto_tree_add_text(tree, tvb, offset, len,
394                            "Fragmentation Header");
395            rthdr_tree = proto_item_add_subtree(ti, ett_ipv6);
396
397            proto_tree_add_text(rthdr_tree, tvb,
398                          offset + offsetof(struct ip6_frag, ip6f_nxt), 1,
399                          "Next header: %s (0x%02x)",
400                          ipprotostr(frag.ip6f_nxt), frag.ip6f_nxt);
401
402 #if 0
403            proto_tree_add_text(rthdr_tree, tvb,
404                          offset + offsetof(struct ip6_frag, ip6f_reserved), 1,
405                          "Reserved: %u",
406                          frag.ip6f_reserved);
407 #endif
408
409            proto_tree_add_item(rthdr_tree, hf_ipv6_frag_offset, tvb,
410                     offset + offsetof(struct ip6_frag, ip6f_offlg), 2, FALSE);
411
412            proto_tree_add_item(rthdr_tree, hf_ipv6_frag_more, tvb,
413                     offset + offsetof(struct ip6_frag, ip6f_offlg), 2, FALSE);
414
415            proto_tree_add_item(rthdr_tree, hf_ipv6_frag_id, tvb,
416                     offset + offsetof(struct ip6_frag, ip6f_ident), 4, FALSE);
417     }
418     return len;
419 }
420
421 static int
422 dissect_mipv6_hoa(tvbuff_t *tvb, proto_tree *dstopt_tree, int offset, packet_info *pinfo)
423 {
424     int len = 0;
425
426     proto_tree_add_uint_format(dstopt_tree, hf_ipv6_mipv6_type, tvb,
427         offset + len, 1,
428         tvb_get_guint8(tvb, offset + len),
429         "Option Type: %u (0x%02x) - Home Address Option",
430         tvb_get_guint8(tvb, offset + len),
431         tvb_get_guint8(tvb, offset + len));
432     len += 1;
433
434     proto_tree_add_uint(dstopt_tree, hf_ipv6_mipv6_length, tvb, offset + len,
435         1, tvb_get_guint8(tvb, offset + len));
436     len += 1;
437
438     proto_tree_add_ipv6(dstopt_tree, hf_ipv6_mipv6_home_address, tvb,
439         offset + len, 16, tvb_get_ptr(tvb, offset + len, 16));
440     SET_ADDRESS(&pinfo->src, AT_IPv6, 16, tvb_get_ptr(tvb, offset + len, 16));
441     len += 16;
442     return len;
443 }
444
445 static const value_string rtalertvals[] = {
446     { IP6OPT_RTALERT_MLD, "MLD" },
447     { IP6OPT_RTALERT_RSVP, "RSVP" },
448     { 0, NULL }
449 };
450
451 /* Like "dissect_ip_tcp_options()", but assumes the length of an option
452    *doesn't* include the type and length bytes. */
453 void
454 dissect_ipv6_options(tvbuff_t *tvb, int offset, guint length,
455                         const ip_tcp_opt *opttab, int nopts, int eol,
456                         packet_info *pinfo, proto_tree *opt_tree)
457 {
458   guchar            opt;
459   const ip_tcp_opt *optp;
460   opt_len_type      len_type;
461   unsigned int      optlen;
462   const char       *name;
463   char              name_str[7+1+1+2+2+1+1];    /* "Unknown (0x%02x)" */
464   void            (*dissect)(const struct ip_tcp_opt *, tvbuff_t *,
465                                 int, guint, packet_info *, proto_tree *);
466   guint             len;
467
468   while (length > 0) {
469     opt = tvb_get_guint8(tvb, offset);
470     for (optp = &opttab[0]; optp < &opttab[nopts]; optp++) {
471       if (optp->optcode == opt)
472         break;
473     }
474     if (optp == &opttab[nopts]) {
475       /* We assume that the only NO_LENGTH options are Pad1 options,
476          so that we can treat unknown options as VARIABLE_LENGTH with a
477          minimum of 0, and at least be able to move on to the next option
478          by using the length in the option. */
479       optp = NULL;      /* indicate that we don't know this option */
480       len_type = VARIABLE_LENGTH;
481       optlen = 0;
482       g_snprintf(name_str, sizeof name_str, "Unknown (0x%02x)", opt);
483       name = name_str;
484       dissect = NULL;
485     } else {
486       len_type = optp->len_type;
487       optlen = optp->optlen;
488       name = optp->name;
489       dissect = optp->dissect;
490     }
491     --length;      /* account for type byte */
492     if (len_type != NO_LENGTH) {
493       /* Option has a length. Is it in the packet? */
494       if (length == 0) {
495         /* Bogus - packet must at least include option code byte and
496            length byte! */
497         proto_tree_add_text(opt_tree, tvb, offset,      1,
498               "%s (length byte past end of options)", name);
499         return;
500       }
501       len = tvb_get_guint8(tvb, offset + 1);  /* total including type, len */
502       --length;    /* account for length byte */
503       if (len > length) {
504         /* Bogus - option goes past the end of the header. */
505         proto_tree_add_text(opt_tree, tvb, offset,      length,
506               "%s (option length = %u byte%s says option goes past end of options)",
507               name, len, plurality(len, "", "s"));
508         return;
509       } else if (len_type == FIXED_LENGTH && len != optlen) {
510         /* Bogus - option length isn't what it's supposed to be for this
511            option. */
512         proto_tree_add_text(opt_tree, tvb, offset,      2 + len,
513               "%s (with option length = %u byte%s; should be %u)", name,
514               len, plurality(len, "", "s"), optlen);
515         return;
516       } else if (len_type == VARIABLE_LENGTH && len < optlen) {
517         /* Bogus - option length is less than what it's supposed to be for
518            this option. */
519         proto_tree_add_text(opt_tree, tvb, offset,      2 + len,
520               "%s (with option length = %u byte%s; should be >= %u)", name,
521               len, plurality(len, "", "s"), optlen);
522         return;
523       } else {
524         if (optp == NULL) {
525           proto_tree_add_text(opt_tree, tvb, offset,    2 + len, "%s (%u byte%s)",
526                                 name, len, plurality(len, "", "s"));
527         } else {
528           if (dissect != NULL) {
529             /* Option has a dissector. */
530             (*dissect)(optp, tvb, offset,          2 + len, pinfo, opt_tree);
531           } else {
532             /* Option has no data, hence no dissector. */
533             proto_tree_add_text(opt_tree, tvb, offset,  2 + len, "%s", name);
534           }
535         }
536         offset += 2 + len;
537       }
538       length -= len;
539     } else {
540       proto_tree_add_text(opt_tree, tvb, offset,      1, "%s", name);
541       offset += 1;
542     }
543     if (opt == eol)
544       break;
545   }
546 }
547
548 static int
549 dissect_unknown_option(tvbuff_t *tvb, int offset, proto_tree *tree)
550 {
551     struct ip6_ext ext;
552     int len;
553     proto_tree *unkopt_tree;
554     proto_item *ti;
555
556     tvb_memcpy(tvb, (guint8 *)&ext, offset, sizeof(ext));
557     len = (ext.ip6e_len + 1) << 3;
558
559     if (tree) {
560         /* !!! specify length */
561         ti = proto_tree_add_item(tree, hf_ipv6_unk_hdr, tvb, offset, len, FALSE);
562
563         unkopt_tree = proto_item_add_subtree(ti, ett_ipv6);
564
565         proto_tree_add_text(unkopt_tree, tvb,
566             offset + offsetof(struct ip6_ext, ip6e_nxt), 1,
567             "Next header: %s (0x%02x)", ipprotostr(ext.ip6e_nxt), ext.ip6e_nxt);
568
569         proto_tree_add_text(unkopt_tree, tvb,
570             offset + offsetof(struct ip6_ext, ip6e_len), 1,
571             "Length: %u (%d bytes)", ext.ip6e_len, len);
572     }
573     return len;
574 }
575
576 static int
577 dissect_opts(tvbuff_t *tvb, int offset, proto_tree *tree, packet_info * pinfo, const int hf_option_item)
578 {
579     struct ip6_ext ext;
580     int len;
581     proto_tree *dstopt_tree;
582     proto_item *ti;
583     gint p;
584     guint8 tmp;
585     int mip_offset = 0, delta = 0;
586
587     tvb_memcpy(tvb, (guint8 *)&ext, offset, sizeof(ext));
588     len = (ext.ip6e_len + 1) << 3;
589
590     if (tree) {
591         /* !!! specify length */
592         ti = proto_tree_add_item(tree, hf_option_item, tvb, offset, len, FALSE);
593
594         dstopt_tree = proto_item_add_subtree(ti, ett_ipv6);
595
596         proto_tree_add_text(dstopt_tree, tvb,
597             offset + offsetof(struct ip6_ext, ip6e_nxt), 1,
598             "Next header: %s (0x%02x)", ipprotostr(ext.ip6e_nxt), ext.ip6e_nxt);
599
600         proto_tree_add_text(dstopt_tree, tvb,
601             offset + offsetof(struct ip6_ext, ip6e_len), 1,
602             "Length: %u (%d bytes)", ext.ip6e_len, len);
603
604         mip_offset = offset;
605         mip_offset += 2;
606
607         p = offset + 2;
608
609         while (p < offset + len) {
610             switch (tvb_get_guint8(tvb, p)) {
611             case IP6OPT_PAD1:
612                 proto_tree_add_item(dstopt_tree, hf_ipv6_opt_pad1, tvb, p, 1, FALSE);
613                 p++;
614                 mip_offset++;
615                 break;
616             case IP6OPT_PADN:
617                 /* RFC 2460 states :
618                  * "The PadN option is used to insert two or more octets of
619                  * padding into the Options area of a header.  For N octets of
620                  * padding, the Opt Data Len field contains the value N-2, and
621                  * the Option Data consists of N-2 zero-valued octets."
622                  */
623                 tmp = tvb_get_guint8(tvb, p + 1);
624                 proto_tree_add_uint_format(dstopt_tree, hf_ipv6_opt_padn, tvb,
625                                             p, tmp + 2, tmp + 2,
626                                             "PadN: %u bytes", tmp + 2);
627                 p += tmp + 2;
628                 mip_offset += tvb_get_guint8(tvb, mip_offset + 1) + 2;
629                 break;
630             case IP6OPT_JUMBO:
631                 tmp = tvb_get_guint8(tvb, p + 1);
632                 if (tmp == 4) {
633                     proto_tree_add_text(dstopt_tree, tvb, p, tmp + 2,
634                         "Jumbo payload: %u (%u bytes)",
635                         tvb_get_ntohl(tvb, p + 2), tmp + 2);
636                 } else {
637                     ti = proto_tree_add_text(dstopt_tree, tvb, p, tmp + 2,
638                         "Jumbo payload: Invalid length (%u bytes)",  tmp);
639                     expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_ERROR,
640                         "Jumbo payload: Invalid length (%u bytes)", tmp);
641                 }
642                 p += tmp + 2;
643                 mip_offset += tvb_get_guint8(tvb, mip_offset+1)+2;
644                 break;
645             case IP6OPT_RTALERT:
646               {
647                 tmp = tvb_get_guint8(tvb, p + 1);
648                 if (tmp == 2) {
649                     proto_tree_add_text(dstopt_tree, tvb, p , tmp + 2,
650                             "Router alert: %s (%u bytes)",
651                             val_to_str(tvb_get_ntohs(tvb, p + 2),
652                                         rtalertvals, "Unknown"),
653                             tmp + 2);
654                 } else {
655                     ti = proto_tree_add_text(dstopt_tree, tvb, p , tmp + 2,
656                             "Router alert: Invalid Length (%u bytes)",
657                             tmp + 2);
658                     expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_ERROR,
659                             "Router alert: Invalid Length (%u bytes)",
660                             tmp + 2);
661                 }
662
663                 p += tmp + 2;
664                 mip_offset += tvb_get_guint8(tvb, mip_offset + 1) + 2;
665                 break;
666               }
667             case IP6OPT_HOME_ADDRESS:
668                 delta = dissect_mipv6_hoa(tvb, dstopt_tree, mip_offset, pinfo);
669                 p += delta;
670                 mip_offset += delta;
671                 break;
672             default:
673                 p = offset + len;
674                 break;
675             }
676         }
677
678         /* decode... */
679     }
680     return len;
681 }
682
683 static int
684 dissect_hopopts(tvbuff_t *tvb, int offset, proto_tree *tree, packet_info * pinfo)
685 {
686     return dissect_opts(tvb, offset, tree, pinfo, hf_ipv6_hop_opt);
687 }
688
689 static int
690 dissect_dstopts(tvbuff_t *tvb, int offset, proto_tree *tree, packet_info * pinfo)
691 {
692     return dissect_opts(tvb, offset, tree, pinfo, hf_ipv6_dst_opt);
693 }
694
695 /* START SHIM6 PART */
696 static guint16 shim_checksum(const guint8 *ptr, int len)
697 {
698         vec_t cksum_vec[1];
699
700         cksum_vec[0].ptr = ptr;
701         cksum_vec[0].len = len;
702         return in_cksum(&cksum_vec[0], 1);
703 }
704
705 static int
706 dissect_shim_hex(tvbuff_t *tvb, int offset, int len, const char *itemname, guint8 bitmask, proto_tree *tree)
707 {
708     proto_item *ti;
709     int count;
710     gint p;
711
712     p = offset;
713
714     ti = proto_tree_add_text(tree, tvb, offset, len, "%s", itemname);
715
716     proto_item_append_text(ti, " 0x%02x", tvb_get_guint8(tvb, p) & bitmask);
717     for (count=1; count<len; count++)
718       proto_item_append_text(ti, "%02x", tvb_get_guint8(tvb, p+count));
719
720     return len;
721 }
722
723 static const value_string shimoptvals[] = {
724     { SHIM6_OPT_RESPVAL,  "Responder Validator Option" },
725     { SHIM6_OPT_LOCLIST,  "Locator List Option" },
726     { SHIM6_OPT_LOCPREF,  "Locator Preferences Option" },
727     { SHIM6_OPT_CGAPDM,   "CGA Parameter Data Structure Option" },
728     { SHIM6_OPT_CGASIG,   "CGA Signature Option" },
729     { SHIM6_OPT_ULIDPAIR, "ULID Pair Option" },
730     { SHIM6_OPT_FII,      "Forked Instance Identifier Option" },
731     { 0, NULL }
732 };
733
734 static const value_string shimverifmethods[] = {
735     { SHIM6_VERIF_HBA, "HBA" },
736     { SHIM6_VERIF_CGA, "CGA" },
737     { 0, NULL }
738 };
739
740 static const value_string shimflags[] _U_ = {
741     { SHIM6_FLAG_BROKEN,    "BROKEN" },
742     { SHIM6_FLAG_TEMPORARY, "TEMPORARY" },
743     { 0, NULL }
744 };
745
746 static const value_string shimreapstates[] = {
747     { SHIM6_REAP_OPERATIONAL, "Operational" },
748     { SHIM6_REAP_EXPLORING,   "Exploring" },
749     { SHIM6_REAP_INBOUNDOK,   "InboundOK" },
750     { 0, NULL }
751 };
752
753 static const value_string shim6_protocol[] = {
754   { 0, "SHIM6" },
755   { 1, "HIP" },
756   { 0, NULL }
757 };
758
759 static void
760 dissect_shim6_opt_loclist(proto_tree * opt_tree, tvbuff_t * tvb, gint *offset)
761 {
762   proto_item * it;
763   proto_tree * subtree;
764   guint count;
765   guint optlen;
766   int p = *offset;
767
768   proto_tree_add_item(opt_tree, hf_ipv6_shim6_opt_loclist, tvb, p, 4, FALSE);
769   p += 4;
770
771   optlen = tvb_get_guint8(tvb, p);
772   proto_tree_add_item(opt_tree, hf_ipv6_shim6_opt_locnum, tvb, p, 1, FALSE);
773   p++;
774
775   /* Verification Methods */
776   it = proto_tree_add_text(opt_tree, tvb, p, optlen,
777                             "Locator Verification Methods");
778   subtree = proto_item_add_subtree(it, ett_ipv6_shim6_verif_methods);
779
780   for (count=0; count < optlen; count++)
781     proto_tree_add_item(subtree, hf_ipv6_shim6_opt_loc_verif_methods, tvb,
782                             p+count, 1, FALSE);
783   p += optlen;
784
785   /* Padding, included in length field */
786   if ((7 - optlen % 8) > 0) {
787       proto_tree_add_text(opt_tree, tvb, p, (7 - optlen % 8), "Padding");
788       p += (7 - optlen % 8);
789   }
790
791   /* Locators */
792   it = proto_tree_add_text(opt_tree, tvb, p, 16 * optlen, "Locators");
793   subtree = proto_item_add_subtree(it, ett_ipv6_shim6_locators);
794
795   for (count=0; count < optlen; count++) {
796       proto_tree_add_item(subtree, hf_ipv6_shim6_locator, tvb, p, 16, FALSE);
797       p += 16;
798   }
799   *offset = p;
800 }
801
802 static void
803 dissect_shim6_opt_loc_pref(proto_tree * opt_tree, tvbuff_t * tvb, gint *offset, gint len, packet_info *pinfo)
804 {
805   proto_tree * subtree;
806   proto_item * it;
807
808   gint p;
809   gint optlen;
810   gint count;
811
812   p = *offset;
813
814   proto_tree_add_item(opt_tree, hf_ipv6_shim6_opt_loclist, tvb, p, 4, FALSE);
815   p += 4;
816
817   optlen = tvb_get_guint8(tvb, p);
818   proto_tree_add_item(opt_tree, hf_ipv6_shim6_opt_elemlen, tvb, p, 1, FALSE);
819
820   if (optlen < 1 || optlen > 3) {
821     it = proto_tree_add_text(opt_tree, tvb, p, 1,
822       "Invalid element length: %u",  optlen);
823     expert_add_info_format(pinfo, it, PI_MALFORMED, PI_ERROR,
824       "Invalid element length: %u", optlen);
825     return;
826   }
827
828   p++;
829
830   /* Locator Preferences */
831   count = 1;
832   while (p < len) {
833     it = proto_tree_add_text(opt_tree, tvb, p, optlen, "Locator Preferences %u", count);
834     subtree = proto_item_add_subtree(it, ett_ipv6_shim6_loc_pref);
835
836     /* Flags */
837     if (optlen >= 1)
838       proto_tree_add_item(subtree, hf_ipv6_shim6_loc_flag, tvb, p, 1, FALSE);
839     /* Priority */
840     if (optlen >= 2)
841       proto_tree_add_item(subtree, hf_ipv6_shim6_loc_prio, tvb, p+1, 1, FALSE);
842     /* Weight */
843     if (optlen >= 3)
844       proto_tree_add_item(subtree, hf_ipv6_shim6_loc_weight, tvb, p+2, 1, FALSE);
845     /*
846      * Shim6 Draft 08 doesn't specify the format when the Element length is
847      * more than three, except that any such formats MUST be defined so that
848      * the first three octets are the same as in the above case, that is, a
849      * of a 1 octet flags field followed by a 1 octet priority field, and a
850      * 1 octet weight field.
851      */
852     p += optlen;
853     count++;
854   }
855   *offset = p;
856 }
857
858
859 static int
860 dissect_shimopts(tvbuff_t *tvb, int offset, proto_tree *tree, packet_info *pinfo)
861 {
862     int len, total_len;
863     gint p;
864     gint padding;
865     proto_tree *opt_tree;
866     proto_item *ti;
867     guint8 tmp[2];
868     const gchar *ctype;
869
870
871     p = offset;
872
873     tmp[0] = tvb_get_guint8(tvb, p++);
874     tmp[1] = tvb_get_guint8(tvb, p++);
875     p += 2;
876
877     len = tvb_get_ntohs(tvb, offset+2);
878     padding = 7 - ((len + 3) % 8);
879     total_len = 4 + len + padding;
880
881     if (tree)
882     {
883         /* Option Type */
884         ctype = val_to_str( (tvb_get_ntohs(tvb, offset) & SHIM6_BITMASK_OPT_TYPE) >> 1, shimoptvals, "Unknown Option Type");
885         ti = proto_tree_add_text(tree, tvb, offset, total_len, "%s", ctype);
886         opt_tree = proto_item_add_subtree(ti, ett_ipv6_shim6_option);
887
888         proto_tree_add_item(opt_tree, hf_ipv6_shim6_opt_type, tvb, offset, 2, FALSE);
889
890         /* Critical */
891         proto_tree_add_item(opt_tree, hf_ipv6_shim6_opt_critical, tvb, offset+1, 1, FALSE);
892
893         /* Content Length */
894         proto_tree_add_item(opt_tree, hf_ipv6_shim6_opt_len, tvb, offset + 2, 2, FALSE);
895         ti = proto_tree_add_uint_format(opt_tree, hf_ipv6_shim6_opt_total_len, tvb, offset+2, 2,
896             total_len, "Total Length: %u", total_len);
897         PROTO_ITEM_SET_GENERATED(ti);
898
899         /* Option Type Specific */
900         switch (tvb_get_ntohs(tvb, offset) >> 1)
901         {
902             case SHIM6_OPT_RESPVAL:
903                 p += dissect_shim_hex(tvb, p, len, "Validator:", 0xff, opt_tree);
904                 if (total_len-(len+4) > 0)
905                     proto_tree_add_text(opt_tree, tvb, p, total_len-(len+4), "Padding");
906                 break;
907             case SHIM6_OPT_LOCLIST:
908                 dissect_shim6_opt_loclist(opt_tree, tvb, &p);
909                 break;
910             case SHIM6_OPT_LOCPREF:
911                 dissect_shim6_opt_loc_pref(opt_tree, tvb, &p, offset+len+4, pinfo);
912                 if (total_len-(len+4) > 0)
913                   proto_tree_add_text(opt_tree, tvb, p, total_len-(len+4), "Padding");
914                 break;
915             case SHIM6_OPT_CGAPDM:
916                 p += dissect_shim_hex(tvb, p, len, "CGA Parameter Data Structure:", 0xff, opt_tree);
917                 if (total_len-(len+4) > 0)
918                     proto_tree_add_text(opt_tree, tvb, p, total_len-(len+4), "Padding");
919                 break;
920             case SHIM6_OPT_CGASIG:
921                 p += dissect_shim_hex(tvb, p, len, "CGA Signature:", 0xff, opt_tree);
922                 if (total_len-(len+4) > 0)
923                     proto_tree_add_text(opt_tree, tvb, p, total_len-(len+4), "Padding");
924                 break;
925             case SHIM6_OPT_ULIDPAIR:
926                 proto_tree_add_text(opt_tree, tvb, p, 4, "Reserved");
927                 p += 4;
928                 proto_tree_add_item(opt_tree, hf_ipv6_shim6_sulid, tvb, p, 16, FALSE);
929                 p += 16;
930                 proto_tree_add_item(opt_tree, hf_ipv6_shim6_rulid, tvb, p, 16, FALSE);
931                 p += 16;
932                 break;
933             case SHIM6_OPT_FII:
934                 proto_tree_add_item(opt_tree, hf_ipv6_shim6_opt_fii, tvb, p, 4, FALSE);
935                 p += 4;
936                 break;
937             default:
938                 break;
939         }
940     }
941     return total_len;
942 }
943
944 static void
945 dissect_shim6_ct(proto_tree * shim_tree, gint hf_item, tvbuff_t * tvb, gint offset, const guchar * label)
946 {
947   guint8 tmp[6];
948   guchar * ct_str;
949
950   tmp[0] = tvb_get_guint8(tvb, offset++);
951   tmp[1] = tvb_get_guint8(tvb, offset++);
952   tmp[2] = tvb_get_guint8(tvb, offset++);
953   tmp[3] = tvb_get_guint8(tvb, offset++);
954   tmp[4] = tvb_get_guint8(tvb, offset++);
955   tmp[5] = tvb_get_guint8(tvb, offset++);
956
957   ct_str = ep_strdup_printf("%s: %02X %02X %02X %02X %02X %02X", label,
958                               tmp[0] & SHIM6_BITMASK_CT, tmp[1], tmp[2],
959                               tmp[3], tmp[4], tmp[5]
960                             );
961   proto_tree_add_none_format(shim_tree, hf_item, tvb, offset - 6, 6, "%s", ct_str);
962 }
963
964 static void
965 dissect_shim6_probes(proto_tree * shim_tree, tvbuff_t * tvb, gint offset,
966                      const guchar * label, guint nbr_probe,
967                      gboolean probes_rcvd)
968 {
969   proto_tree * probes_tree;
970   proto_tree * probe_tree;
971   proto_item * it;
972   gint ett_probes;
973   gint ett_probe;
974   guint count;
975
976   if (probes_rcvd) {
977     ett_probes = ett_ipv6_shim6_probes_rcvd;
978     ett_probe = ett_ipv6_shim6_probe_rcvd;
979   } else {
980     ett_probes = ett_ipv6_shim6_probes_sent;
981     ett_probe = ett_ipv6_shim6_probe_sent;
982   }
983   it = proto_tree_add_text(shim_tree, tvb, offset, 40 * nbr_probe, "%s", label);
984   probes_tree = proto_item_add_subtree(it, ett_probes);
985
986   for (count=0; count < nbr_probe; count++) {
987     it = proto_tree_add_text(probes_tree, tvb, offset, 40, "Probe %u", count+1);
988     probe_tree = proto_item_add_subtree(it, ett_probe);
989
990     proto_tree_add_item(probe_tree, hf_ipv6_shim6_psrc, tvb, offset, 16, FALSE);
991     offset += 16;
992     proto_tree_add_item(probe_tree, hf_ipv6_shim6_pdst, tvb, offset, 16, FALSE);
993     offset += 16;
994
995     proto_tree_add_item(probe_tree, hf_ipv6_shim6_pnonce, tvb, offset, 4, FALSE);
996     offset += 4;
997
998     proto_tree_add_item(probe_tree, hf_ipv6_shim6_pdata, tvb, offset, 4, FALSE);
999     offset += 4;
1000   }
1001 }
1002
1003 /* Dissect SHIM6 data: control messages */
1004 static int
1005 dissect_shimctrl(tvbuff_t *tvb, gint offset, guint type, proto_tree *shim_tree)
1006 {
1007   gint p;
1008   guint8 tmp;
1009   const gchar *sta;
1010   guint probes_sent;
1011   guint probes_rcvd;
1012
1013     p = offset;
1014
1015     switch (type)
1016     {
1017         case SHIM6_TYPE_I1:
1018             dissect_shim6_ct(shim_tree, hf_ipv6_shim6_ct, tvb, p, "Initiator Context Tag");
1019             p += 6;
1020             proto_tree_add_item(shim_tree, hf_ipv6_shim6_inonce, tvb, p, 4, FALSE);
1021             p += 4;
1022             break;
1023         case SHIM6_TYPE_R1:
1024             proto_tree_add_text(shim_tree, tvb, p, 2, "Reserved2");
1025             p += 2;
1026             proto_tree_add_item(shim_tree, hf_ipv6_shim6_inonce, tvb, p, 4, FALSE);
1027             p += 4;
1028             proto_tree_add_item(shim_tree, hf_ipv6_shim6_rnonce, tvb, p, 4, FALSE);
1029             p += 4;
1030             break;
1031         case SHIM6_TYPE_I2:
1032             dissect_shim6_ct(shim_tree, hf_ipv6_shim6_ct, tvb, p, "Initiator Context Tag");
1033             p += 6;
1034             proto_tree_add_item(shim_tree, hf_ipv6_shim6_inonce, tvb, p, 4, FALSE);
1035             p += 4;
1036             proto_tree_add_item(shim_tree, hf_ipv6_shim6_rnonce, tvb, p, 4, FALSE);
1037             p += 4;
1038             proto_tree_add_text(shim_tree, tvb, p, 4, "Reserved2");
1039             p += 4;
1040             break;
1041         case SHIM6_TYPE_R2:
1042             dissect_shim6_ct(shim_tree, hf_ipv6_shim6_ct, tvb, p, "Responder Context Tag");
1043             p += 6;
1044             proto_tree_add_item(shim_tree, hf_ipv6_shim6_inonce, tvb, p, 4, FALSE);
1045             p += 4;
1046             break;
1047         case SHIM6_TYPE_R1BIS:
1048             dissect_shim6_ct(shim_tree, hf_ipv6_shim6_ct, tvb, p, "Packet Context Tag");
1049             p += 6;
1050             proto_tree_add_item(shim_tree, hf_ipv6_shim6_rnonce, tvb, p, 4, FALSE);
1051             p += 4;
1052             break;
1053         case SHIM6_TYPE_I2BIS:
1054             dissect_shim6_ct(shim_tree, hf_ipv6_shim6_ct, tvb, p, "Initiator Context Tag");
1055             p += 6;
1056             proto_tree_add_item(shim_tree, hf_ipv6_shim6_inonce, tvb, p, 4, FALSE);
1057             p += 4;
1058             proto_tree_add_item(shim_tree, hf_ipv6_shim6_rnonce, tvb, p, 4, FALSE);
1059             p += 4;
1060             proto_tree_add_text(shim_tree, tvb, p, 6, "Reserved2");
1061             p += 6;
1062             dissect_shim6_ct(shim_tree, hf_ipv6_shim6_ct, tvb, p, "Initiator Context Tag");
1063             p += 6;
1064             break;
1065         case SHIM6_TYPE_UPD_REQ:
1066         case SHIM6_TYPE_UPD_ACK:
1067             dissect_shim6_ct(shim_tree, hf_ipv6_shim6_ct, tvb, p, "Receiver Context Tag");
1068             p += 6;
1069             proto_tree_add_item(shim_tree, hf_ipv6_shim6_rnonce, tvb, p, 4, FALSE);
1070             p += 4;
1071             break;
1072         case SHIM6_TYPE_KEEPALIVE:
1073             dissect_shim6_ct(shim_tree, hf_ipv6_shim6_ct, tvb, p, "Receiver Context Tag");
1074             p += 6;
1075             proto_tree_add_text(shim_tree, tvb, p, 4, "Reserved2");
1076             p += 4;
1077             break;
1078         case SHIM6_TYPE_PROBE:
1079             dissect_shim6_ct(shim_tree, hf_ipv6_shim6_ct, tvb, p, "Receiver Context Tag");
1080             p += 6;
1081
1082             tmp = tvb_get_guint8(tvb, p);
1083             probes_sent = tmp & SHIM6_BITMASK_PSENT;
1084             probes_rcvd = (tmp & SHIM6_BITMASK_PRECVD) >> 4;
1085
1086             proto_tree_add_uint_format(shim_tree, hf_ipv6_shim6_psent, tvb,
1087                                         p, 1, probes_sent,
1088                                         "Probes Sent: %u", probes_sent);
1089             proto_tree_add_uint_format(shim_tree, hf_ipv6_shim6_precvd, tvb,
1090                                         p, 1, probes_rcvd,
1091                                         "Probes Received: %u", probes_rcvd);
1092             p++;
1093
1094             sta = val_to_str((tvb_get_guint8(tvb, p) & SHIM6_BITMASK_STA) >> 6,
1095                                         shimreapstates, "Unknown REAP State");
1096             proto_tree_add_uint_format(shim_tree, hf_ipv6_shim6_reap, tvb,
1097                 p, 1, (tvb_get_guint8(tvb, p) & SHIM6_BITMASK_STA) >> 6,
1098                 "REAP State: %s", sta);
1099
1100             proto_tree_add_text(shim_tree, tvb, p, 3, "Reserved2");
1101             p += 3;
1102
1103             /* Probes Sent */
1104             if (probes_sent) {
1105               dissect_shim6_probes(shim_tree, tvb, p, "Probes Sent",
1106                                                           probes_sent, FALSE);
1107               p += 40 * probes_sent;
1108             }
1109
1110            /* Probes Received */
1111             if (probes_rcvd) {
1112               dissect_shim6_probes(shim_tree, tvb, p, "Probes Received",
1113                                                           probes_rcvd, TRUE);
1114               p += 40 * probes_rcvd;
1115             }
1116            break;
1117         default:
1118            break;
1119     }
1120     return p-offset;
1121 }
1122
1123 /* Dissect SHIM6 data: payload, common part, options */
1124 static const value_string shimctrlvals[] = {
1125     { SHIM6_TYPE_I1,        "I1" },
1126     { SHIM6_TYPE_R1,        "R1" },
1127     { SHIM6_TYPE_I2,        "I2" },
1128     { SHIM6_TYPE_R2,        "R2" },
1129     { SHIM6_TYPE_R1BIS,     "R1bis" },
1130     { SHIM6_TYPE_I2BIS,     "I2bis" },
1131     { SHIM6_TYPE_UPD_REQ,   "Update Request" },
1132     { SHIM6_TYPE_UPD_ACK,   "Update Acknowledgement" },
1133     { SHIM6_TYPE_KEEPALIVE, "Keepalive" },
1134     { SHIM6_TYPE_PROBE,     "Probe" },
1135     { 0, NULL }
1136 };
1137
1138 static void ipv6_shim6_checkum_additional_info(tvbuff_t * tvb, packet_info * pinfo,
1139     proto_item * it_cksum, int offset, gboolean is_cksum_correct)
1140 {
1141         proto_tree * checksum_tree;
1142         proto_item * item;
1143
1144         checksum_tree = proto_item_add_subtree(it_cksum, ett_ipv6_shim6_cksum);
1145         item = proto_tree_add_boolean(checksum_tree, hf_ipv6_shim6_checksum_good, tvb,
1146            offset, 2, is_cksum_correct);
1147         PROTO_ITEM_SET_GENERATED(item);
1148         item = proto_tree_add_boolean(checksum_tree, hf_ipv6_shim6_checksum_bad, tvb,
1149            offset, 2, !is_cksum_correct);
1150         PROTO_ITEM_SET_GENERATED(item);
1151         if (!is_cksum_correct) {
1152           expert_add_info_format(pinfo, item, PI_CHECKSUM, PI_ERROR, "Bad checksum");
1153           col_append_str(pinfo->cinfo, COL_INFO, " [Shim6 CHECKSUM INCORRECT]");
1154         }
1155 }
1156
1157 static int
1158 dissect_shim6(tvbuff_t *tvb, int offset, proto_tree *tree, packet_info * pinfo)
1159 {
1160     struct ip6_shim shim;
1161     int len;
1162     gint p;
1163     proto_tree *shim_tree;
1164     proto_item *ti;
1165     guint8 tmp[5];
1166
1167     tvb_memcpy(tvb, (guint8 *)&shim, offset, sizeof(shim));
1168     len = (shim.ip6s_len + 1) << 3;
1169
1170     if (tree)
1171     {
1172         ti = proto_tree_add_item(tree, hf_ipv6_shim6, tvb, offset, len, FALSE);
1173         shim_tree = proto_item_add_subtree(ti, ett_ipv6_shim6);
1174
1175         /* Next Header */
1176         proto_tree_add_uint_format(shim_tree, hf_ipv6_shim6_nxt, tvb,
1177             offset + offsetof(struct ip6_shim, ip6s_nxt), 1, shim.ip6s_nxt,
1178             "Next header: %s (0x%02x)", ipprotostr(shim.ip6s_nxt), shim.ip6s_nxt);
1179
1180         /* Header Extension Length */
1181         proto_tree_add_uint_format(shim_tree, hf_ipv6_shim6_len, tvb,
1182             offset + offsetof(struct ip6_shim, ip6s_len), 1, shim.ip6s_len,
1183             "Header Ext Length: %u (%d bytes)", shim.ip6s_len, len);
1184
1185         /* P Field */
1186         proto_tree_add_item(shim_tree, hf_ipv6_shim6_p, tvb,
1187                               offset + offsetof(struct ip6_shim, ip6s_p), 1, FALSE);
1188
1189         /* skip the first 2 bytes (nxt hdr, hdr ext len, p+7bits) */
1190         p = offset + 3;
1191
1192         if (shim.ip6s_p & SHIM6_BITMASK_P)
1193         {
1194             tmp[0] = tvb_get_guint8(tvb, p++);
1195             tmp[1] = tvb_get_guint8(tvb, p++);
1196             tmp[2] = tvb_get_guint8(tvb, p++);
1197             tmp[3] = tvb_get_guint8(tvb, p++);
1198             tmp[4] = tvb_get_guint8(tvb, p++);
1199
1200             /* Payload Extension Header */
1201             proto_tree_add_none_format(shim_tree, hf_ipv6_shim6_ct, tvb,
1202                 offset + offsetof(struct ip6_shim, ip6s_p), 6,
1203                 "Receiver Context Tag: %02x %02x %02x %02x %02x %02x",
1204                 shim.ip6s_p & SHIM6_BITMASK_CT, tmp[0], tmp[1], tmp[2], tmp[3], tmp[4]);
1205         }
1206         else
1207         {
1208             /* Control Message */
1209             guint16 csum;
1210             int advance;
1211
1212             /* Message Type */
1213             proto_tree_add_item(shim_tree, hf_ipv6_shim6_type, tvb,
1214                                 offset + offsetof(struct ip6_shim, ip6s_p), 1,
1215                                 FALSE
1216                                 );
1217
1218             /* Protocol bit (Must be zero for SHIM6) */
1219             proto_tree_add_item(shim_tree, hf_ipv6_shim6_proto, tvb, p, 1, FALSE);
1220             p++;
1221
1222             /* Checksum */
1223             csum = shim_checksum(tvb_get_ptr(tvb, offset, len), len);
1224
1225             if (csum == 0) {
1226                 ti = proto_tree_add_uint_format(shim_tree, hf_ipv6_shim6_checksum, tvb, p, 2,
1227                     tvb_get_ntohs(tvb, p), "Checksum: 0x%04x [correct]", tvb_get_ntohs(tvb, p));
1228                 ipv6_shim6_checkum_additional_info(tvb, pinfo, ti, p, TRUE);
1229             } else {
1230                 ti = proto_tree_add_uint_format(shim_tree, hf_ipv6_shim6_checksum, tvb, p, 2,
1231                     tvb_get_ntohs(tvb, p), "Checksum: 0x%04x [incorrect: should be 0x%04x]",
1232                     tvb_get_ntohs(tvb, p), in_cksum_shouldbe(tvb_get_ntohs(tvb, p), csum));
1233                 ipv6_shim6_checkum_additional_info(tvb, pinfo, ti, p, FALSE);
1234             }
1235             p += 2;
1236
1237             /* Type specific data */
1238             advance = dissect_shimctrl(tvb, p, shim.ip6s_p & SHIM6_BITMASK_TYPE, shim_tree);
1239             p += advance;
1240
1241             /* Options */
1242             while (p < offset+len) {
1243               p += dissect_shimopts(tvb, p, shim_tree, pinfo);
1244             }
1245         }
1246     }
1247     return len;
1248 }
1249
1250 /* END SHIM6 PART */
1251
1252 static void
1253 dissect_ipv6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1254 {
1255   proto_tree *ipv6_tree = NULL;
1256   proto_item *ti;
1257   guint8 nxt;
1258   guint8 stype=0;
1259   int advance;
1260   int poffset;
1261   guint16 plen;
1262   gboolean hopopts, routing, frag, ah, shim6, dstopts;
1263   guint16 offlg;
1264   guint32 ident;
1265   int offset;
1266   fragment_data *ipfd_head;
1267   tvbuff_t   *next_tvb;
1268   gboolean update_col_info = TRUE;
1269   gboolean save_fragmented = FALSE;
1270   const char *sep = "IPv6 ";
1271
1272   struct ip6_hdr ipv6;
1273
1274   col_set_str(pinfo->cinfo, COL_PROTOCOL, "IPv6");
1275   col_clear(pinfo->cinfo, COL_INFO);
1276
1277   offset = 0;
1278   tvb_memcpy(tvb, (guint8 *)&ipv6, offset, sizeof(ipv6));
1279
1280   /* Get extension header and payload length */
1281   plen = g_ntohs(ipv6.ip6_plen);
1282
1283   /* Adjust the length of this tvbuff to include only the IPv6 datagram. */
1284   set_actual_length(tvb, plen + sizeof (struct ip6_hdr));
1285
1286   SET_ADDRESS(&pinfo->net_src, AT_IPv6, 16, tvb_get_ptr(tvb, offset + IP6H_SRC, 16));
1287   SET_ADDRESS(&pinfo->src, AT_IPv6, 16, tvb_get_ptr(tvb, offset + IP6H_SRC, 16));
1288   SET_ADDRESS(&pinfo->net_dst, AT_IPv6, 16, tvb_get_ptr(tvb, offset + IP6H_DST, 16));
1289   SET_ADDRESS(&pinfo->dst, AT_IPv6, 16, tvb_get_ptr(tvb, offset + IP6H_DST, 16));
1290
1291   if (tree) {
1292     proto_tree* pt;
1293     proto_item* pi;
1294
1295     /* !!! specify length */
1296     ti = proto_tree_add_item(tree, proto_ipv6, tvb, offset, 40, FALSE);
1297     ipv6_tree = proto_item_add_subtree(ti, ett_ipv6);
1298
1299     /* !!! warning: version also contains 4 Bit priority */
1300     pi = proto_tree_add_item(ipv6_tree, hf_ipv6_version, tvb,
1301                         offset + offsetof(struct ip6_hdr, ip6_vfc), 1, FALSE);
1302         pt = proto_item_add_subtree(pi,ett_ipv6_version);
1303     pi = proto_tree_add_item(pt, hf_ip_version, tvb,
1304                                                 offset + offsetof(struct ip6_hdr, ip6_vfc), 1, FALSE);
1305         PROTO_ITEM_SET_GENERATED(pi);
1306
1307     proto_tree_add_item(ipv6_tree, hf_ipv6_class, tvb,
1308                         offset + offsetof(struct ip6_hdr, ip6_flow), 4, FALSE);
1309
1310     proto_tree_add_item(ipv6_tree, hf_ipv6_flow, tvb,
1311                         offset + offsetof(struct ip6_hdr, ip6_flow), 4, FALSE);
1312
1313     proto_tree_add_item(ipv6_tree, hf_ipv6_plen, tvb,
1314                         offset + offsetof(struct ip6_hdr, ip6_plen), 2, FALSE);
1315
1316     proto_tree_add_uint_format(ipv6_tree, hf_ipv6_nxt, tvb,
1317                 offset + offsetof(struct ip6_hdr, ip6_nxt), 1,
1318                 ipv6.ip6_nxt,
1319                 "Next header: %s (0x%02x)",
1320                 ipprotostr(ipv6.ip6_nxt), ipv6.ip6_nxt);
1321
1322     proto_tree_add_item(ipv6_tree, hf_ipv6_hlim, tvb,
1323                         offset + offsetof(struct ip6_hdr, ip6_hlim), 1, FALSE);
1324
1325     /* Adds the different items for the source address */
1326     proto_tree_add_item(ipv6_tree, hf_ipv6_src, tvb,
1327                         offset + offsetof(struct ip6_hdr, ip6_src), 16, FALSE);
1328     ti = proto_tree_add_ipv6(ipv6_tree, hf_ipv6_addr, tvb,
1329                               offset + offsetof(struct ip6_hdr, ip6_src),
1330                               16, (guint8 *)&ipv6.ip6_src);
1331     PROTO_ITEM_SET_HIDDEN(ti);
1332     ti = proto_tree_add_string(ipv6_tree, hf_ipv6_src_host, tvb,
1333                               offset + offsetof(struct ip6_hdr, ip6_src),
1334                               16, get_addr_name(&pinfo->src));
1335     PROTO_ITEM_SET_GENERATED(ti);
1336     PROTO_ITEM_SET_HIDDEN(ti);
1337     ti = proto_tree_add_string(ipv6_tree, hf_ipv6_host, tvb,
1338                               offset + offsetof(struct ip6_hdr, ip6_src),
1339                               16, get_addr_name(&pinfo->src));
1340     PROTO_ITEM_SET_GENERATED(ti);
1341     PROTO_ITEM_SET_HIDDEN(ti);
1342
1343     /* Adds different items for the destination address */
1344     proto_tree_add_item(ipv6_tree, hf_ipv6_dst, tvb,
1345                         offset + offsetof(struct ip6_hdr, ip6_dst), 16, FALSE);
1346     ti = proto_tree_add_ipv6(ipv6_tree, hf_ipv6_addr, tvb,
1347                               offset + offsetof(struct ip6_hdr, ip6_dst),
1348                               16, (guint8 *)&ipv6.ip6_dst);
1349     PROTO_ITEM_SET_HIDDEN(ti);
1350     ti = proto_tree_add_string(ipv6_tree, hf_ipv6_dst_host, tvb,
1351                               offset + offsetof(struct ip6_hdr, ip6_dst),
1352                               16, get_addr_name(&pinfo->dst));
1353     PROTO_ITEM_SET_GENERATED(ti);
1354     PROTO_ITEM_SET_HIDDEN(ti);
1355     ti = proto_tree_add_string(ipv6_tree, hf_ipv6_host, tvb,
1356                               offset + offsetof(struct ip6_hdr, ip6_dst),
1357                               16, get_addr_name(&pinfo->dst));
1358     PROTO_ITEM_SET_GENERATED(ti);
1359     PROTO_ITEM_SET_HIDDEN(ti);
1360   }
1361
1362   /* start of the new header (could be a extension header) */
1363   poffset = offset + offsetof(struct ip6_hdr, ip6_nxt);
1364   nxt = tvb_get_guint8(tvb, poffset);
1365   offset += sizeof(struct ip6_hdr);
1366   offlg = 0;
1367   ident = 0;
1368
1369 /* start out assuming this isn't fragmented, and has none of the other
1370    non-final headers */
1371   hopopts = FALSE;
1372   routing = FALSE;
1373   frag = FALSE;
1374   ah = FALSE;
1375   shim6 = FALSE;
1376   dstopts = FALSE;
1377
1378 again:
1379    switch (nxt) {
1380
1381    case IP_PROTO_HOPOPTS:
1382       hopopts = TRUE;
1383       advance = dissect_hopopts(tvb, offset, ipv6_tree, pinfo);
1384       nxt = tvb_get_guint8(tvb, offset);
1385       poffset = offset;
1386       offset += advance;
1387       plen -= advance;
1388       goto again;
1389
1390     case IP_PROTO_ROUTING:
1391       routing = TRUE;
1392       advance = dissect_routing6(tvb, offset, ipv6_tree, pinfo);
1393       nxt = tvb_get_guint8(tvb, offset);
1394       poffset = offset;
1395       offset += advance;
1396       plen -= advance;
1397       goto again;
1398
1399     case IP_PROTO_FRAGMENT:  
1400       advance = dissect_frag6(tvb, offset, pinfo, ipv6_tree,
1401           &offlg, &ident);
1402       nxt = tvb_get_guint8(tvb, offset);
1403       poffset = offset;
1404       offset += advance;
1405       plen -= advance;
1406       frag = offlg & (IP6F_OFF_MASK | IP6F_MORE_FRAG);
1407       save_fragmented |= frag;
1408       if (ipv6_reassemble && frag && tvb_bytes_exist(tvb, offset, plen)) {
1409         ipfd_head = fragment_add_check(tvb, offset, pinfo, ident,
1410         ipv6_fragment_table,
1411         ipv6_reassembled_table,
1412           offlg & IP6F_OFF_MASK,
1413           plen,
1414           offlg & IP6F_MORE_FRAG);
1415         next_tvb = process_reassembled_data(tvb, offset, pinfo, "Reassembled IPv6",
1416         ipfd_head, &ipv6_frag_items, &update_col_info, ipv6_tree);
1417         if (next_tvb) {  /* Process post-fragment headers after reassembly... */
1418           offset= 0;
1419           offlg = 0;
1420           frag = FALSE;
1421           tvb = next_tvb;
1422           goto again; 
1423         }
1424       }
1425       if (!(offlg & IP6F_OFF_MASK)) /*...or in the first fragment */
1426         goto again;
1427       break;
1428
1429     case IP_PROTO_AH:
1430       ah = TRUE;
1431       advance = dissect_ah_header(tvb_new_subset_remaining(tvb, offset),
1432                                   pinfo, ipv6_tree, NULL, NULL);
1433       nxt = tvb_get_guint8(tvb, offset);
1434       poffset = offset;
1435       offset += advance;
1436       plen -= advance;
1437       goto again;
1438
1439     case IP_PROTO_SHIM6:
1440     case IP_PROTO_SHIM6_OLD:
1441       shim6 = TRUE;
1442       advance = dissect_shim6(tvb, offset, ipv6_tree, pinfo);
1443       nxt = tvb_get_guint8(tvb, offset);
1444       stype = tvb_get_guint8(tvb, offset+2);
1445       poffset = offset;
1446       offset += advance;
1447       plen -= advance;
1448       goto again;
1449
1450     case IP_PROTO_DSTOPTS:
1451       dstopts = TRUE;
1452       advance = dissect_dstopts(tvb, offset, ipv6_tree, pinfo);
1453       nxt = tvb_get_guint8(tvb, offset);
1454       poffset = offset;
1455       offset += advance;
1456       plen -= advance;
1457       goto again;
1458
1459     case IP_PROTO_NONE:
1460       break;
1461
1462     default:
1463       /* Since we did not recognize this IPv6 option, check
1464        * whether it is a known protocol. If not, then it
1465        * is an unknown IPv6 option
1466        */
1467       if (!dissector_get_port_handle(ip_dissector_table, nxt)) {
1468         advance = dissect_unknown_option(tvb, offset, ipv6_tree); 
1469         nxt = tvb_get_guint8(tvb, offset);
1470         poffset = offset;
1471         offset += advance;
1472         plen -= advance;
1473         goto again;
1474       }
1475     }
1476
1477 #ifdef TEST_FINALHDR
1478   ti = proto_tree_add_uint(ipv6_tree, hf_ipv6_final, tvb, poffset, 1, nxt);
1479   PROTO_ITEM_SET_HIDDEN(ti);
1480 #endif
1481
1482   /* collect packet info */
1483   pinfo->ipproto = nxt;
1484   pinfo->iplen = sizeof(ipv6) + plen + offset;
1485   pinfo->iphdrlen = offset;
1486
1487   if (offlg & IP6F_OFF_MASK || (ipv6_reassemble && offlg & IP6F_MORE_FRAG)) {
1488     /* Not the first fragment, or the first when we are reassembling and there are more. */
1489     /* Don't dissect it; just show this as a fragment. */
1490     /* COL_INFO was filled in by "dissect_frag6()" */
1491     call_dissector(data_handle, tvb_new_subset_remaining(tvb, offset), pinfo, tree);
1492     return;
1493   } else {
1494     /* First fragment, not fragmented, or already reassembled.  Dissect what we have here. */
1495
1496     /* Get a tvbuff for the payload. */
1497     next_tvb = tvb_new_subset_remaining(tvb, offset);
1498
1499     /*
1500      * If this is the first fragment, but not the only fragment,
1501      * tell the next protocol that.
1502      */
1503     if (offlg & IP6F_MORE_FRAG)
1504       pinfo->fragmented = TRUE;
1505     else
1506       pinfo->fragmented = FALSE;
1507   }
1508
1509
1510   /* do lookup with the subdissector table */
1511   if (!dissector_try_port(ip_dissector_table, nxt, next_tvb, pinfo, tree)) {
1512     /* Unknown protocol.
1513        Handle "no next header" specially. */
1514     if (nxt == IP_PROTO_NONE) {
1515       if (check_col(pinfo->cinfo, COL_INFO)) {
1516         /* If we had an Authentication Header, the AH dissector already
1517            put something in the Info column; leave it there. */
1518         if (!ah) {
1519           if (hopopts || routing || dstopts || shim6) {
1520             if (hopopts) {
1521               col_append_fstr(pinfo->cinfo, COL_INFO, "%shop-by-hop options",
1522                              sep);
1523               sep = ", ";
1524             }
1525             if (routing) {
1526               col_append_fstr(pinfo->cinfo, COL_INFO, "%srouting", sep);
1527               sep = ", ";
1528             }
1529             if (dstopts) {
1530               col_append_fstr(pinfo->cinfo, COL_INFO, "%sdestination options",
1531                               sep);
1532             }
1533             if (shim6) {
1534               if (stype & SHIM6_BITMASK_P) {
1535                 col_append_str(pinfo->cinfo, COL_INFO, "Shim6 (Payload)");
1536               }
1537               else {
1538                 col_append_fstr(pinfo->cinfo, COL_INFO, "Shim6 (%s)",
1539                    val_to_str(stype & SHIM6_BITMASK_TYPE, shimctrlvals, "Unknown"));
1540               }
1541             }
1542           } else
1543             col_set_str(pinfo->cinfo, COL_INFO, "IPv6 no next header");
1544         }
1545       }
1546     } else {
1547       if (check_col(pinfo->cinfo, COL_INFO))
1548         col_add_fstr(pinfo->cinfo, COL_INFO, "%s (0x%02x)", ipprotostr(nxt),nxt);
1549     }
1550     call_dissector(data_handle, next_tvb, pinfo, tree);
1551   }
1552   pinfo->fragmented = save_fragmented;
1553 }
1554
1555 void
1556 proto_register_ipv6(void)
1557 {
1558   static hf_register_info hf[] = {
1559     { &hf_ipv6_version,
1560       { "Version",              "ipv6.version",
1561                                 FT_UINT8, BASE_DEC, NULL, 0xF0, NULL, HFILL }},
1562     { &hf_ip_version,
1563       { "This field makes the filter \"ip.version == 6\" possible",             "ip.version",
1564                                 FT_UINT8, BASE_DEC, NULL, 0xF0, NULL, HFILL }},
1565     { &hf_ipv6_class,
1566       { "Traffic class",        "ipv6.class",
1567                                 FT_UINT32, BASE_HEX, NULL, 0x0FF00000, NULL, HFILL }},
1568     { &hf_ipv6_flow,
1569       { "Flowlabel",            "ipv6.flow",
1570                                 FT_UINT32, BASE_HEX, NULL, 0x000FFFFF, NULL, HFILL }},
1571     { &hf_ipv6_plen,
1572       { "Payload length",       "ipv6.plen",
1573                                 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1574     { &hf_ipv6_nxt,
1575       { "Next header",          "ipv6.nxt",
1576                                 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1577     { &hf_ipv6_hlim,
1578       { "Hop limit",            "ipv6.hlim",
1579                                 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1580     { &hf_ipv6_src,
1581       { "Source",               "ipv6.src",
1582                                 FT_IPv6, BASE_NONE, NULL, 0x0,
1583                                 "Source IPv6 Address", HFILL }},
1584     { &hf_ipv6_src_host,
1585       { "Source Host",          "ipv6.src_host",
1586                                 FT_STRING, BASE_NONE, NULL, 0x0,
1587                                 "Source IPv6 Host", HFILL }},
1588     { &hf_ipv6_dst,
1589       { "Destination",          "ipv6.dst",
1590                                 FT_IPv6, BASE_NONE, NULL, 0x0,
1591                                 "Destination IPv6 Address", HFILL }},
1592     { &hf_ipv6_dst_host,
1593       { "Destination Host",     "ipv6.dst_host",
1594                                 FT_STRING, BASE_NONE, NULL, 0x0,
1595                                 "Destination IPv6 Host", HFILL }},
1596     { &hf_ipv6_addr,
1597       { "Address",              "ipv6.addr",
1598                                 FT_IPv6, BASE_NONE, NULL, 0x0,
1599                                 "Source or Destination IPv6 Address", HFILL }},
1600     { &hf_ipv6_host,
1601       { "Host",                 "ipv6.host",
1602                                 FT_STRING, BASE_NONE, NULL, 0x0,
1603                                 "IPv6 Host", HFILL }},
1604
1605     { &hf_ipv6_opt_pad1,
1606       { "Pad1",                 "ipv6.opt.pad1",
1607                                 FT_NONE, BASE_NONE, NULL, 0x0,
1608                                 "Pad1 Option", HFILL }},
1609     { &hf_ipv6_opt_padn,
1610       { "PadN",                 "ipv6.opt.padn",
1611                                 FT_UINT8, BASE_DEC, NULL, 0x0,
1612                                 "PadN Option", HFILL }},
1613     { &hf_ipv6_dst_opt,
1614       { "Destination Option",   "ipv6.dst_opt",
1615                                 FT_NONE, BASE_NONE, NULL, 0x0,
1616                                 NULL, HFILL }},
1617     { &hf_ipv6_hop_opt,
1618       { "Hop-by-Hop Option",    "ipv6.hop_opt",
1619                                 FT_NONE, BASE_NONE, NULL, 0x0,
1620                                 NULL, HFILL }},
1621     { &hf_ipv6_unk_hdr,
1622       { "Unknown Extension Header",     "ipv6.unknown_hdr",
1623                                 FT_NONE, BASE_NONE, NULL, 0x0,
1624                                 NULL, HFILL }},
1625     { &hf_ipv6_routing_hdr_opt,
1626       { "Routing Header, Type","ipv6.routing_hdr",
1627                                 FT_UINT8, BASE_DEC, NULL, 0x0,
1628                                 "Routing Header Option", HFILL }},
1629     { &hf_ipv6_routing_hdr_type,
1630       { "Type",                 "ipv6.routing_hdr.type",
1631                                 FT_UINT8, BASE_DEC, VALS(&routing_header_type), 0x0,
1632                                 "Routeing Header Type", HFILL }},
1633     { &hf_ipv6_routing_hdr_left,
1634       { "Left Segments",        "ipv6.routing_hdr.left",
1635                                 FT_UINT8, BASE_DEC, NULL, 0x0,
1636                                 "Routing Header Left Segments", HFILL }},
1637     { &hf_ipv6_routing_hdr_addr,
1638       { "Address",              "ipv6.routing_hdr.addr",
1639                                 FT_IPv6, BASE_NONE, NULL, 0x0,
1640                                 "Routing Header Address", HFILL }},
1641     { &hf_ipv6_frag_offset,
1642       { "Offset",               "ipv6.fragment.offset",
1643                                 FT_UINT16, BASE_DEC_HEX, NULL, IP6F_OFF_MASK,
1644                                 "Fragment Offset", HFILL }},
1645     { &hf_ipv6_frag_more,
1646       { "More Fragment",        "ipv6.fragment.more",
1647                                 FT_BOOLEAN, 16, TFS(&tfs_yes_no), IP6F_MORE_FRAG,
1648                                 "More Fragments", HFILL }},
1649     { &hf_ipv6_frag_id,
1650       { "Identification",       "ipv6.framgent.id",
1651                                 FT_UINT32, BASE_HEX, NULL, 0x0,
1652                                 "Fragment Identification", HFILL }},
1653     { &hf_ipv6_fragment_overlap,
1654       { "Fragment overlap",     "ipv6.fragment.overlap",
1655                                 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1656                                 "Fragment overlaps with other fragments", HFILL }},
1657
1658     { &hf_ipv6_fragment_overlap_conflict,
1659       { "Conflicting data in fragment overlap", "ipv6.fragment.overlap.conflict",
1660                                 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1661                                 "Overlapping fragments contained conflicting data", HFILL }},
1662
1663     { &hf_ipv6_fragment_multiple_tails,
1664       { "Multiple tail fragments found", "ipv6.fragment.multipletails",
1665                                 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1666                                 "Several tails were found when defragmenting the packet", HFILL }},
1667
1668     { &hf_ipv6_fragment_too_long_fragment,
1669       { "Fragment too long",    "ipv6.fragment.toolongfragment",
1670                                 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1671                                 "Fragment contained data past end of packet", HFILL }},
1672
1673     { &hf_ipv6_fragment_error,
1674       { "Defragmentation error", "ipv6.fragment.error",
1675                                 FT_FRAMENUM, BASE_NONE, NULL, 0x0,
1676                                 "Defragmentation error due to illegal fragments", HFILL }},
1677
1678     { &hf_ipv6_fragment,
1679       { "IPv6 Fragment",        "ipv6.fragment",
1680                                 FT_FRAMENUM, BASE_NONE, NULL, 0x0,
1681                                 NULL, HFILL }},
1682
1683     { &hf_ipv6_fragments,
1684       { "IPv6 Fragments",       "ipv6.fragments",
1685                                 FT_NONE, BASE_NONE, NULL, 0x0,
1686                                 NULL, HFILL }},
1687
1688     { &hf_ipv6_reassembled_in,
1689       { "Reassembled IPv6 in frame", "ipv6.reassembled_in",
1690                                 FT_FRAMENUM, BASE_NONE, NULL, 0x0,
1691                                 "This IPv6 packet is reassembled in this frame", HFILL }},
1692
1693     /* Mobile IPv6 */
1694     { &hf_ipv6_mipv6_type,
1695       { "Option Type",          "ipv6.mipv6_type",
1696                                 FT_UINT8, BASE_DEC, NULL, 0x0,
1697                                 NULL, HFILL }},
1698     { &hf_ipv6_mipv6_length,
1699       { "Option Length",        "ipv6.mipv6_length",
1700                                 FT_UINT8, BASE_DEC, NULL, 0x0,
1701                                 NULL, HFILL }},
1702     { &hf_ipv6_mipv6_home_address,
1703       { "Home Address", "ipv6.mipv6_home_address",
1704                                 FT_IPv6, BASE_NONE, NULL, 0x0,
1705                                 NULL, HFILL }},
1706
1707     /* SHIM6 */
1708     { &hf_ipv6_shim6,
1709       { "SHIM6",                "ipv6.shim6",
1710                                 FT_NONE, BASE_NONE, NULL, 0x0,
1711                                 NULL, HFILL }},
1712
1713     { &hf_ipv6_shim6_nxt,
1714       { "Next Header",          "ipv6.shim6.nxt",
1715                                 FT_UINT8, BASE_DEC, NULL, 0x0,
1716                                 NULL, HFILL }},
1717
1718     { &hf_ipv6_shim6_len,
1719       { "Header Ext Length",    "ipv6.shim6.len",
1720                                 FT_UINT8, BASE_DEC, NULL, 0x0,
1721                                 NULL, HFILL }},
1722
1723     { &hf_ipv6_shim6_p,
1724       { "P Bit",                "ipv6.shim6.p",
1725                                 FT_BOOLEAN, 8, NULL, SHIM6_BITMASK_P,
1726                                 NULL, HFILL }},
1727
1728     { &hf_ipv6_shim6_ct,
1729       { "Context Tag",          "ipv6.shim6.ct",
1730                                 FT_NONE, BASE_NONE, NULL, 0x0,
1731                                 NULL, HFILL }},
1732
1733     { &hf_ipv6_shim6_type,
1734       { "Message Type",         "ipv6.shim6.type",
1735                                 FT_UINT8, BASE_DEC,
1736                                 VALS(shimctrlvals), SHIM6_BITMASK_TYPE,
1737                                 NULL, HFILL }},
1738
1739     { &hf_ipv6_shim6_proto,
1740       { "Protocol",             "ipv6.shim6.proto",
1741                                 FT_UINT8, BASE_DEC,
1742                                 VALS(shim6_protocol), SHIM6_BITMASK_PROTOCOL,
1743                                 NULL, HFILL }},
1744
1745     { &hf_ipv6_shim6_checksum,
1746       { "Checksum",             "ipv6.shim6.checksum",
1747                                 FT_UINT16, BASE_HEX, NULL, 0x0,
1748                                 "Shim6 Checksum", HFILL }},
1749     { &hf_ipv6_shim6_checksum_bad,
1750       { "Bad Checksum",         "ipv6.shim6.checksum_bad",
1751                                 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1752                                 "Shim6 Bad Checksum", HFILL }},
1753
1754     { &hf_ipv6_shim6_checksum_good,
1755       { "Good Checksum",                "ipv6.shim6.checksum_good",
1756                                 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1757                                 NULL, HFILL }},
1758
1759     { &hf_ipv6_shim6_inonce,
1760       { "Initiator Nonce",      "ipv6.shim6.inonce",
1761                                 FT_UINT32, BASE_DEC_HEX, NULL, 0x0,
1762                                 NULL, HFILL }},
1763
1764     { &hf_ipv6_shim6_rnonce,
1765       { "Responder Nonce",      "ipv6.shim6.rnonce",
1766                                 FT_UINT32, BASE_DEC_HEX, NULL, 0x0,
1767                                 NULL, HFILL }},
1768
1769     { &hf_ipv6_shim6_precvd,
1770       { "Probes Received",      "ipv6.shim6.precvd",
1771                                 FT_UINT8, BASE_DEC, NULL, 0x0,
1772                                 NULL, HFILL }},
1773
1774     { &hf_ipv6_shim6_psent,
1775       { "Probes Sent",          "ipv6.shim6.psent",
1776                                 FT_UINT8, BASE_DEC, NULL, 0x0,
1777                                 NULL, HFILL }},
1778
1779     { &hf_ipv6_shim6_psrc,
1780       { "Source Address",       "ipv6.shim6.psrc",
1781                                 FT_IPv6, BASE_NONE, NULL, 0x0,
1782                                 "Shim6 Probe Source Address", HFILL }},
1783
1784     { &hf_ipv6_shim6_pdst,
1785       { "Destination Address",  "ipv6.shim6.pdst",
1786                                 FT_IPv6, BASE_NONE, NULL, 0x0,
1787                                 "Shim6 Probe Destination Address", HFILL }},
1788
1789     { &hf_ipv6_shim6_pnonce,
1790       { "Nonce",                "ipv6.shim6.pnonce",
1791                                 FT_UINT32, BASE_DEC_HEX, NULL, 0x0,
1792                                 "Shim6 Probe Nonce", HFILL }},
1793
1794     { &hf_ipv6_shim6_pdata,
1795       { "Data",                 "ipv6.shim6.pdata",
1796                                 FT_UINT32, BASE_HEX, NULL, 0x0,
1797                                 "Shim6 Probe Data", HFILL }},
1798
1799     { &hf_ipv6_shim6_sulid,
1800       { "Sender ULID",          "ipv6.shim6.sulid",
1801                                 FT_IPv6, BASE_NONE, NULL, 0x0,
1802                                 "Shim6 Sender ULID", HFILL }},
1803
1804     { &hf_ipv6_shim6_rulid,
1805       { "Receiver ULID",        "ipv6.shim6.rulid",
1806                                 FT_IPv6, BASE_NONE, NULL, 0x0,
1807                                 "Shim6 Receiver ULID", HFILL }},
1808
1809     { &hf_ipv6_shim6_reap,
1810       { "REAP State",           "ipv6.shim6.reap",
1811                                 FT_UINT8, BASE_DEC, NULL, 0x0,
1812                                 NULL, HFILL }},
1813
1814     { &hf_ipv6_shim6_opt_type,
1815       { "Option Type",          "ipv6.shim6.opt.type",
1816                                 FT_UINT16, BASE_DEC,
1817                                 VALS(shimoptvals), SHIM6_BITMASK_OPT_TYPE,
1818                                 "Shim6 Option Type", HFILL }},
1819
1820     { &hf_ipv6_shim6_opt_critical,
1821       { "Option Critical Bit",  "ipv6.shim6.opt.critical",
1822                                 FT_BOOLEAN, 8,
1823                                 TFS(&tfs_yes_no),
1824                                 SHIM6_BITMASK_CRITICAL,
1825                                 "TRUE : option is critical, FALSE: option is not critical",
1826                                 HFILL }},
1827
1828     { &hf_ipv6_shim6_opt_len,
1829       { "Content Length",       "ipv6.shim6.opt.len",
1830                                 FT_UINT16, BASE_DEC, NULL, 0x0,
1831                                 "Content Length Option", HFILL }},
1832
1833     { &hf_ipv6_shim6_opt_total_len,
1834       { "Total Length",         "ipv6.shim6.opt.total_len",
1835                                 FT_UINT16, BASE_DEC, NULL, 0x0,
1836                                 "Total Option Length", HFILL }},
1837
1838     { &hf_ipv6_shim6_opt_loc_verif_methods,
1839       { "Verification Method",  "ipv6.shim6.opt.verif_method",
1840                                 FT_UINT8, BASE_DEC,
1841                                 VALS(shimverifmethods), 0x0,
1842                                 "Locator Verification Method", HFILL }},
1843
1844     { &hf_ipv6_shim6_opt_loclist,
1845       { "Locator List Generation", "ipv6.shim6.opt.loclist",
1846                                 FT_UINT32, BASE_DEC_HEX, NULL, 0x0,
1847                                 NULL, HFILL }},
1848
1849     { &hf_ipv6_shim6_locator,
1850       { "Locator",              "ipv6.shim6.locator",
1851                                 FT_IPv6, BASE_NONE, NULL, 0x0,
1852                                 "Shim6 Locator", HFILL }},
1853
1854     { &hf_ipv6_shim6_opt_locnum,
1855       { "Num Locators",         "ipv6.shim6.opt.locnum",
1856                                 FT_UINT8, BASE_DEC, NULL, 0x0,
1857                                 "Number of Locators in Locator List", HFILL }},
1858
1859     { &hf_ipv6_shim6_opt_elemlen,
1860       { "Element Length",       "ipv6.shim6.opt.elemlen",
1861                                 FT_UINT8, BASE_DEC, NULL, 0x0,
1862                                 "Length of Elements in Locator Preferences Option", HFILL }},
1863     { &hf_ipv6_shim6_loc_flag,
1864       { "Flags",                "ipv6.shim6.loc.flags",
1865                                 FT_UINT8, BASE_DEC, NULL, 0x0,
1866                                 "Locator Preferences Flags", HFILL }},
1867
1868     { &hf_ipv6_shim6_loc_prio,
1869       { "Priority",             "ipv6.shim6.loc.prio",
1870                                 FT_UINT8, BASE_DEC, NULL, 0x0,
1871                                 "Locator Preferences Priority", HFILL }},
1872
1873     { &hf_ipv6_shim6_loc_weight,
1874       { "Weight",               "ipv6.shim6.loc.weight",
1875                                 FT_UINT8, BASE_DEC, NULL, 0x0,
1876                                 "Locator Preferences Weight", HFILL }},
1877
1878     { &hf_ipv6_shim6_opt_fii,
1879       { "Forked Instance Identifier", "ipv6.shim6.opt.fii",
1880                                 FT_UINT32, BASE_DEC_HEX, NULL, 0x0,
1881                                 NULL, HFILL }},
1882
1883 #ifdef TEST_FINALHDR
1884     { &hf_ipv6_final,
1885       { "Final next header",    "ipv6.final",
1886                                 FT_UINT8, BASE_HEX, NULL, 0x0, "", HFILL }},
1887 #endif
1888   };
1889   static gint *ett[] = {
1890     &ett_ipv6,
1891     &ett_ipv6_version,
1892     &ett_ipv6_shim6,
1893     &ett_ipv6_shim6_option,
1894     &ett_ipv6_shim6_locators,
1895     &ett_ipv6_shim6_verif_methods,
1896     &ett_ipv6_shim6_loc_pref,
1897     &ett_ipv6_shim6_probes_sent,
1898     &ett_ipv6_shim6_probes_rcvd,
1899     &ett_ipv6_shim6_probe_sent,
1900     &ett_ipv6_shim6_probe_rcvd,
1901     &ett_ipv6_shim6_cksum,
1902     &ett_ipv6_fragments,
1903     &ett_ipv6_fragment
1904   };
1905   module_t *ipv6_module;
1906
1907   proto_ipv6 = proto_register_protocol("Internet Protocol Version 6", "IPv6", "ipv6");
1908   proto_register_field_array(proto_ipv6, hf, array_length(hf));
1909   proto_register_subtree_array(ett, array_length(ett));
1910
1911   /* Register configuration options */
1912   ipv6_module = prefs_register_protocol(proto_ipv6, NULL);
1913   prefs_register_bool_preference(ipv6_module, "defragment",
1914         "Reassemble fragmented IPv6 datagrams",
1915         "Whether fragmented IPv6 datagrams should be reassembled",
1916         &ipv6_reassemble);
1917
1918   register_dissector("ipv6", dissect_ipv6, proto_ipv6);
1919   register_init_routine(ipv6_reassemble_init);
1920 }
1921
1922 void
1923 proto_reg_handoff_ipv6(void)
1924 {
1925   dissector_handle_t ipv6_handle;
1926
1927   data_handle = find_dissector("data");
1928   ipv6_handle = find_dissector("ipv6");
1929   dissector_add("ethertype", ETHERTYPE_IPv6, ipv6_handle);
1930   dissector_add("ppp.protocol", PPP_IPV6, ipv6_handle);
1931   dissector_add("ppp.protocol", ETHERTYPE_IPv6, ipv6_handle);
1932   dissector_add("gre.proto", ETHERTYPE_IPv6, ipv6_handle);
1933   dissector_add("ip.proto", IP_PROTO_IPV6, ipv6_handle);
1934   dissector_add("null.type", BSD_AF_INET6_BSD, ipv6_handle);
1935   dissector_add("null.type", BSD_AF_INET6_FREEBSD, ipv6_handle);
1936   dissector_add("null.type", BSD_AF_INET6_DARWIN, ipv6_handle);
1937   dissector_add("chdlctype", ETHERTYPE_IPv6, ipv6_handle);
1938   dissector_add("fr.ietf", NLPID_IP6, ipv6_handle);
1939   dissector_add("osinl.excl", NLPID_IP6, ipv6_handle);
1940   dissector_add("x.25.spi", NLPID_IP6, ipv6_handle);
1941   dissector_add("arcnet.protocol_id", ARCNET_PROTO_IPv6, ipv6_handle);
1942
1943   ip_dissector_table = find_dissector_table("ip.proto");
1944 }