Update to the Response Time Statistics taps.
[obnox/wireshark/wip.git] / gtk / smb_stat.c
1 /* smb_stat.c
2  * smb_stat   2003 Ronnie Sahlberg
3  *
4  * $Id: smb_stat.c,v 1.10 2003/08/19 10:09:20 sahlberg Exp $
5  *
6  * Ethereal - Network traffic analyzer
7  * By Gerald Combs <gerald@ethereal.com>
8  * Copyright 1998 Gerald Combs
9  *
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.
14  *
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.
19  *
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.
23  */
24
25 #ifdef HAVE_CONFIG_H
26 # include "config.h"
27 #endif
28
29 #include <stdio.h>
30
31 #ifdef HAVE_SYS_TYPES_H
32 # include <sys/types.h>
33 #endif
34
35 #include <gtk/gtk.h>
36 #include <string.h>
37 #include "menu.h"
38 #include "../epan/packet_info.h"
39 #include "../tap.h"
40 #include "../epan/value_string.h"
41 #include "../smb.h"
42 #include "../register.h"
43 #include "../timestats.h"
44 #include "compat_macros.h"
45 #include "../simple_dialog.h"
46 #include "../file.h"
47 #include "../globals.h"
48 #include "service_response_time_table.h"
49
50 extern GtkWidget   *main_display_filter_widget;
51
52 /* used to keep track of the statistics for an entire program interface */
53 typedef struct _smbstat_t {
54         GtkWidget *win;
55         srt_stat_table smb_srt_table;
56         srt_stat_table trans2_srt_table;
57         srt_stat_table nt_trans_srt_table;
58 } smbstat_t;
59
60
61
62 static void
63 smbstat_reset(void *pss)
64 {
65         smbstat_t *ss=(smbstat_t *)pss;
66
67         reset_srt_table_data(&ss->smb_srt_table);
68         reset_srt_table_data(&ss->trans2_srt_table);
69         reset_srt_table_data(&ss->nt_trans_srt_table);
70 }
71
72 static int
73 smbstat_packet(void *pss, packet_info *pinfo, epan_dissect_t *edt _U_, void *psi)
74 {
75         smbstat_t *ss=(smbstat_t *)pss;
76         smb_info_t *si=psi;
77
78         /* we are only interested in reply packets */
79         if(si->request){
80                 return 0;
81         }
82         /* if we havnt seen the request, just ignore it */
83         if(!si->sip){
84                 return 0;
85         }
86
87         add_srt_table_data(&ss->smb_srt_table, si->cmd, &si->sip->req_time, pinfo);
88
89         if(si->cmd==0xA0){
90                 smb_nt_transact_info_t *sti=(smb_nt_transact_info_t *)si->sip->extra_info;
91
92                 add_srt_table_data(&ss->nt_trans_srt_table, sti->subcmd, &si->sip->req_time, pinfo);
93         } else if(si->cmd==0x32){
94                 smb_transact2_info_t *st2i=(smb_transact2_info_t *)si->sip->extra_info;
95
96                 add_srt_table_data(&ss->trans2_srt_table, st2i->subcmd, &si->sip->req_time, pinfo);
97         }
98
99         return 1;
100 }
101
102
103
104 static void
105 smbstat_draw(void *pss)
106 {
107         smbstat_t *ss=(smbstat_t *)pss;
108
109         draw_srt_table_data(&ss->smb_srt_table);
110         draw_srt_table_data(&ss->trans2_srt_table);
111         draw_srt_table_data(&ss->nt_trans_srt_table);
112 }
113
114
115 void protect_thread_critical_region(void);
116 void unprotect_thread_critical_region(void);
117 static void
118 win_destroy_cb(GtkWindow *win _U_, gpointer data)
119 {
120         smbstat_t *ss=(smbstat_t *)data;
121
122         protect_thread_critical_region();
123         remove_tap_listener(ss);
124         unprotect_thread_critical_region();
125
126         free_srt_table_data(&ss->smb_srt_table);
127         free_srt_table_data(&ss->trans2_srt_table);
128         free_srt_table_data(&ss->nt_trans_srt_table);
129         g_free(ss);
130 }
131
132
133 static void
134 gtk_smbstat_init(char *optarg)
135 {
136         smbstat_t *ss;
137         char *filter=NULL;
138         GtkWidget *label;
139         char filter_string[256];
140         GString *error_string;
141         int i;
142         GtkWidget *vbox;
143
144         if(!strncmp(optarg,"smb,srt,",8)){
145                 filter=optarg+8;
146         } else {
147                 filter=NULL;
148         }
149
150         ss=g_malloc(sizeof(smbstat_t));
151
152         ss->win=gtk_window_new(GTK_WINDOW_TOPLEVEL);
153         gtk_window_set_default_size(GTK_WINDOW(ss->win), 550, 600);
154         gtk_window_set_title(GTK_WINDOW(ss->win), "SMB Service Response Time statistics");
155         SIGNAL_CONNECT(ss->win, "destroy", win_destroy_cb, ss);
156
157         vbox=gtk_vbox_new(FALSE, 0);
158         gtk_container_add(GTK_CONTAINER(ss->win), vbox);
159         gtk_container_set_border_width(GTK_CONTAINER(vbox), 10);
160         gtk_widget_show(vbox);
161
162         label=gtk_label_new("SMB Service Response Time statistics");
163         gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
164         gtk_widget_show(label);
165
166         snprintf(filter_string,255,"Filter:%s",filter?filter:"");
167         label=gtk_label_new(filter_string);
168         gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
169         gtk_widget_show(label);
170
171
172         label=gtk_label_new("SMB Commands");
173         gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
174         gtk_widget_show(label);
175
176         /* We must display TOP LEVEL Widget before calling init_srt_table() */
177         gtk_widget_show(ss->win);
178
179         init_srt_table(&ss->smb_srt_table, 256, vbox);
180         for(i=0;i<256;i++){
181                 init_srt_table_row(&ss->smb_srt_table, i, val_to_str(i, smb_cmd_vals, "Unknown(0x%02x)"));
182         }
183
184
185         label=gtk_label_new("Transaction2 Sub-Commands");
186         gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
187         gtk_widget_show(label);
188         init_srt_table(&ss->trans2_srt_table, 256, vbox);
189         for(i=0;i<256;i++){
190                 init_srt_table_row(&ss->trans2_srt_table, i, val_to_str(i, trans2_cmd_vals, "Unknown(0x%02x)"));
191         }
192
193
194         label=gtk_label_new("NT Transaction Sub-Commands");
195         gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
196         gtk_widget_show(label);
197         init_srt_table(&ss->nt_trans_srt_table, 256, vbox);
198         for(i=0;i<256;i++){
199                 init_srt_table_row(&ss->nt_trans_srt_table, i, val_to_str(i, nt_cmd_vals, "Unknown(0x%02x)"));
200         }
201
202
203         error_string=register_tap_listener("smb", ss, filter, smbstat_reset, smbstat_packet, smbstat_draw);
204         if(error_string){
205                 simple_dialog(ESD_TYPE_WARN, NULL, error_string->str);
206                 g_string_free(error_string, TRUE);
207                 g_free(ss);
208                 return;
209         }
210
211         gtk_widget_show_all(ss->win);
212         redissect_packets(&cfile);
213 }
214
215
216
217 static GtkWidget *dlg=NULL, *dlg_box;
218 static GtkWidget *filter_box;
219 static GtkWidget *filter_label, *filter_entry;
220 static GtkWidget *start_button;
221
222 static void
223 dlg_destroy_cb(void)
224 {
225         dlg=NULL;
226 }
227
228 static void
229 smbstat_start_button_clicked(GtkWidget *item _U_, gpointer data _U_)
230 {
231         char *filter;
232         char str[256];
233
234         filter=(char *)gtk_entry_get_text(GTK_ENTRY(filter_entry));
235         if(filter[0]==0){
236                 gtk_smbstat_init("smb,srt");
237         } else {
238                 sprintf(str,"smb,srt,%s", filter);
239                 gtk_smbstat_init(str);
240         }
241 }
242
243 static void
244 gtk_smbstat_cb(GtkWidget *w _U_, gpointer d _U_)
245 {
246         char *filter;
247
248         /* if the window is already open, bring it to front */
249         if(dlg){
250                 gdk_window_raise(dlg->window);
251                 return;
252         }
253
254         dlg=gtk_window_new(GTK_WINDOW_TOPLEVEL);
255         gtk_window_set_title(GTK_WINDOW(dlg), "SMB Service Response Time statistics");
256         SIGNAL_CONNECT(dlg, "destroy", dlg_destroy_cb, NULL);
257         dlg_box=gtk_vbox_new(FALSE, 0);
258         gtk_container_add(GTK_CONTAINER(dlg), dlg_box);
259         gtk_widget_show(dlg_box);
260
261
262         /* filter box */
263         filter_box=gtk_hbox_new(FALSE, 10);
264         /* Filter label */
265         gtk_container_set_border_width(GTK_CONTAINER(filter_box), 10);
266         filter_label=gtk_label_new("Filter:");
267         gtk_box_pack_start(GTK_BOX(filter_box), filter_label, FALSE, FALSE, 0);
268         gtk_widget_show(filter_label);
269
270         filter_entry=gtk_entry_new_with_max_length(250);
271         gtk_box_pack_start(GTK_BOX(filter_box), filter_entry, FALSE, FALSE, 0);
272         filter=gtk_entry_get_text(GTK_ENTRY(main_display_filter_widget));
273         if(filter){
274                 gtk_entry_set_text(GTK_ENTRY(filter_entry), filter);
275         }
276         gtk_widget_show(filter_entry);
277
278         gtk_box_pack_start(GTK_BOX(dlg_box), filter_box, TRUE, TRUE, 0);
279         gtk_widget_show(filter_box);
280
281
282         /* the start button */
283         start_button=gtk_button_new_with_label("Create Stat");
284         SIGNAL_CONNECT_OBJECT(start_button, "clicked",
285                               smbstat_start_button_clicked, NULL);
286         gtk_box_pack_start(GTK_BOX(dlg_box), start_button, TRUE, TRUE, 0);
287         gtk_widget_show(start_button);
288
289         gtk_widget_show_all(dlg);
290 }
291
292 void
293 register_tap_listener_gtksmbstat(void)
294 {
295         register_ethereal_tap("smb,srt", gtk_smbstat_init);
296 }
297
298 void
299 register_tap_menu_gtksmbstat(void)
300 {
301         register_tap_menu_item("Service Response Time/SMB", gtk_smbstat_cb);
302 }