merge_all_tap_menus() has been moved to menus.c.
[obnox/wireshark/wip.git] / gtk / camel_counter.c
1 /* camel_counter.c
2  * camel message counter for Wireshark
3  * Copyright 2006 Florent Drouin (based on h225_counter.c from Lars Roland)
4  *
5  * $Id$
6  *
7  * Wireshark - Network traffic analyzer
8  * By Gerald Combs <gerald@wireshark.org>
9  * Copyright 1998 Gerald Combs
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
24  */
25
26 #ifdef HAVE_CONFIG_H
27 #include "config.h"
28 #endif
29
30 #ifdef HAVE_SYS_TYPES_H
31 # include <sys/types.h>
32 #endif
33
34 #include <string.h>
35 #include <gtk/gtk.h>
36
37 #include <epan/epan.h>
38 #include <epan/packet_info.h>
39 #include <epan/value_string.h>
40 #include <epan/tap.h>
41 #include <epan/packet.h>
42 #include <epan/asn1.h>
43 #include <epan/camel-persistentdata.h>
44
45 #include "../stat_menu.h"
46 #include "../timestats.h"
47 #include "../simple_dialog.h"
48
49 #include "gtk/main.h"
50 #include "gtk/dlg_utils.h"
51 #include "gtk/gui_utils.h"
52 #include "gtk/gui_stat_util.h"
53 #include "gtk/tap_param_dlg.h"
54
55 #include "gtk/old-gtk-compat.h"
56
57 static void gtk_camelcounter_reset(void *phs);
58 static int gtk_camelcounter_packet(void *phs,
59                                    packet_info *pinfo _U_,
60                                    epan_dissect_t *edt _U_,
61                                    const void *phi);
62 static void gtk_camelcounter_draw(void *phs);
63 static void win_destroy_cb(GtkWindow *win _U_, gpointer data);
64 static void gtk_camelcounter_init(const char *optarg, void *userdata _U_);
65 void register_tap_listener_gtk_camelcounter(void);
66
67 /* following values represent the size of their valuestring arrays */
68
69 struct camelcounter_t {
70   GtkWidget *win;
71   GtkWidget *vbox;
72   char *filter;
73   GtkWidget *scrolled_window;
74   GtkTreeView *table;
75   guint32 camel_msg[camel_MAX_NUM_OPR_CODES];
76 };
77
78 static void gtk_camelcounter_reset(void *phs)
79 {
80   struct camelcounter_t * p_counter= ( struct camelcounter_t *) phs;
81   int i;
82
83   /* Erase Message Type count */
84   for(i=0;i<camel_MAX_NUM_OPR_CODES;i++) {
85     p_counter->camel_msg[i]=0;
86   }
87 }
88
89
90 /*
91  * If there is a valid camel operation, increase the value in the array of counter
92  */
93 static int gtk_camelcounter_packet(void *phs,
94                                    packet_info *pinfo _U_,
95                                    epan_dissect_t *edt _U_,
96                                    const void *phi)
97 {
98   struct camelcounter_t * p_counter =(struct camelcounter_t *)phs;
99   const struct camelsrt_info_t * pi=phi;
100   if (pi->opcode != 255)
101     p_counter->camel_msg[pi->opcode]++;
102
103   return 1;
104 }
105
106 static void gtk_camelcounter_draw(void *phs)
107 {
108   struct camelcounter_t *p_counter=(struct camelcounter_t *)phs;
109   int i;
110   char str[256];
111   GtkListStore *store;
112   GtkTreeIter iter;
113
114   /* Now print Message and Reason Counter Table */
115   /* clear list before printing */
116   store = GTK_LIST_STORE(gtk_tree_view_get_model(p_counter->table));
117   gtk_list_store_clear(store);
118
119   for(i=0;i<camel_MAX_NUM_OPR_CODES;i++) {
120     /* Message counter */
121     if(p_counter->camel_msg[i]!=0) {
122       g_snprintf(str, 256, "Request %s", val_to_str(i,camel_opr_code_strings,"Unknown message "));
123
124       gtk_list_store_append(store, &iter);
125       gtk_list_store_set(store, &iter,
126                                    0, str,
127                                    1, p_counter->camel_msg[i],
128                                    -1);
129     }
130   } /* Message Type */
131 }
132
133 static void win_destroy_cb(GtkWindow *win _U_, gpointer data)
134 {
135   struct camelcounter_t *hs=(struct camelcounter_t *)data;
136
137   protect_thread_critical_region();
138   remove_tap_listener(hs);
139   unprotect_thread_critical_region();
140
141   if(hs->filter){
142     g_free(hs->filter);
143     hs->filter=NULL;
144   }
145   g_free(hs);
146 }
147
148 static const stat_column titles[]={
149   {G_TYPE_STRING, LEFT, "Message Type or Reason"},
150   {G_TYPE_UINT, RIGHT, "Count" }
151 };
152
153 static void gtk_camelcounter_init(const char *optarg, void *userdata _U_)
154 {
155   struct camelcounter_t *p_camelcounter;
156   const char *filter=NULL;
157   GString *error_string;
158   GtkWidget *bbox;
159   GtkWidget *close_bt;
160
161   if(strncmp(optarg,"camel,counter,",14) == 0){
162     filter=optarg+14;
163   } else {
164     filter=NULL;
165   }
166
167   p_camelcounter=g_malloc(sizeof(struct camelcounter_t));
168   p_camelcounter->filter=g_strdup(filter);
169
170   gtk_camelcounter_reset(p_camelcounter);
171
172   /* transient_for top_level */
173   p_camelcounter->win=dlg_window_new("Wireshark: CAMEL counters");
174   gtk_window_set_destroy_with_parent (GTK_WINDOW(p_camelcounter->win), TRUE);
175
176         gtk_window_set_default_size(GTK_WINDOW(p_camelcounter->win), 500, 300);
177
178   p_camelcounter->vbox=gtk_vbox_new(FALSE, 3);
179   gtk_container_set_border_width(GTK_CONTAINER(p_camelcounter->vbox), 12);
180
181   init_main_stat_window(p_camelcounter->win, p_camelcounter->vbox, "CAMEL Messages Counters", filter);
182
183   /* init a scrolled window*/
184   p_camelcounter->scrolled_window = scrolled_window_new(NULL, NULL);
185
186   p_camelcounter->table = create_stat_table(p_camelcounter->scrolled_window, p_camelcounter->vbox, 2, titles);
187
188   error_string=register_tap_listener("CAMEL", p_camelcounter, filter, 0,
189                                        gtk_camelcounter_reset,
190                                        gtk_camelcounter_packet,
191                                        gtk_camelcounter_draw);
192
193   if(error_string){
194     simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", error_string->str);
195     g_string_free(error_string, TRUE);
196     g_free(p_camelcounter);
197     return;
198   }
199
200   /* Button row. */
201   bbox = dlg_button_row_new(GTK_STOCK_CLOSE, NULL);
202   gtk_box_pack_end(GTK_BOX(p_camelcounter->vbox), bbox, FALSE, FALSE, 0);
203
204   close_bt = g_object_get_data(G_OBJECT(bbox), GTK_STOCK_CLOSE);
205   window_set_cancel_button(p_camelcounter->win, close_bt, window_cancel_button_cb);
206
207   g_signal_connect(p_camelcounter->win, "delete_event", G_CALLBACK(window_delete_event_cb), NULL);
208   g_signal_connect(p_camelcounter->win, "destroy", G_CALLBACK(win_destroy_cb), p_camelcounter);
209
210   gtk_widget_show_all(p_camelcounter->win);
211   window_present(p_camelcounter->win);
212
213   cf_retap_packets(&cfile);
214   gdk_window_raise(gtk_widget_get_window(p_camelcounter->win));
215 }
216
217 static tap_param camel_counter_params[] = {
218   { PARAM_FILTER, "Filter", NULL }
219 };
220
221 static tap_param_dlg camel_counter_dlg = {
222   "CAMEL Messages and Response Status",
223   "camel,counter",
224   gtk_camelcounter_init,
225   -1,
226   G_N_ELEMENTS(camel_counter_params),
227   camel_counter_params
228 };
229
230 void  /* Next line mandatory */
231 register_tap_listener_gtk_camelcounter(void)
232 {
233   register_dfilter_stat(&camel_counter_dlg, "_GSM/CAMEL",
234                         REGISTER_STAT_GROUP_TELEPHONY);
235
236 }
237
238 #ifdef MAIN_MENU_USE_UIMANAGER
239 void camel_counter_cb(GtkAction *action, gpointer user_data _U_)
240 {
241         tap_param_dlg_cb(action, &camel_counter_dlg);
242 }
243 #endif