From a97176853010e5e39492d8a1fea79799ef43758b Mon Sep 17 00:00:00 2001 From: Michael Mann Date: Mon, 8 Dec 2014 21:40:24 -0500 Subject: [PATCH] Refactor "color" conversation filters Have dissectors register their desire to be part of "color" conversation filters and have the GUI use that registered list. GUI actually using API will come in a separate commit. Change-Id: I5ffe922d97894fe7bf3182056b76ab5839a9461a Reviewed-on: https://code.wireshark.org/review/5658 Reviewed-by: Michael Mann Petri-Dish: Michael Mann Reviewed-by: Anders Broman --- debian/libwireshark0.symbols | 3 ++ epan/CMakeLists.txt | 1 + epan/Makefile.common | 2 + epan/color_dissector_filters.c | 57 +++++++++++++++++++++++ epan/color_dissector_filters.h | 62 +++++++++++++++++++++++++ epan/dissectors/packet-eth.c | 14 ++++++ epan/dissectors/packet-ip.c | 16 +++++++ epan/dissectors/packet-ipv6.c | 16 +++++++ epan/dissectors/packet-tcp.c | 30 ++++++++++++ epan/dissectors/packet-udp.c | 31 +++++++++++++ epan/proto.c | 27 +++++++++++ epan/proto.h | 6 +++ plugins/profinet/packet-dcom-cba-acco.c | 49 +++++++++++++++++++ 13 files changed, 314 insertions(+) create mode 100644 epan/color_dissector_filters.c create mode 100644 epan/color_dissector_filters.h diff --git a/debian/libwireshark0.symbols b/debian/libwireshark0.symbols index c705f884d7..2fb2f4609b 100644 --- a/debian/libwireshark0.symbols +++ b/debian/libwireshark0.symbols @@ -142,6 +142,7 @@ libwireshark.so.0 libwireshark0 #MINVER# col_set_time@Base 1.9.1 col_set_writable@Base 1.9.1 col_setup@Base 1.9.1 + color_conv_filter_list@Base 1.99.1 column_dump_column_formats@Base 1.12.0~rc1 conversation_add_proto_data@Base 1.9.1 conversation_delete_proto_data@Base 1.9.1 @@ -900,6 +901,7 @@ libwireshark.so.0 libwireshark0 #MINVER# proto_initialize_all_prefixes@Base 1.9.1 proto_is_private@Base 1.9.1 proto_is_protocol_enabled@Base 1.9.1 + proto_is_frame_protocol@Base 1.99.1 proto_item_add_subtree@Base 1.9.1 proto_item_append_string@Base 1.9.1 proto_item_append_text@Base 1.9.1 @@ -1053,6 +1055,7 @@ libwireshark.so.0 libwireshark0 #MINVER# register_ber_oid_syntax@Base 1.9.1 register_ber_syntax_dissector@Base 1.9.1 register_count@Base 1.9.1 + register_color_conversation_filter@Base 1.99.1 register_decode_as@Base 1.12.0~rc1 register_dissector@Base 1.9.1 register_dissector_filter@Base 1.9.1 diff --git a/epan/CMakeLists.txt b/epan/CMakeLists.txt index 8f00aca32a..3e46510db6 100644 --- a/epan/CMakeLists.txt +++ b/epan/CMakeLists.txt @@ -1549,6 +1549,7 @@ set(LIBWIRESHARK_FILES circuit.c column.c column-utils.c + color_dissector_filters.c conversation.c conversation_table.c crc10-tvb.c diff --git a/epan/Makefile.common b/epan/Makefile.common index 7d193a40d4..575a2884d4 100644 --- a/epan/Makefile.common +++ b/epan/Makefile.common @@ -32,6 +32,7 @@ LIBWIRESHARK_SRC = \ atalk-utils.c \ charsets.c \ circuit.c \ + color_dissector_filters.c \ column.c \ column-utils.c \ conversation.c \ @@ -162,6 +163,7 @@ LIBWIRESHARK_INCLUDES = \ charsets.h \ chdlctypes.h \ circuit.h \ + color_dissector_filters.h \ column.h \ column-info.h \ column-utils.h \ diff --git a/epan/color_dissector_filters.c b/epan/color_dissector_filters.c new file mode 100644 index 0000000000..4f6f07492f --- /dev/null +++ b/epan/color_dissector_filters.c @@ -0,0 +1,57 @@ +/* color_dissector_filters.c + * Routines for dissector generated display filters + * + * Wireshark - Network traffic analyzer + * By Gerald Combs + * Copyright 1998 Gerald Combs + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "config.h" + +#include +#include "packet.h" + +#include "color_dissector_filters.h" + + +GList *color_conv_filter_list = NULL; + + +void register_color_conversation_filter(const char *name, is_color_conv_valid_func is_filter_valid, build_color_conv_string_func build_filter_string) { + color_conversation_filter_t *entry; + + entry = (color_conversation_filter_t *)g_malloc(sizeof(color_conversation_filter_t)); + + entry->name = name; + entry->is_filter_valid = is_filter_valid; + entry->build_filter_string = build_filter_string; + + color_conv_filter_list = g_list_append(color_conv_filter_list, entry); +} + +/* + * Editor modelines - http://www.wireshark.org/tools/modelines.html + * + * Local variables: + * c-basic-offset: 4 + * tab-width: 8 + * indent-tabs-mode: nil + * End: + * + * vi: set shiftwidth=4 tabstop=8 expandtab: + * :indentSize=4:tabSize=8:noTabs=true: + */ diff --git a/epan/color_dissector_filters.h b/epan/color_dissector_filters.h new file mode 100644 index 0000000000..2393700ee7 --- /dev/null +++ b/epan/color_dissector_filters.h @@ -0,0 +1,62 @@ +/* color_dissector_filters.h + * Routines for dissector generated colorized conversation filters + * + * Wireshark - Network traffic analyzer + * By Gerald Combs + * Copyright 1998 Gerald Combs + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef __COLOR_DISSECTOR_FILTERS_H__ +#define __COLOR_DISSECTOR_FILTERS_H__ + +#include "ws_symbol_export.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** @file + */ + +/** callback function definition: is a filter available for this packet? */ +typedef gboolean (*is_color_conv_valid_func)(packet_info *pinfo); + +/** callback function definition: return the available filter for this packet or NULL if no filter is available, + Filter needs to be freed after use */ +typedef gchar* (*build_color_conv_string_func)(packet_info *pinfo); + + +/** register a dissector filter */ +WS_DLL_PUBLIC void register_color_conversation_filter(const char *name, is_color_conv_valid_func is_filter_valid, build_color_conv_string_func build_filter_string); + + + +/*** THE FOLLOWING SHOULD NOT BE USED BY ANY DISSECTORS!!! ***/ + +typedef struct color_conversation_filter_s { + const char * name; + is_color_conv_valid_func is_filter_valid; + build_color_conv_string_func build_filter_string; +} color_conversation_filter_t; + +WS_DLL_PUBLIC GList *color_conv_filter_list; + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* color_dissector_filters.h */ diff --git a/epan/dissectors/packet-eth.c b/epan/dissectors/packet-eth.c index 11c97bbe77..c038062202 100644 --- a/epan/dissectors/packet-eth.c +++ b/epan/dissectors/packet-eth.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include "packet-eth.h" #include "packet-ieee8023.h" @@ -163,7 +164,19 @@ eth_hostlist_packet(void *pit, packet_info *pinfo, epan_dissect_t *edt _U_, cons return 1; } +static gboolean +eth_color_filter_valid(packet_info *pinfo) +{ + return (pinfo->dl_src.type == AT_ETHER); +} +static gchar* +eth_build_color_filter(packet_info *pinfo) +{ + return g_strdup_printf("eth.addr eq %s and eth.addr eq %s", + ether_to_str( (const guint8 *)pinfo->dl_src.data), + ether_to_str( (const guint8 *)pinfo->dl_dst.data)); +} /* These are the Netware-ish names for the different Ethernet frame types. @@ -1003,6 +1016,7 @@ proto_register_eth(void) eth_tap = register_tap("eth"); register_conversation_table(proto_eth, TRUE, eth_conversation_packet, eth_hostlist_packet, NULL); + register_color_conversation_filter("Ethernet", eth_color_filter_valid, eth_build_color_filter); } void diff --git a/epan/dissectors/packet-ip.c b/epan/dissectors/packet-ip.c index c34eddb7cd..2dd884141d 100644 --- a/epan/dissectors/packet-ip.c +++ b/epan/dissectors/packet-ip.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -542,6 +543,20 @@ ip_hostlist_packet(void *pit, packet_info *pinfo, epan_dissect_t *edt _U_, const return 1; } +static gboolean +ip_color_filter_valid(packet_info *pinfo) +{ + return proto_is_frame_protocol(pinfo->layers, "ip"); +} + +static gchar* +ip_build_color_filter(packet_info *pinfo) +{ + return g_strdup_printf("ip.addr eq %s and ip.addr eq %s", + ip_to_str( (const guint8 *)pinfo->net_src.data), + ip_to_str( (const guint8 *)pinfo->net_dst.data)); +} + /* * defragmentation of IPv4 */ @@ -3079,6 +3094,7 @@ proto_register_ip(void) register_decode_as(&ip_da); register_conversation_table(proto_ip, TRUE, ip_conversation_packet, ip_hostlist_packet, NULL); + register_color_conversation_filter("IPv4", ip_color_filter_valid, ip_build_color_filter); } void diff --git a/epan/dissectors/packet-ipv6.c b/epan/dissectors/packet-ipv6.c index 9dad84d6d0..06374589a6 100644 --- a/epan/dissectors/packet-ipv6.c +++ b/epan/dissectors/packet-ipv6.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -426,6 +427,20 @@ ipv6_hostlist_packet(void *pit, packet_info *pinfo, epan_dissect_t *edt _U_, con return 1; } +static gboolean +ipv6_color_filter_valid(packet_info *pinfo) +{ + return proto_is_frame_protocol(pinfo->layers, "ipv6"); +} + +static gchar* +ipv6_build_color_filter(packet_info *pinfo) +{ + return g_strdup_printf("ipv6.addr eq %s and ipv6.addr eq %s", + ip6_to_str((const struct e_in6_addr *)pinfo->net_src.data), + ip6_to_str((const struct e_in6_addr *)pinfo->net_dst.data)); +} + static const fragment_items ipv6_frag_items = { &ett_ipv6_fragment, &ett_ipv6_fragments, @@ -3016,6 +3031,7 @@ proto_register_ipv6(void) register_decode_as(&ipv6_next_header_da); register_conversation_table(proto_ipv6, TRUE, ipv6_conversation_packet, ipv6_hostlist_packet, NULL); + register_color_conversation_filter("IPv6", ipv6_color_filter_valid, ipv6_build_color_filter); } void diff --git a/epan/dissectors/packet-tcp.c b/epan/dissectors/packet-tcp.c index 57dfb81c55..0668b4542f 100644 --- a/epan/dissectors/packet-tcp.c +++ b/epan/dissectors/packet-tcp.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -632,6 +633,34 @@ tcpip_hostlist_prefix(void) return "endpoints"; } +static gboolean +tcp_color_filter_valid(packet_info *pinfo) +{ + return proto_is_frame_protocol(pinfo->layers, "tcp"); +} + +static gchar* +tcp_build_color_filter(packet_info *pinfo) +{ + if( pinfo->net_src.type == AT_IPv4 && pinfo->net_dst.type == AT_IPv4 ) { + /* TCP over IPv4 */ + return g_strdup_printf("(ip.addr eq %s and ip.addr eq %s) and (tcp.port eq %d and tcp.port eq %d)", + ip_to_str( (const guint8 *)pinfo->net_src.data), + ip_to_str( (const guint8 *)pinfo->net_dst.data), + pinfo->srcport, pinfo->destport ); + } + + if( pinfo->net_src.type == AT_IPv6 && pinfo->net_dst.type == AT_IPv6 ) { + /* TCP over IPv6 */ + return g_strdup_printf("(ipv6.addr eq %s and ipv6.addr eq %s) and (tcp.port eq %d and tcp.port eq %d)", + ip6_to_str((const struct e_in6_addr *)pinfo->net_src.data), + ip6_to_str((const struct e_in6_addr *)pinfo->net_dst.data), + pinfo->srcport, pinfo->destport ); + } + + return NULL; +} + /* TCP structs and definitions */ /* ************************************************************************** @@ -5935,6 +5964,7 @@ proto_register_tcp(void) register_decode_as(&tcp_da); register_conversation_table(proto_tcp, FALSE, tcpip_conversation_packet, tcpip_hostlist_packet, tcpip_hostlist_prefix); + register_color_conversation_filter("TCP", tcp_color_filter_valid, tcp_build_color_filter); } void diff --git a/epan/dissectors/packet-udp.c b/epan/dissectors/packet-udp.c index 86f874b919..6750e777bc 100644 --- a/epan/dissectors/packet-udp.c +++ b/epan/dissectors/packet-udp.c @@ -44,6 +44,7 @@ #include "packet-ip.h" #include #include +#include #include #include @@ -382,6 +383,35 @@ udpip_hostlist_prefix(void) return "endpoints"; } +static gboolean +udp_color_filter_valid(packet_info *pinfo) +{ + return proto_is_frame_protocol(pinfo->layers, "udp"); +} + +static gchar* +udp_build_color_filter(packet_info *pinfo) +{ + if( pinfo->net_src.type == AT_IPv4 && pinfo->net_dst.type == AT_IPv4 ) { + /* UDP over IPv4 */ + return g_strdup_printf("(ip.addr eq %s and ip.addr eq %s) and (udp.port eq %d and udp.port eq %d)", + ip_to_str( (const guint8 *)pinfo->net_src.data), + ip_to_str( (const guint8 *)pinfo->net_dst.data), + pinfo->srcport, pinfo->destport ); + } + + if( pinfo->net_src.type == AT_IPv6 && pinfo->net_dst.type == AT_IPv6 ) { + /* UDP over IPv6 */ + return g_strdup_printf("(ipv6.addr eq %s and ipv6.addr eq %s) and (udp.port eq %d and udp.port eq %d)", + ip6_to_str((const struct e_in6_addr *)pinfo->net_src.data), + ip6_to_str((const struct e_in6_addr *)pinfo->net_dst.data), + pinfo->srcport, pinfo->destport ); + } + + return NULL; +} + + /* Attach process info to a flow */ /* XXX - We depend on the UDP dissector finding the conversation first */ void @@ -990,6 +1020,7 @@ proto_register_udp(void) register_decode_as(&udp_da); register_conversation_table(proto_udp, FALSE, udpip_conversation_packet, udpip_hostlist_packet, udpip_hostlist_prefix); + register_color_conversation_filter("UDP", udp_color_filter_valid, udp_build_color_filter); register_init_routine(udp_init); diff --git a/epan/proto.c b/epan/proto.c index 5a9268ed46..3d40fc2303 100644 --- a/epan/proto.c +++ b/epan/proto.c @@ -5153,6 +5153,33 @@ proto_get_frame_protocols(const wmem_list_t *layers, gboolean *is_ip, } } +gboolean +proto_is_frame_protocol(const wmem_list_t *layers, const char* proto_name) +{ + wmem_list_frame_t *protos = wmem_list_head(layers); + int proto_id; + const char *name; + + /* Walk the list of a available protocols in the packet and + find "major" ones. */ + /* It might make more sense to assemble and return a bitfield. */ + while (protos != NULL) + { + proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos)); + name = proto_get_protocol_filter_name(proto_id); + + if (!strcmp(name, proto_name)) + { + return TRUE; + } + + protos = wmem_list_frame_next(protos); + } + + return FALSE; +} + + gboolean proto_is_protocol_enabled(const protocol_t *protocol) { diff --git a/epan/proto.h b/epan/proto.h index 490c415a33..dcc97f248a 100644 --- a/epan/proto.h +++ b/epan/proto.h @@ -2054,6 +2054,12 @@ WS_DLL_PUBLIC const char *proto_get_protocol_filter_name(const int proto_id); WS_DLL_PUBLIC void proto_get_frame_protocols(const wmem_list_t *layers, gboolean *is_ip, gboolean *is_tcp, gboolean *is_udp, gboolean *is_sctp, gboolean *is_ssl); +/** Find a protocol by name in a layer list. + * @param layers Protocol layer list + * @param proto_name Name of protocol to find + */ +WS_DLL_PUBLIC gboolean proto_is_frame_protocol(const wmem_list_t *layers, const char* proto_name); + /** Enable / Disable protocol of the given item number. @param proto_id protocol id (0-indexed) @param enabled enable / disable the protocol */ diff --git a/plugins/profinet/packet-dcom-cba-acco.c b/plugins/profinet/packet-dcom-cba-acco.c index 981dd22ac5..8a583b5d34 100644 --- a/plugins/profinet/packet-dcom-cba-acco.c +++ b/plugins/profinet/packet-dcom-cba-acco.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include "packet-dcom-cba-acco.h" @@ -336,6 +337,52 @@ GList *cba_pdevs; /* as we are a plugin, we cannot get this from libwireshark! */ const true_false_string acco_flags_set_truth = { "Set", "Not set" }; +static gboolean +cba_color_filter_valid(packet_info *pinfo) +{ + return ((pinfo->profinet_type != 0) && (pinfo->profinet_type < 10)); +} + +static gchar* +cba_build_color_filter(packet_info *pinfo) +{ + gboolean is_tcp = proto_is_frame_protocol(pinfo->layers, "tcp"); + + if ((pinfo->net_src.type == AT_IPv4) && (pinfo->net_dst.type == AT_IPv4) && is_tcp) { + /* IPv4 */ + switch(pinfo->profinet_type) { + case 1: + return g_strdup_printf("(ip.src eq %s and ip.dst eq %s and cba.acco.dcom == 1) || (ip.src eq %s and ip.dst eq %s and cba.acco.dcom == 0)", + ip_to_str( (const guint8 *)pinfo->net_dst.data), + ip_to_str( (const guint8 *)pinfo->net_src.data), + ip_to_str( (const guint8 *)pinfo->net_src.data), + ip_to_str( (const guint8 *)pinfo->net_dst.data)); + case 2: + return g_strdup_printf("(ip.src eq %s and ip.dst eq %s and cba.acco.dcom == 1) || (ip.src eq %s and ip.dst eq %s and cba.acco.dcom == 0)", + ip_to_str( (const guint8 *)pinfo->net_src.data), + ip_to_str( (const guint8 *)pinfo->net_dst.data), + ip_to_str( (const guint8 *)pinfo->net_dst.data), + ip_to_str( (const guint8 *)pinfo->net_src.data)); + case 3: + return g_strdup_printf("(ip.src eq %s and ip.dst eq %s and cba.acco.srt == 1) || (ip.src eq %s and ip.dst eq %s and cba.acco.srt == 0)", + ip_to_str( (const guint8 *)pinfo->net_dst.data), + ip_to_str( (const guint8 *)pinfo->net_src.data), + ip_to_str( (const guint8 *)pinfo->net_src.data), + ip_to_str( (const guint8 *)pinfo->net_dst.data)); + case 4: + return g_strdup_printf("(ip.src eq %s and ip.dst eq %s and cba.acco.srt == 1) || (ip.src eq %s and ip.dst eq %s and cba.acco.srt == 0)", + ip_to_str( (const guint8 *)pinfo->net_src.data), + ip_to_str( (const guint8 *)pinfo->net_dst.data), + ip_to_str( (const guint8 *)pinfo->net_dst.data), + ip_to_str( (const guint8 *)pinfo->net_src.data)); + default: + return NULL; + } + } + + return NULL; +} + #if 0 static void cba_connection_dump(cba_connection_t *conn, const char *role) @@ -5059,6 +5106,8 @@ proto_register_dcom_cba_acco (void) ett5[4] = &ett_cba_conn_info; proto_ICBAAccoSync = proto_register_protocol ("ICBAAccoSync", "ICBAAccoSync", "cba_acco_sync"); proto_register_subtree_array (ett5, array_length (ett5)); + + register_color_conversation_filter("PN-CBA", cba_color_filter_valid, cba_build_color_filter); }