From 1ba73660c0e0bbc957b6ac64362a4ec43a3b262e Mon Sep 17 00:00:00 2001 From: Gilbert Ramirez Date: Wed, 16 Oct 2002 16:32:59 +0000 Subject: 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 --- epan/dfilter/dfilter.c | 12 ++++---- epan/dfilter/dfvm.c | 61 +++++++++++++++++++++++++++------------- epan/dfilter/dfvm.h | 11 ++++---- epan/dfilter/gencode.c | 76 +++++++++++++++++++++++++++++++------------------- 4 files changed, 101 insertions(+), 59 deletions(-) (limited to 'epan') 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 @@ -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 @@ -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 @@ -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 @@ -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; -- cgit v1.2.3