diff options
-rw-r--r-- | epan/dfilter/dfilter.c | 12 | ||||
-rw-r--r-- | epan/dfilter/dfvm.c | 61 | ||||
-rw-r--r-- | epan/dfilter/dfvm.h | 11 | ||||
-rw-r--r-- | epan/dfilter/gencode.c | 76 |
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; |