aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn Thacker <johnthacker@gmail.com>2022-10-30 07:00:36 -0400
committerAndersBroman <a.broman58@gmail.com>2022-11-01 09:54:03 +0000
commit1293f158975b56f1e3e610c09cef98e84614fea8 (patch)
tree9a9039dd57704f175638bcdae05b6a1a15517226
parentcabe0e0239c619d34b976ba56f24481ca43af276 (diff)
AMQP: Add field table values as fields
Add the name, type, and values of field tables and arrays as fields under the FT_NONE header. This makes them filterable and show up in JSON export. Fix #18385
-rw-r--r--epan/dissectors/packet-amqp.c250
1 files changed, 152 insertions, 98 deletions
diff --git a/epan/dissectors/packet-amqp.c b/epan/dissectors/packet-amqp.c
index 02edbd7ef6..4c0aab48c0 100644
--- a/epan/dissectors/packet-amqp.c
+++ b/epan/dissectors/packet-amqp.c
@@ -1451,6 +1451,20 @@ static int hf_amqp_method_dtx_start_dtx_identifier = -1;
static int hf_amqp_method_tunnel_request_meta_data = -1;
static int hf_amqp_method_confirm_select_nowait = -1;
static int hf_amqp_field = -1;
+static int hf_amqp_field_name = -1;
+static int hf_amqp_field_type = -1;
+static int hf_amqp_field_integer = -1;
+static int hf_amqp_field_unsigned_integer = -1;
+static int hf_amqp_field_string = -1;
+static int hf_amqp_field_boolean = -1;
+static int hf_amqp_field_byte = -1;
+static int hf_amqp_field_unsigned_byte = -1;
+static int hf_amqp_field_short_int = -1;
+static int hf_amqp_field_short_uint = -1;
+static int hf_amqp_field_long_int = -1;
+static int hf_amqp_field_float = -1;
+static int hf_amqp_field_double = -1;
+static int hf_amqp_field_decimal = -1;
static int hf_amqp_field_timestamp = -1;
static int hf_amqp_field_byte_array = -1;
static int hf_amqp_header_class_id = -1;
@@ -1525,6 +1539,7 @@ static gint ett_args = -1;
static gint ett_props = -1;
static gint ett_field_table = -1;
static gint ett_amqp_init = -1;
+static gint ett_amqp_0_9_field = -1;
static gint ett_amqp_0_10_map = -1;
static gint ett_amqp_0_10_array = -1;
static gint ett_amqp_0_10_struct = -1;
@@ -2381,25 +2396,30 @@ get_amqp_0_9_message_len(packet_info *pinfo _U_, tvbuff_t *tvb,
static void
dissect_amqp_0_9_field_table(tvbuff_t *tvb, packet_info *pinfo, int offset, guint length, proto_item *item)
{
- proto_tree *field_table_tree;
+ proto_tree *field_table_tree, *field_item_tree;
+ proto_item *field_item;
guint namelen, vallen;
- const char *name;
+ const guint8 *name;
int field_start;
field_table_tree = proto_item_add_subtree(item, ett_amqp);
while (length != 0) {
field_start = offset;
+ field_item = proto_tree_add_item(field_table_tree, hf_amqp_field, tvb,
+ offset, 1, ENC_NA);
namelen = tvb_get_guint8(tvb, offset);
offset += 1;
length -= 1;
if (length < namelen)
goto too_short;
- name = (char*) tvb_get_string_enc(wmem_packet_scope(), tvb, offset, namelen, ENC_UTF_8|ENC_NA);
+ field_item_tree = proto_item_add_subtree(field_item, ett_amqp_0_9_field);
+ proto_tree_add_item_ret_string(field_item_tree, hf_amqp_field_name, tvb, offset, namelen, ENC_UTF_8, pinfo->pool, &name);
+ proto_item_set_text(field_item, "%s", name);
offset += namelen;
length -= namelen;
- vallen = dissect_amqp_0_9_field_value(tvb, pinfo, offset, length, name, field_table_tree);
+ vallen = dissect_amqp_0_9_field_value(tvb, pinfo, offset, length, name, field_item_tree);
if(vallen == 0)
goto too_short;
offset += vallen;
@@ -2417,7 +2437,8 @@ too_short:
static void
dissect_amqp_0_9_field_array(tvbuff_t *tvb, packet_info *pinfo, int offset, guint length, proto_item *item)
{
- proto_tree *field_table_tree;
+ proto_tree *field_table_tree, *field_item_tree;
+ proto_item *field_item;
int field_start, idx;
guint vallen;
const char *name;
@@ -2427,9 +2448,12 @@ dissect_amqp_0_9_field_array(tvbuff_t *tvb, packet_info *pinfo, int offset, guin
while (length != 0) {
field_start = offset;
- name = wmem_strdup_printf(wmem_packet_scope(), "[%i]", idx);
+ field_item = proto_tree_add_none_format(field_table_tree, hf_amqp_field, tvb,
+ offset, 0, "[%i]", idx);
+ field_item_tree = proto_item_add_subtree(field_item, ett_amqp_0_9_field);
+ name = wmem_strdup_printf(pinfo->pool, "[%i]", idx);
- vallen = dissect_amqp_0_9_field_value(tvb, pinfo, offset, length, name, field_table_tree);
+ vallen = dissect_amqp_0_9_field_value(tvb, pinfo, offset, length, name, field_item_tree);
if(vallen == 0)
goto too_short;
offset += vallen;
@@ -2477,67 +2501,77 @@ too_short:
* who follows the 0-9-1 spec for this bit.
*/
+static const value_string amqp_0_9_field_type_vals[] = {
+ { 'A', "array" },
+ { 'B', "unsigned byte" },
+ { 'D', "decimal" },
+ { 'F', "field table" },
+ { 'I', "integer" },
+ { 'S', "string" },
+ { 'T', "timestamp" },
+ { 'V', "void" },
+ { 'b', "byte" },
+ { 'd', "double" },
+ { 'f', "float" },
+ { 'i', "unsigned integer" },
+ { 'l', "long int" },
+ { 's', "short int" },
+ { 't', "boolean" },
+ { 'u', "short uint" },
+ { 'x', "byte array" },
+ { 0, NULL },
+};
+
static guint
dissect_amqp_0_9_field_value(tvbuff_t *tvb, packet_info *pinfo, int offset, guint length,
- const char *name, proto_tree *field_table_tree)
+ const char *name _U_, proto_tree *field_tree)
{
- proto_item *ti;
+ proto_item *field_item, *type_item, *ti = NULL;
guint vallen;
guint8 type;
- char type_buf[7] = { 0 };
const char *amqp_typename;
- const char *value;
- nstime_t tv;
int value_start;
value_start = offset;
if (length < 1)
return 0; /* too short */
type = tvb_get_guint8(tvb, offset);
+ amqp_typename = char_val_to_str(type, amqp_0_9_field_type_vals, "unknown type");
+ field_item = proto_tree_get_parent(field_tree);
+ proto_item_append_text(field_item, " (%s)", amqp_typename);
+ type_item = proto_tree_add_item(field_tree, hf_amqp_field_type, tvb, offset, 1, ENC_NA);
offset += 1;
length -= 1;
switch (type) {
case 'I': /* signed 32-bit */
- amqp_typename = "integer";
if (length < 4)
return 0; /* too short */
- value = wmem_strdup_printf(wmem_packet_scope(), "%" PRIi32,
- tvb_get_ntohil(tvb, offset));
+ ti = proto_tree_add_item(field_tree, hf_amqp_field_integer, tvb, offset, 4, ENC_BIG_ENDIAN);
offset += 4;
break;
- case 'D':
- amqp_typename = "decimal";
+ case 'D': /* 40-bit decimal floating point, biased towards small numbers */
+ {
if (length < 5)
return 0; /* too short */
- value = wmem_strdup_printf(wmem_packet_scope(), "%f",
- tvb_get_ntohl(tvb, offset+1) / pow(10, tvb_get_guint8(tvb, offset)));
+ double decimal = tvb_get_ntohl(tvb, offset + 1) / pow(10, tvb_get_guint8(tvb, offset));
+ ti = proto_tree_add_double(field_tree, hf_amqp_field_decimal, tvb, offset, 5, decimal);
offset += 5;
break;
+ }
case 'S': /* long string, UTF-8 encoded */
- amqp_typename = "string";
if (length < 4)
return 0; /* too short */
- vallen = tvb_get_ntohl(tvb, offset);
- offset += 4;
- length -= 4;
- if (length < vallen)
- return 0; /* too short */
- value = (char*) tvb_get_string_enc(wmem_packet_scope(), tvb, offset, vallen, ENC_UTF_8|ENC_NA);
+ ti = proto_tree_add_item_ret_length(field_tree, hf_amqp_field_string, tvb, offset, 4, ENC_BIG_ENDIAN|ENC_UTF_8, &vallen);
offset += vallen;
break;
case 'T': /* timestamp (u64) */
if (length < 8)
return 0; /* too short */
- tv.secs = (time_t)tvb_get_ntoh64(tvb, offset);
- tv.nsecs = 0;
-
+ ti = proto_tree_add_item(field_tree, hf_amqp_field_timestamp, tvb,
+ offset, 8, ENC_TIME_SECS|ENC_BIG_ENDIAN);
offset += 8;
- ti = proto_tree_add_time(field_table_tree, hf_amqp_field_timestamp, tvb,
- value_start, offset - value_start, &tv);
- proto_item_prepend_text(ti, "%s ", name);
- return offset - value_start;
+ break;
case 'F': /* nested table */
- amqp_typename = "field table";
if (length < 4)
return 0; /* too short */
vallen = tvb_get_ntohl(tvb, offset);
@@ -2545,90 +2579,67 @@ dissect_amqp_0_9_field_value(tvbuff_t *tvb, packet_info *pinfo, int offset, guin
length -= 4;
if (length < vallen)
return 0; /* too short */
- ti = proto_tree_add_item(field_table_tree, hf_amqp_field, tvb,
- value_start, offset+vallen - value_start, ENC_NA);
- proto_item_set_text(ti, "%s (%s)", name, amqp_typename);
- dissect_amqp_0_9_field_table(tvb, pinfo, offset, vallen, ti);
+ dissect_amqp_0_9_field_table(tvb, pinfo, offset, vallen, field_tree);
offset += vallen;
- return offset - value_start;
+ break;
case 'V':
- amqp_typename = "void";
- value = "";
break;
/* AMQP 0-9-1 types */
case 't': /* boolean */
- amqp_typename = "boolean";
if (length < 1)
return 0; /* too short */
- value = tvb_get_guint8(tvb, offset) ? "true" : "false";
+ ti = proto_tree_add_item(field_tree, hf_amqp_field_boolean, tvb, offset, 1, ENC_NA);
offset += 1;
break;
case 'b': /* signed 8-bit */
- amqp_typename = "byte";
if (length < 1)
return 0; /* too short */
- value = wmem_strdup_printf(wmem_packet_scope(), "%d",
- tvb_get_gint8(tvb, offset));
+ ti = proto_tree_add_item(field_tree, hf_amqp_field_byte, tvb, offset, 1, ENC_NA);
offset += 1;
break;
case 'B': /* unsigned 8-bit */
- amqp_typename = "unsigned byte";
if (length < 1)
return 0; /* too short */
- value = wmem_strdup_printf(wmem_packet_scope(), "%u",
- tvb_get_guint8(tvb, offset));
+ ti = proto_tree_add_item(field_tree, hf_amqp_field_unsigned_byte, tvb, offset, 1, ENC_NA);
offset += 1;
break;
case 's': /* signed 16-bit */
- amqp_typename = "short int";
if (length < 2)
return 0; /* too short */
- value = wmem_strdup_printf(wmem_packet_scope(), "%" PRIi16,
- tvb_get_ntohis(tvb, offset));
+ ti = proto_tree_add_item(field_tree, hf_amqp_field_short_int, tvb, offset, 2, ENC_BIG_ENDIAN);
offset += 2;
break;
case 'u': /* unsigned 16-bit */
- amqp_typename = "short uint";
if (length < 2)
return 0; /* too short */
- value = wmem_strdup_printf(wmem_packet_scope(), "%" PRIu16,
- tvb_get_ntohs(tvb, offset));
+ ti = proto_tree_add_item(field_tree, hf_amqp_field_short_uint, tvb, offset, 2, ENC_BIG_ENDIAN);
offset += 2;
break;
case 'i': /* unsigned 32-bit */
- amqp_typename = "unsigned integer";
if (length < 4)
return 0; /* too short */
- value = wmem_strdup_printf(wmem_packet_scope(), "%" PRIu32,
- tvb_get_ntohl(tvb, offset));
+ ti = proto_tree_add_item(field_tree, hf_amqp_field_unsigned_integer, tvb, offset, 4, ENC_BIG_ENDIAN);
offset += 4;
break;
case 'l': /* signed 64-bit */
- amqp_typename = "long int";
if (length < 8)
return 0; /* too short */
- value = wmem_strdup_printf(wmem_packet_scope(), "%" PRIi64,
- tvb_get_ntohi64(tvb, offset));
+ ti = proto_tree_add_item(field_tree, hf_amqp_field_long_int, tvb, offset, 8, ENC_BIG_ENDIAN);
offset += 8;
break;
case 'f': /* 32-bit float */
- amqp_typename = "float";
if (length < 4)
return 0; /* too short */
- value = wmem_strdup_printf(wmem_packet_scope(), "%f",
- tvb_get_ntohieee_float(tvb, offset));
+ ti = proto_tree_add_item(field_tree, hf_amqp_field_float, tvb, offset, 4, ENC_BIG_ENDIAN);
offset += 4;
break;
case 'd': /* 64-bit float */
- amqp_typename = "double";
if (length < 8)
return 0; /* too short */
- value = wmem_strdup_printf(wmem_packet_scope(), "%f",
- tvb_get_ntohieee_double(tvb, offset));
+ ti = proto_tree_add_item(field_tree, hf_amqp_field_double, tvb, offset, 8, ENC_BIG_ENDIAN);
offset += 8;
break;
case 'A': /* array */
- amqp_typename = "array";
if (length < 4)
return 0; /* too short */
vallen = tvb_get_ntohl(tvb, offset);
@@ -2636,41 +2647,27 @@ dissect_amqp_0_9_field_value(tvbuff_t *tvb, packet_info *pinfo, int offset, guin
length -= 4;
if (length < vallen)
return 0; /* too short */
- ti = proto_tree_add_item(field_table_tree, hf_amqp_field, tvb,
- value_start, offset+vallen - value_start, ENC_NA);
- proto_item_set_text(ti, "%s (%s)", name, amqp_typename);
dissect_amqp_0_9_field_array(tvb, pinfo, offset, vallen, ti);
offset += vallen;
- return offset - value_start;
+ break;
case 'x': /* byte array */
if (length < 4)
return 0; /* too short */
- vallen = tvb_get_ntohl(tvb, offset);
- offset += 4;
- length -= 4;
- if (length < vallen)
- return 0; /* too short */
- ti = proto_tree_add_item(field_table_tree, hf_amqp_field_byte_array, tvb,
- offset, vallen, ENC_NA);
- proto_item_prepend_text(ti, "%s ", name);
+ ti = proto_tree_add_item_ret_length(field_tree, hf_amqp_field_byte_array, tvb,
+ offset, 4, ENC_NA, &vallen);
offset += vallen;
- return offset - value_start;
- default:
- amqp_typename = "";
- value = NULL;
break;
+ default:
+ expert_add_info(pinfo, type_item, &ei_amqp_array_type_unknown);
+ /* Without knowing the type, we don't know how much to increment
+ * the offset, so break out. */
+ return 0;
}
- if (value != NULL)
- proto_tree_add_none_format(field_table_tree, hf_amqp_field, tvb,
- value_start, offset - value_start,
- "%s (%s): %s", name, amqp_typename, value);
- else
- proto_tree_add_none_format(field_table_tree, hf_amqp_field, tvb,
- value_start, offset - value_start,
- "%s: unknown type %s",
- name,
- hfinfo_char_value_format_display(BASE_HEX, type_buf, type));
+ proto_item_set_end(field_item, tvb, offset);
+ if (ti != NULL) {
+ proto_item_append_text(field_item, ": %s", proto_item_get_display_repr(pinfo->pool, ti));
+ }
return offset - value_start;
}
@@ -13270,16 +13267,72 @@ proto_register_amqp(void)
FT_BOOLEAN, 8, NULL, 0x01,
NULL, HFILL}},
{&hf_amqp_field, {
- "AMQP", "amqp.field",
+ "Field", "amqp.field",
FT_NONE, BASE_NONE, NULL, 0,
NULL, HFILL}},
+ {&hf_amqp_field_name, {
+ "Name", "amqp.field.name",
+ FT_STRING, BASE_NONE, NULL, 0,
+ NULL, HFILL}},
+ {&hf_amqp_field_type, {
+ "Type", "amqp.field.type",
+ FT_CHAR, BASE_HEX, VALS(amqp_0_9_field_type_vals), 0,
+ NULL, HFILL}},
+ {&hf_amqp_field_integer, {
+ "Value", "amqp.field.integer",
+ FT_INT32, BASE_DEC, NULL, 0,
+ NULL, HFILL}},
+ {&hf_amqp_field_unsigned_integer, {
+ "Value", "amqp.field.unsigned_integer",
+ FT_UINT32, BASE_DEC, NULL, 0,
+ NULL, HFILL}},
+ {&hf_amqp_field_string, {
+ "Value", "amqp.field.string",
+ FT_UINT_STRING, BASE_NONE, NULL, 0,
+ NULL, HFILL}},
+ {&hf_amqp_field_boolean, {
+ "Value", "amqp.field.boolean",
+ FT_BOOLEAN, BASE_NONE, NULL, 0,
+ NULL, HFILL}},
+ {&hf_amqp_field_byte, {
+ "Value", "amqp.field.byte",
+ FT_INT8, BASE_DEC, NULL, 0,
+ NULL, HFILL}},
+ {&hf_amqp_field_unsigned_byte, {
+ "Value", "amqp.field.unsigned_byte",
+ FT_UINT8, BASE_DEC, NULL, 0,
+ NULL, HFILL}},
+ {&hf_amqp_field_short_int, {
+ "Value", "amqp.field.short_int",
+ FT_INT16, BASE_DEC, NULL, 0,
+ NULL, HFILL}},
+ {&hf_amqp_field_short_uint, {
+ "Value", "amqp.field.short_uint",
+ FT_UINT16, BASE_DEC, NULL, 0,
+ NULL, HFILL}},
+ {&hf_amqp_field_long_int, {
+ "Value", "amqp.field.long_int",
+ FT_INT64, BASE_DEC, NULL, 0,
+ NULL, HFILL}},
+ {&hf_amqp_field_float, {
+ "Value", "amqp.field.float",
+ FT_FLOAT, BASE_NONE, NULL, 0,
+ NULL, HFILL}},
+ {&hf_amqp_field_double, {
+ "Value", "amqp.field.double",
+ FT_DOUBLE, BASE_NONE, NULL, 0,
+ NULL, HFILL}},
+ {&hf_amqp_field_decimal, {
+ "Value", "amqp.field.decimal",
+ FT_DOUBLE, BASE_NONE, NULL, 0,
+ NULL, HFILL}},
{&hf_amqp_field_timestamp, {
- "(timestamp)", "amqp.field.timestamp",
+ "Value", "amqp.field.timestamp",
FT_ABSOLUTE_TIME, ABSOLUTE_TIME_UTC, NULL, 0x0,
NULL, HFILL}},
{&hf_amqp_field_byte_array, {
- "(byte array)", "amqp.field.byte_array",
- FT_BYTES, BASE_NONE, NULL, 0,
+ "Value", "amqp.field.byte_array",
+ FT_UINT_BYTES, BASE_NONE, NULL, 0,
NULL, HFILL}},
{&hf_amqp_header_class_id, {
"Class ID", "amqp.header.class",
@@ -13552,6 +13605,7 @@ proto_register_amqp(void)
&ett_props,
&ett_field_table,
&ett_amqp_init,
+ &ett_amqp_0_9_field,
&ett_amqp_0_10_map,
&ett_amqp_0_10_array,
&ett_amqp_0_10_struct,