summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGerald Combs <gerald@wireshark.org>2014-04-29 11:10:27 -0400
committerMichael Mann <mmann78@netscape.net>2014-07-21 23:19:09 +0000
commit59ef97dd652131a6df0edd26cc8709461587a224 (patch)
treec3428c9388757895136b7ea43d168b1966feb68e
parentd81a34cc24598778d3f8073cf85027a777cbbc10 (diff)
downloadwireshark-59ef97dd652131a6df0edd26cc8709461587a224.tar.gz
[WIP] Add a conversation dialog.
Items are sorted by value. Move common conversation code to ui/conversation_hash.[ch]. Add a conversation_type_e enum along with convenience functions for fetching titles, tap names, etc. We have a single main dialog instead of a main dialog + individual protocol dialogs. It de-clutters the statistics menu and results in simpler code. Conversation type tabs can be added and removed within the dialog itself. The tab list is sticky and saved with the current profile when the dialog closes. Data can be copied as CSV or YAML. Add a FilterAction class and a corresponding filterAction slot to MainWindow. Use it for the Conversations context menu. Add an addressResolutionChanged signal and related plumbing. Get rid of the iterator members in the conversation item struct. Update the GTK+ code accordingly. Excercise for the reader: - Update TShark to use the common hash code. Ping-Bug: 9231 Ping-Bug: 8703 Ping-Bug: 6727 Change-Id: I8728d771fc5b1a85937bed9d898e53c3ecc3a544 Reviewed-on: https://code.wireshark.org/review/2987 Reviewed-by: Michael Mann <mmann78@netscape.net>
-rw-r--r--epan/prefs-int.h13
-rw-r--r--epan/prefs.c16
-rw-r--r--ui/CMakeLists.txt1
-rw-r--r--ui/Makefile.common2
-rw-r--r--ui/conversation_hash.c739
-rw-r--r--ui/conversation_hash.h277
-rw-r--r--ui/gtk/Makefile.common1
-rw-r--r--ui/gtk/conversations_eth.c27
-rw-r--r--ui/gtk/conversations_fc.c7
-rw-r--r--ui/gtk/conversations_fddi.c7
-rw-r--r--ui/gtk/conversations_ip.c7
-rw-r--r--ui/gtk/conversations_ipv6.c7
-rw-r--r--ui/gtk/conversations_ipx.c7
-rw-r--r--ui/gtk/conversations_jxta.c11
-rw-r--r--ui/gtk/conversations_ncp.c27
-rw-r--r--ui/gtk/conversations_rsvp.c9
-rw-r--r--ui/gtk/conversations_sctp.c53
-rw-r--r--ui/gtk/conversations_table.c1314
-rw-r--r--ui/gtk/conversations_table.h80
-rw-r--r--ui/gtk/conversations_tcpip.c7
-rw-r--r--ui/gtk/conversations_tr.c7
-rw-r--r--ui/gtk/conversations_udpip.c7
-rw-r--r--ui/gtk/conversations_usb.c8
-rw-r--r--ui/gtk/conversations_wlan.c7
-rw-r--r--ui/gtk/filter_utils.c2
-rw-r--r--ui/gtk/filter_utils.h2
-rw-r--r--ui/gtk/hostlist_eth.c4
-rw-r--r--ui/gtk/hostlist_fc.c4
-rw-r--r--ui/gtk/hostlist_fddi.c4
-rw-r--r--ui/gtk/hostlist_ip.c4
-rw-r--r--ui/gtk/hostlist_ipv6.c4
-rw-r--r--ui/gtk/hostlist_ipx.c4
-rw-r--r--ui/gtk/hostlist_jxta.c4
-rw-r--r--ui/gtk/hostlist_ncp.c4
-rw-r--r--ui/gtk/hostlist_rsvp.c4
-rw-r--r--ui/gtk/hostlist_sctp.c4
-rw-r--r--ui/gtk/hostlist_table.c14
-rw-r--r--ui/gtk/hostlist_table.h6
-rw-r--r--ui/gtk/hostlist_tcpip.c4
-rw-r--r--ui/gtk/hostlist_tr.c4
-rw-r--r--ui/gtk/hostlist_udpip.c4
-rw-r--r--ui/gtk/hostlist_usb.c4
-rw-r--r--ui/gtk/hostlist_wlan.c4
-rw-r--r--ui/qt/CMakeLists.txt18
-rw-r--r--ui/qt/Makefile.am2
-rw-r--r--ui/qt/Makefile.common8
-rw-r--r--ui/qt/QtShark.pro7
-rw-r--r--ui/qt/conversation_dialog.cpp516
-rw-r--r--ui/qt/conversation_dialog.h102
-rw-r--r--ui/qt/conversation_dialog.ui127
-rw-r--r--ui/qt/conversation_tree_widget.cpp673
-rw-r--r--ui/qt/conversation_tree_widget.h112
-rw-r--r--ui/qt/filter_action.cpp172
-rw-r--r--ui/qt/filter_action.h106
-rw-r--r--ui/qt/main_window.h9
-rw-r--r--ui/qt/main_window.ui9
-rw-r--r--ui/qt/main_window_slots.cpp175
-rw-r--r--ui/qt/packet_list.cpp2
-rw-r--r--ui/qt/packet_list.h2
-rw-r--r--ui/qt/tcp_stream_dialog.h2
-rw-r--r--ui/qt/wireshark_application.cpp13
-rw-r--r--ui/qt/wireshark_application.h3
-rw-r--r--ui/recent.c15
-rw-r--r--ui/recent.h1
-rw-r--r--ui/sat.h (renamed from ui/gtk/sat.h)6
-rw-r--r--wsutil/str_util.c4
66 files changed, 3531 insertions, 1278 deletions
diff --git a/epan/prefs-int.h b/epan/prefs-int.h
index 0b75f4e544..10240cd35c 100644
--- a/epan/prefs-int.h
+++ b/epan/prefs-int.h
@@ -181,4 +181,17 @@ WS_DLL_PUBLIC
int
read_prefs_file(const char *pf_path, FILE *pf, pref_set_pair_cb pref_set_pair_fct, void *private_data);
+/** Convert a string list preference to a preference string.
+ *
+ * Given a GList of gchar pointers, create a quoted, comma-separated
+ * string. Should be used with prefs_get_string_list() and
+ * prefs_clear_string_list().
+ *
+ * @param sl String list.
+ * @return Quoted, joined, and wrapped string. May be empty.
+ */
+WS_DLL_PUBLIC
+char *
+join_string_list(GList *sl);
+
#endif /* prefs-int.h */
diff --git a/epan/prefs.c b/epan/prefs.c
index 6200679979..0f3951982d 100644
--- a/epan/prefs.c
+++ b/epan/prefs.c
@@ -63,7 +63,6 @@ static module_t *prefs_register_module_or_subtree(module_t *parent,
const char *name, const char *title, const char *description, gboolean is_subtree,
void (*apply_cb)(void), gboolean use_gui);
static prefs_set_pref_e set_pref(gchar*, const gchar*, void *, gboolean);
-static char * join_string_list(GList *);
static void free_col_info(GList *);
static void pre_init_prefs(void);
static gboolean prefs_is_column_visible(const gchar *cols_hidden, fmt_data *cfmt);
@@ -1768,10 +1767,7 @@ column_format_to_str_cb(pref_t* pref, gboolean default_val)
}
column_format_str = join_string_list(col_l);
-
- /* This frees the list of strings, but not the strings to which it
- refers; they are free'ed in join_string_list(). */
- g_list_free(col_l);
+ prefs_clear_string_list(col_l);
return column_format_str;
}
@@ -1960,7 +1956,8 @@ capture_column_to_str_cb(pref_t* pref, gboolean default_val)
GList *pref_l = default_val ? pref->default_val.list : prefs.capture_columns;
GList *clp = g_list_first(pref_l);
GList *col_l = NULL;
- gchar *col, *capture_column_str;
+ gchar *col;
+ char *capture_column_str;
while (clp) {
col = (gchar *) clp->data;
@@ -1969,9 +1966,7 @@ capture_column_to_str_cb(pref_t* pref, gboolean default_val)
}
capture_column_str = join_string_list(col_l);
- /* This frees the list of strings, but not the strings to which it
- refers; they are free'ed in write_string_list(). */
- g_list_free(col_l);
+ prefs_clear_string_list(col_l);
return capture_column_str;
}
@@ -2692,8 +2687,7 @@ prefs_get_string_list(const gchar *str)
return(sl);
}
-static char *
-join_string_list(GList *sl)
+char *join_string_list(GList *sl)
{
GString *joined_str = g_string_new("");
GList *cur, *first;
diff --git a/ui/CMakeLists.txt b/ui/CMakeLists.txt
index 4846e1921b..f0a7919107 100644
--- a/ui/CMakeLists.txt
+++ b/ui/CMakeLists.txt
@@ -24,6 +24,7 @@ set(COMMON_UI_SRC
alert_box.c
capture.c
capture_ui_utils.c
+ conversation_hash.c
decode_as_utils.c
export_object.c
export_object_dicom.c
diff --git a/ui/Makefile.common b/ui/Makefile.common
index 3392e9e94a..d478e25663 100644
--- a/ui/Makefile.common
+++ b/ui/Makefile.common
@@ -45,6 +45,7 @@ WIRESHARK_UI_SRC = \
alert_box.c \
capture.c \
capture_ui_utils.c \
+ conversation_hash.c \
decode_as_utils.c \
export_object.c \
export_object_dicom.c \
@@ -79,6 +80,7 @@ noinst_HEADERS = \
capture.h \
capture_globals.h \
capture_ui_utils.h \
+ conversation_hash.h \
decode_as_utils.h \
export_object.h \
last_open_dir.h \
diff --git a/ui/conversation_hash.c b/ui/conversation_hash.c
new file mode 100644
index 0000000000..60da5d3718
--- /dev/null
+++ b/ui/conversation_hash.c
@@ -0,0 +1,739 @@
+/* conversation_hash.c
+ * Copied from gtk/conversations_table.c 2003 Ronnie Sahlberg
+ * Helper routines common to all conversations taps.
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * 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 <glib.h>
+
+#include <epan/address.h>
+#include <epan/addr_resolv.h>
+#include <epan/emem.h>
+#include <epan/to_str.h>
+
+#include "conversation_hash.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";
+
+/*
+ * Compute the hash value for two given address/port pairs if the match
+ * is to be exact.
+ */
+guint
+conversation_hash(gconstpointer key)
+{
+ const conv_key_t *ck = (const conv_key_t *)key;
+ 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;
+
+ return hash_val;
+}
+
+/*
+ * Compare two conversation keys for an exact match.
+ */
+gboolean
+conversation_equal(gconstpointer key1, gconstpointer key2)
+{
+ const conv_key_t *ck1 = (const conv_key_t *)key1;
+ const conv_key_t *ck2 = (const conv_key_t *)key2;
+
+ if (ck1->conv_id == ck2->conv_id)
+ {
+ if (ck1->port1 == ck2->port1 &&
+ ck1->port2 == ck2->port2 &&
+ ADDRESSES_EQUAL(&ck1->addr1, &ck2->addr1) &&
+ ADDRESSES_EQUAL(&ck1->addr2, &ck2->addr2)) {
+ return TRUE;
+ }
+
+ if (ck1->port2 == ck2->port1 &&
+ ck1->port1 == ck2->port2 &&
+ ADDRESSES_EQUAL(&ck1->addr2, &ck2->addr1) &&
+ ADDRESSES_EQUAL(&ck1->addr1, &ck2->addr2)) {
+ return TRUE;
+ }
+ }
+
+ /*
+ * The addresses, ports, or conversation IDs don't match.
+ */
+ return FALSE;
+}
+
+void
+reset_conversation_table_data(conv_hash_t *ch)
+{
+ if (!ch) {
+ return;
+ }
+
+ if (ch->conv_array != NULL) {
+ guint i;
+ for(i = 0; i < ch->conv_array->len; i++){
+ conv_item_t *conv = &g_array_index(ch->conv_array, conv_item_t, i);
+ g_free((gpointer)conv->src_address.data);
+ g_free((gpointer)conv->dst_address.data);
+ }
+
+ g_array_free(ch->conv_array, TRUE);
+ }
+
+ if (ch->hashtable != NULL) {
+ g_hash_table_destroy(ch->hashtable);
+ }
+
+ ch->conv_array=NULL;
+ 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) {
+ return ep_address_to_display(addr);
+ } else {
+ return ep_address_to_str(addr);
+ }
+}
+
+const char *get_conversation_port(guint32 port, port_type ptype, gboolean resolve_names)
+{
+
+ if(!resolve_names) ptype = PT_NONE;
+
+ switch(ptype) {
+ case(PT_TCP):
+ return ep_tcp_port_to_display(port);
+ case(PT_UDP):
+ return ep_udp_port_to_display(port);
+ case(PT_SCTP):
+ return ep_sctp_port_to_display(port);
+ default:
+ return ep_strdup_printf("%d", port);
+ }
+}
+
+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.
+
+ Some addresses, like AT_ETHER may actually be any of multiple types
+ of protocols, either ethernet, tokenring, fddi, wlan etc so we must be
+ more specific there; that's why we need specific_addr_type.
+*/
+static const char *
+conversation_get_filter_name(conv_item_t *conv_item, conv_filter_type_e filter_type)
+{
+
+ if (!conv_item) {
+ return "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";
+}
+
+/* Convert a port number into a string or NULL */
+static char *
+ct_port_to_str(port_type ptype, guint32 port)
+{
+ switch(ptype){
+ case PT_TCP:
+ case PT_UDP:
+ case PT_SCTP:
+ case PT_NCP:
+ return g_strdup_printf("%d", port);
+ default:
+ break;
+ }
+ return NULL;
+}
+
+
+const char *get_conversation_filter(conv_item_t *conv_item, conv_direction_e direction)
+{
+ char *sport, *dport;
+ const char *str = "INVALID";
+
+ sport = ct_port_to_str(conv_item->ptype, conv_item->src_port);
+ dport = ct_port_to_str(conv_item->ptype, conv_item->dst_port);
+
+ switch(direction){
+ case CONV_DIR_A_TO_FROM_B:
+ /* A <-> B */
+ str = ep_strdup_printf("%s==%s%s%s%s%s && %s==%s%s%s%s%s",
+ conversation_get_filter_name(conv_item, CONV_FT_ANY_ADDRESS),
+ ep_address_to_str(&conv_item->src_address),
+ sport?" && ":"",
+ sport?conversation_get_filter_name(conv_item, CONV_FT_ANY_PORT):"",
+ sport?"==":"",
+ sport?sport:"",
+ conversation_get_filter_name(conv_item, CONV_FT_ANY_ADDRESS),
+ ep_address_to_str(&conv_item->dst_address),
+ dport?" && ":"",
+ dport?conversation_get_filter_name(conv_item, CONV_FT_ANY_PORT):"",
+ dport?"==":"",
+ dport?dport:""
+ );
+ break;
+ case CONV_DIR_A_TO_B:
+ /* A --> B */
+ str = ep_strdup_printf("%s==%s%s%s%s%s && %s==%s%s%s%s%s",
+ conversation_get_filter_name(conv_item, CONV_FT_SRC_ADDRESS),
+ ep_address_to_str(&conv_item->src_address),
+ sport?" && ":"",
+ sport?conversation_get_filter_name(conv_item, CONV_FT_SRC_PORT):"",
+ sport?"==":"",
+ sport?sport:"",
+ conversation_get_filter_name(conv_item, CONV_FT_DST_ADDRESS),
+ ep_address_to_str(&conv_item->dst_address),
+ dport?" && ":"",
+ dport?conversation_get_filter_name(conv_item, CONV_FT_DST_PORT):"",
+ dport?"==":"",
+ dport?dport:""
+ );
+ break;
+ case CONV_DIR_A_FROM_B:
+ /* A <-- B */
+ str = ep_strdup_printf("%s==%s%s%s%s%s && %s==%s%s%s%s%s",
+ conversation_get_filter_name(conv_item, CONV_FT_DST_ADDRESS),
+ ep_address_to_str(&conv_item->src_address),
+ sport?" && ":"",
+ sport?conversation_get_filter_name(conv_item, CONV_FT_DST_PORT):"",
+ sport?"==":"",
+ sport?sport:"",
+ conversation_get_filter_name(conv_item, CONV_FT_SRC_ADDRESS),
+ ep_address_to_str(&conv_item->dst_address),
+ dport?" && ":"",
+ dport?conversation_get_filter_name(conv_item, CONV_FT_SRC_PORT):"",
+ dport?"==":"",
+ dport?dport:""
+ );
+ break;
+ case CONV_DIR_A_TO_FROM_ANY:
+ /* A <-> ANY */
+ str = ep_strdup_printf("%s==%s%s%s%s%s",
+ conversation_get_filter_name(conv_item, CONV_FT_ANY_ADDRESS),
+ ep_address_to_str(&conv_item->src_address),
+ sport?" && ":"",
+ sport?conversation_get_filter_name(conv_item, CONV_FT_ANY_PORT):"",
+ sport?"==":"",
+ sport?sport:""
+ );
+ break;
+ case CONV_DIR_A_TO_ANY:
+ /* A --> ANY */
+ str = ep_strdup_printf("%s==%s%s%s%s%s",
+ conversation_get_filter_name(conv_item, CONV_FT_SRC_ADDRESS),
+ ep_address_to_str(&conv_item->src_address),
+ sport?" && ":"",
+ sport?conversation_get_filter_name(conv_item, CONV_FT_SRC_PORT):"",
+ sport?"==":"",
+ sport?sport:""
+ );
+ break;
+ case CONV_DIR_A_FROM_ANY:
+ /* A <-- ANY */
+ str = ep_strdup_printf("%s==%s%s%s%s%s",
+ conversation_get_filter_name(conv_item, CONV_FT_DST_ADDRESS),
+ ep_address_to_str(&conv_item->src_address),
+ sport?" && ":"",
+ sport?conversation_get_filter_name(conv_item, CONV_FT_DST_PORT):"",
+ sport?"==":"",
+ sport?sport:""
+ );
+ break;
+ case CONV_DIR_ANY_TO_FROM_B:
+ /* ANY <-> B */
+ str = ep_strdup_printf("%s==%s%s%s%s%s",
+ conversation_get_filter_name(conv_item, CONV_FT_ANY_ADDRESS),
+ ep_address_to_str(&conv_item->dst_address),
+ dport?" && ":"",
+ dport?conversation_get_filter_name(conv_item, CONV_FT_ANY_PORT):"",
+ dport?"==":"",
+ dport?dport:""
+ );
+ break;
+ case CONV_DIR_ANY_FROM_B:
+ /* ANY <-- B */
+ str = ep_strdup_printf("%s==%s%s%s%s%s",
+ conversation_get_filter_name(conv_item, CONV_FT_SRC_ADDRESS),
+ ep_address_to_str(&conv_item->dst_address),
+ dport?" && ":"",
+ dport?conversation_get_filter_name(conv_item, CONV_FT_SRC_PORT):"",
+ dport?"==":"",
+ dport?dport:""
+ );
+ break;
+ case CONV_DIR_ANY_TO_B:
+ /* ANY --> B */
+ str = ep_strdup_printf("%s==%s%s%s%s%s",
+ conversation_get_filter_name(conv_item, CONV_FT_DST_ADDRESS),
+ ep_address_to_str(&conv_item->dst_address),
+ dport?" && ":"",
+ dport?conversation_get_filter_name(conv_item, CONV_FT_DST_PORT):"",
+ dport?"==":"",
+ dport?dport:""
+ );
+ break;
+ default:
+ break;
+ }
+ g_free(sport);
+ g_free(dport);
+ return str;
+}
+
+/*
+ * 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_hash.h b/ui/conversation_hash.h
new file mode 100644
index 0000000000..a46b202566
--- /dev/null
+++ b/ui/conversation_hash.h
@@ -0,0 +1,277 @@
+/* conversation_hash.h
+ * Copied from gtk/conversations_table.h 2003 Ronnie Sahlberg
+ * Helper routines common to all conversations taps.
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * 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_HASH_H__
+#define __CONVERSATION_HASH_H__
+
+#include <epan/address.h>
+#include <epan/conv_id.h>
+
+#include <wsutil/nstime.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/** @file
+ * Conversation lists.
+ */
+
+/** 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;
+
+/* Filter direction */
+typedef enum {
+ CONV_DIR_A_TO_FROM_B,
+ CONV_DIR_A_TO_B,
+ CONV_DIR_A_FROM_B,
+ CONV_DIR_A_TO_FROM_ANY,
+ CONV_DIR_A_TO_ANY,
+ CONV_DIR_A_FROM_ANY,
+ CONV_DIR_ANY_TO_FROM_B,
+ CONV_DIR_ANY_TO_B,
+ 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 */
+} conv_hash_t;
+
+/** Key for hash lookups */
+typedef struct _conversation_key_t {
+ address addr1;
+ address addr2;
+ guint32 port1;
+ guint32 port2;
+ conv_id_t conv_id;
+} conv_key_t;
+
+/** Conversation information */
+typedef struct _conversation_item_t {
+ conversation_type_e conv_type; /**< conversation type */
+ address src_address; /**< source address */
+ address dst_address; /**< destination address */
+ port_type ptype; /**< port_type (e.g. PT_TCP) */
+ guint32 src_port; /**< source port */
+ guint32 dst_port; /**< destination port */
+ conv_id_t conv_id; /**< conversation id */
+
+ guint64 rx_frames; /**< number of received packets */
+ guint64 tx_frames; /**< number of transmitted packets */
+ guint64 rx_bytes; /**< number of received bytes */
+ guint64 tx_bytes; /**< number of transmitted bytes */
+
+ 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 */
+} conv_item_t;
+
+/** 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.
+ */
+guint conversation_hash(gconstpointer key);
+
+/** 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 conversation_equal(gconstpointer key1, gconstpointer key2);
+
+/** Remove all entries from the conversation table.
+ *
+ * @param ct the table to reset
+ */
+extern void reset_conversation_table_data(conv_hash_t *ch);
+
+/** Add some data to the conversation table.
+ *
+ * @param ct the table to add the data to
+ * @param src source address
+ * @param dst destination address
+ * @param src_port source port
+ * @param dst_port destination port
+ * @param num_frames number of packets
+ * @param num_bytes number of bytes
+ * @param ts timestamp
+ * @param sat address type
+ * @param port_type 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);
+
+/** 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
+ * conversation.
+ *
+ * @param ct the table to add the data to
+ * @param src source address
+ * @param dst destination address
+ * @param src_port source port
+ * @param dst_port destination port
+ * @param num_frames number of packets
+ * @param num_bytes number of bytes
+ * @param ts timestamp
+ * @param sat address type
+ * @param port_type 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,
+ 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);
+
+/** 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:
+ */
diff --git a/ui/gtk/Makefile.common b/ui/gtk/Makefile.common
index aa3d9e4236..cd45d6a44c 100644
--- a/ui/gtk/Makefile.common
+++ b/ui/gtk/Makefile.common
@@ -331,7 +331,6 @@ noinst_HEADERS = \
remote_icons.h \
rtp_player.h \
rtp_stream_dlg.h \
- sat.h \
sctp_stat_gtk.h \
service_response_time_table.h \
time_shift_dlg.h \
diff --git a/ui/gtk/conversations_eth.c b/ui/gtk/conversations_eth.c
index 6e8fa7eec2..cca55f194b 100644
--- a/ui/gtk/conversations_eth.c
+++ b/ui/gtk/conversations_eth.c
@@ -41,11 +41,12 @@ 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)
{
- const eth_hdr *ehdr=(const eth_hdr *)vip;
+ conversations_table *ct = (conversations_table *) pct;
+ const eth_hdr *ehdr=(const eth_hdr *)vip;
- add_conversation_table_data((conversations_table *)pct, &ehdr->src, &ehdr->dst, 0, 0, 1, pinfo->fd->pkt_len, &pinfo->rel_ts, SAT_ETHER, PT_NONE);
+ 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;
+ return 1;
}
@@ -53,28 +54,28 @@ eth_conversation_packet(void *pct, packet_info *pinfo, epan_dissect_t *edt _U_,
static void
eth_conversation_init(const char *opt_arg, void* userdata _U_)
{
- const char *filter=NULL;
+ const char *filter=NULL;
- if(!strncmp(opt_arg,"conv,eth,",9)){
- filter=opt_arg+9;
- } else {
- filter=NULL;
- }
+ if(!strncmp(opt_arg,"conv,eth,",9)){
+ filter=opt_arg+9;
+ } else {
+ filter=NULL;
+ }
- init_conversation_table(TRUE, "Ethernet", "eth", filter, eth_conversation_packet);
+ 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);
+ 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(TRUE, "Ethernet", "eth", NULL /*filter*/, eth_conversation_packet);
+ 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
index 59a522d496..c8733e1e3e 100644
--- a/ui/gtk/conversations_fc.c
+++ b/ui/gtk/conversations_fc.c
@@ -42,9 +42,10 @@ 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((conversations_table *)pct, &fchdr->s_id, &fchdr->d_id, 0, 0, 1, pinfo->fd->pkt_len, &pinfo->rel_ts, SAT_NONE, PT_NONE);
+ 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;
}
@@ -62,7 +63,7 @@ fc_conversation_init(const char *opt_arg, void* userdata _U_)
filter=NULL;
}
- init_conversation_table(TRUE, "Fibre Channel", "fc", filter, fc_conversation_packet);
+ init_conversation_table(CONV_TYPE_FIBRE_CHANNEL, filter, fc_conversation_packet);
}
@@ -76,5 +77,5 @@ void
register_tap_listener_fc_conversation(void)
{
register_stat_cmd_arg("conv,fc", fc_conversation_init, NULL);
- register_conversation_table(TRUE, "Fibre Channel", "fc", NULL /*filter*/, fc_conversation_packet);
+ 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
index 6911bf564a..bef12493f7 100644
--- a/ui/gtk/conversations_fddi.c
+++ b/ui/gtk/conversations_fddi.c
@@ -41,9 +41,10 @@ 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((conversations_table *)pct, &ehdr->src, &ehdr->dst, 0, 0, 1, pinfo->fd->pkt_len, &pinfo->rel_ts, SAT_FDDI, PT_NONE);
+ 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;
}
@@ -61,7 +62,7 @@ fddi_conversation_init(const char *opt_arg, void* userdata _U_ )
filter=NULL;
}
- init_conversation_table(TRUE, "FDDI", "fddi", filter, fddi_conversation_packet);
+ init_conversation_table(CONV_TYPE_FDDI, filter, fddi_conversation_packet);
}
@@ -75,5 +76,5 @@ void
register_tap_listener_fddi_conversation(void)
{
register_stat_cmd_arg("conv,fddi", fddi_conversation_init,NULL);
- register_conversation_table(TRUE, "FDDI", "fddi", NULL /*filter*/, fddi_conversation_packet);
+ 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
index 1f2f33a0e8..280329728a 100644
--- a/ui/gtk/conversations_ip.c
+++ b/ui/gtk/conversations_ip.c
@@ -41,9 +41,10 @@ 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((conversations_table *)pct, &iph->ip_src, &iph->ip_dst, 0, 0, 1, pinfo->fd->pkt_len, &pinfo->rel_ts, SAT_NONE, PT_NONE);
+ 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;
}
@@ -59,7 +60,7 @@ ip_conversation_init(const char *opt_arg, void* userdata _U_)
filter=NULL;
}
- init_conversation_table(TRUE, "IPv4", "ip", filter, ip_conversation_packet);
+ init_conversation_table(CONV_TYPE_IPV4, filter, ip_conversation_packet);
}
@@ -73,5 +74,5 @@ void
register_tap_listener_ip_conversation(void)
{
register_stat_cmd_arg("conv,ip", ip_conversation_init,NULL);
- register_conversation_table(TRUE, "IPv4", "ip", NULL /*filter*/, ip_conversation_packet);
+ 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
index 2a2833eb8c..9634e650e2 100644
--- a/ui/gtk/conversations_ipv6.c
+++ b/ui/gtk/conversations_ipv6.c
@@ -41,6 +41,7 @@ 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;
@@ -51,7 +52,7 @@ ipv6_conversation_packet(void *pct, packet_info *pinfo, epan_dissect_t *edt _U_,
src.data = &ip6h->ip6_src;
dst.data = &ip6h->ip6_dst;
- add_conversation_table_data((conversations_table *)pct, &src, &dst, 0, 0, 1, pinfo->fd->pkt_len, &pinfo->rel_ts, SAT_NONE, PT_NONE);
+ 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;
}
@@ -69,7 +70,7 @@ ipv6_conversation_init(const char *opt_arg, void *userdata _U_)
filter = NULL;
}
- init_conversation_table(TRUE, "IPv6", "ipv6", filter, ipv6_conversation_packet);
+ init_conversation_table(CONV_TYPE_IPV6, filter, ipv6_conversation_packet);
}
void
@@ -82,5 +83,5 @@ void
register_tap_listener_ipv6_conversation(void)
{
register_stat_cmd_arg("conv,ipv6", ipv6_conversation_init, NULL);
- register_conversation_table(TRUE, "IPv6", "ipv6", NULL /*filter*/, ipv6_conversation_packet);
+ 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
index 9593adef93..d1fa85086e 100644
--- a/ui/gtk/conversations_ipx.c
+++ b/ui/gtk/conversations_ipx.c
@@ -41,9 +41,10 @@ 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((conversations_table *)pct, &ipxh->ipx_src, &ipxh->ipx_dst, 0, 0, 1, pinfo->fd->pkt_len, &pinfo->rel_ts, SAT_NONE, PT_NONE);
+ 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;
}
@@ -61,7 +62,7 @@ ipx_conversation_init(const char *opt_arg, void* userdata _U_)
filter=NULL;
}
- init_conversation_table(TRUE, "IPX", "ipx", filter, ipx_conversation_packet);
+ init_conversation_table(CONV_TYPE_IPX, filter, ipx_conversation_packet);
}
@@ -75,5 +76,5 @@ void
register_tap_listener_ipx_conversation(void)
{
register_stat_cmd_arg("conv,ipx", ipx_conversation_init,NULL);
- register_conversation_table(TRUE, "IPX", "ipx", NULL /*filter*/, ipx_conversation_packet);
+ 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
index fb3c1aa929..472a3207a5 100644
--- a/ui/gtk/conversations_jxta.c
+++ b/ui/gtk/conversations_jxta.c
@@ -42,17 +42,18 @@ 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((conversations_table *)pct,
+ add_conversation_table_data(&ct->hash,
&jxtahdr->src_address,
&jxtahdr->dest_address,
0,
0,
1,
jxtahdr->size,
- NULL,
- SAT_JXTA,
+ NULL,
+ CONV_TYPE_JXTA,
PT_NONE);
@@ -70,7 +71,7 @@ jxta_conversation_init(const char *opt_arg, void* userdata _U_)
filter=NULL;
}
- init_conversation_table(TRUE, "JXTA", "jxta", filter, jxta_conversation_packet);
+ init_conversation_table(CONV_TYPE_JXTA, filter, jxta_conversation_packet);
}
@@ -84,5 +85,5 @@ void
register_tap_listener_jxta_conversation(void)
{
register_stat_cmd_arg("conv,jxta", jxta_conversation_init,NULL);
- register_conversation_table(TRUE, "JXTA", "jxta", NULL /*filter*/, jxta_conversation_packet);
+ 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
index 50df44cd3f..4ef3e3bb8e 100644
--- a/ui/gtk/conversations_ncp.c
+++ b/ui/gtk/conversations_ncp.c
@@ -41,40 +41,41 @@ 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)
{
- const struct ncp_common_header *ncph=(const struct ncp_common_header *)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((conversations_table *)pct, &pinfo->src, &pinfo->dst, connection, connection, 1, pinfo->fd->pkt_len, &pinfo->rel_ts, SAT_NONE, PT_NCP);
+ 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;
+ return 1;
}
static void
ncp_conversation_init(const char *opt_arg, void* userdata _U_)
{
- const char *filter=NULL;
+ const char *filter=NULL;
- if(!strncmp(opt_arg,"conv,ncp,",9)){
- filter=opt_arg+9;
- } else {
- filter=NULL;
- }
+ if(!strncmp(opt_arg,"conv,ncp,",9)){
+ filter=opt_arg+9;
+ } else {
+ filter=NULL;
+ }
- init_conversation_table(FALSE, "NCP", "ncp_hdr", filter, ncp_conversation_packet);
+ 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);
+ 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(FALSE, "NCP", "ncp_hdr", NULL /*filter*/, ncp_conversation_packet);
+ 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
index 0ff4b86487..1393c3db71 100644
--- a/ui/gtk/conversations_rsvp.c
+++ b/ui/gtk/conversations_rsvp.c
@@ -41,11 +41,12 @@ 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((conversations_table *)pct,
+ add_conversation_table_data(&ct->hash,
&rsvph->source, &rsvph->destination, 0, 0, 1,
- pinfo->fd->pkt_len, &pinfo->rel_ts, SAT_NONE, PT_NONE);
+ pinfo->fd->pkt_len, &pinfo->rel_ts, CONV_TYPE_RSVP, PT_NONE);
return 1;
}
@@ -61,7 +62,7 @@ rsvp_conversation_init(const char *opt_arg, void* userdata _U_)
filter=NULL;
}
- init_conversation_table(TRUE, "RSVP", "rsvp", filter,
+ init_conversation_table(CONV_TYPE_RSVP, filter,
rsvp_conversation_packet);
}
@@ -76,6 +77,6 @@ void
register_tap_listener_rsvp_conversation(void)
{
register_stat_cmd_arg("conv,rsvp", rsvp_conversation_init,NULL);
- register_conversation_table(TRUE, "RSVP", "rsvp", NULL /*filter*/,
+ 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
index b57f4f760d..5b35be16a9 100644
--- a/ui/gtk/conversations_sctp.c
+++ b/ui/gtk/conversations_sctp.c
@@ -41,49 +41,48 @@ 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)
{
- const struct _sctp_info *sctphdr=(const struct _sctp_info *)vip;
-
- add_conversation_table_data((conversations_table *)pct,
- &sctphdr->ip_src,
- &sctphdr->ip_dst,
- sctphdr->sport,
- sctphdr->dport,
- 1,
- pinfo->fd->pkt_len,
- &pinfo->rel_ts,
- SAT_NONE,
- PT_SCTP);
-
-
- return 1;
+ 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;
+ const char *filter=NULL;
- if(!strncmp(opt_arg,"conv,sctp,",10)){
- filter=opt_arg+10;
- } else {
- filter=NULL;
- }
+ if(!strncmp(opt_arg,"conv,sctp,",10)){
+ filter=opt_arg+10;
+ } else {
+ filter=NULL;
+ }
- init_conversation_table(FALSE, "SCTP", "sctp", filter, sctp_conversation_packet);
+ 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);
+ 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(FALSE, "SCTP", "sctp", NULL /*filter*/, sctp_conversation_packet);
+ 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 a8485c3ca7..2ab15ee7b3 100644
--- a/ui/gtk/conversations_table.c
+++ b/ui/gtk/conversations_table.c
@@ -30,18 +30,16 @@
#include <epan/packet_info.h>
#include <epan/to_str.h>
-#include <epan/address.h>
#include <epan/addr_resolv.h>
#include <epan/tap.h>
-#include "../globals.h"
+#include "globals.h"
#include <epan/stat_groups.h>
#include "ui/simple_dialog.h"
#include "ui/utf8_entities.h"
-#include "ui/gtk/sat.h"
#include "ui/gtk/conversations_table.h"
#include "ui/gtk/filter_utils.h"
#include "ui/gtk/gtkglobals.h"
@@ -74,217 +72,9 @@
else \
return 0;
-/* convert a port number into a string */
-static char *
-ct_port_to_str(int port_type_val, guint32 port)
-{
- static int i=0;
- static gchar *strp, str[4][12];
- gchar *bp;
-
- strp=str[i];
-
- switch(port_type_val){
- case PT_TCP:
- case PT_UDP:
- case PT_SCTP:
- case PT_NCP:
- i = (i+1)%4;
- bp = &strp[11];
-
- *bp = 0;
- do {
- *--bp = (port % 10) +'0';
- } while ((port /= 10) != 0 && bp > strp);
- return bp;
- }
- return NULL;
-}
-
-#define FN_SRC_ADDRESS 0
-#define FN_DST_ADDRESS 1
-#define FN_ANY_ADDRESS 2
-#define FN_SRC_PORT 3
-#define FN_DST_PORT 4
-#define FN_ANY_PORT 5
-/* 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.
-
- Some addresses, like AT_ETHER may actually be any of multiple types
- of protocols, either ethernet, tokenring, fddi, wlan etc so we must be
- more specific there; that's why we need specific_addr_type.
-*/
-static const char *
-ct_get_filter_name(address *addr, int specific_addr_type_val, int port_type_val, int name_type_val)
-{
- switch(name_type_val){
- case FN_SRC_ADDRESS:
- switch(addr->type){
- case AT_ETHER:
- switch(specific_addr_type_val){
- case SAT_ETHER:
- return "eth.src";
- case SAT_WLAN:
- return "wlan.sa";
- case SAT_FDDI:
- return "fddi.src";
- case SAT_TOKENRING:
- 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(specific_addr_type_val){
- case SAT_JXTA:
- return "jxta.message.src";
- default:
- break;
- }
- break;
- case AT_USB:
- return "usb.sa";
- default:
- break;
- }
- break;
- case FN_DST_ADDRESS:
- switch(addr->type){
- case AT_ETHER:
- switch(specific_addr_type_val){
- case SAT_ETHER:
- return "eth.dst";
- case SAT_WLAN:
- return "wlan.da";
- case SAT_FDDI:
- return "fddi.dst";
- case SAT_TOKENRING:
- 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(specific_addr_type_val){
- case SAT_JXTA:
- return "jxta.message.dst";
- default:
- break;
- }
- break;
- case AT_USB:
- return "usb.da";
- default:
- break;
- }
- break;
- case FN_ANY_ADDRESS:
- switch(addr->type){
- case AT_ETHER:
- switch(specific_addr_type_val){
- case SAT_ETHER:
- return "eth.addr";
- case SAT_WLAN:
- return "wlan.addr";
- case SAT_FDDI:
- return "fddi.addr";
- case SAT_TOKENRING:
- 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(specific_addr_type_val){
- case SAT_JXTA:
- return "jxta.message.address";
- default:
- break;
- }
- break;
- case AT_USB:
- return "usb.addr";
- default:
- break;
- }
- break;
- case FN_SRC_PORT:
- switch(port_type_val){
- 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 FN_DST_PORT:
- switch(port_type_val){
- 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 FN_ANY_PORT:
- switch(port_type_val){
- 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;
- }
-
- g_assert_not_reached();
- return NULL;
-}
-
static void
reset_ct_table_data(conversations_table *ct)
{
- guint32 i;
char *display_name;
char title[256];
GString *error_string;
@@ -335,20 +125,7 @@ reset_ct_table_data(conversations_table *ct)
gtk_list_store_clear(store);
/* delete all conversations */
- for(i=0;i<ct->num_conversations;i++){
- conv_t *conv = &g_array_index(ct->conversations, conv_t, i);
- g_free((gpointer)conv->src_address.data);
- g_free((gpointer)conv->dst_address.data);
- }
- if (ct->conversations)
- g_array_free(ct->conversations, TRUE);
-
- if (ct->hashtable != NULL)
- g_hash_table_destroy(ct->hashtable);
-
- ct->conversations=NULL;
- ct->hashtable=NULL;
- ct->num_conversations=0;
+ reset_conversation_table_data(&ct->hash);
}
static void
@@ -368,26 +145,6 @@ ct_win_destroy_cb(GtkWindow *win _U_, gpointer data)
g_free(conversations);
}
-enum
-{
- SRC_ADR_COLUMN,
- SRC_PORT_COLUMN,
- DST_ADR_COLUMN,
- DST_PORT_COLUMN,
- PACKETS_COLUMN,
- BYTES_COLUMN,
- PKT_AB_COLUMN,
- BYTES_AB_COLUMN,
- PKT_BA_COLUMN,
- BYTES_BA_COLUMN,
- START_COLUMN,
- DURATION_COLUMN,
- BPS_AB_COLUMN,
- BPS_BA_COLUMN,
- INDEX_COLUMN,
- N_COLUMNS
-};
-
static gint
ct_sort_func(GtkTreeModel *model,
GtkTreeIter *a,
@@ -399,30 +156,30 @@ ct_sort_func(GtkTreeModel *model,
gint data_column = GPOINTER_TO_INT(user_data);
conversations_table *ct = (conversations_table *)g_object_get_data(G_OBJECT(model), CONV_PTR_KEY);
- conv_t *conv1 = NULL;
- conv_t *conv2 = NULL;
+ conv_item_t *conv1 = NULL;
+ conv_item_t *conv2 = NULL;
double duration1, duration2;
- gtk_tree_model_get(model, a, INDEX_COLUMN, &idx1, -1);
- gtk_tree_model_get(model, b, INDEX_COLUMN, &idx2, -1);
+ gtk_tree_model_get(model, a, CONV_INDEX_COLUMN, &idx1, -1);
+ gtk_tree_model_get(model, b, CONV_INDEX_COLUMN, &idx2, -1);
- if (!ct || idx1 >= ct->num_conversations || idx2 >= ct->num_conversations)
+ if (!ct || idx1 >= ct->hash.conv_array->len || idx2 >= ct->hash.conv_array->len)
return 0;
- conv1 = &g_array_index(ct->conversations, conv_t, idx1);
- conv2 = &g_array_index(ct->conversations, conv_t, idx2);
+ conv1 = &g_array_index(ct->hash.conv_array, conv_item_t, idx1);
+ conv2 = &g_array_index(ct->hash.conv_array, conv_item_t, idx2);
switch(data_column){
- case SRC_ADR_COLUMN: /* Source address */
+ case CONV_COLUMN_SRC_ADDR: /* Source address */
return(CMP_ADDRESS(&conv1->src_address, &conv2->src_address));
- case DST_ADR_COLUMN: /* Destination address */
+ case CONV_COLUMN_DST_ADDR: /* Destination address */
return(CMP_ADDRESS(&conv1->dst_address, &conv2->dst_address));
- case SRC_PORT_COLUMN: /* Source port */
+ case CONV_COLUMN_SRC_PORT: /* Source port */
CMP_NUM(conv1->src_port, conv2->src_port);
- case DST_PORT_COLUMN: /* Destination port */
+ case CONV_COLUMN_DST_PORT: /* Destination port */
CMP_NUM(conv1->dst_port, conv2->dst_port);
- case START_COLUMN: /* Start time */
+ case CONV_COLUMN_START: /* Start time */
return nstime_cmp(&conv1->start_time, &conv2->start_time);
}
@@ -430,15 +187,15 @@ ct_sort_func(GtkTreeModel *model,
duration2 = nstime_to_sec(&conv2->stop_time) - nstime_to_sec(&conv2->start_time);
switch(data_column){
- case DURATION_COLUMN: /* Duration */
+ case CONV_COLUMN_DURATION: /* Duration */
CMP_NUM(duration1, duration2);
- case BPS_AB_COLUMN: /* bps A->B */
+ case CONV_COLUMN_BPS_AB: /* bps A->B */
if (duration1 > 0 && conv1->tx_frames > 1 && duration2 > 0 && conv2->tx_frames > 1) {
CMP_NUM((gint64) conv1->tx_bytes / duration1, (gint64) conv2->tx_bytes / duration2);
} else {
CMP_NUM(conv1->tx_bytes, conv2->tx_bytes);
}
- case BPS_BA_COLUMN: /* bps A<-B */
+ case CONV_COLUMN_BPS_BA: /* bps A<-B */
if (duration1 > 0 && conv1->rx_frames > 1 && duration2 > 0 && conv2->rx_frames > 1) {
CMP_NUM((gint64) conv1->rx_bytes / duration1, (gint64) conv2->rx_bytes / duration2);
} else {
@@ -451,173 +208,37 @@ ct_sort_func(GtkTreeModel *model,
return 0;
}
-/* Filter direction */
-#define DIR_A_TO_FROM_B 0
-#define DIR_A_TO_B 1
-#define DIR_A_FROM_B 2
-#define DIR_A_TO_FROM_ANY 3
-#define DIR_A_TO_ANY 4
-#define DIR_A_FROM_ANY 5
-#define DIR_ANY_TO_FROM_B 6
-#define DIR_ANY_FROM_B 7
-#define DIR_ANY_TO_B 8
-
static void
ct_select_filter_cb(GtkWidget *widget _U_, gpointer callback_data, guint callback_action)
{
- int direction;
+ conv_direction_e direction;
guint32 idx = 0;
conversations_table *ct = (conversations_table *)callback_data;
GtkTreeIter iter;
GtkTreeModel *model;
GtkTreeSelection *sel;
- char *str = NULL;
- char *sport, *dport;
- conv_t *conv;
+ const char *str = NULL;
+ conv_item_t *conv;
- direction=FILTER_EXTRA(callback_action);
+ direction = (conv_direction_e) FILTER_EXTRA(callback_action);
sel = gtk_tree_view_get_selection (GTK_TREE_VIEW(ct->table));
if (!gtk_tree_selection_get_selected(sel, &model, &iter))
return;
gtk_tree_model_get (model, &iter,
- INDEX_COLUMN, &idx,
+ CONV_INDEX_COLUMN, &idx,
-1);
- if(idx>= ct->num_conversations){
+ if(idx >= ct->hash.conv_array->len){
simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "No conversation selected");
return;
}
- conv = &g_array_index(ct->conversations, conv_t, idx);
- sport=ct_port_to_str(conv->port_type, conv->src_port);
- dport=ct_port_to_str(conv->port_type, conv->dst_port);
-
- switch(direction){
- case DIR_A_TO_FROM_B:
- /* A <-> B */
- str = g_strdup_printf("%s==%s%s%s%s%s && %s==%s%s%s%s%s",
- ct_get_filter_name(&conv->src_address, conv->sat, conv->port_type, FN_ANY_ADDRESS),
- ep_address_to_str(&conv->src_address),
- sport?" && ":"",
- sport?ct_get_filter_name(&conv->src_address, conv->sat, conv->port_type, FN_ANY_PORT):"",
- sport?"==":"",
- sport?sport:"",
- ct_get_filter_name(&conv->dst_address, conv->sat, conv->port_type, FN_ANY_ADDRESS),
- ep_address_to_str(&conv->dst_address),
- dport?" && ":"",
- dport?ct_get_filter_name(&conv->dst_address, conv->sat, conv->port_type, FN_ANY_PORT):"",
- dport?"==":"",
- dport?dport:""
- );
- break;
- case DIR_A_TO_B:
- /* A --> B */
- str = g_strdup_printf("%s==%s%s%s%s%s && %s==%s%s%s%s%s",
- ct_get_filter_name(&conv->src_address, conv->sat, conv->port_type, FN_SRC_ADDRESS),
- ep_address_to_str(&conv->src_address),
- sport?" && ":"",
- sport?ct_get_filter_name(&conv->src_address, conv->sat, conv->port_type, FN_SRC_PORT):"",
- sport?"==":"",
- sport?sport:"",
- ct_get_filter_name(&conv->dst_address, conv->sat, conv->port_type, FN_DST_ADDRESS),
- ep_address_to_str(&conv->dst_address),
- dport?" && ":"",
- dport?ct_get_filter_name(&conv->dst_address, conv->sat, conv->port_type, FN_DST_PORT):"",
- dport?"==":"",
- dport?dport:""
- );
- break;
- case DIR_A_FROM_B:
- /* A <-- B */
- str = g_strdup_printf("%s==%s%s%s%s%s && %s==%s%s%s%s%s",
- ct_get_filter_name(&conv->src_address, conv->sat, conv->port_type, FN_DST_ADDRESS),
- ep_address_to_str(&conv->src_address),
- sport?" && ":"",
- sport?ct_get_filter_name(&conv->src_address, conv->sat, conv->port_type, FN_DST_PORT):"",
- sport?"==":"",
- sport?sport:"",
- ct_get_filter_name(&conv->dst_address, conv->sat, conv->port_type, FN_SRC_ADDRESS),
- ep_address_to_str(&conv->dst_address),
- dport?" && ":"",
- dport?ct_get_filter_name(&conv->dst_address, conv->sat, conv->port_type, FN_SRC_PORT):"",
- dport?"==":"",
- dport?dport:""
- );
- break;
- case DIR_A_TO_FROM_ANY:
- /* A <-> ANY */
- str = g_strdup_printf("%s==%s%s%s%s%s",
- ct_get_filter_name(&conv->src_address, conv->sat, conv->port_type, FN_ANY_ADDRESS),
- ep_address_to_str(&conv->src_address),
- sport?" && ":"",
- sport?ct_get_filter_name(&conv->src_address, conv->sat, conv->port_type, FN_ANY_PORT):"",
- sport?"==":"",
- sport?sport:""
- );
- break;
- case DIR_A_TO_ANY:
- /* A --> ANY */
- str = g_strdup_printf("%s==%s%s%s%s%s",
- ct_get_filter_name(&conv->src_address, conv->sat, conv->port_type, FN_SRC_ADDRESS),
- ep_address_to_str(&conv->src_address),
- sport?" && ":"",
- sport?ct_get_filter_name(&conv->src_address, conv->sat, conv->port_type, FN_SRC_PORT):"",
- sport?"==":"",
- sport?sport:""
- );
- break;
- case DIR_A_FROM_ANY:
- /* A <-- ANY */
- str = g_strdup_printf("%s==%s%s%s%s%s",
- ct_get_filter_name(&conv->src_address, conv->sat, conv->port_type, FN_DST_ADDRESS),
- ep_address_to_str(&conv->src_address),
- sport?" && ":"",
- sport?ct_get_filter_name(&conv->src_address, conv->sat, conv->port_type, FN_DST_PORT):"",
- sport?"==":"",
- sport?sport:""
- );
- break;
- case DIR_ANY_TO_FROM_B:
- /* ANY <-> B */
- str = g_strdup_printf("%s==%s%s%s%s%s",
- ct_get_filter_name(&conv->dst_address, conv->sat, conv->port_type, FN_ANY_ADDRESS),
- ep_address_to_str(&conv->dst_address),
- dport?" && ":"",
- dport?ct_get_filter_name(&conv->dst_address, conv->sat, conv->port_type, FN_ANY_PORT):"",
- dport?"==":"",
- dport?dport:""
- );
- break;
- case DIR_ANY_FROM_B:
- /* ANY <-- B */
- str = g_strdup_printf("%s==%s%s%s%s%s",
- ct_get_filter_name(&conv->dst_address, conv->sat, conv->port_type, FN_SRC_ADDRESS),
- ep_address_to_str(&conv->dst_address),
- dport?" && ":"",
- dport?ct_get_filter_name(&conv->dst_address, conv->sat, conv->port_type, FN_SRC_PORT):"",
- dport?"==":"",
- dport?dport:""
- );
- break;
- case DIR_ANY_TO_B:
- /* ANY --> B */
- str = g_strdup_printf("%s==%s%s%s%s%s",
- ct_get_filter_name(&conv->dst_address, conv->sat, conv->port_type, FN_DST_ADDRESS),
- ep_address_to_str(&conv->dst_address),
- dport?" && ":"",
- dport?ct_get_filter_name(&conv->dst_address, conv->sat, conv->port_type, FN_DST_PORT):"",
- dport?"==":"",
- dport?dport:""
- );
- break;
- default:
- g_assert_not_reached();
- }
+ conv = &g_array_index(ct->hash.conv_array, conv_item_t, idx);
- apply_selected_filter (callback_action, str);
+ str = get_conversation_filter(conv, direction);
- g_free (str);
+ apply_selected_filter(callback_action, str);
}
static gboolean
@@ -638,331 +259,331 @@ ct_show_popup_menu_cb(void *widg _U_, GdkEvent *event, conversations_table *ct)
static void
conv_apply_as_selected_AtofromB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_SELECTED, DIR_A_TO_FROM_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_SELECTED, CONV_DIR_A_TO_FROM_B));
}
static void
conv_apply_as_selected_AtoB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_SELECTED, DIR_A_TO_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_SELECTED, CONV_DIR_A_TO_B));
}
static void
conv_apply_as_selected_AfromB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_SELECTED, DIR_A_FROM_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_SELECTED, CONV_DIR_A_FROM_B));
}
static void
conv_apply_as_selected_AtofromAny_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_SELECTED, DIR_A_TO_FROM_ANY));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_SELECTED, CONV_DIR_A_TO_FROM_ANY));
}
static void
conv_apply_as_selected_AtoAny_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_SELECTED, DIR_A_TO_ANY));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_SELECTED, CONV_DIR_A_TO_ANY));
}
static void
conv_apply_as_selected_AfromAny_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_SELECTED, DIR_A_FROM_ANY));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_SELECTED, CONV_DIR_A_FROM_ANY));
}
static void
conv_apply_as_selected_AnytofromB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_SELECTED, DIR_ANY_TO_FROM_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_SELECTED, CONV_DIR_ANY_TO_FROM_B));
}
static void
conv_apply_as_selected_AnyfromB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_SELECTED, DIR_ANY_FROM_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_SELECTED, CONV_DIR_ANY_FROM_B));
}
static void
conv_apply_as_selected_AnytoB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_SELECTED, DIR_ANY_TO_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_SELECTED, CONV_DIR_ANY_TO_B));
}
/* As Not Selected */
static void
conv_apply_as_not_selected_AtofromB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_NOT_SELECTED, DIR_A_TO_FROM_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_NOT_SELECTED, CONV_DIR_A_TO_FROM_B));
}
static void
conv_apply_as_not_selected_AtoB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_NOT_SELECTED, DIR_A_TO_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_NOT_SELECTED, CONV_DIR_A_TO_B));
}
static void
conv_apply_as_not_selected_AfromB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_NOT_SELECTED, DIR_A_FROM_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_NOT_SELECTED, CONV_DIR_A_FROM_B));
}
static void
conv_apply_as_not_selected_AtofromAny_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_NOT_SELECTED, DIR_A_TO_FROM_ANY));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_NOT_SELECTED, CONV_DIR_A_TO_FROM_ANY));
}
static void
conv_apply_as_not_selected_AtoAny_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_NOT_SELECTED, DIR_A_TO_ANY));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_NOT_SELECTED, CONV_DIR_A_TO_ANY));
}
static void
conv_apply_as_not_selected_AfromAny_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_NOT_SELECTED, DIR_A_FROM_ANY));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_NOT_SELECTED, CONV_DIR_A_FROM_ANY));
}
static void
conv_apply_as_not_selected_AnytofromB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_NOT_SELECTED, DIR_ANY_TO_FROM_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_NOT_SELECTED, CONV_DIR_ANY_TO_FROM_B));
}
static void
conv_apply_as_not_selected_AnyfromB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_NOT_SELECTED, DIR_ANY_FROM_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_NOT_SELECTED, CONV_DIR_ANY_FROM_B));
}
static void
conv_apply_as_not_selected_AnytoB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_NOT_SELECTED, DIR_ANY_TO_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_NOT_SELECTED, CONV_DIR_ANY_TO_B));
}
/* And Selected */
static void
conv_apply_and_selected_AtofromB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_AND_SELECTED, DIR_A_TO_FROM_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_AND_SELECTED, CONV_DIR_A_TO_FROM_B));
}
static void
conv_apply_and_selected_AtoB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_AND_SELECTED, DIR_A_TO_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_AND_SELECTED, CONV_DIR_A_TO_B));
}
static void
conv_apply_and_selected_AfromB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_AND_SELECTED, DIR_A_FROM_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_AND_SELECTED, CONV_DIR_A_FROM_B));
}
static void
conv_apply_and_selected_AtofromAny_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_AND_SELECTED, DIR_A_TO_FROM_ANY));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_AND_SELECTED, CONV_DIR_A_TO_FROM_ANY));
}
static void
conv_apply_and_selected_AtoAny_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_AND_SELECTED, DIR_A_TO_ANY));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_AND_SELECTED, CONV_DIR_A_TO_ANY));
}
static void
conv_apply_and_selected_AfromAny_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_AND_SELECTED, DIR_A_FROM_ANY));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_AND_SELECTED, CONV_DIR_A_FROM_ANY));
}
static void
conv_apply_and_selected_AnytofromB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_AND_SELECTED, DIR_ANY_TO_FROM_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_AND_SELECTED, CONV_DIR_ANY_TO_FROM_B));
}
static void
conv_apply_and_selected_AnyfromB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_AND_SELECTED, DIR_ANY_FROM_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_AND_SELECTED, CONV_DIR_ANY_FROM_B));
}
static void
conv_apply_and_selected_AnytoB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_AND_SELECTED, DIR_ANY_TO_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_AND_SELECTED, CONV_DIR_ANY_TO_B));
}
/* Or Selected */
static void
conv_apply_or_selected_AtofromB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_OR_SELECTED, DIR_A_TO_FROM_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_OR_SELECTED, CONV_DIR_A_TO_FROM_B));
}
static void
conv_apply_or_selected_AtoB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_OR_SELECTED, DIR_A_TO_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_OR_SELECTED, CONV_DIR_A_TO_B));
}
static void
conv_apply_or_selected_AfromB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_OR_SELECTED, DIR_A_FROM_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_OR_SELECTED, CONV_DIR_A_FROM_B));
}
static void
conv_apply_or_selected_AtofromAny_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_OR_SELECTED, DIR_A_TO_FROM_ANY));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_OR_SELECTED, CONV_DIR_A_TO_FROM_ANY));
}
static void
conv_apply_or_selected_AtoAny_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_OR_SELECTED, DIR_A_TO_ANY));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_OR_SELECTED, CONV_DIR_A_TO_ANY));
}
static void
conv_apply_or_selected_AfromAny_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_OR_SELECTED, DIR_A_FROM_ANY));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_OR_SELECTED, CONV_DIR_A_FROM_ANY));
}
static void
conv_apply_or_selected_AnytofromB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_OR_SELECTED, DIR_ANY_TO_FROM_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_OR_SELECTED, CONV_DIR_ANY_TO_FROM_B));
}
static void
conv_apply_or_selected_AnyfromB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_OR_SELECTED, DIR_ANY_FROM_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_OR_SELECTED, CONV_DIR_ANY_FROM_B));
}
static void
conv_apply_or_selected_AnytoB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_OR_SELECTED, DIR_ANY_TO_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_OR_SELECTED, CONV_DIR_ANY_TO_B));
}
/* And Not Selected */
static void
conv_apply_and_not_selected_AtofromB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_AND_NOT_SELECTED, DIR_A_TO_FROM_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_AND_NOT_SELECTED, CONV_DIR_A_TO_FROM_B));
}
static void
conv_apply_and_not_selected_AtoB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_AND_NOT_SELECTED, DIR_A_TO_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_AND_NOT_SELECTED, CONV_DIR_A_TO_B));
}
static void
conv_apply_and_not_selected_AfromB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_AND_NOT_SELECTED, DIR_A_FROM_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_AND_NOT_SELECTED, CONV_DIR_A_FROM_B));
}
static void
conv_apply_and_not_selected_AtofromAny_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_AND_NOT_SELECTED, DIR_A_TO_FROM_ANY));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_AND_NOT_SELECTED, CONV_DIR_A_TO_FROM_ANY));
}
static void
conv_apply_and_not_selected_AtoAny_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_AND_NOT_SELECTED, DIR_A_TO_ANY));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_AND_NOT_SELECTED, CONV_DIR_A_TO_ANY));
}
static void
conv_apply_and_not_selected_AfromAny_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_AND_NOT_SELECTED, DIR_A_FROM_ANY));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_AND_NOT_SELECTED, CONV_DIR_A_FROM_ANY));
}
static void
conv_apply_and_not_selected_AnytofromB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_AND_NOT_SELECTED, DIR_ANY_TO_FROM_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_AND_NOT_SELECTED, CONV_DIR_ANY_TO_FROM_B));
}
static void
conv_apply_and_not_selected_AnyfromB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_AND_NOT_SELECTED, DIR_ANY_FROM_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_AND_NOT_SELECTED, CONV_DIR_ANY_FROM_B));
}
static void
conv_apply_and_not_selected_AnytoB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_AND_NOT_SELECTED, DIR_ANY_TO_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_AND_NOT_SELECTED, CONV_DIR_ANY_TO_B));
}
/* Or Not Selected */
static void
conv_apply_or_not_selected_AtofromB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_OR_NOT_SELECTED, DIR_A_TO_FROM_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_OR_NOT_SELECTED, CONV_DIR_A_TO_FROM_B));
}
static void
conv_apply_or_not_selected_AtoB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_AND_NOT_SELECTED, DIR_A_TO_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_AND_NOT_SELECTED, CONV_DIR_A_TO_B));
}
static void
conv_apply_or_not_selected_AfromB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_OR_NOT_SELECTED, DIR_A_FROM_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_OR_NOT_SELECTED, CONV_DIR_A_FROM_B));
}
static void
conv_apply_or_not_selected_AtofromAny_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_OR_NOT_SELECTED, DIR_A_TO_FROM_ANY));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_OR_NOT_SELECTED, CONV_DIR_A_TO_FROM_ANY));
}
static void
conv_apply_or_not_selected_AtoAny_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_OR_NOT_SELECTED, DIR_A_TO_ANY));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_OR_NOT_SELECTED, CONV_DIR_A_TO_ANY));
}
static void
conv_apply_or_not_selected_AfromAny_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_OR_NOT_SELECTED, DIR_A_FROM_ANY));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_OR_NOT_SELECTED, CONV_DIR_A_FROM_ANY));
}
static void
conv_apply_or_not_selected_AnytofromB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_OR_NOT_SELECTED, DIR_ANY_TO_FROM_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_OR_NOT_SELECTED, CONV_DIR_ANY_TO_FROM_B));
}
static void
conv_apply_or_not_selected_AnyfromB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_OR_NOT_SELECTED, DIR_ANY_FROM_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_OR_NOT_SELECTED, CONV_DIR_ANY_FROM_B));
}
static void
conv_apply_or_not_selected_AnytoB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_OR_NOT_SELECTED, DIR_ANY_TO_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_MATCH(ACTYPE_OR_NOT_SELECTED, CONV_DIR_ANY_TO_B));
}
@@ -970,495 +591,495 @@ conv_apply_or_not_selected_AnytoB_cb(GtkAction *action _U_, gpointer user_data)
static void
conv_prepare_as_selected_AtofromB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_SELECTED, DIR_A_TO_FROM_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_SELECTED, CONV_DIR_A_TO_FROM_B));
}
static void
conv_prepare_as_selected_AtoB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_SELECTED, DIR_A_TO_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_SELECTED, CONV_DIR_A_TO_B));
}
static void
conv_prepare_as_selected_AfromB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_SELECTED, DIR_A_FROM_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_SELECTED, CONV_DIR_A_FROM_B));
}
static void
conv_prepare_as_selected_AtofromAny_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_SELECTED, DIR_A_TO_FROM_ANY));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_SELECTED, CONV_DIR_A_TO_FROM_ANY));
}
static void
conv_prepare_as_selected_AtoAny_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_SELECTED, DIR_A_TO_ANY));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_SELECTED, CONV_DIR_A_TO_ANY));
}
static void
conv_prepare_as_selected_AfromAny_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_SELECTED, DIR_A_FROM_ANY));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_SELECTED, CONV_DIR_A_FROM_ANY));
}
static void
conv_prepare_as_selected_AnytofromB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_SELECTED, DIR_ANY_TO_FROM_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_SELECTED, CONV_DIR_ANY_TO_FROM_B));
}
static void
conv_prepare_as_selected_AnyfromB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_SELECTED, DIR_ANY_FROM_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_SELECTED, CONV_DIR_ANY_FROM_B));
}
static void
conv_prepare_as_selected_AnytoB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_SELECTED, DIR_ANY_TO_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_SELECTED, CONV_DIR_ANY_TO_B));
}
/* Prepare As Not Selected */
static void
conv_prepare_as_not_selected_AtofromB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_NOT_SELECTED, DIR_A_TO_FROM_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_NOT_SELECTED, CONV_DIR_A_TO_FROM_B));
}
static void
conv_prepare_as_not_selected_AtoB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_NOT_SELECTED, DIR_A_TO_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_NOT_SELECTED, CONV_DIR_A_TO_B));
}
static void
conv_prepare_as_not_selected_AfromB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_NOT_SELECTED, DIR_A_FROM_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_NOT_SELECTED, CONV_DIR_A_FROM_B));
}
static void
conv_prepare_as_not_selected_AtofromAny_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_NOT_SELECTED, DIR_A_TO_FROM_ANY));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_NOT_SELECTED, CONV_DIR_A_TO_FROM_ANY));
}
static void
conv_prepare_as_not_selected_AtoAny_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_NOT_SELECTED, DIR_A_TO_ANY));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_NOT_SELECTED, CONV_DIR_A_TO_ANY));
}
static void
conv_prepare_as_not_selected_AfromAny_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_NOT_SELECTED, DIR_A_FROM_ANY));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_NOT_SELECTED, CONV_DIR_A_FROM_ANY));
}
static void
conv_prepare_as_not_selected_AnytofromB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_NOT_SELECTED, DIR_ANY_TO_FROM_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_NOT_SELECTED, CONV_DIR_ANY_TO_FROM_B));
}
static void
conv_prepare_as_not_selected_AnyfromB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_NOT_SELECTED, DIR_ANY_FROM_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_NOT_SELECTED, CONV_DIR_ANY_FROM_B));
}
static void
conv_prepare_as_not_selected_AnytoB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_NOT_SELECTED, DIR_ANY_TO_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_NOT_SELECTED, CONV_DIR_ANY_TO_B));
}
/* Prepare And Selected */
static void
conv_prepare_and_selected_AtofromB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_AND_SELECTED, DIR_A_TO_FROM_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_AND_SELECTED, CONV_DIR_A_TO_FROM_B));
}
static void
conv_prepare_and_selected_AtoB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_AND_SELECTED, DIR_A_TO_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_AND_SELECTED, CONV_DIR_A_TO_B));
}
static void
conv_prepare_and_selected_AfromB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_AND_SELECTED, DIR_A_FROM_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_AND_SELECTED, CONV_DIR_A_FROM_B));
}
static void
conv_prepare_and_selected_AtofromAny_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_AND_SELECTED, DIR_A_TO_FROM_ANY));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_AND_SELECTED, CONV_DIR_A_TO_FROM_ANY));
}
static void
conv_prepare_and_selected_AtoAny_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_AND_SELECTED, DIR_A_TO_ANY));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_AND_SELECTED, CONV_DIR_A_TO_ANY));
}
static void
conv_prepare_and_selected_AfromAny_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_AND_SELECTED, DIR_A_FROM_ANY));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_AND_SELECTED, CONV_DIR_A_FROM_ANY));
}
static void
conv_prepare_and_selected_AnytofromB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_AND_SELECTED, DIR_ANY_TO_FROM_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_AND_SELECTED, CONV_DIR_ANY_TO_FROM_B));
}
static void
conv_prepare_and_selected_AnyfromB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_AND_SELECTED, DIR_ANY_FROM_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_AND_SELECTED, CONV_DIR_ANY_FROM_B));
}
static void
conv_prepare_and_selected_AnytoB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_AND_SELECTED, DIR_ANY_TO_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_AND_SELECTED, CONV_DIR_ANY_TO_B));
}
/* Prepare Or Selected */
static void
conv_prepare_or_selected_AtofromB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_OR_SELECTED, DIR_A_TO_FROM_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_OR_SELECTED, CONV_DIR_A_TO_FROM_B));
}
static void
conv_prepare_or_selected_AtoB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_OR_SELECTED, DIR_A_TO_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_OR_SELECTED, CONV_DIR_A_TO_B));
}
static void
conv_prepare_or_selected_AfromB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_OR_SELECTED, DIR_A_FROM_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_OR_SELECTED, CONV_DIR_A_FROM_B));
}
static void
conv_prepare_or_selected_AtofromAny_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_OR_SELECTED, DIR_A_TO_FROM_ANY));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_OR_SELECTED, CONV_DIR_A_TO_FROM_ANY));
}
static void
conv_prepare_or_selected_AtoAny_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_OR_SELECTED, DIR_A_TO_ANY));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_OR_SELECTED, CONV_DIR_A_TO_ANY));
}
static void
conv_prepare_or_selected_AfromAny_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_OR_SELECTED, DIR_A_FROM_ANY));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_OR_SELECTED, CONV_DIR_A_FROM_ANY));
}
static void
conv_prepare_or_selected_AnytofromB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_OR_SELECTED, DIR_ANY_TO_FROM_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_OR_SELECTED, CONV_DIR_ANY_TO_FROM_B));
}
static void
conv_prepare_or_selected_AnyfromB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_OR_SELECTED, DIR_ANY_FROM_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_OR_SELECTED, CONV_DIR_ANY_FROM_B));
}
static void
conv_prepare_or_selected_AnytoB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_OR_SELECTED, DIR_ANY_TO_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_OR_SELECTED, CONV_DIR_ANY_TO_B));
}
/* Prepare And Not Selected */
static void
conv_prepare_and_not_selected_AtofromB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_AND_NOT_SELECTED, DIR_A_TO_FROM_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_AND_NOT_SELECTED, CONV_DIR_A_TO_FROM_B));
}
static void
conv_prepare_and_not_selected_AtoB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_AND_NOT_SELECTED, DIR_A_TO_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_AND_NOT_SELECTED, CONV_DIR_A_TO_B));
}
static void
conv_prepare_and_not_selected_AfromB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_AND_NOT_SELECTED, DIR_A_FROM_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_AND_NOT_SELECTED, CONV_DIR_A_FROM_B));
}
static void
conv_prepare_and_not_selected_AtofromAny_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_AND_NOT_SELECTED, DIR_A_TO_FROM_ANY));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_AND_NOT_SELECTED, CONV_DIR_A_TO_FROM_ANY));
}
static void
conv_prepare_and_not_selected_AtoAny_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_AND_NOT_SELECTED, DIR_A_TO_ANY));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_AND_NOT_SELECTED, CONV_DIR_A_TO_ANY));
}
static void
conv_prepare_and_not_selected_AfromAny_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_AND_NOT_SELECTED, DIR_A_FROM_ANY));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_AND_NOT_SELECTED, CONV_DIR_A_FROM_ANY));
}
static void
conv_prepare_and_not_selected_AnytofromB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_AND_NOT_SELECTED, DIR_ANY_TO_FROM_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_AND_NOT_SELECTED, CONV_DIR_ANY_TO_FROM_B));
}
static void
conv_prepare_and_not_selected_AnyfromB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_AND_NOT_SELECTED, DIR_ANY_FROM_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_AND_NOT_SELECTED, CONV_DIR_ANY_FROM_B));
}
static void
conv_prepare_and_not_selected_AnytoB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_AND_NOT_SELECTED, DIR_ANY_TO_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_AND_NOT_SELECTED, CONV_DIR_ANY_TO_B));
}
/* Prepare Or Not Selected */
static void
conv_prepare_or_not_selected_AtofromB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_OR_NOT_SELECTED, DIR_A_TO_FROM_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_OR_NOT_SELECTED, CONV_DIR_A_TO_FROM_B));
}
static void
conv_prepare_or_not_selected_AtoB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_AND_NOT_SELECTED, DIR_A_TO_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_AND_NOT_SELECTED, CONV_DIR_A_TO_B));
}
static void
conv_prepare_or_not_selected_AfromB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_OR_NOT_SELECTED, DIR_A_FROM_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_OR_NOT_SELECTED, CONV_DIR_A_FROM_B));
}
static void
conv_prepare_or_not_selected_AtofromAny_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_OR_NOT_SELECTED, DIR_A_TO_FROM_ANY));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_OR_NOT_SELECTED, CONV_DIR_A_TO_FROM_ANY));
}
static void
conv_prepare_or_not_selected_AtoAny_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_OR_NOT_SELECTED, DIR_A_TO_ANY));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_OR_NOT_SELECTED, CONV_DIR_A_TO_ANY));
}
static void
conv_prepare_or_not_selected_AfromAny_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_OR_NOT_SELECTED, DIR_A_FROM_ANY));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_OR_NOT_SELECTED, CONV_DIR_A_FROM_ANY));
}
static void
conv_prepare_or_not_selected_AnytofromB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_OR_NOT_SELECTED, DIR_ANY_TO_FROM_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_OR_NOT_SELECTED, CONV_DIR_ANY_TO_FROM_B));
}
static void
conv_prepare_or_not_selected_AnyfromB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_OR_NOT_SELECTED, DIR_ANY_FROM_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_OR_NOT_SELECTED, CONV_DIR_ANY_FROM_B));
}
static void
conv_prepare_or_not_selected_AnytoB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_OR_NOT_SELECTED, DIR_ANY_TO_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_PREPARE(ACTYPE_OR_NOT_SELECTED, CONV_DIR_ANY_TO_B));
}
/* Find packet */
static void
conv_find_AtofromB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_FIND_FRAME(ACTYPE_SELECTED, DIR_A_TO_FROM_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_FIND_FRAME(ACTYPE_SELECTED, CONV_DIR_A_TO_FROM_B));
}
static void
conv_find_AtoB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_FIND_FRAME(ACTYPE_SELECTED, DIR_A_TO_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_FIND_FRAME(ACTYPE_SELECTED, CONV_DIR_A_TO_B));
}
static void
conv_find_AfromB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_FIND_FRAME(ACTYPE_SELECTED, DIR_A_FROM_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_FIND_FRAME(ACTYPE_SELECTED, CONV_DIR_A_FROM_B));
}
static void
conv_find_AtofromAny_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_FIND_FRAME(ACTYPE_SELECTED, DIR_A_TO_FROM_ANY));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_FIND_FRAME(ACTYPE_SELECTED, CONV_DIR_A_TO_FROM_ANY));
}
static void
conv_find_AtoAny_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_FIND_FRAME(ACTYPE_SELECTED, DIR_A_TO_ANY));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_FIND_FRAME(ACTYPE_SELECTED, CONV_DIR_A_TO_ANY));
}
static void
conv_find_AfromAny_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_FIND_FRAME(ACTYPE_SELECTED, DIR_A_FROM_ANY));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_FIND_FRAME(ACTYPE_SELECTED, CONV_DIR_A_FROM_ANY));
}
static void
conv_find_AnytofromB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_FIND_FRAME(ACTYPE_SELECTED, DIR_ANY_TO_FROM_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_FIND_FRAME(ACTYPE_SELECTED, CONV_DIR_ANY_TO_FROM_B));
}
static void
conv_find_AnyfromB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_FIND_FRAME(ACTYPE_SELECTED, DIR_ANY_FROM_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_FIND_FRAME(ACTYPE_SELECTED, CONV_DIR_ANY_FROM_B));
}
static void
conv_find_AnytoB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_FIND_FRAME(ACTYPE_SELECTED, DIR_ANY_TO_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_FIND_FRAME(ACTYPE_SELECTED, CONV_DIR_ANY_TO_B));
}
/* Find next */
static void
conv_find_next_AtofromB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_FIND_NEXT(ACTYPE_NOT_SELECTED, DIR_A_TO_FROM_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_FIND_NEXT(ACTYPE_NOT_SELECTED, CONV_DIR_A_TO_FROM_B));
}
static void
conv_find_next_AtoB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_FIND_NEXT(ACTYPE_NOT_SELECTED, DIR_A_TO_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_FIND_NEXT(ACTYPE_NOT_SELECTED, CONV_DIR_A_TO_B));
}
static void
conv_find_next_AfromB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_FIND_NEXT(ACTYPE_NOT_SELECTED, DIR_A_FROM_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_FIND_NEXT(ACTYPE_NOT_SELECTED, CONV_DIR_A_FROM_B));
}
static void
conv_find_next_AtofromAny_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_FIND_NEXT(ACTYPE_NOT_SELECTED, DIR_A_TO_FROM_ANY));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_FIND_NEXT(ACTYPE_NOT_SELECTED, CONV_DIR_A_TO_FROM_ANY));
}
static void
conv_find_next_AtoAny_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_FIND_NEXT(ACTYPE_NOT_SELECTED, DIR_A_TO_ANY));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_FIND_NEXT(ACTYPE_NOT_SELECTED, CONV_DIR_A_TO_ANY));
}
static void
conv_find_next_AfromAny_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_FIND_NEXT(ACTYPE_NOT_SELECTED, DIR_A_FROM_ANY));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_FIND_NEXT(ACTYPE_NOT_SELECTED, CONV_DIR_A_FROM_ANY));
}
static void
conv_find_next_AnytofromB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_FIND_NEXT(ACTYPE_NOT_SELECTED, DIR_ANY_TO_FROM_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_FIND_NEXT(ACTYPE_NOT_SELECTED, CONV_DIR_ANY_TO_FROM_B));
}
static void
conv_find_next_AnyfromB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_FIND_NEXT(ACTYPE_NOT_SELECTED, DIR_ANY_FROM_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_FIND_NEXT(ACTYPE_NOT_SELECTED, CONV_DIR_ANY_FROM_B));
}
static void
conv_find_next_AnytoB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_FIND_NEXT(ACTYPE_NOT_SELECTED, DIR_ANY_TO_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_FIND_NEXT(ACTYPE_NOT_SELECTED, CONV_DIR_ANY_TO_B));
}
/* Find Previous */
static void
conv_find_previous_AtofromB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_FIND_PREVIOUS(ACTYPE_AND_SELECTED, DIR_A_TO_FROM_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_FIND_PREVIOUS(ACTYPE_AND_SELECTED, CONV_DIR_A_TO_FROM_B));
}
static void
conv_find_previous_AtoB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_FIND_PREVIOUS(ACTYPE_AND_SELECTED, DIR_A_TO_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_FIND_PREVIOUS(ACTYPE_AND_SELECTED, CONV_DIR_A_TO_B));
}
static void
conv_find_previous_AfromB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_FIND_PREVIOUS(ACTYPE_AND_SELECTED, DIR_A_FROM_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_FIND_PREVIOUS(ACTYPE_AND_SELECTED, CONV_DIR_A_FROM_B));
}
static void
conv_find_previous_AtofromAny_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_FIND_PREVIOUS(ACTYPE_AND_SELECTED, DIR_A_TO_FROM_ANY));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_FIND_PREVIOUS(ACTYPE_AND_SELECTED, CONV_DIR_A_TO_FROM_ANY));
}
static void
conv_find_previous_AtoAny_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_FIND_PREVIOUS(ACTYPE_AND_SELECTED, DIR_A_TO_ANY));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_FIND_PREVIOUS(ACTYPE_AND_SELECTED, CONV_DIR_A_TO_ANY));
}
static void
conv_find_previous_AfromAny_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_FIND_PREVIOUS(ACTYPE_AND_SELECTED, DIR_A_FROM_ANY));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_FIND_PREVIOUS(ACTYPE_AND_SELECTED, CONV_DIR_A_FROM_ANY));
}
static void
conv_find_previous_AnytofromB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_FIND_PREVIOUS(ACTYPE_AND_SELECTED, DIR_ANY_TO_FROM_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_FIND_PREVIOUS(ACTYPE_AND_SELECTED, CONV_DIR_ANY_TO_FROM_B));
}
static void
conv_find_previous_AnyfromB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_FIND_PREVIOUS(ACTYPE_AND_SELECTED, DIR_ANY_FROM_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_FIND_PREVIOUS(ACTYPE_AND_SELECTED, CONV_DIR_ANY_FROM_B));
}
static void
conv_find_previous_AnytoB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_FIND_PREVIOUS(ACTYPE_AND_SELECTED, DIR_ANY_TO_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_FIND_PREVIOUS(ACTYPE_AND_SELECTED, CONV_DIR_ANY_TO_B));
}
/* Colorize Conversation */
@@ -1466,55 +1087,55 @@ conv_find_previous_AnytoB_cb(GtkAction *action _U_, gpointer user_data)
static void
conv_color_AtofromB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_COLORIZE(ACTYPE_SELECTED, DIR_A_TO_FROM_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_COLORIZE(ACTYPE_SELECTED, CONV_DIR_A_TO_FROM_B));
}
static void
conv_color_AtoB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_COLORIZE(ACTYPE_SELECTED, DIR_A_TO_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_COLORIZE(ACTYPE_SELECTED, CONV_DIR_A_TO_B));
}
static void
conv_color_AfromB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_COLORIZE(ACTYPE_SELECTED, DIR_A_FROM_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_COLORIZE(ACTYPE_SELECTED, CONV_DIR_A_FROM_B));
}
static void
conv_color_AtofromAny_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_COLORIZE(ACTYPE_SELECTED, DIR_A_TO_FROM_ANY));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_COLORIZE(ACTYPE_SELECTED, CONV_DIR_A_TO_FROM_ANY));
}
static void
conv_color_AtoAny_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_COLORIZE(ACTYPE_SELECTED, DIR_A_TO_ANY));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_COLORIZE(ACTYPE_SELECTED, CONV_DIR_A_TO_ANY));
}
static void
conv_color_AfromAny_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_COLORIZE(ACTYPE_SELECTED, DIR_A_FROM_ANY));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_COLORIZE(ACTYPE_SELECTED, CONV_DIR_A_FROM_ANY));
}
static void
conv_color_AnytofromB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_COLORIZE(ACTYPE_SELECTED, DIR_ANY_TO_FROM_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_COLORIZE(ACTYPE_SELECTED, CONV_DIR_ANY_TO_FROM_B));
}
static void
conv_color_AnyfromB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_COLORIZE(ACTYPE_SELECTED, DIR_ANY_FROM_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_COLORIZE(ACTYPE_SELECTED, CONV_DIR_ANY_FROM_B));
}
static void
conv_color_AnytoB_cb(GtkAction *action _U_, gpointer user_data)
{
- ct_select_filter_cb( NULL, user_data, CALLBACK_COLORIZE(ACTYPE_SELECTED, DIR_ANY_TO_B));
+ ct_select_filter_cb( NULL, user_data, CALLBACK_COLORIZE(ACTYPE_SELECTED, CONV_DIR_ANY_TO_B));
}
static const char *ui_desc_conv_filter_popup =
"<ui>\n"
@@ -1960,84 +1581,32 @@ ct_create_popup_menu(conversations_table *ct)
}
-/* Draw/refresh the address fields of a single entry at the specified index */
-static void
-get_ct_table_address(conversations_table *ct, conv_t *conv, const char **entries)
-{
- char *port;
- guint32 pt;
-
- if(!ct->resolve_names)
- entries[0] = ep_address_to_str(&conv->src_address);
- else {
- entries[0] = (const char *)ep_address_to_display(&conv->src_address);
- }
-
- pt = conv->port_type;
- if(!ct->resolve_names) pt = PT_NONE;
- switch(pt) {
- case(PT_TCP):
- entries[1] = ep_tcp_port_to_display(conv->src_port);
- break;
- case(PT_UDP):
- entries[1] = ep_udp_port_to_display(conv->src_port);
- break;
- case(PT_SCTP):
- entries[1] = ep_sctp_port_to_display(conv->src_port);
- break;
- default:
- port=ct_port_to_str(conv->port_type, conv->src_port);
- entries[1] = port?port:"";
- }
-
- if(!ct->resolve_names)
- entries[2]=ep_address_to_str(&conv->dst_address);
- else {
- entries[2]=(const char *)ep_address_to_display(&conv->dst_address);
- }
-
- switch(pt) {
- case(PT_TCP):
- entries[3]=ep_tcp_port_to_display(conv->dst_port);
- break;
- case(PT_UDP):
- entries[3]=ep_udp_port_to_display(conv->dst_port);
- break;
- case(PT_SCTP):
- entries[3]=ep_sctp_port_to_display(conv->dst_port);
- break;
- default:
- port=ct_port_to_str(conv->port_type, conv->dst_port);
- entries[3]=port?port:"";
- }
-}
-
/* Refresh the address fields of all entries in the list */
static void
draw_ct_table_addresses(conversations_table *ct)
{
- guint32 i;
- const char *entries[4];
+ guint idx;
GtkListStore *store;
-
- if (!ct->num_conversations)
- return;
+ GtkTreeIter iter;
+ gboolean iter_valid;
store = GTK_LIST_STORE(gtk_tree_view_get_model(ct->table));
g_object_ref(store);
gtk_tree_view_set_model(GTK_TREE_VIEW(ct->table), NULL);
-
- for(i=0;i<ct->num_conversations;i++){
- conv_t *conv = &g_array_index(ct->conversations, conv_t, i);
- if (!conv->iter_valid)
- continue;
- get_ct_table_address(ct, conv, entries);
- gtk_list_store_set (store, &conv->iter,
- SRC_ADR_COLUMN, entries[0],
- SRC_PORT_COLUMN, entries[1],
- DST_ADR_COLUMN, entries[2],
- DST_PORT_COLUMN, entries[3],
+ iter_valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), &iter);
+
+ while (iter_valid) {
+ conv_item_t *conv_item;
+
+ gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, CONV_INDEX_COLUMN, &idx, -1);
+ conv_item = &g_array_index(ct->hash.conv_array, conv_item_t, idx);
+ gtk_list_store_set (store, &iter,
+ CONV_COLUMN_SRC_ADDR, get_conversation_address(&conv_item->src_address, ct->resolve_names),
+ CONV_COLUMN_SRC_PORT, get_conversation_port(conv_item->src_port, conv_item->ptype, ct->resolve_names),
+ CONV_COLUMN_DST_ADDR, get_conversation_address(&conv_item->dst_address, ct->resolve_names),
+ CONV_COLUMN_DST_PORT, get_conversation_port(conv_item->src_port, conv_item->ptype, ct->resolve_names),
-1);
+ iter_valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(store), &iter);
}
gtk_tree_view_set_model(GTK_TREE_VIEW(ct->table), GTK_TREE_MODEL(store));
@@ -2047,22 +1616,24 @@ draw_ct_table_addresses(conversations_table *ct)
static void
draw_ct_table_data(conversations_table *ct)
{
- guint32 i;
+ guint idx, new_idx;
char title[256];
GtkListStore *store;
+ GtkTreeIter iter, reselect_iter;
+ gboolean iter_valid;
gboolean first = TRUE;
if (ct->page_lb) {
- if(ct->num_conversations) {
- g_snprintf(title, sizeof(title), "%s: %u", ct->name, ct->num_conversations);
+ if(ct->hash.conv_array && ct->hash.conv_array->len) {
+ g_snprintf(title, sizeof(title), "%s: %u", ct->name, ct->hash.conv_array->len);
} else {
g_snprintf(title, sizeof(title), "%s", ct->name);
}
gtk_label_set_text(GTK_LABEL(ct->page_lb), title);
- gtk_widget_set_sensitive(ct->page_lb, ct->num_conversations);
+ gtk_widget_set_sensitive(ct->page_lb, ct->hash.conv_array && ct->hash.conv_array->len);
} else {
- if(ct->num_conversations) {
- g_snprintf(title, sizeof(title), "%s Conversations: %u", ct->name, ct->num_conversations);
+ if(ct->hash.conv_array && ct->hash.conv_array->len) {
+ g_snprintf(title, sizeof(title), "%s Conversations: %u", ct->name, ct->hash.conv_array->len);
} else {
g_snprintf(title, sizeof(title), "%s Conversations", ct->name);
}
@@ -2070,16 +1641,33 @@ draw_ct_table_data(conversations_table *ct)
}
store = GTK_LIST_STORE(gtk_tree_view_get_model(ct->table));
+ iter_valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), &iter);
+ new_idx = gtk_tree_model_iter_n_children(GTK_TREE_MODEL(store), NULL);
- for(i=0;i<ct->num_conversations;i++){
+ /* Update list items (which may not be in "idx" order), then add new items */
+ while (iter_valid || (ct->hash.conv_array && new_idx < ct->hash.conv_array->len)) {
char start_time[COL_STR_LEN], duration[COL_STR_LEN],
txbps[COL_STR_LEN], rxbps[COL_STR_LEN];
const char *tx_ptr, *rx_ptr;
double duration_s;
- conv_t *conversation = &g_array_index(ct->conversations, conv_t, i);
+ conv_item_t *conv_item;
+
+ if (iter_valid) {
+ gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, CONV_INDEX_COLUMN, &idx, -1);
+ } else {
+ idx = new_idx;
+ new_idx++;
+ }
+ conv_item = &g_array_index(ct->hash.conv_array, conv_item_t, idx);
- if (!conversation->modified)
+ if (!conv_item->modified) {
+ iter_valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(store), &iter);
continue;
+ }
+
+ if (iter_valid && (int)idx == ct->reselection_idx) {
+ reselect_iter = iter;
+ }
if (first) {
g_object_ref(store);
@@ -2087,66 +1675,64 @@ draw_ct_table_data(conversations_table *ct)
first = FALSE;
}
- duration_s = nstime_to_sec(&conversation->stop_time) - nstime_to_sec(&conversation->start_time);
- g_snprintf(start_time, COL_STR_LEN, "%.9f", nstime_to_sec(&conversation->start_time));
+ duration_s = nstime_to_sec(&conv_item->stop_time) - nstime_to_sec(&conv_item->start_time);
+ g_snprintf(start_time, COL_STR_LEN, "%.9f", nstime_to_sec(&conv_item->start_time));
g_snprintf(duration, COL_STR_LEN, "%.4f", duration_s);
- if (duration_s > 0 && conversation->tx_frames > 1) {
- g_snprintf(txbps, COL_STR_LEN, "%.2f", (gint64) conversation->tx_bytes * 8 / duration_s);
+ if (duration_s > 0 && conv_item->tx_frames > 1) {
+ g_snprintf(txbps, COL_STR_LEN, "%.2f", (gint64) conv_item->tx_bytes * 8 / duration_s);
tx_ptr = txbps;
} else {
- tx_ptr = NO_BPS_STR;
+ tx_ptr = NO_BPS_STR;
}
- if (duration_s > 0 && conversation->rx_frames > 1) {
- g_snprintf(rxbps, COL_STR_LEN, "%.2f", (gint64) conversation->rx_bytes * 8 / duration_s);
+ if (duration_s > 0 && conv_item->rx_frames > 1) {
+ g_snprintf(rxbps, COL_STR_LEN, "%.2f", (gint64) conv_item->rx_bytes * 8 / duration_s);
rx_ptr = rxbps;
} else {
rx_ptr = NO_BPS_STR;
}
- conversation->modified = FALSE;
- if (!conversation->iter_valid) {
- const char *entries[4];
-
- get_ct_table_address(ct, conversation, entries);
- conversation->iter_valid = TRUE;
-
- /* All entries, including fixed ones */
- gtk_list_store_insert_with_values( store , &conversation->iter, G_MAXINT,
- SRC_ADR_COLUMN, entries[0],
- SRC_PORT_COLUMN, entries[1],
- DST_ADR_COLUMN, entries[2],
- DST_PORT_COLUMN, entries[3],
- PACKETS_COLUMN, conversation->tx_frames+conversation->rx_frames,
- BYTES_COLUMN, conversation->tx_bytes+conversation->rx_bytes,
- PKT_AB_COLUMN, conversation->tx_frames,
- BYTES_AB_COLUMN, conversation->tx_bytes,
- PKT_BA_COLUMN, conversation->rx_frames,
- BYTES_BA_COLUMN, conversation->rx_bytes,
- START_COLUMN, start_time,
- DURATION_COLUMN, duration,
- BPS_AB_COLUMN, tx_ptr,
- BPS_BA_COLUMN, rx_ptr,
- INDEX_COLUMN, i,
+ conv_item->modified = FALSE;
+
+ if (iter_valid) {
+ /* Existing row. Only changeable entries */
+ gtk_list_store_set(store, &iter,
+ CONV_COLUMN_PACKETS, conv_item->tx_frames+conv_item->rx_frames,
+ CONV_COLUMN_BYTES, conv_item->tx_bytes+conv_item->rx_bytes,
+ CONV_COLUMN_PKT_AB, conv_item->tx_frames,
+ CONV_COLUMN_BYTES_AB, conv_item->tx_bytes,
+ CONV_COLUMN_PKT_BA, conv_item->rx_frames,
+ CONV_COLUMN_BYTES_BA, conv_item->rx_bytes,
+ CONV_COLUMN_START, start_time,
+ CONV_COLUMN_DURATION, duration,
+ CONV_COLUMN_BPS_AB, tx_ptr,
+ CONV_COLUMN_BPS_BA, rx_ptr,
-1);
- }
- else {
- /* Only changeable entries */
- gtk_list_store_set (store, &conversation->iter,
- PACKETS_COLUMN, conversation->tx_frames+conversation->rx_frames,
- BYTES_COLUMN, conversation->tx_bytes+conversation->rx_bytes,
- PKT_AB_COLUMN, conversation->tx_frames,
- BYTES_AB_COLUMN, conversation->tx_bytes,
- PKT_BA_COLUMN, conversation->rx_frames,
- BYTES_BA_COLUMN, conversation->rx_bytes,
- START_COLUMN, start_time,
- DURATION_COLUMN, duration,
- BPS_AB_COLUMN, tx_ptr,
- BPS_BA_COLUMN, rx_ptr,
+ } else {
+ /* New row. All entries, including fixed ones */
+ gtk_list_store_insert_with_values(store, &iter, G_MAXINT,
+ CONV_COLUMN_SRC_ADDR, get_conversation_address(&conv_item->src_address, ct->resolve_names),
+ CONV_COLUMN_SRC_PORT, get_conversation_port(conv_item->src_port, conv_item->ptype, ct->resolve_names),
+ CONV_COLUMN_DST_ADDR, get_conversation_address(&conv_item->dst_address, ct->resolve_names),
+ CONV_COLUMN_DST_PORT, get_conversation_port(conv_item->src_port, conv_item->ptype, ct->resolve_names),
+ CONV_COLUMN_PACKETS, conv_item->tx_frames+conv_item->rx_frames,
+ CONV_COLUMN_BYTES, conv_item->tx_bytes+conv_item->rx_bytes,
+ CONV_COLUMN_PKT_AB, conv_item->tx_frames,
+ CONV_COLUMN_BYTES_AB, conv_item->tx_bytes,
+ CONV_COLUMN_PKT_BA, conv_item->rx_frames,
+ CONV_COLUMN_BYTES_BA, conv_item->rx_bytes,
+ CONV_COLUMN_START, start_time,
+ CONV_COLUMN_DURATION, duration,
+ CONV_COLUMN_BPS_AB, tx_ptr,
+ CONV_COLUMN_BPS_BA, rx_ptr,
+ CONV_INDEX_COLUMN, idx,
-1);
}
+
+ iter_valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(store), &iter);
}
+
if (!first) {
- if (!ct->fixed_col && ct->num_conversations >= 1000) {
+ if (!ct->fixed_col && ct->hash.conv_array && ct->hash.conv_array->len >= 1000) {
/* finding the right size for a column isn't easy
* let it run in autosize a little (1000 is arbitrary)
* and then switch to fixed width.
@@ -2161,13 +1747,10 @@ draw_ct_table_data(conversations_table *ct)
}
/* Restore conversation selection */
- if (ct->conversations && ct->reselection_idx != -1) {
- /* Look up the same conversation */
- conv_t *conversation = &g_array_index(ct->conversations, conv_t, ct->reselection_idx);
- if (conversation) {
- gtk_tree_selection_select_iter(gtk_tree_view_get_selection(GTK_TREE_VIEW(ct->table)),
- &conversation->iter);
- }
+ if (ct->hash.conv_array && ct->reselection_idx != -1) {
+ /* XXX This generates Gtk-CRITICAL **: GtkTreePath *gtk_list_store_get_path ... */
+ gtk_tree_selection_select_iter(gtk_tree_view_get_selection(GTK_TREE_VIEW(ct->table)),
+ &reselect_iter);
}
}
@@ -2179,7 +1762,7 @@ draw_ct_table_data_cb(void *arg)
typedef struct {
int nb_cols;
- gint columns_order[N_COLUMNS];
+ gint columns_order[CONV_NUM_COLUMNS];
GString *CSV_str;
conversations_table *talkers;
} csv_t;
@@ -2193,12 +1776,12 @@ csv_handle(GtkTreeModel *model, GtkTreePath *path _U_, GtkTreeIter *iter,
gchar *table_text;
int i;
guint idx;
- conv_t *conv;
+ conv_item_t *conv;
double duration_s;
guint64 value;
- gtk_tree_model_get(model, iter, INDEX_COLUMN, &idx, -1);
- conv=&g_array_index(csv->talkers->conversations, conv_t, idx);
+ gtk_tree_model_get(model, iter, CONV_INDEX_COLUMN, &idx, -1);
+ conv=&g_array_index(csv->talkers->hash.conv_array, conv_item_t, idx);
duration_s = nstime_to_sec(&conv->stop_time) - nstime_to_sec(&conv->start_time);
for (i=0; i< csv->nb_cols; i++) {
@@ -2206,39 +1789,39 @@ csv_handle(GtkTreeModel *model, GtkTreePath *path _U_, GtkTreeIter *iter,
g_string_append(csv->CSV_str, ",");
switch(csv->columns_order[i]) {
- case SRC_ADR_COLUMN:
- case SRC_PORT_COLUMN:
- case DST_ADR_COLUMN:
- case DST_PORT_COLUMN:
+ case CONV_COLUMN_SRC_ADDR:
+ case CONV_COLUMN_SRC_PORT:
+ case CONV_COLUMN_DST_ADDR:
+ case CONV_COLUMN_DST_PORT:
gtk_tree_model_get(model, iter, csv->columns_order[i], &table_text, -1);
if (table_text) {
g_string_append_printf(csv->CSV_str, "\"%s\"", table_text);
g_free(table_text);
}
break;
- case PACKETS_COLUMN:
- case BYTES_COLUMN:
- case PKT_AB_COLUMN:
- case BYTES_AB_COLUMN:
- case PKT_BA_COLUMN:
- case BYTES_BA_COLUMN:
+ case CONV_COLUMN_PACKETS:
+ case CONV_COLUMN_BYTES:
+ case CONV_COLUMN_PKT_AB:
+ case CONV_COLUMN_BYTES_AB:
+ case CONV_COLUMN_PKT_BA:
+ case CONV_COLUMN_BYTES_BA:
gtk_tree_model_get(model, iter, csv->columns_order[i], &value, -1);
g_string_append_printf(csv->CSV_str, "\"%" G_GINT64_MODIFIER "u\"", value);
break;
- case START_COLUMN:
+ case CONV_COLUMN_START:
g_string_append_printf(csv->CSV_str, "\"%.9f\"", nstime_to_sec(&conv->start_time));
break;
- case DURATION_COLUMN:
+ case CONV_COLUMN_DURATION:
g_string_append_printf(csv->CSV_str, "\"%.4f\"", duration_s);
break;
- case BPS_AB_COLUMN:
+ case CONV_COLUMN_BPS_AB:
if (duration_s > 0 && conv->tx_frames > 1) {
g_string_append_printf(csv->CSV_str, "\"%.2f\"", (gint64) conv->tx_bytes * 8 / duration_s);
} else {
g_string_append(csv->CSV_str, "\"" NO_BPS_STR "\"");
}
break;
- case BPS_BA_COLUMN:
+ case CONV_COLUMN_BPS_BA:
if (duration_s > 0 && conv->rx_frames > 1) {
g_string_append_printf(csv->CSV_str, "\"%.2f\"", (gint64) conv->rx_bytes * 8 / duration_s);
} else {
@@ -2296,26 +1879,25 @@ copy_as_csv_cb(GtkWindow *copy_bt, gpointer data _U_)
g_string_free(csv.CSV_str, TRUE); /* Free the memory */
}
-static gint default_col_size[N_COLUMNS];
+static gint default_col_size[CONV_NUM_COLUMNS];
static void
init_default_col_size(GtkWidget *view)
{
-
- default_col_size[SRC_ADR_COLUMN] = get_default_col_size(view, "00000000.000000000000");
- default_col_size[DST_ADR_COLUMN] = default_col_size[SRC_ADR_COLUMN];
- default_col_size[SRC_PORT_COLUMN] = get_default_col_size(view, "000000");
- default_col_size[DST_PORT_COLUMN] = default_col_size[SRC_PORT_COLUMN];
- default_col_size[PACKETS_COLUMN] = get_default_col_size(view, "00 000 000");
- default_col_size[BYTES_COLUMN] = get_default_col_size(view, "0 000 000 000");
- default_col_size[PKT_AB_COLUMN] = default_col_size[PACKETS_COLUMN];
- default_col_size[PKT_BA_COLUMN] = default_col_size[PACKETS_COLUMN];
- default_col_size[BYTES_AB_COLUMN] = default_col_size[BYTES_COLUMN];
- default_col_size[BYTES_BA_COLUMN] = default_col_size[BYTES_COLUMN];
- default_col_size[START_COLUMN] = get_default_col_size(view, "000000.000000000");
- default_col_size[DURATION_COLUMN] = get_default_col_size(view, "000000.0000");
- default_col_size[BPS_AB_COLUMN] = get_default_col_size(view, "000000000.00");
- default_col_size[BPS_BA_COLUMN] = default_col_size[BPS_AB_COLUMN];
+ default_col_size[CONV_COLUMN_SRC_ADDR] = get_default_col_size(view, "00000000.000000000000");
+ default_col_size[CONV_COLUMN_DST_ADDR] = default_col_size[CONV_COLUMN_SRC_ADDR];
+ default_col_size[CONV_COLUMN_SRC_PORT] = get_default_col_size(view, "000000");
+ default_col_size[CONV_COLUMN_DST_PORT] = default_col_size[CONV_COLUMN_SRC_PORT];
+ default_col_size[CONV_COLUMN_PACKETS] = get_default_col_size(view, "00 000 000");
+ default_col_size[CONV_COLUMN_BYTES] = get_default_col_size(view, "0 000 000 000");
+ default_col_size[CONV_COLUMN_PKT_AB] = default_col_size[CONV_COLUMN_PACKETS];
+ default_col_size[CONV_COLUMN_PKT_BA] = default_col_size[CONV_COLUMN_PACKETS];
+ default_col_size[CONV_COLUMN_BYTES_AB] = default_col_size[CONV_COLUMN_BYTES];
+ default_col_size[CONV_COLUMN_BYTES_BA] = default_col_size[CONV_COLUMN_BYTES];
+ default_col_size[CONV_COLUMN_START] = get_default_col_size(view, "000000.000000000");
+ default_col_size[CONV_COLUMN_DURATION] = get_default_col_size(view, "000000.0000");
+ default_col_size[CONV_COLUMN_BPS_AB] = get_default_col_size(view, "000000000.00");
+ default_col_size[CONV_COLUMN_BPS_BA] = default_col_size[CONV_COLUMN_BPS_AB];
}
static gboolean
@@ -2338,24 +1920,14 @@ init_ct_table_page(conversations_table *conversations, GtkWidget *vbox, gboolean
conversations->resolve_names=TRUE;
conversations->has_ports=!hide_ports;
conversations->fixed_col = FALSE;
- conversations->default_titles[0]="Address A",
- conversations->default_titles[1]="Port A";
- conversations->default_titles[2]="Address B";
- conversations->default_titles[3]="Port B";
- conversations->default_titles[4]="Packets";
- conversations->default_titles[5]="Bytes";
- conversations->default_titles[6]="Packets A" UTF8_RIGHTWARDS_ARROW "B";
- conversations->default_titles[7]="Bytes A" UTF8_RIGHTWARDS_ARROW "B";
- conversations->default_titles[8]="Packets A" UTF8_LEFTWARDS_ARROW "B";
- conversations->default_titles[9]="Bytes A" UTF8_LEFTWARDS_ARROW "B";
- conversations->default_titles[10]="Rel Start";
- conversations->default_titles[11]="Duration";
- conversations->default_titles[12]="bps A" UTF8_RIGHTWARDS_ARROW "B";
- conversations->default_titles[13]="bps A" UTF8_LEFTWARDS_ARROW "B";
+
+ for (i = 0; i < CONV_NUM_COLUMNS; i++) {
+ conversations->default_titles[i] = column_titles[i];
+ }
if (strcmp(table_name, "NCP")==0) {
- conversations->default_titles[1]="Connection A";
- conversations->default_titles[3]="Connection B";
+ conversations->default_titles[CONV_COLUMN_SRC_PORT] = conn_a_title;
+ conversations->default_titles[CONV_COLUMN_DST_PORT] = conn_b_title;
}
g_snprintf(title, sizeof(title), "%s Conversations", table_name);
@@ -2363,7 +1935,7 @@ init_ct_table_page(conversations_table *conversations, GtkWidget *vbox, gboolean
/* Create the store */
- store = gtk_list_store_new (N_COLUMNS, /* Total number of columns */
+ store = gtk_list_store_new (CONV_NUM_COLUMNS + 1, /* Total number of columns */
G_TYPE_STRING, /* Address A */
G_TYPE_STRING, /* Port A */
G_TYPE_STRING, /* Address B */
@@ -2400,14 +1972,14 @@ init_ct_table_page(conversations_table *conversations, GtkWidget *vbox, gboolean
g_object_set_data(G_OBJECT(store), CONV_PTR_KEY, conversations);
g_object_set_data(G_OBJECT(conversations->table), CONV_PTR_KEY, conversations);
- for (i = 0; i < N_COLUMNS -1; i++) {
+ for (i = 0; i < CONV_NUM_COLUMNS; i++) {
renderer = gtk_cell_renderer_text_new ();
g_object_set(renderer, "ypad", 0, NULL);
switch(i) {
- case SRC_ADR_COLUMN: /* addresses and ports */
- case SRC_PORT_COLUMN:
- case DST_ADR_COLUMN:
- case DST_PORT_COLUMN:
+ case CONV_COLUMN_SRC_ADDR: /* addresses and ports */
+ case CONV_COLUMN_SRC_PORT:
+ case CONV_COLUMN_DST_ADDR:
+ case CONV_COLUMN_DST_PORT:
column = gtk_tree_view_column_new_with_attributes (conversations->default_titles[i], renderer, "text",
i, NULL);
if(hide_ports && (i == 1 || i == 3)){
@@ -2416,12 +1988,12 @@ init_ct_table_page(conversations_table *conversations, GtkWidget *vbox, gboolean
}
gtk_tree_sortable_set_sort_func(sortable, i, ct_sort_func, GINT_TO_POINTER(i), NULL);
break;
- case PACKETS_COLUMN: /* counts */
- case BYTES_COLUMN:
- case PKT_AB_COLUMN:
- case BYTES_AB_COLUMN:
- case PKT_BA_COLUMN:
- case BYTES_BA_COLUMN:
+ case CONV_COLUMN_PACKETS: /* counts */
+ case CONV_COLUMN_BYTES:
+ case CONV_COLUMN_PKT_AB:
+ case CONV_COLUMN_BYTES_AB:
+ case CONV_COLUMN_PKT_BA:
+ case CONV_COLUMN_BYTES_BA:
g_object_set(G_OBJECT(renderer), "xalign", 1.0, NULL);
column = gtk_tree_view_column_new_with_attributes (conversations->default_titles[i], renderer, NULL);
gtk_tree_view_column_set_cell_data_func(column, renderer, u64_data_func, GINT_TO_POINTER(i), NULL);
@@ -2453,9 +2025,8 @@ 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->num_conversations=0;
- conversations->conversations=NULL;
- conversations->hashtable=NULL;
+ conversations->hash.conv_array=NULL;
+ conversations->hash.hashtable=NULL;
sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(conversations->table));
gtk_tree_selection_set_mode(sel, GTK_SELECTION_SINGLE);
@@ -2484,9 +2055,9 @@ graph_cb(GtkWidget *follow_stream_bt, gboolean reverse_direction)
GtkTreeModel *model;
GtkTreeSelection *sel;
guint32 idx = 0;
- conv_t *conv;
+ conv_item_t *conv;
- if (!ct)
+ if (!ct || !ct->hash.conv_array)
return;
/* Check for a current selection and that index has associated data */
@@ -2496,14 +2067,14 @@ graph_cb(GtkWidget *follow_stream_bt, gboolean reverse_direction)
return;
}
- gtk_tree_model_get (model, &iter, INDEX_COLUMN, &idx, -1);
- if (idx >= ct->num_conversations) {
+ gtk_tree_model_get (model, &iter, CONV_INDEX_COLUMN, &idx, -1);
+ if (idx >= ct->hash.conv_array->len) {
simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "No conversation selected");
return;
}
/* Look up the conversation for this index */
- conv = &g_array_index(ct->conversations, conv_t, idx);
+ conv = &g_array_index(ct->hash.conv_array, conv_item_t, idx);
if (strcmp(ct->name, "TCP") == 0) {
/* Invoke the graph */
@@ -2536,9 +2107,9 @@ follow_stream_cb(GtkWidget *follow_stream_bt, gpointer data _U_)
GtkTreeSelection *sel;
guint32 idx = 0;
gchar *filter = NULL;
- conv_t *conv;
+ conv_item_t *conv;
- if (!ct)
+ if (!ct || !ct->hash.conv_array)
return;
sel = gtk_tree_view_get_selection (GTK_TREE_VIEW(ct->table));
@@ -2547,13 +2118,13 @@ follow_stream_cb(GtkWidget *follow_stream_bt, gpointer data _U_)
return;
}
- gtk_tree_model_get (model, &iter, INDEX_COLUMN, &idx, -1);
- if (idx >= ct->num_conversations) {
+ gtk_tree_model_get (model, &iter, CONV_INDEX_COLUMN, &idx, -1);
+ if (idx >= ct->hash.conv_array->len) {
simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "No conversation selected");
return;
}
- conv = &g_array_index(ct->conversations, conv_t, idx);
+ conv = &g_array_index(ct->hash.conv_array, conv_item_t, idx);
/* Generate and apply a display filter to isolate the conversation. The
* TCP filter is a special case because it uses the stream identifier/index
@@ -2561,22 +2132,17 @@ follow_stream_cb(GtkWidget *follow_stream_bt, gpointer data _U_)
* in a unique conversation even in the face of port reuse. All others use
* the address/port tuple.
*/
- if ((strcmp(ct->name, "TCP") == 0) && (conv->conv_id != CONV_ID_UNSET))
- {
+ switch (conv->ptype) {
+ case PT_TCP:
filter = g_strdup_printf("tcp.stream eq %d", conv->conv_id);
+ break;
+ case PT_UDP:
+ filter = g_strdup_printf("udp.stream eq %d", conv->conv_id);
+ break;
+ default:
+ filter = g_strdup("INVALID");
}
- else
- {
- filter = g_strdup_printf("%s==%s && %s==%s && %s==%s && %s==%s",
- ct_get_filter_name(&conv->src_address, conv->sat, conv->port_type, FN_ANY_ADDRESS),
- ep_address_to_str(&conv->src_address),
- ct_get_filter_name(&conv->src_address, conv->sat, conv->port_type, FN_ANY_PORT),
- ct_port_to_str(conv->port_type, conv->src_port),
- ct_get_filter_name(&conv->dst_address, conv->sat, conv->port_type, FN_ANY_ADDRESS),
- ep_address_to_str(&conv->dst_address),
- ct_get_filter_name(&conv->dst_address, conv->sat, conv->port_type, FN_ANY_PORT),
- ct_port_to_str(conv->port_type, conv->dst_port));
- }
+
apply_selected_filter(ACTYPE_SELECTED|ACTION_MATCH, filter);
g_free(filter);
filter = NULL;
@@ -2597,11 +2163,12 @@ follow_stream_cb(GtkWidget *follow_stream_bt, gpointer data _U_)
void
-init_conversation_table(gboolean hide_ports, const char *table_name, const char *tap_name, const char *filter, tap_packet_cb packet_func)
+init_conversation_table(conversation_type_e conv_type, const char *filter, tap_packet_cb packet_func)
{
conversations_table *conversations;
char *display_name;
char title[256];
+ const char *table_name = conversation_title(conv_type);
GtkWidget *vbox;
GtkWidget *bbox;
GtkWidget *close_bt, *help_bt;
@@ -2631,7 +2198,10 @@ init_conversation_table(gboolean hide_ports, const char *table_name, const char
gtk_container_add(GTK_CONTAINER(conversations->win), vbox);
gtk_container_set_border_width(GTK_CONTAINER(vbox), DLG_OUTER_MARGIN);
- ret = init_ct_table_page(conversations, vbox, hide_ports, table_name, tap_name, filter, packet_func);
+ ret = init_ct_table_page(conversations, vbox,
+ conversation_hide_ports(conv_type),
+ table_name, conversation_tap_name(conv_type),
+ filter, packet_func);
if(ret == FALSE) {
g_free(conversations);
return;
@@ -2809,15 +2379,15 @@ typedef struct {
static GSList *registered_ct_tables = NULL;
void
-register_conversation_table(gboolean hide_ports, const char *table_name, const char *tap_name, const char *filter, tap_packet_cb packet_func)
+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 = hide_ports;
- table->table_name = table_name;
- table->tap_name = tap_name;
+ 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;
@@ -3011,202 +2581,6 @@ init_conversation_notebook_cb(GtkWidget *w _U_, gpointer d _U_)
gdk_window_raise(gtk_widget_get_window(win));
}
-typedef struct _key {
- address addr1;
- address addr2;
- guint32 port1;
- guint32 port2;
- conv_id_t conv_id;
-} conv_key_t;
-
-
-/*
- * Compute the hash value for two given address/port pairs if the match
- * is to be exact.
- */
-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, &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.
- */
-static gint
-conversation_match(gconstpointer v, gconstpointer w)
-{
- const conv_key_t *v1 = (const conv_key_t *)v;
- const conv_key_t *v2 = (const conv_key_t *)w;
-
- if (v1->conv_id == v2->conv_id)
- {
- if (v1->port1 == v2->port1 &&
- v1->port2 == v2->port2 &&
- ADDRESSES_EQUAL(&v1->addr1, &v2->addr1) &&
- ADDRESSES_EQUAL(&v1->addr2, &v2->addr2)) {
- return 1;
- }
-
- if (v1->port2 == v2->port1 &&
- v1->port1 == v2->port2 &&
- ADDRESSES_EQUAL(&v1->addr2, &v2->addr1) &&
- ADDRESSES_EQUAL(&v1->addr1, &v2->addr2)) {
- return 1;
- }
- }
-
- /*
- * The addresses, ports, or conversation IDs don't match.
- */
- return 0;
-}
-
-
-void
-add_conversation_table_data(conversations_table *ct, const address *src, const address *dst, guint32 src_port, guint32 dst_port, int num_frames, int num_bytes, nstime_t *ts, SAT_E sat, int port_type_val)
-{
- add_conversation_table_data_with_conv_id(ct, src, dst, src_port, dst_port, CONV_ID_UNSET, num_frames, num_bytes, ts, sat, port_type_val);
-}
-
-void
-add_conversation_table_data_with_conv_id(
- conversations_table *ct,
- 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,
- SAT_E sat,
- int port_type_val)
-{
- const address *addr1, *addr2;
- guint32 port1, port2;
- conv_t *conversation = 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 (ct->conversations == NULL) {
- ct->conversations = g_array_sized_new(FALSE, FALSE, sizeof(conv_t), 10000);
-
- ct->hashtable = g_hash_table_new_full(conversation_hash,
- conversation_match, /* 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;
- conversation_idx = GPOINTER_TO_UINT(g_hash_table_lookup(ct->hashtable, &existing_key));
- if (conversation_idx) {
- conversation_idx--;
- conversation=&g_array_index(ct->conversations, conv_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 (conversation == NULL) {
- conv_key_t *new_key;
- conv_t conv;
-
- COPY_ADDRESS(&conv.src_address, addr1);
- COPY_ADDRESS(&conv.dst_address, addr2);
- conv.sat = sat;
- conv.port_type = port_type_val;
- conv.src_port = port1;
- conv.dst_port = port2;
- conv.conv_id = conv_id;
- conv.rx_frames = 0;
- conv.tx_frames = 0;
- conv.rx_bytes = 0;
- conv.tx_bytes = 0;
- conv.iter_valid = FALSE;
- conv.modified = TRUE;
-
- if (ts) {
- memcpy(&conv.start_time, ts, sizeof(conv.start_time));
- memcpy(&conv.stop_time, ts, sizeof(conv.stop_time));
- } else {
- nstime_set_unset(&conv.start_time);
- nstime_set_unset(&conv.stop_time);
- }
- g_array_append_val(ct->conversations, conv);
- conversation_idx = ct->num_conversations;
- conversation=&g_array_index(ct->conversations, conv_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, conversation->src_address.type, conversation->src_address.len, conversation->src_address.data);
- SET_ADDRESS(&new_key->addr2, conversation->dst_address.type, conversation->dst_address.len, conversation->dst_address.data);
- new_key->port1 = port1;
- new_key->port2 = port2;
- new_key->conv_id = conv_id;
- g_hash_table_insert(ct->hashtable, new_key, GUINT_TO_POINTER(conversation_idx +1));
-
- ct->num_conversations++;
- }
-
- /* update the conversation struct */
- conversation->modified = TRUE;
- if ( (!CMP_ADDRESS(src, addr1)) && (!CMP_ADDRESS(dst, addr2)) && (src_port==port1) && (dst_port==port2) ) {
- conversation->tx_frames += num_frames;
- conversation->tx_bytes += num_bytes;
- } else {
- conversation->rx_frames += num_frames;
- conversation->rx_bytes += num_bytes;
- }
-
- if (ts) {
- if (nstime_cmp(ts, &conversation->stop_time) > 0) {
- memcpy(&conversation->stop_time, ts, sizeof(conversation->stop_time));
- } else if (nstime_cmp(ts, &conversation->start_time) < 0) {
- memcpy(&conversation->start_time, ts, sizeof(conversation->start_time));
- }
- }
-}
-
/*
* Editor modelines
*
diff --git a/ui/gtk/conversations_table.h b/ui/gtk/conversations_table.h
index 74a0ea48ff..25e6bc6968 100644
--- a/ui/gtk/conversations_table.h
+++ b/ui/gtk/conversations_table.h
@@ -25,35 +25,12 @@
#define __CONVERSATIONS_TABLE_H__
#include <epan/conv_id.h>
-#include "sat.h"
+#include <ui/conversation_hash.h>
/** @file
* Conversation definitions.
*/
-/** Conversation information */
-typedef struct _conversation_t {
- address src_address; /**< source address */
- address dst_address; /**< destination address */
- SAT_E sat; /**< address type */
- guint32 port_type; /**< port_type (e.g. PT_TCP) */
- guint32 src_port; /**< source port */
- guint32 dst_port; /**< destination port */
- conv_id_t conv_id; /**< conversation id */
-
- guint64 rx_frames; /**< number of received packets */
- guint64 tx_frames; /**< number of transmitted packets */
- guint64 rx_bytes; /**< number of received bytes */
- guint64 tx_bytes; /**< number of transmitted bytes */
-
- 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 */
- GtkTreeIter iter;
- gboolean iter_valid; /**< not a new row */
-} conv_t;
-
/** Conversation widget */
typedef struct _conversations_table {
const char *name; /**< the name of the table */
@@ -67,9 +44,7 @@ typedef struct _conversations_table {
const char *default_titles[14]; /**< Column headers */
GtkWidget *menu; /**< context menu */
gboolean has_ports; /**< table has ports */
- guint32 num_conversations; /**< number of conversations */
- GArray *conversations; /**< array of conversation values */
- GHashTable *hashtable; /**< conversations hash table */
+ conv_hash_t hash; /**< conversations hash table */
gboolean fixed_col; /**< if switched to fixed column */
gboolean resolve_names; /**< resolve address names? */
@@ -85,7 +60,7 @@ typedef struct _conversations_table {
* @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(gboolean hide_ports, const char *table_name, const char *tap_name, const char *filter, tap_packet_cb packet_func);
+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.
*
@@ -95,7 +70,7 @@ extern void register_conversation_table(gboolean hide_ports, const char *table_n
* @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(gboolean hide_ports, const char *table_name, const char *tap_name, const char *filter, tap_packet_cb packet_func);
+extern void init_conversation_table(conversation_type_e conv_type, const char *filter, tap_packet_cb packet_func);
/** Callback for "Conversations" statistics item.
*
@@ -104,51 +79,4 @@ extern void init_conversation_table(gboolean hide_ports, const char *table_name,
*/
extern void init_conversation_notebook_cb(GtkWidget *widget, gpointer data);
-/** Add some data to the conversation table.
- *
- * @param ct the table to add the data to
- * @param src source address
- * @param dst destination address
- * @param src_port source port
- * @param dst_port destination port
- * @param num_frames number of packets
- * @param num_bytes number of bytes
- * @param ts timestamp
- * @param sat address type
- * @param port_type the port type (e.g. PT_TCP)
- */
-extern void add_conversation_table_data(conversations_table *ct, const address *src, const address *dst,
- guint32 src_port, guint32 dst_port, int num_frames, int num_bytes, nstime_t *ts,
- SAT_E sat, int port_type);
-
-/** 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
- * conversation.
- *
- * @param ct the table to add the data to
- * @param src source address
- * @param dst destination address
- * @param src_port source port
- * @param dst_port destination port
- * @param num_frames number of packets
- * @param num_bytes number of bytes
- * @param ts timestamp
- * @param sat address type
- * @param port_type 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(
- conversations_table *ct,
- 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,
- SAT_E sat,
- int port_type);
-
#endif /* __CONVERSATIONS_TABLE_H__ */
diff --git a/ui/gtk/conversations_tcpip.c b/ui/gtk/conversations_tcpip.c
index afd6e76c73..0491c50fd2 100644
--- a/ui/gtk/conversations_tcpip.c
+++ b/ui/gtk/conversations_tcpip.c
@@ -41,9 +41,10 @@ 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((conversations_table *)pct, &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, SAT_NONE, PT_TCP);
+ 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;
}
@@ -61,7 +62,7 @@ tcpip_conversation_init(const char *opt_arg, void* userdata _U_)
filter=NULL;
}
- init_conversation_table(FALSE, "TCP", "tcp", filter, tcpip_conversation_packet);
+ init_conversation_table(CONV_TYPE_TCP, filter, tcpip_conversation_packet);
}
@@ -75,5 +76,5 @@ void
register_tap_listener_tcpip_conversation(void)
{
register_stat_cmd_arg("conv,tcp", tcpip_conversation_init,NULL);
- register_conversation_table(FALSE, "TCP", "tcp", NULL /*filter*/, tcpip_conversation_packet);
+ 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
index 666d400791..0d0b975591 100644
--- a/ui/gtk/conversations_tr.c
+++ b/ui/gtk/conversations_tr.c
@@ -41,9 +41,10 @@ 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((conversations_table *)pct, &trhdr->src, &trhdr->dst, 0, 0, 1, pinfo->fd->pkt_len, &pinfo->rel_ts, SAT_TOKENRING, PT_NONE);
+ 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;
}
@@ -61,7 +62,7 @@ tr_conversation_init(const char *opt_arg, void* userdata _U_)
filter=NULL;
}
- init_conversation_table(TRUE, "Token Ring", "tr", filter, tr_conversation_packet);
+ init_conversation_table(CONV_TYPE_TOKEN_RING, filter, tr_conversation_packet);
}
@@ -75,5 +76,5 @@ void
register_tap_listener_tr_conversation(void)
{
register_stat_cmd_arg("conv,tr", tr_conversation_init, NULL);
- register_conversation_table(TRUE, "Token Ring", "tr", NULL /*filter*/, tr_conversation_packet);
+ 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
index 961b85e751..7663d4a335 100644
--- a/ui/gtk/conversations_udpip.c
+++ b/ui/gtk/conversations_udpip.c
@@ -41,9 +41,10 @@ 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((conversations_table *)pct, &udphdr->ip_src, &udphdr->ip_dst, udphdr->uh_sport, udphdr->uh_dport, 1, pinfo->fd->pkt_len, &pinfo->rel_ts, SAT_NONE, PT_UDP);
+ 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;
}
@@ -61,7 +62,7 @@ udpip_conversation_init(const char *opt_arg, void* userdata _U_)
filter=NULL;
}
- init_conversation_table(FALSE, "UDP", "udp", filter, udpip_conversation_packet);
+ init_conversation_table(CONV_TYPE_UDP, filter, udpip_conversation_packet);
}
@@ -75,5 +76,5 @@ void
register_tap_listener_udpip_conversation(void)
{
register_stat_cmd_arg("conv,udp", udpip_conversation_init, NULL);
- register_conversation_table(FALSE, "UDP", "udp", NULL /*filter*/, udpip_conversation_packet);
+ 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
index e5d12160da..a77b3327ca 100644
--- a/ui/gtk/conversations_usb.c
+++ b/ui/gtk/conversations_usb.c
@@ -40,7 +40,9 @@ 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_)
{
- add_conversation_table_data((conversations_table *)pct, &pinfo->src, &pinfo->dst, 0, 0, 1, pinfo->fd->pkt_len, &pinfo->rel_ts, SAT_NONE, PT_NONE);
+ 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;
}
@@ -58,7 +60,7 @@ usb_conversation_init(const char *opt_arg, void* userdata _U_)
filter = NULL;
}
- init_conversation_table(TRUE, "USB", "usb", filter, usb_conversation_packet);
+ init_conversation_table(CONV_TYPE_USB, filter, usb_conversation_packet);
}
@@ -72,5 +74,5 @@ void
register_tap_listener_usb_conversation(void)
{
register_stat_cmd_arg("conv,usb", usb_conversation_init, NULL);
- register_conversation_table(TRUE, "USB", "usb", NULL /*filter*/, usb_conversation_packet);
+ 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
index 4ab1cb3d45..e9b4e6e35c 100644
--- a/ui/gtk/conversations_wlan.c
+++ b/ui/gtk/conversations_wlan.c
@@ -41,9 +41,10 @@ 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((conversations_table *)pct, &whdr->src, &whdr->dst, 0, 0, 1, pinfo->fd->pkt_len, &pinfo->rel_ts, SAT_WLAN, PT_NONE);
+ 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;
}
@@ -61,7 +62,7 @@ wlan_conversation_init(const char *opt_arg, void* userdata _U_)
filter=NULL;
}
- init_conversation_table(TRUE, "WLAN", "wlan", filter, wlan_conversation_packet);
+ init_conversation_table(CONV_TYPE_WLAN, filter, wlan_conversation_packet);
}
@@ -75,5 +76,5 @@ void
register_tap_listener_wlan_conversation(void)
{
register_stat_cmd_arg("conv,wlan", wlan_conversation_init,NULL);
- register_conversation_table(TRUE, "WLAN", "wlan", NULL /*filter*/, wlan_conversation_packet);
+ register_conversation_table(CONV_TYPE_WLAN, NULL /*filter*/, wlan_conversation_packet);
}
diff --git a/ui/gtk/filter_utils.c b/ui/gtk/filter_utils.c
index 52dacf5eda..87b437ea12 100644
--- a/ui/gtk/filter_utils.c
+++ b/ui/gtk/filter_utils.c
@@ -33,7 +33,7 @@
#include "ui/gtk/old-gtk-compat.h"
void
-apply_selected_filter (guint callback_action, char *filter)
+apply_selected_filter (guint callback_action, const char *filter)
{
int action, type;
char *str = NULL;
diff --git a/ui/gtk/filter_utils.h b/ui/gtk/filter_utils.h
index 535d2c2b34..eb238918c7 100644
--- a/ui/gtk/filter_utils.h
+++ b/ui/gtk/filter_utils.h
@@ -60,6 +60,6 @@
#define FILTER_EXTRA(cb_arg) ((cb_arg) & 0xff)
-extern void apply_selected_filter (guint callback_action, char *filter);
+extern void apply_selected_filter (guint callback_action, const char *filter);
#endif /* __FILTER_UTILS_H__ */
diff --git a/ui/gtk/hostlist_eth.c b/ui/gtk/hostlist_eth.c
index 94dc017b98..3785753415 100644
--- a/ui/gtk/hostlist_eth.c
+++ b/ui/gtk/hostlist_eth.c
@@ -47,8 +47,8 @@ eth_hostlist_packet(void *pit, packet_info *pinfo, epan_dissect_t *edt _U_, cons
/* Take two "add" passes per packet, adding for each direction, ensures that all
packets are counted properly (even if address is sending to itself)
XXX - this could probably be done more efficiently inside hostlist_table */
- add_hostlist_table_data(hosts, &ehdr->src, 0, TRUE, 1, pinfo->fd->pkt_len, SAT_ETHER, PT_NONE);
- add_hostlist_table_data(hosts, &ehdr->dst, 0, FALSE, 1, pinfo->fd->pkt_len, SAT_ETHER, PT_NONE);
+ add_hostlist_table_data(hosts, &ehdr->src, 0, TRUE, 1, pinfo->fd->pkt_len, CONV_TYPE_ETHERNET, PT_NONE);
+ add_hostlist_table_data(hosts, &ehdr->dst, 0, FALSE, 1, pinfo->fd->pkt_len, CONV_TYPE_ETHERNET, PT_NONE);
return 1;
}
diff --git a/ui/gtk/hostlist_fc.c b/ui/gtk/hostlist_fc.c
index b5ab9898ba..401681b57c 100644
--- a/ui/gtk/hostlist_fc.c
+++ b/ui/gtk/hostlist_fc.c
@@ -48,8 +48,8 @@ fc_hostlist_packet(void *pit, packet_info *pinfo, epan_dissect_t *edt _U_, const
/* Take two "add" passes per packet, adding for each direction, ensures that all
packets are counted properly (even if address is sending to itself)
XXX - this could probably be done more efficiently inside hostlist_table */
- add_hostlist_table_data(hosts, &fchdr->s_id, 0, TRUE, 1, pinfo->fd->pkt_len, SAT_NONE, PT_NONE);
- add_hostlist_table_data(hosts, &fchdr->d_id, 0, FALSE, 1, pinfo->fd->pkt_len, SAT_NONE, PT_NONE);
+ add_hostlist_table_data(hosts, &fchdr->s_id, 0, TRUE, 1, pinfo->fd->pkt_len, CONV_TYPE_FIBRE_CHANNEL, PT_NONE);
+ add_hostlist_table_data(hosts, &fchdr->d_id, 0, FALSE, 1, pinfo->fd->pkt_len, CONV_TYPE_FIBRE_CHANNEL, PT_NONE);
return 1;
}
diff --git a/ui/gtk/hostlist_fddi.c b/ui/gtk/hostlist_fddi.c
index e002f87cd6..f93c9881c5 100644
--- a/ui/gtk/hostlist_fddi.c
+++ b/ui/gtk/hostlist_fddi.c
@@ -47,8 +47,8 @@ fddi_hostlist_packet(void *pit, packet_info *pinfo, epan_dissect_t *edt _U_, con
/* Take two "add" passes per packet, adding for each direction, ensures that all
packets are counted properly (even if address is sending to itself)
XXX - this could probably be done more efficiently inside hostlist_table */
- add_hostlist_table_data(hosts, &ehdr->src, 0, TRUE, 1, pinfo->fd->pkt_len, SAT_FDDI, PT_NONE);
- add_hostlist_table_data(hosts, &ehdr->dst, 0, FALSE, 1, pinfo->fd->pkt_len, SAT_FDDI, PT_NONE);
+ add_hostlist_table_data(hosts, &ehdr->src, 0, TRUE, 1, pinfo->fd->pkt_len, CONV_TYPE_FDDI, PT_NONE);
+ add_hostlist_table_data(hosts, &ehdr->dst, 0, FALSE, 1, pinfo->fd->pkt_len, CONV_TYPE_FDDI, PT_NONE);
return 1;
}
diff --git a/ui/gtk/hostlist_ip.c b/ui/gtk/hostlist_ip.c
index a6633636fa..2b2ac5ee55 100644
--- a/ui/gtk/hostlist_ip.c
+++ b/ui/gtk/hostlist_ip.c
@@ -49,8 +49,8 @@ ip_hostlist_packet(void *pit, packet_info *pinfo, epan_dissect_t *edt _U_, const
/* Take two "add" passes per packet, adding for each direction, ensures that all
packets are counted properly (even if address is sending to itself)
XXX - this could probably be done more efficiently inside hostlist_table */
- add_hostlist_table_data(hosts, &iph->ip_src, 0, TRUE, 1, pinfo->fd->pkt_len, SAT_NONE, PT_NONE);
- add_hostlist_table_data(hosts, &iph->ip_dst, 0, FALSE, 1, pinfo->fd->pkt_len, SAT_NONE, PT_NONE);
+ add_hostlist_table_data(hosts, &iph->ip_src, 0, TRUE, 1, pinfo->fd->pkt_len, CONV_TYPE_IPV4, PT_NONE);
+ add_hostlist_table_data(hosts, &iph->ip_dst, 0, FALSE, 1, pinfo->fd->pkt_len, CONV_TYPE_IPV4, PT_NONE);
return 1;
}
diff --git a/ui/gtk/hostlist_ipv6.c b/ui/gtk/hostlist_ipv6.c
index 932319b792..b292479f98 100644
--- a/ui/gtk/hostlist_ipv6.c
+++ b/ui/gtk/hostlist_ipv6.c
@@ -53,8 +53,8 @@ ipv6_hostlist_packet(void *pit, packet_info *pinfo, epan_dissect_t *edt _U_, con
SET_ADDRESS(&src, AT_IPv6, sizeof(struct e_in6_addr), &ip6h->ip6_src);
SET_ADDRESS(&dst, AT_IPv6, sizeof(struct e_in6_addr), &ip6h->ip6_dst);
- add_hostlist_table_data(hosts, &src, 0, TRUE, 1, pinfo->fd->pkt_len, SAT_NONE, PT_NONE);
- add_hostlist_table_data(hosts, &dst, 0, FALSE, 1, pinfo->fd->pkt_len, SAT_NONE, PT_NONE);
+ add_hostlist_table_data(hosts, &src, 0, TRUE, 1, pinfo->fd->pkt_len, CONV_TYPE_IPV6, PT_NONE);
+ add_hostlist_table_data(hosts, &dst, 0, FALSE, 1, pinfo->fd->pkt_len, CONV_TYPE_IPV6, PT_NONE);
return 1;
}
diff --git a/ui/gtk/hostlist_ipx.c b/ui/gtk/hostlist_ipx.c
index 91a39eb0f1..d93acc8510 100644
--- a/ui/gtk/hostlist_ipx.c
+++ b/ui/gtk/hostlist_ipx.c
@@ -47,8 +47,8 @@ ipx_hostlist_packet(void *pit, packet_info *pinfo, epan_dissect_t *edt _U_, cons
/* Take two "add" passes per packet, adding for each direction, ensures that all
packets are counted properly (even if address is sending to itself)
XXX - this could probably be done more efficiently inside hostlist_table */
- add_hostlist_table_data(hosts, &ipxh->ipx_src, 0, TRUE, 1, pinfo->fd->pkt_len, SAT_NONE, PT_NONE);
- add_hostlist_table_data(hosts, &ipxh->ipx_dst, 0, FALSE, 1, pinfo->fd->pkt_len, SAT_NONE, PT_NONE);
+ add_hostlist_table_data(hosts, &ipxh->ipx_src, 0, TRUE, 1, pinfo->fd->pkt_len, CONV_TYPE_IPX, PT_NONE);
+ add_hostlist_table_data(hosts, &ipxh->ipx_dst, 0, FALSE, 1, pinfo->fd->pkt_len, CONV_TYPE_IPX, PT_NONE);
return 1;
}
diff --git a/ui/gtk/hostlist_jxta.c b/ui/gtk/hostlist_jxta.c
index 8402bd8eea..c3876d95fb 100644
--- a/ui/gtk/hostlist_jxta.c
+++ b/ui/gtk/hostlist_jxta.c
@@ -47,8 +47,8 @@ jxta_hostlist_packet(void *pit, packet_info *pinfo _U_, epan_dissect_t *edt _U_,
/* Take two "add" passes per packet, adding for each direction, ensures that all
packets are counted properly (even if address is sending to itself)
XXX - this could probably be done more efficiently inside hostlist_table */
- add_hostlist_table_data(hosts, &jxtahdr->src_address, 0, TRUE, 1, jxtahdr->size, SAT_JXTA, PT_NONE);
- add_hostlist_table_data(hosts, &jxtahdr->dest_address, 0, FALSE, 1, jxtahdr->size, SAT_JXTA, PT_NONE);
+ add_hostlist_table_data(hosts, &jxtahdr->src_address, 0, TRUE, 1, jxtahdr->size, CONV_TYPE_JXTA, PT_NONE);
+ add_hostlist_table_data(hosts, &jxtahdr->dest_address, 0, FALSE, 1, jxtahdr->size, CONV_TYPE_JXTA, PT_NONE);
return 1;
}
diff --git a/ui/gtk/hostlist_ncp.c b/ui/gtk/hostlist_ncp.c
index 79654bbdfa..d605d504ff 100644
--- a/ui/gtk/hostlist_ncp.c
+++ b/ui/gtk/hostlist_ncp.c
@@ -47,8 +47,8 @@ ncp_hostlist_packet(void *pit, packet_info *pinfo, epan_dissect_t *edt _U_, cons
/* Take two "add" passes per packet, adding for each direction, ensures that all
packets are counted properly (even if address is sending to itself)
XXX - this could probably be done more efficiently inside hostlist_table */
- add_hostlist_table_data(hosts, &pinfo->src, 0, TRUE, 1, pinfo->fd->pkt_len, SAT_ETHER, PT_NCP);
- add_hostlist_table_data(hosts, &pinfo->dst, 0, FALSE, 1, pinfo->fd->pkt_len, SAT_ETHER, PT_NCP);
+ add_hostlist_table_data(hosts, &pinfo->src, 0, TRUE, 1, pinfo->fd->pkt_len, CONV_TYPE_ETHERNET, PT_NCP);
+ add_hostlist_table_data(hosts, &pinfo->dst, 0, FALSE, 1, pinfo->fd->pkt_len, CONV_TYPE_ETHERNET, PT_NCP);
return 1;
}
diff --git a/ui/gtk/hostlist_rsvp.c b/ui/gtk/hostlist_rsvp.c
index 711e715fb6..d6986a9abb 100644
--- a/ui/gtk/hostlist_rsvp.c
+++ b/ui/gtk/hostlist_rsvp.c
@@ -51,9 +51,9 @@ rsvp_hostlist_packet(void *pit, packet_info *pinfo, epan_dissect_t *edt _U_, con
* hostlist_table
*/
add_hostlist_table_data(hosts, &rsvph->source, 0, TRUE, 1,
- pinfo->fd->pkt_len, SAT_NONE, PT_NONE);
+ pinfo->fd->pkt_len, CONV_TYPE_RSVP, PT_NONE);
add_hostlist_table_data(hosts, &rsvph->destination, 0, FALSE, 1,
- pinfo->fd->pkt_len, SAT_NONE, PT_NONE);
+ pinfo->fd->pkt_len, CONV_TYPE_RSVP, PT_NONE);
return 1;
}
diff --git a/ui/gtk/hostlist_sctp.c b/ui/gtk/hostlist_sctp.c
index 77a530762f..09ddfbe808 100644
--- a/ui/gtk/hostlist_sctp.c
+++ b/ui/gtk/hostlist_sctp.c
@@ -47,9 +47,9 @@ sctp_hostlist_packet(void *pit, packet_info *pinfo, epan_dissect_t *edt _U_, con
packets are counted properly (even if address is sending to itself)
XXX - this could probably be done more efficiently inside hostlist_table */
add_hostlist_table_data(hosts, &sctphdr->ip_src, sctphdr->sport, TRUE, 1,
- pinfo->fd->pkt_len, SAT_NONE, PT_SCTP);
+ pinfo->fd->pkt_len, CONV_TYPE_SCTP, PT_SCTP);
add_hostlist_table_data(hosts, &sctphdr->ip_dst, sctphdr->dport, FALSE, 1,
- pinfo->fd->pkt_len, SAT_NONE, PT_SCTP);
+ pinfo->fd->pkt_len, CONV_TYPE_SCTP, PT_SCTP);
return 1;
}
diff --git a/ui/gtk/hostlist_table.c b/ui/gtk/hostlist_table.c
index 8be7589347..0f1d034fae 100644
--- a/ui/gtk/hostlist_table.c
+++ b/ui/gtk/hostlist_table.c
@@ -124,13 +124,13 @@ hostlist_get_filter_name(address *addr, int specific_addr_type_val, int port_typ
switch(addr->type){
case AT_ETHER:
switch(specific_addr_type_val){
- case SAT_ETHER:
+ case CONV_TYPE_ETHERNET:
return "eth.addr";
- case SAT_WLAN:
+ case CONV_TYPE_WLAN:
return "wlan.addr";
- case SAT_FDDI:
+ case CONV_TYPE_FDDI:
return "fddi.addr";
- case SAT_TOKENRING:
+ case CONV_TYPE_TOKEN_RING:
return "tr.addr";
default:
break;
@@ -146,7 +146,7 @@ hostlist_get_filter_name(address *addr, int specific_addr_type_val, int port_typ
return "fc.id";
case AT_URI:
switch(specific_addr_type_val){
- case SAT_JXTA:
+ case CONV_TYPE_JXTA:
return "jxta.message.address";
default:
break;
@@ -1778,7 +1778,7 @@ host_match(gconstpointer v, gconstpointer w)
}
void
-add_hostlist_table_data(hostlist_table *hl, const address *addr, guint32 port, gboolean sender, int num_frames, int num_bytes, SAT_E sat, int port_type_val)
+add_hostlist_table_data(hostlist_table *hl, const address *addr, guint32 port, gboolean sender, int num_frames, int num_bytes, conversation_type_e conv_type, int port_type_val)
{
hostlist_talker_t *talker=NULL;
int talker_idx=0;
@@ -1813,7 +1813,7 @@ add_hostlist_table_data(hostlist_table *hl, const address *addr, guint32 port, g
hostlist_talker_t host;
COPY_ADDRESS(&host.myaddress, addr);
- host.sat=sat;
+ host.sat=conv_type;
host.port_type=port_type_val;
host.port=port;
host.rx_frames=0;
diff --git a/ui/gtk/hostlist_table.h b/ui/gtk/hostlist_table.h
index 089a26c075..41c0c9ffc1 100644
--- a/ui/gtk/hostlist_table.h
+++ b/ui/gtk/hostlist_table.h
@@ -24,7 +24,7 @@
#ifndef __HOSTLIST_TABLE_H__
#define __HOSTLIST_TABLE_H__
-#include "sat.h"
+#include <ui/conversation_hash.h>
/** @file
* Hostlist definitions.
@@ -33,7 +33,7 @@
/** Hostlist information */
typedef struct _hostlist_talker_t {
address myaddress; /**< address */
- SAT_E sat; /**< address type */
+ conversation_type_e sat; /**< address type */
guint32 port_type; /**< port_type (e.g. PT_TCP) */
guint32 port; /**< port */
@@ -116,6 +116,6 @@ extern void init_hostlist_notebook_cb(GtkWidget *w, gpointer d);
* @param port_type the port type (e.g. PT_TCP)
*/
void add_hostlist_table_data(hostlist_table *hl, const address *addr,
- guint32 port, gboolean sender, int num_frames, int num_bytes, SAT_E sat, int port_type);
+ guint32 port, gboolean sender, int num_frames, int num_bytes, conversation_type_e sat, int port_type);
#endif /* __HOSTLIST_TABLE_H__ */
diff --git a/ui/gtk/hostlist_tcpip.c b/ui/gtk/hostlist_tcpip.c
index 9c777b5ea5..8f9657b143 100644
--- a/ui/gtk/hostlist_tcpip.c
+++ b/ui/gtk/hostlist_tcpip.c
@@ -47,8 +47,8 @@ tcpip_hostlist_packet(void *pit, packet_info *pinfo, epan_dissect_t *edt _U_, co
/* Take two "add" passes per packet, adding for each direction, ensures that all
packets are counted properly (even if address is sending to itself)
XXX - this could probably be done more efficiently inside hostlist_table */
- add_hostlist_table_data(hosts, &tcphdr->ip_src, tcphdr->th_sport, TRUE, 1, pinfo->fd->pkt_len, SAT_NONE, PT_TCP);
- add_hostlist_table_data(hosts, &tcphdr->ip_dst, tcphdr->th_dport, FALSE, 1, pinfo->fd->pkt_len, SAT_NONE, PT_TCP);
+ add_hostlist_table_data(hosts, &tcphdr->ip_src, tcphdr->th_sport, TRUE, 1, pinfo->fd->pkt_len, CONV_TYPE_TCP, PT_TCP);
+ add_hostlist_table_data(hosts, &tcphdr->ip_dst, tcphdr->th_dport, FALSE, 1, pinfo->fd->pkt_len, CONV_TYPE_TCP, PT_TCP);
return 1;
}
diff --git a/ui/gtk/hostlist_tr.c b/ui/gtk/hostlist_tr.c
index e58bc4e656..a42ecdf355 100644
--- a/ui/gtk/hostlist_tr.c
+++ b/ui/gtk/hostlist_tr.c
@@ -47,8 +47,8 @@ tr_hostlist_packet(void *pit, packet_info *pinfo, epan_dissect_t *edt _U_, const
/* Take two "add" passes per packet, adding for each direction, ensures that all
packets are counted properly (even if address is sending to itself)
XXX - this could probably be done more efficiently inside hostlist_table */
- add_hostlist_table_data(hosts, &trhdr->src, 0, TRUE, 1, pinfo->fd->pkt_len, SAT_TOKENRING, PT_NONE);
- add_hostlist_table_data(hosts, &trhdr->dst, 0, FALSE, 1, pinfo->fd->pkt_len, SAT_TOKENRING, PT_NONE);
+ add_hostlist_table_data(hosts, &trhdr->src, 0, TRUE, 1, pinfo->fd->pkt_len, CONV_TYPE_TOKEN_RING, PT_NONE);
+ add_hostlist_table_data(hosts, &trhdr->dst, 0, FALSE, 1, pinfo->fd->pkt_len, CONV_TYPE_TOKEN_RING, PT_NONE);
return 1;
}
diff --git a/ui/gtk/hostlist_udpip.c b/ui/gtk/hostlist_udpip.c
index 2cdb3841ab..de72c18904 100644
--- a/ui/gtk/hostlist_udpip.c
+++ b/ui/gtk/hostlist_udpip.c
@@ -47,8 +47,8 @@ udpip_hostlist_packet(void *pit, packet_info *pinfo, epan_dissect_t *edt _U_, co
/* Take two "add" passes per packet, adding for each direction, ensures that all
packets are counted properly (even if address is sending to itself)
XXX - this could probably be done more efficiently inside hostlist_table */
- add_hostlist_table_data(hosts, &udphdr->ip_src, udphdr->uh_sport, TRUE, 1, pinfo->fd->pkt_len, SAT_NONE, PT_UDP);
- add_hostlist_table_data(hosts, &udphdr->ip_dst, udphdr->uh_dport, FALSE, 1, pinfo->fd->pkt_len, SAT_NONE, PT_UDP);
+ add_hostlist_table_data(hosts, &udphdr->ip_src, udphdr->uh_sport, TRUE, 1, pinfo->fd->pkt_len, CONV_TYPE_UDP, PT_UDP);
+ add_hostlist_table_data(hosts, &udphdr->ip_dst, udphdr->uh_dport, FALSE, 1, pinfo->fd->pkt_len, CONV_TYPE_UDP, PT_UDP);
return 1;
}
diff --git a/ui/gtk/hostlist_usb.c b/ui/gtk/hostlist_usb.c
index 8bf63b899e..abecdb0b18 100644
--- a/ui/gtk/hostlist_usb.c
+++ b/ui/gtk/hostlist_usb.c
@@ -46,8 +46,8 @@ usb_hostlist_packet(void *pit, packet_info *pinfo, epan_dissect_t *edt _U_, cons
/* Take two "add" passes per packet, adding for each direction, ensures that all
packets are counted properly (even if address is sending to itself)
XXX - this could probably be done more efficiently inside hostlist_table */
- add_hostlist_table_data(hosts, &pinfo->src, 0, TRUE, 1, pinfo->fd->pkt_len, SAT_NONE, PT_NONE);
- add_hostlist_table_data(hosts, &pinfo->dst, 0, FALSE, 1, pinfo->fd->pkt_len, SAT_NONE, PT_NONE);
+ add_hostlist_table_data(hosts, &pinfo->src, 0, TRUE, 1, pinfo->fd->pkt_len, CONV_TYPE_USB, PT_NONE);
+ add_hostlist_table_data(hosts, &pinfo->dst, 0, FALSE, 1, pinfo->fd->pkt_len, CONV_TYPE_USB, PT_NONE);
return 1;
}
diff --git a/ui/gtk/hostlist_wlan.c b/ui/gtk/hostlist_wlan.c
index f456d93e19..b83b1966f7 100644
--- a/ui/gtk/hostlist_wlan.c
+++ b/ui/gtk/hostlist_wlan.c
@@ -47,8 +47,8 @@ wlan_hostlist_packet(void *pit, packet_info *pinfo, epan_dissect_t *edt _U_, con
/* Take two "add" passes per packet, adding for each direction, ensures that all
packets are counted properly (even if address is sending to itself)
XXX - this could probably be done more efficiently inside hostlist_table */
- add_hostlist_table_data(hosts, &whdr->src, 0, TRUE, 1, pinfo->fd->pkt_len, SAT_WLAN, PT_NONE);
- add_hostlist_table_data(hosts, &whdr->dst, 0, FALSE, 1, pinfo->fd->pkt_len, SAT_WLAN, PT_NONE);
+ add_hostlist_table_data(hosts, &whdr->src, 0, TRUE, 1, pinfo->fd->pkt_len, CONV_TYPE_WLAN, PT_NONE);
+ add_hostlist_table_data(hosts, &whdr->dst, 0, FALSE, 1, pinfo->fd->pkt_len, CONV_TYPE_WLAN, PT_NONE);
return 1;
}
diff --git a/ui/qt/CMakeLists.txt b/ui/qt/CMakeLists.txt
index 20a07f3c21..9995320894 100644
--- a/ui/qt/CMakeLists.txt
+++ b/ui/qt/CMakeLists.txt
@@ -37,6 +37,8 @@ set(WIRESHARK_QT_HEADERS
color_utils.h
column_preferences_frame.h
compiled_filter_output.h
+ conversation_dialog.h
+ conversation_tree_widget.h
decode_as_dialog.h
display_filter_combo.h
display_filter_edit.h
@@ -45,6 +47,7 @@ set(WIRESHARK_QT_HEADERS
export_object_dialog.h
export_pdu_dialog.h
file_set_dialog.h
+ filter_action.h
filter_expressions_preferences_frame.h
follow_stream_dialog.h
follow_stream_text.h
@@ -94,12 +97,13 @@ set(WIRESHARK_QT_HEADERS
time_shift_dialog.h
uat_dialog.h
wireshark_application.h
+)
- # No Q_OBJECT:
- # packet_list_record.h
- # qt_ui_utils.h
- # related_packet_delegate.h
- # sparkline_delegate.h
+file(GLOB EXTA_QT_HEADERS
+ packet_list_record.h
+ qt_ui_utils.h
+ related_packet_delegate.h
+ sparkline_delegate.h
)
set(WIRESHARK_QT_SRC
@@ -118,6 +122,7 @@ set(WIRESHARK_QT_SRC
capture_preferences_frame.cpp
column_preferences_frame.cpp
compiled_filter_output.cpp
+ conversation_tree_widget.cpp
decode_as_dialog.cpp
display_filter_combo.cpp
display_filter_edit.cpp
@@ -126,6 +131,7 @@ set(WIRESHARK_QT_SRC
export_object_dialog.cpp
export_pdu_dialog.cpp
file_set_dialog.cpp
+ filter_action.cpp
filter_expressions_preferences_frame.cpp
follow_stream_dialog.cpp
follow_stream_text.cpp
@@ -181,6 +187,7 @@ set(WIRESHARK_QT_SRC
)
set(WIRESHARK_QT_TAP_SRC
+ conversation_dialog.cpp
io_graph_dialog.cpp
stats_tree_dialog.cpp
)
@@ -200,6 +207,7 @@ set(WIRESHARK_QT_UI
capture_interfaces_dialog.ui
column_preferences_frame.ui
compiled_filter_output.ui
+ conversation_dialog.ui
decode_as_dialog.ui
export_object_dialog.ui
export_pdu_dialog.ui
diff --git a/ui/qt/Makefile.am b/ui/qt/Makefile.am
index 04b05786dd..237310cc02 100644
--- a/ui/qt/Makefile.am
+++ b/ui/qt/Makefile.am
@@ -135,6 +135,8 @@ column_preferences_frame.cpp column_preferences_frame.h: ui_column_preferences_f
compiled_filter_output.cpp compiled_filter_output.h: ui_compiled_filter_output.h
+conversation_dialog.cpp conversation_dialog.h: ui_conversation_dialog.h
+
decode_as_dialog.cpp decode_as_dialog.h: ui_decode_as_dialog.h
export_object_dialog.cpp export_object_dialog.h: ui_export_object_dialog.h
diff --git a/ui/qt/Makefile.common b/ui/qt/Makefile.common
index a076ae454b..0ab43598fe 100644
--- a/ui/qt/Makefile.common
+++ b/ui/qt/Makefile.common
@@ -34,6 +34,7 @@ NODIST_GENERATED_HEADER_FILES = \
ui_capture_preferences_frame.h \
ui_column_preferences_frame.h \
ui_compiled_filter_output.h \
+ ui_conversation_dialog.h \
ui_decode_as_dialog.h \
ui_export_object_dialog.h \
ui_export_pdu_dialog.h \
@@ -123,6 +124,8 @@ MOC_HDRS = \
capture_preferences_frame.h \
column_preferences_frame.h \
compiled_filter_output.h \
+ conversation_dialog.h \
+ conversation_tree_widget.h \
decode_as_dialog.h \
display_filter_combo.h \
display_filter_edit.h \
@@ -131,6 +134,7 @@ MOC_HDRS = \
export_object_dialog.h \
export_pdu_dialog.h \
file_set_dialog.h \
+ filter_action.h \
filter_expressions_preferences_frame.h \
follow_stream_dialog.h \
follow_stream_text.h \
@@ -193,6 +197,7 @@ UI_FILES = \
capture_preferences_frame.ui \
column_preferences_frame.ui \
compiled_filter_output.ui \
+ conversation_dialog.ui \
decode_as_dialog.ui \
export_object_dialog.ui \
export_pdu_dialog.ui \
@@ -302,6 +307,8 @@ WIRESHARK_QT_SRC = \
capture_preferences_frame.cpp \
column_preferences_frame.cpp \
compiled_filter_output.cpp \
+ conversation_dialog.cpp \
+ conversation_tree_widget.cpp \
decode_as_dialog.cpp \
display_filter_combo.cpp \
display_filter_edit.cpp \
@@ -310,6 +317,7 @@ WIRESHARK_QT_SRC = \
export_object_dialog.cpp \
export_pdu_dialog.cpp \
file_set_dialog.cpp \
+ filter_action.cpp \
filter_expressions_preferences_frame.cpp \
follow_stream_dialog.cpp \
follow_stream_text.cpp \
diff --git a/ui/qt/QtShark.pro b/ui/qt/QtShark.pro
index bde3136e5a..f5bcb3d2ee 100644
--- a/ui/qt/QtShark.pro
+++ b/ui/qt/QtShark.pro
@@ -211,6 +211,7 @@ FORMS += \
capture_interfaces_dialog.ui \
column_preferences_frame.ui \
compiled_filter_output.ui \
+ conversation_dialog.ui \
decode_as_dialog.ui \
export_object_dialog.ui \
export_pdu_dialog.ui \
@@ -259,11 +260,14 @@ HEADERS += $$HEADERS_WS_C \
capture_preferences_frame.h \
column_preferences_frame.h \
compiled_filter_output.h \
+ conversation_dialog.h \
+ conversation_tree_widget.h \
decode_as_dialog.h \
elided_label.h \
export_dissection_dialog.h \
export_object_dialog.h \
export_pdu_dialog.h \
+ filter_action.h \
filter_expressions_preferences_frame.h \
follow_stream_dialog.h \
follow_stream_text.h \
@@ -585,6 +589,8 @@ SOURCES += \
color_utils.cpp \
column_preferences_frame.cpp \
compiled_filter_output.cpp \
+ conversation_dialog.cpp \
+ conversation_tree_widget.cpp \
decode_as_dialog.cpp \
display_filter_combo.cpp \
display_filter_edit.cpp \
@@ -593,6 +599,7 @@ SOURCES += \
export_object_dialog.cpp \
export_pdu_dialog.cpp \
file_set_dialog.cpp \
+ filter_action.cpp \
filter_expressions_preferences_frame.cpp \
follow_stream_dialog.cpp \
follow_stream_text.cpp \
diff --git a/ui/qt/conversation_dialog.cpp b/ui/qt/conversation_dialog.cpp
new file mode 100644
index 0000000000..866304c702
--- /dev/null
+++ b/ui/qt/conversation_dialog.cpp
@@ -0,0 +1,516 @@
+/* conversation_dialog.cpp
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * 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 "conversation_dialog.h"
+#include "ui_conversation_dialog.h"
+
+#include <epan/addr_resolv.h>
+#include <epan/prefs.h>
+#include <epan/stat_cmd_args.h>
+
+#include <epan/dissectors/packet-tcp.h>
+
+#include "ui/recent.h"
+#include "ui/tap-tcp-stream.h"
+
+#include "wireshark_application.h"
+
+#include <QByteArray>
+#include <QCheckBox>
+#include <QClipboard>
+#include <QContextMenuEvent>
+#include <QList>
+#include <QMap>
+#include <QMessageBox>
+#include <QTabWidget>
+#include <QToolButton>
+
+#include <QDebug>
+
+// To do:
+// - https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=6727
+// - Wide last column?
+// + No arrows on unsorted columns
+// - Add follow stream to context menu
+// + Change "A <- B" to "B -> A"
+// - Improper wildcard handling https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=8010
+// - TShark consolidation https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=6310
+// - Display filter entry?
+// - Add follow, copy & graph actions to context menu.
+
+// Bugs:
+// - Name resolution doesn't do anything if its preference is disabled.
+// - Columns don't resize correctly.
+
+// 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<QString, conversation_type_e> conv_proto_to_type_;
+
+ConversationDialog::ConversationDialog(QWidget *parent, capture_file *cf, const char *stat_arg) :
+ QDialog(parent),
+ ui(new Ui::ConversationDialog),
+ cap_file_(cf)
+{
+ ui->setupUi(this);
+ setAttribute(Qt::WA_DeleteOnClose, true);
+
+ // XXX Use recent settings instead
+ if (parent) {
+ resize(parent->width(), parent->height() * 3 / 4);
+ }
+
+ QMenu *copy_menu = new QMenu();
+ QAction *ca;
+ copy_bt_ = ui->buttonBox->addButton(tr("Copy"), QDialogButtonBox::ActionRole);
+ ca = copy_menu->addAction(tr("as CSV"));
+ ca->setToolTip(tr("Copy all values of this page to the clipboard in CSV (Comma Separated Values) format."));
+ connect(ca, SIGNAL(triggered()), this, SLOT(copyAsCsv()));
+ ca = copy_menu->addAction(tr("as YAML"));
+ ca->setToolTip(tr("Copy all values of this page to the clipboard in the YAML data serialization format."));
+ connect(ca, SIGNAL(triggered()), this, SLOT(copyAsYaml()));
+ copy_bt_->setMenu(copy_menu);
+
+ follow_bt_ = ui->buttonBox->addButton(tr("Follow Stream..."), QDialogButtonBox::ActionRole);
+ follow_bt_->setToolTip(tr("Follow a TCP or UDP stream."));
+ connect(follow_bt_, SIGNAL(clicked()), this, SLOT(followStream()));
+
+ graph_bt_ = ui->buttonBox->addButton(tr("Graph..."), QDialogButtonBox::ActionRole);
+ graph_bt_->setToolTip(tr("Graph a TCP conversation."));
+ connect(graph_bt_, SIGNAL(clicked()), this, SLOT(graphTcp()));
+
+ QList<conversation_type_e> conv_types;
+ 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);
+ }
+ }
+
+ // Reasonable defaults?
+ if (conv_types.isEmpty()) {
+ conv_types << CONV_TYPE_ETHERNET << CONV_TYPE_IPV4 << CONV_TYPE_IPV6 <<CONV_TYPE_TCP << CONV_TYPE_UDP;
+ }
+
+ // Bring the command-line specified type to the front.
+ initStatCmdMap();
+ QStringList stat_args = QString(stat_arg).split(",");
+ if (stat_args.length() > 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];
+ }
+ }
+
+ 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);
+
+ QAction *conv_action = new QAction(title, this);
+ conv_action->setData(qVariantFromValue(ct));
+ conv_action->setCheckable(true);
+ conv_action->setChecked(conv_types.contains(ct));
+ connect(conv_action, SIGNAL(triggered()), this, SLOT(toggleConversation()));
+ conv_type_menu_.addAction(conv_action);
+ }
+
+ ui->conversationTypePushButton->setMenu(&conv_type_menu_);
+
+ updateWidgets();
+ itemSelectionChanged();
+
+ ui->nameResolutionCheckBox->setChecked(gbl_resolv_flags.network_name);
+
+ ui->conversationTabWidget->currentWidget()->setFocus();
+
+ connect(ui->conversationTabWidget, SIGNAL(currentChanged(int)),
+ this, SLOT(itemSelectionChanged()));
+
+ if (cap_file_) {
+ cf_retap_packets(cap_file_);
+ }
+}
+
+ConversationDialog::~ConversationDialog()
+{
+ prefs_clear_string_list(recent.conversation_tabs);
+ recent.conversation_tabs = NULL;
+
+ ConversationTreeWidget *cur_tree = qobject_cast<ConversationTreeWidget *>(ui->conversationTabWidget->currentWidget());
+ foreach (QAction *ca, conv_type_menu_.actions()) {
+ conversation_type_e conv_type = ca->data().value<conversation_type_e>();
+ 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) {
+ recent.conversation_tabs = g_list_prepend(recent.conversation_tabs, title);
+ } else {
+ recent.conversation_tabs = g_list_append(recent.conversation_tabs, title);
+ }
+ }
+ }
+ delete ui;
+}
+
+void ConversationDialog::setCaptureFile(capture_file *cf)
+{
+ if (!cf) { // We only want to know when the file closes.
+ cap_file_ = NULL;
+ ui->displayFilterCheckBox->setEnabled(false);
+ }
+}
+
+void ConversationDialog::initStatCmdMap()
+{
+ if (conv_proto_to_type_.size() > 0) {
+ return;
+ }
+
+ 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)) {
+ return false;
+ }
+
+ ConversationTreeWidget *conv_tree = new ConversationTreeWidget(this, conv_type);
+
+ conv_type_to_tree_[conv_type] = conv_tree;
+
+ ui->conversationTabWidget->addTab(conv_tree, conversation_title(conv_type));
+ connect(conv_tree, SIGNAL(itemSelectionChanged()),
+ this, SLOT(itemSelectionChanged()));
+ connect(conv_tree, SIGNAL(titleChanged(QWidget*,QString)),
+ this, SLOT(setTabText(QWidget*,QString)));
+ connect(conv_tree, SIGNAL(filterAction(QString&,FilterAction::Action,FilterAction::ActionType)),
+ this, SLOT(chainFilterAction(QString&,FilterAction::Action,FilterAction::ActionType)));
+ connect(ui->nameResolutionCheckBox, SIGNAL(toggled(bool)),
+ conv_tree, SLOT(setNameResolutionEnabled(bool)));
+
+ // XXX Move to ConversationTreeWidget ctor?
+ const char *filter = NULL;
+ if (ui->displayFilterCheckBox->isChecked()) {
+ filter = cap_file_->dfilter;
+ } else if (!filter_.isEmpty()) {
+ filter = filter_.toUtf8().constData();
+ }
+ GString *error_string = register_tap_listener(conversation_tap_name(conv_type), conv_tree, filter, 0,
+ ConversationTreeWidget::tapReset,
+ ConversationTreeWidget::tapPacket,
+ ConversationTreeWidget::tapDraw);
+
+ if (error_string) {
+ QMessageBox::warning(this, tr("Conversation %1 failed to register tap listener").arg(conversation_title(conv_type)),
+ error_string->str);
+ g_string_free(error_string, TRUE);
+ }
+ return true;
+}
+
+conversation_type_e ConversationDialog::tabType(int index)
+{
+ ConversationTreeWidget *conv_tree = qobject_cast<ConversationTreeWidget *>(ui->conversationTabWidget->widget(index));
+ if (!conv_tree) {
+ return N_CONV_TYPES; // Need a "none" type?
+ }
+ return conv_tree->conversationType();
+}
+
+conv_item_t *ConversationDialog::currentConversation()
+{
+ ConversationTreeWidget *cur_tree = qobject_cast<ConversationTreeWidget *>(ui->conversationTabWidget->currentWidget());
+
+ if (!cur_tree || cur_tree->selectedItems().count() < 1) {
+ return NULL;
+ }
+
+ return cur_tree->selectedItems()[0]->data(0, Qt::UserRole).value<conv_item_t *>();
+}
+
+void ConversationDialog::followStream()
+{
+ conv_item_t *conv_item = currentConversation();
+ if (!conv_item) {
+ return;
+ }
+
+ QString filter;
+ follow_type_t ftype = FOLLOW_TCP;
+ switch (conv_item->ptype) {
+ case PT_TCP:
+ filter = QString("tcp.stream eq %1").arg(conv_item->conv_id);
+ break;
+ case PT_UDP:
+ filter = QString("udp.stream eq %1").arg(conv_item->conv_id);
+ ftype = FOLLOW_UDP;
+ break;
+ default:
+ break;
+ }
+
+ if (filter.length() < 1) {
+ return;
+ }
+
+ chainFilterAction(filter, FilterAction::ActionApply, FilterAction::ActionTypePlain);
+ openFollowStreamDialog(ftype);
+}
+
+void ConversationDialog::copyAsCsv()
+{
+ ConversationTreeWidget *cur_tree = qobject_cast<ConversationTreeWidget *>(ui->conversationTabWidget->currentWidget());
+ if (!cur_tree) {
+ return;
+ }
+
+ QString csv;
+ QTextStream stream(&csv, QIODevice::Text);
+ for (int row = -1; row < cur_tree->topLevelItemCount(); row ++) {
+ QStringList rdsl;
+ foreach (QVariant v, cur_tree->rowData(row)) {
+ if (!v.isValid()) {
+ rdsl << "\"\"";
+ } else if ((int) v.type() == (int) QMetaType::QString) {
+ rdsl << QString("\"%1\"").arg(v.toString());
+ } else {
+ rdsl << v.toString();
+ }
+ }
+ stream << rdsl.join(",") << endl;
+ }
+ wsApp->clipboard()->setText(stream.readAll());
+}
+
+void ConversationDialog::copyAsYaml()
+{
+ ConversationTreeWidget *cur_tree = qobject_cast<ConversationTreeWidget *>(ui->conversationTabWidget->currentWidget());
+ if (!cur_tree) {
+ return;
+ }
+
+ QString yaml;
+ QTextStream stream(&yaml, QIODevice::Text);
+ stream << "---" << endl;
+ for (int row = -1; row < cur_tree->topLevelItemCount(); row ++) {
+ stream << "-" << endl;
+ foreach (QVariant v, cur_tree->rowData(row)) {
+ stream << " - " << v.toString() << endl;
+ }
+ }
+ wsApp->clipboard()->setText(stream.readAll());
+}
+
+void ConversationDialog::graphTcp()
+{
+ conv_item_t *conv_item = currentConversation();
+ if (!conv_item) {
+ return;
+ }
+
+ // XXX The GTK+ code opens the TCP Stream dialog. We might want
+ // to open the IO Graph dialog instead.
+ QString filter;
+ if (conv_item->ptype == PT_TCP) {
+ filter = QString("tcp.stream eq %1").arg(conv_item->conv_id);
+ } else {
+ return;
+ }
+
+ chainFilterAction(filter, FilterAction::ActionApply, FilterAction::ActionTypePlain);
+ openTcpStreamGraph(GRAPH_TSEQ_TCPTRACE);
+}
+
+void ConversationDialog::updateWidgets()
+{
+ QWidget *cur_w = ui->conversationTabWidget->currentWidget();
+ ui->conversationTabWidget->setUpdatesEnabled(false);
+ ui->conversationTabWidget->clear();
+ foreach (QAction *ca, conv_type_menu_.actions()) {
+ conversation_type_e conv_type = ca->data().value<conversation_type_e>();
+ 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());
+ }
+ }
+ ui->conversationTabWidget->setCurrentWidget(cur_w);
+ ui->conversationTabWidget->setUpdatesEnabled(true);
+}
+
+void ConversationDialog::toggleConversation()
+{
+ QAction *ca = qobject_cast<QAction *>(QObject::sender());
+ if (!ca) {
+ return;
+ }
+
+ conversation_type_e conv_type = ca->data().value<conversation_type_e>();
+ bool new_conv = addConversationType(conv_type);
+ updateWidgets();
+
+ if (ca->isChecked()) {
+ ui->conversationTabWidget->setCurrentWidget(conv_type_to_tree_[conv_type]);
+ }
+
+ if (new_conv) {
+ if (cap_file_) {
+ cf_retap_packets(cap_file_);
+ }
+ }
+}
+
+void ConversationDialog::itemSelectionChanged()
+{
+ bool copy_enable = ui->conversationTabWidget->currentWidget() ? true : false;
+ bool follow_enable = false, graph_enable = false;
+ conv_item_t *conv_item = currentConversation();
+
+ if (cap_file_ && conv_item) {
+ switch (conv_item->ptype) {
+ case PT_TCP:
+ graph_enable = true;
+ // Fall through
+ case PT_UDP:
+ follow_enable = true;
+ break;
+ default:
+ break;
+ }
+ }
+
+ copy_bt_->setEnabled(copy_enable);
+ follow_bt_->setEnabled(follow_enable);
+ graph_bt_->setEnabled(graph_enable);
+}
+
+void ConversationDialog::on_nameResolutionCheckBox_toggled(bool checked)
+{
+ Q_UNUSED(checked);
+ updateWidgets();
+}
+
+void ConversationDialog::on_displayFilterCheckBox_toggled(bool checked)
+{
+ if (!cap_file_) {
+ return;
+ }
+
+ const char *filter = NULL;
+ if (checked) {
+ filter = cap_file_->dfilter;
+ } else if (!filter_.isEmpty()) {
+ filter = filter_.toUtf8().constData();
+ }
+
+ for (int i = 0; i < ui->conversationTabWidget->count(); i++) {
+ set_tap_dfilter(ui->conversationTabWidget->widget(i), filter);
+ }
+
+ cf_retap_packets(cap_file_);
+}
+
+void ConversationDialog::setTabText(QWidget *tree, const QString &text)
+{
+ // Could use QObject::sender as well
+ int index = ui->conversationTabWidget->indexOf(tree);
+ if (index >= 0) {
+ ui->conversationTabWidget->setTabText(index, text);
+ }
+}
+
+void ConversationDialog::chainFilterAction(QString &filter, FilterAction::Action action, FilterAction::ActionType type)
+{
+ if (cap_file_) { // We probably shouldn't fail silently
+ emit filterAction(filter, action, type);
+ }
+}
+
+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)
+{
+ 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);
+}
+}
+
+/*
+ * 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/qt/conversation_dialog.h b/ui/qt/conversation_dialog.h
new file mode 100644
index 0000000000..26bf91c102
--- /dev/null
+++ b/ui/qt/conversation_dialog.h
@@ -0,0 +1,102 @@
+/* conversation_dialog.h
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * 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_DIALOG_H
+#define CONVERSATION_DIALOG_H
+
+#include <conversation_tree_widget.h>
+
+#include <file.h>
+
+#include "ui/follow.h"
+
+#include <QAction>
+#include <QMenu>
+
+#include <QDialog>
+
+namespace Ui {
+class ConversationDialog;
+}
+
+class ConversationDialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ explicit ConversationDialog(QWidget *parent = 0, capture_file *cf = NULL, const char *stat_arg = NULL);
+ ~ConversationDialog();
+
+public slots:
+ void setCaptureFile(capture_file *cf);
+
+signals:
+ void filterAction(QString& filter, FilterAction::Action action, FilterAction::ActionType type);
+ void openFollowStreamDialog(follow_type_t type);
+ void openTcpStreamGraph(int graph_type);
+
+private:
+ Ui::ConversationDialog *ui;
+
+ capture_file *cap_file_;
+ QString filter_;
+ QMenu conv_type_menu_;
+ QMap<conversation_type_e, ConversationTreeWidget *> conv_type_to_tree_;
+ QList<QAction> 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);
+ conv_item_t *currentConversation();
+
+private slots:
+ void updateWidgets();
+ void toggleConversation();
+ void itemSelectionChanged();
+ void on_nameResolutionCheckBox_toggled(bool checked);
+ void on_displayFilterCheckBox_toggled(bool checked);
+ void setTabText(QWidget *tree, const QString &text);
+ void chainFilterAction(QString& filter, FilterAction::Action action, FilterAction::ActionType type);
+ void followStream();
+ void copyAsCsv();
+ void copyAsYaml();
+ void graphTcp();
+ void on_buttonBox_helpRequested();
+};
+
+#endif // CONVERSATION_DIALOG_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/qt/conversation_dialog.ui b/ui/qt/conversation_dialog.ui
new file mode 100644
index 0000000000..247fee1a31
--- /dev/null
+++ b/ui/qt/conversation_dialog.ui
@@ -0,0 +1,127 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>ConversationDialog</class>
+ <widget class="QDialog" name="ConversationDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>680</width>
+ <height>475</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Wireshark: Conversations</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QTabWidget" name="conversationTabWidget"/>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout" stretch="0,0,0,1,0">
+ <item>
+ <widget class="QCheckBox" name="nameResolutionCheckBox">
+ <property name="toolTip">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Show resolved addresses and port names rather than plain values. The corresponding name resolution preference must be enabled.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ <property name="text">
+ <string>Name resolution</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="displayFilterCheckBox">
+ <property name="toolTip">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Only show conversations matching the current display filter&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ <property name="text">
+ <string>Limit to display filter</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="conversationTypePushButton">
+ <property name="toolTip">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Add and remove conversation types.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ <property name="text">
+ <string>Conversation Types</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Close|QDialogButtonBox::Help</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>ConversationDialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>248</x>
+ <y>254</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>157</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>ConversationDialog</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>316</x>
+ <y>260</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>286</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/ui/qt/conversation_tree_widget.cpp b/ui/qt/conversation_tree_widget.cpp
new file mode 100644
index 0000000000..cca65ceaa5
--- /dev/null
+++ b/ui/qt/conversation_tree_widget.cpp
@@ -0,0 +1,673 @@
+/* conversation_tree_widget.cpp
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * 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 "conversation_tree_widget.h"
+
+#include <epan/addr_resolv.h>
+#include <epan/to_str.h>
+
+#include <epan/dissectors/packet-eth.h>
+#include <epan/dissectors/packet-fc.h>
+#include <epan/dissectors/packet-fddi.h>
+#include <epan/dissectors/packet-ip.h>
+#include <epan/dissectors/packet-ipv6.h>
+#include <epan/dissectors/packet-ipx.h>
+#include <epan/dissectors/packet-jxta.h>
+#include <epan/dissectors/packet-ncp-int.h>
+#include <epan/dissectors/packet-rsvp.h>
+#include <epan/dissectors/packet-sctp.h>
+#include <epan/dissectors/packet-tcp.h>
+#include <epan/dissectors/packet-tr.h>
+#include <epan/dissectors/packet-udp.h>
+#include <epan/dissectors/packet-ieee80211.h>
+
+#include <ui/utf8_entities.h>
+
+#include <wsutil/str_util.h>
+
+#include "wireshark_application.h"
+
+#include "qt_ui_utils.h"
+
+#include <QContextMenuEvent>
+#include <QTreeWidgetItemIterator>
+#include <QDebug>
+
+// QTreeWidget subclass that allows tapping
+
+// Minimum bandwidth calculation duration
+// https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=8703
+const double min_bw_calc_duration_ = 5 / 1000.0; // seconds
+const QString bps_na_ = QObject::tr("N/A");
+
+QMap<FilterAction::ActionDirection, conv_direction_e> fad_to_cd_;
+
+// QTreeWidgetItem subclass that allows sorting
+class ConversationTreeWidgetItem : public QTreeWidgetItem
+{
+public:
+ ConversationTreeWidgetItem(QTreeWidget *tree) : QTreeWidgetItem(tree) {}
+ ConversationTreeWidgetItem(QTreeWidget * parent, const QStringList & strings)
+ : QTreeWidgetItem (parent,strings) {}
+
+ // 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 *>();
+
+ if (!conv_item) {
+ 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));
+ setText(CONV_COLUMN_DST_PORT, get_conversation_port(conv_item->dst_port, conv_item->ptype, resolve_names));
+
+ 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);
+ 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);
+ col_str = QString("%L1").arg(conv_item->tx_frames);
+ setText(CONV_COLUMN_PKT_AB, QString::number(conv_item->tx_frames));
+ col_str = gchar_free_to_qstring(format_size(conv_item->tx_bytes, format_size_unit_none|format_size_prefix_si));
+ setText(CONV_COLUMN_BYTES_AB, col_str);
+ col_str = QString("%L1").arg(conv_item->rx_frames);
+ setText(CONV_COLUMN_PKT_BA, QString::number(conv_item->rx_frames));
+ col_str = gchar_free_to_qstring(format_size(conv_item->rx_bytes, format_size_unit_none|format_size_prefix_si));
+ setText(CONV_COLUMN_BYTES_BA, col_str);
+ setText(CONV_COLUMN_START, QString::number(nstime_to_sec(&conv_item->start_time), 'f', 9));
+ setText(CONV_COLUMN_DURATION, QString::number(duration, 'f', 6));
+ if (duration > min_bw_calc_duration_) {
+ bps_ab = gchar_free_to_qstring(format_size((gint64) conv_item->tx_bytes * 8 / duration, format_size_unit_none|format_size_prefix_si));
+ bps_ba = gchar_free_to_qstring(format_size((gint64) conv_item->rx_bytes * 8 / duration, format_size_unit_none|format_size_prefix_si));
+ }
+ setText(CONV_COLUMN_BPS_AB, bps_ab);
+ setText(CONV_COLUMN_BPS_BA, bps_ba);
+
+ conv_item->modified = FALSE;
+ }
+
+ // 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 *>();
+
+ if (!conv_item) {
+ return QVariant();
+ }
+
+ double duration = nstime_to_sec(&conv_item->stop_time) - nstime_to_sec(&conv_item->start_time);
+ double bps_ab = 0, bps_ba = 0;
+ if (duration > min_bw_calc_duration_) {
+ bps_ab = conv_item->tx_bytes * 8 / duration;
+ bps_ba = conv_item->rx_bytes * 8 / duration;
+ }
+
+ switch (col) {
+ case CONV_COLUMN_SRC_ADDR:
+ return get_conversation_address(&conv_item->src_address, resolve_names);
+ case CONV_COLUMN_SRC_PORT:
+ if (resolve_names) {
+ return get_conversation_port(conv_item->src_port, conv_item->ptype, resolve_names);
+ } else {
+ return quint32(conv_item->src_port);
+ }
+ case CONV_COLUMN_DST_ADDR:
+ return get_conversation_address(&conv_item->dst_address, resolve_names);
+ case CONV_COLUMN_DST_PORT:
+ if (resolve_names) {
+ return get_conversation_port(conv_item->dst_port, conv_item->ptype, resolve_names);
+ } else {
+ return quint32(conv_item->dst_port);
+ }
+ case CONV_COLUMN_PACKETS:
+ return quint64(conv_item->tx_frames + conv_item->rx_frames);
+ case CONV_COLUMN_BYTES:
+ return quint64(conv_item->tx_bytes + conv_item->rx_bytes);
+ case CONV_COLUMN_PKT_AB:
+ return quint64(conv_item->tx_frames);
+ case CONV_COLUMN_BYTES_AB:
+ return quint64(conv_item->tx_bytes);
+ case CONV_COLUMN_PKT_BA:
+ return quint64(conv_item->rx_frames);
+ case CONV_COLUMN_BYTES_BA:
+ return quint64(conv_item->rx_bytes);
+ case CONV_COLUMN_START:
+ return nstime_to_sec(&conv_item->start_time);
+ case CONV_COLUMN_DURATION:
+ return duration;
+ case CONV_COLUMN_BPS_AB:
+ return bps_ab;
+ case CONV_COLUMN_BPS_BA:
+ return bps_ba;
+ default:
+ return QVariant();
+ }
+ }
+
+ bool operator< (const QTreeWidgetItem &other) const
+ {
+ conv_item_t *conv_item = data(0, Qt::UserRole).value<conv_item_t *>();
+ conv_item_t *other_item = other.data(0, Qt::UserRole).value<conv_item_t *>();
+
+ if (!conv_item || !other_item) {
+ return false;
+ }
+
+ int sort_col = treeWidget()->sortColumn();
+ double conv_duration = nstime_to_sec(&conv_item->stop_time) - nstime_to_sec(&conv_item->start_time);
+ double other_duration = nstime_to_sec(&other_item->stop_time) - nstime_to_sec(&other_item->start_time);
+
+ switch(sort_col) {
+ case CONV_COLUMN_SRC_ADDR:
+ return cmp_address(&conv_item->src_address, &other_item->src_address) < 0 ? true : false;
+ case CONV_COLUMN_SRC_PORT:
+ return conv_item->src_port < other_item->src_port;
+ case CONV_COLUMN_DST_ADDR:
+ return cmp_address(&conv_item->dst_address, &other_item->dst_address) < 0 ? true : false;
+ case CONV_COLUMN_DST_PORT:
+ return conv_item->dst_port < other_item->dst_port;
+ case CONV_COLUMN_PACKETS:
+ return (conv_item->tx_frames + conv_item->rx_frames) < (other_item->tx_frames + other_item->rx_frames);
+ case CONV_COLUMN_BYTES:
+ return (conv_item->tx_bytes + conv_item->rx_bytes) < (other_item->tx_bytes + other_item->rx_bytes);
+ case CONV_COLUMN_PKT_AB:
+ return conv_item->tx_frames < other_item->tx_frames;
+ case CONV_COLUMN_BYTES_AB:
+ return conv_item->tx_bytes < other_item->tx_bytes;
+ case CONV_COLUMN_PKT_BA:
+ return conv_item->rx_frames < other_item->rx_frames;
+ case CONV_COLUMN_BYTES_BA:
+ return conv_item->rx_bytes < other_item->rx_bytes;
+ case CONV_COLUMN_START:
+ return nstime_to_sec(&conv_item->start_time) < nstime_to_sec(&other_item->start_time);
+ case CONV_COLUMN_DURATION:
+ return conv_duration < other_duration;
+ case CONV_COLUMN_BPS_AB:
+ return conv_item->tx_bytes / conv_duration < other_item->tx_bytes / other_duration;
+ case CONV_COLUMN_BPS_BA:
+ return conv_item->rx_bytes / conv_duration < other_item->rx_bytes / other_duration;
+ default:
+ return false;
+ }
+ }
+
+private:
+};
+
+ConversationTreeWidget::ConversationTreeWidget(QWidget *parent, conversation_type_e conv_type) :
+ QTreeWidget(parent),
+ conv_type_(conv_type),
+ hash_(),
+ resolve_names_(false)
+{
+ setRootIsDecorated(false);
+ sortByColumn(0, Qt::AscendingOrder);
+
+ setColumnCount(CONV_NUM_COLUMNS);
+
+ for (int i = 0; i < CONV_NUM_COLUMNS; i++) {
+ headerItem()->setText(i, column_titles[i]);
+ }
+
+ if (conversation_hide_ports(conv_type)) {
+ hideColumn(CONV_COLUMN_SRC_PORT);
+ hideColumn(CONV_COLUMN_DST_PORT);
+ } else if (conv_type == CONV_TYPE_NCP) {
+ headerItem()->setText(CONV_COLUMN_SRC_PORT, conn_a_title);
+ headerItem()->setText(CONV_COLUMN_DST_PORT, conn_b_title);
+ }
+
+ int one_en = fontMetrics().height() / 2;
+ for (int i = 0; i < CONV_NUM_COLUMNS; i++) {
+ switch (i) {
+ case CONV_COLUMN_SRC_ADDR:
+ case CONV_COLUMN_DST_ADDR:
+ setColumnWidth(i, one_en * strlen("000.000.000.000"));
+ break;
+ case CONV_COLUMN_SRC_PORT:
+ case CONV_COLUMN_DST_PORT:
+ setColumnWidth(i, one_en * strlen("000000"));
+ break;
+ case CONV_COLUMN_PACKETS:
+ case CONV_COLUMN_PKT_AB:
+ case CONV_COLUMN_PKT_BA:
+ setColumnWidth(i, one_en * strlen("00,000"));
+ break;
+ case CONV_COLUMN_BYTES:
+ case CONV_COLUMN_BYTES_AB:
+ case CONV_COLUMN_BYTES_BA:
+ setColumnWidth(i, one_en * strlen("000,000"));
+ break;
+ case CONV_COLUMN_START:
+ setColumnWidth(i, one_en * strlen("00.000"));
+ break;
+ case CONV_COLUMN_DURATION:
+ setColumnWidth(i, one_en * strlen("00.000000"));
+ break;
+ case CONV_COLUMN_BPS_AB:
+ case CONV_COLUMN_BPS_BA:
+ setColumnWidth(i, one_en * strlen("000 k"));
+ break;
+ default:
+ setColumnWidth(i, one_en * 5);
+ }
+ }
+
+ QMenu *submenu;
+
+ initDirectionMap();
+
+ FilterAction::Action cur_action = FilterAction::ActionApply;
+ submenu = ctx_menu_.addMenu(FilterAction::actionName(cur_action));
+ foreach (FilterAction::ActionType at, FilterAction::actionTypes()) {
+ QMenu *subsubmenu = submenu->addMenu(FilterAction::actionTypeName(at));
+ foreach (FilterAction::ActionDirection ad, FilterAction::actionDirections()) {
+ FilterAction *fa = new FilterAction(subsubmenu, cur_action, at, ad);
+ subsubmenu->addAction(fa);
+ connect(fa, SIGNAL(triggered()), this, SLOT(filterActionTriggered()));
+ }
+ }
+
+ cur_action = FilterAction::ActionPrepare;
+ submenu = ctx_menu_.addMenu(FilterAction::actionName(cur_action));
+ foreach (FilterAction::ActionType at, FilterAction::actionTypes()) {
+ QMenu *subsubmenu = submenu->addMenu(FilterAction::actionTypeName(at));
+ foreach (FilterAction::ActionDirection ad, FilterAction::actionDirections()) {
+ FilterAction *fa = new FilterAction(subsubmenu, cur_action, at, ad);
+ subsubmenu->addAction(fa);
+ connect(fa, SIGNAL(triggered()), this, SLOT(filterActionTriggered()));
+ }
+ }
+
+ cur_action = FilterAction::ActionFind;
+ submenu = ctx_menu_.addMenu(FilterAction::actionName(cur_action));
+ foreach (FilterAction::ActionDirection ad, FilterAction::actionDirections()) {
+ FilterAction *fa = new FilterAction(submenu, cur_action, FilterAction::ActionTypePlain, ad);
+ submenu->addAction(fa);
+ connect(fa, SIGNAL(triggered()), this, SLOT(filterActionTriggered()));
+ }
+
+ cur_action = FilterAction::ActionColorize;
+ submenu = ctx_menu_.addMenu(FilterAction::actionName(cur_action));
+ foreach (FilterAction::ActionDirection ad, FilterAction::actionDirections()) {
+ FilterAction *fa = new FilterAction(submenu, cur_action, FilterAction::ActionTypePlain, ad);
+ submenu->addAction(fa);
+ connect(fa, SIGNAL(triggered()), this, SLOT(filterActionTriggered()));
+ }
+
+ updateItems();
+
+ connect(wsApp, SIGNAL(addressResolutionChanged()), this, SLOT(updateItems()));
+}
+
+ConversationTreeWidget::~ConversationTreeWidget() {
+ remove_tap_listener(this);
+ reset_conversation_table_data(&hash_);
+}
+
+// Callbacks for register_tap_listener
+void ConversationTreeWidget::tapReset(void *conv_tree_ptr)
+{
+ ConversationTreeWidget *conv_tree = static_cast<ConversationTreeWidget *>(conv_tree_ptr);
+ 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<ConversationTreeWidget *>(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<ConversationTreeWidget *>(conv_tree_ptr);
+ if (!conv_tree) return;
+
+ conv_tree->updateItems();
+}
+
+QList<QVariant> ConversationTreeWidget::rowData(int row)
+{
+ QList<QVariant> row_data;
+
+ for (int col = 0; col < columnCount(); col++) {
+ if (isColumnHidden(col) || row >= topLevelItemCount()) {
+ continue;
+ }
+ if (row < 0) {
+ row_data << headerItem()->text(col);
+ } else {
+ ConversationTreeWidgetItem *ci = static_cast<ConversationTreeWidgetItem *>(topLevelItem(row));
+ if (ci) {
+ row_data << ci->colData(col, resolve_names_);
+ }
+ }
+ }
+ return row_data;
+}
+
+void ConversationTreeWidget::setNameResolutionEnabled(bool enable)
+{
+ if (resolve_names_ != enable) {
+ resolve_names_ = enable;
+ updateItems();
+ }
+}
+
+void ConversationTreeWidget::contextMenuEvent(QContextMenuEvent *event)
+{
+ bool enable = selectedItems().count() > 0 ? true : false;
+
+ foreach (QMenu *submenu, ctx_menu_.findChildren<QMenu*>()) {
+ submenu->setEnabled(enable);
+ }
+
+ ctx_menu_.exec(event->globalPos());
+}
+
+void ConversationTreeWidget::initDirectionMap()
+{
+ if (fad_to_cd_.size() > 0) {
+ return;
+ }
+
+ fad_to_cd_[FilterAction::ActionDirectionAToFromB] = CONV_DIR_A_TO_FROM_B;
+ fad_to_cd_[FilterAction::ActionDirectionAToB] = CONV_DIR_A_TO_B;
+ fad_to_cd_[FilterAction::ActionDirectionAFromB] = CONV_DIR_A_FROM_B;
+ fad_to_cd_[FilterAction::ActionDirectionAToFromAny] = CONV_DIR_A_TO_FROM_ANY;
+ fad_to_cd_[FilterAction::ActionDirectionAToAny] = CONV_DIR_A_TO_ANY;
+ fad_to_cd_[FilterAction::ActionDirectionAFromAny] = CONV_DIR_A_FROM_ANY;
+ fad_to_cd_[FilterAction::ActionDirectionAnyToFromB] = CONV_DIR_ANY_TO_FROM_B;
+ fad_to_cd_[FilterAction::ActionDirectionAnyToB] = CONV_DIR_ANY_TO_B;
+ fad_to_cd_[FilterAction::ActionDirectionAnyFromB] = CONV_DIR_ANY_FROM_B;
+}
+
+void ConversationTreeWidget::updateItems() {
+ title_ = conversation_title(conv_type_);
+
+ if (hash_.conv_array && hash_.conv_array->len > 0) {
+ title_.append(QString(" %1 %2").arg(UTF8_MIDDLE_DOT).arg(hash_.conv_array->len));
+ }
+ emit titleChanged(this, title_);
+
+ if (!hash_.conv_array) {
+ return;
+ }
+
+ setSortingEnabled(false);
+ 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));
+ addTopLevelItem(ctwi);
+
+ for (int col = 0; col < columnCount(); col++) {
+ switch (col) {
+ case CONV_COLUMN_SRC_ADDR:
+ case CONV_COLUMN_DST_ADDR:
+ break;
+ default:
+ ctwi->setTextAlignment(col, Qt::AlignRight);
+ break;
+ }
+ }
+ }
+ QTreeWidgetItemIterator iter(this);
+ while (*iter) {
+ ConversationTreeWidgetItem *ci = static_cast<ConversationTreeWidgetItem *>(*iter);
+ ci->update(resolve_names_);
+ ++iter;
+ }
+ setSortingEnabled(true);
+
+ for (int col = 0; col < columnCount(); col++) {
+ resizeColumnToContents(col);
+ }
+}
+
+void ConversationTreeWidget::filterActionTriggered()
+{
+ if (selectedItems().count() < 1) {
+ return;
+ }
+
+ FilterAction *fa = qobject_cast<FilterAction *>(QObject::sender());
+ ConversationTreeWidgetItem *ctwi = static_cast<ConversationTreeWidgetItem *>(selectedItems()[0]);
+ if (!fa || !ctwi) {
+ return;
+ }
+
+ conv_item_t *conv_item = ctwi->data(0, Qt::UserRole).value<conv_item_t *>();
+ if (!conv_item) {
+ return;
+ }
+
+ QString filter = get_conversation_filter(conv_item, fad_to_cd_[fa->actionDirection()]);
+ 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
+ *
+ * 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/qt/conversation_tree_widget.h b/ui/qt/conversation_tree_widget.h
new file mode 100644
index 0000000000..223f83a7c0
--- /dev/null
+++ b/ui/qt/conversation_tree_widget.h
@@ -0,0 +1,112 @@
+/* conversation_tree_widget.h
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * 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_TREE_WIDGET_H
+#define CONVERSATION_TREE_WIDGET_H
+
+#include "config.h"
+
+#include <glib.h>
+
+#include <epan/packet.h>
+#include <epan/tap.h>
+
+#include "ui/conversation_hash.h"
+
+#include "filter_action.h"
+
+#include <QMenu>
+#include <QTreeWidget>
+
+Q_DECLARE_METATYPE(conv_item_t *)
+
+class ConversationTreeWidget : public QTreeWidget
+{
+ Q_OBJECT
+public:
+ explicit ConversationTreeWidget(QWidget *parent, conversation_type_e conv_type);
+ ~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<QVariant> rowData(int row);
+
+ conversation_type_e conversationType() { return conv_type_; }
+ // Title string plus optional count
+ const QString &conversationTitle() { return title_; }
+
+signals:
+ void titleChanged(QWidget *tree, const QString &text);
+ void filterAction(QString& filter, FilterAction::Action action, FilterAction::ActionType type);
+
+public slots:
+ void setNameResolutionEnabled(bool enable);
+
+protected:
+ void contextMenuEvent(QContextMenuEvent *event);
+
+private:
+ conversation_type_e conv_type_;
+ QString title_;
+ conv_hash_t hash_;
+ bool resolve_names_;
+ QMenu ctx_menu_;
+
+ void initDirectionMap();
+ int tapEthernetPacket(packet_info *pinfo, const void *vip);
+ int tapFibreChannelPacket(packet_info *pinfo, const void *vip);
+ int tapFddiPacket(packet_info *pinfo, const void *vip);
+ int tapIPv4Packet(packet_info *pinfo, const void *vip);
+ int tapIPv6Packet(packet_info *pinfo, const void *vip);
+ int tapIpxPacket(packet_info *pinfo, const void *vip);
+ int tapJxtaPacket(packet_info *pinfo, const void *vip);
+ int tapNcpPacket(packet_info *pinfo, const void *vip);
+ int tapRsvpPacket(packet_info *pinfo, const void *vip);
+ int tapSctpPacket(packet_info *pinfo, const void *vip);
+ int tapTcpPacket(packet_info *pinfo, const void *vip);
+ int tapTokenRingPacket(packet_info *pinfo, const void *vip);
+ int tapUdpPacket(packet_info *pinfo, const void *vip);
+ int tapUsbPacket(packet_info *pinfo, const void *vip);
+ int tapWlanPacket(packet_info *pinfo, const void *vip);
+
+private slots:
+ void updateItems();
+ void filterActionTriggered();
+};
+
+#endif // CONVERSATION_TREE_WIDGET_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/qt/filter_action.cpp b/ui/qt/filter_action.cpp
new file mode 100644
index 0000000000..e91642eba6
--- /dev/null
+++ b/ui/qt/filter_action.cpp
@@ -0,0 +1,172 @@
+/* filter_action.cpp
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * 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 "filter_action.h"
+
+FilterAction::FilterAction(QObject *parent, Action action, ActionType type, ActionDirection direction) :
+ QAction(parent),
+ action_(action),
+ type_(type),
+ direction_(direction)
+{
+ setText(actionDirectionName(direction));
+}
+
+
+const QList<FilterAction::Action> FilterAction::actions() {
+ static const QList<Action> actions_ = QList<Action>()
+ << ActionApply
+ << ActionPrepare
+ << ActionFind
+ << ActionColorize
+ << ActionWebLookup
+ << ActionCopy;
+ return actions_;
+}
+
+const QString FilterAction::actionName(Action action) {
+ switch (action) {
+ case ActionApply:
+ return QObject::tr("Apply as Filter");
+ break;
+ case ActionPrepare:
+ return QObject::tr("Prepare a Filter");
+ break;
+ case ActionFind:
+ return QObject::tr("Find");
+ break;
+ case ActionColorize:
+ return QObject::tr("Colorize");
+ break;
+ case ActionWebLookup:
+ return QObject::tr("Look Up");
+ break;
+ case ActionCopy:
+ return QObject::tr("Copy");
+ break;
+ default:
+ return QObject::tr("UNKNOWN");
+ break;
+ }
+}
+
+
+const QList<FilterAction::ActionType> FilterAction::actionTypes()
+{
+ static const QList<ActionType> action_types_ = QList<ActionType>()
+ << ActionTypePlain
+ << ActionTypeNot
+ << ActionTypeAnd
+ << ActionTypeOr
+ << ActionTypeAndNot
+ << ActionTypeOrNot;
+ return action_types_;
+}
+
+const QString FilterAction::actionTypeName(ActionType type) {
+ switch (type) {
+ case ActionTypePlain:
+ return QObject::tr("Selected");
+ break;
+ case ActionTypeNot:
+ return QObject::tr("Not Selected");
+ break;
+ case ActionTypeAnd:
+ return QObject::tr(UTF8_HORIZONTAL_ELLIPSIS " and Selected");
+ break;
+ case ActionTypeOr:
+ return QObject::tr(UTF8_HORIZONTAL_ELLIPSIS " or Selected");
+ break;
+ case ActionTypeAndNot:
+ return QObject::tr(UTF8_HORIZONTAL_ELLIPSIS " and not Selected");
+ break;
+ case ActionTypeOrNot:
+ return QObject::tr(UTF8_HORIZONTAL_ELLIPSIS " or not Selected");
+ break;
+ default:
+ return QObject::tr("UNKNOWN");
+ break;
+ }
+}
+
+
+const QList<FilterAction::ActionDirection> FilterAction::actionDirections()
+{
+ static const QList<FilterAction::ActionDirection> action_directions_ = QList<ActionDirection>()
+ << ActionDirectionAToFromB
+ << ActionDirectionAToB
+ << ActionDirectionAFromB
+ << ActionDirectionAToFromAny
+ << ActionDirectionAToAny
+ << ActionDirectionAFromAny
+ << ActionDirectionAnyToFromB
+ << ActionDirectionAnyToB
+ << ActionDirectionAnyFromB;
+ return action_directions_;
+}
+
+const QString FilterAction::actionDirectionName(ActionDirection direction) {
+ switch (direction) {
+ case ActionDirectionAToFromB:
+ return QObject::tr("A " UTF8_LEFT_RIGHT_ARROW " B");
+ break;
+ case ActionDirectionAToB:
+ return QObject::tr("A " UTF8_RIGHTWARDS_ARROW " B");
+ break;
+ case ActionDirectionAFromB:
+ return QObject::tr("B " UTF8_RIGHTWARDS_ARROW " A");
+ break;
+ case ActionDirectionAToFromAny:
+ return QObject::tr("A " UTF8_LEFT_RIGHT_ARROW " Any");
+ break;
+ case ActionDirectionAToAny:
+ return QObject::tr("A " UTF8_RIGHTWARDS_ARROW " Any");
+ break;
+ case ActionDirectionAFromAny:
+ return QObject::tr("Any " UTF8_RIGHTWARDS_ARROW " A");
+ break;
+ case ActionDirectionAnyToFromB:
+ return QObject::tr("Any " UTF8_LEFT_RIGHT_ARROW " B");
+ break;
+ case ActionDirectionAnyToB:
+ return QObject::tr("Any " UTF8_RIGHTWARDS_ARROW " B");
+ break;
+ case ActionDirectionAnyFromB:
+ return QObject::tr("B " UTF8_RIGHTWARDS_ARROW " Any");
+ break;
+ default:
+ return QObject::tr("UNKNOWN");
+ break;
+ }
+}
+
+/*
+ * 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/qt/filter_action.h b/ui/qt/filter_action.h
new file mode 100644
index 0000000000..b1ccff0ec6
--- /dev/null
+++ b/ui/qt/filter_action.h
@@ -0,0 +1,106 @@
+/* filter_action.h
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * 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.
+ */
+
+/* Derived from gtk/filter_utils.h */
+
+#ifndef FILTER_ACTION_H
+#define FILTER_ACTION_H
+
+#include "ui/utf8_entities.h"
+
+#include <QAction>
+
+class FilterAction : public QAction
+{
+ Q_OBJECT
+public:
+ /* Filter actions */
+ enum Action {
+ ActionApply,
+ ActionPrepare,
+ ActionFind,
+ ActionColorize,
+ ActionWebLookup,
+ ActionCopy
+ };
+
+ /* Action type - says what to do with the filter */
+ enum ActionType {
+ ActionTypePlain,
+ ActionTypeNot,
+ ActionTypeAnd,
+ ActionTypeOr,
+ ActionTypeAndNot,
+ ActionTypeOrNot
+ };
+
+ /* Action direction */
+ enum ActionDirection {
+ ActionDirectionAToFromB,
+ ActionDirectionAToB,
+ ActionDirectionAFromB,
+ ActionDirectionAToFromAny,
+ ActionDirectionAToAny,
+ ActionDirectionAFromAny,
+ ActionDirectionAnyToFromB,
+ ActionDirectionAnyToB,
+ ActionDirectionAnyFromB
+ };
+
+ explicit FilterAction(QObject *parent = 0, Action action = ActionApply, ActionType type = ActionTypePlain, ActionDirection direction = ActionDirectionAToFromB);
+
+ Action action() { return action_; }
+ static const QList<Action> actions();
+ static const QString actionName(Action action);
+
+ ActionType actionType() { return type_; }
+ static const QList<ActionType> actionTypes();
+ static const QString actionTypeName(ActionType type);
+
+ ActionDirection actionDirection() { return direction_; }
+ static const QList<ActionDirection> actionDirections();
+ static const QString actionDirectionName(ActionDirection direction);
+
+signals:
+
+public slots:
+
+private:
+ Action action_;
+ ActionType type_;
+ ActionDirection direction_;
+
+};
+
+#endif // FILTER_ACTION_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/qt/main_window.h b/ui/qt/main_window.h
index 725eb5b409..98c205d2df 100644
--- a/ui/qt/main_window.h
+++ b/ui/qt/main_window.h
@@ -53,6 +53,7 @@
#include "display_filter_combo.h"
#include "progress_bar.h"
#include "file_set_dialog.h"
+#include "filter_action.h"
#include "capture_file_dialog.h"
#include "summary_dialog.h"
#include "follow_stream_dialog.h"
@@ -82,6 +83,7 @@ protected:
void closeEvent (QCloseEvent *event);
private:
+ // XXX Move to FilterUtils
enum MatchSelected {
MatchSelectedReplace,
MatchSelectedAnd,
@@ -212,6 +214,9 @@ private slots:
void addDisplayFilterButton(QString df_text);
void displayFilterButtonClicked();
+ // Handle FilterAction signals
+ void filterAction(QString& filter, FilterAction::Action action, FilterAction::ActionType type);
+
/** Pass stat cmd arguments to a slot.
* @param slot Partial slot name, e.g. "StatisticsIOGraph".
* @param "-z" argument, e.g. "io,stat".
@@ -283,7 +288,7 @@ private slots:
void on_actionCaptureOptions_triggered();
#endif
- void matchSelectedFilter(MainWindow::MatchSelected filter_type, bool apply = false, bool copy_only = false);
+ void matchFieldFilter(FilterAction::Action action, FilterAction::ActionType filter_type);
void on_actionAnalyzeAAFSelected_triggered();
void on_actionAnalyzeAAFNotSelected_triggered();
void on_actionAnalyzeAAFAndSelected_triggered();
@@ -368,6 +373,8 @@ private slots:
void on_actionStatisticsBACappObjectId_triggered();
void on_actionStatisticsBACappService_triggered();
void on_actionStatisticsCollectd_triggered();
+ void statCommandConversation(const char *arg = NULL, void *userdata = NULL);
+ void on_actionStatisticsConversations_triggered();
void on_actionStatisticsHART_IP_triggered();
void on_actionStatisticsHTTPPacketCounter_triggered();
void on_actionStatisticsHTTPRequests_triggered();
diff --git a/ui/qt/main_window.ui b/ui/qt/main_window.ui
index 3e31f0549c..a79eaf8660 100644
--- a/ui/qt/main_window.ui
+++ b/ui/qt/main_window.ui
@@ -357,6 +357,7 @@
</widget>
<addaction name="actionSummary"/>
<addaction name="actionProtocol_Hierarchy"/>
+ <addaction name="actionStatisticsConversations"/>
<addaction name="actionStatisticsPacketLen"/>
<addaction name="actionStatisticsIOGraph"/>
<addaction name="separator"/>
@@ -1703,6 +1704,14 @@
<string>&amp;TFTP</string>
</property>
</action>
+ <action name="actionStatisticsConversations">
+ <property name="text">
+ <string>Conversations</string>
+ </property>
+ <property name="toolTip">
+ <string>Conversations at different protocol levels</string>
+ </property>
+ </action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<customwidgets>
diff --git a/ui/qt/main_window_slots.cpp b/ui/qt/main_window_slots.cpp
index 9abfc104cb..b8cc881c2b 100644
--- a/ui/qt/main_window_slots.cpp
+++ b/ui/qt/main_window_slots.cpp
@@ -70,6 +70,7 @@
#endif
#include "capture_file_dialog.h"
+#include "conversation_dialog.h"
#include "decode_as_dialog.h"
#include "export_object_dialog.h"
#include "export_pdu_dialog.h"
@@ -299,6 +300,71 @@ void MainWindow::layoutPanes()
}
}
+void MainWindow::filterAction(QString &action_filter, FilterAction::Action action, FilterAction::ActionType type)
+{
+ QString cur_filter, new_filter;
+
+ if (!df_combo_box_) return;
+ cur_filter = df_combo_box_->lineEdit()->text();
+
+ switch (type) {
+ case FilterAction::ActionTypePlain:
+ new_filter = action_filter;
+ break;
+ case FilterAction::ActionTypeAnd:
+ if (cur_filter.length()) {
+ new_filter = "(" + cur_filter + ") && (" + action_filter + ")";
+ } else {
+ new_filter = action_filter;
+ }
+ break;
+ case FilterAction::ActionTypeOr:
+ if (cur_filter.length()) {
+ new_filter = "(" + cur_filter + ") || (" + action_filter + ")";
+ } else {
+ new_filter = action_filter;
+ }
+ break;
+ case FilterAction::ActionTypeNot:
+ new_filter = "!(" + action_filter + ")";
+ break;
+ case FilterAction::ActionTypeAndNot:
+ if (cur_filter.length()) {
+ new_filter = "(" + cur_filter + ") && !(" + action_filter + ")";
+ } else {
+ new_filter = "!(" + action_filter + ")";
+ }
+ break;
+ case FilterAction::ActionTypeOrNot:
+ if (cur_filter.length()) {
+ new_filter = "(" + cur_filter + ") || !(" + action_filter + ")";
+ } else {
+ new_filter = "!(" + action_filter + ")";
+ }
+ break;
+ default:
+ g_assert_not_reached();
+ break;
+ }
+
+ switch(action) {
+ case FilterAction::ActionApply:
+ df_combo_box_->lineEdit()->setText(new_filter);
+ df_combo_box_->applyDisplayFilter();
+ break;
+ case FilterAction::ActionPrepare:
+ df_combo_box_->lineEdit()->setText(new_filter);
+ df_combo_box_->lineEdit()->setFocus();
+ break;
+ case FilterAction::ActionCopy:
+ wsApp->clipboard()->setText(new_filter);
+ break;
+ default:
+ qDebug() << "FIX FilterAction::Action" << action << "not implemented";
+ break;
+ }
+}
+
// Capture callbacks
void MainWindow::captureCapturePrepared(capture_session *cap_session) {
@@ -1482,7 +1548,7 @@ void MainWindow::on_actionEditCopyValue_triggered()
void MainWindow::on_actionEditCopyAsFilter_triggered()
{
- matchSelectedFilter(MatchSelectedReplace, false, true);
+ matchFieldFilter(FilterAction::ActionCopy, FilterAction::ActionTypePlain);
}
void MainWindow::on_actionEditFindPacket_triggered()
@@ -1643,11 +1709,9 @@ void MainWindow::on_actionViewToolbarDisplayFilter_triggered()
// Analyze Menu
// XXX This should probably be somewhere else.
-void MainWindow::matchSelectedFilter(MainWindow::MatchSelected filter_type, bool apply, bool copy_only)
+void MainWindow::matchFieldFilter(FilterAction::Action action, FilterAction::ActionType filter_type)
{
QString field_filter;
- QString cur_filter;
- QString new_filter;
if (packet_list_->contextMenuActive()) {
field_filter = packet_list_->getFilterFromRowAndColumn();
@@ -1666,121 +1730,70 @@ void MainWindow::matchSelectedFilter(MainWindow::MatchSelected filter_type, bool
return;
}
- if (!df_combo_box_) return;
-
- cur_filter = df_combo_box_->lineEdit()->text();
-
- switch (filter_type) {
- case MatchSelectedReplace:
- new_filter = field_filter;
- break;
- case MatchSelectedAnd:
- if (cur_filter.length()) {
- new_filter = "(" + cur_filter + ") && (" + field_filter + ")";
- } else {
- new_filter = field_filter;
- }
- break;
- case MatchSelectedOr:
- if (cur_filter.length()) {
- new_filter = "(" + cur_filter + ") || (" + field_filter + ")";
- } else {
- new_filter = field_filter;
- }
- break;
- case MatchSelectedNot:
- new_filter = "!(" + field_filter + ")";
- break;
- case MatchSelectedAndNot:
- if (cur_filter.length()) {
- new_filter = "(" + cur_filter + ") && !(" + field_filter + ")";
- } else {
- new_filter = "!(" + field_filter + ")";
- }
- break;
- case MatchSelectedOrNot:
- if (cur_filter.length()) {
- new_filter = "(" + cur_filter + ") || !(" + field_filter + ")";
- } else {
- new_filter = "!(" + field_filter + ")";
- }
- break;
- default:
- g_assert_not_reached();
- break;
- }
-
- if (copy_only) {
- wsApp->clipboard()->setText(new_filter);
- } else {
- df_combo_box_->lineEdit()->setText(new_filter);
- if (apply) {
- df_combo_box_->applyDisplayFilter();
- } else {
- df_combo_box_->lineEdit()->setFocus();
- }
- }
-
+ filterAction(field_filter, action, filter_type);
}
+// XXX We could probably create the analyze and prepare actions
+// dynamically using FilterActions and consolidate the methods
+// below into one callback.
void MainWindow::on_actionAnalyzeAAFSelected_triggered()
{
- matchSelectedFilter(MatchSelectedReplace, true, false);
+ matchFieldFilter(FilterAction::ActionApply, FilterAction::ActionTypePlain);
}
void MainWindow::on_actionAnalyzeAAFNotSelected_triggered()
{
- matchSelectedFilter(MatchSelectedNot, true, false);
+ matchFieldFilter(FilterAction::ActionApply, FilterAction::ActionTypeNot);
}
void MainWindow::on_actionAnalyzeAAFAndSelected_triggered()
{
- matchSelectedFilter(MatchSelectedAnd, true, false);
+ matchFieldFilter(FilterAction::ActionApply, FilterAction::ActionTypeAnd);
}
void MainWindow::on_actionAnalyzeAAFOrSelected_triggered()
{
- matchSelectedFilter(MatchSelectedOr, true, false);
+ matchFieldFilter(FilterAction::ActionApply, FilterAction::ActionTypeOr);
}
void MainWindow::on_actionAnalyzeAAFAndNotSelected_triggered()
{
- matchSelectedFilter(MatchSelectedAndNot, true, false);
+ matchFieldFilter(FilterAction::ActionApply, FilterAction::ActionTypeAndNot);
}
void MainWindow::on_actionAnalyzeAAFOrNotSelected_triggered()
{
- matchSelectedFilter(MatchSelectedOrNot, true, false);
+ matchFieldFilter(FilterAction::ActionApply, FilterAction::ActionTypeOrNot);
}
void MainWindow::on_actionAnalyzePAFSelected_triggered()
{
- matchSelectedFilter(MatchSelectedReplace, false, false);
+ matchFieldFilter(FilterAction::ActionPrepare, FilterAction::ActionTypePlain);
}
void MainWindow::on_actionAnalyzePAFNotSelected_triggered()
{
- matchSelectedFilter(MatchSelectedNot, false, false);
+ matchFieldFilter(FilterAction::ActionPrepare, FilterAction::ActionTypeNot);
}
void MainWindow::on_actionAnalyzePAFAndSelected_triggered()
{
- matchSelectedFilter(MatchSelectedAnd, false, false);
+ matchFieldFilter(FilterAction::ActionPrepare, FilterAction::ActionTypeAnd);
}
void MainWindow::on_actionAnalyzePAFOrSelected_triggered()
{
- matchSelectedFilter(MatchSelectedOr, false, false);
+ matchFieldFilter(FilterAction::ActionPrepare, FilterAction::ActionTypeOr);
}
void MainWindow::on_actionAnalyzePAFAndNotSelected_triggered()
{
- matchSelectedFilter(MatchSelectedAndNot, false, false);
+ matchFieldFilter(FilterAction::ActionPrepare, FilterAction::ActionTypeAndNot);
}
void MainWindow::on_actionAnalyzePAFOrNotSelected_triggered()
{
- matchSelectedFilter(MatchSelectedOrNot, false, false);
+ matchFieldFilter(FilterAction::ActionPrepare, FilterAction::ActionTypeOrNot);
}
void MainWindow::on_actionAnalyzeDecodeAs_triggered()
@@ -2061,6 +2074,26 @@ void MainWindow::on_actionStatisticsCollectd_triggered()
openStatisticsTreeDialog("collectd");
}
+void MainWindow::statCommandConversation(const char *arg, void *userdata)
+{
+ Q_UNUSED(userdata);
+ ConversationDialog *conv_dialog = new ConversationDialog(this, cap_file_, 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)),
+ this, SLOT(openFollowStreamDialog(follow_type_t)));
+ connect(conv_dialog, SIGNAL(openTcpStreamGraph(int)),
+ this, SLOT(openTcpStreamDialog(int)));
+ connect(this, SIGNAL(setCaptureFile(capture_file*)),
+ conv_dialog, SLOT(setCaptureFile(capture_file*)));
+ conv_dialog->show();
+}
+
+void MainWindow::on_actionStatisticsConversations_triggered()
+{
+ statCommandConversation(NULL, NULL);
+}
+
void MainWindow::on_actionStatisticsHART_IP_triggered()
{
openStatisticsTreeDialog("hart_ip");
diff --git a/ui/qt/packet_list.cpp b/ui/qt/packet_list.cpp
index 874ab47457..23e0a88ccf 100644
--- a/ui/qt/packet_list.cpp
+++ b/ui/qt/packet_list.cpp
@@ -386,6 +386,8 @@ PacketList::PacketList(QWidget *parent) :
g_assert(gbl_cur_packet_list == NULL);
gbl_cur_packet_list = this;
+
+ connect(wsApp, SIGNAL(addressResolutionChanged()), this, SLOT(updateAll()));
}
void PacketList::setProtoTree (ProtoTree *proto_tree) {
diff --git a/ui/qt/packet_list.h b/ui/qt/packet_list.h
index 4f972bef0e..f632044a0c 100644
--- a/ui/qt/packet_list.h
+++ b/ui/qt/packet_list.h
@@ -40,7 +40,6 @@ public:
PacketListModel *packetListModel() const;
void setProtoTree(ProtoTree *proto_tree);
void setByteViewTab(ByteViewTab *byteViewTab);
- void updateAll();
void freeze();
void thaw();
void clear();
@@ -92,6 +91,7 @@ public slots:
void ignoreAllDisplayedFrames(bool set);
void setTimeReference();
void unsetAllTimeReferences();
+ void updateAll();
private slots:
void addRelatedFrame(int related_frame);
diff --git a/ui/qt/tcp_stream_dialog.h b/ui/qt/tcp_stream_dialog.h
index 176a5e575c..abcf24fd45 100644
--- a/ui/qt/tcp_stream_dialog.h
+++ b/ui/qt/tcp_stream_dialog.h
@@ -46,7 +46,7 @@ class TCPStreamDialog : public QDialog
Q_OBJECT
public:
- explicit TCPStreamDialog(QWidget *parent = 0, capture_file *cf = NULL, tcp_graph_type graph_type = GRAPH_TSEQ_STEVENS);
+ explicit TCPStreamDialog(QWidget *parent = 0, capture_file *cf = NULL, tcp_graph_type graph_type = GRAPH_TSEQ_TCPTRACE);
~TCPStreamDialog();
signals:
diff --git a/ui/qt/wireshark_application.cpp b/ui/qt/wireshark_application.cpp
index c799d1a6b1..405cdbbf45 100644
--- a/ui/qt/wireshark_application.cpp
+++ b/ui/qt/wireshark_application.cpp
@@ -23,6 +23,7 @@
#include "wsutil/filesystem.h"
+#include "epan/addr_resolv.h"
#include "epan/disabled_protos.h"
#include "epan/tap.h"
#include "epan/timestamp.h"
@@ -190,6 +191,14 @@ void WiresharkApplication::refreshRecentFiles(void) {
}
}
+void WiresharkApplication::refreshAddressResolution()
+{
+ // Anything new show up?
+ if (host_name_lookup_process()) {
+ emit addressResolutionChanged();
+ }
+}
+
void WiresharkApplication::updateTaps()
{
draw_tap_listeners(FALSE);
@@ -590,6 +599,10 @@ WiresharkApplication::WiresharkApplication(int &argc, char **argv) :
connect(&recent_timer_, SIGNAL(timeout()), this, SLOT(refreshRecentFiles()));
recent_timer_.start(2000);
+ addr_resolv_timer_.setParent(this);
+ connect(&addr_resolv_timer_, SIGNAL(timeout()), this, SLOT(refreshAddressResolution()));
+ recent_timer_.start(1000);
+
tap_update_timer_.setParent(this);
tap_update_timer_.setInterval(TAP_UPDATE_DEFAULT_INTERVAL);
connect(this, SIGNAL(appInitialized()), &tap_update_timer_, SLOT(start()));
diff --git a/ui/qt/wireshark_application.h b/ui/qt/wireshark_application.h
index 8bf0912cfa..2c1defc358 100644
--- a/ui/qt/wireshark_application.h
+++ b/ui/qt/wireshark_application.h
@@ -94,6 +94,7 @@ private:
QFont mono_regular_font_;
QFont mono_bold_font_;
QTimer recent_timer_;
+ QTimer addr_resolv_timer_;
QTimer tap_update_timer_;
QList<QString> pending_open_files_;
QSocketNotifier *if_notifier_;
@@ -114,6 +115,7 @@ signals:
void filterExpressionsChanged();
void packetDissectionChanged();
void preferencesChanged();
+ void addressResolutionChanged();
// XXX It might make more sense to move these to main.cpp or main_window.cpp or their own class.
void captureCapturePrepared(capture_session *cap_session);
@@ -141,6 +143,7 @@ private slots:
void ifChangeEventsAvailable();
void itemStatusFinished(const QString filename = "", qint64 size = 0, bool accessible = false);
void refreshRecentFiles(void);
+ void refreshAddressResolution(void);
void updateTaps();
};
diff --git a/ui/recent.c b/ui/recent.c
index bdb93e7c5c..7a67047463 100644
--- a/ui/recent.c
+++ b/ui/recent.c
@@ -74,7 +74,10 @@
#define RECENT_GUI_GEOMETRY_WLAN_STATS_PANE "gui.geometry_status_wlan_stats_pane"
#define RECENT_LAST_USED_PROFILE "gui.last_used_profile"
#define RECENT_GUI_FILEOPEN_REMEMBERED_DIR "gui.fileopen_remembered_dir"
+#define RECENT_GUI_CONVERSATION_TABS "gui.conversation_tabs"
+
#define RECENT_GUI_GEOMETRY "gui.geom."
+
#define RECENT_KEY_PRIVS_WARN_IF_ELEVATED "privs.warn_if_elevated"
#define RECENT_KEY_PRIVS_WARN_IF_NO_NPF "privs.warn_if_no_npf"
@@ -666,6 +669,7 @@ write_profile_recent(void)
{
char *pf_dir_path;
char *rf_path;
+ char *string_list;
FILE *rf;
/* To do:
@@ -790,6 +794,12 @@ write_profile_recent(void)
fprintf(rf, "# Each pair of strings consists of a column format and its pixel width.\n");
packet_list_recent_write_all(rf);
+ fprintf(rf, "\n# Open conversation dialog tabs.\n");
+ fprintf(rf, "# List of conversation names, e.g. \"TCP\", \"IPv6\".\n");
+ string_list = join_string_list(recent.conversation_tabs);
+ fprintf(rf, RECENT_GUI_CONVERSATION_TABS ": %s\n", string_list);
+ g_free(string_list);
+
if (get_last_open_dir() != NULL) {
fprintf(rf, "\n# Last directory navigated to in File Open dialog.\n");
@@ -1024,8 +1034,9 @@ read_set_recent_pair_static(gchar *key, const gchar *value,
return PREFS_SET_SYNTAX_ERR; /* number must be positive */
recent.gui_geometry_main_lower_pane = (gint)num;
recent.has_gui_geometry_main_lower_pane = TRUE;
- }
- else if (strcmp(key, RECENT_KEY_COL_WIDTH) == 0) {
+ } else if (strcmp(key, RECENT_GUI_CONVERSATION_TABS) == 0) {
+ recent.conversation_tabs = prefs_get_string_list(value);
+ } else if (strcmp(key, RECENT_KEY_COL_WIDTH) == 0) {
col_l = prefs_get_string_list(value);
if (col_l == NULL)
return PREFS_SET_SYNTAX_ERR;
diff --git a/ui/recent.h b/ui/recent.h
index 4e77b14c19..70707d5fd2 100644
--- a/ui/recent.h
+++ b/ui/recent.h
@@ -98,6 +98,7 @@ typedef struct recent_settings_tag {
gboolean privs_warn_if_elevated;
gboolean privs_warn_if_no_npf;
GList *col_width_list; /* column widths */
+ GList *conversation_tabs; /* enabled conversation dialog tabs */
gchar *gui_fileopen_remembered_dir; /* folder of last capture loaded in File Open dialog */
} recent_settings_t;
diff --git a/ui/gtk/sat.h b/ui/sat.h
index 032604b11a..c6febc7284 100644
--- a/ui/gtk/sat.h
+++ b/ui/sat.h
@@ -21,8 +21,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-#ifndef __GTK_SAT_H__
-#define __GTK_SAT_H__
+#ifndef __SAT_H__
+#define __SAT_H__
/** @file
* Sub-address type definitions.
@@ -38,4 +38,4 @@ typedef enum {
SAT_JXTA /**< URI : JXTA */
} SAT_E;
-#endif /* __GTK_SAT_H__ */
+#endif /* __SAT_H__ */
diff --git a/wsutil/str_util.c b/wsutil/str_util.c
index 898ae63171..696e861ccb 100644
--- a/wsutil/str_util.c
+++ b/wsutil/str_util.c
@@ -145,7 +145,7 @@ gchar *format_size(gint64 size, format_size_flags_e flags) {
} else if (size / power >= 10) {
g_string_printf(human_str, "%" GROUP_FLAG G_GINT64_MODIFIER "d %s", size / power, prefix[pfx_off+3]);
} else {
- g_string_printf(human_str, "%" GROUP_FLAG G_GINT64_MODIFIER "d ", size);
+ g_string_printf(human_str, "%" GROUP_FLAG G_GINT64_MODIFIER "d", size);
is_small = TRUE;
}
@@ -170,5 +170,5 @@ gchar *format_size(gint64 size, format_size_flags_e flags) {
ret_val = human_str->str;
g_string_free(human_str, FALSE);
- return ret_val;
+ return g_strchomp(ret_val);
}