aboutsummaryrefslogtreecommitdiffstats
path: root/packet-rtp.c
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2000-10-19 06:45:11 +0000
committerGuy Harris <guy@alum.mit.edu>2000-10-19 06:45:11 +0000
commit3f8b7cd0fc93040f23b1d1b0e061dc1097321f4e (patch)
treeb9eea74fb6b18aeb12b57161706786110421caa1 /packet-rtp.c
parent9de17c39f5e6828c6631af911d114f935b0feb4d (diff)
Andreas Sikkema's new H.261 and TPKT dissectors, replacement RTCP and
RTP dissectors, and changes to the Q.931 dissector for use with H.323. svn path=/trunk/; revision=2511
Diffstat (limited to 'packet-rtp.c')
-rw-r--r--packet-rtp.c708
1 files changed, 555 insertions, 153 deletions
diff --git a/packet-rtp.c b/packet-rtp.c
index 88ee2a15bc..6f6008b6ac 100644
--- a/packet-rtp.c
+++ b/packet-rtp.c
@@ -1,9 +1,10 @@
/* packet-rtp.c
- * Routines for RTP packet disassembly
*
- * Jason Lango <jal@netapp.com>
- *
- * $Id: packet-rtp.c,v 1.5 2000/08/13 14:08:43 deniel Exp $
+ * Routines for RTP dissection
+ * RTP = Real time Transport Protocol
+ *
+ * Copyright 2000, Philips Electronics N.V.
+ * Written by Andreas Sikkema <andreas.sikkema@philips.com>
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -23,195 +24,596 @@
* 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.
+ */
+
+/*
+ * This dissector tries to dissect the RTP protocol according to Annex A
+ * of ITU-T Recommendation H.225.0 (02/98) or RFC 1889
*
- *
+ * RTP traffic is handled by an even UDP portnumber. This can be any
+ * port number, but there is a registered port available, port 5004
+ * See Annex B of ITU-T Recommendation H.225.0, section B.7
*/
-#include "config.h"
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <glib.h>
+#include "packet.h"
#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
+# include <sys/types.h>
#endif
#ifdef HAVE_NETINET_IN_H
-#include <netinet/in.h>
+# include <netinet/in.h>
#endif
+#include <stdio.h>
#include <string.h>
-#include <ctype.h>
-#include <stddef.h>
-#include <glib.h>
-#include "packet.h"
#include "packet-rtp.h"
+#include "packet-h261.h"
+#include "conversation.h"
+
+/* RTP header fields */
+static int proto_rtp = -1;
+static int hf_rtp_version = -1;
+static int hf_rtp_padding = -1;
+static int hf_rtp_extension = -1;
+static int hf_rtp_csrc_count = -1;
+static int hf_rtp_marker = -1;
+static int hf_rtp_payload_type = -1;
+static int hf_rtp_seq_nr = -1;
+static int hf_rtp_timestamp = -1;
+static int hf_rtp_ssrc = -1;
+static int hf_rtp_csrc_item = -1;
+static int hf_rtp_data = -1;
+static int hf_rtp_padding_data = -1;
+static int hf_rtp_padding_count= -1;
+
+/* RTP header extension fields */
+static int hf_rtp_prof_define = -1;
+static int hf_rtp_length = -1;
+static int hf_rtp_hdr_ext = -1;
+
+/* RTP fields defining a sub tree */
+static gint ett_rtp = -1;
+static gint ett_csrc_list = -1;
+static gint ett_hdr_ext = -1;
+
+/*
+ * Fields in the first octet of the RTP header.
+ */
-static int proto_rtp = -1;
+/* Version is the first 2 bits of the first octet*/
+#define RTP_VERSION(octet) ((octet) >> 6)
-static gint ett_rtp = -1;
+/* Padding is the third bit; No need to shift, because true is any value
+ other than 0! */
+#define RTP_PADDING(octet) ((octet) & 0x20)
-#define _RTP_FLAG_BITS(hdr, s, n) \
- ((u_int)(((hdr)->rtp_flag_bits >> (8 - (s) - (n))) & ((1 << (n)) - 1)))
-#define RTP_VERSION(hdr) _RTP_FLAG_BITS(hdr, 0, 2)
-#define RTP_PADDING(hdr) _RTP_FLAG_BITS(hdr, 2, 1)
-#define RTP_EXTENSION(hdr) _RTP_FLAG_BITS(hdr, 3, 1)
-#define RTP_CSRC_COUNT(hdr) _RTP_FLAG_BITS(hdr, 4, 4)
+/* Extension bit is the fourth bit */
+#define RTP_EXTENSION(octet) ((octet) & 0x10)
-#define RTP_MARKER(hdr) ((u_int)((hdr)->rtp_type_bits >> 7))
-#define RTP_PAYLOAD_TYPE(hdr) ((u_int)((hdr)->rtp_type_bits & 0x7F))
+/* CSRC count is the last four bits */
+#define RTP_CSRC_COUNT(octet) ((octet) & 0xF)
-typedef struct rtp_hdr {
- guint8 rtp_flag_bits;
- guint8 rtp_type_bits;
- guint16 rtp_seq;
- guint32 rtp_timestamp;
- guint32 rtp_ssrc;
-} rtp_hdr_t;
+static const value_string rtp_version_vals[] =
+{
+ { 0, "Old VAT Version" },
+ { 1, "First Draft Version" },
+ { 2, "RFC 1889 Version" },
+ { 0, NULL },
+};
+
+/*
+ * Fields in the second octet of the RTP header.
+ */
-typedef struct rtp_hdr_ext {
- guint16 rtp_ext_app; /* defined by RTP profile */
- guint16 rtp_ext_length; /* length of extension data in 32 bit words */
-} rtp_hdr_ext_t;
+/* Marker is the first bit of the second octet */
+#define RTP_MARKER(octet) ((octet) & 0x80)
-void
-dissect_rtp(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
+/* Payload type is the last 7 bits */
+#define RTP_PAYLOAD_TYPE(octet) ((octet) & 0x7F)
+
+/*
+ * RTP Payload types
+ * Table B.2 / H.225.0
+ */
+#define PT_PCMU 0
+#define PT_PCMA 8
+#define PT_G722 9
+#define PT_G723 4
+#define PT_G728 15
+#define PT_G729 18
+#define PT_H261 31
+#define PT_H263 34
+
+static const value_string rtp_payload_type_vals[] =
+{
+ { PT_PCMU, "ITU-T G.711 PCMU" },
+ { PT_PCMA, "ITU-T G.711 PCMA" },
+ { PT_G722, "ITU-T G.722" },
+ { PT_G723, "ITU-T G.723" },
+ { PT_G728, "ITU-T G.728" },
+ { PT_G729, "ITU-T G.729" },
+ { PT_H261, "ITU-T H.261" },
+ { PT_H263, "ITU-T H.263" },
+ { 0, NULL },
+};
+
+static address fake_addr;
+static int heur_init = FALSE;
+
+static const char rtp_proto[] = "RTP";
+
+void rtp_add_address( const unsigned char* ip_addr, int prt )
{
- proto_tree *rtp_tree;
- proto_item *ti;
- const u_char *data, *dataend;
- rtp_hdr_t hdr;
- int end_offset;
- int ii;
- guint32 *csrc_ptr;
- rtp_hdr_ext_t ext;
-
- OLD_CHECK_DISPLAY_AS_DATA(proto_rtp, pd, offset, fd, tree);
-
- data = &pd[offset];
- dataend = data + END_OF_FRAME;
- end_offset = offset + END_OF_FRAME;
-
- memcpy(&hdr, data, END_OF_FRAME < sizeof(rtp_hdr_t) ?
- END_OF_FRAME : sizeof(rtp_hdr_t));
- hdr.rtp_seq = ntohs(hdr.rtp_seq);
- hdr.rtp_timestamp = ntohl(hdr.rtp_timestamp);
- hdr.rtp_ssrc = ntohl(hdr.rtp_ssrc);
-
- if (check_col(fd, COL_PROTOCOL))
- col_add_str(fd, COL_PROTOCOL, "RTP");
- if (check_col(fd, COL_INFO)) {
- col_add_fstr(fd, COL_INFO, "SSRC=%lu, Seq=%u, Time=%lu%s",
- (u_long) hdr.rtp_ssrc,
- (u_int) hdr.rtp_seq,
- (u_long) hdr.rtp_timestamp,
- RTP_MARKER(&hdr) ? ", Mark" : "");
+ address src_addr;
+ conversation_t* pconv = ( conversation_t* ) NULL;
+
+ src_addr.type = AT_IPv4;
+ src_addr.len = 4;
+ src_addr.data = ip_addr;
+
+ /*
+ * The first time the function is called let the tcp dissector
+ * know that we're interested in traffic
+ */
+ if ( ! heur_init ) {
+ heur_dissector_add( "udp", dissect_rtp_heur );
+ heur_init = TRUE;
}
- rtp_tree = NULL;
+ /*
+ * Check if the ip address an dport combination is not
+ * already registered
+ */
+ pconv = find_conversation( &src_addr, &fake_addr, PT_UDP, prt, 0 );
+
+ /*
+ * If not, add
+ */
+ if ( ! pconv ) {
+ conversation_new( &src_addr, &fake_addr, PT_UDP, (guint32) prt, (guint32) 0, ( void * ) rtp_proto );
+ }
+
+}
+
+#if 0
+static void rtp_init( void )
+{
+ unsigned char* tmp_data;
+ int i;
+
+ /* Create a fake adddress... */
+ fake_addr.type = AT_IPv4;
+ fake_addr.len = 4;
- if (tree) {
- ti = proto_tree_add_item(tree, proto_rtp, NullTVB, offset, END_OF_FRAME,
- FALSE);
- rtp_tree = proto_item_add_subtree(ti, ett_rtp);
+ tmp_data = malloc( fake_addr.len );
+ for ( i = 0; i < fake_addr.len; i++) {
+ tmp_data[i] = 0;
}
+ fake_addr.data = tmp_data;
+}
+#endif
- if (!rtp_tree)
- return;
-
- if (offset >= end_offset)
- goto bad_len;
- proto_tree_add_text(rtp_tree, NullTVB, offset, 1, "Version: %u (%s)",
- RTP_VERSION(&hdr),
- RTP_VERSION(&hdr) == 3 ? "New Unknown Version" :
- RTP_VERSION(&hdr) == 2 ? "RFC 1889 Version" :
- RTP_VERSION(&hdr) == 1 ? "First Draft Version" :
- "Old Vat Version");
- proto_tree_add_text(rtp_tree, NullTVB, offset, 1, "Padding: %u",
- RTP_PADDING(&hdr));
- proto_tree_add_text(rtp_tree, NullTVB, offset, 1, "Extension: %u",
- RTP_EXTENSION(&hdr));
- proto_tree_add_text(rtp_tree, NullTVB, offset, 1, "CSRC Count: %u",
- RTP_CSRC_COUNT(&hdr));
- offset++;
-
- if (offset >= end_offset)
- goto bad_len;
- proto_tree_add_text(rtp_tree, NullTVB, offset, 1, "Marker: %u",
- RTP_MARKER(&hdr));
- proto_tree_add_text(rtp_tree, NullTVB, offset, 1, "Payload Type: %u",
- RTP_PAYLOAD_TYPE(&hdr));
- offset++;
-
- if (offset >= end_offset)
- goto bad_len;
- proto_tree_add_text(rtp_tree, NullTVB, offset, 2, "Seq: %u",
- (u_int) hdr.rtp_seq);
- offset += 2;
-
- if (offset >= end_offset)
- goto bad_len;
- proto_tree_add_text(rtp_tree, NullTVB, offset, 4, "Timestamp: %lu",
- (u_long) hdr.rtp_timestamp);
- offset += 4;
-
- if (offset >= end_offset)
- goto bad_len;
- proto_tree_add_text(rtp_tree, NullTVB, offset, 4, "SSRC: %lu",
- (u_long) hdr.rtp_ssrc);
- offset += 4;
-
- csrc_ptr = (guint32*) (data + sizeof(rtp_hdr_t));
- for (ii = 0; ii < RTP_CSRC_COUNT(&hdr); ii++) {
- guint32 csrc;
- if (offset >= end_offset)
- goto bad_len;
- csrc = pntohl(csrc_ptr);
- proto_tree_add_text(rtp_tree, NullTVB, offset, 4, "CSRC %d: %lu",
- ii + 1, (u_long) csrc);
- offset += 4;
- csrc_ptr++;
+gboolean
+dissect_rtp_heur( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree )
+{
+ /* This is a heuristic dissector, which means we get all the tcp traffic
+ * not send to a known dissector!
+ * So we first check if the frame is really meant for us.
+ */
+ conversation_t* pconv;
+ if ( ( pconv = find_conversation( &pi.src, &fake_addr, pi.ptype, pi.srcport, 0 ) ) == NULL ) {
+ /*
+ * The source ip:port combination was not what we were looking for, check the destination
+ */
+ if ( ( pconv = find_conversation( &pi.dst, &fake_addr, pi.ptype, pi.destport, 0 ) ) == NULL ) {
+ return FALSE;
+ }
}
- if (RTP_EXTENSION(&hdr)) {
- memcpy(&ext, data + sizeof(rtp_hdr_t),
- END_OF_FRAME < sizeof(rtp_hdr_ext_t) ?
- END_OF_FRAME : sizeof(rtp_hdr_ext_t));
- ext.rtp_ext_app = ntohs(ext.rtp_ext_app);
- ext.rtp_ext_length = ntohs(ext.rtp_ext_length);
+ /*
+ * An RTP conversation always contains data
+ */
+ if ( pconv->data == NULL )
+ return FALSE;
- proto_tree_add_text(rtp_tree, NullTVB, offset, 2,
- "Extension-defined: %x", (u_int) ext.rtp_ext_app);
- offset += 2;
- proto_tree_add_text(rtp_tree, NullTVB, offset, 2,
- "Extension length: %u", (u_int) ext.rtp_ext_length);
- offset += 2;
- proto_tree_add_text(rtp_tree, NullTVB, offset, 4 * ext.rtp_ext_length,
- "Extension Data (%d bytes)",
- (int) 4 * ext.rtp_ext_length);
- offset += 4 * ext.rtp_ext_length;
+ /*
+ * An RTP conversation data always contains "RTP"
+ */
+ if ( strcmp( pconv->data, rtp_proto ) != 0 )
+ return FALSE;
+
+ dissect_rtp( tvb, pinfo, tree );
+
+ return TRUE;
+}
+
+void
+dissect_rtp_data( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_tree *rtp_tree, int offset, unsigned int data_len, unsigned int payload_type )
+{
+ tvbuff_t *newtvb;
+
+ switch( payload_type ) {
+ case PT_H261:
+ /*
+ * What does reported length DO?
+ */
+ newtvb = tvb_new_subset( tvb, offset, data_len, -1 );
+ dissect_h261(newtvb, pinfo, tree);
+ break;
+ default:
+ proto_tree_add_bytes( rtp_tree, hf_rtp_data, tvb, offset, data_len, tvb_get_ptr( tvb, offset, data_len ) );
+ break;
}
+}
- proto_tree_add_text(rtp_tree, NullTVB, offset, END_OF_FRAME,
- "Data (%d bytes)", END_OF_FRAME);
+void
+dissect_rtp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree )
+{
+ proto_item *ti = NULL;
+ proto_tree *rtp_tree = NULL;
+ proto_tree *rtp_csrc_tree = NULL;
+ guint8 octet;
+ unsigned int version;
+ gboolean padding_set;
+ gboolean extension_set;
+ unsigned int csrc_count;
+ gboolean marker_set;
+ unsigned int payload_type;
+ unsigned int i = 0;
+ unsigned int hdr_extension= 0;
+ unsigned int padding_count= 0;
+ unsigned int offset = 0;
+ guint16 seq_num;
+ guint32 timestamp;
+ guint32 sync_src;
+ guint32 csrc_item;
+
+ pinfo->current_proto = "RTP";
+
+ /* Get the fields in the first octet */
+ octet = tvb_get_guint8( tvb, offset );
+ version = RTP_VERSION( octet );
+ padding_set = RTP_PADDING( octet );
+ extension_set = RTP_EXTENSION( octet );
+ csrc_count = RTP_CSRC_COUNT( octet );
+
+ /* Get the fields in the second octet */
+ octet = tvb_get_guint8( tvb, offset + 1 );
+ marker_set = RTP_MARKER( octet );
+ payload_type = RTP_PAYLOAD_TYPE( octet );
+
+ /* Get the subsequent fields */
+ seq_num = tvb_get_ntohs( tvb, offset + 2 );
+ timestamp = tvb_get_ntohl( tvb, offset + 4 );
+ sync_src = tvb_get_ntohl( tvb, offset + 8 );
+
+ if ( check_col( pinfo->fd, COL_PROTOCOL ) ) {
+ col_add_str( pinfo->fd, COL_PROTOCOL, "RTP" );
+ }
+
+ if ( check_col( pinfo->fd, COL_INFO) ) {
+ col_add_fstr( pinfo->fd, COL_INFO,
+ "Payload type=%s, SSRC=%u, Seq=%u, Time=%u%s",
+ val_to_str( payload_type, rtp_payload_type_vals,
+ "Unknown (%u)" ),
+ sync_src,
+ seq_num,
+ timestamp,
+ marker_set ? ", Mark" : "");
+ }
+
+ if ( tree ) {
+ ti = proto_tree_add_item( tree, proto_rtp, tvb, offset, tvb_length_remaining( tvb, offset ), FALSE );
+ rtp_tree = proto_item_add_subtree( ti, ett_rtp );
+
+ proto_tree_add_uint( rtp_tree, hf_rtp_version, tvb,
+ offset, 1, version );
+ proto_tree_add_boolean( rtp_tree, hf_rtp_padding, tvb,
+ offset, 1, padding_set );
+ proto_tree_add_boolean( rtp_tree, hf_rtp_extension, tvb,
+ offset, 1, extension_set );
+ proto_tree_add_uint( rtp_tree, hf_rtp_csrc_count, tvb,
+ offset, 1, csrc_count );
+ offset++;
+
+ proto_tree_add_boolean( rtp_tree, hf_rtp_marker, tvb, offset,
+ 1, marker_set );
+ proto_tree_add_uint( rtp_tree, hf_rtp_payload_type, tvb,
+ offset, 1, payload_type );
+ offset++;
+
+ /* Sequence number 16 bits (2 octets) */
+ proto_tree_add_uint( rtp_tree, hf_rtp_seq_nr, tvb, offset, 2, seq_num );
+ offset += 2;
+
+ /* Timestamp 32 bits (4 octets) */
+ proto_tree_add_uint( rtp_tree, hf_rtp_timestamp, tvb, offset, 4, timestamp );
+ offset += 4;
- return;
+ /* Synchronization source identifier 32 bits (4 octets) */
+ proto_tree_add_uint( rtp_tree, hf_rtp_ssrc, tvb, offset, 4, sync_src );
+ offset += 4;
-bad_len:
- proto_tree_add_text(rtp_tree, NullTVB, end_offset, 0,
- "Unexpected end of packet");
+ /* CSRC list*/
+ if ( csrc_count > 0 ) {
+ ti = proto_tree_add_text(rtp_tree, tvb, offset, csrc_count * 4, "Contributing Source identifiers");
+ rtp_csrc_tree = proto_item_add_subtree( ti, ett_csrc_list );
+ for (i = 0; i < csrc_count; i++ ) {
+ csrc_item = tvb_get_ntohl( tvb, offset );
+ proto_tree_add_uint_format( rtp_csrc_tree,
+ hf_rtp_csrc_item, tvb, offset, 4,
+ csrc_item,
+ "CSRC item %d: %u",
+ i, csrc_item );
+ offset += 4;
+ }
+ }
+
+ /* Optional RTP header extension */
+ if ( extension_set ) {
+ /* Defined by profile field is 16 bits (2 octets) */
+ proto_tree_add_uint( rtp_tree, hf_rtp_prof_define, tvb, offset, 2, tvb_get_ntohs( tvb, offset ) );
+ offset += 2;
+
+ hdr_extension = tvb_get_ntohs( tvb, offset );
+ proto_tree_add_uint( rtp_tree, hf_rtp_length, tvb,
+ offset, 2, hdr_extension);
+ if ( hdr_extension > 0 ) {
+ ti = proto_tree_add_text(rtp_tree, tvb, offset, csrc_count * 4, "Header extensions");
+ /* I'm re-using the old tree variable here
+ from the CSRC list!*/
+ rtp_csrc_tree = proto_item_add_subtree( ti,
+ ett_hdr_ext );
+ for (i = 0; i < hdr_extension; i++ ) {
+ proto_tree_add_uint( rtp_csrc_tree, hf_rtp_hdr_ext, tvb, offset, 4, tvb_get_ntohl( tvb, offset ) );
+ offset += 4;
+ }
+ }
+ }
+ /* Find the padding
+ * The padding count is found in the LAST octet of the packet
+ * This contains the number of octets that can be ignored at
+ * the end of the packet
+ */
+ if ( padding_set ) {
+ padding_count = tvb_get_guint8( tvb, tvb_length( tvb ) - 1 );
+ if ( padding_count > 0 ) {
+ dissect_rtp_data( tvb, pinfo, tree, rtp_tree, offset, tvb_length( tvb ) - padding_count, payload_type );
+ offset = tvb_length( tvb ) - padding_count;
+ proto_tree_add_item( rtp_tree, hf_rtp_padding_data, tvb, offset, padding_count - 1, FALSE );
+ offset += padding_count - 1;
+ proto_tree_add_item( rtp_tree, hf_rtp_padding_count, tvb, offset, 1, FALSE );
+ }
+ else {
+ proto_tree_add_item( rtp_tree, hf_rtp_padding_count, tvb, tvb_length( tvb ) - 1, 1, FALSE );
+ }
+ }
+ else {
+ dissect_rtp_data( tvb, pinfo, tree, rtp_tree, offset, tvb_length_remaining( tvb, offset ) - padding_count, payload_type );
+ }
+ }
}
void
proto_register_rtp(void)
{
-/* static hf_register_info hf[] = {
- { &variable,
- { "Name", "rtp.abbreviation", TYPE, VALS_POINTER }},
- };*/
- static gint *ett[] = {
+ static hf_register_info hf[] =
+ {
+ {
+ &hf_rtp_version,
+ {
+ "Version",
+ "rtp.version",
+ FT_UINT8,
+ BASE_DEC,
+ VALS(rtp_version_vals),
+ 0x0,
+ ""
+ }
+ },
+ {
+ &hf_rtp_padding,
+ {
+ "Padding",
+ "rtp.padding",
+ FT_BOOLEAN,
+ BASE_NONE,
+ NULL,
+ 0x0,
+ ""
+ }
+ },
+ {
+ &hf_rtp_extension,
+ {
+ "Extension",
+ "rtp.ext",
+ FT_BOOLEAN,
+ BASE_NONE,
+ NULL,
+ 0x0,
+ ""
+ }
+ },
+ {
+ &hf_rtp_csrc_count,
+ {
+ "Contributing source identifiers count",
+ "rtp.cc",
+ FT_UINT8,
+ BASE_DEC,
+ NULL,
+ 0x0,
+ ""
+ }
+ },
+ {
+ &hf_rtp_marker,
+ {
+ "Marker",
+ "rtp.marker",
+ FT_BOOLEAN,
+ BASE_NONE,
+ NULL,
+ 0x0,
+ ""
+ }
+ },
+ {
+ &hf_rtp_payload_type,
+ {
+ "Payload type",
+ "rtp.p_type",
+ FT_UINT8,
+ BASE_DEC,
+ VALS(rtp_payload_type_vals),
+ 0x0,
+ ""
+ }
+ },
+ {
+ &hf_rtp_seq_nr,
+ {
+ "Sequence number",
+ "rtp.seq",
+ FT_UINT16,
+ BASE_DEC,
+ NULL,
+ 0x0,
+ ""
+ }
+ },
+ {
+ &hf_rtp_timestamp,
+ {
+ "Timestamp",
+ "rtp.timestamp",
+ FT_UINT32,
+ BASE_DEC,
+ NULL,
+ 0x0,
+ ""
+ }
+ },
+ {
+ &hf_rtp_ssrc,
+ {
+ "Synchronization Source identifier",
+ "rtp.ssrc",
+ FT_UINT32,
+ BASE_DEC,
+ NULL,
+ 0x0,
+ ""
+ }
+ },
+ {
+ &hf_rtp_prof_define,
+ {
+ "Defined by profile",
+ "rtp.ext.profile",
+ FT_UINT16,
+ BASE_DEC,
+ NULL,
+ 0x0,
+ ""
+ }
+ },
+ {
+ &hf_rtp_length,
+ {
+ "Extension length",
+ "rtp.ext.len",
+ FT_UINT16,
+ BASE_DEC,
+ NULL,
+ 0x0,
+ ""
+ }
+ },
+ {
+ &hf_rtp_csrc_item,
+ {
+ "CSRC item",
+ "rtp.csrc.item",
+ FT_UINT32,
+ BASE_DEC,
+ NULL,
+ 0x0,
+ ""
+ }
+ },
+ {
+ &hf_rtp_hdr_ext,
+ {
+ "Header extension",
+ "rtp.hdr_ext",
+ FT_UINT32,
+ BASE_DEC,
+ NULL,
+ 0x0,
+ ""
+ }
+ },
+ {
+ &hf_rtp_data,
+ {
+ "Payload",
+ "rtp.payload",
+ FT_BYTES,
+ BASE_HEX,
+ NULL,
+ 0x0,
+ ""
+ }
+ },
+ {
+ &hf_rtp_padding_data,
+ {
+ "Padding data",
+ "rtp.padding.data",
+ FT_BYTES,
+ BASE_HEX,
+ NULL,
+ 0x0,
+ ""
+ }
+ },
+ {
+ &hf_rtp_padding_count,
+ {
+ "Padding count",
+ "rtp.padding.count",
+ FT_UINT8,
+ BASE_DEC,
+ NULL,
+ 0x0,
+ ""
+ }
+ },
+};
+
+ static gint *ett[] =
+ {
&ett_rtp,
+ &ett_csrc_list,
+ &ett_hdr_ext,
};
- proto_rtp = proto_register_protocol("Realtime Transport Protocol", "rtp");
- /* proto_register_field_array(proto_rtp, hf, array_length(hf));*/
+
+ proto_rtp = proto_register_protocol("Real-Time Transport Protocol", "rtp");
+ proto_register_field_array(proto_rtp, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
+
+#if 0
+ register_init_routine( &rtp_init );
+#endif
}