summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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;