aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Wiens <th.wiens@gmx.de>2016-11-01 12:54:23 +0100
committerGuy Harris <guy@alum.mit.edu>2016-11-02 21:35:02 +0000
commit46160ff0394c9aa1fe99c8ac34fb83d70b206460 (patch)
tree5a0f2fb2fce65b26c8dff4420509e8737fb87207
parenta4f3ca29db9347f81fb6305c791f4fc967dd3eb9 (diff)
proto: Decode negative values in a bitmask field
Allows to use negative values (FT_INT) in a bitmask field. If a field type greater or equal (FT_(U)INT40) is used then also a 64 bit value string and 64 bit format function must be used. Change-Id: Ib86d45bee73a71a784068ab717d35810c6f48017 Reviewed-on: https://code.wireshark.org/review/18601 Petri-Dish: Alexis La Goutte <alexis.lagoutte@gmail.com> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Guy Harris <guy@alum.mit.edu>
-rw-r--r--epan/proto.c126
1 files changed, 114 insertions, 12 deletions
diff --git a/epan/proto.c b/epan/proto.c
index 1cb3f2cc48..606ccc6c40 100644
--- a/epan/proto.c
+++ b/epan/proto.c
@@ -9302,6 +9302,8 @@ proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, const int offset,
guint64 available_bits = 0;
guint64 tmpval;
header_field_info *hf;
+ guint32 integer32;
+ gint no_of_bits;
if (len < 0 || len > 8)
g_assert_not_reached();
@@ -9399,22 +9401,10 @@ proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, const int offset,
break;
- case FT_INT8:
case FT_UINT8:
- case FT_INT16:
case FT_UINT16:
- case FT_INT24:
case FT_UINT24:
- case FT_INT32:
case FT_UINT32:
- case FT_INT40:
- case FT_UINT40:
- case FT_INT48:
- case FT_UINT48:
- case FT_INT56:
- case FT_UINT56:
- case FT_INT64:
- case FT_UINT64:
if (hf->display == BASE_CUSTOM) {
gchar lbl[ITEM_LABEL_LENGTH];
const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
@@ -9444,6 +9434,118 @@ proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, const int offset,
}
break;
+
+ case FT_INT8:
+ case FT_INT16:
+ case FT_INT24:
+ case FT_INT32:
+ integer32 = (guint32) tmpval;
+ if (hf->bitmask) {
+ no_of_bits = ws_count_ones(hf->bitmask);
+ integer32 = ws_sign_ext32(integer32, no_of_bits);
+ }
+ if (hf->display == BASE_CUSTOM) {
+ gchar lbl[ITEM_LABEL_LENGTH];
+ const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
+
+ DISSECTOR_ASSERT(fmtfunc);
+ fmtfunc(lbl, (gint32) integer32);
+ 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((gint32) integer32, hf, "Unknown"));
+ first = FALSE;
+ }
+ else if (!(flags & BMT_NO_INT)) {
+ char buf[32];
+ const char *out;
+
+ if (!first) {
+ proto_item_append_text(item, ", ");
+ }
+
+ out = hfinfo_number_value_format(hf, buf, (gint32) integer32);
+ proto_item_append_text(item, "%s: %s", hf->name, out);
+ first = FALSE;
+ }
+
+ break;
+
+ case FT_UINT40:
+ case FT_UINT48:
+ case FT_UINT56:
+ case FT_UINT64:
+ if (hf->display == BASE_CUSTOM) {
+ gchar lbl[ITEM_LABEL_LENGTH];
+ const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
+
+ DISSECTOR_ASSERT(fmtfunc);
+ fmtfunc(lbl, 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_val64_to_str_const(tmpval, hf, "Unknown"));
+ first = FALSE;
+ }
+ else if (!(flags & BMT_NO_INT)) {
+ char buf[48];
+ const char *out;
+
+ if (!first) {
+ proto_item_append_text(item, ", ");
+ }
+
+ out = hfinfo_number_value_format64(hf, buf, tmpval);
+ proto_item_append_text(item, "%s: %s", hf->name, out);
+ first = FALSE;
+ }
+
+ break;
+
+ case FT_INT40:
+ case FT_INT48:
+ case FT_INT56:
+ case FT_INT64:
+ if (hf->bitmask) {
+ no_of_bits = ws_count_ones(hf->bitmask);
+ tmpval = ws_sign_ext64(tmpval, no_of_bits);
+ }
+ if (hf->display == BASE_CUSTOM) {
+ gchar lbl[ITEM_LABEL_LENGTH];
+ const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
+
+ DISSECTOR_ASSERT(fmtfunc);
+ fmtfunc(lbl, (gint64) 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_val64_to_str_const((gint64) tmpval, hf, "Unknown"));
+ first = FALSE;
+ }
+ else if (!(flags & BMT_NO_INT)) {
+ char buf[48];
+ const char *out;
+
+ if (!first) {
+ proto_item_append_text(item, ", ");
+ }
+
+ out = hfinfo_number_value_format64(hf, buf, (gint64) tmpval);
+ proto_item_append_text(item, "%s: %s", hf->name, out);
+ first = FALSE;
+ }
+
+ break;
+
case FT_BOOLEAN:
if (hf->strings && !(flags & BMT_NO_TFS)) {
/* If we have true/false strings, emit full - otherwise messages