diff options
Diffstat (limited to 'epan/conversation_filter.c')
-rw-r--r-- | epan/conversation_filter.c | 84 |
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 * |