Make the dfilter code support multiple header_field_info's with
authorgram <gram@f5534014-38df-0310-8fa8-9805f1628bb7>
Wed, 16 Oct 2002 16:32:59 +0000 (16:32 +0000)
committergram <gram@f5534014-38df-0310-8fa8-9805f1628bb7>
Wed, 16 Oct 2002 16:32:59 +0000 (16:32 +0000)
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.

git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@6434 f5534014-38df-0310-8fa8-9805f1628bb7

epan/dfilter/dfilter.c
epan/dfilter/dfvm.c
epan/dfilter/dfvm.h
epan/dfilter/gencode.c

index fae8bdd423662ff5e55c1b80aafa3d84f2754548..71e72e7c967f5279a017e3fd22ed13ebf00cfaee 100644 (file)
@@ -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;
index 4b817f19447181bdbc5fd102eba14a12c689c6ac..0be9fc692db6f84f35b4de30746229d80b730ee5 100644 (file)
@@ -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:
index 526342bf1f78072067d547cb7b924dc7982248b3..c97faae5fb62a67983460919d34f2a652a38b505 100644 (file)
@@ -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;
index b872c479cb150d541a57a0beeeb97d88bf3652e7..011f67927b5ab2d699c5d3ba7180ffd96c5fb3c6 100644 (file)
@@ -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;