Ethereal-dev: [Ethereal-dev] Using SDP to detect RTP and RTCP streams
Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.
From: "Lars Roland" <Lars.Roland@xxxxxxx>
Date: Mon, 17 Nov 2003 16:51:45 +0100 (MET)
Hello all, attached is a patch for the sdp dissector. It will add automatic detection of RTP and RTCP for Protocols using SDP (e.g. SIP, MGCP, ...). However, this is a first try and it might not work in some cases. I have tested it only with a few SIP calls. Best Regards, Lars Roland
Index: ethereal/packet-sdp.c =================================================================== RCS file: /cvsroot/ethereal/packet-sdp.c,v retrieving revision 1.35 diff -u -r1.35 packet-sdp.c --- ethereal/packet-sdp.c 14 Oct 2003 21:26:37 -0000 1.35 +++ ethereal/packet-sdp.c 17 Nov 2003 14:42:50 -0000 @@ -32,8 +32,12 @@ #include <glib.h> #include <epan/packet.h> +#include <epan/conversation.h> #include <epan/strutil.h> +static dissector_handle_t rtp_handle=NULL; +static dissector_handle_t rtcp_handle=NULL; + static int proto_sdp = -1; /* Top level fields */ @@ -137,6 +141,11 @@ static void dissect_sdp_media(tvbuff_t *tvb, proto_item *ti); static void dissect_sdp_media_attribute(tvbuff_t *tvb, proto_item *ti); +static char *media_port; +static char *media_proto; +static char *connection_address; +static char *connection_type; + static void dissect_sdp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { @@ -153,6 +162,20 @@ int hf = -1; char *string; + address src_addr; + conversation_t *conv=NULL; + + guint32 ipv4_address=0; + guint32 ipv4_port=0; + gboolean is_rtp=FALSE; + gboolean is_ipv4_addr=FALSE; + struct in_addr ipaddr; + + media_port=NULL; + media_proto=NULL; + connection_address=NULL; + connection_type=NULL; + /* * As RFC 2327 says, "SDP is purely a format for session * description - it does not incorporate a transport protocol, @@ -289,6 +312,60 @@ offset = next_offset; } + + /* Now look, if we have strings collected. + * Try to convert ipv4 address and port into binary format, + * so we can use them to detect rtp and rtcp streams. + * Don't forget to free the strings! + */ + + if(media_port!=NULL) { + ipv4_port = atol(media_port); + g_free(media_port); + } + if(media_proto!=NULL) { + /* Check if media protocol is RTP */ + is_rtp= !strcmp(media_proto,"RTP/AVP"); + g_free(media_proto); + } + if(connection_address!=NULL) { + if(connection_type!=NULL && strcmp(connection_type,"IP4")==0 ) { + if(inet_aton(connection_address, &ipaddr) !=0 ) { + /* connection_address could be converted to a valid ipv4 address*/ + is_ipv4_addr=TRUE; + ipv4_address = ipaddr.s_addr; + } + } + g_free(connection_address); + } + if(connection_type!=NULL) { + g_free(connection_type); + } + + /* Add rtp and rtcp conversation, if available */ + if((!pinfo->fd->flags.visited) && ipv4_address!=0 && ipv4_port!=0 && is_rtp && is_ipv4_addr){ + src_addr.type=AT_IPv4; + src_addr.len=4; + src_addr.data=(char *)&ipv4_address; + + if(rtp_handle){ + conv=find_conversation(&src_addr, &src_addr, PT_UDP, ipv4_port, ipv4_port, NO_ADDR_B|NO_PORT_B); + if(!conv){ + conv=conversation_new(&src_addr, &src_addr, PT_UDP, ipv4_port, ipv4_port, NO_ADDR_B|NO_PORT_B); + conversation_set_dissector(conv, rtp_handle); + } + } + + if(rtcp_handle){ + ipv4_port++; + conv=find_conversation(&src_addr, &src_addr, PT_UDP, ipv4_port, ipv4_port, NO_ADDR_B|NO_PORT_B); + if(!conv){ + conv=conversation_new(&src_addr, &src_addr, PT_UDP, ipv4_port, ipv4_port, NO_ADDR_B|NO_PORT_B); + conversation_set_dissector(conv, rtcp_handle); + } + } + } + datalen = tvb_length_remaining(tvb, offset); if (datalen > 0) { proto_tree_add_text(sdp_tree, tvb, offset, datalen, @@ -414,6 +491,8 @@ if( next_offset == -1 ) return; tokenlen = next_offset - offset; + /* Save connection address type */ + connection_type = tvb_get_string(tvb, offset, tokenlen); proto_tree_add_item(sdp_connection_info_tree, hf_connection_info_address_type,tvb, @@ -424,9 +503,14 @@ next_offset = tvb_find_guint8(tvb,offset,-1,'/'); if( next_offset == -1){ tokenlen = -1; /* end of tvbuff */ + /* Save connection address */ + connection_address = tvb_get_string(tvb, offset, tvb_length_remaining(tvb, offset)); } else { tokenlen = next_offset - offset; + /* Save connection address */ + connection_address = tvb_get_string(tvb, offset, tokenlen); } + proto_tree_add_item(sdp_connection_info_tree, hf_connection_info_connection_address, tvb, offset,tokenlen,FALSE); @@ -667,6 +751,8 @@ if(next_offset != -1){ tokenlen = next_offset - offset; + /* Save port info */ + media_port = tvb_get_string(tvb, offset, tokenlen); proto_tree_add_item(sdp_media_tree, hf_media_port, tvb, offset, tokenlen, FALSE); @@ -684,6 +770,8 @@ if(next_offset == -1) return; tokenlen = next_offset - offset; + /* Save port info */ + media_port = tvb_get_string(tvb, offset, tokenlen); /* XXX Remember Port */ proto_tree_add_item(sdp_media_tree, hf_media_port, tvb, @@ -697,6 +785,8 @@ return; tokenlen = next_offset - offset; + /* Save port protocol */ + media_proto = tvb_get_string(tvb, offset, tokenlen); /* XXX Remember Protocol */ proto_tree_add_item(sdp_media_tree, hf_media_proto, tvb, @@ -722,7 +812,7 @@ * We need to find out the address of the other side first and it * looks like that info can be found in SIP headers only. */ - + } static void dissect_sdp_media_attribute(tvbuff_t *tvb, proto_item * ti){ @@ -987,3 +1077,10 @@ */ register_dissector("sdp", dissect_sdp, proto_sdp); } + +void +proto_reg_handoff_sdp(void) +{ + rtp_handle = find_dissector("rtp"); + rtcp_handle = find_dissector("rtcp"); +} \ No newline at end of file
- Follow-Ups:
- Re: [Ethereal-dev] Using SDP to detect RTP and RTCP streams
- From: Guy Harris
- Re: [Ethereal-dev] Using SDP to detect RTP and RTCP streams
- Prev by Date: Re: [Ethereal-dev] [PATCH][CYGWIN]Default binaries targets
- Next by Date: [Ethereal-dev] gprof data from cygwin build
- Previous by thread: Re: [Ethereal-dev] [PATCH][CYGWIN]Default binaries targets
- Next by thread: Re: [Ethereal-dev] Using SDP to detect RTP and RTCP streams
- Index(es):