"gtk_entry_get_text()" returns a "const char *" - assign the result to
[obnox/wireshark/wip.git] / gtk / smb_stat.c
1 /* smb_stat.c
2  * smb_stat   2003 Ronnie Sahlberg
3  *
4  * $Id$
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 #ifdef HAVE_SYS_TYPES_H
30 # include <sys/types.h>
31 #endif
32
33 #include <string.h>
34
35 #include <gtk/gtk.h>
36
37 #include <epan/packet_info.h>
38 #include <epan/epan.h>
39 #include <epan/value_string.h>
40
41 #include "tap_menu.h"
42 #include <epan/tap.h>
43 #include "../smb.h"
44 #include "../register.h"
45 #include "../timestats.h"
46 #include "compat_macros.h"
47 #include "../simple_dialog.h"
48 #include "ui_util.h"
49 #include "dlg_utils.h"
50 #include "../file.h"
51 #include "../globals.h"
52 #include "filter_dlg.h"
53 #include "service_response_time_table.h"
54 #include "gtkglobals.h"
55
56
57 /* used to keep track of the statistics for an entire program interface */
58 typedef struct _smbstat_t {
59         GtkWidget *win;
60         srt_stat_table smb_srt_table;
61         srt_stat_table trans2_srt_table;
62         srt_stat_table nt_trans_srt_table;
63 } smbstat_t;
64
65 static void
66 smbstat_set_title(smbstat_t *ss)
67 {
68         char *title;
69
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);
73         g_free(title);
74 }
75
76 static void
77 smbstat_reset(void *pss)
78 {
79         smbstat_t *ss=(smbstat_t *)pss;
80
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);
85 }
86
87 static int
88 smbstat_packet(void *pss, packet_info *pinfo, epan_dissect_t *edt _U_, void *psi)
89 {
90         smbstat_t *ss=(smbstat_t *)pss;
91         smb_info_t *si=psi;
92
93         /* we are only interested in reply packets */
94         if(si->request){
95                 return 0;
96         }
97         /* if we havnt seen the request, just ignore it */
98         if(!si->sip){
99                 return 0;
100         }
101
102         add_srt_table_data(&ss->smb_srt_table, si->cmd, &si->sip->req_time, pinfo);
103
104         if(si->cmd==0xA0){
105                 smb_nt_transact_info_t *sti=(smb_nt_transact_info_t *)si->sip->extra_info;
106
107                 if(sti){
108                         add_srt_table_data(&ss->nt_trans_srt_table, sti->subcmd, &si->sip->req_time, pinfo);
109                 }
110         } else if(si->cmd==0x32){
111                 smb_transact2_info_t *st2i=(smb_transact2_info_t *)si->sip->extra_info;
112
113                 if(st2i){
114                         add_srt_table_data(&ss->trans2_srt_table, st2i->subcmd, &si->sip->req_time, pinfo);
115                 }
116         }
117
118         return 1;
119 }
120
121
122
123 static void
124 smbstat_draw(void *pss)
125 {
126         smbstat_t *ss=(smbstat_t *)pss;
127
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);
131 }
132
133
134 void protect_thread_critical_region(void);
135 void unprotect_thread_critical_region(void);
136 static void
137 win_destroy_cb(GtkWindow *win _U_, gpointer data)
138 {
139         smbstat_t *ss=(smbstat_t *)data;
140
141         protect_thread_critical_region();
142         remove_tap_listener(ss);
143         unprotect_thread_critical_region();
144
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);
148         g_free(ss);
149 }
150
151
152 static void
153 gtk_smbstat_init(char *optarg)
154 {
155         smbstat_t *ss;
156         char *filter=NULL;
157         GtkWidget *label;
158         char filter_string[256];
159         GString *error_string;
160         int i;
161         GtkWidget *vbox;
162     GtkWidget *bbox;
163     GtkWidget *close_bt;
164
165         if(!strncmp(optarg,"smb,srt,",8)){
166                 filter=optarg+8;
167         } else {
168                 filter=NULL;
169         }
170
171         ss=g_malloc(sizeof(smbstat_t));
172
173         ss->win=window_new(GTK_WINDOW_TOPLEVEL, "smb-stat");
174         gtk_window_set_default_size(GTK_WINDOW(ss->win), 550, 600);
175         smbstat_set_title(ss);
176
177         vbox=gtk_vbox_new(FALSE, 3);
178         gtk_container_add(GTK_CONTAINER(ss->win), vbox);
179         gtk_container_set_border_width(GTK_CONTAINER(vbox), 12);
180
181         label=gtk_label_new("SMB Service Response Time statistics");
182         gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
183
184         g_snprintf(filter_string,255,"Filter:%s",filter?filter:"");
185         label=gtk_label_new(filter_string);
186         gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
187
188         label=gtk_label_new("SMB Commands");
189         gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
190
191         /* We must display TOP LEVEL Widget before calling init_srt_table() */
192         gtk_widget_show_all(ss->win);
193
194         init_srt_table(&ss->smb_srt_table, 256, vbox, "smb.cmd");
195         for(i=0;i<256;i++){
196                 init_srt_table_row(&ss->smb_srt_table, i, val_to_str(i, smb_cmd_vals, "Unknown(0x%02x)"));
197         }
198
199
200         label=gtk_label_new("Transaction2 Sub-Commands");
201         gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
202         init_srt_table(&ss->trans2_srt_table, 256, vbox, "smb.trans2.cmd");
203         for(i=0;i<256;i++){
204                 init_srt_table_row(&ss->trans2_srt_table, i, val_to_str(i, trans2_cmd_vals, "Unknown(0x%02x)"));
205         }
206
207
208         label=gtk_label_new("NT Transaction Sub-Commands");
209         gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
210         init_srt_table(&ss->nt_trans_srt_table, 256, vbox, "smb.nt.function");
211         for(i=0;i<256;i++){
212                 init_srt_table_row(&ss->nt_trans_srt_table, i, val_to_str(i, nt_cmd_vals, "Unknown(0x%02x)"));
213         }
214
215
216         error_string=register_tap_listener("smb", ss, filter, smbstat_reset, smbstat_packet, smbstat_draw);
217         if(error_string){
218                 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, error_string->str);
219                 g_string_free(error_string, TRUE);
220                 g_free(ss);
221                 return;
222         }
223
224         /* Button row. */
225         bbox = dlg_button_row_new(GTK_STOCK_CLOSE, NULL);
226         gtk_box_pack_end(GTK_BOX(vbox), bbox, FALSE, FALSE, 0);
227
228         close_bt = OBJECT_GET_DATA(bbox, GTK_STOCK_CLOSE);
229     window_set_cancel_button(ss->win, close_bt, window_cancel_button_cb);
230
231     SIGNAL_CONNECT(ss->win, "delete_event", window_delete_event_cb, NULL);
232         SIGNAL_CONNECT(ss->win, "destroy", win_destroy_cb, ss);
233
234     gtk_widget_show_all(ss->win);
235     window_present(ss->win);
236         
237     retap_packets(&cfile);
238 }
239
240
241
242 static GtkWidget *dlg=NULL;
243 static GtkWidget *filter_entry;
244
245 static void
246 dlg_destroy_cb(void)
247 {
248         dlg=NULL;
249 }
250
251 static void
252 smbstat_start_button_clicked(GtkWidget *item _U_, gpointer data _U_)
253 {
254         GString *str;
255         const char *filter;
256
257         str = g_string_new("smb,srt");
258         filter=gtk_entry_get_text(GTK_ENTRY(filter_entry));
259         if(filter[0]!=0){
260                 g_string_sprintfa(str,",%s", filter);
261         }
262         gtk_smbstat_init(str->str);
263         g_string_free(str, TRUE);
264 }
265
266 static void
267 gtk_smbstat_cb(GtkWidget *w _U_, gpointer d _U_)
268 {
269         GtkWidget *dlg_box;
270         GtkWidget *filter_box, *filter_bt;
271         GtkWidget *bbox, *start_button, *cancel_button;
272         const char *filter;
273         static construct_args_t args = {
274           "Service Response Time Statistics Filter",
275           TRUE,
276           FALSE
277         };
278
279         /* if the window is already open, bring it to front */
280         if(dlg){
281                 gdk_window_raise(dlg->window);
282                 return;
283         }
284
285         dlg=dlg_window_new("Ethereal: Compute SMB SRT statistics");
286         gtk_window_set_default_size(GTK_WINDOW(dlg), 300, -1);
287
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);
292
293         /* Filter box */
294         filter_box=gtk_hbox_new(FALSE, 3);
295
296         /* Filter button */
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);
301
302         /* Filter entry */
303         filter_entry=gtk_entry_new();
304     SIGNAL_CONNECT(filter_entry, "changed", filter_te_syntax_check_cb, NULL);
305
306         /* filter prefs dialog */
307         OBJECT_SET_DATA(filter_bt, E_FILT_TE_PTR_KEY, filter_entry);
308         /* filter prefs dialog */
309
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));
312         if(filter){
313                 gtk_entry_set_text(GTK_ENTRY(filter_entry), filter);
314         }
315         gtk_widget_show(filter_entry);
316
317         gtk_box_pack_start(GTK_BOX(dlg_box), filter_box, TRUE, TRUE, 0);
318         gtk_widget_show(filter_box);
319
320         /* button 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);
324
325     start_button = OBJECT_GET_DATA(bbox, ETHEREAL_STOCK_CREATE_STAT);
326     SIGNAL_CONNECT_OBJECT(start_button, "clicked",
327                               smbstat_start_button_clicked, NULL);
328
329     cancel_button = OBJECT_GET_DATA(bbox, GTK_STOCK_CANCEL);
330     window_set_cancel_button(dlg, cancel_button, window_cancel_button_cb);
331
332         /* Catch the "activate" signal on the filter text entry, so that
333            if the user types Return there, we act as if the "Create Stat"
334            button had been selected, as happens if Return is typed if some
335            widget that *doesn't* handle the Return key has the input
336            focus. */
337         dlg_set_activate(filter_entry, start_button);
338
339     gtk_widget_grab_default(start_button );
340
341     /* Give the initial focus to the "Filter" entry box. */
342         gtk_widget_grab_focus(filter_entry);
343
344     SIGNAL_CONNECT(dlg, "delete_event", window_delete_event_cb, NULL);
345         SIGNAL_CONNECT(dlg, "destroy", dlg_destroy_cb, NULL);
346
347     gtk_widget_show_all(dlg);
348     window_present(dlg);
349 }
350
351 void
352 register_tap_listener_gtksmbstat(void)
353 {
354         register_ethereal_tap("smb,srt", gtk_smbstat_init);
355
356         register_tap_menu_item("SMB...", REGISTER_TAP_GROUP_RESPONSE_TIME,
357             gtk_smbstat_cb, NULL, NULL, NULL);
358 }