aboutsummaryrefslogtreecommitdiffstats
path: root/epan
diff options
context:
space:
mode:
authorDaniel Mack <daniel@zonque.org>2014-09-17 18:39:22 +0200
committerMichael Mann <mmann78@netscape.net>2014-10-12 14:15:12 +0000
commited0b19b94bf07056b5e0cfe64d4d05c3ebae801a (patch)
tree4c4dd80aa856bf0a4c55704c88761a2d2ab2199a /epan
parent29afac24a579b01c029b2b5404bda7a102fe2232 (diff)
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.c8
-rw-r--r--epan/proto.c70
-rw-r--r--epan/proto.h2
-rw-r--r--epan/to_str.c12
-rw-r--r--epan/to_str.h6
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);