From Jiri Engelthaler via
[metze/wireshark/wip.git] / epan / proto.c
index b2bbe1cba4eb937975525e8c1b0cdbc0acca531d..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,7 +127,7 @@ 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);
 
@@ -166,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);
@@ -190,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);
@@ -246,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 */
@@ -291,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;
@@ -419,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);
        }
@@ -973,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;
 }
@@ -1051,15 +1045,17 @@ 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);
@@ -1353,6 +1349,14 @@ proto_tree_new_item(field_info *new_fi, proto_tree *tree,
                        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;
@@ -1807,18 +1811,18 @@ test_length(header_field_info *hfinfo, proto_tree *tree, tvbuff_t *tvb,
 /* 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);
+       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);
 
@@ -1828,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,
@@ -1837,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);
 
@@ -1891,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);
 
@@ -1918,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;
 }
@@ -2009,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);
@@ -2017,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;
 }
@@ -2076,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;
 }
@@ -2140,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;
 }
@@ -2204,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;
 }
@@ -2276,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;
 }
@@ -2352,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;
 }
@@ -2483,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;
 }
@@ -2620,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;
 }
@@ -2646,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 *
@@ -2653,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;
 }
@@ -2723,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;
 }
@@ -2787,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;
 }
@@ -2851,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;
 }
@@ -2915,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);
@@ -2926,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:
@@ -2991,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);
@@ -3004,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;
 }
@@ -3062,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);
@@ -3072,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:
@@ -3128,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;
@@ -3137,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);
@@ -3150,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;
 }
@@ -3207,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;
 }
@@ -3322,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;
@@ -3330,8 +3332,6 @@ 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;
 }
 
@@ -3503,6 +3503,17 @@ alloc_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb, con
        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
@@ -3529,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);
@@ -3548,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);
                }
        }
 }
@@ -3583,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);
                }
        }
 }
@@ -3607,6 +3598,14 @@ 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,
@@ -3641,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);
                }
        }
 
@@ -3653,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;
                }
@@ -3663,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;
@@ -3914,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;
                }
@@ -4077,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)
 {
@@ -4390,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 */
@@ -4464,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 *
@@ -4654,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);
@@ -4666,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;
@@ -4682,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;
                }
        }
@@ -4978,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) {
@@ -5044,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;
                }
        }
 
@@ -5178,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)
@@ -5216,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);
                        }
@@ -5234,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:
@@ -5280,6 +5281,16 @@ proto_item_fill_label(field_info *fi, gchar *label_str)
                                   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, 0, hfinfo,
@@ -5361,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);
@@ -5423,7 +5432,7 @@ hf_try_val64_to_str_const(guint64 value, const header_field_info *hfinfo, const
 
 /* 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;
@@ -5439,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 */
@@ -5519,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)
@@ -5528,19 +5542,14 @@ fill_label_number64(field_info *fi, gchar *label_str, gboolean is_signed)
 
        value = fvalue_get_integer64(&fi->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");
-               char        tmp[ITEM_LABEL_LENGTH+1];
-
-               if (IS_BASE_DUAL(hfinfo->display)) {
-                       g_snprintf(tmp, ITEM_LABEL_LENGTH,
-                                       format,  hfinfo->name, value, value);
-               }
-               else {
-                       g_snprintf(tmp, ITEM_LABEL_LENGTH,
-                                       format,  hfinfo->name, value);
-               }
-
 
                if ((hfinfo->display & BASE_DISPLAY_E_MASK) == BASE_NONE) {
                        label_fill(label_str, 0, hfinfo, val_str);
@@ -5549,16 +5558,31 @@ fill_label_number64(field_info *fi, gchar *label_str, gboolean is_signed)
                        label_fill_descr(label_str, 0, hfinfo, val_str, tmp);
                }
        }
-       else 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);
+               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)
 {
@@ -5740,19 +5764,19 @@ hfinfo_uint64_format(const header_field_info *hfinfo)
        /* Pick the proper format string */
        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();
@@ -5769,19 +5793,19 @@ hfinfo_int64_format(const header_field_info *hfinfo)
        /* Pick the proper format string */
        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();
@@ -6117,7 +6141,7 @@ 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;
@@ -6292,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);
@@ -6735,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: