aboutsummaryrefslogtreecommitdiffstats
path: root/epan
diff options
context:
space:
mode:
authorEvan Huus <eapache@gmail.com>2013-07-26 21:51:39 +0000
committerEvan Huus <eapache@gmail.com>2013-07-26 21:51:39 +0000
commit6e3a30794ef9e3270f52bbb5ea2227ff35112f21 (patch)
tree1d7592f45b40281d89259ea429600352e9560461 /epan
parent6580abbbc31c22060e819cfb8b1b8484028b62ec (diff)
Add 64-bit value strings and the appropriate tooling (including yet another
overloaded use of the DISPLAY field). Thanks to Jakub for pointing out I'd done this wrong the first time (months ago in r49357). Fixes severity display for collectd protocol, originally filed at: https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=8472 svn path=/trunk/; revision=50935
Diffstat (limited to 'epan')
-rw-r--r--epan/dissectors/packet-collectd.c6
-rw-r--r--epan/proto.c77
-rw-r--r--epan/proto.h6
-rw-r--r--epan/value_string.c59
-rw-r--r--epan/value_string.h27
5 files changed, 157 insertions, 18 deletions
diff --git a/epan/dissectors/packet-collectd.c b/epan/dissectors/packet-collectd.c
index 7983dd225b..a740f87461 100644
--- a/epan/dissectors/packet-collectd.c
+++ b/epan/dissectors/packet-collectd.c
@@ -138,7 +138,7 @@ static const value_string valuetypenames[] = {
#define SEVERITY_FAILURE 0x01
#define SEVERITY_WARNING 0x02
#define SEVERITY_OKAY 0x04
-static const value_string severity_names[] = {
+static const val64_string severity_names[] = {
{ SEVERITY_FAILURE, "FAILURE" },
{ SEVERITY_WARNING, "WARNING" },
{ SEVERITY_OKAY, "OKAY" },
@@ -1304,7 +1304,7 @@ dissect_collectd (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
proto_item_set_text (pi,
"collectd SEVERITY segment: "
"%s (%"G_GINT64_MODIFIER"u)",
- val_to_str_const ((gint32)ndispatch.severity, severity_names, "UNKNOWN"),
+ val64_to_str_const (ndispatch.severity, severity_names, "UNKNOWN"),
ndispatch.severity);
}
@@ -1470,7 +1470,7 @@ void proto_register_collectd(void)
NULL, 0x0, NULL, HFILL }
},
{ &hf_collectd_data_severity,
- { "Severity", "collectd.data.severity", FT_UINT64, BASE_HEX,
+ { "Severity", "collectd.data.severity", FT_UINT64, BASE_HEX | BASE_VAL64_STRING,
VALS(severity_names),
0x0, NULL, HFILL }
},
diff --git a/epan/proto.c b/epan/proto.c
index a79e4b8fa9..a5df02b3ba 100644
--- a/epan/proto.c
+++ b/epan/proto.c
@@ -5376,10 +5376,24 @@ hf_try_val_to_str(guint32 value, const header_field_info *hfinfo)
if (hfinfo->display & BASE_EXT_STRING)
return try_val_to_str_ext(value, (const value_string_ext *) hfinfo->strings);
+ if (hfinfo->display & BASE_VAL64_STRING)
+ return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
+
return try_val_to_str(value, (const value_string *) hfinfo->strings);
}
static const char *
+hf_try_val64_to_str(guint64 value, const header_field_info *hfinfo)
+{
+ if (hfinfo->display & BASE_VAL64_STRING)
+ return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
+
+ /* If this is reached somebody registered a 64-bit field with a 32-bit
+ * value-string, which isn't right. */
+ DISSECTOR_ASSERT_NOT_REACHED();
+}
+
+static const char *
hf_try_val_to_str_const(guint32 value, const header_field_info *hfinfo, const char *unknown_str)
{
const char *str = hf_try_val_to_str(value, hfinfo);
@@ -5387,6 +5401,14 @@ hf_try_val_to_str_const(guint32 value, const header_field_info *hfinfo, const ch
return (str) ? str : unknown_str;
}
+static const char *
+hf_try_val64_to_str_const(guint64 value, const header_field_info *hfinfo, const char *unknown_str)
+{
+ const char *str = hf_try_val64_to_str(value, hfinfo);
+
+ return (str) ? str : unknown_str;
+}
+
/* Fills data for bitfield ints with val_strings */
static void
fill_label_bitfield(field_info *fi, gchar *label_str)
@@ -5494,13 +5516,34 @@ fill_label_number64(field_info *fi, gchar *label_str, gboolean is_signed)
value = fvalue_get_integer64(&fi->value);
- /* Fill in the textual info */
- if (IS_BASE_DUAL(hfinfo->display)) {
+ 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);
+ }
+ else {
+ 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 {
+ format, hfinfo->name, value, value);
+ }
+ else {
g_snprintf(label_str, ITEM_LABEL_LENGTH,
- format, hfinfo->name, value);
+ format, hfinfo->name, value);
}
}
@@ -5683,7 +5726,7 @@ hfinfo_uint64_format(const header_field_info *hfinfo)
const char *format = NULL;
/* Pick the proper format string */
- switch (hfinfo->display) {
+ switch (hfinfo->display & BASE_DISPLAY_E_MASK) {
case BASE_DEC:
format = "%s: %" G_GINT64_MODIFIER "u";
break;
@@ -5712,7 +5755,7 @@ hfinfo_int64_format(const header_field_info *hfinfo)
const char *format = NULL;
/* Pick the proper format string */
- switch (hfinfo->display) {
+ switch (hfinfo->display & BASE_DISPLAY_E_MASK) {
case BASE_DEC:
format = "%s: %" G_GINT64_MODIFIER "d";
break;
@@ -6032,6 +6075,7 @@ proto_registrar_dump_values(void)
header_field_info *hfinfo;
int i, len, vi;
const value_string *vals;
+ const val64_string *vals64;
const range_string *range;
const true_false_string *tfs;
@@ -6064,9 +6108,10 @@ proto_registrar_dump_values(void)
if (hfinfo->same_name_prev != NULL)
continue;
- vals = NULL;
- range = NULL;
- tfs = NULL;
+ vals = NULL;
+ vals64 = NULL;
+ range = NULL;
+ tfs = NULL;
if (hfinfo->strings != NULL) {
if ((hfinfo->display & BASE_DISPLAY_E_MASK) != BASE_CUSTOM &&
@@ -6085,6 +6130,8 @@ proto_registrar_dump_values(void)
vals = VALUE_STRING_EXT_VS_P((const value_string_ext *)hfinfo->strings);
} else if ((hfinfo->display & BASE_RANGE_STRING) == 0) {
vals = (const value_string *)hfinfo->strings;
+ } else if ((hfinfo->display & BASE_VAL64_STRING) == 0) {
+ vals64 = (const val64_string *)hfinfo->strings;
} else {
range = (const range_string *)hfinfo->strings;
}
@@ -6127,6 +6174,16 @@ proto_registrar_dump_values(void)
vi++;
}
}
+ else if (vals64) {
+ vi = 0;
+ while (vals64[vi].strptr) {
+ printf("V64\t%s\t%" G_GINT64_MODIFIER "u\t%s\n",
+ hfinfo->abbrev,
+ vals64[vi].value,
+ vals64[vi].strptr);
+ vi++;
+ }
+ }
/* print range strings? */
else if (range) {
diff --git a/epan/proto.h b/epan/proto.h
index 358130d7ed..75f5e668a6 100644
--- a/epan/proto.h
+++ b/epan/proto.h
@@ -335,10 +335,10 @@ typedef enum {
} base_display_e;
/* Following constants have to be ORed with a base_display_e when dissector
- * want to use specials MACROs (for the moment, only RVALS) for a
- * header_field_info */
+ * want to use specials value-string MACROs for a header_field_info */
#define BASE_RANGE_STRING 0x10
-#define BASE_EXT_STRING 0x20
+#define BASE_EXT_STRING 0x20
+#define BASE_VAL64_STRING 0x40
/** BASE_ values that cause the field value to be displayed twice */
#define IS_BASE_DUAL(b) ((b)==BASE_DEC_HEX||(b)==BASE_HEX_DEC)
diff --git a/epan/value_string.c b/epan/value_string.c
index a760971d89..f363956726 100644
--- a/epan/value_string.c
+++ b/epan/value_string.c
@@ -103,6 +103,65 @@ try_val_to_str(const guint32 val, const value_string *vs)
return try_val_to_str_idx(val, vs, &ignore_me);
}
+/* 64-BIT VALUE STRING */
+
+const gchar*
+val64_to_str(const guint64 val, const val64_string *vs, const char *fmt)
+{
+ const gchar *ret;
+
+ DISSECTOR_ASSERT(fmt != NULL);
+
+ ret = try_val64_to_str(val, vs);
+ if (ret != NULL)
+ return ret;
+
+ return ep_strdup_printf(fmt, val);
+}
+
+const gchar*
+val64_to_str_const(const guint64 val, const val64_string *vs,
+ const char *unknown_str)
+{
+ const gchar *ret;
+
+ DISSECTOR_ASSERT(unknown_str != NULL);
+
+ ret = try_val64_to_str(val, vs);
+ if (ret != NULL)
+ return ret;
+
+ return unknown_str;
+}
+
+const gchar*
+try_val64_to_str_idx(const guint64 val, const val64_string *vs, gint *idx)
+{
+ gint i = 0;
+
+ DISSECTOR_ASSERT(idx != NULL);
+
+ if(vs) {
+ while (vs[i].strptr) {
+ if (vs[i].value == val) {
+ *idx = i;
+ return(vs[i].strptr);
+ }
+ i++;
+ }
+ }
+
+ *idx = -1;
+ return NULL;
+}
+
+const gchar*
+try_val64_to_str(const guint64 val, const val64_string *vs)
+{
+ gint ignore_me;
+ return try_val64_to_str_idx(val, vs, &ignore_me);
+}
+
/* REVERSE VALUE STRING */
/* We use the same struct as for regular value strings, but we look up strings
diff --git a/epan/value_string.h b/epan/value_string.h
index 1759d0dfb1..a2323e7738 100644
--- a/epan/value_string.h
+++ b/epan/value_string.h
@@ -31,8 +31,8 @@
/* VALUE TO STRING MATCHING */
typedef struct _value_string {
- guint32 value;
- const gchar *strptr;
+ guint32 value;
+ const gchar *strptr;
} value_string;
WS_DLL_PUBLIC
@@ -51,6 +51,29 @@ WS_DLL_PUBLIC
const gchar*
try_val_to_str_idx(const guint32 val, const value_string *vs, gint *idx);
+/* 64-BIT VALUE TO STRING MATCHING */
+
+typedef struct _val64_string {
+ guint64 value;
+ const gchar *strptr;
+} val64_string;
+
+WS_DLL_PUBLIC
+const gchar*
+val64_to_str(const guint64 val, const val64_string *vs, const char *fmt);
+
+WS_DLL_PUBLIC
+const gchar*
+val64_to_str_const(const guint64 val, const val64_string *vs, const char *unknown_str);
+
+WS_DLL_PUBLIC
+const gchar*
+try_val64_to_str(const guint64 val, const val64_string *vs);
+
+WS_DLL_PUBLIC
+const gchar*
+try_val64_to_str_idx(const guint64 val, const val64_string *vs, gint *idx);
+
/* STRING TO VALUE MATCHING */
WS_DLL_PUBLIC