aboutsummaryrefslogtreecommitdiffstats
path: root/epan
diff options
context:
space:
mode:
authorGilbert Ramirez <gram@alumni.rice.edu>2002-10-16 16:32:59 +0000
committerGilbert Ramirez <gram@alumni.rice.edu>2002-10-16 16:32:59 +0000
commit1ba73660c0e0bbc957b6ac64362a4ec43a3b262e (patch)
treee649d5d42ee42a10085030e4ac0f8e9e71a9c55e /epan
parente0cf132365b451fb710649e3798232f33609aeef (diff)
Make the dfilter code support multiple header_field_info's with
the same name (abbreviation). Thus, if multiple protocols or fields are registered with the same name, you can still filter on the name and have the filtering work as expected. svn path=/trunk/; revision=6434
Diffstat (limited to 'epan')
-rw-r--r--epan/dfilter/dfilter.c12
-rw-r--r--epan/dfilter/dfvm.c61
-rw-r--r--epan/dfilter/dfvm.h11
-rw-r--r--epan/dfilter/gencode.c76
4 files changed, 101 insertions, 59 deletions
diff --git a/epan/dfilter/dfilter.c b/epan/dfilter/dfilter.c
index fae8bdd423..71e72e7c96 100644
--- a/epan/dfilter/dfilter.c
+++ b/epan/dfilter/dfilter.c
@@ -1,5 +1,5 @@
/*
- * $Id: dfilter.c,v 1.12 2002/09/09 21:04:15 guy Exp $
+ * $Id: dfilter.c,v 1.13 2002/10/16 16:32:59 gram Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -135,9 +135,9 @@ dfilter_free(dfilter_t *df)
free_insns(df->insns);
}
- if (df->interesting_fields) {
- g_free(df->interesting_fields);
- }
+ if (df->interesting_fields) {
+ g_free(df->interesting_fields);
+ }
g_free(df->registers);
g_free(df->attempted_load);
@@ -250,8 +250,8 @@ dfilter_compile(gchar *text, dfilter_t **dfp)
dfilter = dfilter_new();
dfilter->insns = dfw->insns;
dfw->insns = NULL;
- dfilter->interesting_fields = dfw_interesting_fields(dfw,
- &dfilter->num_interesting_fields);
+ dfilter->interesting_fields = dfw_interesting_fields(dfw,
+ &dfilter->num_interesting_fields);
/* Initialize run-time space */
dfilter->num_registers = dfw->next_register;
diff --git a/epan/dfilter/dfvm.c b/epan/dfilter/dfvm.c
index 4b817f1944..0be9fc692d 100644
--- a/epan/dfilter/dfvm.c
+++ b/epan/dfilter/dfvm.c
@@ -1,5 +1,5 @@
/*
- * $Id: dfvm.c,v 1.8 2002/08/28 20:40:55 jmayer Exp $
+ * $Id: dfvm.c,v 1.9 2002/10/16 16:32:59 gram Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -107,12 +107,12 @@ dfvm_dump(FILE *f, GPtrArray *insns)
switch (insn->op) {
case CHECK_EXISTS:
fprintf(f, "%05d CHECK_EXISTS\t%s\n",
- id, proto_registrar_get_abbrev(arg1->value.numeric));
+ id, arg1->value.hfinfo->abbrev);
break;
case READ_TREE:
fprintf(f, "%05d READ_TREE\t\t%s -> reg#%d\n",
- id, proto_registrar_get_abbrev(arg1->value.numeric),
+ id, arg1->value.hfinfo->abbrev,
arg2->value.numeric);
break;
@@ -187,12 +187,13 @@ dfvm_dump(FILE *f, GPtrArray *insns)
/* Reads a field from the proto_tree and loads the fvalues into a register,
* if that field has not already been read. */
static gboolean
-read_tree(dfilter_t *df, proto_tree *tree, int field_id, int reg)
+read_tree(dfilter_t *df, proto_tree *tree, header_field_info *hfinfo, int reg)
{
GPtrArray *finfos;
field_info *finfo;
int i, len;
GList *fvalues = NULL;
+ gboolean found_something = FALSE;
/* Already loaded in this run of the dfilter? */
if (df->attempted_load[reg]) {
@@ -206,20 +207,32 @@ read_tree(dfilter_t *df, proto_tree *tree, int field_id, int reg)
df->attempted_load[reg] = TRUE;
- finfos = proto_get_finfo_ptr_array(tree, field_id);
- if (!finfos) {
- return FALSE;
+ while (hfinfo) {
+ finfos = proto_get_finfo_ptr_array(tree, hfinfo->id);
+ if (!finfos) {
+ hfinfo = hfinfo->same_name_next;
+ continue;
+ }
+ else if (g_ptr_array_len(finfos) == 0) {
+ hfinfo = hfinfo->same_name_next;
+ continue;
+ }
+ else {
+ found_something = TRUE;
+ }
+
+ len = finfos->len;
+ for (i = 0; i < len; i++) {
+ finfo = g_ptr_array_index(finfos, i);
+ fvalues = g_list_prepend(fvalues, finfo->value);
+ }
+
+ hfinfo = hfinfo->same_name_next;
}
- else if (g_ptr_array_len(finfos) == 0) {
- return FALSE;
- }
-
- len = finfos->len;
- for (i = 0; i < len; i++) {
- finfo = g_ptr_array_index(finfos, i);
- fvalues = g_list_prepend(fvalues, finfo->value);
+
+ if (!found_something) {
+ return FALSE;
}
- fvalues = g_list_reverse(fvalues);
df->registers[reg] = fvalues;
return TRUE;
@@ -308,6 +321,7 @@ dfvm_apply(dfilter_t *df, proto_tree *tree)
dfvm_value_t *arg1;
dfvm_value_t *arg2;
dfvm_value_t *arg3;
+ header_field_info *hfinfo;
g_assert(tree);
@@ -329,13 +343,22 @@ dfvm_apply(dfilter_t *df, proto_tree *tree)
switch (insn->op) {
case CHECK_EXISTS:
- accum = proto_check_for_protocol_or_field(tree,
- arg1->value.numeric);
+ hfinfo = arg1->value.hfinfo;
+ while(hfinfo) {
+ accum = proto_check_for_protocol_or_field(tree,
+ arg1->value.hfinfo->id);
+ if (accum) {
+ break;
+ }
+ else {
+ hfinfo = hfinfo->same_name_next;
+ }
+ }
break;
case READ_TREE:
accum = read_tree(df, tree,
- arg1->value.numeric, arg2->value.numeric);
+ arg1->value.hfinfo, arg2->value.numeric);
break;
case PUT_FVALUE:
diff --git a/epan/dfilter/dfvm.h b/epan/dfilter/dfvm.h
index 526342bf1f..c97faae5fb 100644
--- a/epan/dfilter/dfvm.h
+++ b/epan/dfilter/dfvm.h
@@ -1,5 +1,5 @@
/*
- * $Id: dfvm.h,v 1.7 2002/08/28 20:40:55 jmayer Exp $
+ * $Id: dfvm.h,v 1.8 2002/10/16 16:32:59 gram Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -32,7 +32,7 @@
typedef enum {
EMPTY,
FVALUE,
- FIELD_ID,
+ HFINFO,
INSN_NUMBER,
REGISTER,
INTEGER,
@@ -43,9 +43,10 @@ typedef struct {
dfvm_value_type_t type;
union {
- fvalue_t *fvalue;
- guint32 numeric;
- drange *drange;
+ fvalue_t *fvalue;
+ guint32 numeric;
+ drange *drange;
+ header_field_info *hfinfo;
} value;
} dfvm_value_t;
diff --git a/epan/dfilter/gencode.c b/epan/dfilter/gencode.c
index b872c479cb..011f67927b 100644
--- a/epan/dfilter/gencode.c
+++ b/epan/dfilter/gencode.c
@@ -1,5 +1,5 @@
/*
- * $Id: gencode.c,v 1.7 2002/08/28 20:40:55 jmayer Exp $
+ * $Id: gencode.c,v 1.8 2002/10/16 16:32:59 gram Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -45,45 +45,54 @@ dfw_append_insn(dfwork_t *dfw, dfvm_insn_t *insn)
/* returns register number */
static int
-dfw_append_read_tree(dfwork_t *dfw, int field_id)
+dfw_append_read_tree(dfwork_t *dfw, header_field_info *hfinfo)
{
dfvm_insn_t *insn;
dfvm_value_t *val1, *val2;
int reg = -1;
+ /* Rewind to find the first field of this name. */
+ while (hfinfo->same_name_prev) {
+ hfinfo = hfinfo->same_name_prev;
+ }
+
/* Keep track of which registers
- * were used for which field_id's so that we
+ * were used for which hfinfo's so that we
* can re-use registers. */
reg = GPOINTER_TO_UINT(
- g_hash_table_lookup(dfw->loaded_fields,
- GINT_TO_POINTER(field_id)));
+ g_hash_table_lookup(dfw->loaded_fields, hfinfo));
if (reg) {
/* Reg's are stored in has as reg+1, so
- * that the non-existence of a field_id in
+ * that the non-existence of a hfinfo in
* the hash, or 0, can be differentiated from
- * a field_id being loaded into register #0. */
+ * a hfinfo being loaded into register #0. */
reg--;
}
else {
reg = dfw->next_register++;
g_hash_table_insert(dfw->loaded_fields,
- GUINT_TO_POINTER(field_id),
- GUINT_TO_POINTER(reg + 1));
+ hfinfo, GUINT_TO_POINTER(reg + 1));
- /* Record the FIELD_ID in hash of interesting fields. */
- g_hash_table_insert(dfw->interesting_fields,
- GINT_TO_POINTER(field_id), GUINT_TO_POINTER(TRUE));
- }
+ insn = dfvm_insn_new(READ_TREE);
+ val1 = dfvm_value_new(HFINFO);
+ val1->value.hfinfo = hfinfo;
+ val2 = dfvm_value_new(REGISTER);
+ val2->value.numeric = reg;
- insn = dfvm_insn_new(READ_TREE);
- val1 = dfvm_value_new(FIELD_ID);
- val1->value.numeric = field_id;
- val2 = dfvm_value_new(REGISTER);
- val2->value.numeric = reg;
+ insn->arg1 = val1;
+ insn->arg2 = val2;
+ dfw_append_insn(dfw, insn);
+
+ while (hfinfo) {
+ /* Record the FIELD_ID in hash of interesting fields. */
+ g_hash_table_insert(dfw->interesting_fields,
+ GINT_TO_POINTER(hfinfo->id),
+ GUINT_TO_POINTER(TRUE));
+ hfinfo = hfinfo->same_name_next;
+ }
+
+ }
- insn->arg1 = val1;
- insn->arg2 = val2;
- dfw_append_insn(dfw, insn);
return reg;
}
@@ -119,7 +128,7 @@ dfw_append_mk_range(dfwork_t *dfw, stnode_t *node)
dfvm_value_t *val;
hfinfo = sttype_range_hfinfo(node);
- hf_reg = dfw_append_read_tree(dfw, hfinfo->id);
+ hf_reg = dfw_append_read_tree(dfw, hfinfo);
insn = dfvm_insn_new(MK_RANGE);
@@ -159,7 +168,7 @@ gen_relation(dfwork_t *dfw, dfvm_opcode_t op, stnode_t *st_arg1, stnode_t *st_ar
if (type1 == STTYPE_FIELD) {
hfinfo = stnode_data(st_arg1);
- reg1 = dfw_append_read_tree(dfw, hfinfo->id);
+ reg1 = dfw_append_read_tree(dfw, hfinfo);
insn = dfvm_insn_new(IF_FALSE_GOTO);
jmp1 = dfvm_value_new(INSN_NUMBER);
@@ -178,7 +187,7 @@ gen_relation(dfwork_t *dfw, dfvm_opcode_t op, stnode_t *st_arg1, stnode_t *st_ar
if (type2 == STTYPE_FIELD) {
hfinfo = stnode_data(st_arg2);
- reg2 = dfw_append_read_tree(dfw, hfinfo->id);
+ reg2 = dfw_append_read_tree(dfw, hfinfo);
insn = dfvm_insn_new(IF_FALSE_GOTO);
jmp2 = dfvm_value_new(INSN_NUMBER);
@@ -229,16 +238,25 @@ gen_test(dfwork_t *dfw, stnode_t *st_node)
break;
case TEST_OP_EXISTS:
- val1 = dfvm_value_new(FIELD_ID);
+ val1 = dfvm_value_new(HFINFO);
hfinfo = stnode_data(st_arg1);
- val1->value.numeric = hfinfo->id;
+
+ /* Rewind to find the first field of this name. */
+ while (hfinfo->same_name_prev) {
+ hfinfo = hfinfo->same_name_prev;
+ }
+ val1->value.hfinfo = hfinfo;
insn = dfvm_insn_new(CHECK_EXISTS);
insn->arg1 = val1;
dfw_append_insn(dfw, insn);
- /* Record the FIELD_ID in hash of interesting fields. */
- g_hash_table_insert(dfw->interesting_fields,
- GINT_TO_POINTER(hfinfo->id), GUINT_TO_POINTER(TRUE));
+ /* Record the FIELD_ID in hash of interesting fields. */
+ while (hfinfo) {
+ g_hash_table_insert(dfw->interesting_fields,
+ GINT_TO_POINTER(hfinfo->id),
+ GUINT_TO_POINTER(TRUE));
+ hfinfo = hfinfo->same_name_next;
+ }
break;