Fix a number of proto_tree_add_item() encoding args.
[obnox/wireshark/wip.git] / epan / dissectors / packet-ipv6.c
index 697ee0f5f03367af11e77b23556e7b4efbf3cf3b..d59720f20a73c9dff62a162d82f09db23268c89c 100644 (file)
@@ -33,8 +33,6 @@
 #include <math.h>
 #include <glib.h>
 #include <epan/packet.h>
-#include "packet-ipsec.h"
-#include "packet-ipv6.h"
 #include <epan/ip_opts.h>
 #include <epan/addr_resolv.h>
 #include <epan/prefs.h>
 #include <epan/nlpid.h>
 #include <epan/arcnet_pids.h>
 #include <epan/in_cksum.h>
-#include <epan/value_string.h>
 #include <epan/expert.h>
 #include <epan/emem.h>
 #include <epan/tap.h>
+#include "packet-ipsec.h"
+#include "packet-ipv6.h"
+
+#ifdef HAVE_GEOIP_V6
+#include "GeoIP.h"
+#include <epan/geoip_db.h>
+#endif /* HAVE_GEOIP_V6 */
 
 /*
  * NOTE: ipv6.nxt is not very useful as we will have chained header.
@@ -208,6 +212,30 @@ static int hf_ipv6_traffic_class_dscp = -1;
 static int hf_ipv6_traffic_class_ect  = -1;
 static int hf_ipv6_traffic_class_ce   = -1;
 
+#ifdef HAVE_GEOIP_V6
+static int hf_geoip_country = -1;
+static int hf_geoip_city = -1;
+static int hf_geoip_org = -1;
+static int hf_geoip_isp = -1;
+static int hf_geoip_asnum = -1;
+static int hf_geoip_lat = -1;
+static int hf_geoip_lon = -1;
+static int hf_geoip_src_country = -1;
+static int hf_geoip_src_city = -1;
+static int hf_geoip_src_org = -1;
+static int hf_geoip_src_isp = -1;
+static int hf_geoip_src_asnum = -1;
+static int hf_geoip_src_lat = -1;
+static int hf_geoip_src_lon = -1;
+static int hf_geoip_dst_country = -1;
+static int hf_geoip_dst_city = -1;
+static int hf_geoip_dst_org = -1;
+static int hf_geoip_dst_isp = -1;
+static int hf_geoip_dst_asnum = -1;
+static int hf_geoip_dst_lat = -1;
+static int hf_geoip_dst_lon = -1;
+#endif /* HAVE_GEOIP_V6 */
+
 static gint ett_ipv6                     = -1;
 static gint ett_ipv6_version   = -1;
 static gint ett_ipv6_shim6               = -1;
@@ -224,6 +252,11 @@ static gint ett_ipv6_fragments               = -1;
 static gint ett_ipv6_fragment            = -1;
 static gint ett_ipv6_traffic_class        = -1;
 
+#ifdef HAVE_GEOIP_V6
+static gint ett_geoip_info = -1;
+#endif /* HAVE_GEOIP_V6 */
+
+
 static const fragment_items ipv6_frag_items = {
        &ett_ipv6_fragment,
        &ett_ipv6_fragments,
@@ -250,6 +283,11 @@ static gboolean ipv6_reassemble = TRUE;
 /* Place IPv6 summary in proto tree */
 static gboolean ipv6_summary_in_tree = TRUE;
 
+#ifdef HAVE_GEOIP_V6
+/* Look up addresses in GeoIP */
+static gboolean ipv6_use_geoip = TRUE;
+#endif /* HAVE_GEOIP_V6 */
+
 #ifndef offsetof
 #define        offsetof(type, member)  ((size_t)(&((type *)0)->member))
 #endif
@@ -361,6 +399,153 @@ again:
   }
 }
 
+#ifdef HAVE_GEOIP_V6
+static void
+add_geoip_info(proto_tree *tree, tvbuff_t *tvb, gint offset, struct e_in6_addr src, struct e_in6_addr dst)
+{
+  guint dbnum, num_dbs;
+  int geoip_hf, geoip_src_hf, geoip_dst_hf;
+  const char *geoip_src_str, *geoip_dst_str;
+  proto_item *geoip_info_item;
+  proto_tree *geoip_info_tree;
+  proto_item *item;
+  guint item_cnt;
+
+  num_dbs = geoip_db_num_dbs();
+  if (num_dbs < 1) return;
+
+  geoip_info_item = proto_tree_add_text(tree, tvb, offset + IP6H_SRC, 16, "Source GeoIP: ");
+  geoip_info_tree = proto_item_add_subtree(geoip_info_item, ett_geoip_info);
+  PROTO_ITEM_SET_GENERATED(geoip_info_item);
+  item_cnt = 0;
+
+  for (dbnum = 0; dbnum < num_dbs; dbnum++) {
+    geoip_src_str = geoip_db_lookup_ipv6(dbnum, src, NULL);
+
+    switch (geoip_db_type(dbnum)) {
+      case GEOIP_COUNTRY_EDITION_V6:
+        geoip_hf = hf_geoip_country;
+        geoip_src_hf = hf_geoip_src_country;
+        break;
+#if NUM_DB_TYPES > 31
+      case GEOIP_CITY_EDITION_REV0_V6:
+        geoip_hf = hf_geoip_city;
+        geoip_src_hf = hf_geoip_src_city;
+        break;
+      case GEOIP_CITY_EDITION_REV1_V6:
+        geoip_hf = hf_geoip_city;
+        geoip_src_hf = hf_geoip_src_city;
+        break;
+      case GEOIP_ORG_EDITION_V6:
+        geoip_hf = hf_geoip_org;
+        geoip_src_hf = hf_geoip_src_org;
+        break;
+      case GEOIP_ISP_EDITION_V6:
+        geoip_hf = hf_geoip_isp;
+        geoip_src_hf = hf_geoip_src_isp;
+        break;
+      case GEOIP_ASNUM_EDITION_V6:
+        geoip_hf = hf_geoip_asnum;
+        geoip_src_hf = hf_geoip_src_asnum;
+        break;
+#endif /* DB_NUM_TYPES */
+      case WS_LAT_FAKE_EDITION:
+        geoip_hf = hf_geoip_lat;
+        geoip_src_hf = hf_geoip_src_lat;
+        break;
+      case WS_LON_FAKE_EDITION:
+        geoip_hf = hf_geoip_lon;
+        geoip_src_hf = hf_geoip_src_lon;
+        break;
+      default:
+        continue;
+        break;
+    }
+
+    if (geoip_src_str) {
+      item = proto_tree_add_string_format_value(geoip_info_tree, geoip_src_hf, tvb,
+        offset + IP6H_SRC, 16, geoip_src_str, "%s", geoip_src_str);
+      PROTO_ITEM_SET_GENERATED(item);
+      item  = proto_tree_add_string_format_value(geoip_info_tree, geoip_hf, tvb,
+        offset + IP6H_SRC, 16, geoip_src_str, "%s", geoip_src_str);
+      PROTO_ITEM_SET_GENERATED(item);
+      PROTO_ITEM_SET_HIDDEN(item);
+
+      item_cnt++;
+      proto_item_append_text(geoip_info_item, "%s%s", plurality(item_cnt, "", ", "), geoip_src_str);
+    }
+  }
+
+  if (item_cnt == 0)
+    proto_item_append_text(geoip_info_item, "Unknown");
+
+  geoip_info_item = proto_tree_add_text(tree, tvb, offset + IP6H_DST, 16, "Destination GeoIP: ");
+  geoip_info_tree = proto_item_add_subtree(geoip_info_item, ett_geoip_info);
+  PROTO_ITEM_SET_GENERATED(geoip_info_item);
+  item_cnt = 0;
+
+  for (dbnum = 0; dbnum < num_dbs; dbnum++) {
+    geoip_dst_str = geoip_db_lookup_ipv6(dbnum, dst, NULL);
+
+    switch (geoip_db_type(dbnum)) {
+      case GEOIP_COUNTRY_EDITION_V6:
+        geoip_hf = hf_geoip_country;
+        geoip_dst_hf = hf_geoip_dst_country;
+        break;
+#if NUM_DB_TYPES > 31
+      case GEOIP_CITY_EDITION_REV0_V6:
+        geoip_hf = hf_geoip_city;
+        geoip_dst_hf = hf_geoip_dst_city;
+        break;
+      case GEOIP_CITY_EDITION_REV1_V6:
+        geoip_hf = hf_geoip_city;
+        geoip_dst_hf = hf_geoip_dst_city;
+        break;
+      case GEOIP_ORG_EDITION_V6:
+        geoip_hf = hf_geoip_org;
+        geoip_dst_hf = hf_geoip_dst_org;
+        break;
+      case GEOIP_ISP_EDITION_V6:
+        geoip_hf = hf_geoip_isp;
+        geoip_dst_hf = hf_geoip_dst_isp;
+        break;
+      case GEOIP_ASNUM_EDITION_V6:
+        geoip_hf = hf_geoip_asnum;
+        geoip_dst_hf = hf_geoip_dst_asnum;
+        break;
+#endif /* DB_NUM_TYPES */
+      case WS_LAT_FAKE_EDITION:
+        geoip_hf = hf_geoip_lat;
+        geoip_dst_hf = hf_geoip_dst_lat;
+        break;
+      case WS_LON_FAKE_EDITION:
+        geoip_hf = hf_geoip_lon;
+        geoip_dst_hf = hf_geoip_dst_lon;
+        break;
+      default:
+        continue;
+        break;
+    }
+
+    if (geoip_dst_str) {
+      item = proto_tree_add_string_format_value(geoip_info_tree, geoip_dst_hf, tvb,
+        offset + IP6H_DST, 16, geoip_dst_str, "%s", geoip_dst_str);
+      PROTO_ITEM_SET_GENERATED(item);
+      item  = proto_tree_add_string_format_value(geoip_info_tree, geoip_hf, tvb,
+        offset + IP6H_DST, 16, geoip_dst_str, "%s", geoip_dst_str);
+      PROTO_ITEM_SET_GENERATED(item);
+      PROTO_ITEM_SET_HIDDEN(item);
+
+      item_cnt++;
+      proto_item_append_text(geoip_info_item, "%s%s", plurality(item_cnt, "", ", "), geoip_dst_str);
+    }
+  }
+
+  if (item_cnt == 0)
+    proto_item_append_text(geoip_info_item, "Unknown");
+}
+#endif /* HAVE_GEOIP_V6 */
+
 static void
 ipv6_reassemble_init(void)
 {
@@ -372,7 +557,7 @@ enum {
   IPv6_RT_HEADER_SOURCE_ROUTING=0,
   IPv6_RT_HEADER_NIMROD,
   IPv6_RT_HEADER_MobileIP,
-  IPv6_RT_HEADER_RPL=4,
+  IPv6_RT_HEADER_RPL=4
 };
 
 /* Routeing Header Types */
@@ -413,10 +598,10 @@ dissect_routing6(tvbuff_t *tvb, int offset, proto_tree *tree, packet_info *pinfo
            "Length: %u (%d bytes)", rt.ip6r_len, len);
 
        proto_tree_add_item(rthdr_tree, hf_ipv6_routing_hdr_type, tvb,
-                 offset + offsetof(struct ip6_rthdr, ip6r_type), 1, FALSE);
+                 offset + offsetof(struct ip6_rthdr, ip6r_type), 1, ENC_BIG_ENDIAN);
 
        proto_tree_add_item(rthdr_tree, hf_ipv6_routing_hdr_left, tvb,
-                 offset + offsetof(struct ip6_rthdr, ip6r_segleft), 1, FALSE);
+                 offset + offsetof(struct ip6_rthdr, ip6r_segleft), 1, ENC_BIG_ENDIAN);
 
        seg_left = tvb_get_guint8(tvb, offset + offsetof(struct ip6_rthdr, ip6r_segleft));
 
@@ -434,7 +619,7 @@ dissect_routing6(tvbuff_t *tvb, int offset, proto_tree *tree, packet_info *pinfo
              proto_tree_add_item(rthdr_tree, hf_ipv6_routing_hdr_addr, tvb,
                              offset + offsetof(struct ip6_rthdr0, ip6r0_addr)
                                     + n * sizeof(struct e_in6_addr),
-                             sizeof(struct e_in6_addr), FALSE);
+                             sizeof(struct e_in6_addr), ENC_NA);
              if (seg_left)
                  SET_ADDRESS(&pinfo->dst, AT_IPv6, 16, tvb_get_ptr(tvb,
                              offset + offsetof(struct ip6_rthdr0, ip6r0_addr)
@@ -443,7 +628,7 @@ dissect_routing6(tvbuff_t *tvb, int offset, proto_tree *tree, packet_info *pinfo
        }
        if (rt.ip6r_type == IPv6_RT_HEADER_MobileIP) {
          proto_tree_add_item(rthdr_tree, hf_ipv6_mipv6_home_address, tvb,
-                             offset + 8, 16, FALSE);
+                             offset + 8, 16, ENC_NA);
          SET_ADDRESS(&pinfo->dst, AT_IPv6, 16, tvb_get_ptr(tvb, offset + 8, 16));
        }
     if (rt.ip6r_type == IPv6_RT_HEADER_RPL) {
@@ -457,10 +642,10 @@ dissect_routing6(tvbuff_t *tvb, int offset, proto_tree *tree, packet_info *pinfo
         offset += 4;
         memcpy((guint8 *)&dstAddr, (guint8 *)pinfo->dst.data, pinfo->dst.len);
 
-        proto_tree_add_item(rthdr_tree, hf_ipv6_routing_hdr_rpl_cmprI, tvb, offset, 4, FALSE);
-        proto_tree_add_item(rthdr_tree, hf_ipv6_routing_hdr_rpl_cmprE, tvb, offset, 4, FALSE);
-        proto_tree_add_item(rthdr_tree, hf_ipv6_routing_hdr_rpl_pad, tvb, offset, 4, FALSE);
-        proto_tree_add_item(rthdr_tree, hf_ipv6_routing_hdr_rpl_reserved, tvb, offset, 4, FALSE);
+        proto_tree_add_item(rthdr_tree, hf_ipv6_routing_hdr_rpl_cmprI, tvb, offset, 4, ENC_BIG_ENDIAN);
+        proto_tree_add_item(rthdr_tree, hf_ipv6_routing_hdr_rpl_cmprE, tvb, offset, 4, ENC_BIG_ENDIAN);
+        proto_tree_add_item(rthdr_tree, hf_ipv6_routing_hdr_rpl_pad, tvb, offset, 4, ENC_BIG_ENDIAN);
+        proto_tree_add_item(rthdr_tree, hf_ipv6_routing_hdr_rpl_reserved, tvb, offset, 4, ENC_BIG_ENDIAN);
 
         cmprI = tvb_get_guint8(tvb, offset) & 0xF0;
         cmprE = tvb_get_guint8(tvb, offset) & 0x0F;
@@ -470,9 +655,9 @@ dissect_routing6(tvbuff_t *tvb, int offset, proto_tree *tree, packet_info *pinfo
         cmprI >>= 4;
         pad >>= 4;
 
-        /* from draft-ietf-6man-rpl-routing-header-03: 
+        /* from draft-ietf-6man-rpl-routing-header-03:
         n = (((Hdr Ext Len * 8) - Pad - (16 - CmprE)) / (16 - CmprI)) + 1 */
-        segments = (((rt.ip6r_len * 8) - pad - (16 - cmprE)) / (16 - cmprI)) + 1;      
+        segments = (((rt.ip6r_len * 8) - pad - (16 - cmprE)) / (16 - cmprI)) + 1;
         ti = proto_tree_add_int(rthdr_tree, hf_ipv6_routing_hdr_rpl_segments, tvb, offset, 2, segments);
         PROTO_ITEM_SET_GENERATED(ti);
 
@@ -486,7 +671,7 @@ dissect_routing6(tvbuff_t *tvb, int offset, proto_tree *tree, packet_info *pinfo
             while(segments > 1) {
                 struct e_in6_addr addr;
 
-                proto_tree_add_item(rthdr_tree, hf_ipv6_routing_hdr_rpl_addr, tvb, offset, (16-cmprI), FALSE);
+                proto_tree_add_item(rthdr_tree, hf_ipv6_routing_hdr_rpl_addr, tvb, offset, (16-cmprI), ENC_NA);
                 /* Display Full Address */
                 memcpy((guint8 *)&addr, (guint8 *)&dstAddr, sizeof(dstAddr));
                 tvb_memcpy(tvb, (guint8 *)&addr + cmprI, offset, (16-cmprI));
@@ -495,22 +680,22 @@ dissect_routing6(tvbuff_t *tvb, int offset, proto_tree *tree, packet_info *pinfo
                 offset += (16-cmprI);
                 segments--;
             }
-     
+
             /* We use cmprE for last address for how many bytes to elide, so actual bytes present = 16-CmprE */
             if (segments == 1) {
                 struct e_in6_addr addr;
 
-                proto_tree_add_item(rthdr_tree, hf_ipv6_routing_hdr_rpl_addr, tvb, offset, (16-cmprI), FALSE);
+                proto_tree_add_item(rthdr_tree, hf_ipv6_routing_hdr_rpl_addr, tvb, offset, (16-cmprI), ENC_NA);
                 /* Display Full Address */
                 memcpy((guint8 *)&addr, (guint8 *)&dstAddr, sizeof(dstAddr));
                 tvb_memcpy(tvb, (guint8 *)&addr + cmprE, offset, (16-cmprE));
                 ti = proto_tree_add_ipv6(rthdr_tree, hf_ipv6_routing_hdr_rpl_fulladdr, tvb, offset, (16-cmprE), (guint8 *)&addr);
                 PROTO_ITEM_SET_GENERATED(ti);
                 offset += (16-cmprE);
-            }  
-          
-        }   
-   
+            }
+
+        }
+
     }
     }
 
@@ -555,13 +740,13 @@ dissect_frag6(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree,
 #endif
 
           proto_tree_add_item(rthdr_tree, hf_ipv6_frag_offset, tvb,
-                   offset + offsetof(struct ip6_frag, ip6f_offlg), 2, FALSE);
+                   offset + offsetof(struct ip6_frag, ip6f_offlg), 2, ENC_BIG_ENDIAN);
 
           proto_tree_add_item(rthdr_tree, hf_ipv6_frag_more, tvb,
-                   offset + offsetof(struct ip6_frag, ip6f_offlg), 2, FALSE);
+                   offset + offsetof(struct ip6_frag, ip6f_offlg), 2, ENC_BIG_ENDIAN);
 
           proto_tree_add_item(rthdr_tree, hf_ipv6_frag_id, tvb,
-                   offset + offsetof(struct ip6_frag, ip6f_ident), 4, FALSE);
+                   offset + offsetof(struct ip6_frag, ip6f_ident), 4, ENC_BIG_ENDIAN);
     }
     return len;
 }
@@ -706,7 +891,7 @@ dissect_unknown_option(tvbuff_t *tvb, int offset, proto_tree *tree)
 
     if (tree) {
        /* !!! specify length */
-       ti = proto_tree_add_item(tree, hf_ipv6_unk_hdr, tvb, offset, len, FALSE);
+       ti = proto_tree_add_item(tree, hf_ipv6_unk_hdr, tvb, offset, len, ENC_NA);
 
        unkopt_tree = proto_item_add_subtree(ti, ett_ipv6);
 
@@ -737,7 +922,7 @@ dissect_opts(tvbuff_t *tvb, int offset, proto_tree *tree, packet_info * pinfo, c
 
     if (tree) {
        /* !!! specify length */
-       ti = proto_tree_add_item(tree, hf_option_item, tvb, offset, len, FALSE);
+       ti = proto_tree_add_item(tree, hf_option_item, tvb, offset, len, ENC_NA);
 
        dstopt_tree = proto_item_add_subtree(ti, ett_ipv6);
 
@@ -757,7 +942,7 @@ dissect_opts(tvbuff_t *tvb, int offset, proto_tree *tree, packet_info * pinfo, c
        while (p < offset + len) {
            switch (tvb_get_guint8(tvb, p)) {
            case IP6OPT_PAD1:
-               proto_tree_add_item(dstopt_tree, hf_ipv6_opt_pad1, tvb, p, 1, FALSE);
+               proto_tree_add_item(dstopt_tree, hf_ipv6_opt_pad1, tvb, p, 1, ENC_NA);
                p++;
                mip_offset++;
                break;
@@ -937,11 +1122,11 @@ dissect_shim6_opt_loclist(proto_tree * opt_tree, tvbuff_t * tvb, gint *offset)
   guint optlen;
   int p = *offset;
 
-  proto_tree_add_item(opt_tree, hf_ipv6_shim6_opt_loclist, tvb, p, 4, FALSE);
+  proto_tree_add_item(opt_tree, hf_ipv6_shim6_opt_loclist, tvb, p, 4, ENC_BIG_ENDIAN);
   p += 4;
 
   optlen = tvb_get_guint8(tvb, p);
-  proto_tree_add_item(opt_tree, hf_ipv6_shim6_opt_locnum, tvb, p, 1, FALSE);
+  proto_tree_add_item(opt_tree, hf_ipv6_shim6_opt_locnum, tvb, p, 1, ENC_BIG_ENDIAN);
   p++;
 
   /* Verification Methods */
@@ -951,7 +1136,7 @@ dissect_shim6_opt_loclist(proto_tree * opt_tree, tvbuff_t * tvb, gint *offset)
 
   for (count=0; count < optlen; count++)
     proto_tree_add_item(subtree, hf_ipv6_shim6_opt_loc_verif_methods, tvb,
-                           p+count, 1, FALSE);
+                           p+count, 1, ENC_BIG_ENDIAN);
   p += optlen;
 
   /* Padding, included in length field */
@@ -965,7 +1150,7 @@ dissect_shim6_opt_loclist(proto_tree * opt_tree, tvbuff_t * tvb, gint *offset)
   subtree = proto_item_add_subtree(it, ett_ipv6_shim6_locators);
 
   for (count=0; count < optlen; count++) {
-      proto_tree_add_item(subtree, hf_ipv6_shim6_locator, tvb, p, 16, FALSE);
+      proto_tree_add_item(subtree, hf_ipv6_shim6_locator, tvb, p, 16, ENC_NA);
       p += 16;
   }
   *offset = p;
@@ -983,11 +1168,11 @@ dissect_shim6_opt_loc_pref(proto_tree * opt_tree, tvbuff_t * tvb, gint *offset,
 
   p = *offset;
 
-  proto_tree_add_item(opt_tree, hf_ipv6_shim6_opt_loclist, tvb, p, 4, FALSE);
+  proto_tree_add_item(opt_tree, hf_ipv6_shim6_opt_loclist, tvb, p, 4, ENC_BIG_ENDIAN);
   p += 4;
 
   optlen = tvb_get_guint8(tvb, p);
-  proto_tree_add_item(opt_tree, hf_ipv6_shim6_opt_elemlen, tvb, p, 1, FALSE);
+  proto_tree_add_item(opt_tree, hf_ipv6_shim6_opt_elemlen, tvb, p, 1, ENC_BIG_ENDIAN);
 
   if (optlen < 1 || optlen > 3) {
     it = proto_tree_add_text(opt_tree, tvb, p, 1,
@@ -1007,13 +1192,13 @@ dissect_shim6_opt_loc_pref(proto_tree * opt_tree, tvbuff_t * tvb, gint *offset,
 
     /* Flags */
     if (optlen >= 1)
-      proto_tree_add_item(subtree, hf_ipv6_shim6_loc_flag, tvb, p, 1, FALSE);
+      proto_tree_add_item(subtree, hf_ipv6_shim6_loc_flag, tvb, p, 1, ENC_BIG_ENDIAN);
     /* Priority */
     if (optlen >= 2)
-      proto_tree_add_item(subtree, hf_ipv6_shim6_loc_prio, tvb, p+1, 1, FALSE);
+      proto_tree_add_item(subtree, hf_ipv6_shim6_loc_prio, tvb, p+1, 1, ENC_BIG_ENDIAN);
     /* Weight */
     if (optlen >= 3)
-      proto_tree_add_item(subtree, hf_ipv6_shim6_loc_weight, tvb, p+2, 1, FALSE);
+      proto_tree_add_item(subtree, hf_ipv6_shim6_loc_weight, tvb, p+2, 1, ENC_BIG_ENDIAN);
     /*
      * Shim6 Draft 08 doesn't specify the format when the Element length is
      * more than three, except that any such formats MUST be defined so that
@@ -1036,15 +1221,12 @@ dissect_shimopts(tvbuff_t *tvb, int offset, proto_tree *tree, packet_info *pinfo
     gint padding;
     proto_tree *opt_tree;
     proto_item *ti;
-    guint8 tmp[2];
     const gchar *ctype;
 
 
     p = offset;
 
-    tmp[0] = tvb_get_guint8(tvb, p++);
-    tmp[1] = tvb_get_guint8(tvb, p++);
-    p += 2;
+    p += 4;
 
     len = tvb_get_ntohs(tvb, offset+2);
     padding = 7 - ((len + 3) % 8);
@@ -1057,13 +1239,13 @@ dissect_shimopts(tvbuff_t *tvb, int offset, proto_tree *tree, packet_info *pinfo
        ti = proto_tree_add_text(tree, tvb, offset, total_len, "%s", ctype);
        opt_tree = proto_item_add_subtree(ti, ett_ipv6_shim6_option);
 
-       proto_tree_add_item(opt_tree, hf_ipv6_shim6_opt_type, tvb, offset, 2, FALSE);
+       proto_tree_add_item(opt_tree, hf_ipv6_shim6_opt_type, tvb, offset, 2, ENC_BIG_ENDIAN);
 
        /* Critical */
-       proto_tree_add_item(opt_tree, hf_ipv6_shim6_opt_critical, tvb, offset+1, 1, FALSE);
+       proto_tree_add_item(opt_tree, hf_ipv6_shim6_opt_critical, tvb, offset+1, 1, ENC_BIG_ENDIAN);
 
        /* Content Length */
-       proto_tree_add_item(opt_tree, hf_ipv6_shim6_opt_len, tvb, offset + 2, 2, FALSE);
+       proto_tree_add_item(opt_tree, hf_ipv6_shim6_opt_len, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
        ti = proto_tree_add_uint_format(opt_tree, hf_ipv6_shim6_opt_total_len, tvb, offset+2, 2,
            total_len, "Total Length: %u", total_len);
        PROTO_ITEM_SET_GENERATED(ti);
@@ -1097,13 +1279,13 @@ dissect_shimopts(tvbuff_t *tvb, int offset, proto_tree *tree, packet_info *pinfo
            case SHIM6_OPT_ULIDPAIR:
                proto_tree_add_text(opt_tree, tvb, p, 4, "Reserved");
                p += 4;
-               proto_tree_add_item(opt_tree, hf_ipv6_shim6_sulid, tvb, p, 16, FALSE);
+               proto_tree_add_item(opt_tree, hf_ipv6_shim6_sulid, tvb, p, 16, ENC_NA);
                p += 16;
-               proto_tree_add_item(opt_tree, hf_ipv6_shim6_rulid, tvb, p, 16, FALSE);
+               proto_tree_add_item(opt_tree, hf_ipv6_shim6_rulid, tvb, p, 16, ENC_NA);
                p += 16;
                break;
            case SHIM6_OPT_FII:
-               proto_tree_add_item(opt_tree, hf_ipv6_shim6_opt_fii, tvb, p, 4, FALSE);
+               proto_tree_add_item(opt_tree, hf_ipv6_shim6_opt_fii, tvb, p, 4, ENC_BIG_ENDIAN);
                p += 4;
                break;
            default:
@@ -1159,15 +1341,15 @@ dissect_shim6_probes(proto_tree * shim_tree, tvbuff_t * tvb, gint offset,
     it = proto_tree_add_text(probes_tree, tvb, offset, 40, "Probe %u", count+1);
     probe_tree = proto_item_add_subtree(it, ett_probe);
 
-    proto_tree_add_item(probe_tree, hf_ipv6_shim6_psrc, tvb, offset, 16, FALSE);
+    proto_tree_add_item(probe_tree, hf_ipv6_shim6_psrc, tvb, offset, 16, ENC_NA);
     offset += 16;
-    proto_tree_add_item(probe_tree, hf_ipv6_shim6_pdst, tvb, offset, 16, FALSE);
+    proto_tree_add_item(probe_tree, hf_ipv6_shim6_pdst, tvb, offset, 16, ENC_NA);
     offset += 16;
 
-    proto_tree_add_item(probe_tree, hf_ipv6_shim6_pnonce, tvb, offset, 4, FALSE);
+    proto_tree_add_item(probe_tree, hf_ipv6_shim6_pnonce, tvb, offset, 4, ENC_BIG_ENDIAN);
     offset += 4;
 
-    proto_tree_add_item(probe_tree, hf_ipv6_shim6_pdata, tvb, offset, 4, FALSE);
+    proto_tree_add_item(probe_tree, hf_ipv6_shim6_pdata, tvb, offset, 4, ENC_BIG_ENDIAN);
     offset += 4;
   }
 }
@@ -1189,23 +1371,23 @@ dissect_shimctrl(tvbuff_t *tvb, gint offset, guint type, proto_tree *shim_tree)
        case SHIM6_TYPE_I1:
            dissect_shim6_ct(shim_tree, hf_ipv6_shim6_ct, tvb, p, "Initiator Context Tag");
            p += 6;
-           proto_tree_add_item(shim_tree, hf_ipv6_shim6_inonce, tvb, p, 4, FALSE);
+           proto_tree_add_item(shim_tree, hf_ipv6_shim6_inonce, tvb, p, 4, ENC_BIG_ENDIAN);
            p += 4;
            break;
        case SHIM6_TYPE_R1:
            proto_tree_add_text(shim_tree, tvb, p, 2, "Reserved2");
            p += 2;
-           proto_tree_add_item(shim_tree, hf_ipv6_shim6_inonce, tvb, p, 4, FALSE);
+           proto_tree_add_item(shim_tree, hf_ipv6_shim6_inonce, tvb, p, 4, ENC_BIG_ENDIAN);
            p += 4;
-           proto_tree_add_item(shim_tree, hf_ipv6_shim6_rnonce, tvb, p, 4, FALSE);
+           proto_tree_add_item(shim_tree, hf_ipv6_shim6_rnonce, tvb, p, 4, ENC_BIG_ENDIAN);
            p += 4;
            break;
        case SHIM6_TYPE_I2:
            dissect_shim6_ct(shim_tree, hf_ipv6_shim6_ct, tvb, p, "Initiator Context Tag");
            p += 6;
-           proto_tree_add_item(shim_tree, hf_ipv6_shim6_inonce, tvb, p, 4, FALSE);
+           proto_tree_add_item(shim_tree, hf_ipv6_shim6_inonce, tvb, p, 4, ENC_BIG_ENDIAN);
            p += 4;
-           proto_tree_add_item(shim_tree, hf_ipv6_shim6_rnonce, tvb, p, 4, FALSE);
+           proto_tree_add_item(shim_tree, hf_ipv6_shim6_rnonce, tvb, p, 4, ENC_BIG_ENDIAN);
            p += 4;
            proto_tree_add_text(shim_tree, tvb, p, 4, "Reserved2");
            p += 4;
@@ -1213,21 +1395,21 @@ dissect_shimctrl(tvbuff_t *tvb, gint offset, guint type, proto_tree *shim_tree)
        case SHIM6_TYPE_R2:
            dissect_shim6_ct(shim_tree, hf_ipv6_shim6_ct, tvb, p, "Responder Context Tag");
            p += 6;
-           proto_tree_add_item(shim_tree, hf_ipv6_shim6_inonce, tvb, p, 4, FALSE);
+           proto_tree_add_item(shim_tree, hf_ipv6_shim6_inonce, tvb, p, 4, ENC_BIG_ENDIAN);
            p += 4;
            break;
        case SHIM6_TYPE_R1BIS:
            dissect_shim6_ct(shim_tree, hf_ipv6_shim6_ct, tvb, p, "Packet Context Tag");
            p += 6;
-           proto_tree_add_item(shim_tree, hf_ipv6_shim6_rnonce, tvb, p, 4, FALSE);
+           proto_tree_add_item(shim_tree, hf_ipv6_shim6_rnonce, tvb, p, 4, ENC_BIG_ENDIAN);
            p += 4;
            break;
        case SHIM6_TYPE_I2BIS:
            dissect_shim6_ct(shim_tree, hf_ipv6_shim6_ct, tvb, p, "Initiator Context Tag");
            p += 6;
-           proto_tree_add_item(shim_tree, hf_ipv6_shim6_inonce, tvb, p, 4, FALSE);
+           proto_tree_add_item(shim_tree, hf_ipv6_shim6_inonce, tvb, p, 4, ENC_BIG_ENDIAN);
            p += 4;
-           proto_tree_add_item(shim_tree, hf_ipv6_shim6_rnonce, tvb, p, 4, FALSE);
+           proto_tree_add_item(shim_tree, hf_ipv6_shim6_rnonce, tvb, p, 4, ENC_BIG_ENDIAN);
            p += 4;
            proto_tree_add_text(shim_tree, tvb, p, 6, "Reserved2");
            p += 6;
@@ -1238,7 +1420,7 @@ dissect_shimctrl(tvbuff_t *tvb, gint offset, guint type, proto_tree *shim_tree)
        case SHIM6_TYPE_UPD_ACK:
            dissect_shim6_ct(shim_tree, hf_ipv6_shim6_ct, tvb, p, "Receiver Context Tag");
            p += 6;
-           proto_tree_add_item(shim_tree, hf_ipv6_shim6_rnonce, tvb, p, 4, FALSE);
+           proto_tree_add_item(shim_tree, hf_ipv6_shim6_rnonce, tvb, p, 4, ENC_BIG_ENDIAN);
            p += 4;
            break;
        case SHIM6_TYPE_KEEPALIVE:
@@ -1341,7 +1523,7 @@ dissect_shim6(tvbuff_t *tvb, int offset, proto_tree *tree, packet_info * pinfo)
 
     if (tree)
     {
-       ti = proto_tree_add_item(tree, hf_ipv6_shim6, tvb, offset, len, FALSE);
+       ti = proto_tree_add_item(tree, hf_ipv6_shim6, tvb, offset, len, ENC_NA);
        shim_tree = proto_item_add_subtree(ti, ett_ipv6_shim6);
 
        /* Next Header */
@@ -1356,7 +1538,7 @@ dissect_shim6(tvbuff_t *tvb, int offset, proto_tree *tree, packet_info * pinfo)
 
        /* P Field */
        proto_tree_add_item(shim_tree, hf_ipv6_shim6_p, tvb,
-                             offset + offsetof(struct ip6_shim, ip6s_p), 1, FALSE);
+                             offset + offsetof(struct ip6_shim, ip6s_p), 1, ENC_BIG_ENDIAN);
 
        /* skip the first 2 bytes (nxt hdr, hdr ext len, p+7bits) */
        p = offset + 3;
@@ -1384,11 +1566,11 @@ dissect_shim6(tvbuff_t *tvb, int offset, proto_tree *tree, packet_info * pinfo)
            /* Message Type */
            proto_tree_add_item(shim_tree, hf_ipv6_shim6_type, tvb,
                                offset + offsetof(struct ip6_shim, ip6s_p), 1,
-                               FALSE
+                               ENC_BIG_ENDIAN
                                );
 
            /* Protocol bit (Must be zero for SHIM6) */
-           proto_tree_add_item(shim_tree, hf_ipv6_shim6_proto, tvb, p, 1, FALSE);
+           proto_tree_add_item(shim_tree, hf_ipv6_shim6_proto, tvb, p, 1, ENC_BIG_ENDIAN);
            p++;
 
            /* Checksum */
@@ -1468,36 +1650,36 @@ dissect_ipv6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
     proto_item *ipv6_tc;
     const char *name;
 
-    ipv6_item = proto_tree_add_item(tree, proto_ipv6, tvb, offset, -1, FALSE);
+    ipv6_item = proto_tree_add_item(tree, proto_ipv6, tvb, offset, -1, ENC_NA);
     ipv6_tree = proto_item_add_subtree(ipv6_item, ett_ipv6);
 
     /* !!! warning: (4-bit) version, (6-bit) DSCP, (1-bit) ECN-ECT, (1-bit) ECN-CE and (20-bit) Flow */
     pi = proto_tree_add_item(ipv6_tree, hf_ipv6_version, tvb,
-                       offset + offsetof(struct ip6_hdr, ip6_vfc), 1, FALSE);
+                       offset + offsetof(struct ip6_hdr, ip6_vfc), 1, ENC_BIG_ENDIAN);
        pt = proto_item_add_subtree(pi,ett_ipv6_version);
     pi = proto_tree_add_item(pt, hf_ip_version, tvb,
-                                               offset + offsetof(struct ip6_hdr, ip6_vfc), 1, FALSE);
+                                               offset + offsetof(struct ip6_hdr, ip6_vfc), 1, ENC_BIG_ENDIAN);
        PROTO_ITEM_SET_GENERATED(pi);
 
     ipv6_tc = proto_tree_add_item(ipv6_tree, hf_ipv6_class, tvb,
-                       offset + offsetof(struct ip6_hdr, ip6_flow), 4, FALSE);
+                       offset + offsetof(struct ip6_hdr, ip6_flow), 4, ENC_BIG_ENDIAN);
 
     ipv6_tc_tree = proto_item_add_subtree(ipv6_tc, ett_ipv6_traffic_class);
 
     proto_tree_add_item(ipv6_tc_tree, hf_ipv6_traffic_class_dscp, tvb,
-                       offset + offsetof(struct ip6_hdr, ip6_flow), 4, FALSE);
+                       offset + offsetof(struct ip6_hdr, ip6_flow), 4, ENC_BIG_ENDIAN);
 
     proto_tree_add_item(ipv6_tc_tree, hf_ipv6_traffic_class_ect, tvb,
-                       offset + offsetof(struct ip6_hdr, ip6_flow), 4, FALSE);
+                       offset + offsetof(struct ip6_hdr, ip6_flow), 4, ENC_BIG_ENDIAN);
 
     proto_tree_add_item(ipv6_tc_tree, hf_ipv6_traffic_class_ce, tvb,
-                       offset + offsetof(struct ip6_hdr, ip6_flow), 4, FALSE);
+                       offset + offsetof(struct ip6_hdr, ip6_flow), 4, ENC_BIG_ENDIAN);
 
     proto_tree_add_item(ipv6_tree, hf_ipv6_flow, tvb,
-                       offset + offsetof(struct ip6_hdr, ip6_flow), 4, FALSE);
+                       offset + offsetof(struct ip6_hdr, ip6_flow), 4, ENC_BIG_ENDIAN);
 
     proto_tree_add_item(ipv6_tree, hf_ipv6_plen, tvb,
-                       offset + offsetof(struct ip6_hdr, ip6_plen), 2, FALSE);
+                       offset + offsetof(struct ip6_hdr, ip6_plen), 2, ENC_BIG_ENDIAN);
 
     proto_tree_add_uint_format(ipv6_tree, hf_ipv6_nxt, tvb,
                offset + offsetof(struct ip6_hdr, ip6_nxt), 1,
@@ -1506,11 +1688,11 @@ dissect_ipv6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
                ipprotostr(ipv6.ip6_nxt), ipv6.ip6_nxt);
 
     proto_tree_add_item(ipv6_tree, hf_ipv6_hlim, tvb,
-                       offset + offsetof(struct ip6_hdr, ip6_hlim), 1, FALSE);
+                       offset + offsetof(struct ip6_hdr, ip6_hlim), 1, ENC_BIG_ENDIAN);
 
-    /* Adds the different items for the source address */
+    /* Add the different items for the source address */
     proto_tree_add_item(ipv6_tree, hf_ipv6_src, tvb,
-                       offset + offsetof(struct ip6_hdr, ip6_src), 16, FALSE);
+                       offset + offsetof(struct ip6_hdr, ip6_src), 16, ENC_NA);
     ti = proto_tree_add_ipv6(ipv6_tree, hf_ipv6_addr, tvb,
                              offset + offsetof(struct ip6_hdr, ip6_src),
                              16, (guint8 *)&ipv6.ip6_src);
@@ -1530,19 +1712,20 @@ dissect_ipv6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
     PROTO_ITEM_SET_GENERATED(ti);
     PROTO_ITEM_SET_HIDDEN(ti);
 
+    /* Extract embedded (IPv6 and MAC) address information */
     if (tvb_get_ntohs(tvb, offset + IP6H_SRC) == 0x2002) { /* RFC 3056 section 2 */
       ti = proto_tree_add_item(ipv6_tree, hf_ipv6_src_6to4_gateway_ipv4, tvb,
-                                offset + IP6H_SRC + 2, 4, FALSE);
+                                offset + IP6H_SRC + 2, 4, ENC_BIG_ENDIAN);
       PROTO_ITEM_SET_GENERATED(ti);
       ti = proto_tree_add_item(ipv6_tree, hf_ipv6_src_6to4_sla_id, tvb,
-                                offset + IP6H_SRC + 6, 2, FALSE);
+                                offset + IP6H_SRC + 6, 2, ENC_BIG_ENDIAN);
       PROTO_ITEM_SET_GENERATED(ti);
       ti = proto_tree_add_item(ipv6_tree, hf_ipv6_6to4_gateway_ipv4, tvb,
-                                offset + IP6H_SRC + 2, 4, FALSE);
+                                offset + IP6H_SRC + 2, 4, ENC_BIG_ENDIAN);
       PROTO_ITEM_SET_GENERATED(ti);
       PROTO_ITEM_SET_HIDDEN(ti);
       ti = proto_tree_add_item(ipv6_tree, hf_ipv6_6to4_sla_id, tvb,
-                                offset + IP6H_SRC + 6, 2, FALSE);
+                                offset + IP6H_SRC + 6, 2, ENC_BIG_ENDIAN);
       PROTO_ITEM_SET_GENERATED(ti);
       PROTO_ITEM_SET_HIDDEN(ti);
     } else if (tvb_get_ntohl(tvb, offset + IP6H_SRC) == 0x20010000) { /* RFC 4380 section 4 */
@@ -1550,7 +1733,7 @@ dissect_ipv6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
       guint32 client_v4 = tvb_get_ipv4(tvb, offset + IP6H_SRC + 12) ^ 0xffffffff;
 
       ti = proto_tree_add_item(ipv6_tree, hf_ipv6_src_teredo_server_ipv4, tvb,
-                                offset + IP6H_SRC + 4, 4, FALSE);
+                                offset + IP6H_SRC + 4, 4, ENC_BIG_ENDIAN);
       PROTO_ITEM_SET_GENERATED(ti);
       ti = proto_tree_add_uint(ipv6_tree, hf_ipv6_src_teredo_port, tvb,
                                 offset + IP6H_SRC + 10, 2, mapped_port);
@@ -1559,7 +1742,7 @@ dissect_ipv6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
                                 offset + IP6H_SRC + 12, 4, client_v4);
       PROTO_ITEM_SET_GENERATED(ti);
       ti = proto_tree_add_item(ipv6_tree, hf_ipv6_teredo_server_ipv4, tvb,
-                                offset + IP6H_SRC + 4, 4, FALSE);
+                                offset + IP6H_SRC + 4, 4, ENC_BIG_ENDIAN);
       PROTO_ITEM_SET_GENERATED(ti);
       PROTO_ITEM_SET_HIDDEN(ti);
       ti = proto_tree_add_uint(ipv6_tree, hf_ipv6_teredo_port, tvb,
@@ -1586,17 +1769,17 @@ dissect_ipv6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
       PROTO_ITEM_SET_HIDDEN(ti);
     } else if ((tvb_get_ntohl(tvb, offset + IP6H_SRC + 8) & 0xfcffffff) == 0x00005efe) { /* RFC 5214 section 6.1 */
       ti = proto_tree_add_item(ipv6_tree, hf_ipv6_src_isatap_ipv4, tvb,
-                                offset + IP6H_SRC + 12, 4, FALSE);
+                                offset + IP6H_SRC + 12, 4, ENC_BIG_ENDIAN);
       PROTO_ITEM_SET_GENERATED(ti);
       ti = proto_tree_add_item(ipv6_tree, hf_ipv6_isatap_ipv4, tvb,
-                                offset + IP6H_SRC + 12, 4, FALSE);
+                                offset + IP6H_SRC + 12, 4, ENC_BIG_ENDIAN);
       PROTO_ITEM_SET_GENERATED(ti);
       PROTO_ITEM_SET_HIDDEN(ti);
     }
 
-    /* Adds different items for the destination address */
+    /* Add different items for the destination address */
     proto_tree_add_item(ipv6_tree, hf_ipv6_dst, tvb,
-                       offset + offsetof(struct ip6_hdr, ip6_dst), 16, FALSE);
+                       offset + offsetof(struct ip6_hdr, ip6_dst), 16, ENC_NA);
     ti = proto_tree_add_ipv6(ipv6_tree, hf_ipv6_addr, tvb,
                              offset + offsetof(struct ip6_hdr, ip6_dst),
                              16, (guint8 *)&ipv6.ip6_dst);
@@ -1616,19 +1799,20 @@ dissect_ipv6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
     PROTO_ITEM_SET_GENERATED(ti);
     PROTO_ITEM_SET_HIDDEN(ti);
 
+    /* Extract embedded (IPv6 and MAC) address information */
     if (tvb_get_ntohs(tvb, offset + IP6H_DST) == 0x2002) { /* RFC 3056 section 2 */
       ti = proto_tree_add_item(ipv6_tree, hf_ipv6_dst_6to4_gateway_ipv4, tvb,
-                                offset + IP6H_DST + 2, 4, FALSE);
+                                offset + IP6H_DST + 2, 4, ENC_BIG_ENDIAN);
       PROTO_ITEM_SET_GENERATED(ti);
       ti = proto_tree_add_item(ipv6_tree, hf_ipv6_dst_6to4_sla_id, tvb,
-                                offset + IP6H_DST + 6, 2, FALSE);
+                                offset + IP6H_DST + 6, 2, ENC_BIG_ENDIAN);
       PROTO_ITEM_SET_GENERATED(ti);
       ti = proto_tree_add_item(ipv6_tree, hf_ipv6_6to4_gateway_ipv4, tvb,
-                                offset + IP6H_DST + 2, 4, FALSE);
+                                offset + IP6H_DST + 2, 4, ENC_BIG_ENDIAN);
       PROTO_ITEM_SET_GENERATED(ti);
       PROTO_ITEM_SET_HIDDEN(ti);
       ti = proto_tree_add_item(ipv6_tree, hf_ipv6_6to4_sla_id, tvb,
-                                offset + IP6H_DST + 6, 2, FALSE);
+                                offset + IP6H_DST + 6, 2, ENC_BIG_ENDIAN);
       PROTO_ITEM_SET_GENERATED(ti);
       PROTO_ITEM_SET_HIDDEN(ti);
     } else if (tvb_get_ntohl(tvb, offset + IP6H_DST) == 0x20010000) { /* RFC 4380 section 4 */
@@ -1636,7 +1820,7 @@ dissect_ipv6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
       guint32 client_v4 = tvb_get_ipv4(tvb, offset + IP6H_DST + 12) ^ 0xffffffff;
 
       ti = proto_tree_add_item(ipv6_tree, hf_ipv6_dst_teredo_server_ipv4, tvb,
-                                offset + IP6H_DST + 4, 4, FALSE);
+                                offset + IP6H_DST + 4, 4, ENC_BIG_ENDIAN);
       PROTO_ITEM_SET_GENERATED(ti);
       ti = proto_tree_add_uint(ipv6_tree, hf_ipv6_dst_teredo_port, tvb,
                                 offset + IP6H_DST + 10, 2, mapped_port);
@@ -1645,7 +1829,7 @@ dissect_ipv6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
                                 offset + IP6H_DST + 12, 4, client_v4);
       PROTO_ITEM_SET_GENERATED(ti);
       ti = proto_tree_add_item(ipv6_tree, hf_ipv6_teredo_server_ipv4, tvb,
-                                offset + IP6H_DST + 4, 4, FALSE);
+                                offset + IP6H_DST + 4, 4, ENC_BIG_ENDIAN);
       PROTO_ITEM_SET_GENERATED(ti);
       PROTO_ITEM_SET_HIDDEN(ti);
       ti = proto_tree_add_uint(ipv6_tree, hf_ipv6_teredo_port, tvb,
@@ -1672,15 +1856,21 @@ dissect_ipv6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
       PROTO_ITEM_SET_HIDDEN(ti);
     } else if ((tvb_get_ntohl(tvb, offset + IP6H_DST + 8) & 0xfcffffff) == 0x00005efe) { /* RFC 5214 section 6.1 */
       ti = proto_tree_add_item(ipv6_tree, hf_ipv6_dst_isatap_ipv4, tvb,
-                                offset + IP6H_DST + 12, 4, FALSE);
+                                offset + IP6H_DST + 12, 4, ENC_BIG_ENDIAN);
       PROTO_ITEM_SET_GENERATED(ti);
       ti = proto_tree_add_item(ipv6_tree, hf_ipv6_isatap_ipv4, tvb,
-                                offset + IP6H_DST + 12, 4, FALSE);
+                                offset + IP6H_DST + 12, 4, ENC_BIG_ENDIAN);
       PROTO_ITEM_SET_GENERATED(ti);
       PROTO_ITEM_SET_HIDDEN(ti);
     }
   }
 
+#ifdef HAVE_GEOIP_V6
+  if (tree && ipv6_use_geoip) {
+    add_geoip_info(ipv6_tree, tvb, offset, ipv6.ip6_src, ipv6.ip6_dst);
+  }
+#endif
+
   /* start of the new header (could be a extension header) */
   poffset = offset + offsetof(struct ip6_hdr, ip6_nxt);
   nxt = tvb_get_guint8(tvb, poffset);
@@ -2011,6 +2201,73 @@ proto_register_ipv6(void)
       { "Teredo Client IPv4",          "ipv6.tc_ipv4",
                                FT_IPv4, BASE_NONE, NULL, 0x0,
                                "IPv6 Teredo Client Encapsulated IPv4 Address", HFILL }},
+#ifdef HAVE_GEOIP_V6
+    { &hf_geoip_country,
+      { "Source or Destination GeoIP Country", "ipv6.geoip.country", FT_STRING, BASE_NONE, NULL, 0x0,
+           NULL, HFILL }},
+    { &hf_geoip_city,
+      { "Source or Destination GeoIP City", "ipv6.geoip.city", FT_STRING, BASE_NONE, NULL, 0x0,
+           NULL, HFILL }},
+    { &hf_geoip_org,
+      { "Source or Destination GeoIP Organization", "ipv6.geoip.org", FT_STRING, BASE_NONE, NULL, 0x0,
+           NULL, HFILL }},
+    { &hf_geoip_isp,
+      { "Source or Destination GeoIP ISP", "ipv6.geoip.isp", FT_STRING, BASE_NONE, NULL, 0x0,
+           NULL, HFILL }},
+    { &hf_geoip_asnum,
+      { "Source or Destination GeoIP AS Number", "ipv6.geoip.asnum", FT_STRING, BASE_NONE, NULL, 0x0,
+           NULL, HFILL }},
+    { &hf_geoip_lat,
+      { "Source or Destination GeoIP Latitude", "ipv6.geoip.lat", FT_STRING, BASE_NONE, NULL, 0x0,
+           NULL, HFILL }},
+    { &hf_geoip_lon,
+      { "Source or Destination GeoIP Longitude", "ipv6.geoip.lon", FT_STRING, BASE_NONE, NULL, 0x0,
+           NULL, HFILL }},
+    { &hf_geoip_src_country,
+      { "Source GeoIP Country", "ipv6.geoip.src_country", FT_STRING, BASE_NONE, NULL, 0x0,
+           NULL, HFILL }},
+    { &hf_geoip_src_city,
+      { "Source GeoIP City", "ipv6.geoip.src_city", FT_STRING, BASE_NONE, NULL, 0x0,
+           NULL, HFILL }},
+    { &hf_geoip_src_org,
+      { "Source GeoIP Organization", "ipv6.geoip.src_org", FT_STRING, BASE_NONE, NULL, 0x0,
+           NULL, HFILL }},
+    { &hf_geoip_src_isp,
+      { "Source GeoIP ISP", "ipv6.geoip.src_isp", FT_STRING, BASE_NONE, NULL, 0x0,
+           NULL, HFILL }},
+    { &hf_geoip_src_asnum,
+      { "Source GeoIP AS Number", "ipv6.geoip.src_asnum", FT_STRING, BASE_NONE, NULL, 0x0,
+           NULL, HFILL }},
+    { &hf_geoip_src_lat,
+      { "Source GeoIP Latitude", "ipv6.geoip.src_lat", FT_STRING, BASE_NONE, NULL, 0x0,
+           NULL, HFILL }},
+    { &hf_geoip_src_lon,
+      { "Source GeoIP Longitude", "ipv6.geoip.src_lon", FT_STRING, BASE_NONE, NULL, 0x0,
+           NULL, HFILL }},
+    { &hf_geoip_dst_country,
+      { "Destination GeoIP Country", "ipv6.geoip.dst_country", FT_STRING, BASE_NONE, NULL, 0x0,
+           NULL, HFILL }},
+    { &hf_geoip_dst_city,
+      { "Destination GeoIP City", "ipv6.geoip.dst_city", FT_STRING, BASE_NONE, NULL, 0x0,
+           NULL, HFILL }},
+    { &hf_geoip_dst_org,
+      { "Destination GeoIP Organization", "ipv6.geoip.dst_org", FT_STRING, BASE_NONE, NULL, 0x0,
+           NULL, HFILL }},
+    { &hf_geoip_dst_isp,
+      { "Destination GeoIP ISP", "ipv6.geoip.dst_isp", FT_STRING, BASE_NONE, NULL, 0x0,
+           NULL, HFILL }},
+    { &hf_geoip_dst_asnum,
+      { "Destination GeoIP AS Number", "ipv6.geoip.dst_asnum", FT_STRING, BASE_NONE, NULL, 0x0,
+           NULL, HFILL }},
+    { &hf_geoip_dst_lat,
+      { "Destination GeoIP Latitude", "ipv6.geoip.dst_lat", FT_STRING, BASE_NONE, NULL, 0x0,
+           NULL, HFILL }},
+    { &hf_geoip_dst_lon,
+      { "Destination GeoIP Longitude", "ipv6.geoip.dst_lon", FT_STRING, BASE_NONE, NULL, 0x0,
+           NULL, HFILL }},
+#endif /* HAVE_GEOIP_V6 */
+
+
     { &hf_ipv6_opt_pad1,
       { "Pad1",                        "ipv6.opt.pad1",
                                FT_NONE, BASE_NONE, NULL, 0x0,
@@ -2368,7 +2625,10 @@ proto_register_ipv6(void)
     &ett_ipv6_shim6_cksum,
     &ett_ipv6_fragments,
     &ett_ipv6_fragment,
-    &ett_ipv6_traffic_class
+    &ett_ipv6_traffic_class,
+#ifdef HAVE_GEOIP_V6
+    &ett_geoip_info
+#endif /* HAVE_GEOIP_V6 */
   };
   module_t *ipv6_module;
 
@@ -2386,6 +2646,12 @@ proto_register_ipv6(void)
        "Show IPv6 summary in protocol tree",
        "Whether the IPv6 summary line should be shown in the protocol tree",
        &ipv6_summary_in_tree);
+#ifdef HAVE_GEOIP_V6
+       prefs_register_bool_preference(ipv6_module, "use_geoip" ,
+                 "Enable GeoIP lookups",
+                 "Whether to look up IPv6 addresses in each GeoIP database we have loaded",
+                 &ipv6_use_geoip);
+#endif /* HAVE_GEOIP_V6 */
 
   register_dissector("ipv6", dissect_ipv6, proto_ipv6);
   register_init_routine(ipv6_reassemble_init);