2 * fc_stat 2003 Ronnie Sahlberg
6 * Ethereal - Network traffic analyzer
7 * By Gerald Combs <gerald@ethereal.com>
8 * Copyright 1998 Gerald Combs
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 2
13 * of the License, or (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
29 #ifdef HAVE_SYS_TYPES_H
30 # include <sys/types.h>
37 #include <epan/packet_info.h>
38 #include <epan/epan.h>
39 #include <epan/value_string.h>
42 #include "stat_menu.h"
44 #include <epan/dissectors/packet-fc.h>
45 #include "../register.h"
46 #include "../timestats.h"
47 #include "compat_macros.h"
48 #include "../simple_dialog.h"
50 #include "dlg_utils.h"
52 #include "../globals.h"
53 #include "filter_dlg.h"
54 #include "service_response_time_table.h"
55 #include "gtkglobals.h"
58 /* used to keep track of the statistics for an entire program interface */
59 typedef struct _fcstat_t {
61 srt_stat_table fc_srt_table;
65 fcstat_set_title(fcstat_t *fc)
69 title = g_strdup_printf("Fibre Channel Service Response Time statistics: %s",
70 cf_get_display_name(&cfile));
71 gtk_window_set_title(GTK_WINDOW(fc->win), title);
76 fcstat_reset(void *pfc)
78 fcstat_t *fc=(fcstat_t *)pfc;
80 reset_srt_table_data(&fc->fc_srt_table);
85 fcstat_packet(void *pfc, packet_info *pinfo, epan_dissect_t *edt _U_, const void *psi)
88 fcstat_t *fs=(fcstat_t *)pfc;
90 /* we are only interested in reply packets */
91 if(!(fc->fctl&FC_FCTL_EXCHANGE_RESPONDER)){
94 /* if we havnt seen the request, just ignore it */
95 if( (!fc->fced) || (fc->fced->first_exchange_frame==0) ){
99 add_srt_table_data(&fs->fc_srt_table, fc->type, &fc->fced->fc_time, pinfo);
107 fcstat_draw(void *pfc)
109 fcstat_t *fc=(fcstat_t *)pfc;
111 draw_srt_table_data(&fc->fc_srt_table);
115 void protect_thread_critical_region(void);
116 void unprotect_thread_critical_region(void);
118 win_destroy_cb(GtkWindow *win _U_, gpointer data)
120 fcstat_t *fc=(fcstat_t *)data;
122 protect_thread_critical_region();
123 remove_tap_listener(fc);
124 unprotect_thread_critical_region();
126 free_srt_table_data(&fc->fc_srt_table);
132 gtk_fcstat_init(const char *optarg)
135 const char *filter=NULL;
137 char filter_string[256];
138 GString *error_string;
144 if(!strncmp(optarg,"fc,srt,",7)){
150 fc=g_malloc(sizeof(fcstat_t));
152 fc->win=window_new(GTK_WINDOW_TOPLEVEL, "fc-stat");
153 gtk_window_set_default_size(GTK_WINDOW(fc->win), 550, 400);
154 fcstat_set_title(fc);
156 vbox=gtk_vbox_new(FALSE, 3);
157 gtk_container_add(GTK_CONTAINER(fc->win), vbox);
158 gtk_container_set_border_width(GTK_CONTAINER(vbox), 12);
160 label=gtk_label_new("Fibre Channel Service Response Time statistics");
161 gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
163 g_snprintf(filter_string,255,"Filter:%s",filter?filter:"");
164 label=gtk_label_new(filter_string);
165 gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
167 label=gtk_label_new("Fibre Channel Types");
168 gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
170 /* We must display TOP LEVEL Widget before calling init_srt_table() */
171 gtk_widget_show_all(fc->win);
173 init_srt_table(&fc->fc_srt_table, 256, vbox, NULL);
175 init_srt_table_row(&fc->fc_srt_table, i, val_to_str(i, fc_fc4_val, "Unknown(0x%02x)"));
179 error_string=register_tap_listener("fc", fc, filter, fcstat_reset, fcstat_packet, fcstat_draw);
181 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, error_string->str);
182 g_string_free(error_string, TRUE);
188 bbox = dlg_button_row_new(GTK_STOCK_CLOSE, NULL);
189 gtk_box_pack_end(GTK_BOX(vbox), bbox, FALSE, FALSE, 0);
191 close_bt = OBJECT_GET_DATA(bbox, GTK_STOCK_CLOSE);
192 window_set_cancel_button(fc->win, close_bt, window_cancel_button_cb);
194 SIGNAL_CONNECT(fc->win, "delete_event", window_delete_event_cb, NULL);
195 SIGNAL_CONNECT(fc->win, "destroy", win_destroy_cb, fc);
197 gtk_widget_show_all(fc->win);
198 window_present(fc->win);
200 cf_retap_packets(&cfile);
205 static GtkWidget *dlg=NULL;
206 static GtkWidget *filter_entry;
215 fcstat_start_button_clicked(GtkWidget *item _U_, gpointer data _U_)
220 str = g_string_new("fc,srt");
221 filter=gtk_entry_get_text(GTK_ENTRY(filter_entry));
223 g_string_sprintfa(str,",%s", filter);
225 gtk_fcstat_init(str->str);
226 g_string_free(str, TRUE);
230 gtk_fcstat_cb(GtkWidget *w _U_, gpointer d _U_)
233 GtkWidget *filter_box, *filter_bt;
234 GtkWidget *bbox, *start_button, *cancel_button;
236 static construct_args_t args = {
237 "Service Response Time Statistics Filter",
242 /* if the window is already open, bring it to front */
244 gdk_window_raise(dlg->window);
248 dlg=dlg_window_new("Ethereal: Compute Fibre Channel Service Response Time statistics");
249 gtk_window_set_default_size(GTK_WINDOW(dlg), 400, -1);
251 dlg_box=gtk_vbox_new(FALSE, 10);
252 gtk_container_border_width(GTK_CONTAINER(dlg_box), 10);
253 gtk_container_add(GTK_CONTAINER(dlg), dlg_box);
254 gtk_widget_show(dlg_box);
257 filter_box=gtk_hbox_new(FALSE, 3);
260 filter_bt=BUTTON_NEW_FROM_STOCK(ETHEREAL_STOCK_DISPLAY_FILTER_ENTRY);
261 SIGNAL_CONNECT(filter_bt, "clicked", display_filter_construct_cb, &args);
262 gtk_box_pack_start(GTK_BOX(filter_box), filter_bt, FALSE, FALSE, 0);
263 gtk_widget_show(filter_bt);
266 filter_entry=gtk_entry_new();
267 SIGNAL_CONNECT(filter_entry, "changed", filter_te_syntax_check_cb, NULL);
269 /* filter prefs dialog */
270 OBJECT_SET_DATA(filter_bt, E_FILT_TE_PTR_KEY, filter_entry);
271 /* filter prefs dialog */
273 gtk_box_pack_start(GTK_BOX(filter_box), filter_entry, TRUE, TRUE, 0);
274 filter=gtk_entry_get_text(GTK_ENTRY(main_display_filter_widget));
276 gtk_entry_set_text(GTK_ENTRY(filter_entry), filter);
278 gtk_widget_show(filter_entry);
280 gtk_box_pack_start(GTK_BOX(dlg_box), filter_box, TRUE, TRUE, 0);
281 gtk_widget_show(filter_box);
284 bbox = dlg_button_row_new(ETHEREAL_STOCK_CREATE_STAT, GTK_STOCK_CANCEL, NULL);
285 gtk_box_pack_start(GTK_BOX(dlg_box), bbox, FALSE, FALSE, 0);
286 gtk_widget_show(bbox);
288 start_button = OBJECT_GET_DATA(bbox, ETHEREAL_STOCK_CREATE_STAT);
289 gtk_widget_grab_default(start_button );
290 SIGNAL_CONNECT_OBJECT(start_button, "clicked",
291 fcstat_start_button_clicked, NULL);
293 cancel_button = OBJECT_GET_DATA(bbox, GTK_STOCK_CANCEL);
294 window_set_cancel_button(dlg, cancel_button, window_cancel_button_cb);
296 /* Catch the "activate" signal on the filter text entry, so that
297 if the user types Return there, we act as if the "Create Stat"
298 button had been selected, as happens if Return is typed if some
299 widget that *doesn't* handle the Return key has the input
301 dlg_set_activate(filter_entry, start_button);
303 /* Give the initial focus to the "Filter" entry box. */
304 gtk_widget_grab_focus(filter_entry);
306 SIGNAL_CONNECT(dlg, "delete_event", window_delete_event_cb, NULL);
307 SIGNAL_CONNECT(dlg, "destroy", dlg_destroy_cb, NULL);
309 gtk_widget_show_all(dlg);
314 register_tap_listener_gtkfcstat(void)
316 register_stat_cmd_arg("fc,srt", gtk_fcstat_init);
318 register_stat_menu_item("Fibre Channel...", REGISTER_STAT_GROUP_RESPONSE_TIME,
319 gtk_fcstat_cb, NULL, NULL, NULL);