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