2 * $Id: dfilter.c,v 1.9 2002/04/29 07:55:32 guy Exp $
4 * Ethereal - Network traffic analyzer
5 * By Gerald Combs <gerald@ethereal.com>
6 * Copyright 2001 Gerald Combs
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
30 #ifdef NEED_SNPRINTF_H
34 #include "dfilter-int.h"
35 #include "syntax-tree.h"
39 #include <epan/epan_dissect.h>
41 #define DFILTER_TOKEN_ID_OFFSET 1
43 /* Global error message space for dfilter_compile errors */
44 static gchar dfilter_error_msg_buf[1024];
45 gchar *dfilter_error_msg; /* NULL when no error resulted */
48 extern int hf_text_only;
51 void df_scanner_text(const char *text);
52 void df_scanner_file(FILE *fh);
53 void df_scanner_cleanup(void);
56 /* Holds the singular instance of our Lemon parser object */
57 static void* ParserObj = NULL;
60 dfilter_fail(char *format, ...)
64 /* If we've already reported one error, don't overwite it */
65 if (dfilter_error_msg != NULL)
68 va_start(args, format);
70 vsnprintf(dfilter_error_msg_buf, sizeof(dfilter_error_msg_buf),
72 dfilter_error_msg = dfilter_error_msg_buf;
77 /* Initialize the dfilter module */
82 g_message("I expected ParserObj to be NULL\n");
83 /* Free the Lemon Parser object */
84 DfilterFree(ParserObj, g_free);
86 /* Allocate an instance of our Lemon-based parser */
87 ParserObj = DfilterAlloc(g_malloc);
89 /* Initialize the syntax-tree sub-sub-system */
93 /* Clean-up the dfilter module */
97 /* Free the Lemon Parser object */
99 DfilterFree(ParserObj, g_free);
102 /* Clean up the syntax-tree sub-sub-system */
111 df = g_new(dfilter_t, 1);
117 /* Given a GPtrArray of instructions (dfvm_insn_t),
120 free_insns(GPtrArray *insns)
125 for (i = 0; i < insns->len; i++) {
126 insn = g_ptr_array_index(insns, i);
127 dfvm_insn_free(insn);
132 dfilter_free(dfilter_t *df)
135 free_insns(df->insns);
138 if (df->interesting_fields) {
139 g_free(df->interesting_fields);
142 g_free(df->registers);
143 g_free(df->attempted_load);
153 dfw = g_new(dfwork_t, 1);
156 dfw->syntax_error = FALSE;
158 dfw->loaded_fields = NULL;
159 dfw->interesting_fields = NULL;
160 dfw->next_insn_id = 0;
161 dfw->next_register = 0;
167 dfwork_free(dfwork_t *dfw)
170 stnode_free(dfw->st_root);
173 if (dfw->loaded_fields) {
174 g_hash_table_destroy(dfw->loaded_fields);
177 if (dfw->interesting_fields) {
178 g_hash_table_destroy(dfw->interesting_fields);
182 free_insns(dfw->insns);
191 dfilter_compile(gchar *text, dfilter_t **dfp)
197 dfilter_error_msg = NULL;
201 df_scanner_text(text);
204 df_lval = stnode_new(STTYPE_UNINITIALIZED, NULL);
207 /* Check for end-of-input */
209 /* Tell the parser that we have reached the end of input */
210 Dfilter(ParserObj, 0, NULL, dfw);
212 /* Free the stnode_t that we just generated, since
213 * the parser doesn't know about it and won't free it
215 stnode_free(df_lval);
220 /* Give the token to the parser */
221 Dfilter(ParserObj, token, df_lval, dfw);
223 if (dfw->syntax_error) {
228 /* One last check for syntax error (after EOF) */
229 if (dfw->syntax_error) {
234 /* Success, but was it an empty filter? If so, discard
235 * it and set *dfp to NULL */
236 if (dfw->st_root == NULL) {
241 /* Check semantics and do necessary type conversion*/
242 if (!dfw_semcheck(dfw)) {
246 /* Create bytecode */
249 /* Tuck away the bytecode in the dfilter_t */
250 dfilter = dfilter_new();
251 dfilter->insns = dfw->insns;
253 dfilter->interesting_fields = dfw_interesting_fields(dfw,
254 &dfilter->num_interesting_fields);
256 /* Initialize run-time space */
257 dfilter->num_registers = dfw->next_register;
258 dfilter->registers = g_new0(GList*, dfilter->num_registers);
259 dfilter->attempted_load = g_new0(gboolean, dfilter->num_registers);
261 /* And give it to the user. */
268 df_scanner_cleanup();
276 dfilter_fail("Unable to parse filter string \"%s\".", text);
280 df_scanner_cleanup();
287 dfilter_apply(dfilter_t *df, tvbuff_t *tvb, proto_tree *tree)
289 return dfvm_apply(df, tvb, tree);
293 dfilter_apply_edt(dfilter_t *df, epan_dissect_t* edt)
295 return dfvm_apply(df, edt->tvb, edt->tree);
300 dfilter_foreach_interesting_field(dfilter_t *df, GFunc func,
305 for (i = 0; i < df->num_interesting_fields; i++) {
306 func(GINT_TO_POINTER(df->interesting_fields[i]), user_data);
312 dfilter_dump(dfilter_t *df)
314 dfvm_dump(stdout, df->insns);