LATER... ei_kerberos_kdc_session_key ...
[wireshark-sm.git] / ui / cli / tap-rtspstat.c
blobaccc0f85367be0cf182a3696efbb0dd2ed9089c9
1 /* tap-rtspstat.c
2 * tap-rtspstat March 2011
4 * Stephane GORSE (Orange Labs / France Telecom)
5 * Copied from Jean-Michel FAYARD's works (HTTP)
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
9 * Copyright 1998 Gerald Combs
11 * SPDX-License-Identifier: GPL-2.0-or-later
14 #include "config.h"
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <string.h>
20 #include <glib.h>
22 #include <epan/packet_info.h>
23 #include <epan/value_string.h>
24 #include <epan/tap.h>
25 #include <epan/stat_tap_ui.h>
26 #include <epan/dissectors/packet-rtsp.h>
28 #include <wsutil/wslog.h>
30 #include <wsutil/cmdarg_err.h>
32 void register_tap_listener_rtspstat(void);
34 /* used to keep track of the statictics for an entire program interface */
35 typedef struct _rtsp_stats_t {
36 char *filter;
37 GHashTable *hash_responses;
38 GHashTable *hash_requests;
39 } rtspstat_t;
41 /* used to keep track of the stats for a specific response code
42 * for example it can be { 3, 404, "Not Found" ,...}
43 * which means we captured 3 reply rtsp/1.1 404 Not Found */
44 typedef struct _rtsp_response_code_t {
45 uint32_t packets; /* 3 */
46 unsigned response_code; /* 404 */
47 const char *name; /* Not Found */
48 rtspstat_t *sp;
49 } rtsp_response_code_t;
51 /* used to keep track of the stats for a specific request string */
52 typedef struct _rtsp_request_methode_t {
53 char *response; /* eg. : SETUP */
54 uint32_t packets;
55 rtspstat_t *sp;
56 } rtsp_request_methode_t;
59 /* insert some entries */
60 static void
61 rtsp_init_hash( rtspstat_t *sp)
63 int i;
65 sp->hash_responses = g_hash_table_new(g_direct_hash, g_direct_equal);
67 for (i=0 ; rtsp_status_code_vals[i].strptr ; i++ )
69 rtsp_response_code_t *sc = g_new (rtsp_response_code_t, 1);
70 sc->packets = 0;
71 sc->response_code = rtsp_status_code_vals[i].value;
72 sc->name = rtsp_status_code_vals[i].strptr;
73 sc->sp = sp;
74 g_hash_table_insert( sc->sp->hash_responses, GINT_TO_POINTER(rtsp_status_code_vals[i].value), sc);
76 sp->hash_requests = g_hash_table_new( g_str_hash, g_str_equal);
78 static void
79 rtsp_draw_hash_requests( char *key _U_ , rtsp_request_methode_t *data, char * format)
81 if (data->packets == 0)
82 return;
83 printf( format, data->response, data->packets);
86 static void
87 rtsp_draw_hash_responses( void ** key _U_ , rtsp_response_code_t *data, char * format)
89 if (data == NULL) {
90 ws_warning("No data available, key=%d\n", GPOINTER_TO_INT(key));
91 exit(EXIT_FAILURE);
93 if (data->packets == 0)
94 return;
95 /* " RTSP %3d %-35s %9d packets", */
96 printf(format, data->response_code, data->name, data->packets );
101 /* NOT USED at this moment */
103 static void
104 rtsp_free_hash( void *key, void *value, void *user_data _U_ )
106 g_free(key);
107 g_free(value);
110 static void
111 rtsp_reset_hash_responses(char *key _U_ , rtsp_response_code_t *data, void *ptr _U_ )
113 data->packets = 0;
115 static void
116 rtsp_reset_hash_requests(char *key _U_ , rtsp_request_methode_t *data, void *ptr _U_ )
118 data->packets = 0;
121 static void
122 rtspstat_reset(void *psp )
124 rtspstat_t *sp = (rtspstat_t *)psp;
126 g_hash_table_foreach( sp->hash_responses, (GHFunc)rtsp_reset_hash_responses, NULL);
127 g_hash_table_foreach( sp->hash_requests, (GHFunc)rtsp_reset_hash_requests, NULL);
131 static tap_packet_status
132 rtspstat_packet(void *psp , packet_info *pinfo _U_, epan_dissect_t *edt _U_, const void *pri, tap_flags_t flags _U_)
134 const rtsp_info_value_t *value = (const rtsp_info_value_t *)pri;
135 rtspstat_t *sp = (rtspstat_t *) psp;
137 /* We are only interested in reply packets with a status code */
138 /* Request or reply packets ? */
139 if (value->response_code != 0) {
140 rtsp_response_code_t *sc;
142 sc = (rtsp_response_code_t *)g_hash_table_lookup(
143 sp->hash_responses,
144 GINT_TO_POINTER(value->response_code));
145 if (sc == NULL) {
146 int key;
147 /* non standard status code ; we classify it as others
148 * in the relevant category (Informational,Success,Redirection,Client Error,Server Error)
150 int i = value->response_code;
151 if ((i < 100) || (i >= 600)) {
152 return TAP_PACKET_DONT_REDRAW;
154 else if (i < 200) {
155 key = 199; /* Hopefully, this status code will never be used */
157 else if (i < 300) {
158 key = 299;
160 else if (i < 400) {
161 key = 399;
163 else if (i < 500) {
164 key = 499;
166 else {
167 key = 599;
169 sc = (rtsp_response_code_t *)g_hash_table_lookup(
170 sp->hash_responses,
171 GINT_TO_POINTER(key));
172 if (sc == NULL)
173 return TAP_PACKET_DONT_REDRAW;
175 sc->packets++;
177 else if (value->request_method) {
178 rtsp_request_methode_t *sc;
180 sc = (rtsp_request_methode_t *)g_hash_table_lookup(
181 sp->hash_requests,
182 value->request_method);
183 if (sc == NULL) {
184 sc = g_new(rtsp_request_methode_t, 1);
185 sc->response = g_strdup( value->request_method );
186 sc->packets = 1;
187 sc->sp = sp;
188 g_hash_table_insert( sp->hash_requests, sc->response, sc);
189 } else {
190 sc->packets++;
192 } else {
193 return TAP_PACKET_DONT_REDRAW;
195 return TAP_PACKET_REDRAW;
199 static void
200 rtspstat_draw(void *psp )
202 rtspstat_t *sp = (rtspstat_t *)psp;
203 printf("\n");
204 printf("===================================================================\n");
205 if (!sp->filter || !sp->filter[0])
206 printf("RTSP Statistics\n");
207 else
208 printf("RTSP Statistics with filter %s\n", sp->filter);
210 printf("* RTSP Response Status Codes Packets\n");
211 g_hash_table_foreach( sp->hash_responses, (GHFunc)rtsp_draw_hash_responses,
212 (void *)" %3d %-35s %9d\n");
213 printf("* RTSP Request Methods Packets\n");
214 g_hash_table_foreach( sp->hash_requests, (GHFunc)rtsp_draw_hash_requests,
215 (void *)" %-39s %9d\n");
216 printf("===================================================================\n");
221 /* When called, this function will create a new instance of rtspstat.
223 static void
224 rtspstat_init(const char *opt_arg, void *userdata _U_)
226 rtspstat_t *sp;
227 const char *filter = NULL;
228 GString *error_string;
230 if (!strncmp (opt_arg, "rtsp,stat,", 10)) {
231 filter = opt_arg+10;
232 } else {
233 filter = NULL;
236 sp = g_new(rtspstat_t, 1);
237 sp->filter = g_strdup(filter);
238 /*g_hash_table_foreach( rtsp_status, (GHFunc)rtsp_reset_hash_responses, NULL);*/
241 error_string = register_tap_listener(
242 "rtsp",
244 filter,
246 rtspstat_reset,
247 rtspstat_packet,
248 rtspstat_draw,
249 NULL);
250 if (error_string) {
251 /* error, we failed to attach to the tap. clean up */
252 g_free(sp->filter);
253 g_free(sp);
254 cmdarg_err("Couldn't register rtsp,stat tap: %s",
255 error_string->str);
256 g_string_free(error_string, TRUE);
257 exit(1);
260 rtsp_init_hash(sp);
263 static stat_tap_ui rtspstat_ui = {
264 REGISTER_STAT_GROUP_GENERIC,
265 NULL,
266 "rtsp,stat",
267 rtspstat_init,
269 NULL
272 void
273 register_tap_listener_rtspstat(void)
275 register_stat_tap_ui(&rtspstat_ui, NULL);
279 * Editor modelines - https://www.wireshark.org/tools/modelines.html
281 * Local variables:
282 * c-basic-offset: 8
283 * tab-width: 8
284 * indent-tabs-mode: t
285 * End:
287 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
288 * :indentSize=8:tabSize=8:noTabs=false: