From 31ecdf5b06bff3bb2e706e840c28c519698e6f67 Mon Sep 17 00:00:00 2001 From: Michael Mann Date: Wed, 23 Jul 2014 13:38:55 -0400 Subject: [PATCH] Refactor "common" Conversation table functionality. Refactor (non-GUI) conversation table functionality from gtk/Qt to epan. Also refactor "common GUI" conversation table functionality. The idea is to not have to modify the GUI when a dissector adds a new "conversation type" Change-Id: I11f08d0d7edd631218663ba4b902c4a4c849acda Reviewed-on: https://code.wireshark.org/review/3113 Reviewed-by: Gerald Combs --- epan/CMakeLists.txt | 1 + epan/Makefile.common | 2 + .../conversation_table.c | 734 +++++++----------- .../conversation_table.h | 275 ++++--- epan/dissectors/packet-eth.c | 31 + epan/dissectors/packet-fc.c | 29 + epan/dissectors/packet-fddi.c | 28 + epan/dissectors/packet-ieee80211.c | 29 + epan/dissectors/packet-ip.c | 28 + epan/dissectors/packet-ipv6.c | 38 + epan/dissectors/packet-ipx.c | 30 + epan/dissectors/packet-jxta.c | 31 + epan/dissectors/packet-ncp.c | 30 +- epan/dissectors/packet-rsvp.c | 23 + epan/dissectors/packet-sctp.c | 31 + epan/dissectors/packet-tcp.c | 31 + epan/dissectors/packet-tr.c | 30 + epan/dissectors/packet-udp.c | 29 + epan/dissectors/packet-usb.c | 37 +- epan/proto.c | 22 +- epan/proto.h | 5 + epan/stat_cmd_args.h | 7 + tfshark.c | 1 + tshark.c | 2 + ui/CMakeLists.txt | 2 +- ui/Makefile.common | 4 +- ui/conversation_ui.c | 61 ++ ui/conversation_ui.h | 76 ++ ui/gtk/CMakeLists.txt | 15 - ui/gtk/Makefile.common | 15 - ui/gtk/conversations_eth.c | 81 -- ui/gtk/conversations_fc.c | 81 -- ui/gtk/conversations_fddi.c | 80 -- ui/gtk/conversations_ip.c | 78 -- ui/gtk/conversations_ipv6.c | 87 --- ui/gtk/conversations_ipx.c | 80 -- ui/gtk/conversations_jxta.c | 89 --- ui/gtk/conversations_ncp.c | 81 -- ui/gtk/conversations_rsvp.c | 82 -- ui/gtk/conversations_sctp.c | 88 --- ui/gtk/conversations_table.c | 138 ++-- ui/gtk/conversations_table.h | 18 +- ui/gtk/conversations_tcpip.c | 80 -- ui/gtk/conversations_tr.c | 80 -- ui/gtk/conversations_udpip.c | 80 -- ui/gtk/conversations_usb.c | 78 -- ui/gtk/conversations_wlan.c | 80 -- ui/gtk/hostlist_ncp.c | 4 +- ui/gtk/hostlist_table.h | 24 +- ui/gtk/main.c | 3 + ui/gtk/main_menubar.c | 103 ++- ui/qt/conversation_dialog.cpp | 173 ++--- ui/qt/conversation_dialog.h | 18 +- ui/qt/conversation_tree_widget.cpp | 240 +----- ui/qt/conversation_tree_widget.h | 10 +- ui/qt/main.cpp | 3 + ui/qt/main_window_slots.cpp | 3 +- ui/sat.h | 41 - 58 files changed, 1338 insertions(+), 2342 deletions(-) rename ui/conversation_hash.c => epan/conversation_table.c (64%) rename ui/conversation_hash.h => epan/conversation_table.h (54%) create mode 100644 ui/conversation_ui.c create mode 100644 ui/conversation_ui.h delete mode 100644 ui/gtk/conversations_eth.c delete mode 100644 ui/gtk/conversations_fc.c delete mode 100644 ui/gtk/conversations_fddi.c delete mode 100644 ui/gtk/conversations_ip.c delete mode 100644 ui/gtk/conversations_ipv6.c delete mode 100644 ui/gtk/conversations_ipx.c delete mode 100644 ui/gtk/conversations_jxta.c delete mode 100644 ui/gtk/conversations_ncp.c delete mode 100644 ui/gtk/conversations_rsvp.c delete mode 100644 ui/gtk/conversations_sctp.c delete mode 100644 ui/gtk/conversations_tcpip.c delete mode 100644 ui/gtk/conversations_tr.c delete mode 100644 ui/gtk/conversations_udpip.c delete mode 100644 ui/gtk/conversations_usb.c delete mode 100644 ui/gtk/conversations_wlan.c delete mode 100644 ui/sat.h diff --git a/epan/CMakeLists.txt b/epan/CMakeLists.txt index 3998a7a497..3ecaf480da 100644 --- a/epan/CMakeLists.txt +++ b/epan/CMakeLists.txt @@ -1527,6 +1527,7 @@ set(LIBWIRESHARK_FILES column.c column-utils.c conversation.c + conversation_table.c crc16-tvb.c crc32-tvb.c crc8-tvb.c diff --git a/epan/Makefile.common b/epan/Makefile.common index 1707635e29..675d740428 100644 --- a/epan/Makefile.common +++ b/epan/Makefile.common @@ -35,6 +35,7 @@ LIBWIRESHARK_SRC = \ column.c \ column-utils.c \ conversation.c \ + conversation_table.c \ crc16-tvb.c \ crc32-tvb.c \ crc8-tvb.c \ @@ -163,6 +164,7 @@ LIBWIRESHARK_INCLUDES = \ column-utils.h \ conversation.h \ conversation_debug.h \ + conversation_table.h \ conv_id.h \ crc16-tvb.h \ crc32-tvb.h \ diff --git a/ui/conversation_hash.c b/epan/conversation_table.c similarity index 64% rename from ui/conversation_hash.c rename to epan/conversation_table.c index 41bf81944f..50f1954ea9 100644 --- a/ui/conversation_hash.c +++ b/epan/conversation_table.c @@ -1,6 +1,6 @@ -/* conversation_hash.c - * Copied from gtk/conversations_table.c 2003 Ronnie Sahlberg - * Helper routines common to all conversations taps. +/* conversations_table.c + * conversations_table 2003 Ronnie Sahlberg + * Helper routines common to all endpoint conversations tap. * * Wireshark - Network traffic analyzer * By Gerald Combs @@ -20,62 +20,175 @@ * 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 -#include -#include -#include -#include +#include "packet_info.h" +#include "proto.h" +#include "conversation_table.h" +#include "addr_resolv.h" +#include "emem.h" -#include "conversation_hash.h" -#include "utf8_entities.h" +#include "stat_cmd_args.h" -const char *column_titles[CONV_NUM_COLUMNS] = { - "Address A", - "Port A", - "Address B", - "Port B", - "Packets", - "Bytes", - "Packets A " UTF8_RIGHTWARDS_ARROW " B", - "Bytes A " UTF8_RIGHTWARDS_ARROW " B", - "Packets B " UTF8_RIGHTWARDS_ARROW " A", - "Bytes B " UTF8_RIGHTWARDS_ARROW " A", - "Rel Start", - "Duration", - "bps A " UTF8_RIGHTWARDS_ARROW " B", - "bps B " UTF8_RIGHTWARDS_ARROW " A" +GList *cmd_string_list_ = NULL; + +struct register_ct { + gboolean hide_ports; /* hide TCP / UDP port columns */ + int proto_id; /* protocol id (0-indexed) */ + tap_packet_cb packet_func; /* function to be called for new incoming packets */ + conv_gui_init_cb gui_init_cb; /* GUI specific function to initialize conversation */ }; -const char *conn_a_title = "Connection A"; -const char *conn_b_title = "Connection B"; - -/* - * Compute the hash value for two given address/port pairs if the match - * is to be exact. - */ -guint -conversation_hash(gconstpointer key) +gboolean get_conversation_hide_ports(register_ct_t* ct) { - const conv_key_t *ck = (const conv_key_t *)key; + return ct->hide_ports; +} + +int get_conversation_proto_id(register_ct_t* ct) +{ + if (!ct) { + return -1; + } + return ct->proto_id; +} + +tap_packet_cb get_conversation_packet_func(register_ct_t* ct) +{ + return ct->packet_func; +} + +static GSList *registered_ct_tables = NULL; + +void +dissector_conversation_init(const char *opt_arg, void* userdata) +{ + register_ct_t *table = (register_ct_t*)userdata; + GString *cmd_str = g_string_new("conv,"); + const char *filter=NULL; + + g_string_append(cmd_str, proto_get_protocol_filter_name(table->proto_id)); + if(!strncmp(opt_arg, cmd_str->str, cmd_str->len)){ + filter = opt_arg + cmd_str->len; + } else { + filter = NULL; + } + g_string_free(cmd_str, TRUE); + + if (table->gui_init_cb) + table->gui_init_cb(table, filter); +} + +/** get conversation from protocol ID + * + * @param proto_id protocol ID + * @return tap function handler of conversation + */ +register_ct_t* get_conversation_by_proto_id(int proto_id) +{ + GSList *ct; + register_ct_t *table; + + for(ct = registered_ct_tables; ct != NULL; ct = g_slist_next(ct)){ + table = (register_ct_t*)ct->data; + if ((table) && (table->proto_id == proto_id)) + return table; + } + + return NULL; +} + +static gint +insert_sorted_by_table_name(gconstpointer aparam, gconstpointer bparam) +{ + const register_ct_t *a = (register_ct_t *)aparam; + const register_ct_t *b = (register_ct_t *)bparam; + + return g_ascii_strcasecmp(proto_get_protocol_short_name(find_protocol_by_id(a->proto_id)), proto_get_protocol_short_name(find_protocol_by_id(b->proto_id))); +} + +void +register_conversation_table(const int proto_id, gboolean hide_ports, tap_packet_cb packet_func) +{ + register_ct_t *table; + GString *cmd_str = g_string_new("conv,"); + + table = g_new(register_ct_t,1); + + table->hide_ports = hide_ports; + table->proto_id = proto_id; + table->packet_func = packet_func; + table->gui_init_cb = NULL; + + registered_ct_tables = g_slist_insert_sorted(registered_ct_tables, table, insert_sorted_by_table_name); + + g_string_append(cmd_str, proto_get_protocol_filter_name(table->proto_id)); + cmd_string_list_ = g_list_append(cmd_string_list_, cmd_str->str); + register_stat_cmd_arg(cmd_str->str, dissector_conversation_init, table); + g_string_free(cmd_str, FALSE); +} + +/* Set GUI fields for register_ct list */ +static void +set_gui_data(gpointer data, gpointer user_data) +{ + register_ct_t *table = (register_ct_t*)data; + table->gui_init_cb = (conv_gui_init_cb)user_data; +} + +void conversation_table_set_gui_info(conv_gui_init_cb init_cb) +{ + g_slist_foreach(registered_ct_tables, set_gui_data, init_cb); +} + +void conversation_table_iterate_tables(GFunc func, gpointer user_data) +{ + g_slist_foreach(registered_ct_tables, func, user_data); +} + +guint conversation_table_get_num(void) +{ + return g_slist_length(registered_ct_tables); +} + + +register_ct_t *get_conversation_table_by_num(guint table_num) +{ + return (register_ct_t *) g_slist_nth_data(registered_ct_tables, table_num); +} + +/** Compute the hash value for two given address/port pairs. + * (Parameter type is gconstpointer for GHashTable compatibility.) + * + * @param key Conversation. MUST point to a conv_key_t struct. + * @return Computed key hash. + */ +static guint +conversation_hash(gconstpointer v) +{ + const conv_key_t *key = (const conv_key_t *)v; guint hash_val; hash_val = 0; - ADD_ADDRESS_TO_HASH(hash_val, &ck->addr1); - hash_val += ck->port1; - ADD_ADDRESS_TO_HASH(hash_val, &ck->addr2); - hash_val += ck->port2; - hash_val ^= ck->conv_id; + ADD_ADDRESS_TO_HASH(hash_val, &key->addr1); + hash_val += key->port1; + ADD_ADDRESS_TO_HASH(hash_val, &key->addr2); + hash_val += key->port2; + hash_val ^= key->conv_id; return hash_val; } -/* - * Compare two conversation keys for an exact match. +/** Compare two conversation keys for an exact match. + * (Parameter types are gconstpointer for GHashTable compatibility.) + * + * @param key1 First conversation. MUST point to a conv_key_t struct. + * @param key2 Second conversation. MUST point to a conv_key_t struct. + * @return TRUE if conversations are equal, FALSE otherwise. */ -gboolean +static gboolean conversation_equal(gconstpointer key1, gconstpointer key2) { const conv_key_t *ck1 = (const conv_key_t *)key1; @@ -130,237 +243,6 @@ reset_conversation_table_data(conv_hash_t *ch) ch->hashtable=NULL; } -void -add_conversation_table_data(conv_hash_t *ch, const address *src, const address *dst, guint32 src_port, guint32 dst_port, int num_frames, int num_bytes, nstime_t *ts, conversation_type_e conv_type, port_type ptype) -{ - add_conversation_table_data_with_conv_id(ch, src, dst, src_port, dst_port, CONV_ID_UNSET, num_frames, num_bytes, ts, conv_type, ptype); -} - -void -add_conversation_table_data_with_conv_id(conv_hash_t *ch, - const address *src, - const address *dst, - guint32 src_port, - guint32 dst_port, - conv_id_t conv_id, - int num_frames, - int num_bytes, - nstime_t *ts, - conversation_type_e conv_type, - port_type ptype) -{ - const address *addr1, *addr2; - guint32 port1, port2; - conv_item_t *conv_item = NULL; - unsigned int conversation_idx = 0; - - if (src_port > dst_port) { - addr1 = src; - addr2 = dst; - port1 = src_port; - port2 = dst_port; - } else if (src_port < dst_port) { - addr2 = src; - addr1 = dst; - port2 = src_port; - port1 = dst_port; - } else if (CMP_ADDRESS(src, dst) < 0) { - addr1 = src; - addr2 = dst; - port1 = src_port; - port2 = dst_port; - } else { - addr2 = src; - addr1 = dst; - port2 = src_port; - port1 = dst_port; - } - - /* if we dont have any entries at all yet */ - if (ch->conv_array == NULL) { - ch->conv_array = g_array_sized_new(FALSE, FALSE, sizeof(conv_item_t), 10000); - - ch->hashtable = g_hash_table_new_full(conversation_hash, - conversation_equal, /* key_equal_func */ - g_free, /* key_destroy_func */ - NULL); /* value_destroy_func */ - - } else { - /* try to find it among the existing known conversations */ - conv_key_t existing_key; - - existing_key.addr1 = *addr1; - existing_key.addr2 = *addr2; - existing_key.port1 = port1; - existing_key.port2 = port2; - existing_key.conv_id = conv_id; - if (g_hash_table_lookup_extended(ch->hashtable, &existing_key, NULL, (gpointer *) &conversation_idx)) { - conv_item = &g_array_index(ch->conv_array, conv_item_t, conversation_idx); - } - } - - /* if we still dont know what conversation this is it has to be a new one - and we have to allocate it and append it to the end of the list */ - if (conv_item == NULL) { - conv_key_t *new_key; - conv_item_t new_conv_item; - - COPY_ADDRESS(&new_conv_item.src_address, addr1); - COPY_ADDRESS(&new_conv_item.dst_address, addr2); - new_conv_item.conv_type = conv_type; - new_conv_item.ptype = ptype; - new_conv_item.src_port = port1; - new_conv_item.dst_port = port2; - new_conv_item.conv_id = conv_id; - new_conv_item.rx_frames = 0; - new_conv_item.tx_frames = 0; - new_conv_item.rx_bytes = 0; - new_conv_item.tx_bytes = 0; - new_conv_item.modified = TRUE; - - if (ts) { - memcpy(&new_conv_item.start_time, ts, sizeof(new_conv_item.start_time)); - memcpy(&new_conv_item.stop_time, ts, sizeof(new_conv_item.stop_time)); - } else { - nstime_set_unset(&new_conv_item.start_time); - nstime_set_unset(&new_conv_item.stop_time); - } - g_array_append_val(ch->conv_array, new_conv_item); - conversation_idx = ch->conv_array->len - 1; - conv_item = &g_array_index(ch->conv_array, conv_item_t, conversation_idx); - - /* ct->conversations address is not a constant but src/dst_address.data are */ - new_key = g_new(conv_key_t, 1); - SET_ADDRESS(&new_key->addr1, conv_item->src_address.type, conv_item->src_address.len, conv_item->src_address.data); - SET_ADDRESS(&new_key->addr2, conv_item->dst_address.type, conv_item->dst_address.len, conv_item->dst_address.data); - new_key->port1 = port1; - new_key->port2 = port2; - new_key->conv_id = conv_id; - g_hash_table_insert(ch->hashtable, new_key, GUINT_TO_POINTER(conversation_idx)); - } - - /* update the conversation struct */ - conv_item->modified = TRUE; - if ( (!CMP_ADDRESS(src, addr1)) && (!CMP_ADDRESS(dst, addr2)) && (src_port==port1) && (dst_port==port2) ) { - conv_item->tx_frames += num_frames; - conv_item->tx_bytes += num_bytes; - } else { - conv_item->rx_frames += num_frames; - conv_item->rx_bytes += num_bytes; - } - - if (ts) { - if (nstime_cmp(ts, &conv_item->stop_time) > 0) { - memcpy(&conv_item->stop_time, ts, sizeof(conv_item->stop_time)); - } else if (nstime_cmp(ts, &conv_item->start_time) < 0) { - memcpy(&conv_item->start_time, ts, sizeof(conv_item->start_time)); - } - } -} - -const char *conversation_title(conversation_type_e conv_type) -{ - switch (conv_type) { - case CONV_TYPE_ETHERNET: - return "Ethernet"; - case CONV_TYPE_FIBRE_CHANNEL: - return "Fibre Channel"; - case CONV_TYPE_FDDI: - return "FDDI"; - case CONV_TYPE_IPV4: - return "IPv4"; - case CONV_TYPE_IPV6: - return "IPv6"; - case CONV_TYPE_IPX: - return "IPX"; - case CONV_TYPE_JXTA: - return "JXTA"; - case CONV_TYPE_NCP: - return "NCP"; - case CONV_TYPE_RSVP: - return "RSVP"; - case CONV_TYPE_SCTP: - return "SCTP"; - case CONV_TYPE_TCP: - return "TCP"; - case CONV_TYPE_TOKEN_RING: - return "Token Ring"; - case CONV_TYPE_UDP: - return "UDP"; - case CONV_TYPE_USB: - return "USB"; - case CONV_TYPE_WLAN: - return "WLAN"; - default: - return "Unknown"; - } -} - -conversation_type_e conversation_title_to_type(const char *title) -{ - int i; - - for (i = CONV_TYPE_ETHERNET; i < N_CONV_TYPES; i++) { - conversation_type_e ct = (conversation_type_e) i; - if (strcmp(title, conversation_title(ct)) == 0) { - return ct; - } - } - /* Sensible default? */ - return CONV_TYPE_TCP; -} - -const char *conversation_tap_name(conversation_type_e conv_type) -{ - switch (conv_type) { - case CONV_TYPE_ETHERNET: - return "eth"; - case CONV_TYPE_FIBRE_CHANNEL: - return "fc"; - case CONV_TYPE_FDDI: - return "fddi"; - case CONV_TYPE_IPV4: - return "ip"; - case CONV_TYPE_IPV6: - return "ipv6"; - case CONV_TYPE_IPX: - return "ipx"; - case CONV_TYPE_JXTA: - return "jxta"; - case CONV_TYPE_NCP: - return "ncp_hdr"; - case CONV_TYPE_RSVP: - return "rsvp"; - case CONV_TYPE_SCTP: - return "sctp"; - case CONV_TYPE_TCP: - return "tcp"; - case CONV_TYPE_TOKEN_RING: - return "tr"; - case CONV_TYPE_UDP: - return "udp"; - case CONV_TYPE_USB: - return "usb"; - case CONV_TYPE_WLAN: - return "wlan"; - default: - return "INVALID TAP NAME"; - } -} - -gboolean conversation_hide_ports(conversation_type_e conv_type) -{ - switch (conv_type) { - case CONV_TYPE_NCP: - case CONV_TYPE_SCTP: - case CONV_TYPE_TCP: - case CONV_TYPE_UDP: - return FALSE; - default: - return TRUE; - } -} - const char *get_conversation_address(address *addr, gboolean resolve_names) { if (resolve_names) { @@ -387,15 +269,6 @@ const char *get_conversation_port(guint32 port, port_type ptype, gboolean resolv } } -typedef enum { - CONV_FT_SRC_ADDRESS, - CONV_FT_DST_ADDRESS, - CONV_FT_ANY_ADDRESS, - CONV_FT_SRC_PORT, - CONV_FT_DST_PORT, - CONV_FT_ANY_PORT -} conv_filter_type_e; - /* given an address (to distinguish between ipv4 and ipv6 for tcp/udp), a port_type and a name_type (FN_...) return a string for the filter name. @@ -408,170 +281,11 @@ static const char * conversation_get_filter_name(conv_item_t *conv_item, conv_filter_type_e filter_type) { - if (!conv_item) { - return "INVALID"; + if ((conv_item == NULL) || (conv_item->dissector_info == NULL) || (conv_item->dissector_info->get_filter_type == NULL)) { + return CONV_FILTER_INVALID; } - switch(filter_type){ - case CONV_FT_SRC_ADDRESS: - switch(conv_item->src_address.type){ - case AT_ETHER: - switch(conv_item->conv_type){ - case CONV_TYPE_ETHERNET: - return "eth.src"; - case CONV_TYPE_WLAN: - return "wlan.sa"; - case CONV_TYPE_FDDI: - return "fddi.src"; - case CONV_TYPE_TOKEN_RING: - return "tr.src"; - default: - break; - } - break; - case AT_IPv4: - return "ip.src"; - case AT_IPv6: - return "ipv6.src"; - case AT_IPX: - return "ipx.src"; - case AT_FC: - return "fc.s_id"; - case AT_URI: - switch(conv_item->conv_type){ - case CONV_TYPE_JXTA: - return "jxta.message.src"; - default: - break; - } - break; - case AT_USB: - return "usb.sa"; - default: - break; - } - break; - case CONV_FT_DST_ADDRESS: - switch(conv_item->dst_address.type){ - case AT_ETHER: - switch(conv_item->conv_type){ - case CONV_TYPE_ETHERNET: - return "eth.dst"; - case CONV_TYPE_WLAN: - return "wlan.da"; - case CONV_TYPE_FDDI: - return "fddi.dst"; - case CONV_TYPE_TOKEN_RING: - return "tr.dst"; - default: - break; - } - break; - case AT_IPv4: - return "ip.dst"; - case AT_IPv6: - return "ipv6.dst"; - case AT_IPX: - return "ipx.dst"; - case AT_FC: - return "fc.d_id"; - case AT_URI: - switch(conv_item->conv_type){ - case CONV_TYPE_JXTA: - return "jxta.message.dst"; - default: - break; - } - break; - case AT_USB: - return "usb.da"; - default: - break; - } - break; - case CONV_FT_ANY_ADDRESS: - switch(conv_item->src_address.type){ - case AT_ETHER: - switch(conv_item->conv_type){ - case CONV_TYPE_ETHERNET: - return "eth.addr"; - case CONV_TYPE_WLAN: - return "wlan.addr"; - case CONV_TYPE_FDDI: - return "fddi.addr"; - case CONV_TYPE_TOKEN_RING: - return "tr.addr"; - default: - break; - } - break; - case AT_IPv4: - return "ip.addr"; - case AT_IPv6: - return "ipv6.addr"; - case AT_IPX: - return "ipx.addr"; - case AT_FC: - return "fc.id"; - case AT_URI: - switch(conv_item->conv_type){ - case CONV_TYPE_JXTA: - return "jxta.message.address"; - default: - break; - } - break; - case AT_USB: - return "usb.addr"; - default: - break; - } - break; - case CONV_FT_SRC_PORT: - switch(conv_item->ptype){ - case PT_TCP: - return "tcp.srcport"; - case PT_UDP: - return "udp.srcport"; - case PT_SCTP: - return "sctp.srcport"; - case PT_NCP: - return "ncp.connection"; - default: - break; - } - break; - case CONV_FT_DST_PORT: - switch(conv_item->ptype){ - case PT_TCP: - return "tcp.dstport"; - case PT_UDP: - return "udp.dstport"; - case PT_SCTP: - return "sctp.dstport"; - case PT_NCP: - return "ncp.connection"; - default: - break; - } - break; - case CONV_FT_ANY_PORT: - switch(conv_item->ptype){ - case PT_TCP: - return "tcp.port"; - case PT_UDP: - return "udp.port"; - case PT_SCTP: - return "sctp.port"; - case PT_NCP: - return "ncp.connection"; - default: - break; - } - break; - } - - return "INVALID"; + return conv_item->dissector_info->get_filter_type(conv_item, filter_type); } /* Convert a port number into a string or NULL */ @@ -590,7 +304,6 @@ ct_port_to_str(port_type ptype, guint32 port) return NULL; } - const char *get_conversation_filter(conv_item_t *conv_item, conv_direction_e direction) { char *sport, *dport; @@ -725,6 +438,135 @@ const char *get_conversation_filter(conv_item_t *conv_item, conv_direction_e dir return str; } +void +add_conversation_table_data(conv_hash_t *ch, const address *src, const address *dst, guint32 src_port, guint32 dst_port, int num_frames, int num_bytes, nstime_t *ts, ct_dissector_info_t *ct_info, port_type ptype) +{ + add_conversation_table_data_with_conv_id(ch, src, dst, src_port, dst_port, CONV_ID_UNSET, num_frames, num_bytes, ts, ct_info, ptype); +} + +void +add_conversation_table_data_with_conv_id( + conv_hash_t *ch, + const address *src, + const address *dst, + guint32 src_port, + guint32 dst_port, + conv_id_t conv_id, + int num_frames, + int num_bytes, + nstime_t *ts, + ct_dissector_info_t *ct_info, + port_type ptype) +{ + const address *addr1, *addr2; + guint32 port1, port2; + conv_item_t *conv_item = NULL; + unsigned int conversation_idx = 0; + + if (src_port > dst_port) { + addr1 = src; + addr2 = dst; + port1 = src_port; + port2 = dst_port; + } else if (src_port < dst_port) { + addr2 = src; + addr1 = dst; + port2 = src_port; + port1 = dst_port; + } else if (CMP_ADDRESS(src, dst) < 0) { + addr1 = src; + addr2 = dst; + port1 = src_port; + port2 = dst_port; + } else { + addr2 = src; + addr1 = dst; + port2 = src_port; + port1 = dst_port; + } + + /* if we dont have any entries at all yet */ + if (ch->conv_array == NULL) { + ch->conv_array = g_array_sized_new(FALSE, FALSE, sizeof(conv_item_t), 10000); + + ch->hashtable = g_hash_table_new_full(conversation_hash, + conversation_equal, /* key_equal_func */ + g_free, /* key_destroy_func */ + NULL); /* value_destroy_func */ + + } else { + /* try to find it among the existing known conversations */ + conv_key_t existing_key; + + existing_key.addr1 = *addr1; + existing_key.addr2 = *addr2; + existing_key.port1 = port1; + existing_key.port2 = port2; + existing_key.conv_id = conv_id; + if (g_hash_table_lookup_extended(ch->hashtable, &existing_key, NULL, (gpointer *) &conversation_idx)) { + conv_item = &g_array_index(ch->conv_array, conv_item_t, conversation_idx); + } + } + + /* if we still dont know what conversation this is it has to be a new one + and we have to allocate it and append it to the end of the list */ + if (conv_item == NULL) { + conv_key_t *new_key; + conv_item_t new_conv_item; + + COPY_ADDRESS(&new_conv_item.src_address, addr1); + COPY_ADDRESS(&new_conv_item.dst_address, addr2); + new_conv_item.dissector_info = ct_info; + new_conv_item.ptype = ptype; + new_conv_item.src_port = port1; + new_conv_item.dst_port = port2; + new_conv_item.conv_id = conv_id; + new_conv_item.rx_frames = 0; + new_conv_item.tx_frames = 0; + new_conv_item.rx_bytes = 0; + new_conv_item.tx_bytes = 0; + new_conv_item.modified = TRUE; + + if (ts) { + memcpy(&new_conv_item.start_time, ts, sizeof(new_conv_item.start_time)); + memcpy(&new_conv_item.stop_time, ts, sizeof(new_conv_item.stop_time)); + } else { + nstime_set_unset(&new_conv_item.start_time); + nstime_set_unset(&new_conv_item.stop_time); + } + g_array_append_val(ch->conv_array, new_conv_item); + conversation_idx = ch->conv_array->len - 1; + conv_item = &g_array_index(ch->conv_array, conv_item_t, conversation_idx); + + /* ct->conversations address is not a constant but src/dst_address.data are */ + new_key = g_new(conv_key_t, 1); + SET_ADDRESS(&new_key->addr1, conv_item->src_address.type, conv_item->src_address.len, conv_item->src_address.data); + SET_ADDRESS(&new_key->addr2, conv_item->dst_address.type, conv_item->dst_address.len, conv_item->dst_address.data); + new_key->port1 = port1; + new_key->port2 = port2; + new_key->conv_id = conv_id; + g_hash_table_insert(ch->hashtable, new_key, GUINT_TO_POINTER(conversation_idx)); + } + + /* update the conversation struct */ + conv_item->modified = TRUE; + if ( (!CMP_ADDRESS(src, addr1)) && (!CMP_ADDRESS(dst, addr2)) && (src_port==port1) && (dst_port==port2) ) { + conv_item->tx_frames += num_frames; + conv_item->tx_bytes += num_bytes; + } else { + conv_item->rx_frames += num_frames; + conv_item->rx_bytes += num_bytes; + } + + if (ts) { + if (nstime_cmp(ts, &conv_item->stop_time) > 0) { + memcpy(&conv_item->stop_time, ts, sizeof(conv_item->stop_time)); + } else if (nstime_cmp(ts, &conv_item->start_time) < 0) { + memcpy(&conv_item->start_time, ts, sizeof(conv_item->start_time)); + } + } +} + /* * Editor modelines * diff --git a/ui/conversation_hash.h b/epan/conversation_table.h similarity index 54% rename from ui/conversation_hash.h rename to epan/conversation_table.h index d7a67785bb..d9e6f2bd01 100644 --- a/ui/conversation_hash.h +++ b/epan/conversation_table.h @@ -1,6 +1,6 @@ -/* conversation_hash.h - * Copied from gtk/conversations_table.h 2003 Ronnie Sahlberg - * Helper routines common to all conversations taps. +/* conversation_table.h + * GUI independent helper routines common to all conversations taps. + * Refactored original conversations_table by Ronnie Sahlberg * * Wireshark - Network traffic analyzer * By Gerald Combs @@ -21,61 +21,28 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#ifndef __CONVERSATION_HASH_H__ -#define __CONVERSATION_HASH_H__ +#ifndef __CONVERSATION_TABLE_H__ +#define __CONVERSATION_TABLE_H__ -#include -#include - -#include +#include "conv_id.h" +#include "tap.h" #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /** @file - * Conversation lists. + * Conversation definitions. */ -/** Conversation types */ -/* Sort alphabetically by title */ typedef enum { - CONV_TYPE_ETHERNET, - CONV_TYPE_FIBRE_CHANNEL, - CONV_TYPE_FDDI, - CONV_TYPE_IPV4, - CONV_TYPE_IPV6, - CONV_TYPE_IPX, - CONV_TYPE_JXTA, - CONV_TYPE_NCP, - CONV_TYPE_RSVP, - CONV_TYPE_SCTP, - CONV_TYPE_TCP, - CONV_TYPE_TOKEN_RING, - CONV_TYPE_UDP, - CONV_TYPE_USB, - CONV_TYPE_WLAN, - N_CONV_TYPES -} conversation_type_e; - -typedef enum { - CONV_COLUMN_SRC_ADDR, - CONV_COLUMN_SRC_PORT, - CONV_COLUMN_DST_ADDR, - CONV_COLUMN_DST_PORT, - CONV_COLUMN_PACKETS, - CONV_COLUMN_BYTES, - CONV_COLUMN_PKT_AB, - CONV_COLUMN_BYTES_AB, - CONV_COLUMN_PKT_BA, - CONV_COLUMN_BYTES_BA, - CONV_COLUMN_START, - CONV_COLUMN_DURATION, - CONV_COLUMN_BPS_AB, - CONV_COLUMN_BPS_BA, - CONV_NUM_COLUMNS, - CONV_INDEX_COLUMN = CONV_NUM_COLUMNS -} column_type_e; + CONV_FT_SRC_ADDRESS, + CONV_FT_DST_ADDRESS, + CONV_FT_ANY_ADDRESS, + CONV_FT_SRC_PORT, + CONV_FT_DST_PORT, + CONV_FT_ANY_PORT +} conv_filter_type_e; /* Filter direction */ typedef enum { @@ -90,16 +57,13 @@ typedef enum { CONV_DIR_ANY_FROM_B } conv_direction_e; -extern const char *column_titles[CONV_NUM_COLUMNS]; -extern const char *conn_a_title; -extern const char *conn_b_title; - /** Conversation hash + value storage * Hash table keys are conv_key_t. Hash table values are indexes into conv_array. */ typedef struct _conversation_hash_t { GHashTable *hashtable; /**< conversations hash table */ GArray *conv_array; /**< array of conversation values */ + void *user_data; /**< "GUI" specifics (if necessary) */ } conv_hash_t; /** Key for hash lookups */ @@ -111,9 +75,28 @@ typedef struct _conversation_key_t { conv_id_t conv_id; } conv_key_t; +struct _conversation_item_t; +typedef const char* (*conv_get_filter_type)(struct _conversation_item_t* item, conv_filter_type_e filter); +typedef const char* (*conv_get_conversation_filter_type)(struct _conversation_item_t* item, conv_direction_e direction); + + + +typedef struct _ct_dissector_info { + conv_get_filter_type get_filter_type; +} ct_dissector_info_t; + +#define CONV_FILTER_INVALID "INVALID" + + +struct register_ct; +typedef void (*conv_gui_init_cb)(struct register_ct* ct, const char *filter); + +/** Structure for information about a registered conversation */ +typedef struct register_ct register_ct_t; + /** Conversation information */ typedef struct _conversation_item_t { - conversation_type_e conv_type; /**< conversation type */ + ct_dissector_info_t *dissector_info; /**< conversation information provided by dissector */ address src_address; /**< source address */ address dst_address; /**< destination address */ port_type ptype; /**< port_type (e.g. PT_TCP) */ @@ -129,31 +112,111 @@ typedef struct _conversation_item_t { nstime_t start_time; /**< start time for the conversation */ nstime_t stop_time; /**< stop time for the conversation */ - gboolean modified; /**< new to redraw the row */ + gboolean modified; /**< new to redraw the row (only used in GTK+) */ } conv_item_t; -/** Compute the hash value for two given address/port pairs. - * (Parameter type is gconstpointer for GHashTable compatibility.) +/** Register the conversation table for the multiple conversation window. * - * @param key Conversation. MUST point to a conv_key_t struct. - * @return Computed key hash. + * @param hide_ports hide the port columns + * @param table_name the table name to be displayed + * @param tap_name the registered tap name + * @param packet_func the function to be called for each incoming packet */ -guint conversation_hash(gconstpointer key); +extern void register_conversation_table(const int proto_id, gboolean hide_ports, tap_packet_cb packet_func); -/** Compare two conversation keys for an exact match. - * (Parameter types are gconstpointer for GHashTable compatibility.) +/** Should port columns be hidden? * - * @param key1 First conversation. MUST point to a conv_key_t struct. - * @param key2 Second conversation. MUST point to a conv_key_t struct. - * @return TRUE if conversations are equal, FALSE otherwise. + * @param ct Registered conversation + * @return TRUE if port columns should be hidden for this conversation type. */ -gboolean conversation_equal(gconstpointer key1, gconstpointer key2); +WS_DLL_PUBLIC gboolean get_conversation_hide_ports(register_ct_t* ct); + +/** Get protocol ID from conversation + * + * @param ct Registered conversation + * @return protocol id of conversation + */ +WS_DLL_PUBLIC int get_conversation_proto_id(register_ct_t* ct); + +/** Get tap function handler from conversation + * + * @param ct Registered conversation + * @return tap function handler of conversation + */ +WS_DLL_PUBLIC tap_packet_cb get_conversation_packet_func(register_ct_t* ct); + +/** get conversation from protocol ID + * + * @param proto_id protocol ID + * @return tap function handler of conversation + */ +WS_DLL_PUBLIC register_ct_t* get_conversation_by_proto_id(int proto_id); + +/** Register "initialization function" used by the GUI to create conversation + * table display in GUI + * + * @param init_cb callback function that will be called when converation table "display + * is instantiated in GUI + */ +WS_DLL_PUBLIC void conversation_table_set_gui_info(conv_gui_init_cb init_cb); + +/** Interator to walk converation tables and execute func + * a GUI menu (only used in GTK) + * + * @param func action to be performed on all converation tables + * @param user_data any data needed to help perform function + */ +WS_DLL_PUBLIC void conversation_table_iterate_tables(GFunc func, gpointer user_data); + +/** Total number of converation tables + */ +WS_DLL_PUBLIC guint conversation_table_get_num(void); + +/** Get conversation table by its number + * Tables are ordered alphabetically by title. + * + * @param table_num Item to fetch. + * @return table pointer or NULL. + */ +WS_DLL_PUBLIC register_ct_t* get_conversation_table_by_num(guint table_num); /** Remove all entries from the conversation table. * * @param ch the table to reset */ -extern void reset_conversation_table_data(conv_hash_t *ch); +WS_DLL_PUBLIC void reset_conversation_table_data(conv_hash_t *ch); + +/** Initialize dissector converation for stats and (possibly) GUI. + * + * @param opt_arg filter string to compare with dissector + * @param userdata register_ct_t* for dissector conversation + */ +WS_DLL_PUBLIC void dissector_conversation_init(const char *opt_arg, void* userdata); + +/** Get the string representation of an address. + * + * @param addr The address. + * @param resolve_names Enable name resolution. + * @return An ep_allocated string representing the address. + */ +WS_DLL_PUBLIC const char *get_conversation_address(address *addr, gboolean resolve_names); + +/** Get the string representation of a port. + * + * @param port The port number. + * @param ptype The port type. + * @param resolve_names Enable name resolution. + * @return An ep_allocated string representing the port. + */ +WS_DLL_PUBLIC const char *get_conversation_port(guint32 port, port_type ptype, gboolean resolve_names); + +/** Get a display filter for the given conversation and direction. + * + * @param conv_item The conversation. + * @param direction The desired direction. + * @return An ep_allocated string representing the conversation. + */ +WS_DLL_PUBLIC const char *get_conversation_filter(conv_item_t *conv_item, conv_direction_e direction); /** Add some data to the conversation table. * @@ -165,11 +228,12 @@ extern void reset_conversation_table_data(conv_hash_t *ch); * @param num_frames number of packets * @param num_bytes number of bytes * @param ts timestamp + * @param ct_info callback handlers from the dissector * @param ptype the port type (e.g. PT_TCP) */ extern void add_conversation_table_data(conv_hash_t *ch, const address *src, const address *dst, guint32 src_port, guint32 dst_port, int num_frames, int num_bytes, nstime_t *ts, - conversation_type_e conv_type, port_type ptype); + ct_dissector_info_t *ct_info, port_type ptype); /** Add some data to the conversation table, passing a value to be used in * addition to the address and port quadruple to uniquely identify the @@ -183,11 +247,13 @@ extern void add_conversation_table_data(conv_hash_t *ch, const address *src, con * @param num_frames number of packets * @param num_bytes number of bytes * @param ts timestamp + * @param ct_info callback handlers from the dissector * @param ptype the port type (e.g. PT_TCP) * @param conv_id a value to help differentiate the conversation in case the address and port quadruple is not sufficiently unique */ extern void -add_conversation_table_data_with_conv_id(conv_hash_t *ch, +add_conversation_table_data_with_conv_id( + conv_hash_t *ch, const address *src, const address *dst, guint32 src_port, @@ -196,80 +262,11 @@ add_conversation_table_data_with_conv_id(conv_hash_t *ch, int num_frames, int num_bytes, nstime_t *ts, - conversation_type_e conv_type, + ct_dissector_info_t *ct_info, port_type ptype); -/** Conversation title - * - * @param conv_type Conversation type - * @return Title for this conversation type, e.g. "IPv4". - */ -extern const char * -conversation_title(conversation_type_e conv_type); - -/** Find the conversation type for a given title. - * - * @param title Conversation title - * @return Conversation type, e.g. CONV_TYPE_IPV4 or CONV_TYPE_TCP if not found. - */ -extern conversation_type_e -conversation_title_to_type(const char *title); - -/** Conversation tap name - * - * @param conv_type Conversation type - * @return Tap name for this conversation type, e.g. "tcp". - */ -extern const char * -conversation_tap_name(conversation_type_e conv_type); - -/** Should port columns be hidden? - * - * @param conv_type Conversation type - * @return TRUE if port columns should be hidden for this conversation type. - */ -extern gboolean conversation_hide_ports(conversation_type_e conv_type); - -/** Get the string representation of an address. - * - * @param addr The address. - * @param resolve_names Enable name resolution. - * @return An ep_allocated string representing the address. - */ -const char *get_conversation_address(address *addr, gboolean resolve_names); - -/** Get the string representation of a port. - * - * @param port The port number. - * @param ptype The port type. - * @param resolve_names Enable name resolution. - * @return An ep_allocated string representing the port. - */ -const char *get_conversation_port(guint32 port, port_type ptype, gboolean resolve_names); - -/** Get a display filter for the given conversation and direction. - * - * @param conv_item The conversation. - * @param direction The desired direction. - * @return An ep_allocated string representing the conversation. - */ -const char *get_conversation_filter(conv_item_t *conv_item, conv_direction_e direction); - #ifdef __cplusplus } #endif /* __cplusplus */ -#endif /* __CONVERSATION_HASH_H__ */ - -/* - * Editor modelines - * - * Local Variables: - * c-basic-offset: 4 - * tab-width: 8 - * indent-tabs-mode: nil - * End: - * - * ex: set shiftwidth=4 tabstop=8 expandtab: - * :indentSize=4:tabSize=8:noTabs=true: - */ +#endif /* __CONVERSATION_TABLE_H__ */ diff --git a/epan/dissectors/packet-eth.c b/epan/dissectors/packet-eth.c index 21e7e1195e..f1974631c9 100644 --- a/epan/dissectors/packet-eth.c +++ b/epan/dissectors/packet-eth.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include "packet-eth.h" #include "packet-ieee8023.h" @@ -106,6 +107,34 @@ static const true_false_string lg_tfs = { "Globally unique address (factory default)" }; + +static const char* eth_conv_get_filter_type(conv_item_t* conv, conv_filter_type_e filter) +{ + if ((filter == CONV_FT_SRC_ADDRESS) && (conv->src_address.type == AT_ETHER)) + return "eth.src"; + + if ((filter == CONV_FT_DST_ADDRESS) && (conv->dst_address.type == AT_ETHER)) + return "eth.dst"; + + if ((filter == CONV_FT_ANY_ADDRESS) && (conv->src_address.type == AT_ETHER)) + return "eth.addr"; + + return CONV_FILTER_INVALID; +} + +static ct_dissector_info_t eth_ct_dissector_info = {ð_conv_get_filter_type}; + +static int +eth_conversation_packet(void *pct, packet_info *pinfo, epan_dissect_t *edt _U_, const void *vip) +{ + conv_hash_t *hash = (conv_hash_t*) pct; + const eth_hdr *ehdr=(const eth_hdr *)vip; + + add_conversation_table_data(hash, &ehdr->src, &ehdr->dst, 0, 0, 1, pinfo->fd->pkt_len, &pinfo->rel_ts, ð_ct_dissector_info, PT_NONE); + + return 1; +} + /* These are the Netware-ish names for the different Ethernet frame types. EthernetII: The ethernet with a Type field instead of a length field Ethernet802.2: An 802.3 header followed by an 802.2 header @@ -941,6 +970,8 @@ proto_register_eth(void) register_dissector("eth_withfcs", dissect_eth_withfcs, proto_eth); register_dissector("eth", dissect_eth_maybefcs, proto_eth); eth_tap = register_tap("eth"); + + register_conversation_table(proto_eth, TRUE, eth_conversation_packet); } void diff --git a/epan/dissectors/packet-fc.c b/epan/dissectors/packet-fc.c index 737c7d1162..2ca116f2b5 100644 --- a/epan/dissectors/packet-fc.c +++ b/epan/dissectors/packet-fc.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include "packet-fc.h" #include "packet-fclctl.h" @@ -205,6 +206,32 @@ fc_exchange_init_protocol(void) fcseq_req_hash = g_hash_table_new(fcseq_hash, fcseq_equal); } +static const char* fc_conv_get_filter_type(conv_item_t* conv, conv_filter_type_e filter) +{ + if ((filter == CONV_FT_SRC_ADDRESS) && (conv->src_address.type == AT_FC)) + return "fc.s_id"; + + if ((filter == CONV_FT_DST_ADDRESS) && (conv->dst_address.type == AT_FC)) + return "fc.d_id"; + + if ((filter == CONV_FT_ANY_ADDRESS) && (conv->src_address.type == AT_FC)) + return "fc.id"; + + return CONV_FILTER_INVALID; +} + +static ct_dissector_info_t fc_ct_dissector_info = {&fc_conv_get_filter_type}; + +static int +fc_conversation_packet(void *pct, packet_info *pinfo, epan_dissect_t *edt _U_, const void *vip) +{ + conv_hash_t *hash = (conv_hash_t*) pct; + const fc_hdr *fchdr=(const fc_hdr *)vip; + + add_conversation_table_data(hash, &fchdr->s_id, &fchdr->d_id, 0, 0, 1, pinfo->fd->pkt_len, &pinfo->rel_ts, &fc_ct_dissector_info, PT_NONE); + + return 1; +} const value_string fc_fc4_val[] = { {FC_TYPE_BLS, "Basic Link Svc"}, @@ -1579,6 +1606,8 @@ proto_register_fc(void) proto_register_subtree_array(sof_ett, array_length(sof_ett)); fcsof_handle = register_dissector("fcsof", dissect_fcsof, proto_fcsof); + + register_conversation_table(proto_fc, TRUE, fc_conversation_packet); } diff --git a/epan/dissectors/packet-fddi.c b/epan/dissectors/packet-fddi.c index 50856084da..76a2fda692 100644 --- a/epan/dissectors/packet-fddi.c +++ b/epan/dissectors/packet-fddi.c @@ -33,6 +33,7 @@ #include #include #include +#include #include "packet-fddi.h" #include "packet-llc.h" #include @@ -142,6 +143,32 @@ swap_mac_addr(guint8 *swapped_addr, tvbuff_t *tvb, gint offset) bitswap_buf_inplace(swapped_addr, 6); } +static const char* fddi_conv_get_filter_type(conv_item_t* conv, conv_filter_type_e filter) +{ + if ((filter == CONV_FT_SRC_ADDRESS) && (conv->src_address.type == AT_ETHER)) + return "fddi.src"; + + if ((filter == CONV_FT_DST_ADDRESS) && (conv->dst_address.type == AT_ETHER)) + return "fddi.dst"; + + if ((filter == CONV_FT_ANY_ADDRESS) && (conv->src_address.type == AT_ETHER)) + return "fddi.addr"; + + return CONV_FILTER_INVALID; +} + +static ct_dissector_info_t fddi_ct_dissector_info = {&fddi_conv_get_filter_type}; + +static int +fddi_conversation_packet(void *pct, packet_info *pinfo, epan_dissect_t *edt _U_, const void *vip) +{ + conv_hash_t *hash = (conv_hash_t*) pct; + const fddi_hdr *ehdr=(const fddi_hdr *)vip; + + add_conversation_table_data(hash, &ehdr->src, &ehdr->dst, 0, 0, 1, pinfo->fd->pkt_len, &pinfo->rel_ts, &fddi_ct_dissector_info, PT_NONE); + + return 1; +} void capture_fddi(const guchar *pd, int len, packet_counts *ld) @@ -478,6 +505,7 @@ proto_register_fddi(void) &fddi_padding); fddi_tap = register_tap("fddi"); + register_conversation_table(proto_fddi, TRUE, fddi_conversation_packet); } void diff --git a/epan/dissectors/packet-ieee80211.c b/epan/dissectors/packet-ieee80211.c index a24f53b591..7e7f24606d 100644 --- a/epan/dissectors/packet-ieee80211.c +++ b/epan/dissectors/packet-ieee80211.c @@ -102,6 +102,7 @@ #include #include #include +#include #include #include @@ -5172,6 +5173,33 @@ static const value_string ff_psmp_sta_info_flags[] = { {0, NULL} }; +static const char* wlan_conv_get_filter_type(conv_item_t* conv, conv_filter_type_e filter) +{ + if ((filter == CONV_FT_SRC_ADDRESS) && (conv->src_address.type == AT_ETHER)) + return "wlan.sa"; + + if ((filter == CONV_FT_DST_ADDRESS) && (conv->dst_address.type == AT_ETHER)) + return "wlan.da"; + + if ((filter == CONV_FT_ANY_ADDRESS) && (conv->src_address.type == AT_ETHER)) + return "wlan.addr"; + + return CONV_FILTER_INVALID; +} + +static ct_dissector_info_t wlan_ct_dissector_info = {&wlan_conv_get_filter_type}; + +static int +wlan_conversation_packet(void *pct, packet_info *pinfo, epan_dissect_t *edt _U_, const void *vip) +{ + conv_hash_t *hash = (conv_hash_t*) pct; + const wlan_hdr *whdr=(const wlan_hdr *)vip; + + add_conversation_table_data(hash, &whdr->src, &whdr->dst, 0, 0, 1, pinfo->fd->pkt_len, &pinfo->rel_ts, &wlan_ct_dissector_info, PT_NONE); + + return 1; +} + static void beacon_interval_base_custom(gchar *result, guint32 beacon_interval) { @@ -25898,6 +25926,7 @@ proto_register_ieee80211 (void) register_init_routine(ieee80211_gas_reassembly_init); wlan_tap = register_tap("wlan"); + register_conversation_table(proto_wlan, TRUE, wlan_conversation_packet); /* Register configuration options */ wlan_module = prefs_register_protocol(proto_wlan, init_wepkeys); diff --git a/epan/dissectors/packet-ip.c b/epan/dissectors/packet-ip.c index c9e16d315a..ec61d204b8 100644 --- a/epan/dissectors/packet-ip.c +++ b/epan/dissectors/packet-ip.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -473,6 +474,32 @@ static gpointer ip_value(packet_info *pinfo) return GUINT_TO_POINTER(pinfo->ipproto); } +static const char* ip_conv_get_filter_type(conv_item_t* conv, conv_filter_type_e filter) +{ + if ((filter == CONV_FT_SRC_ADDRESS) && (conv->src_address.type == AT_IPv4)) + return "ip.src"; + + if ((filter == CONV_FT_DST_ADDRESS) && (conv->dst_address.type == AT_IPv4)) + return "ip.dst"; + + if ((filter == CONV_FT_ANY_ADDRESS) && (conv->src_address.type == AT_IPv4)) + return "ip.addr"; + + return CONV_FILTER_INVALID; +} + +static ct_dissector_info_t ip_ct_dissector_info = {&ip_conv_get_filter_type}; + +static int +ip_conversation_packet(void *pct, packet_info *pinfo, epan_dissect_t *edt _U_, const void *vip) +{ + conv_hash_t *hash = (conv_hash_t*) pct; + const ws_ip *iph=(const ws_ip *)vip; + + add_conversation_table_data(hash, &iph->ip_src, &iph->ip_dst, 0, 0, 1, pinfo->fd->pkt_len, &pinfo->rel_ts, &ip_ct_dissector_info, PT_NONE); + + return 1; +} /* * defragmentation of IPv4 @@ -3050,6 +3077,7 @@ proto_register_ip(void) ip_tap = register_tap("ip"); register_decode_as(&ip_da); + register_conversation_table(proto_ip, TRUE, ip_conversation_packet); } void diff --git a/epan/dissectors/packet-ipv6.c b/epan/dissectors/packet-ipv6.c index 22a2eeaf0c..7191c2ca3d 100644 --- a/epan/dissectors/packet-ipv6.c +++ b/epan/dissectors/packet-ipv6.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -347,6 +348,41 @@ static gpointer ipv6_next_header_value(packet_info *pinfo) return p_get_proto_data(pinfo->pool, pinfo, proto_ipv6, IPV6_PROTO_NXT_HDR); } +static const char* ipv6_conv_get_filter_type(conv_item_t* conv, conv_filter_type_e filter) +{ + if ((filter == CONV_FT_SRC_ADDRESS) && (conv->src_address.type == AT_IPv6)) + return "ipv6.src"; + + if ((filter == CONV_FT_DST_ADDRESS) && (conv->dst_address.type == AT_IPv6)) + return "ipv6.dst"; + + if ((filter == CONV_FT_ANY_ADDRESS) && (conv->src_address.type == AT_IPv6)) + return "ipv6.addr"; + + return CONV_FILTER_INVALID; +} + +static ct_dissector_info_t ipv6_ct_dissector_info = {&ipv6_conv_get_filter_type}; + +static int +ipv6_conversation_packet(void *pct, packet_info *pinfo, epan_dissect_t *edt _U_, const void *vip) +{ + conv_hash_t *hash = (conv_hash_t*) pct; + const struct ip6_hdr *ip6h = (const struct ip6_hdr *)vip; + address src; + address dst; + + /* Addresses aren't implemented as 'address' type in struct ip6_hdr */ + src.type = dst.type = AT_IPv6; + src.len = dst.len = sizeof(struct e_in6_addr); + src.data = &ip6h->ip6_src; + dst.data = &ip6h->ip6_dst; + + add_conversation_table_data(hash, &src, &dst, 0, 0, 1, pinfo->fd->pkt_len, &pinfo->rel_ts, &ipv6_ct_dissector_info, PT_NONE); + + return 1; +} + static const fragment_items ipv6_frag_items = { &ett_ipv6_fragment, &ett_ipv6_fragments, @@ -2908,6 +2944,8 @@ proto_register_ipv6(void) register_decode_as(&ipv6_da); register_decode_as(&ipv6_next_header_da); + + register_conversation_table(proto_ipv6, TRUE, ipv6_conversation_packet); } void diff --git a/epan/dissectors/packet-ipx.c b/epan/dissectors/packet-ipx.c index b845bdf3c9..74b0e2f3cd 100644 --- a/epan/dissectors/packet-ipx.c +++ b/epan/dissectors/packet-ipx.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include @@ -146,6 +147,33 @@ dissect_ipxmsg(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree); #define IPX_HEADER_LEN 30 /* It's *always* 30 bytes */ +static const char* ipx_conv_get_filter_type(conv_item_t* conv, conv_filter_type_e filter) +{ + if ((filter == CONV_FT_SRC_ADDRESS) && (conv->src_address.type == AT_IPX)) + return "ipx.src"; + + if ((filter == CONV_FT_DST_ADDRESS) && (conv->dst_address.type == AT_IPX)) + return "ipx.dst"; + + if ((filter == CONV_FT_ANY_ADDRESS) && (conv->src_address.type == AT_IPX)) + return "ipx.addr"; + + return CONV_FILTER_INVALID; +} + +static ct_dissector_info_t ipx_ct_dissector_info = {&ipx_conv_get_filter_type}; + +static int +ipx_conversation_packet(void *pct, packet_info *pinfo, epan_dissect_t *edt _U_, const void *vip) +{ + conv_hash_t *hash = (conv_hash_t*) pct; + const ipxhdr_t *ipxh=(const ipxhdr_t *)vip; + + add_conversation_table_data(hash, &ipxh->ipx_src, &ipxh->ipx_dst, 0, 0, 1, pinfo->fd->pkt_len, &pinfo->rel_ts, &ipx_ct_dissector_info, PT_NONE); + + return 1; +} + /* ================================================================= */ /* IPX */ /* ================================================================= */ @@ -1539,6 +1567,8 @@ proto_register_ipx(void) register_init_routine(&spx_init_protocol); register_postseq_cleanup_routine(&spx_postseq_cleanup); ipx_tap=register_tap("ipx"); + + register_conversation_table(proto_ipx, TRUE, ipx_conversation_packet); } void diff --git a/epan/dissectors/packet-jxta.c b/epan/dissectors/packet-jxta.c index 09a2cfc23a..bc39290d59 100644 --- a/epan/dissectors/packet-jxta.c +++ b/epan/dissectors/packet-jxta.c @@ -39,6 +39,7 @@ #include #include +#include #include #include #include @@ -194,6 +195,34 @@ struct jxta_stream_conversation_data { typedef struct jxta_stream_conversation_data jxta_stream_conversation_data; +static const char* jxta_conv_get_filter_type(conv_item_t* conv, conv_filter_type_e filter) +{ + if ((filter == CONV_FT_SRC_ADDRESS) && (conv->src_address.type == AT_URI)) + return "jxta.message.src"; + + if ((filter == CONV_FT_DST_ADDRESS) && (conv->dst_address.type == AT_URI)) + return "jxta.message.dst"; + + if ((filter == CONV_FT_ANY_ADDRESS) && (conv->src_address.type == AT_URI)) + return "jxta.message.address"; + + return CONV_FILTER_INVALID; +} + +static ct_dissector_info_t jxta_ct_dissector_info = {&jxta_conv_get_filter_type}; + +static int +jxta_conversation_packet(void *pct, packet_info *pinfo _U_, epan_dissect_t *edt _U_, const void *vip) +{ + conv_hash_t *hash = (conv_hash_t*) pct; + const jxta_tap_header *jxtahdr = (const jxta_tap_header *) vip; + + add_conversation_table_data(hash, &jxtahdr->src_address, &jxtahdr->dest_address, + 0, 0, 1, jxtahdr->size, NULL, &jxta_ct_dissector_info, PT_NONE); + + return 1; +} + /** * Prototypes **/ @@ -2322,6 +2351,8 @@ void proto_register_jxta(void) prefs_register_bool_preference(jxta_module, "sctp.heuristic", "Try to discover JXTA in SCTP connections", "Enable to inspect SCTP connections for JXTA conversations.", &gSCTP_HEUR); + + register_conversation_table(proto_jxta, TRUE, jxta_conversation_packet); } diff --git a/epan/dissectors/packet-ncp.c b/epan/dissectors/packet-ncp.c index 8398dc8264..c75c2430ee 100644 --- a/epan/dissectors/packet-ncp.c +++ b/epan/dissectors/packet-ncp.c @@ -54,6 +54,7 @@ #include "packet-ncp-int.h" #include #include +#include #include void proto_register_ncp(void); @@ -295,6 +296,31 @@ mncp_hash_lookup(conversation_t *conversation, guint32 nwconnection, guint8 nwta return (mncp_rhash_value *)g_hash_table_lookup(mncp_rhash, &key); } +static const char* ncp_conv_get_filter_type(conv_item_t* conv _U_, conv_filter_type_e filter) +{ + if ((filter == CONV_FT_SRC_PORT) || (filter == CONV_FT_DST_PORT) || (filter == CONV_FT_ANY_PORT)) + return "ncp.connection"; + + return CONV_FILTER_INVALID; +} + +static ct_dissector_info_t ncp_ct_dissector_info = {&ncp_conv_get_filter_type}; + +static int +ncp_conversation_packet(void *pct, packet_info *pinfo, epan_dissect_t *edt _U_, const void *vip) +{ + conv_hash_t *hash = (conv_hash_t*) pct; + const struct ncp_common_header *ncph=(const struct ncp_common_header *)vip; + guint32 connection; + + connection = (ncph->conn_high * 256)+ncph->conn_low; + if (connection < 65535) { + add_conversation_table_data(hash, &pinfo->src, &pinfo->dst, connection, connection, 1, pinfo->fd->pkt_len, &pinfo->rel_ts, &ncp_ct_dissector_info, PT_NCP); + } + + return 1; +} + /* * Burst packet system flags. */ @@ -1098,8 +1124,10 @@ proto_register_ncp(void) &ncp_echo_file); register_init_routine(&mncp_init_protocol); ncp_tap.stat=register_tap("ncp_srt"); - ncp_tap.hdr=register_tap("ncp_hdr"); + ncp_tap.hdr=register_tap("ncp"); register_postseq_cleanup_routine(&mncp_postseq_cleanup); + + register_conversation_table(proto_ncp, FALSE, ncp_conversation_packet); } void diff --git a/epan/dissectors/packet-rsvp.c b/epan/dissectors/packet-rsvp.c index 1eabc28539..a4c3363aa2 100644 --- a/epan/dissectors/packet-rsvp.c +++ b/epan/dissectors/packet-rsvp.c @@ -108,6 +108,7 @@ #include #include #include +#include #include #include #include @@ -1871,6 +1872,26 @@ rsvp_init_protocol(void) rsvp_request_hash = g_hash_table_new(rsvp_hash, rsvp_equal); } +static const char* rsvp_conv_get_filter_type(conv_item_t* conv _U_, conv_filter_type_e filter _U_) +{ + /* XXX - Not sure about this */ + return CONV_FILTER_INVALID; +} + +static ct_dissector_info_t rsvp_ct_dissector_info = {&rsvp_conv_get_filter_type}; + +static int +rsvp_conversation_packet(void *pct, packet_info *pinfo, epan_dissect_t *edt _U_, const void *vip) +{ + conv_hash_t *hash = (conv_hash_t*) pct; + const rsvp_conversation_info *rsvph = (const rsvp_conversation_info *)vip; + + add_conversation_table_data(hash, &rsvph->source, &rsvph->destination, + 0, 0, 1, pinfo->fd->pkt_len, &pinfo->rel_ts, &rsvp_ct_dissector_info, PT_NONE); + + return 1; +} + static inline int rsvp_class_to_filter_num(int classnum) { @@ -9156,6 +9177,8 @@ proto_register_rsvp(void) /* Initialization routine for RSVP conversations */ register_init_routine(&rsvp_init_protocol); + + register_conversation_table(proto_rsvp, TRUE, rsvp_conversation_packet); } void diff --git a/epan/dissectors/packet-sctp.c b/epan/dissectors/packet-sctp.c index b88ec19b0c..28f01b8335 100644 --- a/epan/dissectors/packet-sctp.c +++ b/epan/dissectors/packet-sctp.c @@ -64,6 +64,7 @@ #include #include #include +#include #include #include #include @@ -774,6 +775,34 @@ sctp_ppi_value2(packet_info *pinfo) return p_get_proto_data(pinfo->pool, pinfo, proto_sctp, 1); } +static const char* sctp_conv_get_filter_type(conv_item_t* conv _U_, conv_filter_type_e filter) +{ + if (filter == CONV_FT_SRC_PORT) + return "sctp.srcport"; + + if (filter == CONV_FT_DST_PORT) + return "sctp.dstport"; + + if (filter == CONV_FT_ANY_PORT) + return "sctp.port"; + + return CONV_FILTER_INVALID; +} + +static ct_dissector_info_t sctp_ct_dissector_info = {&sctp_conv_get_filter_type}; + +static int +sctp_conversation_packet(void *pct, packet_info *pinfo, epan_dissect_t *edt _U_, const void *vip) +{ + conv_hash_t *hash = (conv_hash_t*) pct; + const struct _sctp_info *sctphdr=(const struct _sctp_info *)vip; + + add_conversation_table_data(hash, &sctphdr->ip_src, &sctphdr->ip_dst, + sctphdr->sport, sctphdr->dport, 1, pinfo->fd->pkt_len, &pinfo->rel_ts, &sctp_ct_dissector_info, PT_SCTP); + + + return 1; +} static unsigned int sctp_adler32(const unsigned char *buf, unsigned int len) @@ -4834,6 +4863,8 @@ proto_register_sctp(void) register_decode_as(&sctp_da_port); register_decode_as(&sctp_da_ppi); + + register_conversation_table(proto_sctp, FALSE, sctp_conversation_packet); } void diff --git a/epan/dissectors/packet-tcp.c b/epan/dissectors/packet-tcp.c index 2d69807b96..871825e86d 100644 --- a/epan/dissectors/packet-tcp.c +++ b/epan/dissectors/packet-tcp.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -523,6 +524,34 @@ tcp_both_prompt(packet_info *pinfo, gchar *result) g_snprintf(result, MAX_DECODE_AS_PROMPT_LEN, "both (%u%s%u)", pinfo->srcport, UTF8_LEFT_RIGHT_ARROW, pinfo->destport); } +static const char* tcp_conv_get_filter_type(conv_item_t* conv _U_, conv_filter_type_e filter) +{ + if (filter == CONV_FT_SRC_PORT) + return "tcp.srcport"; + + if (filter == CONV_FT_DST_PORT) + return "tcp.dstport"; + + if (filter == CONV_FT_ANY_PORT) + return "tcp.port"; + + return CONV_FILTER_INVALID; +} + +static ct_dissector_info_t tcp_ct_dissector_info = {&tcp_conv_get_filter_type}; + +static int +tcpip_conversation_packet(void *pct, packet_info *pinfo, epan_dissect_t *edt _U_, const void *vip) +{ + conv_hash_t *hash = (conv_hash_t*) pct; + const struct tcpheader *tcphdr=(const struct tcpheader *)vip; + + add_conversation_table_data_with_conv_id(hash, &tcphdr->ip_src, &tcphdr->ip_dst, tcphdr->th_sport, tcphdr->th_dport, (conv_id_t) tcphdr->th_stream, 1, pinfo->fd->pkt_len, + &pinfo->rel_ts, &tcp_ct_dissector_info, PT_TCP); + + return 1; +} + /* TCP structs and definitions */ /* ************************************************************************** @@ -5818,6 +5847,8 @@ proto_register_tcp(void) register_init_routine(tcp_init); register_decode_as(&tcp_da); + + register_conversation_table(proto_tcp, FALSE, tcpip_conversation_packet); } void diff --git a/epan/dissectors/packet-tr.c b/epan/dissectors/packet-tr.c index 172b30af2c..30d7698897 100644 --- a/epan/dissectors/packet-tr.c +++ b/epan/dissectors/packet-tr.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include "packet-tr.h" #include "packet-llc.h" @@ -127,6 +128,33 @@ static dissector_handle_t trmac_handle; static dissector_handle_t llc_handle; static dissector_handle_t data_handle; +static const char* tr_conv_get_filter_type(conv_item_t* conv, conv_filter_type_e filter) +{ + if ((filter == CONV_FT_SRC_ADDRESS) && (conv->src_address.type == AT_ETHER)) + return "tr.src"; + + if ((filter == CONV_FT_DST_ADDRESS) && (conv->dst_address.type == AT_ETHER)) + return "tr.dst"; + + if ((filter == CONV_FT_ANY_ADDRESS) && (conv->src_address.type == AT_ETHER)) + return "tr.addr"; + + return CONV_FILTER_INVALID; +} + +static ct_dissector_info_t tr_ct_dissector_info = {&tr_conv_get_filter_type}; + +static int +tr_conversation_packet(void *pct, packet_info *pinfo, epan_dissect_t *edt _U_, const void *vip) +{ + conv_hash_t *hash = (conv_hash_t*) pct; + const tr_hdr *trhdr=(const tr_hdr *)vip; + + add_conversation_table_data(hash, &trhdr->src, &trhdr->dst, 0, 0, 1, pinfo->fd->pkt_len, &pinfo->rel_ts, &tr_ct_dissector_info, PT_NONE); + + return 1; +} + /* * DODGY LINUX HACK DODGY LINUX HACK * Linux 2.0.x always passes frames to the Token Ring driver for transmission with @@ -734,6 +762,8 @@ proto_register_tr(void) register_dissector("tr", dissect_tr, proto_tr); tr_tap=register_tap("tr"); + + register_conversation_table(proto_tr, TRUE, tr_conversation_packet); } void diff --git a/epan/dissectors/packet-udp.c b/epan/dissectors/packet-udp.c index 1def80f2d3..4a730dcd3e 100644 --- a/epan/dissectors/packet-udp.c +++ b/epan/dissectors/packet-udp.c @@ -43,6 +43,7 @@ #include "packet-ip.h" #include +#include #include #include @@ -280,6 +281,33 @@ get_udp_conversation_data(conversation_t *conv, packet_info *pinfo) return udpd; } +static const char* udp_conv_get_filter_type(conv_item_t* conv _U_, conv_filter_type_e filter) +{ + if (filter == CONV_FT_SRC_PORT) + return "udp.srcport"; + + if (filter == CONV_FT_DST_PORT) + return "udp.dstport"; + + if (filter == CONV_FT_ANY_PORT) + return "udp.port"; + + return CONV_FILTER_INVALID; +} + +static ct_dissector_info_t udp_ct_dissector_info = {&udp_conv_get_filter_type}; + +static int +udpip_conversation_packet(void *pct, packet_info *pinfo, epan_dissect_t *edt _U_, const void *vip) +{ + conv_hash_t *hash = (conv_hash_t*) pct; + const e_udphdr *udphdr=(const e_udphdr *)vip; + + add_conversation_table_data(hash, &udphdr->ip_src, &udphdr->ip_dst, udphdr->uh_sport, udphdr->uh_dport, 1, pinfo->fd->pkt_len, &pinfo->rel_ts, &udp_ct_dissector_info, PT_UDP); + + return 1; +} + /* Attach process info to a flow */ /* XXX - We depend on the UDP dissector finding the conversation first */ void @@ -891,6 +919,7 @@ proto_register_udp(void) &udplite_check_checksum); register_decode_as(&udp_da); + register_conversation_table(proto_udp, FALSE, udpip_conversation_packet); register_init_routine(udp_init); diff --git a/epan/dissectors/packet-usb.c b/epan/dissectors/packet-usb.c index e94cf8d9d7..aebf750bfe 100644 --- a/epan/dissectors/packet-usb.c +++ b/epan/dissectors/packet-usb.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -1101,6 +1102,30 @@ get_usb_iface_conv_info(packet_info *pinfo, guint8 interface_num) return get_usb_conv_info(conversation); } +static const char* usb_conv_get_filter_type(conv_item_t* conv, conv_filter_type_e filter) +{ + if ((filter == CONV_FT_SRC_ADDRESS) && (conv->src_address.type == AT_USB)) + return "usb.sa"; + + if ((filter == CONV_FT_DST_ADDRESS) && (conv->dst_address.type == AT_USB)) + return "usb.da"; + + if ((filter == CONV_FT_ANY_ADDRESS) && (conv->src_address.type == AT_USB)) + return "usb.addr"; + + return CONV_FILTER_INVALID; +} + +static ct_dissector_info_t usb_ct_dissector_info = {&usb_conv_get_filter_type}; + +static int +usb_conversation_packet(void *pct, packet_info *pinfo, epan_dissect_t *edt _U_, const void *vip _U_) +{ + conv_hash_t *hash = (conv_hash_t*) pct; + add_conversation_table_data(hash, &pinfo->src, &pinfo->dst, 0, 0, 1, pinfo->fd->pkt_len, &pinfo->rel_ts, &usb_ct_dissector_info, PT_NONE); + + return 1; +} /* SETUP dissectors */ @@ -4087,6 +4112,11 @@ proto_register_usb(void) expert_module_t* expert_usb; + proto_usb = proto_register_protocol("USB", "USB", "usb"); + proto_register_field_array(proto_usb, hf, array_length(hf)); + proto_register_subtree_array(usb_subtrees, array_length(usb_subtrees)); + linux_usb_handle = register_dissector("usb", dissect_linux_usb, proto_usb); + expert_usb = expert_register_protocol(proto_usb); expert_register_field_array(expert_usb, ei, array_length(ei)); @@ -4096,11 +4126,6 @@ proto_register_usb(void) protocol_to_dissector = register_dissector_table("usb.protocol", "USB protocol", FT_UINT32, BASE_HEX); product_to_dissector = register_dissector_table("usb.product", "USB product", FT_UINT32, BASE_HEX); - proto_usb = proto_register_protocol("USB", "USB", "usb"); - proto_register_field_array(proto_usb, hf, array_length(hf)); - proto_register_subtree_array(usb_subtrees, array_length(usb_subtrees)); - linux_usb_handle = register_dissector("usb", dissect_linux_usb, proto_usb); - usb_bulk_dissector_table = register_dissector_table("usb.bulk", "USB bulk endpoint", FT_UINT8, BASE_DEC); register_heur_dissector_list("usb.bulk", &heur_bulk_subdissector_list); @@ -4125,6 +4150,8 @@ proto_register_usb(void) register_decode_as(&usb_protocol_da); register_decode_as(&usb_product_da); register_decode_as(&usb_device_da); + + register_conversation_table(proto_usb, TRUE, usb_conversation_packet); } void diff --git a/epan/proto.c b/epan/proto.c index 05d7c9f119..059e18a495 100644 --- a/epan/proto.c +++ b/epan/proto.c @@ -4827,12 +4827,11 @@ proto_register_protocol(const char *name, const char *short_name, } g_hash_table_insert(proto_names, key, (gpointer)name); - existing_name = (const char *)g_hash_table_lookup(proto_short_names, (gpointer)short_name); - if (existing_name != NULL) { + existing_protocol = (const protocol_t *)g_hash_table_lookup(proto_short_names, (gpointer)short_name); + if (existing_protocol != NULL) { g_error("Duplicate protocol short_name \"%s\"!" " This might be caused by an inappropriate plugin or a development error.", short_name); } - g_hash_table_insert(proto_short_names, (gpointer)short_name, (gpointer)short_name); found_invalid = FALSE; for (i = 0; filter_name[i]; i++) { @@ -4865,6 +4864,7 @@ proto_register_protocol(const char *name, const char *short_name, /* list will be sorted later by name, when all protocols completed registering */ protocols = g_list_prepend(protocols, protocol); g_hash_table_insert(proto_filter_names, (gpointer)filter_name, protocol); + g_hash_table_insert(proto_short_names, (gpointer)short_name, protocol); /* Here we allocate a new header_field_info struct */ hfinfo = g_slice_new(header_field_info); @@ -5012,6 +5012,22 @@ int proto_get_id_by_filter_name(const gchar* filter_name) return protocol->proto_id; } +int proto_get_id_by_short_name(const gchar* short_name) +{ + const protocol_t *protocol = NULL; + + if(!short_name){ + fprintf(stderr, "No short name present"); + DISSECTOR_ASSERT(short_name); + } + + protocol = (const protocol_t *)g_hash_table_lookup(proto_short_names, (gpointer)short_name); + + if (protocol == NULL) + return -1; + return protocol->proto_id; +} + const char * proto_get_protocol_name(const int proto_id) { diff --git a/epan/proto.h b/epan/proto.h index cb456f8ebc..dada8a938e 100644 --- a/epan/proto.h +++ b/epan/proto.h @@ -1984,6 +1984,11 @@ WS_DLL_PUBLIC header_field_info *proto_get_next_protocol_field(const int proto_i @return proto_id */ WS_DLL_PUBLIC int proto_get_id_by_filter_name(const gchar* filter_name); +/** Given a protocol's short name. + @param short_name the protocol short name to search for + @return proto_id */ +WS_DLL_PUBLIC int proto_get_id_by_short_name(const gchar* short_name); + /** Can item # n decoding be disabled? @param proto_id protocol id (0-indexed) @return TRUE if it's a protocol, FALSE if it's not */ diff --git a/epan/stat_cmd_args.h b/epan/stat_cmd_args.h index a8bfaf60a2..499bf32a5d 100644 --- a/epan/stat_cmd_args.h +++ b/epan/stat_cmd_args.h @@ -30,6 +30,13 @@ extern "C" { #endif /* __cplusplus */ +/** Register a stat ("-z") command line argument. + * + * @param cmd The command name without arguments, e.g. "conv,tcp" or "io,stat". + * MUST be valid when other stat_cmd routines below are called. + * @param func Callbak to be invoked when the CLI argument is supplied. + * @param userdata Additional data for the callback. + */ WS_DLL_PUBLIC void register_stat_cmd_arg(const char *cmd, void (*func)(const char *arg,void* userdata), void* userdata); WS_DLL_PUBLIC gboolean process_stat_cmd_arg(char *optstr); diff --git a/tfshark.c b/tfshark.c index 008cafa376..6ac6fe06da 100644 --- a/tfshark.c +++ b/tfshark.c @@ -977,6 +977,7 @@ main(int argc, char *argv[]) register_all_plugin_tap_listeners(); #endif register_all_tap_listeners(); + conversation_table_set_gui_info(NULL); * XXX - TODO: Provide GUI function for tfshark * */ /* If invoked with the "-G" flag, we dump out information based on diff --git a/tshark.c b/tshark.c index dcd30b930d..e37e4cf04a 100644 --- a/tshark.c +++ b/tshark.c @@ -104,6 +104,7 @@ #include #include #include +#include #include #include "capture_opts.h" @@ -1198,6 +1199,7 @@ main(int argc, char *argv[]) register_all_plugin_tap_listeners(); #endif register_all_tap_listeners(); + conversation_table_set_gui_info(NULL); /* XXX - TODO: Provide "GUI" function for TShark */ /* If invoked with the "-G" flag, we dump out information based on the argument to the "-G" flag; if no argument is specified, diff --git a/ui/CMakeLists.txt b/ui/CMakeLists.txt index f0a7919107..5926d905e2 100644 --- a/ui/CMakeLists.txt +++ b/ui/CMakeLists.txt @@ -24,7 +24,7 @@ set(COMMON_UI_SRC alert_box.c capture.c capture_ui_utils.c - conversation_hash.c + conversation_ui.c decode_as_utils.c export_object.c export_object_dicom.c diff --git a/ui/Makefile.common b/ui/Makefile.common index d478e25663..e36980afc2 100644 --- a/ui/Makefile.common +++ b/ui/Makefile.common @@ -45,7 +45,7 @@ WIRESHARK_UI_SRC = \ alert_box.c \ capture.c \ capture_ui_utils.c \ - conversation_hash.c \ + conversation_ui.c \ decode_as_utils.c \ export_object.c \ export_object_dicom.c \ @@ -80,7 +80,7 @@ noinst_HEADERS = \ capture.h \ capture_globals.h \ capture_ui_utils.h \ - conversation_hash.h \ + conversation_ui.h \ decode_as_utils.h \ export_object.h \ last_open_dir.h \ diff --git a/ui/conversation_ui.c b/ui/conversation_ui.c new file mode 100644 index 0000000000..6269f054fd --- /dev/null +++ b/ui/conversation_ui.c @@ -0,0 +1,61 @@ +/* conversation_ui.c + * Copied from gtk/conversations_table.c 2003 Ronnie Sahlberg + * Helper routines common to all conversations taps. + * + * 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 "conversation_ui.h" +#include "utf8_entities.h" + +const char *column_titles[CONV_NUM_COLUMNS] = { + "Address A", + "Port A", + "Address B", + "Port B", + "Packets", + "Bytes", + "Packets A " UTF8_RIGHTWARDS_ARROW " B", + "Bytes A " UTF8_RIGHTWARDS_ARROW " B", + "Packets B " UTF8_RIGHTWARDS_ARROW " A", + "Bytes B " UTF8_RIGHTWARDS_ARROW " A", + "Rel Start", + "Duration", + "bps A " UTF8_RIGHTWARDS_ARROW " B", + "bps B " UTF8_RIGHTWARDS_ARROW " A" +}; + +const char *conn_a_title = "Connection A"; +const char *conn_b_title = "Connection B"; + + + +/* + * Editor modelines + * + * Local Variables: + * c-basic-offset: 4 + * tab-width: 8 + * indent-tabs-mode: nil + * End: + * + * ex: set shiftwidth=4 tabstop=8 expandtab: + * :indentSize=4:tabSize=8:noTabs=true: + */ diff --git a/ui/conversation_ui.h b/ui/conversation_ui.h new file mode 100644 index 0000000000..b0e02a08d9 --- /dev/null +++ b/ui/conversation_ui.h @@ -0,0 +1,76 @@ +/* conversation_ui.h + * Copied from gtk/conversations_table.h 2003 Ronnie Sahlberg + * Helper routines common to all conversations taps. + * + * 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 __CONVERSATION_UI_H__ +#define __CONVERSATION_UI_H__ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** @file + * Conversation lists. + */ + +typedef enum { + CONV_COLUMN_SRC_ADDR, + CONV_COLUMN_SRC_PORT, + CONV_COLUMN_DST_ADDR, + CONV_COLUMN_DST_PORT, + CONV_COLUMN_PACKETS, + CONV_COLUMN_BYTES, + CONV_COLUMN_PKT_AB, + CONV_COLUMN_BYTES_AB, + CONV_COLUMN_PKT_BA, + CONV_COLUMN_BYTES_BA, + CONV_COLUMN_START, + CONV_COLUMN_DURATION, + CONV_COLUMN_BPS_AB, + CONV_COLUMN_BPS_BA, + CONV_NUM_COLUMNS, + CONV_INDEX_COLUMN = CONV_NUM_COLUMNS +} column_type_e; + + +extern const char *column_titles[CONV_NUM_COLUMNS]; +extern const char *conn_a_title; +extern const char *conn_b_title; + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __CONVERSATION_UI_H__ */ + +/* + * Editor modelines + * + * Local Variables: + * c-basic-offset: 4 + * tab-width: 8 + * indent-tabs-mode: nil + * End: + * + * ex: set shiftwidth=4 tabstop=8 expandtab: + * :indentSize=4:tabSize=8:noTabs=true: + */ diff --git a/ui/gtk/CMakeLists.txt b/ui/gtk/CMakeLists.txt index 53e6e093f4..6f1b9f6079 100644 --- a/ui/gtk/CMakeLists.txt +++ b/ui/gtk/CMakeLists.txt @@ -130,21 +130,6 @@ set(WIRESHARK_TAP_SRC camel_counter.c camel_srt.c compare_stat.c - conversations_eth.c - conversations_fc.c - conversations_fddi.c - conversations_ip.c - conversations_ipv6.c - conversations_ipx.c - conversations_jxta.c - conversations_ncp.c - conversations_rsvp.c - conversations_sctp.c - conversations_tcpip.c - conversations_tr.c - conversations_udpip.c - conversations_usb.c - conversations_wlan.c dcerpc_stat.c diameter_stat.c expert_comp_dlg.c diff --git a/ui/gtk/Makefile.common b/ui/gtk/Makefile.common index cd45d6a44c..2d644d9009 100644 --- a/ui/gtk/Makefile.common +++ b/ui/gtk/Makefile.common @@ -154,21 +154,6 @@ WIRESHARK_TAP_SRC = \ camel_counter.c \ camel_srt.c \ compare_stat.c \ - conversations_eth.c \ - conversations_fc.c \ - conversations_fddi.c \ - conversations_ip.c \ - conversations_ipv6.c \ - conversations_ipx.c \ - conversations_jxta.c \ - conversations_ncp.c \ - conversations_rsvp.c \ - conversations_sctp.c \ - conversations_tcpip.c \ - conversations_tr.c \ - conversations_udpip.c \ - conversations_usb.c \ - conversations_wlan.c \ dcerpc_stat.c \ diameter_stat.c \ expert_comp_dlg.c \ diff --git a/ui/gtk/conversations_eth.c b/ui/gtk/conversations_eth.c deleted file mode 100644 index cca55f194b..0000000000 --- a/ui/gtk/conversations_eth.c +++ /dev/null @@ -1,81 +0,0 @@ -/* conversations_eth.c - * conversations_eth 2003 Ronnie Sahlberg - * - * 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 - -#include -#include -#include -#include - -#include - -#include "ui/gtk/gui_stat_menu.h" -#include "ui/gtk/conversations_table.h" - -void register_tap_listener_eth_conversation(void); - -static int -eth_conversation_packet(void *pct, packet_info *pinfo, epan_dissect_t *edt _U_, const void *vip) -{ - conversations_table *ct = (conversations_table *) pct; - const eth_hdr *ehdr=(const eth_hdr *)vip; - - add_conversation_table_data(&ct->hash, &ehdr->src, &ehdr->dst, 0, 0, 1, pinfo->fd->pkt_len, &pinfo->rel_ts, CONV_TYPE_ETHERNET, PT_NONE); - - return 1; -} - - - -static void -eth_conversation_init(const char *opt_arg, void* userdata _U_) -{ - const char *filter=NULL; - - if(!strncmp(opt_arg,"conv,eth,",9)){ - filter=opt_arg+9; - } else { - filter=NULL; - } - - init_conversation_table(CONV_TYPE_ETHERNET, filter, eth_conversation_packet); - -} - -void -eth_endpoints_cb(GtkAction *action _U_, gpointer user_data _U_) -{ - eth_conversation_init("conv,eth", NULL); -} - -void -register_tap_listener_eth_conversation(void) -{ - register_stat_cmd_arg("conv,eth", eth_conversation_init,NULL); - register_conversation_table(CONV_TYPE_ETHERNET, NULL /*filter*/, eth_conversation_packet); -} - diff --git a/ui/gtk/conversations_fc.c b/ui/gtk/conversations_fc.c deleted file mode 100644 index c8733e1e3e..0000000000 --- a/ui/gtk/conversations_fc.c +++ /dev/null @@ -1,81 +0,0 @@ -/* conversations_fc.c - * conversations_fc 2003 Ronnie Sahlberg - * - * 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 - -#include -#include -#include -#include -#include - -#include - -#include "ui/gtk/gui_stat_menu.h" -#include "ui/gtk/conversations_table.h" - -void register_tap_listener_fc_conversation(void); - -static int -fc_conversation_packet(void *pct, packet_info *pinfo, epan_dissect_t *edt _U_, const void *vip) -{ - conversations_table *ct = (conversations_table *) pct; - const fc_hdr *fchdr=(const fc_hdr *)vip; - - add_conversation_table_data(&ct->hash, &fchdr->s_id, &fchdr->d_id, 0, 0, 1, pinfo->fd->pkt_len, &pinfo->rel_ts, CONV_TYPE_FIBRE_CHANNEL, PT_NONE); - - return 1; -} - - - -static void -fc_conversation_init(const char *opt_arg, void* userdata _U_) -{ - const char *filter=NULL; - - if(!strncmp(opt_arg,"conv,fc,",8)){ - filter=opt_arg+8; - } else { - filter=NULL; - } - - init_conversation_table(CONV_TYPE_FIBRE_CHANNEL, filter, fc_conversation_packet); - -} - -void -fc_endpoints_cb(GtkAction *action _U_, gpointer user_data _U_) -{ - fc_conversation_init("conv,fc",NULL); -} - -void -register_tap_listener_fc_conversation(void) -{ - register_stat_cmd_arg("conv,fc", fc_conversation_init, NULL); - register_conversation_table(CONV_TYPE_FIBRE_CHANNEL, NULL /*filter*/, fc_conversation_packet); -} diff --git a/ui/gtk/conversations_fddi.c b/ui/gtk/conversations_fddi.c deleted file mode 100644 index bef12493f7..0000000000 --- a/ui/gtk/conversations_fddi.c +++ /dev/null @@ -1,80 +0,0 @@ -/* conversations_fddi.c - * conversations_fddi 2003 Ronnie Sahlberg - * - * 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 - -#include "epan/packet.h" -#include -#include -#include - -#include - -#include "ui/gtk/gui_stat_menu.h" -#include "ui/gtk/conversations_table.h" - -void register_tap_listener_fddi_conversation(void); - -static int -fddi_conversation_packet(void *pct, packet_info *pinfo, epan_dissect_t *edt _U_, const void *vip) -{ - conversations_table *ct = (conversations_table *) pct; - const fddi_hdr *ehdr=(const fddi_hdr *)vip; - - add_conversation_table_data(&ct->hash, &ehdr->src, &ehdr->dst, 0, 0, 1, pinfo->fd->pkt_len, &pinfo->rel_ts, CONV_TYPE_FDDI, PT_NONE); - - return 1; -} - - - -static void -fddi_conversation_init(const char *opt_arg, void* userdata _U_ ) -{ - const char *filter=NULL; - - if(!strncmp(opt_arg,"conv,fddi,",10)){ - filter=opt_arg+10; - } else { - filter=NULL; - } - - init_conversation_table(CONV_TYPE_FDDI, filter, fddi_conversation_packet); - -} - -void -fddi_endpoints_cb(GtkAction *action _U_, gpointer user_data _U_) -{ - fddi_conversation_init("conv,fddi",NULL); -} - -void -register_tap_listener_fddi_conversation(void) -{ - register_stat_cmd_arg("conv,fddi", fddi_conversation_init,NULL); - register_conversation_table(CONV_TYPE_FDDI, NULL /*filter*/, fddi_conversation_packet); -} diff --git a/ui/gtk/conversations_ip.c b/ui/gtk/conversations_ip.c deleted file mode 100644 index 280329728a..0000000000 --- a/ui/gtk/conversations_ip.c +++ /dev/null @@ -1,78 +0,0 @@ -/* conversations_ip.c - * conversations_ip 2003 Ronnie Sahlberg - * - * 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 - -#include -#include -#include -#include - -#include - -#include "ui/gtk/gui_stat_menu.h" -#include "ui/gtk/conversations_table.h" - -void register_tap_listener_ip_conversation(void); - -static int -ip_conversation_packet(void *pct, packet_info *pinfo, epan_dissect_t *edt _U_, const void *vip) -{ - conversations_table *ct = (conversations_table *) pct; - const ws_ip *iph=(const ws_ip *)vip; - - add_conversation_table_data(&ct->hash, &iph->ip_src, &iph->ip_dst, 0, 0, 1, pinfo->fd->pkt_len, &pinfo->rel_ts, CONV_TYPE_IPV4, PT_NONE); - - return 1; -} - -static void -ip_conversation_init(const char *opt_arg, void* userdata _U_) -{ - const char *filter=NULL; - - if(!strncmp(opt_arg,"conv,ip,",8)){ - filter=opt_arg+8; - } else { - filter=NULL; - } - - init_conversation_table(CONV_TYPE_IPV4, filter, ip_conversation_packet); - -} - -void -ip_endpoints_cb(GtkAction *action _U_, gpointer user_data _U_) -{ - ip_conversation_init("conv,ip",NULL); -} - -void -register_tap_listener_ip_conversation(void) -{ - register_stat_cmd_arg("conv,ip", ip_conversation_init,NULL); - register_conversation_table(CONV_TYPE_IPV4, NULL /*filter*/, ip_conversation_packet); -} diff --git a/ui/gtk/conversations_ipv6.c b/ui/gtk/conversations_ipv6.c deleted file mode 100644 index 9634e650e2..0000000000 --- a/ui/gtk/conversations_ipv6.c +++ /dev/null @@ -1,87 +0,0 @@ -/* conversations_ipv6.c 2009 Clif Bratcher - * Modified from conversations_ip 2003 Ronnie Sahlberg - * - * 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 - -#include -#include -#include -#include - -#include - -#include "ui/gtk/gui_stat_menu.h" -#include "ui/gtk/conversations_table.h" - -void register_tap_listener_ipv6_conversation(void); - -static int -ipv6_conversation_packet(void *pct, packet_info *pinfo, epan_dissect_t *edt _U_, const void *vip) -{ - conversations_table *ct = (conversations_table *) pct; - const struct ip6_hdr *ip6h = (const struct ip6_hdr *)vip; - address src; - address dst; - - /* Addresses aren't implemented as 'address' type in struct ip6_hdr */ - src.type = dst.type = AT_IPv6; - src.len = dst.len = sizeof(struct e_in6_addr); - src.data = &ip6h->ip6_src; - dst.data = &ip6h->ip6_dst; - - add_conversation_table_data(&ct->hash, &src, &dst, 0, 0, 1, pinfo->fd->pkt_len, &pinfo->rel_ts, CONV_TYPE_IPV6, PT_NONE); - - return 1; -} - - -static void -ipv6_conversation_init(const char *opt_arg, void *userdata _U_) -{ - const char *filter=NULL; - - if(!strncmp(opt_arg, "conv,ipv6,", 10)) { - filter = opt_arg + 10; - } - else { - filter = NULL; - } - - init_conversation_table(CONV_TYPE_IPV6, filter, ipv6_conversation_packet); -} - -void -ipv6_endpoints_cb(GtkAction *action _U_, gpointer user_data _U_) -{ - ipv6_conversation_init("conv,ipv6", NULL); -} - -void -register_tap_listener_ipv6_conversation(void) -{ - register_stat_cmd_arg("conv,ipv6", ipv6_conversation_init, NULL); - register_conversation_table(CONV_TYPE_IPV6, NULL /*filter*/, ipv6_conversation_packet); -} diff --git a/ui/gtk/conversations_ipx.c b/ui/gtk/conversations_ipx.c deleted file mode 100644 index d1fa85086e..0000000000 --- a/ui/gtk/conversations_ipx.c +++ /dev/null @@ -1,80 +0,0 @@ -/* conversations_ipx.c - * conversations_ipx 2003 Ronnie Sahlberg - * - * 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 - -#include -#include -#include -#include - -#include - -#include "ui/gtk/gui_stat_menu.h" -#include "ui/gtk/conversations_table.h" - -void register_tap_listener_ipx_conversation(void); - -static int -ipx_conversation_packet(void *pct, packet_info *pinfo, epan_dissect_t *edt _U_, const void *vip) -{ - conversations_table *ct = (conversations_table *) pct; - const ipxhdr_t *ipxh=(const ipxhdr_t *)vip; - - add_conversation_table_data(&ct->hash, &ipxh->ipx_src, &ipxh->ipx_dst, 0, 0, 1, pinfo->fd->pkt_len, &pinfo->rel_ts, CONV_TYPE_IPX, PT_NONE); - - return 1; -} - - - -static void -ipx_conversation_init(const char *opt_arg, void* userdata _U_) -{ - const char *filter=NULL; - - if(!strncmp(opt_arg,"conv,ipx,",9)){ - filter=opt_arg+9; - } else { - filter=NULL; - } - - init_conversation_table(CONV_TYPE_IPX, filter, ipx_conversation_packet); - -} - -void -ipx_endpoints_cb(GtkAction *action _U_, gpointer user_data _U_) -{ - ipx_conversation_init("conv,ipx",NULL); -} - -void -register_tap_listener_ipx_conversation(void) -{ - register_stat_cmd_arg("conv,ipx", ipx_conversation_init,NULL); - register_conversation_table(CONV_TYPE_IPX, NULL /*filter*/, ipx_conversation_packet); -} diff --git a/ui/gtk/conversations_jxta.c b/ui/gtk/conversations_jxta.c deleted file mode 100644 index 472a3207a5..0000000000 --- a/ui/gtk/conversations_jxta.c +++ /dev/null @@ -1,89 +0,0 @@ -/* conversations_jxta.c - * conversations_jxta copyright (c) 2005 Mike Duigou - * copied from conversations_sctp.c - * - * 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 - -#include -#include -#include -#include - -#include - -#include "ui/gtk/gui_stat_menu.h" -#include "ui/gtk/conversations_table.h" - -void register_tap_listener_jxta_conversation(void); - -static int -jxta_conversation_packet(void *pct, packet_info *pinfo _U_, epan_dissect_t *edt _U_, const void *vip) -{ - conversations_table *ct = (conversations_table *) pct; - const jxta_tap_header *jxtahdr = (const jxta_tap_header *) vip; - - add_conversation_table_data(&ct->hash, - &jxtahdr->src_address, - &jxtahdr->dest_address, - 0, - 0, - 1, - jxtahdr->size, - NULL, - CONV_TYPE_JXTA, - PT_NONE); - - - return 1; -} - -static void -jxta_conversation_init(const char *opt_arg, void* userdata _U_) -{ - const char *filter=NULL; - - if(!strncmp(opt_arg,"conv,jxta,",10)){ - filter=opt_arg+10; - } else { - filter=NULL; - } - - init_conversation_table(CONV_TYPE_JXTA, filter, jxta_conversation_packet); - -} - -void -jxta_conversation_cb(GtkAction *action _U_, gpointer user_data _U_) -{ - jxta_conversation_init("conv,jxta",NULL); -} - -void -register_tap_listener_jxta_conversation(void) -{ - register_stat_cmd_arg("conv,jxta", jxta_conversation_init,NULL); - register_conversation_table(CONV_TYPE_JXTA, NULL /*filter*/, jxta_conversation_packet); -} diff --git a/ui/gtk/conversations_ncp.c b/ui/gtk/conversations_ncp.c deleted file mode 100644 index 4ef3e3bb8e..0000000000 --- a/ui/gtk/conversations_ncp.c +++ /dev/null @@ -1,81 +0,0 @@ -/* conversations_ncp.c 2005 Greg Morris - * modified from conversations_eth.c 2003 Ronnie Sahlberg - * - * 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 - -#include -#include -#include -#include - -#include - -#include "ui/gtk/gui_stat_menu.h" -#include "ui/gtk/conversations_table.h" - -void register_tap_listener_ncp_conversation(void); - -static int -ncp_conversation_packet(void *pct, packet_info *pinfo, epan_dissect_t *edt _U_, const void *vip) -{ - conversations_table *ct = (conversations_table *) pct; - const struct ncp_common_header *ncph=(const struct ncp_common_header *)vip; - guint32 connection; - - connection = (ncph->conn_high * 256)+ncph->conn_low; - if (connection < 65535) { - add_conversation_table_data(&ct->hash, &pinfo->src, &pinfo->dst, connection, connection, 1, pinfo->fd->pkt_len, &pinfo->rel_ts, CONV_TYPE_NCP, PT_NCP); - } - - return 1; -} - -static void -ncp_conversation_init(const char *opt_arg, void* userdata _U_) -{ - const char *filter=NULL; - - if(!strncmp(opt_arg,"conv,ncp,",9)){ - filter=opt_arg+9; - } else { - filter=NULL; - } - - init_conversation_table(CONV_TYPE_NCP, filter, ncp_conversation_packet); -} - -void -ncp_endpoints_cb(GtkAction *action _U_, gpointer user_data _U_) -{ - ncp_conversation_init("conv,ncp",NULL); -} - -void -register_tap_listener_ncp_conversation(void) -{ - register_stat_cmd_arg("conv,ncp", ncp_conversation_init,NULL); - register_conversation_table(CONV_TYPE_NCP, NULL /*filter*/, ncp_conversation_packet); -} diff --git a/ui/gtk/conversations_rsvp.c b/ui/gtk/conversations_rsvp.c deleted file mode 100644 index 1393c3db71..0000000000 --- a/ui/gtk/conversations_rsvp.c +++ /dev/null @@ -1,82 +0,0 @@ -/* conversations_rsvp.c - * conversations_rsvp.c August 2005, Manu Pathak - * - * 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 - -#include -#include -#include -#include - -#include - -#include "ui/gtk/gui_stat_menu.h" -#include "ui/gtk/conversations_table.h" - -void register_tap_listener_rsvp_conversation(void); - -static int -rsvp_conversation_packet(void *pct, packet_info *pinfo, epan_dissect_t *edt _U_, const void *vip) -{ - conversations_table *ct = (conversations_table *) pct; - const rsvp_conversation_info *rsvph = (const rsvp_conversation_info *)vip; - - add_conversation_table_data(&ct->hash, - &rsvph->source, &rsvph->destination, 0, 0, 1, - pinfo->fd->pkt_len, &pinfo->rel_ts, CONV_TYPE_RSVP, PT_NONE); - - return 1; -} - -static void -rsvp_conversation_init(const char *opt_arg, void* userdata _U_) -{ - const char *filter=NULL; - - if(!strncmp(opt_arg,"conv,rsvp,",10)){ - filter=opt_arg+10; - } else { - filter=NULL; - } - - init_conversation_table(CONV_TYPE_RSVP, filter, - rsvp_conversation_packet); - -} - -void -rsvp_endpoints_cb(GtkAction *action _U_, gpointer user_data _U_) -{ - rsvp_conversation_init("conv,rsvp",NULL); -} - -void -register_tap_listener_rsvp_conversation(void) -{ - register_stat_cmd_arg("conv,rsvp", rsvp_conversation_init,NULL); - register_conversation_table(CONV_TYPE_RSVP, NULL /*filter*/, - rsvp_conversation_packet); -} diff --git a/ui/gtk/conversations_sctp.c b/ui/gtk/conversations_sctp.c deleted file mode 100644 index 5b35be16a9..0000000000 --- a/ui/gtk/conversations_sctp.c +++ /dev/null @@ -1,88 +0,0 @@ -/* conversations_sctp.c - * conversations_sctp 2005 Oleg Terletsky - * - * 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 - -#include -#include -#include -#include - -#include - -#include "ui/gtk/gui_stat_menu.h" -#include "ui/gtk/conversations_table.h" - -void register_tap_listener_sctp_conversation(void); - -static int -sctp_conversation_packet(void *pct, packet_info *pinfo, epan_dissect_t *edt _U_, const void *vip) -{ - conversations_table *ct = (conversations_table *) pct; - const struct _sctp_info *sctphdr=(const struct _sctp_info *)vip; - - add_conversation_table_data(&ct->hash, - &sctphdr->ip_src, - &sctphdr->ip_dst, - sctphdr->sport, - sctphdr->dport, - 1, - pinfo->fd->pkt_len, - &pinfo->rel_ts, - CONV_TYPE_SCTP, - PT_SCTP); - - - return 1; -} - -static void -sctp_conversation_init(const char *opt_arg, void* userdata _U_) -{ - const char *filter=NULL; - - if(!strncmp(opt_arg,"conv,sctp,",10)){ - filter=opt_arg+10; - } else { - filter=NULL; - } - - init_conversation_table(CONV_TYPE_SCTP, filter, sctp_conversation_packet); - -} - -void -sctp_conversation_cb(GtkAction *action _U_, gpointer user_data _U_) -{ - sctp_conversation_init("conv,sctp",NULL); -} - -void -register_tap_listener_sctp_conversation(void) -{ - register_stat_cmd_arg("conv,sctp", sctp_conversation_init,NULL); - register_conversation_table(CONV_TYPE_SCTP, NULL /*filter*/, sctp_conversation_packet); -} diff --git a/ui/gtk/conversations_table.c b/ui/gtk/conversations_table.c index 2ab15ee7b3..efc0daa48d 100644 --- a/ui/gtk/conversations_table.c +++ b/ui/gtk/conversations_table.c @@ -131,7 +131,9 @@ reset_ct_table_data(conversations_table *ct) static void reset_ct_table_data_cb(void *arg) { - reset_ct_table_data((conversations_table *)arg); + conv_hash_t *hash = (conv_hash_t*)arg; + + reset_ct_table_data((conversations_table *)hash->user_data); } static void @@ -139,7 +141,7 @@ ct_win_destroy_cb(GtkWindow *win _U_, gpointer data) { conversations_table *conversations=(conversations_table *)data; - remove_tap_listener(conversations); + remove_tap_listener(&conversations->hash); reset_ct_table_data(conversations); g_free(conversations); @@ -1757,7 +1759,9 @@ draw_ct_table_data(conversations_table *ct) static void draw_ct_table_data_cb(void *arg) { - draw_ct_table_data((conversations_table *)arg); + conv_hash_t *hash = (conv_hash_t*)arg; + + draw_ct_table_data((conversations_table *)hash->user_data); } typedef struct { @@ -2025,8 +2029,9 @@ init_ct_table_page(conversations_table *conversations, GtkWidget *vbox, gboolean gtk_tree_view_set_headers_clickable(conversations->table, TRUE); gtk_tree_view_set_reorderable (conversations->table, TRUE); - conversations->hash.conv_array=NULL; - conversations->hash.hashtable=NULL; + conversations->hash.conv_array = NULL; + conversations->hash.hashtable = NULL; + conversations->hash.user_data = conversations; sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(conversations->table)); gtk_tree_selection_set_mode(sel, GTK_SELECTION_SINGLE); @@ -2035,7 +2040,7 @@ init_ct_table_page(conversations_table *conversations, GtkWidget *vbox, gboolean ct_create_popup_menu(conversations); /* register the tap and rerun the taps on the packet list */ - error_string=register_tap_listener(tap_name, conversations, filter, 0, reset_ct_table_data_cb, packet_func, + error_string=register_tap_listener(tap_name, &conversations->hash, filter, 0, reset_ct_table_data_cb, packet_func, draw_ct_table_data_cb); if(error_string){ simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", error_string->str); @@ -2163,12 +2168,12 @@ follow_stream_cb(GtkWidget *follow_stream_bt, gpointer data _U_) void -init_conversation_table(conversation_type_e conv_type, const char *filter, tap_packet_cb packet_func) +init_conversation_table(struct register_ct* ct, const char *filter) { conversations_table *conversations; char *display_name; char title[256]; - const char *table_name = conversation_title(conv_type); + const char *table_name = proto_get_protocol_short_name(find_protocol_by_id(get_conversation_proto_id(ct))); GtkWidget *vbox; GtkWidget *bbox; GtkWidget *close_bt, *help_bt; @@ -2199,9 +2204,9 @@ init_conversation_table(conversation_type_e conv_type, const char *filter, tap_p gtk_container_set_border_width(GTK_CONTAINER(vbox), DLG_OUTER_MARGIN); ret = init_ct_table_page(conversations, vbox, - conversation_hide_ports(conv_type), - table_name, conversation_tap_name(conv_type), - filter, packet_func); + get_conversation_hide_ports(ct), + table_name, proto_get_protocol_filter_name(get_conversation_proto_id(ct)), + filter, get_conversation_packet_func(ct)); if(ret == FALSE) { g_free(conversations); return; @@ -2341,14 +2346,14 @@ ct_win_destroy_notebook_cb(GtkWindow *win _U_, gpointer data) } static conversations_table * -init_ct_notebook_page_cb(gboolean hide_ports, const char *table_name, const char *tap_name, const char *filter, tap_packet_cb packet_func) +init_ct_notebook_page_cb(register_ct_t *table, const char *filter) { gboolean ret; GtkWidget *page_vbox; conversations_table *conversations; conversations=g_new0(conversations_table,1); - conversations->name=table_name; + conversations->name=proto_get_protocol_short_name(find_protocol_by_id(get_conversation_proto_id(table))); conversations->filter=filter; conversations->resolve_names=TRUE; conversations->use_dfilter=FALSE; @@ -2357,7 +2362,8 @@ init_ct_notebook_page_cb(gboolean hide_ports, const char *table_name, const char conversations->win = page_vbox; gtk_container_set_border_width(GTK_CONTAINER(page_vbox), 6); - ret = init_ct_table_page(conversations, page_vbox, hide_ports, table_name, tap_name, filter, packet_func); + ret = init_ct_table_page(conversations, page_vbox, get_conversation_hide_ports(table), conversations->name, + proto_get_protocol_filter_name(get_conversation_proto_id(table)), filter, get_conversation_packet_func(table)); if(ret == FALSE) { g_free(conversations); return NULL; @@ -2366,35 +2372,6 @@ init_ct_notebook_page_cb(gboolean hide_ports, const char *table_name, const char return conversations; } - -typedef struct { - gboolean hide_ports; /* hide TCP / UDP port columns */ - const char *table_name; /* GUI output name */ - const char *tap_name; /* internal name */ - const char *filter; /* display filter string (unused) */ - tap_packet_cb packet_func; /* function to be called for new incoming packets */ -} register_ct_t; - - -static GSList *registered_ct_tables = NULL; - -void -register_conversation_table(conversation_type_e conv_type, const char *filter, tap_packet_cb packet_func) -{ - register_ct_t *table; - - table = g_new(register_ct_t,1); - - table->hide_ports = conversation_hide_ports(conv_type); - table->table_name = conversation_title(conv_type); - table->tap_name = conversation_tap_name(conv_type); - table->filter = filter; - table->packet_func = packet_func; - - registered_ct_tables = g_slist_append(registered_ct_tables, table); -} - - static void ct_resolve_toggle_dest(GtkWidget *widget, gpointer data) { @@ -2438,11 +2415,37 @@ ct_filter_toggle_dest(GtkWidget *widget, gpointer data) } } +typedef struct _init_ct_page_data { + int page; + void ** pages; + GtkWidget *nb; + GtkWidget *win; +} init_ct_page_data; + +static void +init_ct_page(gpointer data, gpointer user_data) +{ + register_ct_t *table = (register_ct_t*)data; + init_ct_page_data* ct_page_data = (init_ct_page_data*)user_data; + + conversations_table *conversations; + GtkWidget *page_lb; + + conversations = init_ct_notebook_page_cb(table, NULL /*filter*/); + if (conversations) { + + g_object_set_data(G_OBJECT(conversations->win), CONV_PTR_KEY, conversations); + page_lb = gtk_label_new(""); + gtk_notebook_append_page(GTK_NOTEBOOK(ct_page_data->nb), conversations->win, page_lb); + conversations->win = ct_page_data->win; + conversations->page_lb = page_lb; + ct_page_data->pages[++ct_page_data->page] = conversations; + } +} void init_conversation_notebook_cb(GtkWidget *w _U_, gpointer d _U_) { - conversations_table *conversations; char *display_name; char title[256]; GtkWidget *vbox; @@ -2452,19 +2455,16 @@ init_conversation_notebook_cb(GtkWidget *w _U_, gpointer d _U_) GtkWidget *win; GtkWidget *resolv_cb; GtkWidget *filter_cb; - int page; void ** pages; GtkWidget *nb; - GtkWidget *page_lb; - GSList *current_table; - register_ct_t *registered; GtkWidget *copy_bt; GtkWidget *follow_stream_bt; GtkWidget *graph_a_b_bt; GtkWidget *graph_b_a_bt; window_geometry_t tl_geom; + init_ct_page_data ct_page_iter_data; - pages = (void **)g_malloc(sizeof(void *) * (g_slist_length(registered_ct_tables) + 1)); + pages = (void **)g_malloc(sizeof(void *) * (conversation_table_get_num() + 1)); display_name = cf_get_display_name(&cfile); g_snprintf(title, sizeof(title), "Conversations: %s", display_name); @@ -2483,25 +2483,14 @@ init_conversation_notebook_cb(GtkWidget *w _U_, gpointer d _U_) gtk_box_pack_start(GTK_BOX (vbox), nb, TRUE, TRUE, 0); g_object_set_data(G_OBJECT(nb), NB_PAGES_KEY, pages); - page = 0; + ct_page_iter_data.page = 0; + ct_page_iter_data.pages = pages; + ct_page_iter_data.nb = nb; + ct_page_iter_data.win = win; - current_table = registered_ct_tables; - while(current_table) { - registered = (register_ct_t *)current_table->data; - conversations = init_ct_notebook_page_cb(registered->hide_ports, registered->table_name, registered->tap_name, - registered->filter, registered->packet_func); - if (conversations) { - g_object_set_data(G_OBJECT(conversations->win), CONV_PTR_KEY, conversations); - page_lb = gtk_label_new(""); - gtk_notebook_append_page(GTK_NOTEBOOK(nb), conversations->win, page_lb); - conversations->win = win; - conversations->page_lb = page_lb; - pages[++page] = conversations; - } - current_table = g_slist_next(current_table); - } + conversation_table_iterate_tables(init_ct_page, &ct_page_iter_data); - pages[0] = GINT_TO_POINTER(page); + pages[0] = GINT_TO_POINTER(ct_page_iter_data.page); hbox = ws_gtk_box_new(GTK_ORIENTATION_HORIZONTAL, DLG_UNRELATED_SPACING, FALSE); gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); @@ -2538,13 +2527,13 @@ init_conversation_notebook_cb(GtkWidget *w _U_, gpointer d _U_) copy_bt = (GtkWidget *)g_object_get_data(G_OBJECT(bbox), GTK_STOCK_COPY); gtk_widget_set_tooltip_text(copy_bt, "Copy all statistical values of this page to the clipboard in CSV (Comma Separated Values) format."); g_signal_connect(copy_bt, "clicked", G_CALLBACK(copy_as_csv_cb), NULL); - g_object_set_data(G_OBJECT(copy_bt), CONV_PTR_KEY, pages[page]); + g_object_set_data(G_OBJECT(copy_bt), CONV_PTR_KEY, pages[ct_page_iter_data.page]); /* Graph A->B */ graph_a_b_bt = (GtkWidget *)g_object_get_data(G_OBJECT(bbox), WIRESHARK_STOCK_GRAPH_A_B); gtk_widget_set_tooltip_text(graph_a_b_bt, "Graph traffic from address A to address B."); g_object_set_data(G_OBJECT(graph_a_b_bt), E_DFILTER_TE_KEY, main_display_filter_widget); - g_object_set_data(G_OBJECT(graph_a_b_bt), CONV_PTR_KEY, pages[page]); + g_object_set_data(G_OBJECT(graph_a_b_bt), CONV_PTR_KEY, pages[ct_page_iter_data.page]); g_signal_connect(graph_a_b_bt, "clicked", G_CALLBACK(graph_cb), (gpointer)FALSE); g_object_set_data(G_OBJECT(nb), GRAPH_A_B_BT_KEY, graph_a_b_bt); @@ -2552,7 +2541,7 @@ init_conversation_notebook_cb(GtkWidget *w _U_, gpointer d _U_) graph_b_a_bt = (GtkWidget *)g_object_get_data(G_OBJECT(bbox), WIRESHARK_STOCK_GRAPH_B_A); gtk_widget_set_tooltip_text(graph_b_a_bt, "Graph traffic from address B to address A."); g_object_set_data(G_OBJECT(graph_b_a_bt), E_DFILTER_TE_KEY, main_display_filter_widget); - g_object_set_data(G_OBJECT(graph_b_a_bt), CONV_PTR_KEY, pages[page]); + g_object_set_data(G_OBJECT(graph_b_a_bt), CONV_PTR_KEY, pages[ct_page_iter_data.page]); g_signal_connect(graph_b_a_bt, "clicked", G_CALLBACK(graph_cb), (gpointer)TRUE); g_object_set_data(G_OBJECT(nb), GRAPH_B_A_BT_KEY, graph_b_a_bt); @@ -2560,7 +2549,7 @@ init_conversation_notebook_cb(GtkWidget *w _U_, gpointer d _U_) follow_stream_bt = (GtkWidget *)g_object_get_data(G_OBJECT(bbox), WIRESHARK_STOCK_FOLLOW_STREAM); gtk_widget_set_tooltip_text(follow_stream_bt, "Follow Stream."); g_object_set_data(G_OBJECT(follow_stream_bt), E_DFILTER_TE_KEY, main_display_filter_widget); - g_object_set_data(G_OBJECT(follow_stream_bt), CONV_PTR_KEY, pages[page]); + g_object_set_data(G_OBJECT(follow_stream_bt), CONV_PTR_KEY, pages[ct_page_iter_data.page]); g_signal_connect(follow_stream_bt, "clicked", G_CALLBACK(follow_stream_cb), NULL); g_object_set_data(G_OBJECT(nb), FOLLOW_STREAM_BT_KEY, follow_stream_bt); @@ -2581,6 +2570,15 @@ init_conversation_notebook_cb(GtkWidget *w _U_, gpointer d _U_) gdk_window_raise(gtk_widget_get_window(win)); } +void conversation_endpoint_cb(register_ct_t* table) +{ + char cmd_str[50]; + + g_snprintf(cmd_str, 50, "conv,%s", proto_get_protocol_filter_name(get_conversation_proto_id(table))); + + dissector_conversation_init(cmd_str, table); +} + /* * Editor modelines * diff --git a/ui/gtk/conversations_table.h b/ui/gtk/conversations_table.h index 582af54d3c..e4062b5327 100644 --- a/ui/gtk/conversations_table.h +++ b/ui/gtk/conversations_table.h @@ -25,7 +25,8 @@ #define __CONVERSATIONS_TABLE_H__ #include -#include +#include +#include /** @file * Conversation definitions. @@ -52,19 +53,12 @@ typedef struct _conversations_table { int reselection_idx; /**< conversation index to reselect */ } conversations_table; -/** Register the conversation table for the multiple conversation window. - * - * @param filter the optional filter name or NULL - * @param packet_func the function to be called for each incoming packet - */ -extern void register_conversation_table(conversation_type_e conv_type, const char *filter, tap_packet_cb packet_func); - /** Init the conversation table for the single conversation window. * * @param filter the optional filter name or NULL * @param packet_func the function to be called for each incoming packet */ -extern void init_conversation_table(conversation_type_e conv_type, const char *filter, tap_packet_cb packet_func); +extern void init_conversation_table(struct register_ct* ct, const char *filter); /** Callback for "Conversations" statistics item. * @@ -73,4 +67,10 @@ extern void init_conversation_table(conversation_type_e conv_type, const char *f */ extern void init_conversation_notebook_cb(GtkWidget *widget, gpointer data); +/** Function called to instantiate the "GTK conversation table display" + * + * @param table conversation table to be created + */ +extern void conversation_endpoint_cb(register_ct_t* table); + #endif /* __CONVERSATIONS_TABLE_H__ */ diff --git a/ui/gtk/conversations_tcpip.c b/ui/gtk/conversations_tcpip.c deleted file mode 100644 index 0491c50fd2..0000000000 --- a/ui/gtk/conversations_tcpip.c +++ /dev/null @@ -1,80 +0,0 @@ -/* conversations_tcpip.c - * conversations_tcpip 2003 Ronnie Sahlberg - * - * 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 - -#include -#include -#include -#include - -#include - -#include "ui/gtk/gui_stat_menu.h" -#include "ui/gtk/conversations_table.h" - -void register_tap_listener_tcpip_conversation(void); - -static int -tcpip_conversation_packet(void *pct, packet_info *pinfo, epan_dissect_t *edt _U_, const void *vip) -{ - conversations_table *ct = (conversations_table *) pct; - const struct tcpheader *tcphdr=(const struct tcpheader *)vip; - - add_conversation_table_data_with_conv_id(&ct->hash, &tcphdr->ip_src, &tcphdr->ip_dst, tcphdr->th_sport, tcphdr->th_dport, (conv_id_t) tcphdr->th_stream, 1, pinfo->fd->pkt_len, &pinfo->rel_ts, CONV_TYPE_TCP, PT_TCP); - - return 1; -} - - - -static void -tcpip_conversation_init(const char *opt_arg, void* userdata _U_) -{ - const char *filter=NULL; - - if(!strncmp(opt_arg,"conv,tcp,",9)){ - filter=opt_arg+9; - } else { - filter=NULL; - } - - init_conversation_table(CONV_TYPE_TCP, filter, tcpip_conversation_packet); - -} - -void -tcpip_conversation_cb(GtkAction *action _U_, gpointer user_data _U_) -{ - tcpip_conversation_init("conv,tcp",NULL); -} - -void -register_tap_listener_tcpip_conversation(void) -{ - register_stat_cmd_arg("conv,tcp", tcpip_conversation_init,NULL); - register_conversation_table(CONV_TYPE_TCP, NULL /*filter*/, tcpip_conversation_packet); -} diff --git a/ui/gtk/conversations_tr.c b/ui/gtk/conversations_tr.c deleted file mode 100644 index 0d0b975591..0000000000 --- a/ui/gtk/conversations_tr.c +++ /dev/null @@ -1,80 +0,0 @@ -/* conversations_tr.c - * conversations_tr 2003 Ronnie Sahlberg - * - * 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 - -#include -#include -#include -#include - -#include - -#include "ui/gtk/gui_stat_menu.h" -#include "ui/gtk/conversations_table.h" - -void register_tap_listener_tr_conversation(void); - -static int -tr_conversation_packet(void *pct, packet_info *pinfo, epan_dissect_t *edt _U_, const void *vip) -{ - conversations_table *ct = (conversations_table *) pct; - const tr_hdr *trhdr=(const tr_hdr *)vip; - - add_conversation_table_data(&ct->hash, &trhdr->src, &trhdr->dst, 0, 0, 1, pinfo->fd->pkt_len, &pinfo->rel_ts, CONV_TYPE_TOKEN_RING, PT_NONE); - - return 1; -} - - - -static void -tr_conversation_init(const char *opt_arg, void* userdata _U_) -{ - const char *filter=NULL; - - if(!strncmp(opt_arg,"conv,tr,",8)){ - filter=opt_arg+8; - } else { - filter=NULL; - } - - init_conversation_table(CONV_TYPE_TOKEN_RING, filter, tr_conversation_packet); - -} - -void -tr_conversation_cb(GtkAction *action _U_, gpointer user_data _U_) -{ - tr_conversation_init("conv,tr",NULL); -} - -void -register_tap_listener_tr_conversation(void) -{ - register_stat_cmd_arg("conv,tr", tr_conversation_init, NULL); - register_conversation_table(CONV_TYPE_TOKEN_RING, NULL /*filter*/, tr_conversation_packet); -} diff --git a/ui/gtk/conversations_udpip.c b/ui/gtk/conversations_udpip.c deleted file mode 100644 index 7663d4a335..0000000000 --- a/ui/gtk/conversations_udpip.c +++ /dev/null @@ -1,80 +0,0 @@ -/* conversations_udpip.c - * conversations_udpip 2003 Ronnie Sahlberg - * - * 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 - -#include -#include -#include -#include - -#include - -#include "ui/gtk/gui_stat_menu.h" -#include "ui/gtk/conversations_table.h" - -void register_tap_listener_udpip_conversation(void); - -static int -udpip_conversation_packet(void *pct, packet_info *pinfo, epan_dissect_t *edt _U_, const void *vip) -{ - conversations_table *ct = (conversations_table *) pct; - const e_udphdr *udphdr=(const e_udphdr *)vip; - - add_conversation_table_data(&ct->hash, &udphdr->ip_src, &udphdr->ip_dst, udphdr->uh_sport, udphdr->uh_dport, 1, pinfo->fd->pkt_len, &pinfo->rel_ts, CONV_TYPE_UDP, PT_UDP); - - return 1; -} - - - -static void -udpip_conversation_init(const char *opt_arg, void* userdata _U_) -{ - const char *filter=NULL; - - if(!strncmp(opt_arg,"conv,udp,",9)){ - filter=opt_arg+9; - } else { - filter=NULL; - } - - init_conversation_table(CONV_TYPE_UDP, filter, udpip_conversation_packet); - -} - -void -udpip_conversation_cb(GtkAction *action _U_, gpointer user_data _U_) -{ - udpip_conversation_init("conv,udp",NULL); -} - -void -register_tap_listener_udpip_conversation(void) -{ - register_stat_cmd_arg("conv,udp", udpip_conversation_init, NULL); - register_conversation_table(CONV_TYPE_UDP, NULL /*filter*/, udpip_conversation_packet); -} diff --git a/ui/gtk/conversations_usb.c b/ui/gtk/conversations_usb.c deleted file mode 100644 index a77b3327ca..0000000000 --- a/ui/gtk/conversations_usb.c +++ /dev/null @@ -1,78 +0,0 @@ -/* conversations_usb.c 2007 Jon Smirl - * modified from conversations_eth.c 2003 Ronnie Sahlberg - * - * 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 - -#include -#include -#include - -#include - -#include "ui/gtk/gui_stat_menu.h" -#include "ui/gtk/conversations_table.h" - -void register_tap_listener_usb_conversation(void); - -static int -usb_conversation_packet(void *pct, packet_info *pinfo, epan_dissect_t *edt _U_, const void *vip _U_) -{ - conversations_table *ct = (conversations_table *) pct; - - add_conversation_table_data(&ct->hash, &pinfo->src, &pinfo->dst, 0, 0, 1, pinfo->fd->pkt_len, &pinfo->rel_ts, CONV_TYPE_USB, PT_NONE); - - return 1; -} - - - -static void -usb_conversation_init(const char *opt_arg, void* userdata _U_) -{ - const char *filter=NULL; - - if (!strncmp(opt_arg, "conv,usb,", 9)) { - filter = opt_arg + 9; - } else { - filter = NULL; - } - - init_conversation_table(CONV_TYPE_USB, filter, usb_conversation_packet); - -} - -void -usb_endpoints_cb(GtkAction *action _U_, gpointer user_data _U_) -{ - usb_conversation_init("conv,usb", NULL); -} - -void -register_tap_listener_usb_conversation(void) -{ - register_stat_cmd_arg("conv,usb", usb_conversation_init, NULL); - register_conversation_table(CONV_TYPE_USB, NULL /*filter*/, usb_conversation_packet); -} diff --git a/ui/gtk/conversations_wlan.c b/ui/gtk/conversations_wlan.c deleted file mode 100644 index e9b4e6e35c..0000000000 --- a/ui/gtk/conversations_wlan.c +++ /dev/null @@ -1,80 +0,0 @@ -/* conversations_wlan.c 2004 Giles Scott - * modified from conversations_eth.c 2003 Ronnie Sahlberg - * - * 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 - -#include -#include -#include -#include - -#include - -#include "ui/gtk/gui_stat_menu.h" -#include "ui/gtk/conversations_table.h" - -void register_tap_listener_wlan_conversation(void); - -static int -wlan_conversation_packet(void *pct, packet_info *pinfo, epan_dissect_t *edt _U_, const void *vip) -{ - conversations_table *ct = (conversations_table *) pct; - const wlan_hdr *whdr=(const wlan_hdr *)vip; - - add_conversation_table_data(&ct->hash, &whdr->src, &whdr->dst, 0, 0, 1, pinfo->fd->pkt_len, &pinfo->rel_ts, CONV_TYPE_WLAN, PT_NONE); - - return 1; -} - - - -static void -wlan_conversation_init(const char *opt_arg, void* userdata _U_) -{ - const char *filter=NULL; - - if(!strncmp(opt_arg,"conv,wlan,",10)){ - filter=opt_arg+10; - } else { - filter=NULL; - } - - init_conversation_table(CONV_TYPE_WLAN, filter, wlan_conversation_packet); - -} - -void -wlan_endpoints_cb(GtkAction *action _U_, gpointer user_data _U_) -{ - wlan_conversation_init("conv,wlan",NULL); -} - -void -register_tap_listener_wlan_conversation(void) -{ - register_stat_cmd_arg("conv,wlan", wlan_conversation_init,NULL); - register_conversation_table(CONV_TYPE_WLAN, NULL /*filter*/, wlan_conversation_packet); -} diff --git a/ui/gtk/hostlist_ncp.c b/ui/gtk/hostlist_ncp.c index d605d504ff..9889890c37 100644 --- a/ui/gtk/hostlist_ncp.c +++ b/ui/gtk/hostlist_ncp.c @@ -64,7 +64,7 @@ gtk_ncp_hostlist_init(const char *opt_arg, void* userdata _U_) filter=NULL; } - init_hostlist_table(TRUE, "NCP", "ncp_hdr", filter, ncp_hostlist_packet); + init_hostlist_table(TRUE, "NCP", "ncp", filter, ncp_hostlist_packet); } @@ -78,5 +78,5 @@ void register_tap_listener_ncp_hostlist(void) { register_stat_cmd_arg("hosts,ncp", gtk_ncp_hostlist_init,NULL); - register_hostlist_table(TRUE, "NCP", "ncp_hdr", NULL /*filter*/, ncp_hostlist_packet); + register_hostlist_table(TRUE, "NCP", "ncp", NULL /*filter*/, ncp_hostlist_packet); } diff --git a/ui/gtk/hostlist_table.h b/ui/gtk/hostlist_table.h index 41c0c9ffc1..eb1f157662 100644 --- a/ui/gtk/hostlist_table.h +++ b/ui/gtk/hostlist_table.h @@ -24,12 +24,34 @@ #ifndef __HOSTLIST_TABLE_H__ #define __HOSTLIST_TABLE_H__ -#include +#include /** @file * Hostlist definitions. */ +/** Conversation types */ +/* Sort alphabetically by title */ +typedef enum { + CONV_TYPE_ETHERNET, + CONV_TYPE_FIBRE_CHANNEL, + CONV_TYPE_FDDI, + CONV_TYPE_IPV4, + CONV_TYPE_IPV6, + CONV_TYPE_IPX, + CONV_TYPE_JXTA, + CONV_TYPE_NCP, + CONV_TYPE_RSVP, + CONV_TYPE_SCTP, + CONV_TYPE_TCP, + CONV_TYPE_TOKEN_RING, + CONV_TYPE_UDP, + CONV_TYPE_USB, + CONV_TYPE_WLAN, + N_CONV_TYPES +} conversation_type_e; + + /** Hostlist information */ typedef struct _hostlist_talker_t { address myaddress; /**< address */ diff --git a/ui/gtk/main.c b/ui/gtk/main.c index 17fa2a9a0d..453fa5a8c7 100644 --- a/ui/gtk/main.c +++ b/ui/gtk/main.c @@ -92,6 +92,7 @@ #include #include #include +#include #include #include @@ -189,6 +190,7 @@ #include "ui/gtk/proto_help.h" #include "ui/gtk/packet_list.h" #include "ui/gtk/filter_expression_save_dlg.h" +#include "ui/gtk/conversations_table.h" #include "ui/gtk/old-gtk-compat.h" @@ -2575,6 +2577,7 @@ main(int argc, char *argv[]) #endif register_all_tap_listeners(); + conversation_table_set_gui_info(init_conversation_table); splash_update(RA_PREFERENCES, NULL, (gpointer)splash_win); diff --git a/ui/gtk/main_menubar.c b/ui/gtk/main_menubar.c index 5ecbe53132..d36bc7c51f 100644 --- a/ui/gtk/main_menubar.c +++ b/ui/gtk/main_menubar.c @@ -1187,21 +1187,7 @@ static const char *ui_desc_menubar = " \n" " \n" " \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" +" \n" " \n" " \n" " \n" @@ -1654,21 +1640,6 @@ static const GtkActionEntry main_menu_bar_entries[] = { { "/Statistics/ConversationList", NULL, "_Conversation List", NULL, NULL, NULL }, - { "/Statistics/ConversationList/Ethernet", WIRESHARK_STOCK_CONVERSATIONS, "Ethernet", NULL, NULL, G_CALLBACK(eth_endpoints_cb) }, - { "/Statistics/ConversationList/FibreChannel", WIRESHARK_STOCK_CONVERSATIONS, "Fibre Channel", NULL, NULL, G_CALLBACK(fc_endpoints_cb) }, - { "/Statistics/ConversationList/FDDI", WIRESHARK_STOCK_CONVERSATIONS, "FDDI", NULL, NULL, G_CALLBACK(fddi_endpoints_cb) }, - { "/Statistics/ConversationList/IP", WIRESHARK_STOCK_CONVERSATIONS, "IPv4", NULL, NULL, G_CALLBACK(ip_endpoints_cb) }, - { "/Statistics/ConversationList/IPv6", WIRESHARK_STOCK_CONVERSATIONS, "IPv6", NULL, NULL, G_CALLBACK(ipv6_endpoints_cb) }, - { "/Statistics/ConversationList/IPX", WIRESHARK_STOCK_CONVERSATIONS, "IPX", NULL, NULL, G_CALLBACK(ipx_endpoints_cb) }, - { "/Statistics/ConversationList/JXTA", WIRESHARK_STOCK_CONVERSATIONS, "JXTA", NULL, NULL, G_CALLBACK(jxta_conversation_cb) }, - { "/Statistics/ConversationList/NCP", WIRESHARK_STOCK_CONVERSATIONS, "NCP", NULL, NULL, G_CALLBACK(ncp_endpoints_cb) }, - { "/Statistics/ConversationList/RSVP", WIRESHARK_STOCK_CONVERSATIONS, "RSVP", NULL, NULL, G_CALLBACK(rsvp_endpoints_cb) }, - { "/Statistics/ConversationList/SCTP", WIRESHARK_STOCK_CONVERSATIONS, "SCTP", NULL, NULL, G_CALLBACK(sctp_conversation_cb) }, - { "/Statistics/ConversationList/TCPIP", WIRESHARK_STOCK_CONVERSATIONS, "TCP (IPv4 & IPv6)", NULL, NULL, G_CALLBACK(tcpip_conversation_cb) }, - { "/Statistics/ConversationList/TR", WIRESHARK_STOCK_CONVERSATIONS, "Token Ring", NULL, NULL, G_CALLBACK(tr_conversation_cb) }, - { "/Statistics/ConversationList/UDPIP", WIRESHARK_STOCK_CONVERSATIONS, "UDP (IPv4 & IPv6)", NULL, NULL, G_CALLBACK(udpip_conversation_cb) }, - { "/Statistics/ConversationList/USB", WIRESHARK_STOCK_CONVERSATIONS, "USB", NULL, NULL, G_CALLBACK(usb_endpoints_cb) }, - { "/Statistics/ConversationList/WLAN", WIRESHARK_STOCK_CONVERSATIONS, "WLAN", NULL, NULL, G_CALLBACK(wlan_endpoints_cb) }, { "/Statistics/EndpointList", NULL, "_Endpoint List", NULL, NULL, NULL }, { "/Statistics/EndpointList/Ethernet", WIRESHARK_STOCK_ENDPOINTS, "Ethernet", NULL, NULL, G_CALLBACK(gtk_eth_hostlist_cb) }, @@ -3315,7 +3286,7 @@ menu_dissector_filter(capture_file *cf) gtk_ui_manager_insert_action_group (ui_manager_main_menubar, action_group, 0); g_object_set_data (G_OBJECT (ui_manager_main_menubar), - "diessector-filters-merge-id", GUINT_TO_POINTER (merge_id)); + "dissector-filters-merge-id", GUINT_TO_POINTER (merge_id)); /* no items */ if (!list_entry){ @@ -3365,6 +3336,75 @@ menu_dissector_filter(capture_file *cf) } } +static void +menu_endpoints_cb(GtkAction *action _U_, gpointer user_data) +{ + register_ct_t *table = (register_ct_t*)user_data; + + conversation_endpoint_cb(table); +} + +typedef struct { + capture_file *cf; + guint merge_id; + GtkActionGroup *action_group; + int counter; +} conv_menu_t; + +static void +add_conversation_menuitem(gpointer data, gpointer user_data) +{ + register_ct_t *table = (register_ct_t*)data; + conv_menu_t *conv = (conv_menu_t*)user_data; + gchar *action_name; + GtkAction *action; + + action_name = g_strdup_printf ("conversation-%u", conv->counter); + /*g_warning("action_name %s, filter_entry->name %s",action_name,filter_entry->name);*/ + action = (GtkAction *)g_object_new (GTK_TYPE_ACTION, + "name", action_name, + "label", proto_get_protocol_short_name(find_protocol_by_id(get_conversation_proto_id(table))), + "sensitive", TRUE, + NULL); + g_signal_connect (action, "activate", + G_CALLBACK (menu_endpoints_cb), table); + gtk_action_group_add_action (conv->action_group, action); + g_object_unref (action); + + gtk_ui_manager_add_ui (ui_manager_main_menubar, conv->merge_id, + "/Menubar/StatisticsMenu/ConversationListMenu/Conversations", + action_name, + action_name, + GTK_UI_MANAGER_MENUITEM, + FALSE); + g_free(action_name); + conv->counter++; +} + +static void +menu_conversation_list(capture_file *cf) +{ + GtkWidget *submenu_conversation_list; + conv_menu_t conv_data; + + conv_data.merge_id = gtk_ui_manager_new_merge_id (ui_manager_main_menubar); + + conv_data.action_group = gtk_action_group_new ("conversation-list-group"); + + submenu_conversation_list = gtk_ui_manager_get_widget(ui_manager_main_menubar, "/Menubar/StatisticsMenu/ConversationListMenu"); + if(!submenu_conversation_list){ + g_warning("add_recent_items: No submenu_conversation_list found, path= /Menubar/StatisticsMenu/ConversationListMenu"); + } + + gtk_ui_manager_insert_action_group (ui_manager_main_menubar, conv_data.action_group, 0); + g_object_set_data (G_OBJECT (ui_manager_main_menubar), + "conversation-list-merge-id", GUINT_TO_POINTER (conv_data.merge_id)); + + conv_data.cf = cf; + conv_data.counter = 0; + conversation_table_iterate_tables(add_conversation_menuitem, &conv_data); +} + static void menus_init(void) { @@ -3628,6 +3668,7 @@ menus_init(void) popup_menu_list = g_slist_append((GSList *)popup_menu_list, ui_manager_statusbar_profiles_menu); menu_dissector_filter(&cfile); + menu_conversation_list(&cfile); merge_menu_items(merge_menu_items_list); /* Add external menus and items */ diff --git a/ui/qt/conversation_dialog.cpp b/ui/qt/conversation_dialog.cpp index 866304c702..b49f19763b 100644 --- a/ui/qt/conversation_dialog.cpp +++ b/ui/qt/conversation_dialog.cpp @@ -41,10 +41,9 @@ #include #include #include +#include #include -#include - // To do: // - https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=6727 // - Wide last column? @@ -59,19 +58,17 @@ // Bugs: // - Name resolution doesn't do anything if its preference is disabled. // - Columns don't resize correctly. +// - Closing the capture file clears conversation data. // Fixed bugs: // - Friendly unit displays https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=9231 // - Misleading bps calculation https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=8703 -Q_DECLARE_METATYPE(conversation_type_e) - -QMap conv_proto_to_type_; - -ConversationDialog::ConversationDialog(QWidget *parent, capture_file *cf, const char *stat_arg) : +ConversationDialog::ConversationDialog(QWidget *parent, capture_file *cf, int proto_id, const char *filter) : QDialog(parent), ui(new Ui::ConversationDialog), - cap_file_(cf) + cap_file_(cf), + filter_(filter) { ui->setupUi(this); setAttribute(Qt::WA_DeleteOnClose, true); @@ -100,43 +97,43 @@ ConversationDialog::ConversationDialog(QWidget *parent, capture_file *cf, const graph_bt_->setToolTip(tr("Graph a TCP conversation.")); connect(graph_bt_, SIGNAL(clicked()), this, SLOT(graphTcp())); - QList conv_types; + QList conv_protos; for (GList *conv_tab = recent.conversation_tabs; conv_tab; conv_tab = conv_tab->next) { - conversation_type_e ct = conversation_title_to_type((const char *)conv_tab->data); - if (!conv_types.contains(ct)) { - conv_types.append(ct); + int proto_id = proto_get_id_by_short_name((const char *)conv_tab->data); + if (proto_id > -1 && !conv_protos.contains(proto_id)) { + conv_protos.append(proto_id); } } // Reasonable defaults? - if (conv_types.isEmpty()) { - conv_types << CONV_TYPE_ETHERNET << CONV_TYPE_IPV4 << CONV_TYPE_IPV6 < 1 && conv_proto_to_type_.contains(stat_args[1])) { - conversation_type_e ct = conv_proto_to_type_[stat_args[1]]; - conv_types.removeAll(ct); - conv_types.prepend(ct); - if (stat_args.length() > 2) { - filter_ = stat_args[2]; + if (get_conversation_by_proto_id(proto_id)) { + conv_protos.removeAll(proto_id); + conv_protos.prepend(proto_id); + } + + // QTabWidget selects the first item by default. + foreach (int conv_proto, conv_protos) { + addConversationTable(get_conversation_by_proto_id(conv_proto)); + } + + for (guint i = 0; i < conversation_table_get_num(); i++) { + int proto_id = get_conversation_proto_id(get_conversation_table_by_num(i)); + if (proto_id < 0) { + continue; } - } - - foreach (conversation_type_e conv_type, conv_types) { - addConversationType(conv_type); - } - - for (int i = CONV_TYPE_ETHERNET; i < N_CONV_TYPES; i++) { - conversation_type_e ct = (conversation_type_e) i; - QString title = conversation_title(ct); + QString title = proto_get_protocol_short_name(find_protocol_by_id(proto_id)); QAction *conv_action = new QAction(title, this); - conv_action->setData(qVariantFromValue(ct)); + conv_action->setData(qVariantFromValue(proto_id)); conv_action->setCheckable(true); - conv_action->setChecked(conv_types.contains(ct)); + conv_action->setChecked(conv_protos.contains(proto_id)); connect(conv_action, SIGNAL(triggered()), this, SLOT(toggleConversation())); conv_type_menu_.addAction(conv_action); } @@ -165,10 +162,10 @@ ConversationDialog::~ConversationDialog() ConversationTreeWidget *cur_tree = qobject_cast(ui->conversationTabWidget->currentWidget()); foreach (QAction *ca, conv_type_menu_.actions()) { - conversation_type_e conv_type = ca->data().value(); - if (conv_type_to_tree_.contains(conv_type) && ca->isChecked()) { - char *title = g_strdup(conversation_title(conv_type)); - if (conv_type_to_tree_[conv_type] == cur_tree) { + int proto_id = ca->data().value(); + if (proto_id_to_tree_.contains(proto_id) && ca->isChecked()) { + char *title = g_strdup(proto_get_protocol_short_name(find_protocol_by_id(proto_id))); + if (proto_id_to_tree_[proto_id] == cur_tree) { recent.conversation_tabs = g_list_prepend(recent.conversation_tabs, title); } else { recent.conversation_tabs = g_list_append(recent.conversation_tabs, title); @@ -186,40 +183,21 @@ void ConversationDialog::setCaptureFile(capture_file *cf) } } -void ConversationDialog::initStatCmdMap() +bool ConversationDialog::addConversationTable(register_ct_t* table) { - if (conv_proto_to_type_.size() > 0) { - return; - } + int proto_id = get_conversation_proto_id(table); - conv_proto_to_type_["eth"] = CONV_TYPE_ETHERNET; - conv_proto_to_type_["fc"] = CONV_TYPE_FIBRE_CHANNEL; - conv_proto_to_type_["fddi"] = CONV_TYPE_FDDI; - conv_proto_to_type_["ip"] = CONV_TYPE_IPV4; - conv_proto_to_type_["ipv6"] = CONV_TYPE_IPV6; - conv_proto_to_type_["ipx"] = CONV_TYPE_IPX; - conv_proto_to_type_["jxta"] = CONV_TYPE_JXTA; - conv_proto_to_type_["ncp"] = CONV_TYPE_NCP; - conv_proto_to_type_["rsvp"] = CONV_TYPE_RSVP; - conv_proto_to_type_["sctp"] = CONV_TYPE_SCTP; - conv_proto_to_type_["tcp"] = CONV_TYPE_TCP; - conv_proto_to_type_["tr"] = CONV_TYPE_TOKEN_RING; - conv_proto_to_type_["udp"] = CONV_TYPE_UDP; - conv_proto_to_type_["usb"] = CONV_TYPE_USB; - conv_proto_to_type_["wlan"] = CONV_TYPE_WLAN; -} - -bool ConversationDialog::addConversationType(conversation_type_e conv_type) -{ - if (conv_type_to_tree_.contains(conv_type)) { + if (!table || proto_id_to_tree_.contains(proto_id)) { return false; } - ConversationTreeWidget *conv_tree = new ConversationTreeWidget(this, conv_type); + ConversationTreeWidget *conv_tree = new ConversationTreeWidget(this, table); - conv_type_to_tree_[conv_type] = conv_tree; + proto_id_to_tree_[proto_id] = conv_tree; + const char* table_name = proto_get_protocol_short_name(find_protocol_by_id(proto_id)); + + ui->conversationTabWidget->addTab(conv_tree, table_name); - ui->conversationTabWidget->addTab(conv_tree, conversation_title(conv_type)); connect(conv_tree, SIGNAL(itemSelectionChanged()), this, SLOT(itemSelectionChanged())); connect(conv_tree, SIGNAL(titleChanged(QWidget*,QString)), @@ -236,26 +214,21 @@ bool ConversationDialog::addConversationType(conversation_type_e conv_type) } else if (!filter_.isEmpty()) { filter = filter_.toUtf8().constData(); } - GString *error_string = register_tap_listener(conversation_tap_name(conv_type), conv_tree, filter, 0, + + conv_tree->conversationHash()->user_data = conv_tree; + + GString *error_string = register_tap_listener(proto_get_protocol_filter_name(proto_id), conv_tree->conversationHash(), filter, 0, ConversationTreeWidget::tapReset, - ConversationTreeWidget::tapPacket, + get_conversation_packet_func(table), ConversationTreeWidget::tapDraw); if (error_string) { - QMessageBox::warning(this, tr("Conversation %1 failed to register tap listener").arg(conversation_title(conv_type)), + QMessageBox::warning(this, tr("Conversation %1 failed to register tap listener").arg(table_name), error_string->str); g_string_free(error_string, TRUE); } - return true; -} -conversation_type_e ConversationDialog::tabType(int index) -{ - ConversationTreeWidget *conv_tree = qobject_cast(ui->conversationTabWidget->widget(index)); - if (!conv_tree) { - return N_CONV_TYPES; // Need a "none" type? - } - return conv_tree->conversationType(); + return true; } conv_item_t *ConversationDialog::currentConversation() @@ -368,11 +341,11 @@ void ConversationDialog::updateWidgets() ui->conversationTabWidget->setUpdatesEnabled(false); ui->conversationTabWidget->clear(); foreach (QAction *ca, conv_type_menu_.actions()) { - conversation_type_e conv_type = ca->data().value(); - if (conv_type_to_tree_.contains(conv_type) && ca->isChecked()) { - ui->conversationTabWidget->addTab(conv_type_to_tree_[conv_type], - conv_type_to_tree_[conv_type]->conversationTitle()); - conv_type_to_tree_[conv_type]->setNameResolutionEnabled(ui->nameResolutionCheckBox->isChecked()); + int proto_id = ca->data().value(); + if (proto_id_to_tree_.contains(proto_id) && ca->isChecked()) { + ui->conversationTabWidget->addTab(proto_id_to_tree_[proto_id], + proto_id_to_tree_[proto_id]->conversationTitle()); + proto_id_to_tree_[proto_id]->setNameResolutionEnabled(ui->nameResolutionCheckBox->isChecked()); } } ui->conversationTabWidget->setCurrentWidget(cur_w); @@ -386,12 +359,14 @@ void ConversationDialog::toggleConversation() return; } - conversation_type_e conv_type = ca->data().value(); - bool new_conv = addConversationType(conv_type); + int proto_id = ca->data().value(); + register_ct_t* table = get_conversation_by_proto_id(proto_id); + + bool new_conv = addConversationTable(table); updateWidgets(); if (ca->isChecked()) { - ui->conversationTabWidget->setCurrentWidget(conv_type_to_tree_[conv_type]); + ui->conversationTabWidget->setCurrentWidget(proto_id_to_tree_[proto_id]); } if (new_conv) { @@ -472,34 +447,10 @@ void ConversationDialog::on_buttonBox_helpRequested() wsApp->helpTopicAction(HELP_STATS_CONVERSATIONS_DIALOG); } -// Stat command + args - -static void -conversation_init(const char *stat_arg, void* userdata _U_) { - Q_UNUSED(stat_arg) - wsApp->emitStatCommandSignal("Conversation", stat_arg, NULL); -} - -extern "C" { -void -register_tap_listener_all_conversations(void) +void init_conversation_table(struct register_ct* ct, const char *filter) { - register_stat_cmd_arg("conv,eth", conversation_init, NULL); - register_stat_cmd_arg("conv,fc", conversation_init, NULL); - register_stat_cmd_arg("conv,fddi", conversation_init, NULL); - register_stat_cmd_arg("conv,ip", conversation_init, NULL); - register_stat_cmd_arg("conv,ipv6", conversation_init, NULL); - register_stat_cmd_arg("conv,ipx", conversation_init, NULL); - register_stat_cmd_arg("conv,jxta", conversation_init, NULL); - register_stat_cmd_arg("conv,ncp", conversation_init, NULL); - register_stat_cmd_arg("conv,rsvp", conversation_init, NULL); - register_stat_cmd_arg("conv,sctp", conversation_init, NULL); - register_stat_cmd_arg("conv,tcp", conversation_init, NULL); - register_stat_cmd_arg("conv,tr", conversation_init, NULL); - register_stat_cmd_arg("conv,udp", conversation_init, NULL); - register_stat_cmd_arg("conv,usb", conversation_init, NULL); - register_stat_cmd_arg("conv,wlan", conversation_init, NULL); -} + Q_UNUSED(ct) + wsApp->emitStatCommandSignal("Conversation", filter, GINT_TO_POINTER(get_conversation_proto_id(ct))); } /* diff --git a/ui/qt/conversation_dialog.h b/ui/qt/conversation_dialog.h index 26bf91c102..59c183d22c 100644 --- a/ui/qt/conversation_dialog.h +++ b/ui/qt/conversation_dialog.h @@ -27,6 +27,7 @@ #include #include "ui/follow.h" +#include "epan/conversation_table.h" #include #include @@ -42,7 +43,14 @@ class ConversationDialog : public QDialog Q_OBJECT public: - explicit ConversationDialog(QWidget *parent = 0, capture_file *cf = NULL, const char *stat_arg = NULL); + /** Create a new conversation window. + * + * @param parent Parent widget. + * @param cf Capture file. No statistics will be calculated if this is NULL. + * @param proto_id If valid, add this protocol and bring it to the front. + * @param filter Display filter to apply. + */ + explicit ConversationDialog(QWidget *parent = 0, capture_file *cf = NULL, int proto_id = -1, const char *filter = NULL); ~ConversationDialog(); public slots: @@ -59,16 +67,14 @@ private: capture_file *cap_file_; QString filter_; QMenu conv_type_menu_; - QMap conv_type_to_tree_; + QMap proto_id_to_tree_; QList conv_actions_; QPushButton *copy_bt_; QPushButton *follow_bt_; QPushButton *graph_bt_; - void initStatCmdMap(); // Adds a conversation tree. Returns true if the tree was freshly created, false if it was cached. - bool addConversationType(conversation_type_e conv_type); - conversation_type_e tabType(int index); + bool addConversationTable(register_ct_t* table); conv_item_t *currentConversation(); private slots: @@ -86,6 +92,8 @@ private slots: void on_buttonBox_helpRequested(); }; +void init_conversation_table(struct register_ct* ct, const char *filter); + #endif // CONVERSATION_DIALOG_H /* diff --git a/ui/qt/conversation_tree_widget.cpp b/ui/qt/conversation_tree_widget.cpp index cca65ceaa5..00d88bb65a 100644 --- a/ui/qt/conversation_tree_widget.cpp +++ b/ui/qt/conversation_tree_widget.cpp @@ -49,7 +49,6 @@ #include #include -#include // QTreeWidget subclass that allows tapping @@ -61,6 +60,8 @@ const QString bps_na_ = QObject::tr("N/A"); QMap fad_to_cd_; // QTreeWidgetItem subclass that allows sorting +const int ci_col_ = 0; +const int pkts_col_ = 1; class ConversationTreeWidgetItem : public QTreeWidgetItem { public: @@ -70,12 +71,19 @@ public: // Set column text to its cooked representation. void update(gboolean resolve_names) { - conv_item_t *conv_item = data(0, Qt::UserRole).value(); + conv_item_t *conv_item = data(ci_col_, Qt::UserRole).value(); + bool ok; + quint64 cur_packets = data(pkts_col_, Qt::UserRole).toULongLong(&ok); if (!conv_item) { return; } + quint64 packets = conv_item->tx_frames + conv_item->rx_frames; + if (ok && cur_packets == packets) { + return; + } + setText(CONV_COLUMN_SRC_ADDR, get_conversation_address(&conv_item->src_address, resolve_names)); setText(CONV_COLUMN_SRC_PORT, get_conversation_port(conv_item->src_port, conv_item->ptype, resolve_names)); setText(CONV_COLUMN_DST_ADDR, get_conversation_address(&conv_item->dst_address, resolve_names)); @@ -84,7 +92,7 @@ public: double duration = nstime_to_sec(&conv_item->stop_time) - nstime_to_sec(&conv_item->start_time); QString col_str, bps_ab = bps_na_, bps_ba = bps_na_; - col_str = QString("%L1").arg(conv_item->tx_frames + conv_item->rx_frames); + col_str = QString("%L1").arg(packets); setText(CONV_COLUMN_PACKETS, col_str); col_str = gchar_free_to_qstring(format_size(conv_item->tx_bytes + conv_item->rx_bytes, format_size_unit_none|format_size_prefix_si)); setText(CONV_COLUMN_BYTES, col_str); @@ -104,13 +112,12 @@ public: } setText(CONV_COLUMN_BPS_AB, bps_ab); setText(CONV_COLUMN_BPS_BA, bps_ba); - - conv_item->modified = FALSE; + setData(pkts_col_, Qt::UserRole, qVariantFromValue(packets)); } // Return a string, qulonglong, double, or invalid QVariant representing the raw column data. QVariant colData(int col, bool resolve_names) { - conv_item_t *conv_item = data(0, Qt::UserRole).value(); + conv_item_t *conv_item = data(ci_col_, Qt::UserRole).value(); if (!conv_item) { return QVariant(); @@ -167,8 +174,8 @@ public: bool operator< (const QTreeWidgetItem &other) const { - conv_item_t *conv_item = data(0, Qt::UserRole).value(); - conv_item_t *other_item = other.data(0, Qt::UserRole).value(); + conv_item_t *conv_item = data(ci_col_, Qt::UserRole).value(); + conv_item_t *other_item = other.data(ci_col_, Qt::UserRole).value(); if (!conv_item || !other_item) { return false; @@ -215,9 +222,9 @@ public: private: }; -ConversationTreeWidget::ConversationTreeWidget(QWidget *parent, conversation_type_e conv_type) : +ConversationTreeWidget::ConversationTreeWidget(QWidget *parent, register_ct_t* table) : QTreeWidget(parent), - conv_type_(conv_type), + table_(table), hash_(), resolve_names_(false) { @@ -230,10 +237,10 @@ ConversationTreeWidget::ConversationTreeWidget(QWidget *parent, conversation_typ headerItem()->setText(i, column_titles[i]); } - if (conversation_hide_ports(conv_type)) { + if (get_conversation_hide_ports(table_)) { hideColumn(CONV_COLUMN_SRC_PORT); hideColumn(CONV_COLUMN_DST_PORT); - } else if (conv_type == CONV_TYPE_NCP) { + } else if (!strcmp(proto_get_protocol_filter_name(get_conversation_proto_id(table_)), "ncp")) { headerItem()->setText(CONV_COLUMN_SRC_PORT, conn_a_title); headerItem()->setText(CONV_COLUMN_DST_PORT, conn_b_title); } @@ -322,65 +329,25 @@ ConversationTreeWidget::ConversationTreeWidget(QWidget *parent, conversation_typ } ConversationTreeWidget::~ConversationTreeWidget() { - remove_tap_listener(this); + remove_tap_listener(&hash_); reset_conversation_table_data(&hash_); } // Callbacks for register_tap_listener void ConversationTreeWidget::tapReset(void *conv_tree_ptr) { - ConversationTreeWidget *conv_tree = static_cast(conv_tree_ptr); + conv_hash_t *hash = (conv_hash_t*)conv_tree_ptr; + ConversationTreeWidget *conv_tree = static_cast(hash->user_data); if (!conv_tree) return; conv_tree->clear(); reset_conversation_table_data(&conv_tree->hash_); } -int ConversationTreeWidget::tapPacket(void *conv_tree_ptr, packet_info *pinfo, epan_dissect_t *edt, const void *vip) { - Q_UNUSED(edt); - ConversationTreeWidget *conv_tree = static_cast(conv_tree_ptr); - if (!conv_tree) return 0; - - switch (conv_tree->conv_type_) { - case CONV_TYPE_ETHERNET: - return conv_tree->tapEthernetPacket(pinfo, vip); - case CONV_TYPE_FIBRE_CHANNEL: - return conv_tree->tapFibreChannelPacket(pinfo, vip); - case CONV_TYPE_FDDI: - return conv_tree->tapFddiPacket(pinfo, vip); - case CONV_TYPE_IPV4: - return conv_tree->tapIPv4Packet(pinfo, vip); - case CONV_TYPE_IPV6: - return conv_tree->tapIPv6Packet(pinfo, vip); - case CONV_TYPE_IPX: - return conv_tree->tapIpxPacket(pinfo, vip); - case CONV_TYPE_JXTA: - return conv_tree->tapJxtaPacket(pinfo, vip); - case CONV_TYPE_NCP: - return conv_tree->tapNcpPacket(pinfo, vip); - case CONV_TYPE_RSVP: - return conv_tree->tapRsvpPacket(pinfo, vip); - case CONV_TYPE_SCTP: - return conv_tree->tapSctpPacket(pinfo, vip); - case CONV_TYPE_TCP: - return conv_tree->tapTcpPacket(pinfo, vip); - case CONV_TYPE_TOKEN_RING: - return conv_tree->tapTokenRingPacket(pinfo, vip); - case CONV_TYPE_UDP: - return conv_tree->tapUdpPacket(pinfo, vip); - case CONV_TYPE_USB: - return conv_tree->tapUsbPacket(pinfo, vip); - case CONV_TYPE_WLAN: - return conv_tree->tapWlanPacket(pinfo, vip); - default: - return 0; - } - -} - void ConversationTreeWidget::tapDraw(void *conv_tree_ptr) { - ConversationTreeWidget *conv_tree = static_cast(conv_tree_ptr); + conv_hash_t *hash = (conv_hash_t*)conv_tree_ptr; + ConversationTreeWidget *conv_tree = static_cast(hash->user_data); if (!conv_tree) return; conv_tree->updateItems(); @@ -443,7 +410,7 @@ void ConversationTreeWidget::initDirectionMap() } void ConversationTreeWidget::updateItems() { - title_ = conversation_title(conv_type_); + title_ = proto_get_protocol_short_name(find_protocol_by_id(get_conversation_proto_id(table_))); if (hash_.conv_array && hash_.conv_array->len > 0) { title_.append(QString(" %1 %2").arg(UTF8_MIDDLE_DOT).arg(hash_.conv_array->len)); @@ -458,7 +425,7 @@ void ConversationTreeWidget::updateItems() { for (int i = topLevelItemCount(); i < (int) hash_.conv_array->len; i++) { ConversationTreeWidgetItem *ctwi = new ConversationTreeWidgetItem(this); conv_item_t *conv_item = &g_array_index(hash_.conv_array, conv_item_t, i); - ctwi->setData(0, Qt::UserRole, qVariantFromValue(conv_item)); + ctwi->setData(ci_col_, Qt::UserRole, qVariantFromValue(conv_item)); addTopLevelItem(ctwi); for (int col = 0; col < columnCount(); col++) { @@ -497,7 +464,7 @@ void ConversationTreeWidget::filterActionTriggered() return; } - conv_item_t *conv_item = ctwi->data(0, Qt::UserRole).value(); + conv_item_t *conv_item = ctwi->data(ci_col_, Qt::UserRole).value(); if (!conv_item) { return; } @@ -506,159 +473,6 @@ void ConversationTreeWidget::filterActionTriggered() emit filterAction(filter, fa->action(), fa->actionType()); } -int ConversationTreeWidget::tapEthernetPacket(packet_info *pinfo, const void *vip) -{ - const eth_hdr *ehdr = (const eth_hdr *)vip; - - add_conversation_table_data(&hash_, &ehdr->src, &ehdr->dst, 0, 0, 1, pinfo->fd->pkt_len, &pinfo->rel_ts, CONV_TYPE_ETHERNET, PT_NONE); - return 1; -} - -int ConversationTreeWidget::tapFibreChannelPacket(packet_info *pinfo, const void *vip) -{ - const fc_hdr *fchdr=(const fc_hdr *)vip; - - add_conversation_table_data(&hash_, &fchdr->s_id, &fchdr->d_id, 0, 0, 1, pinfo->fd->pkt_len, &pinfo->rel_ts, CONV_TYPE_FIBRE_CHANNEL, PT_NONE); - return 1; -} - -int ConversationTreeWidget::tapFddiPacket(packet_info *pinfo, const void *vip) -{ - const fddi_hdr *ehdr=(const fddi_hdr *)vip; - - add_conversation_table_data(&hash_, &ehdr->src, &ehdr->dst, 0, 0, 1, pinfo->fd->pkt_len, &pinfo->rel_ts, CONV_TYPE_FDDI, PT_NONE); - return 1; -} - -int ConversationTreeWidget::tapIPv4Packet(packet_info *pinfo, const void *vip) -{ - const ws_ip *iph = (const ws_ip *) vip; - - add_conversation_table_data(&hash_, &iph->ip_src, &iph->ip_dst, 0, 0, 1, pinfo->fd->pkt_len, &pinfo->rel_ts, CONV_TYPE_IPV4, PT_NONE); - return 1; -} - -int ConversationTreeWidget::tapIPv6Packet(packet_info *pinfo, const void *vip) -{ - const struct ip6_hdr *ip6h = (const struct ip6_hdr *)vip; - address src; - address dst; - - /* Addresses aren't implemented as 'address' type in struct ip6_hdr */ - src.type = dst.type = AT_IPv6; - src.len = dst.len = sizeof(struct e_in6_addr); - src.data = &ip6h->ip6_src; - dst.data = &ip6h->ip6_dst; - - add_conversation_table_data(&hash_, &src, &dst, 0, 0, 1, pinfo->fd->pkt_len, &pinfo->rel_ts, CONV_TYPE_IPV6, PT_NONE); - return 1; -} - -int ConversationTreeWidget::tapIpxPacket(packet_info *pinfo, const void *vip) -{ - const ipxhdr_t *ipxh = (const ipxhdr_t *)vip; - - add_conversation_table_data(&hash_, &ipxh->ipx_src, &ipxh->ipx_dst, 0, 0, 1, pinfo->fd->pkt_len, &pinfo->rel_ts, CONV_TYPE_IPX, PT_NONE); - return 1; -} - -int ConversationTreeWidget::tapJxtaPacket(packet_info *pinfo, const void *vip) -{ - Q_UNUSED(pinfo); - const jxta_tap_header *jxtahdr = (const jxta_tap_header *) vip; - - add_conversation_table_data(&hash_, - &jxtahdr->src_address, - &jxtahdr->dest_address, - 0, - 0, - 1, - jxtahdr->size, - NULL, - CONV_TYPE_JXTA, - PT_NONE); - return 1; -} - -int ConversationTreeWidget::tapNcpPacket(packet_info *pinfo, const void *vip) -{ - const struct ncp_common_header *ncph=(const struct ncp_common_header *)vip; - guint32 connection; - - connection = (ncph->conn_high * 256) + ncph->conn_low; - if (connection < 65535) { - add_conversation_table_data(&hash_, &pinfo->src, &pinfo->dst, connection, connection, 1, pinfo->fd->pkt_len, &pinfo->rel_ts, CONV_TYPE_NCP, PT_NCP); - } - return 1; -} - -int ConversationTreeWidget::tapRsvpPacket(packet_info *pinfo, const void *vip) -{ - const rsvp_conversation_info *rsvph = (const rsvp_conversation_info *)vip; - - add_conversation_table_data(&hash_, - &rsvph->source, &rsvph->destination, 0, 0, 1, - pinfo->fd->pkt_len, &pinfo->rel_ts, CONV_TYPE_RSVP, PT_NONE); - return 1; -} - -int ConversationTreeWidget::tapSctpPacket(packet_info *pinfo, const void *vip) -{ - const struct _sctp_info *sctphdr = (const struct _sctp_info *)vip; - - add_conversation_table_data(&hash_, - &sctphdr->ip_src, - &sctphdr->ip_dst, - sctphdr->sport, - sctphdr->dport, - (conv_id_t) sctphdr->verification_tag, - pinfo->fd->pkt_len, - &pinfo->rel_ts, - CONV_TYPE_SCTP, - PT_SCTP); - return 1; -} - -int ConversationTreeWidget::tapTcpPacket(packet_info *pinfo, const void *vip) -{ - const struct tcpheader *tcphdr = (const struct tcpheader *) vip; - - add_conversation_table_data_with_conv_id(&hash_, &tcphdr->ip_src, &tcphdr->ip_dst, tcphdr->th_sport, tcphdr->th_dport, (conv_id_t) tcphdr->th_stream, 1, pinfo->fd->pkt_len, &pinfo->rel_ts, CONV_TYPE_TCP, PT_TCP); - return 1; -} - -int ConversationTreeWidget::tapTokenRingPacket(packet_info *pinfo, const void *vip) -{ - const tr_hdr *trhdr=(const tr_hdr *)vip; - - add_conversation_table_data(&hash_, &trhdr->src, &trhdr->dst, 0, 0, 1, pinfo->fd->pkt_len, &pinfo->rel_ts, CONV_TYPE_TOKEN_RING, PT_NONE); - return 1; -} - -int ConversationTreeWidget::tapUdpPacket(packet_info *pinfo, const void *vip) -{ - const e_udphdr *udphdr = (const e_udphdr *)vip; - - add_conversation_table_data(&hash_, &udphdr->ip_src, &udphdr->ip_dst, udphdr->uh_sport, udphdr->uh_dport, (conv_id_t) udphdr->uh_stream, pinfo->fd->pkt_len, &pinfo->rel_ts, CONV_TYPE_UDP, PT_UDP); - return 1; -} - -int ConversationTreeWidget::tapUsbPacket(packet_info *pinfo, const void *vip) -{ - Q_UNUSED(vip); - add_conversation_table_data(&hash_, &pinfo->src, &pinfo->dst, 0, 0, 1, pinfo->fd->pkt_len, &pinfo->rel_ts, CONV_TYPE_USB, PT_NONE); - return 1; -} - -int ConversationTreeWidget::tapWlanPacket(packet_info *pinfo, const void *vip) -{ - const wlan_hdr *whdr=(const wlan_hdr *)vip; - - add_conversation_table_data(&hash_, &whdr->src, &whdr->dst, 0, 0, 1, pinfo->fd->pkt_len, &pinfo->rel_ts, CONV_TYPE_WLAN, PT_NONE); - return 1; -} - - /* * Editor modelines * diff --git a/ui/qt/conversation_tree_widget.h b/ui/qt/conversation_tree_widget.h index 223f83a7c0..b170f83ad4 100644 --- a/ui/qt/conversation_tree_widget.h +++ b/ui/qt/conversation_tree_widget.h @@ -28,8 +28,9 @@ #include #include +#include "epan/conversation_table.h" -#include "ui/conversation_hash.h" +#include "ui/conversation_ui.h" #include "filter_action.h" @@ -42,20 +43,19 @@ class ConversationTreeWidget : public QTreeWidget { Q_OBJECT public: - explicit ConversationTreeWidget(QWidget *parent, conversation_type_e conv_type); + explicit ConversationTreeWidget(QWidget *parent, register_ct_t* table); ~ConversationTreeWidget(); static void tapReset(void *conv_tree_ptr); - static int tapPacket(void *conv_tree_ptr, packet_info *pinfo, epan_dissect_t *edt, const void *vip); static void tapDraw(void *conv_tree_ptr); // String, int, or double data for each column in a row. // Passing -1 returns titles. QList rowData(int row); - conversation_type_e conversationType() { return conv_type_; } // Title string plus optional count const QString &conversationTitle() { return title_; } + conv_hash_t* conversationHash() {return &hash_;} signals: void titleChanged(QWidget *tree, const QString &text); @@ -68,7 +68,7 @@ protected: void contextMenuEvent(QContextMenuEvent *event); private: - conversation_type_e conv_type_; + register_ct_t* table_; QString title_; conv_hash_t hash_; bool resolve_names_; diff --git a/ui/qt/main.cpp b/ui/qt/main.cpp index 7ec385ddf1..8bc06c7265 100644 --- a/ui/qt/main.cpp +++ b/ui/qt/main.cpp @@ -76,6 +76,7 @@ #include #include #include +#include #include #ifdef HAVE_PLUGINS @@ -141,6 +142,7 @@ #include #include #include +#include "conversation_dialog.h" #ifdef HAVE_LIBPCAP capture_options global_capture_opts; @@ -908,6 +910,7 @@ int main(int argc, char *argv[]) #endif register_all_tap_listeners(); + conversation_table_set_gui_info(init_conversation_table); if (ex_opt_count("read_format") > 0) { in_file_type = open_info_name_to_type(ex_opt_get_next("read_format")); diff --git a/ui/qt/main_window_slots.cpp b/ui/qt/main_window_slots.cpp index d9c441a2aa..da8139eece 100644 --- a/ui/qt/main_window_slots.cpp +++ b/ui/qt/main_window_slots.cpp @@ -2076,8 +2076,7 @@ void MainWindow::on_actionStatisticsCollectd_triggered() void MainWindow::statCommandConversation(const char *arg, void *userdata) { - Q_UNUSED(userdata); - ConversationDialog *conv_dialog = new ConversationDialog(this, cap_file_, arg); + ConversationDialog *conv_dialog = new ConversationDialog(this, cap_file_, GPOINTER_TO_INT(userdata), arg); connect(conv_dialog, SIGNAL(filterAction(QString&,FilterAction::Action,FilterAction::ActionType)), this, SLOT(filterAction(QString&,FilterAction::Action,FilterAction::ActionType))); connect(conv_dialog, SIGNAL(openFollowStreamDialog(follow_type_t)), diff --git a/ui/sat.h b/ui/sat.h deleted file mode 100644 index c6febc7284..0000000000 --- a/ui/sat.h +++ /dev/null @@ -1,41 +0,0 @@ -/* sat.h - * 2003 Ronnie Sahlberg - * Sub-address types for MAC/URI addresses - * - * 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 __SAT_H__ -#define __SAT_H__ - -/** @file - * Sub-address type definitions. - */ - -/** Address type */ -typedef enum { - SAT_NONE, /**< no address type */ - SAT_ETHER, /**< MAC : Ethernet */ - SAT_WLAN, /**< MAC : Wireless LAN */ - SAT_FDDI, /**< MAC : FDDI */ - SAT_TOKENRING, /**< MAC : Token Ring */ - SAT_JXTA /**< URI : JXTA */ -} SAT_E; - -#endif /* __SAT_H__ */