diff options
author | João Valverde <j@v6e.pt> | 2022-02-27 09:56:41 +0000 |
---|---|---|
committer | A Wireshark GitLab Utility <gerald+gitlab-utility@wireshark.org> | 2022-03-28 11:20:41 +0000 |
commit | ac0a69636ba799f976c7fc01f137c0bbb89b0a17 (patch) | |
tree | 67eacf57e0a627ed8da5053207e9d4ad0927414e /epan/ftypes | |
parent | 677b68aa3b58558d9062f2c80ef72cfc2ec0c4d8 (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.c | 9 | ||||
-rw-r--r-- | epan/ftypes/ftype-double.c | 9 | ||||
-rw-r--r-- | epan/ftypes/ftype-guid.c | 1 | ||||
-rw-r--r-- | epan/ftypes/ftype-ieee-11073-float.c | 2 | ||||
-rw-r--r-- | epan/ftypes/ftype-integer.c | 144 | ||||
-rw-r--r-- | epan/ftypes/ftype-ipv4.c | 1 | ||||
-rw-r--r-- | epan/ftypes/ftype-ipv6.c | 1 | ||||
-rw-r--r-- | epan/ftypes/ftype-none.c | 1 | ||||
-rw-r--r-- | epan/ftypes/ftype-protocol.c | 1 | ||||
-rw-r--r-- | epan/ftypes/ftype-string.c | 5 | ||||
-rw-r--r-- | epan/ftypes/ftype-time.c | 10 | ||||
-rw-r--r-- | epan/ftypes/ftypes-int.h | 12 | ||||
-rw-r--r-- | epan/ftypes/ftypes.c | 35 | ||||
-rw-r--r-- | epan/ftypes/ftypes.h | 8 |
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 } |