2 * smb_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>
41 #include <epan/stat_cmd_args.h>
42 #include "../stat_menu.h"
43 #include "gtk_stat_menu.h"
46 #include "../register.h"
47 #include "../timestats.h"
48 #include "compat_macros.h"
49 #include "../simple_dialog.h"
50 #include "gui_utils.h"
51 #include "dlg_utils.h"
53 #include "../globals.h"
54 #include "filter_dlg.h"
55 #include "service_response_time_table.h"
56 #include "gtkglobals.h"
59 /* used to keep track of the statistics for an entire program interface */
60 typedef struct _smbstat_t {
62 srt_stat_table smb_srt_table;
63 srt_stat_table trans2_srt_table;
64 srt_stat_table nt_trans_srt_table;
68 smbstat_set_title(smbstat_t *ss)
72 title = g_strdup_printf("SMB Service Response Time statistics: %s",
73 cf_get_display_name(&cfile));
74 gtk_window_set_title(GTK_WINDOW(ss->win), title);
79 smbstat_reset(void *pss)
81 smbstat_t *ss=(smbstat_t *)pss;
83 reset_srt_table_data(&ss->smb_srt_table);
84 reset_srt_table_data(&ss->trans2_srt_table);
85 reset_srt_table_data(&ss->nt_trans_srt_table);
86 smbstat_set_title(ss);
90 smbstat_packet(void *pss, packet_info *pinfo, epan_dissect_t *edt _U_, const void *psi)
92 smbstat_t *ss=(smbstat_t *)pss;
93 const smb_info_t *si=psi;
95 /* we are only interested in reply packets */
99 /* if we havnt seen the request, just ignore it */
104 add_srt_table_data(&ss->smb_srt_table, si->cmd, &si->sip->req_time, pinfo);
106 if(si->cmd==0xA0 && si->sip->extra_info_type == SMB_EI_NTI){
107 smb_nt_transact_info_t *sti=(smb_nt_transact_info_t *)si->sip->extra_info;
110 add_srt_table_data(&ss->nt_trans_srt_table, sti->subcmd, &si->sip->req_time, pinfo);
112 } else if(si->cmd==0x32 && si->sip->extra_info_type == SMB_EI_T2I){
113 smb_transact2_info_t *st2i=(smb_transact2_info_t *)si->sip->extra_info;
116 add_srt_table_data(&ss->trans2_srt_table, st2i->subcmd, &si->sip->req_time, pinfo);
126 smbstat_draw(void *pss)
128 smbstat_t *ss=(smbstat_t *)pss;
130 draw_srt_table_data(&ss->smb_srt_table);
131 draw_srt_table_data(&ss->trans2_srt_table);
132 draw_srt_table_data(&ss->nt_trans_srt_table);
136 void protect_thread_critical_region(void);
137 void unprotect_thread_critical_region(void);
139 win_destroy_cb(GtkWindow *win _U_, gpointer data)
141 smbstat_t *ss=(smbstat_t *)data;
143 protect_thread_critical_region();
144 remove_tap_listener(ss);
145 unprotect_thread_critical_region();
147 free_srt_table_data(&ss->smb_srt_table);
148 free_srt_table_data(&ss->trans2_srt_table);
149 free_srt_table_data(&ss->nt_trans_srt_table);
155 gtk_smbstat_init(const char *optarg)
158 const char *filter=NULL;
160 char filter_string[256];
161 GString *error_string;
167 if(!strncmp(optarg,"smb,srt,",8)){
173 ss=g_malloc(sizeof(smbstat_t));
175 ss->win=window_new(GTK_WINDOW_TOPLEVEL, "smb-stat");
176 gtk_window_set_default_size(GTK_WINDOW(ss->win), 550, 600);
177 smbstat_set_title(ss);
179 vbox=gtk_vbox_new(FALSE, 3);
180 gtk_container_add(GTK_CONTAINER(ss->win), vbox);
181 gtk_container_set_border_width(GTK_CONTAINER(vbox), 12);
183 label=gtk_label_new("SMB Service Response Time statistics");
184 gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
186 g_snprintf(filter_string,255,"Filter:%s",filter?filter:"");
187 label=gtk_label_new(filter_string);
188 gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
190 label=gtk_label_new("SMB Commands");
191 gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
193 /* We must display TOP LEVEL Widget before calling init_srt_table() */
194 gtk_widget_show_all(ss->win);
196 init_srt_table(&ss->smb_srt_table, 256, vbox, "smb.cmd");
198 init_srt_table_row(&ss->smb_srt_table, i, val_to_str(i, smb_cmd_vals, "Unknown(0x%02x)"));
202 label=gtk_label_new("Transaction2 Sub-Commands");
203 gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
204 init_srt_table(&ss->trans2_srt_table, 256, vbox, "smb.trans2.cmd");
206 init_srt_table_row(&ss->trans2_srt_table, i, val_to_str(i, trans2_cmd_vals, "Unknown(0x%02x)"));
210 label=gtk_label_new("NT Transaction Sub-Commands");
211 gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
212 init_srt_table(&ss->nt_trans_srt_table, 256, vbox, "smb.nt.function");
214 init_srt_table_row(&ss->nt_trans_srt_table, i, val_to_str(i, nt_cmd_vals, "Unknown(0x%02x)"));
218 error_string=register_tap_listener("smb", ss, filter, smbstat_reset, smbstat_packet, smbstat_draw);
220 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, error_string->str);
221 g_string_free(error_string, TRUE);
227 bbox = dlg_button_row_new(GTK_STOCK_CLOSE, NULL);
228 gtk_box_pack_end(GTK_BOX(vbox), bbox, FALSE, FALSE, 0);
230 close_bt = OBJECT_GET_DATA(bbox, GTK_STOCK_CLOSE);
231 window_set_cancel_button(ss->win, close_bt, window_cancel_button_cb);
233 SIGNAL_CONNECT(ss->win, "delete_event", window_delete_event_cb, NULL);
234 SIGNAL_CONNECT(ss->win, "destroy", win_destroy_cb, ss);
236 gtk_widget_show_all(ss->win);
237 window_present(ss->win);
239 cf_retap_packets(&cfile);
244 static GtkWidget *dlg=NULL;
245 static GtkWidget *filter_entry;
254 smbstat_start_button_clicked(GtkWidget *item _U_, gpointer data _U_)
259 str = g_string_new("smb,srt");
260 filter=gtk_entry_get_text(GTK_ENTRY(filter_entry));
262 g_string_sprintfa(str,",%s", filter);
264 gtk_smbstat_init(str->str);
265 g_string_free(str, TRUE);
269 gtk_smbstat_cb(GtkWidget *w _U_, gpointer d _U_)
272 GtkWidget *filter_box, *filter_bt;
273 GtkWidget *bbox, *start_button, *cancel_button;
275 static construct_args_t args = {
276 "Service Response Time Statistics Filter",
281 /* if the window is already open, bring it to front */
283 gdk_window_raise(dlg->window);
287 dlg=dlg_window_new("Ethereal: Compute SMB SRT statistics");
288 gtk_window_set_default_size(GTK_WINDOW(dlg), 300, -1);
290 dlg_box=gtk_vbox_new(FALSE, 10);
291 gtk_container_border_width(GTK_CONTAINER(dlg_box), 10);
292 gtk_container_add(GTK_CONTAINER(dlg), dlg_box);
293 gtk_widget_show(dlg_box);
296 filter_box=gtk_hbox_new(FALSE, 3);
299 filter_bt=BUTTON_NEW_FROM_STOCK(ETHEREAL_STOCK_DISPLAY_FILTER_ENTRY);
300 SIGNAL_CONNECT(filter_bt, "clicked", display_filter_construct_cb, &args);
301 gtk_box_pack_start(GTK_BOX(filter_box), filter_bt, FALSE, TRUE, 0);
302 gtk_widget_show(filter_bt);
305 filter_entry=gtk_entry_new();
306 SIGNAL_CONNECT(filter_entry, "changed", filter_te_syntax_check_cb, NULL);
308 /* filter prefs dialog */
309 OBJECT_SET_DATA(filter_bt, E_FILT_TE_PTR_KEY, filter_entry);
310 /* filter prefs dialog */
312 gtk_box_pack_start(GTK_BOX(filter_box), filter_entry, TRUE, TRUE, 0);
313 filter=gtk_entry_get_text(GTK_ENTRY(main_display_filter_widget));
315 gtk_entry_set_text(GTK_ENTRY(filter_entry), filter);
317 gtk_widget_show(filter_entry);
319 gtk_box_pack_start(GTK_BOX(dlg_box), filter_box, TRUE, TRUE, 0);
320 gtk_widget_show(filter_box);
323 bbox = dlg_button_row_new(ETHEREAL_STOCK_CREATE_STAT, GTK_STOCK_CANCEL, NULL);
324 gtk_box_pack_start(GTK_BOX(dlg_box), bbox, FALSE, FALSE, 0);
325 gtk_widget_show(bbox);
327 start_button = OBJECT_GET_DATA(bbox, ETHEREAL_STOCK_CREATE_STAT);
328 SIGNAL_CONNECT_OBJECT(start_button, "clicked",
329 smbstat_start_button_clicked, NULL);
331 cancel_button = OBJECT_GET_DATA(bbox, GTK_STOCK_CANCEL);
332 window_set_cancel_button(dlg, cancel_button, window_cancel_button_cb);
334 /* Catch the "activate" signal on the filter text entry, so that
335 if the user types Return there, we act as if the "Create Stat"
336 button had been selected, as happens if Return is typed if some
337 widget that *doesn't* handle the Return key has the input
339 dlg_set_activate(filter_entry, start_button);
341 gtk_widget_grab_default(start_button );
343 /* Give the initial focus to the "Filter" entry box. */
344 gtk_widget_grab_focus(filter_entry);
346 SIGNAL_CONNECT(dlg, "delete_event", window_delete_event_cb, NULL);
347 SIGNAL_CONNECT(dlg, "destroy", dlg_destroy_cb, NULL);
349 gtk_widget_show_all(dlg);
354 register_tap_listener_gtksmbstat(void)
356 register_stat_cmd_arg("smb,srt", gtk_smbstat_init);
358 register_stat_menu_item("SMB...", REGISTER_STAT_GROUP_RESPONSE_TIME,
359 gtk_smbstat_cb, NULL, NULL, NULL);