diff options
author | Gerald Combs <gerald@wireshark.org> | 2015-08-31 12:24:48 -0700 |
---|---|---|
committer | Gerald Combs <gerald@wireshark.org> | 2015-08-31 23:06:09 +0000 |
commit | 377d215e0fd1022a093fa44b32f396948e70c119 (patch) | |
tree | 4a798c715645ec953e1ae447ddec555c3f509bbb | |
parent | e9614ad7bad3078876c370a5e2f697fb61664322 (diff) |
Convert the MTP3 stats to new "generic stat API".
Convert both the MTP3 statistics and summary. As with the GSM stats this
is mostly untested.
Change-Id: I7af8d5f21c8161dc95f7f2c710f32364b6f6a431
Reviewed-on: https://code.wireshark.org/review/10338
Petri-Dish: Gerald Combs <gerald@wireshark.org>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Gerald Combs <gerald@wireshark.org>
-rw-r--r-- | epan/dissectors/packet-mtp3.c | 197 | ||||
-rw-r--r-- | epan/dissectors/packet-mtp3.h | 14 | ||||
-rw-r--r-- | epan/stat_groups.h | 1 | ||||
-rw-r--r-- | ui/gtk/CMakeLists.txt | 1 | ||||
-rw-r--r-- | ui/gtk/Makefile.common | 2 | ||||
-rw-r--r-- | ui/gtk/main_menubar.c | 3 | ||||
-rw-r--r-- | ui/gtk/mtp3_stat.c | 461 | ||||
-rw-r--r-- | ui/gtk/mtp3_summary.c | 125 | ||||
-rw-r--r-- | ui/gtk/tap_param_dlg.c | 1 | ||||
-rw-r--r-- | ui/qt/CMakeLists.txt | 3 | ||||
-rw-r--r-- | ui/qt/Makefile.am | 2 | ||||
-rw-r--r-- | ui/qt/Makefile.common | 4 | ||||
-rw-r--r-- | ui/qt/Wireshark.pro | 3 | ||||
-rw-r--r-- | ui/qt/gsm_map_summary_dialog.cpp | 6 | ||||
-rw-r--r-- | ui/qt/gsm_map_summary_dialog.ui | 2 | ||||
-rw-r--r-- | ui/qt/main_window.cpp | 14 | ||||
-rw-r--r-- | ui/qt/main_window.h | 1 | ||||
-rw-r--r-- | ui/qt/main_window.ui | 33 | ||||
-rw-r--r-- | ui/qt/main_window_slots.cpp | 7 | ||||
-rw-r--r-- | ui/qt/mtp3_summary_dialog.cpp | 404 | ||||
-rw-r--r-- | ui/qt/mtp3_summary_dialog.h (renamed from ui/gtk/mtp3_stat.h) | 64 | ||||
-rw-r--r-- | ui/qt/mtp3_summary_dialog.ui | 71 |
22 files changed, 909 insertions, 510 deletions
diff --git a/epan/dissectors/packet-mtp3.c b/epan/dissectors/packet-mtp3.c index 69debea5fd..781a8aef89 100644 --- a/epan/dissectors/packet-mtp3.c +++ b/epan/dissectors/packet-mtp3.c @@ -38,6 +38,7 @@ #include "config.h" #include <epan/packet.h> +#include <epan/stat_tap_ui.h> #include <epan/tap.h> #include <epan/prefs.h> #include <wiretap/wtap.h> @@ -768,6 +769,182 @@ dissect_mtp3(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) mtp3_standard = pref_mtp3_standard; } +/* TAP STAT INFO */ + +typedef enum +{ + OPC_COLUMN, + DPC_COLUMN, + SI_COLUMN, + NUM_MSUS_COLUMN, + NUM_BYTES_COLUMN, + AVG_BYTES_COLUMN +} mtp3_stat_columns; + +static stat_tap_table_item mtp3_stat_fields[] = { + {TABLE_ITEM_STRING, TAP_ALIGN_LEFT, "OPC", "%-25s"}, + {TABLE_ITEM_STRING, TAP_ALIGN_LEFT, "DPC", "%-25s"}, + {TABLE_ITEM_STRING, TAP_ALIGN_LEFT, "SI", "%-25s"}, + {TABLE_ITEM_UINT, TAP_ALIGN_RIGHT, "MSUs", "%d"}, + {TABLE_ITEM_UINT, TAP_ALIGN_RIGHT, "Bytes", "%d"}, + {TABLE_ITEM_FLOAT, TAP_ALIGN_RIGHT, "Avg Bytes", "%f"}, +}; + +static void mtp3_stat_init(new_stat_tap_ui* new_stat, new_stat_tap_gui_init_cb gui_callback, void* gui_data) +{ + int num_fields = sizeof(mtp3_stat_fields)/sizeof(stat_tap_table_item); + new_stat_tap_table* table; + + table = new_stat_tap_init_table("MTP3 Statistics", num_fields, 0, NULL, gui_callback, gui_data); + new_stat_tap_add_table(new_stat, table); +} + +static gboolean +mtp3_stat_packet(void *tapdata, packet_info *pinfo _U_, epan_dissect_t *edt _U_, const void *m3tr_ptr) +{ + new_stat_data_t* stat_data = (new_stat_data_t*)tapdata; + const mtp3_tap_rec_t *m3tr = (const mtp3_tap_rec_t *)m3tr_ptr; + gboolean found = FALSE; + guint element; + new_stat_tap_table* table; + stat_tap_table_item_type* item_data; + guint msu_count; + guint byte_count; + double avg_bytes = 0.0; + + if (m3tr->mtp3_si_code >= MTP3_NUM_SI_CODE) + { + /* + * we thought this si_code was not used ? + * is MTP3_NUM_SI_CODE out of date ? + */ + return(FALSE); + } + + /* + * look for opc/dpc pair + */ + table = g_array_index(stat_data->new_stat_tap_data->tables, new_stat_tap_table*, 0); + for (element = 0; element < table->num_elements; element++) + { + stat_tap_table_item_type *opc_data, *dpc_data, *si_data; + opc_data = new_stat_tap_get_field_data(table, element, OPC_COLUMN); + dpc_data = new_stat_tap_get_field_data(table, element, DPC_COLUMN); + si_data = new_stat_tap_get_field_data(table, element, SI_COLUMN); + + if (memcmp(&m3tr->addr_opc, opc_data->user_data.ptr_value, sizeof(mtp3_addr_pc_t)) == 0) + { + if (memcmp(&m3tr->addr_dpc, dpc_data->user_data.ptr_value, sizeof(mtp3_addr_pc_t)) == 0) + { + if (m3tr->mtp3_si_code == si_data->user_data.uint_value) + { + found = TRUE; + break; + } + } + } + } + + if (!found) { + /* Add a new row */ + /* XXX The old version added a row per SI. */ + int num_fields = sizeof(mtp3_stat_fields)/sizeof(stat_tap_table_item); + stat_tap_table_item_type items[sizeof(mtp3_stat_fields)/sizeof(stat_tap_table_item)]; + char str[256]; + const char *sis; + char *col_str; + + memset(items, 0, sizeof(items)); + + items[OPC_COLUMN].type = TABLE_ITEM_STRING; + items[DPC_COLUMN].type = TABLE_ITEM_STRING; + items[SI_COLUMN].type = TABLE_ITEM_STRING; + items[NUM_MSUS_COLUMN].type = TABLE_ITEM_UINT; + items[NUM_BYTES_COLUMN].type = TABLE_ITEM_UINT; + items[AVG_BYTES_COLUMN].type = TABLE_ITEM_FLOAT; + + new_stat_tap_init_table_row(table, element, num_fields, items); + + item_data = new_stat_tap_get_field_data(table, element, OPC_COLUMN); + mtp3_addr_to_str_buf(&m3tr->addr_opc, str, 256); + item_data->value.string_value = g_strdup(str); + item_data->user_data.ptr_value = g_memdup(&m3tr->addr_opc, sizeof(mtp3_tap_rec_t)); + new_stat_tap_set_field_data(table, element, OPC_COLUMN, item_data); + + item_data = new_stat_tap_get_field_data(table, element, DPC_COLUMN); + mtp3_addr_to_str_buf(&m3tr->addr_dpc, str, 256); + item_data->value.string_value = g_strdup(str); + item_data->user_data.ptr_value = g_memdup(&m3tr->addr_dpc, sizeof(mtp3_tap_rec_t)); + new_stat_tap_set_field_data(table, element, DPC_COLUMN, item_data); + + sis = try_val_to_str(m3tr->mtp3_si_code, mtp3_service_indicator_code_short_vals); + if (sis) { + col_str = g_strdup(sis); + } else { + col_str = g_strdup_printf("Unknown service indicator %d", m3tr->mtp3_si_code); + } + + item_data = new_stat_tap_get_field_data(table, element, SI_COLUMN); + item_data->value.string_value = col_str; + item_data->user_data.uint_value = m3tr->mtp3_si_code; + new_stat_tap_set_field_data(table, element, SI_COLUMN, item_data); + } + + item_data = new_stat_tap_get_field_data(table, element, NUM_MSUS_COLUMN); + item_data->value.uint_value++; + msu_count = item_data->value.uint_value; + new_stat_tap_set_field_data(table, element, NUM_MSUS_COLUMN, item_data); + + item_data = new_stat_tap_get_field_data(table, element, NUM_BYTES_COLUMN); + item_data->value.uint_value += m3tr->size; + byte_count = item_data->value.uint_value; + new_stat_tap_set_field_data(table, element, NUM_BYTES_COLUMN, item_data); + + if (msu_count > 0) { + avg_bytes = (double) byte_count / msu_count; + } + item_data = new_stat_tap_get_field_data(table, element, AVG_BYTES_COLUMN); + item_data->value.float_value = avg_bytes; + new_stat_tap_set_field_data(table, element, AVG_BYTES_COLUMN, item_data); + + return TRUE; +} + +static void +mtp3_stat_reset(new_stat_tap_table* table) +{ + guint element; + stat_tap_table_item_type* item_data; + + for (element = 0; element < table->num_elements; element++) + { + item_data = new_stat_tap_get_field_data(table, element, NUM_MSUS_COLUMN); + item_data->value.uint_value = 0; + new_stat_tap_set_field_data(table, element, NUM_MSUS_COLUMN, item_data); + + item_data = new_stat_tap_get_field_data(table, element, NUM_BYTES_COLUMN); + item_data->value.uint_value = 0; + new_stat_tap_set_field_data(table, element, NUM_BYTES_COLUMN, item_data); + } +} + +static void +mtp3_stat_free_table_item(new_stat_tap_table* table _U_, guint row _U_, guint column, stat_tap_table_item_type* field_data) +{ + switch(column) { + case OPC_COLUMN: + case DPC_COLUMN: + g_free((char*)field_data->user_data.ptr_value); + /* Fall through */ + case SI_COLUMN: + g_free((char*)field_data->value.string_value); + break; + default: + break; + } +} + + void proto_register_mtp3(void) { @@ -849,6 +1026,25 @@ proto_register_mtp3(void) { NULL, NULL, 0 } }; + static tap_param mtp3_stat_params[] = { + { PARAM_FILTER, "filter", "Filter", NULL, TRUE } + }; + + static new_stat_tap_ui mtp3_stat_table = { + REGISTER_STAT_GROUP_TELEPHONY_MTP3, + "MTP3 Statistics", + "mtp3", + "mtp3,msus", + mtp3_stat_init, + mtp3_stat_packet, + mtp3_stat_reset, + mtp3_stat_free_table_item, + NULL, + sizeof(mtp3_stat_fields)/sizeof(stat_tap_table_item), mtp3_stat_fields, + sizeof(mtp3_stat_params)/sizeof(tap_param), mtp3_stat_params, + NULL + }; + /* Register the protocol name and description */ proto_mtp3 = proto_register_protocol("Message Transfer Part Level 3", "MTP3", "mtp3"); @@ -902,6 +1098,7 @@ proto_register_mtp3(void) "Decode the spare bits of the SIO as the MSU priority (a national option in ITU)", &mtp3_show_itu_priority); + register_new_stat_tap_ui(&mtp3_stat_table); } void diff --git a/epan/dissectors/packet-mtp3.h b/epan/dissectors/packet-mtp3.h index 0a02cd2c63..e5270d3a5b 100644 --- a/epan/dissectors/packet-mtp3.h +++ b/epan/dissectors/packet-mtp3.h @@ -18,8 +18,8 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#ifndef __PACKET_MTP3_H_ -#define __PACKET_MTP3_H_ +#ifndef __PACKET_MTP3_H__ +#define __PACKET_MTP3_H__ #include "ws_symbol_export.h" @@ -74,6 +74,10 @@ typedef struct _mtp3_tap_rec_t { #define JAPAN_PC_LENGTH 2 #define JAPAN_PC_MASK 0xffff +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + WS_DLL_PUBLIC void mtp3_addr_to_str_buf(const mtp3_addr_pc_t *addr_pc_p, gchar *buf, int buf_len); extern void mtp3_pc_to_str_buf(const guint32 pc, gchar *buf, int buf_len); extern gchar* mtp3_pc_to_str(const guint32 pc); @@ -126,4 +130,8 @@ WS_DLL_PUBLIC const value_string mtp3_service_indicator_code_short_vals[]; #define MTP3_NI_NAT1 0x3 WS_DLL_PUBLIC const value_string mtp3_network_indicator_vals[]; -#endif +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __PACKET_MTP3_H__ */ diff --git a/epan/stat_groups.h b/epan/stat_groups.h index f31eba9c8f..28f5353aa4 100644 --- a/epan/stat_groups.h +++ b/epan/stat_groups.h @@ -66,6 +66,7 @@ typedef enum { REGISTER_STAT_GROUP_TELEPHONY_ANSI, /* name says it all */ REGISTER_STAT_GROUP_TELEPHONY_GSM, /* GSM (and UMTS?) */ REGISTER_STAT_GROUP_TELEPHONY_LTE, /* name says it all */ + REGISTER_STAT_GROUP_TELEPHONY_MTP3, /* name says it all */ REGISTER_STAT_GROUP_TELEPHONY_SCTP, /* name says it all */ REGISTER_TOOLS_GROUP_UNSORTED /* unsorted tools */ } register_stat_group_t; diff --git a/ui/gtk/CMakeLists.txt b/ui/gtk/CMakeLists.txt index 923bd57284..662a897441 100644 --- a/ui/gtk/CMakeLists.txt +++ b/ui/gtk/CMakeLists.txt @@ -209,7 +209,6 @@ set(WIRESHARK_TAP_SRC lbm_uimflow_dlg.c mac_lte_stat_dlg.c mcast_stream_dlg.c - mtp3_stat.c mtp3_summary.c rlc_lte_graph.c rlc_lte_stat_dlg.c diff --git a/ui/gtk/Makefile.common b/ui/gtk/Makefile.common index b9e2cb6a56..2df560b987 100644 --- a/ui/gtk/Makefile.common +++ b/ui/gtk/Makefile.common @@ -160,7 +160,6 @@ WIRESHARK_TAP_SRC = \ lbm_uimflow_dlg.c \ mac_lte_stat_dlg.c \ mcast_stream_dlg.c \ - mtp3_stat.c \ mtp3_summary.c \ rlc_lte_graph.c \ rlc_lte_stat_dlg.c \ @@ -251,7 +250,6 @@ noinst_HEADERS = \ main_welcome_private.h \ manual_addr_resolv.h \ mcast_stream_dlg.h \ - mtp3_stat.h \ network_icons.h \ old-gtk-compat.h \ packet_history.h \ diff --git a/ui/gtk/main_menubar.c b/ui/gtk/main_menubar.c index a1f94578ef..3c3df2f753 100644 --- a/ui/gtk/main_menubar.c +++ b/ui/gtk/main_menubar.c @@ -1087,7 +1087,6 @@ static const char *ui_desc_menubar = " <menuitem name='LTE_RLC_Graph' action='/Telephony/LTE/RLCGraph'/>\n" " </menu>\n" " <menu name= 'MTP3menu' action='/Telephony/MTP3'>\n" -" <menuitem name='MSUs' action='/Telephony/MTP3/MSUs'/>\n" " <menuitem name='MSUSummary' action='/Telephony/MTP3/MSUSummary'/>\n" " </menu>\n" " <menu name= 'RTPmenu' action='/Telephony/RTP'>\n" @@ -1509,7 +1508,6 @@ static const GtkActionEntry main_menu_bar_entries[] = { { "/Telephony/LTE", NULL, "_LTE", NULL, NULL, NULL }, { "/Telephony/LTE/RLCGraph", NULL, "RLC _Graph...", NULL, NULL, G_CALLBACK(rlc_lte_graph_cb) }, { "/Telephony/MTP3", NULL, "_MTP3", NULL, NULL, NULL }, - { "/Telephony/MTP3/MSUs", NULL, "MSUs", NULL, NULL, G_CALLBACK(mtp3_stat_gtk_cb) }, { "/Telephony/MTP3/MSUSummary", NULL, "MSU Summary", NULL, NULL, G_CALLBACK(mtp3_sum_gtk_sum_cb) }, { "/Telephony/RTP", NULL, "_RTP", NULL, NULL, NULL }, { "/Telephony/RTP/StreamAnalysis", NULL, "Stream Analysis...", NULL, NULL, G_CALLBACK(rtp_analysis_cb) }, @@ -3540,6 +3538,7 @@ stat_group_name(register_stat_group_t group) {REGISTER_STAT_GROUP_TELEPHONY_ANSI, "/Menubar/TelephonyMenu|Telephony/ANSI|Telephony#ANSI"}, /* ANSI-specific */ {REGISTER_STAT_GROUP_TELEPHONY_GSM, "/Menubar/TelephonyMenu|Telephony/GSM|Telephony#GSM"}, /* GSM-specific */ {REGISTER_STAT_GROUP_TELEPHONY_LTE, "/Menubar/TelephonyMenu|Telephony/LTEmenu|Telephony#LTE"}, /* LTE-specific */ + {REGISTER_STAT_GROUP_TELEPHONY_MTP3, "/Menubar/TelephonyMenu|Telephony/MTP3menu|Telephony#MTP3"}, /* MTP3-specific */ {REGISTER_STAT_GROUP_TELEPHONY_SCTP, "/Menubar/TelephonyMenu|Telephony/SCTPmenu|Telephony#SCTP"}, /* SCTP-specific */ {REGISTER_TOOLS_GROUP_UNSORTED, "/Menubar/ToolsMenu|Tools"}, /* unsorted tools */ {0, NULL} diff --git a/ui/gtk/mtp3_stat.c b/ui/gtk/mtp3_stat.c deleted file mode 100644 index 628390e5a5..0000000000 --- a/ui/gtk/mtp3_stat.c +++ /dev/null @@ -1,461 +0,0 @@ -/* mtp3_stat.c - * - * Copyright 2004, Michael Lum <mlum [AT] telostech.com> - * In association with Telos Technology Inc. - * - * Modified from gsm_map_stat.c - * - * 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. - */ - -/* - * This TAP provides statistics for MTP3: - */ - -#include "config.h" - -#include <stdlib.h> -#include <string.h> - -#include <gtk/gtk.h> - -#include "epan/packet_info.h" -#include "epan/value_string.h" -#include <epan/stat_tap_ui.h> -#include <epan/tap.h> -#include <epan/dissectors/packet-mtp3.h> - -#include "ui/simple_dialog.h" - -#include "ui/gtk/gui_stat_menu.h" -#include "ui/gtk/dlg_utils.h" -#include "ui/gtk/gui_utils.h" -#include "ui/gtk/mtp3_stat.h" - - -void register_tap_listener_gtkmtp3_stat(void); - -enum -{ - OPC_COLUMN, - DPC_COLUMN, - SI_COLUMN, - NUM_MSUS_COLUMN, - NUM_BYTES_COLUMN, - AVG_BYTES_COLUMN, - N_COLUMN /* The number of columns */ -}; - - -typedef struct _mtp3_stat_dlg_t { - GtkWidget *win; - GtkWidget *scrolled_win; - GtkWidget *table; - char *entries[N_COLUMN]; -} mtp3_stat_dlg_t; - -static mtp3_stat_dlg_t dlg; - -mtp3_stat_t mtp3_stat[MTP3_MAX_NUM_OPC_DPC]; -guint8 mtp3_num_used; - - - -/* Create list */ -static -GtkWidget* create_list(void) -{ - - GtkListStore *list_store; - GtkWidget *list; - GtkTreeViewColumn *column; - GtkCellRenderer *renderer; - GtkTreeSortable *sortable; - GtkTreeView *list_view; - GtkTreeSelection *selection; - - /* Create the store */ - list_store = gtk_list_store_new(N_COLUMN, /* Total number of columns XXX*/ - G_TYPE_STRING, /* OPC */ - G_TYPE_STRING, /* DPC */ - G_TYPE_STRING, /* SI */ - G_TYPE_INT, /* Num MSUs */ - G_TYPE_INT, /* Num Bytes */ - G_TYPE_FLOAT); /* Avg Bytes */ - - /* Create a view */ - list = gtk_tree_view_new_with_model (GTK_TREE_MODEL (list_store)); - - list_view = GTK_TREE_VIEW(list); - sortable = GTK_TREE_SORTABLE(list_store); - - /* Speed up the list display */ - gtk_tree_view_set_fixed_height_mode(list_view, TRUE); - - /* Setup the sortable columns */ - gtk_tree_sortable_set_sort_column_id(sortable, OPC_COLUMN, GTK_SORT_ASCENDING); - gtk_tree_view_set_headers_clickable(list_view, FALSE); - - /* The view now holds a reference. We can get rid of our own reference */ - g_object_unref (G_OBJECT (list_store)); - - /* - * Create the first column packet, associating the "text" attribute of the - * cell_renderer to the first column of the model - */ - /* 1:st column */ - renderer = gtk_cell_renderer_text_new (); - column = gtk_tree_view_column_new_with_attributes ("OPC", renderer, - "text", OPC_COLUMN, - NULL); - - gtk_tree_view_column_set_sort_column_id(column, OPC_COLUMN); - gtk_tree_view_column_set_resizable(column, TRUE); - gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED); - gtk_tree_view_column_set_min_width(column, 80); - - /* Add the column to the view. */ - gtk_tree_view_append_column (list_view, column); - - /* 2:nd column... */ - renderer = gtk_cell_renderer_text_new (); - column = gtk_tree_view_column_new_with_attributes ("DPC", renderer, - "text", DPC_COLUMN, - NULL); - gtk_tree_view_column_set_sort_column_id(column, DPC_COLUMN); - gtk_tree_view_column_set_resizable(column, TRUE); - 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 (list_view, column); - - /* 3:d column... */ - renderer = gtk_cell_renderer_text_new (); - column = gtk_tree_view_column_new_with_attributes ("SI", renderer, - "text", SI_COLUMN, - NULL); - gtk_tree_view_column_set_sort_column_id(column, SI_COLUMN); - gtk_tree_view_column_set_resizable(column, TRUE); - gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED); - gtk_tree_view_column_set_min_width(column, 110); - gtk_tree_view_append_column (list_view, column); - - /* 4:th column... */ - renderer = gtk_cell_renderer_text_new (); - column = gtk_tree_view_column_new_with_attributes ("Num MSUs", renderer, - "text", NUM_MSUS_COLUMN, - NULL); - - - gtk_tree_view_column_set_sort_column_id(column, NUM_MSUS_COLUMN); - gtk_tree_view_column_set_resizable(column, TRUE); - 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 (list_view, column); - - /* 5:th column... */ - renderer = gtk_cell_renderer_text_new (); - column = gtk_tree_view_column_new_with_attributes ("Num Bytes", renderer, - "text", NUM_BYTES_COLUMN, - NULL); - - gtk_tree_view_column_set_sort_column_id(column, NUM_BYTES_COLUMN); - gtk_tree_view_column_set_resizable(column, TRUE); - 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 (list_view, column); - - /* 6:th column... */ - renderer = gtk_cell_renderer_text_new (); - column = gtk_tree_view_column_new_with_attributes ("Avg Bytes", renderer, - "text", AVG_BYTES_COLUMN, - NULL); - gtk_tree_view_column_set_cell_data_func(column, renderer, float_data_func, - GINT_TO_POINTER(AVG_BYTES_COLUMN), NULL); - - gtk_tree_view_column_set_sort_column_id(column, AVG_BYTES_COLUMN); - gtk_tree_view_column_set_resizable(column, TRUE); - 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 (list_view, column); - - /* Now enable the sorting of each column */ - gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(list_view), TRUE); - gtk_tree_view_set_headers_clickable(GTK_TREE_VIEW(list_view), TRUE); - - /* Setup the selection handler */ - selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(list)); - gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE); - - return list; - -} - -static void -mtp3_stat_reset( - void *tapdata) -{ - mtp3_stat_t (*stat_p)[MTP3_MAX_NUM_OPC_DPC] = (mtp3_stat_t(*)[MTP3_MAX_NUM_OPC_DPC])tapdata; - - mtp3_num_used = 0; - memset(stat_p, 0, MTP3_MAX_NUM_OPC_DPC * sizeof(mtp3_stat_t)); - - if (dlg.win != NULL) - { - gtk_list_store_clear(GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(dlg.table)))); - } -} - - -static gboolean -mtp3_stat_packet( - void *tapdata, - packet_info *pinfo _U_, - epan_dissect_t *edt _U_, - const void *data) -{ - mtp3_stat_t (*stat_p)[MTP3_MAX_NUM_OPC_DPC] = (mtp3_stat_t(*)[MTP3_MAX_NUM_OPC_DPC])tapdata; - const mtp3_tap_rec_t *data_p = (const mtp3_tap_rec_t *)data; - int i; - - if (data_p->mtp3_si_code >= MTP3_NUM_SI_CODE) - { - /* - * we thought this si_code was not used ? - * is MTP3_NUM_SI_CODE out of date ? - */ - return(FALSE); - } - - /* - * look for opc/dpc pair - */ - i = 0; - while (i < mtp3_num_used) - { - if (memcmp(&data_p->addr_opc, &(*stat_p)[i].addr_opc, sizeof(mtp3_addr_pc_t)) == 0) - { - if (memcmp(&data_p->addr_dpc, &(*stat_p)[i].addr_dpc, sizeof(mtp3_addr_pc_t)) == 0) - { - break; - } - } - - i++; - } - - if (i == mtp3_num_used) - { - if (mtp3_num_used == MTP3_MAX_NUM_OPC_DPC) - { - /* - * too many - */ - return(FALSE); - } - - mtp3_num_used++; - } - - (*stat_p)[i].addr_opc = data_p->addr_opc; - (*stat_p)[i].addr_dpc = data_p->addr_dpc; - (*stat_p)[i].mtp3_si_code[data_p->mtp3_si_code].num_msus++; - (*stat_p)[i].mtp3_si_code[data_p->mtp3_si_code].size += data_p->size; - - return(TRUE); -} - - -static void -mtp3_stat_draw( - void *tapdata) -{ - mtp3_stat_t (*stat_p)[MTP3_MAX_NUM_OPC_DPC] = (mtp3_stat_t(*)[MTP3_MAX_NUM_OPC_DPC])tapdata; - int i,j; - char str[256]; - float avg; - GtkListStore *list_store = NULL; - GtkTreeIter iter; - - if (!dlg.win || !tapdata) - { - return; - } - - i = 0; - - list_store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW (dlg.table))); /* Get store */ - while (i < mtp3_num_used) - { - mtp3_addr_to_str_buf(&(*stat_p)[i].addr_opc, str, 256); - dlg.entries[0] = g_strdup(str); - - mtp3_addr_to_str_buf(&(*stat_p)[i].addr_dpc, str, 256); - dlg.entries[1] = g_strdup(str); - - for (j=0; j < MTP3_NUM_SI_CODE; j++){ - /* Creates a new row at position. iter will be changed to point to this new row. - * If position is larger than the number of rows on the list, then the new row will be appended to the list. - * The row will be filled with the values given to this function. - * : - * should generally be preferred when inserting rows in a sorted list store. - */ - avg = 0.0f; - if ((*stat_p)[i].mtp3_si_code[j].num_msus !=0){ - avg = (float)(*stat_p)[i].mtp3_si_code[j].size/(float)(*stat_p)[i].mtp3_si_code[j].num_msus; - } - - - gtk_list_store_insert_with_values( list_store , &iter, G_MAXINT, - OPC_COLUMN, dlg.entries[0], - DPC_COLUMN, dlg.entries[1], - SI_COLUMN, mtp3_service_indicator_code_short_vals[j].strptr, - NUM_MSUS_COLUMN, (*stat_p)[i].mtp3_si_code[j].num_msus, - NUM_BYTES_COLUMN, (*stat_p)[i].mtp3_si_code[j].size, - AVG_BYTES_COLUMN, avg, - -1); - } - i++; - } -} - - - - -static void -mtp3_stat_gtk_win_destroy_cb( - GtkWindow *win _U_, - gpointer user_data) -{ - memset((void *) user_data, 0, sizeof(mtp3_stat_dlg_t)); -} - - -static void -mtp3_stat_gtk_win_create( - mtp3_stat_dlg_t *dlg_p, - const char *title) -{ - GtkWidget *vbox; - GtkWidget *bt_close; - GtkWidget *bbox; - - - dlg_p->win = dlg_window_new(title); /* transient_for top_level */ - gtk_window_set_destroy_with_parent (GTK_WINDOW(dlg_p->win), TRUE); - - gtk_window_set_default_size(GTK_WINDOW(dlg_p->win), 640, 390); - - vbox = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 3, FALSE); - gtk_container_add(GTK_CONTAINER(dlg_p->win), vbox); - gtk_container_set_border_width(GTK_CONTAINER(vbox), 12); - - dlg_p->scrolled_win = scrolled_window_new(NULL, NULL); - gtk_box_pack_start(GTK_BOX(vbox), dlg_p->scrolled_win, TRUE, TRUE, 0); - - dlg_p->table = create_list(); - - gtk_widget_show(dlg_p->table); - - gtk_container_add(GTK_CONTAINER(dlg_p->scrolled_win), dlg_p->table); - - /* Button row. */ - bbox = dlg_button_row_new(GTK_STOCK_CLOSE, NULL); - gtk_box_pack_start(GTK_BOX(vbox), bbox, FALSE, FALSE, 0); - - bt_close = (GtkWidget *)g_object_get_data(G_OBJECT(bbox), GTK_STOCK_CLOSE); - window_set_cancel_button(dlg_p->win, bt_close, window_cancel_button_cb); - - g_signal_connect(dlg_p->win, "delete_event", G_CALLBACK(window_delete_event_cb), NULL); - g_signal_connect(dlg_p->win, "destroy", G_CALLBACK(mtp3_stat_gtk_win_destroy_cb), dlg_p); - - gtk_widget_show_all(dlg_p->win); - window_present(dlg_p->win); -} - - -void mtp3_stat_gtk_cb(GtkAction *action _U_, gpointer user_data _U_) -{ - - /* - * if the window is already open, bring it to front - */ - if (dlg.win) - { - gdk_window_raise(gtk_widget_get_window(dlg.win)); - return; - } - - mtp3_stat_gtk_win_create(&dlg, "MTP3 Statistics"); - - mtp3_stat_draw(&mtp3_stat); -} - - -static void -mtp3_stat_gtk_init( const char *opt_arg _U_, void* userdata _U_) -{ - mtp3_stat_gtk_cb(NULL, NULL); -} - - -static stat_tap_ui mtp3_stat_ui = { - REGISTER_STAT_GROUP_GENERIC, - NULL, - "mtp3,msus", - mtp3_stat_gtk_init, - 0, - NULL -}; - -void -register_tap_listener_gtkmtp3_stat(void) -{ - GString *err_p; - - - memset((void *) &mtp3_stat, 0, sizeof(mtp3_stat_t)); - - err_p = - register_tap_listener("mtp3", &mtp3_stat, NULL, 0, - mtp3_stat_reset, - mtp3_stat_packet, - mtp3_stat_draw); - - if (err_p != NULL) - { - simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK, "%s", err_p->str); - g_string_free(err_p, TRUE); - - exit(1); - } - register_stat_tap_ui(&mtp3_stat_ui, NULL); -} - -/* - * Editor modelines - http://www.wireshark.org/tools/modelines.html - * - * Local variables: - * c-basic-offset: 4 - * tab-width: 8 - * indent-tabs-mode: nil - * End: - * - * vi: set shiftwidth=4 tabstop=8 expandtab: - * :indentSize=4:tabSize=8:noTabs=true: - */ diff --git a/ui/gtk/mtp3_summary.c b/ui/gtk/mtp3_summary.c index 85b319f8ec..11c8bfeef1 100644 --- a/ui/gtk/mtp3_summary.c +++ b/ui/gtk/mtp3_summary.c @@ -27,26 +27,38 @@ #include "config.h" -#include <string.h> +#include <stdlib.h> #include <gtk/gtk.h> -#include "epan/packet_info.h" -#include "epan/value_string.h" +#include <epan/packet_info.h> +#include <epan/stat_groups.h> +#include <epan/tap.h> +#include <epan/value_string.h> + #include <epan/dissectors/packet-mtp3.h> -#include <epan/stat_groups.h> -#include "../globals.h" -#include "../summary.h" +#include "globals.h" +#include "summary.h" + +#include "ui/simple_dialog.h" #include "ui/gtk/gui_stat_menu.h" #include "ui/gtk/dlg_utils.h" #include "ui/gtk/gui_utils.h" -#include "ui/gtk/mtp3_stat.h" #define SUM_STR_MAX 1024 -void register_tap_listener_gtkmtp3_summary(void); +typedef struct _mtp3_stat_si_code_t { + int num_msus; + int size; +} mtp3_stat_si_code_t; + +typedef struct _mtp3_stat_t { + mtp3_addr_pc_t addr_opc; + mtp3_addr_pc_t addr_dpc; + mtp3_stat_si_code_t mtp3_si_code[MTP3_NUM_SI_CODE]; +} mtp3_stat_t; typedef struct _my_columns_t { guint32 value; @@ -65,6 +77,15 @@ enum N_COLUMN /* The number of columns */ }; +/* + * I don't like it but I don't have time to create + * the code for a dynamic size solution + */ +#define MTP3_MAX_NUM_OPC_DPC 50 + +static mtp3_stat_t mtp3_stat[MTP3_MAX_NUM_OPC_DPC]; +static guint8 mtp3_num_used; + /* Create list */ static GtkWidget * create_list(void) @@ -436,9 +457,95 @@ mtp3_sum_gtk_sum_cb(GtkAction *action _U_, gpointer user_data _U_) } +static void +mtp3_summary_reset( + void *tapdata) +{ + mtp3_stat_t (*stat_p)[MTP3_MAX_NUM_OPC_DPC] = (mtp3_stat_t(*)[MTP3_MAX_NUM_OPC_DPC])tapdata; + + mtp3_num_used = 0; + memset(stat_p, 0, MTP3_MAX_NUM_OPC_DPC * sizeof(mtp3_stat_t)); +} + + +static gboolean +mtp3_summary_packet( + void *tapdata, + packet_info *pinfo _U_, + epan_dissect_t *edt _U_, + const void *data) +{ + mtp3_stat_t (*stat_p)[MTP3_MAX_NUM_OPC_DPC] = (mtp3_stat_t(*)[MTP3_MAX_NUM_OPC_DPC])tapdata; + const mtp3_tap_rec_t *data_p = (const mtp3_tap_rec_t *)data; + int i; + + if (data_p->mtp3_si_code >= MTP3_NUM_SI_CODE) + { + /* + * we thought this si_code was not used ? + * is MTP3_NUM_SI_CODE out of date ? + */ + return(FALSE); + } + + /* + * look for opc/dpc pair + */ + i = 0; + while (i < mtp3_num_used) + { + if (memcmp(&data_p->addr_opc, &(*stat_p)[i].addr_opc, sizeof(mtp3_addr_pc_t)) == 0) + { + if (memcmp(&data_p->addr_dpc, &(*stat_p)[i].addr_dpc, sizeof(mtp3_addr_pc_t)) == 0) + { + break; + } + } + + i++; + } + + if (i == mtp3_num_used) + { + if (mtp3_num_used == MTP3_MAX_NUM_OPC_DPC) + { + /* + * too many + */ + return(FALSE); + } + + mtp3_num_used++; + } + + (*stat_p)[i].addr_opc = data_p->addr_opc; + (*stat_p)[i].addr_dpc = data_p->addr_dpc; + (*stat_p)[i].mtp3_si_code[data_p->mtp3_si_code].num_msus++; + (*stat_p)[i].mtp3_si_code[data_p->mtp3_si_code].size += data_p->size; + + return(TRUE); +} + void -register_tap_listener_gtkmtp3_summary(void) +register_tap_listener_gtk_mtp3_summary(void) { + GString *err_p; + + memset((void *) &mtp3_stat, 0, sizeof(mtp3_stat)); + + err_p = + register_tap_listener("mtp3", &mtp3_stat, NULL, 0, + mtp3_summary_reset, + mtp3_summary_packet, + NULL); + + if (err_p != NULL) + { + simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK, "%s", err_p->str); + g_string_free(err_p, TRUE); + + exit(1); + } } /* diff --git a/ui/gtk/tap_param_dlg.c b/ui/gtk/tap_param_dlg.c index baf2661902..5818c26971 100644 --- a/ui/gtk/tap_param_dlg.c +++ b/ui/gtk/tap_param_dlg.c @@ -116,6 +116,7 @@ register_param_stat(tap_param_dlg *info, const char *name, case REGISTER_STAT_GROUP_TELEPHONY_ANSI: case REGISTER_STAT_GROUP_TELEPHONY_GSM: case REGISTER_STAT_GROUP_TELEPHONY_LTE: + case REGISTER_STAT_GROUP_TELEPHONY_MTP3: case REGISTER_STAT_GROUP_TELEPHONY_SCTP: break; diff --git a/ui/qt/CMakeLists.txt b/ui/qt/CMakeLists.txt index b19093f7c0..b396262dc3 100644 --- a/ui/qt/CMakeLists.txt +++ b/ui/qt/CMakeLists.txt @@ -84,6 +84,7 @@ set(WIRESHARK_QT_HEADERS main_window_preferences_frame.h manage_interfaces_dialog.h module_preferences_scroll_area.h + mtp3_summary_dialog.h multicast_statistics_dialog.h overlay_scroll_bar.h packet_comment_dialog.h @@ -290,6 +291,7 @@ set(WIRESHARK_QT_TAP_SRC funnel_statistics.cpp gsm_map_summary_dialog.cpp io_graph_dialog.cpp + mtp3_summary_dialog.cpp multicast_statistics_dialog.cpp rtp_stream_dialog.cpp sctp_all_assocs_dialog.cpp @@ -342,6 +344,7 @@ set(WIRESHARK_QT_UI main_window_preferences_frame.ui manage_interfaces_dialog.ui module_preferences_scroll_area.ui + mtp3_summary_dialog.ui packet_comment_dialog.ui packet_dialog.ui packet_format_group_box.ui diff --git a/ui/qt/Makefile.am b/ui/qt/Makefile.am index 96d9da598b..6ef89c94f0 100644 --- a/ui/qt/Makefile.am +++ b/ui/qt/Makefile.am @@ -208,6 +208,8 @@ manage_interfaces_dialog.$(OBJEXT): ui_manage_interfaces_dialog.h module_preferences_scroll_area.$(OBJEXT): ui_module_preferences_scroll_area.h +mtp3_summary_dialog.$(OBJEXT): ui_mtp3_summary_dialog.h + packet_comment_dialog.$(OBJEXT): ui_packet_comment_dialog.h packet_dialog.$(OBJEXT): ui_packet_dialog.h diff --git a/ui/qt/Makefile.common b/ui/qt/Makefile.common index dc5ce3252d..df7a11e72b 100644 --- a/ui/qt/Makefile.common +++ b/ui/qt/Makefile.common @@ -68,6 +68,7 @@ NODIST_GENERATED_HEADER_FILES = \ ui_main_window_preferences_frame.h \ ui_manage_interfaces_dialog.h \ ui_module_preferences_scroll_area.h \ + ui_mtp3_summary_dialog.h \ ui_overlay_scroll_bar.h \ ui_packet_comment_dialog.h \ ui_packet_dialog.h \ @@ -199,6 +200,7 @@ MOC_HDRS = \ manage_interfaces_dialog.h \ module_preferences_scroll_area.h \ multicast_statistics_dialog.h \ + mtp3_summary_dialog.h \ overlay_scroll_bar.h \ packet_comment_dialog.h \ packet_dialog.h \ @@ -295,6 +297,7 @@ UI_FILES = \ main_window_preferences_frame.ui \ manage_interfaces_dialog.ui \ module_preferences_scroll_area.ui \ + mtp3_summary_dialog.ui \ packet_format_group_box.ui \ packet_range_group_box.ui \ packet_comment_dialog.ui \ @@ -493,6 +496,7 @@ WIRESHARK_QT_TAP_SRC = \ funnel_statistics.cpp \ gsm_map_summary_dialog.cpp \ io_graph_dialog.cpp \ + mtp3_summary_dialog.cpp \ multicast_statistics_dialog.cpp \ rtp_stream_dialog.cpp \ sctp_all_assocs_dialog.cpp \ diff --git a/ui/qt/Wireshark.pro b/ui/qt/Wireshark.pro index 8e1445cf1f..fc870daddb 100644 --- a/ui/qt/Wireshark.pro +++ b/ui/qt/Wireshark.pro @@ -247,6 +247,7 @@ FORMS += \ main_window_preferences_frame.ui \ manage_interfaces_dialog.ui \ module_preferences_scroll_area.ui \ + mtp3_summary_dialog.ui \ packet_comment_dialog.ui \ packet_dialog.ui \ packet_format_group_box.ui \ @@ -323,6 +324,7 @@ HEADERS += $$HEADERS_WS_C \ main_window_preferences_frame.h \ manage_interfaces_dialog.h \ module_preferences_scroll_area.h \ + mtp3_summary_dialog.h \ multicast_statistics_dialog.h \ overlay_scroll_bar.h \ packet_comment_dialog.h \ @@ -710,6 +712,7 @@ SOURCES += \ main_window_slots.cpp \ manage_interfaces_dialog.cpp \ module_preferences_scroll_area.cpp \ + mtp3_summary_dialog.cpp \ multicast_statistics_dialog.cpp \ overlay_scroll_bar.cpp \ packet_comment_dialog.cpp \ diff --git a/ui/qt/gsm_map_summary_dialog.cpp b/ui/qt/gsm_map_summary_dialog.cpp index a1bb0e8f77..8edb1a7133 100644 --- a/ui/qt/gsm_map_summary_dialog.cpp +++ b/ui/qt/gsm_map_summary_dialog.cpp @@ -80,7 +80,7 @@ QString GsmMapSummaryDialog::summaryToHtml() QString section_tmpl; QString table_begin, table_end; QString table_row_begin, table_ul_row_begin, table_row_end; - QString table_vheader_tmpl, table_hheader20_tmpl, table_hheader25_tmpl; + QString table_vheader_tmpl; QString table_data_tmpl; section_tmpl = "<p><strong>%1</strong></p>\n"; @@ -90,11 +90,9 @@ QString GsmMapSummaryDialog::summaryToHtml() table_ul_row_begin = "<tr style=\"border-bottom: 1px solid gray;\">\n"; table_row_end = "</tr>\n"; table_vheader_tmpl = "<td width=\"50%\">%1:</td>"; // <th align="left"> looked odd - table_hheader20_tmpl = "<td width=\"20%\"><u>%1</u></td>"; - table_hheader25_tmpl = "<td width=\"25%\"><u>%1</u></td>"; table_data_tmpl = "<td>%1</td>"; - if (!file_closed_) { + if (cap_file_.isValid()) { /* initial computations */ summary_fill_in(cap_file_.capFile(), &summary); #ifdef HAVE_LIBPCAP diff --git a/ui/qt/gsm_map_summary_dialog.ui b/ui/qt/gsm_map_summary_dialog.ui index 925db6c943..c9723dc4d6 100644 --- a/ui/qt/gsm_map_summary_dialog.ui +++ b/ui/qt/gsm_map_summary_dialog.ui @@ -6,7 +6,7 @@ <rect> <x>0</x> <y>0</y> - <width>540</width> + <width>640</width> <height>420</height> </rect> </property> diff --git a/ui/qt/main_window.cpp b/ui/qt/main_window.cpp index 42ffbd377e..b7e4ad44d5 100644 --- a/ui/qt/main_window.cpp +++ b/ui/qt/main_window.cpp @@ -1991,6 +1991,7 @@ static QList<register_stat_group_t> menu_groups = QList<register_stat_group_t>() << REGISTER_STAT_GROUP_TELEPHONY_ANSI << REGISTER_STAT_GROUP_TELEPHONY_GSM << REGISTER_STAT_GROUP_TELEPHONY_LTE + << REGISTER_STAT_GROUP_TELEPHONY_MTP3 << REGISTER_STAT_GROUP_TELEPHONY_SCTP << REGISTER_TOOLS_GROUP_UNSORTED; @@ -2016,6 +2017,9 @@ void MainWindow::addMenuActions(QList<QAction *> &actions, int menu_group) case REGISTER_STAT_GROUP_TELEPHONY_GSM: main_ui_->menuGSM->addAction(action); break; + case REGISTER_STAT_GROUP_TELEPHONY_MTP3: + main_ui_->menuMTP3->addAction(action); + break; case REGISTER_TOOLS_GROUP_UNSORTED: { // Allow the creation of submenus. Mimics the behavor of @@ -2078,6 +2082,9 @@ void MainWindow::removeMenuActions(QList<QAction *> &actions, int menu_group) case REGISTER_STAT_GROUP_TELEPHONY_GSM: main_ui_->menuGSM->removeAction(action); break; + case REGISTER_STAT_GROUP_TELEPHONY_MTP3: + main_ui_->menuMTP3->removeAction(action); + break; case REGISTER_TOOLS_GROUP_UNSORTED: { // Allow removal of submenus. @@ -2108,6 +2115,7 @@ void MainWindow::addDynamicMenus() { // Manual additions wsApp->addDynamicMenuGroupItem(REGISTER_STAT_GROUP_TELEPHONY_GSM, main_ui_->actionTelephonyGsmMapSummary); + wsApp->addDynamicMenuGroupItem(REGISTER_STAT_GROUP_TELEPHONY_MTP3, main_ui_->actionTelephonyMtp3Summary); // Fill in each menu foreach (register_stat_group_t menu_group, menu_groups) { @@ -2124,6 +2132,12 @@ void MainWindow::addDynamicMenus() if (wsApp->dynamicMenuGroupItems(REGISTER_STAT_GROUP_TELEPHONY_ANSI).length() > 0) { main_ui_->actionTelephonyANSIPlaceholder->setVisible(false); } + if (wsApp->dynamicMenuGroupItems(REGISTER_STAT_GROUP_TELEPHONY_GSM).length() > 0) { + main_ui_->actionTelephonyGSMPlaceholder->setVisible(false); + } + if (wsApp->dynamicMenuGroupItems(REGISTER_STAT_GROUP_TELEPHONY_MTP3).length() > 0) { + main_ui_->actionTelephonyMTP3Placeholder->setVisible(false); + } } void MainWindow::reloadDynamicMenus() diff --git a/ui/qt/main_window.h b/ui/qt/main_window.h index 40e1233e5e..6b6a8c93dd 100644 --- a/ui/qt/main_window.h +++ b/ui/qt/main_window.h @@ -529,6 +529,7 @@ private slots: void openVoipCallsDialog(bool all_flows = false); void on_actionTelephonyVoipCalls_triggered(); void on_actionTelephonyGsmMapSummary_triggered(); + void on_actionTelephonyMtp3Summary_triggered(); void on_actionTelephonyISUPMessages_triggered(); void on_actionTelephonyRTPStreams_triggered(); void on_actionTelephonyRTPStreamAnalysis_triggered(); diff --git a/ui/qt/main_window.ui b/ui/qt/main_window.ui index 3c184a7dce..e40db97e1a 100644 --- a/ui/qt/main_window.ui +++ b/ui/qt/main_window.ui @@ -528,12 +528,19 @@ <property name="title"> <string>GSM</string> </property> - <addaction name="actionTelephonyANSIPlaceholder"/> + <addaction name="actionTelephonyGSMPlaceholder"/> + </widget> + <widget class="QMenu" name="menuMTP3"> + <property name="title"> + <string>MTP3</string> + </property> + <addaction name="actionTelephonyMTP3Placeholder"/> </widget> <addaction name="actionTelephonyVoipCalls"/> <addaction name="menuANSI"/> <addaction name="menuGSM"/> <addaction name="actionTelephonyISUPMessages"/> + <addaction name="menuMTP3"/> <addaction name="menuRTP"/> <addaction name="menuRTSP"/> <addaction name="menuTelephonySCTP"/> @@ -2361,6 +2368,14 @@ <string>GSM MAP summary statistics</string> </property> </action> + <action name="actionTelephonyMtp3Summary"> + <property name="text"> + <string>MTP3 Summary</string> + </property> + <property name="toolTip"> + <string>MTP3 summary statistics</string> + </property> + </action> <action name="actionTelephonyVoipCalls"> <property name="text"> <string>&VoIP Calls</string> @@ -2487,6 +2502,22 @@ <string>No ANSI statistics registered</string> </property> </action> + <action name="actionTelephonyGSMPlaceholder"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string>No GSM statistics registered</string> + </property> + </action> + <action name="actionTelephonyMTP3Placeholder"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string>No MTP3 statistics registered</string> + </property> + </action> <action name="actionStatisticsResolvedAddresses"> <property name="text"> <string>Resolved Addresses</string> diff --git a/ui/qt/main_window_slots.cpp b/ui/qt/main_window_slots.cpp index 8678847a0d..0d0ac3e4c9 100644 --- a/ui/qt/main_window_slots.cpp +++ b/ui/qt/main_window_slots.cpp @@ -109,6 +109,7 @@ #include "lbm_uimflow_dialog.h" #include "lbm_lbtrm_transport_dialog.h" #include "lbm_lbtru_transport_dialog.h" +#include "mtp3_summary_dialog.h" #include "multicast_statistics_dialog.h" #include "packet_comment_dialog.h" #include "packet_dialog.h" @@ -2971,6 +2972,12 @@ void MainWindow::on_actionTelephonyGsmMapSummary_triggered() gms_dialog->show(); } +void MainWindow::on_actionTelephonyMtp3Summary_triggered() +{ + Mtp3SummaryDialog *mtp3s_dialog = new Mtp3SummaryDialog(*this, capture_file_); + mtp3s_dialog->show(); +} + void MainWindow::on_actionTelephonyISUPMessages_triggered() { openStatisticsTreeDialog("isup_msg"); diff --git a/ui/qt/mtp3_summary_dialog.cpp b/ui/qt/mtp3_summary_dialog.cpp new file mode 100644 index 0000000000..069cfad32f --- /dev/null +++ b/ui/qt/mtp3_summary_dialog.cpp @@ -0,0 +1,404 @@ +/* mtp3_summary_dialog.cpp + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@wireshark.org> + * Copyright 1998 Gerald Combs + * + * 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 "mtp3_summary_dialog.h" +#include "ui_mtp3_summary_dialog.h" + +#include "config.h" + +#include <glib.h> + +#include "globals.h" +#include "summary.h" + +#include <epan/tap.h> + +#include <epan/dissectors/packet-mtp3.h> + +#include "ui/capture_globals.h" +#include "ui/simple_dialog.h" + +#include "qt_ui_utils.h" + +#include <QTextStream> + +typedef struct _mtp3_stat_si_code_t { + int num_msus; + int size; +} mtp3_stat_si_code_t; + +typedef struct _mtp3_stat_t { + mtp3_addr_pc_t addr_opc; + mtp3_addr_pc_t addr_dpc; + mtp3_stat_si_code_t mtp3_si_code[MTP3_NUM_SI_CODE]; +} mtp3_stat_t; + +#define MTP3_MAX_NUM_OPC_DPC 50 + +static mtp3_stat_t mtp3_stat[MTP3_MAX_NUM_OPC_DPC]; +static size_t mtp3_num_used; + +Mtp3SummaryDialog::Mtp3SummaryDialog(QWidget &parent, CaptureFile &capture_file) : + WiresharkDialog(parent, capture_file), + ui(new Ui::Mtp3SummaryDialog) +{ + ui->setupUi(this); + + setWindowSubtitle(tr("MTP3 Summary")); + updateWidgets(); +} + +Mtp3SummaryDialog::~Mtp3SummaryDialog() +{ + delete ui; +} + +QString Mtp3SummaryDialog::summaryToHtml() +{ + summary_tally summary; + memset(&summary, 0, sizeof(summary_tally)); + + QString section_tmpl; + QString table_begin, table_end; + QString table_row_begin, table_ul_row_begin, table_row_end; + QString table_vheader_tmpl, table_hheader15_tmpl, table_hheader25_tmpl; + QString table_data_tmpl; + + section_tmpl = "<p><strong>%1</strong></p>\n"; + table_begin = "<p><table>\n"; + table_end = "</table></p>\n"; + table_row_begin = "<tr>\n"; + table_ul_row_begin = "<tr style=\"border-bottom: 1px solid gray;\">\n"; + table_row_end = "</tr>\n"; + table_vheader_tmpl = "<td width=\"50%\">%1:</td>"; // <th align="left"> looked odd + table_hheader15_tmpl = "<td width=\"15%\"><u>%1</u></td>"; + table_hheader25_tmpl = "<td width=\"25%\"><u>%1</u></td>"; + table_data_tmpl = "<td>%1</td>"; + + if (cap_file_.isValid()) { + /* initial computations */ + summary_fill_in(cap_file_.capFile(), &summary); +#ifdef HAVE_LIBPCAP + summary_fill_in_capture(cap_file_.capFile(), &global_capture_opts, &summary); +#endif + } + + QString summary_str; + QTextStream out(&summary_str); + + // File Section + out << section_tmpl.arg(tr("File")); + out << table_begin; + + out << table_row_begin + << table_vheader_tmpl.arg(tr("Name")) + << table_data_tmpl.arg(summary.filename) + << table_row_end; + + out << table_row_begin + << table_vheader_tmpl.arg(tr("Length")) + << table_data_tmpl.arg(file_size_to_qstring(summary.file_length)) + << table_row_end; + + QString format_str = wtap_file_type_subtype_string(summary.file_type); + if (summary.iscompressed) { + format_str.append(tr(" (gzip compressed)")); + } + out << table_row_begin + << table_vheader_tmpl.arg(tr("Format")) + << table_data_tmpl.arg(format_str) + << table_row_end; + + if (summary.has_snap) { + out << table_row_begin + << table_vheader_tmpl.arg(tr("Snapshot length")) + << table_data_tmpl.arg(summary.snap) + << table_row_end; + } + + out << table_end; + + // Data Section + out << section_tmpl.arg(tr("Data")); + out << table_begin; + + if (summary.packet_count_ts == summary.packet_count && + summary.packet_count >= 1) + { + // start time + out << table_row_begin + << table_vheader_tmpl.arg(tr("First packet")) + << table_data_tmpl.arg(time_t_to_qstring((time_t)summary.start_time)) + << table_row_end; + + // stop time + out << table_row_begin + << table_vheader_tmpl.arg(tr("Last packet")) + << table_data_tmpl.arg(time_t_to_qstring((time_t)summary.stop_time)) + << table_row_end; + + // elapsed seconds (capture duration) + if (summary.packet_count_ts > 1) + { + /* elapsed seconds */ + QString elapsed_str; + unsigned int elapsed_time = (unsigned int)summary.elapsed_time; + if (elapsed_time/86400) + { + elapsed_str = QString("%1 days ").arg(elapsed_time / 86400); + } + + elapsed_str += QString("%1:%2:%3") + .arg(elapsed_time % 86400 / 3600, 2, 10, QChar('0')) + .arg(elapsed_time % 3600 / 60, 2, 10, QChar('0')) + .arg(elapsed_time % 60, 2, 10, QChar('0')); + out << table_row_begin + << table_vheader_tmpl.arg(tr("Elapsed")) + << table_data_tmpl.arg(elapsed_str) + << table_row_end; + } + } + + // count + out << table_row_begin + << table_vheader_tmpl.arg(tr("Packets")) + << table_data_tmpl.arg(summary.packet_count) + << table_row_end; + + out << table_end; + + // TRANSLATOR Abbreviation for "not applicable" + QString n_a = tr("N/A"); + int total_msus = 0; + int total_bytes = 0; + double seconds = summary.stop_time - summary.start_time; + + // SI Section + out << section_tmpl.arg(tr("Service Indicator (SI) Totals")); + out << table_begin; + + out << table_row_begin + << table_hheader25_tmpl.arg(tr("SI")) + << table_hheader15_tmpl.arg(tr("MSUs")) + << table_hheader15_tmpl.arg(tr("MSUs/s")) + << table_hheader15_tmpl.arg(tr("Bytes")) + << table_hheader15_tmpl.arg(tr("Bytes/MSU")) + << table_hheader15_tmpl.arg(tr("Bytes/s")) + << table_row_end; + + for (size_t si_code = 0; si_code < MTP3_NUM_SI_CODE; si_code++) { + int si_msus = 0; + int si_bytes = 0; + QString msus_s_str = n_a; + QString bytes_msu_str = n_a; + QString bytes_s_str = n_a; + + for (size_t stat_idx = 0; stat_idx < mtp3_num_used; stat_idx++) { + si_msus += mtp3_stat[stat_idx].mtp3_si_code[si_code].num_msus; + si_bytes += mtp3_stat[stat_idx].mtp3_si_code[si_code].size; + } + total_msus += si_msus; + total_bytes += si_bytes; + + if (seconds > 0) { + msus_s_str = QString("%1").arg(si_msus / seconds, 1, 'f', 1); + bytes_s_str = QString("%1").arg(si_bytes / seconds, 1, 'f', 1); + } + + if (si_msus > 0) { + bytes_msu_str = QString("%1").arg((double) si_bytes / si_msus, 1, 'f', 1); + } + + out << table_row_begin + << table_data_tmpl.arg(mtp3_service_indicator_code_short_vals[si_code].strptr) + << table_data_tmpl.arg(si_msus) + << table_data_tmpl.arg(msus_s_str) + << table_data_tmpl.arg(si_bytes) + << table_data_tmpl.arg(bytes_msu_str) + << table_data_tmpl.arg(bytes_s_str) + << table_row_end; + } + + out << table_end; + + // Totals Section + + QString total_msus_s_str = n_a; + QString total_bytes_msu_str = n_a; + QString total_bytes_s_str = n_a; + + if (seconds > 0) { + total_msus_s_str = QString("%1").arg(total_msus / seconds, 1, 'f', 1); + total_bytes_s_str = QString("%1").arg(total_bytes / seconds, 1, 'f', 1); + } + if (total_msus > 0) { + total_bytes_msu_str = QString("%1").arg((double) total_bytes / total_msus, 1, 'f', 1); + } + + out << section_tmpl.arg(tr("Totals")); + out << table_begin; + + out << table_row_begin + << table_vheader_tmpl.arg(tr("Total MSUs")) + << table_data_tmpl.arg(total_msus) + << table_row_end; + + out << table_row_begin + << table_vheader_tmpl.arg(tr("MSUs/s")) + << table_data_tmpl.arg(total_msus_s_str) + << table_row_end; + + out << table_row_begin + << table_vheader_tmpl.arg(tr("Total Bytes")) + << table_data_tmpl.arg(total_bytes) + << table_row_end; + + out << table_row_begin + << table_vheader_tmpl.arg(tr("Average Bytes/MSU")) + << table_data_tmpl.arg(total_bytes_msu_str) + << table_row_end; + + out << table_row_begin + << table_vheader_tmpl.arg(tr("Average Bytes/s")) + << table_data_tmpl.arg(total_bytes_s_str) + << table_row_end; + + out << table_end; + + return summary_str; +} + +void Mtp3SummaryDialog::updateWidgets() +{ + ui->summaryTextEdit->setHtml(summaryToHtml()); +} + +extern "C" { + +static void +mtp3_summary_reset( + void *tapdata) +{ + mtp3_stat_t (*stat_p)[MTP3_MAX_NUM_OPC_DPC] = (mtp3_stat_t(*)[MTP3_MAX_NUM_OPC_DPC])tapdata; + + mtp3_num_used = 0; + memset(stat_p, 0, MTP3_MAX_NUM_OPC_DPC * sizeof(mtp3_stat_t)); +} + + +static gboolean +mtp3_summary_packet( + void *tapdata, + packet_info *pinfo _U_, + epan_dissect_t *edt _U_, + const void *data) +{ + mtp3_stat_t (*stat_p)[MTP3_MAX_NUM_OPC_DPC] = (mtp3_stat_t(*)[MTP3_MAX_NUM_OPC_DPC])tapdata; + const mtp3_tap_rec_t *data_p = (const mtp3_tap_rec_t *)data; + size_t i; + + if (data_p->mtp3_si_code >= MTP3_NUM_SI_CODE) + { + /* + * we thought this si_code was not used ? + * is MTP3_NUM_SI_CODE out of date ? + */ + return(FALSE); + } + + /* + * look for opc/dpc pair + */ + i = 0; + while (i < mtp3_num_used) + { + if (memcmp(&data_p->addr_opc, &(*stat_p)[i].addr_opc, sizeof(mtp3_addr_pc_t)) == 0) + { + if (memcmp(&data_p->addr_dpc, &(*stat_p)[i].addr_dpc, sizeof(mtp3_addr_pc_t)) == 0) + { + break; + } + } + + i++; + } + + if (i == mtp3_num_used) + { + if (mtp3_num_used == MTP3_MAX_NUM_OPC_DPC) + { + /* + * too many + */ + return(FALSE); + } + + mtp3_num_used++; + } + + (*stat_p)[i].addr_opc = data_p->addr_opc; + (*stat_p)[i].addr_dpc = data_p->addr_dpc; + (*stat_p)[i].mtp3_si_code[data_p->mtp3_si_code].num_msus++; + (*stat_p)[i].mtp3_si_code[data_p->mtp3_si_code].size += data_p->size; + + return(TRUE); +} + +void +register_tap_listener_qt_mtp3_summary(void) +{ + GString *err_p; + + memset((void *) &mtp3_stat, 0, sizeof(mtp3_stat)); + + err_p = + register_tap_listener("mtp3", &mtp3_stat, NULL, 0, + mtp3_summary_reset, + mtp3_summary_packet, + NULL); + + if (err_p != NULL) + { + simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err_p->str); + g_string_free(err_p, TRUE); + + exit(1); + } +} + +} // extern "C" + +/* + * Editor modelines + * + * Local Variables: + * c-basic-offset: 4 + * tab-width: 8 + * indent-tabs-mode: nil + * End: + * + * ex: set shiftwidth=4 tabstop=8 expandtab: + * :indentSize=4:tabSize=8:noTabs=true: + */ diff --git a/ui/gtk/mtp3_stat.h b/ui/qt/mtp3_summary_dialog.h index 2ac9aa11f5..3c8d821db9 100644 --- a/ui/gtk/mtp3_stat.h +++ b/ui/qt/mtp3_summary_dialog.h @@ -1,7 +1,8 @@ -/* mtp3_stat.h +/* mtp3_summary_dialog.h * - * Copyright 2004, Michael Lum <mlum [AT] telostech.com>, - * In association with Telos Technology Inc. + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@wireshark.org> + * Copyright 1998 Gerald Combs * * Wireshark - Network traffic analyzer * By Gerald Combs <gerald@wireshark.org> @@ -22,32 +23,43 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#ifndef __MTP3_STAT_H__ -#define __MTP3_STAT_H__ +#ifndef MTP3_SUMMARY_DIALOG_H +#define MTP3_SUMMARY_DIALOG_H -/** @file - * Statistics for MTP3. - * @todo Could someone with more knowledge of this comment it for doxygen? - */ +#include "wireshark_dialog.h" -typedef struct _mtp3_stat_si_code_t { - int num_msus; - int size; -} mtp3_stat_si_code_t; +namespace Ui { +class Mtp3SummaryDialog; +} -typedef struct _mtp3_stat_t { - mtp3_addr_pc_t addr_opc; - mtp3_addr_pc_t addr_dpc; - mtp3_stat_si_code_t mtp3_si_code[MTP3_NUM_SI_CODE]; -} mtp3_stat_t; +class Mtp3SummaryDialog : public WiresharkDialog +{ + Q_OBJECT -/* - * I don't like it but I don't have time to create - * the code for a dynamic size solution - */ -#define MTP3_MAX_NUM_OPC_DPC 50 +public: + explicit Mtp3SummaryDialog(QWidget &parent, CaptureFile& capture_file); + ~Mtp3SummaryDialog(); + +private: + Ui::Mtp3SummaryDialog *ui; -extern mtp3_stat_t mtp3_stat[]; -extern guint8 mtp3_num_used; + QString summaryToHtml(); -#endif /* __MTP3_STAT_H__ */ +private slots: + void updateWidgets(); +}; + +#endif // MTP3_SUMMARY_DIALOG_H + +/* + * Editor modelines + * + * Local Variables: + * c-basic-offset: 4 + * tab-width: 8 + * indent-tabs-mode: nil + * End: + * + * ex: set shiftwidth=4 tabstop=8 expandtab: + * :indentSize=4:tabSize=8:noTabs=true: + */ diff --git a/ui/qt/mtp3_summary_dialog.ui b/ui/qt/mtp3_summary_dialog.ui new file mode 100644 index 0000000000..168a284170 --- /dev/null +++ b/ui/qt/mtp3_summary_dialog.ui @@ -0,0 +1,71 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>Mtp3SummaryDialog</class> + <widget class="QDialog" name="Mtp3SummaryDialog"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>640</width> + <height>420</height> + </rect> + </property> + <property name="windowTitle"> + <string>Dialog</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QTextEdit" name="summaryTextEdit"> + <property name="readOnly"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="standardButtons"> + <set>QDialogButtonBox::Close</set> + </property> + </widget> + </item> + </layout> + </widget> + <resources/> + <connections> + <connection> + <sender>buttonBox</sender> + <signal>accepted()</signal> + <receiver>Mtp3SummaryDialog</receiver> + <slot>accept()</slot> + <hints> + <hint type="sourcelabel"> + <x>248</x> + <y>254</y> + </hint> + <hint type="destinationlabel"> + <x>157</x> + <y>274</y> + </hint> + </hints> + </connection> + <connection> + <sender>buttonBox</sender> + <signal>rejected()</signal> + <receiver>Mtp3SummaryDialog</receiver> + <slot>reject()</slot> + <hints> + <hint type="sourcelabel"> + <x>316</x> + <y>260</y> + </hint> + <hint type="destinationlabel"> + <x>286</x> + <y>274</y> + </hint> + </hints> + </connection> + </connections> +</ui> |