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/emem.h>
|
||||||
#include <epan/uat.h>
|
#include <epan/uat.h>
|
||||||
#include <epan/report_err.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 uat_t* dfilter_macro_uat = NULL;
|
||||||
static dfilter_macro_t* macros = NULL;
|
static dfilter_macro_t* macros = NULL;
|
||||||
static guint num_macros;
|
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) {
|
void dfilter_macro_foreach(dfilter_macro_cb_t cb, void* data) {
|
||||||
guint i;
|
guint i;
|
||||||
|
@ -101,6 +146,7 @@ static gchar* dfilter_macro_resolve(gchar* name, gchar** args, const gchar** err
|
||||||
GString* text;
|
GString* text;
|
||||||
int argc = 0;
|
int argc = 0;
|
||||||
dfilter_macro_t* m = NULL;
|
dfilter_macro_t* m = NULL;
|
||||||
|
fvt_cache_entry_t* e;
|
||||||
int* arg_pos_p;
|
int* arg_pos_p;
|
||||||
gchar** parts;
|
gchar** parts;
|
||||||
gchar* ret;
|
gchar* ret;
|
||||||
|
@ -115,9 +161,18 @@ static gchar* dfilter_macro_resolve(gchar* name, gchar** args, const gchar** err
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m) {
|
if (!m) {
|
||||||
|
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);
|
*error = ep_strdup_printf("macro '%s' does not exist", name);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (args) {
|
if (args) {
|
||||||
while(args[argc]) argc++;
|
while(args[argc]) argc++;
|
||||||
|
@ -221,7 +276,7 @@ gchar* dfilter_macro_apply(const gchar* text, guint depth, const gchar** error)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
} case NAME: {
|
} case NAME: {
|
||||||
if ( isalnum((guchar)c) || c == '_' ) {
|
if ( isalnum((int)c) || c == '_' || c == '-' || c == '.' ) {
|
||||||
g_string_append_c(name,c);
|
g_string_append_c(name,c);
|
||||||
} else if ( c == ':') {
|
} else if ( c == ':') {
|
||||||
state = ARGS;
|
state = ARGS;
|
||||||
|
@ -482,8 +537,14 @@ void dfilter_macro_init(void) {
|
||||||
macro_update,
|
macro_update,
|
||||||
macro_free,
|
macro_free,
|
||||||
uat_fields);
|
uat_fields);
|
||||||
|
|
||||||
|
fvt_cache = g_hash_table_new(g_str_hash,g_str_equal);
|
||||||
}
|
}
|
||||||
|
|
||||||
void dfilter_macro_get_uat(void** p) {
|
void dfilter_macro_get_uat(void** p) {
|
||||||
*p = dfilter_macro_uat;
|
*p = dfilter_macro_uat;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -54,4 +54,6 @@ void dfilter_macro_init(void);
|
||||||
|
|
||||||
void dfilter_macro_get_uat(void**);
|
void dfilter_macro_get_uat(void**);
|
||||||
|
|
||||||
|
void dfilter_macro_build_ftv_cache(void* tree_root);
|
||||||
|
|
||||||
#endif /* _DFILTER_MACRO_H */
|
#endif /* _DFILTER_MACRO_H */
|
||||||
|
|
|
@ -409,8 +409,6 @@ proto_cleanup(void)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef gboolean (*proto_tree_traverse_func)(proto_node *, gpointer);
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
proto_tree_traverse_pre_order(proto_tree *tree, proto_tree_traverse_func func,
|
proto_tree_traverse_pre_order(proto_tree *tree, proto_tree_traverse_func func,
|
||||||
gpointer data)
|
gpointer data)
|
||||||
|
@ -439,7 +437,7 @@ proto_tree_traverse_pre_order(proto_tree *tree, proto_tree_traverse_func func,
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
gboolean
|
||||||
proto_tree_traverse_in_order(proto_tree *tree, proto_tree_traverse_func func,
|
proto_tree_traverse_in_order(proto_tree *tree, proto_tree_traverse_func func,
|
||||||
gpointer data)
|
gpointer data)
|
||||||
{
|
{
|
||||||
|
|
|
@ -317,7 +317,10 @@ typedef proto_node proto_item;
|
||||||
((proto_item) ? FI_SET_FLAG((proto_item)->finfo, FI_URL) : 0)
|
((proto_item) ? FI_SET_FLAG((proto_item)->finfo, FI_URL) : 0)
|
||||||
|
|
||||||
typedef void (*proto_tree_foreach_func)(proto_node *, gpointer);
|
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,
|
extern void proto_tree_children_foreach(proto_tree *tree,
|
||||||
proto_tree_foreach_func func, gpointer data);
|
proto_tree_foreach_func func, gpointer data);
|
||||||
|
|
||||||
|
|
3
file.c
3
file.c
|
@ -75,6 +75,7 @@
|
||||||
#include <epan/dissectors/packet-data.h>
|
#include <epan/dissectors/packet-data.h>
|
||||||
#include <epan/dissectors/packet-ber.h>
|
#include <epan/dissectors/packet-ber.h>
|
||||||
#include <epan/timestamp.h>
|
#include <epan/timestamp.h>
|
||||||
|
#include <epan/dfilter/dfilter-macro.h>
|
||||||
#include "file_util.h"
|
#include "file_util.h"
|
||||||
|
|
||||||
|
|
||||||
|
@ -3252,6 +3253,8 @@ cf_select_packet(capture_file *cf, int row)
|
||||||
epan_dissect_run(cf->edt, &cf->pseudo_header, cf->pd, cf->current_frame,
|
epan_dissect_run(cf->edt, &cf->pseudo_header, cf->pd, cf->current_frame,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
|
dfilter_macro_build_ftv_cache(cf->edt->tree);
|
||||||
|
|
||||||
cf_callback_invoke(cf_cb_packet_selected, cf);
|
cf_callback_invoke(cf_cb_packet_selected, cf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue