2013-08-18 19:49:08 +00:00
/* packet-rtpproxy.c
* RTPproxy command protocol dissector
* Copyright 2013 , Peter Lemenkov < lemenkov @ gmail . com >
*
* This dissector tries to dissect rtpproxy control protocol . Please visit this
* link for brief details on the command format :
*
* http : //www.rtpproxy.org/wiki/RTPproxy/Protocol
*
* Wireshark - Network traffic analyzer
* By Gerald Combs < gerald @ wireshark . org >
* Copyright 1999 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 . , 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 USA .
*/
# include "config.h"
2013-12-03 22:16:49 +00:00
# include <stdlib.h>
2013-10-09 20:14:12 +00:00
# include <ctype.h>
2013-11-26 22:05:33 +00:00
# include <glib.h>
2013-10-09 20:14:12 +00:00
2013-11-26 22:05:33 +00:00
# include <epan/address.h>
2013-08-18 19:49:08 +00:00
# include <epan/packet.h>
# include <epan/prefs.h>
2013-10-02 16:37:10 +00:00
# include <epan/conversation.h>
2013-11-28 14:11:48 +00:00
# include <epan/expert.h>
2013-11-29 22:56:34 +00:00
# include <epan/rtp_pt.h>
2013-12-21 17:23:17 +00:00
# include <epan/addr_resolv.h>
2013-08-18 19:49:08 +00:00
2013-11-26 22:05:33 +00:00
/* For setting up RTP/RTCP dissectors based on the RTPproxy's answers */
# include "packet-rtp.h"
# include "packet-rtcp.h"
2013-12-12 06:11:05 +00:00
void proto_register_rtpproxy ( void ) ;
2013-08-18 19:49:08 +00:00
static int proto_rtpproxy = - 1 ;
static int hf_rtpproxy_cookie = - 1 ;
static int hf_rtpproxy_error = - 1 ;
static int hf_rtpproxy_status = - 1 ;
static int hf_rtpproxy_ok = - 1 ;
static int hf_rtpproxy_ipv4 = - 1 ;
static int hf_rtpproxy_ipv6 = - 1 ;
static int hf_rtpproxy_port = - 1 ;
static int hf_rtpproxy_lf = - 1 ;
static int hf_rtpproxy_request = - 1 ;
static int hf_rtpproxy_command = - 1 ;
static int hf_rtpproxy_command_parameters = - 1 ;
2013-11-26 22:32:33 +00:00
static int hf_rtpproxy_command_parameter = - 1 ;
static int hf_rtpproxy_command_parameter_codec = - 1 ;
2013-12-13 18:10:21 +00:00
static int hf_rtpproxy_command_parameter_local_ipv4 = - 1 ;
static int hf_rtpproxy_command_parameter_remote_ipv4 = - 1 ;
2013-11-26 22:32:33 +00:00
static int hf_rtpproxy_command_parameter_repacketize = - 1 ;
static int hf_rtpproxy_command_parameter_dtmf = - 1 ;
/* static int hf_rtpproxy_command_parameter_cmap = -1; TODO */
static int hf_rtpproxy_command_parameter_proto = - 1 ;
static int hf_rtpproxy_command_parameter_transcode = - 1 ;
static int hf_rtpproxy_command_parameter_acc = - 1 ;
2013-08-18 19:49:08 +00:00
static int hf_rtpproxy_callid = - 1 ;
static int hf_rtpproxy_copy_target = - 1 ;
static int hf_rtpproxy_playback_filename = - 1 ;
static int hf_rtpproxy_playback_codec = - 1 ;
static int hf_rtpproxy_notify = - 1 ;
static int hf_rtpproxy_notify_ipv4 = - 1 ;
2013-11-17 14:48:55 +00:00
static int hf_rtpproxy_notify_ipv6 = - 1 ;
2013-08-18 19:49:08 +00:00
static int hf_rtpproxy_notify_port = - 1 ;
static int hf_rtpproxy_notify_tag = - 1 ;
static int hf_rtpproxy_tag = - 1 ;
static int hf_rtpproxy_mediaid = - 1 ;
static int hf_rtpproxy_reply = - 1 ;
static int hf_rtpproxy_version_request = - 1 ;
static int hf_rtpproxy_version_supported = - 1 ;
2014-02-20 11:50:09 +00:00
static int hf_rtpproxy_ng_bencode = - 1 ;
2013-08-18 19:49:08 +00:00
2013-11-28 14:11:48 +00:00
/* Expert fields */
static expert_field ei_rtpproxy_timeout = EI_INIT ;
2013-12-20 20:31:40 +00:00
static expert_field ei_rtpproxy_notify_no_ip = EI_INIT ;
2013-12-13 18:10:21 +00:00
static expert_field ei_rtpproxy_bad_ipv4 = EI_INIT ;
static expert_field ei_rtpproxy_bad_ipv6 = EI_INIT ;
2013-11-28 14:11:48 +00:00
2013-10-02 16:37:10 +00:00
/* Request/response tracking */
static int hf_rtpproxy_request_in = - 1 ;
static int hf_rtpproxy_response_in = - 1 ;
2013-11-06 20:39:10 +00:00
static int hf_rtpproxy_response_time = - 1 ;
2013-10-02 16:37:10 +00:00
typedef struct _rtpproxy_info {
guint32 req_frame ;
guint32 resp_frame ;
2013-11-06 20:39:10 +00:00
nstime_t req_time ;
2013-11-30 09:50:04 +00:00
gchar * callid ;
2013-10-02 16:37:10 +00:00
} rtpproxy_info_t ;
2013-11-26 22:05:33 +00:00
static dissector_handle_t rtcp_handle ;
2013-11-26 22:40:52 +00:00
static dissector_handle_t rtp_events_handle ;
static dissector_handle_t rtp_handle ;
2014-02-20 11:50:09 +00:00
static dissector_handle_t bencode_handle ;
2013-11-26 22:05:33 +00:00
2013-10-02 16:37:10 +00:00
typedef struct _rtpproxy_conv_info {
wmem_tree_t * trans ;
} rtpproxy_conv_info_t ;
2013-11-11 16:36:16 +00:00
static const string_string versiontypenames [ ] = {
{ " 20040107 " , " Basic RTP proxy functionality " } ,
{ " 20050322 " , " Support for multiple RTP streams and MOH " } ,
{ " 20060704 " , " Support for extra parameter in the V command " } ,
{ " 20071116 " , " Support for RTP re-packetization " } ,
{ " 20071218 " , " Support for forking (copying) RTP stream " } ,
{ " 20080403 " , " Support for RTP statistics querying " } ,
{ " 20081102 " , " Support for setting codecs in the update/lookup command " } ,
{ " 20081224 " , " Support for session timeout notifications " } ,
{ " 20090810 " , " Support for automatic bridging " } ,
{ 0 , NULL }
} ;
2013-08-18 19:49:08 +00:00
static const value_string commandtypenames [ ] = {
{ ' V ' , " Handshake/Ping " } ,
{ ' v ' , " Handshake/Ping " } ,
{ ' U ' , " Offer/Update " } ,
{ ' u ' , " Offer/Update " } ,
{ ' L ' , " Answer/Lookup " } ,
{ ' l ' , " Answer/Lookup " } ,
{ ' I ' , " Information " } ,
{ ' i ' , " Information " } ,
{ ' X ' , " Close all active sessions " } ,
{ ' x ' , " Close all active sessions " } ,
{ ' D ' , " Delete an active session (Bye/Cancel/Error) " } ,
{ ' d ' , " Delete an active session (Bye/Cancel/Error) " } ,
{ ' P ' , " Start playback (music-on-hold) " } ,
{ ' p ' , " Start playback (music-on-hold) " } ,
{ ' S ' , " Stop playback (music-on-hold) " } ,
{ ' s ' , " Stop playback (music-on-hold) " } ,
{ ' R ' , " Start recording " } ,
{ ' r ' , " Start recording " } ,
{ ' C ' , " Copy stream " } ,
{ ' c ' , " Copy stream " } ,
{ ' Q ' , " Query info about a session " } ,
{ ' q ' , " Query info about a session " } ,
{ 0 , NULL }
} ;
2013-11-26 22:32:33 +00:00
static const value_string paramtypenames [ ] = {
/* Official command parameters */
{ ' 4 ' , " Remote address is IPv4 " } ,
{ ' 6 ' , " Remote address is IPv6 " } ,
{ ' a ' , " Asymmetric RTP " } ,
{ ' A ' , " Asymmetric RTP " } ,
{ ' b ' , " Brief stats " } ,
{ ' B ' , " Brief stats " } ,
{ ' c ' , " Codecs " } ,
{ ' C ' , " Codecs " } ,
{ ' e ' , " External network (non RFC 1918) " } ,
{ ' E ' , " External network (non RFC 1918) " } ,
{ ' i ' , " Internal network (RFC 1918) " } ,
{ ' I ' , " Internal network (RFC 1918) " } ,
{ ' l ' , " Local address " } ,
{ ' L ' , " Local address " } ,
{ ' r ' , " Remote address " } ,
{ ' R ' , " Remote address " } ,
{ ' s ' , " Symmetric RTP (default) " } ,
{ ' S ' , " Symmetric RTP (default) " } ,
{ ' w ' , " Weak connection (allows roaming) " } ,
{ ' W ' , " Weak connection (allows roaming) " } ,
{ ' z ' , " repacketiZe " } ,
{ ' Z ' , " repacketiZe " } ,
/* Unofficial command parameters / expensions */
{ ' d ' , " DTMF payload ID (unofficial extension) " } ,
{ ' D ' , " DTMF payload ID (unofficial extension) " } ,
{ ' m ' , " codec Mapping (unofficial extension) " } ,
{ ' M ' , " codec Mapping (unofficial extension) " } ,
{ ' p ' , " Protocol type (unofficial extension) " } ,
{ ' P ' , " Protocol type (unofficial extension) " } ,
{ ' t ' , " Transcode to (unofficial extension) " } ,
{ ' T ' , " Transcode to (unofficial extension) " } ,
{ ' v ' , " Accounting (unofficial extension) " } ,
{ ' V ' , " Accounting (unofficial extension) " } ,
{ 0 , NULL }
} ;
static const value_string prototypenames [ ] = {
{ ' 0 ' , " UDP (default) " } ,
{ ' 1 ' , " TCP " } ,
{ ' 2 ' , " SCTP " } ,
{ 0 , NULL }
} ;
static const value_string acctypenames [ ] = {
{ ' 0 ' , " Start " } ,
{ ' 1 ' , " Interim update " } ,
{ ' 2 ' , " Stop " } ,
{ 0 , NULL }
} ;
2013-08-18 19:49:08 +00:00
static const value_string oktypenames [ ] = {
{ ' 0 ' , " Ok " } ,
{ ' 1 ' , " Version Supported " } ,
{ 0 , NULL }
} ;
2013-11-11 02:06:17 +00:00
static const string_string errortypenames [ ] = {
{ " E0 " , " Syntax error " } ,
{ " E1 " , " Syntax error " } ,
{ " E2 " , " Syntax error " } ,
{ " E3 " , " Unknown command " } ,
{ " E4 " , " Syntax error " } ,
{ " E5 " , " Out of memory " } ,
{ " E6 " , " <no description> " } ,
{ " E7 " , " Software error (can't create listener) " } ,
{ " E8 " , " Not Found " } ,
{ " E10 " , " Software error (can't create listener) " } ,
{ " E11 " , " Out of memory " } ,
{ " E12 " , " Out of memory " } ,
{ " E13 " , " Out of memory " } ,
{ " E14 " , " Out of memory " } ,
2013-08-18 19:49:08 +00:00
{ 0 , NULL }
} ;
static gint ett_rtpproxy = - 1 ;
static gint ett_rtpproxy_request = - 1 ;
static gint ett_rtpproxy_command = - 1 ;
2013-11-26 22:32:33 +00:00
static gint ett_rtpproxy_command_parameters = - 1 ;
static gint ett_rtpproxy_command_parameters_codecs = - 1 ;
static gint ett_rtpproxy_command_parameters_local = - 1 ;
static gint ett_rtpproxy_command_parameters_remote = - 1 ;
static gint ett_rtpproxy_command_parameters_repacketize = - 1 ;
static gint ett_rtpproxy_command_parameters_dtmf = - 1 ;
static gint ett_rtpproxy_command_parameters_cmap = - 1 ;
static gint ett_rtpproxy_command_parameters_proto = - 1 ;
static gint ett_rtpproxy_command_parameters_transcode = - 1 ;
static gint ett_rtpproxy_command_parameters_acc = - 1 ;
2013-08-18 19:49:08 +00:00
static gint ett_rtpproxy_tag = - 1 ;
static gint ett_rtpproxy_notify = - 1 ;
static gint ett_rtpproxy_reply = - 1 ;
2014-02-20 11:50:09 +00:00
static gint ett_rtpproxy_ng_bencode = - 1 ;
2013-11-28 14:11:48 +00:00
/* Default values */
2013-08-18 19:49:08 +00:00
static guint rtpproxy_tcp_port = 22222 ;
static guint rtpproxy_udp_port = 22222 ;
2013-11-26 22:05:33 +00:00
static gboolean rtpproxy_establish_conversation = TRUE ;
2013-12-20 20:31:40 +00:00
/* See - http://www.opensips.org/html/docs/modules/devel/rtpproxy.html#id250016 */
2013-11-28 14:11:48 +00:00
/* See - http://www.kamailio.org/docs/modules/devel/modules/rtpproxy.html#idm448 */
static guint rtpproxy_timeout = 1000 ;
static nstime_t rtpproxy_timeout_ns = { 1 , 0 } ;
2013-08-18 19:49:08 +00:00
void proto_reg_handoff_rtpproxy ( void ) ;
2013-12-12 06:11:05 +00:00
static gint
2013-11-25 22:25:03 +00:00
rtpproxy_add_tag ( proto_tree * rtpproxy_tree , tvbuff_t * tvb , guint begin , guint realsize )
2013-08-18 19:49:08 +00:00
{
proto_item * ti = NULL ;
proto_tree * another_tree = NULL ;
gint new_offset ;
guint end ;
new_offset = tvb_find_guint8 ( tvb , begin , - 1 , ' ' ) ;
if ( new_offset < 0 )
end = realsize ; /* No more parameters */
else
end = new_offset ;
/* SER/OpenSER/OpenSIPS/Kamailio adds Media-ID right after the Tag
* separated by a semicolon
*/
new_offset = tvb_find_guint8 ( tvb , begin , end , ' ; ' ) ;
if ( new_offset = = - 1 ) {
ti = proto_tree_add_item ( rtpproxy_tree , hf_rtpproxy_tag , tvb , begin , end - begin , ENC_ASCII | ENC_NA ) ;
another_tree = proto_item_add_subtree ( ti , ett_rtpproxy_tag ) ;
ti = proto_tree_add_item ( another_tree , hf_rtpproxy_mediaid , tvb , new_offset + 1 , 0 , ENC_ASCII | ENC_NA ) ;
2013-11-17 14:32:40 +00:00
proto_item_append_text ( ti , " <skipped> " ) ;
2013-12-15 16:17:08 +00:00
PROTO_ITEM_SET_GENERATED ( ti ) ;
2013-08-18 19:49:08 +00:00
}
else {
ti = proto_tree_add_item ( rtpproxy_tree , hf_rtpproxy_tag , tvb , begin , new_offset - begin , ENC_ASCII | ENC_NA ) ;
2013-12-15 16:17:08 +00:00
if ( ( guint ) new_offset = = begin ) {
2013-11-17 14:32:40 +00:00
proto_item_append_text ( ti , " <skipped> " ) ; /* A very first Offer/Update command */
2013-12-15 16:17:08 +00:00
PROTO_ITEM_SET_GENERATED ( ti ) ;
}
2013-08-18 19:49:08 +00:00
another_tree = proto_item_add_subtree ( ti , ett_rtpproxy_tag ) ;
proto_tree_add_item ( another_tree , hf_rtpproxy_mediaid , tvb , new_offset + 1 , end - ( new_offset + 1 ) , ENC_ASCII | ENC_NA ) ;
}
return ( end = = realsize ? - 1 : ( gint ) end ) ;
}
2013-12-12 06:11:05 +00:00
static void
2013-12-13 18:10:21 +00:00
rtpproxy_add_parameter ( tvbuff_t * tvb , packet_info * pinfo , proto_tree * rtpproxy_tree , guint begin , guint realsize )
2013-11-26 22:32:33 +00:00
{
proto_item * ti ;
proto_tree * another_tree = NULL ;
guint offset = 0 ;
guint new_offset = 0 ;
2013-11-27 08:09:55 +00:00
gint i ;
2013-11-26 22:40:52 +00:00
guint pt = 0 ;
2013-11-26 22:32:33 +00:00
gchar * * codecs = NULL ;
2013-11-26 22:54:25 +00:00
guint codec_len ;
2013-11-26 22:32:33 +00:00
guint8 * rawstr = NULL ;
2013-12-13 18:10:21 +00:00
guint32 ipaddr [ 4 ] ; /* Enough room for IPv4 or IPv6 */
2013-11-26 22:32:33 +00:00
/* Extract the entire parameters line. */
/* Something like "t4p1iic8,0,2,4,18,96,97,98,100,101" */
2014-06-17 15:30:58 +00:00
rawstr = tvb_get_string_enc ( wmem_packet_scope ( ) , tvb , begin , realsize , ENC_ASCII ) ;
2013-11-26 22:32:33 +00:00
while ( offset < realsize ) {
ti = proto_tree_add_item ( rtpproxy_tree , hf_rtpproxy_command_parameter , tvb , begin + offset , 1 , ENC_NA ) ;
offset + + ; /* Skip 1-byte parameter's type */
switch ( g_ascii_tolower ( tvb_get_guint8 ( tvb , begin + offset - 1 ) ) )
{
/* Official long parameters */
case ' c ' :
new_offset = ( gint ) strspn ( rawstr + offset , " 0123456789, " ) ;
another_tree = proto_item_add_subtree ( ti , ett_rtpproxy_command_parameters_codecs ) ;
2014-06-17 15:30:58 +00:00
codecs = g_strsplit ( tvb_get_string_enc ( wmem_packet_scope ( ) , tvb , begin + offset , new_offset , ENC_ASCII ) , " , " , 0 ) ;
2013-11-27 08:09:55 +00:00
i = 0 ;
2013-11-26 22:32:33 +00:00
while ( codecs [ i ] ) {
2013-11-26 22:54:25 +00:00
/* We assume strings < 2^32-1 bytes long. :-) */
codec_len = ( guint ) strlen ( codecs [ i ] ) ;
2013-12-26 15:42:06 +00:00
ti = proto_tree_add_uint ( another_tree , hf_rtpproxy_command_parameter_codec , tvb , begin + offset , codec_len ,
2014-06-17 15:30:58 +00:00
( guint16 ) g_ascii_strtoull ( ( gchar * ) tvb_get_string_enc ( wmem_packet_scope ( ) , tvb , begin + offset , codec_len , ENC_ASCII ) , NULL , 10 ) ) ;
2013-11-29 22:56:34 +00:00
proto_item_append_text ( ti , " (%s) " , val_to_str_ext ( ( guint ) strtoul ( tvb_format_text ( tvb , begin + offset , codec_len ) , NULL , 10 ) , & rtp_payload_type_vals_ext , " Unknown " ) ) ;
2013-11-26 22:54:25 +00:00
offset + = codec_len ;
2013-11-26 22:32:33 +00:00
if ( codecs [ i + 1 ] )
offset + + ; /* skip comma */
i + + ;
} ;
g_strfreev ( codecs ) ;
break ;
case ' l ' :
new_offset = ( gint ) strspn ( rawstr + offset , " 0123456789. " ) ;
another_tree = proto_item_add_subtree ( ti , ett_rtpproxy_command_parameters_local ) ;
2014-06-17 15:30:58 +00:00
if ( str_to_ip ( ( char * ) tvb_get_string_enc ( wmem_packet_scope ( ) , tvb , begin + offset , new_offset , ENC_ASCII ) , ipaddr ) )
2013-12-13 18:10:21 +00:00
proto_tree_add_ipv4 ( another_tree , hf_rtpproxy_command_parameter_local_ipv4 , tvb , begin + offset , new_offset , ipaddr [ 0 ] ) ;
else
proto_tree_add_expert ( another_tree , pinfo , & ei_rtpproxy_bad_ipv4 , tvb , begin + offset , new_offset ) ;
2013-11-26 22:32:33 +00:00
offset + = new_offset ;
break ;
case ' r ' :
new_offset = ( gint ) strspn ( rawstr + offset , " 0123456789. " ) ;
another_tree = proto_item_add_subtree ( ti , ett_rtpproxy_command_parameters_remote ) ;
2014-06-17 15:30:58 +00:00
if ( str_to_ip ( ( char * ) tvb_get_string_enc ( wmem_packet_scope ( ) , tvb , begin + offset , new_offset , ENC_ASCII ) , ipaddr ) )
2013-12-13 18:10:21 +00:00
proto_tree_add_ipv4 ( another_tree , hf_rtpproxy_command_parameter_remote_ipv4 , tvb , begin + offset , new_offset , ipaddr [ 0 ] ) ;
else
proto_tree_add_expert ( another_tree , pinfo , & ei_rtpproxy_bad_ipv4 , tvb , begin + offset , new_offset ) ;
2013-11-26 22:32:33 +00:00
offset + = new_offset ;
break ;
case ' z ' :
new_offset = ( gint ) strspn ( rawstr + offset , " 0123456789 " ) ;
another_tree = proto_item_add_subtree ( ti , ett_rtpproxy_command_parameters_repacketize ) ;
2013-12-26 15:42:06 +00:00
proto_tree_add_uint ( another_tree , hf_rtpproxy_command_parameter_repacketize , tvb , begin + offset , new_offset ,
2014-06-17 15:30:58 +00:00
( guint16 ) g_ascii_strtoull ( ( gchar * ) tvb_get_string_enc ( wmem_packet_scope ( ) , tvb , begin + offset , new_offset , ENC_ASCII ) , NULL , 10 ) ) ;
2013-11-26 22:32:33 +00:00
offset + = new_offset ;
break ;
/* Unofficial long parameters */
case ' d ' :
new_offset = ( gint ) strspn ( rawstr + offset , " 0123456789 " ) ;
another_tree = proto_item_add_subtree ( ti , ett_rtpproxy_command_parameters_dtmf ) ;
2013-12-26 15:42:06 +00:00
proto_tree_add_uint ( another_tree , hf_rtpproxy_command_parameter_dtmf , tvb , begin + offset , new_offset ,
2014-06-17 15:30:58 +00:00
( guint16 ) g_ascii_strtoull ( ( gchar * ) tvb_get_string_enc ( wmem_packet_scope ( ) , tvb , begin + offset , new_offset , ENC_ASCII ) , NULL , 10 ) ) ;
2013-11-26 22:40:52 +00:00
if ( rtpproxy_establish_conversation ) {
pt = ( guint ) strtoul ( tvb_format_text ( tvb , begin + offset , new_offset ) , NULL , 10 ) ;
dissector_add_uint ( " rtp.pt " , pt , rtp_events_handle ) ;
}
2013-11-26 22:32:33 +00:00
offset + = new_offset ;
break ;
case ' m ' :
new_offset = ( gint ) strspn ( rawstr + offset , " 0123456789=, " ) ;
/* TODO */
offset + = new_offset ;
break ;
case ' p ' :
another_tree = proto_item_add_subtree ( ti , ett_rtpproxy_command_parameters_proto ) ;
proto_tree_add_item ( another_tree , hf_rtpproxy_command_parameter_proto , tvb , begin + offset , 1 , ENC_NA ) ;
offset + + ;
break ;
case ' t ' :
new_offset = ( gint ) strspn ( rawstr + offset , " 0123456789 " ) ;
another_tree = proto_item_add_subtree ( ti , ett_rtpproxy_command_parameters_transcode ) ;
2013-12-26 15:42:06 +00:00
ti = proto_tree_add_uint ( another_tree , hf_rtpproxy_command_parameter_transcode , tvb , begin + offset , new_offset ,
2014-06-17 15:30:58 +00:00
( guint16 ) g_ascii_strtoull ( ( gchar * ) tvb_get_string_enc ( wmem_packet_scope ( ) , tvb , begin + offset , new_offset , ENC_ASCII ) , NULL , 10 ) ) ;
2013-11-29 22:56:34 +00:00
proto_item_append_text ( ti , " (%s) " , val_to_str_ext ( ( guint ) strtoul ( tvb_format_text ( tvb , begin + offset , new_offset ) , NULL , 10 ) , & rtp_payload_type_vals_ext , " Unknown " ) ) ;
2013-11-26 22:32:33 +00:00
offset + = new_offset ;
break ;
case ' v ' :
another_tree = proto_item_add_subtree ( ti , ett_rtpproxy_command_parameters_acc ) ;
proto_tree_add_item ( another_tree , hf_rtpproxy_command_parameter_acc , tvb , begin + offset , 1 , ENC_NA ) ;
offset + + ;
break ;
default :
break ;
}
}
}
2013-12-12 06:11:05 +00:00
static rtpproxy_info_t *
2013-10-02 16:37:10 +00:00
rtpproxy_add_tid ( gboolean is_request , tvbuff_t * tvb , packet_info * pinfo , proto_tree * rtpproxy_tree , rtpproxy_conv_info_t * rtpproxy_conv , gchar * cookie )
{
rtpproxy_info_t * rtpproxy_info ;
proto_item * pi ;
if ( ! PINFO_FD_VISITED ( pinfo ) ) {
if ( is_request ) {
rtpproxy_info = wmem_new ( wmem_file_scope ( ) , rtpproxy_info_t ) ;
rtpproxy_info - > req_frame = PINFO_FD_NUM ( pinfo ) ;
rtpproxy_info - > resp_frame = 0 ;
2013-11-06 20:39:10 +00:00
rtpproxy_info - > req_time = pinfo - > fd - > abs_ts ;
2013-11-30 09:50:04 +00:00
rtpproxy_info - > callid = NULL ;
2013-10-02 16:37:10 +00:00
wmem_tree_insert_string ( rtpproxy_conv - > trans , cookie , rtpproxy_info , 0 ) ;
} else {
rtpproxy_info = ( rtpproxy_info_t * ) wmem_tree_lookup_string ( rtpproxy_conv - > trans , cookie , 0 ) ;
if ( rtpproxy_info ) {
rtpproxy_info - > resp_frame = PINFO_FD_NUM ( pinfo ) ;
}
}
} else {
rtpproxy_info = ( rtpproxy_info_t * ) wmem_tree_lookup_string ( rtpproxy_conv - > trans , cookie , 0 ) ;
if ( rtpproxy_info & & ( is_request ? rtpproxy_info - > resp_frame : rtpproxy_info - > req_frame ) ) {
2013-11-06 20:39:10 +00:00
nstime_t ns ;
2013-10-02 16:37:10 +00:00
pi = proto_tree_add_uint ( rtpproxy_tree , is_request ? hf_rtpproxy_response_in : hf_rtpproxy_request_in , tvb , 0 , 0 , is_request ? rtpproxy_info - > resp_frame : rtpproxy_info - > req_frame ) ;
PROTO_ITEM_SET_GENERATED ( pi ) ;
2013-11-06 20:39:10 +00:00
/* If reply then calculate response time */
if ( ! is_request ) {
nstime_delta ( & ns , & pinfo - > fd - > abs_ts , & rtpproxy_info - > req_time ) ;
pi = proto_tree_add_time ( rtpproxy_tree , hf_rtpproxy_response_time , tvb , 0 , 0 , & ns ) ;
PROTO_ITEM_SET_GENERATED ( pi ) ;
2013-11-28 14:11:48 +00:00
if ( nstime_cmp ( & rtpproxy_timeout_ns , & ns ) < 0 )
2013-12-03 10:54:10 +00:00
expert_add_info_format ( pinfo , rtpproxy_tree , & ei_rtpproxy_timeout , " Response timeout %.3f seconds " , nstime_to_sec ( & ns ) ) ;
2013-11-06 20:39:10 +00:00
}
2013-10-02 16:37:10 +00:00
}
}
2013-11-30 09:50:04 +00:00
/* Could be NULL so we should check it before dereferencing */
return rtpproxy_info ;
2013-10-02 16:37:10 +00:00
}
2013-12-12 06:11:05 +00:00
static void
2013-12-13 18:10:21 +00:00
rtpproxy_add_notify_addr ( tvbuff_t * tvb , packet_info * pinfo , proto_tree * rtpproxy_tree , guint begin , guint end )
2013-11-17 13:59:06 +00:00
{
2013-11-17 14:48:55 +00:00
gint offset = 0 ;
gint tmp = 0 ;
gboolean ipv6 = FALSE ;
2013-12-13 18:10:21 +00:00
guint32 ipaddr [ 4 ] ; /* Enough room for IPv4 or IPv6 */
2013-11-17 13:59:06 +00:00
proto_item * ti ;
2013-11-17 14:48:55 +00:00
/* Check for at least one colon */
offset = tvb_find_guint8 ( tvb , begin , end , ' : ' ) ;
if ( offset ! = - 1 ) {
/* Find if it's the latest colon (not in case of a IPv6) */
while ( ( tmp = tvb_find_guint8 ( tvb , offset + 1 , end , ' : ' ) ) ! = - 1 ) {
ipv6 = TRUE ;
offset = tmp ;
}
/* We have ip:port */
2013-12-13 18:10:21 +00:00
if ( ipv6 ) {
2014-06-17 15:30:58 +00:00
if ( str_to_ip6 ( ( char * ) tvb_get_string_enc ( wmem_packet_scope ( ) , tvb , begin , offset - begin , ENC_ASCII ) , ipaddr ) )
2013-12-13 18:10:21 +00:00
proto_tree_add_ipv6 ( rtpproxy_tree , hf_rtpproxy_notify_ipv6 , tvb , begin , offset - begin , ( const guint8 * ) ipaddr ) ;
else
proto_tree_add_expert ( rtpproxy_tree , pinfo , & ei_rtpproxy_bad_ipv6 , tvb , begin , offset - begin ) ;
}
else {
2014-06-17 15:30:58 +00:00
if ( str_to_ip ( ( char * ) tvb_get_string_enc ( wmem_packet_scope ( ) , tvb , begin , offset - begin , ENC_ASCII ) , ipaddr ) )
2013-12-13 18:10:21 +00:00
proto_tree_add_ipv4 ( rtpproxy_tree , hf_rtpproxy_notify_ipv4 , tvb , begin , offset - begin , ipaddr [ 0 ] ) ;
else
proto_tree_add_expert ( rtpproxy_tree , pinfo , & ei_rtpproxy_bad_ipv4 , tvb , begin , offset - begin ) ;
}
2013-12-26 15:42:06 +00:00
proto_tree_add_uint ( rtpproxy_tree , hf_rtpproxy_notify_port , tvb , offset + 1 , end - ( offset + 1 ) ,
2014-06-17 15:30:58 +00:00
( guint16 ) g_ascii_strtoull ( ( gchar * ) tvb_get_string_enc ( wmem_packet_scope ( ) , tvb , offset + 1 , end - ( offset + 1 ) , ENC_ASCII ) , NULL , 10 ) ) ;
2013-11-17 14:48:55 +00:00
}
else {
2013-12-13 18:10:21 +00:00
/* Only port is supplied - take IPv4/IPv6 from ip.src/ipv6.src respectively */
2013-12-20 20:31:40 +00:00
expert_add_info ( pinfo , rtpproxy_tree , & ei_rtpproxy_notify_no_ip ) ;
2013-12-13 18:10:21 +00:00
if ( pinfo - > src . type = = AT_IPv4 )
ti = proto_tree_add_ipv4 ( rtpproxy_tree , hf_rtpproxy_notify_ipv4 , tvb , begin , 0 , ( ( guint32 * ) ( pinfo - > src . data ) ) [ 0 ] ) ;
else
ti = proto_tree_add_ipv6 ( rtpproxy_tree , hf_rtpproxy_notify_ipv6 , tvb , begin , 0 , ( const guint8 * ) ( pinfo - > src . data ) ) ;
2013-12-15 16:17:08 +00:00
PROTO_ITEM_SET_GENERATED ( ti ) ;
2013-12-26 15:42:06 +00:00
proto_tree_add_uint ( rtpproxy_tree , hf_rtpproxy_notify_port , tvb , begin , end - begin ,
2014-06-17 15:30:58 +00:00
( guint16 ) g_ascii_strtoull ( ( gchar * ) tvb_get_string_enc ( wmem_packet_scope ( ) , tvb , begin , end - begin , ENC_ASCII ) , NULL , 10 ) ) ;
2013-11-17 13:59:06 +00:00
}
}
2013-10-09 20:14:12 +00:00
static int
dissect_rtpproxy ( tvbuff_t * tvb , packet_info * pinfo , proto_tree * tree , void * data _U_ )
2013-08-18 19:49:08 +00:00
{
gboolean has_lf = FALSE ;
2013-10-09 20:30:18 +00:00
gint offset = 0 ;
2013-08-18 19:49:08 +00:00
gint new_offset = 0 ;
guint tmp ;
2014-02-20 11:50:09 +00:00
guint tmp2 ;
2013-10-09 20:30:18 +00:00
gint realsize = 0 ;
2013-08-18 19:49:08 +00:00
guint8 * rawstr ;
2013-11-11 02:06:17 +00:00
guint8 * tmpstr ;
2013-08-18 19:49:08 +00:00
proto_item * ti ;
2013-11-26 22:32:33 +00:00
proto_item * ti2 ;
2013-08-18 19:49:08 +00:00
proto_tree * rtpproxy_tree ;
2013-10-02 16:37:10 +00:00
conversation_t * conversation ;
rtpproxy_conv_info_t * rtpproxy_conv ;
gchar * cookie = NULL ;
2013-11-26 22:05:33 +00:00
/* For RT(C)P setup */
address addr ;
guint16 port ;
2013-12-13 18:10:21 +00:00
guint32 ipaddr [ 4 ] ; /* Enough room for IPv4 or IPv6 */
2013-11-30 09:50:04 +00:00
rtpproxy_info_t * rtpproxy_info = NULL ;
2014-02-20 11:50:09 +00:00
tvbuff_t * subtvb ;
2013-08-18 19:49:08 +00:00
2013-10-09 20:14:12 +00:00
/* If it does not start with a printable character it's not RTPProxy */
if ( ! isprint ( tvb_get_guint8 ( tvb , 0 ) ) )
return 0 ;
/* Extract Cookie */
offset = tvb_find_guint8 ( tvb , offset , - 1 , ' ' ) ;
if ( offset = = - 1 )
return 0 ;
2013-08-18 19:49:08 +00:00
/* Clear out stuff in the info column - we''l set it later */
col_clear ( pinfo - > cinfo , COL_INFO ) ;
ti = proto_tree_add_item ( tree , proto_rtpproxy , tvb , 0 , - 1 , ENC_NA ) ;
rtpproxy_tree = proto_item_add_subtree ( ti , ett_rtpproxy ) ;
2013-08-19 19:59:52 +00:00
proto_tree_add_item ( rtpproxy_tree , hf_rtpproxy_cookie , tvb , 0 , offset , ENC_ASCII | ENC_NA ) ;
2014-06-17 15:30:58 +00:00
cookie = tvb_get_string_enc ( wmem_packet_scope ( ) , tvb , 0 , offset , ENC_ASCII ) ;
2013-08-18 19:49:08 +00:00
/* Skip whitespace */
offset = tvb_skip_wsp ( tvb , offset + 1 , - 1 ) ;
/* Calculate size to prevent recalculation in the future */
realsize = tvb_reported_length ( tvb ) ;
2013-11-30 09:50:04 +00:00
2013-08-18 19:49:08 +00:00
/* Check for LF (required for TCP connection, optional for UDP) */
if ( tvb_get_guint8 ( tvb , realsize - 1 ) = = ' \n ' ) {
col_set_str ( pinfo - > cinfo , COL_PROTOCOL , " RTPproxy " ) ;
/* Don't count trailing LF */
realsize - = 1 ;
has_lf = TRUE ;
}
else
2013-12-20 20:31:40 +00:00
col_set_str ( pinfo - > cinfo , COL_PROTOCOL , " RTPproxy (no LF) " ) ; /* FIXME replace with expert info field */
2013-08-18 19:49:08 +00:00
2013-11-30 09:50:04 +00:00
2013-10-02 16:37:10 +00:00
/* Try to create conversation */
conversation = find_or_create_conversation ( pinfo ) ;
rtpproxy_conv = ( rtpproxy_conv_info_t * ) conversation_get_proto_data ( conversation , proto_rtpproxy ) ;
if ( ! rtpproxy_conv ) {
rtpproxy_conv = wmem_new ( wmem_file_scope ( ) , rtpproxy_conv_info_t ) ;
rtpproxy_conv - > trans = wmem_tree_new ( wmem_file_scope ( ) ) ;
conversation_add_proto_data ( conversation , proto_rtpproxy , rtpproxy_conv ) ;
}
2013-08-18 19:49:08 +00:00
/* Get payload string */
2014-06-17 15:30:58 +00:00
rawstr = tvb_get_string_enc ( wmem_packet_scope ( ) , tvb , offset , realsize - offset , ENC_ASCII ) ;
2013-08-18 19:49:08 +00:00
/* Extract command */
tmp = g_ascii_tolower ( tvb_get_guint8 ( tvb , offset ) ) ;
switch ( tmp )
{
case ' s ' :
/* A specific case - long statistics answer */
/* %COOKIE% sessions created %NUM0% active sessions: %NUM1% */
2013-10-02 16:37:10 +00:00
rtpproxy_add_tid ( FALSE , tvb , pinfo , rtpproxy_tree , rtpproxy_conv , cookie ) ;
2013-08-18 19:49:08 +00:00
if ( ' e ' = = tvb_get_guint8 ( tvb , offset + 1 ) ) {
col_add_fstr ( pinfo - > cinfo , COL_INFO , " Reply: %s " , rawstr ) ;
ti = proto_tree_add_item ( rtpproxy_tree , hf_rtpproxy_reply , tvb , offset , - 1 , ENC_NA ) ;
rtpproxy_tree = proto_item_add_subtree ( ti , ett_rtpproxy_reply ) ;
2013-10-02 17:33:19 +00:00
proto_tree_add_item ( rtpproxy_tree , hf_rtpproxy_status , tvb , offset , realsize - offset , ENC_ASCII | ENC_NA ) ;
2013-08-18 19:49:08 +00:00
break ;
}
case ' i ' :
case ' x ' :
case ' u ' :
case ' l ' :
case ' d ' :
2014-02-20 11:50:09 +00:00
tmp2 = tvb_get_guint8 ( tvb , offset + 1 ) ;
if ( ( ' 1 ' < = tmp2 ) & & ( tmp2 < = ' 9 ' ) & & ( tvb_get_guint8 ( tvb , offset + 2 ) = = ' : ' ) ) {
col_add_fstr ( pinfo - > cinfo , COL_INFO , " RTPproxy-ng: %s " , rawstr ) ;
ti = proto_tree_add_item ( rtpproxy_tree , hf_rtpproxy_ng_bencode , tvb , offset , - 1 , ENC_ASCII | ENC_NA ) ;
rtpproxy_tree = proto_item_add_subtree ( ti , ett_rtpproxy_ng_bencode ) ;
2014-06-01 18:38:24 +00:00
subtvb = tvb_new_subset_remaining ( tvb , offset ) ;
2014-02-20 11:50:09 +00:00
call_dissector ( bencode_handle , subtvb , pinfo , rtpproxy_tree ) ;
break ;
}
2013-08-18 19:49:08 +00:00
case ' p ' :
case ' v ' :
case ' r ' :
case ' c ' :
case ' q ' :
2013-11-30 09:50:04 +00:00
rtpproxy_info = rtpproxy_add_tid ( TRUE , tvb , pinfo , rtpproxy_tree , rtpproxy_conv , cookie ) ;
2013-08-18 19:49:08 +00:00
col_add_fstr ( pinfo - > cinfo , COL_INFO , " Request: %s " , rawstr ) ;
ti = proto_tree_add_item ( rtpproxy_tree , hf_rtpproxy_request , tvb , offset , - 1 , ENC_NA ) ;
rtpproxy_tree = proto_item_add_subtree ( ti , ett_rtpproxy_request ) ;
/* A specific case - version request */
2013-10-09 22:30:59 +00:00
if ( ( tmp = = ' v ' ) & & ( offset + ( gint ) strlen ( " VF YYYMMDD " ) + 1 = = realsize ) ) {
2013-08-18 19:49:08 +00:00
/* Skip whitespace */
2013-08-18 20:09:05 +00:00
new_offset = tvb_skip_wsp ( tvb , offset + ( ( guint ) strlen ( " VF " ) + 1 ) , - 1 ) ;
2013-11-11 22:15:30 +00:00
ti = proto_tree_add_item ( rtpproxy_tree , hf_rtpproxy_version_request , tvb , new_offset , ( gint ) strlen ( " YYYYMMDD " ) , ENC_ASCII | ENC_NA ) ;
2014-06-17 15:30:58 +00:00
tmpstr = tvb_get_string_enc ( wmem_packet_scope ( ) , tvb , new_offset , ( gint ) strlen ( " YYYYMMDD " ) , ENC_ASCII ) ;
2013-11-11 22:15:30 +00:00
proto_item_append_text ( ti , " (%s) " , str_to_str ( tmpstr , versiontypenames , " Unknown " ) ) ;
2013-08-18 19:49:08 +00:00
break ;
}
/* All other commands */
ti = proto_tree_add_item ( rtpproxy_tree , hf_rtpproxy_command , tvb , offset , 1 , ENC_NA ) ;
/* A specific case - handshake/ping */
if ( tmp = = ' v ' )
break ; /* No more parameters */
/* A specific case - close all calls */
if ( tmp = = ' x ' )
break ; /* No more parameters */
/* Extract parameters */
/* Parameters should be right after the command and before EOL (in case of Info command) or before whitespace */
2013-10-09 20:30:18 +00:00
new_offset = ( tmp = = ' i ' ? ( realsize - 1 > offset ? offset + ( gint ) strlen ( " Ib " ) : offset + ( gint ) strlen ( " I " ) ) : tvb_find_guint8 ( tvb , offset , - 1 , ' ' ) ) ;
2013-08-18 19:49:08 +00:00
2013-10-09 20:30:18 +00:00
if ( new_offset ! = offset + 1 ) {
2013-08-18 19:49:08 +00:00
rtpproxy_tree = proto_item_add_subtree ( ti , ett_rtpproxy_command ) ;
2013-11-26 22:32:33 +00:00
ti2 = proto_tree_add_item ( rtpproxy_tree , hf_rtpproxy_command_parameters , tvb , offset + 1 , new_offset - ( offset + 1 ) , ENC_ASCII | ENC_NA ) ;
2013-12-13 18:10:21 +00:00
rtpproxy_add_parameter ( tvb , pinfo , proto_item_add_subtree ( ti2 , ett_rtpproxy_command_parameters ) , offset + 1 , new_offset - ( offset + 1 ) ) ;
2013-08-18 19:49:08 +00:00
rtpproxy_tree = proto_item_get_parent ( ti ) ;
}
/* A specific case - query information */
if ( tmp = = ' i ' )
break ; /* No more parameters */
/* Skip whitespace */
offset = tvb_skip_wsp ( tvb , new_offset + 1 , - 1 ) ;
/* Extract Call-ID */
new_offset = tvb_find_guint8 ( tvb , offset , - 1 , ' ' ) ;
proto_tree_add_item ( rtpproxy_tree , hf_rtpproxy_callid , tvb , offset , new_offset - offset , ENC_ASCII | ENC_NA ) ;
2013-11-30 09:50:04 +00:00
if ( rtpproxy_info & & ! rtpproxy_info - > callid )
2014-06-17 15:30:58 +00:00
rtpproxy_info - > callid = tvb_get_string_enc ( wmem_file_scope ( ) , tvb , offset , new_offset - offset , ENC_ASCII ) ;
2013-08-18 19:49:08 +00:00
/* Skip whitespace */
offset = tvb_skip_wsp ( tvb , new_offset + 1 , - 1 ) ;
/* Extract IP and Port in case of Offer/Answer */
if ( ( tmp = = ' u ' ) | | ( tmp = = ' l ' ) ) {
/* Extract IP */
new_offset = tvb_find_guint8 ( tvb , offset , - 1 , ' ' ) ;
2013-12-13 18:10:21 +00:00
if ( tvb_find_guint8 ( tvb , offset , new_offset - offset , ' : ' ) = = - 1 ) {
2014-06-17 15:30:58 +00:00
if ( str_to_ip ( ( char * ) tvb_get_string_enc ( wmem_packet_scope ( ) , tvb , offset , new_offset - offset , ENC_ASCII ) , ipaddr ) )
2013-12-13 18:10:21 +00:00
proto_tree_add_ipv4 ( rtpproxy_tree , hf_rtpproxy_ipv4 , tvb , offset , new_offset - offset , ipaddr [ 0 ] ) ;
else
proto_tree_add_expert ( rtpproxy_tree , pinfo , & ei_rtpproxy_bad_ipv4 , tvb , offset , new_offset - offset ) ;
}
else {
2014-06-17 15:30:58 +00:00
if ( str_to_ip6 ( ( char * ) tvb_get_string_enc ( wmem_packet_scope ( ) , tvb , offset , new_offset - offset , ENC_ASCII ) , ipaddr ) )
2013-12-13 18:10:21 +00:00
proto_tree_add_ipv6 ( rtpproxy_tree , hf_rtpproxy_ipv6 , tvb , offset , new_offset - offset , ( const guint8 * ) ipaddr ) ;
else
proto_tree_add_expert ( rtpproxy_tree , pinfo , & ei_rtpproxy_bad_ipv6 , tvb , offset , new_offset - offset ) ;
}
2013-08-18 19:49:08 +00:00
/* Skip whitespace */
offset = tvb_skip_wsp ( tvb , new_offset + 1 , - 1 ) ;
/* Extract Port */
new_offset = tvb_find_guint8 ( tvb , offset , - 1 , ' ' ) ;
2013-12-26 15:42:06 +00:00
proto_tree_add_uint ( rtpproxy_tree , hf_rtpproxy_port , tvb , offset , new_offset - offset ,
2014-06-17 15:30:58 +00:00
( guint16 ) g_ascii_strtoull ( ( gchar * ) tvb_get_string_enc ( wmem_packet_scope ( ) , tvb , offset , new_offset - offset , ENC_ASCII ) , NULL , 10 ) ) ;
2013-08-18 19:49:08 +00:00
/* Skip whitespace */
offset = tvb_skip_wsp ( tvb , new_offset + 1 , - 1 ) ;
}
/* Extract Copy target */
if ( tmp = = ' c ' ) {
new_offset = tvb_find_guint8 ( tvb , offset , - 1 , ' ' ) ;
proto_tree_add_item ( rtpproxy_tree , hf_rtpproxy_copy_target , tvb , offset , new_offset - offset , ENC_ASCII | ENC_NA ) ;
/* Skip whitespace */
offset = tvb_skip_wsp ( tvb , new_offset + 1 , - 1 ) ;
}
/* Extract Playback file and codecs */
if ( tmp = = ' p ' ) {
/* Extract filename */
new_offset = tvb_find_guint8 ( tvb , offset , - 1 , ' ' ) ;
proto_tree_add_item ( rtpproxy_tree , hf_rtpproxy_playback_filename , tvb , offset , new_offset - offset , ENC_ASCII | ENC_NA ) ;
/* Skip whitespace */
offset = tvb_skip_wsp ( tvb , new_offset + 1 , - 1 ) ;
/* Extract codec */
new_offset = tvb_find_guint8 ( tvb , offset , - 1 , ' ' ) ;
2013-12-26 15:42:06 +00:00
proto_tree_add_uint ( rtpproxy_tree , hf_rtpproxy_playback_codec , tvb , offset , new_offset - offset ,
2014-06-17 15:30:58 +00:00
( guint16 ) g_ascii_strtoull ( ( gchar * ) tvb_get_string_enc ( wmem_packet_scope ( ) , tvb , offset , new_offset - offset , ENC_ASCII ) , NULL , 10 ) ) ;
2013-08-18 19:49:08 +00:00
/* Skip whitespace */
offset = tvb_skip_wsp ( tvb , new_offset + 1 , - 1 ) ;
}
/* Extract first tag */
2013-11-25 22:25:03 +00:00
new_offset = rtpproxy_add_tag ( rtpproxy_tree , tvb , offset , realsize ) ;
2013-08-18 19:49:08 +00:00
if ( new_offset = = - 1 )
break ; /* No more parameters */
/* Skip whitespace */
offset = tvb_skip_wsp ( tvb , new_offset + 1 , - 1 ) ;
/* Extract second tag */
2013-11-25 22:25:03 +00:00
new_offset = rtpproxy_add_tag ( rtpproxy_tree , tvb , offset , realsize ) ;
2013-08-18 19:49:08 +00:00
if ( new_offset = = - 1 )
break ; /* No more parameters */
/* Skip whitespace */
offset = tvb_skip_wsp ( tvb , new_offset + 1 , - 1 ) ;
/* Extract Notification address */
if ( tmp = = ' u ' ) {
2013-10-02 17:33:19 +00:00
ti = proto_tree_add_item ( rtpproxy_tree , hf_rtpproxy_notify , tvb , offset , realsize - offset , ENC_ASCII | ENC_NA ) ;
2013-08-18 19:49:08 +00:00
proto_item_set_text ( ti , " Notify " ) ;
rtpproxy_tree = proto_item_add_subtree ( ti , ett_rtpproxy_notify ) ;
2013-11-17 13:59:06 +00:00
/* Check for NotifyTag parameter (separated by space) */
new_offset = tvb_find_guint8 ( tvb , offset , - 1 , ' ' ) ;
2013-08-18 19:49:08 +00:00
if ( new_offset = = - 1 ) {
2013-11-17 13:59:06 +00:00
/* NotifyTag wasn't found (we should re-use Call-ID instead) */
2013-12-13 18:10:21 +00:00
rtpproxy_add_notify_addr ( tvb , pinfo , rtpproxy_tree , offset , realsize ) ;
2013-08-18 19:49:08 +00:00
break ; /* No more parameters */
}
2013-11-17 13:59:06 +00:00
/* NotifyTag was found */
2013-12-13 18:10:21 +00:00
rtpproxy_add_notify_addr ( tvb , pinfo , rtpproxy_tree , offset , new_offset ) ;
2013-08-18 19:49:08 +00:00
/* Skip whitespace */
offset = tvb_skip_wsp ( tvb , new_offset + 1 , - 1 ) ;
proto_tree_add_item ( rtpproxy_tree , hf_rtpproxy_notify_tag , tvb , offset , realsize - offset , ENC_ASCII | ENC_NA ) ;
}
break ;
case ' a ' :
case ' e ' :
case ' 0 ' :
case ' 1 ' :
case ' 2 ' :
case ' 3 ' :
case ' 4 ' :
case ' 5 ' :
case ' 6 ' :
case ' 7 ' :
case ' 8 ' :
case ' 9 ' :
2013-11-30 09:50:04 +00:00
rtpproxy_info = rtpproxy_add_tid ( FALSE , tvb , pinfo , rtpproxy_tree , rtpproxy_conv , cookie ) ;
2013-08-18 19:49:08 +00:00
if ( tmp = = ' e ' )
col_add_fstr ( pinfo - > cinfo , COL_INFO , " Error reply: %s " , rawstr ) ;
else
col_add_fstr ( pinfo - > cinfo , COL_INFO , " Reply: %s " , rawstr ) ;
ti = proto_tree_add_item ( rtpproxy_tree , hf_rtpproxy_reply , tvb , offset , - 1 , ENC_NA ) ;
rtpproxy_tree = proto_item_add_subtree ( ti , ett_rtpproxy_reply ) ;
2013-11-30 09:50:04 +00:00
if ( rtpproxy_info & & rtpproxy_info - > callid ) {
ti = proto_tree_add_string ( rtpproxy_tree , hf_rtpproxy_callid , tvb , offset , 0 , rtpproxy_info - > callid ) ;
PROTO_ITEM_SET_GENERATED ( ti ) ;
}
2013-08-18 19:49:08 +00:00
if ( tmp = = ' e ' ) {
2013-11-11 02:06:17 +00:00
tmp = tvb_find_line_end ( tvb , offset , - 1 , & new_offset , FALSE ) ;
2014-06-17 15:30:58 +00:00
tmpstr = tvb_get_string_enc ( wmem_packet_scope ( ) , tvb , offset , tmp , ENC_ASCII ) ;
2013-11-11 22:15:30 +00:00
ti = proto_tree_add_item ( rtpproxy_tree , hf_rtpproxy_error , tvb , offset , ( gint ) strlen ( tmpstr ) , ENC_ASCII | ENC_NA ) ;
proto_item_append_text ( ti , " (%s) " , str_to_str ( tmpstr , errortypenames , " Unknown " ) ) ;
2013-08-18 19:49:08 +00:00
break ;
}
if ( tmp = = ' a ' ) {
/* A specific case - short statistics answer */
/* %COOKIE% active sessions: %NUM1% */
2013-10-02 17:33:19 +00:00
proto_tree_add_item ( rtpproxy_tree , hf_rtpproxy_status , tvb , offset , realsize - offset , ENC_ASCII | ENC_NA ) ;
2013-08-18 19:49:08 +00:00
break ;
}
2013-10-09 22:30:59 +00:00
if ( ( tmp = = ' 0 ' ) & & ( ( tvb_reported_length ( tvb ) = = ( guint ) ( offset + 1 ) ) | | ( tvb_reported_length ( tvb ) = = ( guint ) ( offset + 2 ) ) ) ) {
2013-08-18 19:49:08 +00:00
proto_tree_add_item ( rtpproxy_tree , hf_rtpproxy_ok , tvb , offset , 1 , ENC_ASCII | ENC_NA ) ;
break ;
}
2013-10-09 22:30:59 +00:00
if ( ( tmp = = ' 1 ' ) & & ( ( tvb_reported_length ( tvb ) = = ( guint ) ( offset + 1 ) ) | | ( tvb_reported_length ( tvb ) = = ( guint ) ( offset + 2 ) ) ) ) {
2013-08-18 19:49:08 +00:00
proto_tree_add_item ( rtpproxy_tree , hf_rtpproxy_ok , tvb , offset , 1 , ENC_ASCII | ENC_NA ) ;
break ;
}
2013-10-09 22:30:59 +00:00
if ( tvb_reported_length ( tvb ) = = ( guint ) ( offset + 9 ) ) {
2013-08-18 19:49:08 +00:00
proto_tree_add_item ( rtpproxy_tree , hf_rtpproxy_version_supported , tvb , offset , 8 , ENC_ASCII | ENC_NA ) ;
break ;
}
/* Extract Port */
new_offset = tvb_find_guint8 ( tvb , offset , - 1 , ' ' ) ;
2013-11-26 22:05:33 +00:00
/* Convert port to unsigned 16-bit number */
2014-06-17 15:30:58 +00:00
port = ( guint16 ) g_ascii_strtoull ( ( gchar * ) tvb_get_string_enc ( wmem_packet_scope ( ) , tvb , offset , new_offset - offset , ENC_ASCII ) , NULL , 10 ) ;
2013-12-26 15:42:06 +00:00
proto_tree_add_uint ( rtpproxy_tree , hf_rtpproxy_port , tvb , offset , new_offset - offset , port ) ;
2013-08-18 19:49:08 +00:00
/* Skip whitespace */
offset = tvb_skip_wsp ( tvb , new_offset + 1 , - 1 ) ;
/* Extract IP */
2013-12-13 18:10:21 +00:00
memset ( & addr , 0 , sizeof ( address ) ) ;
2014-05-14 12:03:09 +00:00
/* Try rtpengine bogus extension first. It appends 4 or
* 6 depending on type of the IP . See
* https : //github.com/sipwise/rtpengine/blob/master/daemon/call_interfaces.c#L66
* for further details */
tmp = tvb_find_guint8 ( tvb , offset , - 1 , ' ' ) ;
2014-05-21 03:01:49 +00:00
if ( tmp = = ( guint ) ( - 1 ) ) {
2014-05-14 12:03:09 +00:00
/* No extension - operate normally */
tmp = tvb_find_line_end ( tvb , offset , - 1 , & new_offset , FALSE ) ;
}
else {
tmp - = offset ;
}
2013-11-26 22:05:33 +00:00
if ( tvb_find_guint8 ( tvb , offset , - 1 , ' : ' ) = = - 1 ) {
2014-06-17 15:30:58 +00:00
if ( str_to_ip ( ( char * ) tvb_get_string_enc ( wmem_packet_scope ( ) , tvb , offset , tmp , ENC_ASCII ) , ipaddr ) ) {
2013-12-13 18:10:21 +00:00
addr . type = AT_IPv4 ;
addr . len = 4 ;
addr . data = wmem_memdup ( wmem_packet_scope ( ) , ipaddr , 4 ) ;
proto_tree_add_ipv4 ( rtpproxy_tree , hf_rtpproxy_ipv4 , tvb , offset , tmp , ipaddr [ 0 ] ) ;
}
else
proto_tree_add_expert ( rtpproxy_tree , pinfo , & ei_rtpproxy_bad_ipv4 , tvb , offset , tmp ) ;
2013-11-26 22:05:33 +00:00
}
else {
2014-06-17 15:30:58 +00:00
if ( str_to_ip6 ( ( char * ) tvb_get_string_enc ( wmem_packet_scope ( ) , tvb , offset , tmp , ENC_ASCII ) , ipaddr ) ) {
2013-12-13 18:10:21 +00:00
addr . type = AT_IPv6 ;
addr . len = 16 ;
addr . data = wmem_memdup ( wmem_packet_scope ( ) , ipaddr , 16 ) ;
proto_tree_add_ipv6 ( rtpproxy_tree , hf_rtpproxy_ipv6 , tvb , offset , tmp , ( const guint8 * ) ipaddr ) ;
}
else
proto_tree_add_expert ( rtpproxy_tree , pinfo , & ei_rtpproxy_bad_ipv6 , tvb , offset , tmp ) ;
2013-11-26 22:05:33 +00:00
}
if ( rtpproxy_establish_conversation ) {
if ( rtp_handle ) {
/* FIXME tell if isn't a video stream, and setup codec mapping */
2013-12-13 18:10:21 +00:00
if ( addr . len )
rtp_add_address ( pinfo , & addr , port , 0 , " RTPproxy " , pinfo - > fd - > num , 0 , NULL ) ;
2013-11-26 22:05:33 +00:00
}
if ( rtcp_handle ) {
2013-12-13 18:10:21 +00:00
if ( addr . len )
rtcp_add_address ( pinfo , & addr , port + 1 , 0 , " RTPproxy " , pinfo - > fd - > num ) ;
2013-11-26 22:05:33 +00:00
}
}
2013-08-18 19:49:08 +00:00
break ;
default :
break ;
}
if ( has_lf )
proto_tree_add_item ( rtpproxy_tree , hf_rtpproxy_lf , tvb , realsize , 1 , ENC_NA ) ;
2013-10-09 20:14:12 +00:00
2014-06-19 17:18:16 +00:00
return tvb_length ( tvb ) ;
2013-08-18 19:49:08 +00:00
}
void
proto_register_rtpproxy ( void )
{
module_t * rtpproxy_module ;
2013-11-28 14:11:48 +00:00
expert_module_t * expert_rtpproxy_module ;
2013-08-18 19:49:08 +00:00
static hf_register_info hf [ ] = {
{
& hf_rtpproxy_cookie ,
{
" Cookie " ,
" rtpproxy.cookie " ,
FT_STRING ,
BASE_NONE ,
NULL ,
0x0 ,
NULL ,
HFILL
}
} ,
{
& hf_rtpproxy_version_request ,
{
" Version Request " ,
" rtpproxy.version " ,
FT_STRING ,
BASE_NONE ,
NULL ,
0x0 ,
NULL ,
HFILL
}
} ,
{
& hf_rtpproxy_version_supported ,
{
" Version Supported " ,
" rtpproxy.version_supported " ,
FT_STRING ,
BASE_NONE ,
NULL ,
0x0 ,
NULL ,
HFILL
}
} ,
{
& hf_rtpproxy_error ,
{
" Error " ,
" rtpproxy.error " ,
2013-11-11 02:06:17 +00:00
FT_STRING ,
BASE_NONE ,
NULL ,
2013-08-18 19:49:08 +00:00
0x0 ,
NULL ,
HFILL
}
} ,
{
& hf_rtpproxy_ok ,
{
" Ok " ,
" rtpproxy.ok " ,
FT_UINT8 ,
BASE_DEC ,
VALS ( oktypenames ) ,
0x0 ,
NULL ,
HFILL
}
} ,
{
& hf_rtpproxy_status ,
{
" Status " ,
" rtpproxy.status " ,
FT_STRING ,
BASE_NONE ,
NULL ,
0x0 ,
NULL ,
HFILL
}
} ,
{
& hf_rtpproxy_ipv4 ,
{
" IPv4 " ,
" rtpproxy.ipv4 " ,
2013-12-13 18:10:21 +00:00
FT_IPv4 ,
2013-08-18 19:49:08 +00:00
BASE_NONE ,
NULL ,
0x0 ,
NULL ,
HFILL
}
} ,
{
& hf_rtpproxy_ipv6 ,
{
" IPv6 " ,
" rtpproxy.ipv6 " ,
2013-12-13 18:10:21 +00:00
FT_IPv6 ,
2013-08-18 19:49:08 +00:00
BASE_NONE ,
NULL ,
0x0 ,
NULL ,
HFILL
}
} ,
{
& hf_rtpproxy_port ,
{
" Port " ,
" rtpproxy.port " ,
2013-12-26 15:42:06 +00:00
FT_UINT16 , /* 0 - 65535 */
BASE_DEC ,
2013-08-18 19:49:08 +00:00
NULL ,
0x0 ,
NULL ,
HFILL
}
} ,
{
& hf_rtpproxy_request ,
{
" Request " ,
" rtpproxy.request " ,
FT_NONE ,
BASE_NONE ,
NULL ,
0x0 ,
NULL ,
HFILL
}
} ,
{
& hf_rtpproxy_command ,
{
" Command " ,
" rtpproxy.command " ,
FT_UINT8 ,
BASE_DEC ,
VALS ( commandtypenames ) ,
0x0 ,
NULL ,
HFILL
}
} ,
{
& hf_rtpproxy_command_parameters ,
{
" Command parameters " ,
" rtpproxy.command_parameters " ,
FT_STRING ,
BASE_NONE ,
NULL ,
0x0 ,
NULL ,
HFILL
}
} ,
2013-11-26 22:32:33 +00:00
{
& hf_rtpproxy_command_parameter ,
{
" Parameter " ,
" rtpproxy.command_parameter " ,
FT_UINT8 ,
BASE_DEC ,
VALS ( paramtypenames ) ,
0x0 ,
NULL ,
HFILL
}
} ,
{
& hf_rtpproxy_command_parameter_codec ,
{
" Allowed codec " ,
" rtpproxy.command_parameter_codec " ,
2013-12-26 15:42:06 +00:00
FT_UINT8 , /* 0 - 127 */
BASE_DEC ,
2013-11-26 22:32:33 +00:00
NULL ,
0x0 ,
NULL ,
HFILL
}
} ,
{
2013-12-13 18:10:21 +00:00
& hf_rtpproxy_command_parameter_local_ipv4 ,
2013-11-26 22:32:33 +00:00
{
2013-12-13 18:10:21 +00:00
" Local IPv4 address " ,
" rtpproxy.command_parameter_local_ipv4 " ,
FT_IPv4 , /* FIXME - is it ever possible to see IPv6 here? */
2013-11-26 22:32:33 +00:00
BASE_NONE ,
NULL ,
0x0 ,
NULL ,
HFILL
}
} ,
{
2013-12-13 18:10:21 +00:00
& hf_rtpproxy_command_parameter_remote_ipv4 ,
2013-11-26 22:32:33 +00:00
{
2013-12-13 18:10:21 +00:00
" Remote IPv4 address " ,
" rtpproxy.command_parameter_remote_ipv4 " ,
FT_IPv4 , /* FIXME - is it ever possible to see IPv6 here? */
2013-11-26 22:32:33 +00:00
BASE_NONE ,
NULL ,
0x0 ,
NULL ,
HFILL
}
} ,
{
& hf_rtpproxy_command_parameter_repacketize ,
{
" Repacketize (ms) " ,
" rtpproxy.command_parameter_repacketize " ,
2013-12-26 15:42:06 +00:00
FT_UINT16 , /* 0 - 1000 milliseconds */
BASE_DEC ,
2013-11-26 22:32:33 +00:00
NULL ,
0x0 ,
NULL ,
HFILL
}
} ,
{
& hf_rtpproxy_command_parameter_dtmf ,
{
" DTMF payload ID " ,
" rtpproxy.command_parameter_dtmf " ,
2013-12-26 15:42:06 +00:00
FT_UINT8 , /* 0 - 127 */
BASE_DEC ,
2013-11-26 22:32:33 +00:00
NULL ,
0x0 ,
NULL ,
HFILL
}
} ,
{
& hf_rtpproxy_command_parameter_proto ,
{
" RTP tramsission protocol " ,
" rtpproxy.command_parameter_proto " ,
FT_UINT8 ,
BASE_DEC ,
VALS ( prototypenames ) ,
0x0 ,
NULL ,
HFILL
}
} ,
{
& hf_rtpproxy_command_parameter_transcode ,
{
" Transcode to " ,
" rtpproxy.command_parameter_transcode " ,
2013-12-26 15:42:06 +00:00
FT_UINT8 , /* 0 - 127 */
BASE_DEC ,
2013-11-26 22:32:33 +00:00
NULL ,
0x0 ,
NULL ,
HFILL
}
} ,
{
& hf_rtpproxy_command_parameter_acc ,
{
" Accounting " ,
" rtpproxy.command_parameter_acc " ,
FT_UINT8 ,
BASE_DEC ,
VALS ( acctypenames ) ,
0x0 ,
NULL ,
HFILL
}
} ,
2013-08-18 19:49:08 +00:00
{
& hf_rtpproxy_copy_target ,
{
" Copy target " ,
" rtpproxy.copy_target " ,
2013-12-26 15:42:06 +00:00
FT_STRING , /* Filename or UDP address, e.g. /var/tmp/fileXXXX.yyy or IP:Port */
2013-08-18 19:49:08 +00:00
BASE_NONE ,
NULL ,
0x0 ,
NULL ,
HFILL
}
} ,
{
& hf_rtpproxy_playback_filename ,
{
" Playback filename " ,
" rtpproxy.playback_filename " ,
FT_STRING ,
BASE_NONE ,
NULL ,
0x0 ,
NULL ,
HFILL
}
} ,
{
& hf_rtpproxy_playback_codec ,
{
" Playback codec " ,
" rtpproxy.playback_codec " ,
2013-12-26 15:42:06 +00:00
FT_UINT8 , /* 0 - 127 */
BASE_DEC ,
2013-08-18 19:49:08 +00:00
NULL ,
0x0 ,
NULL ,
HFILL
}
} ,
{
& hf_rtpproxy_callid ,
{
" Call-ID " ,
" rtpproxy.callid " ,
FT_STRING ,
BASE_NONE ,
NULL ,
0x0 ,
NULL ,
HFILL
}
} ,
{
& hf_rtpproxy_notify ,
{
" Notify " ,
" rtpproxy.notify " ,
FT_STRING ,
BASE_NONE ,
NULL ,
0x0 ,
NULL ,
HFILL
}
} ,
{
& hf_rtpproxy_tag ,
{
" Tag " ,
" rtpproxy.tag " ,
FT_STRING ,
BASE_NONE ,
NULL ,
0x0 ,
NULL ,
HFILL
}
} ,
{
& hf_rtpproxy_mediaid ,
{
" Media-ID " ,
" rtpproxy.mediaid " ,
FT_STRING ,
BASE_NONE ,
NULL ,
0x0 ,
NULL ,
HFILL
}
} ,
{
& hf_rtpproxy_notify_ipv4 ,
{
" Notification IPv4 " ,
" rtpproxy.notify_ipv4 " ,
2013-12-13 18:10:21 +00:00
FT_IPv4 ,
2013-08-18 19:49:08 +00:00
BASE_NONE ,
NULL ,
0x0 ,
NULL ,
HFILL
}
} ,
2013-11-17 14:48:55 +00:00
{
& hf_rtpproxy_notify_ipv6 ,
{
" Notification IPv6 " ,
" rtpproxy.notify_ipv6 " ,
2013-12-13 18:10:21 +00:00
FT_IPv6 ,
2013-11-17 14:48:55 +00:00
BASE_NONE ,
NULL ,
0x0 ,
NULL ,
HFILL
}
} ,
2013-08-18 19:49:08 +00:00
{
& hf_rtpproxy_notify_port ,
{
" Notification Port " ,
" rtpproxy.notify_port " ,
2013-12-26 15:42:06 +00:00
FT_UINT16 ,
BASE_DEC ,
2013-08-18 19:49:08 +00:00
NULL ,
0x0 ,
NULL ,
HFILL
}
} ,
{
& hf_rtpproxy_notify_tag ,
{
" Notification Tag " ,
" rtpproxy.notify_tag " ,
FT_STRING ,
BASE_NONE ,
NULL ,
0x0 ,
NULL ,
HFILL
}
} ,
{
& hf_rtpproxy_reply ,
{
" Reply " ,
" rtpproxy.reply " ,
FT_NONE ,
BASE_NONE ,
NULL ,
0x0 ,
NULL ,
HFILL
}
} ,
{
& hf_rtpproxy_lf ,
{
" LF " ,
" rtpproxy.lf " ,
2013-12-13 14:16:54 +00:00
FT_NONE ,
BASE_NONE ,
NULL ,
2013-08-18 19:49:08 +00:00
0x0 ,
NULL ,
HFILL
}
} ,
2013-10-02 16:37:10 +00:00
{
& hf_rtpproxy_request_in ,
{
" Request In " ,
" rtpproxy.request_in " ,
FT_FRAMENUM ,
BASE_NONE ,
NULL ,
0x0 ,
NULL ,
HFILL
}
} ,
{
& hf_rtpproxy_response_in ,
{
" Response In " ,
" rtpproxy.response_in " ,
FT_FRAMENUM ,
BASE_NONE ,
NULL ,
0x0 ,
NULL ,
HFILL
}
2013-11-06 20:39:10 +00:00
} ,
{
& hf_rtpproxy_response_time ,
{
" Response Time " ,
" rtpproxy.response_time " ,
FT_RELATIVE_TIME ,
BASE_NONE ,
NULL ,
0x0 ,
" The time between the Request and the Reply " ,
HFILL
}
2014-02-20 11:50:09 +00:00
} ,
{
& hf_rtpproxy_ng_bencode ,
{
" RTPproxy-ng bencode packet " ,
" rtpproxy.ng.bencode " ,
FT_STRING ,
BASE_NONE ,
NULL ,
0x0 ,
" Serialized structure of integers, dictionaries, strings and lists. " ,
HFILL
}
2013-10-02 16:37:10 +00:00
}
2013-08-18 19:49:08 +00:00
} ;
2013-11-28 14:11:48 +00:00
static ei_register_info ei [ ] = {
{ & ei_rtpproxy_timeout , { " rtpproxy.response_timeout " , PI_RESPONSE_CODE , PI_WARN , " TIMEOUT " , EXPFILL } } ,
2013-12-20 20:31:40 +00:00
{ & ei_rtpproxy_notify_no_ip , { " rtpproxy.notify_no_ip " , PI_RESPONSE_CODE , PI_COMMENT , " No notification IP address provided. Using ip.src or ipv6.src as a value. " , EXPFILL } } ,
2013-12-13 18:10:21 +00:00
{ & ei_rtpproxy_bad_ipv4 , { " rtpproxy.bad_ipv4 " , PI_MALFORMED , PI_ERROR , " Bad IPv4 " , EXPFILL } } ,
{ & ei_rtpproxy_bad_ipv6 , { " rtpproxy.bad_ipv6 " , PI_MALFORMED , PI_ERROR , " Bad IPv6 " , EXPFILL } } ,
2013-11-28 14:11:48 +00:00
} ;
2013-08-18 19:49:08 +00:00
/* Setup protocol subtree array */
static gint * ett [ ] = {
& ett_rtpproxy ,
& ett_rtpproxy_request ,
& ett_rtpproxy_command ,
2013-11-26 22:32:33 +00:00
& ett_rtpproxy_command_parameters ,
& ett_rtpproxy_command_parameters_codecs ,
& ett_rtpproxy_command_parameters_local ,
& ett_rtpproxy_command_parameters_remote ,
& ett_rtpproxy_command_parameters_repacketize ,
& ett_rtpproxy_command_parameters_dtmf ,
& ett_rtpproxy_command_parameters_cmap ,
& ett_rtpproxy_command_parameters_proto ,
& ett_rtpproxy_command_parameters_transcode ,
& ett_rtpproxy_command_parameters_acc ,
2013-08-18 19:49:08 +00:00
& ett_rtpproxy_tag ,
& ett_rtpproxy_notify ,
2014-02-20 11:50:09 +00:00
& ett_rtpproxy_reply ,
& ett_rtpproxy_ng_bencode
2013-08-18 19:49:08 +00:00
} ;
proto_rtpproxy = proto_register_protocol (
" Sippy RTPproxy Protocol " , /* name */
" RTPproxy " , /* short name */
" rtpproxy " /* abbrev */
) ;
proto_register_field_array ( proto_rtpproxy , hf , array_length ( hf ) ) ;
proto_register_subtree_array ( ett , array_length ( ett ) ) ;
2013-11-28 14:11:48 +00:00
expert_rtpproxy_module = expert_register_protocol ( proto_rtpproxy ) ;
expert_register_field_array ( expert_rtpproxy_module , ei , array_length ( ei ) ) ;
2013-08-18 19:49:08 +00:00
rtpproxy_module = prefs_register_protocol ( proto_rtpproxy , proto_reg_handoff_rtpproxy ) ;
2013-11-28 14:11:48 +00:00
2013-08-18 19:49:08 +00:00
prefs_register_uint_preference ( rtpproxy_module , " tcp.port " ,
" RTPproxy TCP Port " , /* Title */
" RTPproxy TCP Port " , /* Descr */
10 ,
& rtpproxy_tcp_port ) ;
prefs_register_uint_preference ( rtpproxy_module , " udp.port " ,
" RTPproxy UDP Port " , /* Title */
" RTPproxy UDP Port " , /* Descr */
10 ,
& rtpproxy_udp_port ) ;
2013-11-28 14:11:48 +00:00
2013-11-26 22:05:33 +00:00
prefs_register_bool_preference ( rtpproxy_module , " establish_conversation " ,
" Establish Media Conversation " ,
" Specifies that RTP/RTCP/T.38/MSRP/etc streams are decoded based "
" upon port numbers found in RTPproxy answers " ,
& rtpproxy_establish_conversation ) ;
2013-11-28 14:11:48 +00:00
prefs_register_uint_preference ( rtpproxy_module , " reply.timeout " ,
" RTPproxy reply timeout " , /* Title */
" Maximum timeout value in waiting for reply from RTPProxy (in milliseconds). " , /* Descr */
10 ,
& rtpproxy_timeout ) ;
2013-08-18 19:49:08 +00:00
}
void
proto_reg_handoff_rtpproxy ( void )
{
static guint old_rtpproxy_tcp_port = 0 ;
static guint old_rtpproxy_udp_port = 0 ;
static gboolean rtpproxy_initialized = FALSE ;
static dissector_handle_t rtpproxy_tcp_handle , rtpproxy_udp_handle ;
if ( ! rtpproxy_initialized ) {
2013-10-09 20:14:12 +00:00
rtpproxy_tcp_handle = new_create_dissector_handle ( dissect_rtpproxy , proto_rtpproxy ) ;
rtpproxy_udp_handle = new_create_dissector_handle ( dissect_rtpproxy , proto_rtpproxy ) ;
2013-08-18 19:49:08 +00:00
rtpproxy_initialized = TRUE ;
}
/* Register TCP port for dissection */
if ( old_rtpproxy_tcp_port ! = 0 & & old_rtpproxy_tcp_port ! = rtpproxy_tcp_port )
dissector_delete_uint ( " tcp.port " , old_rtpproxy_tcp_port , rtpproxy_tcp_handle ) ;
if ( rtpproxy_tcp_port ! = 0 & & old_rtpproxy_tcp_port ! = rtpproxy_tcp_port )
dissector_add_uint ( " tcp.port " , rtpproxy_tcp_port , rtpproxy_tcp_handle ) ;
old_rtpproxy_tcp_port = rtpproxy_tcp_port ;
/* Register UDP port for dissection */
if ( old_rtpproxy_udp_port ! = 0 & & old_rtpproxy_udp_port ! = rtpproxy_udp_port )
dissector_delete_uint ( " udp.port " , old_rtpproxy_udp_port , rtpproxy_udp_handle ) ;
if ( rtpproxy_udp_port ! = 0 & & old_rtpproxy_udp_port ! = rtpproxy_udp_port )
dissector_add_uint ( " udp.port " , rtpproxy_udp_port , rtpproxy_udp_handle ) ;
old_rtpproxy_udp_port = rtpproxy_udp_port ;
2013-11-26 22:05:33 +00:00
rtcp_handle = find_dissector ( " rtcp " ) ;
2013-11-26 22:40:52 +00:00
rtp_events_handle = find_dissector ( " rtpevent " ) ;
rtp_handle = find_dissector ( " rtp " ) ;
2014-02-20 11:50:09 +00:00
bencode_handle = find_dissector ( " bencode " ) ;
2013-11-28 14:11:48 +00:00
/* Calculate nstime_t struct for the timeout from the rtpproxy_timeout value in milliseconds */
rtpproxy_timeout_ns . secs = ( rtpproxy_timeout - rtpproxy_timeout % 1000 ) / 1000 ;
rtpproxy_timeout_ns . nsecs = ( rtpproxy_timeout % 1000 ) * 1000 ;
2013-08-18 19:49:08 +00:00
}
/*
* Editor modelines - http : //www.wireshark.org/tools/modelines.html
*
* Local variables :
* c - basic - offset : 8
* tab - width : 8
* indent - tabs - mode : t
* End :
*
* vi : set shiftwidth = 8 tabstop = 8 noexpandtab :
* : indentSize = 8 : tabSize = 8 : noTabs = false :
*/