3 * $Id: packet-rtcp.c,v 1.42 2004/05/31 19:35:53 etxrab Exp $
5 * Routines for RTCP dissection
6 * RTCP = Real-time Transport Control Protocol
8 * Copyright 2000, Philips Electronics N.V.
9 * Written by Andreas Sikkema <h323@ramdyne.nl>
11 * Copyright 2004, Anders Broman <anders.broman@ericsson.com>
13 * Ethereal - Network traffic analyzer
14 * By Gerald Combs <gerald@ethereal.com>
15 * Copyright 1998 Gerald Combs
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.
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.
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.
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.
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
41 * See also http://www.iana.org/assignments/rtp-parameters
50 #include <epan/packet.h>
55 #include "packet-rtcp.h"
57 #include "packet-ntp.h"
59 #include <epan/conversation.h>
61 /* Version is the first 2 bits of the first octet*/
62 #define RTCP_VERSION(octet) ((octet) >> 6)
64 /* Padding is the third bit; no need to shift, because true is any value
66 #define RTCP_PADDING(octet) ((octet) & 0x20)
68 /* Receiver/ Sender count is the 5 last bits */
69 #define RTCP_COUNT(octet) ((octet) & 0x1F)
71 static const value_string rtcp_version_vals[] =
73 { 0, "Old VAT Version" },
74 { 1, "First Draft Version" },
75 { 2, "RFC 1889 Version" },
79 /* RTCP packet types according to Section A.11.1 */
80 /* And http://www.iana.org/assignments/rtp-parameters */
87 /* Supplemental H.261 specific RTCP packet types according to Section C.3.5 */
91 static const value_string rtcp_packet_type_vals[] =
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"},
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
116 static const value_string rtcp_sdes_type_vals[] =
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)"},
130 /* RTCP Application PoC1 Value strings */
131 static const value_string rtcp_app_poc1_floor_cnt_type_vals[] =
133 { 0, "Floor Request"},
137 { 4, "Floor Release"},
139 { 6, "Floor Revoke"},
143 static const value_string rtcp_app_poc1_reason_code1_vals[] =
145 { 1, "Floor already in use"},
146 { 2, "Internal PoC server error"},
150 static const value_string rtcp_app_poc1_reason_code2_vals[] =
152 { 1, "Only one user"},
153 { 2, "Talk burst too long"},
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;
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;
213 static address fake_addr;
214 static int heur_init = FALSE;
216 static gboolean dissect_rtcp_heur( tvbuff_t *tvb, packet_info *pinfo,
218 static void dissect_rtcp( tvbuff_t *tvb, packet_info *pinfo,
221 void rtcp_add_address( packet_info *pinfo, const unsigned char* ip_addr,
225 conversation_t* pconv;
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
232 if (pinfo->fd->flags.visited)
235 src_addr.type = AT_IPv4;
237 src_addr.data = ip_addr;
240 * The first time the function is called let the udp dissector
241 * know that we're interested in traffic
244 heur_dissector_add( "udp", dissect_rtcp_heur, proto_rtcp );
249 * Check if the ip address and port combination is not
252 pconv = find_conversation( &src_addr, &fake_addr, PT_UDP, prt, 0, 0 );
256 * XXX - use wildcard address and port B?
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);
267 static void rtcp_init( void )
269 unsigned char* tmp_data;
272 /* Create a fake adddress... */
273 fake_addr.type = AT_IPv4;
276 tmp_data = g_malloc( fake_addr.len );
277 for ( i = 0; i < fake_addr.len; i++) {
280 fake_addr.data = tmp_data;
285 dissect_rtcp_heur( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree )
287 conversation_t* pconv;
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.
294 if ( ( pconv = find_conversation( &pinfo->src, &fake_addr, pinfo->ptype,
295 pinfo->srcport, 0, 0 ) ) == NULL ) {
297 * The source ip:port combination was not what we were
298 * looking for, check the destination
300 if ( ( pconv = find_conversation( &pinfo->dst, &fake_addr,
301 pinfo->ptype, pinfo->destport, 0, 0 ) ) == NULL ) {
308 * An RTCP conversation always has a data item for RTCP.
309 * (Its existence is sufficient to indicate that this is an RTCP
312 if (conversation_get_proto_data(pconv, proto_rtcp) == NULL)
316 * The message is a valid RTCP message!
318 dissect_rtcp( tvb, pinfo, tree );
325 dissect_rtcp_nack( tvbuff_t *tvb, int offset, proto_tree *tree )
327 /* Packet type = FIR (H261) */
328 proto_tree_add_uint( tree, hf_rtcp_rc, tvb, offset, 1, tvb_get_guint8( tvb, offset ) );
330 /* Packet type, 8 bits = APP */
331 proto_tree_add_item( tree, hf_rtcp_pt, tvb, offset, 1, FALSE );
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 ) );
339 proto_tree_add_uint( tree, hf_rtcp_ssrc_source, tvb, offset, 4, tvb_get_ntohl( tvb, offset ) );
343 proto_tree_add_uint( tree, hf_rtcp_fsn, tvb, offset, 2, tvb_get_ntohs( tvb, offset ) );
347 proto_tree_add_uint( tree, hf_rtcp_blp, tvb, offset, 2, tvb_get_ntohs( tvb, offset ) );
354 dissect_rtcp_fir( tvbuff_t *tvb, int offset, proto_tree *tree )
356 /* Packet type = FIR (H261) */
357 proto_tree_add_uint( tree, hf_rtcp_rc, tvb, offset, 1, tvb_get_guint8( tvb, offset ) );
359 /* Packet type, 8 bits = APP */
360 proto_tree_add_item( tree, hf_rtcp_pt, tvb, offset, 1, FALSE );
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 ) );
368 proto_tree_add_uint( tree, hf_rtcp_ssrc_source, tvb, offset, 4, tvb_get_ntohl( tvb, offset ) );
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 )
378 unsigned int counter = 0;
382 guint items_start_offset;
383 proto_tree *PoC1_tree;
384 proto_item *PoC1_item;
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";
391 proto_tree_add_uint( tree, hf_rtcp_ssrc_source, tvb, offset, 4, tvb_get_ntohl( tvb, offset ) );
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,
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);
407 /* Applications specific data */
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
412 packet_len -= tvb_get_guint8( tvb, offset + packet_len - 1 );
414 proto_tree_add_item( tree, hf_rtcp_app_data, tvb, offset, packet_len, FALSE );
415 offset += packet_len;
418 }else{/* PoC1 Application */
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)") );
427 /* Applications specific data */
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
432 packet_len -= tvb_get_guint8( tvb, offset + packet_len - 1 );
434 /* Create a subtree for the PoC1 Application items; we don't yet know
436 items_start_offset = offset;
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 );
443 proto_tree_add_item( PoC1_tree, hf_rtcp_app_data, tvb, offset, packet_len, FALSE );
444 switch ( rtcp_subtype ) {
446 sdes_type = tvb_get_guint8( tvb, offset );
447 proto_tree_add_item( PoC1_tree, hf_rtcp_ssrc_type, tvb, offset, 1, FALSE );
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 );
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 );
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 );
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;
473 proto_tree_add_item( PoC1_tree, hf_rtcp_app_poc1_reason_code1, tvb, offset, 1, FALSE );
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 );
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;
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");
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 );
501 offset += packet_len;
508 dissect_rtcp_bye( tvbuff_t *tvb, int offset, proto_tree *tree,
511 unsigned int chunk = 1;
512 unsigned int reason_length = 0;
513 char* reason_text = NULL;
515 while ( chunk <= count ) {
516 /* source identifier, 32 bits */
517 proto_tree_add_item( tree, hf_rtcp_ssrc_source, tvb, offset, 4, FALSE);
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 );
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;
539 dissect_rtcp_sdes( tvbuff_t *tvb, int offset, proto_tree *tree,
542 unsigned int chunk = 1;
543 proto_item *sdes_item;
544 proto_tree *sdes_tree;
545 proto_tree *sdes_item_tree;
548 int items_start_offset;
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;
556 while ( chunk <= count ) {
557 /* Create a subtree for this chunk; we don't yet know
559 start_offset = offset;
561 ssrc = tvb_get_ntohl( tvb, offset );
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.
569 * A chunk with zero items (four null octets) is valid but useless."
571 proto_tree_add_text(tree, tvb, offset, 4, "Padding");
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 );
579 /* SSRC_n source identifier, 32 bits */
580 proto_tree_add_uint( sdes_tree, hf_rtcp_ssrc_source, tvb, offset, 4, ssrc );
583 /* Create a subtree for the SDES items; we don't yet know
585 items_start_offset = offset;
586 ti = proto_tree_add_text(sdes_tree, tvb, offset, -1,
588 sdes_item_tree = proto_item_add_subtree( ti, ett_sdes_item );
591 * Not every message is ended with "null" bytes, so check for
592 * end of frame instead.
594 while ( ( tvb_reported_length_remaining( tvb, offset ) > 0 )
595 && ( tvb_get_guint8( tvb, offset ) != RTCP_SDES_END ) ) {
597 sdes_type = tvb_get_guint8( tvb, offset );
598 proto_tree_add_item( sdes_item_tree, hf_rtcp_ssrc_type, tvb, offset, 1, FALSE );
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 );
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.
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 );
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;
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 );
636 /* Set the length of the items subtree. */
637 proto_item_set_len(ti, offset - items_start_offset);
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
643 if ( offset % 4 != 0 )
644 offset = ((offset / 4) + 1 ) * 4;
646 /* Set the length of this chunk. */
647 proto_item_set_len(sdes_item, offset - start_offset);
654 dissect_rtcp_rr( tvbuff_t *tvb, int offset, proto_tree *tree,
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;
663 unsigned int cum_nr = 0;
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 );
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 ) );
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 );
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 );
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,
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
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 ) );
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 ) );
706 /* Interarrival jitter */
707 proto_tree_add_uint( ssrc_tree, hf_rtcp_ssrc_jitter, tvb,
708 offset, 4, tvb_get_ntohl( tvb, offset ) );
711 /* Last SR timestamp */
712 proto_tree_add_uint( ssrc_tree, hf_rtcp_ssrc_lsr, tvb,
713 offset, 4, tvb_get_ntohl( tvb, offset ) );
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 ) );
727 dissect_rtcp_sr( tvbuff_t *tvb, int offset, proto_tree *tree,
731 gchar buff[ NTP_TS_SIZE ];
732 char* ptime = tvb_get_ptr( tvb, offset, 8 );
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 ); ??????????????????????????????????????????????????????????????????
741 * XXX - RFC 1889 says this is an NTP timestamp, but that appears
742 * not to be the case.
744 proto_tree_add_text(tree, tvb, offset, 4, "Timestamp, MSW: %u",
745 tvb_get_ntohl(tvb, offset));
747 proto_tree_add_text(tree, tvb, offset, 4, "Timestamp, LSW: %u",
748 tvb_get_ntohl(tvb, offset));
751 /* RTP timestamp, 32 bits */
752 proto_tree_add_uint( tree, hf_rtcp_rtp_timestamp, tvb, offset, 4, tvb_get_ntohl( tvb, offset ) );
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 ) );
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 ) );
761 /* The rest of the packet is equal to the RR packet */
763 offset = dissect_rtcp_rr( tvb, offset, tree, count );
769 dissect_rtcp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree )
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;
781 if ( check_col( pinfo->cinfo, COL_PROTOCOL ) ) {
782 col_set_str( pinfo->cinfo, COL_PROTOCOL, "RTCP" );
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 ) ) {
790 col_set_str( pinfo->cinfo, COL_INFO, "Sender Report");
793 col_set_str( pinfo->cinfo, COL_INFO, "Receiver Report");
796 col_set_str( pinfo->cinfo, COL_INFO, "Source Description");
799 col_set_str( pinfo->cinfo, COL_INFO, "Goodbye");
802 col_set_str( pinfo->cinfo, COL_INFO, "Application defined");
805 col_set_str( pinfo->cinfo, COL_INFO, "Extended report");
808 col_set_str( pinfo->cinfo, COL_INFO, "Full Intra-frame Request (H.261)");
811 col_set_str( pinfo->cinfo, COL_INFO, "Negative Acknowledgement (H.261)");
814 col_set_str( pinfo->cinfo, COL_INFO, "Unknown packet type");
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.
827 while ( tvb_bytes_exist( tvb, offset, 4) ) {
829 * First retreive the packet_type
831 packet_type = tvb_get_guint8( tvb, offset + 1 );
834 * Check if it's a valid type
836 if ( ( packet_type < 192 ) || ( packet_type > 204 ) )
840 * get the packet-length for the complete RTCP packet
842 packet_length = ( tvb_get_ntohs( tvb, offset + 2 ) + 1 ) * 4;
844 ti = proto_tree_add_item(tree, proto_rtcp, tvb, offset, packet_length, FALSE );
845 rtcp_tree = proto_item_add_subtree( ti, ett_rtcp );
847 temp_byte = tvb_get_guint8( tvb, offset );
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 );
856 switch ( packet_type ) {
859 /* Receiver report count, 5 bits */
860 proto_tree_add_uint( rtcp_tree, hf_rtcp_rc, tvb, offset, 1, temp_byte );
862 /* Packet type, 8 bits */
863 proto_tree_add_item( rtcp_tree, hf_rtcp_pt, tvb, offset, 1, FALSE );
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 ) );
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 ) );
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 );
876 /* Source count, 5 bits */
877 proto_tree_add_uint( rtcp_tree, hf_rtcp_sc, tvb, offset, 1, temp_byte );
879 /* Packet type, 8 bits */
880 proto_tree_add_item( rtcp_tree, hf_rtcp_pt, tvb, offset, 1, FALSE );
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 ) );
885 dissect_rtcp_sdes( tvb, offset, rtcp_tree, elem_count );
886 offset += packet_length - 4;
889 /* Source count, 5 bits */
890 proto_tree_add_uint( rtcp_tree, hf_rtcp_sc, tvb, offset, 1, temp_byte );
892 /* Packet type, 8 bits */
893 proto_tree_add_item( rtcp_tree, hf_rtcp_pt, tvb, offset, 1, FALSE );
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 ) );
898 offset = dissect_rtcp_bye( tvb, offset, rtcp_tree, elem_count );
901 /* Subtype, 5 bits */
902 rtcp_subtype = elem_count;
903 proto_tree_add_uint( rtcp_tree, hf_rtcp_subtype, tvb, offset, 1, elem_count );
905 /* Packet type, 8 bits */
906 proto_tree_add_item( rtcp_tree, hf_rtcp_pt, tvb, offset, 1, FALSE );
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 ) );
911 offset = dissect_rtcp_app( tvb, pinfo, offset,
912 rtcp_tree, padding_set,
913 packet_length - 4, rtcp_subtype );
916 offset = dissect_rtcp_fir( tvb, offset, rtcp_tree );
919 offset = dissect_rtcp_nack( tvb, offset, rtcp_tree );
923 * To prevent endless loops in case of an unknown message type
924 * increase offset. Some time the while will end :-)
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
935 /* If everything went according to plan offset should now point to the
936 * first octet of the padding
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 );
946 proto_register_rtcp(void)
948 static hf_register_info hf[] =
957 VALS(rtcp_version_vals),
977 "Reception report count",
1005 VALS( rtcp_packet_type_vals ),
1023 &hf_rtcp_ssrc_sender,
1038 "rtcp.timestamp.ntp",
1047 &hf_rtcp_rtp_timestamp,
1050 "rtcp.timestamp.rtp",
1059 &hf_rtcp_sender_pkt_cnt,
1061 "Sender's packet count",
1062 "rtcp.sender.packetcount",
1071 &hf_rtcp_sender_oct_cnt,
1073 "Sender's octet count",
1074 "rtcp.sender.octetcount",
1083 &hf_rtcp_ssrc_source,
1086 "rtcp.ssrc.identifier",
1095 &hf_rtcp_ssrc_fraction,
1098 "rtcp.ssrc.fraction",
1107 &hf_rtcp_ssrc_cum_nr,
1109 "Cumulative number of packets lost",
1119 &hf_rtcp_ssrc_ext_high_seq,
1121 "Extended highest sequence number received",
1122 "rtcp.ssrc.ext_high",
1131 &hf_rtcp_ssrc_high_seq,
1133 "Highest sequence number received",
1134 "rtcp.ssrc.high_seq",
1143 &hf_rtcp_ssrc_high_cycles,
1145 "Sequence number cycles count",
1146 "rtcp.ssrc.high_cycles",
1155 &hf_rtcp_ssrc_jitter,
1157 "Interarrival jitter",
1169 "Last SR timestamp",
1181 "Delay since last SR timestamp",
1193 "SSRC / CSRC identifier",
1194 "rtcp.sdes.ssrc_csrc",
1209 VALS( rtcp_sdes_type_vals ),
1215 &hf_rtcp_ssrc_length,
1239 &hf_rtcp_ssrc_prefix_len,
1242 "rtcp.sdes.prefix.length",
1251 &hf_rtcp_ssrc_prefix_string,
1254 "rtcp.sdes.prefix.string",
1275 &hf_rtcp_name_ascii,
1289 "Application specific data",
1299 &hf_rtcp_app_PoC1_subtype,
1302 "rtcp.app.PoC1.subtype",
1305 VALS(rtcp_app_poc1_floor_cnt_type_vals),
1312 &hf_rtcp_app_poc1_sip_uri,
1315 "rtcp.app.poc1.sip.uri",
1324 &hf_rtcp_app_poc1_disp_name,
1327 "rtcp.app.poc1.disp.name",
1336 &hf_rtcp_app_poc1_last_pkt_seq_no,
1338 "Seq. no of last RTP packet",
1339 "rtcp.app.poc1.last.pkt.seq.no",
1348 &hf_rtcp_app_poc1_reason_code1,
1351 "rtcp.app.poc1.reason.code",
1354 VALS(rtcp_app_poc1_reason_code2_vals),
1360 &hf_rtcp_app_poc1_item_len,
1363 "rtcp.app.poc1.item.len",
1372 &hf_rtcp_app_poc1_reason1_phrase,
1375 "rtcp.app.poc1.reason.phrase",
1384 &hf_rtcp_app_poc1_reason_code2,
1387 "rtcp.app.poc1.reason.code",
1390 VALS(rtcp_app_poc1_reason_code2_vals),
1396 &hf_rtcp_app_poc1_additionalinfo,
1398 "additional information",
1399 "rtcp.app.poc1.add.info",
1410 "First sequence number",
1422 "Bitmask of following lost packets",
1432 &hf_rtcp_padding_count,
1435 "rtcp.padding.count",
1444 &hf_rtcp_padding_data,
1447 "rtcp.padding.data",
1457 static gint *ett[] =
1469 proto_rtcp = proto_register_protocol("Real-time Transport Control Protocol",
1471 proto_register_field_array(proto_rtcp, hf, array_length(hf));
1472 proto_register_subtree_array(ett, array_length(ett));
1474 register_dissector("rtcp", dissect_rtcp, proto_rtcp);
1477 register_init_routine( &rtcp_init );
1482 proto_reg_handoff_rtcp(void)
1484 dissector_handle_t rtcp_handle;
1487 * Register this dissector as one that can be selected by a
1490 rtcp_handle = find_dissector("rtcp");
1491 dissector_add_handle("udp.port", rtcp_handle);