As per Ulf's request add ${proto.field} macros that will use the value of the given field has in the last selected packet.

svn path=/trunk/; revision=22427
This commit is contained in:
Luis Ontanon 2007-07-30 23:32:47 +00:00
parent c1c9e0bb90
commit 9865b6346f
5 changed files with 74 additions and 7 deletions

View File

@ -37,10 +37,55 @@
#include <epan/emem.h>
#include <epan/uat.h>
#include <epan/report_err.h>
#include <epan/proto.h>
typedef struct {
const char* name;
gboolean usable;
char* repr;
} fvt_cache_entry_t;
static uat_t* dfilter_macro_uat = NULL;
static dfilter_macro_t* macros = NULL;
static guint num_macros;
static GHashTable* fvt_cache = NULL;
static gboolean free_value(gpointer k _U_, gpointer v, gpointer u _U_) {
fvt_cache_entry_t* e = v;
if (e->repr) g_free(e->repr);
g_free(e);
return TRUE;
}
static gboolean fvt_cache_cb(proto_node * node, gpointer data _U_) {
field_info* finfo = node->finfo;
fvt_cache_entry_t* e;
if (!finfo) return FALSE;
if ((e = g_hash_table_lookup(fvt_cache,finfo->hfinfo->abbrev))) {
e->usable = FALSE;
} else if (finfo->value.ftype->val_to_string_repr) {
switch (finfo->hfinfo->type) {
case FT_NONE:
case FT_PROTOCOL:
return FALSE;
default:
break;
}
e = g_malloc(sizeof(fvt_cache_entry_t));
e->name = finfo->hfinfo->abbrev,
e->repr = fvalue_to_string_repr(&(finfo->value), FTREPR_DFILTER, NULL);
e->usable = TRUE;
g_hash_table_insert(fvt_cache,(void*)finfo->hfinfo->abbrev,e);
}
return FALSE;
}
void dfilter_macro_build_ftv_cache(void* tree_root) {
g_hash_table_foreach_remove(fvt_cache,free_value,NULL);
proto_tree_traverse_in_order(tree_root, fvt_cache_cb, NULL);
}
void dfilter_macro_foreach(dfilter_macro_cb_t cb, void* data) {
guint i;
@ -101,6 +146,7 @@ static gchar* dfilter_macro_resolve(gchar* name, gchar** args, const gchar** err
GString* text;
int argc = 0;
dfilter_macro_t* m = NULL;
fvt_cache_entry_t* e;
int* arg_pos_p;
gchar** parts;
gchar* ret;
@ -115,8 +161,17 @@ static gchar* dfilter_macro_resolve(gchar* name, gchar** args, const gchar** err
}
if (!m) {
*error = ep_strdup_printf("macro '%s' does not exist", name);
return NULL;
if (fvt_cache && (e = g_hash_table_lookup(fvt_cache,name) )) {
if(e->usable) {
return e->repr;
} else {
*error = ep_strdup_printf("macro '%s' is unusable", name);
return NULL;
}
} else {
*error = ep_strdup_printf("macro '%s' does not exist", name);
return NULL;
}
}
if (args) {
@ -221,7 +276,7 @@ gchar* dfilter_macro_apply(const gchar* text, guint depth, const gchar** error)
}
break;
} case NAME: {
if ( isalnum((guchar)c) || c == '_' ) {
if ( isalnum((int)c) || c == '_' || c == '-' || c == '.' ) {
g_string_append_c(name,c);
} else if ( c == ':') {
state = ARGS;
@ -482,8 +537,14 @@ void dfilter_macro_init(void) {
macro_update,
macro_free,
uat_fields);
fvt_cache = g_hash_table_new(g_str_hash,g_str_equal);
}
void dfilter_macro_get_uat(void** p) {
*p = dfilter_macro_uat;
}

View File

@ -54,4 +54,6 @@ void dfilter_macro_init(void);
void dfilter_macro_get_uat(void**);
void dfilter_macro_build_ftv_cache(void* tree_root);
#endif /* _DFILTER_MACRO_H */

View File

@ -409,8 +409,6 @@ proto_cleanup(void)
}
typedef gboolean (*proto_tree_traverse_func)(proto_node *, gpointer);
static gboolean
proto_tree_traverse_pre_order(proto_tree *tree, proto_tree_traverse_func func,
gpointer data)
@ -439,7 +437,7 @@ proto_tree_traverse_pre_order(proto_tree *tree, proto_tree_traverse_func func,
return FALSE;
}
static gboolean
gboolean
proto_tree_traverse_in_order(proto_tree *tree, proto_tree_traverse_func func,
gpointer data)
{

View File

@ -317,7 +317,10 @@ typedef proto_node proto_item;
((proto_item) ? FI_SET_FLAG((proto_item)->finfo, FI_URL) : 0)
typedef void (*proto_tree_foreach_func)(proto_node *, gpointer);
typedef gboolean (*proto_tree_traverse_func)(proto_node *, gpointer);
extern gboolean proto_tree_traverse_in_order(proto_tree *tree,
proto_tree_traverse_func func, gpointer data);
extern void proto_tree_children_foreach(proto_tree *tree,
proto_tree_foreach_func func, gpointer data);

5
file.c
View File

@ -75,6 +75,7 @@
#include <epan/dissectors/packet-data.h>
#include <epan/dissectors/packet-ber.h>
#include <epan/timestamp.h>
#include <epan/dfilter/dfilter-macro.h>
#include "file_util.h"
@ -3251,7 +3252,9 @@ cf_select_packet(capture_file *cf, int row)
epan_dissect_run(cf->edt, &cf->pseudo_header, cf->pd, cf->current_frame,
NULL);
dfilter_macro_build_ftv_cache(cf->edt->tree);
cf_callback_invoke(cf_cb_packet_selected, cf);
}