aboutsummaryrefslogtreecommitdiffstats
path: root/epan/ftypes
diff options
context:
space:
mode:
authorJoão Valverde <j@v6e.pt>2022-02-27 09:56:41 +0000
committerA Wireshark GitLab Utility <gerald+gitlab-utility@wireshark.org>2022-03-28 11:20:41 +0000
commitac0a69636ba799f976c7fc01f137c0bbb89b0a17 (patch)
tree67eacf57e0a627ed8da5053207e9d4ad0927414e /epan/ftypes
parent677b68aa3b58558d9062f2c80ef72cfc2ec0c4d8 (diff)
dfilter: Add support for unary arithmetic
This change implements a unary minus operator. Filter: tcp.window_size_scalefactor == -tcp.dstport Instructions: 00000 READ_TREE tcp.window_size_scalefactor -> reg#0 00001 IF_FALSE_GOTO 6 00002 READ_TREE tcp.dstport -> reg#1 00003 IF_FALSE_GOTO 6 00004 MK_MINUS -reg#1 -> reg#2 00005 ANY_EQ reg#0 == reg#2 00006 RETURN It is supported for integer types, floats and relative time values. The unsigned integer types are promoted to a 32 bit signed integer. Unary plus is implemented as a no-op. The plus sign is simply ignored. Constant arithmetic expressions are computed during compilation. Overflow with constants is a compile time error. Overflow with variables is a run time error and silently ignored. Only a debug message will be printed to the console. Related to #15504.
Diffstat (limited to 'epan/ftypes')
-rw-r--r--epan/ftypes/ftype-bytes.c9
-rw-r--r--epan/ftypes/ftype-double.c9
-rw-r--r--epan/ftypes/ftype-guid.c1
-rw-r--r--epan/ftypes/ftype-ieee-11073-float.c2
-rw-r--r--epan/ftypes/ftype-integer.c144
-rw-r--r--epan/ftypes/ftype-ipv4.c1
-rw-r--r--epan/ftypes/ftype-ipv6.c1
-rw-r--r--epan/ftypes/ftype-none.c1
-rw-r--r--epan/ftypes/ftype-protocol.c1
-rw-r--r--epan/ftypes/ftype-string.c5
-rw-r--r--epan/ftypes/ftype-time.c10
-rw-r--r--epan/ftypes/ftypes-int.h12
-rw-r--r--epan/ftypes/ftypes.c35
-rw-r--r--epan/ftypes/ftypes.h8
14 files changed, 151 insertions, 88 deletions
diff --git a/epan/ftypes/ftype-bytes.c b/epan/ftypes/ftype-bytes.c
index a7a9362a4f..e07052554d 100644
--- a/epan/ftypes/ftype-bytes.c
+++ b/epan/ftypes/ftype-bytes.c
@@ -605,6 +605,7 @@ ftype_register_bytes(void)
len,
slice,
bytes_bitwise_and, /* bitwise_and */
+ NULL, /* unary_minus */
};
static ftype_t uint_bytes_type = {
@@ -630,6 +631,7 @@ ftype_register_bytes(void)
len,
slice,
bytes_bitwise_and, /* bitwise_and */
+ NULL, /* unary_minus */
};
static ftype_t ax25_type = {
@@ -655,6 +657,7 @@ ftype_register_bytes(void)
len,
slice,
bytes_bitwise_and, /* bitwise_and */
+ NULL, /* unary_minus */
};
static ftype_t vines_type = {
@@ -680,6 +683,7 @@ ftype_register_bytes(void)
len,
slice,
bytes_bitwise_and, /* bitwise_and */
+ NULL, /* unary_minus */
};
static ftype_t ether_type = {
@@ -705,6 +709,7 @@ ftype_register_bytes(void)
len,
slice,
bytes_bitwise_and, /* bitwise_and */
+ NULL, /* unary_minus */
};
static ftype_t oid_type = {
@@ -730,6 +735,7 @@ ftype_register_bytes(void)
len,
slice,
bytes_bitwise_and, /* bitwise_and */
+ NULL, /* unary_minus */
};
static ftype_t rel_oid_type = {
@@ -755,6 +761,7 @@ ftype_register_bytes(void)
len,
slice,
bytes_bitwise_and, /* bitwise_and */
+ NULL, /* unary_minus */
};
static ftype_t system_id_type = {
@@ -780,6 +787,7 @@ ftype_register_bytes(void)
len,
slice,
bytes_bitwise_and, /* bitwise_and */
+ NULL, /* unary_minus */
};
static ftype_t fcwwn_type = {
@@ -805,6 +813,7 @@ ftype_register_bytes(void)
len,
slice,
bytes_bitwise_and, /* bitwise_and */
+ NULL, /* unary_minus */
};
ftype_register(FT_BYTES, &bytes_type);
diff --git a/epan/ftypes/ftype-double.c b/epan/ftypes/ftype-double.c
index 2dcaaafa62..0fdc53b414 100644
--- a/epan/ftypes/ftype-double.c
+++ b/epan/ftypes/ftype-double.c
@@ -85,6 +85,13 @@ double_val_to_repr(wmem_allocator_t *scope, const fvalue_t *fv, ftrepr_t rtype _
return buf;
}
+enum ft_result
+val_unary_minus(fvalue_t * dst, const fvalue_t *src, char **err_ptr _U_)
+{
+ dst->value.floating = -src->value.floating;
+ return FT_OK;
+}
+
static int
cmp_order(const fvalue_t *a, const fvalue_t *b)
{
@@ -122,6 +129,7 @@ ftype_register_double(void)
NULL,
NULL,
NULL, /* bitwise_and */
+ val_unary_minus, /* unary_minus */
};
static ftype_t double_type = {
@@ -147,6 +155,7 @@ ftype_register_double(void)
NULL,
NULL,
NULL, /* bitwise_and */
+ val_unary_minus, /* unary_minus */
};
ftype_register(FT_FLOAT, &float_type);
diff --git a/epan/ftypes/ftype-guid.c b/epan/ftypes/ftype-guid.c
index af4e9a58fe..2c4e05c931 100644
--- a/epan/ftypes/ftype-guid.c
+++ b/epan/ftypes/ftype-guid.c
@@ -120,6 +120,7 @@ ftype_register_guid(void)
NULL,
NULL,
NULL,
+ NULL, /* unary_minus */
};
ftype_register(FT_GUID, &guid_type);
diff --git a/epan/ftypes/ftype-ieee-11073-float.c b/epan/ftypes/ftype-ieee-11073-float.c
index a1ba68adb2..a5423eb5fa 100644
--- a/epan/ftypes/ftype-ieee-11073-float.c
+++ b/epan/ftypes/ftype-ieee-11073-float.c
@@ -921,6 +921,7 @@ Example: 114 is 0x0072
NULL, /* len */
NULL, /* slice */
NULL, /* bitwise_and */
+ NULL, /* unary_minus */
};
/*
@@ -973,6 +974,7 @@ Example: 36.4 is 0xFF00016C
NULL, /* len */
NULL, /* slice */
NULL, /* bitwise_and */
+ NULL, /* unary_minus */
};
ftype_register(FT_IEEE_11073_SFLOAT, &sfloat_type);
diff --git a/epan/ftypes/ftype-integer.c b/epan/ftypes/ftype-integer.c
index faa0f8e155..a93563a344 100644
--- a/epan/ftypes/ftype-integer.c
+++ b/epan/ftypes/ftype-integer.c
@@ -53,10 +53,6 @@ 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);
}
@@ -71,19 +67,6 @@ uint_from_literal(fvalue_t *fv, const char *s, gboolean allow_partial_value _U_,
unsigned long value;
char *endptr;
- /*
- * Try to parse it as a number.
- */
- if (strchr (s, '-') && strtol(s, NULL, 0) < 0) {
- /*
- * Probably a negative integer, but will be
- * "converted in the obvious manner" by strtoul().
- */
- if (err_msg != NULL)
- *err_msg = ws_strdup_printf("\"%s\" too small for this field, minimum 0.", s);
- return FALSE;
- }
-
errno = 0;
value = binary_strtoul(s, &endptr);
@@ -155,19 +138,9 @@ 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(binstr + 2, endptr, 2);
}
return strtol(s, endptr, 0);
@@ -180,20 +153,6 @@ sint_from_literal(fvalue_t *fv, const char *s, gboolean allow_partial_value _U_,
long value;
char *endptr;
- /*
- * Try to parse it as a number.
- */
- if (!strchr (s, '-') && strtoul(s, NULL, 0) > G_MAXINT32) {
- /*
- * Probably a positive integer > G_MAXINT32, but
- * will be "converted in the obvious manner" by
- * strtol().
- */
- if (err_msg != NULL)
- *err_msg = ws_strdup_printf("\"%s\" causes an integer overflow.", s);
- return FALSE;
- }
-
errno = 0;
value = binary_strtol(s, &endptr);
@@ -493,10 +452,6 @@ 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);
}
@@ -511,16 +466,6 @@ _uint64_from_literal(fvalue_t *fv, const char *s, gboolean allow_partial_value _
guint64 value;
char *endptr;
- if (strchr (s, '-') && g_ascii_strtoll(s, NULL, 0) < 0) {
- /*
- * Probably a negative integer, but will be
- * "converted in the obvious manner" by g_ascii_strtoull().
- */
- if (err_msg != NULL)
- *err_msg = ws_strdup_printf("\"%s\" causes an integer underflow.", s);
- return FALSE;
- }
-
errno = 0;
value = binary_strtoull(s, &endptr);
@@ -591,19 +536,9 @@ 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(binstr + 2, endptr, 2);
}
return g_ascii_strtoll(s, endptr, 0);
@@ -616,16 +551,6 @@ _sint64_from_literal(fvalue_t *fv, const char *s, gboolean allow_partial_value _
gint64 value;
char *endptr;
- if (!strchr (s, '-') && g_ascii_strtoull(s, NULL, 0) > G_MAXINT64) {
- /*
- * Probably a positive integer > G_MAXINT64, but will be
- * "converted in the obvious manner" by g_ascii_strtoll().
- */
- if (err_msg != NULL)
- *err_msg = ws_strdup_printf("\"%s\" causes an integer overflow.", s);
- return FALSE;
- }
-
errno = 0;
value = binary_strtoll(s, &endptr);
@@ -754,6 +679,21 @@ uint_is_zero(const fvalue_t *fv)
}
enum ft_result
+uint_unary_minus(fvalue_t *dst, const fvalue_t *src, char **err_ptr)
+{
+ /* Unsigned integers are promoted to 32 bits. */
+ if (src->value.uinteger > G_MAXINT32) {
+ if (err_ptr)
+ *err_ptr = ws_strdup_printf("%"G_GUINT32_FORMAT" overflows gint32",
+ src->value.uinteger);
+ return FT_ERR_OVERFLOW;
+ }
+ FTYPE_LOOKUP(FT_INT32, dst->ftype);
+ dst->value.sinteger = -(gint32)src->value.uinteger;
+ return FT_OK;
+}
+
+enum ft_result
uint64_bitwise_and(fvalue_t *dst, const fvalue_t *a, const fvalue_t *b, char **err_ptr _U_)
{
dst->value.uinteger64 = a->value.uinteger64 & b->value.uinteger64;
@@ -767,6 +707,21 @@ uint64_is_zero(const fvalue_t *fv)
}
enum ft_result
+uint64_unary_minus(fvalue_t *dst, const fvalue_t *src, char **err_ptr)
+{
+ /* Unsigned64 integers are promoted to 64 bits. */
+ if (src->value.uinteger64 > G_MAXINT64) {
+ if (err_ptr)
+ *err_ptr = ws_strdup_printf("%"G_GUINT64_FORMAT" overflows gint64",
+ src->value.uinteger64);
+ return FT_ERR_OVERFLOW;
+ }
+ FTYPE_LOOKUP(FT_INT64, dst->ftype);
+ dst->value.sinteger64 = -(gint64)src->value.uinteger64;
+ return FT_OK;
+}
+
+enum ft_result
sint_bitwise_and(fvalue_t *dst, const fvalue_t *a, const fvalue_t *b, char **err_ptr _U_)
{
dst->value.sinteger = a->value.sinteger & b->value.sinteger;
@@ -780,6 +735,13 @@ sint_is_zero(const fvalue_t *fv)
}
enum ft_result
+sint_unary_minus(fvalue_t * dst, const fvalue_t *src, char **err_ptr _U_)
+{
+ dst->value.sinteger = -src->value.sinteger;
+ return FT_OK;
+}
+
+enum ft_result
sint64_bitwise_and(fvalue_t *dst, const fvalue_t *a, const fvalue_t *b, char **err_ptr _U_)
{
dst->value.sinteger64 = a->value.sinteger64 & b->value.sinteger64;
@@ -792,6 +754,13 @@ sint64_is_zero(const fvalue_t *fv)
return fv->value.sinteger64 == 0;
}
+enum ft_result
+sint64_unary_minus(fvalue_t * dst, const fvalue_t *src, char **err_ptr _U_)
+{
+ dst->value.sinteger64 = -src->value.sinteger64;
+ return FT_OK;
+}
+
/* BOOLEAN-specific */
static gboolean
@@ -916,6 +885,7 @@ ftype_register_integers(void)
NULL, /* len */
NULL, /* slice */
uint_bitwise_and, /* bitwise_and */
+ uint_unary_minus, /* unary_minus */
};
static ftype_t uint8_type = {
FT_UINT8, /* ftype */
@@ -940,6 +910,7 @@ ftype_register_integers(void)
NULL, /* len */
NULL, /* slice */
uint_bitwise_and, /* bitwise_and */
+ uint_unary_minus, /* unary_minus */
};
static ftype_t uint16_type = {
FT_UINT16, /* ftype */
@@ -964,6 +935,7 @@ ftype_register_integers(void)
NULL, /* len */
NULL, /* slice */
uint_bitwise_and, /* bitwise_and */
+ uint_unary_minus, /* unary_minus */
};
static ftype_t uint24_type = {
FT_UINT24, /* ftype */
@@ -988,6 +960,7 @@ ftype_register_integers(void)
NULL, /* len */
NULL, /* slice */
uint_bitwise_and, /* bitwise_and */
+ uint_unary_minus, /* unary_minus */
};
static ftype_t uint32_type = {
FT_UINT32, /* ftype */
@@ -1012,6 +985,7 @@ ftype_register_integers(void)
NULL, /* len */
NULL, /* slice */
uint_bitwise_and, /* bitwise_and */
+ uint_unary_minus, /* unary_minus */
};
static ftype_t uint40_type = {
FT_UINT40, /* ftype */
@@ -1036,6 +1010,7 @@ ftype_register_integers(void)
NULL, /* len */
NULL, /* slice */
uint64_bitwise_and, /* bitwise_and */
+ uint64_unary_minus, /* unary_minus */
};
static ftype_t uint48_type = {
FT_UINT48, /* ftype */
@@ -1060,6 +1035,7 @@ ftype_register_integers(void)
NULL, /* len */
NULL, /* slice */
uint64_bitwise_and, /* bitwise_and */
+ uint64_unary_minus, /* unary_minus */
};
static ftype_t uint56_type = {
FT_UINT56, /* ftype */
@@ -1084,6 +1060,7 @@ ftype_register_integers(void)
NULL, /* len */
NULL, /* slice */
uint64_bitwise_and, /* bitwise_and */
+ uint64_unary_minus, /* unary_minus */
};
static ftype_t uint64_type = {
FT_UINT64, /* ftype */
@@ -1108,6 +1085,7 @@ ftype_register_integers(void)
NULL, /* len */
NULL, /* slice */
uint64_bitwise_and, /* bitwise_and */
+ uint64_unary_minus, /* unary_minus */
};
static ftype_t int8_type = {
FT_INT8, /* ftype */
@@ -1132,6 +1110,7 @@ ftype_register_integers(void)
NULL, /* len */
NULL, /* slice */
sint_bitwise_and, /* bitwise_and */
+ sint_unary_minus, /* unary_minus */
};
static ftype_t int16_type = {
FT_INT16, /* ftype */
@@ -1156,6 +1135,7 @@ ftype_register_integers(void)
NULL, /* len */
NULL, /* slice */
sint_bitwise_and, /* bitwise_and */
+ sint_unary_minus, /* unary_minus */
};
static ftype_t int24_type = {
FT_INT24, /* ftype */
@@ -1180,6 +1160,7 @@ ftype_register_integers(void)
NULL, /* len */
NULL, /* slice */
sint_bitwise_and, /* bitwise_and */
+ sint_unary_minus, /* unary_minus */
};
static ftype_t int32_type = {
FT_INT32, /* ftype */
@@ -1204,6 +1185,7 @@ ftype_register_integers(void)
NULL, /* len */
NULL, /* slice */
sint_bitwise_and, /* bitwise_and */
+ sint_unary_minus, /* unary_minus */
};
static ftype_t int40_type = {
FT_INT40, /* ftype */
@@ -1228,6 +1210,7 @@ ftype_register_integers(void)
NULL, /* len */
NULL, /* slice */
sint64_bitwise_and, /* bitwise_and */
+ sint64_unary_minus, /* unary_minus */
};
static ftype_t int48_type = {
FT_INT48, /* ftype */
@@ -1252,6 +1235,7 @@ ftype_register_integers(void)
NULL, /* len */
NULL, /* slice */
sint64_bitwise_and, /* bitwise_and */
+ sint64_unary_minus, /* unary_minus */
};
static ftype_t int56_type = {
FT_INT56, /* ftype */
@@ -1276,6 +1260,7 @@ ftype_register_integers(void)
NULL, /* len */
NULL, /* slice */
sint64_bitwise_and, /* bitwise_and */
+ sint64_unary_minus, /* unary_minus */
};
static ftype_t int64_type = {
FT_INT64, /* ftype */
@@ -1300,6 +1285,7 @@ ftype_register_integers(void)
NULL, /* len */
NULL, /* slice */
sint64_bitwise_and, /* bitwise_and */
+ sint64_unary_minus, /* unary_minus */
};
static ftype_t boolean_type = {
FT_BOOLEAN, /* ftype */
@@ -1324,6 +1310,7 @@ ftype_register_integers(void)
NULL, /* len */
NULL, /* slice */
NULL, /* bitwise_and */
+ NULL, /* unary_minus */
};
static ftype_t ipxnet_type = {
@@ -1349,6 +1336,7 @@ ftype_register_integers(void)
NULL, /* len */
NULL, /* slice */
uint_bitwise_and, /* bitwise_and */
+ uint_unary_minus, /* unary_minus */
};
static ftype_t framenum_type = {
@@ -1374,6 +1362,7 @@ ftype_register_integers(void)
NULL, /* len */
NULL, /* slice */
uint_bitwise_and, /* bitwise_and */
+ uint_unary_minus, /* unary_minus */
};
static ftype_t eui64_type = {
@@ -1399,6 +1388,7 @@ ftype_register_integers(void)
NULL, /* len */
NULL, /* slice */
uint64_bitwise_and, /* bitwise_and */
+ uint64_unary_minus, /* unary_minus */
};
ftype_register(FT_CHAR, &char_type);
diff --git a/epan/ftypes/ftype-ipv4.c b/epan/ftypes/ftype-ipv4.c
index d3cf02a947..fe032cf7f4 100644
--- a/epan/ftypes/ftype-ipv4.c
+++ b/epan/ftypes/ftype-ipv4.c
@@ -172,6 +172,7 @@ ftype_register_ipv4(void)
NULL,
slice,
bitwise_and,
+ NULL, /* unary_minus */
};
ftype_register(FT_IPv4, &ipv4_type);
diff --git a/epan/ftypes/ftype-ipv6.c b/epan/ftypes/ftype-ipv6.c
index 4daae57b13..224940f49c 100644
--- a/epan/ftypes/ftype-ipv6.c
+++ b/epan/ftypes/ftype-ipv6.c
@@ -195,6 +195,7 @@ ftype_register_ipv6(void)
NULL,
slice,
bitwise_and,
+ NULL, /* unary_minus */
};
ftype_register(FT_IPv6, &ipv6_type);
diff --git a/epan/ftypes/ftype-none.c b/epan/ftypes/ftype-none.c
index 56da4cb2a1..937d2e9429 100644
--- a/epan/ftypes/ftype-none.c
+++ b/epan/ftypes/ftype-none.c
@@ -38,6 +38,7 @@ ftype_register_none(void)
NULL, /* len */
NULL, /* slice */
NULL, /* biwise_and */
+ NULL, /* unary_minus */
};
ftype_register(FT_NONE, &none_type);
}
diff --git a/epan/ftypes/ftype-protocol.c b/epan/ftypes/ftype-protocol.c
index e7da850576..a52b6815e3 100644
--- a/epan/ftypes/ftype-protocol.c
+++ b/epan/ftypes/ftype-protocol.c
@@ -333,6 +333,7 @@ ftype_register_tvbuff(void)
len,
slice,
NULL,
+ NULL, /* unary_minus */
};
diff --git a/epan/ftypes/ftype-string.c b/epan/ftypes/ftype-string.c
index 0563ce03bb..157cff7263 100644
--- a/epan/ftypes/ftype-string.c
+++ b/epan/ftypes/ftype-string.c
@@ -186,6 +186,7 @@ ftype_register_string(void)
len,
slice,
NULL, /* bitwise_and */
+ NULL, /* unary_minus */
};
static ftype_t stringz_type = {
FT_STRINGZ, /* ftype */
@@ -210,6 +211,7 @@ ftype_register_string(void)
len,
slice,
NULL, /* bitwise_and */
+ NULL, /* unary_minus */
};
static ftype_t uint_string_type = {
FT_UINT_STRING, /* ftype */
@@ -234,6 +236,7 @@ ftype_register_string(void)
len,
slice,
NULL, /* bitwise_and */
+ NULL, /* unary_minus */
};
static ftype_t stringzpad_type = {
FT_STRINGZPAD, /* ftype */
@@ -258,6 +261,7 @@ ftype_register_string(void)
len,
slice,
NULL, /* bitwise_and */
+ NULL, /* unary_minus */
};
static ftype_t stringztrunc_type = {
FT_STRINGZTRUNC, /* ftype */
@@ -282,6 +286,7 @@ ftype_register_string(void)
len,
slice,
NULL, /* bitwise_and */
+ NULL, /* unary_minus */
};
ftype_register(FT_STRING, &string_type);
diff --git a/epan/ftypes/ftype-time.c b/epan/ftypes/ftype-time.c
index c3848e99b8..18eb376073 100644
--- a/epan/ftypes/ftype-time.c
+++ b/epan/ftypes/ftype-time.c
@@ -411,6 +411,14 @@ time_is_zero(const fvalue_t *fv)
return nstime_is_zero(&fv->value.time);
}
+static enum ft_result
+time_unary_minus(fvalue_t * dst, const fvalue_t *src, char **err_ptr _U_)
+{
+ dst->value.time.secs = -src->value.time.secs;
+ dst->value.time.nsecs = -src->value.time.nsecs;
+ return FT_OK;
+}
+
void
ftype_register_time(void)
{
@@ -438,6 +446,7 @@ ftype_register_time(void)
NULL,
NULL,
NULL, /* bitwise_and */
+ NULL, /* unary_minus */
};
static ftype_t reltime_type = {
FT_RELATIVE_TIME, /* ftype */
@@ -462,6 +471,7 @@ ftype_register_time(void)
NULL,
NULL,
NULL, /* bitwise_and */
+ time_unary_minus, /* unary_minus */
};
ftype_register(FT_ABSOLUTE_TIME, &abstime_type);
diff --git a/epan/ftypes/ftypes-int.h b/epan/ftypes/ftypes-int.h
index eba613e0c9..56758a3a03 100644
--- a/epan/ftypes/ftypes-int.h
+++ b/epan/ftypes/ftypes-int.h
@@ -13,9 +13,17 @@
#include "ftypes.h"
#include <epan/proto.h>
+extern ftype_t* type_list[FT_NUM_TYPES];
+
+/* Given an ftenum number, return an ftype_t* */
+#define FTYPE_LOOKUP(ftype, result) \
+ /* Check input */ \
+ ws_assert(ftype < FT_NUM_TYPES); \
+ result = type_list[ftype];
+
enum ft_result {
FT_OK,
- FT_ERROR,
+ FT_ERR_OVERFLOW,
};
typedef void (*FvalueNewFunc)(fvalue_t*);
@@ -53,6 +61,7 @@ typedef gboolean (*FvalueIsZero)(const fvalue_t*);
typedef guint (*FvalueLen)(fvalue_t*);
typedef void (*FvalueSlice)(fvalue_t*, GByteArray *, guint offset, guint length);
typedef enum ft_result (*FvalueBitwiseAnd)(fvalue_t *, const fvalue_t*, const fvalue_t*, gchar **);
+typedef enum ft_result (*FvalueUnaryMinus)(fvalue_t *, const fvalue_t*, gchar **);
struct _ftype_t {
ftenum_t ftype;
@@ -97,6 +106,7 @@ struct _ftype_t {
FvalueLen len;
FvalueSlice slice;
FvalueBitwiseAnd bitwise_and;
+ FvalueUnaryMinus unary_minus;
};
void ftype_register(enum ftenum ftype, ftype_t *ft);
diff --git a/epan/ftypes/ftypes.c b/epan/ftypes/ftypes.c
index 6619e0e5cd..2f05fcb901 100644
--- a/epan/ftypes/ftypes.c
+++ b/epan/ftypes/ftypes.c
@@ -13,7 +13,7 @@
#include <wsutil/ws_assert.h>
/* Keep track of ftype_t's via their ftenum number */
-static ftype_t* type_list[FT_NUM_TYPES];
+ftype_t* type_list[FT_NUM_TYPES];
/* Initialize the ftype module. */
void
@@ -46,13 +46,6 @@ ftype_register(enum ftenum ftype, ftype_t *ft)
type_list[ftype] = ft;
}
-/* Given an ftenum number, return an ftype_t* */
-#define FTYPE_LOOKUP(ftype, result) \
- /* Check input */ \
- ws_assert(ftype < FT_NUM_TYPES); \
- result = type_list[ftype];
-
-
/* from README.dissector:
Note that the formats used must all belong to the same list as defined below:
@@ -193,6 +186,15 @@ ftype_can_bitwise_and(enum ftenum ftype)
}
gboolean
+ftype_can_unary_minus(enum ftenum ftype)
+{
+ ftype_t *ft;
+
+ FTYPE_LOOKUP(ftype, ft);
+ return ft->unary_minus != NULL;
+}
+
+gboolean
ftype_can_contains(enum ftenum ftype)
{
ftype_t *ft;
@@ -760,7 +762,7 @@ fvalue_is_zero(const fvalue_t *a)
}
fvalue_t *
-fvalue_bitwise_and(const fvalue_t *a, const fvalue_t *b, gchar **err_msg)
+fvalue_bitwise_and(const fvalue_t *a, const fvalue_t *b, char **err_msg)
{
fvalue_t *result;
@@ -775,6 +777,21 @@ fvalue_bitwise_and(const fvalue_t *a, const fvalue_t *b, gchar **err_msg)
return result;
}
+fvalue_t*
+fvalue_unary_minus(const fvalue_t *fv, char **err_msg)
+{
+ fvalue_t *result;
+
+ ws_assert(fv->ftype->unary_minus);
+
+ result = fvalue_new(fv->ftype->ftype);
+ if (fv->ftype->unary_minus(result, fv, err_msg) != FT_OK) {
+ fvalue_free(result);
+ return NULL;
+ }
+ return result;
+}
+
/*
* Editor modelines - https://www.wireshark.org/tools/modelines.html
*
diff --git a/epan/ftypes/ftypes.h b/epan/ftypes/ftypes.h
index aab6e9e3c9..234ef4e9b1 100644
--- a/epan/ftypes/ftypes.h
+++ b/epan/ftypes/ftypes.h
@@ -182,6 +182,9 @@ ftype_can_cmp(enum ftenum ftype);
gboolean
ftype_can_bitwise_and(enum ftenum ftype);
+gboolean
+ftype_can_unary_minus(enum ftenum ftype);
+
WS_DLL_PUBLIC
gboolean
ftype_can_contains(enum ftenum ftype);
@@ -363,7 +366,10 @@ fvalue_t*
fvalue_slice(fvalue_t *fv, drange_t *dr);
fvalue_t*
-fvalue_bitwise_and(const fvalue_t *a, const fvalue_t *b, gchar **err_msg);
+fvalue_bitwise_and(const fvalue_t *a, const fvalue_t *b, char **err_msg);
+
+fvalue_t*
+fvalue_unary_minus(const fvalue_t *fv, char **err_msg);
#ifdef __cplusplus
}