2 * smb_stat 2003 Ronnie Sahlberg
4 * $Id: smb_stat.c,v 1.38 2004/02/22 18:58:35 ulfl Exp $
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>
44 #include "../register.h"
45 #include "../timestats.h"
46 #include "compat_macros.h"
47 #include "../simple_dialog.h"
49 #include "dlg_utils.h"
51 #include "../globals.h"
52 #include "filter_prefs.h"
53 #include "service_response_time_table.h"
55 extern GtkWidget *main_display_filter_widget;
57 /* used to keep track of the statistics for an entire program interface */
58 typedef struct _smbstat_t {
60 srt_stat_table smb_srt_table;
61 srt_stat_table trans2_srt_table;
62 srt_stat_table nt_trans_srt_table;
66 smbstat_set_title(smbstat_t *ss)
70 title = g_strdup_printf("SMB Service Response Time statistics: %s",
71 cf_get_display_name(&cfile));
72 gtk_window_set_title(GTK_WINDOW(ss->win), title);
77 smbstat_reset(void *pss)
79 smbstat_t *ss=(smbstat_t *)pss;
81 reset_srt_table_data(&ss->smb_srt_table);
82 reset_srt_table_data(&ss->trans2_srt_table);
83 reset_srt_table_data(&ss->nt_trans_srt_table);
84 smbstat_set_title(ss);
88 smbstat_packet(void *pss, packet_info *pinfo, epan_dissect_t *edt _U_, void *psi)
90 smbstat_t *ss=(smbstat_t *)pss;
93 /* we are only interested in reply packets */
97 /* if we havnt seen the request, just ignore it */
102 add_srt_table_data(&ss->smb_srt_table, si->cmd, &si->sip->req_time, pinfo);
105 smb_nt_transact_info_t *sti=(smb_nt_transact_info_t *)si->sip->extra_info;
108 add_srt_table_data(&ss->nt_trans_srt_table, sti->subcmd, &si->sip->req_time, pinfo);
110 } else if(si->cmd==0x32){
111 smb_transact2_info_t *st2i=(smb_transact2_info_t *)si->sip->extra_info;
114 add_srt_table_data(&ss->trans2_srt_table, st2i->subcmd, &si->sip->req_time, pinfo);
124 smbstat_draw(void *pss)
126 smbstat_t *ss=(smbstat_t *)pss;
128 draw_srt_table_data(&ss->smb_srt_table);
129 draw_srt_table_data(&ss->trans2_srt_table);
130 draw_srt_table_data(&ss->nt_trans_srt_table);
134 void protect_thread_critical_region(void);
135 void unprotect_thread_critical_region(void);
137 win_destroy_cb(GtkWindow *win _U_, gpointer data)
139 smbstat_t *ss=(smbstat_t *)data;
141 protect_thread_critical_region();
142 remove_tap_listener(ss);
143 unprotect_thread_critical_region();
145 free_srt_table_data(&ss->smb_srt_table);
146 free_srt_table_data(&ss->trans2_srt_table);
147 free_srt_table_data(&ss->nt_trans_srt_table);
153 gtk_smbstat_init(char *optarg)
158 char filter_string[256];
159 GString *error_string;
163 if(!strncmp(optarg,"smb,srt,",8)){
169 ss=g_malloc(sizeof(smbstat_t));
171 ss->win=window_new(GTK_WINDOW_TOPLEVEL, NULL);
172 gtk_window_set_default_size(GTK_WINDOW(ss->win), 550, 600);
173 smbstat_set_title(ss);
174 SIGNAL_CONNECT(ss->win, "destroy", win_destroy_cb, ss);
176 vbox=gtk_vbox_new(FALSE, 0);
177 gtk_container_add(GTK_CONTAINER(ss->win), vbox);
178 gtk_container_set_border_width(GTK_CONTAINER(vbox), 10);
179 gtk_widget_show(vbox);
181 label=gtk_label_new("SMB Service Response Time statistics");
182 gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
183 gtk_widget_show(label);
185 snprintf(filter_string,255,"Filter:%s",filter?filter:"");
186 label=gtk_label_new(filter_string);
187 gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
188 gtk_widget_show(label);
191 label=gtk_label_new("SMB Commands");
192 gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
193 gtk_widget_show(label);
195 /* We must display TOP LEVEL Widget before calling init_srt_table() */
196 gtk_widget_show(ss->win);
198 init_srt_table(&ss->smb_srt_table, 256, vbox, "smb.cmd");
200 init_srt_table_row(&ss->smb_srt_table, i, val_to_str(i, smb_cmd_vals, "Unknown(0x%02x)"));
204 label=gtk_label_new("Transaction2 Sub-Commands");
205 gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
206 gtk_widget_show(label);
207 init_srt_table(&ss->trans2_srt_table, 256, vbox, "smb.trans2.cmd");
209 init_srt_table_row(&ss->trans2_srt_table, i, val_to_str(i, trans2_cmd_vals, "Unknown(0x%02x)"));
213 label=gtk_label_new("NT Transaction Sub-Commands");
214 gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
215 gtk_widget_show(label);
216 init_srt_table(&ss->nt_trans_srt_table, 256, vbox, "smb.nt.function");
218 init_srt_table_row(&ss->nt_trans_srt_table, i, val_to_str(i, nt_cmd_vals, "Unknown(0x%02x)"));
222 error_string=register_tap_listener("smb", ss, filter, smbstat_reset, smbstat_packet, smbstat_draw);
224 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, error_string->str);
225 g_string_free(error_string, TRUE);
230 gtk_widget_show_all(ss->win);
231 retap_packets(&cfile);
236 static GtkWidget *dlg=NULL;
237 static GtkWidget *filter_entry;
246 dlg_cancel_cb(GtkWidget *cancel_bt _U_, gpointer parent_w)
248 gtk_widget_destroy(GTK_WIDGET(parent_w));
252 smbstat_start_button_clicked(GtkWidget *item _U_, gpointer data _U_)
257 str = g_string_new("smb,srt");
258 filter=(char *)gtk_entry_get_text(GTK_ENTRY(filter_entry));
260 g_string_sprintfa(str,",%s", filter);
262 gtk_smbstat_init(str->str);
263 g_string_free(str, TRUE);
267 gtk_smbstat_cb(GtkWidget *w _U_, gpointer d _U_)
270 GtkWidget *filter_box, *filter_bt;
271 GtkWidget *bbox, *start_button, *cancel_button;
273 static construct_args_t args = {
274 "Service Response Time Statistics Filter",
279 /* if the window is already open, bring it to front */
281 gdk_window_raise(dlg->window);
285 dlg=dlg_window_new("Ethereal: Compute SMB SRT statistics");
286 SIGNAL_CONNECT(dlg, "destroy", dlg_destroy_cb, NULL);
288 dlg_box=gtk_vbox_new(FALSE, 10);
289 gtk_container_border_width(GTK_CONTAINER(dlg_box), 10);
290 gtk_container_add(GTK_CONTAINER(dlg), dlg_box);
291 gtk_widget_show(dlg_box);
294 filter_box=gtk_hbox_new(FALSE, 3);
297 filter_bt=BUTTON_NEW_FROM_STOCK(ETHEREAL_STOCK_DISPLAY_FILTER_ENTRY);
298 SIGNAL_CONNECT(filter_bt, "clicked", display_filter_construct_cb, &args);
299 gtk_box_pack_start(GTK_BOX(filter_box), filter_bt, FALSE, TRUE, 0);
300 gtk_widget_show(filter_bt);
303 filter_entry=gtk_entry_new();
304 WIDGET_SET_SIZE(filter_entry, 300, -1);
306 /* filter prefs dialog */
307 OBJECT_SET_DATA(filter_bt, E_FILT_TE_PTR_KEY, filter_entry);
308 /* filter prefs dialog */
310 gtk_box_pack_start(GTK_BOX(filter_box), filter_entry, TRUE, TRUE, 0);
311 filter=gtk_entry_get_text(GTK_ENTRY(main_display_filter_widget));
313 gtk_entry_set_text(GTK_ENTRY(filter_entry), filter);
315 gtk_widget_show(filter_entry);
317 gtk_box_pack_start(GTK_BOX(dlg_box), filter_box, TRUE, TRUE, 0);
318 gtk_widget_show(filter_box);
321 bbox = dlg_button_row_new(ETHEREAL_STOCK_CREATE_STAT, GTK_STOCK_CANCEL, NULL);
322 gtk_box_pack_start(GTK_BOX(dlg_box), bbox, FALSE, FALSE, 0);
323 gtk_widget_show(bbox);
325 start_button = OBJECT_GET_DATA(bbox, ETHEREAL_STOCK_CREATE_STAT);
326 gtk_widget_grab_default(start_button );
327 SIGNAL_CONNECT_OBJECT(start_button, "clicked",
328 smbstat_start_button_clicked, NULL);
330 cancel_button = OBJECT_GET_DATA(bbox, GTK_STOCK_CANCEL);
331 SIGNAL_CONNECT(cancel_button, "clicked", dlg_cancel_cb, dlg);
333 /* Catch the "activate" signal on the filter text entry, so that
334 if the user types Return there, we act as if the "Create Stat"
335 button had been selected, as happens if Return is typed if some
336 widget that *doesn't* handle the Return key has the input
338 dlg_set_activate(filter_entry, start_button);
340 /* Catch the "key_press_event" signal in the window, so that we can
341 catch the ESC key being pressed and act as if the "Cancel" button
342 had been selected. */
343 dlg_set_cancel(dlg, cancel_button);
345 /* Give the initial focus to the "Filter" entry box. */
346 gtk_widget_grab_focus(filter_entry);
348 gtk_widget_show_all(dlg);
352 register_tap_listener_gtksmbstat(void)
354 register_ethereal_tap("smb,srt", gtk_smbstat_init);
356 register_tap_menu_item("SMB (Service Response Time...)", REGISTER_TAP_LAYER_APPLICATION,
357 gtk_smbstat_cb, NULL, NULL, NULL);