Warningfix:
[obnox/wireshark/wip.git] / gtk / h225_ras_srt.c
1 /* h225_ras_srt.c
2  * H.225 RAS Service Response Time statistics for Wireshar
3  * Copyright 2003 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
36 #include <gtk/gtk.h>
37
38 #include <epan/packet.h>
39 #include <epan/packet_info.h>
40 #include <epan/epan.h>
41 #include <epan/value_string.h>
42 #include <epan/tap.h>
43 #include <epan/dissectors/packet-h225.h>
44
45 #include "../register.h"
46 #include "../timestats.h"
47 #include "../simple_dialog.h"
48 #include "../file.h"
49 #include "../globals.h"
50 #include "../stat_menu.h"
51
52 #include "gtk/gui_stat_util.h"
53 #include "gtk/dlg_utils.h"
54 #include "gtk/tap_dfilter_dlg.h"
55 #include "gtk/gui_utils.h"
56 #include "gtk/main.h"
57
58
59 static void gtk_h225rassrt_init(const char *optarg, void *userdata);
60
61 static tap_dfilter_dlg h225_rassrt_dlg = {
62         "H.225 RAS Service Response Time",
63         "h225,srt",
64         gtk_h225rassrt_init,
65         -1
66 };
67
68 /* following values represent the size of their valuestring arrays */
69 #define NUM_RAS_STATS 7
70
71 static const value_string ras_message_category[] = {
72   {  0, "Gatekeeper    "},
73   {  1, "Registration  "},
74   {  2, "UnRegistration"},
75   {  3, "Admission     "},
76   {  4, "Bandwidth     "},
77   {  5, "Disengage     "},
78   {  6, "Location      "},
79   {  0, NULL }
80 };
81
82 typedef enum _ras_type {
83         RAS_REQUEST,
84         RAS_CONFIRM,
85         RAS_REJECT,
86         RAS_OTHER
87 }ras_type;
88
89 typedef enum _ras_category {
90         RAS_GATEKEEPER,
91         RAS_REGISTRATION,
92         RAS_UNREGISTRATION,
93         RAS_ADMISSION,
94         RAS_BANDWIDTH,
95         RAS_DISENGAGE,
96         RAS_LOCATION,
97         RAS_OTHERS
98 }ras_category;
99
100 /* Summary of response-time calculations*/
101 typedef struct _h225_rtd_t {
102         guint32 open_req_num;
103         guint32 disc_rsp_num;
104         guint32 req_dup_num;
105         guint32 rsp_dup_num;
106         timestat_t stats;
107 } h225_rtd_t;
108
109 /* used to keep track of the statistics for an entire program interface */
110 typedef struct _h225rassrt_t {
111         GtkWidget *win;
112         GtkWidget *vbox;
113         char *filter;
114         GtkWidget *scrolled_window;
115         GtkCList *table;
116         h225_rtd_t ras_rtd[NUM_RAS_STATS];
117 } h225rassrt_t;
118
119
120 static void
121 h225rassrt_reset(void *phs)
122 {
123         h225rassrt_t *hs=(h225rassrt_t *)phs;
124         int i;
125
126         for(i=0;i<NUM_RAS_STATS;i++) {
127                 hs->ras_rtd[i].stats.num = 0;
128                 hs->ras_rtd[i].stats.min_num = 0;
129                 hs->ras_rtd[i].stats.max_num = 0;
130                 hs->ras_rtd[i].stats.min.secs = 0;
131                 hs->ras_rtd[i].stats.min.nsecs = 0;
132                 hs->ras_rtd[i].stats.max.secs = 0;
133                 hs->ras_rtd[i].stats.max.nsecs = 0;
134                 hs->ras_rtd[i].stats.tot.secs = 0;
135                 hs->ras_rtd[i].stats.tot.nsecs = 0;
136                 hs->ras_rtd[i].open_req_num = 0;
137                 hs->ras_rtd[i].disc_rsp_num = 0;
138                 hs->ras_rtd[i].req_dup_num = 0;
139                 hs->ras_rtd[i].rsp_dup_num = 0;
140         }
141
142 }
143
144
145 static int
146 h225rassrt_packet(void *phs, packet_info *pinfo _U_, epan_dissect_t *edt _U_, const void *phi)
147 {
148         h225rassrt_t *hs=(h225rassrt_t *)phs;
149         const h225_packet_info *pi=phi;
150
151         ras_type rasmsg_type = RAS_OTHER;
152         ras_category rascategory = RAS_OTHERS;
153
154         if (pi->msg_type != H225_RAS || pi->msg_tag == -1) {
155                 /* No RAS Message or uninitialized msg_tag -> return */
156                 return 0;
157         }
158
159         if (pi->msg_tag < 21) {
160                 /* */
161                 rascategory = pi->msg_tag / 3;
162                 rasmsg_type = pi->msg_tag % 3;
163         }
164         else {
165                 /* No SRT yet (ToDo) */
166                 return 0;
167         }
168
169         switch(rasmsg_type) {
170
171         case RAS_REQUEST:
172                 if(pi->is_duplicate){
173                         hs->ras_rtd[rascategory].req_dup_num++;
174                 }
175                 else {
176                         hs->ras_rtd[rascategory].open_req_num++;
177                 }
178                 break;
179
180         case RAS_CONFIRM:
181                 /* no break - delay stats are identical for Confirm and Reject  */
182         case RAS_REJECT:
183                 if(pi->is_duplicate){
184                         /* Duplicate is ignored */
185                         hs->ras_rtd[rascategory].rsp_dup_num++;
186                 }
187                 else if (!pi->request_available) {
188                         /* no request was seen, ignore response  */
189                         hs->ras_rtd[rascategory].disc_rsp_num++;
190                 }
191                 else {
192                         hs->ras_rtd[rascategory].open_req_num--;
193                         time_stat_update(&(hs->ras_rtd[rascategory].stats),&(pi->delta_time), pinfo);
194                 }
195                 break;
196
197         default:
198                 return 0;
199         }
200         return 1;
201 }
202
203 static void
204 h225rassrt_draw(void *phs)
205 {
206         h225rassrt_t *hs=(h225rassrt_t *)phs;
207         int i;
208         char *str[11];
209
210         for(i=0;i<11;i++) {
211                 str[i]=g_malloc(sizeof(char[256]));
212         }
213         /* Now print Message and Reason Counter Table */
214         /* clear list before printing */
215         gtk_clist_clear(hs->table);
216
217         for(i=0;i<NUM_RAS_STATS;i++) {
218                 /* nothing seen, nothing to do */
219                 if(hs->ras_rtd[i].stats.num==0){
220                         continue;
221                 }
222
223                 g_snprintf(str[0], sizeof(char[256]),
224             "%s", val_to_str(i,ras_message_category,"Other"));
225                 g_snprintf(str[1], sizeof(char[256]),
226             "%7d", hs->ras_rtd[i].stats.num);
227                 g_snprintf(str[2], sizeof(char[256]),
228             "%8.2f msec", nstime_to_msec(&(hs->ras_rtd[i].stats.min)));
229                 g_snprintf(str[3], sizeof(char[256]),
230             "%8.2f msec", nstime_to_msec(&(hs->ras_rtd[i].stats.max)));;
231                 g_snprintf(str[4], sizeof(char[256]),
232             "%8.2f msec", get_average(&(hs->ras_rtd[i].stats.tot), hs->ras_rtd[i].stats.num));
233                 g_snprintf(str[5], sizeof(char[256]),
234             "%6u", hs->ras_rtd[i].stats.min_num);
235                 g_snprintf(str[6], sizeof(char[256]),
236             "%6u", hs->ras_rtd[i].stats.max_num);
237                 g_snprintf(str[7], sizeof(char[256]),
238             "%4u", hs->ras_rtd[i].open_req_num);
239                 g_snprintf(str[8], sizeof(char[256]),
240             "%4u", hs->ras_rtd[i].disc_rsp_num);
241                 g_snprintf(str[9], sizeof(char[256]),
242             "%4u", hs->ras_rtd[i].req_dup_num);
243                 g_snprintf(str[10], sizeof(char[256]),
244             "%4u", hs->ras_rtd[i].rsp_dup_num);
245                 gtk_clist_append(GTK_CLIST(hs->table), str);
246         }
247
248         gtk_widget_show(GTK_WIDGET(hs->table));
249
250 }
251
252 static void
253 win_destroy_cb(GtkWindow *win _U_, gpointer data)
254 {
255         h225rassrt_t *hs=(h225rassrt_t *)data;
256
257         protect_thread_critical_region();
258         remove_tap_listener(hs);
259         unprotect_thread_critical_region();
260
261         if(hs->filter){
262                 g_free(hs->filter);
263                 hs->filter=NULL;
264         }
265         g_free(hs);
266 }
267
268
269 static const gchar *titles[]={
270                         "RAS-Type",
271                         "Measurements",
272                         "Min RTT",
273                         "Max RTT",
274                         "Avg RTT",
275                         "Min in Frame",
276                         "Max in Frame",
277                         "Open Requests",
278                         "Discarded Responses",
279                         "Repeated Requests",
280                         "Repeated Responses" };
281
282 static void
283 gtk_h225rassrt_init(const char *optarg, void *userdata _U_)
284 {
285         h225rassrt_t *hs;
286         const char *filter=NULL;
287         GString *error_string;
288         GtkWidget *bbox;
289         GtkWidget *close_bt;
290
291         if(strncmp(optarg,"h225,srt,",9) == 0){
292                 filter=optarg+9;
293         } else {
294                 filter="";
295         }
296
297         hs=g_malloc(sizeof(h225rassrt_t));
298         hs->filter=g_strdup(filter);
299
300         h225rassrt_reset(hs);
301
302         hs->win=window_new(GTK_WINDOW_TOPLEVEL, "h225-ras-srt");
303         gtk_window_set_default_size(GTK_WINDOW(hs->win), 600, 300);
304
305         hs->vbox=gtk_vbox_new(FALSE, 3);
306         gtk_container_set_border_width(GTK_CONTAINER(hs->vbox), 12);
307
308         init_main_stat_window(hs->win, hs->vbox, "H.225 RAS Service Response Time", filter);
309
310         /* init a scrolled window*/
311         hs->scrolled_window = scrolled_window_new(NULL, NULL);
312
313         hs->table = create_stat_table(hs->scrolled_window, hs->vbox, 11, titles);
314
315         error_string=register_tap_listener("h225", hs, filter, h225rassrt_reset, h225rassrt_packet, h225rassrt_draw);
316         if(error_string){
317                 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", error_string->str);
318                 g_string_free(error_string, TRUE);
319                 g_free(hs->filter);
320                 g_free(hs);
321                 return;
322         }
323
324         /* Button row. */
325         bbox = dlg_button_row_new(GTK_STOCK_CLOSE, NULL);
326         gtk_box_pack_end(GTK_BOX(hs->vbox), bbox, FALSE, FALSE, 0);
327
328         close_bt = g_object_get_data(G_OBJECT(bbox), GTK_STOCK_CLOSE);
329         window_set_cancel_button(hs->win, close_bt, window_cancel_button_cb);
330
331         g_signal_connect(hs->win, "delete_event", G_CALLBACK(window_delete_event_cb), NULL);
332         g_signal_connect(hs->win, "destroy", G_CALLBACK(win_destroy_cb), hs);
333
334         gtk_widget_show_all(hs->win);
335         window_present(hs->win);
336
337         cf_retap_packets(&cfile, FALSE);
338         gdk_window_raise(hs->win->window);
339 }
340
341 void
342 register_tap_listener_gtk_h225rassrt(void)
343 {
344         register_dfilter_stat(&h225_rassrt_dlg, "H.225 RAS",
345             REGISTER_STAT_GROUP_RESPONSE_TIME);
346 }