diff options
author | Daniel Mack <daniel@zonque.org> | 2014-09-17 18:39:22 +0200 |
---|---|---|
committer | Michael Mann <mmann78@netscape.net> | 2014-10-12 14:15:12 +0000 |
commit | ed0b19b94bf07056b5e0cfe64d4d05c3ebae801a (patch) | |
tree | 4c4dd80aa856bf0a4c55704c88761a2d2ab2199a /epan | |
parent | 29afac24a579b01c029b2b5404bda7a102fe2232 (diff) | |
download | wireshark-ed0b19b94bf07056b5e0cfe64d4d05c3ebae801a.tar.gz |
Make boolean bitmask type 64-bit wide
There are protocols out there that have 64-bit wide bit mask fields, so
make the internal representation and bitfield decoders 64-bit aware.
For this, the ws_ctz() fallback and bits_count_ones() have to be tweaked
slightly.
Change-Id: I19237b954a69c9e6c55864f281993c1e8731a233
Reviewed-on: https://code.wireshark.org/review/4158
Petri-Dish: Alexis La Goutte <alexis.lagoutte@gmail.com>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Alexis La Goutte <alexis.lagoutte@gmail.com>
Reviewed-by: Michael Mann <mmann78@netscape.net>
Diffstat (limited to 'epan')
-rw-r--r-- | epan/ftypes/ftype-integer.c | 8 | ||||
-rw-r--r-- | epan/proto.c | 70 | ||||
-rw-r--r-- | epan/proto.h | 2 | ||||
-rw-r--r-- | epan/to_str.c | 12 | ||||
-rw-r--r-- | epan/to_str.h | 6 |
5 files changed, 63 insertions, 35 deletions
diff --git a/epan/ftypes/ftype-integer.c b/epan/ftypes/ftype-integer.c index 2bf81d6781..e603a9bf4a 100644 --- a/epan/ftypes/ftype-integer.c +++ b/epan/ftypes/ftype-integer.c @@ -1077,7 +1077,7 @@ ftype_register_integers(void) 0, /* wire_size */ boolean_fvalue_new, /* new_value */ NULL, /* free_value */ - uint32_from_unparsed, /* val_from_unparsed */ + uint64_from_unparsed, /* val_from_unparsed */ NULL, /* val_from_string */ boolean_to_repr, /* val_to_string_repr */ boolean_repr_len, /* len_string_repr */ @@ -1090,13 +1090,13 @@ ftype_register_integers(void) NULL, /* set_value_tvbuff */ set_uinteger, /* set_value_uinteger */ NULL, /* set_value_sinteger */ - NULL, /* set_value_integer64 */ + set_integer64, /* set_value_integer64 */ NULL, /* set_value_floating */ NULL, /* get_value */ - get_uinteger, /* get_value_uinteger */ + NULL, /* get_value_uinteger */ NULL, /* get_value_sinteger */ - NULL, /* get_value_integer64 */ + get_integer64, /* get_value_integer64 */ NULL, /* get_value_floating */ bool_eq, /* cmp_eq */ diff --git a/epan/proto.c b/epan/proto.c index 88c3e33f09..3d7c2e5860 100644 --- a/epan/proto.c +++ b/epan/proto.c @@ -239,7 +239,7 @@ proto_tree_set_system_id(field_info *fi, const guint8* value_ptr, gint length); static void proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length); static void -proto_tree_set_boolean(field_info *fi, guint32 value); +proto_tree_set_boolean(field_info *fi, guint64 value); static void proto_tree_set_float(field_info *fi, float value); static void @@ -1645,7 +1645,7 @@ proto_tree_new_item(field_info *new_fi, proto_tree *tree, if (encoding) encoding = ENC_LITTLE_ENDIAN; proto_tree_set_boolean(new_fi, - get_uint_value(tree, tvb, start, length, encoding)); + get_uint64_value(tree, tvb, start, length, encoding)); break; /* XXX - make these just FT_UINT? */ @@ -2974,7 +2974,25 @@ proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint len static void proto_tree_set_uint64(field_info *fi, guint64 value) { - fvalue_set_integer64(&fi->value, value); + header_field_info *hfinfo; + guint64 integer; + gint no_of_bits; + + hfinfo = fi->hfinfo; + integer = value; + + if (hfinfo->bitmask) { + /* Mask out irrelevant portions */ + integer &= hfinfo->bitmask; + + /* Shift bits */ + integer >>= hfinfo_bitshift(hfinfo); + + no_of_bits = ws_count_ones(hfinfo->bitmask); + integer = ws_sign_ext64(integer, no_of_bits); + } + + fvalue_set_integer64(&fi->value, integer); } /* Add a FT_STRING, FT_STRINGZ, or FT_STRINGZPAD to a proto_tree. Creates @@ -3281,9 +3299,9 @@ proto_tree_add_boolean_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, /* Set the FT_BOOLEAN value */ static void -proto_tree_set_boolean(field_info *fi, guint32 value) +proto_tree_set_boolean(field_info *fi, guint64 value) { - proto_tree_set_uint(fi, value); + proto_tree_set_uint64(fi, value); } /* Add a FT_FLOAT to a proto_tree */ @@ -4011,10 +4029,14 @@ proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ITEM_LABEL_NEW(PNODE_POOL(pi), fi->rep); if (hf->bitmask && (hf->type == FT_BOOLEAN || IS_FT_UINT(hf->type))) { - guint32 val; + guint64 val; char *p; - val = fvalue_get_uinteger(&fi->value); + if (IS_FT_UINT(hf->type)) + val = fvalue_get_uinteger(&fi->value); + else + val = fvalue_get_integer64(&fi->value); + val <<= hfinfo_bitshift(hf); p = decode_bitfield_value(fi->rep->representation, val, hf->bitmask, hfinfo_bitwidth(hf)); @@ -6004,8 +6026,8 @@ fill_label_boolean(field_info *fi, gchar *label_str) { char *p = label_str; int bitfield_byte_length = 0, bitwidth; - guint32 unshifted_value; - guint32 value; + guint64 unshifted_value; + guint64 value; header_field_info *hfinfo = fi->hfinfo; const true_false_string *tfstring = (const true_false_string *)&tfs_true_false; @@ -6014,7 +6036,7 @@ fill_label_boolean(field_info *fi, gchar *label_str) tfstring = (const struct true_false_string*) hfinfo->strings; } - value = fvalue_get_uinteger(&fi->value); + value = fvalue_get_integer64(&fi->value); if (hfinfo->bitmask) { /* Figure out the bit width */ bitwidth = hfinfo_bitwidth(hfinfo); @@ -7006,9 +7028,10 @@ proto_registrar_dump_fields(void) else if (strlen(blurb) == 0) blurb = "\"\""; - printf("F\t%s\t%s\t%s\t%s\t%s\t0x%x\t%s\n", + printf("F\t%s\t%s\t%s\t%s\t%s\t0x%llx\t%s\n", hfinfo->name, hfinfo->abbrev, enum_name, - parent_hfinfo->abbrev, base_name, hfinfo->bitmask, blurb); + parent_hfinfo->abbrev, base_name, + (unsigned long long) hfinfo->bitmask, blurb); } } } @@ -7344,9 +7367,9 @@ proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, const int offset, const guint encoding, const int flags, gboolean first) { - guint32 value = 0; - guint32 available_bits = 0; - guint32 tmpval; + guint64 value = 0; + guint64 available_bits = 0; + guint64 tmpval; proto_tree *tree = NULL; header_field_info *hf; @@ -7370,13 +7393,18 @@ proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, const int offset, tvb_get_ntohl(tvb, offset); available_bits = 0xFFFFFFFF; break; + case 8: + value = encoding ? tvb_get_letoh64(tvb, offset) : + tvb_get_ntoh64(tvb, offset); + available_bits = 0xFFFFFFFFFFFFFFFF; + break; default: g_assert_not_reached(); } tree = proto_item_add_subtree(item, ett); while (*fields) { - guint32 present_bits; + guint64 present_bits; PROTO_REGISTRAR_GET_NTH(**fields,hf); DISSECTOR_ASSERT(hf->bitmask != 0); @@ -7408,14 +7436,14 @@ proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, const int offset, const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings; DISSECTOR_ASSERT(fmtfunc); - fmtfunc(lbl, tmpval); + fmtfunc(lbl, (guint32) tmpval); proto_item_append_text(item, "%s%s: %s", first ? "" : ", ", hf->name, lbl); first = FALSE; } else if (hf->strings) { proto_item_append_text(item, "%s%s: %s", first ? "" : ", ", - hf->name, hf_try_val_to_str_const(tmpval, hf, "Unknown")); + hf->name, hf_try_val_to_str_const((guint32) tmpval, hf, "Unknown")); first = FALSE; } else if (!(flags & BMT_NO_INT)) { @@ -7426,7 +7454,7 @@ proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, const int offset, proto_item_append_text(item, ", "); } - out = hfinfo_number_value_format(hf, buf, tmpval); + out = hfinfo_number_value_format(hf, buf, (guint32) tmpval); proto_item_append_text(item, "%s: %s", hf->name, out); first = FALSE; } @@ -7691,7 +7719,7 @@ _proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb, 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); + (guint64)value ? tfstring->true_string : tfstring->false_string); break; case FT_UINT8: @@ -7852,7 +7880,7 @@ proto_tree_add_split_bits_item_ret_val(proto_tree *tree, const int hfindex, tvbu tvb, octet_offset, octet_length, (guint32)value, "%s = %s: %s", bf_str, hf_field->name, - (guint32)value ? tfstring->true_string : tfstring->false_string); + (guint64)value ? tfstring->true_string : tfstring->false_string); break; case FT_UINT8: diff --git a/epan/proto.h b/epan/proto.h index 65a1ca2d35..eb788561c6 100644 --- a/epan/proto.h +++ b/epan/proto.h @@ -477,7 +477,7 @@ struct _header_field_info { typically converted by VALS(), RVALS() or TFS(). If this is an FT_PROTOCOL then it points to the associated protocol_t structure */ - guint32 bitmask; /**< [BITMASK] bitmask of interesting bits */ + guint64 bitmask; /**< [BITMASK] bitmask of interesting bits */ const char *blurb; /**< [FIELDDESCR] Brief description of field */ /* ------- set by proto routines (prefilled by HFILL macro, see below) ------ */ diff --git a/epan/to_str.c b/epan/to_str.c index 5b42179001..f9b876a0e0 100644 --- a/epan/to_str.c +++ b/epan/to_str.c @@ -996,15 +996,15 @@ decode_bits_in_field(const guint bit_offset, const gint no_of_bits, const guint6 Return a pointer to the character after that string. */ /*XXX this needs a buf_len check */ char * -other_decode_bitfield_value(char *buf, const guint32 val, const guint32 mask, const int width) +other_decode_bitfield_value(char *buf, const guint64 val, const guint64 mask, const int width) { int i; - guint32 bit; + guint64 bit; char *p; i = 0; p = buf; - bit = 1 << (width - 1); + bit = 1ULL << (width - 1); for (;;) { if (mask & bit) { /* This bit is part of the field. Show its value. */ @@ -1028,7 +1028,7 @@ other_decode_bitfield_value(char *buf, const guint32 val, const guint32 mask, co } char * -decode_bitfield_value(char *buf, const guint32 val, const guint32 mask, const int width) +decode_bitfield_value(char *buf, const guint64 val, const guint64 mask, const int width) { char *p; @@ -1041,7 +1041,7 @@ decode_bitfield_value(char *buf, const guint32 val, const guint32 mask, const in /* Generate a string describing a numeric bitfield (an N-bit field whose value is just a number). */ const char * -decode_numeric_bitfield(const guint32 val, const guint32 mask, const int width, +decode_numeric_bitfield(const guint64 val, const guint64 mask, const int width, const char *fmt) { char *buf; @@ -1051,7 +1051,7 @@ decode_numeric_bitfield(const guint32 val, const guint32 mask, const int width, buf=(char *)ep_alloc(1025); /* isn't this a bit overkill? */ /* Compute the number of bits we have to shift the bitfield right to extract its value. */ - while ((mask & (1<<shift)) == 0) + while ((mask & (1ULL << shift)) == 0) shift++; p = decode_bitfield_value(buf, val, mask, width); diff --git a/epan/to_str.h b/epan/to_str.h index 6d180dba44..963d228856 100644 --- a/epan/to_str.h +++ b/epan/to_str.h @@ -94,11 +94,11 @@ gchar* guid_to_str_buf(const e_guid_t*, gchar*, int); WS_DLL_PUBLIC char *decode_bits_in_field(const guint bit_offset, const gint no_of_bits, const guint64 value); -WS_DLL_PUBLIC char *other_decode_bitfield_value(char *buf, const guint32 val, const guint32 mask, +WS_DLL_PUBLIC char *other_decode_bitfield_value(char *buf, const guint64 val, const guint64 mask, const int width); -WS_DLL_PUBLIC char *decode_bitfield_value(char *buf, const guint32 val, const guint32 mask, +WS_DLL_PUBLIC char *decode_bitfield_value(char *buf, const guint64 val, const guint64 mask, const int width); -WS_DLL_PUBLIC const char *decode_numeric_bitfield(const guint32 val, const guint32 mask, const int width, +WS_DLL_PUBLIC const char *decode_numeric_bitfield(const guint64 val, const guint64 mask, const int width, const char *fmt) G_GNUC_PRINTF(4, 0); WS_DLL_PUBLIC const gchar* port_type_to_str (port_type type); |