summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordameiss <netshark@ameissnet.com>2014-06-19 18:08:39 -0400
committerEvan Huus <eapache@gmail.com>2014-06-20 06:32:02 +0000
commitb1da5099dbb7b94f362bcc3e2b6e057b6763df71 (patch)
tree777150c1e62f1a8b1ef2cd5ee44a30d0ae1e4b51
parent224ab2d9c1633869fc01b378ede3f1a70dc546ab (diff)
downloadwireshark-b1da5099dbb7b94f362bcc3e2b6e057b6763df71.tar.gz
Add GTK modules for existing LBM dissectors.
Mainly cherry-picked from commit 46a808acf4e8c87b61169bfac00799857b38f1f0, but there were a few minor issues that were merged into this single commit. bug: 10204 Change-Id: Ie21cc07b0ac9a56648ec72062ce58a1ac800318e Reviewed-on: https://code.wireshark.org/review/2427 Reviewed-by: Michael Mann <mmann78@netscape.net> Reviewed-by: Evan Huus <eapache@gmail.com>
-rw-r--r--ui/gtk/CMakeLists.txt2
-rw-r--r--ui/gtk/Makefile.common4
-rw-r--r--ui/gtk/lbm_stream_dlg.c777
-rw-r--r--ui/gtk/lbm_stream_dlg.h46
-rw-r--r--ui/gtk/lbm_uimflow_dlg.c457
-rw-r--r--ui/gtk/lbm_uimflow_dlg.h46
-rw-r--r--ui/gtk/main_menubar.c41
7 files changed, 1373 insertions, 0 deletions
diff --git a/ui/gtk/CMakeLists.txt b/ui/gtk/CMakeLists.txt
index 48fc8e4100..53e6e093f4 100644
--- a/ui/gtk/CMakeLists.txt
+++ b/ui/gtk/CMakeLists.txt
@@ -174,6 +174,8 @@ set(WIRESHARK_TAP_SRC
hostlist_wlan.c
iax2_analysis.c
io_stat.c
+ lbm_stream_dlg.c
+ lbm_uimflow_dlg.c
ldap_stat.c
mac_lte_stat_dlg.c
mcast_stream_dlg.c
diff --git a/ui/gtk/Makefile.common b/ui/gtk/Makefile.common
index 3c08706251..aa3d9e4236 100644
--- a/ui/gtk/Makefile.common
+++ b/ui/gtk/Makefile.common
@@ -199,6 +199,8 @@ WIRESHARK_TAP_SRC = \
hostlist_wlan.c \
iax2_analysis.c \
io_stat.c \
+ lbm_stream_dlg.c \
+ lbm_uimflow_dlg.c \
ldap_stat.c \
mac_lte_stat_dlg.c \
mcast_stream_dlg.c \
@@ -284,6 +286,8 @@ noinst_HEADERS = \
iax2_analysis.h \
keys.h \
layouts.h \
+ lbm_stream_dlg.h \
+ lbm_uimflow_dlg.h \
macros_dlg.h \
main.h \
main_airpcap_toolbar.h \
diff --git a/ui/gtk/lbm_stream_dlg.c b/ui/gtk/lbm_stream_dlg.c
new file mode 100644
index 0000000000..d21d9e11a8
--- /dev/null
+++ b/ui/gtk/lbm_stream_dlg.c
@@ -0,0 +1,777 @@
+/* lbm_stream_dlg.c
+ * Routines for LBMC stream dialog
+ *
+ * Copyright (c) 2005-2014 Informatica Corporation. All Rights Reserved.
+ *
+ * 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/to_str.h>
+#include <stat_menu.h>
+#include <epan/funnel.h>
+#include <epan/packet.h>
+#include <epan/tap.h>
+#include <epan/wmem/wmem.h>
+#include <gtk/gtk.h>
+#include <ui/gtk/gui_utils.h>
+#include <ui/gtk/dlg_utils.h>
+#include <cfile.h>
+#include <globals.h>
+#include <epan/dissectors/packet-lbm.h>
+#include "lbm_stream_dlg.h"
+
+/* Stream structures. */
+typedef struct
+{
+ guint64 channel;
+ gchar * endpoint_a;
+ gchar * endpoint_b;
+ guint32 first_frame;
+ guint32 last_frame;
+ guint32 messages;
+ guint32 bytes;
+ GtkTreeIter iter;
+ GSequence * substreams;
+} lbmc_stream_dlg_stream_entry_t;
+
+typedef struct
+{
+ guint32 substream_id;
+ gchar * endpoint_a;
+ gchar * endpoint_b;
+ guint32 first_frame;
+ guint32 last_frame;
+ guint32 messages;
+ guint32 bytes;
+ GtkTreeIter iter;
+ lbmc_stream_dlg_stream_entry_t * parent;
+} lbmc_stream_dlg_substream_entry_t;
+
+/* Tree definitions. */
+#define LBMC_STREAM_DLG_STORE_STREAM_DISPLAY_COLUMN 0
+#define LBMC_STREAM_DLG_STORE_ENDPOINTA_COLUMN 1
+#define LBMC_STREAM_DLG_STORE_ENDPOINTB_COLUMN 2
+#define LBMC_STREAM_DLG_STORE_MESSAGES_COLUMN 3
+#define LBMC_STREAM_DLG_STORE_BYTES_COLUMN 4
+#define LBMC_STREAM_DLG_STORE_FIRST_FRAME_COLUMN 5
+#define LBMC_STREAM_DLG_STORE_LAST_FRAME_COLUMN 6
+#define LBMC_STREAM_DLG_STORE_CHANNEL_COLUMN 7
+#define LBMC_STREAM_DLG_STORE_SUBSTREAM_COLUMN 8
+
+static const gchar * global_stream_view_data = "stream-view";
+
+typedef struct
+{
+ GtkWidget * dialog;
+ GtkTreeModel * model;
+ GSequence * stream_table;
+} lbmc_stream_dlg_info_t;
+
+static lbmc_stream_dlg_info_t * global_stream_dialog_info = NULL;
+
+static gchar * lbmc_stream_dlg_format_endpoint_ep(const lbm_uim_stream_endpoint_t * endpoint)
+{
+ gchar * buf = NULL;
+
+ if (endpoint->type == lbm_uim_instance_stream)
+ {
+ buf = bytes_to_ep_str(endpoint->stream_info.ctxinst.ctxinst, sizeof(endpoint->stream_info.ctxinst.ctxinst));
+ }
+ else
+ {
+ buf = wmem_strdup_printf(wmem_packet_scope(),
+ "%" G_GUINT32_FORMAT ":%s:%" G_GUINT16_FORMAT,
+ endpoint->stream_info.dest.domain,
+ address_to_str(wmem_packet_scope(), &(endpoint->stream_info.dest.addr)),
+ endpoint->stream_info.dest.port);
+ }
+ return (buf);
+}
+
+/**************************************************************/
+/* Common functions. */
+/**************************************************************/
+static void lbmc_stream_dlg_stream_entry_destroy_cb(gpointer data)
+{
+ lbmc_stream_dlg_stream_entry_t * stream = (lbmc_stream_dlg_stream_entry_t *)data;
+
+ if (stream->substreams != NULL)
+ {
+ g_sequence_free(stream->substreams);
+ stream->substreams = NULL;
+ }
+ g_free(data);
+}
+
+static void lbmc_stream_dlg_substream_entry_destroy_cb(gpointer data)
+{
+ g_free(data);
+}
+
+static void lbmc_stream_dlg_reset_stream_table(lbmc_stream_dlg_info_t * info)
+{
+ if (info->stream_table != NULL)
+ {
+ g_sequence_free(info->stream_table);
+ info->stream_table = NULL;
+ }
+ info->stream_table = g_sequence_new(lbmc_stream_dlg_stream_entry_destroy_cb);
+}
+
+static void lbmc_stream_dlg_window_destroy_event_cb(GtkWindow * window _U_, gpointer user_data)
+{
+ lbmc_stream_dlg_info_t * info = (lbmc_stream_dlg_info_t *)user_data;
+
+ remove_tap_listener(info);
+ if (info->stream_table != NULL)
+ {
+ g_sequence_free(info->stream_table);
+ info->stream_table = NULL;
+ }
+ global_stream_dialog_info = NULL;
+ g_free(info);
+}
+
+static GtkTreeModel * lbmc_stream_dlg_create_model(void)
+{
+ GtkTreeStore * store = NULL;
+
+ store = gtk_tree_store_new(9, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_UINT, G_TYPE_UINT, G_TYPE_UINT, G_TYPE_UINT, G_TYPE_UINT64, G_TYPE_UINT);
+ return (GTK_TREE_MODEL(store));
+}
+
+static void lbmc_stream_dlg_stream_cell_data_function(GtkTreeViewColumn * column _U_, GtkCellRenderer * renderer, GtkTreeModel * model, GtkTreeIter * iter, gpointer user_data _U_)
+{
+ char stream_buf[64];
+ guint64 channel;
+ guint substream_id;
+
+ gtk_tree_model_get(model, iter,
+ LBMC_STREAM_DLG_STORE_CHANNEL_COLUMN, &channel,
+ LBMC_STREAM_DLG_STORE_SUBSTREAM_COLUMN, &substream_id,
+ -1);
+ if (substream_id == 0)
+ {
+ g_snprintf(stream_buf, (gulong)sizeof(stream_buf), "%" G_GUINT64_FORMAT, channel);
+ /* Left-align */
+ g_object_set(renderer, "xalign", 0.0, NULL);
+ }
+ else
+ {
+ g_snprintf(stream_buf, (gulong)sizeof(stream_buf), "%" G_GUINT64_FORMAT ".%u", channel, substream_id);
+ /* Right-align */
+ g_object_set(renderer, "xalign", 1.0, NULL);
+ }
+ g_object_set(renderer, "text", stream_buf, NULL);
+}
+
+static void lbmc_stream_dlg_string_cell_data_function(GtkTreeViewColumn * column _U_, GtkCellRenderer * renderer, GtkTreeModel * model, GtkTreeIter * iter, gpointer user_data)
+{
+ gchar * value = NULL;
+ gint data_column;
+
+ data_column = GPOINTER_TO_INT(user_data);
+ gtk_tree_model_get(model, iter, data_column, &value, -1);
+ g_object_set(renderer, "text", value, NULL);
+ /* Left-align */
+ g_object_set(renderer, "xalign", 0.0, NULL);
+}
+
+static void lbmc_stream_dlg_guint_cell_data_function(GtkTreeViewColumn * column _U_, GtkCellRenderer * renderer, GtkTreeModel * model, GtkTreeIter * iter, gpointer user_data)
+{
+ guint uint_value;
+ gint data_column;
+ char value[64];
+
+ data_column = GPOINTER_TO_INT(user_data);
+ gtk_tree_model_get(model, iter, data_column, &uint_value, -1);
+ g_snprintf(value, (gulong)sizeof(value), "%u", uint_value);
+ g_object_set(renderer, "text", value, NULL);
+ /* Right-align */
+ g_object_set(renderer, "xalign", 1.0, NULL);
+}
+
+static gint lbmc_stream_dlg_guint_sort_func(GtkTreeModel * model, GtkTreeIter * a, GtkTreeIter * b, gpointer user_data)
+{
+ guint32 val_a;
+ guint32 val_b;
+ gint data_column;
+
+ data_column = GPOINTER_TO_INT(user_data);
+ gtk_tree_model_get(model, a, data_column, &val_a, -1);
+ gtk_tree_model_get(model, b, data_column, &val_b, -1);
+ if (val_a == val_b)
+ {
+ return (0);
+ }
+ else if (val_a < val_b)
+ {
+ return (-1);
+ }
+ else
+ {
+ return (1);
+ }
+}
+
+static gint lbmc_stream_dlg_stream_sort_func(GtkTreeModel * model, GtkTreeIter * a, GtkTreeIter * b, gpointer user_data _U_)
+{
+ guint stream_a;
+ guint substream_a;
+ guint stream_b;
+ guint substream_b;
+
+ gtk_tree_model_get(model, a,
+ LBMC_STREAM_DLG_STORE_CHANNEL_COLUMN, &stream_a,
+ LBMC_STREAM_DLG_STORE_SUBSTREAM_COLUMN, &substream_a,
+ -1);
+ gtk_tree_model_get(model, b,
+ LBMC_STREAM_DLG_STORE_CHANNEL_COLUMN, &stream_b,
+ LBMC_STREAM_DLG_STORE_SUBSTREAM_COLUMN, &substream_b,
+ -1);
+ if (stream_a == stream_b)
+ {
+ if (substream_a == substream_b)
+ {
+ return (0);
+ }
+ else if (substream_a < substream_b)
+ {
+ return (-1);
+ }
+ else
+ {
+ return (1);
+ }
+ }
+ else if (stream_a < stream_b)
+ {
+ return (-1);
+ }
+ else
+ {
+ return (1);
+ }
+}
+
+static gint lbmc_stream_dlg_string_sort_func(GtkTreeModel * model, GtkTreeIter * a, GtkTreeIter * b, gpointer user_data)
+{
+ const gchar * str_a = NULL;
+ const gchar * str_b = NULL;
+ gint ret = 0;
+
+ /* The col to get data from is in user_data */
+ gint data_column = GPOINTER_TO_INT(user_data);
+
+ gtk_tree_model_get(model, a, data_column, &str_a, -1);
+ gtk_tree_model_get(model, b, data_column, &str_b, -1);
+
+ if (str_a == str_b)
+ {
+ /* it's worth testing because a lot of rows point to the same data */
+ return 0;
+ }
+ else if (str_a == NULL || str_b == NULL)
+ {
+ ret = (str_a == NULL) ? -1 : 1;
+ }
+ else
+ {
+ ret = g_ascii_strcasecmp(str_a, str_b);
+ }
+ return (ret);
+}
+
+static GtkWidget * lbmc_stream_dlg_create_view_and_model(lbmc_stream_dlg_info_t * info)
+{
+ GtkWidget * view = NULL;
+ GtkTreeViewColumn * column;
+ GtkCellRenderer * renderer;
+ GtkTreeSortable * sortable;
+
+ info->model = lbmc_stream_dlg_create_model();
+ view = gtk_tree_view_new();
+ sortable = GTK_TREE_SORTABLE(GTK_TREE_STORE(info->model));
+#if GTK_CHECK_VERSION(2,6,0)
+ gtk_tree_view_set_fixed_height_mode(GTK_TREE_VIEW(view), TRUE);
+#endif
+ gtk_tree_view_set_headers_clickable(GTK_TREE_VIEW(view), FALSE);
+
+ /* Column 1 - Stream */
+ renderer = gtk_cell_renderer_text_new();
+ g_object_set(renderer, "ypad", 0, NULL);
+ column = gtk_tree_view_column_new_with_attributes("Stream", renderer, NULL);
+ gtk_tree_view_column_set_sort_column_id(column, LBMC_STREAM_DLG_STORE_STREAM_DISPLAY_COLUMN);
+ gtk_tree_view_column_set_resizable(column, TRUE);
+ gtk_tree_view_column_set_cell_data_func(column, renderer, lbmc_stream_dlg_stream_cell_data_function, GINT_TO_POINTER(LBMC_STREAM_DLG_STORE_STREAM_DISPLAY_COLUMN), NULL);
+ gtk_tree_sortable_set_sort_func(sortable, LBMC_STREAM_DLG_STORE_STREAM_DISPLAY_COLUMN, lbmc_stream_dlg_stream_sort_func, GINT_TO_POINTER(LBMC_STREAM_DLG_STORE_STREAM_DISPLAY_COLUMN), NULL);
+ gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
+ gtk_tree_view_column_set_min_width(column, 80);
+ gtk_tree_view_append_column(GTK_TREE_VIEW(view), column);
+
+ /* Column 2 - EndpointA */
+ renderer = gtk_cell_renderer_text_new();
+ g_object_set(renderer, "ypad", 0, NULL);
+ column = gtk_tree_view_column_new_with_attributes("Endpoint A", renderer, NULL);
+ gtk_tree_view_column_set_sort_column_id(column, LBMC_STREAM_DLG_STORE_ENDPOINTA_COLUMN);
+ gtk_tree_view_column_set_resizable(column, TRUE);
+ gtk_tree_view_column_set_cell_data_func(column, renderer, lbmc_stream_dlg_string_cell_data_function, GINT_TO_POINTER(LBMC_STREAM_DLG_STORE_ENDPOINTA_COLUMN), NULL);
+ gtk_tree_sortable_set_sort_func(sortable, LBMC_STREAM_DLG_STORE_ENDPOINTA_COLUMN, lbmc_stream_dlg_string_sort_func, GINT_TO_POINTER(LBMC_STREAM_DLG_STORE_ENDPOINTA_COLUMN), NULL);
+ gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
+ gtk_tree_view_column_set_min_width(column, 140);
+ gtk_tree_view_append_column(GTK_TREE_VIEW(view), column);
+
+ /* Column 3 - EndpointB */
+ renderer = gtk_cell_renderer_text_new();
+ g_object_set(renderer, "ypad", 0, NULL);
+ column = gtk_tree_view_column_new_with_attributes("Endpoint B", renderer, NULL);
+ gtk_tree_view_column_set_sort_column_id(column, LBMC_STREAM_DLG_STORE_ENDPOINTB_COLUMN);
+ gtk_tree_view_column_set_resizable(column, TRUE);
+ gtk_tree_view_column_set_cell_data_func(column, renderer, lbmc_stream_dlg_string_cell_data_function, GINT_TO_POINTER(LBMC_STREAM_DLG_STORE_ENDPOINTB_COLUMN), NULL);
+ gtk_tree_sortable_set_sort_func(sortable, LBMC_STREAM_DLG_STORE_ENDPOINTB_COLUMN, lbmc_stream_dlg_string_sort_func, GINT_TO_POINTER(LBMC_STREAM_DLG_STORE_ENDPOINTB_COLUMN), NULL);
+ gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
+ gtk_tree_view_column_set_min_width(column, 140);
+ gtk_tree_view_append_column(GTK_TREE_VIEW(view), column);
+
+ /* Column 4 - Messages */
+ renderer = gtk_cell_renderer_text_new();
+ g_object_set(renderer, "ypad", 0, NULL);
+ column = gtk_tree_view_column_new_with_attributes("Messages", renderer, NULL);
+ gtk_tree_view_column_set_sort_column_id(column, LBMC_STREAM_DLG_STORE_MESSAGES_COLUMN);
+ gtk_tree_view_column_set_resizable(column, TRUE);
+ gtk_tree_view_column_set_cell_data_func(column, renderer, lbmc_stream_dlg_guint_cell_data_function, GINT_TO_POINTER(LBMC_STREAM_DLG_STORE_MESSAGES_COLUMN), NULL);
+ gtk_tree_sortable_set_sort_func(sortable, LBMC_STREAM_DLG_STORE_MESSAGES_COLUMN, lbmc_stream_dlg_guint_sort_func, GINT_TO_POINTER(LBMC_STREAM_DLG_STORE_MESSAGES_COLUMN), NULL);
+ gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
+ gtk_tree_view_column_set_min_width(column, 100);
+ gtk_tree_view_append_column(GTK_TREE_VIEW(view), column);
+
+ /* Column 5 - Bytes */
+ renderer = gtk_cell_renderer_text_new();
+ g_object_set(renderer, "ypad", 0, NULL);
+ column = gtk_tree_view_column_new_with_attributes("Bytes", renderer, NULL);
+ gtk_tree_view_column_set_sort_column_id(column, LBMC_STREAM_DLG_STORE_BYTES_COLUMN);
+ gtk_tree_view_column_set_resizable(column, TRUE);
+ gtk_tree_view_column_set_cell_data_func(column, renderer, lbmc_stream_dlg_guint_cell_data_function, GINT_TO_POINTER(LBMC_STREAM_DLG_STORE_BYTES_COLUMN), NULL);
+ gtk_tree_sortable_set_sort_func(sortable, LBMC_STREAM_DLG_STORE_BYTES_COLUMN, lbmc_stream_dlg_guint_sort_func, GINT_TO_POINTER(LBMC_STREAM_DLG_STORE_BYTES_COLUMN), NULL);
+ gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
+ gtk_tree_view_column_set_min_width(column, 80);
+ gtk_tree_view_append_column(GTK_TREE_VIEW(view), column);
+
+ /* Column 6 - First frame */
+ renderer = gtk_cell_renderer_text_new();
+ g_object_set(renderer, "ypad", 0, NULL);
+ column = gtk_tree_view_column_new_with_attributes("First frame", renderer, NULL);
+ gtk_tree_view_column_set_sort_column_id(column, LBMC_STREAM_DLG_STORE_FIRST_FRAME_COLUMN);
+ gtk_tree_view_column_set_resizable(column, TRUE);
+ gtk_tree_view_column_set_cell_data_func(column, renderer, lbmc_stream_dlg_guint_cell_data_function, GINT_TO_POINTER(LBMC_STREAM_DLG_STORE_FIRST_FRAME_COLUMN), NULL);
+ gtk_tree_sortable_set_sort_func(sortable, LBMC_STREAM_DLG_STORE_FIRST_FRAME_COLUMN, lbmc_stream_dlg_guint_sort_func, GINT_TO_POINTER(LBMC_STREAM_DLG_STORE_FIRST_FRAME_COLUMN), NULL);
+ gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
+ gtk_tree_view_column_set_min_width(column, 100);
+ gtk_tree_view_append_column(GTK_TREE_VIEW(view), column);
+
+ /* Column 6 - Last frame */
+ renderer = gtk_cell_renderer_text_new();
+ g_object_set(renderer, "ypad", 0, NULL);
+ column = gtk_tree_view_column_new_with_attributes("Last frame", renderer, NULL);
+ gtk_tree_view_column_set_sort_column_id(column, LBMC_STREAM_DLG_STORE_LAST_FRAME_COLUMN);
+ gtk_tree_view_column_set_resizable(column, TRUE);
+ gtk_tree_view_column_set_cell_data_func(column, renderer, lbmc_stream_dlg_guint_cell_data_function, GINT_TO_POINTER(LBMC_STREAM_DLG_STORE_LAST_FRAME_COLUMN), NULL);
+ gtk_tree_sortable_set_sort_func(sortable, LBMC_STREAM_DLG_STORE_FIRST_FRAME_COLUMN, lbmc_stream_dlg_guint_sort_func, GINT_TO_POINTER(LBMC_STREAM_DLG_STORE_LAST_FRAME_COLUMN), NULL);
+ gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
+ gtk_tree_view_column_set_min_width(column, 100);
+ gtk_tree_view_append_column(GTK_TREE_VIEW(view), column);
+
+ gtk_tree_view_set_model(GTK_TREE_VIEW(view), info->model);
+ g_object_unref(info->model);
+ return (view);
+}
+
+static lbmc_stream_dlg_info_t * lbmc_stream_dlg_window_create(void)
+{
+ GtkWidget * vbox = NULL;
+ GtkWidget * view = NULL;
+ GtkWidget * button_row = NULL;
+ GtkWidget * close_button = NULL;
+ GtkWidget * scrolled_window = NULL;
+ lbmc_stream_dlg_info_t * info = NULL;
+
+ /* Setup the info structure. */
+ info = (lbmc_stream_dlg_info_t *)g_malloc(sizeof(lbmc_stream_dlg_info_t));
+ info->dialog = NULL;
+ info->model = NULL;
+ info->stream_table = NULL;
+ lbmc_stream_dlg_reset_stream_table(info);
+
+ /* Create the main window */
+ info->dialog = dlg_window_new("29West LBMC Streams");
+ g_signal_connect(info->dialog, "delete_event", G_CALLBACK(window_delete_event_cb), NULL);
+ g_signal_connect(info->dialog, "destroy", G_CALLBACK(lbmc_stream_dlg_window_destroy_event_cb), (gpointer)info);
+ gtk_window_set_default_size(GTK_WINDOW(info->dialog), 800, 400);
+
+ /* Build the vbox (to contain the tree view and buttons) */
+ vbox = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 3, FALSE);
+ gtk_container_add(GTK_CONTAINER(info->dialog), vbox);
+ gtk_container_set_border_width(GTK_CONTAINER(vbox), 12);
+
+ /* Build the tree view */
+ view = lbmc_stream_dlg_create_view_and_model(info);
+ g_object_set_data((GObject *)info->dialog, global_stream_view_data, (gpointer)view);
+
+ /* Build a scrolling container for the tree view */
+ scrolled_window = scrolled_window_new(NULL, NULL);
+ gtk_container_add(GTK_CONTAINER(scrolled_window), view);
+
+ /* Add the scrolling container to the vbox */
+ gtk_box_pack_start(GTK_BOX(vbox), scrolled_window, TRUE, TRUE, 0);
+
+ /* Build the button row */
+ button_row = dlg_button_row_new(GTK_STOCK_CLOSE, NULL);
+
+ /* Add the button row to the vbox */
+ gtk_box_pack_end(GTK_BOX(vbox), button_row, FALSE, FALSE, 0);
+
+ /* Connect to the close button */
+ close_button = (GtkWidget *)g_object_get_data(G_OBJECT(button_row), GTK_STOCK_CLOSE);
+ window_set_cancel_button(info->dialog, close_button, window_cancel_button_cb);
+ gtk_widget_show_all(info->dialog);
+ return (info);
+}
+
+/**************************************************************/
+/* Tap callbacks. */
+/**************************************************************/
+static void lbmc_stream_dlg_tap_reset(void * tap_data)
+{
+ lbmc_stream_dlg_info_t * info = (lbmc_stream_dlg_info_t *)tap_data;
+
+ gtk_tree_store_clear(GTK_TREE_STORE(info->model));
+ lbmc_stream_dlg_reset_stream_table(info);
+}
+
+static gint lbmc_stream_dlg_stream_compare_cb(gconstpointer lhs, gconstpointer rhs, gpointer user_data _U_)
+{
+ const lbmc_stream_dlg_stream_entry_t * stream1 = (const lbmc_stream_dlg_stream_entry_t *)lhs;
+ const lbmc_stream_dlg_stream_entry_t * stream2 = (const lbmc_stream_dlg_stream_entry_t *)rhs;
+
+ if (stream1->channel == stream2->channel)
+ {
+ return (0);
+ }
+ else if (stream1->channel < stream2->channel)
+ {
+ return (-1);
+ }
+ return (1);
+}
+
+static gint lbmc_stream_dlg_substream_compare_cb(gconstpointer lhs, gconstpointer rhs, gpointer user_data _U_)
+{
+ const lbmc_stream_dlg_substream_entry_t * substream1 = (const lbmc_stream_dlg_substream_entry_t *)lhs;
+ const lbmc_stream_dlg_substream_entry_t * substream2 = (const lbmc_stream_dlg_substream_entry_t *)rhs;
+
+ if (substream1->substream_id == substream2->substream_id)
+ {
+ return (0);
+ }
+ else if (substream1->substream_id < substream2->substream_id)
+ {
+ return (-1);
+ }
+ return (1);
+}
+
+static gboolean lbmc_stream_dlg_tap_packet(void * tap_data, packet_info * pinfo, epan_dissect_t * edt _U_, const void * stream_info)
+{
+ const lbm_uim_stream_tap_info_t * tapinfo = (const lbm_uim_stream_tap_info_t *)stream_info;
+ lbmc_stream_dlg_info_t * info = (lbmc_stream_dlg_info_t *)tap_data;
+ GtkTreeIter stream_iter;
+ GtkTreeIter stream_insert_before_iter;
+ lbmc_stream_dlg_stream_entry_t * stream = NULL;
+ GSequenceIter * stream_entry_it;
+ lbmc_stream_dlg_stream_entry_t stream_key;
+ gboolean add_stream = FALSE;
+ gboolean add_stream_before = FALSE;
+ GtkTreeIter substream_iter;
+ GtkTreeIter substream_insert_before_iter;
+ lbmc_stream_dlg_substream_entry_t * substream = NULL;
+ GSequenceIter * substream_entry_it;
+ lbmc_stream_dlg_substream_entry_t substream_key;
+ gboolean add_substream = FALSE;
+ gboolean add_substream_before = FALSE;
+ GtkTreePath * stream_path = NULL;
+ GtkTreePath * substream_path = NULL;
+
+ memset((void *)&stream_key, 0, sizeof(lbmc_stream_dlg_stream_entry_t));
+ stream_key.channel = tapinfo->channel;
+ stream_entry_it = g_sequence_search(info->stream_table, (gpointer)&stream_key, lbmc_stream_dlg_stream_compare_cb, NULL);
+ /* If the node exists, g_sequence_search() will return an iterator giving the NEXT node. */
+ if (g_sequence_iter_is_begin(stream_entry_it))
+ {
+ /*
+ The iterator marks the beginning of the sequence, so the node doesn't exist
+ and the previous node doesn't exist.
+ */
+ add_stream = TRUE;
+ if (g_sequence_iter_is_end(stream_entry_it))
+ {
+ /* Iterator is both beginning and end, so the list is empty - just append it. */
+ }
+ else
+ {
+ /* Not the end, so we'll insert before the next stream. */
+ stream = (lbmc_stream_dlg_stream_entry_t *)g_sequence_get(stream_entry_it);
+ add_stream_before = TRUE;
+ stream_insert_before_iter = stream->iter;
+ }
+ }
+ else
+ {
+ GSequenceIter * save_stream_entry_it = stream_entry_it;
+
+ stream_entry_it = g_sequence_iter_prev(stream_entry_it);
+ stream = (lbmc_stream_dlg_stream_entry_t *)g_sequence_get(stream_entry_it);
+ if (stream->channel != tapinfo->channel)
+ {
+ /* Not the one we were looking for. */
+ add_stream = TRUE;
+ if (g_sequence_iter_is_end(save_stream_entry_it))
+ {
+ /* Insert after -> append */
+ }
+ else
+ {
+ /* Insert before */
+ stream = (lbmc_stream_dlg_stream_entry_t *)g_sequence_get(stream_entry_it);
+ add_stream_before = TRUE;
+ stream_insert_before_iter = stream->iter;
+ }
+ }
+ }
+
+ if (add_stream)
+ {
+ char valbuf[256];
+
+ stream = (lbmc_stream_dlg_stream_entry_t *)g_malloc(sizeof(lbmc_stream_dlg_stream_entry_t));
+ stream->channel = tapinfo->channel;
+ stream->endpoint_a = wmem_strdup(wmem_file_scope(), lbmc_stream_dlg_format_endpoint_ep(&(tapinfo->endpoint_a)));
+ stream->endpoint_b = wmem_strdup(wmem_file_scope(), lbmc_stream_dlg_format_endpoint_ep(&(tapinfo->endpoint_b)));
+ stream->first_frame = (guint32)(~0);
+ stream->last_frame = 0;
+ stream->messages = 0;
+ stream->bytes = 0;
+ stream->substreams = g_sequence_new(lbmc_stream_dlg_substream_entry_destroy_cb);
+ (void) g_sequence_insert_sorted(info->stream_table, (void *)stream, lbmc_stream_dlg_stream_compare_cb, NULL);
+ if (add_stream_before)
+ {
+ gtk_tree_store_insert_before(GTK_TREE_STORE(info->model), &stream_iter, NULL, &stream_insert_before_iter);
+ }
+ else
+ {
+ gtk_tree_store_append(GTK_TREE_STORE(info->model), &stream_iter, NULL);
+ }
+ stream->iter = stream_iter;
+ g_snprintf(valbuf, (gulong)sizeof(valbuf), "%" G_GUINT64_FORMAT, stream->channel);
+ gtk_tree_store_set(GTK_TREE_STORE(info->model), &(stream->iter),
+ LBMC_STREAM_DLG_STORE_STREAM_DISPLAY_COLUMN, valbuf,
+ LBMC_STREAM_DLG_STORE_ENDPOINTA_COLUMN, stream->endpoint_a,
+ LBMC_STREAM_DLG_STORE_ENDPOINTB_COLUMN, stream->endpoint_b,
+ LBMC_STREAM_DLG_STORE_MESSAGES_COLUMN, (guint)0,
+ LBMC_STREAM_DLG_STORE_BYTES_COLUMN, (guint)0,
+ LBMC_STREAM_DLG_STORE_FIRST_FRAME_COLUMN, (guint)0,
+ LBMC_STREAM_DLG_STORE_LAST_FRAME_COLUMN, (guint)0,
+ LBMC_STREAM_DLG_STORE_CHANNEL_COLUMN, (guint)stream->channel,
+ LBMC_STREAM_DLG_STORE_SUBSTREAM_COLUMN, (guint)0,
+ -1);
+ }
+ stream_iter = stream->iter;
+ if (stream->first_frame > pinfo->fd->num)
+ {
+ stream->first_frame = pinfo->fd->num;
+ }
+ if (stream->last_frame < pinfo->fd->num)
+ {
+ stream->last_frame = pinfo->fd->num;
+ }
+ stream->bytes += tapinfo->bytes;
+ stream->messages++;
+ gtk_tree_store_set(GTK_TREE_STORE(info->model), &stream_iter,
+ LBMC_STREAM_DLG_STORE_MESSAGES_COLUMN, (guint)stream->messages,
+ LBMC_STREAM_DLG_STORE_BYTES_COLUMN, (guint)stream->bytes,
+ LBMC_STREAM_DLG_STORE_FIRST_FRAME_COLUMN, (guint)stream->first_frame,
+ LBMC_STREAM_DLG_STORE_LAST_FRAME_COLUMN, (guint)stream->last_frame,
+ -1);
+
+ memset((void *)&substream_key, 0, sizeof(lbmc_stream_dlg_substream_entry_t));
+ substream_key.substream_id = tapinfo->substream_id;
+ substream_entry_it = g_sequence_search(stream->substreams, (gpointer)&substream_key, lbmc_stream_dlg_substream_compare_cb, NULL);
+ /* If the node exists, g_sequence_search() will return an iterator giving the NEXT node. */
+ if (g_sequence_iter_is_begin(substream_entry_it))
+ {
+ /*
+ The iterator marks the beginning of the sequence, so the node doesn't exist
+ and the previous node doesn't exist.
+ */
+ add_substream = TRUE;
+ if (g_sequence_iter_is_end(substream_entry_it))
+ {
+ /* Iterator is both beginning and end, so the list is empty - just append it. */
+ }
+ else
+ {
+ /* Not the end, so we'll insert before the next stream. */
+ substream = (lbmc_stream_dlg_substream_entry_t *)g_sequence_get(substream_entry_it);
+ add_substream_before = TRUE;
+ substream_insert_before_iter = substream->iter;
+ }
+ }
+ else
+ {
+ GSequenceIter * save_substream_entry_it = substream_entry_it;
+
+ substream_entry_it = g_sequence_iter_prev(substream_entry_it);
+ substream = (lbmc_stream_dlg_substream_entry_t *)g_sequence_get(substream_entry_it);
+ if (substream->substream_id != tapinfo->substream_id)
+ {
+ /* Not the one we were looking for. */
+ add_substream = TRUE;
+ if (g_sequence_iter_is_end(save_substream_entry_it))
+ {
+ /* Insert after -> append */
+ }
+ else
+ {
+ /* Insert before */
+ substream = (lbmc_stream_dlg_substream_entry_t *)g_sequence_get(substream_entry_it);
+ add_substream_before = TRUE;
+ substream_insert_before_iter = substream->iter;
+ }
+ }
+ }
+ if (add_substream)
+ {
+ char valbuf[256];
+
+ substream = (lbmc_stream_dlg_substream_entry_t *)g_malloc(sizeof(lbmc_stream_dlg_substream_entry_t));
+ substream->substream_id = tapinfo->substream_id;
+ substream->endpoint_a = wmem_strdup_printf(wmem_file_scope(), "%s:%" G_GUINT16_FORMAT, address_to_str(wmem_packet_scope(), &(pinfo->src)), (guint16)pinfo->srcport);
+ substream->endpoint_b = wmem_strdup_printf(wmem_file_scope(), "%s:%" G_GUINT16_FORMAT, address_to_str(wmem_packet_scope(), &(pinfo->dst)), (guint16)pinfo->destport);
+ substream->first_frame = (guint32)(~0);
+ substream->last_frame = 0;
+ substream->messages = 0;
+ substream->bytes = 0;
+ substream->parent = stream;
+ (void) g_sequence_insert_sorted(stream->substreams, (void *)substream, lbmc_stream_dlg_substream_compare_cb, NULL);
+ if (add_substream_before)
+ {
+ gtk_tree_store_insert_before(GTK_TREE_STORE(info->model), &substream_iter, &stream_iter, &substream_insert_before_iter);
+ }
+ else
+ {
+ gtk_tree_store_append(GTK_TREE_STORE(info->model), &substream_iter, &stream_iter);
+ }
+ substream->iter = substream_iter;
+ g_snprintf(valbuf, (gulong)sizeof(valbuf), "%" G_GUINT64_FORMAT ":%" G_GUINT32_FORMAT, stream->channel, substream->substream_id);
+ gtk_tree_store_set(GTK_TREE_STORE(info->model), &(substream->iter),
+ LBMC_STREAM_DLG_STORE_STREAM_DISPLAY_COLUMN, valbuf,
+ LBMC_STREAM_DLG_STORE_ENDPOINTA_COLUMN, substream->endpoint_a,
+ LBMC_STREAM_DLG_STORE_ENDPOINTB_COLUMN, substream->endpoint_b,
+ LBMC_STREAM_DLG_STORE_MESSAGES_COLUMN, (guint)0,
+ LBMC_STREAM_DLG_STORE_BYTES_COLUMN, (guint)0,
+ LBMC_STREAM_DLG_STORE_FIRST_FRAME_COLUMN, (guint)0,
+ LBMC_STREAM_DLG_STORE_LAST_FRAME_COLUMN, (guint)0,
+ LBMC_STREAM_DLG_STORE_CHANNEL_COLUMN, (guint)stream->channel,
+ LBMC_STREAM_DLG_STORE_SUBSTREAM_COLUMN, (guint)substream->substream_id,
+ -1);
+ }
+ substream_iter = substream->iter;
+ if (substream->first_frame > pinfo->fd->num)
+ {
+ substream->first_frame = pinfo->fd->num;
+ }
+ if (substream->last_frame < pinfo->fd->num)
+ {
+ substream->last_frame = pinfo->fd->num;
+ }
+ substream->bytes += tapinfo->bytes;
+ substream->messages++;
+ gtk_tree_store_set(GTK_TREE_STORE(info->model), &substream_iter,
+ LBMC_STREAM_DLG_STORE_MESSAGES_COLUMN, (guint)substream->messages,
+ LBMC_STREAM_DLG_STORE_BYTES_COLUMN, (guint)substream->bytes,
+ LBMC_STREAM_DLG_STORE_FIRST_FRAME_COLUMN, (guint)substream->first_frame,
+ LBMC_STREAM_DLG_STORE_LAST_FRAME_COLUMN, (guint)substream->last_frame,
+ -1);
+ substream_path = gtk_tree_model_get_path(info->model, &(substream->iter));
+ gtk_tree_model_row_changed(info->model, substream_path, &(substream->iter));
+ gtk_tree_path_free(substream_path);
+ substream_path = NULL;
+ stream_path = gtk_tree_model_get_path(info->model, &(stream->iter));
+ gtk_tree_model_row_changed(info->model, stream_path, &(stream->iter));
+ gtk_tree_path_free(stream_path);
+ stream_path = NULL;
+ return (TRUE);
+}
+
+static void lbmc_stream_dlg_tap_draw(void * tap_data _U_)
+{
+ /* Nothing to do. */
+}
+
+/**************************************************************/
+/* Stream table functions. */
+/**************************************************************/
+void lbmc_stream_dlg_stream_menu_cb(gpointer arg _U_)
+{
+ GString * err_msg;
+
+ if (global_stream_dialog_info != NULL)
+ {
+ gtk_widget_show(global_stream_dialog_info->dialog);
+ return;
+ }
+ global_stream_dialog_info = lbmc_stream_dlg_window_create();
+ err_msg = register_tap_listener("lbm_stream",
+ (void *)global_stream_dialog_info,
+ NULL,
+ TL_REQUIRES_COLUMNS,
+ lbmc_stream_dlg_tap_reset,
+ lbmc_stream_dlg_tap_packet,
+ lbmc_stream_dlg_tap_draw);
+ if (err_msg != NULL)
+ {
+ fprintf(stderr, "register_tap_listener: %s\n", err_msg->str);
+ g_string_free(err_msg, TRUE);
+ }
+ cf_retap_packets(&cfile);
+}
+
+/*
+ * Editor modelines - http://www.wireshark.org/tools/modelines.html
+ *
+ * Local variables:
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * vi: set shiftwidth=4 tabstop=4 expandtab:
+ * :indentSize=4:tabSize=4:noTabs=true:
+ */
diff --git a/ui/gtk/lbm_stream_dlg.h b/ui/gtk/lbm_stream_dlg.h
new file mode 100644
index 0000000000..6d6cf543a3
--- /dev/null
+++ b/ui/gtk/lbm_stream_dlg.h
@@ -0,0 +1,46 @@
+/* lbm_stream_dlg.h
+ * Routines for LBMC stream dialog
+ *
+ * Copyright (c) 2005-2014 Informatica Corporation. All Rights Reserved.
+ *
+ * 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 LBM_STREAM_DLG_H_INCLUDED
+#define LBM_STREAM_DLG_H_INCLUDED
+
+#include "config.h"
+#include <glib.h>
+
+void lbmc_stream_dlg_stream_menu_cb(gpointer arg);
+
+#endif
+
+/*
+ * Editor modelines - http://www.wireshark.org/tools/modelines.html
+ *
+ * Local variables:
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * vi: set shiftwidth=4 tabstop=4 expandtab:
+ * :indentSize=4:tabSize=4:noTabs=true:
+ */
diff --git a/ui/gtk/lbm_uimflow_dlg.c b/ui/gtk/lbm_uimflow_dlg.c
new file mode 100644
index 0000000000..80430fa876
--- /dev/null
+++ b/ui/gtk/lbm_uimflow_dlg.c
@@ -0,0 +1,457 @@
+/* lbm_uimflow_dlg.c
+ * Routines for LBMC UIM flow graph
+ *
+ * Copyright (c) 2005-2014 Informatica Corporation. All Rights Reserved.
+ *
+ * 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/to_str.h>
+#include <stat_menu.h>
+#include <epan/funnel.h>
+#include <epan/packet.h>
+#include <epan/tap.h>
+#include <gtk/gtk.h>
+#include "ui/gtk/gui_utils.h"
+#include "ui/gtk/dlg_utils.h"
+#include <cfile.h>
+#include <globals.h>
+#include "ui/gtk/graph_analysis.h"
+#include <epan/dissectors/packet-lbm.h>
+#include "lbm_uimflow_dlg.h"
+
+typedef enum
+{
+ select_all_packets,
+ select_displayed_packets
+} lbmc_uim_flow_select_t;
+
+typedef struct
+{
+ gboolean have_tap_listener;
+ int tap_identifier;
+ seq_analysis_info_t * graph_analysis;
+ graph_analysis_data_t * graph_analysis_data;
+ GtkWidget * flow_graph_dialog;
+ lbmc_uim_flow_select_t packet_select_type;
+ GtkWidget * select_all_radio_button;
+ GtkWidget * select_displayed_radio_button;
+} lbm_uimflow_dialog_t;
+
+static lbm_uimflow_dialog_t dialog_data = { FALSE, -1, NULL, NULL, NULL, select_displayed_packets, NULL, NULL };
+
+static void lbmc_uim_flow_graph_data_init(void)
+{
+ dialog_data.graph_analysis = (seq_analysis_info_t *)g_malloc0(sizeof(seq_analysis_info_t));
+ dialog_data.graph_analysis->type = SEQ_ANALYSIS_ANY;
+ dialog_data.graph_analysis->all_packets = TRUE;
+ dialog_data.graph_analysis->any_addr = TRUE;
+ dialog_data.graph_analysis->nconv = 0;
+ dialog_data.graph_analysis->list = NULL;
+ dialog_data.graph_analysis->ht = NULL;
+ dialog_data.graph_analysis->num_nodes = 0;
+}
+
+static void lbmc_uim_flow_toggle_select_all_cb(GtkWidget * widget _U_, gpointer user_data _U_)
+{
+ /* is the button now active? */
+ if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog_data.select_all_radio_button)))
+ {
+ dialog_data.packet_select_type = select_all_packets;
+ }
+}
+
+static void lbmc_uim_flow_toggle_select_displayed_cb(GtkWidget * widget _U_, gpointer user_data _U_)
+{
+ /* is the button now active? */
+ if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog_data.select_displayed_radio_button)))
+ {
+ dialog_data.packet_select_type = select_displayed_packets;
+ }
+}
+
+static void lbmc_uim_flow_tap_reset(void * tap_data _U_)
+{
+ seq_analysis_item_t * graph_item;
+ GList * list;
+
+ if (dialog_data.graph_analysis != NULL)
+ {
+ /* free the graph data items */
+ list = g_list_first(dialog_data.graph_analysis->list);
+ while (list)
+ {
+ graph_item = (seq_analysis_item_t *)list->data;
+ g_free(graph_item->frame_label);
+ g_free(graph_item->time_str);
+ g_free(graph_item->comment);
+ g_free(list->data);
+ list = g_list_next(list);
+ }
+ g_list_free(dialog_data.graph_analysis->list);
+ dialog_data.graph_analysis->nconv = 0;
+ dialog_data.graph_analysis->list = NULL;
+ }
+}
+
+static int lbmc_uim_flow_graph_add_to_graph(packet_info * pinfo, const lbm_uim_stream_info_t * stream_info)
+{
+ lbm_uim_stream_endpoint_t epa;
+ lbm_uim_stream_endpoint_t epb;
+ seq_analysis_item_t * item;
+ gchar * ctxinst1 = NULL;
+ gchar * ctxinst2 = NULL;
+ gboolean swap_endpoints = FALSE;
+ int rc;
+
+ if (stream_info->endpoint_a.type != stream_info->endpoint_b.type)
+ {
+ return (1);
+ }
+ if (stream_info->endpoint_a.type == lbm_uim_instance_stream)
+ {
+ rc = memcmp((void *)stream_info->endpoint_a.stream_info.ctxinst.ctxinst,
+ (void *)stream_info->endpoint_b.stream_info.ctxinst.ctxinst,
+ LBM_CONTEXT_INSTANCE_BLOCK_SZ);
+ if (rc <= 0)
+ {
+ swap_endpoints = FALSE;
+ }
+ else
+ {
+ swap_endpoints = TRUE;
+ }
+ }
+ else
+ {
+ if (stream_info->endpoint_a.stream_info.dest.domain < stream_info->endpoint_b.stream_info.dest.domain)
+ {
+ swap_endpoints = FALSE;
+ }
+ else if (stream_info->endpoint_a.stream_info.dest.domain > stream_info->endpoint_b.stream_info.dest.domain)
+ {
+ swap_endpoints = TRUE;
+ }
+ else
+ {
+ int compare;
+
+ compare = CMP_ADDRESS(&(stream_info->endpoint_a.stream_info.dest.addr), &(stream_info->endpoint_b.stream_info.dest.addr));
+ if (compare < 0)
+ {
+ swap_endpoints = FALSE;
+ }
+ else if (compare > 0)
+ {
+ swap_endpoints = TRUE;
+ }
+ else
+ {
+ if (stream_info->endpoint_a.stream_info.dest.port <= stream_info->endpoint_b.stream_info.dest.port)
+ {
+ swap_endpoints = FALSE;
+ }
+ else
+ {
+ swap_endpoints = TRUE;
+ }
+ }
+ }
+ }
+ if (swap_endpoints == FALSE)
+ {
+ epa = stream_info->endpoint_a;
+ epb = stream_info->endpoint_b;
+ }
+ else
+ {
+ epb = stream_info->endpoint_a;
+ epa = stream_info->endpoint_b;
+ }
+ item = (seq_analysis_item_t *)g_malloc(sizeof(seq_analysis_item_t));
+ COPY_ADDRESS(&(item->src_addr), &(pinfo->src));
+ COPY_ADDRESS(&(item->dst_addr), &(pinfo->dst));
+ item->fd = pinfo->fd;
+ item->port_src = pinfo->srcport;
+ item->port_dst = pinfo->destport;
+ if (stream_info->description == NULL)
+ {
+ item->frame_label = g_strdup_printf("(%" G_GUINT32_FORMAT ")", stream_info->sqn);
+ }
+ else
+ {
+ item->frame_label = g_strdup_printf("%s (%" G_GUINT32_FORMAT ")", stream_info->description, stream_info->sqn);
+ }
+ if (epa.type == lbm_uim_instance_stream)
+ {
+ ctxinst1 = bytes_to_ep_str(epa.stream_info.ctxinst.ctxinst, sizeof(epa.stream_info.ctxinst.ctxinst));
+ ctxinst2 = bytes_to_ep_str(epb.stream_info.ctxinst.ctxinst, sizeof(epb.stream_info.ctxinst.ctxinst));
+ item->comment = g_strdup_printf("%s <-> %s [%" G_GUINT64_FORMAT "]",
+ ctxinst1,
+ ctxinst2,
+ stream_info->channel);
+ }
+ else
+ {
+ item->comment = g_strdup_printf("%" G_GUINT32_FORMAT ":%s:%" G_GUINT16_FORMAT " <-> %" G_GUINT32_FORMAT ":%s:%" G_GUINT16_FORMAT " [%" G_GUINT64_FORMAT "]",
+ epa.stream_info.dest.domain,
+ address_to_str(wmem_packet_scope(), &(epa.stream_info.dest.addr)),
+ epa.stream_info.dest.port,
+ epb.stream_info.dest.domain,
+ address_to_str(wmem_packet_scope(), &(epb.stream_info.dest.addr)),
+ epb.stream_info.dest.port,
+ stream_info->channel);
+ }
+ item->conv_num = (guint16)LBM_CHANNEL_ID(stream_info->channel);
+ item->display = TRUE;
+ item->line_style = 1;
+ dialog_data.graph_analysis->list = g_list_prepend(dialog_data.graph_analysis->list, (gpointer)item);
+ return (1);
+}
+
+static gboolean lbmc_uim_flow_tap_packet(void * tap_data _U_, packet_info * pinfo, epan_dissect_t * edt _U_, const void * stream_info)
+{
+ const lbm_uim_stream_info_t * info = (const lbm_uim_stream_info_t *)stream_info;
+ if ((dialog_data.packet_select_type == select_all_packets) || (pinfo->fd->flags.passed_dfilter == 1))
+ {
+ lbmc_uim_flow_graph_add_to_graph(pinfo, info);
+ return (TRUE);
+ }
+ return (FALSE);
+}
+
+static void lbmc_uim_flow_tap_draw(void * tap_data _U_)
+{
+ return;
+}
+
+static void lbmc_uim_flow_remove_tap_listener(void)
+{
+ remove_tap_listener(&(dialog_data.tap_identifier));
+ dialog_data.have_tap_listener = FALSE;
+}
+
+static void lbmc_uim_flow_graph_on_ok_cb(GtkButton * button _U_, gpointer user_data)
+{
+ GList * list = NULL;
+ gchar time_str[COL_MAX_LEN];
+
+ if (dialog_data.have_tap_listener == TRUE)
+ {
+ /* remove_tap_listeners */
+ lbmc_uim_flow_remove_tap_listener();
+ }
+
+ /* Scan for displayed packets (retap all packets) */
+ if (dialog_data.have_tap_listener == FALSE)
+ {
+ GString * err_msg;
+
+ err_msg = register_tap_listener("lbm_uim",
+ &(dialog_data.tap_identifier),
+ NULL,
+ TL_REQUIRES_COLUMNS,
+ lbmc_uim_flow_tap_reset,
+ lbmc_uim_flow_tap_packet,
+ lbmc_uim_flow_tap_draw);
+ if (err_msg != NULL)
+ {
+ fprintf(stderr, "register_tap_listener: %s\n", err_msg->str);
+ g_string_free(err_msg, TRUE);
+ }
+ dialog_data.have_tap_listener = TRUE;
+ }
+ cf_retap_packets(&cfile);
+ dialog_data.graph_analysis->list = g_list_reverse(dialog_data.graph_analysis->list);
+ /* Fill in the timestamps. */
+ list = g_list_first(dialog_data.graph_analysis->list);
+ while (list != NULL)
+ {
+ seq_analysis_item_t * seq_item = (seq_analysis_item_t *)list->data;
+ set_fd_time(cfile.epan, seq_item->fd, time_str);
+ seq_item->time_str = g_strdup(time_str);
+ list = g_list_next(list);
+ }
+ if (dialog_data.graph_analysis_data->dlg.window != NULL)
+ {
+ graph_analysis_update(dialog_data.graph_analysis_data);
+ }
+ else
+ {
+ dialog_data.graph_analysis_data->dlg.parent_w = (GtkWidget *)user_data;
+ graph_analysis_create(dialog_data.graph_analysis_data);
+ }
+}
+
+static void lbmc_uim_flow_graph_on_destroy_cb(GtkWidget * widget _U_, gpointer user_data _U_)
+{
+ /* remove_tap_listeners */
+ lbmc_uim_flow_remove_tap_listener();
+
+ /* Clean up memory used by tap */
+ lbmc_uim_flow_tap_reset(NULL);
+
+ g_assert(dialog_data.graph_analysis != NULL);
+ g_assert(dialog_data.graph_analysis_data != NULL);
+
+ g_free(dialog_data.graph_analysis);
+ dialog_data.graph_analysis = NULL;
+
+ g_free(dialog_data.graph_analysis_data);
+ dialog_data.graph_analysis_data = NULL;
+
+ /* Note that we no longer have a "Flow Graph" dialog box. */
+ dialog_data.flow_graph_dialog = NULL;
+}
+
+static void lbmc_uim_flow_graph_dlg_create(void)
+{
+ GtkWidget * flow_graph_dlg_w = NULL;
+ GtkWidget * main_vb = NULL;
+ GtkWidget * hbuttonbox = NULL;
+ GtkWidget * bt_cancel = NULL;
+ GtkWidget * bt_ok = NULL;
+ GtkWidget * range_fr = NULL;
+ GtkWidget * range_grid = NULL;
+
+ flow_graph_dlg_w = dlg_window_new("Wireshark: UIM Flow Graph");
+ gtk_window_set_destroy_with_parent(GTK_WINDOW(flow_graph_dlg_w), TRUE);
+
+ gtk_window_set_default_size(GTK_WINDOW(flow_graph_dlg_w), 250, 150);
+
+ main_vb = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 0, FALSE);
+ gtk_container_add(GTK_CONTAINER(flow_graph_dlg_w), main_vb);
+ gtk_container_set_border_width(GTK_CONTAINER(main_vb), 7);
+
+ gtk_widget_show(flow_graph_dlg_w);
+
+ /*** Packet range frame ***/
+ range_fr = gtk_frame_new("Choose packets");
+ gtk_box_pack_start(GTK_BOX(main_vb), range_fr, FALSE, FALSE, 5);
+
+ range_grid = ws_gtk_grid_new();
+ gtk_container_set_border_width(GTK_CONTAINER(range_grid), 5);
+ gtk_container_add(GTK_CONTAINER(range_fr), range_grid);
+
+ /* Process all packets */
+ dialog_data.select_all_radio_button = gtk_radio_button_new_with_mnemonic_from_widget(NULL, "_All packets");
+ gtk_widget_set_tooltip_text(dialog_data.select_all_radio_button, ("Process all packets"));
+ g_signal_connect(dialog_data.select_all_radio_button, "toggled", G_CALLBACK(lbmc_uim_flow_toggle_select_all_cb), NULL);
+ ws_gtk_grid_attach_extended(GTK_GRID(range_grid), dialog_data.select_all_radio_button, 0, 0, 1, 1,
+ (GtkAttachOptions)(GTK_FILL), (GtkAttachOptions)(0), 0, 0);
+ if (dialog_data.packet_select_type == select_all_packets)
+ {
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog_data.select_all_radio_button), TRUE);
+ }
+ gtk_widget_show(dialog_data.select_all_radio_button);
+
+ /* Process displayed packets */
+ dialog_data.select_displayed_radio_button =
+ gtk_radio_button_new_with_mnemonic_from_widget(GTK_RADIO_BUTTON(dialog_data.select_all_radio_button), "_Displayed packets");
+ gtk_widget_set_tooltip_text(dialog_data.select_displayed_radio_button, ("Process displayed packets"));
+ g_signal_connect(dialog_data.select_displayed_radio_button, "toggled", G_CALLBACK(lbmc_uim_flow_toggle_select_displayed_cb), NULL);
+ ws_gtk_grid_attach_extended(GTK_GRID(range_grid), dialog_data.select_displayed_radio_button, 0, 1, 1, 1,
+ (GtkAttachOptions)(GTK_FILL), (GtkAttachOptions)(0), 0, 0);
+ if (dialog_data.packet_select_type == select_displayed_packets)
+ {
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog_data.select_displayed_radio_button), TRUE);
+ }
+ gtk_widget_show(dialog_data.select_displayed_radio_button);
+
+ gtk_widget_show(range_grid);
+ gtk_widget_show(range_fr);
+
+ /* button row */
+ hbuttonbox = gtk_button_box_new(GTK_ORIENTATION_HORIZONTAL);
+ gtk_box_pack_start(GTK_BOX(main_vb), hbuttonbox, FALSE, FALSE, 5);
+ gtk_button_box_set_layout(GTK_BUTTON_BOX(hbuttonbox), GTK_BUTTONBOX_SPREAD);
+ gtk_box_set_spacing(GTK_BOX(hbuttonbox), 30);
+
+ bt_ok = gtk_button_new_from_stock(GTK_STOCK_OK);
+ gtk_container_add(GTK_CONTAINER(hbuttonbox), bt_ok);
+ gtk_widget_set_tooltip_text(bt_ok, "Show the flow graph");
+ g_signal_connect(bt_ok, "clicked", G_CALLBACK(lbmc_uim_flow_graph_on_ok_cb), flow_graph_dlg_w);
+ gtk_widget_show(bt_ok);
+
+ bt_cancel = gtk_button_new_from_stock(GTK_STOCK_CANCEL);
+ gtk_container_add(GTK_CONTAINER(hbuttonbox), bt_cancel);
+#if GTK_CHECK_VERSION(2,18,0)
+ gtk_widget_set_can_default(bt_cancel, TRUE);
+#else
+ GTK_WIDGET_SET_FLAGS(bt_cancel, GTK_CAN_DEFAULT);
+#endif
+ gtk_widget_set_tooltip_text(bt_cancel, "Cancel this dialog");
+ window_set_cancel_button(flow_graph_dlg_w, bt_cancel, window_cancel_button_cb);
+
+ g_signal_connect(flow_graph_dlg_w, "delete_event", G_CALLBACK(window_delete_event_cb), NULL);
+ g_signal_connect(flow_graph_dlg_w, "destroy", G_CALLBACK(lbmc_uim_flow_graph_on_destroy_cb), NULL);
+
+ gtk_widget_show_all(flow_graph_dlg_w);
+ window_present(flow_graph_dlg_w);
+
+ dialog_data.flow_graph_dialog = flow_graph_dlg_w;
+}
+
+static void lbmc_uim_flow_graph_init_tap(const char * dummy _U_, void * user_data _U_)
+{
+ /*
+ The storage allocated by lbmc_uim_flow_graph_data_init() and lbmc_uim_graph_analysis_init()
+ will be considered to be "associated with" the dialog_data.flow_graph_dialog dialog box. It will be freed
+ when the dialog_data.flow_graph_dialog dialog box is destroyed.
+ */
+ if (dialog_data.flow_graph_dialog != NULL)
+ {
+ g_assert(dialog_data.graph_analysis != NULL);
+ g_assert(dialog_data.graph_analysis_data != NULL);
+ /* There's already a dialog box; reactivate it. */
+ reactivate_window(dialog_data.flow_graph_dialog);
+ }
+ else
+ {
+ g_assert(dialog_data.graph_analysis == NULL);
+ g_assert(dialog_data.graph_analysis_data == NULL);
+ /* initialize graph items store */
+ lbmc_uim_flow_graph_data_init();
+
+ /* init the Graph Analysis */
+ dialog_data.graph_analysis_data = graph_analysis_init(dialog_data.graph_analysis);
+
+ lbmc_uim_flow_graph_dlg_create();
+ }
+}
+
+void lbmc_uim_flow_menu_cb(gpointer arg _U_)
+{
+ lbmc_uim_flow_graph_init_tap("", NULL);
+}
+
+/*
+ * Editor modelines - http://www.wireshark.org/tools/modelines.html
+ *
+ * Local variables:
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * vi: set shiftwidth=4 tabstop=4 expandtab:
+ * :indentSize=4:tabSize=4:noTabs=true:
+ */
diff --git a/ui/gtk/lbm_uimflow_dlg.h b/ui/gtk/lbm_uimflow_dlg.h
new file mode 100644
index 0000000000..5b74ace192
--- /dev/null
+++ b/ui/gtk/lbm_uimflow_dlg.h
@@ -0,0 +1,46 @@
+/* lbm_uimflow_dlg.h
+ * Routines for LBMC UIM flow graph dialog
+ *
+ * Copyright (c) 2005-2014 Informatica Corporation. All Rights Reserved.
+ *
+ * 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 LBM_UIMFLOW_DLG_H_INCLUDED
+#define LBM_UIMFLOW_DLG_H_INCLUDED
+
+#include "config.h"
+#include <glib.h>
+
+void lbmc_uim_flow_menu_cb(gpointer arg);
+
+#endif
+
+/*
+ * Editor modelines - http://www.wireshark.org/tools/modelines.html
+ *
+ * Local variables:
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * vi: set shiftwidth=4 tabstop=4 expandtab:
+ * :indentSize=4:tabSize=4:noTabs=true:
+ */
diff --git a/ui/gtk/main_menubar.c b/ui/gtk/main_menubar.c
index 463311f93c..b3749f4599 100644
--- a/ui/gtk/main_menubar.c
+++ b/ui/gtk/main_menubar.c
@@ -115,6 +115,8 @@
#include "ui/gtk/conversation_hastables_dlg.h"
#include "ui/gtk/packet_list.h"
+#include "ui/gtk/lbm_stream_dlg.h"
+#include "ui/gtk/lbm_uimflow_dlg.h"
#ifdef HAVE_LIBPCAP
#include "capture_opts.h"
@@ -1222,6 +1224,27 @@ static const char *ui_desc_menubar =
" <menuitem name='ONC-RPC' action='/Statistics/ServiceResponseTime/ONC-RPC'/>\n"
" </menu>\n"
" <separator/>\n"
+" <menu name= '29West' action='/Statistics/29West'>\n"
+" <menu name= '29WestTopicMenu' action='/Statistics/29West/Topics'>\n"
+" <menuitem name='29WestTopicAdsTopic' action='/Statistics/29West/Topics/lbmr_topic_ads_topic'/>\n"
+" <menuitem name='29WestTopicAdsSource' action='/Statistics/29West/Topics/lbmr_topic_ads_source'/>\n"
+" <menuitem name='29WestTopicAdsTransport' action='/Statistics/29West/Topics/lbmr_topic_ads_transport'/>\n"
+" <menuitem name='29WestTopicQueriesTopic' action='/Statistics/29West/Topics/lbmr_topic_queries_topic'/>\n"
+" <menuitem name='29WestTopicQueriesReceiver' action='/Statistics/29West/Topics/lbmr_topic_queries_receiver'/>\n"
+" <menuitem name='29WestTopicQueriesPattern' action='/Statistics/29West/Topics/lbmr_topic_queries_pattern'/>\n"
+" <menuitem name='29WestTopicQueriesPatternReceiver' action='/Statistics/29West/Topics/lbmr_topic_queries_pattern_receiver'/>\n"
+" </menu>\n"
+" <menu name= '29WestQueueMenu' action='/Statistics/29West/Queues'>\n"
+" <menuitem name='29WestQueueAdsQueue' action='/Statistics/29West/Queues/lbmr_queue_ads_queue'/>\n"
+" <menuitem name='29WestQueueAdsSource' action='/Statistics/29West/Queues/lbmr_queue_ads_source'/>\n"
+" <menuitem name='29WestQueueQueriesQueue' action='/Statistics/29West/Queues/lbmr_queue_queries_queue'/>\n"
+" <menuitem name='29WestQueueQueriesReceiver' action='/Statistics/29West/Queues/lbmr_queue_queries_receiver'/>\n"
+" </menu>\n"
+" <menu name= '29WestUIMMenu' action='/Statistics/29West/UIM'>\n"
+" <menuitem name='29WestUIMStreams' action='/Statistics/29West/UIM/Streams' />\n"
+" <menuitem name='29WestUIMStreamFlowGraph' action='/Statistics/29West/UIM/StreamFlowGraph' />\n"
+" </menu>\n"
+" </menu>\n"
" <menuitem name='ANCP' action='/Statistics/ancp'/>\n"
" <menu name= 'BACnetMenu' action='/Statistics/BACnet'>\n"
" <menuitem name='bacapp_instanceid' action='/Statistics/BACnet/bacapp_instanceid'/>\n"
@@ -1666,6 +1689,24 @@ static const GtkActionEntry main_menu_bar_entries[] = {
{ "/Statistics/ServiceResponseTime/DCE-RPC", WIRESHARK_STOCK_TIME, "DCE-RPC...", NULL, NULL, G_CALLBACK(gtk_dcerpcstat_cb) },
{ "/Statistics/ServiceResponseTime/ONC-RPC", WIRESHARK_STOCK_TIME, "ONC-RPC...", NULL, NULL, G_CALLBACK(gtk_rpcstat_cb) },
+ { "/Statistics/29West", NULL, "29West", NULL, NULL, NULL },
+ { "/Statistics/29West/Topics", NULL, "Topics", NULL, NULL, NULL },
+ { "/Statistics/29West/Topics/lbmr_topic_ads_topic", NULL, "Advertisements by Topic", NULL, NULL, G_CALLBACK(gtk_stats_tree_cb) },
+ { "/Statistics/29West/Topics/lbmr_topic_ads_source", NULL, "Advertisements by Source", NULL, NULL, G_CALLBACK(gtk_stats_tree_cb) },
+ { "/Statistics/29West/Topics/lbmr_topic_ads_transport", NULL, "Advertisements by Transport", NULL, NULL, G_CALLBACK(gtk_stats_tree_cb) },
+ { "/Statistics/29West/Topics/lbmr_topic_queries_topic", NULL, "Queries by Topic", NULL, NULL, G_CALLBACK(gtk_stats_tree_cb) },
+ { "/Statistics/29West/Topics/lbmr_topic_queries_receiver", NULL, "Queries by Receiver", NULL, NULL, G_CALLBACK(gtk_stats_tree_cb) },
+ { "/Statistics/29West/Topics/lbmr_topic_queries_pattern", NULL, "Wildcard Queries by Pattern", NULL, NULL, G_CALLBACK(gtk_stats_tree_cb) },
+ { "/Statistics/29West/Topics/lbmr_topic_queries_pattern_receiver", NULL, "Wildcard Queries by Receiver", NULL, NULL, G_CALLBACK(gtk_stats_tree_cb) },
+ { "/Statistics/29West/Queues", NULL, "Queues", NULL, NULL, NULL },
+ { "/Statistics/29West/Queues/lbmr_queue_ads_queue", NULL, "Advertisements by Queue", NULL, NULL, G_CALLBACK(gtk_stats_tree_cb) },
+ { "/Statistics/29West/Queues/lbmr_queue_ads_source", NULL, "Advertisements by Source", NULL, NULL, G_CALLBACK(gtk_stats_tree_cb) },
+ { "/Statistics/29West/Queues/lbmr_queue_queries_queue", NULL, "Queries by Queue", NULL, NULL, G_CALLBACK(gtk_stats_tree_cb) },
+ { "/Statistics/29West/Queues/lbmr_queue_queries_receiver", NULL, "Queries by Receiver", NULL, NULL, G_CALLBACK(gtk_stats_tree_cb) },
+ { "/Statistics/29West/UIM", NULL, "UIM", NULL, NULL, NULL },
+ { "/Statistics/29West/UIM/Streams", NULL, "Streams", NULL, NULL, G_CALLBACK(lbmc_stream_dlg_stream_menu_cb) },
+ { "/Statistics/29West/UIM/StreamFlowGraph", WIRESHARK_STOCK_FLOW_GRAPH, "Stream Flow Graph", NULL, NULL, G_CALLBACK(lbmc_uim_flow_menu_cb) },
+
{ "/Statistics/ancp", NULL, "ANCP", NULL, NULL, G_CALLBACK(gtk_stats_tree_cb) },
{ "/Statistics/BACnet", NULL, "BACnet", NULL, NULL, NULL },
{ "/Statistics/BACnet/bacapp_instanceid", NULL, "Packets sorted by Instance ID", NULL, NULL, G_CALLBACK(gtk_stats_tree_cb) },