RTP: RTP dissector is able to decode RTP over TCP (RFC 4571)

Bug: 13251
Change-Id: I56a01e779f7f0eadc8a078f88543269a91148f00
Reviewed-on: https://code.wireshark.org/review/19293
Petri-Dish: Michael Mann <mmann78@netscape.net>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Michael Mann <mmann78@netscape.net>
This commit is contained in:
Jiri Novak 2016-12-14 22:55:05 +01:00 committed by Michael Mann
parent 5696b842b1
commit 7eee48ad55
16 changed files with 77 additions and 28 deletions

View File

@ -371,7 +371,7 @@ static void h245_setup_channels(packet_info *pinfo, channel_info_t *upcoming_cha
/* DEBUG g_warning("h245_setup_channels media_addr.addr.type %u port %u",upcoming_channel_lcl->media_addr.addr.type, upcoming_channel_lcl->media_addr.port );
*/
if (upcoming_channel_lcl->media_addr.addr.type!=AT_NONE && upcoming_channel_lcl->media_addr.port!=0) {
srtp_add_address(pinfo, &upcoming_channel_lcl->media_addr.addr,
srtp_add_address(pinfo, PT_UDP, &upcoming_channel_lcl->media_addr.addr,
upcoming_channel_lcl->media_addr.port, 0,
"H245", pinfo->num, upcoming_channel_lcl->is_video , rtp_dyn_payload, dummy_srtp_info);
}

View File

@ -6844,7 +6844,7 @@ elem_a2p_bearer_format(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guin
rtp_dyn_payload_used = TRUE;
first_assigned_found = TRUE;
rtp_add_address(pinfo, &data_p->rtp_src_addr, data_p->rtp_port, 0, "IOS5",
rtp_add_address(pinfo, PT_UDP, &data_p->rtp_src_addr, data_p->rtp_port, 0, "IOS5",
pinfo->num, FALSE, rtp_dyn_payload);
}

View File

@ -296,7 +296,7 @@ dissect_applemidi_heur( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, voi
rtp_dyn_payload = rtp_dyn_payload_new();
rtp_dyn_payload_insert(rtp_dyn_payload, 97, "rtp-midi", 10000);
rtp_add_address( pinfo, &pinfo->src, pinfo->srcport, 0, APPLEMIDI_DISSECTOR_SHORTNAME,
rtp_add_address( pinfo, PT_UDP, &pinfo->src, pinfo->srcport, 0, APPLEMIDI_DISSECTOR_SHORTNAME,
pinfo->num, FALSE, rtp_dyn_payload);
/* call dissect_applemidi() from now on for UDP packets on this "connection"

View File

@ -3695,7 +3695,7 @@ be_aoip_trans_lay_add(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U_, g
}
if ((!pinfo->fd->flags.visited) && rtp_port != 0) {
rtp_add_address(pinfo, &rtp_dst_addr, rtp_port, 0, "BSS MAP", pinfo->num, FALSE, 0);
rtp_add_address(pinfo, PT_UDP, &rtp_dst_addr, rtp_port, 0, "BSS MAP", pinfo->num, FALSE, 0);
rtcp_add_address(pinfo, &rtp_dst_addr, rtp_port+1, 0, "BSS MAP", pinfo->num);
}
return(curr_offset - offset);

View File

@ -502,7 +502,7 @@ static void h245_setup_channels(packet_info *pinfo, channel_info_t *upcoming_cha
/* DEBUG g_warning("h245_setup_channels media_addr.addr.type %u port %u",upcoming_channel_lcl->media_addr.addr.type, upcoming_channel_lcl->media_addr.port );
*/
if (upcoming_channel_lcl->media_addr.addr.type!=AT_NONE && upcoming_channel_lcl->media_addr.port!=0) {
srtp_add_address(pinfo, &upcoming_channel_lcl->media_addr.addr,
srtp_add_address(pinfo, PT_UDP, &upcoming_channel_lcl->media_addr.addr,
upcoming_channel_lcl->media_addr.port, 0,
"H245", pinfo->num, upcoming_channel_lcl->is_video , rtp_dyn_payload, dummy_srtp_info);
}

View File

@ -3200,7 +3200,7 @@ dissct_rsl_ipaccess_msg(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int
}
conversation_delete_proto_data(conv, proto_rsl);
wmem_free(wmem_file_scope(), dyn_pl_info);
rtp_add_address(pinfo, &src_addr, local_port, 0,
rtp_add_address(pinfo, PT_UDP, &src_addr, local_port, 0,
"GSM A-bis/IP", pinfo->num, 0, dyn_pl);
rtcp_add_address(pinfo, &src_addr, local_port+1, 0,
"GSM A-bis/IP", pinfo->num);

View File

@ -147,6 +147,7 @@ static const fragment_items rtp_fragment_items = {
};
static dissector_handle_t rtp_handle;
static dissector_handle_t rtp_rfc4571_handle;
static dissector_handle_t rtcp_handle;
static dissector_handle_t classicstun_handle;
static dissector_handle_t stun_handle;
@ -273,6 +274,9 @@ static int hf_rtp_ext_rfc5285_length = -1;
static int hf_rtp_ext_rfc5285_appbits = -1;
static int hf_rtp_ext_rfc5285_data = -1;
/* RFC 4571 Header extension */
static int hf_rfc4571_header_len = -1;
#define RTP0_INVALID 0
#define RTP0_STUN 1
#define RTP0_CLASSICSTUN 2
@ -1235,7 +1239,7 @@ bluetooth_add_address(packet_info *pinfo, address *addr, guint32 stream_number,
/* Set up an SRTP conversation */
void
srtp_add_address(packet_info *pinfo, address *addr, int port, int other_port,
srtp_add_address(packet_info *pinfo, const port_type ptype, address *addr, int port, int other_port,
const gchar *setup_method, guint32 setup_frame_number,
gboolean is_video _U_, rtp_dyn_payload_t *rtp_dyn_payload,
struct srtp_info *srtp_info)
@ -1249,13 +1253,13 @@ srtp_add_address(packet_info *pinfo, address *addr, int port, int other_port,
* we've already done this work, so we don't need to do it
* again.
*/
if ((pinfo->fd->flags.visited) || (rtp_handle == NULL))
if ((pinfo->fd->flags.visited) || (rtp_handle == NULL) || (rtp_rfc4571_handle == NULL))
{
return;
}
DPRINT(("#%u: %srtp_add_address(%s, %u, %u, %s, %u)",
pinfo->num, (srtp_info)?"s":"", address_to_str(wmem_packet_scope(), addr), port,
DPRINT(("#%u: %srtp_add_address(%d, %s, %u, %u, %s, %u)",
pinfo->num, (srtp_info)?"s":"", ptype, address_to_str(wmem_packet_scope(), addr), port,
other_port, setup_method, setup_frame_number));
DINDENT();
@ -1265,7 +1269,7 @@ srtp_add_address(packet_info *pinfo, address *addr, int port, int other_port,
* Check if the ip address and port combination is not
* already registered as a conversation.
*/
p_conv = find_conversation(setup_frame_number, addr, &null_addr, PT_UDP, port, other_port,
p_conv = find_conversation(setup_frame_number, addr, &null_addr, ptype, port, other_port,
NO_ADDR_B | (!other_port ? NO_PORT_B : 0));
DENDENT();
@ -1275,13 +1279,19 @@ srtp_add_address(packet_info *pinfo, address *addr, int port, int other_port,
* If not, create a new conversation.
*/
if (!p_conv || p_conv->setup_frame != setup_frame_number) {
p_conv = conversation_new(setup_frame_number, addr, &null_addr, PT_UDP,
p_conv = conversation_new(setup_frame_number, addr, &null_addr, ptype,
(guint32)port, (guint32)other_port,
NO_ADDR2 | (!other_port ? NO_PORT2 : 0));
}
/* Set dissector */
conversation_set_dissector(p_conv, rtp_handle);
if (ptype == PT_UDP) {
conversation_set_dissector(p_conv, rtp_handle);
} else if (ptype == PT_TCP) {
conversation_set_dissector(p_conv, rtp_rfc4571_handle);
} else {
DISSECTOR_ASSERT(FALSE);
}
/*
* Check if the conversation has data associated with it.
@ -1335,11 +1345,11 @@ srtp_add_address(packet_info *pinfo, address *addr, int port, int other_port,
/* Set up an RTP conversation */
void
rtp_add_address(packet_info *pinfo, address *addr, int port, int other_port,
rtp_add_address(packet_info *pinfo, const port_type ptype, address *addr, int port, int other_port,
const gchar *setup_method, guint32 setup_frame_number,
gboolean is_video , rtp_dyn_payload_t *rtp_dyn_payload)
{
srtp_add_address(pinfo, addr, port, other_port, setup_method, setup_frame_number, is_video, rtp_dyn_payload, NULL);
srtp_add_address(pinfo, ptype, addr, port, other_port, setup_method, setup_frame_number, is_video, rtp_dyn_payload, NULL);
}
static gboolean
@ -1749,8 +1759,6 @@ dissect_rtp_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
pinfo->desegment_len = 0;
}
static int
dissect_rtp_rfc2198(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
{
@ -1840,6 +1848,30 @@ dissect_rtp_rfc2198(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* d
return tvb_captured_length(tvb);
}
static int
dissect_rtp_rfc4571(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
{
gint offset = 0;
unsigned int packet_len;
unsigned int rtp_packet_len;
tvbuff_t *nexttvb;
packet_len = tvb_reported_length(tvb);
if ( packet_len < 2 )
return 0;
/* Is packet longer than length item */
rtp_packet_len = tvb_get_ntohs( tvb, offset );
if (packet_len != rtp_packet_len)
return 0;
proto_tree_add_uint( tree, hf_rfc4571_header_len, tvb, offset, 2, rtp_packet_len);
offset += 2;
nexttvb = tvb_new_subset_remaining( tvb, offset);
return dissect_rtp( nexttvb, pinfo, tree, data );
}
static void
dissect_rtp_hext_rfc5285_onebyte( tvbuff_t *tvb, packet_info *pinfo,
proto_tree *rtp_hext_tree )
@ -3552,6 +3584,18 @@ proto_register_rtp(void)
HFILL
}
},
{
&hf_rfc4571_header_len,
{
"RFC 4571 packet len",
"rtp.rfc4571.len",
FT_UINT16,
BASE_DEC,
NULL,
0x0,
NULL, HFILL
}
},
/* reassembly stuff */
{&hf_rtp_fragments,
@ -3667,6 +3711,7 @@ proto_register_rtp(void)
register_dissector("rtp", dissect_rtp, proto_rtp);
register_dissector("rtp.rfc2198", dissect_rtp_rfc2198, proto_rtp);
register_dissector("rtp.rfc4571", dissect_rtp_rfc4571, proto_rtp);
rtp_tap = register_tap("rtp");
@ -3729,8 +3774,10 @@ proto_reg_handoff_rtp(void)
rtp_handle = find_dissector("rtp");
rtp_rfc2198_handle = find_dissector("rtp.rfc2198");
rtp_rfc4571_handle = find_dissector("rtp.rfc4571");
dissector_add_for_decode_as("udp.port", rtp_handle);
dissector_add_for_decode_as("tcp.port", rtp_rfc4571_handle);
dissector_add_string("rtp_dyn_payload_type", "red", rtp_rfc2198_handle);
heur_dissector_add( "udp", dissect_rtp_heur_udp, "RTP over UDP", "rtp_udp", proto_rtp, HEURISTIC_DISABLE);
heur_dissector_add("stun", dissect_rtp_heur_app, "RTP over TURN", "rtp_stun", proto_rtp, HEURISTIC_DISABLE);

View File

@ -193,6 +193,7 @@ struct _rtp_conversation_info
/* Add an RTP conversation with the given details */
WS_DLL_PUBLIC
void rtp_add_address(packet_info *pinfo,
const port_type ptype,
address *addr, int port,
int other_port,
const gchar *setup_method,
@ -203,6 +204,7 @@ void rtp_add_address(packet_info *pinfo,
/* Add an SRTP conversation with the given details */
WS_DLL_PUBLIC
void srtp_add_address(packet_info *pinfo,
const port_type ptype,
address *addr, int port,
int other_port,
const gchar *setup_method,

View File

@ -881,7 +881,7 @@ dissect_rtpproxy(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data
if (rtp_handle) {
/* FIXME tell if isn't a video stream, and setup codec mapping */
if (addr.len)
rtp_add_address(pinfo, &addr, port, 0, "RTPproxy", pinfo->num, 0, NULL);
rtp_add_address(pinfo, PT_UDP, &addr, port, 0, "RTPproxy", pinfo->num, 0, NULL);
}
if (rtcp_handle) {
if (addr.len)

View File

@ -636,7 +636,7 @@ rtsp_create_conversation(packet_info *pinfo, proto_item *ti,
if (rtp_transport)
{
/* There is always data for RTP */
rtp_add_address(pinfo, &pinfo->dst, c_data_port, s_data_port,
rtp_add_address(pinfo, PT_UDP, &pinfo->dst, c_data_port, s_data_port,
"RTSP", pinfo->num, is_video, NULL);
/* RTCP only if indicated */

View File

@ -2141,7 +2141,7 @@ apply_sdp_transport(packet_info *pinfo, transport_info_t *transport_info, int re
DINDENT();
/* srtp_add_address and rtp_add_address are given the request_frame's not this frame's number,
because that's where the RTP flow started, and thus conversation needs to check against */
srtp_add_address(pinfo, &media_desc->conn_addr, media_desc->media_port, 0, "SDP", establish_frame,
srtp_add_address(pinfo, PT_UDP, &media_desc->conn_addr, media_desc->media_port, 0, "SDP", establish_frame,
media_desc->is_video,
media_desc->media.rtp_dyn_payload, srtp_info);
DENDENT();
@ -2149,7 +2149,7 @@ apply_sdp_transport(packet_info *pinfo, transport_info_t *transport_info, int re
DPRINT(("calling rtp_add_address, channel=%d, media_port=%d",
i, media_desc->media_port));
DINDENT();
rtp_add_address(pinfo, &media_desc->conn_addr, media_desc->media_port, 0, "SDP", establish_frame,
rtp_add_address(pinfo, PT_UDP, &media_desc->conn_addr, media_desc->media_port, 0, "SDP", establish_frame,
media_desc->is_video,
media_desc->media.rtp_dyn_payload);
DENDENT();

View File

@ -2271,7 +2271,7 @@ dissect_skinny_ipv4or6(ptvcursor_t *cursor, int hfindex_ipv4, int hfindex_ipv6,
src_addr.len = 4;
src_addr.data = (guint8 *)&ip_address;
ip_address = tvb_get_ipv4(tvb, offset);
rtp_add_address(pinfo, &src_addr, tvb_get_letohl(tvb, offset), 0, "Skinny", pinfo->num, is_video, NULL);
rtp_add_address(pinfo, PT_UDP, &src_addr, tvb_get_letohl(tvb, offset), 0, "Skinny", pinfo->num, is_video, NULL);
ptvcursor_add(cursor, hfindex_ipv4, 4, ENC_BIG_ENDIAN);
if (hdr_version >= V17_MSG_TYPE) {
/* skip over the extra room for ipv6 addresses */
@ -2283,7 +2283,7 @@ dissect_skinny_ipv4or6(ptvcursor_t *cursor, int hfindex_ipv4, int hfindex_ipv6,
src_addr.len = 16;
src_addr.data = (guint8 *)&IPv6;
tvb_get_ipv6(tvb, offset, &IPv6);
rtp_add_address(pinfo, &src_addr, tvb_get_letohl(tvb, offset), 0, "Skinny", pinfo->num, is_video, NULL);
rtp_add_address(pinfo, PT_UDP, &src_addr, tvb_get_letohl(tvb, offset), 0, "Skinny", pinfo->num, is_video, NULL);
ptvcursor_add(cursor, hfindex_ipv6, 16, ENC_NA);
} else {
/* Invalid : skip over ipv6 space completely */

View File

@ -224,7 +224,7 @@ static void _dissect_ua_msg(tvbuff_t *tvb,
if ((remote_rtp_addr.data != NULL) && (remote_rtp_port != 0))
{
rtp_add_address(pinfo, &remote_rtp_addr, remote_rtp_port, 0,
rtp_add_address(pinfo, PT_UDP, &remote_rtp_addr, remote_rtp_port, 0,
"UA", pinfo->num, 0, NULL);
rtcp_add_address(pinfo, &remote_rtp_addr, remote_rtp_port+1, 0,
"UA", pinfo->num);

View File

@ -1539,7 +1539,7 @@ dissect_uma_IE(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
}
if((!pinfo->fd->flags.visited) && RTP_UDP_port!=0){
rtp_add_address(pinfo, &src_addr, RTP_UDP_port, 0, "UMA", pinfo->num, FALSE, 0);
rtp_add_address(pinfo, PT_UDP, &src_addr, RTP_UDP_port, 0, "UMA", pinfo->num, FALSE, 0);
if ((RTP_UDP_port & 0x1) == 0){ /* Even number RTP port RTCP should follow on odd number */
RTCP_UDP_port = RTP_UDP_port + 1;
rtcp_add_address(pinfo, &src_addr, RTCP_UDP_port, 0, "UMA", pinfo->num);

View File

@ -452,10 +452,10 @@ dissect_Conf2ACK(packet_info *pinfo) {
dummy_srtp_info->mki_len = 0;
dummy_srtp_info->auth_tag_len = 4;
srtp_add_address(pinfo, &pinfo->net_src, pinfo->srcport, pinfo->destport,
srtp_add_address(pinfo, PT_UDP, &pinfo->net_src, pinfo->srcport, pinfo->destport,
"ZRTP", pinfo->num, FALSE, NULL, dummy_srtp_info);
srtp_add_address(pinfo, &pinfo->net_dst, pinfo->destport, pinfo->srcport,
srtp_add_address(pinfo, PT_UDP, &pinfo->net_dst, pinfo->destport, pinfo->srcport,
"ZRTP", pinfo->num, FALSE, NULL, dummy_srtp_info);
srtcp_add_address(pinfo, &pinfo->net_src, pinfo->srcport+1, pinfo->destport+1,

View File

@ -2310,7 +2310,7 @@ dissect_audio_switch(proto_tree *msg_tree,packet_info *pinfo,
set_address(&far_addr, AT_IPv4, 4, &far_ip_addr);
far_port = tvb_get_ntohs(tvb, offset-8);
rtp_add_address(pinfo, &far_addr, far_port, 0, "UNISTIM", pinfo->num, FALSE, NULL);
rtp_add_address(pinfo, PT_UDP, &far_addr, far_port, 0, "UNISTIM", pinfo->num, FALSE, NULL);
far_port = tvb_get_ntohs(tvb, offset-6);
rtcp_add_address(pinfo, &far_addr, far_port, 0, "UNISTIM", pinfo->num);