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 * Information on PoC can be found from http://www.openmobilealliance.org/
45 * RTCP XR is specified in RFC 3611.
47 * See also http://www.iana.org/assignments/rtp-parameters
56 #include <epan/packet.h>
61 #include "packet-rtcp.h"
62 #include "packet-ntp.h"
63 #include <epan/conversation.h>
65 #include <epan/prefs.h>
66 #include <epan/emem.h>
69 /* Version is the first 2 bits of the first octet*/
70 #define RTCP_VERSION(octet) ((octet) >> 6)
72 /* Padding is the third bit; no need to shift, because true is any value
74 #define RTCP_PADDING(octet) ((octet) & 0x20)
76 /* Receiver/ Sender count is the 5 last bits */
77 #define RTCP_COUNT(octet) ((octet) & 0x1F)
79 static dissector_handle_t rtcp_handle;
81 static const value_string rtcp_version_vals[] =
83 { 0, "Old VAT Version" },
84 { 1, "First Draft Version" },
85 { 2, "RFC 1889 Version" },
89 /* RTCP packet types according to Section A.11.1 */
90 /* And http://www.iana.org/assignments/rtp-parameters */
96 #define RTCP_RTPFB 205
99 /* Supplemental H.261 specific RTCP packet types according to Section C.3.5 */
101 #define RTCP_NACK 193
103 static const value_string rtcp_packet_type_vals[] =
105 { RTCP_SR, "Sender Report" },
106 { RTCP_RR, "Receiver Report" },
107 { RTCP_SDES, "Source description" },
108 { RTCP_BYE, "Goodbye" },
109 { RTCP_APP, "Application specific" },
110 { RTCP_FIR, "Full Intra-frame Request (H.261)" },
111 { RTCP_NACK, "Negative Acknowledgement (H.261)" },
112 { RTCP_RTPFB, "Generic RTP Feedback" },
113 { RTCP_PSFB, "Payload-specific" },
114 { RTCP_XR, "Extended report (RFC 3611)"},
118 /* RTCP SDES types (Section A.11.2) */
119 #define RTCP_SDES_END 0
120 #define RTCP_SDES_CNAME 1
121 #define RTCP_SDES_NAME 2
122 #define RTCP_SDES_EMAIL 3
123 #define RTCP_SDES_PHONE 4
124 #define RTCP_SDES_LOC 5
125 #define RTCP_SDES_TOOL 6
126 #define RTCP_SDES_NOTE 7
127 #define RTCP_SDES_PRIV 8
128 #define RTCP_SDES_H323_CADDR 9
130 static const value_string rtcp_sdes_type_vals[] =
132 { RTCP_SDES_END, "END" },
133 { RTCP_SDES_CNAME, "CNAME (user and domain)" },
134 { RTCP_SDES_NAME, "NAME (common name)" },
135 { RTCP_SDES_EMAIL, "EMAIL (e-mail address)" },
136 { RTCP_SDES_PHONE, "PHONE (phone number)" },
137 { RTCP_SDES_LOC, "LOC (geographic location)" },
138 { RTCP_SDES_TOOL, "TOOL (name/version of source app)" },
139 { RTCP_SDES_NOTE, "NOTE (note about source)" },
140 { RTCP_SDES_PRIV, "PRIV (private extensions)" },
141 { RTCP_SDES_H323_CADDR,"H323-CADDR (H.323 callable address)"},
145 /* RTCP XR Blocks (Section 4, RTC 3611) */
146 #define RTCP_XR_LOSS_RLE 1
147 #define RTCP_XR_DUP_RLE 2
148 #define RTCP_XR_PKT_RXTIMES 3
149 #define RTCP_XR_REF_TIME 4
150 #define RTCP_XR_DLRR 5
151 #define RTCP_XR_STATS_SUMRY 6
152 #define RTCP_XR_VOIP_METRCS 7
154 static const value_string rtcp_xr_type_vals[] =
156 { RTCP_XR_LOSS_RLE, "Loss Run Length Encoding Report Block" },
157 { RTCP_XR_DUP_RLE, "Duplicate Run Length Encoding Report Block" },
158 { RTCP_XR_PKT_RXTIMES, "Packet Receipt Times Report Block" },
159 { RTCP_XR_REF_TIME, "Receiver Reference Time Report Block" },
160 { RTCP_XR_DLRR, "DLRR Report Block" },
161 { RTCP_XR_STATS_SUMRY, "Statistics Summary Report Block" },
162 { RTCP_XR_VOIP_METRCS, "VoIP Metrics Report Block" },
166 /* XR VoIP Metrics Block - PLC Algorithms */
167 static const value_string rtcp_xr_plc_algo_vals[] =
169 { 0, "Unspecified" },
176 /* XR VoIP Metrics Block - JB Adaptive */
177 static const value_string rtcp_xr_jb_adaptive_vals[] =
181 { 2, "Non-Adaptive" },
186 /* XR Stats Summary Block - IP TTL or Hop Limit */
187 static const value_string rtcp_xr_ip_ttl_vals[] =
189 { 0, "No TTL Values" },
196 /* RTCP Application PoC1 Value strings
197 * OMA-TS-PoC-UserPlane-V1_0-20051006-C
199 static const value_string rtcp_app_poc1_floor_cnt_type_vals[] =
201 { 0, "TBCP Talk Burst Request"},
202 { 1, "TBCP Talk Burst Granted"},
203 { 2, "TBCP Talk Burst Taken (no reply expected)"},
204 { 3, "TBCP Talk Burst Deny"},
205 { 4, "TBCP Talk Burst Release"},
206 { 5, "TBCP Talk Burst Idle"},
207 { 6, "TBCP Talk Burst Revoke"},
208 { 7, "TBCP Talk Burst Acknowledgement"},
209 { 8, "TBCP Queue Status Request"},
210 { 9, "TBCP Queue Status Response"},
211 { 11, "TBCP Disconnect"},
212 { 15, "TBCP Connect"},
213 { 18, "TBCP Talk Burst Taken (ack expected)"},
217 static const value_string rtcp_app_poc1_reason_code1_vals[] =
219 { 1, "Floor already in use"},
220 { 2, "Internal PoC server error"},
221 { 3, "Only one participant in the group"},
222 { 4, "Retry-after timer has not expired"},
227 static const value_string rtcp_app_poc1_reason_code2_vals[] =
229 { 1, "Only one user"},
230 { 2, "Talk burst too long"},
231 { 3, "No permission to send a Talk Burst"},
232 { 4, "Talk burst pre-empted"},
236 static const value_string rtcp_app_poc1_reason_code_ack_vals[] =
240 { 2, "Not accepted"},
243 static const value_string rtcp_app_poc1_conn_sess_type_vals[] =
248 { 3, "Pre-arranged"},
253 static const value_string rtcp_app_poc1_qsresp_priority_vals[] =
255 { 0, "No priority (un-queued)"},
256 { 1, "Normal priority"},
257 { 2, "High priority"},
258 { 3, "Pre-emptive priority"},
262 /* RTCP header fields */
263 static int proto_rtcp = -1;
264 static int hf_rtcp_version = -1;
265 static int hf_rtcp_padding = -1;
266 static int hf_rtcp_rc = -1;
267 static int hf_rtcp_sc = -1;
268 static int hf_rtcp_pt = -1;
269 static int hf_rtcp_length = -1;
270 static int hf_rtcp_ssrc_sender = -1;
271 static int hf_rtcp_ntp = -1;
272 static int hf_rtcp_ntp_msw = -1;
273 static int hf_rtcp_ntp_lsw = -1;
274 static int hf_rtcp_rtp_timestamp = -1;
275 static int hf_rtcp_sender_pkt_cnt = -1;
276 static int hf_rtcp_sender_oct_cnt = -1;
277 static int hf_rtcp_ssrc_source = -1;
278 static int hf_rtcp_ssrc_fraction = -1;
279 static int hf_rtcp_ssrc_cum_nr = -1;
280 static int hf_rtcp_ssrc_discarded = -1;
281 /* First the 32 bit number, then the split
282 * up 16 bit values */
283 /* These two are added to a subtree */
284 static int hf_rtcp_ssrc_ext_high_seq = -1;
285 static int hf_rtcp_ssrc_high_seq = -1;
286 static int hf_rtcp_ssrc_high_cycles = -1;
287 static int hf_rtcp_ssrc_jitter = -1;
288 static int hf_rtcp_ssrc_lsr = -1;
289 static int hf_rtcp_ssrc_dlsr = -1;
290 static int hf_rtcp_ssrc_csrc = -1;
291 static int hf_rtcp_sdes_type = -1;
292 static int hf_rtcp_sdes_length = -1;
293 static int hf_rtcp_sdes_text = -1;
294 static int hf_rtcp_sdes_prefix_len = -1;
295 static int hf_rtcp_sdes_prefix_string= -1;
296 static int hf_rtcp_subtype = -1;
297 static int hf_rtcp_name_ascii = -1;
298 static int hf_rtcp_app_data = -1;
299 static int hf_rtcp_fsn = -1;
300 static int hf_rtcp_blp = -1;
301 static int hf_rtcp_padding_count = -1;
302 static int hf_rtcp_padding_data = -1;
303 static int hf_rtcp_app_poc1_subtype = -1;
304 static int hf_rtcp_app_poc1_sip_uri = -1;
305 static int hf_rtcp_app_poc1_disp_name = -1;
306 static int hf_rtcp_app_poc1_stt = -1;
307 static int hf_rtcp_app_poc1_partic = -1;
308 static int hf_rtcp_app_poc1_ssrc_granted = -1;
309 static int hf_rtcp_app_poc1_last_pkt_seq_no = -1;
310 static int hf_rtcp_app_poc1_reason_code1 = -1;
311 static int hf_rtcp_app_poc1_item_len = -1;
312 static int hf_rtcp_app_poc1_reason1_phrase = -1;
313 static int hf_rtcp_app_poc1_reason_code2 = -1;
314 static int hf_rtcp_app_poc1_additionalinfo = -1;
315 static int hf_rtcp_app_poc1_ack_subtype = -1;
316 static int hf_rtcp_app_poc1_ack_reason_code = -1;
317 static int hf_rtcp_app_poc1_qsresp_priority = -1;
318 static int hf_rtcp_app_poc1_qsresp_position = -1;
319 static int hf_rtcp_app_poc1_conn_content_1st_byte[5] = { -1, -1, -1, -1, -1 };
320 static int hf_rtcp_app_poc1_conn_session_type = -1;
321 static int hf_rtcp_app_poc1_conn_add_ind_mao = -1;
322 static int hf_rtcp_app_poc1_conn_sdes_items[5] = { -1, -1, -1, -1, -1 };
323 static int hf_rtcp_xr_block_type = -1;
324 static int hf_rtcp_xr_block_specific = -1;
325 static int hf_rtcp_xr_block_length = -1;
326 static int hf_rtcp_xr_thinning = -1;
327 static int hf_rtcp_xr_voip_metrics_burst_density = -1;
328 static int hf_rtcp_xr_voip_metrics_gap_density = -1;
329 static int hf_rtcp_xr_voip_metrics_burst_duration = -1;
330 static int hf_rtcp_xr_voip_metrics_gap_duration = -1;
331 static int hf_rtcp_xr_voip_metrics_rtdelay = -1;
332 static int hf_rtcp_xr_voip_metrics_esdelay = -1;
333 static int hf_rtcp_xr_voip_metrics_siglevel = -1;
334 static int hf_rtcp_xr_voip_metrics_noiselevel = -1;
335 static int hf_rtcp_xr_voip_metrics_rerl = -1;
336 static int hf_rtcp_xr_voip_metrics_gmin = -1;
337 static int hf_rtcp_xr_voip_metrics_rfactor = -1;
338 static int hf_rtcp_xr_voip_metrics_extrfactor = -1;
339 static int hf_rtcp_xr_voip_metrics_moslq = -1;
340 static int hf_rtcp_xr_voip_metrics_moscq = -1;
341 static int hf_rtcp_xr_voip_metrics_plc = -1;
342 static int hf_rtcp_xr_voip_metrics_jbadaptive = -1;
343 static int hf_rtcp_xr_voip_metrics_jbrate = -1;
344 static int hf_rtcp_xr_voip_metrics_jbnominal = -1;
345 static int hf_rtcp_xr_voip_metrics_jbmax = -1;
346 static int hf_rtcp_xr_voip_metrics_jbabsmax = -1;
347 static int hf_rtcp_xr_stats_loss_flag = -1;
348 static int hf_rtcp_xr_stats_dup_flag = -1;
349 static int hf_rtcp_xr_stats_jitter_flag = -1;
350 static int hf_rtcp_xr_stats_ttl = -1;
351 static int hf_rtcp_xr_beginseq = -1;
352 static int hf_rtcp_xr_endseq = -1;
353 static int hf_rtcp_xr_stats_lost = -1;
354 static int hf_rtcp_xr_stats_dups = -1;
355 static int hf_rtcp_xr_stats_minjitter = -1;
356 static int hf_rtcp_xr_stats_maxjitter = -1;
357 static int hf_rtcp_xr_stats_meanjitter = -1;
358 static int hf_rtcp_xr_stats_devjitter = -1;
359 static int hf_rtcp_xr_stats_minttl = -1;
360 static int hf_rtcp_xr_stats_maxttl = -1;
361 static int hf_rtcp_xr_stats_meanttl = -1;
362 static int hf_rtcp_xr_stats_devttl = -1;
363 static int hf_rtcp_xr_lrr = -1;
364 static int hf_rtcp_xr_dlrr = -1;
366 /* RTCP setup fields */
367 static int hf_rtcp_setup = -1;
368 static int hf_rtcp_setup_frame = -1;
369 static int hf_rtcp_setup_method = -1;
371 /* RTCP roundtrip delay fields */
372 static int hf_rtcp_last_sr_timestamp_frame = -1;
373 static int hf_rtcp_roundtrip_delay = -1;
377 /* RTCP fields defining a sub tree */
378 static gint ett_rtcp = -1;
379 static gint ett_ssrc = -1;
380 static gint ett_ssrc_item = -1;
381 static gint ett_ssrc_ext_high = -1;
382 static gint ett_sdes = -1;
383 static gint ett_sdes_item = -1;
384 static gint ett_PoC1 = -1;
385 static gint ett_rtcp_setup = -1;
386 static gint ett_rtcp_roundtrip_delay = -1;
387 static gint ett_xr_block = -1;
388 static gint ett_xr_block_contents = -1;
389 static gint ett_xr_ssrc = -1;
390 static gint ett_xr_loss_chunk = -1;
391 static gint ett_poc1_conn_contents = -1;
393 /* Main dissection function */
394 static void dissect_rtcp( tvbuff_t *tvb, packet_info *pinfo,
397 /* Heuristic dissection */
398 static gboolean global_rtcp_heur = FALSE;
399 static gboolean dissect_rtcp_heur( tvbuff_t *tvb, packet_info *pinfo,
402 /* Displaying set info */
403 static gboolean global_rtcp_show_setup_info = TRUE;
404 static void show_setup_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
406 /* Related to roundtrip calculation (using LSR and DLSR) */
407 static gboolean global_rtcp_show_roundtrip_calculation = FALSE;
408 #define MIN_ROUNDTRIP_TO_REPORT_DEFAULT 10
409 static guint global_rtcp_show_roundtrip_calculation_minimum = MIN_ROUNDTRIP_TO_REPORT_DEFAULT;
410 static void remember_outgoing_sr(packet_info *pinfo, long lsr);
411 static void calculate_roundtrip_delay(tvbuff_t *tvb, packet_info *pinfo,
412 proto_tree *tree, guint32 lsr, guint32 dlsr);
413 static void add_roundtrip_delay_info(tvbuff_t *tvb, packet_info *pinfo,
414 proto_tree *tree, guint frame, guint delay);
417 /* Set up an RTCP conversation using the info given */
418 void rtcp_add_address( packet_info *pinfo,
419 address *addr, int port,
421 const gchar *setup_method, guint32 setup_frame_number)
424 conversation_t* p_conv;
425 struct _rtcp_conversation_info *p_conv_data = NULL;
428 * If this isn't the first time this packet has been processed,
429 * we've already done this work, so we don't need to do it
432 if (pinfo->fd->flags.visited)
437 SET_ADDRESS(&null_addr, AT_NONE, 0, NULL);
440 * Check if the ip address and port combination is not
441 * already registered as a conversation.
443 p_conv = find_conversation( pinfo->fd->num, addr, &null_addr, PT_UDP, port, other_port,
444 NO_ADDR_B | (!other_port ? NO_PORT_B : 0));
447 * If not, create a new conversation.
450 p_conv = conversation_new( pinfo->fd->num, addr, &null_addr, PT_UDP,
451 (guint32)port, (guint32)other_port,
452 NO_ADDR2 | (!other_port ? NO_PORT2 : 0));
456 conversation_set_dissector(p_conv, rtcp_handle);
459 * Check if the conversation has data associated with it.
461 p_conv_data = conversation_get_proto_data(p_conv, proto_rtcp);
464 * If not, add a new data item.
466 if ( ! p_conv_data ) {
467 /* Create conversation data */
468 p_conv_data = se_alloc(sizeof(struct _rtcp_conversation_info));
473 memset(p_conv_data, 0, sizeof(struct _rtcp_conversation_info));
474 conversation_add_proto_data(p_conv, proto_rtcp, p_conv_data);
478 * Update the conversation data.
480 p_conv_data->setup_method_set = TRUE;
481 strncpy(p_conv_data->setup_method, setup_method, MAX_RTCP_SETUP_METHOD_SIZE);
482 p_conv_data->setup_method[MAX_RTCP_SETUP_METHOD_SIZE] = '\0';
483 p_conv_data->setup_frame_number = setup_frame_number;
487 dissect_rtcp_heur( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree )
489 unsigned int offset = 0;
490 unsigned int first_byte;
491 unsigned int packet_type;
493 /* This is a heuristic dissector, which means we get all the UDP
494 * traffic not sent to a known dissector and not claimed by
495 * a heuristic dissector called before us!
498 if (!global_rtcp_heur)
503 /* Was it sent between 2 odd-numbered ports? */
504 if (!(pinfo->srcport % 2) || !(pinfo->destport % 2))
509 /* Look at first byte */
510 first_byte = tvb_get_guint8(tvb, offset);
512 /* Are version bits set to 2? */
513 if (((first_byte & 0xC0) >> 6) != 2)
518 /* Look at packet type */
519 packet_type = tvb_get_guint8(tvb, offset + 1);
521 /* First packet within compound packet is supposed to be a sender
522 or receiver report. Also see BYE so allow this... */
523 if (!((packet_type == RTCP_SR) || (packet_type == RTCP_RR) ||
524 packet_type == RTCP_BYE))
529 /* Overall length must be a multiple of 4 bytes */
530 if (tvb_length(tvb) % 4)
535 /* OK, dissect as RTCP */
536 dissect_rtcp(tvb, pinfo, tree);
542 dissect_rtcp_nack( tvbuff_t *tvb, int offset, proto_tree *tree )
544 /* Packet type = FIR (H261) */
545 proto_tree_add_uint( tree, hf_rtcp_rc, tvb, offset, 1, tvb_get_guint8( tvb, offset ) );
547 /* Packet type, 8 bits = APP */
548 proto_tree_add_item( tree, hf_rtcp_pt, tvb, offset, 1, FALSE );
551 /* Packet length in 32 bit words minus one */
552 proto_tree_add_uint( tree, hf_rtcp_length, tvb, offset, 2, tvb_get_ntohs( tvb, offset ) );
556 proto_tree_add_uint( tree, hf_rtcp_ssrc_source, tvb, offset, 4, tvb_get_ntohl( tvb, offset ) );
560 proto_tree_add_uint( tree, hf_rtcp_fsn, tvb, offset, 2, tvb_get_ntohs( tvb, offset ) );
564 proto_tree_add_uint( tree, hf_rtcp_blp, tvb, offset, 2, tvb_get_ntohs( tvb, offset ) );
571 dissect_rtcp_fir( tvbuff_t *tvb, int offset, proto_tree *tree )
573 /* Packet type = FIR (H261) */
574 proto_tree_add_uint( tree, hf_rtcp_rc, tvb, offset, 1, tvb_get_guint8( tvb, offset ) );
576 /* Packet type, 8 bits = APP */
577 proto_tree_add_item( tree, hf_rtcp_pt, tvb, offset, 1, FALSE );
580 /* Packet length in 32 bit words minus one */
581 proto_tree_add_uint( tree, hf_rtcp_length, tvb, offset, 2, tvb_get_ntohs( tvb, offset ) );
585 proto_tree_add_uint( tree, hf_rtcp_ssrc_source, tvb, offset, 4, tvb_get_ntohl( tvb, offset ) );
592 dissect_rtcp_app( tvbuff_t *tvb,packet_info *pinfo, int offset, proto_tree *tree,
593 unsigned int padding, unsigned int packet_len, guint rtcp_subtype, guint32 app_length )
595 unsigned int counter = 0;
599 guint items_start_offset;
600 proto_tree *PoC1_tree;
601 proto_item *PoC1_item;
603 /* XXX If more application types are to be dissected it may be useful to use a table like in packet-sip.c */
604 static const char app_name_str[] = "PoC1";
608 proto_tree_add_uint( tree, hf_rtcp_ssrc_source, tvb, offset, 4, tvb_get_ntohl( tvb, offset ) );
613 for( counter = 0; counter < 4; counter++ )
614 ascii_name[ counter ] = tvb_get_guint8( tvb, offset + counter );
615 /* strncpy( ascii_name, pd + offset, 4 ); */
616 ascii_name[4] = '\0';
617 proto_tree_add_string( tree, hf_rtcp_name_ascii, tvb, offset, 4,
619 if ( strncasecmp(ascii_name,app_name_str,4 ) != 0 ){ /* Not PoC1 */
620 if (check_col(pinfo->cinfo, COL_INFO))
621 col_append_fstr(pinfo->cinfo, COL_INFO,"( %s ) subtype=%u",ascii_name, rtcp_subtype);
624 /* Applications specific data */
626 /* If there's padding present, we have to remove that from the data part
627 * The last octet of the packet contains the length of the padding
629 packet_len -= tvb_get_guint8( tvb, offset + packet_len - 1 );
631 proto_tree_add_item( tree, hf_rtcp_app_data, tvb, offset, packet_len, FALSE );
632 offset += packet_len;
635 }else{/* PoC1 Application */
636 guint8 t2timer_code, participants_code;
638 item = proto_tree_add_uint( tree, hf_rtcp_app_poc1_subtype, tvb, offset - 8, 1, rtcp_subtype );
639 PROTO_ITEM_SET_GENERATED(item);
640 if (check_col(pinfo->cinfo, COL_INFO))
641 col_append_fstr(pinfo->cinfo, COL_INFO,"(%s) subtype=%s",ascii_name,
642 val_to_str(rtcp_subtype,rtcp_app_poc1_floor_cnt_type_vals,"unknown (%u)") );
645 app_length = app_length -8;
646 if ( packet_len == 0 )
647 return offset; /* No more data */
648 /* Applications specific data */
650 /* If there's padding present, we have to remove that from the data part
651 * The last octet of the packet contains the length of the padding
653 packet_len -= tvb_get_guint8( tvb, offset + packet_len - 1 );
655 /* Create a subtree for the PoC1 Application items; we don't yet know
657 items_start_offset = offset;
659 PoC1_item = proto_tree_add_text(tree, tvb, offset, packet_len,
660 "PoC1 Application specific data");
661 PoC1_tree = proto_item_add_subtree( PoC1_item, ett_PoC1 );
664 proto_tree_add_item( PoC1_tree, hf_rtcp_app_data, tvb, offset, packet_len, FALSE );
665 switch ( rtcp_subtype ) {
666 case 1: /* TBCP Granted */
667 t2timer_code = tvb_get_guint8(tvb, offset);
670 if (t2timer_code != 101) /* SHALL be 101 */
673 item_len = tvb_get_guint8(tvb, offset);
676 if (item_len != 2) /* SHALL be 2 */
679 proto_tree_add_item(PoC1_tree, hf_rtcp_app_poc1_stt, tvb, offset, 2, FALSE );
681 packet_len -= item_len;
683 participants_code = tvb_get_guint8(tvb, offset);
686 if (participants_code != 100) /* SHALL be 100 */
689 item_len = tvb_get_guint8(tvb, offset);
692 if (item_len != 2) /* SHALL be 2 */
695 proto_tree_add_item(PoC1_tree, hf_rtcp_app_poc1_partic, tvb, offset, 2, FALSE );
697 packet_len -= item_len;
699 case 2: /* TBCP Talk Burst Taken (no reply expected) */
700 case 18: /* TBCP Talk Burst Taken (ack expected) */
701 proto_tree_add_item(PoC1_tree, hf_rtcp_app_poc1_ssrc_granted, tvb, offset, 4, FALSE );
704 sdes_type = tvb_get_guint8( tvb, offset );
705 proto_tree_add_item( PoC1_tree, hf_rtcp_sdes_type, tvb, offset, 1, FALSE );
708 /* Item length, 8 bits */
709 item_len = tvb_get_guint8( tvb, offset );
710 proto_tree_add_item( PoC1_tree, hf_rtcp_sdes_length, tvb, offset, 1, FALSE );
713 proto_tree_add_item( PoC1_tree, hf_rtcp_app_poc1_sip_uri, tvb, offset, item_len, FALSE );
714 offset = offset + item_len;
715 packet_len = packet_len - item_len;
717 /* In the application dependent data, the TBCP Talk Burst Taken message SHALL carry
718 * a SSRC field and SDES items, CNAME and MAY carry SDES item NAME to identify the
719 * PoC Client that has been granted permission to send a Talk Burst.
720 * The SDES item NAME SHALL be included if it is known by the PoC Server.
721 * Therefore the length of the packet will vary depending on numbwe of SDES items
722 * and the size of the SDES items.
724 if ( packet_len == 0 )
727 sdes_type = tvb_get_guint8( tvb, offset );
728 proto_tree_add_item( PoC1_tree, hf_rtcp_sdes_type, tvb, offset, 1, FALSE );
731 /* Item length, 8 bits */
732 item_len = tvb_get_guint8( tvb, offset );
733 proto_tree_add_item( PoC1_tree, hf_rtcp_sdes_length, tvb, offset, 1, FALSE );
737 proto_tree_add_item( PoC1_tree, hf_rtcp_app_poc1_disp_name, tvb, offset, item_len, FALSE );
738 offset = offset + item_len;
739 packet_len = packet_len - item_len;
743 participants_code = tvb_get_guint8(tvb, offset);
746 if (participants_code != 100) /* SHALL be 100 */
748 item_len = tvb_get_guint8(tvb, offset);
751 if (item_len != 2) /* SHALL be 2 */
753 proto_tree_add_item(PoC1_tree, hf_rtcp_app_poc1_partic, tvb, offset, 2, FALSE );
755 packet_len -= item_len;
757 case 3: /* TBCP Talk Burst Deny */
758 proto_tree_add_item( PoC1_tree, hf_rtcp_app_poc1_reason_code1, tvb, offset, 1, FALSE );
761 /* Item length, 8 bits */
762 item_len = tvb_get_guint8( tvb, offset );
763 proto_tree_add_item( PoC1_tree, hf_rtcp_app_poc1_item_len, tvb, offset, 1, FALSE );
767 proto_tree_add_item( PoC1_tree, hf_rtcp_app_poc1_reason1_phrase, tvb, offset, item_len, FALSE );
768 offset = offset + item_len;
769 packet_len = packet_len - item_len;
771 case 4: /* TBCP Talk Burst Release */
772 proto_tree_add_item( PoC1_tree, hf_rtcp_app_poc1_last_pkt_seq_no, tvb, offset, 2, FALSE );
773 proto_tree_add_text(PoC1_tree, tvb, offset + 2, 2, "Padding 2 bytes");
777 /* 5 TBCP Talk Burst Idle */
778 case 6: /* TBCP Talk Burst Revoke */
779 proto_tree_add_item( PoC1_tree, hf_rtcp_app_poc1_reason_code2, tvb, offset, 2, FALSE );
780 proto_tree_add_item( PoC1_tree, hf_rtcp_app_poc1_additionalinfo, tvb, offset + 2, 2, FALSE );
785 case 7: /* TBCP Talk Burst Acknowledgement */
786 proto_tree_add_item( PoC1_tree, hf_rtcp_app_poc1_ack_subtype, tvb, offset, 1, FALSE );
787 proto_tree_add_item( PoC1_tree, hf_rtcp_app_poc1_ack_reason_code, tvb, offset, 2, FALSE );
788 proto_tree_add_text( PoC1_tree, tvb, offset + 2, 2, "Padding 2 bytes" );
793 /* 8 TBCP Queue Status Request */
795 case 9: /*TBCP Queue Status Response */
796 proto_tree_add_item( PoC1_tree, hf_rtcp_app_poc1_qsresp_priority, tvb, offset, 1, FALSE );
797 proto_tree_add_item( PoC1_tree, hf_rtcp_app_poc1_qsresp_position, tvb, offset + 1, 2, FALSE );
798 proto_tree_add_text( PoC1_tree, tvb, offset + 3, 1, "Padding 1 byte" );
803 /* 11 TBCP Disconnect */
805 case 15: /* TBCP Connect */
807 proto_item *content = proto_tree_add_text(PoC1_tree, tvb, offset, 2, "SDES item content");
808 gboolean contents[5];
811 proto_tree *content_tree = proto_item_add_subtree(content, ett_poc1_conn_contents);
812 guint temp_byte = tvb_get_guint8( tvb, offset );
814 for ( i = 0; i < sizeof(contents) /
815 sizeof(contents[0]) &&
816 i < sizeof(hf_rtcp_app_poc1_conn_content_1st_byte) /
817 sizeof(hf_rtcp_app_poc1_conn_content_1st_byte[0]);
819 proto_tree_add_item( content_tree, hf_rtcp_app_poc1_conn_content_1st_byte[i], tvb, offset, 1, FALSE );
820 contents[i] = temp_byte & (1 << (7-i));
823 proto_tree_add_item( PoC1_tree, hf_rtcp_app_poc1_conn_session_type, tvb, offset + 2, 1, FALSE );
825 proto_tree_add_item( PoC1_tree, hf_rtcp_app_poc1_conn_add_ind_mao, tvb, offset + 3, 1, FALSE );
830 for ( i = 0; i < sizeof(contents) /
831 sizeof(contents[0]); ++i ) {
833 guint sdes_type, sdes_len;
834 sdes_type = tvb_get_guint8( tvb, offset++ );
835 sdes_len = tvb_get_guint8( tvb, offset );
837 proto_tree_add_item( PoC1_tree, hf_rtcp_app_poc1_conn_sdes_items[i], tvb, offset, 1, FALSE );
839 offset += sdes_len + 1;
840 packet_len -= (sdes_len + 2);
848 offset += packet_len;
855 dissect_rtcp_bye( tvbuff_t *tvb, int offset, proto_tree *tree,
858 unsigned int chunk = 1;
859 unsigned int reason_length = 0;
860 char* reason_text = NULL;
862 while ( chunk <= count ) {
863 /* source identifier, 32 bits */
864 proto_tree_add_item( tree, hf_rtcp_ssrc_source, tvb, offset, 4, FALSE);
869 if ( tvb_reported_length_remaining( tvb, offset ) > 0 ) {
870 /* Bye reason consists of an 8 bit length l and a string with length l */
871 reason_length = tvb_get_guint8( tvb, offset );
872 proto_tree_add_item( tree, hf_rtcp_sdes_length, tvb, offset, 1, FALSE );
875 reason_text = tvb_get_ephemeral_string(tvb, offset, reason_length);
876 proto_tree_add_string( tree, hf_rtcp_sdes_text, tvb, offset, reason_length, reason_text );
877 offset += reason_length;
885 dissect_rtcp_sdes( tvbuff_t *tvb, int offset, proto_tree *tree,
888 unsigned int chunk = 1;
889 proto_item *sdes_item;
890 proto_tree *sdes_tree;
891 proto_tree *sdes_item_tree;
894 int items_start_offset;
896 unsigned int item_len = 0;
897 unsigned int sdes_type = 0;
898 unsigned int prefix_len = 0;
900 while ( chunk <= count ) {
901 /* Create a subtree for this chunk; we don't yet know
903 start_offset = offset;
905 ssrc = tvb_get_ntohl( tvb, offset );
906 sdes_item = proto_tree_add_text(tree, tvb, offset, -1,
907 "Chunk %u, SSRC/CSRC %u", chunk, ssrc);
908 sdes_tree = proto_item_add_subtree( sdes_item, ett_sdes );
910 /* SSRC_n source identifier, 32 bits */
911 proto_tree_add_uint( sdes_tree, hf_rtcp_ssrc_source, tvb, offset, 4, ssrc );
914 /* Create a subtree for the SDES items; we don't yet know
916 items_start_offset = offset;
917 ti = proto_tree_add_text(sdes_tree, tvb, offset, -1,
919 sdes_item_tree = proto_item_add_subtree( ti, ett_sdes_item );
922 * Not every message is ended with "null" bytes, so check for
923 * end of frame as well.
925 while ( tvb_reported_length_remaining( tvb, offset ) > 0 ) {
927 sdes_type = tvb_get_guint8( tvb, offset );
928 proto_tree_add_item( sdes_item_tree, hf_rtcp_sdes_type, tvb, offset, 1, FALSE );
931 if ( sdes_type == RTCP_SDES_END ) {
936 /* Item length, 8 bits */
937 item_len = tvb_get_guint8( tvb, offset );
938 proto_tree_add_item( sdes_item_tree, hf_rtcp_sdes_length, tvb, offset, 1, FALSE );
941 if ( item_len != 0 ) {
942 if ( sdes_type == RTCP_SDES_PRIV ) {
943 /* PRIV adds two items between the
944 * SDES length and value - an 8 bit
945 * length giving the length of a
946 * "prefix string", and the string.
948 prefix_len = tvb_get_guint8( tvb, offset );
949 if ( prefix_len + 1 > item_len ) {
950 proto_tree_add_uint_format( sdes_item_tree,
951 hf_rtcp_sdes_prefix_len, tvb,
952 offset, 1, prefix_len,
953 "Prefix length: %u (bogus, must be <= %u)",
954 prefix_len, item_len - 1);
958 proto_tree_add_item( sdes_item_tree, hf_rtcp_sdes_prefix_len, tvb, offset, 1, FALSE );
961 proto_tree_add_item( sdes_item_tree, hf_rtcp_sdes_prefix_string, tvb, offset, prefix_len, FALSE );
962 offset += prefix_len;
963 item_len -= prefix_len +1;
967 proto_tree_add_item( sdes_item_tree, hf_rtcp_sdes_text, tvb, offset, item_len, FALSE );
972 /* Set the length of the items subtree. */
973 proto_item_set_len(ti, offset - items_start_offset);
975 /* 32 bits = 4 bytes, so.....
976 * If offset % 4 != 0, we divide offset by 4, add one and then
977 * multiply by 4 again to reach the boundary
979 if ( offset % 4 != 0 )
980 offset = ((offset / 4) + 1 ) * 4;
982 /* Set the length of this chunk. */
983 proto_item_set_len(sdes_item, offset - start_offset);
989 static void parse_xr_type_specific_field(tvbuff_t *tvb, gint offset, guint block_type, proto_tree *tree)
991 guint8 flags = tvb_get_guint8(tvb, offset);
993 switch (block_type) {
994 case RTCP_XR_LOSS_RLE:
995 case RTCP_XR_DUP_RLE:
996 case RTCP_XR_PKT_RXTIMES:
997 proto_tree_add_uint(tree, hf_rtcp_xr_thinning, tvb, offset, 1, flags);
1000 case RTCP_XR_STATS_SUMRY:
1001 proto_tree_add_boolean(tree, hf_rtcp_xr_stats_loss_flag, tvb, offset, 1, flags);
1002 proto_tree_add_boolean(tree, hf_rtcp_xr_stats_dup_flag, tvb, offset, 1, flags);
1003 proto_tree_add_boolean(tree, hf_rtcp_xr_stats_jitter_flag, tvb, offset, 1, flags);
1004 proto_tree_add_uint(tree, hf_rtcp_xr_stats_ttl, tvb, offset, 1, flags);
1008 proto_tree_add_uint(tree, hf_rtcp_xr_block_specific, tvb, offset, 1, flags);
1013 static gboolean validate_xr_block_length(tvbuff_t *tvb, int offset, guint block_type, guint block_len, proto_tree *tree)
1015 proto_tree_add_uint(tree, hf_rtcp_xr_block_length, tvb, offset, 2, block_len);
1016 switch (block_type) {
1017 case RTCP_XR_REF_TIME:
1019 proto_tree_add_text(tree, tvb, offset, 2, "Invalid block length, should be 2");
1022 case RTCP_XR_STATS_SUMRY:
1024 proto_tree_add_text(tree, tvb, offset, 2, "Invalid block length, should be 9");
1027 case RTCP_XR_VOIP_METRCS:
1029 proto_tree_add_text(tree, tvb, offset, 2, "Invalid block length, should be 8");
1039 dissect_rtcp_xr(tvbuff_t *tvb, packet_info *pinfo _U_, int offset, proto_tree *tree, gint packet_len)
1041 guint block_num = 1;
1043 /* Packet length should at least be 4 */
1044 if (packet_len < 4) {
1045 proto_tree_add_text(tree, tvb, offset, packet_len, "Missing Sender SSRC");
1046 return offset + packet_len;
1050 proto_tree_add_item( tree, hf_rtcp_ssrc_sender, tvb, offset, 4, FALSE );
1054 for(;packet_len > 0; block_num++) {
1055 guint block_type = tvb_get_guint8(tvb, offset), block_length = 0;
1056 gint content_length = 0;
1057 gboolean valid = TRUE;
1059 /* Create a subtree for this block, dont know the length yet*/
1060 proto_item *block = proto_tree_add_text(tree, tvb, offset, -1, "Block %u", block_num);
1061 proto_tree *xr_block_tree = proto_item_add_subtree(block, ett_xr_block);
1062 proto_item *contents = NULL;
1063 proto_item *content_tree = NULL;
1065 proto_tree_add_item(xr_block_tree, hf_rtcp_xr_block_type, tvb, offset, 1, FALSE);
1067 if (packet_len >= 2) {
1068 parse_xr_type_specific_field(tvb, offset + 1, block_type, xr_block_tree);
1069 if (packet_len >= 4) {
1070 block_length = tvb_get_ntohs(tvb, offset + 2);
1071 valid = validate_xr_block_length(tvb, offset + 2, block_type, block_length, xr_block_tree);
1074 proto_tree_add_text(xr_block_tree, tvb, offset + 1, packet_len, "Missing Required Block Headers");
1075 return offset + packet_len;
1078 content_length = block_length * 4;
1079 proto_item_set_len(block, content_length + 4);
1081 if (content_length > packet_len) {
1082 proto_tree_add_text(xr_block_tree, tvb, offset + 2, 2, "Block length is greater than packet length");
1088 contents = proto_tree_add_text(xr_block_tree, tvb, offset, content_length, "Contents");
1089 content_tree = proto_item_add_subtree(contents, ett_xr_block_contents);
1091 switch (block_type) {
1092 case RTCP_XR_VOIP_METRCS: {
1093 guint fraction_rate, value;
1096 proto_tree_add_item(content_tree, hf_rtcp_ssrc_source, tvb, offset, 4, FALSE);
1100 fraction_rate = tvb_get_guint8(tvb, offset);
1101 proto_tree_add_uint_format(content_tree, hf_rtcp_ssrc_fraction, tvb, offset, 1,
1102 fraction_rate, "Fraction lost: %u / 256", fraction_rate);
1106 fraction_rate = tvb_get_guint8(tvb, offset);
1107 proto_tree_add_uint_format(content_tree, hf_rtcp_ssrc_discarded, tvb, offset, 1,
1108 fraction_rate, "Fraction Discarded: %u / 256", fraction_rate);
1112 proto_tree_add_item(content_tree, hf_rtcp_xr_voip_metrics_burst_density, tvb, offset, 1, FALSE);
1116 proto_tree_add_item(content_tree, hf_rtcp_xr_voip_metrics_gap_density, tvb, offset, 1, FALSE);
1119 /* Burst Duration */
1120 proto_tree_add_item(content_tree, hf_rtcp_xr_voip_metrics_burst_duration, tvb, offset, 2, FALSE);
1124 proto_tree_add_item(content_tree, hf_rtcp_xr_voip_metrics_gap_duration, tvb, offset, 2, FALSE);
1127 /* Round Trip Delay */
1128 proto_tree_add_item(content_tree, hf_rtcp_xr_voip_metrics_rtdelay, tvb, offset, 2, FALSE);
1131 /* End System Delay */
1132 proto_tree_add_item(content_tree, hf_rtcp_xr_voip_metrics_esdelay, tvb, offset, 2, FALSE);
1136 proto_tree_add_item(content_tree, hf_rtcp_xr_voip_metrics_siglevel, tvb, offset, 1, FALSE);
1140 proto_tree_add_item(content_tree, hf_rtcp_xr_voip_metrics_noiselevel, tvb, offset, 1, FALSE);
1144 proto_tree_add_item(content_tree, hf_rtcp_xr_voip_metrics_rerl, tvb, offset, 1, FALSE);
1148 proto_tree_add_item(content_tree, hf_rtcp_xr_voip_metrics_gmin, tvb, offset, 1, FALSE);
1152 proto_tree_add_item(content_tree, hf_rtcp_xr_voip_metrics_rfactor, tvb, offset, 1, FALSE);
1155 /* external R Factor */
1156 proto_tree_add_item(content_tree, hf_rtcp_xr_voip_metrics_extrfactor, tvb, offset, 1, FALSE);
1160 proto_tree_add_float(content_tree, hf_rtcp_xr_voip_metrics_moslq, tvb, offset, 1,
1161 (gfloat)tvb_get_guint8(tvb, offset) / 10);
1165 proto_tree_add_float(content_tree, hf_rtcp_xr_voip_metrics_moscq, tvb, offset, 1,
1166 (gfloat)tvb_get_guint8(tvb, offset) / 10);
1169 /* PLC, JB Adaptive, JB Rate */
1170 value = tvb_get_guint8(tvb, offset);
1171 proto_tree_add_uint(content_tree, hf_rtcp_xr_voip_metrics_plc, tvb, offset, 1, value);
1172 proto_tree_add_uint(content_tree, hf_rtcp_xr_voip_metrics_jbadaptive, tvb, offset, 1, value);
1173 proto_tree_add_uint(content_tree, hf_rtcp_xr_voip_metrics_jbrate, tvb, offset, 1, value);
1174 offset += 2; /* skip over reseved bit */
1177 proto_tree_add_item(content_tree, hf_rtcp_xr_voip_metrics_jbnominal, tvb, offset, 2, FALSE);
1181 proto_tree_add_item(content_tree, hf_rtcp_xr_voip_metrics_jbmax, tvb, offset, 2, FALSE);
1185 proto_tree_add_item(content_tree, hf_rtcp_xr_voip_metrics_jbabsmax, tvb, offset, 2, FALSE);
1191 case RTCP_XR_STATS_SUMRY: {
1193 proto_tree_add_item(content_tree, hf_rtcp_ssrc_source, tvb, offset, 4, FALSE);
1197 proto_tree_add_item(content_tree, hf_rtcp_xr_beginseq, tvb, offset, 2, FALSE);
1201 proto_tree_add_item(content_tree, hf_rtcp_xr_endseq, tvb, offset, 2, FALSE);
1205 proto_tree_add_item(content_tree, hf_rtcp_xr_stats_lost, tvb, offset, 4, FALSE);
1209 proto_tree_add_item(content_tree, hf_rtcp_xr_stats_dups, tvb, offset, 4, FALSE);
1213 proto_tree_add_item(content_tree, hf_rtcp_xr_stats_minjitter, tvb, offset, 4, FALSE);
1217 proto_tree_add_item(content_tree, hf_rtcp_xr_stats_maxjitter, tvb, offset, 4, FALSE);
1221 proto_tree_add_item(content_tree, hf_rtcp_xr_stats_meanjitter, tvb, offset, 4, FALSE);
1225 proto_tree_add_item(content_tree, hf_rtcp_xr_stats_devjitter, tvb, offset, 4, FALSE);
1229 proto_tree_add_item(content_tree, hf_rtcp_xr_stats_minttl, tvb, offset, 1, FALSE);
1233 proto_tree_add_item(content_tree, hf_rtcp_xr_stats_maxttl, tvb, offset, 1, FALSE);
1237 proto_tree_add_item(content_tree, hf_rtcp_xr_stats_meanttl, tvb, offset, 1, FALSE);
1241 proto_tree_add_item(content_tree, hf_rtcp_xr_stats_devttl, tvb, offset, 1, FALSE);
1247 case RTCP_XR_REF_TIME: {
1248 guint32 ts_msw, ts_lsw;
1250 ts_msw = tvb_get_ntohl(tvb, offset);
1251 proto_tree_add_text(content_tree, tvb, offset, 4, "Timestamp, MSW: %u", ts_msw);
1253 ts_lsw = tvb_get_ntohl(tvb, offset);
1254 proto_tree_add_text(content_tree, tvb, offset, 4, "Timestamp, LSW: %u", ts_lsw);
1260 case RTCP_XR_DLRR: {
1261 /* Each report block is 12 bytes */
1262 gint sources = content_length / 12;
1264 for(counter = 0; counter < sources; counter++) {
1265 /* Create a new subtree for a length of 12 bytes */
1266 proto_tree *ti = proto_tree_add_text(content_tree, tvb, offset, 12, "Source %u", counter + 1);
1267 proto_tree *ssrc_tree = proto_item_add_subtree(ti, ett_xr_ssrc);
1269 /* SSRC_n source identifier, 32 bits */
1270 proto_tree_add_item(ssrc_tree, hf_rtcp_ssrc_source, tvb, offset, 4, FALSE);
1273 /* Last RR timestamp */
1274 proto_tree_add_item(ssrc_tree, hf_rtcp_xr_lrr, tvb, offset, 4, FALSE);
1277 /* Delay since last RR timestamp */
1278 proto_tree_add_item(ssrc_tree, hf_rtcp_xr_dlrr, tvb, offset, 4, FALSE);
1282 if (content_length % 12 != 0)
1283 offset += content_length % 12;
1287 case RTCP_XR_PKT_RXTIMES: {
1288 /* 8 bytes of fixed header */
1289 gint count = 0, skip = 8;
1293 proto_tree_add_item(content_tree, hf_rtcp_ssrc_source, tvb, offset, 4, FALSE);
1297 begin = tvb_get_ntohs(tvb, offset);
1298 proto_tree_add_uint(content_tree, hf_rtcp_xr_beginseq, tvb, offset, 2, begin);
1302 proto_tree_add_item(content_tree, hf_rtcp_xr_endseq, tvb, offset, 2, FALSE);
1305 for(count = 0; skip < content_length; skip += 4, count++) {
1306 proto_tree_add_text(content_tree, tvb, offset, 4, "Seq: %u, Timestamp: %u",
1307 (begin + count) % 65536, FALSE);
1313 case RTCP_XR_LOSS_RLE:
1314 case RTCP_XR_DUP_RLE: {
1315 /* 8 bytes of fixed header */
1316 gint count = 0, skip = 8;
1318 proto_item *chunks_item;
1319 proto_tree *chunks_tree;
1322 proto_tree_add_item(content_tree, hf_rtcp_ssrc_source, tvb, offset, 4, FALSE);
1326 begin = tvb_get_ntohs(tvb, offset);
1327 proto_tree_add_uint(content_tree, hf_rtcp_xr_beginseq, tvb, offset, 2, begin);
1331 proto_tree_add_item(content_tree, hf_rtcp_xr_endseq, tvb, offset, 2, FALSE);
1335 chunks_item = proto_tree_add_text(content_tree, tvb, offset, content_length,"Report Chunks");
1336 chunks_tree = proto_item_add_subtree(chunks_item, ett_xr_loss_chunk);
1338 for(count = 1; skip < content_length; skip += 2, count++) {
1339 guint value = tvb_get_ntohs(tvb, offset);
1342 proto_tree_add_text(chunks_tree, tvb, offset, 2,
1343 "Chunk: %u -- Null Terminator ",
1345 } else if ( ! ( value & 0x8000 )) {
1346 const gchar* run_type = (value & 0x4000) ? "1s" : "0s";
1348 proto_tree_add_text(chunks_tree, tvb, offset, 2,
1349 "Chunk: %u -- Length Run %s, length: %u",
1350 count, run_type, value);
1353 other_decode_bitfield_value(bits, value, 0x00007FFF, 16);
1354 proto_tree_add_text(chunks_tree, tvb, offset, 2,
1355 "Chunk: %u -- Bit Vector, bits: %s",
1365 /* skip over the unknown block */
1366 offset += content_length;
1369 packet_len -= content_length;
1375 dissect_rtcp_rr( packet_info *pinfo, tvbuff_t *tvb, int offset, proto_tree *tree,
1376 unsigned int count )
1378 unsigned int counter = 1;
1379 proto_tree *ssrc_tree = (proto_tree*) NULL;
1380 proto_tree *ssrc_sub_tree = (proto_tree*) NULL;
1381 proto_tree *high_sec_tree = (proto_tree*) NULL;
1382 proto_item *ti = (proto_item*) NULL;
1384 unsigned int cum_nr = 0;
1386 while ( counter <= count ) {
1389 /* Create a new subtree for a length of 24 bytes */
1390 ti = proto_tree_add_text(tree, tvb, offset, 24,
1391 "Source %u", counter );
1392 ssrc_tree = proto_item_add_subtree( ti, ett_ssrc );
1394 /* SSRC_n source identifier, 32 bits */
1395 proto_tree_add_item( ssrc_tree, hf_rtcp_ssrc_source, tvb, offset, 4, FALSE );
1398 ti = proto_tree_add_text(ssrc_tree, tvb, offset, 20, "SSRC contents" );
1399 ssrc_sub_tree = proto_item_add_subtree( ti, ett_ssrc_item );
1401 /* Fraction lost, 8bits */
1402 rr_flt = tvb_get_guint8( tvb, offset );
1403 proto_tree_add_uint_format( ssrc_sub_tree, hf_rtcp_ssrc_fraction, tvb,
1404 offset, 1, rr_flt, "Fraction lost: %u / 256", rr_flt );
1407 /* Cumulative number of packets lost, 24 bits */
1408 cum_nr = tvb_get_ntohl( tvb, offset ) >> 8;
1409 proto_tree_add_uint( ssrc_sub_tree, hf_rtcp_ssrc_cum_nr, tvb,
1410 offset, 3, cum_nr );
1413 /* Extended highest sequence nr received, 32 bits
1414 * Just for the sake of it, let's add another subtree
1415 * because this might be a little clearer
1417 ti = proto_tree_add_uint( ssrc_tree, hf_rtcp_ssrc_ext_high_seq,
1418 tvb, offset, 4, tvb_get_ntohl( tvb, offset ) );
1419 high_sec_tree = proto_item_add_subtree( ti, ett_ssrc_ext_high );
1420 /* Sequence number cycles */
1421 proto_tree_add_item( high_sec_tree, hf_rtcp_ssrc_high_cycles,
1422 tvb, offset, 2, FALSE );
1424 /* highest sequence number received */
1425 proto_tree_add_item( high_sec_tree, hf_rtcp_ssrc_high_seq,
1426 tvb, offset, 2, FALSE );
1429 /* Interarrival jitter */
1430 proto_tree_add_item( ssrc_tree, hf_rtcp_ssrc_jitter, tvb,
1434 /* Last SR timestamp */
1435 lsr = tvb_get_ntohl( tvb, offset );
1436 proto_tree_add_uint( ssrc_tree, hf_rtcp_ssrc_lsr, tvb,
1440 /* Delay since last SR timestamp */
1441 dlsr = tvb_get_ntohl( tvb, offset );
1442 proto_tree_add_uint( ssrc_tree, hf_rtcp_ssrc_dlsr, tvb,
1446 /* Do roundtrip calculation */
1447 if (global_rtcp_show_roundtrip_calculation)
1449 /* Based on delay since SR was sent in other direction */
1450 calculate_roundtrip_delay(tvb, pinfo, ssrc_tree, lsr, dlsr);
1460 dissect_rtcp_sr( packet_info *pinfo, tvbuff_t *tvb, int offset, proto_tree *tree,
1461 unsigned int count )
1464 guint32 ts_msw, ts_lsw;
1468 ts_msw = tvb_get_ntohl(tvb, offset);
1469 proto_tree_add_item(tree, hf_rtcp_ntp_msw, tvb, offset, 4, FALSE);
1471 ts_lsw = tvb_get_ntohl(tvb, offset+4);
1472 proto_tree_add_item(tree, hf_rtcp_ntp_lsw, tvb, offset+4, 4, FALSE);
1474 buff=ntp_fmt_ts(tvb_get_ptr( tvb, offset, 8 ));
1475 item = proto_tree_add_string_format( tree, hf_rtcp_ntp, tvb, offset, 8, ( const char* ) buff, "MSW and LSW as NTP timestamp: %s", buff );
1476 PROTO_ITEM_SET_GENERATED(item);
1479 /* RTP timestamp, 32 bits */
1480 proto_tree_add_uint( tree, hf_rtcp_rtp_timestamp, tvb, offset, 4, tvb_get_ntohl( tvb, offset ) );
1482 /* Sender's packet count, 32 bits */
1483 proto_tree_add_uint( tree, hf_rtcp_sender_pkt_cnt, tvb, offset, 4, tvb_get_ntohl( tvb, offset ) );
1485 /* Sender's octet count, 32 bits */
1486 proto_tree_add_uint( tree, hf_rtcp_sender_oct_cnt, tvb, offset, 4, tvb_get_ntohl( tvb, offset ) );
1489 /* Record the time of this packet in the sender's conversation */
1490 if (global_rtcp_show_roundtrip_calculation)
1492 /* Use middle 32 bits of 64-bit time value */
1493 guint32 lsr = ((ts_msw & 0x0000ffff) << 16 | (ts_lsw & 0xffff0000) >> 16);
1495 /* Record the time that we sent this in appropriate conversation */
1496 remember_outgoing_sr(pinfo, lsr);
1499 /* The rest of the packet is equal to the RR packet */
1501 offset = dissect_rtcp_rr( pinfo, tvb, offset, tree, count );
1506 /* Look for conversation info and display any setup info found */
1507 void show_setup_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1509 /* Conversation and current data */
1510 conversation_t *p_conv = NULL;
1511 struct _rtcp_conversation_info *p_conv_data = NULL;
1513 /* Use existing packet data if available */
1514 p_conv_data = p_get_proto_data(pinfo->fd, proto_rtcp);
1518 /* First time, get info from conversation */
1519 p_conv = find_conversation(pinfo->fd->num, &pinfo->net_dst, &pinfo->net_src,
1521 pinfo->destport, pinfo->srcport, NO_ADDR_B);
1525 /* Look for data in conversation */
1526 struct _rtcp_conversation_info *p_conv_packet_data;
1527 p_conv_data = conversation_get_proto_data(p_conv, proto_rtcp);
1531 /* Save this conversation info into packet info */
1532 p_conv_packet_data = se_alloc(sizeof(struct _rtcp_conversation_info));
1533 if (!p_conv_packet_data)
1537 memcpy(p_conv_packet_data, p_conv_data,
1538 sizeof(struct _rtcp_conversation_info));
1540 p_add_proto_data(pinfo->fd, proto_rtcp, p_conv_packet_data);
1545 /* Create setup info subtree with summary info. */
1546 if (p_conv_data && p_conv_data->setup_method_set)
1548 proto_tree *rtcp_setup_tree;
1549 proto_item *ti = proto_tree_add_string_format(tree, hf_rtcp_setup, tvb, 0, 0,
1551 "Stream setup by %s (frame %u)",
1552 p_conv_data->setup_method,
1553 p_conv_data->setup_frame_number);
1554 PROTO_ITEM_SET_GENERATED(ti);
1555 rtcp_setup_tree = proto_item_add_subtree(ti, ett_rtcp_setup);
1556 if (rtcp_setup_tree)
1558 /* Add details into subtree */
1559 proto_item* item = proto_tree_add_uint(rtcp_setup_tree, hf_rtcp_setup_frame,
1560 tvb, 0, 0, p_conv_data->setup_frame_number);
1561 PROTO_ITEM_SET_GENERATED(item);
1562 item = proto_tree_add_string(rtcp_setup_tree, hf_rtcp_setup_method,
1563 tvb, 0, 0, p_conv_data->setup_method);
1564 PROTO_ITEM_SET_GENERATED(item);
1570 /* Update conversation data to record time that outgoing rr/sr was sent */
1571 static void remember_outgoing_sr(packet_info *pinfo, long lsr)
1573 conversation_t *p_conv = NULL;
1574 struct _rtcp_conversation_info *p_conv_data = NULL;
1575 struct _rtcp_conversation_info *p_packet_data = NULL;
1577 /* This information will be accessed when an incoming packet comes back to
1578 the side that sent this packet, so no use storing in the packet
1579 info. However, do store the fact that we've already set this info
1583 /**************************************************************************/
1584 /* First of all, see if we've already stored this information for this sr */
1586 /* Look first in packet info */
1587 p_packet_data = p_get_proto_data(pinfo->fd, proto_rtcp);
1588 if (p_packet_data && p_packet_data->last_received_set &&
1589 p_packet_data->last_received_frame_number >= pinfo->fd->num)
1591 /* We already did this, OK */
1596 /**************************************************************************/
1597 /* Otherwise, we want to find/create the conversation and update it */
1599 /* First time, get info from conversation.
1600 Even though we think of this as an outgoing packet being sent,
1601 we store the time as being received by the destination. */
1602 p_conv = find_conversation(pinfo->fd->num, &pinfo->net_dst, &pinfo->net_src,
1604 pinfo->destport, pinfo->srcport, NO_ADDR_B);
1606 /* If the conversation doesn't exist, create it now. */
1609 p_conv = conversation_new(pinfo->fd->num, &pinfo->net_dst, &pinfo->net_src, PT_UDP,
1610 pinfo->destport, pinfo->srcport,
1614 /* Give up if can't create it */
1620 /****************************************************/
1621 /* Now find/create conversation data */
1622 p_conv_data = conversation_get_proto_data(p_conv, proto_rtcp);
1625 /* Allocate memory for data */
1626 p_conv_data = se_alloc(sizeof(struct _rtcp_conversation_info));
1629 /* Give up if couldn't allocate space for memory */
1632 memset(p_conv_data, 0, sizeof(struct _rtcp_conversation_info));
1634 /* Add it to conversation. */
1635 conversation_add_proto_data(p_conv, proto_rtcp, p_conv_data);
1638 /*******************************************************/
1639 /* Update conversation data */
1640 p_conv_data->last_received_set = TRUE;
1641 p_conv_data->last_received_frame_number = pinfo->fd->num;
1642 p_conv_data->last_received_timestamp = pinfo->fd->abs_ts;
1643 p_conv_data->last_received_ts = lsr;
1646 /****************************************************************/
1647 /* Update packet info to record conversation state */
1649 /* Will use/create packet info */
1652 p_packet_data = se_alloc(sizeof(struct _rtcp_conversation_info));
1655 /* Give up if allocation fails */
1658 memset(p_packet_data, 0, sizeof(struct _rtcp_conversation_info));
1660 p_add_proto_data(pinfo->fd, proto_rtcp, p_packet_data);
1663 /* Copy current conversation data into packet info */
1664 p_packet_data->last_received_set = TRUE;
1665 p_packet_data->last_received_frame_number = p_conv_data->last_received_frame_number;
1666 p_packet_data->last_received_timestamp = p_conv_data->last_received_timestamp;
1670 /* Use received sr to work out what the roundtrip delay is
1671 (at least between capture point and the other endpoint involved in
1672 the conversation) */
1673 static void calculate_roundtrip_delay(tvbuff_t *tvb, packet_info *pinfo,
1674 proto_tree *tree, guint32 lsr, guint32 dlsr)
1676 /*****************************************************/
1677 /* This is called dissecting an SR. We need to:
1678 - look in the packet info for stored calculation. If found, use.
1679 - look up the conversation of the sending side to see when the
1680 'last SR' was detected (received)
1681 - calculate the network delay using the that packet time,
1682 this packet time, and dlsr
1683 *****************************************************/
1685 conversation_t *p_conv = NULL;
1686 struct _rtcp_conversation_info *p_conv_data = NULL;
1687 struct _rtcp_conversation_info *p_packet_data = NULL;
1690 /*************************************************/
1691 /* Look for previous result */
1692 p_packet_data = p_get_proto_data(pinfo->fd, proto_rtcp);
1693 if (p_packet_data && p_packet_data->lsr_matched)
1696 add_roundtrip_delay_info(tvb, pinfo, tree,
1697 p_packet_data->calculated_delay_used_frame,
1698 p_packet_data->calculated_delay);
1703 /********************************************************************/
1704 /* Look for captured timestamp of last SR in conversation of sender */
1705 /* of this packet */
1706 p_conv = find_conversation(pinfo->fd->num, &pinfo->net_src, &pinfo->net_dst,
1708 pinfo->srcport, pinfo->destport, NO_ADDR_B);
1714 /* Look for conversation data */
1715 p_conv_data = conversation_get_proto_data(p_conv, proto_rtcp);
1721 if (p_conv_data->last_received_set)
1723 /* Store result of calculation in packet info */
1726 /* Create packet info if it doesn't exist */
1727 p_packet_data = se_alloc(sizeof(struct _rtcp_conversation_info));
1730 /* Give up if allocation fails */
1734 memset(p_packet_data, 0, sizeof(struct _rtcp_conversation_info));
1736 /* Set as packet info */
1737 p_add_proto_data(pinfo->fd, proto_rtcp, p_packet_data);
1740 /* Don't allow match seemingly calculated from same frame! */
1741 if (pinfo->fd->num == p_conv_data->last_received_frame_number)
1746 /* Any previous report must match the lsr given here */
1747 if (p_conv_data->last_received_ts == lsr)
1749 /* Look at time of since original packet was sent */
1750 gint seconds_between_packets =
1751 pinfo->fd->abs_ts.secs - p_conv_data->last_received_timestamp.secs;
1752 gint nseconds_between_packets =
1753 pinfo->fd->abs_ts.nsecs - p_conv_data->last_received_timestamp.nsecs;
1755 gint total_gap = (seconds_between_packets*1000) +
1756 (nseconds_between_packets / 1000000);
1757 gint delay = total_gap - (int)(((double)dlsr/(double)65536) * 1000.0);
1759 /* Record that the LSR matches */
1760 p_packet_data->lsr_matched = TRUE;
1762 /* No useful calculation can be done if dlsr not set... */
1765 p_packet_data->calculated_delay = delay;
1766 p_packet_data->calculated_delay_used_frame = p_conv_data->last_received_frame_number;
1770 add_roundtrip_delay_info(tvb, pinfo, tree, p_conv_data->last_received_frame_number, delay);
1775 /* Show the calcaulted roundtrip delay info by adding protocol tree items
1776 and appending text to the info column */
1777 static void add_roundtrip_delay_info(tvbuff_t *tvb, packet_info *pinfo,
1778 proto_tree *tree, guint frame, guint delay)
1780 /* 'Last SR' frame used in calculation. Show this even if no delay shown */
1781 proto_item* item = proto_tree_add_uint(tree,
1782 hf_rtcp_last_sr_timestamp_frame,
1784 PROTO_ITEM_SET_GENERATED(item);
1786 /* Don't report on calculated delays below the threshold.
1787 Won't report a delay of 0 (which also indicates no valid
1788 calculated value to report) */
1789 if (delay < global_rtcp_show_roundtrip_calculation_minimum)
1794 /* Calculated delay in ms */
1795 item = proto_tree_add_uint(tree, hf_rtcp_roundtrip_delay, tvb, 0, 0, delay);
1796 PROTO_ITEM_SET_GENERATED(item);
1798 /* Report delay in INFO column */
1799 if (check_col(pinfo->cinfo, COL_INFO))
1803 col_append_fstr(pinfo->cinfo, COL_INFO,
1804 " (roundtrip delay <-> %s = %ums, using frame %u)",
1805 address_to_str(&pinfo->net_src), delay, frame);
1813 dissect_rtcp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree )
1815 proto_item *ti = NULL;
1816 proto_tree *rtcp_tree = NULL;
1817 unsigned int temp_byte = 0;
1818 unsigned int padding_set = 0;
1819 unsigned int elem_count = 0;
1820 unsigned int packet_type = 0;
1821 unsigned int offset = 0;
1822 guint16 packet_length = 0;
1823 guint rtcp_subtype = 0;
1824 guint32 app_length = 0;
1826 if ( check_col( pinfo->cinfo, COL_PROTOCOL ) ) {
1827 col_set_str( pinfo->cinfo, COL_PROTOCOL, "RTCP" );
1830 if ( check_col( pinfo->cinfo, COL_INFO) ) {
1831 /* The second octet contains the packet type */
1832 /* switch ( pd[ offset + 1 ] ) { */
1833 switch ( tvb_get_guint8( tvb, 1 ) ) {
1835 col_set_str( pinfo->cinfo, COL_INFO, "Sender Report");
1838 col_set_str( pinfo->cinfo, COL_INFO, "Receiver Report");
1841 col_set_str( pinfo->cinfo, COL_INFO, "Source Description");
1844 col_set_str( pinfo->cinfo, COL_INFO, "Goodbye");
1847 col_set_str( pinfo->cinfo, COL_INFO, "Application defined");
1850 col_set_str( pinfo->cinfo, COL_INFO, "Extended report");
1853 col_set_str( pinfo->cinfo, COL_INFO, "Full Intra-frame Request (H.261)");
1856 col_set_str( pinfo->cinfo, COL_INFO, "Negative Acknowledgement (H.261)");
1859 col_set_str( pinfo->cinfo, COL_INFO, "Unknown packet type");
1865 * Check if there are at least 4 bytes left in the frame,
1866 * the last 16 bits of those is the length of the current
1867 * RTCP message. The last compound message contains padding,
1868 * that enables us to break from the while loop.
1870 while ( tvb_bytes_exist( tvb, offset, 4) ) {
1872 * First retreive the packet_type
1874 packet_type = tvb_get_guint8( tvb, offset + 1 );
1877 * Check if it's a valid type
1879 if ( ( packet_type < 192 ) || ( packet_type > 207 ) )
1883 * get the packet-length for the complete RTCP packet
1885 packet_length = ( tvb_get_ntohs( tvb, offset + 2 ) + 1 ) * 4;
1887 ti = proto_tree_add_item(tree, proto_rtcp, tvb, offset, packet_length, FALSE );
1888 proto_item_append_text(ti, " (%s)",
1889 val_to_str(packet_type,
1890 rtcp_packet_type_vals,
1893 rtcp_tree = proto_item_add_subtree( ti, ett_rtcp );
1895 /* Conversation setup info */
1896 if (global_rtcp_show_setup_info)
1898 show_setup_info(tvb, pinfo, rtcp_tree);
1902 temp_byte = tvb_get_guint8( tvb, offset );
1904 proto_tree_add_uint( rtcp_tree, hf_rtcp_version, tvb,
1905 offset, 1, temp_byte);
1906 padding_set = RTCP_PADDING( temp_byte );
1908 proto_tree_add_boolean( rtcp_tree, hf_rtcp_padding, tvb,
1909 offset, 1, temp_byte );
1910 elem_count = RTCP_COUNT( temp_byte );
1912 switch ( packet_type ) {
1915 /* Receiver report count, 5 bits */
1916 proto_tree_add_uint( rtcp_tree, hf_rtcp_rc, tvb, offset, 1, temp_byte );
1918 /* Packet type, 8 bits */
1919 proto_tree_add_item( rtcp_tree, hf_rtcp_pt, tvb, offset, 1, FALSE );
1921 /* Packet length in 32 bit words MINUS one, 16 bits */
1922 proto_tree_add_uint( rtcp_tree, hf_rtcp_length, tvb, offset, 2, tvb_get_ntohs( tvb, offset ) );
1924 /* Sender Synchronization source, 32 bits */
1925 proto_tree_add_uint( rtcp_tree, hf_rtcp_ssrc_sender, tvb, offset, 4, tvb_get_ntohl( tvb, offset ) );
1928 if ( packet_type == RTCP_SR ) offset = dissect_rtcp_sr( pinfo, tvb, offset, rtcp_tree, elem_count );
1929 else offset = dissect_rtcp_rr( pinfo, tvb, offset, rtcp_tree, elem_count );
1932 /* Source count, 5 bits */
1933 proto_tree_add_uint( rtcp_tree, hf_rtcp_sc, tvb, offset, 1, temp_byte );
1935 /* Packet type, 8 bits */
1936 proto_tree_add_item( rtcp_tree, hf_rtcp_pt, tvb, offset, 1, FALSE );
1938 /* Packet length in 32 bit words MINUS one, 16 bits */
1939 proto_tree_add_uint( rtcp_tree, hf_rtcp_length, tvb, offset, 2, tvb_get_ntohs( tvb, offset ) );
1941 dissect_rtcp_sdes( tvb, offset, rtcp_tree, elem_count );
1942 offset += packet_length - 4;
1945 /* Source count, 5 bits */
1946 proto_tree_add_uint( rtcp_tree, hf_rtcp_sc, tvb, offset, 1, temp_byte );
1948 /* Packet type, 8 bits */
1949 proto_tree_add_item( rtcp_tree, hf_rtcp_pt, tvb, offset, 1, FALSE );
1951 /* Packet length in 32 bit words MINUS one, 16 bits */
1952 proto_tree_add_uint( rtcp_tree, hf_rtcp_length, tvb, offset, 2, tvb_get_ntohs( tvb, offset ) );
1954 offset = dissect_rtcp_bye( tvb, offset, rtcp_tree, elem_count );
1957 /* Subtype, 5 bits */
1958 rtcp_subtype = elem_count;
1959 proto_tree_add_uint( rtcp_tree, hf_rtcp_subtype, tvb, offset, 1, elem_count );
1961 /* Packet type, 8 bits */
1962 proto_tree_add_item( rtcp_tree, hf_rtcp_pt, tvb, offset, 1, FALSE );
1964 /* Packet length in 32 bit words MINUS one, 16 bits */
1965 app_length = tvb_get_ntohs( tvb, offset ) <<2;
1966 proto_tree_add_uint( rtcp_tree, hf_rtcp_length, tvb, offset, 2, app_length );
1968 offset = dissect_rtcp_app( tvb, pinfo, offset,rtcp_tree, padding_set, packet_length - 4, rtcp_subtype, app_length);
1971 /* Reserved, 5 bits, Ignore */
1973 /* Packet type, 8 bits */
1974 proto_tree_add_item( rtcp_tree, hf_rtcp_pt, tvb, offset, 1, FALSE );
1976 /* Packet length in 32 bit words MINUS one, 16 bits */
1977 proto_tree_add_uint( rtcp_tree, hf_rtcp_length, tvb, offset, 2, tvb_get_ntohs( tvb, offset ) );
1979 offset = dissect_rtcp_xr( tvb, pinfo, offset, rtcp_tree, packet_length - 4 );
1982 offset = dissect_rtcp_fir( tvb, offset, rtcp_tree );
1985 offset = dissect_rtcp_nack( tvb, offset, rtcp_tree );
1989 * To prevent endless loops in case of an unknown message type
1990 * increase offset. Some time the while will end :-)
1996 /* If the padding bit is set, the last octet of the
1997 * packet contains the length of the padding
1998 * We only have to check for this at the end of the LAST RTCP message
2000 if ( padding_set ) {
2001 /* If everything went according to plan offset should now point to the
2002 * first octet of the padding
2004 proto_tree_add_item( rtcp_tree, hf_rtcp_padding_data, tvb, offset, tvb_length_remaining( tvb, offset) - 1, FALSE );
2005 offset += tvb_length_remaining( tvb, offset) - 1;
2006 proto_tree_add_item( rtcp_tree, hf_rtcp_padding_count, tvb, offset, 1, FALSE );
2011 proto_register_rtcp(void)
2013 static hf_register_info hf[] =
2022 VALS(rtcp_version_vals),
2042 "Reception report count",
2070 VALS( rtcp_packet_type_vals ),
2088 &hf_rtcp_ssrc_sender,
2103 "rtcp.timestamp.ntp.msw",
2115 "rtcp.timestamp.ntp.lsw",
2127 "rtcp.timestamp.ntp",
2136 &hf_rtcp_rtp_timestamp,
2139 "rtcp.timestamp.rtp",
2148 &hf_rtcp_sender_pkt_cnt,
2150 "Sender's packet count",
2151 "rtcp.sender.packetcount",
2160 &hf_rtcp_sender_oct_cnt,
2162 "Sender's octet count",
2163 "rtcp.sender.octetcount",
2172 &hf_rtcp_ssrc_source,
2175 "rtcp.ssrc.identifier",
2184 &hf_rtcp_ssrc_fraction,
2187 "rtcp.ssrc.fraction",
2196 &hf_rtcp_ssrc_cum_nr,
2198 "Cumulative number of packets lost",
2208 &hf_rtcp_ssrc_ext_high_seq,
2210 "Extended highest sequence number received",
2211 "rtcp.ssrc.ext_high",
2220 &hf_rtcp_ssrc_high_seq,
2222 "Highest sequence number received",
2223 "rtcp.ssrc.high_seq",
2232 &hf_rtcp_ssrc_high_cycles,
2234 "Sequence number cycles count",
2235 "rtcp.ssrc.high_cycles",
2244 &hf_rtcp_ssrc_jitter,
2246 "Interarrival jitter",
2258 "Last SR timestamp",
2270 "Delay since last SR timestamp",
2282 "SSRC / CSRC identifier",
2283 "rtcp.sdes.ssrc_csrc",
2298 VALS( rtcp_sdes_type_vals ),
2304 &hf_rtcp_sdes_length,
2328 &hf_rtcp_sdes_prefix_len,
2331 "rtcp.sdes.prefix.length",
2340 &hf_rtcp_sdes_prefix_string,
2343 "rtcp.sdes.prefix.string",
2364 &hf_rtcp_name_ascii,
2378 "Application specific data",
2388 &hf_rtcp_app_poc1_subtype,
2391 "rtcp.app.PoC1.subtype",
2394 VALS(rtcp_app_poc1_floor_cnt_type_vals),
2400 &hf_rtcp_app_poc1_sip_uri,
2403 "rtcp.app.poc1.sip.uri",
2412 &hf_rtcp_app_poc1_disp_name,
2415 "rtcp.app.poc1.disp.name",
2424 &hf_rtcp_app_poc1_stt,
2426 "Stop talking timer",
2427 "rtcp.app.poc1.stt",
2436 &hf_rtcp_app_poc1_partic,
2438 "Number of participants",
2439 "rtcp.app.poc1.participants",
2448 &hf_rtcp_app_poc1_ssrc_granted,
2450 "SSRC of client granted permission to talk",
2451 "rtcp.app.poc1.ssrc.granted",
2460 &hf_rtcp_app_poc1_last_pkt_seq_no,
2462 "Seq. no of last RTP packet",
2463 "rtcp.app.poc1.last.pkt.seq.no",
2472 &hf_rtcp_app_poc1_reason_code1,
2475 "rtcp.app.poc1.reason.code",
2478 VALS(rtcp_app_poc1_reason_code1_vals),
2484 &hf_rtcp_app_poc1_item_len,
2487 "rtcp.app.poc1.item.len",
2496 &hf_rtcp_app_poc1_reason1_phrase,
2499 "rtcp.app.poc1.reason.phrase",
2508 &hf_rtcp_app_poc1_reason_code2,
2511 "rtcp.app.poc1.reason.code",
2514 VALS(rtcp_app_poc1_reason_code2_vals),
2520 &hf_rtcp_app_poc1_additionalinfo,
2522 "additional information",
2523 "rtcp.app.poc1.add.info",
2532 &hf_rtcp_app_poc1_ack_subtype,
2535 "rtcp.app.poc1.ack.subtype",
2538 VALS(rtcp_app_poc1_floor_cnt_type_vals),
2544 &hf_rtcp_app_poc1_ack_reason_code,
2547 "rtcp.app.poc1.ack.reason.code",
2550 VALS(rtcp_app_poc1_reason_code_ack_vals),
2556 &hf_rtcp_app_poc1_qsresp_priority,
2559 "rtcp.app.poc1.qsresp.priority",
2562 VALS(rtcp_app_poc1_qsresp_priority_vals),
2568 &hf_rtcp_app_poc1_qsresp_position,
2571 "rtcp.app.poc1.qsresp.position",
2580 &hf_rtcp_app_poc1_conn_content_1st_byte[0],
2582 "Identity of inviting client",
2583 "rtcp.app.poc1.conn.content.a.id",
2592 &hf_rtcp_app_poc1_conn_content_1st_byte[1],
2594 "Nick name of inviting client",
2595 "rtcp.app.poc1.conn.content.a.dn",
2604 &hf_rtcp_app_poc1_conn_content_1st_byte[2],
2607 "rtcp.app.poc1.conn.content.sess.id",
2616 &hf_rtcp_app_poc1_conn_content_1st_byte[3],
2619 "rtcp.app.poc1.conn.content.grp.dn",
2628 &hf_rtcp_app_poc1_conn_content_1st_byte[4],
2631 "rtcp.app.poc1.conn.content.grp.id",
2640 &hf_rtcp_app_poc1_conn_session_type,
2643 "rtcp.app.poc1.conn.session.type",
2646 VALS(rtcp_app_poc1_conn_sess_type_vals),
2652 &hf_rtcp_app_poc1_conn_add_ind_mao,
2654 "Manual answer override",
2655 "rtcp.app.poc1.conn.add.ind.mao",
2664 &hf_rtcp_app_poc1_conn_sdes_items[0],
2666 "Identity of inviting client",
2667 "rtcp.app.poc1.conn.sdes.a.id",
2676 &hf_rtcp_app_poc1_conn_sdes_items[1],
2678 "Nick name of inviting client",
2679 "rtcp.app.poc1.conn.sdes.a.dn",
2688 &hf_rtcp_app_poc1_conn_sdes_items[2],
2691 "rtcp.app.poc1.conn.sdes.sess.id",
2700 &hf_rtcp_app_poc1_conn_sdes_items[3],
2703 "rtcp.app.poc1.conn.sdes.grp.dn",
2712 &hf_rtcp_app_poc1_conn_sdes_items[4],
2715 "rtcp.app.poc1.conn.sdes.grp.id",
2726 "First sequence number",
2738 "Bitmask of following lost packets",
2748 &hf_rtcp_padding_count,
2751 "rtcp.padding.count",
2760 &hf_rtcp_padding_data,
2763 "rtcp.padding.data",
2780 "Stream setup, method and frame number", HFILL
2784 &hf_rtcp_setup_frame,
2792 "Frame that set up this stream", HFILL
2796 &hf_rtcp_setup_method,
2799 "rtcp.setup-method",
2804 "Method used to set up this stream", HFILL
2808 &hf_rtcp_last_sr_timestamp_frame,
2810 "Frame matching Last SR timestamp",
2816 "Frame matching LSR field (used to calculate roundtrip delay)", HFILL
2820 &hf_rtcp_roundtrip_delay,
2822 "Roundtrip Delay(ms)",
2823 "rtcp.roundtrip-delay",
2828 "Calculated roundtrip delay in ms", HFILL
2832 &hf_rtcp_xr_block_type,
2838 VALS(rtcp_xr_type_vals),
2844 &hf_rtcp_xr_block_specific,
2856 &hf_rtcp_xr_block_length,
2864 "Block Length", HFILL
2868 &hf_rtcp_ssrc_discarded,
2870 "Fraction discarded",
2871 "rtcp.ssrc.discarded",
2876 "Discard Rate", HFILL
2880 &hf_rtcp_xr_voip_metrics_burst_density,
2883 "rtcp.xr.voipmetrics.burstdensity",
2892 &hf_rtcp_xr_voip_metrics_gap_density,
2895 "rtcp.xr.voipmetrics.gapdensity",
2904 &hf_rtcp_xr_voip_metrics_burst_duration,
2906 "Burst Duration(ms)",
2907 "rtcp.xr.voipmetrics.burstduration",
2916 &hf_rtcp_xr_voip_metrics_gap_duration,
2919 "rtcp.xr.voipmetrics.gapduration",
2928 &hf_rtcp_xr_voip_metrics_rtdelay,
2930 "Round Trip Delay(ms)",
2931 "rtcp.xr.voipmetrics.rtdelay",
2940 &hf_rtcp_xr_voip_metrics_esdelay,
2942 "End System Delay(ms)",
2943 "rtcp.xr.voipmetrics.esdelay",
2952 &hf_rtcp_xr_voip_metrics_siglevel,
2955 "rtcp.xr.voipmetrics.signallevel",
2960 "Signal level of 127 indicates this parameter is unavailable", HFILL
2964 &hf_rtcp_xr_voip_metrics_noiselevel,
2967 "rtcp.xr.voipmetrics.noiselevel",
2972 "Noise level of 127 indicates this parameter is unavailable", HFILL
2976 &hf_rtcp_xr_voip_metrics_rerl,
2978 "Residual Echo Return Loss",
2979 "rtcp.xr.voipmetrics.rerl",
2988 &hf_rtcp_xr_voip_metrics_gmin,
2991 "rtcp.xr.voipmetrics.gmin",
3000 &hf_rtcp_xr_voip_metrics_rfactor,
3003 "rtcp.xr.voipmetrics.rfactor",
3008 "R Factor is in the range of 0 to 100; 127 indicates this parameter is unavailable", HFILL
3012 &hf_rtcp_xr_voip_metrics_extrfactor,
3014 "External R Factor",
3015 "rtcp.xr.voipmetrics.extrfactor",
3020 "R Factor is in the range of 0 to 100; 127 indicates this parameter is unavailable", HFILL
3024 &hf_rtcp_xr_voip_metrics_moslq,
3026 "MOS - Listening Quality",
3027 "rtcp.xr.voipmetrics.moslq",
3032 "MOS is in the range of 1 to 5; 127 indicates this parameter is unavailable", HFILL
3036 &hf_rtcp_xr_voip_metrics_moscq,
3038 "MOS - Conversational Quality",
3039 "rtcp.xr.voipmetrics.moscq",
3044 "MOS is in the range of 1 to 5; 127 indicates this parameter is unavailable", HFILL
3048 &hf_rtcp_xr_voip_metrics_plc,
3050 "Packet Loss Conealment Algorithm",
3051 "rtcp.xr.voipmetrics.plc",
3054 VALS(rtcp_xr_plc_algo_vals),
3060 &hf_rtcp_xr_voip_metrics_jbadaptive,
3062 "Adaptive Jitter Buffer Algorithm",
3063 "rtcp.xr.voipmetrics.jba",
3066 VALS(rtcp_xr_jb_adaptive_vals),
3072 &hf_rtcp_xr_voip_metrics_jbrate,
3074 "Jitter Buffer Rate",
3075 "rtcp.xr.voipmetrics.jbrate",
3084 &hf_rtcp_xr_voip_metrics_jbnominal,
3086 "Nominal Jitter Buffer Size",
3087 "rtcp.xr.voipmetrics.jbnominal",
3096 &hf_rtcp_xr_voip_metrics_jbmax,
3098 "Maximum Jitter Buffer Size",
3099 "rtcp.xr.voipmetrics.jbmax",
3108 &hf_rtcp_xr_voip_metrics_jbabsmax,
3110 "Absolute Maximum Jitter Buffer Size",
3111 "rtcp.xr.voipmetrics.jbabsmax",
3120 &hf_rtcp_xr_thinning,
3132 &hf_rtcp_xr_stats_loss_flag,
3135 "rtcp.xr.stats.lrflag",
3144 &hf_rtcp_xr_stats_dup_flag,
3146 "Duplicates Report Flag",
3147 "rtcp.xr.stats.dupflag",
3156 &hf_rtcp_xr_stats_jitter_flag,
3158 "Jitter Report Flag",
3159 "rtcp.xr.stats.jitterflag",
3168 &hf_rtcp_xr_stats_ttl,
3170 "TTL or Hop Limit Flag",
3171 "rtcp.xr.stats.ttl",
3174 VALS(rtcp_xr_ip_ttl_vals),
3182 "End Sequence Number",
3192 &hf_rtcp_xr_beginseq,
3194 "Begin Sequence Number",
3204 &hf_rtcp_xr_stats_lost,
3207 "rtcp.xr.stats.lost",
3216 &hf_rtcp_xr_stats_dups,
3218 "Duplicate Packets",
3219 "rtcp.xr.stats.dups",
3228 &hf_rtcp_xr_stats_minjitter,
3231 "rtcp.xr.stats.minjitter",
3240 &hf_rtcp_xr_stats_maxjitter,
3243 "rtcp.xr.stats.maxjitter",
3252 &hf_rtcp_xr_stats_meanjitter,
3255 "rtcp.xr.stats.meanjitter",
3264 &hf_rtcp_xr_stats_devjitter,
3266 "Standard Deviation of Jitter",
3267 "rtcp.xr.stats.devjitter",
3276 &hf_rtcp_xr_stats_minttl,
3278 "Minimum TTL or Hop Limit",
3279 "rtcp.xr.stats.minttl",
3288 &hf_rtcp_xr_stats_maxttl,
3290 "Maximum TTL or Hop Limit",
3291 "rtcp.xr.stats.maxttl",
3300 &hf_rtcp_xr_stats_meanttl,
3302 "Mean TTL or Hop Limit",
3303 "rtcp.xr.stats.meanttl",
3312 &hf_rtcp_xr_stats_devttl,
3314 "Standard Deviation of TTL",
3315 "rtcp.xr.stats.devttl",
3326 "Last RR timestamp",
3338 "Delay since last RR timestamp",
3349 static gint *ett[] =
3359 &ett_rtcp_roundtrip_delay,
3361 &ett_xr_block_contents,
3364 &ett_poc1_conn_contents
3367 module_t *rtcp_module;
3369 proto_rtcp = proto_register_protocol("Real-time Transport Control Protocol",
3371 proto_register_field_array(proto_rtcp, hf, array_length(hf));
3372 proto_register_subtree_array(ett, array_length(ett));
3374 register_dissector("rtcp", dissect_rtcp, proto_rtcp);
3376 rtcp_module = prefs_register_protocol(proto_rtcp, NULL);
3378 prefs_register_bool_preference(rtcp_module, "show_setup_info",
3379 "Show stream setup information",
3380 "Where available, show which protocol and frame caused "
3381 "this RTCP stream to be created",
3382 &global_rtcp_show_setup_info);
3384 prefs_register_bool_preference(rtcp_module, "heuristic_rtcp",
3385 "Try to decode RTCP outside of conversations ",
3386 "If call control SIP/H.323/RTSP/.. messages are missing in the trace, "
3387 "RTCP isn't decoded without this",
3390 prefs_register_bool_preference(rtcp_module, "show_roundtrip_calculation",
3391 "Show relative roundtrip calculations",
3392 "Try to work out network delay by comparing time between packets "
3393 "as captured and delays as seen by endpoint",
3394 &global_rtcp_show_roundtrip_calculation);
3396 prefs_register_uint_preference(rtcp_module, "roundtrip_min_threshhold",
3397 "Minimum roundtrip calculations to report (ms)",
3398 "Minimum calculated roundtrip delay time in milliseconds that "
3399 "should be reported",
3400 MIN_ROUNDTRIP_TO_REPORT_DEFAULT, &global_rtcp_show_roundtrip_calculation_minimum);
3406 proto_reg_handoff_rtcp(void)
3409 * Register this dissector as one that can be selected by a
3412 rtcp_handle = find_dissector("rtcp");
3413 dissector_add_handle("udp.port", rtcp_handle);
3415 heur_dissector_add( "udp", dissect_rtcp_heur, proto_rtcp);