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