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
This commit is contained in:
Evan Huus 2013-07-26 21:51:39 +00:00
parent 6580abbbc3
commit 6e3a30794e
5 changed files with 157 additions and 18 deletions

View File

@ -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 }
},

View File

@ -5376,9 +5376,23 @@ 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)
{
@ -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) {

View File

@ -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)

View File

@ -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

View File

@ -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