diff --git a/doc/wireshark-filter.adoc b/doc/wireshark-filter.adoc index e46dcbbe13..308f708af5 100644 --- a/doc/wireshark-filter.adoc +++ b/doc/wireshark-filter.adoc @@ -130,6 +130,7 @@ The filter language has the following functions: string(field) - converts a non-string field to string max(f1,...,fn) - return the maximum value min(f1,...,fn) - return the minimum value + abs(field) - return the absolute value of numeric fields upper() and lower() are useful for performing case-insensitive string comparisons. For example: diff --git a/docbook/release-notes.adoc b/docbook/release-notes.adoc index 4d1add870c..902b0f8db8 100644 --- a/docbook/release-notes.adoc +++ b/docbook/release-notes.adoc @@ -68,7 +68,7 @@ They previously shipped with Npcap 1.55. ** Arithmetic is supported for numeric fields with the usual operators: +, -, *, /, %. Arithmetic expressions must be grouped using curly brackets (not parenthesis). ** Logical AND now has higher precedence than logical OR, in line with most programming languages. -** Adds new display filter functions max() and min(). +** Adds new display filter functions max(), min() and abs(). * text2pcap and "Import from Hex Dump": ** text2pcap supports writing the output file in all the capture file formats diff --git a/docbook/wsug_src/WSUG_chapter_work.adoc b/docbook/wsug_src/WSUG_chapter_work.adoc index cfd9ebe1fa..70a3e6da45 100644 --- a/docbook/wsug_src/WSUG_chapter_work.adoc +++ b/docbook/wsug_src/WSUG_chapter_work.adoc @@ -813,6 +813,7 @@ The display filter language has a number of functions to convert fields, see |string |Converts a non-string field to a string. |max |Return the maximum value for the arguments. |min |Return the minimum value for the arguments. +|abs |Return the absolute value for the argument. |=== The `upper` and `lower` functions can used to force case-insensitive matches: diff --git a/epan/dfilter/dfunctions.c b/epan/dfilter/dfunctions.c index 256a8ee525..6c05f92162 100644 --- a/epan/dfilter/dfunctions.c +++ b/epan/dfilter/dfunctions.c @@ -224,6 +224,43 @@ df_func_min(GSList **args, guint32 arg_count, GSList **retval) return df_func_compare(args, arg_count, retval, fvalue_lt); } +static gboolean +df_func_abs(GSList **args, guint32 arg_count, GSList **retval) +{ + GSList *arg1; + fvalue_t *fv_arg, *new_fv; + char *err_msg = NULL; + GSList *result = NULL; + + ws_assert(arg_count == 1); + arg1 = args[0]; + if (arg1 == NULL) + return FALSE; + + while (arg1) { + fv_arg = arg1->data; + if (fvalue_is_negative(fv_arg)) { + new_fv = fvalue_unary_minus(fv_arg, &err_msg); + if (new_fv == NULL) { + ws_debug("abs: %s", err_msg); + g_free(err_msg); + err_msg = NULL; + } + } + else { + new_fv = fvalue_dup(fv_arg); + } + result = g_slist_prepend(result, new_fv); + arg1 = arg1->next; + } + + if (g_slist_length(result) == 0) + return FALSE; + + *retval = result; + return TRUE; +} + /* For upper() and lower() checks that the parameter passed to * it is an FT_STRING */ static void @@ -379,6 +416,35 @@ ul_semcheck_compare(dfwork_t *dfw, const char *func_name, } } +static void +ul_semcheck_absolute_value(dfwork_t *dfw, const char *func_name, + GSList *param_list, stloc_t *func_loc _U_) +{ + ws_assert(g_slist_length(param_list) == 1); + stnode_t *st_node; + ftenum_t ftype; + const header_field_info *hfinfo; + + st_node = param_list->data; + dfw_resolve_unparsed(dfw, st_node); + + switch (stnode_type_id(st_node)) { + case STTYPE_FIELD: + case STTYPE_REFERENCE: + hfinfo = stnode_data(st_node); + ftype = hfinfo->type; + break; + default: + FAIL(dfw, st_node, "Type %s is not valid for %s", + stnode_type_name(st_node), func_name); + } + + if (!ftype_can_is_negative(ftype)) { + FAIL(dfw, st_node, "'%s' is not a valid argument to '%s'()", + stnode_todisplay(st_node), func_name); + } +} + /* The table of all display-filter functions */ static df_func_def_t df_functions[] = { @@ -387,8 +453,9 @@ df_functions[] = { { "len", df_func_len, FT_UINT32, 1, 1, ul_semcheck_is_field }, { "count", df_func_count, FT_UINT32, 1, 1, ul_semcheck_is_field }, { "string", df_func_string, FT_STRING, 1, 1, ul_semcheck_string_param }, - { "max", df_func_max, /*Any*/ 0, 1, 0, ul_semcheck_compare }, - { "min", df_func_min, /*Any*/ 0, 1, 0, ul_semcheck_compare }, + { "max", df_func_max, 0, 1, 0, ul_semcheck_compare }, + { "min", df_func_min, 0, 1, 0, ul_semcheck_compare }, + { "abs", df_func_abs, 0, 1, 1, ul_semcheck_absolute_value }, { NULL, NULL, FT_NONE, 0, 0, NULL } }; diff --git a/epan/ftypes/ftype-bytes.c b/epan/ftypes/ftype-bytes.c index 5e77a701e0..35908df27d 100644 --- a/epan/ftypes/ftype-bytes.c +++ b/epan/ftypes/ftype-bytes.c @@ -633,6 +633,7 @@ ftype_register_bytes(void) cmp_matches, bytes_is_zero, /* is_zero */ + NULL, /* is_negative */ len, slice, bytes_bitwise_and, /* bitwise_and */ @@ -665,6 +666,7 @@ ftype_register_bytes(void) NULL, /* cmp_matches */ bytes_is_zero, /* is_zero */ + NULL, /* is_negative */ len, slice, bytes_bitwise_and, /* bitwise_and */ @@ -697,6 +699,7 @@ ftype_register_bytes(void) cmp_matches, bytes_is_zero, /* is_zero */ + NULL, /* is_negative */ len, slice, bytes_bitwise_and, /* bitwise_and */ @@ -729,6 +732,7 @@ ftype_register_bytes(void) cmp_matches, bytes_is_zero, /* is_zero */ + NULL, /* is_negative */ len, slice, bytes_bitwise_and, /* bitwise_and */ @@ -761,6 +765,7 @@ ftype_register_bytes(void) cmp_matches, bytes_is_zero, /* is_zero */ + NULL, /* is_negative */ len, slice, bytes_bitwise_and, /* bitwise_and */ @@ -793,6 +798,7 @@ ftype_register_bytes(void) NULL, /* cmp_matches */ bytes_is_zero, /* is_zero */ + NULL, /* is_negative */ len, slice, bytes_bitwise_and, /* bitwise_and */ @@ -825,6 +831,7 @@ ftype_register_bytes(void) NULL, /* cmp_matches */ bytes_is_zero, /* is_zero */ + NULL, /* is_negative */ len, slice, bytes_bitwise_and, /* bitwise_and */ @@ -857,6 +864,7 @@ ftype_register_bytes(void) NULL, /* cmp_matches */ bytes_is_zero, /* is_zero */ + NULL, /* is_negative */ len, slice, bytes_bitwise_and, /* bitwise_and */ @@ -889,6 +897,7 @@ ftype_register_bytes(void) cmp_matches, bytes_is_zero, /* is_zero */ + NULL, /* is_negative */ len, slice, bytes_bitwise_and, /* bitwise_and */ diff --git a/epan/ftypes/ftype-double.c b/epan/ftypes/ftype-double.c index 511dcdc707..70d1723741 100644 --- a/epan/ftypes/ftype-double.c +++ b/epan/ftypes/ftype-double.c @@ -116,6 +116,18 @@ cmp_order(const fvalue_t *a, const fvalue_t *b) return 0; } +static gboolean +val_is_zero(const fvalue_t *fv_a) +{ + return fv_a->value.floating == 0; +} + +static gboolean +val_is_negative(const fvalue_t *fv_a) +{ + return fv_a->value.floating < 0; +} + void ftype_register_double(void) { @@ -140,7 +152,8 @@ ftype_register_double(void) NULL, /* cmp_contains */ NULL, /* cmp_matches */ - NULL, /* is_zero */ + val_is_zero, /* is_zero */ + val_is_negative, /* is_negative */ NULL, NULL, NULL, /* bitwise_and */ @@ -172,7 +185,8 @@ ftype_register_double(void) NULL, /* cmp_contains */ NULL, /* cmp_matches */ - NULL, /* is_zero */ + val_is_zero, /* is_zero */ + val_is_negative, /* is_negative */ NULL, NULL, NULL, /* bitwise_and */ diff --git a/epan/ftypes/ftype-guid.c b/epan/ftypes/ftype-guid.c index afd96537a0..9fed8e6680 100644 --- a/epan/ftypes/ftype-guid.c +++ b/epan/ftypes/ftype-guid.c @@ -121,6 +121,7 @@ ftype_register_guid(void) NULL, NULL, NULL, + NULL, NULL, /* unary_minus */ NULL, /* add */ NULL, /* subtract */ diff --git a/epan/ftypes/ftype-ieee-11073-float.c b/epan/ftypes/ftype-ieee-11073-float.c index ed5237e91f..245fcf69ee 100644 --- a/epan/ftypes/ftype-ieee-11073-float.c +++ b/epan/ftypes/ftype-ieee-11073-float.c @@ -919,6 +919,7 @@ Example: 114 is 0x0072 NULL, /* cmp_matches */ sfloat_ieee_11073_is_zero, /* is_zero */ + NULL, /* is_negative */ NULL, /* len */ NULL, /* slice */ NULL, /* bitwise_and */ @@ -978,6 +979,7 @@ Example: 36.4 is 0xFF00016C NULL, /* cmp_matches */ float_ieee_11073_is_zero, /* is_zero */ + NULL, /* is_negative */ NULL, /* len */ NULL, /* slice */ NULL, /* bitwise_and */ diff --git a/epan/ftypes/ftype-integer.c b/epan/ftypes/ftype-integer.c index 58853b250b..f16bf79b55 100644 --- a/epan/ftypes/ftype-integer.c +++ b/epan/ftypes/ftype-integer.c @@ -679,6 +679,12 @@ uint_is_zero(const fvalue_t *fv) return fv->value.uinteger == 0; } +gboolean +uint_is_negative(const fvalue_t *fv _U_) +{ + return FALSE; +} + enum ft_result uint_unary_minus(fvalue_t *dst, const fvalue_t *src, char **err_ptr) { @@ -707,6 +713,12 @@ uint64_is_zero(const fvalue_t *fv) return fv->value.uinteger64 == 0; } +gboolean +uint64_is_negative(const fvalue_t *fv _U_) +{ + return FALSE; +} + enum ft_result uint64_unary_minus(fvalue_t *dst, const fvalue_t *src, char **err_ptr) { @@ -735,6 +747,12 @@ sint_is_zero(const fvalue_t *fv) return fv->value.sinteger == 0; } +gboolean +sint_is_negative(const fvalue_t *fv) +{ + return fv->value.sinteger < 0; +} + enum ft_result sint_unary_minus(fvalue_t * dst, const fvalue_t *src, char **err_ptr _U_) { @@ -755,6 +773,12 @@ sint64_is_zero(const fvalue_t *fv) return fv->value.sinteger64 == 0; } +gboolean +sint64_is_negative(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_) { @@ -1158,6 +1182,7 @@ ftype_register_integers(void) NULL, /* cmp_matches */ uint_is_zero, /* is_zero */ + uint_is_negative, /* is_negative */ NULL, /* len */ NULL, /* slice */ uint_bitwise_and, /* bitwise_and */ @@ -1189,6 +1214,7 @@ ftype_register_integers(void) NULL, /* cmp_matches */ uint_is_zero, /* is_zero */ + uint_is_negative, /* is_negative */ NULL, /* len */ NULL, /* slice */ uint_bitwise_and, /* bitwise_and */ @@ -1220,6 +1246,7 @@ ftype_register_integers(void) NULL, /* cmp_matches */ uint_is_zero, /* is_zero */ + uint_is_negative, /* is_negative */ NULL, /* len */ NULL, /* slice */ uint_bitwise_and, /* bitwise_and */ @@ -1251,6 +1278,7 @@ ftype_register_integers(void) NULL, /* cmp_matches */ uint_is_zero, /* is_zero */ + uint_is_negative, /* is_negative */ NULL, /* len */ NULL, /* slice */ uint_bitwise_and, /* bitwise_and */ @@ -1282,6 +1310,7 @@ ftype_register_integers(void) NULL, /* cmp_matches */ uint_is_zero, /* is_zero */ + uint_is_negative, /* is_negative */ NULL, /* len */ NULL, /* slice */ uint_bitwise_and, /* bitwise_and */ @@ -1313,6 +1342,7 @@ ftype_register_integers(void) NULL, /* cmp_matches */ uint64_is_zero, /* is_zero */ + uint64_is_negative, /* is_negative */ NULL, /* len */ NULL, /* slice */ uint64_bitwise_and, /* bitwise_and */ @@ -1344,6 +1374,7 @@ ftype_register_integers(void) NULL, /* cmp_matches */ uint64_is_zero, /* is_zero */ + uint64_is_negative, /* is_negative */ NULL, /* len */ NULL, /* slice */ uint64_bitwise_and, /* bitwise_and */ @@ -1375,6 +1406,7 @@ ftype_register_integers(void) NULL, /* cmp_matches */ uint64_is_zero, /* is_zero */ + uint64_is_negative, /* is_negative */ NULL, /* len */ NULL, /* slice */ uint64_bitwise_and, /* bitwise_and */ @@ -1406,6 +1438,7 @@ ftype_register_integers(void) NULL, /* cmp_matches */ uint64_is_zero, /* is_zero */ + uint64_is_negative, /* is_negative */ NULL, /* len */ NULL, /* slice */ uint64_bitwise_and, /* bitwise_and */ @@ -1437,6 +1470,7 @@ ftype_register_integers(void) NULL, /* cmp_matches */ sint_is_zero, /* is_zero */ + sint_is_negative, /* is_negative */ NULL, /* len */ NULL, /* slice */ sint_bitwise_and, /* bitwise_and */ @@ -1468,6 +1502,7 @@ ftype_register_integers(void) NULL, /* cmp_matches */ sint_is_zero, /* is_zero */ + sint_is_negative, /* is_negative */ NULL, /* len */ NULL, /* slice */ sint_bitwise_and, /* bitwise_and */ @@ -1499,6 +1534,7 @@ ftype_register_integers(void) NULL, /* cmp_matches */ sint_is_zero, /* is_zero */ + sint_is_negative, /* is_negative */ NULL, /* len */ NULL, /* slice */ sint_bitwise_and, /* bitwise_and */ @@ -1530,6 +1566,7 @@ ftype_register_integers(void) NULL, /* cmp_matches */ sint_is_zero, /* is_zero */ + sint_is_negative, /* is_negative */ NULL, /* len */ NULL, /* slice */ sint_bitwise_and, /* bitwise_and */ @@ -1561,6 +1598,7 @@ ftype_register_integers(void) NULL, /* cmp_matches */ sint64_is_zero, /* is_zero */ + sint64_is_negative, /* is_negative */ NULL, /* len */ NULL, /* slice */ sint64_bitwise_and, /* bitwise_and */ @@ -1592,6 +1630,7 @@ ftype_register_integers(void) NULL, /* cmp_matches */ sint64_is_zero, /* is_zero */ + sint64_is_negative, /* is_negative */ NULL, /* len */ NULL, /* slice */ sint64_bitwise_and, /* bitwise_and */ @@ -1623,6 +1662,7 @@ ftype_register_integers(void) NULL, /* cmp_matches */ sint64_is_zero, /* is_zero */ + sint64_is_negative, /* is_negative */ NULL, /* len */ NULL, /* slice */ sint64_bitwise_and, /* bitwise_and */ @@ -1654,6 +1694,7 @@ ftype_register_integers(void) NULL, /* cmp_matches */ sint64_is_zero, /* is_zero */ + sint64_is_negative, /* is_negative */ NULL, /* len */ NULL, /* slice */ sint64_bitwise_and, /* bitwise_and */ @@ -1685,6 +1726,7 @@ ftype_register_integers(void) NULL, /* cmp_matches */ uint64_is_zero, /* is_zero */ + uint64_is_negative, /* is_negative */ NULL, /* len */ NULL, /* slice */ NULL, /* bitwise_and */ @@ -1717,6 +1759,7 @@ ftype_register_integers(void) NULL, /* cmp_matches */ uint_is_zero, /* is_zero */ + uint_is_negative, /* is_negative */ NULL, /* len */ NULL, /* slice */ uint_bitwise_and, /* bitwise_and */ @@ -1749,6 +1792,7 @@ ftype_register_integers(void) NULL, /* cmp_matches */ uint_is_zero, /* is_zero */ + uint_is_negative, /* is_negative */ NULL, /* len */ NULL, /* slice */ uint_bitwise_and, /* bitwise_and */ @@ -1781,6 +1825,7 @@ ftype_register_integers(void) NULL, /* cmp_matches */ uint64_is_zero, /* is_zero */ + uint64_is_negative, /* is_negative */ NULL, /* len */ NULL, /* slice */ uint64_bitwise_and, /* bitwise_and */ diff --git a/epan/ftypes/ftype-ipv4.c b/epan/ftypes/ftype-ipv4.c index 8fd79b819c..eff2c6f154 100644 --- a/epan/ftypes/ftype-ipv4.c +++ b/epan/ftypes/ftype-ipv4.c @@ -171,6 +171,7 @@ ftype_register_ipv4(void) is_zero, NULL, + NULL, slice, bitwise_and, NULL, /* unary_minus */ diff --git a/epan/ftypes/ftype-ipv6.c b/epan/ftypes/ftype-ipv6.c index 8ae6b9c172..42a36689fe 100644 --- a/epan/ftypes/ftype-ipv6.c +++ b/epan/ftypes/ftype-ipv6.c @@ -194,6 +194,7 @@ ftype_register_ipv6(void) is_zero, NULL, + NULL, slice, bitwise_and, NULL, /* unary_minus */ diff --git a/epan/ftypes/ftype-none.c b/epan/ftypes/ftype-none.c index 3d0694c16f..4e02b9b54c 100644 --- a/epan/ftypes/ftype-none.c +++ b/epan/ftypes/ftype-none.c @@ -36,6 +36,7 @@ ftype_register_none(void) NULL, /* cmp_matches */ NULL, /* is_zero */ + NULL, /* is_negative */ NULL, /* len */ NULL, /* slice */ NULL, /* biwise_and */ diff --git a/epan/ftypes/ftype-protocol.c b/epan/ftypes/ftype-protocol.c index c9b7996cea..0171234905 100644 --- a/epan/ftypes/ftype-protocol.c +++ b/epan/ftypes/ftype-protocol.c @@ -339,6 +339,7 @@ ftype_register_tvbuff(void) cmp_matches, is_zero, + NULL, len, slice, NULL, diff --git a/epan/ftypes/ftype-string.c b/epan/ftypes/ftype-string.c index 776e980c22..4b1e58f6dd 100644 --- a/epan/ftypes/ftype-string.c +++ b/epan/ftypes/ftype-string.c @@ -190,6 +190,7 @@ ftype_register_string(void) cmp_matches, string_is_zero, /* is_zero */ + NULL, /* is_negative */ len, slice, NULL, /* bitwise_and */ @@ -221,6 +222,7 @@ ftype_register_string(void) cmp_matches, string_is_zero, /* is_zero */ + NULL, /* is_negative */ len, slice, NULL, /* bitwise_and */ @@ -252,6 +254,7 @@ ftype_register_string(void) cmp_matches, string_is_zero, /* is_zero */ + NULL, /* is_negative */ len, slice, NULL, /* bitwise_and */ @@ -283,6 +286,7 @@ ftype_register_string(void) cmp_matches, string_is_zero, /* is_zero */ + NULL, /* is_negative */ len, slice, NULL, /* bitwise_and */ @@ -314,6 +318,7 @@ ftype_register_string(void) cmp_matches, string_is_zero, /* is_zero */ + NULL, /* is_negative */ len, slice, NULL, /* bitwise_and */ diff --git a/epan/ftypes/ftype-time.c b/epan/ftypes/ftype-time.c index dbddb0ca66..80ff769908 100644 --- a/epan/ftypes/ftype-time.c +++ b/epan/ftypes/ftype-time.c @@ -417,6 +417,12 @@ time_is_zero(const fvalue_t *fv) return nstime_is_zero(&fv->value.time); } +static gboolean +time_is_negative(const fvalue_t *fv) +{ + return fv->value.time.secs < 0; +} + static enum ft_result time_unary_minus(fvalue_t * dst, const fvalue_t *src, char **err_ptr _U_) { @@ -464,6 +470,7 @@ ftype_register_time(void) NULL, /* cmp_matches */ time_is_zero, /* is_zero */ + NULL, /* is_negative */ NULL, NULL, NULL, /* bitwise_and */ @@ -495,6 +502,7 @@ ftype_register_time(void) NULL, /* cmp_matches */ time_is_zero, /* is_zero */ + time_is_negative, /* is_negative */ NULL, NULL, NULL, /* bitwise_and */ diff --git a/epan/ftypes/ftypes-int.h b/epan/ftypes/ftypes-int.h index 8d9e872834..47654c8127 100644 --- a/epan/ftypes/ftypes-int.h +++ b/epan/ftypes/ftypes-int.h @@ -59,7 +59,7 @@ typedef int (*FvalueCmp)(const fvalue_t*, const fvalue_t*); typedef gboolean (*FvalueContains)(const fvalue_t*, const fvalue_t*); typedef gboolean (*FvalueMatches)(const fvalue_t*, const ws_regex_t*); -typedef gboolean (*FvalueIsZero)(const fvalue_t*); +typedef gboolean (*FvalueIs)(const fvalue_t*); typedef guint (*FvalueLen)(fvalue_t*); typedef void (*FvalueSlice)(fvalue_t*, GByteArray *, guint offset, guint length); typedef enum ft_result (*FvalueUnaryOp)(fvalue_t *, const fvalue_t*, gchar **); @@ -105,7 +105,8 @@ struct _ftype_t { FvalueContains cmp_contains; FvalueMatches cmp_matches; - FvalueIsZero is_zero; + FvalueIs is_zero; + FvalueIs is_negative; FvalueLen len; FvalueSlice slice; FvalueBinaryOp bitwise_and; diff --git a/epan/ftypes/ftypes.c b/epan/ftypes/ftypes.c index 305a84b43c..b651f15dd1 100644 --- a/epan/ftypes/ftypes.c +++ b/epan/ftypes/ftypes.c @@ -290,6 +290,15 @@ ftype_can_is_zero(enum ftenum ftype) return ft->is_zero ? TRUE : FALSE; } +gboolean +ftype_can_is_negative(enum ftenum ftype) +{ + ftype_t *ft; + + FTYPE_LOOKUP(ftype, ft); + return ft->is_negative ? TRUE : FALSE; +} + /* ---------------------------------------------------------- */ /* Allocate and initialize an fvalue_t, given an ftype */ @@ -844,6 +853,12 @@ fvalue_is_zero(const fvalue_t *a) return a->ftype->is_zero(a); } +gboolean +fvalue_is_negative(const fvalue_t *a) +{ + return a->ftype->is_negative(a); +} + static fvalue_t * _fvalue_binop(FvalueBinaryOp op, const fvalue_t *a, const fvalue_t *b, char **err_msg) { diff --git a/epan/ftypes/ftypes.h b/epan/ftypes/ftypes.h index d39c144692..c1c1356d7e 100644 --- a/epan/ftypes/ftypes.h +++ b/epan/ftypes/ftypes.h @@ -215,6 +215,10 @@ WS_DLL_PUBLIC gboolean ftype_can_is_zero(enum ftenum ftype); +WS_DLL_PUBLIC +gboolean +ftype_can_is_negative(enum ftenum ftype); + /* ---------------- FVALUE ----------------- */ #include @@ -380,6 +384,9 @@ fvalue_matches(const fvalue_t *a, const ws_regex_t *re); gboolean fvalue_is_zero(const fvalue_t *a); +gboolean +fvalue_is_negative(const fvalue_t *a); + guint fvalue_length(fvalue_t *fv); diff --git a/packaging/debian/libwireshark0.symbols b/packaging/debian/libwireshark0.symbols index a13e1a89fd..ba44007c20 100644 --- a/packaging/debian/libwireshark0.symbols +++ b/packaging/debian/libwireshark0.symbols @@ -730,6 +730,7 @@ libwireshark.so.0 libwireshark0 #MINVER# ftype_can_cmp@Base 3.7.0 ftype_can_contains@Base 1.9.1 ftype_can_eq@Base 1.9.1 + ftype_can_is_negative@Base 3.7.0 ftype_can_is_zero@Base 3.7.0 ftype_can_matches@Base 1.9.1 ftype_can_slice@Base 1.9.1 diff --git a/test/suite_dfilter/group_function.py b/test/suite_dfilter/group_function.py index 4ae1d4cddb..460599a6c9 100644 --- a/test/suite_dfilter/group_function.py +++ b/test/suite_dfilter/group_function.py @@ -65,3 +65,11 @@ class case_dfunction_maxmin(unittest.TestCase): def test_max_3(self, checkDFilterCount): dfilter = 'max(udp.srcport, udp.dstport) < 5060' checkDFilterCount(dfilter, 1) + +@fixtures.uses_fixtures +class case_dfunction_abs(unittest.TestCase): + trace_file = "dhcp.pcapng" + + def test_function_abs_1(self, checkDFilterCount): + dfilter = 'udp.dstport == abs(-67)' + checkDFilterCount(dfilter, 2)