forked from osmocom/wireshark
From Jason Lango:
Clean up RTSP Transport parsing and sub-conversation code. Dissect RTP/MP4 (and other RTP/xxx) as RTP/AVP (for now). svn path=/trunk/; revision=3912
This commit is contained in:
parent
dd1b7eafaf
commit
0ee22efcd6
|
@ -1,6 +1,6 @@
|
|||
/* packet-rtcp.c
|
||||
*
|
||||
* $Id: packet-rtcp.c,v 1.21 2001/09/03 10:33:06 guy Exp $
|
||||
* $Id: packet-rtcp.c,v 1.22 2001/09/08 00:43:51 guy Exp $
|
||||
*
|
||||
* Routines for RTCP dissection
|
||||
* RTCP = Real-time Transport Control Protocol
|
||||
|
@ -1218,6 +1218,8 @@ proto_register_rtcp(void)
|
|||
proto_register_field_array(proto_rtcp, hf, array_length(hf));
|
||||
proto_register_subtree_array(ett, array_length(ett));
|
||||
|
||||
register_dissector("rtcp", dissect_rtcp, proto_rtcp);
|
||||
|
||||
#if 0
|
||||
register_init_routine( &rtcp_init );
|
||||
#endif
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* Copyright 2000, Philips Electronics N.V.
|
||||
* Written by Andreas Sikkema <andreas.sikkema@philips.com>
|
||||
*
|
||||
* $Id: packet-rtp.c,v 1.24 2001/09/03 10:33:06 guy Exp $
|
||||
* $Id: packet-rtp.c,v 1.25 2001/09/08 00:43:51 guy Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@ethereal.com>
|
||||
|
@ -766,6 +766,8 @@ proto_register_rtp(void)
|
|||
proto_register_field_array(proto_rtp, hf, array_length(hf));
|
||||
proto_register_subtree_array(ett, array_length(ett));
|
||||
|
||||
register_dissector("rtp", dissect_rtp, proto_rtp);
|
||||
|
||||
#if 0
|
||||
register_init_routine( &rtp_init );
|
||||
#endif
|
||||
|
|
138
packet-rtsp.c
138
packet-rtsp.c
|
@ -4,7 +4,7 @@
|
|||
* Jason Lango <jal@netapp.com>
|
||||
* Liberally copied from packet-http.c, by Guy Harris <guy@alum.mit.edu>
|
||||
*
|
||||
* $Id: packet-rtsp.c,v 1.41 2001/09/03 10:33:06 guy Exp $
|
||||
* $Id: packet-rtsp.c,v 1.42 2001/09/08 00:43:51 guy Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@ethereal.com>
|
||||
|
@ -51,6 +51,13 @@ static int hf_rtsp_method = -1;
|
|||
static int hf_rtsp_url = -1;
|
||||
static int hf_rtsp_status = -1;
|
||||
|
||||
static dissector_handle_t sdp_handle;
|
||||
static dissector_handle_t rtp_handle;
|
||||
static dissector_handle_t rtcp_handle;
|
||||
|
||||
static GMemChunk *rtsp_vals = NULL;
|
||||
#define rtsp_hash_init_count 20
|
||||
|
||||
#define TCP_PORT_RTSP 554
|
||||
|
||||
/*
|
||||
|
@ -62,6 +69,22 @@ static int hf_rtsp_status = -1;
|
|||
|
||||
#define RTSP_FRAMEHDR ('$')
|
||||
|
||||
typedef struct {
|
||||
dissector_handle_t dissector;
|
||||
} rtsp_interleaved_t;
|
||||
|
||||
#define RTSP_MAX_INTERLEAVED (8)
|
||||
|
||||
/*
|
||||
* Careful about dynamically allocating memory in this structure (say
|
||||
* for dynamically increasing the size of the 'interleaved' array) -
|
||||
* the containing structure is garbage collected and contained
|
||||
* pointers will not be freed.
|
||||
*/
|
||||
typedef struct {
|
||||
rtsp_interleaved_t interleaved[RTSP_MAX_INTERLEAVED];
|
||||
} rtsp_conversation_data_t;
|
||||
|
||||
static int
|
||||
dissect_rtspinterleaved(tvbuff_t *tvb, int offset, packet_info *pinfo,
|
||||
proto_tree *tree)
|
||||
|
@ -74,6 +97,9 @@ dissect_rtspinterleaved(tvbuff_t *tvb, int offset, packet_info *pinfo,
|
|||
guint16 rf_len; /* packet length */
|
||||
gint framelen;
|
||||
tvbuff_t *next_tvb;
|
||||
conversation_t *conv;
|
||||
rtsp_conversation_data_t *data;
|
||||
dissector_handle_t dissector;
|
||||
|
||||
orig_offset = offset;
|
||||
rf_start = tvb_get_guint8(tvb, offset);
|
||||
|
@ -126,7 +152,20 @@ dissect_rtspinterleaved(tvbuff_t *tvb, int offset, packet_info *pinfo,
|
|||
if (framelen > rf_len)
|
||||
framelen = rf_len;
|
||||
next_tvb = tvb_new_subset(tvb, offset, framelen, rf_len);
|
||||
dissect_data(next_tvb, 0, pinfo, tree);
|
||||
|
||||
conv = find_conversation(&pinfo->src, &pinfo->dst, pinfo->ptype,
|
||||
pinfo->srcport, pinfo->destport, 0);
|
||||
|
||||
if (conv &&
|
||||
(data = conversation_get_proto_data(conv, proto_rtsp)) &&
|
||||
rf_chan < RTSP_MAX_INTERLEAVED &&
|
||||
(dissector = data->interleaved[rf_chan].dissector)) {
|
||||
call_dissector(dissector, next_tvb, pinfo, tree);
|
||||
} else {
|
||||
proto_tree_add_text(rtspframe_tree, tvb, offset, rf_len,
|
||||
"Data (%u bytes)", rf_len);
|
||||
}
|
||||
|
||||
offset += rf_len;
|
||||
|
||||
return offset - orig_offset;
|
||||
|
@ -152,8 +191,6 @@ static const char *rtsp_methods[] = {
|
|||
|
||||
#define RTSP_NMETHODS (sizeof rtsp_methods / sizeof rtsp_methods[0])
|
||||
|
||||
static dissector_handle_t sdp_handle;
|
||||
|
||||
static rtsp_type_t
|
||||
is_rtsp_request_or_reply(const u_char *line, size_t linelen)
|
||||
{
|
||||
|
@ -210,7 +247,8 @@ is_content_sdp(const u_char *line, size_t linelen)
|
|||
static const char rtsp_transport[] = "Transport:";
|
||||
static const char rtsp_sps[] = "server_port=";
|
||||
static const char rtsp_cps[] = "client_port=";
|
||||
static const char rtsp_rtp[] = "rtp/avp";
|
||||
static const char rtsp_rtp[] = "rtp/";
|
||||
static const char rtsp_inter[] = "interleaved=";
|
||||
|
||||
static void
|
||||
rtsp_create_conversation(packet_info *pinfo, const u_char *line_begin,
|
||||
|
@ -219,8 +257,8 @@ rtsp_create_conversation(packet_info *pinfo, const u_char *line_begin,
|
|||
conversation_t *conv;
|
||||
u_char buf[256];
|
||||
u_char *tmp;
|
||||
int c_data_port, c_mon_port;
|
||||
int s_data_port, s_mon_port;
|
||||
u_int c_data_port, c_mon_port;
|
||||
u_int s_data_port, s_mon_port;
|
||||
address null_addr;
|
||||
|
||||
if (line_len > sizeof(buf) - 1) {
|
||||
|
@ -235,23 +273,73 @@ rtsp_create_conversation(packet_info *pinfo, const u_char *line_begin,
|
|||
tmp = buf + STRLEN_CONST(rtsp_transport);
|
||||
while (*tmp && isspace(*tmp))
|
||||
tmp++;
|
||||
if (strncasecmp(tmp, rtsp_rtp, strlen(rtsp_rtp)) != 0)
|
||||
return; /* we don't know this transport */
|
||||
if (strncasecmp(tmp, rtsp_rtp, strlen(rtsp_rtp)) != 0) {
|
||||
g_warning("Frame %u: rtsp: unknown transport", pinfo->fd->num);
|
||||
return;
|
||||
}
|
||||
|
||||
c_data_port = c_mon_port = 0;
|
||||
s_data_port = s_mon_port = 0;
|
||||
if ((tmp = strstr(buf, rtsp_sps))) {
|
||||
tmp += strlen(rtsp_sps);
|
||||
if (sscanf(tmp, "%u-%u", &s_data_port, &s_mon_port) < 1)
|
||||
g_warning("rtsp: failed to parse server_port");
|
||||
if (sscanf(tmp, "%u-%u", &s_data_port, &s_mon_port) < 1) {
|
||||
g_warning("Frame %u: rtsp: bad server_port",
|
||||
pinfo->fd->num);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if ((tmp = strstr(buf, rtsp_cps))) {
|
||||
tmp += strlen(rtsp_cps);
|
||||
if (sscanf(tmp, "%u-%u", &c_data_port, &c_mon_port) < 1)
|
||||
g_warning("rtsp: failed to parse client_port");
|
||||
if (sscanf(tmp, "%u-%u", &c_data_port, &c_mon_port) < 1) {
|
||||
g_warning("Frame %u: rtsp: bad client_port",
|
||||
pinfo->fd->num);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!c_data_port)
|
||||
if (!c_data_port) {
|
||||
rtsp_conversation_data_t *data;
|
||||
u_int s_data_chan, s_mon_chan;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* Deal with RTSP TCP-interleaved conversations.
|
||||
*/
|
||||
if ((tmp = strstr(buf, rtsp_inter)) == NULL) {
|
||||
/*
|
||||
* No interleaved or server_port - probably a
|
||||
* SETUP request, rather than reply.
|
||||
*/
|
||||
return;
|
||||
}
|
||||
tmp += strlen(rtsp_inter);
|
||||
i = sscanf(tmp, "%u-%u", &s_data_chan, &s_mon_chan);
|
||||
if (i < 1) {
|
||||
g_warning("Frame %u: rtsp: bad interleaved",
|
||||
pinfo->fd->num);
|
||||
return;
|
||||
}
|
||||
conv = find_conversation(&pinfo->src, &pinfo->dst, pinfo->ptype,
|
||||
pinfo->srcport, pinfo->destport, 0);
|
||||
if (!conv) {
|
||||
conv = conversation_new(&pinfo->src, &pinfo->dst,
|
||||
pinfo->ptype, pinfo->srcport, pinfo->destport,
|
||||
0);
|
||||
}
|
||||
data = conversation_get_proto_data(conv, proto_rtsp);
|
||||
if (!data) {
|
||||
data = g_mem_chunk_alloc(rtsp_vals);
|
||||
conversation_add_proto_data(conv, proto_rtsp, data);
|
||||
}
|
||||
if (s_data_chan < RTSP_MAX_INTERLEAVED) {
|
||||
data->interleaved[s_data_chan].dissector =
|
||||
rtp_handle;
|
||||
}
|
||||
if (i > 1 && s_mon_chan < RTSP_MAX_INTERLEAVED) {
|
||||
data->interleaved[s_mon_chan].dissector =
|
||||
rtcp_handle;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* We only want to match on the destination address, not the
|
||||
|
@ -698,6 +786,21 @@ dissect_rtsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
rtsp_init(void)
|
||||
{
|
||||
/* Routine to initialize rtsp protocol before each capture or filter pass. */
|
||||
/* Release any memory if needed. Then setup the memory chunks. */
|
||||
|
||||
if (rtsp_vals)
|
||||
g_mem_chunk_destroy(rtsp_vals);
|
||||
|
||||
rtsp_vals = g_mem_chunk_new("rtsp_vals",
|
||||
sizeof(rtsp_conversation_data_t),
|
||||
rtsp_hash_init_count * sizeof(rtsp_conversation_data_t),
|
||||
G_ALLOC_AND_FREE);
|
||||
}
|
||||
|
||||
void
|
||||
proto_register_rtsp(void)
|
||||
{
|
||||
|
@ -718,6 +821,8 @@ proto_register_rtsp(void)
|
|||
"RTSP", "rtsp");
|
||||
proto_register_field_array(proto_rtsp, hf, array_length(hf));
|
||||
proto_register_subtree_array(ett, array_length(ett));
|
||||
|
||||
register_init_routine(rtsp_init); /* register re-init routine */
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -725,8 +830,7 @@ proto_reg_handoff_rtsp(void)
|
|||
{
|
||||
dissector_add("tcp.port", TCP_PORT_RTSP, dissect_rtsp, proto_rtsp);
|
||||
|
||||
/*
|
||||
* Get a handle for the SDP dissector.
|
||||
*/
|
||||
sdp_handle = find_dissector("sdp");
|
||||
rtp_handle = find_dissector("rtp");
|
||||
rtcp_handle = find_dissector("rtcp");
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue