Don't include the header file to get the SNMP version unless we're
[obnox/wireshark/wip.git] / packet-rtp.c
1 /* packet-rtp.c
2  *
3  * Routines for RTP dissection
4  * RTP = Real time Transport Protocol
5  *
6  * Copyright 2000, Philips Electronics N.V.
7  * Written by Andreas Sikkema <andreas.sikkema@philips.com>
8  *
9  * $Id: packet-rtp.c,v 1.36 2002/08/28 21:00:30 jmayer Exp $
10  *
11  * Ethereal - Network traffic analyzer
12  * By Gerald Combs <gerald@ethereal.com>
13  * Copyright 1998 Gerald Combs
14  *
15  * This program is free software; you can redistribute it and/or
16  * modify it under the terms of the GNU General Public License
17  * as published by the Free Software Foundation; either version 2
18  * of the License, or (at your option) any later version.
19  *
20  * This program is distributed in the hope that it will be useful,
21  * but WITHOUT ANY WARRANTY; without even the implied warranty of
22  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23  * GNU General Public License for more details.
24  *
25  * You should have received a copy of the GNU General Public License
26  * along with this program; if not, write to the Free Software
27  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
28  */
29
30 /*
31  * This dissector tries to dissect the RTP protocol according to Annex A
32  * of ITU-T Recommendation H.225.0 (02/98) or RFC 1889
33  *
34  * RTP traffic is handled by an even UDP portnumber. This can be any
35  * port number, but there is a registered port available, port 5004
36  * See Annex B of ITU-T Recommendation H.225.0, section B.7
37  *
38  * This doesn't dissect older versions of RTP, such as:
39  *
40  *    the vat protocol ("version 0") - see
41  *
42  *      ftp://ftp.ee.lbl.gov/conferencing/vat/alpha-test/vatsrc-4.0b2.tar.gz
43  *
44  *    and look in "session-vat.cc" if you want to write a dissector
45  *    (have fun - there aren't any nice header files showing the packet
46  *    format);
47  *
48  *    version 1, as documented in
49  *
50  *      ftp://gaia.cs.umass.edu/pub/hgschulz/rtp/draft-ietf-avt-rtp-04.txt
51  */
52
53
54 #ifdef HAVE_CONFIG_H
55 # include "config.h"
56 #endif
57
58 #include <glib.h>
59 #include <epan/packet.h>
60
61 #include <stdio.h>
62 #include <string.h>
63
64 #include "packet-rtp.h"
65 #include <epan/conversation.h>
66
67 /* RTP header fields             */
68 static int proto_rtp           = -1;
69 static int hf_rtp_version      = -1;
70 static int hf_rtp_padding      = -1;
71 static int hf_rtp_extension    = -1;
72 static int hf_rtp_csrc_count   = -1;
73 static int hf_rtp_marker       = -1;
74 static int hf_rtp_payload_type = -1;
75 static int hf_rtp_seq_nr       = -1;
76 static int hf_rtp_timestamp    = -1;
77 static int hf_rtp_ssrc         = -1;
78 static int hf_rtp_csrc_item    = -1;
79 static int hf_rtp_data         = -1;
80 static int hf_rtp_padding_data = -1;
81 static int hf_rtp_padding_count= -1;
82
83 /* RTP header extension fields   */
84 static int hf_rtp_prof_define  = -1;
85 static int hf_rtp_length       = -1;
86 static int hf_rtp_hdr_ext      = -1;
87
88 /* RTP fields defining a sub tree */
89 static gint ett_rtp       = -1;
90 static gint ett_csrc_list = -1;
91 static gint ett_hdr_ext   = -1;
92
93 static dissector_handle_t h261_handle;
94 static dissector_handle_t mpeg1_handle;
95 static dissector_handle_t data_handle;
96
97 static gboolean dissect_rtp_heur( tvbuff_t *tvb, packet_info *pinfo,
98     proto_tree *tree );
99 static void dissect_rtp( tvbuff_t *tvb, packet_info *pinfo,
100     proto_tree *tree );
101
102 /*
103  * Fields in the first octet of the RTP header.
104  */
105
106 /* Version is the first 2 bits of the first octet*/
107 #define RTP_VERSION(octet)      ((octet) >> 6)
108
109 /* Padding is the third bit; No need to shift, because true is any value
110    other than 0! */
111 #define RTP_PADDING(octet)      ((octet) & 0x20)
112
113 /* Extension bit is the fourth bit */
114 #define RTP_EXTENSION(octet)    ((octet) & 0x10)
115
116 /* CSRC count is the last four bits */
117 #define RTP_CSRC_COUNT(octet)   ((octet) & 0xF)
118
119 static const value_string rtp_version_vals[] =
120 {
121         { 0, "Old VAT Version" },
122         { 1, "First Draft Version" },
123         { 2, "RFC 1889 Version" },
124         { 0, NULL },
125 };
126
127 /*
128  * Fields in the second octet of the RTP header.
129  */
130
131 /* Marker is the first bit of the second octet */
132 #define RTP_MARKER(octet)       ((octet) & 0x80)
133
134 /* Payload type is the last 7 bits */
135 #define RTP_PAYLOAD_TYPE(octet) ((octet) & 0x7F)
136
137 /*
138  * RTP Payload types
139  * Table B.2 / H.225.0
140  * Also RFC 1890
141  */
142 #define PT_PCMU         0
143 #define PT_1016         1
144 #define PT_G721         2
145 #define PT_GSM          3
146 #define PT_G723         4
147 #define PT_DVI4_8000    5
148 #define PT_DVI4_16000   6
149 #define PT_LPC          7
150 #define PT_PCMA         8
151 #define PT_G722         9
152 #define PT_L16_STEREO   10
153 #define PT_L16_MONO     11
154 #define PT_MPA          14
155 #define PT_G728         15
156 #define PT_G729         18
157 #define PT_CELB         25
158 #define PT_JPEG         26
159 #define PT_NV           28
160 #define PT_H261         31
161 #define PT_MPV          32
162 #define PT_MP2T         33
163 #define PT_H263         34
164
165 static const value_string rtp_payload_type_vals[] =
166 {
167         { PT_PCMU,      "ITU-T G.711 PCMU" },
168         { PT_1016,      "USA Federal Standard FS-1016" },
169         { PT_G721,      "ITU-T G.721" },
170         { PT_GSM,       "GSM 06.10" },
171         { PT_G723,      "ITU-T G.723" },
172         { PT_DVI4_8000, "DVI4 8000 samples/s" },
173         { PT_DVI4_16000, "DVI4 16000 samples/s" },
174         { PT_LPC,       "LPC" },
175         { PT_PCMA,      "ITU-T G.711 PCMA" },
176         { PT_G722,      "ITU-T G.722" },
177         { PT_L16_STEREO, "16-bit uncompressed audio, stereo" },
178         { PT_L16_MONO,  "16-bit uncompressed audio, monaural" },
179         { PT_MPA,       "MPEG-I/II Audeo"},
180         { PT_G728,      "ITU-T G.728" },
181         { PT_G729,      "ITU-T G.729" },
182         { PT_CELB,      "Sun CELL-B" },
183         { PT_JPEG,      "JPEG" },
184         { PT_NV,        "'nv' program" },
185         { PT_H261,      "ITU-T H.261" },
186         { PT_MPV,       "MPEG-I/II Video"},
187         { PT_MP2T,      "MPEG-II transport streams"},
188         { PT_H263,      "ITU-T H.263" },
189         { 0,            NULL },
190 };
191
192 static address fake_addr;
193 static int heur_init = FALSE;
194
195 void rtp_add_address( packet_info *pinfo, const unsigned char* ip_addr,
196     int prt )
197 {
198         address src_addr;
199         conversation_t* pconv;
200
201         /*
202          * If this isn't the first time this packet has been processed,
203          * we've already done this work, so we don't need to do it
204          * again.
205          */
206         if (pinfo->fd->flags.visited)
207                 return;
208
209         src_addr.type = AT_IPv4;
210         src_addr.len = 4;
211         src_addr.data = ip_addr;
212
213         /*
214          * The first time the function is called let the tcp dissector
215          * know that we're interested in traffic
216          */
217         if ( ! heur_init ) {
218                 heur_dissector_add( "udp", dissect_rtp_heur, proto_rtp );
219                 heur_init = TRUE;
220         }
221
222         /*
223          * Check if the ip address an dport combination is not
224          * already registered
225          */
226         pconv = find_conversation( &src_addr, &fake_addr, PT_UDP, prt, 0, 0 );
227
228         /*
229          * If not, add
230          * XXX - use wildcard address and port B?
231          */
232         if ( ! pconv ) {
233                 pconv = conversation_new( &src_addr, &fake_addr, PT_UDP,
234                     (guint32) prt, (guint32) 0, 0 );
235                 conversation_add_proto_data(pconv, proto_rtp, NULL);
236         }
237
238 }
239
240 #if 0
241 static void rtp_init( void )
242 {
243         unsigned char* tmp_data;
244         int i;
245
246         /* Create a fake adddress... */
247         fake_addr.type = AT_IPv4;
248         fake_addr.len = 4;
249
250         tmp_data = malloc( fake_addr.len );
251         for ( i = 0; i < fake_addr.len; i++) {
252                 tmp_data[i] = 0;
253         }
254         fake_addr.data = tmp_data;
255 }
256 #endif
257
258 static gboolean
259 dissect_rtp_heur( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree )
260 {
261         conversation_t* pconv;
262
263         /* This is a heuristic dissector, which means we get all the TCP
264          * traffic not sent to a known dissector and not claimed by
265          * a heuristic dissector called before us!
266          * So we first check if the frame is really meant for us.
267          */
268         if ( ( pconv = find_conversation( &pinfo->src, &fake_addr, pinfo->ptype,
269             pinfo->srcport, 0, 0 ) ) == NULL ) {
270                 /*
271                  * The source ip:port combination was not what we were
272                  * looking for, check the destination
273                  */
274                 if ( ( pconv = find_conversation( &pinfo->dst, &fake_addr,
275                     pinfo->ptype, pinfo->destport, 0, 0 ) ) == NULL ) {
276                         return FALSE;
277                 }
278         }
279
280         /*
281          * An RTP conversation always has a data item for RTP.
282          * (Its existence is sufficient to indicate that this is an RTP
283          * conversation.)
284          */
285         if (conversation_get_proto_data(pconv, proto_rtp) == NULL)
286                 return FALSE;
287
288         dissect_rtp( tvb, pinfo, tree );
289
290         return TRUE;
291 }
292
293 static void
294 dissect_rtp_data( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
295     proto_tree *rtp_tree, int offset, unsigned int data_len,
296     unsigned int data_reported_len, unsigned int payload_type )
297 {
298         tvbuff_t *newtvb;
299
300         switch( payload_type ) {
301                 case PT_H261:
302                         newtvb = tvb_new_subset( tvb, offset, data_len,
303                             data_reported_len );
304                         call_dissector(h261_handle, newtvb, pinfo, tree);
305                         break;
306
307                 case PT_MPV:
308                         newtvb = tvb_new_subset( tvb, offset, data_len,
309                             data_reported_len );
310                         call_dissector(mpeg1_handle, newtvb, pinfo, tree);
311                         break;
312
313                 default:
314                         proto_tree_add_item( rtp_tree, hf_rtp_data, tvb, offset, data_len, FALSE );
315                         break;
316         }
317 }
318
319 static void
320 dissect_rtp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree )
321 {
322         proto_item *ti            = NULL;
323         proto_tree *rtp_tree      = NULL;
324         proto_tree *rtp_csrc_tree = NULL;
325         guint8      octet;
326         unsigned int version;
327         gboolean    padding_set;
328         gboolean    extension_set;
329         unsigned int csrc_count;
330         gboolean    marker_set;
331         unsigned int payload_type;
332         unsigned int i            = 0;
333         unsigned int hdr_extension= 0;
334         unsigned int padding_count;
335         int         data_len;
336         unsigned int offset = 0;
337         guint16     seq_num;
338         guint32     timestamp;
339         guint32     sync_src;
340         guint32     csrc_item;
341
342         /* Get the fields in the first octet */
343         octet = tvb_get_guint8( tvb, offset );
344         version = RTP_VERSION( octet );
345
346         if (version != 2) {
347                 /*
348                  * Unknown or unsupported version.
349                  */
350                 if ( check_col( pinfo->cinfo, COL_PROTOCOL ) )   {
351                         col_set_str( pinfo->cinfo, COL_PROTOCOL, "RTP" );
352                 }
353
354                 if ( check_col( pinfo->cinfo, COL_INFO) ) {
355                         col_add_fstr( pinfo->cinfo, COL_INFO,
356                             "Unknown RTP version %u", version);
357                 }
358
359                 if ( tree ) {
360                         ti = proto_tree_add_item( tree, proto_rtp, tvb, offset, -1, FALSE );
361                         rtp_tree = proto_item_add_subtree( ti, ett_rtp );
362
363                         proto_tree_add_uint( rtp_tree, hf_rtp_version, tvb,
364                             offset, 1, version );
365                 }
366                 return;
367         }
368
369         padding_set = RTP_PADDING( octet );
370         extension_set = RTP_EXTENSION( octet );
371         csrc_count = RTP_CSRC_COUNT( octet );
372
373         /* Get the fields in the second octet */
374         octet = tvb_get_guint8( tvb, offset + 1 );
375         marker_set = RTP_MARKER( octet );
376         payload_type = RTP_PAYLOAD_TYPE( octet );
377
378         /* Get the subsequent fields */
379         seq_num = tvb_get_ntohs( tvb, offset + 2 );
380         timestamp = tvb_get_ntohl( tvb, offset + 4 );
381         sync_src = tvb_get_ntohl( tvb, offset + 8 );
382
383         if ( check_col( pinfo->cinfo, COL_PROTOCOL ) )   {
384                 col_set_str( pinfo->cinfo, COL_PROTOCOL, "RTP" );
385         }
386
387         if ( check_col( pinfo->cinfo, COL_INFO) ) {
388                 col_add_fstr( pinfo->cinfo, COL_INFO,
389                     "Payload type=%s, SSRC=%u, Seq=%u, Time=%u%s",
390                     val_to_str( payload_type, rtp_payload_type_vals,
391                         "Unknown (%u)" ),
392                     sync_src,
393                     seq_num,
394                     timestamp,
395                     marker_set ? ", Mark" : "");
396         }
397
398         if ( tree ) {
399                 ti = proto_tree_add_item( tree, proto_rtp, tvb, offset, -1, FALSE );
400                 rtp_tree = proto_item_add_subtree( ti, ett_rtp );
401
402                 proto_tree_add_uint( rtp_tree, hf_rtp_version, tvb,
403                     offset, 1, version );
404                 proto_tree_add_boolean( rtp_tree, hf_rtp_padding, tvb,
405                     offset, 1, padding_set );
406                 proto_tree_add_boolean( rtp_tree, hf_rtp_extension, tvb,
407                     offset, 1, extension_set );
408                 proto_tree_add_uint( rtp_tree, hf_rtp_csrc_count, tvb,
409                     offset, 1, csrc_count );
410                 offset++;
411
412                 proto_tree_add_boolean( rtp_tree, hf_rtp_marker, tvb, offset,
413                     1, marker_set );
414                 proto_tree_add_uint( rtp_tree, hf_rtp_payload_type, tvb,
415                     offset, 1, payload_type );
416                 offset++;
417
418                 /* Sequence number 16 bits (2 octets) */
419                 proto_tree_add_uint( rtp_tree, hf_rtp_seq_nr, tvb, offset, 2, seq_num );
420                 offset += 2;
421
422                 /* Timestamp 32 bits (4 octets) */
423                 proto_tree_add_uint( rtp_tree, hf_rtp_timestamp, tvb, offset, 4, timestamp );
424                 offset += 4;
425
426                 /* Synchronization source identifier 32 bits (4 octets) */
427                 proto_tree_add_uint( rtp_tree, hf_rtp_ssrc, tvb, offset, 4, sync_src );
428                 offset += 4;
429
430                 /* CSRC list*/
431                 if ( csrc_count > 0 ) {
432                         ti = proto_tree_add_text(rtp_tree, tvb, offset, csrc_count * 4, "Contributing Source identifiers");
433                         rtp_csrc_tree = proto_item_add_subtree( ti, ett_csrc_list );
434                         for (i = 0; i < csrc_count; i++ ) {
435                                 csrc_item = tvb_get_ntohl( tvb, offset );
436                                 proto_tree_add_uint_format( rtp_csrc_tree,
437                                     hf_rtp_csrc_item, tvb, offset, 4,
438                                     csrc_item,
439                                     "CSRC item %d: %u",
440                                     i, csrc_item );
441                                 offset += 4;
442                         }
443                 }
444
445                 /* Optional RTP header extension */
446                 if ( extension_set ) {
447                         /* Defined by profile field is 16 bits (2 octets) */
448                         proto_tree_add_uint( rtp_tree, hf_rtp_prof_define, tvb, offset, 2, tvb_get_ntohs( tvb, offset ) );
449                         offset += 2;
450
451                         hdr_extension = tvb_get_ntohs( tvb, offset );
452                         proto_tree_add_uint( rtp_tree, hf_rtp_length, tvb,
453                             offset, 2, hdr_extension);
454                         offset += 2;
455                         if ( hdr_extension > 0 ) {
456                                 ti = proto_tree_add_text(rtp_tree, tvb, offset, csrc_count * 4, "Header extensions");
457                                 /* I'm re-using the old tree variable here
458                                    from the CSRC list!*/
459                                 rtp_csrc_tree = proto_item_add_subtree( ti,
460                                     ett_hdr_ext );
461                                 for (i = 0; i < hdr_extension; i++ ) {
462                                         proto_tree_add_uint( rtp_csrc_tree, hf_rtp_hdr_ext, tvb, offset, 4, tvb_get_ntohl( tvb, offset ) );
463                                         offset += 4;
464                                 }
465                         }
466                 }
467
468                 if ( padding_set ) {
469                         /*
470                          * This RTP frame has padding - find it.
471                          *
472                          * The padding count is found in the LAST octet of
473                          * the packet; it contains the number of octets
474                          * that can be ignored at the end of the packet.
475                          */
476                         if (tvb_length(tvb) < tvb_reported_length(tvb)) {
477                                 /*
478                                  * We don't *have* the last octet of the
479                                  * packet, so we can't get the padding
480                                  * count.
481                                  *
482                                  * Put an indication of that into the
483                                  * tree, and just put in a raw data
484                                  * item.
485                                  */
486                                 proto_tree_add_text(rtp_tree, tvb, 0, 0,
487                                     "Frame has padding, but not all the frame data was captured");
488                                 call_dissector(data_handle,
489                                     tvb_new_subset(tvb, offset, -1, -1),
490                                     pinfo, rtp_tree);
491                                 return;
492                         }
493
494                         padding_count = tvb_get_guint8( tvb,
495                             tvb_reported_length( tvb ) - 1 );
496                         data_len =
497                             tvb_reported_length_remaining( tvb, offset ) - padding_count;
498                         if (data_len > 0) {
499                                 /*
500                                  * There's data left over when you take out
501                                  * the padding; dissect it.
502                                  */
503                                 dissect_rtp_data( tvb, pinfo, tree, rtp_tree,
504                                     offset,
505                                     data_len,
506                                     data_len,
507                                     payload_type );
508                                 offset += data_len;
509                         } else if (data_len < 0) {
510                                 /*
511                                  * The padding count is bigger than the
512                                  * amount of RTP payload in the packet!
513                                  * Clip the padding count.
514                                  *
515                                  * XXX - put an item in the tree to indicate
516                                  * that the padding count is bogus?
517                                  */
518                                 padding_count =
519                                     tvb_reported_length_remaining(tvb, offset);
520                         }
521                         if (padding_count > 1) {
522                                 /*
523                                  * There's more than one byte of padding;
524                                  * show all but the last byte as padding
525                                  * data.
526                                  */
527                                 proto_tree_add_item( rtp_tree, hf_rtp_padding_data,
528                                     tvb, offset, padding_count - 1, FALSE );
529                                 offset += padding_count - 1;
530                         }
531                         /*
532                          * Show the last byte in the PDU as the padding
533                          * count.
534                          */
535                         proto_tree_add_item( rtp_tree, hf_rtp_padding_count,
536                             tvb, offset, 1, FALSE );
537                 }
538                 else {
539                         /*
540                          * No padding.
541                          */
542                         dissect_rtp_data( tvb, pinfo, tree, rtp_tree, offset,
543                             tvb_length_remaining( tvb, offset ),
544                             tvb_reported_length_remaining( tvb, offset ),
545                             payload_type );
546                 }
547         }
548 }
549
550 void
551 proto_register_rtp(void)
552 {
553         static hf_register_info hf[] =
554         {
555                 {
556                         &hf_rtp_version,
557                         {
558                                 "Version",
559                                 "rtp.version",
560                                 FT_UINT8,
561                                 BASE_DEC,
562                                 VALS(rtp_version_vals),
563                                 0x0,
564                                 "", HFILL
565                         }
566                 },
567                 {
568                         &hf_rtp_padding,
569                         {
570                                 "Padding",
571                                 "rtp.padding",
572                                 FT_BOOLEAN,
573                                 BASE_NONE,
574                                 NULL,
575                                 0x0,
576                                 "", HFILL
577                         }
578                 },
579                 {
580                         &hf_rtp_extension,
581                         {
582                                 "Extension",
583                                 "rtp.ext",
584                                 FT_BOOLEAN,
585                                 BASE_NONE,
586                                 NULL,
587                                 0x0,
588                                 "", HFILL
589                         }
590                 },
591                 {
592                         &hf_rtp_csrc_count,
593                         {
594                                 "Contributing source identifiers count",
595                                 "rtp.cc",
596                                 FT_UINT8,
597                                 BASE_DEC,
598                                 NULL,
599                                 0x0,
600                                 "", HFILL
601                         }
602                 },
603                 {
604                         &hf_rtp_marker,
605                         {
606                                 "Marker",
607                                 "rtp.marker",
608                                 FT_BOOLEAN,
609                                 BASE_NONE,
610                                 NULL,
611                                 0x0,
612                                 "", HFILL
613                         }
614                 },
615                 {
616                         &hf_rtp_payload_type,
617                         {
618                                 "Payload type",
619                                 "rtp.p_type",
620                                 FT_UINT8,
621                                 BASE_DEC,
622                                 VALS(rtp_payload_type_vals),
623                                 0x0,
624                                 "", HFILL
625                         }
626                 },
627                 {
628                         &hf_rtp_seq_nr,
629                         {
630                                 "Sequence number",
631                                 "rtp.seq",
632                                 FT_UINT16,
633                                 BASE_DEC,
634                                 NULL,
635                                 0x0,
636                                 "", HFILL
637                         }
638                 },
639                 {
640                         &hf_rtp_timestamp,
641                         {
642                                 "Timestamp",
643                                 "rtp.timestamp",
644                                 FT_UINT32,
645                                 BASE_DEC,
646                                 NULL,
647                                 0x0,
648                                 "", HFILL
649                         }
650                 },
651                 {
652                         &hf_rtp_ssrc,
653                         {
654                                 "Synchronization Source identifier",
655                                 "rtp.ssrc",
656                                 FT_UINT32,
657                                 BASE_DEC,
658                                 NULL,
659                                 0x0,
660                                 "", HFILL
661                         }
662                 },
663                 {
664                         &hf_rtp_prof_define,
665                         {
666                                 "Defined by profile",
667                                 "rtp.ext.profile",
668                                 FT_UINT16,
669                                 BASE_DEC,
670                                 NULL,
671                                 0x0,
672                                 "", HFILL
673                         }
674                 },
675                 {
676                         &hf_rtp_length,
677                         {
678                                 "Extension length",
679                                 "rtp.ext.len",
680                                 FT_UINT16,
681                                 BASE_DEC,
682                                 NULL,
683                                 0x0,
684                                 "", HFILL
685                         }
686                 },
687                 {
688                         &hf_rtp_csrc_item,
689                         {
690                                 "CSRC item",
691                                 "rtp.csrc.item",
692                                 FT_UINT32,
693                                 BASE_DEC,
694                                 NULL,
695                                 0x0,
696                                 "", HFILL
697                         }
698                 },
699                 {
700                         &hf_rtp_hdr_ext,
701                         {
702                                 "Header extension",
703                                 "rtp.hdr_ext",
704                                 FT_UINT32,
705                                 BASE_DEC,
706                                 NULL,
707                                 0x0,
708                                 "", HFILL
709                         }
710                 },
711                 {
712                         &hf_rtp_data,
713                         {
714                                 "Payload",
715                                 "rtp.payload",
716                                 FT_BYTES,
717                                 BASE_HEX,
718                                 NULL,
719                                 0x0,
720                                 "", HFILL
721                         }
722                 },
723                 {
724                         &hf_rtp_padding_data,
725                         {
726                                 "Padding data",
727                                 "rtp.padding.data",
728                                 FT_BYTES,
729                                 BASE_HEX,
730                                 NULL,
731                                 0x0,
732                                 "", HFILL
733                         }
734                 },
735                 {
736                         &hf_rtp_padding_count,
737                         {
738                                 "Padding count",
739                                 "rtp.padding.count",
740                                 FT_UINT8,
741                                 BASE_DEC,
742                                 NULL,
743                                 0x0,
744                                 "", HFILL
745                         }
746                 },
747 };
748
749         static gint *ett[] =
750         {
751                 &ett_rtp,
752                 &ett_csrc_list,
753                 &ett_hdr_ext,
754         };
755
756
757         proto_rtp = proto_register_protocol("Real-Time Transport Protocol",
758             "RTP", "rtp");
759         proto_register_field_array(proto_rtp, hf, array_length(hf));
760         proto_register_subtree_array(ett, array_length(ett));
761
762         register_dissector("rtp", dissect_rtp, proto_rtp);
763
764 #if 0
765         register_init_routine( &rtp_init );
766 #endif
767 }
768
769 void
770 proto_reg_handoff_rtp(void)
771 {
772         dissector_handle_t rtp_handle;
773
774         /*
775          * Get handles for the H.261 and MPEG-1 dissectors.
776          */
777         h261_handle = find_dissector("h261");
778         mpeg1_handle = find_dissector("mpeg1");
779         data_handle = find_dissector("data");
780
781         /*
782          * Register this dissector as one that can be selected by a
783          * UDP port number.
784          */
785         rtp_handle = find_dissector("rtp");
786         dissector_add_handle("udp.port", rtp_handle);
787 }