From Jiri Engelthaler via
[metze/wireshark/wip.git] / epan / proto.c
index a6b0325515f33fb265a2e3fbb069413212cef628..fc1b0f7afcb102cc12d9ab1070208adb966b3294 100644 (file)
@@ -29,6 +29,7 @@
 #include <ctype.h>
 #include <glib.h>
 #include <float.h>
+#include <wsutil/swar.h>
 
 #include "packet.h"
 #include "ptvcursor.h"
@@ -71,17 +72,6 @@ struct ptvcursor {
        gint         offset;
 };
 
-/* Candidates for assembler */
-static int
-wrs_count_bitshift(const guint32 bitmask)
-{
-       int bitshift = 0;
-
-       while ((bitmask & (1 << bitshift)) == 0)
-               bitshift++;
-       return bitshift;
-}
-
 #define cVALS(x) (const value_string*)(x)
 
 /** See inlined comments.
@@ -137,10 +127,11 @@ wrs_count_bitshift(const guint32 bitmask)
 static const char *hf_try_val_to_str(guint32 value, const header_field_info *hfinfo);
 
 static void fill_label_boolean(field_info *fi, gchar *label_str);
-static void fill_label_bitfield(field_info *fi, gchar *label_str);
+static void fill_label_bitfield(field_info *fi, gchar *label_str, gboolean is_signed);
 static void fill_label_number(field_info *fi, gchar *label_str, gboolean is_signed);
 static void fill_label_number64(field_info *fi, gchar *label_str, gboolean is_signed);
 
+static const char *hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[32], guint32 value);
 static const char *hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[32], guint32 value);
 static const char *hfinfo_number_value_format(const header_field_info *hfinfo, char buf[32], guint32 value);
 static const char *hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[32], guint32 value);
@@ -152,8 +143,8 @@ static proto_item *
 proto_tree_add_node(proto_tree *tree, field_info *fi);
 
 static void
-get_hfi_and_length(header_field_info *hfinfo, tvbuff_t *tvb, const gint start, gint *length,
-                  gint *item_length);
+get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const gint start, gint *length,
+               gint *item_length);
 
 static field_info *
 new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
@@ -165,7 +156,7 @@ alloc_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
 
 static proto_item *
 proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
-                 gint start, gint *length, field_info **pfi);
+                 gint start, gint *length);
 
 static void
 proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap);
@@ -189,6 +180,10 @@ proto_tree_set_ax25(field_info *fi, const guint8* value);
 static void
 proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, gint start);
 static void
+proto_tree_set_vines(field_info *fi, const guint8* value);
+static void
+proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, gint start);
+static void
 proto_tree_set_ether(field_info *fi, const guint8* value);
 static void
 proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, gint start);
@@ -245,8 +240,8 @@ struct _protocol {
        const char *short_name;   /* short description */
        const char *filter_name;  /* name of this protocol in filters */
        int         proto_id;     /* field ID for this protocol */
-       GList      *fields;       /* fields for this protocol */
-       GList      *last_field;   /* pointer to end of list of fields */
+       GSList     *fields;       /* fields for this protocol */
+       GSList     *last_field;   /* pointer to end of list of fields */
        gboolean    is_enabled;   /* TRUE if protocol is enabled */
        gboolean    can_toggle;   /* TRUE if is_enabled can be changed */
        gboolean    is_private;   /* TRUE is protocol is private */
@@ -290,7 +285,8 @@ typedef struct _gpa_hfinfo_t {
        guint32             allocated_len;
        header_field_info **hfi;
 } gpa_hfinfo_t;
-gpa_hfinfo_t gpa_hfinfo;
+
+static gpa_hfinfo_t gpa_hfinfo;
 
 /* Balanced tree of abbreviations and IDs */
 static GTree *gpa_name_tree = NULL;
@@ -418,7 +414,7 @@ proto_cleanup(void)
                DISSECTOR_ASSERT(protocol->proto_id == hfinfo->id);
 
                g_slice_free(header_field_info, hfinfo);
-               g_list_free(protocol->fields);
+               g_slist_free(protocol->fields);
                protocols = g_list_remove(protocols, protocol);
                g_free(protocol);
        }
@@ -648,7 +644,7 @@ proto_field_is_referenced(proto_tree *tree, int proto_id)
 }
 
 
-/* Finds a record in the hf_info_records array by id. */
+/* Finds a record in the hfinfo array by id. */
 header_field_info *
 proto_registrar_get_nth(guint hfindex)
 {
@@ -731,7 +727,7 @@ proto_initialize_all_prefixes(void) {
        g_hash_table_foreach_remove(prefixes, initialize_prefix, NULL);
 }
 
-/* Finds a record in the hf_info_records array by name.
+/* Finds a record in the hfinfo array by name.
  * If it fails to find it in the already registered fields,
  * it tries to find and call an initializer in the prefixes
  * table and if so it looks again.
@@ -972,12 +968,11 @@ static proto_item *
 proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, gint start, gint length)
 {
        proto_item *pi;
-       field_info *new_fi;
 
        if (tree == NULL)
                return NULL;
 
-       pi = proto_tree_add_pi(tree, &hfi_text_only, tvb, start, &length, &new_fi);
+       pi = proto_tree_add_pi(tree, &hfi_text_only, tvb, start, &length);
 
        return pi;
 }
@@ -1050,27 +1045,23 @@ proto_tree_add_debug_text(proto_tree *tree, const char *format, ...)
 /* We could probably get away with changing is_error to a minimum length value. */
 static void
 report_type_length_mismatch(proto_tree *tree, const gchar *descr, int length, gboolean is_error) {
-       tree_data_t *tree_data = PTREE_DATA(tree);
-       field_info *fi_save = tree_data->fi_tmp;
+       if (tree) {
+               tree_data_t *tree_data = PTREE_DATA(tree);
+               field_info *fi_save = tree_data->fi_tmp;
 
-       /* Keep the current item from getting freed by proto_tree_new_item. */
-       tree_data->fi_tmp = NULL;
+               /* Keep the current item from getting freed by proto_tree_new_item. */
+               tree_data->fi_tmp = NULL;
 
-       expert_add_info_format(NULL, tree, PI_MALFORMED, is_error ? PI_ERROR : PI_WARN, "Trying to fetch %s with length %d", descr, length);
+               expert_add_info_format(NULL, tree, PI_MALFORMED, is_error ? PI_ERROR : PI_WARN, "Trying to fetch %s with length %d", descr, length);
 
-       tree_data->fi_tmp = fi_save;
+               tree_data->fi_tmp = fi_save;
+       }
 
        if (is_error) {
                THROW(ReportedBoundsError);
        }
 }
 
-/*
- * NOTE: to support code written when proto_tree_add_item() took a
- * gboolean as its last argument, with FALSE meaning "big-endian"
- * and TRUE meaning "little-endian", we treat any non-zero value of
- * "encoding" as meaning "little-endian".
- */
 static guint32
 get_uint_value(proto_tree *tree, tvbuff_t *tvb, gint offset, gint length, const guint encoding)
 {
@@ -1084,18 +1075,18 @@ get_uint_value(proto_tree *tree, tvbuff_t *tvb, gint offset, gint length, const
                break;
 
        case 2:
-               value = encoding ? tvb_get_letohs(tvb, offset)
-                                : tvb_get_ntohs(tvb, offset);
+               value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohs(tvb, offset)
+                                                      : tvb_get_ntohs(tvb, offset);
                break;
 
        case 3:
-               value = encoding ? tvb_get_letoh24(tvb, offset)
-                                : tvb_get_ntoh24(tvb, offset);
+               value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh24(tvb, offset)
+                                                      : tvb_get_ntoh24(tvb, offset);
                break;
 
        case 4:
-               value = encoding ? tvb_get_letohl(tvb, offset)
-                                : tvb_get_ntohl(tvb, offset);
+               value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohl(tvb, offset)
+                                                      : tvb_get_ntohl(tvb, offset);
                break;
 
        default:
@@ -1104,8 +1095,8 @@ get_uint_value(proto_tree *tree, tvbuff_t *tvb, gint offset, gint length, const
                        value = 0;
                } else {
                        length_error = FALSE;
-                       value = encoding ? tvb_get_letohl(tvb, offset)
-                                        : tvb_get_ntohl(tvb, offset);
+                       value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohl(tvb, offset)
+                                                              : tvb_get_ntohl(tvb, offset);
                }
                report_type_length_mismatch(tree, "an unsigned integer", length, length_error);
                break;
@@ -1339,7 +1330,7 @@ proto_tree_new_item(field_info *new_fi, proto_tree *tree,
                                report_type_length_mismatch(tree, "an IPXNET address", length, length_error);
                        }
                        proto_tree_set_ipxnet(new_fi,
-                               get_uint_value(tree, tvb, start, FT_IPXNET_LEN, FALSE));
+                               get_uint_value(tree, tvb, start, FT_IPXNET_LEN, ENC_BIG_ENDIAN));
                        break;
 
                case FT_IPv6:
@@ -1353,12 +1344,19 @@ proto_tree_new_item(field_info *new_fi, proto_tree *tree,
                case FT_AX25:
                        if (length != 7) {
                                length_error = length < 7 ? TRUE : FALSE;
-                               expert_add_info_format(NULL, tree, PI_MALFORMED, PI_ERROR, "Trying to fetch an AX.25 address with length %d", length);
-                               THROW(ReportedBoundsError);
+                               report_type_length_mismatch(tree, "an AX.25 address", length, length_error);
                        }
                        proto_tree_set_ax25_tvb(new_fi, tvb, start);
                        break;
 
+               case FT_VINES:
+                       if (length != VINES_ADDR_LEN) {
+                               length_error = length < VINES_ADDR_LEN ? TRUE : FALSE;
+                               report_type_length_mismatch(tree, "a Vines address", length, length_error);
+                       }
+                       proto_tree_set_vines_tvb(new_fi, tvb, start);
+                       break;
+
                case FT_ETHER:
                        if (length != FT_ETHER_LEN) {
                                length_error = length < FT_ETHER_LEN ? TRUE : FALSE;
@@ -1751,7 +1749,7 @@ ptvcursor_add(ptvcursor_t *ptvc, int hfindex, gint length,
 
        offset = ptvc->offset;
        PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
-       get_hfi_and_length(hfinfo, ptvc->tvb, offset, &length, &item_length);
+       get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length);
        ptvc->offset += length;
        if (hfinfo->type == FT_UINT_BYTES || hfinfo->type == FT_UINT_STRING) {
                /*
@@ -1777,7 +1775,7 @@ ptvcursor_add(ptvcursor_t *ptvc, int hfindex, gint length,
  */
 static void
 test_length(header_field_info *hfinfo, proto_tree *tree, tvbuff_t *tvb,
-           gint start, gint length, gboolean little_endian)
+           gint start, gint length, const guint encoding)
 {
        gint size = length;
 
@@ -1787,7 +1785,7 @@ test_length(header_field_info *hfinfo, proto_tree *tree, tvbuff_t *tvb,
        if (hfinfo->type == FT_UINT_BYTES || hfinfo->type == FT_UINT_STRING) {
                guint32 n;
 
-               n = get_uint_value(tree, tvb, start, length, little_endian);
+               n = get_uint_value(tree, tvb, start, length, encoding);
                if (n > size + n) {
                        /* If n > size + n then we have an integer overflow, so
                         * set size to -1, which will force the
@@ -1799,25 +1797,32 @@ test_length(header_field_info *hfinfo, proto_tree *tree, tvbuff_t *tvb,
                else {
                        size += n;
                }
+       } else if (hfinfo->type == FT_STRINGZ) {
+               /* If we're fetching until the end of the TVB, only validate
+                * that the offset is within range.
+                */
+               if (length == -1)
+                       size = 0;
        }
+
        tvb_ensure_bytes_exist(tvb, start, size);
 }
 
 /* Add an item to a proto_tree, using the text label registered to that item;
    the item is extracted from the tvbuff handed to it. */
 proto_item *
-proto_tree_add_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
+proto_tree_add_item_new(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
                    const gint start, gint length, const guint encoding)
 {
        field_info        *new_fi;
-       header_field_info *hfinfo;
        gint              item_length;
 
-       PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
-       get_hfi_and_length(hfinfo, tvb, start, &length, &item_length);
+       DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
+
+       get_hfi_length(hfinfo, tvb, start, &length, &item_length);
        test_length(hfinfo, tree, tvb, start, item_length, encoding);
 
-       TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
+       TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
 
        new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
 
@@ -1827,6 +1832,13 @@ proto_tree_add_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
        return proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
 }
 
+proto_item *
+proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
+                   const gint start, gint length, const guint encoding)
+{
+        return proto_tree_add_item_new(tree, proto_registrar_get_nth(hfindex), tvb, start, length, encoding);
+}
+
 /* Add a FT_NONE to a proto_tree */
 proto_item *
 proto_tree_add_none_format(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
@@ -1836,13 +1848,12 @@ proto_tree_add_none_format(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
        proto_item        *pi;
        va_list            ap;
        header_field_info *hfinfo;
-       field_info        *new_fi;
 
        TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
 
        DISSECTOR_ASSERT(hfinfo->type == FT_NONE);
 
-       pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length, &new_fi);
+       pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
 
        TRY_TO_FAKE_THIS_REPR(pi);
 
@@ -1890,16 +1901,15 @@ proto_tree_add_protocol_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
 {
        proto_item        *pi;
        va_list            ap;
-       field_info        *new_fi;
        header_field_info *hfinfo;
 
        TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
 
        DISSECTOR_ASSERT(hfinfo->type == FT_PROTOCOL);
 
-       pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length, &new_fi);
+       pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
 
-       proto_tree_set_protocol_tvb(new_fi, (start == 0 ? tvb : tvb_new_subset(tvb, start, length, length)));
+       proto_tree_set_protocol_tvb(PNODE_FINFO(pi), (start == 0 ? tvb : tvb_new_subset(tvb, start, length, length)));
 
        TRY_TO_FAKE_THIS_REPR(pi);
 
@@ -1917,15 +1927,14 @@ proto_tree_add_bytes(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
                     gint length, const guint8 *start_ptr)
 {
        proto_item        *pi;
-       field_info        *new_fi;
        header_field_info *hfinfo;
 
        TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
 
        DISSECTOR_ASSERT(hfinfo->type == FT_BYTES);
 
-       pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length, &new_fi);
-       proto_tree_set_bytes(new_fi, start_ptr, length);
+       pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
+       proto_tree_set_bytes(PNODE_FINFO(pi), start_ptr, length);
 
        return pi;
 }
@@ -2008,7 +2017,6 @@ proto_tree_add_time(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
                    gint length, nstime_t *value_ptr)
 {
        proto_item        *pi;
-       field_info        *new_fi;
        header_field_info *hfinfo;
 
        TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
@@ -2016,8 +2024,8 @@ proto_tree_add_time(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
        DISSECTOR_ASSERT(hfinfo->type == FT_ABSOLUTE_TIME ||
                         hfinfo->type == FT_RELATIVE_TIME);
 
-       pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length, &new_fi);
-       proto_tree_set_time(new_fi, value_ptr);
+       pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
+       proto_tree_set_time(PNODE_FINFO(pi), value_ptr);
 
        return pi;
 }
@@ -2075,15 +2083,14 @@ proto_tree_add_ipxnet(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
                      gint length, guint32 value)
 {
        proto_item        *pi;
-       field_info        *new_fi;
        header_field_info *hfinfo;
 
        TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
 
        DISSECTOR_ASSERT(hfinfo->type == FT_IPXNET);
 
-       pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length, &new_fi);
-       proto_tree_set_ipxnet(new_fi, value);
+       pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
+       proto_tree_set_ipxnet(PNODE_FINFO(pi), value);
 
        return pi;
 }
@@ -2139,15 +2146,14 @@ proto_tree_add_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
                    gint length, guint32 value)
 {
        proto_item        *pi;
-       field_info        *new_fi;
        header_field_info *hfinfo;
 
        TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
 
        DISSECTOR_ASSERT(hfinfo->type == FT_IPv4);
 
-       pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length, &new_fi);
-       proto_tree_set_ipv4(new_fi, value);
+       pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
+       proto_tree_set_ipv4(PNODE_FINFO(pi), value);
 
        return pi;
 }
@@ -2203,15 +2209,14 @@ proto_tree_add_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
                    gint length, const guint8* value_ptr)
 {
        proto_item        *pi;
-       field_info        *new_fi;
        header_field_info *hfinfo;
 
        TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
 
        DISSECTOR_ASSERT(hfinfo->type == FT_IPv6);
 
-       pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length, &new_fi);
-       proto_tree_set_ipv6(new_fi, value_ptr);
+       pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
+       proto_tree_set_ipv6(PNODE_FINFO(pi), value_ptr);
 
        return pi;
 }
@@ -2275,15 +2280,14 @@ proto_tree_add_guid(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
                    gint length, const e_guid_t *value_ptr)
 {
        proto_item        *pi;
-       field_info        *new_fi;
        header_field_info *hfinfo;
 
        TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
 
        DISSECTOR_ASSERT(hfinfo->type == FT_GUID);
 
-       pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length, &new_fi);
-       proto_tree_set_guid(new_fi, value_ptr);
+       pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
+       proto_tree_set_guid(PNODE_FINFO(pi), value_ptr);
 
        return pi;
 }
@@ -2351,15 +2355,14 @@ proto_tree_add_oid(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
                   gint length, const guint8* value_ptr)
 {
        proto_item        *pi;
-       field_info        *new_fi;
        header_field_info *hfinfo;
 
        TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
 
        DISSECTOR_ASSERT(hfinfo->type == FT_OID);
 
-       pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length, &new_fi);
-       proto_tree_set_oid(new_fi, value_ptr, length);
+       pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
+       proto_tree_set_oid(PNODE_FINFO(pi), value_ptr, length);
 
        return pi;
 }
@@ -2482,16 +2485,15 @@ proto_tree_add_string(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
                      gint length, const char* value)
 {
        proto_item        *pi;
-       field_info        *new_fi;
        header_field_info *hfinfo;
 
        TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
 
        DISSECTOR_ASSERT(hfinfo->type == FT_STRING || hfinfo->type == FT_STRINGZ);
 
-       pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length, &new_fi);
+       pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
        DISSECTOR_ASSERT(length >= 0);
-       proto_tree_set_string(new_fi, value);
+       proto_tree_set_string(PNODE_FINFO(pi), value);
 
        return pi;
 }
@@ -2564,7 +2566,7 @@ proto_item_append_string(proto_item *pi, const char *str)
 {
        field_info        *fi;
        header_field_info *hfinfo;
-       gchar             *old_str, *new_str;
+       const gchar       *old_str, *new_str;
 
        if (!pi)
                return;
@@ -2581,8 +2583,11 @@ proto_item_append_string(proto_item *pi, const char *str)
        }
        DISSECTOR_ASSERT(hfinfo->type == FT_STRING || hfinfo->type == FT_STRINGZ);
        old_str = (guint8 *)fvalue_get(&fi->value);
-       new_str = ep_strdup_printf("%s%s", old_str, str);
-       fvalue_set(&fi->value, new_str, FALSE);
+       if (old_str && old_str[0])
+               new_str = ep_strconcat(old_str, str, NULL);
+       else
+               new_str = str;
+       fvalue_set(&fi->value, (gpointer) new_str, FALSE);
 }
 
 /* Set the FT_STRING value */
@@ -2616,15 +2621,14 @@ proto_tree_add_ax25(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gi
                const guint8* value)
 {
        proto_item              *pi;
-       field_info              *new_fi;
        header_field_info       *hfinfo;
 
        TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
 
        DISSECTOR_ASSERT(hfinfo->type == FT_AX25);
 
-       pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length, &new_fi);
-       proto_tree_set_ax25(new_fi, value);
+       pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
+       proto_tree_set_ax25(PNODE_FINFO(pi), value);
 
        return pi;
 }
@@ -2642,6 +2646,18 @@ proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, gint start)
        proto_tree_set_ax25(fi, tvb_get_ptr(tvb, start, 7));
 }
 
+/* Set the FT_VINES value */
+static void
+proto_tree_set_vines(field_info *fi, const guint8* value)
+{
+       fvalue_set(&fi->value, (gpointer) value, FALSE);
+}
+
+static void
+proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, gint start)
+{
+       proto_tree_set_vines(fi, tvb_get_ptr(tvb, start, FT_VINES_ADDR_LEN));
+}
 
 /* Add a FT_ETHER to a proto_tree */
 proto_item *
@@ -2649,15 +2665,14 @@ proto_tree_add_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
                     gint length, const guint8* value)
 {
        proto_item        *pi;
-       field_info        *new_fi;
        header_field_info *hfinfo;
 
        TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
 
        DISSECTOR_ASSERT(hfinfo->type == FT_ETHER);
 
-       pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length, &new_fi);
-       proto_tree_set_ether(new_fi, value);
+       pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
+       proto_tree_set_ether(PNODE_FINFO(pi), value);
 
        return pi;
 }
@@ -2719,15 +2734,14 @@ proto_tree_add_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
                       gint length, guint32 value)
 {
        proto_item        *pi;
-       field_info        *new_fi;
        header_field_info *hfinfo;
 
        TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
 
        DISSECTOR_ASSERT(hfinfo->type == FT_BOOLEAN);
 
-       pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length, &new_fi);
-       proto_tree_set_boolean(new_fi, value);
+       pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
+       proto_tree_set_boolean(PNODE_FINFO(pi), value);
 
        return pi;
 }
@@ -2783,15 +2797,14 @@ proto_tree_add_float(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
                     gint length, float value)
 {
        proto_item        *pi;
-       field_info        *new_fi;
        header_field_info *hfinfo;
 
        TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
 
        DISSECTOR_ASSERT(hfinfo->type == FT_FLOAT);
 
-       pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length, &new_fi);
-       proto_tree_set_float(new_fi, value);
+       pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
+       proto_tree_set_float(PNODE_FINFO(pi), value);
 
        return pi;
 }
@@ -2847,15 +2860,14 @@ proto_tree_add_double(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
                      gint length, double value)
 {
        proto_item        *pi;
-       field_info        *new_fi;
        header_field_info *hfinfo;
 
        TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
 
        DISSECTOR_ASSERT(hfinfo->type == FT_DOUBLE);
 
-       pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length, &new_fi);
-       proto_tree_set_double(new_fi, value);
+       pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
+       proto_tree_set_double(PNODE_FINFO(pi), value);
 
        return pi;
 }
@@ -2911,7 +2923,6 @@ proto_tree_add_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
                    gint length, guint32 value)
 {
        proto_item        *pi = NULL;
-       field_info        *new_fi;
        header_field_info *hfinfo;
 
        TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
@@ -2922,9 +2933,8 @@ proto_tree_add_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
                case FT_UINT24:
                case FT_UINT32:
                case FT_FRAMENUM:
-                       pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length,
-                                       &new_fi);
-                       proto_tree_set_uint(new_fi, value);
+                       pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
+                       proto_tree_set_uint(PNODE_FINFO(pi), value);
                        break;
 
                default:
@@ -2987,9 +2997,7 @@ proto_tree_set_uint(field_info *fi, guint32 value)
                integer &= hfinfo->bitmask;
 
                /* Shift bits */
-               if (hfinfo->bitshift > 0) {
-                       integer >>= hfinfo->bitshift;
-               }
+               integer >>= hfinfo_bitshift(hfinfo);
        }
 
        fvalue_set_uinteger(&fi->value, integer);
@@ -3000,16 +3008,15 @@ proto_item *
 proto_tree_add_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
                      gint length, guint64 value)
 {
-       proto_item        *pi = NULL;
-       field_info        *new_fi;
+       proto_item        *pi;
        header_field_info *hfinfo;
 
        TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
 
        DISSECTOR_ASSERT(hfinfo->type == FT_UINT64);
 
-       pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length, &new_fi);
-       proto_tree_set_uint64(new_fi, value);
+       pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
+       proto_tree_set_uint64(PNODE_FINFO(pi), value);
 
        return pi;
 }
@@ -3058,7 +3065,6 @@ proto_tree_add_int(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
                   gint length, gint32 value)
 {
        proto_item        *pi = NULL;
-       field_info        *new_fi;
        header_field_info *hfinfo;
 
        TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
@@ -3068,9 +3074,8 @@ proto_tree_add_int(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
                case FT_INT16:
                case FT_INT24:
                case FT_INT32:
-                       pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length,
-                                       &new_fi);
-                       proto_tree_set_int(new_fi, value);
+                       pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
+                       proto_tree_set_int(PNODE_FINFO(pi), value);
                        break;
 
                default:
@@ -3124,6 +3129,7 @@ proto_tree_set_int(field_info *fi, gint32 value)
 {
        header_field_info *hfinfo;
        guint32            integer;
+       gint               no_of_bits;
 
        hfinfo = fi->hfinfo;
        integer = (guint32) value;
@@ -3133,9 +3139,11 @@ proto_tree_set_int(field_info *fi, gint32 value)
                integer &= hfinfo->bitmask;
 
                /* Shift bits */
-               if (hfinfo->bitshift > 0) {
-                       integer >>= hfinfo->bitshift;
-               }
+               integer >>= hfinfo_bitshift(hfinfo);
+
+               no_of_bits = swar_count_bits(hfinfo->bitmask);
+               if (integer & (1 << (no_of_bits-1)))
+                       integer |= (-1 << no_of_bits);
        }
 
        fvalue_set_sinteger(&fi->value, integer);
@@ -3146,16 +3154,15 @@ proto_item *
 proto_tree_add_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
                     gint length, gint64 value)
 {
-       proto_item        *pi = NULL;
-       field_info        *new_fi;
+       proto_item        *pi;
        header_field_info *hfinfo;
 
        TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
 
        DISSECTOR_ASSERT(hfinfo->type == FT_INT64);
 
-       pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length, &new_fi);
-       proto_tree_set_uint64(new_fi, (guint64)value);
+       pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
+       proto_tree_set_uint64(PNODE_FINFO(pi), (guint64)value);
 
        return pi;
 }
@@ -3203,15 +3210,14 @@ proto_tree_add_eui64(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
                     gint length, const guint64 value)
 {
        proto_item        *pi;
-       field_info        *new_fi;
        header_field_info *hfinfo;
 
        TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
 
        DISSECTOR_ASSERT(hfinfo->type == FT_EUI64);
 
-       pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length, &new_fi);
-       proto_tree_set_eui64(new_fi, value);
+       pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
+       proto_tree_set_eui64(PNODE_FINFO(pi), value);
 
        return pi;
 }
@@ -3318,7 +3324,7 @@ proto_tree_add_node(proto_tree *tree, field_info *fi)
  * Sets *pfi to address of newly-allocated field_info struct */
 static proto_item *
 proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb, gint start,
-                 gint *length, field_info **pfi)
+                 gint *length)
 {
        proto_item *pi;
        field_info *fi;
@@ -3326,17 +3332,15 @@ proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb, gi
        fi = alloc_field_info(tree, hfinfo, tvb, start, length);
        pi = proto_tree_add_node(tree, fi);
 
-       *pfi = fi;
-
        return pi;
 }
 
 
 static void
-get_hfi_and_length(header_field_info *hfinfo, tvbuff_t *tvb, const gint start, gint *length,
+get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const gint start, gint *length,
                   gint *item_length)
 {
-       gint               length_remaining;
+       gint length_remaining;
 
        /*
         * We only allow a null tvbuff if the item has a zero length,
@@ -3495,10 +3499,21 @@ alloc_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb, con
 {
        gint               item_length;
 
-       get_hfi_and_length(hfinfo, tvb, start, length, &item_length);
+       get_hfi_length(hfinfo, tvb, start, length, &item_length);
        return new_field_info(tree, hfinfo, tvb, start, item_length);
 }
 
+static void
+label_mark_truncated_start(char *label_str)
+{
+       static const char trunc_str[] = "[truncated] ";
+       const size_t trunc_len = sizeof(trunc_str)-1;
+
+       memmove(label_str + trunc_len, label_str, ITEM_LABEL_LENGTH - trunc_len);
+       memcpy(label_str, trunc_str, trunc_len);
+       label_str[ITEM_LABEL_LENGTH-1] = '\0';
+}
+
 /* If the protocol tree is to be visible, set the representation of a
    proto_tree entry with the name of the field for the item and with
    the value formatted with the supplied printf-style format and
@@ -3525,8 +3540,7 @@ proto_tree_set_representation_value(proto_item *pi, const char *format, va_list
                        char *p;
 
                        val = fvalue_get_uinteger(&fi->value);
-                       if (hf->bitshift > 0)
-                               val <<= hf->bitshift;
+                       val <<= hfinfo_bitshift(hf);
 
                        p = decode_bitfield_value(fi->rep->representation, val, hf->bitmask, hfinfo_bitwidth(hf));
                        ret = (int) (p - fi->rep->representation);
@@ -3544,18 +3558,8 @@ proto_tree_set_representation_value(proto_item *pi, const char *format, va_list
                        /* Uh oh, we don't have enough room.  Tell the user
                         * that the field is truncated.
                         */
-                       char *oldrep;
-
-                       /*      Argh, we cannot reuse 'ap' here.  So make a copy
-                        *      of what we formatted for (re)use below.
-                        */
-                       oldrep = g_strdup(fi->rep->representation);
-
-                       g_snprintf(fi->rep->representation,
-                                  ITEM_LABEL_LENGTH,
-                                  "[truncated] %s",
-                                  oldrep);
-                       g_free(oldrep);
+                       /* XXX, label_mark_truncated() ? */
+                       label_mark_truncated_start(fi->rep->representation);
                }
        }
 }
@@ -3579,16 +3583,7 @@ proto_tree_set_representation(proto_item *pi, const char *format, va_list ap)
                        /* Uh oh, we don't have enough room.  Tell the user
                         * that the field is truncated.
                         */
-                       char *oldrep;
-
-                       /*      Argh, we cannot reuse 'ap' here.  So make a copy
-                        *      of what we formatted for (re)use below.
-                        */
-                       oldrep = g_strdup(fi->rep->representation);
-
-                       g_snprintf(fi->rep->representation, ITEM_LABEL_LENGTH,
-                                  "[truncated] %s", oldrep);
-                       g_free(oldrep);
+                       label_mark_truncated_start(fi->rep->representation);
                }
        }
 }
@@ -3603,13 +3598,20 @@ protoo_strlcpy(gchar *dest, const gchar *src, gsize dest_size)
        return (int) res;
 }
 
+static header_field_info *
+hfinfo_same_name_get_prev(const header_field_info *hfinfo)
+{
+       if (hfinfo->same_name_prev_id == -1)
+               return NULL;
+       return proto_registrar_get_nth(hfinfo->same_name_prev_id);
+}
+
 /* -------------------------- */
 const gchar *
 proto_custom_set(proto_tree* tree, const int field_id, gint occurrence,
                 gchar *result, gchar *expr, const int size)
 {
-       guint32            u_integer;
-       gint32             integer;
+       guint32            number;
        guint8            *bytes;
        ipv4_addr         *ipv4;
        struct e_in6_addr *ipv6;
@@ -3624,6 +3626,7 @@ proto_custom_set(proto_tree* tree, const int field_id, gint occurrence,
        header_field_info*  hfinfo;
        const gchar        *abbrev        = NULL;
 
+       const char *hf_str_val;
        char number_buf[32];
        const char *number_out;
 
@@ -3637,8 +3640,8 @@ proto_custom_set(proto_tree* tree, const int field_id, gint occurrence,
 
        if (occurrence < 0) {
                /* Search other direction */
-               while (hfinfo->same_name_prev) {
-                       hfinfo = hfinfo->same_name_prev;
+               while (hfinfo->same_name_prev_id != -1) {
+                       hfinfo = proto_registrar_get_nth(hfinfo->same_name_prev_id);
                }
        }
 
@@ -3649,7 +3652,7 @@ proto_custom_set(proto_tree* tree, const int field_id, gint occurrence,
                        if (occurrence < 0) {
                                hfinfo = hfinfo->same_name_next;
                        } else {
-                               hfinfo = hfinfo->same_name_prev;
+                               hfinfo = hfinfo_same_name_get_prev(hfinfo);
                        }
                        continue;
                }
@@ -3659,7 +3662,7 @@ proto_custom_set(proto_tree* tree, const int field_id, gint occurrence,
                        if (occurrence < 0) {
                                hfinfo = hfinfo->same_name_next;
                        } else {
-                               hfinfo = hfinfo->same_name_prev;
+                               hfinfo = hfinfo_same_name_get_prev(hfinfo);
                        }
                        prev_len += len;
                        continue;
@@ -3726,57 +3729,66 @@ proto_custom_set(proto_tree* tree, const int field_id, gint occurrence,
                                break;
 
                        case FT_BOOLEAN:
-                               u_integer = fvalue_get_uinteger(&finfo->value);
+                               number = fvalue_get_uinteger(&finfo->value);
                                tfstring = (const true_false_string *)&tfs_true_false;
                                if (hfinfo->strings) {
                                        tfstring = (const struct true_false_string*) hfinfo->strings;
                                }
                                offset_r += protoo_strlcpy(result+offset_r,
-                                                          u_integer ?
+                                                          number ?
                                                             tfstring->true_string :
                                                             tfstring->false_string, size-offset_r);
 
                                offset_e += protoo_strlcpy(expr+offset_e,
-                                                          u_integer ? "1" : "0", size-offset_e);
+                                                          number ? "1" : "0", size-offset_e);
                                break;
 
+                       /* XXX - make these just FT_NUMBER? */
+                       case FT_INT8:
+                       case FT_INT16:
+                       case FT_INT24:
+                       case FT_INT32:
                        case FT_UINT8:
                        case FT_UINT16:
                        case FT_UINT24:
                        case FT_UINT32:
                        case FT_FRAMENUM:
-                               u_integer = fvalue_get_uinteger(&finfo->value);
+                               hf_str_val = NULL;
+                               number = IS_FT_INT(hfinfo->type) ? 
+                                               (guint32) fvalue_get_sinteger(&finfo->value) :
+                                               fvalue_get_uinteger(&finfo->value);
+
                                if ((hfinfo->display & BASE_DISPLAY_E_MASK) == BASE_CUSTOM) {
                                        gchar tmp[ITEM_LABEL_LENGTH];
                                        custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
 
                                        DISSECTOR_ASSERT(fmtfunc);
-                                       fmtfunc(tmp, u_integer);
-                                       g_strlcpy(result+offset_r, tmp, size-offset_r);
+                                       fmtfunc(tmp, number);
+
+                                       offset_r += protoo_strlcpy(result+offset_r, tmp, size-offset_r);
+
                                } else if (hfinfo->strings) {
-                                       const char *str_val = hf_try_val_to_str(u_integer, hfinfo);
+                                       number_out = hf_str_val = hf_try_val_to_str(number, hfinfo);
+
+                                       if (!number_out)
+                                               number_out = hfinfo_number_value_format_display(hfinfo, BASE_DEC, number_buf, number);
 
-                                       if (str_val)
-                                               g_strlcpy(result+offset_r, str_val, size-offset_r);
-                                       else
-                                               g_snprintf(result+offset_r, size-offset_r, "%u", u_integer);
+                                       offset_r += protoo_strlcpy(result+offset_r, number_out, size-offset_r);
 
                                } else {
-                                       number_out = hfinfo_number_value_format(hfinfo, number_buf, u_integer);
+                                       number_out = hfinfo_number_value_format(hfinfo, number_buf, number);
 
-                                       g_strlcpy(result+offset_r, number_out, size-offset_r);
+                                       offset_r += protoo_strlcpy(result+offset_r, number_out, size-offset_r);
                                }
 
-                               if (hfinfo->strings && (hfinfo->display & BASE_DISPLAY_E_MASK) == BASE_NONE) {
-                                       g_snprintf(expr+offset_e, size-offset_e,
-                                                  "\"%s\"", result+offset_r);
+                               if (hf_str_val && (hfinfo->display & BASE_DISPLAY_E_MASK) == BASE_NONE) {
+                                       g_snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
                                } else {
-                                       number_out = hfinfo_numeric_value_format(hfinfo, number_buf, u_integer);
+                                       number_out = hfinfo_numeric_value_format(hfinfo, number_buf, number);
 
                                        g_strlcpy(expr+offset_e, number_out, size-offset_e);
                                }
 
-                               offset_r = (int)strlen(result);
                                offset_e = (int)strlen(expr);
                                break;
 
@@ -3799,44 +3811,6 @@ proto_custom_set(proto_tree* tree, const int field_id, gint occurrence,
                                                           eui64_to_str(fvalue_get_integer64(&finfo->value)),
                                                           size-offset_r);
                                break;
-                       /* XXX - make these just FT_INT? */
-                       case FT_INT8:
-                       case FT_INT16:
-                       case FT_INT24:
-                       case FT_INT32:
-                               integer = fvalue_get_sinteger(&finfo->value);
-                               if ((hfinfo->display & BASE_DISPLAY_E_MASK) == BASE_CUSTOM) {
-                                       gchar tmp[ITEM_LABEL_LENGTH];
-                                       custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
-
-                                       DISSECTOR_ASSERT(fmtfunc);
-                                       fmtfunc(tmp, integer);
-                                       g_strlcpy(result+offset_r, tmp, size-offset_r);
-                               } else if (hfinfo->strings) {
-                                       const char *str_val = hf_try_val_to_str(integer, hfinfo);
-
-                                       if (str_val)
-                                               g_strlcpy(result+offset_r, str_val, size-offset_r);
-                                       else
-                                               g_snprintf(result+offset_r, size-offset_r, "%d", integer);
-
-                               } else {
-                                       number_out = hfinfo_number_value_format(hfinfo, number_buf, integer);
-
-                                       g_strlcpy(result+offset_r, number_out, size-offset_r);
-                               }
-
-                               if (hfinfo->strings && (hfinfo->display & BASE_DISPLAY_E_MASK) == BASE_NONE) {
-                                       g_snprintf(expr+offset_e, size-offset_e, "\"%s\"", result+offset_r);
-                               } else {
-                                       number_out = hfinfo_numeric_value_format(hfinfo, number_buf, (guint32) integer);
-
-                                       g_strlcpy(expr+offset_e, number_out, size-offset_e);
-                               }
-
-                               offset_r = (int)strlen(result);
-                               offset_e = (int)strlen(expr);
-                               break;
 
                        case FT_IPv4:
                                ipv4 = (ipv4_addr *)fvalue_get(&finfo->value);
@@ -3939,7 +3913,7 @@ proto_custom_set(proto_tree* tree, const int field_id, gint occurrence,
 
                if (occurrence == 0) {
                        /* Fetch next hfinfo with same name (abbrev) */
-                       hfinfo = hfinfo->same_name_prev;
+                       hfinfo = hfinfo_same_name_get_prev(hfinfo);
                } else {
                        hfinfo = NULL;
                }
@@ -4102,30 +4076,6 @@ proto_item_get_len(const proto_item *pi)
        return fi ? fi->length : -1;
 }
 
-
-/** clear flags according to the mask and set new flag values */
-#define FI_REPLACE_FLAGS(fi, mask, flags_in) { \
-       (fi->flags = (fi)->flags & ~(mask)); \
-       (fi->flags = (fi)->flags | (flags_in)); \
-}
-
-gboolean
-proto_item_set_expert_flags(proto_item *pi, const int group, const guint severity)
-{
-       if (pi == NULL || PITEM_FINFO(pi) == NULL)
-               return FALSE;
-
-       /* only change things if severity is worse or at least equal than before */
-       if (severity >= FI_GET_FLAG(PITEM_FINFO(pi), PI_SEVERITY_MASK)) {
-               FI_REPLACE_FLAGS(PITEM_FINFO(pi), PI_GROUP_MASK, group);
-               FI_REPLACE_FLAGS(PITEM_FINFO(pi), PI_SEVERITY_MASK, severity);
-
-               return TRUE;
-       }
-
-       return FALSE;
-}
-
 proto_tree *
 proto_tree_create_root(packet_info *pinfo)
 {
@@ -4415,7 +4365,6 @@ proto_register_protocol(const char *name, const char *short_name,
        hfinfo->display = BASE_NONE;
        hfinfo->strings = protocol;
        hfinfo->bitmask = 0;
-       hfinfo->bitshift = 0;
        hfinfo->ref_type = HF_REF_TYPE_NONE;
        hfinfo->blurb = NULL;
        hfinfo->parent = -1; /* this field differentiates protos and fields */
@@ -4489,29 +4438,25 @@ header_field_info *
 proto_get_first_protocol_field(const int proto_id, void **cookie)
 {
        protocol_t       *protocol = find_protocol_by_id(proto_id);
-       hf_register_info *ptr;
 
        if ((protocol == NULL) || (protocol->fields == NULL))
                return NULL;
 
        *cookie = protocol->fields;
-       ptr = (hf_register_info *)protocol->fields->data;
-       return &ptr->hfinfo;
+       return (header_field_info *)protocol->fields->data;
 }
 
 header_field_info *
 proto_get_next_protocol_field(void **cookie)
 {
-       GList            *list_item = (GList *)*cookie;
-       hf_register_info *ptr;
+       GSList           *list_item = (GSList *)*cookie;
 
-       list_item = g_list_next(list_item);
+       list_item = g_slist_next(list_item);
        if (list_item == NULL)
                return NULL;
 
        *cookie = list_item;
-       ptr = (hf_register_info *)list_item->data;
-       return &ptr->hfinfo;
+       return (header_field_info *)list_item->data;
 }
 
 protocol_t *
@@ -4679,11 +4624,11 @@ proto_register_field_array(const int parent, hf_register_info *hf, const int num
 
                if (proto != NULL) {
                        if (proto->fields == NULL) {
-                               proto->fields = g_list_append(NULL, ptr);
+                               proto->fields = g_slist_append(NULL, &ptr->hfinfo);
                                proto->last_field = proto->fields;
                        } else {
                                proto->last_field =
-                                       g_list_append(proto->last_field, ptr)->next;
+                                       g_slist_append(proto->last_field, &ptr->hfinfo)->next;
                        }
                }
                field_id = proto_register_field_init(&ptr->hfinfo, parent);
@@ -4691,13 +4636,44 @@ proto_register_field_array(const int parent, hf_register_info *hf, const int num
        }
 }
 
+void
+proto_register_fields(const int parent, header_field_info **hfi, const int num_records)
+{
+       int               i;
+       protocol_t       *proto;
+
+       proto = find_protocol_by_id(parent);
+       for (i = 0; i < num_records; i++) {
+               /*
+                * Make sure we haven't registered this yet.
+                */
+               if (hfi[i]->id != -1) {
+                       fprintf(stderr,
+                               "Duplicate field detected in call to proto_register_field_array: %s is already registered\n",
+                               hfi[i]->abbrev);
+                       return;
+               }
+
+               if (proto != NULL) {
+                       if (proto->fields == NULL) {
+                               proto->fields = g_slist_append(NULL, hfi[i]);
+                               proto->last_field = proto->fields;
+                       } else {
+                               proto->last_field =
+                                       g_slist_append(proto->last_field, hfi[i])->next;
+                       }
+               }
+               proto_register_field_init(hfi[i], parent);
+       }
+}
+
 /* unregister already registered fields */
 void
 proto_unregister_field (const int parent, gint hf_id)
 {
        hf_register_info *hf;
        protocol_t       *proto;
-       GList            *field;
+       GSList           *field;
 
        if (hf_id == -1 || hf_id == 0)
                return;
@@ -4707,13 +4683,14 @@ proto_unregister_field (const int parent, gint hf_id)
                return;
        }
 
-       for (field = g_list_first (proto->fields); field; field = g_list_next (field)) {
+       for (field = proto->fields; field; field = field->next) {
                hf = (hf_register_info *)field->data;
                if (*hf->p_id == hf_id) {
                        /* Found the hf_id in this protocol */
                        g_tree_steal (gpa_name_tree, hf->hfinfo.abbrev);
-                       proto->fields = g_list_remove_link (proto->fields, field);
-                       proto->last_field = g_list_last (proto->fields);
+                       /* XXX, memleak? g_slist_delete_link() */
+                       proto->fields = g_slist_remove_link (proto->fields, field);
+                       proto->last_field = g_slist_last (proto->fields);
                        break;
                }
        }
@@ -4789,6 +4766,13 @@ static const value_string hf_display[] = {
        { BASE_DEC_HEX|BASE_RANGE_STRING, "BASE_DEC_HEX|BASE_RANGE_STRING" },
        { BASE_HEX_DEC|BASE_RANGE_STRING, "BASE_HEX_DEC|BASE_RANGE_STRING" },
        { BASE_CUSTOM|BASE_RANGE_STRING,  "BASE_CUSTOM|BASE_RANGE_STRING"  },
+       { BASE_NONE|BASE_VAL64_STRING,    "BASE_NONE|BASE_VAL64_STRING"    },
+       { BASE_DEC|BASE_VAL64_STRING,     "BASE_DEC|BASE_VAL64_STRING"     },
+       { BASE_HEX|BASE_VAL64_STRING,     "BASE_HEX|BASE_VAL64_STRING"     },
+       { BASE_OCT|BASE_VAL64_STRING,     "BASE_OCT|BASE_VAL64_STRING"     },
+       { BASE_DEC_HEX|BASE_VAL64_STRING, "BASE_DEC_HEX|BASE_VAL64_STRING" },
+       { BASE_HEX_DEC|BASE_VAL64_STRING, "BASE_HEX_DEC|BASE_VAL64_STRING" },
+       { BASE_CUSTOM|BASE_VAL64_STRING,  "BASE_CUSTOM|BASE_VAL64_STRING"  },
        { ABSOLUTE_TIME_LOCAL,            "ABSOLUTE_TIME_LOCAL"            },
        { ABSOLUTE_TIME_UTC,              "ABSOLUTE_TIME_UTC"              },
        { ABSOLUTE_TIME_DOY_UTC,          "ABSOLUTE_TIME_DOY_UTC"          },
@@ -4996,14 +4980,9 @@ proto_register_field_init(header_field_info *hfinfo, const int parent)
 
        tmp_fld_check_assert(hfinfo);
 
-       /* if this is a bitfield, compute bitshift */
-       if (hfinfo->bitmask) {
-               hfinfo->bitshift = wrs_count_bitshift(hfinfo->bitmask);
-       }
-
        hfinfo->parent         = parent;
        hfinfo->same_name_next = NULL;
-       hfinfo->same_name_prev = NULL;
+       hfinfo->same_name_prev_id = -1;
 
        /* if we always add and never delete, then id == len - 1 is correct */
        if (gpa_hfinfo.len >= gpa_hfinfo.allocated_len) {
@@ -5062,10 +5041,10 @@ proto_register_field_init(header_field_info *hfinfo, const int parent)
 
                        hfinfo->same_name_next = same_name_next_hfinfo;
                        if (same_name_next_hfinfo)
-                               same_name_next_hfinfo->same_name_prev = hfinfo;
+                               same_name_next_hfinfo->same_name_prev_id = hfinfo->id;
 
                        same_name_hfinfo->same_name_next = hfinfo;
-                       hfinfo->same_name_prev = same_name_hfinfo;
+                       hfinfo->same_name_prev_id = same_name_hfinfo->id;
                }
        }
 
@@ -5116,32 +5095,73 @@ proto_register_subtree_array(gint *const *indices, const int num_indices)
        }
 }
 
-static int
-label_fill_descr(char *label_str, const header_field_info *hfinfo, const char *text, const char *descr)
+static inline gsize
+label_concat(char *label_str, gsize pos, const char *str)
 {
-       gint ret;
+       if (pos < ITEM_LABEL_LENGTH)
+               pos += g_strlcpy(label_str + pos, str, ITEM_LABEL_LENGTH - pos);
 
-       ret = g_snprintf(label_str, ITEM_LABEL_LENGTH, "%s: %s (%s)", hfinfo->name, text, descr);
-       if (ret >= ITEM_LABEL_LENGTH) {
+       return pos;
+}
+
+static void
+label_mark_truncated(char *label_str, gsize name_pos)
+{
+       static const char trunc_str[] = " [truncated]";
+       const size_t trunc_len = sizeof(trunc_str)-1;
+
+       /* ..... field_name: dataaaaaaaaaaaaa
+        *                 |
+        *                 ^^^^^ name_pos
+        *
+        * ..... field_name [truncated]: dataaaaaaaaaaaaa */
+
+       if (name_pos < ITEM_LABEL_LENGTH - trunc_len) {
+               memmove(label_str + name_pos + trunc_len, label_str + name_pos, ITEM_LABEL_LENGTH - name_pos - trunc_len);
+               memcpy(label_str + name_pos, trunc_str, trunc_len);
+               label_str[ITEM_LABEL_LENGTH-1] = '\0';
+
+       } else if (name_pos < ITEM_LABEL_LENGTH)
+               g_strlcpy(label_str + name_pos, trunc_str, ITEM_LABEL_LENGTH - name_pos);
+}
+
+static gsize
+label_fill(char *label_str, gsize pos, const header_field_info *hfinfo, const char *text)
+{
+       gsize name_pos;
+
+       /* "%s: %s", hfinfo->name, text */
+       name_pos = pos = label_concat(label_str, pos, hfinfo->name);
+       pos = label_concat(label_str, pos, ": ");
+       pos = label_concat(label_str, pos, text ? text : "(null)");
+
+       if (pos >= ITEM_LABEL_LENGTH) {
                /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
-               ret = g_snprintf(label_str, ITEM_LABEL_LENGTH, "%s [truncated]: %s (%s)", hfinfo->name, text, descr);
+               label_mark_truncated(label_str, name_pos);
        }
 
-       return ret;
+       return pos;
 }
 
-static int
-label_fill(char *label_str, const header_field_info *hfinfo, const char *text)
+static gsize
+label_fill_descr(char *label_str, gsize pos, const header_field_info *hfinfo, const char *text, const char *descr)
 {
-       gint ret;
+       gsize name_pos;
+
+       /* "%s: %s (%s)", hfinfo->name, text, descr */
+       name_pos = pos = label_concat(label_str, pos, hfinfo->name);
+       pos = label_concat(label_str, pos, ": ");
+       pos = label_concat(label_str, pos, text ? text : "(null)");
+       pos = label_concat(label_str, pos, " (");
+       pos = label_concat(label_str, pos, descr ? descr : "(null)");
+       pos = label_concat(label_str, pos, ")");
 
-       ret = g_snprintf(label_str, ITEM_LABEL_LENGTH, "%s: %s", hfinfo->name, text);
-       if (ret >= ITEM_LABEL_LENGTH) {
+       if (pos >= ITEM_LABEL_LENGTH) {
                /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
-               ret = g_snprintf(label_str, ITEM_LABEL_LENGTH, "%s [truncated]: %s", hfinfo->name, text);
+               label_mark_truncated(label_str, name_pos);
        }
 
-       return ret;
+       return pos;
 }
 
 void
@@ -5155,6 +5175,7 @@ proto_item_fill_label(field_info *fi, gchar *label_str)
        e_guid_t          *guid;
        guint32            n_addr; /* network-order IPv4 address */
        const gchar       *name;
+       address            addr;
 
        if (!fi) {
                if (label_str)
@@ -5178,7 +5199,7 @@ proto_item_fill_label(field_info *fi, gchar *label_str)
                case FT_BYTES:
                case FT_UINT_BYTES:
                        bytes = (guint8 *)fvalue_get(&fi->value);
-                       label_fill(label_str, hfinfo,
+                       label_fill(label_str, 0, hfinfo,
                                        (bytes) ? bytes_to_str(bytes, fvalue_length(&fi->value)) : "<MISSING>");
                        break;
 
@@ -5193,7 +5214,7 @@ proto_item_fill_label(field_info *fi, gchar *label_str)
                case FT_UINT24:
                case FT_UINT32:
                        if (hfinfo->bitmask) {
-                               fill_label_bitfield(fi, label_str);
+                               fill_label_bitfield(fi, label_str, FALSE);
                        } else {
                                fill_label_number(fi, label_str, FALSE);
                        }
@@ -5211,8 +5232,11 @@ proto_item_fill_label(field_info *fi, gchar *label_str)
                case FT_INT16:
                case FT_INT24:
                case FT_INT32:
-                       DISSECTOR_ASSERT(!hfinfo->bitmask);
-                       fill_label_number(fi, label_str, TRUE);
+                       if (hfinfo->bitmask) {
+                               fill_label_bitfield(fi, label_str, TRUE);
+                       } else {
+                               fill_label_number(fi, label_str, TRUE);
+                       }
                        break;
 
                case FT_INT64:
@@ -5232,7 +5256,7 @@ proto_item_fill_label(field_info *fi, gchar *label_str)
                        break;
 
                case FT_ABSOLUTE_TIME:
-                       label_fill(label_str, hfinfo,
+                       label_fill(label_str, 0, hfinfo,
                                   abs_time_to_str((const nstime_t *)fvalue_get(&fi->value),
                                                (absolute_time_display_e)hfinfo->display, TRUE));
                        break;
@@ -5252,14 +5276,24 @@ proto_item_fill_label(field_info *fi, gchar *label_str)
 
                case FT_AX25:
                        bytes = (guint8 *)fvalue_get(&fi->value);
-                       label_fill_descr(label_str, hfinfo,
+                       label_fill_descr(label_str, 0, hfinfo,
                                   get_ax25_name(bytes),
                                   ax25_to_str(bytes));
                        break;
 
+               case FT_VINES:
+                       addr.type = AT_VINES;
+                       addr.len  = VINES_ADDR_LEN;
+                       addr.data = (guint8 *)fvalue_get(&fi->value);
+
+                       g_snprintf(label_str, ITEM_LABEL_LENGTH,
+                                  "%s: %s", hfinfo->name,
+                                  address_to_str( &addr ));
+                       break;
+
                case FT_ETHER:
                        bytes = (guint8 *)fvalue_get(&fi->value);
-                       label_fill_descr(label_str, hfinfo,
+                       label_fill_descr(label_str, 0, hfinfo,
                                   get_ether_name(bytes),
                                   ether_to_str(bytes));
                        break;
@@ -5267,37 +5301,37 @@ proto_item_fill_label(field_info *fi, gchar *label_str)
                case FT_IPv4:
                        ipv4 = (ipv4_addr *)fvalue_get(&fi->value);
                        n_addr = ipv4_get_net_order_addr(ipv4);
-                       label_fill_descr(label_str, hfinfo,
+                       label_fill_descr(label_str, 0, hfinfo,
                                   get_hostname(n_addr),
                                   ip_to_str((guint8*)&n_addr));
                        break;
 
                case FT_IPv6:
                        bytes = (guint8 *)fvalue_get(&fi->value);
-                       label_fill_descr(label_str, hfinfo,
+                       label_fill_descr(label_str, 0, hfinfo,
                                   get_hostname6((struct e_in6_addr *)bytes),
                                   ip6_to_str((struct e_in6_addr*)bytes));
                        break;
 
                case FT_GUID:
                        guid = (e_guid_t *)fvalue_get(&fi->value);
-                       label_fill(label_str, hfinfo, guid_to_str(guid));
+                       label_fill(label_str, 0, hfinfo, guid_to_str(guid));
                        break;
 
                case FT_OID:
                        bytes = (guint8 *)fvalue_get(&fi->value);
                        name = oid_resolved_from_encoded(bytes, fvalue_length(&fi->value));
                        if (name) {
-                               label_fill_descr(label_str, hfinfo,
+                               label_fill_descr(label_str, 0, hfinfo,
                                         oid_encoded2string(bytes, fvalue_length(&fi->value)), name);
                        } else {
-                               label_fill(label_str, hfinfo,
+                               label_fill(label_str, 0, hfinfo,
                                         oid_encoded2string(bytes, fvalue_length(&fi->value)));
                        }
                        break;
                case FT_EUI64:
                        integer64 = fvalue_get_integer64(&fi->value);
-                       label_fill_descr(label_str, hfinfo,
+                       label_fill_descr(label_str, 0, hfinfo,
                                   get_eui64_name(integer64),
                                   eui64_to_str(integer64));
                        break;
@@ -5305,7 +5339,7 @@ proto_item_fill_label(field_info *fi, gchar *label_str)
                case FT_STRINGZ:
                case FT_UINT_STRING:
                        bytes = (guint8 *)fvalue_get(&fi->value);
-                       label_fill(label_str, hfinfo, format_text(bytes, strlen(bytes)));
+                       label_fill(label_str, 0, hfinfo, format_text(bytes, strlen(bytes)));
                        break;
 
                default:
@@ -5338,9 +5372,7 @@ fill_label_boolean(field_info *fi, gchar *label_str)
 
                /* Un-shift bits */
                unshifted_value = value;
-               if (hfinfo->bitshift > 0) {
-                       unshifted_value <<= hfinfo->bitshift;
-               }
+               unshifted_value <<= hfinfo_bitshift(hfinfo);
 
                /* Create the bitfield first */
                p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
@@ -5348,9 +5380,7 @@ fill_label_boolean(field_info *fi, gchar *label_str)
        }
 
        /* Fill in the textual info */
-       g_snprintf(p, ITEM_LABEL_LENGTH - bitfield_byte_length,
-                  "%s: %s",  hfinfo->name,
-                  value ? tfstring->true_string : tfstring->false_string);
+       label_fill(label_str, bitfield_byte_length, hfinfo, value ? tfstring->true_string : tfstring->false_string);
 }
 
 static const char *
@@ -5362,9 +5392,28 @@ hf_try_val_to_str(guint32 value, const header_field_info *hfinfo)
        if (hfinfo->display & BASE_EXT_STRING)
                return try_val_to_str_ext(value, (const value_string_ext *) hfinfo->strings);
 
+       if (hfinfo->display & BASE_VAL64_STRING)
+               return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
+
        return try_val_to_str(value, (const value_string *) hfinfo->strings);
 }
 
+static const char *
+hf_try_val64_to_str(guint64 value, const header_field_info *hfinfo)
+{
+       if (hfinfo->display & BASE_VAL64_STRING)
+               return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
+
+       /* If this is reached somebody registered a 64-bit field with a 32-bit
+        * value-string, which isn't right. */
+       DISSECTOR_ASSERT_NOT_REACHED();
+
+       /* This is necessary to squelch MSVC errors; is there
+          any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
+          never returns? */
+       return NULL;
+}
+
 static const char *
 hf_try_val_to_str_const(guint32 value, const header_field_info *hfinfo, const char *unknown_str)
 {
@@ -5373,9 +5422,17 @@ hf_try_val_to_str_const(guint32 value, const header_field_info *hfinfo, const ch
        return (str) ? str : unknown_str;
 }
 
+static const char *
+hf_try_val64_to_str_const(guint64 value, const header_field_info *hfinfo, const char *unknown_str)
+{
+       const char *str = hf_try_val64_to_str(value, hfinfo);
+
+       return (str) ? str : unknown_str;
+}
+
 /* Fills data for bitfield ints with val_strings */
 static void
-fill_label_bitfield(field_info *fi, gchar *label_str)
+fill_label_bitfield(field_info *fi, gchar *label_str, gboolean is_signed)
 {
        char       *p;
        int         bitfield_byte_length, bitwidth;
@@ -5391,10 +5448,14 @@ fill_label_bitfield(field_info *fi, gchar *label_str)
        bitwidth = hfinfo_bitwidth(hfinfo);
 
        /* Un-shift bits */
-       unshifted_value = fvalue_get_uinteger(&fi->value);
+       if (is_signed)
+               unshifted_value = fvalue_get_sinteger(&fi->value);
+       else
+               unshifted_value = fvalue_get_uinteger(&fi->value);
+
        value = unshifted_value;
-       if (hfinfo->bitshift > 0) {
-               unshifted_value <<= hfinfo->bitshift;
+       if (hfinfo->bitmask) {
+               unshifted_value <<= hfinfo_bitshift(hfinfo);
        }
 
        /* Create the bitfield first */
@@ -5408,25 +5469,21 @@ fill_label_bitfield(field_info *fi, gchar *label_str)
 
                DISSECTOR_ASSERT(fmtfunc);
                fmtfunc(tmp, value);
-               g_snprintf(p, ITEM_LABEL_LENGTH - bitfield_byte_length,
-                          "%s: %s", hfinfo->name, tmp);
+               label_fill(label_str, bitfield_byte_length, hfinfo, tmp);
        }
        else if (hfinfo->strings) {
                const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
 
                out = hfinfo_number_vals_format(hfinfo, buf, value);
                if (out == NULL) /* BASE_NONE so don't put integer in descr */
-                       g_snprintf(p, ITEM_LABEL_LENGTH - bitfield_byte_length,
-                          "%s: %s",  hfinfo->name, val_str);
+                       label_fill(label_str, bitfield_byte_length, hfinfo, val_str);
                else
-                       g_snprintf(p, ITEM_LABEL_LENGTH - bitfield_byte_length,
-                          "%s: %s (%s)",  hfinfo->name, val_str, out);
+                       label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out);
        }
        else {
                out = hfinfo_number_value_format(hfinfo, buf, value);
 
-               g_snprintf(p, ITEM_LABEL_LENGTH - bitfield_byte_length,
-                                  "%s: %s",  hfinfo->name, out);
+               label_fill(label_str, bitfield_byte_length, hfinfo, out);
        }
 }
 
@@ -5451,21 +5508,21 @@ fill_label_number(field_info *fi, gchar *label_str, gboolean is_signed)
 
                DISSECTOR_ASSERT(fmtfunc);
                fmtfunc(tmp, value);
-               label_fill(label_str, hfinfo, tmp);
+               label_fill(label_str, 0, hfinfo, tmp);
        }
        else if (hfinfo->strings) {
                const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
 
                out = hfinfo_number_vals_format(hfinfo, buf, value);
                if (out == NULL) /* BASE_NONE so don't put integer in descr */
-                       label_fill(label_str, hfinfo, val_str);
+                       label_fill(label_str, 0, hfinfo, val_str);
                else
-                       label_fill_descr(label_str, hfinfo, val_str, out);
+                       label_fill_descr(label_str, 0, hfinfo, val_str, out);
        }
        else {
                out = hfinfo_number_value_format(hfinfo, buf, value);
 
-               label_fill(label_str, hfinfo, out);
+               label_fill(label_str, 0, hfinfo, out);
        }
 }
 
@@ -5475,6 +5532,7 @@ fill_label_number64(field_info *fi, gchar *label_str, gboolean is_signed)
        const char        *format = NULL;
        header_field_info *hfinfo = fi->hfinfo;
        guint64            value;
+       char               tmp[ITEM_LABEL_LENGTH+1];
 
        /* Pick the proper format string */
        if (is_signed)
@@ -5484,16 +5542,47 @@ fill_label_number64(field_info *fi, gchar *label_str, gboolean is_signed)
 
        value = fvalue_get_integer64(&fi->value);
 
-       /* Fill in the textual info */
-       if (IS_BASE_DUAL(hfinfo->display)) {
-               g_snprintf(label_str, ITEM_LABEL_LENGTH,
-                          format,  hfinfo->name, value, value);
-       } else {
-               g_snprintf(label_str, ITEM_LABEL_LENGTH,
-                          format,  hfinfo->name, value);
+       /* Format the temporary string */
+       if (IS_BASE_DUAL(hfinfo->display))
+               g_snprintf(tmp, ITEM_LABEL_LENGTH, format, value, value);
+       else
+               g_snprintf(tmp, ITEM_LABEL_LENGTH, format, value);
+
+       if (hfinfo->strings) {
+               const char *val_str = hf_try_val64_to_str_const(value, hfinfo, "Unknown");
+
+               if ((hfinfo->display & BASE_DISPLAY_E_MASK) == BASE_NONE) {
+                       label_fill(label_str, 0, hfinfo, val_str);
+               }
+               else {
+                       label_fill_descr(label_str, 0, hfinfo, val_str, tmp);
+               }
+       }
+       else {
+               label_fill(label_str, 0, hfinfo, tmp);
        }
 }
 
+int
+hfinfo_bitshift(const header_field_info *hfinfo)
+{
+       const guint32 bitmask = hfinfo->bitmask;
+
+#if defined(__GNUC__) && ((__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
+       g_assert(bitmask != 0);
+
+       return __builtin_ctz(bitmask);
+#else
+       /* From http://graphics.stanford.edu/~seander/bithacks.html#ZerosOnRightMultLookup */
+       static const int table[32] = {
+               0,   1, 28,  2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17,  4, 8,
+               31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18,  6, 11,  5, 10, 9
+       };
+
+       return table[((guint32)((bitmask & -(gint32)bitmask) * 0x077CB531U)) >> 27];
+#endif
+}
+
 int
 hfinfo_bitwidth(const header_field_info *hfinfo)
 {
@@ -5564,7 +5653,7 @@ char *uint_to_str_back(char *ptr, guint32 value);
 char *int_to_str_back(char *ptr, gint32 value);
 
 static const char *
-_hfinfo_number_value_format(const header_field_info *hfinfo, int display, char buf[32], guint32 value)
+hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[32], guint32 value)
 {
        char *ptr = &buf[31];
        gboolean isint = IS_FT_INT(hfinfo->type);
@@ -5616,7 +5705,7 @@ hfinfo_number_value_format(const header_field_info *hfinfo, char buf[32], guint3
                display = BASE_DEC;
        }
 
-       return _hfinfo_number_value_format(hfinfo, display, buf, value);
+       return hfinfo_number_value_format_display(hfinfo, display, buf, value);
 }
 
 static const char *
@@ -5647,7 +5736,7 @@ hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[32], guint
                        break;
        }
 
-       return _hfinfo_number_value_format(hfinfo, display, buf, value);
+       return hfinfo_number_value_format_display(hfinfo, display, buf, value);
 }
 
 static const char *
@@ -5664,7 +5753,7 @@ hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[32], guint32
        if (display == BASE_HEX_DEC)
                display = BASE_HEX;
 
-       return _hfinfo_number_value_format(hfinfo, display, buf, value);
+       return hfinfo_number_value_format_display(hfinfo, display, buf, value);
 }
 
 static const char *
@@ -5673,21 +5762,21 @@ hfinfo_uint64_format(const header_field_info *hfinfo)
        const char *format = NULL;
 
        /* Pick the proper format string */
-       switch (hfinfo->display) {
+       switch (hfinfo->display & BASE_DISPLAY_E_MASK) {
                case BASE_DEC:
-                       format = "%s: %" G_GINT64_MODIFIER "u";
+                       format = "%" G_GINT64_MODIFIER "u";
                        break;
                case BASE_DEC_HEX:
-                       format = "%s: %" G_GINT64_MODIFIER "u (0x%016" G_GINT64_MODIFIER "x)";
+                       format = "%" G_GINT64_MODIFIER "u (0x%016" G_GINT64_MODIFIER "x)";
                        break;
                case BASE_OCT: /* I'm lazy */
-                       format = "%s: %#" G_GINT64_MODIFIER "o";
+                       format = "%#" G_GINT64_MODIFIER "o";
                        break;
                case BASE_HEX:
-                       format = "%s: 0x%016" G_GINT64_MODIFIER "x";
+                       format = "0x%016" G_GINT64_MODIFIER "x";
                        break;
                case BASE_HEX_DEC:
-                       format = "%s: 0x%016" G_GINT64_MODIFIER "x (%" G_GINT64_MODIFIER "u)";
+                       format = "0x%016" G_GINT64_MODIFIER "x (%" G_GINT64_MODIFIER "u)";
                        break;
                default:
                        DISSECTOR_ASSERT_NOT_REACHED();
@@ -5702,21 +5791,21 @@ hfinfo_int64_format(const header_field_info *hfinfo)
        const char *format = NULL;
 
        /* Pick the proper format string */
-       switch (hfinfo->display) {
+       switch (hfinfo->display & BASE_DISPLAY_E_MASK) {
                case BASE_DEC:
-                       format = "%s: %" G_GINT64_MODIFIER "d";
+                       format = "%" G_GINT64_MODIFIER "d";
                        break;
                case BASE_DEC_HEX:
-                       format = "%s: %" G_GINT64_MODIFIER "d (0x%016" G_GINT64_MODIFIER "x)";
+                       format = "%" G_GINT64_MODIFIER "d (0x%016" G_GINT64_MODIFIER "x)";
                        break;
                case BASE_OCT: /* I'm lazy */
-                       format = "%s: %#" G_GINT64_MODIFIER "o";
+                       format = "%#" G_GINT64_MODIFIER "o";
                        break;
                case BASE_HEX:
-                       format = "%s: 0x%016" G_GINT64_MODIFIER "x";
+                       format = "0x%016" G_GINT64_MODIFIER "x";
                        break;
                case BASE_HEX_DEC:
-                       format = "%s: 0x%016" G_GINT64_MODIFIER "x (%" G_GINT64_MODIFIER "d)";
+                       format = "0x%016" G_GINT64_MODIFIER "x (%" G_GINT64_MODIFIER "d)";
                        break;
                default:
                        DISSECTOR_ASSERT_NOT_REACHED();
@@ -6022,6 +6111,7 @@ proto_registrar_dump_values(void)
        header_field_info       *hfinfo;
        int                     i, len, vi;
        const value_string      *vals;
+       const val64_string      *vals64;
        const range_string      *range;
        const true_false_string *tfs;
 
@@ -6051,12 +6141,13 @@ proto_registrar_dump_values(void)
                         * *maximum* length is 2 bytes, and be used
                         * for all lengths.)
                         */
-                       if (hfinfo->same_name_prev != NULL)
+                       if (hfinfo->same_name_prev_id != -1)
                                continue;
 
-                       vals  = NULL;
-                       range = NULL;
-                       tfs   = NULL;
+                       vals   = NULL;
+                       vals64 = NULL;
+                       range  = NULL;
+                       tfs    = NULL;
 
                        if (hfinfo->strings != NULL) {
                                if ((hfinfo->display & BASE_DISPLAY_E_MASK) != BASE_CUSTOM &&
@@ -6075,6 +6166,8 @@ proto_registrar_dump_values(void)
                                                vals = VALUE_STRING_EXT_VS_P((const value_string_ext *)hfinfo->strings);
                                        } else if ((hfinfo->display & BASE_RANGE_STRING) == 0) {
                                                vals = (const value_string *)hfinfo->strings;
+                                       } else if ((hfinfo->display & BASE_VAL64_STRING) == 0) {
+                                               vals64 = (const val64_string *)hfinfo->strings;
                                        } else {
                                                range = (const range_string *)hfinfo->strings;
                                        }
@@ -6117,6 +6210,16 @@ proto_registrar_dump_values(void)
                                        vi++;
                                }
                        }
+                       else if (vals64) {
+                               vi = 0;
+                               while (vals64[vi].strptr) {
+                                       printf("V64\t%s\t%" G_GINT64_MODIFIER "u\t%s\n",
+                                               hfinfo->abbrev,
+                                               vals64[vi].value,
+                                               vals64[vi].strptr);
+                                       vi++;
+                               }
+                       }
 
                        /* print range strings? */
                        else if (range) {
@@ -6213,7 +6316,7 @@ proto_registrar_dump_fields(void)
                         * *maximum* length is 2 bytes, and be used
                         * for all lengths.)
                         */
-                       if (hfinfo->same_name_prev != NULL)
+                       if (hfinfo->same_name_prev_id != -1)
                                continue;
 
                        PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo);
@@ -6656,7 +6759,7 @@ proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, const int offset,
                        fields++;
                        continue;
                }
-               tmpval = (value & hf->bitmask) >> hf->bitshift;
+               tmpval = (value & hf->bitmask) >> hfinfo_bitshift(hf);
 
                switch (hf->type) {
                case FT_INT8:
@@ -6849,15 +6952,27 @@ proto_tree_add_bitmask_text(proto_tree *parent_tree, tvbuff_t *tvb,
 }
 
 proto_item *
-proto_tree_add_bits_item(proto_tree *tree, const int hf_index, tvbuff_t *tvb,
+proto_tree_add_bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
                         const guint bit_offset, const gint no_of_bits,
                         const guint encoding)
 {
        header_field_info *hfinfo;
+       gint              octet_length;
+       gint              octet_offset;
+
+       PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
+
+       octet_length = (no_of_bits + 7) >> 3;
+       octet_offset = bit_offset >> 3;
+       test_length(hfinfo, tree, tvb, octet_offset, octet_length, encoding);
 
-       TRY_TO_FAKE_THIS_ITEM(tree, hf_index, hfinfo);
+       /* Yes, we try to fake this item again in proto_tree_add_bits_ret_val()
+        * but only after doing a bunch more work (which we can, in the common
+        * case, shortcut here).
+        */
+       TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
 
-       return proto_tree_add_bits_ret_val(tree, hf_index, tvb, bit_offset, no_of_bits, NULL, encoding);
+       return proto_tree_add_bits_ret_val(tree, hfindex, tvb, bit_offset, no_of_bits, NULL, encoding);
 }
 
 /*
@@ -6867,7 +6982,7 @@ proto_tree_add_bits_item(proto_tree *tree, const int hf_index, tvbuff_t *tvb,
  */
 
 static proto_item *
-_proto_tree_add_bits_ret_val(proto_tree *tree, const int hf_index, tvbuff_t *tvb,
+_proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
                            const guint bit_offset, const gint no_of_bits,
                            guint64 *return_value, const guint encoding)
 {
@@ -6884,7 +6999,7 @@ _proto_tree_add_bits_ret_val(proto_tree *tree, const int hf_index, tvbuff_t *tvb
        const true_false_string *tfstring;
 
        /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
-       PROTO_REGISTRAR_GET_NTH(hf_index, hf_field);
+       PROTO_REGISTRAR_GET_NTH(hfindex, hf_field);
 
        if (hf_field->bitmask != 0) {
                REPORT_DISSECTOR_BUG(ep_strdup_printf("Incompatible use of proto_tree_add_bits_ret_val"
@@ -6901,10 +7016,7 @@ _proto_tree_add_bits_ret_val(proto_tree *tree, const int hf_index, tvbuff_t *tvb
         * Calculate the number of octets used to hold the bits
         */
        tot_no_bits = ((bit_offset&0x7) + no_of_bits);
-       length = tot_no_bits>>3;
-       /* If we are using part of the next octet, increase length by 1 */
-       if (tot_no_bits & 0x07)
-               length++;
+       length = (tot_no_bits + 7) >> 3;
 
        if (no_of_bits < 65) {
                value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
@@ -6933,7 +7045,7 @@ _proto_tree_add_bits_ret_val(proto_tree *tree, const int hf_index, tvbuff_t *tvb
        }
 
        /* Coast clear. Try and fake it */
-       TRY_TO_FAKE_THIS_ITEM(tree, hf_index, hf_field);
+       TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
 
        bf_str = decode_bits_in_field(bit_offset, no_of_bits, value);
 
@@ -6943,7 +7055,7 @@ _proto_tree_add_bits_ret_val(proto_tree *tree, const int hf_index, tvbuff_t *tvb
                tfstring = (const true_false_string *) &tfs_true_false;
                if (hf_field->strings)
                        tfstring = (const true_false_string *)hf_field->strings;
-               return proto_tree_add_boolean_format(tree, hf_index, tvb, offset, length, (guint32)value,
+               return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, (guint32)value,
                        "%s = %s: %s",
                        bf_str, hf_field->name,
                        (guint32)value ? tfstring->true_string : tfstring->false_string);
@@ -6953,7 +7065,7 @@ _proto_tree_add_bits_ret_val(proto_tree *tree, const int hf_index, tvbuff_t *tvb
        case FT_UINT16:
        case FT_UINT24:
        case FT_UINT32:
-               pi = proto_tree_add_uint(tree, hf_index, tvb, offset, length, (guint32)value);
+               pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (guint32)value);
                fill_label_number(PITEM_FINFO(pi), lbl_str, FALSE);
                break;
 
@@ -6961,17 +7073,17 @@ _proto_tree_add_bits_ret_val(proto_tree *tree, const int hf_index, tvbuff_t *tvb
        case FT_INT16:
        case FT_INT24:
        case FT_INT32:
-               pi = proto_tree_add_int(tree, hf_index, tvb, offset, length, (gint32)value);
+               pi = proto_tree_add_int(tree, hfindex, tvb, offset, length, (gint32)value);
                fill_label_number(PITEM_FINFO(pi), lbl_str, TRUE);
                break;
 
        case FT_UINT64:
-               pi = proto_tree_add_uint64(tree, hf_index, tvb, offset, length, value);
+               pi = proto_tree_add_uint64(tree, hfindex, tvb, offset, length, value);
                fill_label_number64(PITEM_FINFO(pi), lbl_str, FALSE);
                break;
 
        case FT_INT64:
-               pi = proto_tree_add_int64(tree, hf_index, tvb, offset, length, (gint64)value);
+               pi = proto_tree_add_int64(tree, hfindex, tvb, offset, length, (gint64)value);
                fill_label_number64(PITEM_FINFO(pi), lbl_str, TRUE);
                break;
 
@@ -6986,7 +7098,7 @@ _proto_tree_add_bits_ret_val(proto_tree *tree, const int hf_index, tvbuff_t *tvb
 }
 
 proto_item *
-proto_tree_add_split_bits_item_ret_val(proto_tree *tree, const int hf_index, tvbuff_t *tvb,
+proto_tree_add_split_bits_item_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
                                       const guint bit_offset, const crumb_spec_t *crumb_spec,
                                       guint64 *return_value)
 {
@@ -7007,7 +7119,7 @@ proto_tree_add_split_bits_item_ret_val(proto_tree *tree, const int hf_index, tvb
        const true_false_string *tfstring;
 
        /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
-       PROTO_REGISTRAR_GET_NTH(hf_index, hf_field);
+       PROTO_REGISTRAR_GET_NTH(hfindex, hf_field);
 
        if (hf_field->bitmask != 0) {
                REPORT_DISSECTOR_BUG(ep_strdup_printf(
@@ -7077,7 +7189,7 @@ proto_tree_add_split_bits_item_ret_val(proto_tree *tree, const int hf_index, tvb
        }
 
        /* Coast clear. Try and fake it */
-       TRY_TO_FAKE_THIS_ITEM(tree, hf_index, hf_field);
+       TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
 
        /* initialise the format string */
        bf_str    = (char *)ep_alloc(256);
@@ -7104,7 +7216,7 @@ proto_tree_add_split_bits_item_ret_val(proto_tree *tree, const int hf_index, tvb
                tfstring = (const true_false_string *) &tfs_true_false;
                if (hf_field->strings)
                        tfstring = (const true_false_string *) hf_field->strings;
-               return proto_tree_add_boolean_format(tree, hf_index,
+               return proto_tree_add_boolean_format(tree, hfindex,
                                                     tvb, octet_offset, octet_length, (guint32)value,
                                                     "%s = %s: %s",
                                                     bf_str, hf_field->name,
@@ -7115,7 +7227,7 @@ proto_tree_add_split_bits_item_ret_val(proto_tree *tree, const int hf_index, tvb
        case FT_UINT16:
        case FT_UINT24:
        case FT_UINT32:
-               pi = proto_tree_add_uint(tree, hf_index, tvb, octet_offset, octet_length, (guint32)value);
+               pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (guint32)value);
                fill_label_number(PITEM_FINFO(pi), lbl_str, FALSE);
                break;
 
@@ -7123,17 +7235,17 @@ proto_tree_add_split_bits_item_ret_val(proto_tree *tree, const int hf_index, tvb
        case FT_INT16:
        case FT_INT24:
        case FT_INT32:
-               pi = proto_tree_add_int(tree, hf_index, tvb, octet_offset, octet_length, (gint32)value);
+               pi = proto_tree_add_int(tree, hfindex, tvb, octet_offset, octet_length, (gint32)value);
                fill_label_number(PITEM_FINFO(pi), lbl_str, TRUE);
                break;
 
        case FT_UINT64:
-               pi = proto_tree_add_uint64(tree, hf_index, tvb, octet_offset, octet_length, value);
+               pi = proto_tree_add_uint64(tree, hfindex, tvb, octet_offset, octet_length, value);
                fill_label_number64(PITEM_FINFO(pi), lbl_str, FALSE);
                break;
 
        case FT_INT64:
-               pi = proto_tree_add_int64(tree, hf_index, tvb, octet_offset, octet_length, (gint64)value);
+               pi = proto_tree_add_int64(tree, hfindex, tvb, octet_offset, octet_length, (gint64)value);
                fill_label_number64(PITEM_FINFO(pi), lbl_str, TRUE);
                break;
 
@@ -7147,12 +7259,12 @@ proto_tree_add_split_bits_item_ret_val(proto_tree *tree, const int hf_index, tvb
 }
 
 void
-proto_tree_add_split_bits_crumb(proto_tree *tree, const int hf_index, tvbuff_t *tvb, const guint bit_offset,
+proto_tree_add_split_bits_crumb(proto_tree *tree, const int hfindex, tvbuff_t *tvb, const guint bit_offset,
                                const crumb_spec_t *crumb_spec, guint16 crumb_index)
 {
-       header_field_info *hf_info;
+       header_field_info *hfinfo;
 
-       PROTO_REGISTRAR_GET_NTH(hf_index, hf_info);
+       PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
        proto_tree_add_text(tree, tvb,
                            bit_offset >> 3,
                            ((bit_offset + crumb_spec[crumb_index].crumb_bit_length - 1) >> 3) - (bit_offset >> 3) + 1,
@@ -7163,17 +7275,17 @@ proto_tree_add_split_bits_crumb(proto_tree *tree, const int hf_index, tvbuff_t *
                                                              crumb_spec[crumb_index].crumb_bit_length,
                                                              ENC_BIG_ENDIAN)),
                            crumb_index,
-                           hf_info->name);
+                           hfinfo->name);
 }
 
 proto_item *
-proto_tree_add_bits_ret_val(proto_tree *tree, const int hf_index, tvbuff_t *tvb,
+proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
                            const guint bit_offset, const gint no_of_bits,
                            guint64 *return_value, const guint encoding)
 {
        proto_item *item;
 
-       if ((item = _proto_tree_add_bits_ret_val(tree, hf_index, tvb,
+       if ((item = _proto_tree_add_bits_ret_val(tree, hfindex, tvb,
                                                 bit_offset, no_of_bits,
                                                 return_value, encoding))) {
                FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_OFFSET(bit_offset));
@@ -7183,7 +7295,7 @@ proto_tree_add_bits_ret_val(proto_tree *tree, const int hf_index, tvbuff_t *tvb,
 }
 
 static proto_item *
-_proto_tree_add_bits_format_value(proto_tree *tree, const int hf_index,
+_proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
                                 tvbuff_t *tvb, const guint bit_offset,
                                 const gint no_of_bits, void *value_ptr,
                                 gchar *value_str)
@@ -7196,7 +7308,7 @@ _proto_tree_add_bits_format_value(proto_tree *tree, const int hf_index,
        header_field_info *hf_field;
 
        /* We do not have to return a value, try to fake it as soon as possible */
-       TRY_TO_FAKE_THIS_ITEM(tree, hf_index, hf_field);
+       TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
 
        if (hf_field->bitmask != 0) {
                REPORT_DISSECTOR_BUG(ep_strdup_printf(
@@ -7240,7 +7352,7 @@ _proto_tree_add_bits_format_value(proto_tree *tree, const int hf_index,
         */
        switch (hf_field->type) {
        case FT_BOOLEAN:
-               return proto_tree_add_boolean_format(tree, hf_index, tvb, offset, length, *(guint32 *)value_ptr,
+               return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, *(guint32 *)value_ptr,
                                                     "%s: %s", str, value_str);
                break;
 
@@ -7248,12 +7360,12 @@ _proto_tree_add_bits_format_value(proto_tree *tree, const int hf_index,
        case FT_UINT16:
        case FT_UINT24:
        case FT_UINT32:
-               return proto_tree_add_uint_format(tree, hf_index, tvb, offset, length, *(guint32 *)value_ptr,
+               return proto_tree_add_uint_format(tree, hfindex, tvb, offset, length, *(guint32 *)value_ptr,
                                                  "%s: %s", str, value_str);
                break;
 
        case FT_UINT64:
-               return proto_tree_add_uint64_format(tree, hf_index, tvb, offset, length, *(guint64 *)value_ptr,
+               return proto_tree_add_uint64_format(tree, hfindex, tvb, offset, length, *(guint64 *)value_ptr,
                                                    "%s: %s", str, value_str);
                break;
 
@@ -7261,17 +7373,17 @@ _proto_tree_add_bits_format_value(proto_tree *tree, const int hf_index,
        case FT_INT16:
        case FT_INT24:
        case FT_INT32:
-               return proto_tree_add_int_format(tree, hf_index, tvb, offset, length, *(gint32 *)value_ptr,
+               return proto_tree_add_int_format(tree, hfindex, tvb, offset, length, *(gint32 *)value_ptr,
                                                 "%s: %s", str, value_str);
                break;
 
        case FT_INT64:
-               return proto_tree_add_int64_format(tree, hf_index, tvb, offset, length, *(gint64 *)value_ptr,
+               return proto_tree_add_int64_format(tree, hfindex, tvb, offset, length, *(gint64 *)value_ptr,
                                                   "%s: %s", str, value_str);
                break;
 
        case FT_FLOAT:
-               return proto_tree_add_float_format(tree, hf_index, tvb, offset, length, *(float *)value_ptr,
+               return proto_tree_add_float_format(tree, hfindex, tvb, offset, length, *(float *)value_ptr,
                                                   "%s: %s", str, value_str);
                break;
 
@@ -7283,14 +7395,14 @@ _proto_tree_add_bits_format_value(proto_tree *tree, const int hf_index,
 }
 
 static proto_item *
-proto_tree_add_bits_format_value(proto_tree *tree, const int hf_index,
+proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
                                 tvbuff_t *tvb, const guint bit_offset,
                                 const gint no_of_bits, void *value_ptr,
                                 gchar *value_str)
 {
        proto_item *item;
 
-       if ((item = _proto_tree_add_bits_format_value(tree, hf_index,
+       if ((item = _proto_tree_add_bits_format_value(tree, hfindex,
                                                      tvb, bit_offset, no_of_bits,
                                                      value_ptr, value_str))) {
                FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_OFFSET(bit_offset));
@@ -7305,7 +7417,7 @@ proto_tree_add_bits_format_value(proto_tree *tree, const int hf_index,
        va_end(ap);
 
 proto_item *
-proto_tree_add_uint_bits_format_value(proto_tree *tree, const int hf_index,
+proto_tree_add_uint_bits_format_value(proto_tree *tree, const int hfindex,
                                      tvbuff_t *tvb, const guint bit_offset,
                                      const gint no_of_bits, guint32 value,
                                      const char *format, ...)
@@ -7314,7 +7426,7 @@ proto_tree_add_uint_bits_format_value(proto_tree *tree, const int hf_index,
        gchar  *dst;
        header_field_info *hf_field;
 
-       TRY_TO_FAKE_THIS_ITEM(tree, hf_index, hf_field);
+       TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
 
        switch (hf_field->type) {
                case FT_UINT8:
@@ -7331,11 +7443,11 @@ proto_tree_add_uint_bits_format_value(proto_tree *tree, const int hf_index,
 
        CREATE_VALUE_STRING(dst, format, ap);
 
-       return proto_tree_add_bits_format_value(tree, hf_index, tvb, bit_offset, no_of_bits, &value, dst);
+       return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
 }
 
 proto_item *
-proto_tree_add_float_bits_format_value(proto_tree *tree, const int hf_index,
+proto_tree_add_float_bits_format_value(proto_tree *tree, const int hfindex,
                                       tvbuff_t *tvb, const guint bit_offset,
                                       const gint no_of_bits, float value,
                                       const char *format, ...)
@@ -7344,17 +7456,17 @@ proto_tree_add_float_bits_format_value(proto_tree *tree, const int hf_index,
        gchar  *dst;
        header_field_info *hf_field;
 
-       TRY_TO_FAKE_THIS_ITEM(tree, hf_index, hf_field);
+       TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
 
        DISSECTOR_ASSERT(hf_field->type == FT_FLOAT);
 
        CREATE_VALUE_STRING(dst, format, ap);
 
-       return proto_tree_add_bits_format_value(tree, hf_index, tvb, bit_offset, no_of_bits, &value, dst);
+       return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
 }
 
 proto_item *
-proto_tree_add_int_bits_format_value(proto_tree *tree, const int hf_index,
+proto_tree_add_int_bits_format_value(proto_tree *tree, const int hfindex,
                                     tvbuff_t *tvb, const guint bit_offset,
                                     const gint no_of_bits, gint32 value,
                                     const char *format, ...)
@@ -7363,7 +7475,7 @@ proto_tree_add_int_bits_format_value(proto_tree *tree, const int hf_index,
        gchar  *dst;
        header_field_info *hf_field;
 
-       TRY_TO_FAKE_THIS_ITEM(tree, hf_index, hf_field);
+       TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
 
        switch (hf_field->type) {
                case FT_INT8:
@@ -7380,11 +7492,11 @@ proto_tree_add_int_bits_format_value(proto_tree *tree, const int hf_index,
 
        CREATE_VALUE_STRING(dst, format, ap);
 
-       return proto_tree_add_bits_format_value(tree, hf_index, tvb, bit_offset, no_of_bits, &value, dst);
+       return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
 }
 
 proto_item *
-proto_tree_add_boolean_bits_format_value(proto_tree *tree, const int hf_index,
+proto_tree_add_boolean_bits_format_value(proto_tree *tree, const int hfindex,
                                         tvbuff_t *tvb, const guint bit_offset,
                                         const gint no_of_bits, guint32 value,
                                         const char *format, ...)
@@ -7393,13 +7505,13 @@ proto_tree_add_boolean_bits_format_value(proto_tree *tree, const int hf_index,
        gchar  *dst;
        header_field_info *hf_field;
 
-       TRY_TO_FAKE_THIS_ITEM(tree, hf_index, hf_field);
+       TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
 
        DISSECTOR_ASSERT(hf_field->type == FT_BOOLEAN);
 
        CREATE_VALUE_STRING(dst, format, ap);
 
-       return proto_tree_add_bits_format_value(tree, hf_index, tvb, bit_offset, no_of_bits, &value, dst);
+       return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
 }
 
 guchar