update epan/dissectors/pidl/drsuapi/drsuapi.idl from samba
[wireshark-sm.git] / ui / cli / tap-camelsrt.c
blob0f98b99695bebae0a998a04211aa0c13b05485fa
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)
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * SPDX-License-Identifier: GPL-2.0-or-later
12 #include "config.h"
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <string.h>
18 #include "epan/packet.h"
19 #include <epan/tap.h>
20 #include "epan/value_string.h"
21 #include "epan/asn1.h"
22 #include "epan/dissectors/packet-camel.h"
23 #include "epan/dissectors/packet-tcap.h"
24 #include "epan/timestats.h"
25 #include "epan/stat_tap_ui.h"
27 #include <wsutil/cmdarg_err.h>
29 void register_tap_listener_camelsrt(void);
31 /* Save the first NUM_RAS_STATS stats in the array to calculate percentile */
32 #define NUM_RAS_STATS 500000
34 /* Number of couple message Request/Response to analyze*/
35 #define NB_CRITERIA 7
37 /* used to keep track of the statistics for an entire program interface */
38 struct camelsrt_t {
39 char *filter;
40 uint32_t count[NB_CAMELSRT_CATEGORY];
41 timestat_t stats[NB_CAMELSRT_CATEGORY];
42 nstime_t delta_time[NB_CAMELSRT_CATEGORY][NUM_RAS_STATS];
45 /* Reset the counter */
46 static void camelsrt_reset(void *phs)
48 struct camelsrt_t *hs = (struct camelsrt_t *)phs;
49 memset(hs, 0, sizeof(struct camelsrt_t));
53 static tap_packet_status camelsrt_packet(void *phs,
54 packet_info *pinfo _U_,
55 epan_dissect_t *edt _U_,
56 const void *phi, tap_flags_t flags _U_)
58 struct camelsrt_t *hs = (struct camelsrt_t *)phs;
59 const struct camelsrt_info_t * pi = (const struct camelsrt_info_t *)phi;
60 int i;
62 for (i=0; i<NB_CAMELSRT_CATEGORY; i++) {
63 if (pi->bool_msginfo[i] &&
64 pi->msginfo[i].is_delta_time
65 && pi->msginfo[i].request_available
66 && !pi->msginfo[i].is_duplicate ) {
68 time_stat_update(&(hs->stats[i]),
69 &(pi->msginfo[i].delta_time),
70 pinfo);
72 if (hs->count[i] < NUM_RAS_STATS) {
73 hs->delta_time[i][hs->count[i]++]
74 = pi->msginfo[i].delta_time;
78 return TAP_PACKET_REDRAW;
82 static void camelsrt_draw(void *phs)
84 struct camelsrt_t *hs = (struct camelsrt_t *)phs;
85 unsigned j, z;
86 uint32_t li;
87 int somme, iteration = 0;
88 timestat_t *rtd_temp;
89 double x, delay, delay_max, delay_min, delta;
90 double criteria[NB_CRITERIA] = { 5.0, 10.0, 75.0, 90.0, 95.0, 99.0, 99.90 };
91 double delay_criteria[NB_CRITERIA];
92 char* tmp_str;
94 printf("\n");
95 printf("Camel Service Response Time (SRT) Statistics:\n");
96 printf("=================================================================================================\n");
97 printf("| Category | Measure | Min SRT | Max SRT | Avg SRT | Min frame | Max frame |\n");
98 printf("|-------------------------|---------|-----------|-----------|-----------|-----------|-----------|\n");
100 j = 1;
101 tmp_str = val_to_str_wmem(NULL, j, camelSRTtype_naming, "Unknown Message 0x%02x");
102 printf("|%24s |%8u |%8.2f s |%8.2f s |%8.2f s |%10u |%10u |\n",
103 tmp_str,
104 hs->stats[j].num,
105 nstime_to_sec(&(hs->stats[j].min)),
106 nstime_to_sec(&(hs->stats[j].max)),
107 get_average(&(hs->stats[j].tot), hs->stats[j].num)/1000.0,
108 hs->stats[j].min_num,
109 hs->stats[j].max_num
111 wmem_free(NULL, tmp_str);
112 for (j=2; j<NB_CAMELSRT_CATEGORY; j++) {
113 if (hs->stats[j].num == 0) {
114 tmp_str = val_to_str_wmem(NULL, j, camelSRTtype_naming, "Unknown Message 0x%02x");
115 printf("|%24s |%8u |%8.2f ms|%8.2f ms|%8.2f ms|%10u |%10u |\n",
116 tmp_str, 0U, 0.0, 0.0, 0.0, 0U, 0U);
117 wmem_free(NULL, tmp_str);
118 continue;
121 tmp_str = val_to_str_wmem(NULL, j, camelSRTtype_naming, "Unknown Message 0x%02x");
122 printf("|%24s |%8u |%8.2f ms|%8.2f ms|%8.2f ms|%10u |%10u |\n",
123 tmp_str,
124 hs->stats[j].num,
125 MIN(9999, nstime_to_msec(&(hs->stats[j].min))),
126 MIN(9999, nstime_to_msec(&(hs->stats[j].max))),
127 MIN(9999, get_average(&(hs->stats[j].tot), hs->stats[j].num)),
128 hs->stats[j].min_num,
129 hs->stats[j].max_num
131 wmem_free(NULL, tmp_str);
132 } /* j category */
134 printf("=================================================================================================\n");
136 * Display 95%
139 printf("| Category/Criteria |");
140 for (z=0; z<NB_CRITERIA; z++) printf("%7.2f%% |", criteria[z]);
141 printf("\n");
143 printf("|-------------------------|");
144 for (z=0; z<NB_CRITERIA; z++) printf("---------|");
145 printf("\n");
146 /* calculate the delay max to have a given number of messages (in percentage) */
147 for (j=2; j<NB_CAMELSRT_CATEGORY;j++) {
149 rtd_temp = &(hs->stats[j]);
151 if (hs->count[j] > 0) {
152 /* Calculate the delay to answer to p% of the MS */
153 for (z=0; z<NB_CRITERIA; z++) {
154 iteration = 0;
155 delay_max = (double)rtd_temp->max.secs*1000 +(double)rtd_temp->max.nsecs/1000000;
156 delay_min = (double)rtd_temp->min.secs*1000 +(double)rtd_temp->min.nsecs/1000000;
157 delay = delay_min;
158 delta = delay_max-delay_min;
159 while ( (delta > 0.001) && (iteration < 10000) ) {
160 somme = 0;
161 iteration++;
163 for (li=0; li<hs->count[j]; li++) {
164 x = hs->delta_time[j][li].secs*1000
165 + (double)hs->delta_time[j][li].nsecs/1000000;
166 if (x <= delay) somme++;
168 if ( somme*100 > hs->count[j]*criteria[z] ) { /* trop grand */
169 delay_max = delay;
170 delay = (delay_max+delay_min)/2;
171 delta = delay_max-delay_min;
172 } else { /* trop petit */
173 delay_min = delay;
174 delay = (delay_max+delay_min)/2;
175 delta = delay_max-delay_min;
177 } /* while */
178 delay_criteria[z] = delay;
179 } /* z criteria */
180 /* Append the result to the table */
181 tmp_str = val_to_str_wmem(NULL, j, camelSRTtype_naming, "Unknown Message 0x%02x");
182 printf("X%24s |", tmp_str);
183 wmem_free(NULL, tmp_str);
184 for (z=0; z<NB_CRITERIA; z++) printf("%8.2f |", MIN(9999, delay_criteria[z]));
185 printf("\n");
186 } else { /* count */
187 tmp_str = val_to_str_wmem(NULL, j, camelSRTtype_naming, "Unknown Message 0x%02x");
188 printf("X%24s |", tmp_str);
189 wmem_free(NULL, tmp_str);
190 for (z=0; z<NB_CRITERIA; z++) printf("%8.2f |", 0.0);
191 printf("\n");
192 } /* count */
193 }/* j category */
194 printf("===========================");
195 for (z=0; z<NB_CRITERIA; z++) printf("==========");
196 printf("\n");
199 static void camelsrt_init(const char *opt_arg, void *userdata _U_)
201 struct camelsrt_t *p_camelsrt;
202 GString *error_string;
204 p_camelsrt = g_new(struct camelsrt_t, 1);
205 camelsrt_reset(p_camelsrt);
207 if (!strncmp(opt_arg, "camel,srt,", 10)) {
208 p_camelsrt->filter = g_strdup(opt_arg+10);
209 } else {
210 p_camelsrt->filter = NULL;
213 error_string = register_tap_listener("CAMEL",
214 p_camelsrt,
215 p_camelsrt->filter,
217 NULL,
218 camelsrt_packet,
219 camelsrt_draw,
220 NULL);
222 if (error_string) {
223 /* error, we failed to attach to the tap. clean up */
224 g_free(p_camelsrt->filter);
225 g_free(p_camelsrt);
227 cmdarg_err("Couldn't register camel,srt tap: %s", error_string->str);
228 g_string_free(error_string, TRUE);
229 exit(1);
233 * If we are using tshark, we have to display the stats, even if the stats are not persistent
234 * As the frame are proceeded in the chronological order, we do not need persistent stats
235 * Whereas, with wireshark, it is not possible to have the correct display, if the stats are
236 * not saved along the analyze
238 gtcap_StatSRT = true;
239 gcamel_StatSRT = true;
242 static stat_tap_ui camelsrt_ui = {
243 REGISTER_STAT_GROUP_GENERIC,
244 NULL,
245 "camel,srt",
246 camelsrt_init,
248 NULL
251 void
252 register_tap_listener_camelsrt(void)
254 register_stat_tap_ui(&camelsrt_ui, NULL);
258 * Editor modelines - https://www.wireshark.org/tools/modelines.html
260 * Local Variables:
261 * c-basic-offset: 2
262 * tab-width: 8
263 * indent-tabs-mode: nil
264 * End:
266 * ex: set shiftwidth=2 tabstop=8 expandtab:
267 * :indentSize=2:tabSize=8:noTabs=true: