⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dfilter.c

📁 ethereal公司开发的aodv路由协议代码
💻 C
字号:
/* * $Id: dfilter.c,v 1.7 2002/01/21 07:37:37 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@ethereal.com> * Copyright 2001 Gerald Combs *  * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. *  * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. *  * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. */#ifdef HAVE_CONFIG_H#include "config.h"#endif#include <stdio.h>#include <string.h>#ifdef NEED_SNPRINTF_H#include "snprintf.h"#endif#include "dfilter-int.h"#include "syntax-tree.h"#include "gencode.h"#include "semcheck.h"#include "dfvm.h"#include <epan/epan_dissect.h>/* Balanced tree of abbreviations and IDs */GTree *dfilter_tokens = NULL;#define DFILTER_TOKEN_ID_OFFSET	1/* Comparision function for tree insertion. A wrapper around strcmp() */static int g_strcmp(gconstpointer a, gconstpointer b);/* Global error message space for dfilter_compile errors */gchar dfilter_error_msg_buf[1024];gchar *dfilter_error_msg;	/* NULL when no error resulted *//* In proto.c */extern int hf_text_only;/* From scanner.c */void    df_scanner_text(const char *text);void    df_scanner_file(FILE *fh);void    df_scanner_cleanup(void);int     df_lex(void);/* Holds the singular instance of our Lemon parser object */void*		ParserObj = NULL;voiddfilter_fail(char *format, ...){	va_list	args;	/* If we've already reported one error, don't overwite it */	if (dfilter_error_msg != NULL)		return;	va_start(args, format);	vsnprintf(dfilter_error_msg_buf, sizeof(dfilter_error_msg_buf),			format, args);	dfilter_error_msg = dfilter_error_msg_buf;	va_end(args);}/* Initialize the dfilter module */voiddfilter_init(void){	int 			id, num_symbols;	char 			*abbrev;	header_field_info	*hfinfo, *same_name_hfinfo, *same_name_next_hfinfo;	num_symbols = proto_registrar_n();	if (dfilter_tokens) {		/* XXX - needed? */		g_message("I expected hf_ids to be NULL\n");		g_tree_destroy(dfilter_tokens);		/* Make sure the hfinfo->same_name links are broken */		for (id = 0; id < num_symbols; id++) {			hfinfo = proto_registrar_get_nth(id);			hfinfo->same_name_next = NULL;			hfinfo->same_name_prev = NULL;		}	}	dfilter_tokens = g_tree_new(g_strcmp);	/* Populate the abbrev/ID GTree (header-field symbol table) */		for (id = 0; id < num_symbols; id++) {		if (id == hf_text_only) {			continue;		}		abbrev = proto_registrar_get_abbrev(id);		hfinfo = proto_registrar_get_nth(id);		g_assert(abbrev);		/* Not Null */		g_assert(abbrev[0] != 0);	/* Not empty string */		/* We allow multiple hfinfo's to be registered under the same		 * abbreviation. This was done for X.25, as, depending		 * on whether it's modulo-8 or modulo-128 operation,		 * some bitfield fields may be in different bits of		 * a byte, and we want to be able to refer to that field		 * with one name regardless of whether the packets		 * are modulo-8 or modulo-128 packets. */		same_name_hfinfo = g_tree_lookup(dfilter_tokens, abbrev);		if (same_name_hfinfo) {			/* There's already a field with this name.			 * Put it after that field in the list of			 * fields with this name, then allow the code			 * after this if{} block to replace the old			 * hfinfo with the new hfinfo in the GTree. Thus,			 * we end up with a linked-list of same-named hfinfo's,			 * with the root of the list being the hfinfo in the GTree */			same_name_next_hfinfo =			    same_name_hfinfo->same_name_next;			hfinfo->same_name_next = same_name_next_hfinfo;			if (same_name_next_hfinfo)				same_name_next_hfinfo->same_name_prev = hfinfo;			same_name_hfinfo->same_name_next = hfinfo;			hfinfo->same_name_prev = same_name_hfinfo;		}		g_tree_insert(dfilter_tokens, abbrev, hfinfo);	}	if (ParserObj) {		g_message("I expected ParserObj to be NULL\n");		/* Free the Lemon Parser object */		DfilterFree(ParserObj, g_free);	}	/* Allocate an instance of our Lemon-based parser */	ParserObj = DfilterAlloc(g_malloc);	/* Initialize the syntax-tree sub-sub-system */	sttype_init();}/* Clean-up the dfilter module */voiddfilter_cleanup(void){	/* Free the abbrev/ID GTree */	if (dfilter_tokens) {		g_tree_destroy(dfilter_tokens);		dfilter_tokens = NULL;	}	/* Free the Lemon Parser object */	if (ParserObj) {		DfilterFree(ParserObj, g_free);	}	/* Clean up the syntax-tree sub-sub-system */	sttype_cleanup();}/* Lookup an abbreviation in our token tree, returing the ID # * If the abbreviation doesn't exit, returns -1 */header_field_info*dfilter_lookup_token(char *abbrev){	g_assert(abbrev != NULL);	return g_tree_lookup(dfilter_tokens, abbrev);}/* String comparison func for dfilter_token GTree */static intg_strcmp(gconstpointer a, gconstpointer b){	return strcmp((const char*)a, (const char*)b);}static dfilter_t*dfilter_new(void){	dfilter_t	*df;	df = g_new(dfilter_t, 1);	df->insns = NULL;	return df;}/* Given a GPtrArray of instructions (dfvm_insn_t), * free them. */static voidfree_insns(GPtrArray *insns){	unsigned int	i;	dfvm_insn_t	*insn;	for (i = 0; i < insns->len; i++) {		insn = g_ptr_array_index(insns, i);		dfvm_insn_free(insn);	}}voiddfilter_free(dfilter_t *df){	if (df->insns) {		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);}static dfwork_t*dfwork_new(void){	dfwork_t	*dfw;	dfw = g_new(dfwork_t, 1);	dfw->st_root = NULL;	dfw->syntax_error = FALSE;	dfw->insns = NULL;	dfw->loaded_fields = NULL;	dfw->interesting_fields = NULL;	dfw->next_insn_id = 0;	dfw->next_register = 0;	return dfw;}static voiddfwork_free(dfwork_t *dfw){	if (dfw->st_root) {		stnode_free(dfw->st_root);	}	if (dfw->loaded_fields) {		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);}gbooleandfilter_compile(gchar *text, dfilter_t **dfp){	int		token;	dfilter_t	*dfilter;	dfwork_t	*dfw;	dfilter_error_msg = NULL;	dfw = dfwork_new();	df_scanner_text(text);	while (1) {		df_lval = stnode_new(STTYPE_UNINITIALIZED, NULL);		token = df_lex();		/* Check for end-of-input */		if (token == 0) {			/* Tell the parser that we have reached the end of input */			Dfilter(ParserObj, 0, NULL, dfw);			/* Free the stnode_t that we just generated, since			 * the parser doesn't know about it and won't free it			 * for us. */			stnode_free(df_lval);			df_lval = NULL;			break;		}		/* Give the token to the parser */		Dfilter(ParserObj, token, df_lval, dfw);		if (dfw->syntax_error) {			break;		}	}	/* One last check for syntax error (after EOF) */	if (dfw->syntax_error) {		goto FAILURE;	}	/* Success, but was it an empty filter? If so, discard	 * it and set *dfp to NULL */	if (dfw->st_root == NULL) {		*dfp = NULL;	}	else {		/* Check semantics and do necessary type conversion*/		if (!dfw_semcheck(dfw)) {			goto FAILURE;		}		/* Create bytecode */		dfw_gencode(dfw);			/* Tuck away the bytecode in the dfilter_t */		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;		dfilter->registers = g_new0(GList*, dfilter->num_registers);		dfilter->attempted_load = g_new0(gboolean, dfilter->num_registers);		/* And give it to the user. */		*dfp = dfilter;	}	/* SUCCESS */	dfwork_free(dfw);	/* Reset flex */	df_scanner_cleanup();	return TRUE;FAILURE:	if (dfw) {		dfwork_free(dfw);	}	dfilter_fail("Unable to parse filter string \"%s\".", text);	*dfp = NULL;	/* Reset flex */	df_scanner_cleanup();	return FALSE;}gbooleandfilter_apply(dfilter_t *df, tvbuff_t *tvb, proto_tree *tree){	return dfvm_apply(df, tvb, tree);}gbooleandfilter_apply_edt(dfilter_t *df, epan_dissect_t* edt){	return dfvm_apply(df, edt->tvb, edt->tree);}voiddfilter_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);    }}                voiddfilter_dump(dfilter_t *df){	dfvm_dump(stdout, df->insns);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -