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