forked from osmocom/wireshark
From Stéphane Gorse:
The menu gets a new item (Statistics -> RTSP -> Packet Counter). Like HTTP, filter can be set and then the dialog windows shows the result of the RTSP analysis. https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=6042 svn path=/trunk/; revision=37741
This commit is contained in:
parent
e9e32d7844
commit
4c219ee855
|
@ -129,6 +129,7 @@ TSHARK_TAP_SRC = \
|
|||
tap-rpcstat.c \
|
||||
tap-rpcprogs.c \
|
||||
tap-rtp.c \
|
||||
tap-rtspstat.c \
|
||||
tap-scsistat.c \
|
||||
tap-sctpchunkstat.c \
|
||||
tap-sipstat.c \
|
||||
|
|
|
@ -1286,6 +1286,7 @@ DISSECTOR_INCLUDES = \
|
|||
packet-rtps2.h \
|
||||
packet-rtp-events.h \
|
||||
packet-rtse.h \
|
||||
packet-rtsp.h \
|
||||
packet-rwall.h \
|
||||
packet-rx.h \
|
||||
packet-s1ap.h \
|
||||
|
|
|
@ -48,12 +48,76 @@
|
|||
#include <epan/emem.h>
|
||||
#include <epan/tap.h>
|
||||
#include <epan/tap-voip.h>
|
||||
#include <epan/stats_tree.h>
|
||||
#include <wsutil/str_util.h>
|
||||
|
||||
#include "packet-rdt.h"
|
||||
#include "packet-rtp.h"
|
||||
#include "packet-rtcp.h"
|
||||
#include "packet-e164.h"
|
||||
#include "packet-rtsp.h"
|
||||
|
||||
static int rtsp_tap = -1;
|
||||
static rtsp_info_value_t *rtsp_stat_info;
|
||||
|
||||
/* http://www.iana.org/assignments/rtsp-parameters/rtsp-parameters.xml */
|
||||
|
||||
const value_string rtsp_status_code_vals[] = {
|
||||
{ 100, "Continue" },
|
||||
{ 199, "Informational - Others" },
|
||||
|
||||
{ 200, "OK"},
|
||||
{ 201, "Created"},
|
||||
{ 250, "Low on Storage Space"},
|
||||
{ 299, "Success - Others"},
|
||||
|
||||
{ 300, "Multiple Choices"},
|
||||
{ 301, "Moved Permanently"},
|
||||
{ 302, "Moved Temporarily"},
|
||||
{ 303, "See Other"},
|
||||
{ 305, "Use Proxy"},
|
||||
{ 399, "Redirection - Others"},
|
||||
|
||||
{ 400, "Bad Request"},
|
||||
{ 401, "Unauthorized"},
|
||||
{ 402, "Payment Required"},
|
||||
{ 403, "Forbidden"},
|
||||
{ 404, "Not Found"},
|
||||
{ 405, "Method Not Allowed"},
|
||||
{ 406, "Not Acceptable"},
|
||||
{ 407, "Proxy Authentication Required"},
|
||||
{ 408, "Request Timeout"},
|
||||
{ 410, "Gone"},
|
||||
{ 411, "Length Required"},
|
||||
{ 412, "Precondition Failed"},
|
||||
{ 413, "Request Entity Too Large"},
|
||||
{ 414, "Request-URI Too Long"},
|
||||
{ 415, "Unsupported Media Type"},
|
||||
{ 451, "Invalid Parameter"},
|
||||
{ 452, "Illegal Conferenec Identifier"},
|
||||
{ 453, "Not Enough Bandwidth"},
|
||||
{ 454, "Session Not Found"},
|
||||
{ 455, "Method Not Valid In This State"},
|
||||
{ 456, "Header Field Not Valid"},
|
||||
{ 457, "Invalid Range"},
|
||||
{ 458, "Parameter Is Read-Only"},
|
||||
{ 459, "Aggregate Operation Not Allowed"},
|
||||
{ 460, "Only Aggregate Operation Allowed"},
|
||||
{ 461, "Unsupported Transport"},
|
||||
{ 462, "Destination Unreachable"},
|
||||
{ 499, "Client Error - Others"},
|
||||
|
||||
{ 500, "Internal Server Error"},
|
||||
{ 501, "Not Implemented"},
|
||||
{ 502, "Bad Gateway"},
|
||||
{ 503, "Service Unavailable"},
|
||||
{ 504, "Gateway Timeout"},
|
||||
{ 505, "RTSP Version not supported"},
|
||||
{ 551, "Option Not Support"},
|
||||
{ 599, "Server Error - Others"},
|
||||
|
||||
{ 0, NULL}
|
||||
};
|
||||
|
||||
static int proto_rtsp = -1;
|
||||
|
||||
|
@ -80,6 +144,90 @@ static dissector_handle_t rtcp_handle;
|
|||
static dissector_handle_t rdt_handle;
|
||||
static dissector_table_t media_type_dissector_table;
|
||||
|
||||
static const gchar *st_str_packets = "Total RTSP Packets";
|
||||
static const gchar *st_str_requests = "RTSP Request Packets";
|
||||
static const gchar *st_str_responses = "RTSP Response Packets";
|
||||
static const gchar *st_str_resp_broken = "???: broken";
|
||||
static const gchar *st_str_resp_100 = "1xx: Informational";
|
||||
static const gchar *st_str_resp_200 = "2xx: Success";
|
||||
static const gchar *st_str_resp_300 = "3xx: Redirection";
|
||||
static const gchar *st_str_resp_400 = "4xx: Client Error";
|
||||
static const gchar *st_str_resp_500 = "5xx: Server Error";
|
||||
static const gchar *st_str_other = "Other RTSP Packets";
|
||||
|
||||
static int st_node_packets = -1;
|
||||
static int st_node_requests = -1;
|
||||
static int st_node_responses = -1;
|
||||
static int st_node_resp_broken = -1;
|
||||
static int st_node_resp_100 = -1;
|
||||
static int st_node_resp_200 = -1;
|
||||
static int st_node_resp_300 = -1;
|
||||
static int st_node_resp_400 = -1;
|
||||
static int st_node_resp_500 = -1;
|
||||
static int st_node_other = -1;
|
||||
|
||||
static void
|
||||
rtsp_stats_tree_init(stats_tree* st)
|
||||
{
|
||||
st_node_packets = stats_tree_create_node(st, st_str_packets, 0, TRUE);
|
||||
st_node_requests = stats_tree_create_pivot(st, st_str_requests, st_node_packets);
|
||||
st_node_responses = stats_tree_create_node(st, st_str_responses, st_node_packets, TRUE);
|
||||
st_node_resp_broken = stats_tree_create_node(st, st_str_resp_broken, st_node_responses, TRUE);
|
||||
st_node_resp_100 = stats_tree_create_node(st, st_str_resp_100, st_node_responses, TRUE);
|
||||
st_node_resp_200 = stats_tree_create_node(st, st_str_resp_200, st_node_responses, TRUE);
|
||||
st_node_resp_300 = stats_tree_create_node(st, st_str_resp_300, st_node_responses, TRUE);
|
||||
st_node_resp_400 = stats_tree_create_node(st, st_str_resp_400, st_node_responses, TRUE);
|
||||
st_node_resp_500 = stats_tree_create_node(st, st_str_resp_500, st_node_responses, TRUE);
|
||||
st_node_other = stats_tree_create_node(st, st_str_other, st_node_packets,FALSE);
|
||||
}
|
||||
|
||||
/* RTSP/Packet Counter stats packet function */
|
||||
static int
|
||||
rtsp_stats_tree_packet(stats_tree* st, packet_info* pinfo _U_, epan_dissect_t* edt _U_, const void* p)
|
||||
{
|
||||
const rtsp_info_value_t* v = p;
|
||||
guint i = v->response_code;
|
||||
int resp_grp;
|
||||
const gchar *resp_str;
|
||||
static gchar str[64];
|
||||
|
||||
tick_stat_node(st, st_str_packets, 0, FALSE);
|
||||
|
||||
if (i) {
|
||||
tick_stat_node(st, st_str_responses, st_node_packets, FALSE);
|
||||
|
||||
if ( (i<100)||(i>=600) ) {
|
||||
resp_grp = st_node_resp_broken;
|
||||
resp_str = st_str_resp_broken;
|
||||
} else if (i<200) {
|
||||
resp_grp = st_node_resp_100;
|
||||
resp_str = st_str_resp_100;
|
||||
} else if (i<300) {
|
||||
resp_grp = st_node_resp_200;
|
||||
resp_str = st_str_resp_200;
|
||||
} else if (i<400) {
|
||||
resp_grp = st_node_resp_300;
|
||||
resp_str = st_str_resp_300;
|
||||
} else if (i<500) {
|
||||
resp_grp = st_node_resp_400;
|
||||
resp_str = st_str_resp_400;
|
||||
} else {
|
||||
resp_grp = st_node_resp_500;
|
||||
resp_str = st_str_resp_500;
|
||||
}
|
||||
|
||||
tick_stat_node(st, resp_str, st_node_responses, FALSE);
|
||||
|
||||
g_snprintf(str, sizeof(str),"%u %s",i,val_to_str(i,rtsp_status_code_vals, "Unknown (%d)"));
|
||||
tick_stat_node(st, str, resp_grp, FALSE);
|
||||
} else if (v->request_method) {
|
||||
stats_tree_tick_pivot(st,st_node_requests,v->request_method);
|
||||
} else {
|
||||
tick_stat_node(st, st_str_other, st_node_packets, FALSE);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
void proto_reg_handoff_rtsp(void);
|
||||
|
||||
/*
|
||||
|
@ -298,6 +446,9 @@ static gboolean
|
|||
is_rtsp_request_or_reply(const guchar *line, size_t linelen, rtsp_type_t *type)
|
||||
{
|
||||
unsigned ii;
|
||||
const guchar *next_token;
|
||||
int tokenlen;
|
||||
gchar response_chars[4];
|
||||
|
||||
/* Is this an RTSP reply? */
|
||||
if (linelen >= 5 && g_ascii_strncasecmp("RTSP/", line, 5) == 0) {
|
||||
|
@ -305,6 +456,17 @@ is_rtsp_request_or_reply(const guchar *line, size_t linelen, rtsp_type_t *type)
|
|||
* Yes.
|
||||
*/
|
||||
*type = RTSP_REPLY;
|
||||
/* The first token is the version. */
|
||||
tokenlen = get_token_len(line, line+5, &next_token);
|
||||
if (tokenlen != 0) {
|
||||
/* The next token is the status code. */
|
||||
tokenlen = get_token_len(next_token, line+linelen, &next_token);
|
||||
if (tokenlen >= 3) {
|
||||
memcpy(response_chars, next_token, 3);
|
||||
response_chars[3] = '\0';
|
||||
rtsp_stat_info->response_code = strtoul(response_chars, NULL, 10);
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -320,6 +482,7 @@ is_rtsp_request_or_reply(const guchar *line, size_t linelen, rtsp_type_t *type)
|
|||
(len == linelen || isspace(line[len])))
|
||||
{
|
||||
*type = RTSP_REQUEST;
|
||||
rtsp_stat_info->request_method = ep_strndup(rtsp_methods[ii], len+1);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
@ -559,6 +722,13 @@ dissect_rtspmessage(tvbuff_t *tvb, int offset, packet_info *pinfo,
|
|||
gchar *session_id = NULL;
|
||||
voip_packet_info_t *stat_info = NULL;
|
||||
|
||||
rtsp_stat_info = ep_alloc(sizeof(rtsp_info_value_t));
|
||||
rtsp_stat_info->framenum = pinfo->fd->num;
|
||||
rtsp_stat_info->response_code = 0;
|
||||
rtsp_stat_info->request_method = NULL;
|
||||
rtsp_stat_info->request_uri = NULL;
|
||||
rtsp_stat_info->rtsp_host = NULL;
|
||||
|
||||
/*
|
||||
* Is this a request or response?
|
||||
*
|
||||
|
@ -1097,6 +1267,9 @@ dissect_rtspmessage(tvbuff_t *tvb, int offset, packet_info *pinfo,
|
|||
*/
|
||||
offset += datalen;
|
||||
}
|
||||
|
||||
tap_queue_packet(rtsp_tap, pinfo, rtsp_stat_info);
|
||||
|
||||
return offset - orig_offset;
|
||||
}
|
||||
|
||||
|
@ -1305,6 +1478,10 @@ proto_register_rtsp(void)
|
|||
"of a request spanning multiple TCP segments",
|
||||
&rtsp_desegment_body);
|
||||
|
||||
/*
|
||||
* Register for tapping
|
||||
*/
|
||||
rtsp_tap = register_tap("rtsp"); /* RTSP statistics tap */
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1338,5 +1515,7 @@ proto_reg_handoff_rtsp(void)
|
|||
|
||||
saved_rtsp_tcp_port = global_rtsp_tcp_port;
|
||||
saved_rtsp_tcp_alternate_port = global_rtsp_tcp_alternate_port;
|
||||
|
||||
stats_tree_register("rtsp","rtsp","RTSP/Packet Counter", 0, rtsp_stats_tree_packet, rtsp_stats_tree_init, NULL );
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
/* packet-rtsp.h
|
||||
*
|
||||
* $Id$
|
||||
* Liberally copied from packet-http.h,
|
||||
* by Stephane GORSE (Orange Labs / France Telecom)
|
||||
*
|
||||
* Wireshark - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@wireshark.org>
|
||||
* Copyright 1998 Gerald Combs
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __PACKET_RTSP_H__
|
||||
#define __PACKET_RTSP_H__
|
||||
|
||||
/* Used for RTSP statistics */
|
||||
typedef struct _rtsp_info_value_t {
|
||||
guint32 framenum;
|
||||
gchar *request_method;
|
||||
guint response_code;
|
||||
gchar *rtsp_host;
|
||||
gchar *request_uri;
|
||||
} rtsp_info_value_t;
|
||||
|
||||
WS_VAR_IMPORT const value_string rtsp_status_code_vals[];
|
||||
|
||||
#endif /* __PACKET_RTSP_H__ */
|
|
@ -930,6 +930,7 @@ rtp_add_address
|
|||
rtp_free_hash_dyn_payload
|
||||
rtp_payload_type_short_vals_ext DATA
|
||||
rtp_payload_type_vals_ext DATA
|
||||
rtsp_status_code_vals DATA
|
||||
running_in_build_directory
|
||||
rval_to_str
|
||||
sccp_message_type_acro_values DATA
|
||||
|
|
|
@ -0,0 +1,282 @@
|
|||
/* tap-rtspstat.c
|
||||
* tap-rtspstat March 2011
|
||||
*
|
||||
* Stephane GORSE (Orange Labs / France Telecom)
|
||||
* Copied from Jean-Michel FAYARD's works (HTTP)
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* Wireshark - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@wireshark.org>
|
||||
* Copyright 1998 Gerald Combs
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "epan/packet_info.h"
|
||||
#include "epan/value_string.h"
|
||||
#include <epan/tap.h>
|
||||
#include <epan/stat_cmd_args.h>
|
||||
#include "register.h"
|
||||
#include <epan/dissectors/packet-rtsp.h>
|
||||
|
||||
|
||||
/* used to keep track of the statictics for an entire program interface */
|
||||
typedef struct _rtsp_stats_t {
|
||||
char *filter;
|
||||
GHashTable *hash_responses;
|
||||
GHashTable *hash_requests;
|
||||
} rtspstat_t;
|
||||
|
||||
/* used to keep track of the stats for a specific response code
|
||||
* for example it can be { 3, 404, "Not Found" ,...}
|
||||
* which means we captured 3 reply rtsp/1.1 404 Not Found */
|
||||
typedef struct _rtsp_response_code_t {
|
||||
guint32 packets; /* 3 */
|
||||
guint response_code; /* 404 */
|
||||
const gchar *name; /* Not Found */
|
||||
rtspstat_t *sp;
|
||||
} rtsp_response_code_t;
|
||||
|
||||
/* used to keep track of the stats for a specific request string */
|
||||
typedef struct _rtsp_request_methode_t {
|
||||
gchar *response; /* eg. : SETUP */
|
||||
guint32 packets;
|
||||
rtspstat_t *sp;
|
||||
} rtsp_request_methode_t;
|
||||
|
||||
|
||||
/* insert some entries */
|
||||
static void
|
||||
rtsp_init_hash( rtspstat_t *sp)
|
||||
{
|
||||
int i;
|
||||
|
||||
sp->hash_responses = g_hash_table_new( g_int_hash, g_int_equal);
|
||||
|
||||
for (i=0 ; rtsp_status_code_vals[i].strptr ; i++ )
|
||||
{
|
||||
gint *key = g_malloc (sizeof(gint));
|
||||
rtsp_response_code_t *sc = g_malloc (sizeof(rtsp_response_code_t));
|
||||
*key = rtsp_status_code_vals[i].value;
|
||||
sc->packets=0;
|
||||
sc->response_code = *key;
|
||||
sc->name=rtsp_status_code_vals[i].strptr;
|
||||
sc->sp = sp;
|
||||
g_hash_table_insert( sc->sp->hash_responses, key, sc);
|
||||
}
|
||||
sp->hash_requests = g_hash_table_new( g_str_hash, g_str_equal);
|
||||
}
|
||||
static void
|
||||
rtsp_draw_hash_requests( gchar *key _U_ , rtsp_request_methode_t *data, gchar * format)
|
||||
{
|
||||
if (data->packets==0)
|
||||
return;
|
||||
printf( format, data->response, data->packets);
|
||||
}
|
||||
|
||||
static void
|
||||
rtsp_draw_hash_responses( gint * key _U_ , rtsp_response_code_t *data, char * format)
|
||||
{
|
||||
if (data==NULL) {
|
||||
g_warning("No data available, key=%d\n", *key);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (data->packets==0)
|
||||
return;
|
||||
/* " RTSP %3d %-35s %9d packets", */
|
||||
printf(format, data->response_code, data->name, data->packets );
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* NOT USED at this moment */
|
||||
/*
|
||||
static void
|
||||
rtsp_free_hash( gpointer key, gpointer value, gpointer user_data _U_ )
|
||||
{
|
||||
g_free(key);
|
||||
g_free(value);
|
||||
}
|
||||
*/
|
||||
static void
|
||||
rtsp_reset_hash_responses(gchar *key _U_ , rtsp_response_code_t *data, gpointer ptr _U_ )
|
||||
{
|
||||
data->packets = 0;
|
||||
}
|
||||
static void
|
||||
rtsp_reset_hash_requests(gchar *key _U_ , rtsp_request_methode_t *data, gpointer ptr _U_ )
|
||||
{
|
||||
data->packets = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
rtspstat_reset(void *psp )
|
||||
{
|
||||
rtspstat_t *sp=psp;
|
||||
|
||||
g_hash_table_foreach( sp->hash_responses, (GHFunc)rtsp_reset_hash_responses, NULL);
|
||||
g_hash_table_foreach( sp->hash_requests, (GHFunc)rtsp_reset_hash_requests, NULL);
|
||||
|
||||
}
|
||||
|
||||
static int
|
||||
rtspstat_packet(void *psp , packet_info *pinfo _U_, epan_dissect_t *edt _U_, const void *pri)
|
||||
{
|
||||
const rtsp_info_value_t *value=pri;
|
||||
rtspstat_t *sp=(rtspstat_t *) psp;
|
||||
|
||||
/* We are only interested in reply packets with a status code */
|
||||
/* Request or reply packets ? */
|
||||
if (value->response_code!=0) {
|
||||
guint *key=g_malloc( sizeof(guint) );
|
||||
rtsp_response_code_t *sc;
|
||||
|
||||
*key=value->response_code;
|
||||
sc = g_hash_table_lookup(
|
||||
sp->hash_responses,
|
||||
key);
|
||||
if (sc==NULL){
|
||||
/* non standard status code ; we classify it as others
|
||||
* in the relevant category (Informational,Success,Redirection,Client Error,Server Error)
|
||||
*/
|
||||
int i = value->response_code;
|
||||
if ((i<100) || (i>=600)) {
|
||||
return 0;
|
||||
}
|
||||
else if (i<200){
|
||||
*key=199; /* Hopefully, this status code will never be used */
|
||||
}
|
||||
else if (i<300){
|
||||
*key=299;
|
||||
}
|
||||
else if (i<400){
|
||||
*key=399;
|
||||
}
|
||||
else if (i<500){
|
||||
*key=499;
|
||||
}
|
||||
else{
|
||||
*key=599;
|
||||
}
|
||||
sc = g_hash_table_lookup(
|
||||
sp->hash_responses,
|
||||
key);
|
||||
if (sc==NULL)
|
||||
return 0;
|
||||
}
|
||||
sc->packets++;
|
||||
}
|
||||
else if (value->request_method){
|
||||
rtsp_request_methode_t *sc;
|
||||
|
||||
sc = g_hash_table_lookup(
|
||||
sp->hash_requests,
|
||||
value->request_method);
|
||||
if (sc==NULL){
|
||||
sc=g_malloc( sizeof(rtsp_request_methode_t) );
|
||||
sc->response=g_strdup( value->request_method );
|
||||
sc->packets=1;
|
||||
sc->sp = sp;
|
||||
g_hash_table_insert( sp->hash_requests, sc->response, sc);
|
||||
} else {
|
||||
sc->packets++;
|
||||
}
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
rtspstat_draw(void *psp )
|
||||
{
|
||||
rtspstat_t *sp=psp;
|
||||
printf("\n");
|
||||
printf("===================================================================\n");
|
||||
if (! sp->filter[0])
|
||||
printf("RTSP Statistics\n");
|
||||
else
|
||||
printf("RTSP Statistics with filter %s\n", sp->filter);
|
||||
|
||||
printf( "* RTSP Status Codes in reply packets\n");
|
||||
g_hash_table_foreach( sp->hash_responses, (GHFunc)rtsp_draw_hash_responses,
|
||||
" RTSP %3d %s\n");
|
||||
printf("* List of RTSP Request methods\n");
|
||||
g_hash_table_foreach( sp->hash_requests, (GHFunc)rtsp_draw_hash_requests,
|
||||
" %9s %d \n");
|
||||
printf("===================================================================\n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* When called, this function will create a new instance of gtk_rtspstat.
|
||||
*/
|
||||
static void
|
||||
gtk_rtspstat_init(const char *optarg,void* userdata _U_)
|
||||
{
|
||||
rtspstat_t *sp;
|
||||
const char *filter=NULL;
|
||||
GString *error_string;
|
||||
|
||||
if (!strncmp (optarg, "rtsp,stat,", 10)){
|
||||
filter=optarg+10;
|
||||
} else {
|
||||
filter=NULL;
|
||||
}
|
||||
|
||||
sp = g_malloc( sizeof(rtspstat_t) );
|
||||
if(filter){
|
||||
sp->filter=g_strdup(filter);
|
||||
} else {
|
||||
sp->filter=NULL;
|
||||
}
|
||||
/*g_hash_table_foreach( rtsp_status, (GHFunc)rtsp_reset_hash_responses, NULL);*/
|
||||
|
||||
|
||||
error_string = register_tap_listener(
|
||||
"rtsp",
|
||||
sp,
|
||||
filter,
|
||||
0,
|
||||
rtspstat_reset,
|
||||
rtspstat_packet,
|
||||
rtspstat_draw);
|
||||
if (error_string){
|
||||
/* error, we failed to attach to the tap. clean up */
|
||||
g_free(sp->filter);
|
||||
g_free(sp);
|
||||
fprintf (stderr, "tshark: Couldn't register rtsp,stat tap: %s\n",
|
||||
error_string->str);
|
||||
g_string_free(error_string, TRUE);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
rtsp_init_hash(sp);
|
||||
}
|
||||
|
||||
void
|
||||
register_tap_listener_gtkrtspstat(void)
|
||||
{
|
||||
register_stat_cmd_arg("rtsp,stat,", gtk_rtspstat_init,NULL);
|
||||
}
|
Loading…
Reference in New Issue