Add dissection of application PoC1 data
[obnox/wireshark/wip.git] / packet-rtcp.c
1 /* packet-rtcp.c
2  *
3  * $Id: packet-rtcp.c,v 1.42 2004/05/31 19:35:53 etxrab Exp $
4  *
5  * Routines for RTCP dissection
6  * RTCP = Real-time Transport Control Protocol
7  *
8  * Copyright 2000, Philips Electronics N.V.
9  * Written by Andreas Sikkema <h323@ramdyne.nl>
10  *
11  * Copyright 2004, Anders Broman <anders.broman@ericsson.com>
12  *
13  * Ethereal - Network traffic analyzer
14  * By Gerald Combs <gerald@ethereal.com>
15  * Copyright 1998 Gerald Combs
16  *
17  * This program is free software; you can redistribute it and/or
18  * modify it under the terms of the GNU General Public License
19  * as published by the Free Software Foundation; either version 2
20  * of the License, or (at your option) any later version.
21  *
22  * This program is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
25  * GNU General Public License for more details.
26  *
27  * You should have received a copy of the GNU General Public License
28  * along with this program; if not, write to the Free Software
29  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
30  */
31
32 /*
33  * This dissector tries to dissect the RTCP protocol according to Annex A
34  * of ITU-T Recommendation H.225.0 (02/98) and RFC 1889
35  * H.225.0 literally copies RFC 1889, but omitting a few sections.
36  *
37  * RTCP traffic is handled by an uneven UDP portnumber. This can be any
38  * port number, but there is a registered port available, port 5005
39  * See Annex B of ITU-T Recommendation H.225.0, section B.7
40  *
41  * See also http://www.iana.org/assignments/rtp-parameters
42  */
43
44
45 #ifdef HAVE_CONFIG_H
46 # include "config.h"
47 #endif
48
49 #include <glib.h>
50 #include <epan/packet.h>
51
52 #include <stdio.h>
53 #include <string.h>
54
55 #include "packet-rtcp.h"
56 #if 0
57 #include "packet-ntp.h"
58 #endif
59 #include <epan/conversation.h>
60
61 /* Version is the first 2 bits of the first octet*/
62 #define RTCP_VERSION(octet)     ((octet) >> 6)
63
64 /* Padding is the third bit; no need to shift, because true is any value
65    other than 0! */
66 #define RTCP_PADDING(octet)     ((octet) & 0x20)
67
68 /* Receiver/ Sender count is the 5 last bits  */
69 #define RTCP_COUNT(octet)       ((octet) & 0x1F)
70
71 static const value_string rtcp_version_vals[] =
72 {
73         { 0, "Old VAT Version" },
74         { 1, "First Draft Version" },
75         { 2, "RFC 1889 Version" },
76         { 0, NULL },
77 };
78
79 /* RTCP packet types according to Section A.11.1 */
80 /* And http://www.iana.org/assignments/rtp-parameters */
81 #define RTCP_SR   200
82 #define RTCP_RR   201
83 #define RTCP_SDES 202
84 #define RTCP_BYE  203
85 #define RTCP_APP  204
86 #define RTCP_XR   207
87 /* Supplemental H.261 specific RTCP packet types according to Section C.3.5 */
88 #define RTCP_FIR  192
89 #define RTCP_NACK 193
90
91 static const value_string rtcp_packet_type_vals[] =
92 {
93         { RTCP_SR,   "Sender Report" },
94         { RTCP_RR,   "Receiver Report" },
95         { RTCP_SDES, "Source description" },
96         { RTCP_BYE,  "Goodbye" },
97         { RTCP_APP,  "Application specific" },
98         { RTCP_FIR,  "Full Intra-frame Request (H.261)" },
99         { RTCP_NACK, "Negative Acknowledgement (H.261)" },
100         { RTCP_XR,       "Extended report"},
101         { 0,         NULL },
102 };
103
104 /* RTCP SDES types (Section A.11.2) */
105 #define RTCP_SDES_END    0
106 #define RTCP_SDES_CNAME  1
107 #define RTCP_SDES_NAME   2
108 #define RTCP_SDES_EMAIL  3
109 #define RTCP_SDES_PHONE  4
110 #define RTCP_SDES_LOC    5
111 #define RTCP_SDES_TOOL   6
112 #define RTCP_SDES_NOTE   7
113 #define RTCP_SDES_PRIV   8
114 #define RTCP_SDES_H323_CADDR   9
115
116 static const value_string rtcp_sdes_type_vals[] =
117 {
118         { RTCP_SDES_END,   "END" },
119         { RTCP_SDES_CNAME, "CNAME (user and domain)" },
120         { RTCP_SDES_NAME,  "NAME (common name)" },
121         { RTCP_SDES_EMAIL, "EMAIL (e-mail address)" },
122         { RTCP_SDES_PHONE, "PHONE (phone number)" },
123         { RTCP_SDES_LOC,   "LOC (geographic location)" },
124         { RTCP_SDES_TOOL,  "TOOL (name/version of source app)" },
125         { RTCP_SDES_NOTE,  "NOTE (note about source)" },
126         { RTCP_SDES_PRIV,  "PRIV (private extensions)" },
127         { RTCP_SDES_H323_CADDR,"H323-CADDR (H.323 callable address)"},
128         { 0,               NULL },
129 };
130 /* RTCP Application PoC1 Value strings */
131 static const value_string rtcp_app_poc1_floor_cnt_type_vals[] =
132 {
133         {  0,   "Floor Request"},
134         {  1,   "Floor Grant"},
135         {  2,   "Floor Taken"},
136         {  3,   "Floor Deny"},
137         {  4,   "Floor Release"},
138         {  5,   "Floor Idle"},
139         {  6,   "Floor Revoke"},
140         {  0,               NULL },
141 };
142
143 static const value_string rtcp_app_poc1_reason_code1_vals[] =
144 {
145         {  1,   "Floor already in use"},
146         {  2,   "Internal PoC server error"},
147         {  0,               NULL },
148 };
149
150 static const value_string rtcp_app_poc1_reason_code2_vals[] =
151 {
152         {  1,   "Only one user"},
153         {  2,   "Talk burst too long"},
154         { 0,               NULL },
155 };
156 /* RTCP header fields                   */
157 static int proto_rtcp                = -1;
158 static int hf_rtcp_version           = -1;
159 static int hf_rtcp_padding           = -1;
160 static int hf_rtcp_rc                = -1;
161 static int hf_rtcp_sc                = -1;
162 static int hf_rtcp_pt                = -1;
163 static int hf_rtcp_length            = -1;
164 static int hf_rtcp_ssrc_sender       = -1;
165 static int hf_rtcp_ntp               = -1;
166 static int hf_rtcp_rtp_timestamp     = -1;
167 static int hf_rtcp_sender_pkt_cnt    = -1;
168 static int hf_rtcp_sender_oct_cnt    = -1;
169 static int hf_rtcp_ssrc_source       = -1;
170 static int hf_rtcp_ssrc_fraction     = -1;
171 static int hf_rtcp_ssrc_cum_nr       = -1;
172 /* First the 32 bit number, then the split
173  * up 16 bit values */
174 /* These two are added to a subtree */
175 static int hf_rtcp_ssrc_ext_high_seq = -1;
176 static int hf_rtcp_ssrc_high_seq     = -1;
177 static int hf_rtcp_ssrc_high_cycles  = -1;
178 static int hf_rtcp_ssrc_jitter       = -1;
179 static int hf_rtcp_ssrc_lsr          = -1;
180 static int hf_rtcp_ssrc_dlsr         = -1;
181 static int hf_rtcp_ssrc_csrc         = -1;
182 static int hf_rtcp_ssrc_type         = -1;
183 static int hf_rtcp_ssrc_length       = -1;
184 static int hf_rtcp_ssrc_text         = -1;
185 static int hf_rtcp_ssrc_prefix_len   = -1;
186 static int hf_rtcp_ssrc_prefix_string= -1;
187 static int hf_rtcp_subtype           = -1;
188 static int hf_rtcp_name_ascii        = -1;
189 static int hf_rtcp_app_data          = -1;
190 static int hf_rtcp_fsn               = -1;
191 static int hf_rtcp_blp               = -1;
192 static int hf_rtcp_padding_count     = -1;
193 static int hf_rtcp_padding_data      = -1;
194 static int hf_rtcp_app_PoC1_subtype                     = -1; 
195 static int hf_rtcp_app_poc1_sip_uri                     = -1;
196 static int hf_rtcp_app_poc1_disp_name           = -1;
197 static int hf_rtcp_app_poc1_last_pkt_seq_no = -1;
198 static int hf_rtcp_app_poc1_reason_code1        = -1;
199 static int hf_rtcp_app_poc1_item_len            = -1;
200 static int hf_rtcp_app_poc1_reason1_phrase      = -1;
201 static int hf_rtcp_app_poc1_reason_code2        = -1;
202 static int hf_rtcp_app_poc1_additionalinfo      = -1;
203
204 /* RTCP fields defining a sub tree */
205 static gint ett_rtcp                    = -1;
206 static gint ett_ssrc                    = -1;
207 static gint ett_ssrc_item               = -1;
208 static gint ett_ssrc_ext_high   = -1;
209 static gint ett_sdes                    = -1;
210 static gint ett_sdes_item               = -1;
211 static gint ett_PoC1                    = -1;
212
213 static address fake_addr;
214 static int heur_init = FALSE;
215
216 static gboolean dissect_rtcp_heur( tvbuff_t *tvb, packet_info *pinfo,
217     proto_tree *tree );
218 static void dissect_rtcp( tvbuff_t *tvb, packet_info *pinfo,
219      proto_tree *tree );
220
221 void rtcp_add_address( packet_info *pinfo, const unsigned char* ip_addr,
222     int prt )
223 {
224         address src_addr;
225         conversation_t* pconv;
226
227         /*
228          * If this isn't the first time this packet has been processed,
229          * we've already done this work, so we don't need to do it
230          * again.
231          */
232         if (pinfo->fd->flags.visited)
233                 return;
234
235         src_addr.type = AT_IPv4;
236         src_addr.len = 4;
237         src_addr.data = ip_addr;
238
239         /*
240          * The first time the function is called let the udp dissector
241          * know that we're interested in traffic
242          */
243         if ( ! heur_init ) {
244                 heur_dissector_add( "udp", dissect_rtcp_heur, proto_rtcp );
245                 heur_init = TRUE;
246         }
247
248         /*
249          * Check if the ip address and port combination is not
250          * already registered
251          */
252         pconv = find_conversation( &src_addr, &fake_addr, PT_UDP, prt, 0, 0 );
253
254         /*
255          * If not, add
256          * XXX - use wildcard address and port B?
257          */
258         if ( ! pconv ) {
259                 pconv = conversation_new( &src_addr, &fake_addr, PT_UDP,
260                     (guint32) prt, (guint32) 0, 0 );
261                 conversation_add_proto_data(pconv, proto_rtcp, NULL);
262         }
263
264 }
265
266 #if 0
267 static void rtcp_init( void )
268 {
269         unsigned char* tmp_data;
270         int i;
271
272         /* Create a fake adddress... */
273         fake_addr.type = AT_IPv4;
274         fake_addr.len = 4;
275
276         tmp_data = g_malloc( fake_addr.len );
277         for ( i = 0; i < fake_addr.len; i++) {
278                 tmp_data[i] = 0;
279         }
280         fake_addr.data = tmp_data;
281 }
282 #endif
283
284 static gboolean
285 dissect_rtcp_heur( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree )
286 {
287         conversation_t* pconv;
288
289         /* This is a heuristic dissector, which means we get all the UDP
290          * traffic not sent to a known dissector and not claimed by
291          * a heuristic dissector called before us!
292          * So we first check if the frame is really meant for us.
293          */
294         if ( ( pconv = find_conversation( &pinfo->src, &fake_addr, pinfo->ptype,
295             pinfo->srcport, 0, 0 ) ) == NULL ) {
296                 /*
297                  * The source ip:port combination was not what we were
298                  * looking for, check the destination
299                  */
300                 if ( ( pconv = find_conversation( &pinfo->dst, &fake_addr,
301                     pinfo->ptype, pinfo->destport, 0, 0 ) ) == NULL ) {
302                         return FALSE;
303                 }
304         }
305
306
307         /*
308          * An RTCP conversation always has a data item for RTCP.
309          * (Its existence is sufficient to indicate that this is an RTCP
310          * conversation.)
311          */
312         if (conversation_get_proto_data(pconv, proto_rtcp) == NULL)
313                 return FALSE;
314
315         /*
316          * The message is a valid RTCP message!
317          */
318         dissect_rtcp( tvb, pinfo, tree );
319
320         return TRUE;
321 }
322
323
324 static int
325 dissect_rtcp_nack( tvbuff_t *tvb, int offset, proto_tree *tree )
326 {
327         /* Packet type = FIR (H261) */
328         proto_tree_add_uint( tree, hf_rtcp_rc, tvb, offset, 1, tvb_get_guint8( tvb, offset ) );
329         offset++;
330         /* Packet type, 8 bits  = APP */
331         proto_tree_add_item( tree, hf_rtcp_pt, tvb, offset, 1, FALSE );
332         offset++;
333
334         /* Packet length in 32 bit words minus one */
335         proto_tree_add_uint( tree, hf_rtcp_length, tvb, offset, 2, tvb_get_ntohs( tvb, offset ) );
336         offset += 2;
337
338         /* SSRC  */
339         proto_tree_add_uint( tree, hf_rtcp_ssrc_source, tvb, offset, 4, tvb_get_ntohl( tvb, offset ) );
340         offset += 4;
341
342         /* FSN, 16 bits */
343         proto_tree_add_uint( tree, hf_rtcp_fsn, tvb, offset, 2, tvb_get_ntohs( tvb, offset ) );
344         offset += 2;
345
346         /* BLP, 16 bits */
347         proto_tree_add_uint( tree, hf_rtcp_blp, tvb, offset, 2, tvb_get_ntohs( tvb, offset ) );
348         offset += 2;
349
350         return offset;
351 }
352
353 static int
354 dissect_rtcp_fir( tvbuff_t *tvb, int offset, proto_tree *tree )
355 {
356         /* Packet type = FIR (H261) */
357         proto_tree_add_uint( tree, hf_rtcp_rc, tvb, offset, 1, tvb_get_guint8( tvb, offset ) );
358         offset++;
359         /* Packet type, 8 bits  = APP */
360         proto_tree_add_item( tree, hf_rtcp_pt, tvb, offset, 1, FALSE );
361         offset++;
362
363         /* Packet length in 32 bit words minus one */
364         proto_tree_add_uint( tree, hf_rtcp_length, tvb, offset, 2, tvb_get_ntohs( tvb, offset ) );
365         offset += 2;
366
367         /* SSRC  */
368         proto_tree_add_uint( tree, hf_rtcp_ssrc_source, tvb, offset, 4, tvb_get_ntohl( tvb, offset ) );
369         offset += 4;
370
371         return offset;
372 }
373
374 static int
375 dissect_rtcp_app( tvbuff_t *tvb,packet_info *pinfo, int offset, proto_tree *tree,
376     unsigned int padding, unsigned int packet_len, guint rtcp_subtype )
377 {
378         unsigned int counter = 0;
379         char ascii_name[5];
380         guint sdes_type         = 0;
381         guint item_len          = 0;
382         guint items_start_offset;
383         proto_tree *PoC1_tree;
384         proto_item *PoC1_item;
385
386         /* XXX If more application types are to be dissected it may be useful to use a table like in packet-sip.c */ 
387         static const char app_name_str[] = "PoC1";
388
389
390         /* SSRC / CSRC */
391         proto_tree_add_uint( tree, hf_rtcp_ssrc_source, tvb, offset, 4, tvb_get_ntohl( tvb, offset ) );
392         offset += 4;
393         packet_len -= 4;
394
395         /* Name (ASCII) */
396         for( counter = 0; counter < 4; counter++ )
397             ascii_name[ counter ] = tvb_get_guint8( tvb, offset + counter );
398         /* strncpy( ascii_name, pd + offset, 4 ); */
399         ascii_name[4] = '\0';
400         proto_tree_add_string( tree, hf_rtcp_name_ascii, tvb, offset, 4,
401             ascii_name );
402         if ( strncasecmp(ascii_name,app_name_str,4 ) != 0 ){ /* Not PoC1 */
403                 if (check_col(pinfo->cinfo, COL_INFO))
404                         col_append_fstr(pinfo->cinfo, COL_INFO,"( %s ) subtype=%u",ascii_name, rtcp_subtype);
405                 offset += 4;
406                 packet_len -= 4;
407                 /* Applications specific data */
408                 if ( padding ) {
409                         /* If there's padding present, we have to remove that from the data part
410                         * The last octet of the packet contains the length of the padding
411                         */
412                         packet_len -= tvb_get_guint8( tvb, offset + packet_len - 1 );
413                 }
414                 proto_tree_add_item( tree, hf_rtcp_app_data, tvb, offset, packet_len, FALSE );
415                 offset += packet_len;
416
417                 return offset;
418         }else{/* PoC1 Application */
419                 proto_item *item;
420                 item = proto_tree_add_uint( tree, hf_rtcp_app_PoC1_subtype, tvb, offset - 8, 1, rtcp_subtype );
421                 PROTO_ITEM_SET_GENERATED(item);
422                 if (check_col(pinfo->cinfo, COL_INFO))
423                         col_append_fstr(pinfo->cinfo, COL_INFO,"(%s) subtype=%s",ascii_name,
424                                 val_to_str(rtcp_subtype,rtcp_app_poc1_floor_cnt_type_vals,"unknown (%u)") );
425                 offset += 4;
426                 packet_len -= 4;
427                 /* Applications specific data */
428                 if ( padding ) {
429                         /* If there's padding present, we have to remove that from the data part
430                         * The last octet of the packet contains the length of the padding
431                         */
432                         packet_len -= tvb_get_guint8( tvb, offset + packet_len - 1 );
433                 }
434                 /* Create a subtree for the PoC1 Application items; we don't yet know
435                    the length */
436                 items_start_offset = offset;
437
438                 PoC1_item = proto_tree_add_text(tree, tvb, offset, packet_len,
439                     "PoC1 Application specific data");
440                 PoC1_tree = proto_item_add_subtree( PoC1_item, ett_PoC1 );
441
442
443                 proto_tree_add_item( PoC1_tree, hf_rtcp_app_data, tvb, offset, packet_len, FALSE );
444                 switch ( rtcp_subtype ) {
445                         case 2:
446                                 sdes_type = tvb_get_guint8( tvb, offset );
447                                 proto_tree_add_item( PoC1_tree, hf_rtcp_ssrc_type, tvb, offset, 1, FALSE );
448                                 offset++;
449                                 packet_len--;
450                                 /* Item length, 8 bits */
451                                 item_len = tvb_get_guint8( tvb, offset );
452                                 proto_tree_add_item( PoC1_tree, hf_rtcp_ssrc_length, tvb, offset, 1, FALSE );
453                                 offset++;
454                                 packet_len--;
455                                 proto_tree_add_item( PoC1_tree, hf_rtcp_app_poc1_sip_uri, tvb, offset, item_len, FALSE );
456                                 offset = offset + item_len;
457                                 packet_len = packet_len - item_len;
458                                 sdes_type = tvb_get_guint8( tvb, offset );
459                                 proto_tree_add_item( PoC1_tree, hf_rtcp_ssrc_type, tvb, offset, 1, FALSE );
460                                 offset++;
461                                 packet_len--;
462                                 /* Item length, 8 bits */
463                                 item_len = tvb_get_guint8( tvb, offset );
464                                 proto_tree_add_item( PoC1_tree, hf_rtcp_ssrc_length, tvb, offset, 1, FALSE );
465                                 offset++;
466                                 packet_len--;
467                                 if ( item_len != 0 )
468                                         proto_tree_add_item( PoC1_tree, hf_rtcp_app_poc1_disp_name, tvb, offset, item_len, FALSE );
469                                 offset = offset + item_len;
470                                 packet_len = packet_len - item_len;
471                                 break;
472                         case 3:                         
473                                 proto_tree_add_item( PoC1_tree, hf_rtcp_app_poc1_reason_code1, tvb, offset, 1, FALSE );
474                                 offset++;
475                                 packet_len--;
476                                 /* Item length, 8 bits */
477                                 item_len = tvb_get_guint8( tvb, offset );
478                                 proto_tree_add_item( PoC1_tree, hf_rtcp_app_poc1_item_len, tvb, offset, 1, FALSE );
479                                 offset++;
480                                 packet_len--;
481                                 if ( item_len != 0 )
482                                         proto_tree_add_item( PoC1_tree, hf_rtcp_app_poc1_reason1_phrase, tvb, offset, item_len, FALSE );
483                                 offset = offset + item_len;
484                                 packet_len = packet_len - item_len;
485                                 break;
486                         case 4:                         
487                                 proto_tree_add_item( PoC1_tree, hf_rtcp_app_poc1_last_pkt_seq_no, tvb, offset, 2, FALSE );
488                             proto_tree_add_text(PoC1_tree, tvb, offset + 2, 2, "Padding 2 bytes");
489                             offset += 4;
490                                 packet_len-=4;
491                                 break;
492                         case 6:                         
493                                 proto_tree_add_item( PoC1_tree, hf_rtcp_app_poc1_reason_code2, tvb, offset, 2, FALSE );
494                                 proto_tree_add_item( PoC1_tree, hf_rtcp_app_poc1_additionalinfo, tvb, offset + 2, 2, FALSE );
495                             offset += 4;
496                                 packet_len-=4;
497                                 break;
498                         default:
499                                 break;
500                 }
501                 offset += packet_len;
502                 return offset;
503         }
504 }
505
506
507 static int
508 dissect_rtcp_bye( tvbuff_t *tvb, int offset, proto_tree *tree,
509     unsigned int count )
510 {
511         unsigned int chunk          = 1;
512         unsigned int reason_length  = 0;
513         char* reason_text = NULL;
514
515         while ( chunk <= count ) {
516                 /* source identifier, 32 bits */
517                 proto_tree_add_item( tree, hf_rtcp_ssrc_source, tvb, offset, 4, FALSE);
518                 offset += 4;
519                 chunk++;
520         }
521
522         if ( tvb_reported_length_remaining( tvb, offset ) > 0 ) {
523                 /* Bye reason consists of an 8 bit length l and a string with length l */
524                 reason_length = tvb_get_guint8( tvb, offset );
525                 proto_tree_add_item( tree, hf_rtcp_ssrc_length, tvb, offset, 1, FALSE );
526                 offset++;
527
528                 reason_text = tvb_get_string(tvb, offset, reason_length);
529                 proto_tree_add_string( tree, hf_rtcp_ssrc_text, tvb, offset, reason_length, reason_text );
530                 g_free( reason_text );
531                 offset += reason_length;
532         }
533
534         return offset;
535
536 }
537
538 static void
539 dissect_rtcp_sdes( tvbuff_t *tvb, int offset, proto_tree *tree,
540     unsigned int count )
541 {
542         unsigned int chunk          = 1;
543         proto_item *sdes_item;
544         proto_tree *sdes_tree;
545         proto_tree *sdes_item_tree;
546         proto_item *ti;
547         int start_offset;
548         int items_start_offset;
549         guint32 ssrc;
550         unsigned int item_len       = 0;
551         unsigned int sdes_type      = 0;
552         unsigned int counter        = 0;
553         unsigned int prefix_len     = 0;
554         char *prefix_string = NULL;
555
556         while ( chunk <= count ) {
557                 /* Create a subtree for this chunk; we don't yet know
558                    the length. */
559                 start_offset = offset;
560
561                 ssrc = tvb_get_ntohl( tvb, offset );
562                 if (ssrc == 0) {
563                     /* According to RFC1889 section 6.4:
564                      * "The list of items in each chunk is terminated by one or more
565                      * null octets, the first of which is interpreted as an item type
566                      * of zero to denote the end of the list, and the remainder as
567                      * needed to pad until the next 32-bit boundary.
568                      *
569                      * A chunk with zero items (four null octets) is valid but useless."
570                      */
571                     proto_tree_add_text(tree, tvb, offset, 4, "Padding");
572                     offset += 4;
573                     continue;
574                 }
575                 sdes_item = proto_tree_add_text(tree, tvb, offset, -1,
576                     "Chunk %u, SSRC/CSRC %u", chunk, ssrc);
577                 sdes_tree = proto_item_add_subtree( sdes_item, ett_sdes );
578
579                 /* SSRC_n source identifier, 32 bits */
580                 proto_tree_add_uint( sdes_tree, hf_rtcp_ssrc_source, tvb, offset, 4, ssrc );
581                 offset += 4;
582
583                 /* Create a subtree for the SDES items; we don't yet know
584                    the length */
585                 items_start_offset = offset;
586                 ti = proto_tree_add_text(sdes_tree, tvb, offset, -1,
587                     "SDES items" );
588                 sdes_item_tree = proto_item_add_subtree( ti, ett_sdes_item );
589
590                 /*
591                  * Not every message is ended with "null" bytes, so check for
592                  * end of frame instead.
593                  */
594                 while ( ( tvb_reported_length_remaining( tvb, offset ) > 0 )
595                     && ( tvb_get_guint8( tvb, offset ) != RTCP_SDES_END ) ) {
596                         /* ID, 8 bits */
597                         sdes_type = tvb_get_guint8( tvb, offset );
598                         proto_tree_add_item( sdes_item_tree, hf_rtcp_ssrc_type, tvb, offset, 1, FALSE );
599                         offset++;
600
601                         /* Item length, 8 bits */
602                         item_len = tvb_get_guint8( tvb, offset );
603                         proto_tree_add_item( sdes_item_tree, hf_rtcp_ssrc_length, tvb, offset, 1, FALSE );
604                         offset++;
605
606                         if ( sdes_type == RTCP_SDES_PRIV ) {
607                                 /* PRIV adds two items between the SDES length
608                                  * and value - an 8 bit length giving the
609                                  * length of a "prefix string", and the string.
610                                  */
611                                 prefix_len = tvb_get_guint8( tvb, offset );
612                                 proto_tree_add_item( sdes_item_tree, hf_rtcp_ssrc_prefix_len, tvb, offset, 1, FALSE );
613                                 offset++;
614
615                                 prefix_string = g_malloc( prefix_len + 1 );
616                                 for ( counter = 0; counter < prefix_len; counter++ )
617                                         prefix_string[ counter ] =
618                                             tvb_get_guint8( tvb, offset + counter );
619                                 /* strncpy( prefix_string, pd + offset, prefix_len ); */
620                                 prefix_string[ prefix_len ] = '\0';
621                                 proto_tree_add_string( sdes_item_tree, hf_rtcp_ssrc_prefix_string, tvb, offset, prefix_len, prefix_string );
622                                 g_free( prefix_string );
623                                 offset += prefix_len;
624                         }
625                         prefix_string = g_malloc( item_len + 1 );
626                         for ( counter = 0; counter < item_len; counter++ )
627                             prefix_string[ counter ] =
628                                 tvb_get_guint8( tvb, offset + counter );
629                         /* strncpy( prefix_string, pd + offset, item_len ); */
630                         prefix_string[ item_len] = 0;
631                         proto_tree_add_string( sdes_item_tree, hf_rtcp_ssrc_text, tvb, offset, item_len, prefix_string );
632                         g_free( prefix_string );
633                         offset += item_len;
634                 }
635
636                 /* Set the length of the items subtree. */
637                 proto_item_set_len(ti, offset - items_start_offset);
638
639                 /* 32 bits = 4 bytes, so.....
640                  * If offset % 4 != 0, we divide offset by 4, add one and then
641                  * multiply by 4 again to reach the boundary
642                  */
643                 if ( offset % 4 != 0 )
644                         offset = ((offset / 4) + 1 ) * 4;
645
646                 /* Set the length of this chunk. */
647                 proto_item_set_len(sdes_item, offset - start_offset);
648
649                 chunk++;
650         }
651 }
652
653 static int
654 dissect_rtcp_rr( tvbuff_t *tvb, int offset, proto_tree *tree,
655     unsigned int count )
656 {
657         unsigned int counter = 1;
658         proto_tree *ssrc_tree = (proto_tree*) NULL;
659         proto_tree *ssrc_sub_tree = (proto_tree*) NULL;
660         proto_tree *high_sec_tree = (proto_tree*) NULL;
661         proto_item *ti = (proto_item*) NULL;
662         guint8 rr_flt;
663         unsigned int cum_nr = 0;
664
665         while ( counter <= count ) {
666                 /* Create a new subtree for a length of 24 bytes */
667                 ti = proto_tree_add_text(tree, tvb, offset, 24,
668                     "Source %u", counter );
669                 ssrc_tree = proto_item_add_subtree( ti, ett_ssrc );
670
671                 /* SSRC_n source identifier, 32 bits */
672                 proto_tree_add_uint( ssrc_tree, hf_rtcp_ssrc_source, tvb, offset, 4, tvb_get_ntohl( tvb, offset ) );
673                 offset += 4;
674
675                 ti = proto_tree_add_text(ssrc_tree, tvb, offset, 20, "SSRC contents" );
676                 ssrc_sub_tree = proto_item_add_subtree( ti, ett_ssrc_item );
677
678                 /* Fraction lost, 8bits */
679                 rr_flt = tvb_get_guint8( tvb, offset );
680                 proto_tree_add_uint_format( ssrc_sub_tree, hf_rtcp_ssrc_fraction, tvb,
681                     offset, 1, rr_flt, "Fraction lost: %u / 256", rr_flt );
682                 offset++;
683
684                 /* Cumulative number of packets lost, 24 bits */
685                 cum_nr = tvb_get_ntohl( tvb, offset ) >> 8;
686                 proto_tree_add_uint( ssrc_sub_tree, hf_rtcp_ssrc_cum_nr, tvb,
687                     offset, 3, cum_nr );
688                 offset += 3;
689
690                 /* Extended highest sequence nr received, 32 bits
691                  * Just for the sake of it, let's add another subtree
692                  * because this might be a little clearer
693                  */
694                 ti = proto_tree_add_uint( ssrc_tree, hf_rtcp_ssrc_ext_high_seq,
695                     tvb, offset, 4, tvb_get_ntohl( tvb, offset ) );
696                 high_sec_tree = proto_item_add_subtree( ti, ett_ssrc_ext_high );
697                 /* Sequence number cycles */
698                 proto_tree_add_uint( high_sec_tree, hf_rtcp_ssrc_high_cycles,
699                     tvb, offset, 2, tvb_get_ntohs( tvb, offset ) );
700                 offset += 2;
701                 /* highest sequence number received */
702                 proto_tree_add_uint( high_sec_tree, hf_rtcp_ssrc_high_seq,
703                     tvb, offset, 2, tvb_get_ntohs( tvb, offset ) );
704                 offset += 2;
705
706                 /* Interarrival jitter */
707                 proto_tree_add_uint( ssrc_tree, hf_rtcp_ssrc_jitter, tvb,
708                     offset, 4, tvb_get_ntohl( tvb, offset ) );
709                 offset += 4;
710
711                 /* Last SR timestamp */
712                 proto_tree_add_uint( ssrc_tree, hf_rtcp_ssrc_lsr, tvb,
713                     offset, 4, tvb_get_ntohl( tvb, offset ) );
714                 offset += 4;
715
716                 /* Delay since last SR timestamp */
717                 proto_tree_add_uint( ssrc_tree, hf_rtcp_ssrc_dlsr, tvb,
718                     offset, 4, tvb_get_ntohl( tvb, offset ) );
719                 offset += 4;
720                 counter++;
721         }
722
723         return offset;
724 }
725
726 static int
727 dissect_rtcp_sr( tvbuff_t *tvb, int offset, proto_tree *tree,
728     unsigned int count )
729 {
730 #if 0
731         gchar buff[ NTP_TS_SIZE ];
732         char* ptime = tvb_get_ptr( tvb, offset, 8 );
733
734         /* Retreive the NTP timestamp. Using the NTP dissector for this */
735         ntp_fmt_ts( ptime, buff );
736         proto_tree_add_string_format( tree, hf_rtcp_ntp, tvb, offset, 8, ( const char* ) &buff, "NTP timestamp: %s", &buff );
737         free( ptime ); ??????????????????????????????????????????????????????????????????
738         offset += 8;
739 #else
740         /*
741          * XXX - RFC 1889 says this is an NTP timestamp, but that appears
742          * not to be the case.
743          */
744         proto_tree_add_text(tree, tvb, offset, 4, "Timestamp, MSW: %u",
745                 tvb_get_ntohl(tvb, offset));
746         offset += 4;
747         proto_tree_add_text(tree, tvb, offset, 4, "Timestamp, LSW: %u",
748                 tvb_get_ntohl(tvb, offset));
749         offset += 4;
750 #endif
751         /* RTP timestamp, 32 bits */
752         proto_tree_add_uint( tree, hf_rtcp_rtp_timestamp, tvb, offset, 4, tvb_get_ntohl( tvb, offset ) );
753         offset += 4;
754         /* Sender's packet count, 32 bits */
755         proto_tree_add_uint( tree, hf_rtcp_sender_pkt_cnt, tvb, offset, 4, tvb_get_ntohl( tvb, offset ) );
756         offset += 4;
757         /* Sender's octet count, 32 bits */
758         proto_tree_add_uint( tree, hf_rtcp_sender_oct_cnt, tvb, offset, 4, tvb_get_ntohl( tvb, offset ) );
759         offset += 4;
760
761         /* The rest of the packet is equal to the RR packet */
762         if ( count != 0 )
763                 offset = dissect_rtcp_rr( tvb, offset, tree, count );
764
765         return offset;
766 }
767
768 static void
769 dissect_rtcp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree )
770 {
771         proto_item *ti           = NULL;
772         proto_tree *rtcp_tree    = NULL;
773         unsigned int temp_byte   = 0;
774         unsigned int padding_set = 0;
775         unsigned int elem_count  = 0;
776         unsigned int packet_type = 0;
777         unsigned int offset      = 0;
778         guint16 packet_length    = 0;
779         guint rtcp_subtype               = 0;
780
781         if ( check_col( pinfo->cinfo, COL_PROTOCOL ) )   {
782                 col_set_str( pinfo->cinfo, COL_PROTOCOL, "RTCP" );
783         }
784
785         if ( check_col( pinfo->cinfo, COL_INFO) ) {
786                 /* The second octet contains the packet type */
787                 /* switch ( pd[ offset + 1 ] ) { */
788                 switch ( tvb_get_guint8( tvb, 1 ) ) {
789                         case RTCP_SR:
790                                 col_set_str( pinfo->cinfo, COL_INFO, "Sender Report");
791                                 break;
792                         case RTCP_RR:
793                                 col_set_str( pinfo->cinfo, COL_INFO, "Receiver Report");
794                                 break;
795                         case RTCP_SDES:
796                                 col_set_str( pinfo->cinfo, COL_INFO, "Source Description");
797                                 break;
798                         case RTCP_BYE:
799                                 col_set_str( pinfo->cinfo, COL_INFO, "Goodbye");
800                                 break;
801                         case RTCP_APP:
802                                 col_set_str( pinfo->cinfo, COL_INFO, "Application defined");
803                                 break;
804                         case RTCP_XR:
805                                 col_set_str( pinfo->cinfo, COL_INFO, "Extended report");
806                                 break;
807                         case RTCP_FIR:
808                                 col_set_str( pinfo->cinfo, COL_INFO, "Full Intra-frame Request (H.261)");
809                                 break;
810                         case RTCP_NACK:
811                                 col_set_str( pinfo->cinfo, COL_INFO, "Negative Acknowledgement (H.261)");
812                                 break;
813                         default:
814                                 col_set_str( pinfo->cinfo, COL_INFO, "Unknown packet type");
815                                 break;
816                 }
817         }
818
819         if ( tree ) {
820
821                 /*
822                  * Check if there are at least 4 bytes left in the frame,
823                  * the last 16 bits of those is the length of the current
824                  * RTCP message. The last compound message contains padding,
825                  * that enables us to break from the while loop.
826                  */
827                 while ( tvb_bytes_exist( tvb, offset, 4) ) {
828                         /*
829                          * First retreive the packet_type
830                          */
831                         packet_type = tvb_get_guint8( tvb, offset + 1 );
832
833                         /*
834                          * Check if it's a valid type
835                          */
836                         if ( ( packet_type < 192 ) || ( packet_type >  204 ) )
837                                 break;
838
839                         /*
840                          * get the packet-length for the complete RTCP packet
841                          */
842                         packet_length = ( tvb_get_ntohs( tvb, offset + 2 ) + 1 ) * 4;
843
844                         ti = proto_tree_add_item(tree, proto_rtcp, tvb, offset, packet_length, FALSE );
845                         rtcp_tree = proto_item_add_subtree( ti, ett_rtcp );
846
847                         temp_byte = tvb_get_guint8( tvb, offset );
848
849                         proto_tree_add_uint( rtcp_tree, hf_rtcp_version, tvb,
850                             offset, 1, temp_byte);
851                         padding_set = RTCP_PADDING( temp_byte );
852                         proto_tree_add_boolean( rtcp_tree, hf_rtcp_padding, tvb,
853                             offset, 1, temp_byte );
854                         elem_count = RTCP_COUNT( temp_byte );
855
856                         switch ( packet_type ) {
857                                 case RTCP_SR:
858                                 case RTCP_RR:
859                                         /* Receiver report count, 5 bits */
860                                         proto_tree_add_uint( rtcp_tree, hf_rtcp_rc, tvb, offset, 1, temp_byte );
861                                         offset++;
862                                         /* Packet type, 8 bits */
863                                         proto_tree_add_item( rtcp_tree, hf_rtcp_pt, tvb, offset, 1, FALSE );
864                                         offset++;
865                                         /* Packet length in 32 bit words MINUS one, 16 bits */
866                                         proto_tree_add_uint( rtcp_tree, hf_rtcp_length, tvb, offset, 2, tvb_get_ntohs( tvb, offset ) );
867                                         offset += 2;
868                                         /* Sender Synchronization source, 32 bits */
869                                         proto_tree_add_uint( rtcp_tree, hf_rtcp_ssrc_sender, tvb, offset, 4, tvb_get_ntohl( tvb, offset ) );
870                                         offset += 4;
871
872                                         if ( packet_type == RTCP_SR ) offset = dissect_rtcp_sr( tvb, offset, rtcp_tree, elem_count );
873                                         else offset = dissect_rtcp_rr( tvb, offset, rtcp_tree, elem_count );
874                                         break;
875                                 case RTCP_SDES:
876                                         /* Source count, 5 bits */
877                                         proto_tree_add_uint( rtcp_tree, hf_rtcp_sc, tvb, offset, 1, temp_byte );
878                                         offset++;
879                                         /* Packet type, 8 bits */
880                                         proto_tree_add_item( rtcp_tree, hf_rtcp_pt, tvb, offset, 1, FALSE );
881                                         offset++;
882                                         /* Packet length in 32 bit words MINUS one, 16 bits */
883                                         proto_tree_add_uint( rtcp_tree, hf_rtcp_length, tvb, offset, 2, tvb_get_ntohs( tvb, offset ) );
884                                         offset += 2;
885                                         dissect_rtcp_sdes( tvb, offset, rtcp_tree, elem_count );
886                                         offset += packet_length - 4;
887                                         break;
888                                 case RTCP_BYE:
889                                         /* Source count, 5 bits */
890                                         proto_tree_add_uint( rtcp_tree, hf_rtcp_sc, tvb, offset, 1, temp_byte );
891                                         offset++;
892                                         /* Packet type, 8 bits */
893                                         proto_tree_add_item( rtcp_tree, hf_rtcp_pt, tvb, offset, 1, FALSE );
894                                         offset++;
895                                         /* Packet length in 32 bit words MINUS one, 16 bits */
896                                         proto_tree_add_uint( rtcp_tree, hf_rtcp_length, tvb, offset, 2, tvb_get_ntohs( tvb, offset ) );
897                                         offset += 2;
898                                         offset = dissect_rtcp_bye( tvb, offset, rtcp_tree, elem_count );
899                                         break;
900                                 case RTCP_APP:
901                                         /* Subtype, 5 bits */
902                                         rtcp_subtype = elem_count;
903                                         proto_tree_add_uint( rtcp_tree, hf_rtcp_subtype, tvb, offset, 1, elem_count );
904                                         offset++;
905                                         /* Packet type, 8 bits */
906                                         proto_tree_add_item( rtcp_tree, hf_rtcp_pt, tvb, offset, 1, FALSE );
907                                         offset++;
908                                         /* Packet length in 32 bit words MINUS one, 16 bits */
909                                         proto_tree_add_uint( rtcp_tree, hf_rtcp_length, tvb, offset, 2, tvb_get_ntohs( tvb, offset ) );
910                                         offset += 2;
911                                         offset = dissect_rtcp_app( tvb, pinfo, offset,
912                                             rtcp_tree, padding_set,
913                                             packet_length - 4, rtcp_subtype );
914                                         break;
915                                 case RTCP_FIR:
916                                         offset = dissect_rtcp_fir( tvb, offset, rtcp_tree );
917                                         break;
918                                 case RTCP_NACK:
919                                         offset = dissect_rtcp_nack( tvb, offset, rtcp_tree );
920                                         break;
921                                 default:
922                                         /*
923                                          * To prevent endless loops in case of an unknown message type
924                                          * increase offset. Some time the while will end :-)
925                                          */
926                                         offset++;
927                                         break;
928                         }
929                 }
930                 /* If the padding bit is set, the last octet of the
931                  * packet contains the length of the padding
932                  * We only have to check for this at the end of the LAST RTCP message
933                  */
934                 if ( padding_set ) {
935                         /* If everything went according to plan offset should now point to the
936                          * first octet of the padding
937                          */
938                         proto_tree_add_item( rtcp_tree, hf_rtcp_padding_data, tvb, offset, tvb_length_remaining( tvb, offset) - 1, FALSE );
939                         offset += tvb_length_remaining( tvb, offset) - 1;
940                         proto_tree_add_item( rtcp_tree, hf_rtcp_padding_count, tvb, offset, 1, FALSE );
941                 }
942         }
943 }
944
945 void
946 proto_register_rtcp(void)
947 {
948         static hf_register_info hf[] =
949         {
950                 {
951                         &hf_rtcp_version,
952                         {
953                                 "Version",
954                                 "rtcp.version",
955                                 FT_UINT8,
956                                 BASE_DEC,
957                                 VALS(rtcp_version_vals),
958                                 0xC0,
959                                 "", HFILL
960                         }
961                 },
962                 {
963                         &hf_rtcp_padding,
964                         {
965                                 "Padding",
966                                 "rtcp.padding",
967                                 FT_BOOLEAN,
968                                 8,
969                                 NULL,
970                                 0x20,
971                                 "", HFILL
972                         }
973                 },
974                 {
975                         &hf_rtcp_rc,
976                         {
977                                 "Reception report count",
978                                 "rtcp.rc",
979                                 FT_UINT8,
980                                 BASE_DEC,
981                                 NULL,
982                                 0x1F,
983                                 "", HFILL
984                         }
985                 },
986                 {
987                         &hf_rtcp_sc,
988                         {
989                                 "Source count",
990                                 "rtcp.sc",
991                                 FT_UINT8,
992                                 BASE_DEC,
993                                 NULL,
994                                 0x1F,
995                                 "", HFILL
996                         }
997                 },
998                 {
999                         &hf_rtcp_pt,
1000                         {
1001                                 "Packet type",
1002                                 "rtcp.pt",
1003                                 FT_UINT8,
1004                                 BASE_DEC,
1005                                 VALS( rtcp_packet_type_vals ),
1006                                 0x0,
1007                                 "", HFILL
1008                         }
1009                 },
1010                 {
1011                         &hf_rtcp_length,
1012                         {
1013                                 "Length",
1014                                 "rtcp.length",
1015                                 FT_UINT16,
1016                                 BASE_DEC,
1017                                 NULL,
1018                                 0x0,
1019                                 "", HFILL
1020                         }
1021                 },
1022                 {
1023                         &hf_rtcp_ssrc_sender,
1024                         {
1025                                 "Sender SSRC",
1026                                 "rtcp.senderssrc",
1027                                 FT_UINT32,
1028                                 BASE_DEC,
1029                                 NULL,
1030                                 0x0,
1031                                 "", HFILL
1032                         }
1033                 },
1034                 {
1035                         &hf_rtcp_ntp,
1036                         {
1037                                 "NTP timestamp",
1038                                 "rtcp.timestamp.ntp",
1039                                 FT_STRING,
1040                                 BASE_NONE,
1041                                 NULL,
1042                                 0x0,
1043                                 "", HFILL
1044                         }
1045                 },
1046                 {
1047                         &hf_rtcp_rtp_timestamp,
1048                         {
1049                                 "RTP timestamp",
1050                                 "rtcp.timestamp.rtp",
1051                                 FT_UINT32,
1052                                 BASE_DEC,
1053                                 NULL,
1054                                 0x0,
1055                                 "", HFILL
1056                         }
1057                 },
1058                 {
1059                         &hf_rtcp_sender_pkt_cnt,
1060                         {
1061                                 "Sender's packet count",
1062                                 "rtcp.sender.packetcount",
1063                                 FT_UINT32,
1064                                 BASE_DEC,
1065                                 NULL,
1066                                 0x0,
1067                                 "", HFILL
1068                         }
1069                 },
1070                 {
1071                         &hf_rtcp_sender_oct_cnt,
1072                         {
1073                                 "Sender's octet count",
1074                                 "rtcp.sender.octetcount",
1075                                 FT_UINT32,
1076                                 BASE_DEC,
1077                                 NULL,
1078                                 0x0,
1079                                 "", HFILL
1080                         }
1081                 },
1082                 {
1083                         &hf_rtcp_ssrc_source,
1084                         {
1085                                 "Identifier",
1086                                 "rtcp.ssrc.identifier",
1087                                 FT_UINT32,
1088                                 BASE_DEC,
1089                                 NULL,
1090                                 0x0,
1091                                 "", HFILL
1092                         }
1093                 },
1094                 {
1095                         &hf_rtcp_ssrc_fraction,
1096                         {
1097                                 "Fraction lost",
1098                                 "rtcp.ssrc.fraction",
1099                                 FT_UINT8,
1100                                 BASE_DEC,
1101                                 NULL,
1102                                 0x0,
1103                                 "", HFILL
1104                         }
1105                 },
1106                 {
1107                         &hf_rtcp_ssrc_cum_nr,
1108                         {
1109                                 "Cumulative number of packets lost",
1110                                 "rtcp.ssrc.cum_nr",
1111                                 FT_UINT32,
1112                                 BASE_DEC,
1113                                 NULL,
1114                                 0x0,
1115                                 "", HFILL
1116                         }
1117                 },
1118                 {
1119                         &hf_rtcp_ssrc_ext_high_seq,
1120                         {
1121                                 "Extended highest sequence number received",
1122                                 "rtcp.ssrc.ext_high",
1123                                 FT_UINT32,
1124                                 BASE_DEC,
1125                                 NULL,
1126                                 0x0,
1127                                 "", HFILL
1128                         }
1129                 },
1130                 {
1131                         &hf_rtcp_ssrc_high_seq,
1132                         {
1133                                 "Highest sequence number received",
1134                                 "rtcp.ssrc.high_seq",
1135                                 FT_UINT16,
1136                                 BASE_DEC,
1137                                 NULL,
1138                                 0x0,
1139                                 "", HFILL
1140                         }
1141                 },
1142                 {
1143                         &hf_rtcp_ssrc_high_cycles,
1144                         {
1145                                 "Sequence number cycles count",
1146                                 "rtcp.ssrc.high_cycles",
1147                                 FT_UINT16,
1148                                 BASE_DEC,
1149                                 NULL,
1150                                 0x0,
1151                                 "", HFILL
1152                         }
1153                 },
1154                 {
1155                         &hf_rtcp_ssrc_jitter,
1156                         {
1157                                 "Interarrival jitter",
1158                                 "rtcp.ssrc.jitter",
1159                                 FT_UINT32,
1160                                 BASE_DEC,
1161                                 NULL,
1162                                 0x0,
1163                                 "", HFILL
1164                         }
1165                 },
1166                 {
1167                         &hf_rtcp_ssrc_lsr,
1168                         {
1169                                 "Last SR timestamp",
1170                                 "rtcp.ssrc.lsr",
1171                                 FT_UINT32,
1172                                 BASE_DEC,
1173                                 NULL,
1174                                 0x0,
1175                                 "", HFILL
1176                         }
1177                 },
1178                 {
1179                         &hf_rtcp_ssrc_dlsr,
1180                         {
1181                                 "Delay since last SR timestamp",
1182                                 "rtcp.ssrc.dlsr",
1183                                 FT_UINT32,
1184                                 BASE_DEC,
1185                                 NULL,
1186                                 0x0,
1187                                 "", HFILL
1188                         }
1189                 },
1190                 {
1191                         &hf_rtcp_ssrc_csrc,
1192                         {
1193                                 "SSRC / CSRC identifier",
1194                                 "rtcp.sdes.ssrc_csrc",
1195                                 FT_UINT32,
1196                                 BASE_DEC,
1197                                 NULL,
1198                                 0x0,
1199                                 "", HFILL
1200                         }
1201                 },
1202                 {
1203                         &hf_rtcp_ssrc_type,
1204                         {
1205                                 "Type",
1206                                 "rtcp.sdes.type",
1207                                 FT_UINT8,
1208                                 BASE_DEC,
1209                                 VALS( rtcp_sdes_type_vals ),
1210                                 0x0,
1211                                 "", HFILL
1212                         }
1213                 },
1214                 {
1215                         &hf_rtcp_ssrc_length,
1216                         {
1217                                 "Length",
1218                                 "rtcp.sdes.length",
1219                                 FT_UINT32,
1220                                 BASE_DEC,
1221                                 NULL,
1222                                 0x0,
1223                                 "", HFILL
1224                         }
1225                 },
1226                 {
1227                         &hf_rtcp_ssrc_text,
1228                         {
1229                                 "Text",
1230                                 "rtcp.sdes.text",
1231                                 FT_STRING,
1232                                 BASE_NONE,
1233                                 NULL,
1234                                 0x0,
1235                                 "", HFILL
1236                         }
1237                 },
1238                 {
1239                         &hf_rtcp_ssrc_prefix_len,
1240                         {
1241                                 "Prefix length",
1242                                 "rtcp.sdes.prefix.length",
1243                                 FT_UINT8,
1244                                 BASE_DEC,
1245                                 NULL,
1246                                 0x0,
1247                                 "", HFILL
1248                         }
1249                 },
1250                 {
1251                         &hf_rtcp_ssrc_prefix_string,
1252                         {
1253                                 "Prefix string",
1254                                 "rtcp.sdes.prefix.string",
1255                                 FT_STRING,
1256                                 BASE_NONE,
1257                                 NULL,
1258                                 0x0,
1259                                 "", HFILL
1260                         }
1261                 },
1262                 {
1263                         &hf_rtcp_subtype,
1264                         {
1265                                 "Subtype",
1266                                 "rtcp.app.subtype",
1267                                 FT_UINT8,
1268                                 BASE_DEC,
1269                                 NULL,
1270                                 0x0,
1271                                 "", HFILL
1272                         }
1273                 },
1274                 {
1275                         &hf_rtcp_name_ascii,
1276                         {
1277                                 "Name (ASCII)",
1278                                 "rtcp.app.name",
1279                                 FT_STRING,
1280                                 BASE_NONE,
1281                                 NULL,
1282                                 0x0,
1283                                 "", HFILL
1284                         }
1285                 },
1286                 {
1287                         &hf_rtcp_app_data,
1288                         {
1289                                 "Application specific data",
1290                                 "rtcp.app.data",
1291                                 FT_BYTES,
1292                                 BASE_NONE,
1293                                 NULL,
1294                                 0x0,
1295                                 "", HFILL
1296                         }
1297                 },
1298                 {
1299                         &hf_rtcp_app_PoC1_subtype,
1300                         {
1301                                 "Subtype",
1302                                 "rtcp.app.PoC1.subtype",
1303                                 FT_UINT8,
1304                                 BASE_DEC,
1305                                 VALS(rtcp_app_poc1_floor_cnt_type_vals),
1306                                 0x0,
1307                                 "", HFILL
1308                         }
1309                 },
1310
1311                 {
1312                         &hf_rtcp_app_poc1_sip_uri,
1313                 {
1314                                 "SIP URI",
1315                                 "rtcp.app.poc1.sip.uri",
1316                                 FT_STRING,
1317                                 BASE_NONE,
1318                                 NULL,
1319                                 0x0,
1320                                 "", HFILL
1321                         }
1322                 },
1323                 {
1324                         &hf_rtcp_app_poc1_disp_name,
1325                 {
1326                                 "Display Name",
1327                                 "rtcp.app.poc1.disp.name",
1328                                 FT_STRING,
1329                                 BASE_NONE,
1330                                 NULL,
1331                                 0x0,
1332                                 "", HFILL
1333                         }
1334                 },
1335                 {
1336                         &hf_rtcp_app_poc1_last_pkt_seq_no,
1337                 {
1338                                 "Seq. no of last RTP packet",
1339                                 "rtcp.app.poc1.last.pkt.seq.no",
1340                                 FT_UINT16,
1341                                 BASE_DEC,
1342                                 NULL,
1343                                 0x0,
1344                                 "", HFILL
1345                         }
1346                 },
1347                 {
1348                         &hf_rtcp_app_poc1_reason_code1,
1349                 {
1350                                 "Reason code",
1351                                 "rtcp.app.poc1.reason.code",
1352                                 FT_UINT8,
1353                                 BASE_DEC,
1354                                 VALS(rtcp_app_poc1_reason_code2_vals),
1355                                 0x0,
1356                                 "", HFILL
1357                         }
1358                 },
1359                 {
1360                         &hf_rtcp_app_poc1_item_len,
1361                 {
1362                                 "Item length",
1363                                 "rtcp.app.poc1.item.len",
1364                                 FT_UINT8,
1365                                 BASE_DEC,
1366                                 NULL,
1367                                 0x0,
1368                                 "", HFILL
1369                         }
1370                 },
1371                 {
1372                         &hf_rtcp_app_poc1_reason1_phrase,
1373                 {
1374                                 "Reason Phrase",
1375                                 "rtcp.app.poc1.reason.phrase",
1376                                 FT_STRING,
1377                                 BASE_NONE,
1378                                 NULL,
1379                                 0x0,
1380                                 "", HFILL
1381                         }
1382                 },
1383                 {
1384                         &hf_rtcp_app_poc1_reason_code2,
1385                 {
1386                                 "Reason code",
1387                                 "rtcp.app.poc1.reason.code",
1388                                 FT_UINT16,
1389                                 BASE_DEC,
1390                                 VALS(rtcp_app_poc1_reason_code2_vals),
1391                                 0x0,
1392                                 "", HFILL
1393                         }
1394                 },
1395                 {
1396                         &hf_rtcp_app_poc1_additionalinfo,
1397                 {
1398                                 "additional information",
1399                                 "rtcp.app.poc1.add.info",
1400                                 FT_UINT16,
1401                                 BASE_DEC,
1402                                 NULL,
1403                                 0x0,
1404                                 "", HFILL
1405                         }
1406                 },
1407                 {
1408                         &hf_rtcp_fsn,
1409                         {
1410                                 "First sequence number",
1411                                 "rtcp.nack.fsn",
1412                                 FT_UINT16,
1413                                 BASE_DEC,
1414                                 NULL,
1415                                 0x0,
1416                                 "", HFILL
1417                         }
1418                 },
1419                 {
1420                         &hf_rtcp_blp,
1421                         {
1422                                 "Bitmask of following lost packets",
1423                                 "rtcp.nack.blp",
1424                                 FT_UINT16,
1425                                 BASE_DEC,
1426                                 NULL,
1427                                 0x0,
1428                                 "", HFILL
1429                         }
1430                 },
1431                 {
1432                         &hf_rtcp_padding_count,
1433                         {
1434                                 "Padding count",
1435                                 "rtcp.padding.count",
1436                                 FT_UINT8,
1437                                 BASE_DEC,
1438                                 NULL,
1439                                 0x0,
1440                                 "", HFILL
1441                         }
1442                 },
1443                 {
1444                         &hf_rtcp_padding_data,
1445                         {
1446                                 "Padding data",
1447                                 "rtcp.padding.data",
1448                                 FT_BYTES,
1449                                 BASE_NONE,
1450                                 NULL,
1451                                 0x0,
1452                                 "", HFILL
1453                         }
1454                 },
1455 };
1456
1457         static gint *ett[] =
1458         {
1459                 &ett_rtcp,
1460                 &ett_ssrc,
1461                 &ett_ssrc_item,
1462                 &ett_ssrc_ext_high,
1463                 &ett_sdes,
1464                 &ett_sdes_item,
1465                 &ett_PoC1,
1466         };
1467
1468
1469         proto_rtcp = proto_register_protocol("Real-time Transport Control Protocol",
1470             "RTCP", "rtcp");
1471         proto_register_field_array(proto_rtcp, hf, array_length(hf));
1472         proto_register_subtree_array(ett, array_length(ett));
1473
1474         register_dissector("rtcp", dissect_rtcp, proto_rtcp);
1475
1476 #if 0
1477         register_init_routine( &rtcp_init );
1478 #endif
1479 }
1480
1481 void
1482 proto_reg_handoff_rtcp(void)
1483 {
1484         dissector_handle_t rtcp_handle;
1485
1486         /*
1487          * Register this dissector as one that can be selected by a
1488          * UDP port number.
1489          */
1490         rtcp_handle = find_dissector("rtcp");
1491         dissector_add_handle("udp.port", rtcp_handle);
1492 }