Squelch more const warnings (and fix some memory leaks that found).
[obnox/wireshark/wip.git] / gtk / ldap_stat.c
1 /* ldap_stat.c
2  * ldap_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 <epan/dissectors/packet-ldap.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 _ldapstat_t {
59         GtkWidget *win;
60         srt_stat_table ldap_srt_table;
61 } ldapstat_t;
62
63 static void
64 ldapstat_set_title(ldapstat_t *ldap)
65 {
66         char            *title;
67
68         title = g_strdup_printf("LDAP Service Response Time statistics: %s",
69             cf_get_display_name(&cfile));
70         gtk_window_set_title(GTK_WINDOW(ldap->win), title);
71         g_free(title);
72 }
73
74 static void
75 ldapstat_reset(void *pldap)
76 {
77         ldapstat_t *ldap=(ldapstat_t *)pldap;
78
79         reset_srt_table_data(&ldap->ldap_srt_table);
80         ldapstat_set_title(ldap);
81 }
82
83 static int
84 ldapstat_packet(void *pldap, packet_info *pinfo, epan_dissect_t *edt _U_, const void *psi)
85 {
86         const ldap_call_response_t *ldap=psi;
87         ldapstat_t *fs=(ldapstat_t *)pldap;
88
89         /* we are only interested in reply packets */
90         if(ldap->is_request){
91                 return 0;
92         }
93         /* if we havnt seen the request, just ignore it */
94         if(!ldap->req_frame){ 
95                 return 0;
96         }
97
98         /* only use the commands we know how to handle */
99         switch(ldap->protocolOpTag){
100         case LDAP_REQ_BIND:
101         case LDAP_REQ_SEARCH:
102         case LDAP_REQ_MODIFY:
103         case LDAP_REQ_ADD:
104         case LDAP_REQ_DELETE:
105         case LDAP_REQ_MODRDN:
106         case LDAP_REQ_COMPARE:
107         case LDAP_REQ_EXTENDED:
108                 break;
109         default:
110                 return 0;
111         }
112
113         add_srt_table_data(&fs->ldap_srt_table, ldap->protocolOpTag, &ldap->req_time, pinfo);
114
115         return 1;
116 }
117
118
119
120 static void
121 ldapstat_draw(void *pldap)
122 {
123         ldapstat_t *ldap=(ldapstat_t *)pldap;
124
125         draw_srt_table_data(&ldap->ldap_srt_table);
126 }
127
128
129 void protect_thread_critical_region(void);
130 void unprotect_thread_critical_region(void);
131 static void
132 win_destroy_cb(GtkWindow *win _U_, gpointer data)
133 {
134         ldapstat_t *ldap=(ldapstat_t *)data;
135
136         protect_thread_critical_region();
137         remove_tap_listener(ldap);
138         unprotect_thread_critical_region();
139
140         free_srt_table_data(&ldap->ldap_srt_table);
141         g_free(ldap);
142 }
143
144
145 static void
146 gtk_ldapstat_init(const char *optarg)
147 {
148         ldapstat_t *ldap;
149         const char *filter=NULL;
150         GtkWidget *label;
151         char filter_string[256];
152         GString *error_string;
153         GtkWidget *vbox;
154         GtkWidget *bbox;
155         GtkWidget *close_bt;
156
157         if(!strncmp(optarg,"ldap,srt,",9)){
158                 filter=optarg+9;
159         } else {
160                 filter=NULL;
161         }
162
163         ldap=g_malloc(sizeof(ldapstat_t));
164
165         ldap->win=window_new(GTK_WINDOW_TOPLEVEL, "ldap-stat");
166         gtk_window_set_default_size(GTK_WINDOW(ldap->win), 550, 400);
167         ldapstat_set_title(ldap);
168
169         vbox=gtk_vbox_new(FALSE, 3);
170         gtk_container_add(GTK_CONTAINER(ldap->win), vbox);
171         gtk_container_set_border_width(GTK_CONTAINER(vbox), 12);
172
173         label=gtk_label_new("LDAP Service Response Time statistics");
174         gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
175
176         g_snprintf(filter_string,255,"Filter:%s",filter?filter:"");
177         label=gtk_label_new(filter_string);
178         gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
179
180         label=gtk_label_new("LDAP Commands");
181         gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
182
183         /* We must display TOP LEVEL Widget before calling init_srt_table() */
184         gtk_widget_show_all(ldap->win);
185
186         init_srt_table(&ldap->ldap_srt_table, 24, vbox, NULL);
187         init_srt_table_row(&ldap->ldap_srt_table, 0, "Bind");
188         init_srt_table_row(&ldap->ldap_srt_table, 1, "<unknown>");
189         init_srt_table_row(&ldap->ldap_srt_table, 2, "<unknown>");
190         init_srt_table_row(&ldap->ldap_srt_table, 3, "Search");
191         init_srt_table_row(&ldap->ldap_srt_table, 4, "<unknown>");
192         init_srt_table_row(&ldap->ldap_srt_table, 5, "<unknown>");
193         init_srt_table_row(&ldap->ldap_srt_table, 6, "Modify");
194         init_srt_table_row(&ldap->ldap_srt_table, 7, "<unknown>");
195         init_srt_table_row(&ldap->ldap_srt_table, 8, "Add");
196         init_srt_table_row(&ldap->ldap_srt_table, 9, "<unknown>");
197         init_srt_table_row(&ldap->ldap_srt_table, 10, "Delete");
198         init_srt_table_row(&ldap->ldap_srt_table, 11, "<unknown>");
199         init_srt_table_row(&ldap->ldap_srt_table, 12, "Modrdn");
200         init_srt_table_row(&ldap->ldap_srt_table, 13, "<unknown>");
201         init_srt_table_row(&ldap->ldap_srt_table, 14, "Compare");
202         init_srt_table_row(&ldap->ldap_srt_table, 15, "<unknown>");
203         init_srt_table_row(&ldap->ldap_srt_table, 16, "<unknown>");
204         init_srt_table_row(&ldap->ldap_srt_table, 17, "<unknown>");
205         init_srt_table_row(&ldap->ldap_srt_table, 18, "<unknown>");
206         init_srt_table_row(&ldap->ldap_srt_table, 19, "<unknown>");
207         init_srt_table_row(&ldap->ldap_srt_table, 20, "<unknown>");
208         init_srt_table_row(&ldap->ldap_srt_table, 21, "<unknown>");
209         init_srt_table_row(&ldap->ldap_srt_table, 22, "<unknown>");
210         init_srt_table_row(&ldap->ldap_srt_table, 23, "Extended");
211
212
213         error_string=register_tap_listener("ldap", ldap, filter, ldapstat_reset, ldapstat_packet, ldapstat_draw);
214         if(error_string){
215                 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, error_string->str);
216                 g_string_free(error_string, TRUE);
217                 g_free(ldap);
218                 return;
219         }
220
221         /* Button row. */
222         bbox = dlg_button_row_new(GTK_STOCK_CLOSE, NULL);
223         gtk_box_pack_end(GTK_BOX(vbox), bbox, FALSE, FALSE, 0);
224
225         close_bt = OBJECT_GET_DATA(bbox, GTK_STOCK_CLOSE);
226         window_set_cancel_button(ldap->win, close_bt, window_cancel_button_cb);
227
228         SIGNAL_CONNECT(ldap->win, "delete_event", window_delete_event_cb, NULL);
229         SIGNAL_CONNECT(ldap->win, "destroy", win_destroy_cb, ldap);
230
231         gtk_widget_show_all(ldap->win);
232         window_present(ldap->win);
233         
234         cf_retap_packets(&cfile);
235 }
236
237
238
239 static GtkWidget *dlg=NULL;
240 static GtkWidget *filter_entry;
241
242 static void
243 dlg_destroy_cb(void)
244 {
245         dlg=NULL;
246 }
247
248 static void
249 ldapstat_start_button_clicked(GtkWidget *item _U_, gpointer data _U_)
250 {
251         GString *str;
252         const char *filter;
253
254         str = g_string_new("ldap,srt");
255         filter=gtk_entry_get_text(GTK_ENTRY(filter_entry));
256         if(filter[0]!=0){
257                 g_string_sprintfa(str,",%s", filter);
258         }
259         gtk_ldapstat_init(str->str);
260         g_string_free(str, TRUE);
261 }
262
263 static void
264 gtk_ldapstat_cb(GtkWidget *w _U_, gpointer d _U_)
265 {
266         GtkWidget *dlg_box;
267         GtkWidget *filter_box, *filter_bt;
268         GtkWidget *bbox, *start_button, *cancel_button;
269         const char *filter;
270         static construct_args_t args = {
271           "Service Response Time Statistics Filter",
272           TRUE,
273           FALSE
274         };
275
276         /* if the window is already open, bring it to front */
277         if(dlg){
278                 gdk_window_raise(dlg->window);
279                 return;
280         }
281
282         dlg=dlg_window_new("Ethereal: Compute LDAP Service Response Time statistics");
283         gtk_window_set_default_size(GTK_WINDOW(dlg), 300, -1);
284
285         dlg_box=gtk_vbox_new(FALSE, 10);
286         gtk_container_border_width(GTK_CONTAINER(dlg_box), 10);
287         gtk_container_add(GTK_CONTAINER(dlg), dlg_box);
288         gtk_widget_show(dlg_box);
289
290         /* Filter box */
291         filter_box=gtk_hbox_new(FALSE, 3);
292
293         /* Filter button */
294         filter_bt=BUTTON_NEW_FROM_STOCK(ETHEREAL_STOCK_DISPLAY_FILTER_ENTRY);
295         SIGNAL_CONNECT(filter_bt, "clicked", display_filter_construct_cb, &args);
296         gtk_box_pack_start(GTK_BOX(filter_box), filter_bt, FALSE, FALSE, 0);
297         gtk_widget_show(filter_bt);
298
299         /* Filter entry */
300         filter_entry=gtk_entry_new();
301     SIGNAL_CONNECT(filter_entry, "changed", filter_te_syntax_check_cb, NULL);
302
303         /* filter prefs dialog */
304         OBJECT_SET_DATA(filter_bt, E_FILT_TE_PTR_KEY, filter_entry);
305         /* filter prefs dialog */
306
307         gtk_box_pack_start(GTK_BOX(filter_box), filter_entry, TRUE, TRUE, 0);
308         filter=gtk_entry_get_text(GTK_ENTRY(main_display_filter_widget));
309         if(filter){
310                 gtk_entry_set_text(GTK_ENTRY(filter_entry), filter);
311         }
312         gtk_widget_show(filter_entry);
313
314         gtk_box_pack_start(GTK_BOX(dlg_box), filter_box, TRUE, TRUE, 0);
315         gtk_widget_show(filter_box);
316
317         /* button box */
318     bbox = dlg_button_row_new(ETHEREAL_STOCK_CREATE_STAT, GTK_STOCK_CANCEL, NULL);
319         gtk_box_pack_start(GTK_BOX(dlg_box), bbox, FALSE, FALSE, 0);
320     gtk_widget_show(bbox);
321
322     start_button = OBJECT_GET_DATA(bbox, ETHEREAL_STOCK_CREATE_STAT);
323     SIGNAL_CONNECT_OBJECT(start_button, "clicked",
324                               ldapstat_start_button_clicked, NULL);
325
326     cancel_button = OBJECT_GET_DATA(bbox, GTK_STOCK_CANCEL);
327     window_set_cancel_button(dlg, cancel_button, window_cancel_button_cb);
328
329         /* Catch the "activate" signal on the filter text entry, so that
330            if the user types Return there, we act as if the "Create Stat"
331            button had been selected, as happens if Return is typed if some
332            widget that *doesn't* handle the Return key has the input
333            focus. */
334         dlg_set_activate(filter_entry, start_button);
335
336     gtk_widget_grab_default(start_button );
337
338     /* Give the initial focus to the "Filter" entry box. */
339         gtk_widget_grab_focus(filter_entry);
340
341         SIGNAL_CONNECT(dlg, "destroy", dlg_destroy_cb, NULL);
342
343     gtk_widget_show_all(dlg);
344     window_present(dlg);
345 }
346
347 void
348 register_tap_listener_gtkldapstat(void)
349 {
350         register_tap_listener_cmd_arg("ldap,srt", gtk_ldapstat_init);
351
352         register_tap_menu_item("LDAP...", REGISTER_TAP_GROUP_RESPONSE_TIME,
353             gtk_ldapstat_cb, NULL, NULL, NULL);
354 }