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
18 #include "epan/packet.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*/
37 /* used to keep track of the statistics for an entire program interface */
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
;
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
),
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
;
87 int somme
, iteration
= 0;
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
];
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");
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",
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
,
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
);
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",
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
,
131 wmem_free(NULL
, tmp_str
);
134 printf("=================================================================================================\n");
139 printf("| Category/Criteria |");
140 for (z
=0; z
<NB_CRITERIA
; z
++) printf("%7.2f%% |", criteria
[z
]);
143 printf("|-------------------------|");
144 for (z
=0; z
<NB_CRITERIA
; z
++) printf("---------|");
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
++) {
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;
158 delta
= delay_max
-delay_min
;
159 while ( (delta
> 0.001) && (iteration
< 10000) ) {
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 */
170 delay
= (delay_max
+delay_min
)/2;
171 delta
= delay_max
-delay_min
;
172 } else { /* trop petit */
174 delay
= (delay_max
+delay_min
)/2;
175 delta
= delay_max
-delay_min
;
178 delay_criteria
[z
] = delay
;
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
]));
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);
194 printf("===========================");
195 for (z
=0; z
<NB_CRITERIA
; z
++) printf("==========");
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);
210 p_camelsrt
->filter
= NULL
;
213 error_string
= register_tap_listener("CAMEL",
223 /* error, we failed to attach to the tap. clean up */
224 g_free(p_camelsrt
->filter
);
227 cmdarg_err("Couldn't register camel,srt tap: %s", error_string
->str
);
228 g_string_free(error_string
, TRUE
);
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
,
252 register_tap_listener_camelsrt(void)
254 register_stat_tap_ui(&camelsrt_ui
, NULL
);
258 * Editor modelines - https://www.wireshark.org/tools/modelines.html
263 * indent-tabs-mode: nil
266 * ex: set shiftwidth=2 tabstop=8 expandtab:
267 * :indentSize=2:tabSize=8:noTabs=true: