diff options
author | Gilbert Ramirez <gram@alumni.rice.edu> | 2001-12-18 19:09:08 +0000 |
---|---|---|
committer | Gilbert Ramirez <gram@alumni.rice.edu> | 2001-12-18 19:09:08 +0000 |
commit | 791f5774d0fdabdb706bfd7056e534713cc4e4d6 (patch) | |
tree | 35f987f9914fead0fb5fefe79df280b7340831b4 /epan/dfilter | |
parent | 4e013a44de86f8146cfd7d440adb67366e37273a (diff) |
Provide for per-protocol-tree data in the proto_tree code.
Put a hash-table of "interesting" fields in the per-proto-tree data.
The dfilter code records which fields/protocols are "interesting" (by which
I mean, their value or existence is checked). Thus, the proto_tree routines
can create special arrays of field_info*'s that are ready for the dfilter
engine to use during a filter operation.
Also store the "proto_tree_is_visible" boolean, renamed "visible", in
the per-proto-tree data.
Move epan_dissect_t to its own header file to make #include dependencies
easier to handle.
Provide epan_dissect_fill_in_columns(), which accepts just the epan_dissect_t*
as an argument.
epan_dissect_new() needs to be followed by epan_dissect_run() for the
dissection to actually take place. Between those two calls,
epan_dissect_prime_dfilter() can be run 0, 1, or multiple times in order to
prime the empty proto_tree with the "intersesting" fields from the dfilter_t.
svn path=/trunk/; revision=4422
Diffstat (limited to 'epan/dfilter')
-rw-r--r-- | epan/dfilter/dfilter-int.h | 5 | ||||
-rw-r--r-- | epan/dfilter/dfilter.c | 27 | ||||
-rw-r--r-- | epan/dfilter/dfilter.h | 12 | ||||
-rw-r--r-- | epan/dfilter/dfvm.c | 6 | ||||
-rw-r--r-- | epan/dfilter/gencode.c | 50 | ||||
-rw-r--r-- | epan/dfilter/gencode.h | 3 | ||||
-rw-r--r-- | epan/dfilter/semcheck.c | 3 |
7 files changed, 96 insertions, 10 deletions
diff --git a/epan/dfilter/dfilter-int.h b/epan/dfilter/dfilter-int.h index c1e6774438..89e1857f8f 100644 --- a/epan/dfilter/dfilter-int.h +++ b/epan/dfilter/dfilter-int.h @@ -1,5 +1,5 @@ /* - * $Id: dfilter-int.h,v 1.3 2001/02/15 06:22:45 guy Exp $ + * $Id: dfilter-int.h,v 1.4 2001/12/18 19:09:06 gram Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@zing.org> @@ -35,6 +35,8 @@ struct _dfilter_t { int num_registers; GList **registers; gboolean *attempted_load; + int *interesting_fields; + int num_interesting_fields; }; typedef struct { @@ -43,6 +45,7 @@ typedef struct { gboolean syntax_error; GPtrArray *insns; GHashTable *loaded_fields; + GHashTable *interesting_fields; int next_insn_id; int next_register; } dfwork_t; diff --git a/epan/dfilter/dfilter.c b/epan/dfilter/dfilter.c index 0380f15662..1f5743d23e 100644 --- a/epan/dfilter/dfilter.c +++ b/epan/dfilter/dfilter.c @@ -1,5 +1,5 @@ /* - * $Id: dfilter.c,v 1.5 2001/07/13 00:55:54 guy Exp $ + * $Id: dfilter.c,v 1.6 2001/12/18 19:09:06 gram Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@zing.org> @@ -37,6 +37,7 @@ #include "gencode.h" #include "semcheck.h" #include "dfvm.h" +#include "epan_dissect.h" /* Balanced tree of abbreviations and IDs */ @@ -228,6 +229,10 @@ dfilter_free(dfilter_t *df) free_insns(df->insns); } + if (df->interesting_fields) { + g_free(df->interesting_fields); + } + g_free(df->registers); g_free(df->attempted_load); g_free(df); @@ -245,6 +250,7 @@ dfwork_new(void) dfw->syntax_error = FALSE; dfw->insns = NULL; dfw->loaded_fields = NULL; + dfw->interesting_fields = NULL; dfw->next_insn_id = 0; dfw->next_register = 0; @@ -262,10 +268,15 @@ dfwork_free(dfwork_t *dfw) g_hash_table_destroy(dfw->loaded_fields); } + if (dfw->interesting_fields) { + g_hash_table_destroy(dfw->interesting_fields); + } + if (dfw->insns) { free_insns(dfw->insns); } + g_free(dfw); } @@ -333,6 +344,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); /* Initialize run-time space */ dfilter->num_registers = dfw->next_register; @@ -378,6 +391,18 @@ dfilter_apply_edt(dfilter_t *df, epan_dissect_t* edt) void +dfilter_foreach_interesting_field(dfilter_t *df, GFunc func, + gpointer user_data) +{ + int i; + + for (i = 0; i < df->num_interesting_fields; i++) { + func(GINT_TO_POINTER(df->interesting_fields[i]), user_data); + } +} + + +void dfilter_dump(dfilter_t *df) { dfvm_dump(stdout, df->insns); diff --git a/epan/dfilter/dfilter.h b/epan/dfilter/dfilter.h index afd93fb824..49eba9c5db 100644 --- a/epan/dfilter/dfilter.h +++ b/epan/dfilter/dfilter.h @@ -1,5 +1,5 @@ /* - * $Id: dfilter.h,v 1.2 2001/02/01 20:31:18 gram Exp $ + * $Id: dfilter.h,v 1.3 2001/12/18 19:09:06 gram Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@zing.org> @@ -25,12 +25,14 @@ #define DFILTER_H #include <glib.h> -#include "epan.h" -#include "proto.h" /* Passed back to user */ typedef struct _dfilter_t dfilter_t; +#include "epan.h" +#include "proto.h" + + /* Module-level initialization */ void dfilter_init(void); @@ -75,6 +77,10 @@ dfilter_apply_edt(dfilter_t *df, epan_dissect_t* edt); gboolean dfilter_apply(dfilter_t *df, tvbuff_t *tvb, proto_tree *tree); +/* Run a callback for each interesting field in the dfilter. */ +void +dfilter_foreach_interesting_field(dfilter_t *df, GFunc func, + gpointer user_data); /* Print bytecode of dfilter to stdout */ void diff --git a/epan/dfilter/dfvm.c b/epan/dfilter/dfvm.c index bc1c48c21d..02bf948a5c 100644 --- a/epan/dfilter/dfvm.c +++ b/epan/dfilter/dfvm.c @@ -1,5 +1,5 @@ /* - * $Id: dfvm.c,v 1.4 2001/12/13 05:55:23 gram Exp $ + * $Id: dfvm.c,v 1.5 2001/12/18 19:09:06 gram Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@zing.org> @@ -211,6 +211,9 @@ read_tree(dfilter_t *df, proto_tree *tree, int field_id, int reg) if (!finfos) { return FALSE; } + else if (g_ptr_array_len(finfos) == 0) { + return FALSE; + } len = finfos->len; for (i = 0; i < len; i++) { @@ -218,7 +221,6 @@ read_tree(dfilter_t *df, proto_tree *tree, int field_id, int reg) fvalues = g_list_prepend(fvalues, finfo->value); } fvalues = g_list_reverse(fvalues); - g_ptr_array_free(finfos, TRUE); df->registers[reg] = fvalues; return TRUE; diff --git a/epan/dfilter/gencode.c b/epan/dfilter/gencode.c index cf3e1d5787..d8d0119005 100644 --- a/epan/dfilter/gencode.c +++ b/epan/dfilter/gencode.c @@ -1,5 +1,5 @@ /* - * $Id: gencode.c,v 1.3 2001/02/27 19:23:28 gram Exp $ + * $Id: gencode.c,v 1.4 2001/12/18 19:09:06 gram Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@zing.org> @@ -57,7 +57,7 @@ dfw_append_read_tree(dfwork_t *dfw, int field_id) * can re-use registers. */ reg = GPOINTER_TO_UINT( g_hash_table_lookup(dfw->loaded_fields, - GUINT_TO_POINTER(field_id))); + GINT_TO_POINTER(field_id))); if (reg) { /* Reg's are stored in has as reg+1, so * that the non-existence of a field_id in @@ -70,6 +70,10 @@ dfw_append_read_tree(dfwork_t *dfw, int field_id) g_hash_table_insert(dfw->loaded_fields, GUINT_TO_POINTER(field_id), 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); @@ -232,6 +236,11 @@ gen_test(dfwork_t *dfw, stnode_t *st_node) 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)); + break; case TEST_OP_NOT: @@ -312,7 +321,44 @@ dfw_gencode(dfwork_t *dfw) { dfw->insns = g_ptr_array_new(); dfw->loaded_fields = g_hash_table_new(g_direct_hash, g_direct_equal); + dfw->interesting_fields = g_hash_table_new(g_direct_hash, g_direct_equal); gencode(dfw, dfw->st_root); dfw_append_insn(dfw, dfvm_insn_new(RETURN)); } + + +typedef struct { + int i; + int *fields; +} hash_key_iterator; + +static void +get_hash_key(gpointer key, gpointer value, gpointer user_data) +{ + int field_id = GPOINTER_TO_INT(key); + hash_key_iterator *hki = user_data; + + hki->fields[hki->i] = field_id; + hki->i++; +} + +int* +dfw_interesting_fields(dfwork_t *dfw, int *caller_num_fields) +{ + int num_fields = g_hash_table_size(dfw->interesting_fields); + + hash_key_iterator hki; + + if (num_fields == 0) { + *caller_num_fields = 0; + return NULL; + } + + hki.fields = g_new(int, num_fields); + hki.i = 0; + + g_hash_table_foreach(dfw->interesting_fields, get_hash_key, &hki); + *caller_num_fields = num_fields; + return hki.fields; +} diff --git a/epan/dfilter/gencode.h b/epan/dfilter/gencode.h index db56b9082c..2148b2be58 100644 --- a/epan/dfilter/gencode.h +++ b/epan/dfilter/gencode.h @@ -4,4 +4,7 @@ void dfw_gencode(dfwork_t *dfw); +int* +dfw_interesting_fields(dfwork_t *dfw, int *caller_num_fields); + #endif diff --git a/epan/dfilter/semcheck.c b/epan/dfilter/semcheck.c index 025d471baa..5afb7b6b0a 100644 --- a/epan/dfilter/semcheck.c +++ b/epan/dfilter/semcheck.c @@ -1,5 +1,5 @@ /* - * $Id: semcheck.c,v 1.6 2001/11/02 10:09:49 guy Exp $ + * $Id: semcheck.c,v 1.7 2001/12/18 19:09:06 gram Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@ethereal.com> @@ -32,6 +32,7 @@ #include "sttype-test.h" #include "exceptions.h" +#include "packet.h" static void semcheck(dfwork_t *dfw, stnode_t *st_node); |