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