diff options
author | Thomas Wiens <th.wiens@gmx.de> | 2016-11-01 12:54:23 +0100 |
---|---|---|
committer | Guy Harris <guy@alum.mit.edu> | 2016-11-02 21:35:02 +0000 |
commit | 46160ff0394c9aa1fe99c8ac34fb83d70b206460 (patch) | |
tree | 5a0f2fb2fce65b26c8dff4420509e8737fb87207 | |
parent | a4f3ca29db9347f81fb6305c791f4fc967dd3eb9 (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.c | 126 |
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 |