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 * Copyright 2005, Nagarjuna Venna <nvenna@brixnet.com>
15 * Ethereal - Network traffic analyzer
16 * By Gerald Combs <gerald@ethereal.com>
17 * Copyright 1998 Gerald Combs
19 * This program is free software; you can redistribute it and/or
20 * modify it under the terms of the GNU General Public License
21 * as published by the Free Software Foundation; either version 2
22 * of the License, or (at your option) any later version.
24 * This program is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * GNU General Public License for more details.
29 * You should have received a copy of the GNU General Public License
30 * along with this program; if not, write to the Free Software
31 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
35 * This dissector tries to dissect the RTCP protocol according to Annex A
36 * of ITU-T Recommendation H.225.0 (02/98) and RFC 1889
37 * H.225.0 literally copies RFC 1889, but omitting a few sections.
39 * RTCP traffic is handled by an uneven UDP portnumber. This can be any
40 * port number, but there is a registered port available, port 5005
41 * See Annex B of ITU-T Recommendation H.225.0, section B.7
43 * RTCP XR is specified in RFC 3611.
45 * See also http://www.iana.org/assignments/rtp-parameters
54 #include <epan/packet.h>
59 #include "packet-rtcp.h"
60 #include "packet-ntp.h"
61 #include <epan/conversation.h>
63 #include <epan/prefs.h>
64 #include <epan/emem.h>
67 /* Version is the first 2 bits of the first octet*/
68 #define RTCP_VERSION(octet) ((octet) >> 6)
70 /* Padding is the third bit; no need to shift, because true is any value
72 #define RTCP_PADDING(octet) ((octet) & 0x20)
74 /* Receiver/ Sender count is the 5 last bits */
75 #define RTCP_COUNT(octet) ((octet) & 0x1F)
77 static dissector_handle_t rtcp_handle;
79 static const value_string rtcp_version_vals[] =
81 { 0, "Old VAT Version" },
82 { 1, "First Draft Version" },
83 { 2, "RFC 1889 Version" },
87 /* RTCP packet types according to Section A.11.1 */
88 /* And http://www.iana.org/assignments/rtp-parameters */
94 #define RTCP_RTPFB 205
97 /* Supplemental H.261 specific RTCP packet types according to Section C.3.5 */
101 static const value_string rtcp_packet_type_vals[] =
103 { RTCP_SR, "Sender Report" },
104 { RTCP_RR, "Receiver Report" },
105 { RTCP_SDES, "Source description" },
106 { RTCP_BYE, "Goodbye" },
107 { RTCP_APP, "Application specific" },
108 { RTCP_FIR, "Full Intra-frame Request (H.261)" },
109 { RTCP_NACK, "Negative Acknowledgement (H.261)" },
110 { RTCP_RTPFB, "Generic RTP Feedback" },
111 { RTCP_PSFB, "Payload-specific" },
112 { RTCP_XR, "Extended report (RFC 3611)"},
116 /* RTCP SDES types (Section A.11.2) */
117 #define RTCP_SDES_END 0
118 #define RTCP_SDES_CNAME 1
119 #define RTCP_SDES_NAME 2
120 #define RTCP_SDES_EMAIL 3
121 #define RTCP_SDES_PHONE 4
122 #define RTCP_SDES_LOC 5
123 #define RTCP_SDES_TOOL 6
124 #define RTCP_SDES_NOTE 7
125 #define RTCP_SDES_PRIV 8
126 #define RTCP_SDES_H323_CADDR 9
128 static const value_string rtcp_sdes_type_vals[] =
130 { RTCP_SDES_END, "END" },
131 { RTCP_SDES_CNAME, "CNAME (user and domain)" },
132 { RTCP_SDES_NAME, "NAME (common name)" },
133 { RTCP_SDES_EMAIL, "EMAIL (e-mail address)" },
134 { RTCP_SDES_PHONE, "PHONE (phone number)" },
135 { RTCP_SDES_LOC, "LOC (geographic location)" },
136 { RTCP_SDES_TOOL, "TOOL (name/version of source app)" },
137 { RTCP_SDES_NOTE, "NOTE (note about source)" },
138 { RTCP_SDES_PRIV, "PRIV (private extensions)" },
139 { RTCP_SDES_H323_CADDR,"H323-CADDR (H.323 callable address)"},
143 /* RTCP XR Blocks (Section 4, RTC 3611) */
144 #define RTCP_XR_LOSS_RLE 1
145 #define RTCP_XR_DUP_RLE 2
146 #define RTCP_XR_PKT_RXTIMES 3
147 #define RTCP_XR_REF_TIME 4
148 #define RTCP_XR_DLRR 5
149 #define RTCP_XR_STATS_SUMRY 6
150 #define RTCP_XR_VOIP_METRCS 7
152 static const value_string rtcp_xr_type_vals[] =
154 { RTCP_XR_LOSS_RLE, "Loss Run Length Encoding Report Block" },
155 { RTCP_XR_DUP_RLE, "Duplicate Run Length Encoding Report Block" },
156 { RTCP_XR_PKT_RXTIMES, "Packet Receipt Times Report Block" },
157 { RTCP_XR_REF_TIME, "Receiver Reference Time Report Block" },
158 { RTCP_XR_DLRR, "DLRR Report Block" },
159 { RTCP_XR_STATS_SUMRY, "Statistics Summary Report Block" },
160 { RTCP_XR_VOIP_METRCS, "VoIP Metrics Report Block" },
164 /* XR VoIP Metrics Block - PLC Algorithms */
165 static const value_string rtcp_xr_plc_algo_vals[] =
167 { 0, "Unspecified" },
174 /* XR VoIP Metrics Block - JB Adaptive */
175 static const value_string rtcp_xr_jb_adaptive_vals[] =
179 { 2, "Non-Adaptive" },
184 /* XR Stats Summary Block - IP TTL or Hop Limit */
185 static const value_string rtcp_xr_ip_ttl_vals[] =
187 { 0, "No TTL Values" },
194 /* RTCP Application PoC1 Value strings */
195 static const value_string rtcp_app_poc1_floor_cnt_type_vals[] =
197 { 0, "Floor Request"},
201 { 4, "Floor Release"},
203 { 6, "Floor Revoke"},
205 { 8, "TBCP Queue Status Request"},
206 { 9, "TBCP Queue Status Response"},
207 { 11, "TBCP Disconnect"},
208 { 15, "TBCP Connect"},
209 { 18, "Floor Taken (ack expected)"},
213 static const value_string rtcp_app_poc1_reason_code1_vals[] =
215 { 1, "Floor already in use"},
216 { 2, "Internal PoC server error"},
217 { 3, "Only one participant in the group"},
218 { 4, "Retry-after timer has not expired"},
223 static const value_string rtcp_app_poc1_reason_code2_vals[] =
225 { 1, "Only one user"},
226 { 2, "Talk burst too long"},
227 { 3, "No permission"},
228 { 4, "Talk burst pre-empted"},
232 static const value_string rtcp_app_poc1_conn_sess_type_vals[] =
237 { 3, "Pre-arranged"},
242 static const value_string rtcp_app_poc1_qsresp_priority_vals[] =
244 { 0, "No priority (un-queued)"},
245 { 1, "Normal priority"},
246 { 2, "High priority"},
247 { 3, "Pre-emptive priority"},
251 /* RTCP header fields */
252 static int proto_rtcp = -1;
253 static int hf_rtcp_version = -1;
254 static int hf_rtcp_padding = -1;
255 static int hf_rtcp_rc = -1;
256 static int hf_rtcp_sc = -1;
257 static int hf_rtcp_pt = -1;
258 static int hf_rtcp_length = -1;
259 static int hf_rtcp_ssrc_sender = -1;
260 static int hf_rtcp_ntp = -1;
261 static int hf_rtcp_rtp_timestamp = -1;
262 static int hf_rtcp_sender_pkt_cnt = -1;
263 static int hf_rtcp_sender_oct_cnt = -1;
264 static int hf_rtcp_ssrc_source = -1;
265 static int hf_rtcp_ssrc_fraction = -1;
266 static int hf_rtcp_ssrc_cum_nr = -1;
267 static int hf_rtcp_ssrc_discarded = -1;
268 /* First the 32 bit number, then the split
269 * up 16 bit values */
270 /* These two are added to a subtree */
271 static int hf_rtcp_ssrc_ext_high_seq = -1;
272 static int hf_rtcp_ssrc_high_seq = -1;
273 static int hf_rtcp_ssrc_high_cycles = -1;
274 static int hf_rtcp_ssrc_jitter = -1;
275 static int hf_rtcp_ssrc_lsr = -1;
276 static int hf_rtcp_ssrc_dlsr = -1;
277 static int hf_rtcp_ssrc_csrc = -1;
278 static int hf_rtcp_ssrc_type = -1;
279 static int hf_rtcp_ssrc_length = -1;
280 static int hf_rtcp_ssrc_text = -1;
281 static int hf_rtcp_ssrc_prefix_len = -1;
282 static int hf_rtcp_ssrc_prefix_string= -1;
283 static int hf_rtcp_subtype = -1;
284 static int hf_rtcp_name_ascii = -1;
285 static int hf_rtcp_app_data = -1;
286 static int hf_rtcp_fsn = -1;
287 static int hf_rtcp_blp = -1;
288 static int hf_rtcp_padding_count = -1;
289 static int hf_rtcp_padding_data = -1;
290 static int hf_rtcp_app_poc1_subtype = -1;
291 static int hf_rtcp_app_poc1_sip_uri = -1;
292 static int hf_rtcp_app_poc1_disp_name = -1;
293 static int hf_rtcp_app_poc1_last_pkt_seq_no = -1;
294 static int hf_rtcp_app_poc1_reason_code1 = -1;
295 static int hf_rtcp_app_poc1_item_len = -1;
296 static int hf_rtcp_app_poc1_reason1_phrase = -1;
297 static int hf_rtcp_app_poc1_reason_code2 = -1;
298 static int hf_rtcp_app_poc1_additionalinfo = -1;
299 static int hf_rtcp_app_poc1_ack_subtype = -1;
300 static int hf_rtcp_app_poc1_ack_reason_code = -1;
301 static int hf_rtcp_app_poc1_qsresp_priority = -1;
302 static int hf_rtcp_app_poc1_qsresp_position = -1;
303 static int hf_rtcp_app_poc1_conn_content_1st_byte[5] = { -1, -1, -1, -1, -1 };
304 static int hf_rtcp_app_poc1_conn_session_type = -1;
305 static int hf_rtcp_app_poc1_conn_add_ind_mao = -1;
306 static int hf_rtcp_app_poc1_conn_sdes_items[5] = { -1, -1, -1, -1, -1 };
307 static int hf_rtcp_xr_block_type = -1;
308 static int hf_rtcp_xr_block_specific = -1;
309 static int hf_rtcp_xr_block_length = -1;
310 static int hf_rtcp_xr_thinning = -1;
311 static int hf_rtcp_xr_voip_metrics_burst_density = -1;
312 static int hf_rtcp_xr_voip_metrics_gap_density = -1;
313 static int hf_rtcp_xr_voip_metrics_burst_duration = -1;
314 static int hf_rtcp_xr_voip_metrics_gap_duration = -1;
315 static int hf_rtcp_xr_voip_metrics_rtdelay = -1;
316 static int hf_rtcp_xr_voip_metrics_esdelay = -1;
317 static int hf_rtcp_xr_voip_metrics_siglevel = -1;
318 static int hf_rtcp_xr_voip_metrics_noiselevel = -1;
319 static int hf_rtcp_xr_voip_metrics_rerl = -1;
320 static int hf_rtcp_xr_voip_metrics_gmin = -1;
321 static int hf_rtcp_xr_voip_metrics_rfactor = -1;
322 static int hf_rtcp_xr_voip_metrics_extrfactor = -1;
323 static int hf_rtcp_xr_voip_metrics_moslq = -1;
324 static int hf_rtcp_xr_voip_metrics_moscq = -1;
325 static int hf_rtcp_xr_voip_metrics_plc = -1;
326 static int hf_rtcp_xr_voip_metrics_jbadaptive = -1;
327 static int hf_rtcp_xr_voip_metrics_jbrate = -1;
328 static int hf_rtcp_xr_voip_metrics_jbnominal = -1;
329 static int hf_rtcp_xr_voip_metrics_jbmax = -1;
330 static int hf_rtcp_xr_voip_metrics_jbabsmax = -1;
331 static int hf_rtcp_xr_stats_loss_flag = -1;
332 static int hf_rtcp_xr_stats_dup_flag = -1;
333 static int hf_rtcp_xr_stats_jitter_flag = -1;
334 static int hf_rtcp_xr_stats_ttl = -1;
335 static int hf_rtcp_xr_beginseq = -1;
336 static int hf_rtcp_xr_endseq = -1;
337 static int hf_rtcp_xr_stats_lost = -1;
338 static int hf_rtcp_xr_stats_dups = -1;
339 static int hf_rtcp_xr_stats_minjitter = -1;
340 static int hf_rtcp_xr_stats_maxjitter = -1;
341 static int hf_rtcp_xr_stats_meanjitter = -1;
342 static int hf_rtcp_xr_stats_devjitter = -1;
343 static int hf_rtcp_xr_stats_minttl = -1;
344 static int hf_rtcp_xr_stats_maxttl = -1;
345 static int hf_rtcp_xr_stats_meanttl = -1;
346 static int hf_rtcp_xr_stats_devttl = -1;
347 static int hf_rtcp_xr_lrr = -1;
348 static int hf_rtcp_xr_dlrr = -1;
350 /* RTCP setup fields */
351 static int hf_rtcp_setup = -1;
352 static int hf_rtcp_setup_frame = -1;
353 static int hf_rtcp_setup_method = -1;
355 /* RTCP roundtrip delay fields */
356 static int hf_rtcp_roundtrip_delay = -1;
357 static int hf_rtcp_roundtrip_delay_frame = -1;
358 static int hf_rtcp_roundtrip_delay_delay = -1;
362 /* RTCP fields defining a sub tree */
363 static gint ett_rtcp = -1;
364 static gint ett_ssrc = -1;
365 static gint ett_ssrc_item = -1;
366 static gint ett_ssrc_ext_high = -1;
367 static gint ett_sdes = -1;
368 static gint ett_sdes_item = -1;
369 static gint ett_PoC1 = -1;
370 static gint ett_rtcp_setup = -1;
371 static gint ett_rtcp_roundtrip_delay = -1;
372 static gint ett_xr_block = -1;
373 static gint ett_xr_block_contents = -1;
374 static gint ett_xr_ssrc = -1;
375 static gint ett_xr_loss_chunk = -1;
376 static gint ett_poc1_conn_contents = -1;
378 /* Main dissection function */
379 static void dissect_rtcp( tvbuff_t *tvb, packet_info *pinfo,
382 /* Heuristic dissection */
383 static gboolean global_rtcp_heur = FALSE;
384 static gboolean dissect_rtcp_heur( tvbuff_t *tvb, packet_info *pinfo,
387 /* Displaying set info */
388 static gboolean global_rtcp_show_setup_info = TRUE;
389 static void show_setup_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
391 /* Related to roundtrip calculation (using LSR and DLSR) */
392 static gboolean global_rtcp_show_roundtrip_calculation = FALSE;
393 #define MIN_ROUNDTRIP_TO_REPORT_DEFAULT 10
394 static guint global_rtcp_show_roundtrip_calculation_minimum = MIN_ROUNDTRIP_TO_REPORT_DEFAULT;
395 static void remember_outgoing_sr(packet_info *pinfo, long lsr);
396 static void calculate_roundtrip_delay(tvbuff_t *tvb, packet_info *pinfo,
397 proto_tree *tree, guint32 lsr, guint32 dlsr);
398 static void add_roundtrip_delay_info(tvbuff_t *tvb, packet_info *pinfo,
399 proto_tree *tree, guint frame, guint delay);
402 /* Set up an RTCP conversation using the info given */
403 void rtcp_add_address( packet_info *pinfo,
404 address *addr, int port,
406 const gchar *setup_method, guint32 setup_frame_number)
409 conversation_t* p_conv;
410 struct _rtcp_conversation_info *p_conv_data = NULL;
413 * If this isn't the first time this packet has been processed,
414 * we've already done this work, so we don't need to do it
417 if (pinfo->fd->flags.visited)
422 SET_ADDRESS(&null_addr, AT_NONE, 0, NULL);
425 * Check if the ip address and port combination is not
426 * already registered as a conversation.
428 p_conv = find_conversation( pinfo->fd->num, addr, &null_addr, PT_UDP, port, other_port,
429 NO_ADDR_B | (!other_port ? NO_PORT_B : 0));
432 * If not, create a new conversation.
435 p_conv = conversation_new( pinfo->fd->num, addr, &null_addr, PT_UDP,
436 (guint32)port, (guint32)other_port,
437 NO_ADDR2 | (!other_port ? NO_PORT2 : 0));
441 conversation_set_dissector(p_conv, rtcp_handle);
444 * Check if the conversation has data associated with it.
446 p_conv_data = conversation_get_proto_data(p_conv, proto_rtcp);
449 * If not, add a new data item.
451 if ( ! p_conv_data ) {
452 /* Create conversation data */
453 p_conv_data = se_alloc(sizeof(struct _rtcp_conversation_info));
458 memset(p_conv_data, 0, sizeof(struct _rtcp_conversation_info));
459 conversation_add_proto_data(p_conv, proto_rtcp, p_conv_data);
463 * Update the conversation data.
465 p_conv_data->setup_method_set = TRUE;
466 strncpy(p_conv_data->setup_method, setup_method, MAX_RTCP_SETUP_METHOD_SIZE);
467 p_conv_data->setup_method[MAX_RTCP_SETUP_METHOD_SIZE] = '\0';
468 p_conv_data->setup_frame_number = setup_frame_number;
472 dissect_rtcp_heur( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree )
474 unsigned int offset = 0;
475 unsigned int first_byte;
476 unsigned int packet_type;
478 /* This is a heuristic dissector, which means we get all the UDP
479 * traffic not sent to a known dissector and not claimed by
480 * a heuristic dissector called before us!
483 if (!global_rtcp_heur)
488 /* Was it sent between 2 odd-numbered ports? */
489 if (!(pinfo->srcport % 2) || !(pinfo->destport % 2))
494 /* Look at first byte */
495 first_byte = tvb_get_guint8(tvb, offset);
497 /* Are version bits set to 2? */
498 if (((first_byte & 0xC0) >> 6) != 2)
503 /* Look at packet type */
504 packet_type = tvb_get_guint8(tvb, offset + 1);
506 /* First packet within compound packet is supposed to be a sender
507 or receiver report. Also see BYE so allow this... */
508 if (!((packet_type == RTCP_SR) || (packet_type == RTCP_RR) ||
509 packet_type == RTCP_BYE))
514 /* Overall length must be a multiple of 4 bytes */
515 if (tvb_length(tvb) % 4)
520 /* OK, dissect as RTCP */
521 dissect_rtcp(tvb, pinfo, tree);
527 dissect_rtcp_nack( tvbuff_t *tvb, int offset, proto_tree *tree )
529 /* Packet type = FIR (H261) */
530 proto_tree_add_uint( tree, hf_rtcp_rc, tvb, offset, 1, tvb_get_guint8( tvb, offset ) );
532 /* Packet type, 8 bits = APP */
533 proto_tree_add_item( tree, hf_rtcp_pt, tvb, offset, 1, FALSE );
536 /* Packet length in 32 bit words minus one */
537 proto_tree_add_uint( tree, hf_rtcp_length, tvb, offset, 2, tvb_get_ntohs( tvb, offset ) );
541 proto_tree_add_uint( tree, hf_rtcp_ssrc_source, tvb, offset, 4, tvb_get_ntohl( tvb, offset ) );
545 proto_tree_add_uint( tree, hf_rtcp_fsn, tvb, offset, 2, tvb_get_ntohs( tvb, offset ) );
549 proto_tree_add_uint( tree, hf_rtcp_blp, tvb, offset, 2, tvb_get_ntohs( tvb, offset ) );
556 dissect_rtcp_fir( tvbuff_t *tvb, int offset, proto_tree *tree )
558 /* Packet type = FIR (H261) */
559 proto_tree_add_uint( tree, hf_rtcp_rc, tvb, offset, 1, tvb_get_guint8( tvb, offset ) );
561 /* Packet type, 8 bits = APP */
562 proto_tree_add_item( tree, hf_rtcp_pt, tvb, offset, 1, FALSE );
565 /* Packet length in 32 bit words minus one */
566 proto_tree_add_uint( tree, hf_rtcp_length, tvb, offset, 2, tvb_get_ntohs( tvb, offset ) );
570 proto_tree_add_uint( tree, hf_rtcp_ssrc_source, tvb, offset, 4, tvb_get_ntohl( tvb, offset ) );
577 dissect_rtcp_app( tvbuff_t *tvb,packet_info *pinfo, int offset, proto_tree *tree,
578 unsigned int padding, unsigned int packet_len, guint rtcp_subtype )
580 unsigned int counter = 0;
584 guint items_start_offset;
585 proto_tree *PoC1_tree;
586 proto_item *PoC1_item;
588 /* XXX If more application types are to be dissected it may be useful to use a table like in packet-sip.c */
589 static const char app_name_str[] = "PoC1";
593 proto_tree_add_uint( tree, hf_rtcp_ssrc_source, tvb, offset, 4, tvb_get_ntohl( tvb, offset ) );
598 for( counter = 0; counter < 4; counter++ )
599 ascii_name[ counter ] = tvb_get_guint8( tvb, offset + counter );
600 /* strncpy( ascii_name, pd + offset, 4 ); */
601 ascii_name[4] = '\0';
602 proto_tree_add_string( tree, hf_rtcp_name_ascii, tvb, offset, 4,
604 if ( strncasecmp(ascii_name,app_name_str,4 ) != 0 ){ /* Not PoC1 */
605 if (check_col(pinfo->cinfo, COL_INFO))
606 col_append_fstr(pinfo->cinfo, COL_INFO,"( %s ) subtype=%u",ascii_name, rtcp_subtype);
609 /* Applications specific data */
611 /* If there's padding present, we have to remove that from the data part
612 * The last octet of the packet contains the length of the padding
614 packet_len -= tvb_get_guint8( tvb, offset + packet_len - 1 );
616 proto_tree_add_item( tree, hf_rtcp_app_data, tvb, offset, packet_len, FALSE );
617 offset += packet_len;
620 }else{/* PoC1 Application */
622 item = proto_tree_add_uint( tree, hf_rtcp_app_poc1_subtype, tvb, offset - 8, 1, rtcp_subtype );
623 PROTO_ITEM_SET_GENERATED(item);
624 if (check_col(pinfo->cinfo, COL_INFO))
625 col_append_fstr(pinfo->cinfo, COL_INFO,"(%s) subtype=%s",ascii_name,
626 val_to_str(rtcp_subtype,rtcp_app_poc1_floor_cnt_type_vals,"unknown (%u)") );
629 /* Applications specific data */
631 /* If there's padding present, we have to remove that from the data part
632 * The last octet of the packet contains the length of the padding
634 packet_len -= tvb_get_guint8( tvb, offset + packet_len - 1 );
636 /* Create a subtree for the PoC1 Application items; we don't yet know
638 items_start_offset = offset;
640 PoC1_item = proto_tree_add_text(tree, tvb, offset, packet_len,
641 "PoC1 Application specific data");
642 PoC1_tree = proto_item_add_subtree( PoC1_item, ett_PoC1 );
645 proto_tree_add_item( PoC1_tree, hf_rtcp_app_data, tvb, offset, packet_len, FALSE );
646 switch ( rtcp_subtype ) {
649 sdes_type = tvb_get_guint8( tvb, offset );
650 proto_tree_add_item( PoC1_tree, hf_rtcp_ssrc_type, tvb, offset, 1, FALSE );
653 /* Item length, 8 bits */
654 item_len = tvb_get_guint8( tvb, offset );
655 proto_tree_add_item( PoC1_tree, hf_rtcp_ssrc_length, tvb, offset, 1, FALSE );
658 proto_tree_add_item( PoC1_tree, hf_rtcp_app_poc1_sip_uri, tvb, offset, item_len, FALSE );
659 offset = offset + item_len;
660 packet_len = packet_len - item_len;
661 sdes_type = tvb_get_guint8( tvb, offset );
662 proto_tree_add_item( PoC1_tree, hf_rtcp_ssrc_type, tvb, offset, 1, FALSE );
665 /* Item length, 8 bits */
666 item_len = tvb_get_guint8( tvb, offset );
667 proto_tree_add_item( PoC1_tree, hf_rtcp_ssrc_length, tvb, offset, 1, FALSE );
671 proto_tree_add_item( PoC1_tree, hf_rtcp_app_poc1_disp_name, tvb, offset, item_len, FALSE );
672 offset = offset + item_len;
673 packet_len = packet_len - item_len;
676 proto_tree_add_item( PoC1_tree, hf_rtcp_app_poc1_reason_code1, tvb, offset, 1, FALSE );
679 /* Item length, 8 bits */
680 item_len = tvb_get_guint8( tvb, offset );
681 proto_tree_add_item( PoC1_tree, hf_rtcp_app_poc1_item_len, tvb, offset, 1, FALSE );
685 proto_tree_add_item( PoC1_tree, hf_rtcp_app_poc1_reason1_phrase, tvb, offset, item_len, FALSE );
686 offset = offset + item_len;
687 packet_len = packet_len - item_len;
690 proto_tree_add_item( PoC1_tree, hf_rtcp_app_poc1_last_pkt_seq_no, tvb, offset, 2, FALSE );
691 proto_tree_add_text(PoC1_tree, tvb, offset + 2, 2, "Padding 2 bytes");
696 proto_tree_add_item( PoC1_tree, hf_rtcp_app_poc1_reason_code2, tvb, offset, 2, FALSE );
697 proto_tree_add_item( PoC1_tree, hf_rtcp_app_poc1_additionalinfo, tvb, offset + 2, 2, FALSE );
703 proto_tree_add_item( PoC1_tree, hf_rtcp_app_poc1_ack_subtype, tvb, offset, 1, FALSE );
704 proto_tree_add_item( PoC1_tree, hf_rtcp_app_poc1_ack_reason_code, tvb, offset, 2, FALSE );
705 proto_tree_add_text( PoC1_tree, tvb, offset + 2, 2, "Padding 2 bytes" );
711 proto_tree_add_item( PoC1_tree, hf_rtcp_app_poc1_qsresp_priority, tvb, offset, 1, FALSE );
712 proto_tree_add_item( PoC1_tree, hf_rtcp_app_poc1_qsresp_position, tvb, offset + 1, 2, FALSE );
713 proto_tree_add_text( PoC1_tree, tvb, offset + 3, 1, "Padding 1 byte" );
719 proto_item *content = proto_tree_add_text(PoC1_tree, tvb, offset, 2, "SDES item content");
720 gboolean contents[5];
723 proto_tree *content_tree = proto_item_add_subtree(content, ett_poc1_conn_contents);
724 guint temp_byte = tvb_get_guint8( tvb, offset );
726 for ( i = 0; i < sizeof(contents) /
727 sizeof(contents[0]) &&
728 i < sizeof(hf_rtcp_app_poc1_conn_content_1st_byte) /
729 sizeof(hf_rtcp_app_poc1_conn_content_1st_byte[0]);
731 proto_tree_add_item( content_tree, hf_rtcp_app_poc1_conn_content_1st_byte[i], tvb, offset, 1, FALSE );
732 contents[i] = temp_byte & (1 << (7-i));
735 proto_tree_add_item( PoC1_tree, hf_rtcp_app_poc1_conn_session_type, tvb, offset + 2, 1, FALSE );
737 proto_tree_add_item( PoC1_tree, hf_rtcp_app_poc1_conn_add_ind_mao, tvb, offset + 3, 1, FALSE );
742 for ( i = 0; i < sizeof(contents) /
743 sizeof(contents[0]); ++i ) {
745 guint sdes_type, sdes_len;
746 sdes_type = tvb_get_guint8( tvb, offset++ );
747 sdes_len = tvb_get_guint8( tvb, offset );
749 proto_tree_add_item( PoC1_tree, hf_rtcp_app_poc1_conn_sdes_items[i], tvb, offset, 1, FALSE );
751 offset += sdes_len + 1;
752 packet_len -= (sdes_len + 2);
760 offset += packet_len;
767 dissect_rtcp_bye( tvbuff_t *tvb, int offset, proto_tree *tree,
770 unsigned int chunk = 1;
771 unsigned int reason_length = 0;
772 char* reason_text = NULL;
774 while ( chunk <= count ) {
775 /* source identifier, 32 bits */
776 proto_tree_add_item( tree, hf_rtcp_ssrc_source, tvb, offset, 4, FALSE);
781 if ( tvb_reported_length_remaining( tvb, offset ) > 0 ) {
782 /* Bye reason consists of an 8 bit length l and a string with length l */
783 reason_length = tvb_get_guint8( tvb, offset );
784 proto_tree_add_item( tree, hf_rtcp_ssrc_length, tvb, offset, 1, FALSE );
787 reason_text = tvb_get_ephemeral_string(tvb, offset, reason_length);
788 proto_tree_add_string( tree, hf_rtcp_ssrc_text, tvb, offset, reason_length, reason_text );
789 offset += reason_length;
797 dissect_rtcp_sdes( tvbuff_t *tvb, int offset, proto_tree *tree,
800 unsigned int chunk = 1;
801 proto_item *sdes_item;
802 proto_tree *sdes_tree;
803 proto_tree *sdes_item_tree;
806 int items_start_offset;
808 unsigned int item_len = 0;
809 unsigned int sdes_type = 0;
810 unsigned int counter = 0;
811 unsigned int prefix_len = 0;
812 char *prefix_string = NULL;
814 while ( chunk <= count ) {
815 /* Create a subtree for this chunk; we don't yet know
817 start_offset = offset;
819 ssrc = tvb_get_ntohl( tvb, offset );
820 sdes_item = proto_tree_add_text(tree, tvb, offset, -1,
821 "Chunk %u, SSRC/CSRC %u", chunk, ssrc);
822 sdes_tree = proto_item_add_subtree( sdes_item, ett_sdes );
824 /* SSRC_n source identifier, 32 bits */
825 proto_tree_add_uint( sdes_tree, hf_rtcp_ssrc_source, tvb, offset, 4, ssrc );
828 /* Create a subtree for the SDES items; we don't yet know
830 items_start_offset = offset;
831 ti = proto_tree_add_text(sdes_tree, tvb, offset, -1,
833 sdes_item_tree = proto_item_add_subtree( ti, ett_sdes_item );
836 * Not every message is ended with "null" bytes, so check for
837 * end of frame as well.
839 while ( tvb_reported_length_remaining( tvb, offset ) > 0 ) {
841 sdes_type = tvb_get_guint8( tvb, offset );
842 proto_tree_add_item( sdes_item_tree, hf_rtcp_ssrc_type, tvb, offset, 1, FALSE );
845 if ( sdes_type == RTCP_SDES_END ) {
850 /* Item length, 8 bits */
851 item_len = tvb_get_guint8( tvb, offset );
852 proto_tree_add_item( sdes_item_tree, hf_rtcp_ssrc_length, tvb, offset, 1, FALSE );
855 if ( sdes_type == RTCP_SDES_PRIV ) {
856 /* PRIV adds two items between the SDES length
857 * and value - an 8 bit length giving the
858 * length of a "prefix string", and the string.
860 prefix_len = tvb_get_guint8( tvb, offset );
861 proto_tree_add_item( sdes_item_tree, hf_rtcp_ssrc_prefix_len, tvb, offset, 1, FALSE );
864 prefix_string = ep_alloc( prefix_len + 1 );
865 for ( counter = 0; counter < prefix_len; counter++ )
866 prefix_string[ counter ] =
867 tvb_get_guint8( tvb, offset + counter );
868 /* strncpy( prefix_string, pd + offset, prefix_len ); */
869 prefix_string[ prefix_len ] = '\0';
870 proto_tree_add_string( sdes_item_tree, hf_rtcp_ssrc_prefix_string, tvb, offset, prefix_len, prefix_string );
871 offset += prefix_len;
873 prefix_string = ep_alloc( item_len + 1 );
874 for ( counter = 0; counter < item_len; counter++ )
875 prefix_string[ counter ] =
876 tvb_get_guint8( tvb, offset + counter );
877 /* strncpy( prefix_string, pd + offset, item_len ); */
878 prefix_string[ item_len] = 0;
879 proto_tree_add_string( sdes_item_tree, hf_rtcp_ssrc_text, tvb, offset, item_len, prefix_string );
883 /* Set the length of the items subtree. */
884 proto_item_set_len(ti, offset - items_start_offset);
886 /* 32 bits = 4 bytes, so.....
887 * If offset % 4 != 0, we divide offset by 4, add one and then
888 * multiply by 4 again to reach the boundary
890 if ( offset % 4 != 0 )
891 offset = ((offset / 4) + 1 ) * 4;
893 /* Set the length of this chunk. */
894 proto_item_set_len(sdes_item, offset - start_offset);
900 static void parse_xr_type_specific_field(tvbuff_t *tvb, gint offset, guint block_type, proto_tree *tree)
902 guint8 flags = tvb_get_guint8(tvb, offset);
904 switch (block_type) {
905 case RTCP_XR_LOSS_RLE:
906 case RTCP_XR_DUP_RLE:
907 case RTCP_XR_PKT_RXTIMES:
908 proto_tree_add_uint(tree, hf_rtcp_xr_thinning, tvb, offset, 1, flags);
911 case RTCP_XR_STATS_SUMRY:
912 proto_tree_add_boolean(tree, hf_rtcp_xr_stats_loss_flag, tvb, offset, 1, flags);
913 proto_tree_add_boolean(tree, hf_rtcp_xr_stats_dup_flag, tvb, offset, 1, flags);
914 proto_tree_add_boolean(tree, hf_rtcp_xr_stats_jitter_flag, tvb, offset, 1, flags);
915 proto_tree_add_uint(tree, hf_rtcp_xr_stats_ttl, tvb, offset, 1, flags);
919 proto_tree_add_uint(tree, hf_rtcp_xr_block_specific, tvb, offset, 1, flags);
924 static gboolean validate_xr_block_length(tvbuff_t *tvb, int offset, guint block_type, guint block_len, proto_tree *tree)
926 proto_tree_add_uint(tree, hf_rtcp_xr_block_length, tvb, offset, 2, block_len);
927 switch (block_type) {
928 case RTCP_XR_REF_TIME:
930 proto_tree_add_text(tree, tvb, offset, 2, "Invalid block length, should be 2");
933 case RTCP_XR_STATS_SUMRY:
935 proto_tree_add_text(tree, tvb, offset, 2, "Invalid block length, should be 9");
938 case RTCP_XR_VOIP_METRCS:
940 proto_tree_add_text(tree, tvb, offset, 2, "Invalid block length, should be 8");
950 dissect_rtcp_xr(tvbuff_t *tvb, packet_info *pinfo _U_, int offset, proto_tree *tree, gint packet_len)
954 /* Packet length should at least be 4 */
955 if (packet_len < 4) {
956 proto_tree_add_text(tree, tvb, offset, packet_len, "Missing Sender SSRC");
957 return offset + packet_len;
961 proto_tree_add_item( tree, hf_rtcp_ssrc_sender, tvb, offset, 4, FALSE );
965 for(;packet_len > 0; block_num++) {
966 guint block_type = tvb_get_guint8(tvb, offset), block_length = 0;
967 gint content_length = 0;
968 gboolean valid = TRUE;
970 /* Create a subtree for this block, dont know the length yet*/
971 proto_item *block = proto_tree_add_text(tree, tvb, offset, -1, "Block %u", block_num);
972 proto_tree *xr_block_tree = proto_item_add_subtree(block, ett_xr_block);
973 proto_item *contents = NULL;
974 proto_item *content_tree = NULL;
976 proto_tree_add_item(xr_block_tree, hf_rtcp_xr_block_type, tvb, offset, 1, FALSE);
978 if (packet_len >= 2) {
979 parse_xr_type_specific_field(tvb, offset + 1, block_type, xr_block_tree);
980 if (packet_len >= 4) {
981 block_length = tvb_get_ntohs(tvb, offset + 2);
982 valid = validate_xr_block_length(tvb, offset + 2, block_type, block_length, xr_block_tree);
985 proto_tree_add_text(xr_block_tree, tvb, offset + 1, packet_len, "Missing Required Block Headers");
986 return offset + packet_len;
989 content_length = block_length * 4;
990 proto_item_set_len(block, content_length + 4);
992 if (content_length > packet_len) {
993 proto_tree_add_text(xr_block_tree, tvb, offset + 2, 2, "Block length is greater than packet length");
999 contents = proto_tree_add_text(xr_block_tree, tvb, offset, content_length, "Contents");
1000 content_tree = proto_item_add_subtree(contents, ett_xr_block_contents);
1002 switch (block_type) {
1003 case RTCP_XR_VOIP_METRCS: {
1004 guint fraction_rate, value;
1007 proto_tree_add_item(content_tree, hf_rtcp_ssrc_source, tvb, offset, 4, FALSE);
1011 fraction_rate = tvb_get_guint8(tvb, offset);
1012 proto_tree_add_uint_format(content_tree, hf_rtcp_ssrc_fraction, tvb, offset, 1,
1013 fraction_rate, "Fraction lost: %u / 256", fraction_rate);
1017 fraction_rate = tvb_get_guint8(tvb, offset);
1018 proto_tree_add_uint_format(content_tree, hf_rtcp_ssrc_discarded, tvb, offset, 1,
1019 fraction_rate, "Fraction Discarded: %u / 256", fraction_rate);
1023 proto_tree_add_item(content_tree, hf_rtcp_xr_voip_metrics_burst_density, tvb, offset, 1, FALSE);
1027 proto_tree_add_item(content_tree, hf_rtcp_xr_voip_metrics_gap_density, tvb, offset, 1, FALSE);
1030 /* Burst Duration */
1031 proto_tree_add_item(content_tree, hf_rtcp_xr_voip_metrics_burst_duration, tvb, offset, 2, FALSE);
1035 proto_tree_add_item(content_tree, hf_rtcp_xr_voip_metrics_gap_duration, tvb, offset, 2, FALSE);
1038 /* Round Trip Delay */
1039 proto_tree_add_item(content_tree, hf_rtcp_xr_voip_metrics_rtdelay, tvb, offset, 2, FALSE);
1042 /* End System Delay */
1043 proto_tree_add_item(content_tree, hf_rtcp_xr_voip_metrics_esdelay, tvb, offset, 2, FALSE);
1047 proto_tree_add_item(content_tree, hf_rtcp_xr_voip_metrics_siglevel, tvb, offset, 1, FALSE);
1051 proto_tree_add_item(content_tree, hf_rtcp_xr_voip_metrics_noiselevel, tvb, offset, 1, FALSE);
1055 proto_tree_add_item(content_tree, hf_rtcp_xr_voip_metrics_rerl, tvb, offset, 1, FALSE);
1059 proto_tree_add_item(content_tree, hf_rtcp_xr_voip_metrics_gmin, tvb, offset, 1, FALSE);
1063 proto_tree_add_item(content_tree, hf_rtcp_xr_voip_metrics_rfactor, tvb, offset, 1, FALSE);
1066 /* external R Factor */
1067 proto_tree_add_item(content_tree, hf_rtcp_xr_voip_metrics_extrfactor, tvb, offset, 1, FALSE);
1071 proto_tree_add_float(content_tree, hf_rtcp_xr_voip_metrics_moslq, tvb, offset, 1,
1072 (gfloat)tvb_get_guint8(tvb, offset) / 10);
1076 proto_tree_add_float(content_tree, hf_rtcp_xr_voip_metrics_moscq, tvb, offset, 1,
1077 (gfloat)tvb_get_guint8(tvb, offset) / 10);
1080 /* PLC, JB Adaptive, JB Rate */
1081 value = tvb_get_guint8(tvb, offset);
1082 proto_tree_add_uint(content_tree, hf_rtcp_xr_voip_metrics_plc, tvb, offset, 1, value);
1083 proto_tree_add_uint(content_tree, hf_rtcp_xr_voip_metrics_jbadaptive, tvb, offset, 1, value);
1084 proto_tree_add_uint(content_tree, hf_rtcp_xr_voip_metrics_jbrate, tvb, offset, 1, value);
1085 offset += 2; /* skip over reseved bit */
1088 proto_tree_add_item(content_tree, hf_rtcp_xr_voip_metrics_jbnominal, tvb, offset, 2, FALSE);
1092 proto_tree_add_item(content_tree, hf_rtcp_xr_voip_metrics_jbmax, tvb, offset, 2, FALSE);
1096 proto_tree_add_item(content_tree, hf_rtcp_xr_voip_metrics_jbabsmax, tvb, offset, 2, FALSE);
1102 case RTCP_XR_STATS_SUMRY: {
1104 proto_tree_add_item(content_tree, hf_rtcp_ssrc_source, tvb, offset, 4, FALSE);
1108 proto_tree_add_item(content_tree, hf_rtcp_xr_beginseq, tvb, offset, 2, FALSE);
1112 proto_tree_add_item(content_tree, hf_rtcp_xr_endseq, tvb, offset, 2, FALSE);
1116 proto_tree_add_item(content_tree, hf_rtcp_xr_stats_lost, tvb, offset, 4, FALSE);
1120 proto_tree_add_item(content_tree, hf_rtcp_xr_stats_dups, tvb, offset, 4, FALSE);
1124 proto_tree_add_item(content_tree, hf_rtcp_xr_stats_minjitter, tvb, offset, 4, FALSE);
1128 proto_tree_add_item(content_tree, hf_rtcp_xr_stats_maxjitter, tvb, offset, 4, FALSE);
1132 proto_tree_add_item(content_tree, hf_rtcp_xr_stats_meanjitter, tvb, offset, 4, FALSE);
1136 proto_tree_add_item(content_tree, hf_rtcp_xr_stats_devjitter, tvb, offset, 4, FALSE);
1140 proto_tree_add_item(content_tree, hf_rtcp_xr_stats_minttl, tvb, offset, 1, FALSE);
1144 proto_tree_add_item(content_tree, hf_rtcp_xr_stats_maxttl, tvb, offset, 1, FALSE);
1148 proto_tree_add_item(content_tree, hf_rtcp_xr_stats_meanttl, tvb, offset, 1, FALSE);
1152 proto_tree_add_item(content_tree, hf_rtcp_xr_stats_devttl, tvb, offset, 1, FALSE);
1158 case RTCP_XR_REF_TIME: {
1159 guint32 ts_msw, ts_lsw;
1161 ts_msw = tvb_get_ntohl(tvb, offset);
1162 proto_tree_add_text(content_tree, tvb, offset, 4, "Timestamp, MSW: %u", ts_msw);
1164 ts_lsw = tvb_get_ntohl(tvb, offset);
1165 proto_tree_add_text(content_tree, tvb, offset, 4, "Timestamp, LSW: %u", ts_lsw);
1171 case RTCP_XR_DLRR: {
1172 /* Each report block is 12 bytes */
1173 gint sources = content_length / 12;
1175 for(counter = 0; counter < sources; counter++) {
1176 /* Create a new subtree for a length of 12 bytes */
1177 proto_tree *ti = proto_tree_add_text(content_tree, tvb, offset, 12, "Source %u", counter + 1);
1178 proto_tree *ssrc_tree = proto_item_add_subtree(ti, ett_xr_ssrc);
1180 /* SSRC_n source identifier, 32 bits */
1181 proto_tree_add_item(ssrc_tree, hf_rtcp_ssrc_source, tvb, offset, 4, FALSE);
1184 /* Last RR timestamp */
1185 proto_tree_add_item(ssrc_tree, hf_rtcp_xr_lrr, tvb, offset, 4, FALSE);
1188 /* Delay since last RR timestamp */
1189 proto_tree_add_item(ssrc_tree, hf_rtcp_xr_dlrr, tvb, offset, 4, FALSE);
1193 if (content_length % 12 != 0)
1194 offset += content_length % 12;
1198 case RTCP_XR_PKT_RXTIMES: {
1199 /* 8 bytes of fixed header */
1200 gint count = 0, skip = 8;
1204 proto_tree_add_item(content_tree, hf_rtcp_ssrc_source, tvb, offset, 4, FALSE);
1208 begin = tvb_get_ntohs(tvb, offset);
1209 proto_tree_add_uint(content_tree, hf_rtcp_xr_beginseq, tvb, offset, 2, begin);
1213 proto_tree_add_item(content_tree, hf_rtcp_xr_endseq, tvb, offset, 2, FALSE);
1216 for(count = 0; skip < content_length; skip += 4, count++) {
1217 proto_tree_add_text(content_tree, tvb, offset, 4, "Seq: %u, Timestamp: %u",
1218 (begin + count) % 65536, FALSE);
1224 case RTCP_XR_LOSS_RLE:
1225 case RTCP_XR_DUP_RLE: {
1226 /* 8 bytes of fixed header */
1227 gint count = 0, skip = 8;
1229 proto_item *chunks_item;
1230 proto_tree *chunks_tree;
1233 proto_tree_add_item(content_tree, hf_rtcp_ssrc_source, tvb, offset, 4, FALSE);
1237 begin = tvb_get_ntohs(tvb, offset);
1238 proto_tree_add_uint(content_tree, hf_rtcp_xr_beginseq, tvb, offset, 2, begin);
1242 proto_tree_add_item(content_tree, hf_rtcp_xr_endseq, tvb, offset, 2, FALSE);
1246 chunks_item = proto_tree_add_text(content_tree, tvb, offset, content_length,"Report Chunks");
1247 chunks_tree = proto_item_add_subtree(chunks_item, ett_xr_loss_chunk);
1249 for(count = 1; skip < content_length; skip += 2, count++) {
1250 guint value = tvb_get_ntohs(tvb, offset);
1253 proto_tree_add_text(chunks_tree, tvb, offset, 2,
1254 "Chunk: %u -- Null Terminator ",
1256 } else if (( value & 0x8000 )) {
1257 const gchar* run_type = (value & 0x4000) ? "1s" : "0s";
1259 proto_tree_add_text(chunks_tree, tvb, offset, 2,
1260 "Chunk: %u -- Length Run %s, length: %u",
1261 count, run_type, value);
1264 other_decode_bitfield_value(bits, value, 0x00007FFF, 16);
1265 proto_tree_add_text(chunks_tree, tvb, offset, 2,
1266 "Chunk: %u -- Bit Vector, bits: %s",
1276 /* skip over the unknown block */
1277 offset += content_length;
1280 packet_len -= content_length;
1286 dissect_rtcp_rr( packet_info *pinfo, tvbuff_t *tvb, int offset, proto_tree *tree,
1287 unsigned int count )
1289 unsigned int counter = 1;
1290 proto_tree *ssrc_tree = (proto_tree*) NULL;
1291 proto_tree *ssrc_sub_tree = (proto_tree*) NULL;
1292 proto_tree *high_sec_tree = (proto_tree*) NULL;
1293 proto_item *ti = (proto_item*) NULL;
1295 unsigned int cum_nr = 0;
1297 while ( counter <= count ) {
1300 /* Create a new subtree for a length of 24 bytes */
1301 ti = proto_tree_add_text(tree, tvb, offset, 24,
1302 "Source %u", counter );
1303 ssrc_tree = proto_item_add_subtree( ti, ett_ssrc );
1305 /* SSRC_n source identifier, 32 bits */
1306 proto_tree_add_item( ssrc_tree, hf_rtcp_ssrc_source, tvb, offset, 4, FALSE );
1309 ti = proto_tree_add_text(ssrc_tree, tvb, offset, 20, "SSRC contents" );
1310 ssrc_sub_tree = proto_item_add_subtree( ti, ett_ssrc_item );
1312 /* Fraction lost, 8bits */
1313 rr_flt = tvb_get_guint8( tvb, offset );
1314 proto_tree_add_uint_format( ssrc_sub_tree, hf_rtcp_ssrc_fraction, tvb,
1315 offset, 1, rr_flt, "Fraction lost: %u / 256", rr_flt );
1318 /* Cumulative number of packets lost, 24 bits */
1319 cum_nr = tvb_get_ntohl( tvb, offset ) >> 8;
1320 proto_tree_add_uint( ssrc_sub_tree, hf_rtcp_ssrc_cum_nr, tvb,
1321 offset, 3, cum_nr );
1324 /* Extended highest sequence nr received, 32 bits
1325 * Just for the sake of it, let's add another subtree
1326 * because this might be a little clearer
1328 ti = proto_tree_add_uint( ssrc_tree, hf_rtcp_ssrc_ext_high_seq,
1329 tvb, offset, 4, tvb_get_ntohl( tvb, offset ) );
1330 high_sec_tree = proto_item_add_subtree( ti, ett_ssrc_ext_high );
1331 /* Sequence number cycles */
1332 proto_tree_add_item( high_sec_tree, hf_rtcp_ssrc_high_cycles,
1333 tvb, offset, 2, FALSE );
1335 /* highest sequence number received */
1336 proto_tree_add_item( high_sec_tree, hf_rtcp_ssrc_high_seq,
1337 tvb, offset, 2, FALSE );
1340 /* Interarrival jitter */
1341 proto_tree_add_item( ssrc_tree, hf_rtcp_ssrc_jitter, tvb,
1345 /* Last SR timestamp */
1346 lsr = tvb_get_ntohl( tvb, offset );
1347 proto_tree_add_uint( ssrc_tree, hf_rtcp_ssrc_lsr, tvb,
1351 /* Delay since last SR timestamp */
1352 dlsr = tvb_get_ntohl( tvb, offset );
1353 proto_tree_add_uint( ssrc_tree, hf_rtcp_ssrc_dlsr, tvb,
1357 /* Do roundtrip calculation */
1358 if (global_rtcp_show_roundtrip_calculation)
1360 /* Based on delay since SR was send in other direction */
1361 calculate_roundtrip_delay(tvb, pinfo, ssrc_tree, lsr, dlsr);
1371 dissect_rtcp_sr( packet_info *pinfo, tvbuff_t *tvb, int offset, proto_tree *tree,
1372 unsigned int count )
1376 char* ptime = tvb_get_ptr( tvb, offset, 8 );
1378 /* Retreive the NTP timestamp. Using the NTP dissector for this */
1379 buff=ntp_fmt_ts(ptime);
1380 proto_tree_add_string_format( tree, hf_rtcp_ntp, tvb, offset, 8, ( const char* ) buff, "NTP timestamp: %s", buff );
1381 free( ptime ); /*??????????????????????????????????????????????????????????????????*/
1385 * XXX - RFC 1889 says this is an NTP timestamp, but that appears
1386 * not to be the case.
1389 guint32 ts_msw, ts_lsw;
1391 char* ptime = tvb_get_ptr( tvb, offset, 8 );
1393 ts_msw = tvb_get_ntohl(tvb, offset);
1394 proto_tree_add_text(tree, tvb, offset, 4, "Timestamp, MSW: %u", ts_msw);
1396 ts_lsw = tvb_get_ntohl(tvb, offset);
1397 proto_tree_add_text(tree, tvb, offset, 4, "Timestamp, LSW: %u", ts_lsw);
1400 buff=ntp_fmt_ts(ptime);
1401 item = proto_tree_add_string_format( tree, hf_rtcp_ntp, tvb, offset-8, 8, ( const char* ) buff, "MSW and LSW as NTP timestamp: %s", buff );
1402 PROTO_ITEM_SET_GENERATED(item);
1403 free( ptime ); /*??????????????????????????????????????????????????????????????????*/
1406 /* RTP timestamp, 32 bits */
1407 proto_tree_add_uint( tree, hf_rtcp_rtp_timestamp, tvb, offset, 4, tvb_get_ntohl( tvb, offset ) );
1409 /* Sender's packet count, 32 bits */
1410 proto_tree_add_uint( tree, hf_rtcp_sender_pkt_cnt, tvb, offset, 4, tvb_get_ntohl( tvb, offset ) );
1412 /* Sender's octet count, 32 bits */
1413 proto_tree_add_uint( tree, hf_rtcp_sender_oct_cnt, tvb, offset, 4, tvb_get_ntohl( tvb, offset ) );
1416 /* Record the time of this packet in the sender's conversation */
1417 if (global_rtcp_show_roundtrip_calculation)
1419 /* Use middle 32 bits of 64-bit time value */
1420 guint32 lsr = ((ts_msw & 0x0000ffff) << 16 | (ts_lsw & 0xffff0000) >> 16);
1422 /* Record the time that we sent this in appropriate conversation */
1423 remember_outgoing_sr(pinfo, lsr);
1426 /* The rest of the packet is equal to the RR packet */
1428 offset = dissect_rtcp_rr( pinfo, tvb, offset, tree, count );
1433 /* Look for conversation info and display any setup info found */
1434 void show_setup_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1436 /* Conversation and current data */
1437 conversation_t *p_conv = NULL;
1438 struct _rtcp_conversation_info *p_conv_data = NULL;
1440 /* Use existing packet data if available */
1441 p_conv_data = p_get_proto_data(pinfo->fd, proto_rtcp);
1445 /* First time, get info from conversation */
1446 p_conv = find_conversation(pinfo->fd->num, &pinfo->net_dst, &pinfo->net_src,
1448 pinfo->destport, pinfo->srcport, NO_ADDR_B);
1452 /* Look for data in conversation */
1453 struct _rtcp_conversation_info *p_conv_packet_data;
1454 p_conv_data = conversation_get_proto_data(p_conv, proto_rtcp);
1458 /* Save this conversation info into packet info */
1459 p_conv_packet_data = se_alloc(sizeof(struct _rtcp_conversation_info));
1460 if (!p_conv_packet_data)
1464 memcpy(p_conv_packet_data, p_conv_data,
1465 sizeof(struct _rtcp_conversation_info));
1467 p_add_proto_data(pinfo->fd, proto_rtcp, p_conv_packet_data);
1472 /* Create setup info subtree with summary info. */
1473 if (p_conv_data && p_conv_data->setup_method_set)
1475 proto_tree *rtcp_setup_tree;
1476 proto_item *ti = proto_tree_add_string_format(tree, hf_rtcp_setup, tvb, 0, 0,
1478 "Stream setup by %s (frame %u)",
1479 p_conv_data->setup_method,
1480 p_conv_data->setup_frame_number);
1481 PROTO_ITEM_SET_GENERATED(ti);
1482 rtcp_setup_tree = proto_item_add_subtree(ti, ett_rtcp_setup);
1483 if (rtcp_setup_tree)
1485 /* Add details into subtree */
1486 proto_item* item = proto_tree_add_uint(rtcp_setup_tree, hf_rtcp_setup_frame,
1487 tvb, 0, 0, p_conv_data->setup_frame_number);
1488 PROTO_ITEM_SET_GENERATED(item);
1489 item = proto_tree_add_string(rtcp_setup_tree, hf_rtcp_setup_method,
1490 tvb, 0, 0, p_conv_data->setup_method);
1491 PROTO_ITEM_SET_GENERATED(item);
1497 /* Update conversation data to record time that outgoing rr/sr was sent */
1498 static void remember_outgoing_sr(packet_info *pinfo, long lsr)
1500 conversation_t *p_conv = NULL;
1501 struct _rtcp_conversation_info *p_conv_data = NULL;
1502 struct _rtcp_conversation_info *p_packet_data = NULL;
1504 /* This information will be accessed when an incoming packet comes back to
1505 the side that sent this packet, so no use storing in the packet
1506 info. However, do store the fact that we've already set this info
1510 /**************************************************************************/
1511 /* First of all, see if we've already stored this information for this sr */
1513 /* Look first in packet info */
1514 p_packet_data = p_get_proto_data(pinfo->fd, proto_rtcp);
1515 if (p_packet_data && p_packet_data->last_received_set &&
1516 p_packet_data->last_received_frame_number >= pinfo->fd->num)
1518 /* We already did this, OK */
1523 /**************************************************************************/
1524 /* Otherwise, we want to find/create the conversation and update it */
1526 /* First time, get info from conversation.
1527 Even though we think of this as an outgoing packet being sent,
1528 we store the time as being received by the destination. */
1529 p_conv = find_conversation(pinfo->fd->num, &pinfo->net_dst, &pinfo->net_src,
1531 pinfo->destport, pinfo->srcport, NO_ADDR_B);
1533 /* If the conversation doesn't exist, create it now. */
1536 p_conv = conversation_new(pinfo->fd->num, &pinfo->net_dst, &pinfo->net_src, PT_UDP,
1537 pinfo->destport, pinfo->srcport,
1541 /* Give up if can't create it */
1547 /****************************************************/
1548 /* Now find/create conversation data */
1549 p_conv_data = conversation_get_proto_data(p_conv, proto_rtcp);
1552 /* Allocate memory for data */
1553 p_conv_data = se_alloc(sizeof(struct _rtcp_conversation_info));
1556 /* Give up if couldn't allocate space for memory */
1559 memset(p_conv_data, 0, sizeof(struct _rtcp_conversation_info));
1561 /* Add it to conversation. */
1562 conversation_add_proto_data(p_conv, proto_rtcp, p_conv_data);
1565 /*******************************************************/
1566 /* Update conversation data */
1567 p_conv_data->last_received_set = TRUE;
1568 p_conv_data->last_received_frame_number = pinfo->fd->num;
1569 p_conv_data->last_received_timestamp = pinfo->fd->abs_ts;
1570 p_conv_data->last_received_ts = lsr;
1573 /****************************************************************/
1574 /* Update packet info to record conversation state */
1576 /* Will use/create packet info */
1579 p_packet_data = se_alloc(sizeof(struct _rtcp_conversation_info));
1582 /* Give up if allocation fails */
1585 memset(p_packet_data, 0, sizeof(struct _rtcp_conversation_info));
1587 p_add_proto_data(pinfo->fd, proto_rtcp, p_packet_data);
1590 /* Copy current conversation data into packet info */
1591 p_packet_data->last_received_set = TRUE;
1592 p_packet_data->last_received_frame_number = p_conv_data->last_received_frame_number;
1593 p_packet_data->last_received_timestamp = p_conv_data->last_received_timestamp;
1597 /* Use received sr to work out what the roundtrip delay is
1598 (at least between capture point and the other endpoint involved in
1599 the conversation) */
1600 static void calculate_roundtrip_delay(tvbuff_t *tvb, packet_info *pinfo,
1601 proto_tree *tree, guint32 lsr, guint32 dlsr)
1603 /*****************************************************/
1604 /* This is called dissecting an SR. We need to:
1605 - look in the packet info for stored calculation. If found, use.
1606 - look up the conversation of the sending side to see when the
1607 'last SR' was detected (received)
1608 - calculate the network delay using the that packet time,
1609 this packet time, and dlsr
1610 *****************************************************/
1612 conversation_t *p_conv = NULL;
1613 struct _rtcp_conversation_info *p_conv_data = NULL;
1614 struct _rtcp_conversation_info *p_packet_data = NULL;
1617 /*************************************************/
1618 /* Look for previously stored calculation result */
1619 p_packet_data = p_get_proto_data(pinfo->fd, proto_rtcp);
1620 if (p_packet_data && p_packet_data->calculated_delay_set)
1623 add_roundtrip_delay_info(tvb, pinfo, tree,
1624 p_packet_data->calculated_delay_used_frame,
1625 p_packet_data->calculated_delay);
1630 /********************************************************************/
1631 /* Look for captured timestamp of last SR in conversation of sender */
1632 /* of this packet */
1633 p_conv = find_conversation(pinfo->fd->num, &pinfo->net_src, &pinfo->net_dst,
1635 pinfo->srcport, pinfo->destport, NO_ADDR_B);
1641 /* Look for conversation data */
1642 p_conv_data = conversation_get_proto_data(p_conv, proto_rtcp);
1648 if (p_conv_data->last_received_set)
1650 /* Store result of calculation in packet info */
1653 /* Create packet info if it doesn't exist */
1654 p_packet_data = se_alloc(sizeof(struct _rtcp_conversation_info));
1657 /* Give up if allocation fails */
1661 memset(p_packet_data, 0, sizeof(struct _rtcp_conversation_info));
1663 /* Set as packet info */
1664 p_add_proto_data(pinfo->fd, proto_rtcp, p_packet_data);
1667 /* Any previous report must match the lsr given here */
1668 if (p_conv_data->last_received_ts == lsr)
1670 /* Look at time of since original packet was sent */
1671 gint seconds_between_packets =
1672 pinfo->fd->abs_ts.secs - p_conv_data->last_received_timestamp.secs;
1673 gint nseconds_between_packets =
1674 pinfo->fd->abs_ts.nsecs - p_conv_data->last_received_timestamp.nsecs;
1677 gint total_gap = ((seconds_between_packets*1000000) +
1678 nseconds_between_packets) / 1000000;
1679 gint delay = total_gap - (int)(((double)dlsr/(double)65536) * 1000.0);
1681 /* No useful calculation can be done if dlsr not set... */
1687 p_packet_data->calculated_delay_set = TRUE;
1688 p_packet_data->calculated_delay = delay;
1689 p_packet_data->calculated_delay_used_frame = p_conv_data->last_received_frame_number;
1692 add_roundtrip_delay_info(tvb, pinfo, tree, p_conv_data->last_received_frame_number, delay);
1697 /* Show the calcaulted roundtrip delay info by adding protocol tree items
1698 and appending text to the info column */
1699 static void add_roundtrip_delay_info(tvbuff_t *tvb, packet_info *pinfo,
1700 proto_tree *tree, guint frame, guint delay)
1702 proto_tree *rtcp_roundtrip_delay_tree;
1705 /* Don't report on calculated delays below the threshold */
1706 if (delay < global_rtcp_show_roundtrip_calculation_minimum)
1711 /* Add labelled subtree for roundtrip delay info */
1712 ti = proto_tree_add_string_format(tree, hf_rtcp_roundtrip_delay, tvb, 0, 0,
1714 "Calculated Roundtrip delay <-> %s = %ums, using frame %u",
1715 address_to_str(&pinfo->net_src), delay,
1718 PROTO_ITEM_SET_GENERATED(ti);
1719 rtcp_roundtrip_delay_tree = proto_item_add_subtree(ti, ett_rtcp_roundtrip_delay);
1720 if (rtcp_roundtrip_delay_tree)
1722 /* Add details into subtree */
1723 proto_item* item = proto_tree_add_uint(rtcp_roundtrip_delay_tree,
1724 hf_rtcp_roundtrip_delay_frame,
1726 PROTO_ITEM_SET_GENERATED(item);
1727 item = proto_tree_add_uint(rtcp_roundtrip_delay_tree, hf_rtcp_roundtrip_delay_delay,
1729 PROTO_ITEM_SET_GENERATED(item);
1732 /* Report delay in INFO column */
1733 if (check_col(pinfo->cinfo, COL_INFO))
1735 col_append_fstr(pinfo->cinfo, COL_INFO,
1736 " (roundtrip delay <-> %s = %ums, using frame %u)",
1737 address_to_str(&pinfo->net_src), delay, frame);
1744 dissect_rtcp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree )
1746 proto_item *ti = NULL;
1747 proto_tree *rtcp_tree = NULL;
1748 unsigned int temp_byte = 0;
1749 unsigned int padding_set = 0;
1750 unsigned int elem_count = 0;
1751 unsigned int packet_type = 0;
1752 unsigned int offset = 0;
1753 guint16 packet_length = 0;
1754 guint rtcp_subtype = 0;
1756 if ( check_col( pinfo->cinfo, COL_PROTOCOL ) ) {
1757 col_set_str( pinfo->cinfo, COL_PROTOCOL, "RTCP" );
1760 if ( check_col( pinfo->cinfo, COL_INFO) ) {
1761 /* The second octet contains the packet type */
1762 /* switch ( pd[ offset + 1 ] ) { */
1763 switch ( tvb_get_guint8( tvb, 1 ) ) {
1765 col_set_str( pinfo->cinfo, COL_INFO, "Sender Report");
1768 col_set_str( pinfo->cinfo, COL_INFO, "Receiver Report");
1771 col_set_str( pinfo->cinfo, COL_INFO, "Source Description");
1774 col_set_str( pinfo->cinfo, COL_INFO, "Goodbye");
1777 col_set_str( pinfo->cinfo, COL_INFO, "Application defined");
1780 col_set_str( pinfo->cinfo, COL_INFO, "Extended report");
1783 col_set_str( pinfo->cinfo, COL_INFO, "Full Intra-frame Request (H.261)");
1786 col_set_str( pinfo->cinfo, COL_INFO, "Negative Acknowledgement (H.261)");
1789 col_set_str( pinfo->cinfo, COL_INFO, "Unknown packet type");
1795 * Check if there are at least 4 bytes left in the frame,
1796 * the last 16 bits of those is the length of the current
1797 * RTCP message. The last compound message contains padding,
1798 * that enables us to break from the while loop.
1800 while ( tvb_bytes_exist( tvb, offset, 4) ) {
1802 * First retreive the packet_type
1804 packet_type = tvb_get_guint8( tvb, offset + 1 );
1807 * Check if it's a valid type
1809 if ( ( packet_type < 192 ) || ( packet_type > 207 ) )
1813 * get the packet-length for the complete RTCP packet
1815 packet_length = ( tvb_get_ntohs( tvb, offset + 2 ) + 1 ) * 4;
1817 ti = proto_tree_add_item(tree, proto_rtcp, tvb, offset, packet_length, FALSE );
1818 rtcp_tree = proto_item_add_subtree( ti, ett_rtcp );
1820 /* Conversation setup info */
1821 if (global_rtcp_show_setup_info)
1823 show_setup_info(tvb, pinfo, rtcp_tree);
1827 temp_byte = tvb_get_guint8( tvb, offset );
1829 proto_tree_add_uint( rtcp_tree, hf_rtcp_version, tvb,
1830 offset, 1, temp_byte);
1831 padding_set = RTCP_PADDING( temp_byte );
1833 proto_tree_add_boolean( rtcp_tree, hf_rtcp_padding, tvb,
1834 offset, 1, temp_byte );
1835 elem_count = RTCP_COUNT( temp_byte );
1837 switch ( packet_type ) {
1840 /* Receiver report count, 5 bits */
1841 proto_tree_add_uint( rtcp_tree, hf_rtcp_rc, tvb, offset, 1, temp_byte );
1843 /* Packet type, 8 bits */
1844 proto_tree_add_item( rtcp_tree, hf_rtcp_pt, tvb, offset, 1, FALSE );
1846 /* Packet length in 32 bit words MINUS one, 16 bits */
1847 proto_tree_add_uint( rtcp_tree, hf_rtcp_length, tvb, offset, 2, tvb_get_ntohs( tvb, offset ) );
1849 /* Sender Synchronization source, 32 bits */
1850 proto_tree_add_uint( rtcp_tree, hf_rtcp_ssrc_sender, tvb, offset, 4, tvb_get_ntohl( tvb, offset ) );
1853 if ( packet_type == RTCP_SR ) offset = dissect_rtcp_sr( pinfo, tvb, offset, rtcp_tree, elem_count );
1854 else offset = dissect_rtcp_rr( pinfo, tvb, offset, rtcp_tree, elem_count );
1857 /* Source count, 5 bits */
1858 proto_tree_add_uint( rtcp_tree, hf_rtcp_sc, tvb, offset, 1, temp_byte );
1860 /* Packet type, 8 bits */
1861 proto_tree_add_item( rtcp_tree, hf_rtcp_pt, tvb, offset, 1, FALSE );
1863 /* Packet length in 32 bit words MINUS one, 16 bits */
1864 proto_tree_add_uint( rtcp_tree, hf_rtcp_length, tvb, offset, 2, tvb_get_ntohs( tvb, offset ) );
1866 dissect_rtcp_sdes( tvb, offset, rtcp_tree, elem_count );
1867 offset += packet_length - 4;
1870 /* Source count, 5 bits */
1871 proto_tree_add_uint( rtcp_tree, hf_rtcp_sc, tvb, offset, 1, temp_byte );
1873 /* Packet type, 8 bits */
1874 proto_tree_add_item( rtcp_tree, hf_rtcp_pt, tvb, offset, 1, FALSE );
1876 /* Packet length in 32 bit words MINUS one, 16 bits */
1877 proto_tree_add_uint( rtcp_tree, hf_rtcp_length, tvb, offset, 2, tvb_get_ntohs( tvb, offset ) );
1879 offset = dissect_rtcp_bye( tvb, offset, rtcp_tree, elem_count );
1882 /* Subtype, 5 bits */
1883 rtcp_subtype = elem_count;
1884 proto_tree_add_uint( rtcp_tree, hf_rtcp_subtype, tvb, offset, 1, elem_count );
1886 /* Packet type, 8 bits */
1887 proto_tree_add_item( rtcp_tree, hf_rtcp_pt, tvb, offset, 1, FALSE );
1889 /* Packet length in 32 bit words MINUS one, 16 bits */
1890 proto_tree_add_uint( rtcp_tree, hf_rtcp_length, tvb, offset, 2, tvb_get_ntohs( tvb, offset ) );
1892 offset = dissect_rtcp_app( tvb, pinfo, offset,
1893 rtcp_tree, padding_set,
1894 packet_length - 4, rtcp_subtype );
1897 /* Reserved, 5 bits, Ignore */
1899 /* Packet type, 8 bits */
1900 proto_tree_add_item( rtcp_tree, hf_rtcp_pt, tvb, offset, 1, FALSE );
1902 /* Packet length in 32 bit words MINUS one, 16 bits */
1903 proto_tree_add_uint( rtcp_tree, hf_rtcp_length, tvb, offset, 2, tvb_get_ntohs( tvb, offset ) );
1905 offset = dissect_rtcp_xr( tvb, pinfo, offset, rtcp_tree, packet_length - 4 );
1908 offset = dissect_rtcp_fir( tvb, offset, rtcp_tree );
1911 offset = dissect_rtcp_nack( tvb, offset, rtcp_tree );
1915 * To prevent endless loops in case of an unknown message type
1916 * increase offset. Some time the while will end :-)
1922 /* If the padding bit is set, the last octet of the
1923 * packet contains the length of the padding
1924 * We only have to check for this at the end of the LAST RTCP message
1926 if ( padding_set ) {
1927 /* If everything went according to plan offset should now point to the
1928 * first octet of the padding
1930 proto_tree_add_item( rtcp_tree, hf_rtcp_padding_data, tvb, offset, tvb_length_remaining( tvb, offset) - 1, FALSE );
1931 offset += tvb_length_remaining( tvb, offset) - 1;
1932 proto_tree_add_item( rtcp_tree, hf_rtcp_padding_count, tvb, offset, 1, FALSE );
1937 proto_register_rtcp(void)
1939 static hf_register_info hf[] =
1948 VALS(rtcp_version_vals),
1968 "Reception report count",
1996 VALS( rtcp_packet_type_vals ),
2014 &hf_rtcp_ssrc_sender,
2029 "rtcp.timestamp.ntp",
2038 &hf_rtcp_rtp_timestamp,
2041 "rtcp.timestamp.rtp",
2050 &hf_rtcp_sender_pkt_cnt,
2052 "Sender's packet count",
2053 "rtcp.sender.packetcount",
2062 &hf_rtcp_sender_oct_cnt,
2064 "Sender's octet count",
2065 "rtcp.sender.octetcount",
2074 &hf_rtcp_ssrc_source,
2077 "rtcp.ssrc.identifier",
2086 &hf_rtcp_ssrc_fraction,
2089 "rtcp.ssrc.fraction",
2098 &hf_rtcp_ssrc_cum_nr,
2100 "Cumulative number of packets lost",
2110 &hf_rtcp_ssrc_ext_high_seq,
2112 "Extended highest sequence number received",
2113 "rtcp.ssrc.ext_high",
2122 &hf_rtcp_ssrc_high_seq,
2124 "Highest sequence number received",
2125 "rtcp.ssrc.high_seq",
2134 &hf_rtcp_ssrc_high_cycles,
2136 "Sequence number cycles count",
2137 "rtcp.ssrc.high_cycles",
2146 &hf_rtcp_ssrc_jitter,
2148 "Interarrival jitter",
2160 "Last SR timestamp",
2172 "Delay since last SR timestamp",
2184 "SSRC / CSRC identifier",
2185 "rtcp.sdes.ssrc_csrc",
2200 VALS( rtcp_sdes_type_vals ),
2206 &hf_rtcp_ssrc_length,
2230 &hf_rtcp_ssrc_prefix_len,
2233 "rtcp.sdes.prefix.length",
2242 &hf_rtcp_ssrc_prefix_string,
2245 "rtcp.sdes.prefix.string",
2266 &hf_rtcp_name_ascii,
2280 "Application specific data",
2290 &hf_rtcp_app_poc1_subtype,
2293 "rtcp.app.PoC1.subtype",
2296 VALS(rtcp_app_poc1_floor_cnt_type_vals),
2302 &hf_rtcp_app_poc1_sip_uri,
2305 "rtcp.app.poc1.sip.uri",
2314 &hf_rtcp_app_poc1_disp_name,
2317 "rtcp.app.poc1.disp.name",
2326 &hf_rtcp_app_poc1_last_pkt_seq_no,
2328 "Seq. no of last RTP packet",
2329 "rtcp.app.poc1.last.pkt.seq.no",
2338 &hf_rtcp_app_poc1_reason_code1,
2341 "rtcp.app.poc1.reason.code",
2344 VALS(rtcp_app_poc1_reason_code1_vals),
2350 &hf_rtcp_app_poc1_item_len,
2353 "rtcp.app.poc1.item.len",
2362 &hf_rtcp_app_poc1_reason1_phrase,
2365 "rtcp.app.poc1.reason.phrase",
2374 &hf_rtcp_app_poc1_reason_code2,
2377 "rtcp.app.poc1.reason.code",
2380 VALS(rtcp_app_poc1_reason_code2_vals),
2386 &hf_rtcp_app_poc1_additionalinfo,
2388 "additional information",
2389 "rtcp.app.poc1.add.info",
2398 &hf_rtcp_app_poc1_ack_subtype,
2401 "rtcp.app.poc1.ack.subtype",
2404 VALS(rtcp_app_poc1_floor_cnt_type_vals),
2410 &hf_rtcp_app_poc1_ack_reason_code,
2413 "rtcp.app.poc1.ack.reason.code",
2422 &hf_rtcp_app_poc1_qsresp_priority,
2425 "rtcp.app.poc1.qsresp.priority",
2428 VALS(rtcp_app_poc1_qsresp_priority_vals),
2434 &hf_rtcp_app_poc1_qsresp_position,
2437 "rtcp.app.poc1.qsresp.position",
2446 &hf_rtcp_app_poc1_conn_content_1st_byte[0],
2448 "Identity of inviting client",
2449 "rtcp.app.poc1.conn.content.a.id",
2458 &hf_rtcp_app_poc1_conn_content_1st_byte[1],
2460 "Nick name of inviting client",
2461 "rtcp.app.poc1.conn.content.a.dn",
2470 &hf_rtcp_app_poc1_conn_content_1st_byte[2],
2473 "rtcp.app.poc1.conn.content.sess.id",
2482 &hf_rtcp_app_poc1_conn_content_1st_byte[3],
2485 "rtcp.app.poc1.conn.content.grp.dn",
2494 &hf_rtcp_app_poc1_conn_content_1st_byte[4],
2497 "rtcp.app.poc1.conn.content.grp.id",
2506 &hf_rtcp_app_poc1_conn_session_type,
2509 "rtcp.app.poc1.conn.session.type",
2512 VALS(rtcp_app_poc1_conn_sess_type_vals),
2518 &hf_rtcp_app_poc1_conn_add_ind_mao,
2520 "Manual answer override",
2521 "rtcp.app.poc1.conn.add.ind.mao",
2530 &hf_rtcp_app_poc1_conn_sdes_items[0],
2532 "Identity of inviting client",
2533 "rtcp.app.poc1.conn.sdes.a.id",
2542 &hf_rtcp_app_poc1_conn_sdes_items[1],
2544 "Nick name of inviting client",
2545 "rtcp.app.poc1.conn.sdes.a.dn",
2554 &hf_rtcp_app_poc1_conn_sdes_items[2],
2557 "rtcp.app.poc1.conn.sdes.sess.id",
2566 &hf_rtcp_app_poc1_conn_sdes_items[3],
2569 "rtcp.app.poc1.conn.sdes.grp.dn",
2578 &hf_rtcp_app_poc1_conn_sdes_items[4],
2581 "rtcp.app.poc1.conn.sdes.grp.id",
2592 "First sequence number",
2604 "Bitmask of following lost packets",
2614 &hf_rtcp_padding_count,
2617 "rtcp.padding.count",
2626 &hf_rtcp_padding_data,
2629 "rtcp.padding.data",
2646 "Stream setup, method and frame number", HFILL
2650 &hf_rtcp_setup_frame,
2658 "Frame that set up this stream", HFILL
2662 &hf_rtcp_setup_method,
2665 "rtcp.setup-method",
2670 "Method used to set up this stream", HFILL
2674 &hf_rtcp_roundtrip_delay,
2677 "rtcp.roundtrip-delay",
2682 "Calculated roundtrip delay, frame and ms value", HFILL
2686 &hf_rtcp_roundtrip_delay_frame,
2688 "Previous SR frame used in calculation",
2689 "rtcp.roundtrip-previous-sr-frame",
2694 "Frame used to calculate roundtrip delay", HFILL
2698 &hf_rtcp_roundtrip_delay_delay,
2700 "Roundtrip Delay(ms)",
2701 "rtcp.roundtrip-delay-delay",
2706 "Calculated roundtrip delay in ms", HFILL
2710 &hf_rtcp_xr_block_type,
2716 VALS(rtcp_xr_type_vals),
2722 &hf_rtcp_xr_block_specific,
2734 &hf_rtcp_xr_block_length,
2742 "Block Length", HFILL
2746 &hf_rtcp_ssrc_discarded,
2748 "Fraction discarded",
2749 "rtcp.ssrc.discarded",
2754 "Discard Rate", HFILL
2758 &hf_rtcp_xr_voip_metrics_burst_density,
2761 "rtcp.xr.voipmetrics.burstdensity",
2770 &hf_rtcp_xr_voip_metrics_gap_density,
2773 "rtcp.xr.voipmetrics.gapdensity",
2782 &hf_rtcp_xr_voip_metrics_burst_duration,
2784 "Burst Duration(ms)",
2785 "rtcp.xr.voipmetrics.burstduration",
2794 &hf_rtcp_xr_voip_metrics_gap_duration,
2797 "rtcp.xr.voipmetrics.gapduration",
2806 &hf_rtcp_xr_voip_metrics_rtdelay,
2808 "Round Trip Delay(ms)",
2809 "rtcp.xr.voipmetrics.rtdelay",
2818 &hf_rtcp_xr_voip_metrics_esdelay,
2820 "End System Delay(ms)",
2821 "rtcp.xr.voipmetrics.esdelay",
2830 &hf_rtcp_xr_voip_metrics_siglevel,
2833 "rtcp.xr.voipmetrics.signallevel",
2838 "Signal level of 127 indicates this parameter is unavailable", HFILL
2842 &hf_rtcp_xr_voip_metrics_noiselevel,
2845 "rtcp.xr.voipmetrics.noiselevel",
2850 "Noise level of 127 indicates this parameter is unavailable", HFILL
2854 &hf_rtcp_xr_voip_metrics_rerl,
2856 "Residual Echo Return Loss",
2857 "rtcp.xr.voipmetrics.rerl",
2866 &hf_rtcp_xr_voip_metrics_gmin,
2869 "rtcp.xr.voipmetrics.gmin",
2878 &hf_rtcp_xr_voip_metrics_rfactor,
2881 "rtcp.xr.voipmetrics.rfactor",
2886 "R Factor is in the range of 0 to 100; 127 indicates this parameter is unavailable", HFILL
2890 &hf_rtcp_xr_voip_metrics_extrfactor,
2892 "External R Factor",
2893 "rtcp.xr.voipmetrics.extrfactor",
2898 "R Factor is in the range of 0 to 100; 127 indicates this parameter is unavailable", HFILL
2902 &hf_rtcp_xr_voip_metrics_moslq,
2904 "MOS - Listening Quality",
2905 "rtcp.xr.voipmetrics.moslq",
2910 "MOS is in the range of 1 to 5; 127 indicates this parameter is unavailable", HFILL
2914 &hf_rtcp_xr_voip_metrics_moscq,
2916 "MOS - Conversational Quality",
2917 "rtcp.xr.voipmetrics.moscq",
2922 "MOS is in the range of 1 to 5; 127 indicates this parameter is unavailable", HFILL
2926 &hf_rtcp_xr_voip_metrics_plc,
2928 "Packet Loss Conealment Algorithm",
2929 "rtcp.xr.voipmetrics.plc",
2932 VALS(rtcp_xr_plc_algo_vals),
2938 &hf_rtcp_xr_voip_metrics_jbadaptive,
2940 "Adaptive Jitter Buffer Algorithm",
2941 "rtcp.xr.voipmetrics.jba",
2944 VALS(rtcp_xr_jb_adaptive_vals),
2950 &hf_rtcp_xr_voip_metrics_jbrate,
2952 "Jitter Buffer Rate",
2953 "rtcp.xr.voipmetrics.jbrate",
2962 &hf_rtcp_xr_voip_metrics_jbnominal,
2964 "Nominal Jitter Buffer Size",
2965 "rtcp.xr.voipmetrics.jbnominal",
2974 &hf_rtcp_xr_voip_metrics_jbmax,
2976 "Maximum Jitter Buffer Size",
2977 "rtcp.xr.voipmetrics.jbmax",
2986 &hf_rtcp_xr_voip_metrics_jbabsmax,
2988 "Absolute Maximum Jitter Buffer Size",
2989 "rtcp.xr.voipmetrics.jbabsmax",
2998 &hf_rtcp_xr_thinning,
3010 &hf_rtcp_xr_stats_loss_flag,
3013 "rtcp.xr.stats.lrflag",
3022 &hf_rtcp_xr_stats_dup_flag,
3024 "Duplicates Report Flag",
3025 "rtcp.xr.stats.dupflag",
3034 &hf_rtcp_xr_stats_jitter_flag,
3036 "Jitter Report Flag",
3037 "rtcp.xr.stats.jitterflag",
3046 &hf_rtcp_xr_stats_ttl,
3048 "TTL or Hop Limit Flag",
3049 "rtcp.xr.stats.ttl",
3052 VALS(rtcp_xr_ip_ttl_vals),
3060 "End Sequence Number",
3070 &hf_rtcp_xr_beginseq,
3072 "Begin Sequence Number",
3082 &hf_rtcp_xr_stats_lost,
3085 "rtcp.xr.stats.lost",
3094 &hf_rtcp_xr_stats_dups,
3096 "Duplicate Packets",
3097 "rtcp.xr.stats.dups",
3106 &hf_rtcp_xr_stats_minjitter,
3109 "rtcp.xr.stats.minjitter",
3118 &hf_rtcp_xr_stats_maxjitter,
3121 "rtcp.xr.stats.maxjitter",
3130 &hf_rtcp_xr_stats_meanjitter,
3133 "rtcp.xr.stats.meanjitter",
3142 &hf_rtcp_xr_stats_devjitter,
3144 "Standard Deviation of Jitter",
3145 "rtcp.xr.stats.devjitter",
3154 &hf_rtcp_xr_stats_minttl,
3156 "Minimum TTL or Hop Limit",
3157 "rtcp.xr.stats.minttl",
3166 &hf_rtcp_xr_stats_maxttl,
3168 "Maximum TTL or Hop Limit",
3169 "rtcp.xr.stats.maxttl",
3178 &hf_rtcp_xr_stats_meanttl,
3180 "Mean TTL or Hop Limit",
3181 "rtcp.xr.stats.meanttl",
3190 &hf_rtcp_xr_stats_devttl,
3192 "Standard Deviation of TTL",
3193 "rtcp.xr.stats.devttl",
3204 "Last RR timestamp",
3216 "Delay since last RR timestamp",
3227 static gint *ett[] =
3237 &ett_rtcp_roundtrip_delay,
3239 &ett_xr_block_contents,
3242 &ett_poc1_conn_contents
3245 module_t *rtcp_module;
3247 proto_rtcp = proto_register_protocol("Real-time Transport Control Protocol",
3249 proto_register_field_array(proto_rtcp, hf, array_length(hf));
3250 proto_register_subtree_array(ett, array_length(ett));
3252 register_dissector("rtcp", dissect_rtcp, proto_rtcp);
3254 rtcp_module = prefs_register_protocol(proto_rtcp, NULL);
3256 prefs_register_bool_preference(rtcp_module, "show_setup_info",
3257 "Show stream setup information",
3258 "Where available, show which protocol and frame caused "
3259 "this RTCP stream to be created",
3260 &global_rtcp_show_setup_info);
3262 prefs_register_bool_preference(rtcp_module, "heuristic_rtcp",
3263 "Try to decode RTCP outside of conversations ",
3264 "If call control SIP/H.323/RTSP/.. messages are missing in the trace, "
3265 "RTCP isn't decoded without this",
3268 prefs_register_bool_preference(rtcp_module, "show_roundtrip_calculation",
3269 "Show relative roundtrip calculations",
3270 "Try to work out network delay by comparing time between packets "
3271 "as captured and delays as seen by endpoint",
3272 &global_rtcp_show_roundtrip_calculation);
3274 prefs_register_uint_preference(rtcp_module, "roundtrip_min_threshhold",
3275 "Minimum roundtrip calculations to report (ms)",
3276 "Minimum calculated roundtrip delay time in milliseconds that "
3277 "should be reported",
3278 MIN_ROUNDTRIP_TO_REPORT_DEFAULT, &global_rtcp_show_roundtrip_calculation_minimum);
3284 proto_reg_handoff_rtcp(void)
3287 * Register this dissector as one that can be selected by a
3290 rtcp_handle = find_dissector("rtcp");
3291 dissector_add_handle("udp.port", rtcp_handle);
3293 heur_dissector_add( "udp", dissect_rtcp_heur, proto_rtcp);