aboutsummaryrefslogtreecommitdiffstats
path: root/epan/conversation_filter.c
diff options
context:
space:
mode:
Diffstat (limited to 'epan/conversation_filter.c')
-rw-r--r--epan/conversation_filter.c84
1 files changed, 70 insertions, 14 deletions
diff --git a/epan/conversation_filter.c b/epan/conversation_filter.c
index 4379c70daa..58d776b39c 100644
--- a/epan/conversation_filter.c
+++ b/epan/conversation_filter.c
@@ -17,11 +17,24 @@
#include "conversation_filter.h"
-GList *conv_filter_list = NULL;
+GList *packet_conv_filter_list = NULL;
+GList *log_conv_filter_list = NULL;
+static GSList *conversation_proto_names = NULL;
-void register_conversation_filter(const char *proto_name, const char *display_name,
- is_filter_valid_func is_filter_valid, build_filter_string_func build_filter_string) {
+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, void *user_data) {
conversation_filter_t *entry;
entry = g_new(conversation_filter_t, 1);
@@ -30,11 +43,42 @@ void register_conversation_filter(const char *proto_name, const char *display_na
entry->display_name = display_name;
entry->is_filter_valid = is_filter_valid;
entry->build_filter_string = build_filter_string;
+ entry->user_data = user_data;
+
+ *conv_filter_list = g_list_append(*conv_filter_list, entry);
+}
- conv_filter_list = g_list_append(conv_filter_list, entry);
+void register_conversation_filter(const char *proto_name, const char *display_name,
+ is_filter_valid_func is_filter_valid, build_filter_string_func build_filter_string, void *user_data) {
+ do_register_conversation_filter(&packet_conv_filter_list,
+ proto_name,
+ display_name,
+ is_filter_valid,
+ build_filter_string,
+ user_data);
+}
+
+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, void *user_data) {
+ do_register_conversation_filter(&log_conv_filter_list,
+ proto_name,
+ display_name,
+ is_filter_valid,
+ build_filter_string,
+ user_data);
}
-struct conversation_filter_s* find_conversation_filter(const char *name)
+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;
conversation_filter_t* filter;
@@ -57,21 +101,23 @@ static void conversation_filter_free(gpointer p, gpointer user_data _U_)
void conversation_filters_cleanup(void)
{
- g_list_foreach(conv_filter_list, conversation_filter_free, NULL);
- g_list_free(conv_filter_list);
+ g_list_foreach(packet_conv_filter_list, conversation_filter_free, NULL);
+ 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);
}
-gchar *conversation_filter_from_packet(struct _packet_info *pinfo)
+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(layers[i]);
- if (conv_filter && conv_filter->is_filter_valid(pinfo)) {
- if ((filter = conv_filter->build_filter_string(pinfo)) != NULL)
+ 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, conv_filter->user_data)) {
+ if ((filter = conv_filter->build_filter_string(pinfo, conv_filter->user_data)) != NULL)
return filter;
}
}
@@ -79,6 +125,16 @@ gchar *conversation_filter_from_packet(struct _packet_info *pinfo)
return NULL;
}
+gchar *conversation_filter_from_packet(struct _packet_info *pinfo)
+{
+ return conversation_filter_from_pinfo(packet_conv_filter_list, pinfo);
+}
+
+gchar *conversation_filter_from_log(struct _packet_info *pinfo)
+{
+ return conversation_filter_from_pinfo(log_conv_filter_list, pinfo);
+}
+
/*
* Editor modelines - https://www.wireshark.org/tools/modelines.html
*