/* packet-rtcp.c
*
- * $Id: packet-rtcp.c,v 1.23 2001/11/26 05:13:12 hagbard Exp $
+ * $Id: packet-rtcp.c,v 1.46 2004/06/30 21:08:58 etxrab Exp $
*
* Routines for RTCP dissection
* RTCP = Real-time Transport Control Protocol
- *
+ *
* Copyright 2000, Philips Electronics N.V.
- * Written by Andreas Sikkema <andreas.sikkema@philips.com>
+ * Written by Andreas Sikkema <h323@ramdyne.nl>
+ *
+ * Copyright 2004, Anders Broman <anders.broman@ericsson.com>
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
* 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.
* of ITU-T Recommendation H.225.0 (02/98) and RFC 1889
* H.225.0 literally copies RFC 1889, but omitting a few sections.
*
- * RTCP traffic is handled by an uneven UDP portnumber. This can be any
+ * RTCP traffic is handled by an uneven UDP portnumber. This can be any
* port number, but there is a registered port available, port 5005
* See Annex B of ITU-T Recommendation H.225.0, section B.7
*
+ * See also http://www.iana.org/assignments/rtp-parameters
*/
#endif
#include <glib.h>
-#include "packet.h"
-
-#ifdef HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif
-
-#ifdef HAVE_NETINET_IN_H
-# include <netinet/in.h>
-#endif
+#include <epan/packet.h>
#include <stdio.h>
#include <string.h>
#if 0
#include "packet-ntp.h"
#endif
-#include "conversation.h"
+#include <epan/conversation.h>
+
+#include "prefs.h"
+
/* Version is the first 2 bits of the first octet*/
#define RTCP_VERSION(octet) ((octet) >> 6)
/* Receiver/ Sender count is the 5 last bits */
#define RTCP_COUNT(octet) ((octet) & 0x1F)
-static const value_string rtcp_version_vals[] =
+static dissector_handle_t rtcp_handle;
+
+static const value_string rtcp_version_vals[] =
{
{ 0, "Old VAT Version" },
{ 1, "First Draft Version" },
};
/* RTCP packet types according to Section A.11.1 */
+/* And http://www.iana.org/assignments/rtp-parameters */
#define RTCP_SR 200
#define RTCP_RR 201
#define RTCP_SDES 202
#define RTCP_BYE 203
#define RTCP_APP 204
+#define RTCP_XR 207
/* Supplemental H.261 specific RTCP packet types according to Section C.3.5 */
#define RTCP_FIR 192
#define RTCP_NACK 193
-static const value_string rtcp_packet_type_vals[] =
+static const value_string rtcp_packet_type_vals[] =
{
{ RTCP_SR, "Sender Report" },
{ RTCP_RR, "Receiver Report" },
{ RTCP_APP, "Application specific" },
{ RTCP_FIR, "Full Intra-frame Request (H.261)" },
{ RTCP_NACK, "Negative Acknowledgement (H.261)" },
+ { RTCP_XR, "Extended report"},
{ 0, NULL },
};
#define RTCP_SDES_TOOL 6
#define RTCP_SDES_NOTE 7
#define RTCP_SDES_PRIV 8
+#define RTCP_SDES_H323_CADDR 9
-static const value_string rtcp_sdes_type_vals[] =
+static const value_string rtcp_sdes_type_vals[] =
{
{ RTCP_SDES_END, "END" },
{ RTCP_SDES_CNAME, "CNAME (user and domain)" },
{ RTCP_SDES_TOOL, "TOOL (name/version of source app)" },
{ RTCP_SDES_NOTE, "NOTE (note about source)" },
{ RTCP_SDES_PRIV, "PRIV (private extensions)" },
+ { RTCP_SDES_H323_CADDR,"H323-CADDR (H.323 callable address)"},
{ 0, NULL },
};
+/* RTCP Application PoC1 Value strings */
+static const value_string rtcp_app_poc1_floor_cnt_type_vals[] =
+{
+ { 0, "Floor Request"},
+ { 1, "Floor Grant"},
+ { 2, "Floor Taken"},
+ { 3, "Floor Deny"},
+ { 4, "Floor Release"},
+ { 5, "Floor Idle"},
+ { 6, "Floor Revoke"},
+ { 0, NULL },
+};
+
+static const value_string rtcp_app_poc1_reason_code1_vals[] =
+{
+ { 1, "Floor already in use"},
+ { 2, "Internal PoC server error"},
+ { 0, NULL },
+};
+static const value_string rtcp_app_poc1_reason_code2_vals[] =
+{
+ { 1, "Only one user"},
+ { 2, "Talk burst too long"},
+ { 0, NULL },
+};
/* RTCP header fields */
static int proto_rtcp = -1;
static int hf_rtcp_version = -1;
static int hf_rtcp_ssrc_source = -1;
static int hf_rtcp_ssrc_fraction = -1;
static int hf_rtcp_ssrc_cum_nr = -1;
-/* First the 32 bit number, then the split
+/* First the 32 bit number, then the split
* up 16 bit values */
/* These two are added to a subtree */
static int hf_rtcp_ssrc_ext_high_seq = -1;
static int hf_rtcp_blp = -1;
static int hf_rtcp_padding_count = -1;
static int hf_rtcp_padding_data = -1;
+static int hf_rtcp_app_poc1_subtype = -1;
+static int hf_rtcp_app_poc1_sip_uri = -1;
+static int hf_rtcp_app_poc1_disp_name = -1;
+static int hf_rtcp_app_poc1_last_pkt_seq_no = -1;
+static int hf_rtcp_app_poc1_reason_code1 = -1;
+static int hf_rtcp_app_poc1_item_len = -1;
+static int hf_rtcp_app_poc1_reason1_phrase = -1;
+static int hf_rtcp_app_poc1_reason_code2 = -1;
+static int hf_rtcp_app_poc1_additionalinfo = -1;
+
+/* RTCP setup fields */
+static int hf_rtcp_setup = -1;
+static int hf_rtcp_setup_frame = -1;
+static int hf_rtcp_setup_method = -1;
+
/* RTCP fields defining a sub tree */
-static gint ett_rtcp = -1;
-static gint ett_ssrc = -1;
-static gint ett_ssrc_item = -1;
-static gint ett_ssrc_ext_high = -1;
-static gint ett_sdes = -1;
-static gint ett_sdes_item = -1;
+static gint ett_rtcp = -1;
+static gint ett_ssrc = -1;
+static gint ett_ssrc_item = -1;
+static gint ett_ssrc_ext_high = -1;
+static gint ett_sdes = -1;
+static gint ett_sdes_item = -1;
+static gint ett_PoC1 = -1;
+static gint ett_rtcp_setup = -1;
static address fake_addr;
static int heur_init = FALSE;
-static dissector_handle_t data_handle;
-
static gboolean dissect_rtcp_heur( tvbuff_t *tvb, packet_info *pinfo,
proto_tree *tree );
+static void dissect_rtcp( tvbuff_t *tvb, packet_info *pinfo,
+ proto_tree *tree );
+static void show_setup_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
+
+/* Preferences bool to control whether or not setup info should be shown */
+static gboolean global_rtcp_show_setup_info = TRUE;
+
+/* Memory chunk for storing conversation and per-packet info */
+static GMemChunk *rtcp_conversations = NULL;
-void rtcp_add_address( packet_info *pinfo, const unsigned char* ip_addr,
- int prt )
+
+void rtcp_add_address( packet_info *pinfo,
+ const unsigned char* ip_addr, int port,
+ int other_port,
+ gchar *setup_method, guint32 setup_frame_number)
{
address src_addr;
- conversation_t* pconv;
+ conversation_t* p_conv;
+ struct _rtcp_conversation_info *p_conv_data = NULL;
/*
* If this isn't the first time this packet has been processed,
* again.
*/
if (pinfo->fd->flags.visited)
+ {
return;
+ }
- src_addr.type = AT_IPv4;
- src_addr.len = 4;
+ src_addr.type = pinfo->net_src.type;
+ src_addr.len = pinfo->net_src.len;
src_addr.data = ip_addr;
/*
* The first time the function is called let the udp dissector
* know that we're interested in traffic
- */
+ * TODO???
+ *
if ( ! heur_init ) {
heur_dissector_add( "udp", dissect_rtcp_heur, proto_rtcp );
heur_init = TRUE;
}
+ */
/*
- * Check if the ip address and port combination is not
+ * Check if the ip address and port combination is not
* already registered
*/
- pconv = find_conversation( &src_addr, &fake_addr, PT_UDP, prt, 0, 0 );
+ p_conv = find_conversation( &src_addr, &src_addr, PT_UDP, port, other_port,
+ NO_ADDR_B | (!other_port ? NO_PORT_B : 0));
/*
* If not, add
- * XXX - use wildcard address and port B?
*/
- if ( ! pconv ) {
- pconv = conversation_new( &src_addr, &fake_addr, PT_UDP,
- (guint32) prt, (guint32) 0, 0 );
- conversation_add_proto_data(pconv, proto_rtcp, NULL);
+ if ( ! p_conv ) {
+ /* Create conversation data */
+ p_conv_data = g_mem_chunk_alloc(rtcp_conversations);
+
+ /* Check length first time we look at method string */
+ strncpy(p_conv_data->method, setup_method,
+ (strlen(setup_method)+1 <= MAX_RTCP_SETUP_METHOD_SIZE) ?
+ strlen(setup_method)+1 :
+ MAX_RTCP_SETUP_METHOD_SIZE);
+ p_conv_data->method[MAX_RTCP_SETUP_METHOD_SIZE] = '\0';
+ p_conv_data->frame_number = setup_frame_number;
+
+ /* Create conversation with this data */
+ p_conv = conversation_new( &src_addr, &src_addr, PT_UDP,
+ (guint32)port, (guint32)other_port,
+ NO_ADDR2 | (!other_port ? NO_PORT2 : 0));
+ conversation_add_proto_data(p_conv, proto_rtcp, p_conv_data);
+
+ /* Set dissector */
+ conversation_set_dissector(p_conv, rtcp_handle);
+ }
+ else
+ {
+ /* Update existing conversation data */
+ p_conv_data = conversation_get_proto_data(p_conv, proto_rtcp);
+ strcpy(p_conv_data->method, setup_method);
+ p_conv_data->frame_number = setup_frame_number;
}
-
}
-#if 0
-static void rtcp_init( void )
+static void rtcp_init( void )
{
unsigned char* tmp_data;
int i;
+ /* (Re)allocate mem chunk for conversations */
+ if (rtcp_conversations)
+ {
+ g_mem_chunk_destroy(rtcp_conversations);
+ }
+ rtcp_conversations = g_mem_chunk_new("rtcp_conversations",
+ sizeof(struct _rtcp_conversation_info),
+ 20 * sizeof(struct _rtcp_conversation_info),
+ G_ALLOC_ONLY);
+
+
/* Create a fake adddress... */
fake_addr.type = AT_IPv4;
fake_addr.len = 4;
- tmp_data = malloc( fake_addr.len );
+ tmp_data = g_malloc( fake_addr.len );
for ( i = 0; i < fake_addr.len; i++) {
tmp_data[i] = 0;
}
fake_addr.data = tmp_data;
}
-#endif
static gboolean
dissect_rtcp_heur( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree )
{
conversation_t* pconv;
- if (!proto_is_protocol_enabled(proto_rtcp))
- return FALSE; /* RTCP has been disabled */
-
/* This is a heuristic dissector, which means we get all the UDP
* traffic not sent to a known dissector and not claimed by
* a heuristic dissector called before us!
static int
-dissect_rtcp_nack( tvbuff_t *tvb, int offset, frame_data *fd, proto_tree *tree )
+dissect_rtcp_nack( tvbuff_t *tvb, int offset, proto_tree *tree )
{
/* Packet type = FIR (H261) */
- proto_tree_add_uint( tree, hf_rtcp_rc, tvb, offset, 1, tvb_get_guint8( tvb, offset ) & 31 );
+ proto_tree_add_uint( tree, hf_rtcp_rc, tvb, offset, 1, tvb_get_guint8( tvb, offset ) );
offset++;
/* Packet type, 8 bits = APP */
proto_tree_add_item( tree, hf_rtcp_pt, tvb, offset, 1, FALSE );
/* SSRC */
proto_tree_add_uint( tree, hf_rtcp_ssrc_source, tvb, offset, 4, tvb_get_ntohl( tvb, offset ) );
offset += 4;
-
+
/* FSN, 16 bits */
proto_tree_add_uint( tree, hf_rtcp_fsn, tvb, offset, 2, tvb_get_ntohs( tvb, offset ) );
offset += 2;
}
static int
-dissect_rtcp_fir( tvbuff_t *tvb, int offset, frame_data *fd, proto_tree *tree )
+dissect_rtcp_fir( tvbuff_t *tvb, int offset, proto_tree *tree )
{
/* Packet type = FIR (H261) */
- proto_tree_add_uint( tree, hf_rtcp_rc, tvb, offset, 1, tvb_get_guint8( tvb, offset ) & 31 );
+ proto_tree_add_uint( tree, hf_rtcp_rc, tvb, offset, 1, tvb_get_guint8( tvb, offset ) );
offset++;
/* Packet type, 8 bits = APP */
proto_tree_add_item( tree, hf_rtcp_pt, tvb, offset, 1, FALSE );
/* SSRC */
proto_tree_add_uint( tree, hf_rtcp_ssrc_source, tvb, offset, 4, tvb_get_ntohl( tvb, offset ) );
offset += 4;
-
+
return offset;
}
static int
-dissect_rtcp_app( tvbuff_t *tvb, int offset, frame_data *fd, proto_tree *tree,
- unsigned int padding, unsigned int packet_len )
+dissect_rtcp_app( tvbuff_t *tvb,packet_info *pinfo, int offset, proto_tree *tree,
+ unsigned int padding, unsigned int packet_len, guint rtcp_subtype )
{
unsigned int counter = 0;
char ascii_name[5];
+ guint sdes_type = 0;
+ guint item_len = 0;
+ guint items_start_offset;
+ proto_tree *PoC1_tree;
+ proto_item *PoC1_item;
+
+ /* XXX If more application types are to be dissected it may be useful to use a table like in packet-sip.c */
+ static const char app_name_str[] = "PoC1";
+
/* SSRC / CSRC */
proto_tree_add_uint( tree, hf_rtcp_ssrc_source, tvb, offset, 4, tvb_get_ntohl( tvb, offset ) );
ascii_name[4] = '\0';
proto_tree_add_string( tree, hf_rtcp_name_ascii, tvb, offset, 4,
ascii_name );
- offset += 4;
- packet_len -= 4;
+ if ( strncasecmp(ascii_name,app_name_str,4 ) != 0 ){ /* Not PoC1 */
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_append_fstr(pinfo->cinfo, COL_INFO,"( %s ) subtype=%u",ascii_name, rtcp_subtype);
+ offset += 4;
+ packet_len -= 4;
+ /* Applications specific data */
+ if ( padding ) {
+ /* If there's padding present, we have to remove that from the data part
+ * The last octet of the packet contains the length of the padding
+ */
+ packet_len -= tvb_get_guint8( tvb, offset + packet_len - 1 );
+ }
+ proto_tree_add_item( tree, hf_rtcp_app_data, tvb, offset, packet_len, FALSE );
+ offset += packet_len;
+
+ return offset;
+ }else{/* PoC1 Application */
+ proto_item *item;
+ item = proto_tree_add_uint( tree, hf_rtcp_app_poc1_subtype, tvb, offset - 8, 1, rtcp_subtype );
+ PROTO_ITEM_SET_GENERATED(item);
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_append_fstr(pinfo->cinfo, COL_INFO,"(%s) subtype=%s",ascii_name,
+ val_to_str(rtcp_subtype,rtcp_app_poc1_floor_cnt_type_vals,"unknown (%u)") );
+ offset += 4;
+ packet_len -= 4;
+ /* Applications specific data */
+ if ( padding ) {
+ /* If there's padding present, we have to remove that from the data part
+ * The last octet of the packet contains the length of the padding
+ */
+ packet_len -= tvb_get_guint8( tvb, offset + packet_len - 1 );
+ }
+ /* Create a subtree for the PoC1 Application items; we don't yet know
+ the length */
+ items_start_offset = offset;
- /* Applications specific data */
- if ( padding ) {
- /* If there's padding present, we have to remove that from the data part
- * The last octet of the packet contains the length of the padding
- */
- packet_len -= tvb_get_guint8( tvb, offset + packet_len - 1 );
- }
- proto_tree_add_item( tree, hf_rtcp_app_data, tvb, offset, packet_len, FALSE );
- offset += packet_len;
+ PoC1_item = proto_tree_add_text(tree, tvb, offset, packet_len,
+ "PoC1 Application specific data");
+ PoC1_tree = proto_item_add_subtree( PoC1_item, ett_PoC1 );
- return offset;
+
+ proto_tree_add_item( PoC1_tree, hf_rtcp_app_data, tvb, offset, packet_len, FALSE );
+ switch ( rtcp_subtype ) {
+ case 2:
+ sdes_type = tvb_get_guint8( tvb, offset );
+ proto_tree_add_item( PoC1_tree, hf_rtcp_ssrc_type, tvb, offset, 1, FALSE );
+ offset++;
+ packet_len--;
+ /* Item length, 8 bits */
+ item_len = tvb_get_guint8( tvb, offset );
+ proto_tree_add_item( PoC1_tree, hf_rtcp_ssrc_length, tvb, offset, 1, FALSE );
+ offset++;
+ packet_len--;
+ proto_tree_add_item( PoC1_tree, hf_rtcp_app_poc1_sip_uri, tvb, offset, item_len, FALSE );
+ offset = offset + item_len;
+ packet_len = packet_len - item_len;
+ sdes_type = tvb_get_guint8( tvb, offset );
+ proto_tree_add_item( PoC1_tree, hf_rtcp_ssrc_type, tvb, offset, 1, FALSE );
+ offset++;
+ packet_len--;
+ /* Item length, 8 bits */
+ item_len = tvb_get_guint8( tvb, offset );
+ proto_tree_add_item( PoC1_tree, hf_rtcp_ssrc_length, tvb, offset, 1, FALSE );
+ offset++;
+ packet_len--;
+ if ( item_len != 0 )
+ proto_tree_add_item( PoC1_tree, hf_rtcp_app_poc1_disp_name, tvb, offset, item_len, FALSE );
+ offset = offset + item_len;
+ packet_len = packet_len - item_len;
+ break;
+ case 3:
+ proto_tree_add_item( PoC1_tree, hf_rtcp_app_poc1_reason_code1, tvb, offset, 1, FALSE );
+ offset++;
+ packet_len--;
+ /* Item length, 8 bits */
+ item_len = tvb_get_guint8( tvb, offset );
+ proto_tree_add_item( PoC1_tree, hf_rtcp_app_poc1_item_len, tvb, offset, 1, FALSE );
+ offset++;
+ packet_len--;
+ if ( item_len != 0 )
+ proto_tree_add_item( PoC1_tree, hf_rtcp_app_poc1_reason1_phrase, tvb, offset, item_len, FALSE );
+ offset = offset + item_len;
+ packet_len = packet_len - item_len;
+ break;
+ case 4:
+ proto_tree_add_item( PoC1_tree, hf_rtcp_app_poc1_last_pkt_seq_no, tvb, offset, 2, FALSE );
+ proto_tree_add_text(PoC1_tree, tvb, offset + 2, 2, "Padding 2 bytes");
+ offset += 4;
+ packet_len-=4;
+ break;
+ case 6:
+ proto_tree_add_item( PoC1_tree, hf_rtcp_app_poc1_reason_code2, tvb, offset, 2, FALSE );
+ proto_tree_add_item( PoC1_tree, hf_rtcp_app_poc1_additionalinfo, tvb, offset + 2, 2, FALSE );
+ offset += 4;
+ packet_len-=4;
+ break;
+ default:
+ break;
+ }
+ offset += packet_len;
+ return offset;
+ }
}
+
static int
-dissect_rtcp_bye( tvbuff_t *tvb, int offset, frame_data *fd, proto_tree *tree,
+dissect_rtcp_bye( tvbuff_t *tvb, int offset, proto_tree *tree,
unsigned int count )
{
unsigned int chunk = 1;
unsigned int reason_length = 0;
- unsigned int counter = 0;
char* reason_text = NULL;
while ( chunk <= count ) {
/* source identifier, 32 bits */
- proto_tree_add_uint( tree, hf_rtcp_ssrc_source, tvb, offset, 4, tvb_get_ntohl( tvb, offset ) );
+ proto_tree_add_item( tree, hf_rtcp_ssrc_source, tvb, offset, 4, FALSE);
offset += 4;
+ chunk++;
}
- /* Bye reason consists of an 8 bit length l and a string with length l */
- reason_length = tvb_get_guint8( tvb, offset );
- proto_tree_add_item( tree, hf_rtcp_ssrc_length, tvb, offset, 1, FALSE );
- offset++;
+ if ( tvb_reported_length_remaining( tvb, offset ) > 0 ) {
+ /* Bye reason consists of an 8 bit length l and a string with length l */
+ reason_length = tvb_get_guint8( tvb, offset );
+ proto_tree_add_item( tree, hf_rtcp_ssrc_length, tvb, offset, 1, FALSE );
+ offset++;
- reason_text = ( char* ) malloc( reason_length + 1 );
- for ( counter = 0; counter < reason_length; counter++ ) reason_text[ counter ] = tvb_get_guint8( tvb, offset + counter );
- /* strncpy( reason_text, pd + offset, reason_length ); */
- reason_text[ reason_length ] = '\0';
- proto_tree_add_string( tree, hf_rtcp_ssrc_text, tvb, offset, reason_length, reason_text );
- free( reason_text );
- offset += reason_length;
+ reason_text = tvb_get_string(tvb, offset, reason_length);
+ proto_tree_add_string( tree, hf_rtcp_ssrc_text, tvb, offset, reason_length, reason_text );
+ g_free( reason_text );
+ offset += reason_length;
+ }
return offset;
}
-static int
-dissect_rtcp_sdes( tvbuff_t *tvb, int offset, frame_data *fd, proto_tree *tree,
+static void
+dissect_rtcp_sdes( tvbuff_t *tvb, int offset, proto_tree *tree,
unsigned int count )
{
unsigned int chunk = 1;
unsigned int counter = 0;
unsigned int prefix_len = 0;
char *prefix_string = NULL;
-
+
while ( chunk <= count ) {
/* Create a subtree for this chunk; we don't yet know
the length. */
start_offset = offset;
ssrc = tvb_get_ntohl( tvb, offset );
- sdes_item = proto_tree_add_text(tree, tvb, offset, 0,
+ if (ssrc == 0) {
+ /* According to RFC1889 section 6.4:
+ * "The list of items in each chunk is terminated by one or more
+ * null octets, the first of which is interpreted as an item type
+ * of zero to denote the end of the list, and the remainder as
+ * needed to pad until the next 32-bit boundary.
+ *
+ * A chunk with zero items (four null octets) is valid but useless."
+ */
+ proto_tree_add_text(tree, tvb, offset, 4, "Padding");
+ offset += 4;
+ continue;
+ }
+ sdes_item = proto_tree_add_text(tree, tvb, offset, -1,
"Chunk %u, SSRC/CSRC %u", chunk, ssrc);
sdes_tree = proto_item_add_subtree( sdes_item, ett_sdes );
offset += 4;
/* Create a subtree for the SDES items; we don't yet know
- the length */
+ the length */
items_start_offset = offset;
- ti = proto_tree_add_text(sdes_tree, tvb, offset, 0,
+ ti = proto_tree_add_text(sdes_tree, tvb, offset, -1,
"SDES items" );
sdes_item_tree = proto_item_add_subtree( ti, ett_sdes_item );
-
+
/*
* Not every message is ended with "null" bytes, so check for
* end of frame instead.
proto_tree_add_item( sdes_item_tree, hf_rtcp_ssrc_prefix_len, tvb, offset, 1, FALSE );
offset++;
- prefix_string = ( char * ) malloc( prefix_len + 1 );
+ prefix_string = g_malloc( prefix_len + 1 );
for ( counter = 0; counter < prefix_len; counter++ )
prefix_string[ counter ] =
tvb_get_guint8( tvb, offset + counter );
/* strncpy( prefix_string, pd + offset, prefix_len ); */
prefix_string[ prefix_len ] = '\0';
proto_tree_add_string( sdes_item_tree, hf_rtcp_ssrc_prefix_string, tvb, offset, prefix_len, prefix_string );
- free( prefix_string );
+ g_free( prefix_string );
offset += prefix_len;
}
- prefix_string = ( char * ) malloc( item_len + 1 );
+ prefix_string = g_malloc( item_len + 1 );
for ( counter = 0; counter < item_len; counter++ )
prefix_string[ counter ] =
tvb_get_guint8( tvb, offset + counter );
/* strncpy( prefix_string, pd + offset, item_len ); */
prefix_string[ item_len] = 0;
proto_tree_add_string( sdes_item_tree, hf_rtcp_ssrc_text, tvb, offset, item_len, prefix_string );
- free( prefix_string );
+ g_free( prefix_string );
offset += item_len;
}
/* Set the length of the items subtree. */
proto_item_set_len(ti, offset - items_start_offset);
- /* 32 bits = 4 bytes, so.....
- * If offset % 4 != 0, we divide offset by 4, add one and then
+ /* 32 bits = 4 bytes, so.....
+ * If offset % 4 != 0, we divide offset by 4, add one and then
* multiply by 4 again to reach the boundary
*/
if ( offset % 4 != 0 )
chunk++;
}
-
-
- return offset;
}
static int
-dissect_rtcp_rr( tvbuff_t *tvb, int offset, frame_data *fd, proto_tree *tree,
+dissect_rtcp_rr( tvbuff_t *tvb, int offset, proto_tree *tree,
unsigned int count )
{
unsigned int counter = 1;
ti = proto_tree_add_text(tree, tvb, offset, 24,
"Source %u", counter );
ssrc_tree = proto_item_add_subtree( ti, ett_ssrc );
-
+
/* SSRC_n source identifier, 32 bits */
proto_tree_add_uint( ssrc_tree, hf_rtcp_ssrc_source, tvb, offset, 4, tvb_get_ntohl( tvb, offset ) );
offset += 4;
-
+
ti = proto_tree_add_text(ssrc_tree, tvb, offset, 20, "SSRC contents" );
ssrc_sub_tree = proto_item_add_subtree( ti, ett_ssrc_item );
}
static int
-dissect_rtcp_sr( tvbuff_t *tvb, int offset, frame_data *fd, proto_tree *tree,
+dissect_rtcp_sr( tvbuff_t *tvb, int offset, proto_tree *tree,
unsigned int count )
{
#if 0
/* The rest of the packet is equal to the RR packet */
if ( count != 0 )
- offset = dissect_rtcp_rr( tvb, offset, fd, tree, count );
+ offset = dissect_rtcp_rr( tvb, offset, tree, count );
return offset;
}
-void
+/* Look for conversation info and display any setup info found */
+void show_setup_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+ /* Conversation and current data */
+ conversation_t *p_conv = NULL;
+ struct _rtcp_conversation_info *p_conv_data = NULL;
+
+ /* Use existing packet data if available */
+ p_conv_data = p_get_proto_data(pinfo->fd, proto_rtcp);
+
+ if (!p_conv_data)
+ {
+ /* First time, get info from conversation */
+ p_conv = find_conversation(&pinfo->net_dst, &pinfo->net_src,
+ pinfo->ptype,
+ pinfo->destport, pinfo->srcport, NO_ADDR_B);
+
+ if (p_conv)
+ {
+ /* Create space for packet info */
+ struct _rtcp_conversation_info *p_conv_packet_data;
+ p_conv_data = conversation_get_proto_data(p_conv, proto_rtcp);
+
+ /* Save this conversation info into packet info */
+ p_conv_packet_data = g_mem_chunk_alloc(rtcp_conversations);
+ strcpy(p_conv_packet_data->method, p_conv_data->method);
+ p_conv_packet_data->frame_number = p_conv_data->frame_number;
+ p_add_proto_data(pinfo->fd, proto_rtcp, p_conv_packet_data);
+ }
+ }
+
+ /* Create setup info subtree with summary info. */
+ if (p_conv_data)
+ {
+ proto_tree *rtcp_setup_tree;
+ proto_item *ti = proto_tree_add_string_format(tree, hf_rtcp_setup, tvb, 0, 0,
+ "",
+ "Stream setup by %s (frame %d)",
+ p_conv_data->method,
+ p_conv_data->frame_number);
+ PROTO_ITEM_SET_GENERATED(ti);
+ rtcp_setup_tree = proto_item_add_subtree(ti, ett_rtcp_setup);
+ if (rtcp_setup_tree)
+ {
+ /* Add details into subtree */
+ proto_item* item = proto_tree_add_uint(rtcp_setup_tree, hf_rtcp_setup_frame,
+ tvb, 0, 0, p_conv_data->frame_number);
+ PROTO_ITEM_SET_GENERATED(item);
+ item = proto_tree_add_string(rtcp_setup_tree, hf_rtcp_setup_method,
+ tvb, 0, 0, p_conv_data->method);
+ PROTO_ITEM_SET_GENERATED(item);
+ }
+ }
+}
+
+
+static void
dissect_rtcp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree )
{
proto_item *ti = NULL;
unsigned int packet_type = 0;
unsigned int offset = 0;
guint16 packet_length = 0;
+ guint rtcp_subtype = 0;
- CHECK_DISPLAY_AS_X(data_handle,proto_rtcp, tvb, pinfo, tree);
-
- pinfo->current_proto = "RTCP";
-
- if ( check_col( pinfo->fd, COL_PROTOCOL ) ) {
- col_set_str( pinfo->fd, COL_PROTOCOL, "RTCP" );
+ if ( check_col( pinfo->cinfo, COL_PROTOCOL ) ) {
+ col_set_str( pinfo->cinfo, COL_PROTOCOL, "RTCP" );
}
-
- if ( check_col( pinfo->fd, COL_INFO) ) {
+
+ if ( check_col( pinfo->cinfo, COL_INFO) ) {
/* The second octet contains the packet type */
/* switch ( pd[ offset + 1 ] ) { */
switch ( tvb_get_guint8( tvb, 1 ) ) {
case RTCP_SR:
- col_set_str( pinfo->fd, COL_INFO, "Sender Report");
+ col_set_str( pinfo->cinfo, COL_INFO, "Sender Report");
break;
case RTCP_RR:
- col_set_str( pinfo->fd, COL_INFO, "Receiver Report");
+ col_set_str( pinfo->cinfo, COL_INFO, "Receiver Report");
break;
case RTCP_SDES:
- col_set_str( pinfo->fd, COL_INFO, "Source Description");
+ col_set_str( pinfo->cinfo, COL_INFO, "Source Description");
break;
case RTCP_BYE:
- col_set_str( pinfo->fd, COL_INFO, "Goodbye");
+ col_set_str( pinfo->cinfo, COL_INFO, "Goodbye");
break;
case RTCP_APP:
- col_set_str( pinfo->fd, COL_INFO, "Application defined");
+ col_set_str( pinfo->cinfo, COL_INFO, "Application defined");
+ break;
+ case RTCP_XR:
+ col_set_str( pinfo->cinfo, COL_INFO, "Extended report");
break;
case RTCP_FIR:
- col_set_str( pinfo->fd, COL_INFO, "Full Intra-frame Request (H.261)");
+ col_set_str( pinfo->cinfo, COL_INFO, "Full Intra-frame Request (H.261)");
break;
case RTCP_NACK:
- col_set_str( pinfo->fd, COL_INFO, "Negative Acknowledgement (H.261)");
+ col_set_str( pinfo->cinfo, COL_INFO, "Negative Acknowledgement (H.261)");
break;
default:
- col_set_str( pinfo->fd, COL_INFO, "Unknown packet type");
+ col_set_str( pinfo->cinfo, COL_INFO, "Unknown packet type");
break;
}
}
if ( tree ) {
-
- /*
- * Check if there are at least 4 bytes left in the frame,
- * the last 16 bits of those is the length of the current
+ /*
+ * Check if there are at least 4 bytes left in the frame,
+ * the last 16 bits of those is the length of the current
* RTCP message. The last compound message contains padding,
* that enables us to break from the while loop.
*/
while ( tvb_bytes_exist( tvb, offset, 4) ) {
- /*
+ /*
* First retreive the packet_type
*/
packet_type = tvb_get_guint8( tvb, offset + 1 );
*/
if ( ( packet_type < 192 ) || ( packet_type > 204 ) )
break;
-
+
/*
* get the packet-length for the complete RTCP packet
*/
packet_length = ( tvb_get_ntohs( tvb, offset + 2 ) + 1 ) * 4;
- ti = proto_tree_add_item(tree, proto_rtcp, tvb, offset, packet_length, FALSE );
+ ti = proto_tree_add_item(tree, proto_rtcp, tvb, offset, packet_length, FALSE );
rtcp_tree = proto_item_add_subtree( ti, ett_rtcp );
+
+ /* Conversation setup info */
+ if (global_rtcp_show_setup_info)
+ {
+ show_setup_info(tvb, pinfo, rtcp_tree);
+ }
+
+
temp_byte = tvb_get_guint8( tvb, offset );
proto_tree_add_uint( rtcp_tree, hf_rtcp_version, tvb,
- offset, 1, RTCP_VERSION( temp_byte ) );
+ offset, 1, temp_byte);
padding_set = RTCP_PADDING( temp_byte );
proto_tree_add_boolean( rtcp_tree, hf_rtcp_padding, tvb,
- offset, 1, padding_set );
+ offset, 1, temp_byte );
elem_count = RTCP_COUNT( temp_byte );
switch ( packet_type ) {
case RTCP_SR:
case RTCP_RR:
/* Receiver report count, 5 bits */
- proto_tree_add_uint( rtcp_tree, hf_rtcp_rc, tvb, offset, 1, elem_count );
+ proto_tree_add_uint( rtcp_tree, hf_rtcp_rc, tvb, offset, 1, temp_byte );
offset++;
/* Packet type, 8 bits */
proto_tree_add_item( rtcp_tree, hf_rtcp_pt, tvb, offset, 1, FALSE );
proto_tree_add_uint( rtcp_tree, hf_rtcp_ssrc_sender, tvb, offset, 4, tvb_get_ntohl( tvb, offset ) );
offset += 4;
- if ( packet_type == RTCP_SR ) offset = dissect_rtcp_sr( tvb, offset, pinfo->fd, rtcp_tree, elem_count );
- else offset = dissect_rtcp_rr( tvb, offset, pinfo->fd, rtcp_tree, elem_count );
+ if ( packet_type == RTCP_SR ) offset = dissect_rtcp_sr( tvb, offset, rtcp_tree, elem_count );
+ else offset = dissect_rtcp_rr( tvb, offset, rtcp_tree, elem_count );
break;
case RTCP_SDES:
/* Source count, 5 bits */
- proto_tree_add_uint( rtcp_tree, hf_rtcp_sc, tvb, offset, 1, elem_count );
+ proto_tree_add_uint( rtcp_tree, hf_rtcp_sc, tvb, offset, 1, temp_byte );
offset++;
/* Packet type, 8 bits */
proto_tree_add_item( rtcp_tree, hf_rtcp_pt, tvb, offset, 1, FALSE );
/* Packet length in 32 bit words MINUS one, 16 bits */
proto_tree_add_uint( rtcp_tree, hf_rtcp_length, tvb, offset, 2, tvb_get_ntohs( tvb, offset ) );
offset += 2;
- offset = dissect_rtcp_sdes( tvb, offset, pinfo->fd, rtcp_tree, elem_count );
+ dissect_rtcp_sdes( tvb, offset, rtcp_tree, elem_count );
+ offset += packet_length - 4;
break;
case RTCP_BYE:
/* Source count, 5 bits */
- proto_tree_add_uint( rtcp_tree, hf_rtcp_sc, tvb, offset, 1, elem_count );
+ proto_tree_add_uint( rtcp_tree, hf_rtcp_sc, tvb, offset, 1, temp_byte );
offset++;
/* Packet type, 8 bits */
proto_tree_add_item( rtcp_tree, hf_rtcp_pt, tvb, offset, 1, FALSE );
/* Packet length in 32 bit words MINUS one, 16 bits */
proto_tree_add_uint( rtcp_tree, hf_rtcp_length, tvb, offset, 2, tvb_get_ntohs( tvb, offset ) );
offset += 2;
- offset = dissect_rtcp_bye( tvb, offset, pinfo->fd, rtcp_tree, elem_count );
+ offset = dissect_rtcp_bye( tvb, offset, rtcp_tree, elem_count );
break;
case RTCP_APP:
/* Subtype, 5 bits */
+ rtcp_subtype = elem_count;
proto_tree_add_uint( rtcp_tree, hf_rtcp_subtype, tvb, offset, 1, elem_count );
offset++;
/* Packet type, 8 bits */
/* Packet length in 32 bit words MINUS one, 16 bits */
proto_tree_add_uint( rtcp_tree, hf_rtcp_length, tvb, offset, 2, tvb_get_ntohs( tvb, offset ) );
offset += 2;
- offset = dissect_rtcp_app( tvb, offset,
- pinfo->fd, rtcp_tree, padding_set,
- packet_length - 4 );
+ offset = dissect_rtcp_app( tvb, pinfo, offset,
+ rtcp_tree, padding_set,
+ packet_length - 4, rtcp_subtype );
break;
case RTCP_FIR:
- offset = dissect_rtcp_fir( tvb, offset, pinfo->fd, rtcp_tree );
+ offset = dissect_rtcp_fir( tvb, offset, rtcp_tree );
break;
case RTCP_NACK:
- offset = dissect_rtcp_nack( tvb, offset, pinfo->fd, rtcp_tree );
+ offset = dissect_rtcp_nack( tvb, offset, rtcp_tree );
break;
default:
/*
break;
}
}
- /* If the padding bit is set, the last octet of the
- * packet contains the length of the padding
+ /* If the padding bit is set, the last octet of the
+ * packet contains the length of the padding
* We only have to check for this at the end of the LAST RTCP message
*/
if ( padding_set ) {
- /* If everything went according to plan offset should now point to the
- * first octet of the padding
+ /* If everything went according to plan offset should now point to the
+ * first octet of the padding
*/
proto_tree_add_item( rtcp_tree, hf_rtcp_padding_data, tvb, offset, tvb_length_remaining( tvb, offset) - 1, FALSE );
offset += tvb_length_remaining( tvb, offset) - 1;
void
proto_register_rtcp(void)
{
- static hf_register_info hf[] =
+ static hf_register_info hf[] =
{
- {
+ {
&hf_rtcp_version,
- {
- "Version",
- "rtcp.version",
- FT_UINT8,
- BASE_DEC,
- VALS(rtcp_version_vals),
- 0x0,
- "", HFILL
+ {
+ "Version",
+ "rtcp.version",
+ FT_UINT8,
+ BASE_DEC,
+ VALS(rtcp_version_vals),
+ 0xC0,
+ "", HFILL
}
},
- {
+ {
&hf_rtcp_padding,
- {
- "Padding",
- "rtcp.padding",
- FT_BOOLEAN,
- BASE_NONE,
- NULL,
- 0x0,
- "", HFILL
+ {
+ "Padding",
+ "rtcp.padding",
+ FT_BOOLEAN,
+ 8,
+ NULL,
+ 0x20,
+ "", HFILL
}
},
- {
+ {
&hf_rtcp_rc,
- {
- "Reception report count",
- "rtcp.rc",
- FT_UINT8,
- BASE_DEC,
- NULL,
- 0x0,
- "", HFILL
+ {
+ "Reception report count",
+ "rtcp.rc",
+ FT_UINT8,
+ BASE_DEC,
+ NULL,
+ 0x1F,
+ "", HFILL
}
},
- {
+ {
&hf_rtcp_sc,
- {
- "Source count",
- "rtcp.sc",
- FT_UINT8,
- BASE_DEC,
- NULL,
- 0x0,
- "", HFILL
+ {
+ "Source count",
+ "rtcp.sc",
+ FT_UINT8,
+ BASE_DEC,
+ NULL,
+ 0x1F,
+ "", HFILL
}
},
- {
+ {
&hf_rtcp_pt,
- {
- "Packet type",
- "rtcp.pt",
- FT_UINT8,
- BASE_DEC,
- VALS( rtcp_packet_type_vals ),
+ {
+ "Packet type",
+ "rtcp.pt",
+ FT_UINT8,
+ BASE_DEC,
+ VALS( rtcp_packet_type_vals ),
0x0,
- "", HFILL
+ "", HFILL
}
},
- {
+ {
&hf_rtcp_length,
- {
- "Length",
- "rtcp.length",
- FT_UINT16,
- BASE_DEC,
- NULL,
+ {
+ "Length",
+ "rtcp.length",
+ FT_UINT16,
+ BASE_DEC,
+ NULL,
0x0,
- "", HFILL
+ "", HFILL
}
},
- {
+ {
&hf_rtcp_ssrc_sender,
- {
- "Sender SSRC",
- "rtcp.senderssrc",
- FT_UINT32,
- BASE_DEC,
- NULL,
+ {
+ "Sender SSRC",
+ "rtcp.senderssrc",
+ FT_UINT32,
+ BASE_DEC,
+ NULL,
0x0,
- "", HFILL
+ "", HFILL
}
},
- {
+ {
&hf_rtcp_ntp,
- {
- "NTP timestamp",
- "rtcp.timestamp.ntp",
- FT_STRING,
- BASE_NONE,
- NULL,
+ {
+ "NTP timestamp",
+ "rtcp.timestamp.ntp",
+ FT_STRING,
+ BASE_NONE,
+ NULL,
0x0,
- "", HFILL
+ "", HFILL
}
},
- {
+ {
&hf_rtcp_rtp_timestamp,
- {
- "RTP timestamp",
- "rtcp.timestamp.rtp",
- FT_UINT32,
- BASE_DEC,
- NULL,
+ {
+ "RTP timestamp",
+ "rtcp.timestamp.rtp",
+ FT_UINT32,
+ BASE_DEC,
+ NULL,
0x0,
- "", HFILL
+ "", HFILL
}
},
- {
+ {
&hf_rtcp_sender_pkt_cnt,
- {
- "Sender's packet count",
- "rtcp.sender.packetcount",
- FT_UINT32,
- BASE_DEC,
- NULL,
+ {
+ "Sender's packet count",
+ "rtcp.sender.packetcount",
+ FT_UINT32,
+ BASE_DEC,
+ NULL,
0x0,
- "", HFILL
+ "", HFILL
}
},
- {
+ {
&hf_rtcp_sender_oct_cnt,
- {
- "Sender's octet count",
- "rtcp.sender.octetcount",
- FT_UINT32,
- BASE_DEC,
- NULL,
+ {
+ "Sender's octet count",
+ "rtcp.sender.octetcount",
+ FT_UINT32,
+ BASE_DEC,
+ NULL,
0x0,
- "", HFILL
+ "", HFILL
}
},
- {
+ {
&hf_rtcp_ssrc_source,
- {
- "Identifier",
- "rtcp.ssrc.identifier",
- FT_UINT32,
- BASE_DEC,
- NULL,
+ {
+ "Identifier",
+ "rtcp.ssrc.identifier",
+ FT_UINT32,
+ BASE_DEC,
+ NULL,
0x0,
- "", HFILL
+ "", HFILL
}
},
- {
+ {
&hf_rtcp_ssrc_fraction,
- {
- "Fraction lost",
- "rtcp.ssrc.fraction",
- FT_UINT8,
- BASE_DEC,
- NULL,
+ {
+ "Fraction lost",
+ "rtcp.ssrc.fraction",
+ FT_UINT8,
+ BASE_DEC,
+ NULL,
0x0,
- "", HFILL
+ "", HFILL
}
},
- {
+ {
&hf_rtcp_ssrc_cum_nr,
- {
- "Cumulative number of packets lost",
- "rtcp.ssrc.cum_nr",
- FT_UINT32,
- BASE_DEC,
- NULL,
+ {
+ "Cumulative number of packets lost",
+ "rtcp.ssrc.cum_nr",
+ FT_UINT32,
+ BASE_DEC,
+ NULL,
0x0,
- "", HFILL
+ "", HFILL
}
},
- {
+ {
&hf_rtcp_ssrc_ext_high_seq,
- {
- "Extended highest sequence number received",
- "rtcp.ssrc.ext_high",
- FT_UINT32,
- BASE_DEC,
- NULL,
+ {
+ "Extended highest sequence number received",
+ "rtcp.ssrc.ext_high",
+ FT_UINT32,
+ BASE_DEC,
+ NULL,
0x0,
- "", HFILL
+ "", HFILL
}
},
- {
+ {
&hf_rtcp_ssrc_high_seq,
- {
- "Highest sequence number received",
- "rtcp.ssrc.high_seq",
- FT_UINT16,
- BASE_DEC,
- NULL,
+ {
+ "Highest sequence number received",
+ "rtcp.ssrc.high_seq",
+ FT_UINT16,
+ BASE_DEC,
+ NULL,
0x0,
- "", HFILL
+ "", HFILL
}
},
- {
+ {
&hf_rtcp_ssrc_high_cycles,
- {
- "Sequence number cycles count",
- "rtcp.ssrc.high_cycles",
- FT_UINT16,
- BASE_DEC,
- NULL,
+ {
+ "Sequence number cycles count",
+ "rtcp.ssrc.high_cycles",
+ FT_UINT16,
+ BASE_DEC,
+ NULL,
0x0,
- "", HFILL
+ "", HFILL
}
},
- {
+ {
&hf_rtcp_ssrc_jitter,
- {
- "Interarrival jitter",
- "rtcp.ssrc.jitter",
- FT_UINT32,
- BASE_DEC,
- NULL,
+ {
+ "Interarrival jitter",
+ "rtcp.ssrc.jitter",
+ FT_UINT32,
+ BASE_DEC,
+ NULL,
0x0,
- "", HFILL
+ "", HFILL
}
},
- {
+ {
&hf_rtcp_ssrc_lsr,
- {
- "Last SR timestamp",
- "rtcp.ssrc.lsr",
- FT_UINT32,
- BASE_DEC,
- NULL,
+ {
+ "Last SR timestamp",
+ "rtcp.ssrc.lsr",
+ FT_UINT32,
+ BASE_DEC,
+ NULL,
0x0,
- "", HFILL
+ "", HFILL
}
},
- {
+ {
&hf_rtcp_ssrc_dlsr,
- {
- "Delay since last SR timestamp",
- "rtcp.ssrc.dlsr",
- FT_UINT32,
- BASE_DEC,
- NULL,
+ {
+ "Delay since last SR timestamp",
+ "rtcp.ssrc.dlsr",
+ FT_UINT32,
+ BASE_DEC,
+ NULL,
0x0,
- "", HFILL
+ "", HFILL
}
},
- {
+ {
&hf_rtcp_ssrc_csrc,
- {
- "SSRC / CSRC identifier",
- "rtcp.sdes.ssrc_csrc",
- FT_UINT32,
- BASE_DEC,
- NULL,
+ {
+ "SSRC / CSRC identifier",
+ "rtcp.sdes.ssrc_csrc",
+ FT_UINT32,
+ BASE_DEC,
+ NULL,
0x0,
- "", HFILL
+ "", HFILL
}
},
- {
+ {
&hf_rtcp_ssrc_type,
- {
- "Type",
- "rtcp.sdes.type",
- FT_UINT8,
- BASE_DEC,
- VALS( rtcp_sdes_type_vals ),
+ {
+ "Type",
+ "rtcp.sdes.type",
+ FT_UINT8,
+ BASE_DEC,
+ VALS( rtcp_sdes_type_vals ),
0x0,
- "", HFILL
+ "", HFILL
}
},
- {
+ {
&hf_rtcp_ssrc_length,
- {
- "Length",
- "rtcp.sdes.length",
- FT_UINT32,
- BASE_DEC,
- NULL,
+ {
+ "Length",
+ "rtcp.sdes.length",
+ FT_UINT32,
+ BASE_DEC,
+ NULL,
0x0,
- "", HFILL
+ "", HFILL
}
},
- {
+ {
&hf_rtcp_ssrc_text,
- {
- "Text",
- "rtcp.sdes.text",
- FT_STRING,
- BASE_NONE,
- NULL,
+ {
+ "Text",
+ "rtcp.sdes.text",
+ FT_STRING,
+ BASE_NONE,
+ NULL,
0x0,
- "", HFILL
+ "", HFILL
}
},
- {
+ {
&hf_rtcp_ssrc_prefix_len,
- {
- "Prefix length",
- "rtcp.sdes.prefix.length",
- FT_UINT8,
- BASE_DEC,
- NULL,
+ {
+ "Prefix length",
+ "rtcp.sdes.prefix.length",
+ FT_UINT8,
+ BASE_DEC,
+ NULL,
0x0,
- "", HFILL
+ "", HFILL
}
},
- {
+ {
&hf_rtcp_ssrc_prefix_string,
- {
- "Prefix string",
- "rtcp.sdes.prefix.string",
- FT_STRING,
- BASE_NONE,
- NULL,
+ {
+ "Prefix string",
+ "rtcp.sdes.prefix.string",
+ FT_STRING,
+ BASE_NONE,
+ NULL,
0x0,
- "", HFILL
+ "", HFILL
}
},
- {
+ {
&hf_rtcp_subtype,
- {
- "Subtype",
- "rtcp.app.subtype",
- FT_UINT8,
- BASE_DEC,
- NULL,
+ {
+ "Subtype",
+ "rtcp.app.subtype",
+ FT_UINT8,
+ BASE_DEC,
+ NULL,
0x0,
- "", HFILL
+ "", HFILL
}
},
- {
+ {
&hf_rtcp_name_ascii,
- {
- "Name (ASCII)",
- "rtcp.app.name",
- FT_STRING,
- BASE_NONE,
- NULL,
+ {
+ "Name (ASCII)",
+ "rtcp.app.name",
+ FT_STRING,
+ BASE_NONE,
+ NULL,
0x0,
- "", HFILL
+ "", HFILL
}
},
- {
+ {
&hf_rtcp_app_data,
- {
- "Application specific data",
- "rtcp.app.data",
- FT_BYTES,
- BASE_NONE,
- NULL,
+ {
+ "Application specific data",
+ "rtcp.app.data",
+ FT_BYTES,
+ BASE_NONE,
+ NULL,
+ 0x0,
+ "", HFILL
+ }
+ },
+ {
+ &hf_rtcp_app_poc1_subtype,
+ {
+ "Subtype",
+ "rtcp.app.PoC1.subtype",
+ FT_UINT8,
+ BASE_DEC,
+ VALS(rtcp_app_poc1_floor_cnt_type_vals),
+ 0x0,
+ "", HFILL
+ }
+ },
+ {
+ &hf_rtcp_app_poc1_sip_uri,
+ {
+ "SIP URI",
+ "rtcp.app.poc1.sip.uri",
+ FT_STRING,
+ BASE_NONE,
+ NULL,
+ 0x0,
+ "", HFILL
+ }
+ },
+ {
+ &hf_rtcp_app_poc1_disp_name,
+ {
+ "Display Name",
+ "rtcp.app.poc1.disp.name",
+ FT_STRING,
+ BASE_NONE,
+ NULL,
+ 0x0,
+ "", HFILL
+ }
+ },
+ {
+ &hf_rtcp_app_poc1_last_pkt_seq_no,
+ {
+ "Seq. no of last RTP packet",
+ "rtcp.app.poc1.last.pkt.seq.no",
+ FT_UINT16,
+ BASE_DEC,
+ NULL,
+ 0x0,
+ "", HFILL
+ }
+ },
+ {
+ &hf_rtcp_app_poc1_reason_code1,
+ {
+ "Reason code",
+ "rtcp.app.poc1.reason.code",
+ FT_UINT8,
+ BASE_DEC,
+ VALS(rtcp_app_poc1_reason_code1_vals),
0x0,
- "", HFILL
+ "", HFILL
}
},
- {
+ {
+ &hf_rtcp_app_poc1_item_len,
+ {
+ "Item length",
+ "rtcp.app.poc1.item.len",
+ FT_UINT8,
+ BASE_DEC,
+ NULL,
+ 0x0,
+ "", HFILL
+ }
+ },
+ {
+ &hf_rtcp_app_poc1_reason1_phrase,
+ {
+ "Reason Phrase",
+ "rtcp.app.poc1.reason.phrase",
+ FT_STRING,
+ BASE_NONE,
+ NULL,
+ 0x0,
+ "", HFILL
+ }
+ },
+ {
+ &hf_rtcp_app_poc1_reason_code2,
+ {
+ "Reason code",
+ "rtcp.app.poc1.reason.code",
+ FT_UINT16,
+ BASE_DEC,
+ VALS(rtcp_app_poc1_reason_code2_vals),
+ 0x0,
+ "", HFILL
+ }
+ },
+ {
+ &hf_rtcp_app_poc1_additionalinfo,
+ {
+ "additional information",
+ "rtcp.app.poc1.add.info",
+ FT_UINT16,
+ BASE_DEC,
+ NULL,
+ 0x0,
+ "", HFILL
+ }
+ },
+ {
&hf_rtcp_fsn,
- {
- "First sequence number",
- "rtcp.nack.fsn",
- FT_UINT16,
- BASE_DEC,
- NULL,
+ {
+ "First sequence number",
+ "rtcp.nack.fsn",
+ FT_UINT16,
+ BASE_DEC,
+ NULL,
0x0,
- "", HFILL
+ "", HFILL
}
},
- {
+ {
&hf_rtcp_blp,
- {
- "Bitmask of following lost packets",
- "rtcp.nack.blp",
- FT_UINT16,
- BASE_DEC,
- NULL,
+ {
+ "Bitmask of following lost packets",
+ "rtcp.nack.blp",
+ FT_UINT16,
+ BASE_DEC,
+ NULL,
0x0,
- "", HFILL
+ "", HFILL
}
},
- {
+ {
&hf_rtcp_padding_count,
- {
- "Padding count",
- "rtcp.padding.count",
- FT_UINT8,
- BASE_DEC,
- NULL,
+ {
+ "Padding count",
+ "rtcp.padding.count",
+ FT_UINT8,
+ BASE_DEC,
+ NULL,
0x0,
- "", HFILL
+ "", HFILL
}
},
- {
+ {
&hf_rtcp_padding_data,
- {
- "Padding data",
- "rtcp.padding.data",
- FT_BYTES,
- BASE_NONE,
- NULL,
+ {
+ "Padding data",
+ "rtcp.padding.data",
+ FT_BYTES,
+ BASE_NONE,
+ NULL,
0x0,
- "", HFILL
+ "", HFILL
}
},
-};
-
- static gint *ett[] =
+ {
+ &hf_rtcp_setup,
+ {
+ "Stream setup",
+ "rtcp.setup",
+ FT_STRING,
+ BASE_NONE,
+ NULL,
+ 0x0,
+ "Stream setup, method and frame number", HFILL
+ }
+ },
+ {
+ &hf_rtcp_setup_frame,
+ {
+ "Setup frame",
+ "rtcp.setup-frame",
+ FT_FRAMENUM,
+ BASE_NONE,
+ NULL,
+ 0x0,
+ "Frame that set up this stream", HFILL
+ }
+ },
+ {
+ &hf_rtcp_setup_method,
+ {
+ "Setup Method",
+ "rtcp.setup-method",
+ FT_STRING,
+ BASE_NONE,
+ NULL,
+ 0x0,
+ "Method used to set up this stream", HFILL
+ }
+ }
+
+ };
+
+ static gint *ett[] =
{
&ett_rtcp,
&ett_ssrc,
&ett_ssrc_ext_high,
&ett_sdes,
&ett_sdes_item,
+ &ett_PoC1,
+ &ett_rtcp_setup
};
+ module_t *rtcp_module;
proto_rtcp = proto_register_protocol("Real-time Transport Control Protocol",
"RTCP", "rtcp");
register_dissector("rtcp", dissect_rtcp, proto_rtcp);
-#if 0
+ rtcp_module = prefs_register_protocol(proto_rtcp, NULL);
+
+ prefs_register_bool_preference(rtcp_module, "show_setup_info",
+ "Show stream setup information",
+ "Where available, show which protocol and frame caused "
+ "this RTCP stream to be created",
+ &global_rtcp_show_setup_info);
+
register_init_routine( &rtcp_init );
-#endif
}
void
proto_reg_handoff_rtcp(void)
{
- data_handle = find_dissector("data");
/*
- * Register this dissector as one that can be assigned to a
- * UDP conversation.
+ * Register this dissector as one that can be selected by a
+ * UDP port number.
*/
- conv_dissector_add("udp", dissect_rtcp, proto_rtcp);
+ rtcp_handle = find_dissector("rtcp");
+ dissector_add_handle("udp.port", rtcp_handle);
}