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:
parent
c1c9e0bb90
commit
9865b6346f
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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
5
file.c
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue