aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dfilter
diff options
context:
space:
mode:
authorGilbert Ramirez <gram@alumni.rice.edu>2001-12-18 19:09:08 +0000
committerGilbert Ramirez <gram@alumni.rice.edu>2001-12-18 19:09:08 +0000
commit791f5774d0fdabdb706bfd7056e534713cc4e4d6 (patch)
tree35f987f9914fead0fb5fefe79df280b7340831b4 /epan/dfilter
parent4e013a44de86f8146cfd7d440adb67366e37273a (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.h5
-rw-r--r--epan/dfilter/dfilter.c27
-rw-r--r--epan/dfilter/dfilter.h12
-rw-r--r--epan/dfilter/dfvm.c6
-rw-r--r--epan/dfilter/gencode.c50
-rw-r--r--epan/dfilter/gencode.h3
-rw-r--r--epan/dfilter/semcheck.c3
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);