Get rid of an unused structure member.
[metze/wireshark/wip.git] / ui / cli / tap-camelsrt.c
1 /* tap_camelsrt.c
2  * CAMEL Service Response Time statistics for tshark
3  * Copyright 2006 Florent Drouin (based on tap_h225rassrt.c from Lars Roland)
4  *
5  * Wireshark - Network traffic analyzer
6  * By Gerald Combs <gerald@wireshark.org>
7  * Copyright 1998 Gerald Combs
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License
11  * as published by the Free Software Foundation; either version 2
12  * of the License, or (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22  */
23
24 #include "config.h"
25
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29
30 #include "epan/packet.h"
31 #include <epan/tap.h>
32 #include "epan/value_string.h"
33 #include "epan/asn1.h"
34 #include "epan/dissectors/packet-camel.h"
35 #include "epan/dissectors/packet-tcap.h"
36 #include "epan/timestats.h"
37 #include "epan/stat_tap_ui.h"
38
39
40 void register_tap_listener_camelsrt(void);
41
42 /* Save the the first NUM_RAS_STATS stats in the array to calculate percentile */
43 #define NUM_RAS_STATS 500000
44
45 /* Number of couple message Request/Response to analyze*/
46 #define NB_CRITERIA 7
47
48 /* used to keep track of the statistics for an entire program interface */
49 struct camelsrt_t {
50   char *filter;
51   guint32 count[NB_CAMELSRT_CATEGORY];
52   timestat_t stats[NB_CAMELSRT_CATEGORY];
53   nstime_t delta_time[NB_CAMELSRT_CATEGORY][NUM_RAS_STATS];
54 };
55
56 /* Reset the counter */
57 static void camelsrt_reset(void *phs)
58 {
59   struct camelsrt_t *hs = (struct camelsrt_t *)phs;
60   memset(hs, 0, sizeof(struct camelsrt_t));
61 }
62
63
64 static int camelsrt_packet(void *phs,
65                            packet_info *pinfo _U_,
66                            epan_dissect_t *edt _U_,
67                            const void *phi)
68 {
69   struct camelsrt_t *hs = (struct camelsrt_t *)phs;
70   const struct camelsrt_info_t * pi = (const struct camelsrt_info_t *)phi;
71   int i;
72
73   for (i=0; i<NB_CAMELSRT_CATEGORY; i++) {
74     if (pi->bool_msginfo[i] &&
75         pi->msginfo[i].is_delta_time
76         && pi->msginfo[i].request_available
77         && !pi->msginfo[i].is_duplicate ) {
78
79       time_stat_update(&(hs->stats[i]),
80                        &(pi->msginfo[i].delta_time),
81                        pinfo);
82
83       if (hs->count[i] < NUM_RAS_STATS) {
84         hs->delta_time[i][hs->count[i]++]
85           = pi->msginfo[i].delta_time;
86       }
87     }
88   }
89   return 1;
90 }
91
92
93 static void camelsrt_draw(void *phs)
94 {
95   struct camelsrt_t *hs = (struct camelsrt_t *)phs;
96   guint j, z;
97   guint32 li;
98   int somme, iteration = 0;
99   timestat_t *rtd_temp;
100   double x, delay, delay_max, delay_min, delta;
101   double criteria[NB_CRITERIA] = { 5.0, 10.0, 75.0, 90.0, 95.0, 99.0, 99.90 };
102   double delay_criteria[NB_CRITERIA];
103   gchar* tmp_str;
104
105   printf("\n");
106   printf("Camel Service Response Time (SRT) Statistics:\n");
107   printf("=================================================================================================\n");
108   printf("|        Category         | Measure |  Min SRT  |  Max SRT  |  Avg SRT  | Min frame | Max frame |\n");
109   printf("|-------------------------|---------|-----------|-----------|-----------|-----------|-----------|\n");
110
111   j = 1;
112   tmp_str = val_to_str_wmem(NULL, j, camelSRTtype_naming, "Unknown Message 0x%02x");
113   printf("|%24s |%8u |%8.2f s |%8.2f s |%8.2f s |%10u |%10u |\n",
114          tmp_str,
115          hs->stats[j].num,
116          nstime_to_sec(&(hs->stats[j].min)),
117          nstime_to_sec(&(hs->stats[j].max)),
118          get_average(&(hs->stats[j].tot), hs->stats[j].num)/1000.0,
119          hs->stats[j].min_num,
120          hs->stats[j].max_num
121          );
122   wmem_free(NULL, tmp_str);
123   for (j=2; j<NB_CAMELSRT_CATEGORY; j++) {
124     if (hs->stats[j].num == 0) {
125       tmp_str = val_to_str_wmem(NULL, j, camelSRTtype_naming, "Unknown Message 0x%02x");
126       printf("|%24s |%8u |%8.2f ms|%8.2f ms|%8.2f ms|%10u |%10u |\n",
127              tmp_str, 0U, 0.0, 0.0, 0.0, 0U, 0U);
128       wmem_free(NULL, tmp_str);
129       continue;
130     }
131
132     tmp_str = val_to_str_wmem(NULL, j, camelSRTtype_naming, "Unknown Message 0x%02x");
133     printf("|%24s |%8u |%8.2f ms|%8.2f ms|%8.2f ms|%10u |%10u |\n",
134            tmp_str,
135            hs->stats[j].num,
136            MIN(9999, nstime_to_msec(&(hs->stats[j].min))),
137            MIN(9999, nstime_to_msec(&(hs->stats[j].max))),
138            MIN(9999, get_average(&(hs->stats[j].tot), hs->stats[j].num)),
139            hs->stats[j].min_num,
140            hs->stats[j].max_num
141            );
142     wmem_free(NULL, tmp_str);
143   } /* j category */
144
145   printf("=================================================================================================\n");
146   /*
147    * Display 95%
148    */
149
150   printf("|   Category/Criteria     |");
151   for (z=0; z<NB_CRITERIA; z++) printf("%7.2f%% |", criteria[z]);
152   printf("\n");
153
154   printf("|-------------------------|");
155   for (z=0; z<NB_CRITERIA; z++) printf("---------|");
156   printf("\n");
157   /* calculate the delay max to have a given number of messages (in percentage) */
158   for (j=2; j<NB_CAMELSRT_CATEGORY;j++) {
159
160     rtd_temp = &(hs->stats[j]);
161
162     if (hs->count[j] > 0) {
163       /* Calculate the delay to answer to p% of the MS */
164       for (z=0; z<NB_CRITERIA; z++) {
165         iteration = 0;
166         delay_max = (double)rtd_temp->max.secs*1000 +(double)rtd_temp->max.nsecs/1000000;
167         delay_min = (double)rtd_temp->min.secs*1000 +(double)rtd_temp->min.nsecs/1000000;
168         delay = delay_min;
169         delta = delay_max-delay_min;
170         while ( (delta > 0.001) && (iteration < 10000) ) {
171           somme = 0;
172           iteration++;
173
174           for (li=0; li<hs->count[j]; li++) {
175             x = hs->delta_time[j][li].secs*1000
176               + (double)hs->delta_time[j][li].nsecs/1000000;
177             if (x <= delay) somme++;
178           }
179           if ( somme*100 > hs->count[j]*criteria[z] ) { /* trop grand */
180             delay_max = delay;
181             delay = (delay_max+delay_min)/2;
182             delta = delay_max-delay_min;
183           } else { /* trop petit */
184             delay_min = delay;
185             delay = (delay_max+delay_min)/2;
186             delta = delay_max-delay_min;
187           }
188         } /* while */
189         delay_criteria[z] = delay;
190       } /* z criteria */
191       /* Append the result to the table */
192       tmp_str = val_to_str_wmem(NULL, j, camelSRTtype_naming, "Unknown Message 0x%02x");
193       printf("X%24s |", tmp_str);
194       wmem_free(NULL, tmp_str);
195       for (z=0; z<NB_CRITERIA; z++) printf("%8.2f |", MIN(9999, delay_criteria[z]));
196       printf("\n");
197     } else { /* count */
198       tmp_str = val_to_str_wmem(NULL, j, camelSRTtype_naming, "Unknown Message 0x%02x");
199       printf("X%24s |", tmp_str);
200       wmem_free(NULL, tmp_str);
201       for (z=0; z<NB_CRITERIA; z++) printf("%8.2f |", 0.0);
202       printf("\n");
203     } /* count */
204   }/* j category */
205   printf("===========================");
206   for (z=0; z<NB_CRITERIA; z++) printf("==========");
207   printf("\n");
208 }
209
210 static void camelsrt_init(const char *opt_arg, void *userdata _U_)
211 {
212   struct camelsrt_t *p_camelsrt;
213   GString *error_string;
214
215   p_camelsrt = g_new(struct camelsrt_t, 1);
216   if (!strncmp(opt_arg, "camel,srt,", 9)) {
217     p_camelsrt->filter = g_strdup(opt_arg+9);
218   } else {
219     p_camelsrt->filter = NULL;
220   }
221   camelsrt_reset(p_camelsrt);
222
223   error_string = register_tap_listener("CAMEL",
224                                      p_camelsrt,
225                                      p_camelsrt->filter,
226                                      0,
227                                      NULL,
228                                      camelsrt_packet,
229                                      camelsrt_draw);
230
231   if (error_string) {
232     /* error, we failed to attach to the tap. clean up */
233     g_free(p_camelsrt->filter);
234     g_free(p_camelsrt);
235
236     fprintf(stderr, "tshark: Couldn't register camel,srt tap: %s\n",
237             error_string->str);
238     g_string_free(error_string, TRUE);
239     exit(1);
240   }
241
242   /*
243    * If we are using tshark, we have to display the stats, even if the stats are not persistent
244    * As the frame are proceeded in the chronological order, we do not need persistent stats
245    * Whereas, with wireshark, it is not possible to have the correct display, if the stats are
246    * not saved along the analyze
247    */
248   gtcap_StatSRT = TRUE;
249   gcamel_StatSRT = TRUE;
250 }
251
252 static stat_tap_ui camelsrt_ui = {
253   REGISTER_STAT_GROUP_GENERIC,
254   NULL,
255   "camel,srt",
256   camelsrt_init,
257   0,
258   NULL
259 };
260
261 void /* Next line mandatory */
262 register_tap_listener_camelsrt(void)
263 {
264   register_stat_tap_ui(&camelsrt_ui, NULL);
265 }
266
267 /*
268  * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
269  *
270  * Local Variables:
271  * c-basic-offset: 2
272  * tab-width: 8
273  * indent-tabs-mode: nil
274  * End:
275  *
276  * ex: set shiftwidth=2 tabstop=8 expandtab:
277  * :indentSize=2:tabSize=8:noTabs=true:
278  */