From b1da5099dbb7b94f362bcc3e2b6e057b6763df71 Mon Sep 17 00:00:00 2001 From: dameiss Date: Thu, 19 Jun 2014 18:08:39 -0400 Subject: 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 Reviewed-by: Evan Huus --- ui/gtk/CMakeLists.txt | 2 + ui/gtk/Makefile.common | 4 + ui/gtk/lbm_stream_dlg.c | 777 +++++++++++++++++++++++++++++++++++++++++++++++ ui/gtk/lbm_stream_dlg.h | 46 +++ ui/gtk/lbm_uimflow_dlg.c | 457 ++++++++++++++++++++++++++++ ui/gtk/lbm_uimflow_dlg.h | 46 +++ ui/gtk/main_menubar.c | 41 +++ 7 files changed, 1373 insertions(+) create mode 100644 ui/gtk/lbm_stream_dlg.c create mode 100644 ui/gtk/lbm_stream_dlg.h create mode 100644 ui/gtk/lbm_uimflow_dlg.c create mode 100644 ui/gtk/lbm_uimflow_dlg.h 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 + * Copyright 1998 Gerald Combs + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "config.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#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 + * 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 + +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 + * Copyright 1998 Gerald Combs + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "config.h" +#include +#include +#include +#include +#include +#include +#include +#include "ui/gtk/gui_utils.h" +#include "ui/gtk/dlg_utils.h" +#include +#include +#include "ui/gtk/graph_analysis.h" +#include +#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 + * 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 + +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 = " \n" " \n" " \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" " \n" " \n" " \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) }, -- cgit v1.2.1