Add a "contains" operator for byte-strings, strings, and tvbuffs (protocols).
The search uses a naive approach; more work is required to add a Boyer-Moore Search algorithm. svn path=/trunk/; revision=8280
This commit is contained in:
parent
d3562c0480
commit
52338a3baf
|
@ -1384,6 +1384,11 @@ abbreviations:
|
|||
ge, >= Greater than or Equal to
|
||||
le, <= Less than or Equal to
|
||||
|
||||
An additional operater exists that is expressed only in English, not
|
||||
punctuation:
|
||||
|
||||
contains Does the protocol, byte-string, or string contain a value
|
||||
|
||||
Furthermore, each protocol field is typed. The types are:
|
||||
|
||||
Unsigned integer (either 8-bit, 16-bit, 24-bit, or 32-bit)
|
||||
|
@ -1480,7 +1485,7 @@ Use of octal to look for "HEAD":
|
|||
This means that you must escape backslashes with backslashes inside
|
||||
double quotes:
|
||||
|
||||
smb.path == "\\\\SERVER\\SHARE"
|
||||
smb.path contains "\\\\SERVER\\SHARE"
|
||||
|
||||
to look for \\SERVER\SHARE in "smb.path".
|
||||
|
||||
|
|
|
@ -599,6 +599,11 @@ abbreviations:
|
|||
ge, >= Greater than or Equal to
|
||||
le, <= Less than or Equal to
|
||||
|
||||
An additional operater exists that is expressed only in English, not
|
||||
punctuation:
|
||||
|
||||
contains Does the protocol, byte-string, or string contain a value
|
||||
|
||||
Furthermore, each protocol field is typed. The types are:
|
||||
|
||||
Unsigned integer (either 8-bit, 16-bit, 24-bit, or 32-bit)
|
||||
|
@ -695,7 +700,7 @@ Use of octal to look for "HEAD":
|
|||
This means that you must escape backslashes with backslashes inside
|
||||
double quotes:
|
||||
|
||||
smb.path == "\\\\SERVER\\SHARE"
|
||||
smb.path contains "\\\\SERVER\\SHARE"
|
||||
|
||||
to look for \\SERVER\SHARE in "smb.path".
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* $Id: dfvm.c,v 1.9 2002/10/16 16:32:59 gram Exp $
|
||||
* $Id: dfvm.c,v 1.10 2003/08/27 15:23:03 gram Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@zing.org>
|
||||
|
@ -403,6 +403,11 @@ dfvm_apply(dfilter_t *df, proto_tree *tree)
|
|||
arg1->value.numeric, arg2->value.numeric);
|
||||
break;
|
||||
|
||||
case ANY_CONTAINS:
|
||||
accum = any_test(df, fvalue_contains,
|
||||
arg1->value.numeric, arg2->value.numeric);
|
||||
break;
|
||||
|
||||
case NOT:
|
||||
accum = !accum;
|
||||
break;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* $Id: dfvm.h,v 1.8 2002/10/16 16:32:59 gram Exp $
|
||||
* $Id: dfvm.h,v 1.9 2003/08/27 15:23:04 gram Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@ethereal.com>
|
||||
|
@ -67,6 +67,7 @@ typedef enum {
|
|||
ANY_GE,
|
||||
ANY_LT,
|
||||
ANY_LE,
|
||||
ANY_CONTAINS,
|
||||
MK_RANGE
|
||||
|
||||
} dfvm_opcode_t;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* $Id: gencode.c,v 1.10 2003/06/13 10:03:25 guy Exp $
|
||||
* $Id: gencode.c,v 1.11 2003/08/27 15:23:04 gram Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@ethereal.com>
|
||||
|
@ -319,6 +319,10 @@ gen_test(dfwork_t *dfw, stnode_t *st_node)
|
|||
case TEST_OP_LE:
|
||||
gen_relation(dfw, ANY_LE, st_arg1, st_arg2);
|
||||
break;
|
||||
|
||||
case TEST_OP_CONTAINS:
|
||||
gen_relation(dfw, ANY_CONTAINS, st_arg1, st_arg2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: grammar.lemon,v 1.5 2003/07/25 03:44:01 gram Exp $ */
|
||||
/* $Id: grammar.lemon,v 1.6 2003/08/27 15:23:04 gram Exp $ */
|
||||
|
||||
%include {
|
||||
#ifdef HAVE_CONFIG_H
|
||||
|
@ -108,7 +108,7 @@ shifting 3 more symbols. */
|
|||
/* Associativity */
|
||||
%left TEST_AND.
|
||||
%left TEST_OR.
|
||||
%nonassoc TEST_EQ TEST_NE TEST_LT TEST_LE TEST_GT TEST_GE.
|
||||
%nonassoc TEST_EQ TEST_NE TEST_LT TEST_LE TEST_GT TEST_GE TEST_CONTAINS.
|
||||
%right TEST_NOT.
|
||||
|
||||
/* Top-level targets */
|
||||
|
@ -247,6 +247,7 @@ rel_op2(O) ::= TEST_GT. { O = TEST_OP_GT; }
|
|||
rel_op2(O) ::= TEST_GE. { O = TEST_OP_GE; }
|
||||
rel_op2(O) ::= TEST_LT. { O = TEST_OP_LT; }
|
||||
rel_op2(O) ::= TEST_LE. { O = TEST_OP_LE; }
|
||||
rel_op2(O) ::= TEST_CONTAINS. { O = TEST_OP_CONTAINS; }
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
%{
|
||||
/*
|
||||
* $Id: scanner.l,v 1.8 2003/07/25 03:44:01 gram Exp $
|
||||
* $Id: scanner.l,v 1.9 2003/08/27 15:23:04 gram Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@ethereal.com>
|
||||
|
@ -77,6 +77,7 @@ GString* quoted_string = NULL;
|
|||
"lt" return simple(TOKEN_TEST_LT);
|
||||
"<=" return simple(TOKEN_TEST_LE);
|
||||
"le" return simple(TOKEN_TEST_LE);
|
||||
"contains" return simple(TOKEN_TEST_CONTAINS);
|
||||
|
||||
"!" return simple(TOKEN_TEST_NOT);
|
||||
"not" return simple(TOKEN_TEST_NOT);
|
||||
|
@ -221,6 +222,7 @@ simple(int token)
|
|||
case TOKEN_TEST_GE:
|
||||
case TOKEN_TEST_LT:
|
||||
case TOKEN_TEST_LE:
|
||||
case TOKEN_TEST_CONTAINS:
|
||||
case TOKEN_TEST_NOT:
|
||||
case TOKEN_TEST_AND:
|
||||
case TOKEN_TEST_OR:
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* $Id: semcheck.c,v 1.18 2003/07/25 03:44:01 gram Exp $
|
||||
* $Id: semcheck.c,v 1.19 2003/08/27 15:23:04 gram Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@ethereal.com>
|
||||
|
@ -260,6 +260,7 @@ is_bytes_type(enum ftenum type)
|
|||
* and possibly some modifications of syntax tree nodes. */
|
||||
static void
|
||||
check_relation_LHS_FIELD(const char *relation_string, FtypeCanFunc can_func,
|
||||
gboolean allow_partial_value,
|
||||
stnode_t *st_node, stnode_t *st_arg1, stnode_t *st_arg2)
|
||||
{
|
||||
stnode_t *new_st;
|
||||
|
@ -318,7 +319,7 @@ check_relation_LHS_FIELD(const char *relation_string, FtypeCanFunc can_func,
|
|||
}
|
||||
else if (type2 == STTYPE_UNPARSED) {
|
||||
s = stnode_data(st_arg2);
|
||||
fvalue = fvalue_from_unparsed(ftype1, s, dfilter_fail);
|
||||
fvalue = fvalue_from_unparsed(ftype1, s, allow_partial_value, dfilter_fail);
|
||||
if (!fvalue) {
|
||||
/* check value_string */
|
||||
fvalue = mk_fvalue_from_val_string(hfinfo1, s);
|
||||
|
@ -358,7 +359,8 @@ check_relation_LHS_FIELD(const char *relation_string, FtypeCanFunc can_func,
|
|||
}
|
||||
|
||||
static void
|
||||
check_relation_LHS_STRING(FtypeCanFunc can_func _U_, stnode_t *st_node,
|
||||
check_relation_LHS_STRING(FtypeCanFunc can_func _U_, gboolean allow_partial_value _U_,
|
||||
stnode_t *st_node,
|
||||
stnode_t *st_arg1, stnode_t *st_arg2)
|
||||
{
|
||||
stnode_t *new_st;
|
||||
|
@ -389,7 +391,7 @@ check_relation_LHS_STRING(FtypeCanFunc can_func _U_, stnode_t *st_node,
|
|||
sttype_test_set2_args(st_node, new_st, st_arg2);
|
||||
stnode_free(st_arg1);
|
||||
}
|
||||
else if (type2 == STTYPE_STRING) {
|
||||
else if (type2 == STTYPE_STRING || type2 == STTYPE_UNPARSED) {
|
||||
/* Well now that's silly... */
|
||||
dfilter_fail("Neither \"%s\" nor \"%s\" are field or protocol names.",
|
||||
stnode_data(st_arg1),
|
||||
|
@ -412,7 +414,8 @@ check_relation_LHS_STRING(FtypeCanFunc can_func _U_, stnode_t *st_node,
|
|||
}
|
||||
|
||||
static void
|
||||
check_relation_LHS_UNPARSED(FtypeCanFunc can_func _U_, stnode_t *st_node,
|
||||
check_relation_LHS_UNPARSED(FtypeCanFunc can_func _U_, gboolean allow_partial_value,
|
||||
stnode_t *st_node,
|
||||
stnode_t *st_arg1, stnode_t *st_arg2)
|
||||
{
|
||||
stnode_t *new_st;
|
||||
|
@ -430,7 +433,7 @@ check_relation_LHS_UNPARSED(FtypeCanFunc can_func _U_, stnode_t *st_node,
|
|||
ftype2 = hfinfo2->type;
|
||||
|
||||
s = stnode_data(st_arg1);
|
||||
fvalue = fvalue_from_unparsed(ftype2, s, dfilter_fail);
|
||||
fvalue = fvalue_from_unparsed(ftype2, s, allow_partial_value, dfilter_fail);
|
||||
if (!fvalue) {
|
||||
/* check value_string */
|
||||
fvalue = mk_fvalue_from_val_string(hfinfo2, s);
|
||||
|
@ -443,7 +446,7 @@ check_relation_LHS_UNPARSED(FtypeCanFunc can_func _U_, stnode_t *st_node,
|
|||
sttype_test_set2_args(st_node, new_st, st_arg2);
|
||||
stnode_free(st_arg1);
|
||||
}
|
||||
else if (type2 == STTYPE_STRING) {
|
||||
else if (type2 == STTYPE_STRING || type2 == STTYPE_UNPARSED) {
|
||||
/* Well now that's silly... */
|
||||
dfilter_fail("Neither \"%s\" nor \"%s\" are field or protocol names.",
|
||||
stnode_data(st_arg1),
|
||||
|
@ -451,8 +454,9 @@ check_relation_LHS_UNPARSED(FtypeCanFunc can_func _U_, stnode_t *st_node,
|
|||
THROW(TypeError);
|
||||
}
|
||||
else if (type2 == STTYPE_RANGE) {
|
||||
/* XXX - is this right? */
|
||||
s = stnode_data(st_arg1);
|
||||
fvalue = fvalue_from_unparsed(FT_BYTES, s, dfilter_fail);
|
||||
fvalue = fvalue_from_unparsed(FT_BYTES, s, allow_partial_value, dfilter_fail);
|
||||
if (!fvalue) {
|
||||
THROW(TypeError);
|
||||
}
|
||||
|
@ -529,7 +533,8 @@ check_drange_sanity(stnode_t *st)
|
|||
}
|
||||
|
||||
static void
|
||||
check_relation_LHS_RANGE(FtypeCanFunc can_func _U_, stnode_t *st_node,
|
||||
check_relation_LHS_RANGE(FtypeCanFunc can_func _U_, gboolean allow_partial_value,
|
||||
stnode_t *st_node,
|
||||
stnode_t *st_arg1, stnode_t *st_arg2)
|
||||
{
|
||||
stnode_t *new_st;
|
||||
|
@ -589,7 +594,7 @@ check_relation_LHS_RANGE(FtypeCanFunc can_func _U_, stnode_t *st_node,
|
|||
}
|
||||
else if (type2 == STTYPE_UNPARSED) {
|
||||
s = stnode_data(st_arg2);
|
||||
fvalue = fvalue_from_unparsed(FT_BYTES, s, dfilter_fail);
|
||||
fvalue = fvalue_from_unparsed(FT_BYTES, s, allow_partial_value, dfilter_fail);
|
||||
if (!fvalue) {
|
||||
THROW(TypeError);
|
||||
}
|
||||
|
@ -609,21 +614,26 @@ check_relation_LHS_RANGE(FtypeCanFunc can_func _U_, stnode_t *st_node,
|
|||
|
||||
/* Check the semantics of any relational test. */
|
||||
static void
|
||||
check_relation(const char *relation_string, FtypeCanFunc can_func, stnode_t *st_node,
|
||||
check_relation(const char *relation_string, gboolean allow_partial_value,
|
||||
FtypeCanFunc can_func, stnode_t *st_node,
|
||||
stnode_t *st_arg1, stnode_t *st_arg2)
|
||||
{
|
||||
switch (stnode_type_id(st_arg1)) {
|
||||
case STTYPE_FIELD:
|
||||
check_relation_LHS_FIELD(relation_string, can_func, st_node, st_arg1, st_arg2);
|
||||
check_relation_LHS_FIELD(relation_string, can_func,
|
||||
allow_partial_value, st_node, st_arg1, st_arg2);
|
||||
break;
|
||||
case STTYPE_STRING:
|
||||
check_relation_LHS_STRING(can_func, st_node, st_arg1, st_arg2);
|
||||
check_relation_LHS_STRING(can_func,
|
||||
allow_partial_value, st_node, st_arg1, st_arg2);
|
||||
break;
|
||||
case STTYPE_RANGE:
|
||||
check_relation_LHS_RANGE(can_func, st_node, st_arg1, st_arg2);
|
||||
check_relation_LHS_RANGE(can_func,
|
||||
allow_partial_value, st_node, st_arg1, st_arg2);
|
||||
break;
|
||||
case STTYPE_UNPARSED:
|
||||
check_relation_LHS_UNPARSED(can_func, st_node, st_arg1, st_arg2);
|
||||
check_relation_LHS_UNPARSED(can_func,
|
||||
allow_partial_value, st_node, st_arg1, st_arg2);
|
||||
break;
|
||||
|
||||
case STTYPE_UNINITIALIZED:
|
||||
|
@ -664,23 +674,29 @@ check_test(stnode_t *st_node)
|
|||
break;
|
||||
|
||||
case TEST_OP_EQ:
|
||||
check_relation("==", ftype_can_eq, st_node, st_arg1, st_arg2);
|
||||
check_relation("==", FALSE, ftype_can_eq, st_node, st_arg1, st_arg2);
|
||||
break;
|
||||
case TEST_OP_NE:
|
||||
check_relation("!=", ftype_can_ne, st_node, st_arg1, st_arg2);
|
||||
check_relation("!=", FALSE, ftype_can_ne, st_node, st_arg1, st_arg2);
|
||||
break;
|
||||
case TEST_OP_GT:
|
||||
check_relation(">", ftype_can_gt, st_node, st_arg1, st_arg2);
|
||||
check_relation(">", FALSE, ftype_can_gt, st_node, st_arg1, st_arg2);
|
||||
break;
|
||||
case TEST_OP_GE:
|
||||
check_relation(">=", ftype_can_ge, st_node, st_arg1, st_arg2);
|
||||
check_relation(">=", FALSE, ftype_can_ge, st_node, st_arg1, st_arg2);
|
||||
break;
|
||||
case TEST_OP_LT:
|
||||
check_relation("<", ftype_can_lt, st_node, st_arg1, st_arg2);
|
||||
check_relation("<", FALSE, ftype_can_lt, st_node, st_arg1, st_arg2);
|
||||
break;
|
||||
case TEST_OP_LE:
|
||||
check_relation("<=", ftype_can_le, st_node, st_arg1, st_arg2);
|
||||
check_relation("<=", FALSE, ftype_can_le, st_node, st_arg1, st_arg2);
|
||||
break;
|
||||
case TEST_OP_CONTAINS:
|
||||
check_relation("contains", TRUE, ftype_can_contains, st_node, st_arg1, st_arg2);
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* $Id: sttype-test.c,v 1.3 2002/08/28 20:40:56 jmayer Exp $
|
||||
* $Id: sttype-test.c,v 1.4 2003/08/27 15:23:05 gram Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@zing.org>
|
||||
|
@ -90,6 +90,8 @@ num_operands(test_op_t op)
|
|||
return 2;
|
||||
case TEST_OP_LE:
|
||||
return 2;
|
||||
case TEST_OP_CONTAINS:
|
||||
return 2;
|
||||
}
|
||||
g_assert_not_reached();
|
||||
return -1;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* $Id: sttype-test.h,v 1.3 2002/08/28 20:40:56 jmayer Exp $
|
||||
* $Id: sttype-test.h,v 1.4 2003/08/27 15:23:05 gram Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@zing.org>
|
||||
|
@ -35,7 +35,8 @@ typedef enum {
|
|||
TEST_OP_GT,
|
||||
TEST_OP_GE,
|
||||
TEST_OP_LT,
|
||||
TEST_OP_LE
|
||||
TEST_OP_LE,
|
||||
TEST_OP_CONTAINS
|
||||
} test_op_t;
|
||||
|
||||
void
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* $Id: ftype-bytes.c,v 1.16 2003/07/25 03:44:02 gram Exp $
|
||||
* $Id: ftype-bytes.c,v 1.17 2003/08/27 15:23:05 gram Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@ethereal.com>
|
||||
|
@ -28,6 +28,7 @@
|
|||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <epan/resolv.h>
|
||||
#include <epan/strutil.h>
|
||||
#include <epan/int-64bit.h>
|
||||
|
||||
#define ETHER_LEN 6
|
||||
|
@ -129,7 +130,7 @@ is_byte_sep(guint8 c)
|
|||
}
|
||||
|
||||
static gboolean
|
||||
val_from_unparsed(fvalue_t *fv, char *s, LogFunc logfunc)
|
||||
bytes_from_unparsed(fvalue_t *fv, char *s, gboolean allow_partial_value _U_, LogFunc logfunc)
|
||||
{
|
||||
GByteArray *bytes;
|
||||
guint8 val;
|
||||
|
@ -226,7 +227,7 @@ val_from_unparsed(fvalue_t *fv, char *s, LogFunc logfunc)
|
|||
}
|
||||
|
||||
static gboolean
|
||||
ether_from_unparsed(fvalue_t *fv, char *s, LogFunc logfunc)
|
||||
ether_from_unparsed(fvalue_t *fv, char *s, gboolean allow_partial_value, LogFunc logfunc)
|
||||
{
|
||||
guint8 *mac;
|
||||
|
||||
|
@ -235,7 +236,18 @@ ether_from_unparsed(fvalue_t *fv, char *s, LogFunc logfunc)
|
|||
* up as an Ethernet host name if it does, and if that fails,
|
||||
* we'll log a message.
|
||||
*/
|
||||
if (val_from_unparsed(fv, s, NULL)) {
|
||||
if (bytes_from_unparsed(fv, s, TRUE, NULL)) {
|
||||
if (fv->value.bytes->len > ETHER_LEN) {
|
||||
logfunc("\"%s\" contains too many bytes to be a valid Ethernet address.",
|
||||
s);
|
||||
return FALSE;
|
||||
}
|
||||
else if (fv->value.bytes->len < ETHER_LEN && !allow_partial_value) {
|
||||
logfunc("\"%s\" contains too few bytes to be a valid Ethernet address.",
|
||||
s);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -251,7 +263,7 @@ ether_from_unparsed(fvalue_t *fv, char *s, LogFunc logfunc)
|
|||
}
|
||||
|
||||
static gboolean
|
||||
ipv6_from_unparsed(fvalue_t *fv, char *s, LogFunc logfunc)
|
||||
ipv6_from_unparsed(fvalue_t *fv, char *s, gboolean allow_partial_value _U_, LogFunc logfunc)
|
||||
{
|
||||
guint8 buffer[16];
|
||||
|
||||
|
@ -265,7 +277,7 @@ ipv6_from_unparsed(fvalue_t *fv, char *s, LogFunc logfunc)
|
|||
}
|
||||
|
||||
static gboolean
|
||||
u64_from_unparsed(fvalue_t *fv, char *s, LogFunc logfunc)
|
||||
u64_from_unparsed(fvalue_t *fv, char *s, gboolean allow_partial_value _U_, LogFunc logfunc)
|
||||
{
|
||||
guint8 buffer[8];
|
||||
|
||||
|
@ -279,7 +291,7 @@ u64_from_unparsed(fvalue_t *fv, char *s, LogFunc logfunc)
|
|||
}
|
||||
|
||||
static gboolean
|
||||
i64_from_unparsed(fvalue_t *fv, char *s, LogFunc logfunc)
|
||||
i64_from_unparsed(fvalue_t *fv, char *s, gboolean allow_partial_value _U_, LogFunc logfunc)
|
||||
{
|
||||
guint8 buffer[8];
|
||||
|
||||
|
@ -577,6 +589,20 @@ cmp_le_i64(fvalue_t *fv_a, fvalue_t *fv_b)
|
|||
return (memcmp(a->data, b->data, a->len) <= 0);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
cmp_contains(fvalue_t *fv_a, fvalue_t *fv_b)
|
||||
{
|
||||
GByteArray *a = fv_a->value.bytes;
|
||||
GByteArray *b = fv_b->value.bytes;
|
||||
|
||||
if (epan_memmem(a->data, a->len, b->data, b->len)) {
|
||||
return TRUE;
|
||||
}
|
||||
else {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ftype_register_bytes(void)
|
||||
{
|
||||
|
@ -587,7 +613,7 @@ ftype_register_bytes(void)
|
|||
0, /* wire_size */
|
||||
bytes_fvalue_new, /* new_value */
|
||||
bytes_fvalue_free, /* free_value */
|
||||
val_from_unparsed, /* val_from_unparsed */
|
||||
bytes_from_unparsed, /* val_from_unparsed */
|
||||
NULL, /* val_from_string */
|
||||
bytes_to_repr, /* val_to_string_repr */
|
||||
bytes_repr_len, /* len_string_repr */
|
||||
|
@ -606,6 +632,7 @@ ftype_register_bytes(void)
|
|||
cmp_ge,
|
||||
cmp_lt,
|
||||
cmp_le,
|
||||
cmp_contains,
|
||||
|
||||
len,
|
||||
slice,
|
||||
|
@ -617,7 +644,7 @@ ftype_register_bytes(void)
|
|||
0, /* wire_size */
|
||||
bytes_fvalue_new, /* new_value */
|
||||
bytes_fvalue_free, /* free_value */
|
||||
val_from_unparsed, /* val_from_unparsed */
|
||||
bytes_from_unparsed, /* val_from_unparsed */
|
||||
NULL, /* val_from_string */
|
||||
bytes_to_repr, /* val_to_string_repr */
|
||||
bytes_repr_len, /* len_string_repr */
|
||||
|
@ -636,6 +663,7 @@ ftype_register_bytes(void)
|
|||
cmp_ge,
|
||||
cmp_lt,
|
||||
cmp_le,
|
||||
cmp_contains,
|
||||
|
||||
len,
|
||||
slice,
|
||||
|
@ -666,6 +694,7 @@ ftype_register_bytes(void)
|
|||
cmp_ge,
|
||||
cmp_lt,
|
||||
cmp_le,
|
||||
cmp_contains,
|
||||
|
||||
len,
|
||||
slice,
|
||||
|
@ -696,6 +725,7 @@ ftype_register_bytes(void)
|
|||
cmp_ge,
|
||||
cmp_lt,
|
||||
cmp_le,
|
||||
cmp_contains,
|
||||
|
||||
len,
|
||||
slice,
|
||||
|
@ -726,6 +756,7 @@ ftype_register_bytes(void)
|
|||
cmp_ge,
|
||||
cmp_lt,
|
||||
cmp_le,
|
||||
NULL, /* cmp_contains */
|
||||
|
||||
len,
|
||||
slice,
|
||||
|
@ -756,6 +787,7 @@ ftype_register_bytes(void)
|
|||
cmp_ge_i64,
|
||||
cmp_lt_i64,
|
||||
cmp_le_i64,
|
||||
NULL, /* cmp_contains */
|
||||
|
||||
len,
|
||||
slice,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* $Id: ftype-double.c,v 1.10 2003/07/31 03:52:43 guy Exp $
|
||||
* $Id: ftype-double.c,v 1.11 2003/08/27 15:23:06 gram Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@ethereal.com>
|
||||
|
@ -51,7 +51,7 @@ value_get_floating(fvalue_t *fv)
|
|||
}
|
||||
|
||||
static gboolean
|
||||
val_from_unparsed(fvalue_t *fv, char *s, LogFunc logfunc)
|
||||
val_from_unparsed(fvalue_t *fv, char *s, gboolean allow_partial_value _U_, LogFunc logfunc)
|
||||
{
|
||||
char *endptr = NULL;
|
||||
|
||||
|
@ -181,6 +181,7 @@ ftype_register_double(void)
|
|||
cmp_ge,
|
||||
cmp_lt,
|
||||
cmp_le,
|
||||
NULL, /* cmp_contains */
|
||||
|
||||
NULL,
|
||||
NULL,
|
||||
|
@ -211,6 +212,7 @@ ftype_register_double(void)
|
|||
cmp_ge,
|
||||
cmp_lt,
|
||||
cmp_le,
|
||||
NULL, /* cmp_contains */
|
||||
|
||||
NULL,
|
||||
NULL,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* $Id: ftype-integer.c,v 1.14 2003/07/25 03:44:02 gram Exp $
|
||||
* $Id: ftype-integer.c,v 1.15 2003/08/27 15:23:06 gram Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@ethereal.com>
|
||||
|
@ -49,7 +49,7 @@ get_integer(fvalue_t *fv)
|
|||
}
|
||||
|
||||
static gboolean
|
||||
val_from_unparsed(fvalue_t *fv, char *s, LogFunc logfunc)
|
||||
val_from_unparsed(fvalue_t *fv, char *s, gboolean allow_partial_value _U_, LogFunc logfunc)
|
||||
{
|
||||
char *endptr;
|
||||
|
||||
|
@ -78,7 +78,7 @@ val_from_unparsed(fvalue_t *fv, char *s, LogFunc logfunc)
|
|||
}
|
||||
|
||||
static gboolean
|
||||
ipxnet_from_unparsed(fvalue_t *fv, char *s, LogFunc logfunc)
|
||||
ipxnet_from_unparsed(fvalue_t *fv, char *s, gboolean allow_partial_value _U_, LogFunc logfunc)
|
||||
{
|
||||
guint32 val;
|
||||
gboolean known;
|
||||
|
@ -88,7 +88,7 @@ ipxnet_from_unparsed(fvalue_t *fv, char *s, LogFunc logfunc)
|
|||
* up as an IPX network name if it does, and if that fails,
|
||||
* we'll log a message.
|
||||
*/
|
||||
if (val_from_unparsed(fv, s, NULL)) {
|
||||
if (val_from_unparsed(fv, s, TRUE, NULL)) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -242,6 +242,7 @@ ftype_register_integers(void)
|
|||
u_cmp_ge,
|
||||
u_cmp_lt,
|
||||
u_cmp_le,
|
||||
NULL, /* cmp_contains */
|
||||
|
||||
NULL, /* len */
|
||||
NULL, /* slice */
|
||||
|
@ -271,6 +272,7 @@ ftype_register_integers(void)
|
|||
u_cmp_ge,
|
||||
u_cmp_lt,
|
||||
u_cmp_le,
|
||||
NULL, /* cmp_contains */
|
||||
|
||||
NULL, /* len */
|
||||
NULL, /* slice */
|
||||
|
@ -300,6 +302,7 @@ ftype_register_integers(void)
|
|||
u_cmp_ge,
|
||||
u_cmp_lt,
|
||||
u_cmp_le,
|
||||
NULL, /* cmp_contains */
|
||||
|
||||
NULL, /* len */
|
||||
NULL, /* slice */
|
||||
|
@ -329,6 +332,7 @@ ftype_register_integers(void)
|
|||
u_cmp_ge,
|
||||
u_cmp_lt,
|
||||
u_cmp_le,
|
||||
NULL, /* cmp_contains */
|
||||
|
||||
NULL, /* len */
|
||||
NULL, /* slice */
|
||||
|
@ -358,6 +362,7 @@ ftype_register_integers(void)
|
|||
s_cmp_ge,
|
||||
s_cmp_lt,
|
||||
s_cmp_le,
|
||||
NULL, /* cmp_contains */
|
||||
|
||||
NULL, /* len */
|
||||
NULL, /* slice */
|
||||
|
@ -387,6 +392,7 @@ ftype_register_integers(void)
|
|||
s_cmp_ge,
|
||||
s_cmp_lt,
|
||||
s_cmp_le,
|
||||
NULL, /* cmp_contains */
|
||||
|
||||
NULL, /* len */
|
||||
NULL, /* slice */
|
||||
|
@ -416,6 +422,7 @@ ftype_register_integers(void)
|
|||
s_cmp_ge,
|
||||
s_cmp_lt,
|
||||
s_cmp_le,
|
||||
NULL, /* cmp_contains */
|
||||
|
||||
NULL, /* len */
|
||||
NULL, /* slice */
|
||||
|
@ -445,6 +452,7 @@ ftype_register_integers(void)
|
|||
s_cmp_ge,
|
||||
s_cmp_lt,
|
||||
s_cmp_le,
|
||||
NULL, /* cmp_contains */
|
||||
|
||||
NULL, /* len */
|
||||
NULL, /* slice */
|
||||
|
@ -474,6 +482,7 @@ ftype_register_integers(void)
|
|||
NULL, /* cmp_ge */
|
||||
NULL, /* cmp_lt */
|
||||
NULL, /* cmp_le */
|
||||
NULL, /* cmp_contains */
|
||||
|
||||
NULL, /* len */
|
||||
NULL, /* slice */
|
||||
|
@ -504,6 +513,7 @@ ftype_register_integers(void)
|
|||
u_cmp_ge,
|
||||
u_cmp_lt,
|
||||
u_cmp_le,
|
||||
NULL, /* cmp_contains */
|
||||
|
||||
NULL, /* len */
|
||||
NULL, /* slice */
|
||||
|
@ -534,6 +544,7 @@ ftype_register_integers(void)
|
|||
u_cmp_ge,
|
||||
u_cmp_lt,
|
||||
u_cmp_le,
|
||||
NULL, /* cmp_contains */
|
||||
|
||||
NULL, /* len */
|
||||
NULL, /* slice */
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* $Id: ftype-ipv4.c,v 1.12 2003/07/31 04:18:01 guy Exp $
|
||||
* $Id: ftype-ipv4.c,v 1.13 2003/08/27 15:23:07 gram Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@ethereal.com>
|
||||
|
@ -45,7 +45,7 @@ value_get(fvalue_t *fv)
|
|||
}
|
||||
|
||||
static gboolean
|
||||
val_from_unparsed(fvalue_t *fv, char *s, LogFunc logfunc)
|
||||
val_from_unparsed(fvalue_t *fv, char *s, gboolean allow_partial_value _U_, LogFunc logfunc)
|
||||
{
|
||||
guint32 addr;
|
||||
unsigned int nmask_bits;
|
||||
|
@ -99,7 +99,7 @@ val_from_unparsed(fvalue_t *fv, char *s, LogFunc logfunc)
|
|||
}
|
||||
|
||||
/* XXX - this is inefficient */
|
||||
nmask_fvalue = fvalue_from_unparsed(FT_UINT32, net_str, logfunc);
|
||||
nmask_fvalue = fvalue_from_unparsed(FT_UINT32, net_str, FALSE, logfunc);
|
||||
g_free(s_copy);
|
||||
if (!nmask_fvalue) {
|
||||
return FALSE;
|
||||
|
@ -202,6 +202,7 @@ ftype_register_ipv4(void)
|
|||
cmp_ge,
|
||||
cmp_lt,
|
||||
cmp_le,
|
||||
NULL, /* cmp_contains */
|
||||
|
||||
NULL,
|
||||
NULL,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* $Id: ftype-none.c,v 1.6 2003/07/25 03:44:03 gram Exp $
|
||||
* $Id: ftype-none.c,v 1.7 2003/08/27 15:23:07 gram Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@zing.org>
|
||||
|
@ -57,6 +57,7 @@ ftype_register_none(void)
|
|||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL, /* cmp_contains */
|
||||
|
||||
NULL,
|
||||
NULL,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* $Id: ftype-string.c,v 1.12 2003/07/30 22:25:35 guy Exp $
|
||||
* $Id: ftype-string.c,v 1.13 2003/08/27 15:23:07 gram Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@ethereal.com>
|
||||
|
@ -117,6 +117,32 @@ val_from_string(fvalue_t *fv, char *s, LogFunc logfunc _U_)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
val_from_unparsed(fvalue_t *fv, char *s, gboolean allow_partial_value _U_, LogFunc logfunc)
|
||||
{
|
||||
fvalue_t *fv_bytes;
|
||||
/* Does this look like a byte-string? */
|
||||
fv_bytes = fvalue_from_unparsed(FT_BYTES, s, TRUE, NULL);
|
||||
if (fv_bytes) {
|
||||
/* Copy the bytes over to a string and terminate it
|
||||
* with a NUL. XXX - what if the user embeds a NUL
|
||||
* in the middle of the byte string? */
|
||||
int num_bytes = fv_bytes->value.bytes->len;
|
||||
|
||||
fv->value.string = g_malloc(num_bytes + 1);
|
||||
memcpy(fv->value.string, fv->value.bytes->data, num_bytes);
|
||||
fv->value.string[num_bytes] = '\0';
|
||||
|
||||
fvalue_free(fv_bytes);
|
||||
return TRUE;
|
||||
}
|
||||
else {
|
||||
/* Just turn it into a string */
|
||||
return val_from_string(fv, s, logfunc);
|
||||
}
|
||||
g_assert_not_reached();
|
||||
}
|
||||
|
||||
static guint
|
||||
len(fvalue_t *fv)
|
||||
{
|
||||
|
@ -170,6 +196,25 @@ cmp_le(fvalue_t *a, fvalue_t *b)
|
|||
return (strcmp(a->value.string, b->value.string) <= 0);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
cmp_contains(fvalue_t *fv_a, fvalue_t *fv_b)
|
||||
{
|
||||
/* According to
|
||||
* http://www.introl.com/introl-demo/Libraries/C/ANSI_C/string/strstr.html
|
||||
* strstr() returns a non-NULL value if needle is an empty
|
||||
* string. We don't that behavior for cmp_contains. */
|
||||
if (strlen(fv_b->value.string) == 0) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (strstr(fv_a->value.string, fv_b->value.string)) {
|
||||
return TRUE;
|
||||
}
|
||||
else {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ftype_register_string(void)
|
||||
{
|
||||
|
@ -180,7 +225,7 @@ ftype_register_string(void)
|
|||
0, /* wire_size */
|
||||
string_fvalue_new, /* new_value */
|
||||
string_fvalue_free, /* free_value */
|
||||
val_from_string, /* val_from_unparsed */
|
||||
val_from_unparsed, /* val_from_unparsed */
|
||||
val_from_string, /* val_from_string */
|
||||
string_to_repr, /* val_to_string_repr */
|
||||
string_repr_len, /* len_string_repr */
|
||||
|
@ -199,6 +244,7 @@ ftype_register_string(void)
|
|||
cmp_ge,
|
||||
cmp_lt,
|
||||
cmp_le,
|
||||
cmp_contains, /* cmp_contains */
|
||||
|
||||
len,
|
||||
slice,
|
||||
|
@ -209,7 +255,7 @@ ftype_register_string(void)
|
|||
0,
|
||||
string_fvalue_new,
|
||||
string_fvalue_free,
|
||||
val_from_string, /* val_from_unparsed */
|
||||
val_from_unparsed, /* val_from_unparsed */
|
||||
val_from_string, /* val_from_string */
|
||||
NULL, /* val_to_string_repr */
|
||||
NULL, /* len_string_repr */
|
||||
|
@ -228,6 +274,7 @@ ftype_register_string(void)
|
|||
cmp_ge,
|
||||
cmp_lt,
|
||||
cmp_le,
|
||||
cmp_contains, /* cmp_contains */
|
||||
|
||||
len,
|
||||
slice,
|
||||
|
@ -238,7 +285,7 @@ ftype_register_string(void)
|
|||
0,
|
||||
string_fvalue_new,
|
||||
string_fvalue_free,
|
||||
val_from_string, /* val_from_unparsed */
|
||||
val_from_unparsed, /* val_from_unparsed */
|
||||
val_from_string, /* val_from_string */
|
||||
NULL, /* val_to_string_repr */
|
||||
NULL, /* len_string_repr */
|
||||
|
@ -257,6 +304,7 @@ ftype_register_string(void)
|
|||
cmp_ge,
|
||||
cmp_lt,
|
||||
cmp_le,
|
||||
cmp_contains, /* cmp_contains */
|
||||
|
||||
len,
|
||||
slice,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* $Id: ftype-time.c,v 1.20 2003/07/30 22:50:39 guy Exp $
|
||||
* $Id: ftype-time.c,v 1.21 2003/08/27 15:23:07 gram Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@ethereal.com>
|
||||
|
@ -167,7 +167,7 @@ get_nsecs(char *startp, int *nsecs)
|
|||
}
|
||||
|
||||
static gboolean
|
||||
relative_val_from_unparsed(fvalue_t *fv, char *s, LogFunc logfunc)
|
||||
relative_val_from_unparsed(fvalue_t *fv, char *s, gboolean allow_partial_value _U_, LogFunc logfunc)
|
||||
{
|
||||
char *curptr, *endptr;
|
||||
|
||||
|
@ -277,6 +277,12 @@ fail:
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
absolute_val_from_unparsed(fvalue_t *fv, char *s, gboolean allow_partial_value _U_, LogFunc logfunc)
|
||||
{
|
||||
return absolute_val_from_string(fv, s, logfunc);
|
||||
}
|
||||
|
||||
static void
|
||||
time_fvalue_new(fvalue_t *fv)
|
||||
{
|
||||
|
@ -337,7 +343,7 @@ ftype_register_time(void)
|
|||
0,
|
||||
time_fvalue_new,
|
||||
NULL,
|
||||
absolute_val_from_string, /* val_from_unparsed */
|
||||
absolute_val_from_unparsed, /* val_from_unparsed */
|
||||
absolute_val_from_string, /* val_from_string */
|
||||
absolute_val_to_repr, /* val_to_string_repr */
|
||||
absolute_val_repr_len, /* len_string_repr */
|
||||
|
@ -356,6 +362,8 @@ ftype_register_time(void)
|
|||
cmp_ge,
|
||||
cmp_lt,
|
||||
cmp_le,
|
||||
NULL, /* cmp_contains */
|
||||
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
@ -384,6 +392,8 @@ ftype_register_time(void)
|
|||
cmp_ge,
|
||||
cmp_lt,
|
||||
cmp_le,
|
||||
NULL, /* cmp_contains */
|
||||
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* $Id: ftype-tvbuff.c,v 1.9 2003/07/25 03:44:03 gram Exp $
|
||||
* $Id: ftype-tvbuff.c,v 1.10 2003/08/27 15:23:08 gram Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@ethereal.com>
|
||||
|
@ -27,10 +27,21 @@
|
|||
#include <ftypes-int.h>
|
||||
#include <epan/gdebug.h>
|
||||
|
||||
#define tvb_is_private fvalue_gboolean1
|
||||
|
||||
static void
|
||||
value_new(fvalue_t *fv)
|
||||
{
|
||||
fv->value.tvb = NULL;
|
||||
fv->tvb_is_private = FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
value_free(fvalue_t *fv)
|
||||
{
|
||||
if (fv->tvb_is_private) {
|
||||
tvb_free_chain(fv->value.tvb);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -41,6 +52,66 @@ value_set(fvalue_t *fv, gpointer value, gboolean already_copied)
|
|||
fv->value.tvb = value;
|
||||
}
|
||||
|
||||
static void
|
||||
free_tvb_data(void *data)
|
||||
{
|
||||
g_free(data);
|
||||
}
|
||||
|
||||
|
||||
static gboolean
|
||||
val_from_string(fvalue_t *fv, char *s, LogFunc logfunc _U_)
|
||||
{
|
||||
tvbuff_t *new_tvb;
|
||||
guint8 *private_data;
|
||||
|
||||
/* Make a tvbuff from the string. We can drop the
|
||||
* terminating NUL. */
|
||||
private_data = g_memdup(s, strlen(s));
|
||||
new_tvb = tvb_new_real_data(private_data,
|
||||
strlen(s), strlen(s));
|
||||
|
||||
/* Let the tvbuff know how to delete the data. */
|
||||
tvb_set_free_cb(new_tvb, free_tvb_data);
|
||||
|
||||
/* And let us know that we need to free the tvbuff */
|
||||
fv->tvb_is_private = TRUE;
|
||||
fv->value.tvb = new_tvb;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
val_from_unparsed(fvalue_t *fv, char *s, gboolean allow_partial_value _U_, LogFunc logfunc)
|
||||
{
|
||||
fvalue_t *fv_bytes;
|
||||
tvbuff_t *new_tvb;
|
||||
guint8 *private_data;
|
||||
|
||||
/* Does this look like a byte string? */
|
||||
fv_bytes = fvalue_from_unparsed(FT_BYTES, s, TRUE, NULL);
|
||||
if (fv_bytes) {
|
||||
/* Make a tvbuff from the bytes */
|
||||
private_data = g_memdup(fv_bytes->value.bytes->data,
|
||||
fv_bytes->value.bytes->len);
|
||||
new_tvb = tvb_new_real_data(private_data,
|
||||
fv_bytes->value.bytes->len,
|
||||
fv_bytes->value.bytes->len);
|
||||
|
||||
/* Let the tvbuff know how to delete the data. */
|
||||
tvb_set_free_cb(new_tvb, free_tvb_data);
|
||||
|
||||
/* And let us know that we need to free the tvbuff */
|
||||
fv->tvb_is_private = TRUE;
|
||||
fv->value.tvb = new_tvb;
|
||||
return TRUE;
|
||||
}
|
||||
else {
|
||||
/* Treat it as a string. */
|
||||
return val_from_string(fv, s, logfunc);
|
||||
}
|
||||
g_assert_not_reached();
|
||||
}
|
||||
|
||||
static gpointer
|
||||
value_get(fvalue_t *fv)
|
||||
{
|
||||
|
@ -74,18 +145,29 @@ slice(fvalue_t *fv, GByteArray *bytes, guint offset, guint length)
|
|||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
cmp_contains(fvalue_t *fv_a, fvalue_t *fv_b)
|
||||
{
|
||||
if (tvb_find_tvb(fv_a->value.tvb, fv_b->value.tvb, 0) > -1) {
|
||||
return TRUE;
|
||||
}
|
||||
else {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ftype_register_tvbuff(void)
|
||||
{
|
||||
|
||||
static ftype_t protocol_type = {
|
||||
"FT_PROTOCOL",
|
||||
"protocol",
|
||||
0,
|
||||
value_new,
|
||||
NULL,
|
||||
NULL, /* val_from_unparsed */
|
||||
NULL, /* val_from_string */
|
||||
"FT_PROTOCOL", /* name */
|
||||
"protocol", /* pretty_name */
|
||||
0, /* wire_size */
|
||||
value_new, /* new_value */
|
||||
value_free, /* free_value */
|
||||
val_from_unparsed, /* val_from_unparsed */
|
||||
val_from_string, /* val_from_string */
|
||||
NULL, /* val_to_string_repr */
|
||||
NULL, /* len_string_repr */
|
||||
|
||||
|
@ -103,6 +185,7 @@ ftype_register_tvbuff(void)
|
|||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
cmp_contains, /* cmp_contains */
|
||||
|
||||
len,
|
||||
slice,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* $Id: ftypes-int.h,v 1.9 2003/07/25 03:44:03 gram Exp $
|
||||
* $Id: ftypes-int.h,v 1.10 2003/08/27 15:23:08 gram Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@ethereal.com>
|
||||
|
@ -29,7 +29,7 @@
|
|||
typedef void (*FvalueNewFunc)(fvalue_t*);
|
||||
typedef void (*FvalueFreeFunc)(fvalue_t*);
|
||||
|
||||
typedef gboolean (*FvalueFromUnparsed)(fvalue_t*, char*, LogFunc);
|
||||
typedef gboolean (*FvalueFromUnparsed)(fvalue_t*, char*, gboolean, LogFunc);
|
||||
typedef gboolean (*FvalueFromString)(fvalue_t*, char*, LogFunc);
|
||||
typedef void (*FvalueToStringRepr)(fvalue_t*, ftrepr_t, char*);
|
||||
typedef int (*FvalueStringReprLen)(fvalue_t*, ftrepr_t);
|
||||
|
@ -74,6 +74,7 @@ struct _ftype_t {
|
|||
FvalueCmp cmp_ge;
|
||||
FvalueCmp cmp_lt;
|
||||
FvalueCmp cmp_le;
|
||||
FvalueCmp cmp_contains;
|
||||
|
||||
FvalueLen len;
|
||||
FvalueSlice slice;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* $Id: ftypes.c,v 1.10 2003/07/25 03:44:03 gram Exp $
|
||||
* $Id: ftypes.c,v 1.11 2003/08/27 15:23:08 gram Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@ethereal.com>
|
||||
|
@ -198,6 +198,15 @@ ftype_can_le(enum ftenum ftype)
|
|||
return ft->cmp_le ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
ftype_can_contains(enum ftenum ftype)
|
||||
{
|
||||
ftype_t *ft;
|
||||
|
||||
ft = ftype_lookup(ftype);
|
||||
return ft->cmp_contains ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------- */
|
||||
|
||||
/* Allocate and initialize an fvalue_t, given an ftype */
|
||||
|
@ -236,13 +245,13 @@ fvalue_free(fvalue_t *fv)
|
|||
}
|
||||
|
||||
fvalue_t*
|
||||
fvalue_from_unparsed(ftenum_t ftype, char *s, LogFunc logfunc)
|
||||
fvalue_from_unparsed(ftenum_t ftype, char *s, gboolean allow_partial_value, LogFunc logfunc)
|
||||
{
|
||||
fvalue_t *fv;
|
||||
|
||||
fv = fvalue_new(ftype);
|
||||
if (fv->ftype->val_from_unparsed) {
|
||||
if (fv->ftype->val_from_unparsed(fv, s, logfunc)) {
|
||||
if (fv->ftype->val_from_unparsed(fv, s, allow_partial_value, logfunc)) {
|
||||
return fv;
|
||||
}
|
||||
}
|
||||
|
@ -507,3 +516,11 @@ fvalue_le(fvalue_t *a, fvalue_t *b)
|
|||
g_assert(a->ftype->cmp_le);
|
||||
return a->ftype->cmp_le(a, b);
|
||||
}
|
||||
|
||||
gboolean
|
||||
fvalue_contains(fvalue_t *a, fvalue_t *b)
|
||||
{
|
||||
/* XXX - check compatibility of a and b */
|
||||
g_assert(a->ftype->cmp_contains);
|
||||
return a->ftype->cmp_contains(a, b);
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* ftypes.h
|
||||
* Definitions for field types
|
||||
*
|
||||
* $Id: ftypes.h,v 1.18 2003/07/25 03:44:04 gram Exp $
|
||||
* $Id: ftypes.h,v 1.19 2003/08/27 15:23:08 gram Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@ethereal.com>
|
||||
|
@ -120,6 +120,9 @@ ftype_can_lt(enum ftenum ftype);
|
|||
gboolean
|
||||
ftype_can_le(enum ftenum ftype);
|
||||
|
||||
gboolean
|
||||
ftype_can_contains(enum ftenum ftype);
|
||||
|
||||
/* ---------------- FVALUE ----------------- */
|
||||
|
||||
#include <epan/ipv4.h>
|
||||
|
@ -141,6 +144,11 @@ typedef struct {
|
|||
nstime_t time;
|
||||
tvbuff_t *tvb;
|
||||
} value;
|
||||
|
||||
/* The following is provided for private use
|
||||
* by the fvalue. */
|
||||
gboolean fvalue_gboolean1;
|
||||
|
||||
} fvalue_t;
|
||||
|
||||
fvalue_t*
|
||||
|
@ -152,10 +160,10 @@ fvalue_free(fvalue_t *fv);
|
|||
typedef void (*LogFunc)(char*,...);
|
||||
|
||||
fvalue_t*
|
||||
fvalue_from_unparsed(ftenum_t ftype, char *s, LogFunc log);
|
||||
fvalue_from_unparsed(ftenum_t ftype, char *s, gboolean allow_partial_value, LogFunc logfunc);
|
||||
|
||||
fvalue_t*
|
||||
fvalue_from_string(ftenum_t ftype, char *s, LogFunc log);
|
||||
fvalue_from_string(ftenum_t ftype, char *s, LogFunc logfunc);
|
||||
|
||||
/* Returns the length of the string required to hold the
|
||||
* string representation of the the field value.
|
||||
|
@ -213,6 +221,9 @@ fvalue_lt(fvalue_t *a, fvalue_t *b);
|
|||
gboolean
|
||||
fvalue_le(fvalue_t *a, fvalue_t *b);
|
||||
|
||||
gboolean
|
||||
fvalue_contains(fvalue_t *a, fvalue_t *b);
|
||||
|
||||
guint
|
||||
fvalue_length(fvalue_t *fv);
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* strutil.c
|
||||
* String utility routines
|
||||
*
|
||||
* $Id: strutil.c,v 1.11 2003/08/01 01:39:00 guy Exp $
|
||||
* $Id: strutil.c,v 1.12 2003/08/27 15:23:02 gram Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@ethereal.com>
|
||||
|
@ -301,3 +301,34 @@ bytes_to_str_punct(const guint8 *bd, int bd_len, gchar punct) {
|
|||
*p = '\0';
|
||||
return cur;
|
||||
}
|
||||
|
||||
/* Return the first occurrence of needle in haystack.
|
||||
* If not found, return NULL.
|
||||
* If either haystack or needle has 0 length, return NULL.
|
||||
* Algorithm copied from GNU's glibc 2.3.2 memcmp() */
|
||||
const guint8 *
|
||||
epan_memmem(const guint8 *haystack, guint haystack_len,
|
||||
const guint8 *needle, guint needle_len)
|
||||
{
|
||||
const guint8 *begin;
|
||||
const guint8 *const last_possible
|
||||
= haystack + haystack_len - needle_len;
|
||||
|
||||
if (needle_len == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (needle_len > haystack_len) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (begin = haystack ; begin <= last_possible; ++begin) {
|
||||
if (begin[0] == needle[0] &&
|
||||
!memcmp(&begin[1], needle + 1,
|
||||
needle_len - 1)) {
|
||||
return begin;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* strutil.h
|
||||
* String utility definitions
|
||||
*
|
||||
* $Id: strutil.h,v 1.10 2003/07/04 03:41:00 gram Exp $
|
||||
* $Id: strutil.h,v 1.11 2003/08/27 15:23:02 gram Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@ethereal.com>
|
||||
|
@ -35,6 +35,9 @@ gchar* format_text(const guchar *line, int len);
|
|||
gchar* bytes_to_str(const guint8 *, int);
|
||||
gchar* bytes_to_str_punct(const guint8 *, int, gchar punct);
|
||||
|
||||
const guint8 * epan_memmem(const guint8 *haystack, guint haystack_len,
|
||||
const guint8 *needle, guint needle_len);
|
||||
|
||||
/* Surround a string or a macro, resolved to a string, with double quotes */
|
||||
#define _STRINGIFY(a) # a
|
||||
#define STRINGIFY(a) _STRINGIFY(a)
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
* the data of a backing tvbuff, or can be a composite of
|
||||
* other tvbuffs.
|
||||
*
|
||||
* $Id: tvbuff.c,v 1.48 2003/08/08 08:19:50 guy Exp $
|
||||
* $Id: tvbuff.c,v 1.49 2003/08/27 15:23:02 gram Exp $
|
||||
*
|
||||
* Copyright (c) 2000 by Gilbert Ramirez <gram@alumni.rice.edu>
|
||||
*
|
||||
|
@ -2141,3 +2141,33 @@ tvb_get_ds_tvb(tvbuff_t *tvb)
|
|||
{
|
||||
return tvb->ds_tvb;
|
||||
}
|
||||
|
||||
/* Find a needle tvbuff within a haystack tvbuff. */
|
||||
gint
|
||||
tvb_find_tvb(tvbuff_t *haystack_tvb, tvbuff_t *needle_tvb, gint haystack_offset)
|
||||
{
|
||||
guint haystack_abs_offset, haystack_abs_length;
|
||||
const guint8 *haystack_data;
|
||||
const guint8 *needle_data;
|
||||
const guint needle_len = needle_tvb->length;
|
||||
const guint8 *location;
|
||||
|
||||
/* Get pointers to the tvbuffs' data. */
|
||||
haystack_data = tvb_get_ptr(haystack_tvb, 0, -1);
|
||||
needle_data = tvb_get_ptr(needle_tvb, 0, -1);
|
||||
|
||||
check_offset_length(haystack_tvb, haystack_offset, -1,
|
||||
&haystack_abs_offset, &haystack_abs_length);
|
||||
|
||||
location = epan_memmem(haystack_data + haystack_abs_offset, haystack_abs_length,
|
||||
needle_data, needle_len);
|
||||
|
||||
if (location) {
|
||||
return location - haystack_data;
|
||||
}
|
||||
else {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
* the data of a backing tvbuff, or can be a composite of
|
||||
* other tvbuffs.
|
||||
*
|
||||
* $Id: tvbuff.h,v 1.33 2003/06/12 08:33:31 guy Exp $
|
||||
* $Id: tvbuff.h,v 1.34 2003/08/27 15:23:03 gram Exp $
|
||||
*
|
||||
* Copyright (c) 2000 by Gilbert Ramirez <gram@alumni.rice.edu>
|
||||
*
|
||||
|
@ -435,6 +435,13 @@ extern gchar *tvb_bytes_to_str(tvbuff_t *tvb, gint offset, gint len);
|
|||
|
||||
extern tvbuff_t *tvb_get_ds_tvb(tvbuff_t *tvb);
|
||||
|
||||
/* Locate a sub-tvbuff within another tvbuff, starting at position
|
||||
* 'haystack_offset'. Returns the index of the beginning of 'needle' within
|
||||
* 'haystack', or -1 if 'needle' is not found. The index is relative
|
||||
* to the start of 'haystack', not 'haystack_offset'. */
|
||||
extern gint tvb_find_tvb(tvbuff_t *haystack_tvb, tvbuff_t *needle_tvb,
|
||||
gint haystack_offset);
|
||||
|
||||
/************** END OF ACCESSORS ****************/
|
||||
|
||||
#endif /* __TVBUFF_H__ */
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
* Copyright 2000, Jeffrey C. Foster <jfoste@woodward.com> and
|
||||
* Guy Harris <guy@alum.mit.edu>
|
||||
*
|
||||
* $Id: dfilter_expr_dlg.c,v 1.35 2003/08/25 00:15:02 guy Exp $
|
||||
* $Id: dfilter_expr_dlg.c,v 1.36 2003/08/27 15:23:10 gram Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@ethereal.com>
|
||||
|
@ -280,6 +280,9 @@ show_relations(GtkWidget *relation_label, GtkWidget *relation_list,
|
|||
if (ftype_can_le(ftype) ||
|
||||
(ftype_can_slice(ftype) && ftype_can_le(FT_BYTES)))
|
||||
add_relation_list(relation_list, "<=");
|
||||
if (ftype_can_contains(ftype) ||
|
||||
(ftype_can_slice(ftype) && ftype_can_contains(FT_BYTES)))
|
||||
add_relation_list(relation_list, "contains");
|
||||
|
||||
/*
|
||||
* And show the list.
|
||||
|
@ -883,6 +886,8 @@ dfilter_expr_dlg_accept_cb(GtkWidget *w, gpointer filter_te_arg)
|
|||
can_compare = ftype_can_ge(ftype);
|
||||
else if (strcmp(item_str, "<=") == 0)
|
||||
can_compare = ftype_can_le(ftype);
|
||||
else if (strcmp(item_str, "contains") == 0)
|
||||
can_compare = ftype_can_contains(ftype);
|
||||
else
|
||||
can_compare = TRUE; /* not a comparison */
|
||||
if (!can_compare) {
|
||||
|
@ -928,8 +933,14 @@ dfilter_expr_dlg_accept_cb(GtkWidget *w, gpointer filter_te_arg)
|
|||
* for the type of the field; if a range string was
|
||||
* specified, must be valid for FT_BYTES.
|
||||
*/
|
||||
fvalue = fvalue_from_unparsed(ftype, stripped_value_str,
|
||||
dfilter_report_bad_value);
|
||||
if (strcmp(item_str, "contains") == 0) {
|
||||
fvalue = fvalue_from_unparsed(ftype, stripped_value_str, TRUE,
|
||||
dfilter_report_bad_value);
|
||||
}
|
||||
else {
|
||||
fvalue = fvalue_from_unparsed(ftype, stripped_value_str, FALSE,
|
||||
dfilter_report_bad_value);
|
||||
}
|
||||
if (fvalue == NULL) {
|
||||
/*
|
||||
* It's not valid.
|
||||
|
|
|
@ -4,7 +4,7 @@ Test-suite to test ethereal's dfilter mechanism.
|
|||
"""
|
||||
|
||||
#
|
||||
# $Id: dfilter-test.py,v 1.2 2003/07/25 03:44:05 gram Exp $
|
||||
# $Id: dfilter-test.py,v 1.3 2003/08/27 15:23:11 gram Exp $
|
||||
#
|
||||
# Copyright (C) 2003 by Gilbert Ramirez <gram@alumni.rice.edu>
|
||||
#
|
||||
|
@ -454,6 +454,22 @@ class Bytes(Test):
|
|||
return self.DFilterCount(pkt_nfs,
|
||||
"nfs.fattr3.size == 264000", 0)
|
||||
|
||||
def ck_contains_1(self):
|
||||
return self.DFilterCount(pkt_ipx_rip,
|
||||
"ipx.src.node contains a3", 1)
|
||||
|
||||
def ck_contains_2(self):
|
||||
return self.DFilterCount(pkt_ipx_rip,
|
||||
"ipx.src.node contains a3:e3", 1)
|
||||
|
||||
def ck_contains_3(self):
|
||||
return self.DFilterCount(pkt_ipx_rip,
|
||||
"ipx.src.node contains 00:aa:00:a3:e3:a4", 1)
|
||||
|
||||
def ck_contains_4(self):
|
||||
return self.DFilterCount(pkt_ipx_rip,
|
||||
"ipx.src.node contains aa:e3", 0)
|
||||
|
||||
|
||||
tests = [
|
||||
ck_eq_1,
|
||||
|
@ -482,6 +498,10 @@ class Bytes(Test):
|
|||
ck_bytes_2,
|
||||
ck_uint64_1,
|
||||
ck_uint64_2,
|
||||
ck_contains_1,
|
||||
ck_contains_2,
|
||||
ck_contains_3,
|
||||
ck_contains_4,
|
||||
]
|
||||
|
||||
|
||||
|
@ -967,6 +987,29 @@ class String(Test):
|
|||
return self.DFilterCount(pkt_tftp,
|
||||
'tftp.type == "junk"', 0)
|
||||
|
||||
def ck_contains_1(self):
|
||||
return self.DFilterCount(pkt_http,
|
||||
'http.request.method contains "E"', 1)
|
||||
|
||||
def ck_contains_2(self):
|
||||
return self.DFilterCount(pkt_http,
|
||||
'http.request.method contains "EA"', 1)
|
||||
|
||||
def ck_contains_3(self):
|
||||
return self.DFilterCount(pkt_http,
|
||||
'http.request.method contains "HEAD"', 1)
|
||||
|
||||
def ck_contains_4(self):
|
||||
return self.DFilterCount(pkt_http,
|
||||
'http.request.method contains "POST"', 0)
|
||||
|
||||
def ck_contains_5(self):
|
||||
return self.DFilterCount(pkt_http,
|
||||
'http.request.method contains 50:4f:53:54"', 0) # "POST"
|
||||
|
||||
def ck_contains_6(self):
|
||||
return self.DFilterCount(pkt_http,
|
||||
'http.request.method contains 48:45:41:44"', 1) # "HEAD"
|
||||
|
||||
|
||||
tests = [
|
||||
|
@ -995,6 +1038,11 @@ class String(Test):
|
|||
# ck_slice_8,
|
||||
ck_stringz_1,
|
||||
ck_stringz_2,
|
||||
ck_contains_1,
|
||||
ck_contains_2,
|
||||
ck_contains_3,
|
||||
ck_contains_4,
|
||||
ck_contains_5,
|
||||
]
|
||||
|
||||
|
||||
|
@ -1124,6 +1172,26 @@ class TVB(Test):
|
|||
"ip[-1] == 0x86", 0)
|
||||
|
||||
|
||||
def ck_contains_1(self):
|
||||
return self.DFilterCount(pkt_http,
|
||||
"eth contains 6b", 1)
|
||||
|
||||
def ck_contains_2(self):
|
||||
return self.DFilterCount(pkt_http,
|
||||
"eth contains 09:6b:88", 1)
|
||||
|
||||
def ck_contains_3(self):
|
||||
return self.DFilterCount(pkt_http,
|
||||
"eth contains 00:e0:81:00:b0:28:00:09:6b:88:f5:c9:08:00", 1)
|
||||
|
||||
def ck_contains_4(self):
|
||||
return self.DFilterCount(pkt_http,
|
||||
"eth contains ff:ff:ff", 0)
|
||||
|
||||
def ck_contains_5(self):
|
||||
return self.DFilterCount(pkt_http,
|
||||
'http contains "HEAD"', 1)
|
||||
|
||||
|
||||
tests = [
|
||||
ck_slice_1,
|
||||
|
@ -1132,6 +1200,11 @@ class TVB(Test):
|
|||
# XXX
|
||||
# ck_slice_4,
|
||||
# ck_slice_5,
|
||||
ck_contains_1,
|
||||
ck_contains_2,
|
||||
ck_contains_3,
|
||||
ck_contains_4,
|
||||
ck_contains_5,
|
||||
]
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue