dfilter: Tweak representation for length-1 byte array

Make dfilter byte representation always use ':' for consistency.

Make 1 byte be represented as "XX:" with the colon suffix to
make it nonambiguous that is is a byte and not other type,
like a protocol.

The difference is can be seen in the following programs. In the
before representation it is not obvious at all that the second
"fc" value is a literal bytes value and not the value of the
protocol "fc", although it can be inferred from the lack of
a READ_TREE instruction. In the After we know that "fc:" must
be bytes and not a protocol.

Note that a leading colon is a syntactical expedient to say
"this value with any type is a literal value and not a protocol
field." A terminating colon is just a part of the dfilter
literal bytes syntax.

Before:

Filter: fc == :fc

Syntax tree:
 0 TEST_ANY_EQ:
   1 FIELD(fc <FT_PROTOCOL>)
   1 FVALUE(fc <FT_PROTOCOL>)

Instructions:
00000 READ_TREE		fc <FT_PROTOCOL> -> reg#0
00001 IF_FALSE_GOTO	3
00002 ANY_EQ		reg#0 == fc <FT_PROTOCOL>

After:

Filter: fc == :fc

Syntax tree:
 0 TEST_ANY_EQ:
   1 FIELD(fc <FT_PROTOCOL>)
   1 FVALUE(fc: <FT_PROTOCOL>)

Instructions:
00000 READ_TREE		fc <FT_PROTOCOL> -> reg#0
00001 IF_FALSE_GOTO	3
00002 ANY_EQ		reg#0 == fc: <FT_PROTOCOL>
This commit is contained in:
João Valverde 2023-01-02 01:42:55 +00:00
parent c762d8492b
commit f37c7c4062
5 changed files with 44 additions and 9 deletions

View File

@ -121,7 +121,7 @@ IPv6Address ({h16}:){6}{ls32}|::({h16}:){5}{ls32}|({h16})?::({h16}:){4}{ls32}|((
V4CidrPrefix \/[[:digit:]]{1,2}
V6CidrPrefix \/[[:digit:]]{1,3}
ColonBytes {hex2}(:{hex2})+
ColonBytes ({hex2}:)|({hex2}(:{hex2})+)
DotBytes {hex2}(\.{hex2})+
HyphenBytes {hex2}(-{hex2})+

View File

@ -69,11 +69,38 @@ system_id_to_repr(wmem_allocator_t *scope, const fvalue_t *fv, ftrepr_t rtype _U
return print_system_id(scope, fv->value.bytes->data, fv->value.bytes->len);
}
char *
bytes_to_dfilter_repr(wmem_allocator_t *scope,
const guint8 *src, size_t src_size)
{
char *buf;
size_t max_char_size;
char *buf_ptr;
/* Include space for extra punct and '\0'. */
max_char_size = src_size * 3 + 1;
buf = wmem_alloc(scope, max_char_size);
buf_ptr = bytes_to_hexstr_punct(buf, src, src_size, ':');
if (src_size == 1)
*buf_ptr++ = ':';
*buf_ptr = '\0';
return buf;
}
static char *
bytes_to_repr(wmem_allocator_t *scope, const fvalue_t *fv, ftrepr_t rtype, int field_display)
{
char separator;
if (rtype == FTREPR_DFILTER) {
if (fv->value.bytes->len == 0) {
/* An empty byte array in a display filter is represented as "" */
return wmem_strdup(scope, "\"\"");
}
return bytes_to_dfilter_repr(scope, fv->value.bytes->data, fv->value.bytes->len);
}
switch(FIELD_DISPLAY(field_display))
{
case SEP_DOT:
@ -94,11 +121,6 @@ bytes_to_repr(wmem_allocator_t *scope, const fvalue_t *fv, ftrepr_t rtype, int f
return bytes_to_str_punct_maxlen(scope, fv->value.bytes->data, fv->value.bytes->len, separator, 0);
}
if (rtype == FTREPR_DFILTER) {
/* An empty byte array in a display filter is represented as "" */
return wmem_strdup(scope, "\"\"");
}
return wmem_strdup(scope, "");
}

View File

@ -169,7 +169,7 @@ val_from_charconst(fvalue_t *fv, unsigned long num, gchar **err_msg)
}
static char *
val_to_repr(wmem_allocator_t *scope, const fvalue_t *fv, ftrepr_t rtype _U_, int field_display _U_)
val_to_repr(wmem_allocator_t *scope, const fvalue_t *fv, ftrepr_t rtype, int field_display _U_)
{
guint length;
char *volatile buf = NULL;
@ -183,8 +183,12 @@ val_to_repr(wmem_allocator_t *scope, const fvalue_t *fv, ftrepr_t rtype _U_, int
else
length = tvb_captured_length(fv->value.protocol.tvb);
if (length)
buf = bytes_to_str_punct_maxlen(scope, tvb_get_ptr(fv->value.protocol.tvb, 0, length), length, ':', 0);
if (length) {
if (rtype == FTREPR_DFILTER)
buf = bytes_to_dfilter_repr(scope, tvb_get_ptr(fv->value.protocol.tvb, 0, length), length);
else
buf = bytes_to_str_punct_maxlen(scope, tvb_get_ptr(fv->value.protocol.tvb, 0, length), length, ':', 0);
}
}
CATCH_ALL {
/* nothing */

View File

@ -160,6 +160,10 @@ byte_array_from_literal(const char *s, gchar **err_msg);
GByteArray *
byte_array_from_charconst(unsigned long num, gchar **err_msg);
char *
bytes_to_dfilter_repr(wmem_allocator_t *scope,
const guint8 *src, size_t src_size);
#endif /* FTYPES_INT_H */
/*

View File

@ -188,6 +188,11 @@ class case_equality(unittest.TestCase):
dfilter = 'frame[37] == :fc'
checkDFilterCount(dfilter, 1)
def test_rhs_bias_3(self, checkDFilterCount):
# Byte 0xFC on the RHS
dfilter = 'frame[37] == fc:'
checkDFilterCount(dfilter, 1)
def test_rhs_literal_bias_4(self, checkDFilterCount):
# Protocol "Fibre Channel" on the RHS
dfilter = 'frame[37] == .fc'