diff options
-rw-r--r-- | epan/dissectors/packet-rpc.c | 164 | ||||
-rw-r--r-- | epan/stat_tap_ui.h | 11 | ||||
-rw-r--r-- | ui/gtk/CMakeLists.txt | 1 | ||||
-rw-r--r-- | ui/gtk/Makefile.common | 1 | ||||
-rw-r--r-- | ui/gtk/main_menubar.c | 2 | ||||
-rw-r--r-- | ui/gtk/rpc_progs.c | 450 | ||||
-rw-r--r-- | ui/qt/simple_statistics_dialog.cpp | 21 | ||||
-rw-r--r-- | ui/qt/simple_statistics_dialog.h | 4 |
8 files changed, 191 insertions, 463 deletions
diff --git a/epan/dissectors/packet-rpc.c b/epan/dissectors/packet-rpc.c index d192f0d81d..69702e1254 100644 --- a/epan/dissectors/packet-rpc.c +++ b/epan/dissectors/packet-rpc.c @@ -33,6 +33,7 @@ #include <epan/prefs.h> #include <epan/reassemble.h> #include <epan/tap.h> +#include <epan/stat_tap_ui.h> #include <epan/srt_table.h> #include <epan/strutil.h> #include <epan/show_exception.h> @@ -3810,6 +3811,149 @@ rpc_cleanup_protocol(void) g_hash_table_destroy(rpc_reassembly_table); } +/* Tap statistics */ +typedef enum +{ + PROGRAM_NAME_COLUMN, + PROGRAM_NUM_COLUMN, + VERSION_COLUMN, + CALLS_COLUMN, + MIN_SRT_COLUMN, + MAX_SRT_COLUMN, + AVG_SRT_COLUMN +} rpc_prog_stat_columns; + +static stat_tap_table_item rpc_prog_stat_fields[] = { + {TABLE_ITEM_STRING, TAP_ALIGN_LEFT, "Program", "%-25s"}, + {TABLE_ITEM_UINT, TAP_ALIGN_RIGHT, "Program Num", "%u"}, + {TABLE_ITEM_UINT, TAP_ALIGN_RIGHT, "Version", "%u"}, + {TABLE_ITEM_UINT, TAP_ALIGN_RIGHT, "Calls", "%u"}, + {TABLE_ITEM_FLOAT, TAP_ALIGN_RIGHT, "Min SRT (s)", "%.2f"}, + {TABLE_ITEM_FLOAT, TAP_ALIGN_RIGHT, "Max SRT (s)", "%.2f"}, + {TABLE_ITEM_FLOAT, TAP_ALIGN_RIGHT, "Avg SRT (s)", "%.2f"} +}; + +void rpc_prog_stat_init(new_stat_tap_ui* new_stat, new_stat_tap_gui_init_cb gui_callback, void* gui_data) +{ + int num_fields = sizeof(rpc_prog_stat_fields)/sizeof(stat_tap_table_item); + new_stat_tap_table* table; + + table = new_stat_tap_init_table("ONC-RPC Program Statistics", num_fields, 0, NULL, gui_callback, gui_data); + new_stat_tap_add_table(new_stat, table); + +} + +static gboolean +rpc_prog_stat_packet(void *tapdata, packet_info *pinfo _U_, epan_dissect_t *edt _U_, const void *rciv_ptr) +{ + new_stat_data_t* stat_data = (new_stat_data_t*)tapdata; + const rpc_call_info_value *ri = (const rpc_call_info_value *)rciv_ptr; + int num_fields = sizeof(rpc_prog_stat_fields)/sizeof(stat_tap_table_item); + nstime_t delta; + double delta_s = 0.0; + guint call_count; + guint element; + gboolean found = FALSE; + new_stat_tap_table* table; + stat_tap_table_item_type* item_data; + + 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 *program_data, *version_data; + program_data = new_stat_tap_get_field_data(table, element, PROGRAM_NUM_COLUMN); + version_data = new_stat_tap_get_field_data(table, element, VERSION_COLUMN); + + if ((ri->prog == program_data->value.uint_value) && (ri->vers == version_data->value.uint_value)) { + found = TRUE; + break; + } + } + + if (!found) { + /* Add a new row */ + stat_tap_table_item_type items[sizeof(rpc_prog_stat_fields)/sizeof(stat_tap_table_item)]; + memset(items, 0, sizeof(items)); + + items[PROGRAM_NAME_COLUMN].type = TABLE_ITEM_STRING; + items[PROGRAM_NAME_COLUMN].value.string_value = g_strdup(rpc_prog_name(ri->prog)); + items[PROGRAM_NUM_COLUMN].type = TABLE_ITEM_UINT; + items[PROGRAM_NUM_COLUMN].value.uint_value = ri->prog; + items[VERSION_COLUMN].type = TABLE_ITEM_UINT; + items[VERSION_COLUMN].value.uint_value = ri->vers; + items[CALLS_COLUMN].type = TABLE_ITEM_UINT; + items[MIN_SRT_COLUMN].type = TABLE_ITEM_FLOAT; + items[MAX_SRT_COLUMN].type = TABLE_ITEM_FLOAT; + items[AVG_SRT_COLUMN].type = TABLE_ITEM_FLOAT; + + new_stat_tap_init_table_row(table, element, num_fields, items); + } + + /* we are only interested in reply packets */ + if (ri->request) { + return FALSE; + } + + item_data = new_stat_tap_get_field_data(table, element, CALLS_COLUMN); + item_data->value.uint_value++; + call_count = item_data->value.uint_value; + new_stat_tap_set_field_data(table, element, CALLS_COLUMN, item_data); + + /* calculate time delta between request and reply */ + nstime_delta(&delta, &pinfo->fd->abs_ts, &ri->req_time); + delta_s = nstime_to_sec(&delta); + + item_data = new_stat_tap_get_field_data(table, element, MIN_SRT_COLUMN); + if (item_data->value.float_value == 0.0 || delta_s < item_data->value.float_value) { + item_data->value.float_value = delta_s; + new_stat_tap_set_field_data(table, element, MIN_SRT_COLUMN, item_data); + } + + item_data = new_stat_tap_get_field_data(table, element, MAX_SRT_COLUMN); + if (item_data->value.float_value == 0.0 || delta_s > item_data->value.float_value) { + item_data->value.float_value = delta_s; + new_stat_tap_set_field_data(table, element, MAX_SRT_COLUMN, item_data); + } + + item_data = new_stat_tap_get_field_data(table, element, AVG_SRT_COLUMN); + item_data->user_data.float_value += delta_s; + item_data->value.float_value = item_data->user_data.float_value / call_count; + new_stat_tap_set_field_data(table, element, AVG_SRT_COLUMN, item_data); + + return TRUE; +} + +static void +rpc_prog_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, CALLS_COLUMN); + item_data->value.uint_value = 0; + new_stat_tap_set_field_data(table, element, CALLS_COLUMN, item_data); + item_data = new_stat_tap_get_field_data(table, element, MIN_SRT_COLUMN); + item_data->value.float_value = 0.0; + new_stat_tap_set_field_data(table, element, MIN_SRT_COLUMN, item_data); + item_data = new_stat_tap_get_field_data(table, element, MAX_SRT_COLUMN); + item_data->value.float_value = 0.0; + new_stat_tap_set_field_data(table, element, MAX_SRT_COLUMN, item_data); + item_data = new_stat_tap_get_field_data(table, element, AVG_SRT_COLUMN); + item_data->value.float_value = 0.0; + new_stat_tap_set_field_data(table, element, AVG_SRT_COLUMN, item_data); + } +} + +static void +rpc_prog_stat_free_table_item(new_stat_tap_table* table _U_, guint row _U_, guint column, stat_tap_table_item_type* field_data) +{ + if (column != PROGRAM_NAME_COLUMN) return; + g_free((char*)field_data->value.string_value); +} + /* will be called once from register.c at startup time */ void proto_register_rpc(void) @@ -4076,6 +4220,25 @@ proto_register_rpc(void) module_t *rpc_module; expert_module_t* expert_rpc; + static tap_param rpc_prog_stat_params[] = { + { PARAM_FILTER, "filter", "Filter", NULL, TRUE } + }; + + static new_stat_tap_ui rpc_prog_stat_table = { + REGISTER_STAT_GROUP_UNSORTED, + "ONC-RPC Programs", + "rpc", + "rpc,programs", + rpc_prog_stat_init, + rpc_prog_stat_packet, + rpc_prog_stat_reset, + rpc_prog_stat_free_table_item, + NULL, + sizeof(rpc_prog_stat_fields)/sizeof(stat_tap_table_item), rpc_prog_stat_fields, + sizeof(rpc_prog_stat_params)/sizeof(tap_param), rpc_prog_stat_params, + NULL + }; + proto_rpc = proto_register_protocol("Remote Procedure Call", "RPC", "rpc"); subdissector_call_table = register_custom_dissector_table("rpc.call", "RPC Call Functions", rpc_proc_hash, rpc_proc_equal); @@ -4121,6 +4284,7 @@ proto_register_rpc(void) rpc_tap = register_tap("rpc"); register_srt_table(proto_rpc, NULL, 1, rpcstat_packet, rpcstat_init, rpcstat_param); + register_new_stat_tap_ui(&rpc_prog_stat_table); /* * Init the hash tables. Dissectors for RPC protocols must diff --git a/epan/stat_tap_ui.h b/epan/stat_tap_ui.h index 4689cd6293..4f1c99e7c4 100644 --- a/epan/stat_tap_ui.h +++ b/epan/stat_tap_ui.h @@ -87,6 +87,17 @@ typedef struct _stat_tap_table_item_type gfloat float_value; gint enum_value; } value; + /* Scratch space for the dissector. Alternatively we could also add support + * for hidden columns. */ + union + { + guint uint_value; + gint int_value; + const char* string_value; + gfloat float_value; + gint enum_value; + void* ptr_value; + } user_data; } stat_tap_table_item_type; /* Possible alignments */ diff --git a/ui/gtk/CMakeLists.txt b/ui/gtk/CMakeLists.txt index fa0a7a9019..923bd57284 100644 --- a/ui/gtk/CMakeLists.txt +++ b/ui/gtk/CMakeLists.txt @@ -213,7 +213,6 @@ set(WIRESHARK_TAP_SRC mtp3_summary.c rlc_lte_graph.c rlc_lte_stat_dlg.c - rpc_progs.c rpc_stat.c rtp_analysis.c rtp_stream_dlg.c diff --git a/ui/gtk/Makefile.common b/ui/gtk/Makefile.common index 143a6e1b78..b9e2cb6a56 100644 --- a/ui/gtk/Makefile.common +++ b/ui/gtk/Makefile.common @@ -164,7 +164,6 @@ WIRESHARK_TAP_SRC = \ mtp3_summary.c \ rlc_lte_graph.c \ rlc_lte_stat_dlg.c \ - rpc_progs.c \ rpc_stat.c \ rtp_analysis.c \ rtp_stream_dlg.c \ diff --git a/ui/gtk/main_menubar.c b/ui/gtk/main_menubar.c index ad916efa5f..3244c1c448 100644 --- a/ui/gtk/main_menubar.c +++ b/ui/gtk/main_menubar.c @@ -1059,7 +1059,6 @@ static const char *ui_desc_menubar = " <menuitem name='http_srv' action='/Statistics/HTTP/http_srv'/>\n" " </menu>\n" " <menuitem name='HTTP2' action='/Statistics/http2'/>\n" -" <menuitem name='ONC-RPC-Programs' action='/Statistics/ONC-RPC-Programs'/>\n" " <menu name= 'SametimeMenu' action='/Statistics/Sametime'>\n" " <menuitem name='sametime' action='/Statistics/Sametime/sametime'/>\n" " </menu>\n" @@ -1477,7 +1476,6 @@ static const GtkActionEntry main_menu_bar_entries[] = { { "/Statistics/HTTP/http_req", NULL, "Requests", NULL, NULL, G_CALLBACK(gtk_stats_tree_cb) }, { "/Statistics/HTTP/http_srv", NULL, "Load Distribution", NULL, NULL, G_CALLBACK(gtk_stats_tree_cb) }, { "/Statistics/http2", NULL, "HTTP2", NULL, NULL, G_CALLBACK(gtk_stats_tree_cb) }, - { "/Statistics/ONC-RPC-Programs", NULL, "ONC-RPC Programs", NULL, NULL, G_CALLBACK(gtk_rpcprogs_cb) }, { "/Statistics/Sametime", NULL, "Sametime", NULL, NULL, NULL }, { "/Statistics/Sametime/sametime", NULL, "Messages", NULL, NULL, G_CALLBACK(gtk_stats_tree_cb) }, { "/Statistics/TCPStreamGraphMenu", NULL, "TCP StreamGraph", NULL, NULL, NULL }, diff --git a/ui/gtk/rpc_progs.c b/ui/gtk/rpc_progs.c deleted file mode 100644 index d60a2cbec7..0000000000 --- a/ui/gtk/rpc_progs.c +++ /dev/null @@ -1,450 +0,0 @@ -/* rpc_progs.c - * rpc_progs 2002 Ronnie Sahlberg - * - * 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 module provides rpc call/reply SRT statistics to Wireshark. - * It is only used by Wireshark and not TShark - * - * It serves as an example on how to use the tap api. - */ - -#include "config.h" - -#include <stdlib.h> - -#include <gtk/gtk.h> - -#include <epan/packet_info.h> -#include <epan/stat_tap_ui.h> -#include <epan/tap.h> -#include <epan/dissectors/packet-rpc.h> - - -#include "ui/gtk/gui_stat_menu.h" -#include "ui/gtk/gui_utils.h" -#include "ui/gtk/dlg_utils.h" -#include "ui/gtk/main.h" - - -#define NANOSECS_PER_SEC 1000000000 - -void register_tap_listener_gtkrpcprogs(void); - -static GtkWidget *win = NULL; -static GtkWidget *grid = NULL; -static int num_progs = 0; - -/* used to keep track of statistics for a specific program/version */ -typedef struct _rpc_program_t { - struct _rpc_program_t *next; - - guint32 program; - GtkWidget *wprogram; - gchar sprogram[24]; - - guint32 version; - GtkWidget *wversion; - gchar sversion[16]; - - int num; - GtkWidget *wnum; - gchar snum[16]; - - nstime_t min; - GtkWidget *wmin; - gchar smin[16]; - - nstime_t max; - GtkWidget *wmax; - gchar smax[16]; - - nstime_t tot; - GtkWidget *wavg; - gchar savg[16]; -} rpc_program_t; - -static rpc_program_t *prog_list = NULL; - - -static char * -rpcprogs_gen_title(void) -{ - char *display_name; - char *title; - - display_name = cf_get_display_name(&cfile); - title = g_strdup_printf("ONC-RPC Program Statistics: %s", - display_name); - g_free(display_name); - return title; -} - -static void -rpcprogs_init_grid(GtkWidget *grid_parent) -{ - GtkWidget *tmp; - - grid = ws_gtk_grid_new(); - ws_gtk_grid_set_homogeneous(GTK_GRID(grid), TRUE); - - gtk_container_add(GTK_CONTAINER(grid_parent), grid); - - tmp = gtk_label_new("Program"); - ws_gtk_grid_attach_defaults(GTK_GRID(grid), tmp, 0, 0, 1, 1); - gtk_label_set_justify(GTK_LABEL(tmp), GTK_JUSTIFY_LEFT); - - tmp = gtk_label_new("Version"); - ws_gtk_grid_attach_defaults(GTK_GRID(grid), tmp, 1, 0, 1, 1); - gtk_label_set_justify(GTK_LABEL(tmp), GTK_JUSTIFY_RIGHT); - - tmp = gtk_label_new("Calls"); - ws_gtk_grid_attach_defaults(GTK_GRID(grid), tmp, 2, 0, 1, 1); - gtk_label_set_justify(GTK_LABEL(tmp), GTK_JUSTIFY_RIGHT); - - tmp = gtk_label_new("Min SRT"); - ws_gtk_grid_attach_defaults(GTK_GRID(grid), tmp, 3, 0, 1, 1); - gtk_label_set_justify(GTK_LABEL(tmp), GTK_JUSTIFY_RIGHT); - - tmp = gtk_label_new("Max SRT"); - ws_gtk_grid_attach_defaults(GTK_GRID(grid), tmp, 4, 0, 1, 1); - gtk_label_set_justify(GTK_LABEL(tmp), GTK_JUSTIFY_RIGHT); - - tmp = gtk_label_new("Avg SRT"); - ws_gtk_grid_attach_defaults(GTK_GRID(grid), tmp, 5, 0, 1, 1); - gtk_label_set_justify(GTK_LABEL(tmp), GTK_JUSTIFY_RIGHT); -} - - - -static void -rpcprogs_reset(void *dummy _U_) -{ - GtkWidget *grid_parent; - rpc_program_t *rp; - - while (prog_list) { - rp = prog_list; - prog_list = prog_list->next; - g_free(rp); - } - num_progs = 0; - - grid_parent = gtk_widget_get_parent(grid); - gtk_widget_destroy(grid); /* also destroys the widgets contained within the grid */ - grid = NULL; - - rpcprogs_init_grid(grid_parent); - gtk_widget_show(grid); - -} - -static void -add_new_program(rpc_program_t *rp) -{ - num_progs++; - - rp->wprogram = gtk_label_new("0"); - ws_gtk_grid_attach_defaults(GTK_GRID(grid), rp->wprogram, 0, num_progs, 1, 1); - gtk_widget_show(rp->wprogram); - - rp->wversion = gtk_label_new("0"); - ws_gtk_grid_attach_defaults(GTK_GRID(grid), rp->wversion, 1, num_progs, 1, 1); - gtk_widget_show(rp->wversion); - - rp->wnum = gtk_label_new("0"); - ws_gtk_grid_attach_defaults(GTK_GRID(grid), rp->wnum, 2, num_progs, 1, 1); - gtk_widget_show(rp->wnum); - - rp->wmin = gtk_label_new("0"); - ws_gtk_grid_attach_defaults(GTK_GRID(grid), rp->wmin, 3, num_progs, 1, 1); - gtk_widget_show(rp->wmin); - - rp->wmax = gtk_label_new("0"); - ws_gtk_grid_attach_defaults(GTK_GRID(grid), rp->wmax, 4, num_progs, 1, 1); - gtk_widget_show(rp->wmax); - - rp->wavg = gtk_label_new("0"); - ws_gtk_grid_attach_defaults(GTK_GRID(grid), rp->wavg, 5, num_progs, 1, 1); - gtk_widget_show(rp->wavg); - - rp->num = 0; - rp->min.secs = 0; - rp->min.nsecs = 0; - rp->max.secs = 0; - rp->max.nsecs = 0; - rp->tot.secs = 0; - rp->tot.nsecs = 0; -} - - - -static gboolean -rpcprogs_packet(void *dummy _U_, packet_info *pinfo, epan_dissect_t *edt _U_, const void *arg) -{ - const rpc_call_info_value *ri = (const rpc_call_info_value *)arg; - nstime_t delta; - rpc_program_t *rp; - - if (!prog_list) { - /* the list was empty */ - rp = (rpc_program_t *)g_malloc(sizeof(rpc_program_t)); - add_new_program(rp); - rp->next = NULL; - rp->program = ri->prog; - rp->version = ri->vers; - prog_list = rp; - } else if ((ri->prog == prog_list->program) && (ri->vers == prog_list->version)) { - rp = prog_list; - } else if ( (ri->prog < prog_list->program) - || ((ri->prog == prog_list->program) && (ri->vers < prog_list->version))) { - /* we should be first entry in list */ - rp = (rpc_program_t *)g_malloc(sizeof(rpc_program_t)); - add_new_program(rp); - rp->next = prog_list; - rp->program = ri->prog; - rp->version = ri->vers; - prog_list = rp; - } else { - /* we go somewhere else in the list */ - for (rp = prog_list; rp; rp = rp->next) { - if ((rp->next) - && (rp->next->program == ri->prog) - && (rp->next->version == ri->vers)) { - rp = rp->next; - break; - } - if ((!rp->next) - || (rp->next->program > ri->prog) - || ( (rp->next->program == ri->prog) - && (rp->next->version > ri->vers))) { - rpc_program_t *trp; - trp = (rpc_program_t *)g_malloc(sizeof(rpc_program_t)); - add_new_program(trp); - trp->next = rp->next; - trp->program = ri->prog; - trp->version = ri->vers; - rp->next = trp; - rp = trp; - break; - } - } - } - - - /* we are only interested in reply packets */ - if (ri->request || !rp) { - return FALSE; - } - - /* calculate time delta between request and reply */ - nstime_delta(&delta, &pinfo->fd->abs_ts, &ri->req_time); - - if ((rp->max.secs == 0) - && (rp->max.nsecs == 0) ) { - rp->max.secs = delta.secs; - rp->max.nsecs = delta.nsecs; - } - - if ((rp->min.secs == 0) - && (rp->min.nsecs == 0) ) { - rp->min.secs = delta.secs; - rp->min.nsecs = delta.nsecs; - } - - if ( (delta.secs < rp->min.secs) - || ( (delta.secs == rp->min.secs) - && (delta.nsecs < rp->min.nsecs) ) ) { - rp->min.secs = delta.secs; - rp->min.nsecs = delta.nsecs; - } - - if ( (delta.secs > rp->max.secs) - || ( (delta.secs == rp->max.secs) - && (delta.nsecs > rp->max.nsecs) ) ) { - rp->max.secs = delta.secs; - rp->max.nsecs = delta.nsecs; - } - - rp->tot.secs += delta.secs; - rp->tot.nsecs += delta.nsecs; - if (rp->tot.nsecs > NANOSECS_PER_SEC) { - rp->tot.nsecs -= NANOSECS_PER_SEC; - rp->tot.secs++; - } - rp->num++; - - return TRUE; -} - - -static void -rpcprogs_draw(void *dummy _U_) -{ - rpc_program_t *rp; - int i; - guint64 td; - - for (rp=prog_list,i=1; rp; rp=rp->next,i++) { - /* Ignore procedures with no calls */ - if (rp->num == 0) { - continue; - } - /* Scale the average SRT in units of 1us and round to the nearest us. - tot.secs is a time_t which may be 32 or 64 bits (or even floating) - depending on the platform. After casting tot.secs to a 64 bits int, it - would take a capture with a duration of over 136 *years* to - overflow the secs portion of td. */ - td = ((guint64)(rp->tot.secs))*NANOSECS_PER_SEC + rp->tot.nsecs; - td = ((td / rp->num) + 500) / 1000; - - g_snprintf(rp->sprogram, sizeof(rp->sprogram), "%s",rpc_prog_name(rp->program)); - gtk_label_set_text(GTK_LABEL(rp->wprogram), rp->sprogram); - - g_snprintf(rp->sversion, sizeof(rp->sversion), "%d",rp->version); - gtk_label_set_text(GTK_LABEL(rp->wversion), rp->sversion); - - g_snprintf(rp->snum, sizeof(rp->snum), "%d",rp->num); - gtk_label_set_text(GTK_LABEL(rp->wnum), rp->snum); - - g_snprintf(rp->smin, sizeof(rp->smin), "%3d.%06d",(int)rp->min.secs, (rp->min.nsecs+500)/1000); - gtk_label_set_text(GTK_LABEL(rp->wmin), rp->smin); - - g_snprintf(rp->smax, sizeof(rp->smax), "%3d.%06d",(int)rp->max.secs, (rp->max.nsecs+500)/1000); - gtk_label_set_text(GTK_LABEL(rp->wmax), rp->smax); - - g_snprintf(rp->savg, sizeof(rp->savg), "%3d.%06d",(int)(td/1000000),(int)(td%1000000)); - gtk_label_set_text(GTK_LABEL(rp->wavg), rp->savg); - - } -} - -static void -win_destroy_cb(void *dummy _U_, gpointer data _U_) -{ - rpc_program_t *rp, *rp2; - - remove_tap_listener(win); - - win = NULL; - for (rp=prog_list; rp;) { - rp2 = rp->next; - g_free(rp); - rp = rp2; - } - prog_list = NULL; -} - - -/* When called, this function will start rpcprogs - */ -static void -gtk_rpcprogs_init(const char *opt_arg _U_, void* userdata _U_) -{ - char *title_string; - GtkWidget *vbox; - GtkWidget *stat_label; - GtkWidget *grid_parent; - GString *error_string; - GtkWidget *bt_close; - GtkWidget *bbox; - - if (win) { - gdk_window_raise(gtk_widget_get_window(win)); - return; - } - - title_string = rpcprogs_gen_title(); - win = dlg_window_new(title_string); /* transient_for top_level */ - gtk_window_set_destroy_with_parent(GTK_WINDOW(win), TRUE); - - vbox = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 3, FALSE); - gtk_container_add(GTK_CONTAINER(win), vbox); - gtk_container_set_border_width(GTK_CONTAINER(vbox), 12); - - stat_label = gtk_label_new(title_string); - g_free(title_string); - gtk_box_pack_start(GTK_BOX(vbox), stat_label, FALSE, FALSE, 0); - - /* wrap grid in a dummy container so that the grid can be */ - /* destroyed and re-created as needed. */ - /* XXX: This is a kludge; Better: Use a GtkTreeView & etc. */ - grid_parent = ws_gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0, TRUE); - gtk_box_pack_start(GTK_BOX(vbox), grid_parent, TRUE, TRUE, 0); - rpcprogs_init_grid(grid_parent); - - error_string = register_tap_listener("rpc", win, NULL, 0, rpcprogs_reset, rpcprogs_packet, rpcprogs_draw); - if (error_string) { - fprintf(stderr, "wireshark: Couldn't register rpc,programs tap: %s\n", - error_string->str); - g_string_free(error_string, TRUE); - exit(1); - } - - /* 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(win, bt_close, window_cancel_button_cb); - - g_signal_connect(win, "delete_event", G_CALLBACK(window_delete_event_cb), NULL); - g_signal_connect(win, "destroy", G_CALLBACK(win_destroy_cb), NULL); - - gtk_widget_show_all(win); - window_present(win); - - cf_retap_packets(&cfile); - gdk_window_raise(gtk_widget_get_window(win)); -} - -void -gtk_rpcprogs_cb(GtkWidget *w _U_, gpointer data _U_) -{ - gtk_rpcprogs_init("", NULL); -} - -static stat_tap_ui rpcprogs_ui = { - REGISTER_STAT_GROUP_GENERIC, - NULL, - "rpc,programs", - gtk_rpcprogs_init, - 0, - NULL -}; - -void -register_tap_listener_gtkrpcprogs(void) -{ - register_stat_tap_ui(&rpcprogs_ui, NULL); -} - -/* - * Editor modelines - http://www.wireshark.org/tools/modelines.html - * - * Local variables: - * c-basic-offset: 8 - * tab-width: 8 - * indent-tabs-mode: t - * End: - * - * vi: set shiftwidth=8 tabstop=8 noexpandtab: - * :indentSize=8:tabSize=8:noTabs=false: - */ diff --git a/ui/qt/simple_statistics_dialog.cpp b/ui/qt/simple_statistics_dialog.cpp index ed77b3655e..285c002911 100644 --- a/ui/qt/simple_statistics_dialog.cpp +++ b/ui/qt/simple_statistics_dialog.cpp @@ -188,7 +188,7 @@ TapParameterDialog *SimpleStatisticsDialog::createSimpleStatisticsDialog(QWidget return new SimpleStatisticsDialog(parent, cf, stu, filter); } -void SimpleStatisticsDialog::addSimpleStatisticsTable(const _stat_tap_table *st_table) +void SimpleStatisticsDialog::addMissingRows(struct _new_stat_data_t *stat_data) { // Hierarchy: // - tables (GTK+ UI only supports one currently) @@ -197,11 +197,18 @@ void SimpleStatisticsDialog::addSimpleStatisticsTable(const _stat_tap_table *st_ // For multiple table support we might want to add them as subtrees, with // the top-level tree item text set to the column labels for that table. - for (guint element = 0; element < st_table->num_elements; element++) { + // Add any missing rows. + guint table_index = 0; + new_stat_tap_table* st_table = g_array_index(stat_data->new_stat_tap_data->tables, new_stat_tap_table*, table_index); + for (guint element = statsTreeWidget()->topLevelItemCount(); element < st_table->num_elements; element++) { stat_tap_table_item_type* fields = new_stat_tap_get_field_data(st_table, element, 0); - new SimpleStatisticsTreeWidgetItem(statsTreeWidget(), st_table->num_fields, fields); + SimpleStatisticsTreeWidgetItem *ss_ti = new SimpleStatisticsTreeWidgetItem(statsTreeWidget(), st_table->num_fields, fields); + for (int col = 0; col < (int) stu_->nfields; col++) { + if (stu_->fields[col].align == TAP_ALIGN_RIGHT) { + ss_ti->setTextAlignment(col, Qt::AlignRight); + } + } } - } void SimpleStatisticsDialog::tapReset(void *sd_ptr) @@ -212,10 +219,6 @@ void SimpleStatisticsDialog::tapReset(void *sd_ptr) reset_stat_table(sd->new_stat_tap_data, NULL, NULL); ss_dlg->statsTreeWidget()->clear(); - - guint table_index = 0; - new_stat_tap_table* st_table = g_array_index(sd->new_stat_tap_data->tables, new_stat_tap_table*, table_index); - ss_dlg->addSimpleStatisticsTable(st_table); } void SimpleStatisticsDialog::tapDraw(void *sd_ptr) @@ -224,6 +227,8 @@ void SimpleStatisticsDialog::tapDraw(void *sd_ptr) SimpleStatisticsDialog *ss_dlg = static_cast<SimpleStatisticsDialog *>(sd->user_data); if (!ss_dlg) return; + ss_dlg->addMissingRows(sd); + QTreeWidgetItemIterator it(ss_dlg->statsTreeWidget()); while (*it) { if ((*it)->type() == simple_row_type_) { diff --git a/ui/qt/simple_statistics_dialog.h b/ui/qt/simple_statistics_dialog.h index 60938f2755..befd654d4b 100644 --- a/ui/qt/simple_statistics_dialog.h +++ b/ui/qt/simple_statistics_dialog.h @@ -24,6 +24,8 @@ #include "tap_parameter_dialog.h" +struct _new_stat_data_t; + class SimpleStatisticsDialog : public TapParameterDialog { Q_OBJECT @@ -38,7 +40,7 @@ protected: * @param st_table The table to add. */ // gtk:service_response_table.h:init_srt_table - void addSimpleStatisticsTable(const struct _stat_tap_table *st_table); + void addMissingRows(struct _new_stat_data_t *stat_data); private: struct _new_stat_tap_ui *stu_; |