forked from osmocom/wireshark
epan: Add the ability to add conversation filter protocols.
Convert our conversation protocols to a dynamic list and add add_conversation_filter_protocol(). Use it in the Falco Bridge plugin to add protocols with conversation filters.
This commit is contained in:
parent
f6061c4a3c
commit
87b0288b8d
|
@ -20,6 +20,19 @@
|
|||
GList *packet_conv_filter_list = NULL;
|
||||
GList *log_conv_filter_list = NULL;
|
||||
|
||||
static GSList *conversation_proto_names = NULL;
|
||||
|
||||
void conversation_filters_init(void)
|
||||
{
|
||||
// add_conversation_filter_protocol prepends entries to the list. Add
|
||||
// lower layers first so that upper-layer conversations take precedence.
|
||||
add_conversation_filter_protocol("eth");
|
||||
add_conversation_filter_protocol("ipv6");
|
||||
add_conversation_filter_protocol("ip");
|
||||
add_conversation_filter_protocol("udp");
|
||||
add_conversation_filter_protocol("tcp");
|
||||
}
|
||||
|
||||
static void do_register_conversation_filter(GList **conv_filter_list, const char *proto_name, const char *display_name,
|
||||
is_filter_valid_func is_filter_valid, build_filter_string_func build_filter_string) {
|
||||
conversation_filter_t *entry;
|
||||
|
@ -52,6 +65,16 @@ void register_log_conversation_filter(const char *proto_name, const char *displa
|
|||
build_filter_string);
|
||||
}
|
||||
|
||||
void add_conversation_filter_protocol(const char *proto_name)
|
||||
{
|
||||
for (GSList *cur_entry = conversation_proto_names; cur_entry; cur_entry = g_slist_next(cur_entry)) {
|
||||
if (strcmp(proto_name, cur_entry->data) == 0) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
conversation_proto_names = g_slist_prepend(conversation_proto_names, (void *)proto_name);
|
||||
}
|
||||
|
||||
static struct conversation_filter_s* find_conversation_filter(GList *conv_filter_list, const char *name)
|
||||
{
|
||||
GList *list_entry = conv_filter_list;
|
||||
|
@ -79,17 +102,17 @@ void conversation_filters_cleanup(void)
|
|||
g_list_free(packet_conv_filter_list);
|
||||
g_list_foreach(log_conv_filter_list, conversation_filter_free, NULL);
|
||||
g_list_free(log_conv_filter_list);
|
||||
|
||||
g_slist_free(conversation_proto_names);
|
||||
}
|
||||
|
||||
static gchar *conversation_filter_from_pinfo(GList *conv_filter_list, struct _packet_info *pinfo)
|
||||
{
|
||||
const char *layers[] = { "tcp", "udp", "ip", "ipv6", "eth" };
|
||||
conversation_filter_t *conv_filter;
|
||||
gchar *filter;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS(layers); i++) {
|
||||
conv_filter = find_conversation_filter(conv_filter_list, layers[i]);
|
||||
for (GSList *cur_entry = conversation_proto_names; cur_entry; cur_entry = g_slist_next(cur_entry)) {
|
||||
conv_filter = find_conversation_filter(conv_filter_list, (const char *) cur_entry->data);
|
||||
if (conv_filter && conv_filter->is_filter_valid(pinfo)) {
|
||||
if ((filter = conv_filter->build_filter_string(pinfo)) != NULL)
|
||||
return filter;
|
||||
|
|
|
@ -21,6 +21,9 @@ extern "C" {
|
|||
/** @file
|
||||
*/
|
||||
|
||||
/** Initialize internal structures */
|
||||
extern void conversation_filters_init(void);
|
||||
|
||||
/** callback function definition: is a filter available for this packet? */
|
||||
typedef gboolean (*is_filter_valid_func)(struct _packet_info *pinfo);
|
||||
|
||||
|
@ -35,8 +38,13 @@ WS_DLL_PUBLIC void register_conversation_filter(const char *proto_name, const ch
|
|||
/** register a dissector filter for logs */
|
||||
WS_DLL_PUBLIC void register_log_conversation_filter(const char *proto_name, const char *display_name,
|
||||
is_filter_valid_func is_filter_valid, build_filter_string_func build_filter_string);
|
||||
/**
|
||||
* Prepend a protocol to the list of filterable protocols.
|
||||
* @param A valid protocol name.
|
||||
*/
|
||||
WS_DLL_PUBLIC void add_conversation_filter_protocol(const char *proto_name);
|
||||
|
||||
/* Cleanup internal structures */
|
||||
/** Cleanup internal structures */
|
||||
extern void conversation_filters_cleanup(void);
|
||||
|
||||
/**
|
||||
|
|
|
@ -302,6 +302,7 @@ epan_init(register_cb cb, gpointer client_data, gboolean load_plugins)
|
|||
conversation_init();
|
||||
capture_dissector_init();
|
||||
reassembly_tables_init();
|
||||
conversation_filters_init();
|
||||
g_slist_foreach(epan_plugins, epan_plugin_init, NULL);
|
||||
proto_init(epan_plugin_register_all_procotols, epan_plugin_register_all_handoffs, cb, client_data);
|
||||
g_slist_foreach(epan_plugins, epan_plugin_register_all_tap_listeners, NULL);
|
||||
|
|
|
@ -22,6 +22,7 @@ libwireshark.so.0 libwireshark0 #MINVER#
|
|||
abs_time_secs_to_str_ex@Base 3.7.0
|
||||
abs_time_to_str_ex@Base 3.7.0
|
||||
add_ber_encoded_label@Base 3.7.0
|
||||
add_conversation_filter_protocol@Base 3.7.0
|
||||
add_conversation_table_data@Base 2.5.0
|
||||
add_conversation_table_data_with_conv_id@Base 2.5.0
|
||||
add_hostlist_table_data@Base 2.5.0
|
||||
|
|
|
@ -123,7 +123,6 @@ static conv_fld_info conv_fld_infos[MAX_N_CONV_FILTERS];
|
|||
DECLARE_CONV_FLTS()
|
||||
static char conv_flt_vals[MAX_N_CONV_FILTERS][MAX_CONV_FILTER_STR_LEN];
|
||||
static guint conv_vals_cnt = 0;
|
||||
static guint conv_fld_cnt = 0;
|
||||
|
||||
void
|
||||
register_conversation_filters_mappings(void)
|
||||
|
@ -161,6 +160,8 @@ configure_plugin(bridge_info* bi, char* config _U_)
|
|||
bi->field_flags = (guint32*)wmem_alloc(wmem_epan_scope(), bi->visible_fields * sizeof(guint32));
|
||||
|
||||
uint32_t fld_cnt = 0;
|
||||
size_t conv_fld_cnt = 0;
|
||||
|
||||
for (uint32_t j = 0; j < tot_fields; j++)
|
||||
{
|
||||
bi->hf_ids[fld_cnt] = -1;
|
||||
|
@ -227,13 +228,16 @@ configure_plugin(bridge_info* bi, char* config _U_)
|
|||
conv_fld_infos[conv_fld_cnt].field_info = ri;
|
||||
const char *source_name = get_sinsp_source_name(bi->ssi);
|
||||
conv_fld_infos[conv_fld_cnt].proto_name = source_name;
|
||||
// XXX We currently build a filter per field. Should we "and" them instead?
|
||||
register_log_conversation_filter(source_name, finfo.hfinfo.name, fv_func[conv_fld_cnt], bfs_func[conv_fld_cnt]);
|
||||
conv_fld_cnt++;
|
||||
}
|
||||
fld_cnt++;
|
||||
}
|
||||
proto_register_field_array(proto_falco_bridge, bi->hf, fld_cnt);
|
||||
|
||||
if (conv_fld_cnt > 0) {
|
||||
add_conversation_filter_protocol(get_sinsp_source_name(bi->ssi));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2493,7 +2493,7 @@ void LogwolfMainWindow::colorizeConversation(bool create_rule)
|
|||
if (capture_file_.capFile() && selectedRows().count() > 0) {
|
||||
packet_info *pi = capture_file_.packetInfo();
|
||||
guint8 cc_num = colorize_action->data().toUInt();
|
||||
gchar *filter = conversation_filter_from_packet(pi);
|
||||
gchar *filter = conversation_filter_from_log(pi);
|
||||
if (filter == NULL) {
|
||||
mainApp->pushStatus(WiresharkApplication::TemporaryStatus, tr("Unable to build conversation filter."));
|
||||
return;
|
||||
|
|
Loading…
Reference in New Issue