dfilter: Add support for binary literal constants

Example: 0b1001, 0B111000, etc.
pespin/osmux-wip
João Valverde 2022-02-23 17:02:53 +00:00 committed by A Wireshark GitLab Utility
parent 1aef88df4b
commit 9cc3e7e1bb
5 changed files with 103 additions and 7 deletions

View File

@ -172,13 +172,14 @@ Each protocol field is typed. The types are:
Unsigned integer, 1, 2, 3, 4, or 8 bytes
1-byte ASCII character
An integer may be expressed in decimal, octal, or hexadecimal notation,
An integer may be expressed in decimal, octal, hexadecimal or binary notation,
or as a C-style character constant. The following six display filters
are equivalent:
frame.len > 10
frame.len > 012
frame.len > 0xa
frame.len > 0b1010
frame.len > '\n'
frame.len > '\x0a'
frame.len > '\012'

View File

@ -57,6 +57,7 @@ They previously shipped with Npcap 1.55.
** Adds the aliases "any_eq" for "==" and "all_ne" for "!=".
** Date and time can be given in UTC using ISO 8601 (with 'Z' timezone) or by appending the suffix "UTC" to the legacy formats.
Otherwise local time is used.
** Integer literal constants may be written in binary (in addition to decimal/octal/hexadecimal) using the prefix "0b" or "0B".
* text2pcap and "Import from Hex Dump":
** text2pcap supports writing the output file in all the capture file formats

View File

@ -541,17 +541,19 @@ of the types with examples of how to use them in display filters.
Unsigned integer::
Can be 8, 16, 24, 32, or 64 bits. You can express integers in decimal, octal,
or hexadecimal. The following display filters are equivalent:
hexadecimal or binary. The following display filters are equivalent:
+
`ip.len le 1500`
+
`ip.len le 02734`
+
`ip.len le 0x5dc`
+
`ip.len le 0b10111011100`
Signed integer::
Can be 8, 16, 24, 32, or 64 bits. As with unsigned integers you can use
decimal, octal, or hexadecimal.
decimal, octal, hexadecimal or binary.
Boolean::
Can be 1 (for true), or 0 (for false).

View File

@ -48,6 +48,22 @@ get_sinteger(fvalue_t *fv)
return fv->value.sinteger;
}
static unsigned long
binary_strtoul(const char *s, char **endptr)
{
const char *binstr = s;
if (*binstr == '+') {
binstr++;
}
if (binstr[0] == '0' && (binstr[1] == 'b' || binstr[1] == 'B')) {
return strtoul(binstr + 2, endptr, 2);
}
return strtoul(s, endptr, 0);
}
static gboolean
uint_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value _U_, gchar **err_msg,
guint32 max)
@ -69,7 +85,7 @@ uint_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value _U_
}
errno = 0;
value = strtoul(s, &endptr, 0);
value = binary_strtoul(s, &endptr);
if (errno == EINVAL || endptr == s || *endptr != '\0') {
/* This isn't a valid number. */
@ -135,6 +151,28 @@ uint_from_charconst(fvalue_t *fv, unsigned long num, gchar **err_msg _U_)
return TRUE;
}
static long
binary_strtol(const char *s, char **endptr)
{
const char *binstr = s;
gboolean negative = FALSE;
if (*binstr == '+') {
binstr++;
}
else if (*binstr == '-') {
binstr++;
negative = TRUE;
}
if (binstr[0] == '0' && (binstr[1] == 'b' || binstr[1] == 'B')) {
long value = strtol(binstr + 2, endptr, 2);
return negative ? -value : +value;
}
return strtol(s, endptr, 0);
}
static gboolean
sint_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value _U_, gchar **err_msg,
gint32 max, gint32 min)
@ -157,7 +195,7 @@ sint_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value _U_
}
errno = 0;
value = strtol(s, &endptr, 0);
value = binary_strtol(s, &endptr);
if (errno == EINVAL || endptr == s || *endptr != '\0') {
/* This isn't a valid number. */
@ -456,6 +494,22 @@ get_sinteger64(fvalue_t *fv)
return fv->value.sinteger64;
}
static unsigned long long
binary_strtoull(const char *s, char **endptr)
{
const char *binstr = s;
if (*binstr == '+') {
binstr++;
}
if (binstr[0] == '0' && (binstr[1] == 'b' || binstr[1] == 'B')) {
return g_ascii_strtoull(binstr + 2, endptr, 2);
}
return g_ascii_strtoull(s, endptr, 0);
}
static gboolean
_uint64_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value _U_, gchar **err_msg,
guint64 max)
@ -474,7 +528,7 @@ _uint64_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value
}
errno = 0;
value = g_ascii_strtoull(s, &endptr, 0);
value = binary_strtoull(s, &endptr);
if (errno == EINVAL || endptr == s || *endptr != '\0') {
/* This isn't a valid number. */
@ -539,6 +593,28 @@ uint64_from_charconst(fvalue_t *fv, unsigned long num, gchar **err_msg _U_)
return TRUE;
}
static long long
binary_strtoll(const char *s, char **endptr)
{
const char *binstr = s;
gboolean negative = FALSE;
if (*binstr == '+') {
binstr++;
}
else if (*binstr == '-') {
binstr++;
negative = TRUE;
}
if (binstr[0] == '0' && (binstr[1] == 'b' || binstr[1] == 'B')) {
long long value = g_ascii_strtoll(binstr + 2, endptr, 2);
return negative ? -value : +value;
}
return g_ascii_strtoll(s, endptr, 0);
}
static gboolean
_sint64_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value _U_, gchar **err_msg,
gint64 max, gint64 min)
@ -557,7 +633,7 @@ _sint64_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value
}
errno = 0;
value = g_ascii_strtoll(s, &endptr, 0);
value = binary_strtoll(s, &endptr);
if (errno == EINVAL || endptr == s || *endptr != '\0') {
/* This isn't a valid number. */

View File

@ -37,6 +37,22 @@ class case_integer(unittest.TestCase):
error = '"the" was unexpected in this context.'
checkDFilterFail(dfilter, error)
def test_eq_6(self, checkDFilterCount):
dfilter = "udp.srcport == 123"
checkDFilterCount(dfilter, 1)
def test_eq_7(self, checkDFilterCount):
dfilter = "udp.srcport == 0173"
checkDFilterCount(dfilter, 1)
def test_eq_8(self, checkDFilterCount):
dfilter = "udp.srcport == 0x7B"
checkDFilterCount(dfilter, 1)
def test_eq_9(self, checkDFilterCount):
dfilter = "udp.srcport == 0b1111011"
checkDFilterCount(dfilter, 1)
def test_ne_1(self, checkDFilterCount):
dfilter = "ip.version != 0"
checkDFilterCount(dfilter, 1)