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
22 #include <epan/packet_info.h>
23 #include <epan/value_string.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
{
37 GHashTable
*hash_responses
;
38 GHashTable
*hash_requests
;
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 */
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 */
56 } rtsp_request_methode_t
;
59 /* insert some entries */
61 rtsp_init_hash( rtspstat_t
*sp
)
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);
71 sc
->response_code
= rtsp_status_code_vals
[i
].value
;
72 sc
->name
= rtsp_status_code_vals
[i
].strptr
;
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
);
79 rtsp_draw_hash_requests( char *key _U_
, rtsp_request_methode_t
*data
, char * format
)
81 if (data
->packets
== 0)
83 printf( format
, data
->response
, data
->packets
);
87 rtsp_draw_hash_responses( void ** key _U_
, rtsp_response_code_t
*data
, char * format
)
90 ws_warning("No data available, key=%d\n", GPOINTER_TO_INT(key
));
93 if (data
->packets
== 0)
95 /* " RTSP %3d %-35s %9d packets", */
96 printf(format
, data
->response_code
, data
->name
, data
->packets
);
101 /* NOT USED at this moment */
104 rtsp_free_hash( void *key, void *value, void *user_data _U_ )
111 rtsp_reset_hash_responses(char *key _U_
, rtsp_response_code_t
*data
, void *ptr _U_
)
116 rtsp_reset_hash_requests(char *key _U_
, rtsp_request_methode_t
*data
, void *ptr _U_
)
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(
144 GINT_TO_POINTER(value
->response_code
));
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
;
155 key
= 199; /* Hopefully, this status code will never be used */
169 sc
= (rtsp_response_code_t
*)g_hash_table_lookup(
171 GINT_TO_POINTER(key
));
173 return TAP_PACKET_DONT_REDRAW
;
177 else if (value
->request_method
) {
178 rtsp_request_methode_t
*sc
;
180 sc
= (rtsp_request_methode_t
*)g_hash_table_lookup(
182 value
->request_method
);
184 sc
= g_new(rtsp_request_methode_t
, 1);
185 sc
->response
= g_strdup( value
->request_method
);
188 g_hash_table_insert( sp
->hash_requests
, sc
->response
, sc
);
193 return TAP_PACKET_DONT_REDRAW
;
195 return TAP_PACKET_REDRAW
;
200 rtspstat_draw(void *psp
)
202 rtspstat_t
*sp
= (rtspstat_t
*)psp
;
204 printf("===================================================================\n");
205 if (!sp
->filter
|| !sp
->filter
[0])
206 printf("RTSP Statistics\n");
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.
224 rtspstat_init(const char *opt_arg
, void *userdata _U_
)
227 const char *filter
= NULL
;
228 GString
*error_string
;
230 if (!strncmp (opt_arg
, "rtsp,stat,", 10)) {
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(
251 /* error, we failed to attach to the tap. clean up */
254 cmdarg_err("Couldn't register rtsp,stat tap: %s",
256 g_string_free(error_string
, TRUE
);
263 static stat_tap_ui rtspstat_ui
= {
264 REGISTER_STAT_GROUP_GENERIC
,
273 register_tap_listener_rtspstat(void)
275 register_stat_tap_ui(&rtspstat_ui
, NULL
);
279 * Editor modelines - https://www.wireshark.org/tools/modelines.html
284 * indent-tabs-mode: t
287 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
288 * :indentSize=8:tabSize=8:noTabs=false: