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 * Copyright 2010, Matteo Valdina <zanfire@gmail.com>
17 * Wireshark - Network traffic analyzer
18 * By Gerald Combs <gerald@wireshark.org>
19 * Copyright 1998 Gerald Combs
21 * This program is free software; you can redistribute it and/or
22 * modify it under the terms of the GNU General Public License
23 * as published by the Free Software Foundation; either version 2
24 * of the License, or (at your option) any later version.
26 * This program is distributed in the hope that it will be useful,
27 * but WITHOUT ANY WARRANTY; without even the implied warranty of
28 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29 * GNU General Public License for more details.
31 * You should have received a copy of the GNU General Public License
32 * along with this program; if not, write to the Free Software
33 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
37 * This dissector tries to dissect the RTCP protocol according to Annex A
38 * of ITU-T Recommendation H.225.0 (02/98) and RFC 1889
39 * H.225.0 literally copies RFC 1889, but omitting a few sections.
41 * RTCP traffic is handled by an uneven UDP portnumber. This can be any
42 * port number, but there is a registered port available, port 5005
43 * See Annex B of ITU-T Recommendation H.225.0, section B.7
45 * Information on PoC can be found from http://www.openmobilealliance.org/
47 * RTCP XR is specified in RFC 3611.
49 * See also http://www.iana.org/assignments/rtp-parameters
51 * RTCP FB is specified in RFC 4585 and extended by RFC 5104
61 #include <epan/packet.h>
66 #include "packet-rtcp.h"
67 #include "packet-rtp.h"
68 #include "packet-ntp.h"
69 #include <epan/conversation.h>
71 #include <epan/prefs.h>
72 #include <epan/emem.h>
73 #include <epan/expert.h>
74 #include <epan/strutil.h>
76 /* Version is the first 2 bits of the first octet*/
77 #define RTCP_VERSION(octet) ((octet) >> 6)
79 /* Padding is the third bit; no need to shift, because true is any value
81 #define RTCP_PADDING(octet) ((octet) & 0x20)
83 /* Receiver/ Sender count is the 5 last bits */
84 #define RTCP_COUNT(octet) ((octet) & 0x1F)
86 static dissector_handle_t rtcp_handle;
88 /* add dissector table to permit sub-protocol registration */
89 static dissector_table_t rtcp_dissector_table;
91 static const value_string rtcp_version_vals[] =
93 { 2, "RFC 1889 Version" },
94 { 0, "Old VAT Version" },
95 { 1, "First Draft Version" },
99 /* RTCP packet types according to Section A.11.1 */
100 /* And http://www.iana.org/assignments/rtp-parameters */
103 #define RTCP_SDES 202
106 #define RTCP_RTPFB 205
107 #define RTCP_PSFB 206
111 /* Supplemental H.261 specific RTCP packet types according to Section C.3.5 */
113 #define RTCP_NACK 193
114 #define RTCP_SMPTETC 194
117 static const value_string rtcp_packet_type_vals[] =
119 { RTCP_SR, "Sender Report" },
120 { RTCP_RR, "Receiver Report" },
121 { RTCP_SDES, "Source description" },
122 { RTCP_BYE, "Goodbye" },
123 { RTCP_APP, "Application specific" },
124 { RTCP_RTPFB,"Generic RTP Feedback" },
125 { RTCP_PSFB, "Payload-specific" },
126 { RTCP_XR, "Extended report (RFC 3611)"},
127 { RTCP_AVB, "AVB RTCP packet (IEEE1733)" },
128 { RTCP_RSI, "Receiver Summary Information" },
129 { RTCP_FIR, "Full Intra-frame Request (H.261)" },
130 { RTCP_NACK, "Negative Acknowledgement (H.261)" },
131 { RTCP_SMPTETC, "SMPTE time-code mapping" },
132 { RTCP_IJ, "Extended inter-arrival jitter report" },
136 /* RTCP SDES types (Section A.11.2) */
137 #define RTCP_SDES_END 0
138 #define RTCP_SDES_CNAME 1
139 #define RTCP_SDES_NAME 2
140 #define RTCP_SDES_EMAIL 3
141 #define RTCP_SDES_PHONE 4
142 #define RTCP_SDES_LOC 5
143 #define RTCP_SDES_TOOL 6
144 #define RTCP_SDES_NOTE 7
145 #define RTCP_SDES_PRIV 8
146 #define RTCP_SDES_H323_CADDR 9
148 static const value_string rtcp_sdes_type_vals[] =
150 { RTCP_SDES_END, "END" },
151 { RTCP_SDES_CNAME, "CNAME (user and domain)" },
152 { RTCP_SDES_NAME, "NAME (common name)" },
153 { RTCP_SDES_EMAIL, "EMAIL (e-mail address)" },
154 { RTCP_SDES_PHONE, "PHONE (phone number)" },
155 { RTCP_SDES_LOC, "LOC (geographic location)" },
156 { RTCP_SDES_TOOL, "TOOL (name/version of source app)" },
157 { RTCP_SDES_NOTE, "NOTE (note about source)" },
158 { RTCP_SDES_PRIV, "PRIV (private extensions)" },
159 { RTCP_SDES_H323_CADDR,"H323-CADDR (H.323 callable address)"},
163 /* RTCP XR Blocks (Section 4, RTC 3611)
164 * or http://www.iana.org/assignments/rtcp-xr-block-types */
165 #define RTCP_XR_LOSS_RLE 1
166 #define RTCP_XR_DUP_RLE 2
167 #define RTCP_XR_PKT_RXTIMES 3
168 #define RTCP_XR_REF_TIME 4
169 #define RTCP_XR_DLRR 5
170 #define RTCP_XR_STATS_SUMRY 6
171 #define RTCP_XR_VOIP_METRCS 7
172 #define RTCP_XR_BT_XNQ 8
173 #define RTCP_XR_TI_VOIP 9
174 #define RTCP_XR_PR_LOSS_RLE 10
175 #define RTCP_XR_MC_ACQ 11
177 static const value_string rtcp_xr_type_vals[] =
179 { RTCP_XR_LOSS_RLE, "Loss Run Length Encoding Report Block" },
180 { RTCP_XR_DUP_RLE, "Duplicate Run Length Encoding Report Block" },
181 { RTCP_XR_PKT_RXTIMES, "Packet Receipt Times Report Block" },
182 { RTCP_XR_REF_TIME, "Receiver Reference Time Report Block" },
183 { RTCP_XR_DLRR, "DLRR Report Block" },
184 { RTCP_XR_STATS_SUMRY, "Statistics Summary Report Block" },
185 { RTCP_XR_VOIP_METRCS, "VoIP Metrics Report Block" },
186 { RTCP_XR_BT_XNQ, "BT XNQ RTCP XR (RFC5093) Report Block" },
187 { RTCP_XR_TI_VOIP, "Texas Instruments Extended VoIP Quality Block" },
188 { RTCP_XR_PR_LOSS_RLE, "Post-repair Loss RLE Report Block" },
189 { RTCP_XR_MC_ACQ, "Multicast Acquisition Report Block" },
190 { 12, "Inter-destination Media Synchronization Block" }, /* [http://www.etsi.org/deliver/etsi_ts/183000_183099/183063/][ETSI 183 063][Miguel_Angel_Reina_Ortega] */
194 /* XR VoIP Metrics Block - PLC Algorithms */
195 static const value_string rtcp_xr_plc_algo_vals[] =
197 { 0, "Unspecified" },
204 /* XR VoIP Metrics Block - JB Adaptive */
205 static const value_string rtcp_xr_jb_adaptive_vals[] =
209 { 2, "Non-Adaptive" },
214 /* XR Stats Summary Block - IP TTL or Hop Limit */
215 static const value_string rtcp_xr_ip_ttl_vals[] =
217 { 0, "No TTL Values" },
224 /* RTCP Application PoC1 Value strings
225 * OMA-TS-PoC-UserPlane-V1_0-20060609-A
228 #define TBCP_BURST_REQUEST 0
229 #define TBCP_BURST_GRANTED 1
230 #define TBCP_BURST_TAKEN_EXPECT_NO_REPLY 2
231 #define TBCP_BURST_DENY 3
232 #define TBCP_BURST_RELEASE 4
233 #define TBCP_BURST_IDLE 5
234 #define TBCP_BURST_REVOKE 6
235 #define TBCP_BURST_ACKNOWLEDGMENT 7
236 #define TBCP_QUEUE_STATUS_REQUEST 8
237 #define TBCP_QUEUE_STATUS_RESPONSE 9
238 #define TBCP_DISCONNECT 11
239 #define TBCP_CONNECT 15
240 #define TBCP_BURST_TAKEN_EXPECT_REPLY 18
243 static const value_string rtcp_app_poc1_floor_cnt_type_vals[] =
245 { TBCP_BURST_REQUEST, "TBCP Talk Burst Request"},
246 { TBCP_BURST_GRANTED, "TBCP Talk Burst Granted"},
247 { TBCP_BURST_TAKEN_EXPECT_NO_REPLY, "TBCP Talk Burst Taken (no ack expected)"},
248 { TBCP_BURST_DENY, "TBCP Talk Burst Deny"},
249 { TBCP_BURST_RELEASE, "TBCP Talk Burst Release"},
250 { TBCP_BURST_IDLE, "TBCP Talk Burst Idle"},
251 { TBCP_BURST_REVOKE, "TBCP Talk Burst Revoke"},
252 { TBCP_BURST_ACKNOWLEDGMENT, "TBCP Talk Burst Acknowledgement"},
253 { TBCP_QUEUE_STATUS_REQUEST, "TBCP Queue Status Request"},
254 { TBCP_QUEUE_STATUS_RESPONSE, "TBCP Queue Status Response"},
255 { TBCP_DISCONNECT, "TBCP Disconnect"},
256 { TBCP_CONNECT, "TBCP Connect"},
257 { TBCP_BURST_TAKEN_EXPECT_REPLY, "TBCP Talk Burst Taken (ack expected)"},
261 static const value_string rtcp_app_poc1_reason_code1_vals[] =
263 { 1, "Another PoC User has permission"},
264 { 2, "Internal PoC server error"},
265 { 3, "Only one participant in the group"},
266 { 4, "Retry-after timer has not expired"},
271 static const value_string rtcp_app_poc1_reason_code2_vals[] =
273 { 1, "Only one user"},
274 { 2, "Talk burst too long"},
275 { 3, "No permission to send a Talk Burst"},
276 { 4, "Talk burst pre-empted"},
280 static const value_string rtcp_app_poc1_reason_code_ack_vals[] =
284 { 2, "Not accepted"},
287 static const value_string rtcp_app_poc1_conn_sess_type_vals[] =
292 { 3, "Pre-arranged"},
297 static const value_string rtcp_app_poc1_qsresp_priority_vals[] =
299 { 0, "No priority (un-queued)"},
300 { 1, "Normal priority"},
301 { 2, "High priority"},
302 { 3, "Pre-emptive priority"},
306 /* 3GPP 29.414 RTP Multiplexing */
307 static const value_string rtcp_app_mux_selection_vals[] =
309 { 0, "No multiplexing applied"},
310 { 1, "Multiplexing without RTP header compression applied"},
311 { 2, "Multiplexing with RTP header compression applied"},
316 /* RFC 4585 and RFC 5104 */
317 static const value_string rtcp_rtpfb_fmt_vals[] =
319 { 1, "Generic negative acknowledgement (NACK)"},
320 { 3, "Temporary Maximum Media Stream Bit Rate Request (TMMBR)"},
321 { 4, "Temporary Maximum Media Stream Bit Rate Notification (TMMBN)"},
322 { 31, "Reserved for future extensions"},
326 static const value_string rtcp_psfb_fmt_vals[] =
328 { 1, "Picture Loss Indication"},
329 { 2, "Slice Loss Indication"},
330 { 3, "Reference Picture Selection Indication"},
331 { 4, "Full Intra Request (FIR) Command"},
332 { 5, "Temporal-Spatial Trade-off Request (TSTR)"},
333 { 6, "Temporal-Spatial Trade-off Notification (TSTN"},
334 { 7, "Video Back Channel Message (VBCM)"},
335 { 15, "Application Layer Feedback"},
336 { 31, "Reserved for future extensions"},
340 /* RTCP header fields */
341 static int proto_rtcp = -1;
342 static int hf_rtcp_version = -1;
343 static int hf_rtcp_padding = -1;
344 static int hf_rtcp_rc = -1;
345 static int hf_rtcp_sc = -1;
346 static int hf_rtcp_pt = -1;
347 static int hf_rtcp_length = -1;
348 static int hf_rtcp_ssrc_sender = -1;
349 static int hf_rtcp_ssrc_media_source = -1;
350 static int hf_rtcp_ntp = -1;
351 static int hf_rtcp_ntp_msw = -1;
352 static int hf_rtcp_ntp_lsw = -1;
353 static int hf_rtcp_rtp_timestamp = -1;
354 static int hf_rtcp_sender_pkt_cnt = -1;
355 static int hf_rtcp_sender_oct_cnt = -1;
356 static int hf_rtcp_ssrc_source = -1;
357 static int hf_rtcp_ssrc_fraction = -1;
358 static int hf_rtcp_ssrc_cum_nr = -1;
359 static int hf_rtcp_ssrc_discarded = -1;
360 /* First the 32 bit number, then the split
361 * up 16 bit values */
362 /* These two are added to a subtree */
363 static int hf_rtcp_ssrc_ext_high_seq = -1;
364 static int hf_rtcp_ssrc_high_seq = -1;
365 static int hf_rtcp_ssrc_high_cycles = -1;
366 static int hf_rtcp_ssrc_jitter = -1;
367 static int hf_rtcp_ssrc_lsr = -1;
368 static int hf_rtcp_ssrc_dlsr = -1;
369 static int hf_rtcp_ssrc_csrc = -1;
370 static int hf_rtcp_sdes_type = -1;
371 static int hf_rtcp_sdes_length = -1;
372 static int hf_rtcp_sdes_text = -1;
373 static int hf_rtcp_sdes_prefix_len = -1;
374 static int hf_rtcp_sdes_prefix_string= -1;
375 static int hf_rtcp_subtype = -1;
376 static int hf_rtcp_name_ascii = -1;
377 static int hf_rtcp_app_data = -1;
378 static int hf_rtcp_fsn = -1;
379 static int hf_rtcp_blp = -1;
380 static int hf_rtcp_padding_count = -1;
381 static int hf_rtcp_padding_data = -1;
382 static int hf_rtcp_profile_specific_extension = -1;
383 static int hf_rtcp_app_poc1 = -1;
384 static int hf_rtcp_app_poc1_subtype = -1;
385 static int hf_rtcp_app_poc1_sip_uri = -1;
386 static int hf_rtcp_app_poc1_disp_name = -1;
387 static int hf_rtcp_app_poc1_priority = -1;
388 static int hf_rtcp_app_poc1_request_ts = -1;
389 static int hf_rtcp_app_poc1_stt = -1;
390 static int hf_rtcp_app_poc1_partic = -1;
391 static int hf_rtcp_app_poc1_ssrc_granted = -1;
392 static int hf_rtcp_app_poc1_last_pkt_seq_no = -1;
393 static int hf_rtcp_app_poc1_ignore_seq_no = -1;
394 static int hf_rtcp_app_poc1_reason_code1 = -1;
395 static int hf_rtcp_app_poc1_reason1_phrase = -1;
396 static int hf_rtcp_app_poc1_reason_code2 = -1;
397 static int hf_rtcp_app_poc1_new_time_request = -1;
398 static int hf_rtcp_app_poc1_ack_subtype = -1;
399 static int hf_rtcp_app_poc1_ack_reason_code = -1;
400 static int hf_rtcp_app_poc1_qsresp_priority = -1;
401 static int hf_rtcp_app_poc1_qsresp_position = -1;
402 static int hf_rtcp_app_poc1_conn_content[5] = { -1, -1, -1, -1, -1 };
403 static int hf_rtcp_app_poc1_conn_session_type = -1;
404 static int hf_rtcp_app_poc1_conn_add_ind_mao = -1;
405 static int hf_rtcp_app_poc1_conn_sdes_items[5] = { -1, -1, -1, -1, -1 };
406 static int hf_rtcp_app_mux = -1;
407 static int hf_rtcp_app_mux_mux = -1;
408 static int hf_rtcp_app_mux_cp = -1;
409 static int hf_rtcp_app_mux_selection = -1;
410 static int hf_rtcp_app_mux_localmuxport = -1;
411 static int hf_rtcp_xr_block_type = -1;
412 static int hf_rtcp_xr_block_specific = -1;
413 static int hf_rtcp_xr_block_length = -1;
414 static int hf_rtcp_xr_thinning = -1;
415 static int hf_rtcp_xr_voip_metrics_burst_density = -1;
416 static int hf_rtcp_xr_voip_metrics_gap_density = -1;
417 static int hf_rtcp_xr_voip_metrics_burst_duration = -1;
418 static int hf_rtcp_xr_voip_metrics_gap_duration = -1;
419 static int hf_rtcp_xr_voip_metrics_rtdelay = -1;
420 static int hf_rtcp_xr_voip_metrics_esdelay = -1;
421 static int hf_rtcp_xr_voip_metrics_siglevel = -1;
422 static int hf_rtcp_xr_voip_metrics_noiselevel = -1;
423 static int hf_rtcp_xr_voip_metrics_rerl = -1;
424 static int hf_rtcp_xr_voip_metrics_gmin = -1;
425 static int hf_rtcp_xr_voip_metrics_rfactor = -1;
426 static int hf_rtcp_xr_voip_metrics_extrfactor = -1;
427 static int hf_rtcp_xr_voip_metrics_moslq = -1;
428 static int hf_rtcp_xr_voip_metrics_moscq = -1;
429 static int hf_rtcp_xr_voip_metrics_plc = -1;
430 static int hf_rtcp_xr_voip_metrics_jbadaptive = -1;
431 static int hf_rtcp_xr_voip_metrics_jbrate = -1;
432 static int hf_rtcp_xr_voip_metrics_jbnominal = -1;
433 static int hf_rtcp_xr_voip_metrics_jbmax = -1;
434 static int hf_rtcp_xr_voip_metrics_jbabsmax = -1;
435 static int hf_rtcp_xr_stats_loss_flag = -1;
436 static int hf_rtcp_xr_stats_dup_flag = -1;
437 static int hf_rtcp_xr_stats_jitter_flag = -1;
438 static int hf_rtcp_xr_stats_ttl = -1;
439 static int hf_rtcp_xr_beginseq = -1;
440 static int hf_rtcp_xr_endseq = -1;
441 static int hf_rtcp_xr_stats_lost = -1;
442 static int hf_rtcp_xr_stats_dups = -1;
443 static int hf_rtcp_xr_stats_minjitter = -1;
444 static int hf_rtcp_xr_stats_maxjitter = -1;
445 static int hf_rtcp_xr_stats_meanjitter = -1;
446 static int hf_rtcp_xr_stats_devjitter = -1;
447 static int hf_rtcp_xr_stats_minttl = -1;
448 static int hf_rtcp_xr_stats_maxttl = -1;
449 static int hf_rtcp_xr_stats_meanttl = -1;
450 static int hf_rtcp_xr_stats_devttl = -1;
451 static int hf_rtcp_xr_lrr = -1;
452 static int hf_rtcp_xr_dlrr = -1;
453 static int hf_rtcp_length_check = -1;
454 static int hf_rtcp_bye_reason_not_padded = -1;
455 static int hf_rtcp_rtpfb_fmt = -1;
456 static int hf_rtcp_rtpfb_nack_pid = -1;
457 static int hf_rtcp_rtpfb_nack_blp = -1;
458 static int hf_rtcp_psfb_fmt = -1;
459 static int hf_rtcp_fci = -1;
460 static int hf_rtcp_psfb_fir_fci_ssrc = -1;
461 static int hf_rtcp_psfb_fir_fci_csn = -1;
462 static int hf_rtcp_psfb_fir_fci_reserved = -1;
463 static int hf_rtcp_rtpfb_tmbbr_fci_ssrc = -1;
464 static int hf_rtcp_rtpfb_tmbbr_fci_exp = -1;
465 static int hf_rtcp_rtpfb_tmbbr_fci_mantissa = -1;
466 static int hf_rtcp_rtpfb_tmbbr_fci_bitrate = -1;
467 static int hf_rtcp_rtpfb_tmbbr_fci_measuredoverhead = -1;
468 static int hf_srtcp_e = -1;
469 static int hf_srtcp_index = -1;
470 static int hf_srtcp_mki = -1;
471 static int hf_srtcp_auth_tag = -1;
472 static int hf_rtcp_xr_btxnq_begseq = -1; /* added for BT XNQ block (RFC5093) */
473 static int hf_rtcp_xr_btxnq_endseq = -1;
474 static int hf_rtcp_xr_btxnq_vmaxdiff = -1;
475 static int hf_rtcp_xr_btxnq_vrange = -1;
476 static int hf_rtcp_xr_btxnq_vsum = -1;
477 static int hf_rtcp_xr_btxnq_cycles = -1;
478 static int hf_rtcp_xr_btxnq_jbevents = -1;
479 static int hf_rtcp_xr_btxnq_tdegnet = -1;
480 static int hf_rtcp_xr_btxnq_tdegjit = -1;
481 static int hf_rtcp_xr_btxnq_es = -1;
482 static int hf_rtcp_xr_btxnq_ses = -1;
483 static int hf_rtcp_xr_btxnq_spare = -1;
485 /* RTCP setup fields */
486 static int hf_rtcp_setup = -1;
487 static int hf_rtcp_setup_frame = -1;
488 static int hf_rtcp_setup_method = -1;
490 /* RTCP roundtrip delay fields */
491 static int hf_rtcp_last_sr_timestamp_frame = -1;
492 static int hf_rtcp_time_since_last_sr = -1;
493 static int hf_rtcp_roundtrip_delay = -1;
497 /* RTCP fields defining a sub tree */
498 static gint ett_rtcp = -1;
499 static gint ett_rtcp_sr = -1;
500 static gint ett_rtcp_rr = -1;
501 static gint ett_rtcp_sdes = -1;
502 static gint ett_rtcp_bye = -1;
503 static gint ett_rtcp_app = -1;
504 static gint ett_rtcp_rtpfb = -1;
505 static gint ett_rtcp_psfb = -1;
506 static gint ett_rtcp_xr = -1;
507 static gint ett_rtcp_fir = -1;
508 static gint ett_rtcp_nack = -1;
509 static gint ett_ssrc = -1;
510 static gint ett_ssrc_item = -1;
511 static gint ett_ssrc_ext_high = -1;
512 static gint ett_sdes = -1;
513 static gint ett_sdes_item = -1;
514 static gint ett_PoC1 = -1;
515 static gint ett_mux = -1;
516 static gint ett_rtcp_setup = -1;
517 static gint ett_rtcp_roundtrip_delay = -1;
518 static gint ett_xr_block = -1;
519 static gint ett_xr_block_contents = -1;
520 static gint ett_xr_ssrc = -1;
521 static gint ett_xr_loss_chunk = -1;
522 static gint ett_poc1_conn_contents = -1;
523 static gint ett_rtcp_nack_blp = -1;
524 /* Protocol registration */
525 void proto_register_rtcp(void);
526 void proto_reg_handoff_rtcp(void);
528 /* Main dissection function */
529 static void dissect_rtcp( tvbuff_t *tvb, packet_info *pinfo,
532 /* Heuristic dissection */
533 static gboolean global_rtcp_heur = FALSE;
534 static gboolean dissect_rtcp_heur( tvbuff_t *tvb, packet_info *pinfo,
537 /* Displaying set info */
538 static gboolean global_rtcp_show_setup_info = TRUE;
539 static void show_setup_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
541 /* Related to roundtrip calculation (using LSR and DLSR) */
542 static gboolean global_rtcp_show_roundtrip_calculation = FALSE;
543 #define MIN_ROUNDTRIP_TO_REPORT_DEFAULT 10
544 static guint global_rtcp_show_roundtrip_calculation_minimum = MIN_ROUNDTRIP_TO_REPORT_DEFAULT;
545 static void remember_outgoing_sr(packet_info *pinfo, long lsr);
546 static void calculate_roundtrip_delay(tvbuff_t *tvb, packet_info *pinfo,
547 proto_tree *tree, guint32 lsr, guint32 dlsr);
548 static void add_roundtrip_delay_info(tvbuff_t *tvb, packet_info *pinfo,
551 guint gap_between_reports, gint delay);
554 /* Set up an RTCP conversation using the info given */
555 void srtcp_add_address( packet_info *pinfo,
556 address *addr, int port,
558 const gchar *setup_method, guint32 setup_frame_number,
559 struct srtp_info *srtcp_info)
562 conversation_t* p_conv;
563 struct _rtcp_conversation_info *p_conv_data = NULL;
566 * If this isn't the first time this packet has been processed,
567 * we've already done this work, so we don't need to do it
570 if (pinfo->fd->flags.visited)
576 printf("#%u: %srtcp_add_address(%s, %u, %u, %s, %u\n", pinfo->fd->num, (srtcp_info)?"s":"", ep_address_to_str(addr), port, other_port, setup_method, setup_frame_number);
579 SET_ADDRESS(&null_addr, AT_NONE, 0, NULL);
582 * Check if the ip address and port combination is not
583 * already registered as a conversation.
585 p_conv = find_conversation( pinfo->fd->num, addr, &null_addr, PT_UDP, port, other_port,
586 NO_ADDR_B | (!other_port ? NO_PORT_B : 0));
589 * If not, create a new conversation.
592 p_conv = conversation_new( pinfo->fd->num, addr, &null_addr, PT_UDP,
593 (guint32)port, (guint32)other_port,
594 NO_ADDR2 | (!other_port ? NO_PORT2 : 0));
598 conversation_set_dissector(p_conv, rtcp_handle);
601 * Check if the conversation has data associated with it.
603 p_conv_data = conversation_get_proto_data(p_conv, proto_rtcp);
606 * If not, add a new data item.
608 if ( ! p_conv_data ) {
609 /* Create conversation data */
610 p_conv_data = se_alloc0(sizeof(struct _rtcp_conversation_info));
611 conversation_add_proto_data(p_conv, proto_rtcp, p_conv_data);
615 * Update the conversation data.
617 p_conv_data->setup_method_set = TRUE;
618 g_strlcpy(p_conv_data->setup_method, setup_method, MAX_RTCP_SETUP_METHOD_SIZE);
619 p_conv_data->setup_frame_number = setup_frame_number;
620 p_conv_data->srtcp_info = srtcp_info;
623 /* Set up an RTCP conversation using the info given */
624 void rtcp_add_address( packet_info *pinfo,
625 address *addr, int port,
627 const gchar *setup_method, guint32 setup_frame_number)
629 srtcp_add_address(pinfo, addr, port, other_port, setup_method, setup_frame_number, NULL);
633 dissect_rtcp_heur( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree )
635 unsigned int offset = 0;
636 unsigned int first_byte;
637 unsigned int packet_type;
639 /* This is a heuristic dissector, which means we get all the UDP
640 * traffic not sent to a known dissector and not claimed by
641 * a heuristic dissector called before us!
644 if (!global_rtcp_heur)
649 /* Was it sent to an odd-numbered port? */
650 if ((pinfo->destport % 2) == 0)
652 return FALSE; /* no */
655 /* Look at first byte */
656 first_byte = tvb_get_guint8(tvb, offset);
658 /* Are version bits set to 2? */
659 if (((first_byte & 0xC0) >> 6) != 2)
664 /* Look at packet type */
665 packet_type = tvb_get_guint8(tvb, offset + 1);
667 /* First packet within compound packet is supposed to be a sender
669 - allow BYE because this happens anyway
670 - allow APP because TBCP ("PoC1") packets aren't compound... */
671 if (!((packet_type == RTCP_SR) || (packet_type == RTCP_RR) ||
672 (packet_type == RTCP_BYE) || (packet_type == RTCP_APP)))
677 /* Overall length must be a multiple of 4 bytes */
678 if (tvb_reported_length(tvb) % 4)
683 /* OK, dissect as RTCP */
684 dissect_rtcp(tvb, pinfo, tree);
688 /* Dissect the length field. Append to this field text indicating the number of
689 actual bytes this translates to (i.e. (raw value + 1) * 4) */
690 int dissect_rtcp_length_field( proto_tree *tree, tvbuff_t *tvb, int offset)
693 unsigned short raw_length = tvb_get_ntohs( tvb, offset );
694 ti = proto_tree_add_item( tree, hf_rtcp_length, tvb, offset, 2, FALSE);
695 proto_item_append_text(ti, " (%u bytes)", (raw_length+1)*4);
702 dissect_rtcp_nack( tvbuff_t *tvb, int offset, proto_tree *tree )
704 /* Packet type = FIR (H261) */
705 proto_tree_add_item( tree, hf_rtcp_rc, tvb, offset, 1, FALSE );
707 /* Packet type, 8 bits = APP */
708 proto_tree_add_item( tree, hf_rtcp_pt, tvb, offset, 1, FALSE );
711 /* Packet length in 32 bit words minus one */
712 offset = dissect_rtcp_length_field(tree, tvb, offset);
715 proto_tree_add_item( tree, hf_rtcp_ssrc_source, tvb, offset, 4, FALSE );
719 proto_tree_add_item( tree, hf_rtcp_fsn, tvb, offset, 2, FALSE );
723 proto_tree_add_item( tree, hf_rtcp_blp, tvb, offset, 2, FALSE );
730 dissect_rtcp_rtpfb_tmmbr( tvbuff_t *tvb, int offset, proto_tree *rtcp_tree, proto_item *top_item, int num_fci, int is_notification)
734 guint32 mantissa = 0;
735 proto_item *ti = (proto_item*) NULL;
736 proto_tree *fci_tree = (proto_tree*) NULL;
738 if (is_notification == 1) {
739 ti = proto_tree_add_text( rtcp_tree, tvb, offset, 8, "TMMBN %d", num_fci );
741 ti = proto_tree_add_text( rtcp_tree, tvb, offset, 8, "TMMBR %d", num_fci );
744 fci_tree = proto_item_add_subtree( ti, ett_ssrc );
746 proto_tree_add_item( fci_tree, hf_rtcp_rtpfb_tmbbr_fci_ssrc, tvb, offset, 4, FALSE );
749 proto_tree_add_item( fci_tree, hf_rtcp_rtpfb_tmbbr_fci_exp, tvb, offset, 1, FALSE );
750 exp = (tvb_get_guint8(tvb, offset) & 0xfc) >> 2;
752 proto_tree_add_item( fci_tree, hf_rtcp_rtpfb_tmbbr_fci_mantissa, tvb, offset, 3, FALSE );
753 mantissa = (tvb_get_ntohl( tvb, offset) & 0x3fffe00) >> 9;
754 bitrate = mantissa << exp;
755 proto_tree_add_string_format_value( fci_tree, hf_rtcp_rtpfb_tmbbr_fci_bitrate, tvb, offset, 3, "", "%u", bitrate);
758 proto_tree_add_item( fci_tree, hf_rtcp_rtpfb_tmbbr_fci_measuredoverhead, tvb, offset, 1, FALSE );
761 if (top_item != NULL) {
762 proto_item_append_text(top_item, ": TMMBR: %u", bitrate);
769 dissect_rtcp_rtpfb_nack( tvbuff_t *tvb, int offset, proto_tree *rtcp_tree, proto_item *top_item)
773 int nack_num_frames_lost = 0;
774 proto_tree *bitfield_tree;
775 unsigned int rtcp_rtpfb_nack_pid = 0;
776 unsigned int rtcp_rtpfb_nack_blp = 0;
777 proto_item *ti = (proto_item*) NULL;
779 proto_tree_add_item(rtcp_tree, hf_rtcp_rtpfb_nack_pid, tvb, offset, 2, FALSE);
780 rtcp_rtpfb_nack_pid = tvb_get_ntohs(tvb, offset);
783 ti = proto_tree_add_item(rtcp_tree, hf_rtcp_rtpfb_nack_blp, tvb, offset, 2, FALSE);
785 proto_item_set_text(ti, "RTCP Transport Feedback NACK BLP: ");
786 rtcp_rtpfb_nack_blp = tvb_get_ntohs(tvb, offset);
787 bitfield_tree = proto_item_add_subtree( ti, ett_rtcp_nack_blp);
788 nack_num_frames_lost ++;
789 if (rtcp_rtpfb_nack_blp) {
790 for (i = 0; i < 16; i ++) {
791 g_snprintf(strbuf, 64, "Frame %d also lost", rtcp_rtpfb_nack_pid + i + 1);
792 proto_tree_add_text(bitfield_tree, tvb, offset, 2, "%s",
793 decode_boolean_bitfield(rtcp_rtpfb_nack_blp, (1<<i), 16, strbuf, ""));
795 if (rtcp_rtpfb_nack_blp & (1<<i)) {
796 proto_item *hidden_ti;
797 hidden_ti = proto_tree_add_uint(bitfield_tree, hf_rtcp_rtpfb_nack_pid, tvb, offset, 2, rtcp_rtpfb_nack_pid + i + 1);
798 PROTO_ITEM_SET_HIDDEN(hidden_ti);
799 proto_item_append_text(ti, "%d ", rtcp_rtpfb_nack_pid + i + 1);
800 nack_num_frames_lost ++;
804 proto_item_set_text(ti, "0 (No additional frames lost)");
808 if (top_item != NULL) {
809 proto_item_append_text(top_item, ": NACK: %d frames lost", nack_num_frames_lost);
816 dissect_rtcp_rtpfb( tvbuff_t *tvb, int offset, proto_tree *rtcp_tree, proto_item *top_item)
818 unsigned int counter = 0;
819 unsigned int rtcp_rtpfb_fmt = 0;
820 int packet_length = 0;
821 int start_offset = offset;
823 /* Transport layer FB message */
824 /* Feedback message type (FMT): 5 bits */
825 proto_tree_add_item( rtcp_tree, hf_rtcp_rtpfb_fmt, tvb, offset, 1, FALSE );
826 rtcp_rtpfb_fmt = (tvb_get_guint8(tvb, offset) & 0x1f);
829 /* Packet type, 8 bits */
830 proto_tree_add_item( rtcp_tree, hf_rtcp_pt, tvb, offset, 1, FALSE );
833 /* Packet length in 32 bit words MINUS one, 16 bits */
834 packet_length = (tvb_get_ntohs(tvb, offset) + 1) * 4;
835 offset = dissect_rtcp_length_field(rtcp_tree, tvb, offset);
837 /* SSRC of packet sender, 32 bits */
838 proto_tree_add_item( rtcp_tree, hf_rtcp_ssrc_sender, tvb, offset, 4, FALSE );
841 /* SSRC of media source, 32 bits */
842 proto_tree_add_item( rtcp_tree, hf_rtcp_ssrc_media_source, tvb, offset, 4, FALSE );
845 /* Transport-Layer Feedback Message Elements */
846 while ((offset - start_offset) < packet_length) {
848 if (rtcp_rtpfb_fmt == 1) {
849 offset = dissect_rtcp_rtpfb_nack(tvb, offset, rtcp_tree, top_item);
850 } else if (rtcp_rtpfb_fmt == 3) {
851 offset = dissect_rtcp_rtpfb_tmmbr(tvb, offset, rtcp_tree, top_item, counter, 0);
852 } else if (rtcp_rtpfb_fmt == 4) {
853 offset = dissect_rtcp_rtpfb_tmmbr(tvb, offset, rtcp_tree, top_item, counter, 1);
856 proto_tree_add_item(rtcp_tree, hf_rtcp_fci, tvb, offset, packet_length - offset, FALSE );
857 offset = start_offset + packet_length;
864 dissect_rtcp_psfb( tvbuff_t *tvb, int offset, proto_tree *rtcp_tree,
867 unsigned int counter = 0;
868 unsigned int num_fci = 0;
869 unsigned int read_fci = 0;
870 proto_tree *fci_tree = (proto_tree*) NULL;
871 proto_item *ti = (proto_item*) NULL;
872 unsigned int rtcp_psfb_fmt = 0;
873 int base_offset = offset;
875 /* Payload-specific FB message */
876 /* Feedback message type (FMT): 5 bits */
877 proto_tree_add_item( rtcp_tree, hf_rtcp_psfb_fmt, tvb, offset, 1, FALSE );
878 rtcp_psfb_fmt = (tvb_get_guint8(tvb, offset) & 0x1f);
881 /* Packet type, 8 bits */
882 proto_tree_add_item( rtcp_tree, hf_rtcp_pt, tvb, offset, 1, FALSE );
885 /* Packet length in 32 bit words MINUS one, 16 bits */
886 num_fci = (tvb_get_ntohs(tvb, offset) - 2);
887 offset = dissect_rtcp_length_field(rtcp_tree, tvb, offset);
889 /* SSRC of packet sender, 32 bits */
890 proto_tree_add_item( rtcp_tree, hf_rtcp_ssrc_sender, tvb, offset, 4, FALSE );
893 /* SSRC of media source, 32 bits */
894 proto_tree_add_item( rtcp_tree, hf_rtcp_ssrc_media_source, tvb, offset, 4, FALSE );
897 /* Feedback Control Information (FCI) */
898 while ( read_fci < num_fci ) {
900 if (rtcp_psfb_fmt == 4) {
901 /* Create a new subtree for a length of 8 bytes */
902 ti = proto_tree_add_text( rtcp_tree, tvb, offset, 8, "FIR %u", ++counter );
903 fci_tree = proto_item_add_subtree( ti, ett_ssrc );
905 proto_tree_add_item( fci_tree, hf_rtcp_psfb_fir_fci_ssrc, tvb, offset, 4, FALSE );
907 /* Command Sequence Number 8 bit*/
908 proto_tree_add_item( fci_tree, hf_rtcp_psfb_fir_fci_csn, tvb, offset, 1, FALSE );
909 /*proto_tree_add_item( ssrc_tree, hf_rtcp_ssrc_source, tvb, offset, 4, FALSE );*/
912 proto_tree_add_item( fci_tree, hf_rtcp_psfb_fir_fci_reserved, tvb, offset, 3, FALSE );
920 /* Append undecoded FCI information */
921 if ((packet_length - (offset - base_offset)) > 0) {
922 proto_tree_add_item( rtcp_tree, hf_rtcp_fci, tvb, offset, packet_length - (offset - base_offset), FALSE );
923 offset = base_offset + packet_length;
929 dissect_rtcp_fir( tvbuff_t *tvb, int offset, proto_tree *tree )
931 /* Packet type = FIR (H261) */
932 proto_tree_add_item( tree, hf_rtcp_rc, tvb, offset, 1, FALSE );
934 /* Packet type, 8 bits = APP */
935 proto_tree_add_item( tree, hf_rtcp_pt, tvb, offset, 1, FALSE );
938 /* Packet length in 32 bit words minus one */
939 offset = dissect_rtcp_length_field(tree, tvb, offset);
942 proto_tree_add_item( tree, hf_rtcp_ssrc_source, tvb, offset, 4, FALSE );
949 dissect_rtcp_app( tvbuff_t *tvb,packet_info *pinfo, int offset, proto_tree *tree,
950 unsigned int padding, unsigned int packet_len, guint rtcp_subtype,
953 unsigned int counter = 0;
957 guint items_start_offset;
958 proto_tree *PoC1_tree;
959 proto_item *PoC1_item;
961 /* XXX If more application types are to be dissected it may be useful to use a table like in packet-sip.c */
962 static const char poc1_app_name_str[] = "PoC1";
963 static const char mux_app_name_str[] = "3GPP";
967 proto_tree_add_item( tree, hf_rtcp_ssrc_source, tvb, offset, 4, FALSE );
971 /* Application Name (ASCII) */
972 for( counter = 0; counter < 4; counter++ )
973 ascii_name[ counter ] = tvb_get_guint8( tvb, offset + counter );
974 /* g_strlcpy( ascii_name, pd + offset, 4 ); */
975 ascii_name[4] = '\0';
976 proto_tree_add_string( tree, hf_rtcp_name_ascii, tvb, offset, 4,
979 /* See if we can handle this application type */
980 if ( g_ascii_strncasecmp(ascii_name, poc1_app_name_str,4 ) == 0 )
982 /* PoC1 Application */
983 guint8 t2timer_code, participants_code;
985 item = proto_tree_add_uint( tree, hf_rtcp_app_poc1_subtype, tvb, offset - 8, 1, rtcp_subtype );
986 PROTO_ITEM_SET_GENERATED(item);
987 col_add_fstr(pinfo->cinfo, COL_INFO,"(%s) %s",ascii_name,
988 val_to_str(rtcp_subtype,rtcp_app_poc1_floor_cnt_type_vals,"unknown (%u)") );
991 app_length = app_length -8;
992 if ( packet_len == 0 )
993 return offset; /* No more data */
994 /* Applications specific data */
996 /* If there's padding present, we have to remove that from the data part
997 * The last octet of the packet contains the length of the padding
999 packet_len -= tvb_get_guint8( tvb, offset + packet_len - 1 );
1001 /* Create a subtree for the PoC1 Application items; we don't yet know
1003 items_start_offset = offset;
1005 /* Top-level poc tree */
1006 PoC1_item = proto_tree_add_item(tree, hf_rtcp_app_poc1, tvb, offset, packet_len, FALSE);
1007 PoC1_tree = proto_item_add_subtree( PoC1_item, ett_PoC1 );
1009 /* Dissect it according to its subtype */
1010 switch ( rtcp_subtype ) {
1012 case TBCP_BURST_REQUEST:
1017 /* Both items here are optional */
1018 if (tvb_reported_length_remaining( tvb, offset) == 0)
1023 /* Look for a code in the first byte */
1024 code = tvb_get_guint8(tvb, offset);
1028 /* Priority (optional) */
1031 item_len = tvb_get_guint8(tvb, offset);
1034 if (item_len != 2) /* SHALL be 2 */
1037 priority = tvb_get_ntohs(tvb, offset);
1038 proto_tree_add_item(PoC1_tree, hf_rtcp_app_poc1_priority, tvb, offset, 2, FALSE );
1042 col_append_fstr(pinfo->cinfo, COL_INFO,
1044 val_to_str(priority,
1045 rtcp_app_poc1_qsresp_priority_vals,
1048 /* Look for (optional) next code */
1049 if (tvb_reported_length_remaining( tvb, offset) == 0)
1053 code = tvb_get_guint8(tvb, offset);
1059 /* Request timestamp (optional) */
1063 item_len = tvb_get_guint8(tvb, offset);
1066 if (item_len != 8) /* SHALL be 8 */
1069 buff = ntp_fmt_ts(tvb_get_ptr(tvb, offset, 8));
1070 proto_tree_add_string_format(PoC1_tree, hf_rtcp_app_poc1_request_ts,
1071 tvb, offset, 8, buff,
1072 "Request timestamp: %s", buff );
1076 col_append_fstr(pinfo->cinfo, COL_INFO, " ts=\"%s\"", buff);
1081 case TBCP_BURST_GRANTED:
1084 guint16 stop_talking_time;
1085 guint16 participants;
1087 /* Stop talking timer (now mandatory) */
1088 t2timer_code = tvb_get_guint8(tvb, offset);
1091 if (t2timer_code != 101) /* SHALL be 101 */
1094 item_len = tvb_get_guint8(tvb, offset);
1097 if (item_len != 2) /* SHALL be 2 */
1100 stop_talking_time = tvb_get_ntohs(tvb, offset);
1101 ti = proto_tree_add_item(PoC1_tree, hf_rtcp_app_poc1_stt, tvb, offset, 2, FALSE );
1103 /* Append text with meanings of value */
1104 switch (stop_talking_time)
1107 proto_item_append_text(ti, " unknown");
1110 proto_item_append_text(ti, " infinity");
1113 proto_item_append_text(ti, " seconds");
1117 packet_len -= item_len;
1119 col_append_fstr(pinfo->cinfo, COL_INFO, " stop-talking-time=%u",
1122 /* Participants (optional) */
1123 if (tvb_reported_length_remaining( tvb, offset) == 0)
1127 participants_code = tvb_get_guint8(tvb, offset);
1130 if (participants_code != 100) /* SHALL be 100 */
1133 item_len = tvb_get_guint8(tvb, offset);
1136 if (item_len != 2) /* SHALL be 2 */
1139 participants = tvb_get_ntohs(tvb, offset);
1140 ti = proto_tree_add_item(PoC1_tree, hf_rtcp_app_poc1_partic, tvb, offset, 2, FALSE );
1142 /* Append text with meanings of extreme values */
1143 switch (participants)
1146 proto_item_append_text(ti, " (not known)");
1149 proto_item_append_text(ti, " (or more)");
1155 packet_len -= item_len;
1157 col_append_fstr(pinfo->cinfo, COL_INFO, " participants=%u",
1162 case TBCP_BURST_TAKEN_EXPECT_NO_REPLY:
1163 case TBCP_BURST_TAKEN_EXPECT_REPLY:
1165 guint16 participants;
1168 /* SSRC of PoC client */
1169 proto_tree_add_item(PoC1_tree, hf_rtcp_app_poc1_ssrc_granted, tvb, offset, 4, FALSE );
1173 /* SDES type (must be CNAME) */
1174 sdes_type = tvb_get_guint8( tvb, offset );
1175 proto_tree_add_item( PoC1_tree, hf_rtcp_sdes_type, tvb, offset, 1, FALSE );
1178 if (sdes_type != RTCP_SDES_CNAME)
1184 item_len = tvb_get_guint8( tvb, offset );
1185 /* Item len of 1 because its an FT_UINT_STRING... */
1186 proto_tree_add_item(PoC1_tree, hf_rtcp_app_poc1_sip_uri,
1187 tvb, offset, 1, FALSE );
1190 col_append_fstr(pinfo->cinfo, COL_INFO, " CNAME=\"%s\"",
1191 tvb_get_ephemeral_string(tvb, offset, item_len));
1194 packet_len = packet_len - item_len - 1;
1196 /* In the application dependent data, the TBCP Talk Burst Taken message SHALL carry
1197 * a SSRC field and SDES items, CNAME and MAY carry SDES item NAME to identify the
1198 * PoC Client that has been granted permission to send a Talk Burst.
1200 * The SDES item NAME SHALL be included if it is known by the PoC Server.
1201 * Therefore the length of the packet will vary depending on number of SDES items
1202 * and the size of the SDES items.
1204 if ( packet_len == 0 )
1207 /* SDES type (must be NAME if present) */
1208 sdes_type = tvb_get_guint8( tvb, offset );
1209 if (sdes_type == RTCP_SDES_NAME) {
1210 proto_tree_add_item( PoC1_tree, hf_rtcp_sdes_type, tvb, offset, 1, FALSE );
1215 item_len = tvb_get_guint8( tvb, offset );
1216 /* Item len of 1 because its an FT_UINT_STRING... */
1217 proto_tree_add_item(PoC1_tree, hf_rtcp_app_poc1_disp_name,
1218 tvb, offset, 1, FALSE);
1221 col_append_fstr(pinfo->cinfo, COL_INFO, " DISPLAY-NAME=\"%s\"",
1222 tvb_get_ephemeral_string(tvb, offset, item_len));
1225 packet_len = packet_len - item_len - 1;
1227 if (packet_len == 0) {
1231 /* Move onto next 4-byte boundary */
1233 int padding2 = (4-(offset%4));
1235 packet_len -= padding2;
1239 /* Participants (optional) */
1240 if (tvb_reported_length_remaining( tvb, offset) == 0) {
1243 participants_code = tvb_get_guint8(tvb, offset);
1246 if (participants_code != 100) { /* SHALL be 100 */
1249 item_len = tvb_get_guint8(tvb, offset);
1252 if (item_len != 2) { /* SHALL be 2 */
1256 participants = tvb_get_ntohs(tvb, offset);
1257 ti = proto_tree_add_item(PoC1_tree, hf_rtcp_app_poc1_partic, tvb, offset, 2, FALSE );
1259 /* Append text with meanings of extreme values */
1260 switch (participants) {
1262 proto_item_append_text(ti, " (not known)");
1265 proto_item_append_text(ti, " (or more)");
1271 col_append_fstr(pinfo->cinfo, COL_INFO, " Participants=%u",
1274 packet_len -= item_len;
1278 case TBCP_BURST_DENY:
1283 reason_code = tvb_get_guint8(tvb, offset);
1284 proto_tree_add_item( PoC1_tree, hf_rtcp_app_poc1_reason_code1, tvb, offset, 1, FALSE );
1288 col_append_fstr(pinfo->cinfo, COL_INFO, " reason-code=\"%s\"",
1289 val_to_str(reason_code,
1290 rtcp_app_poc1_reason_code1_vals,
1294 item_len = tvb_get_guint8( tvb, offset );
1295 if ( item_len != 0 )
1296 proto_tree_add_item( PoC1_tree, hf_rtcp_app_poc1_reason1_phrase, tvb, offset, 1, FALSE );
1298 offset += (item_len+1);
1299 packet_len -= (item_len+1);
1303 case TBCP_BURST_RELEASE:
1305 guint16 last_seq_no;
1306 guint16 ignore_last_seq_no;
1308 /* Sequence number of last RTP packet in burst */
1309 proto_tree_add_item( PoC1_tree, hf_rtcp_app_poc1_last_pkt_seq_no, tvb, offset, 2, FALSE );
1310 last_seq_no = tvb_get_ntohs(tvb, offset);
1312 /* Bit 16 is ignore flag */
1314 proto_tree_add_item(PoC1_tree, hf_rtcp_app_poc1_ignore_seq_no, tvb, offset, 2, FALSE );
1315 ignore_last_seq_no = (tvb_get_ntohs(tvb, offset) & 0x8000);
1317 col_append_fstr(pinfo->cinfo, COL_INFO, " last_rtp_seq_no=%u",
1320 /* 15 bits of padding follows */
1327 case TBCP_BURST_IDLE:
1330 case TBCP_BURST_REVOKE:
1333 guint16 reason_code = tvb_get_ntohs(tvb, offset);
1334 proto_tree_add_item( PoC1_tree, hf_rtcp_app_poc1_reason_code2, tvb, offset, 2, FALSE );
1336 /* The meaning of this field depends upon the reason code... */
1337 switch (reason_code)
1339 case 1: /* Only one user */
1340 /* No additional info */
1342 case 2: /* Talk burst too long */
1343 /* Additional info is 16 bits with time (in seconds) client can request */
1344 proto_tree_add_item( PoC1_tree, hf_rtcp_app_poc1_new_time_request, tvb, offset + 2, 2, FALSE );
1346 case 3: /* No permission */
1347 /* No additional info */
1349 case 4: /* Pre-empted */
1350 /* No additional info */
1354 col_append_fstr(pinfo->cinfo, COL_INFO, " reason-code=\"%s\"",
1355 val_to_str(reason_code,
1356 rtcp_app_poc1_reason_code2_vals,
1363 case TBCP_BURST_ACKNOWLEDGMENT:
1367 /* Code of message being acknowledged */
1368 subtype = (tvb_get_guint8(tvb, offset) & 0xf8) >> 3;
1369 proto_tree_add_item( PoC1_tree, hf_rtcp_app_poc1_ack_subtype, tvb, offset, 1, FALSE );
1371 col_append_fstr(pinfo->cinfo, COL_INFO, " (for %s)",
1373 rtcp_app_poc1_floor_cnt_type_vals,
1376 /* Reason code only seen if subtype was Connect */
1377 if (subtype == TBCP_CONNECT)
1379 proto_tree_add_item( PoC1_tree, hf_rtcp_app_poc1_ack_reason_code, tvb, offset, 2, FALSE );
1382 /* 16 bits of padding follow */
1388 case TBCP_QUEUE_STATUS_REQUEST:
1391 case TBCP_QUEUE_STATUS_RESPONSE:
1397 proto_tree_add_item( PoC1_tree, hf_rtcp_app_poc1_qsresp_priority, tvb, offset, 1, FALSE );
1399 /* Queue position. 65535 indicates 'position not available' */
1400 position = tvb_get_ntohs(tvb, offset+1);
1401 ti = proto_tree_add_item( PoC1_tree, hf_rtcp_app_poc1_qsresp_position, tvb, offset+1, 2, FALSE );
1404 proto_item_append_text(ti, " (client is un-queued)");
1406 if (position == 65535)
1408 proto_item_append_text(ti, " (position not available)");
1411 col_append_fstr(pinfo->cinfo, COL_INFO, " position=%u", position);
1413 /* 1 bytes of padding follows */
1420 case TBCP_DISCONNECT:
1425 proto_item *content = proto_tree_add_text(PoC1_tree, tvb, offset, 2, "SDES item content");
1426 gboolean contents[5];
1428 guint8 items_set = 0;
1430 proto_tree *content_tree = proto_item_add_subtree(content, ett_poc1_conn_contents);
1431 guint16 items_field = tvb_get_ntohs(tvb, offset );
1433 /* Dissect each defined bit flag in the SDES item content */
1435 i < sizeof(contents) / sizeof(contents[0]) &&
1436 i < sizeof(hf_rtcp_app_poc1_conn_content) /
1437 sizeof(hf_rtcp_app_poc1_conn_content[0]);
1440 proto_tree_add_item( content_tree, hf_rtcp_app_poc1_conn_content[i], tvb, offset, 2, FALSE );
1441 contents[i] = items_field & (1 << (15-i));
1442 if (contents[i]) ++items_set;
1445 /* Show how many flags were set */
1446 proto_item_append_text(content, " (%u items)", items_set);
1449 proto_tree_add_item( PoC1_tree, hf_rtcp_app_poc1_conn_session_type, tvb, offset + 2, 1, FALSE );
1451 /* Additional indications */
1452 proto_tree_add_item( PoC1_tree, hf_rtcp_app_poc1_conn_add_ind_mao, tvb, offset + 3, 1, FALSE );
1457 /* One SDES item for every set flag in contents array */
1459 i < sizeof(contents) / sizeof(contents[0]);
1461 if ( contents[i] ) {
1462 guint sdes_type2, sdes_len2;
1463 /* (sdes_type2 not currently used...). Could complain if type
1464 doesn't match expected for item... */
1465 sdes_type2 = tvb_get_guint8( tvb, offset++ );
1466 sdes_len2 = tvb_get_guint8( tvb, offset );
1468 /* Add SDES field indicated as present */
1469 proto_tree_add_item( PoC1_tree, hf_rtcp_app_poc1_conn_sdes_items[i], tvb, offset, 1, FALSE );
1471 /* Move past field */
1472 offset += sdes_len2 + 1;
1473 packet_len -= (sdes_len2 + 2);
1482 offset += packet_len;
1485 else if ( g_ascii_strncasecmp(ascii_name, mux_app_name_str,4 ) == 0 )
1487 /* 3GPP Nb protocol extension (3GPP 29.414) for RTP Multiplexing */
1488 col_append_fstr(pinfo->cinfo, COL_INFO,"( %s ) subtype=%u",ascii_name, rtcp_subtype);
1491 /* Applications specific data */
1493 /* If there's padding present, we have to remove that from the data part
1494 * The last octet of the packet contains the length of the padding
1496 packet_len -= tvb_get_guint8( tvb, offset + packet_len - 1 );
1498 if (packet_len == 4)
1500 guint16 local_port = 0;
1502 proto_item* mux_item = proto_tree_add_item(tree, hf_rtcp_app_mux, tvb, offset, packet_len, FALSE);
1503 proto_tree* mux_tree = proto_item_add_subtree( mux_item, ett_mux );
1504 proto_tree_add_item( mux_tree, hf_rtcp_app_mux_mux, tvb, offset, 1, FALSE );
1505 proto_tree_add_item( mux_tree, hf_rtcp_app_mux_cp, tvb, offset, 1, FALSE );
1506 proto_tree_add_item( mux_tree, hf_rtcp_app_mux_selection, tvb, offset, 1, FALSE );
1507 local_port = tvb_get_ntohs( tvb, offset+2 );
1508 proto_tree_add_uint( mux_tree, hf_rtcp_app_mux_localmuxport, tvb, offset+2, 2, local_port*2 );
1512 /* fall back to just showing the data if it's the wrong length */
1513 proto_tree_add_item( tree, hf_rtcp_app_data, tvb, offset, packet_len, FALSE );
1515 offset += packet_len;
1521 tvbuff_t *next_tvb; /* tvb to pass to subdissector */
1522 /* tvb == Pass the entire APP payload so the subdissector can have access to the
1525 next_tvb = tvb_new_subset(tvb, offset-8, app_length+4, app_length+4);
1526 /* look for registered sub-dissectors */
1527 if (dissector_try_string(rtcp_dissector_table, ascii_name, next_tvb, pinfo, tree)) {
1528 /* found subdissector - return tvb_length */
1532 /* If there's padding present, we have to remove that from the data part
1533 * The last octet of the packet contains the length of the padding
1535 packet_len -= tvb_get_guint8( tvb, offset + packet_len - 1 );
1537 offset += packet_len;
1542 /* Unhandled application type, just show app name and raw data */
1543 col_append_fstr(pinfo->cinfo, COL_INFO,"( %s ) subtype=%u",ascii_name, rtcp_subtype);
1546 /* Applications specific data */
1548 /* If there's padding present, we have to remove that from the data part
1549 * The last octet of the packet contains the length of the padding
1551 packet_len -= tvb_get_guint8( tvb, offset + packet_len - 1 );
1553 proto_tree_add_item( tree, hf_rtcp_app_data, tvb, offset, packet_len, FALSE );
1554 offset += packet_len;
1564 dissect_rtcp_bye( tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *tree,
1565 unsigned int count )
1567 unsigned int chunk = 1;
1568 unsigned int reason_length = 0;
1569 gint reason_offset = 0;
1570 char* reason_text = NULL;
1572 while ( chunk <= count ) {
1573 /* source identifier, 32 bits */
1574 proto_tree_add_item( tree, hf_rtcp_ssrc_source, tvb, offset, 4, FALSE);
1579 if ( tvb_reported_length_remaining( tvb, offset ) > 0 ) {
1580 /* Bye reason consists of an 8 bit length l and a string with length l */
1581 reason_length = tvb_get_guint8( tvb, offset );
1582 proto_tree_add_item( tree, hf_rtcp_sdes_length, tvb, offset, 1, FALSE );
1585 reason_offset = offset;
1586 reason_text = (char*)tvb_get_ephemeral_string(tvb, offset, reason_length);
1587 proto_tree_add_string( tree, hf_rtcp_sdes_text, tvb, offset, reason_length, reason_text );
1588 offset += reason_length;
1591 /* BYE packet padded out if string didn't fit in previous word */
1594 gint pad_size = (4 - (offset % 4));
1598 for (i = 0; i < pad_size; i++)
1600 if ((!(tvb_offset_exists(tvb, offset + i))) ||
1601 (tvb_get_guint8(tvb, offset + i) != 0))
1604 ti = proto_tree_add_none_format(tree, hf_rtcp_bye_reason_not_padded,
1605 tvb, reason_offset, reason_length,
1606 "Reason string is not NULL padded (see RFC3550, section 6.6)");
1607 expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_WARN,
1608 "Reason string is not NULL padded (see RFC3550, section 6.6)");
1609 PROTO_ITEM_SET_GENERATED(ti);
1620 dissect_rtcp_sdes( tvbuff_t *tvb, int offset, proto_tree *tree,
1621 unsigned int count )
1623 unsigned int chunk = 1;
1624 proto_item *sdes_item;
1625 proto_tree *sdes_tree;
1626 proto_tree *sdes_item_tree;
1629 int items_start_offset;
1631 unsigned int item_len = 0;
1632 unsigned int sdes_type = 0;
1633 unsigned int prefix_len = 0;
1635 while ( chunk <= count ) {
1636 /* Create a subtree for this chunk; we don't yet know
1638 start_offset = offset;
1640 ssrc = tvb_get_ntohl( tvb, offset );
1641 sdes_item = proto_tree_add_text(tree, tvb, offset, -1,
1642 "Chunk %u, SSRC/CSRC 0x%X", chunk, ssrc);
1643 sdes_tree = proto_item_add_subtree( sdes_item, ett_sdes );
1645 /* SSRC_n source identifier, 32 bits */
1646 proto_tree_add_item( sdes_tree, hf_rtcp_ssrc_source, tvb, offset, 4, FALSE );
1649 /* Create a subtree for the SDES items; we don't yet know
1651 items_start_offset = offset;
1652 ti = proto_tree_add_text(sdes_tree, tvb, offset, -1,
1654 sdes_item_tree = proto_item_add_subtree( ti, ett_sdes_item );
1657 * Not every message is ended with "null" bytes, so check for
1658 * end of frame as well.
1660 while ( tvb_reported_length_remaining( tvb, offset ) > 0 ) {
1662 sdes_type = tvb_get_guint8( tvb, offset );
1663 proto_tree_add_item( sdes_item_tree, hf_rtcp_sdes_type, tvb, offset, 1, FALSE );
1666 if ( sdes_type == RTCP_SDES_END ) {
1671 /* Item length, 8 bits */
1672 item_len = tvb_get_guint8( tvb, offset );
1673 proto_tree_add_item( sdes_item_tree, hf_rtcp_sdes_length, tvb, offset, 1, FALSE );
1676 if ( item_len != 0 ) {
1677 if ( sdes_type == RTCP_SDES_PRIV ) {
1678 /* PRIV adds two items between the
1679 * SDES length and value - an 8 bit
1680 * length giving the length of a
1681 * "prefix string", and the string.
1683 prefix_len = tvb_get_guint8( tvb, offset );
1684 if ( prefix_len + 1 > item_len ) {
1685 proto_tree_add_uint_format( sdes_item_tree,
1686 hf_rtcp_sdes_prefix_len, tvb,
1687 offset, 1, prefix_len,
1688 "Prefix length: %u (bogus, must be <= %u)",
1689 prefix_len, item_len - 1);
1693 proto_tree_add_item( sdes_item_tree, hf_rtcp_sdes_prefix_len, tvb, offset, 1, FALSE );
1696 proto_tree_add_item( sdes_item_tree, hf_rtcp_sdes_prefix_string, tvb, offset, prefix_len, FALSE );
1697 offset += prefix_len;
1698 item_len -= prefix_len +1;
1699 if ( item_len == 0 )
1702 proto_tree_add_item( sdes_item_tree, hf_rtcp_sdes_text, tvb, offset, item_len, FALSE );
1707 /* Set the length of the items subtree. */
1708 proto_item_set_len(ti, offset - items_start_offset);
1710 /* 32 bits = 4 bytes, so.....
1711 * If offset % 4 != 0, we divide offset by 4, add one and then
1712 * multiply by 4 again to reach the boundary
1714 if ( offset % 4 != 0 )
1715 offset = ((offset / 4) + 1 ) * 4;
1717 /* Set the length of this chunk. */
1718 proto_item_set_len(sdes_item, offset - start_offset);
1726 static void parse_xr_type_specific_field(tvbuff_t *tvb, gint offset, guint block_type, proto_tree *tree)
1728 guint8 flags = tvb_get_guint8(tvb, offset);
1730 switch (block_type) {
1731 case RTCP_XR_LOSS_RLE:
1732 case RTCP_XR_DUP_RLE:
1733 case RTCP_XR_PKT_RXTIMES:
1734 proto_tree_add_item(tree, hf_rtcp_xr_thinning, tvb, offset, 1, FALSE);
1737 case RTCP_XR_STATS_SUMRY:
1738 proto_tree_add_boolean(tree, hf_rtcp_xr_stats_loss_flag, tvb, offset, 1, flags);
1739 proto_tree_add_boolean(tree, hf_rtcp_xr_stats_dup_flag, tvb, offset, 1, flags);
1740 proto_tree_add_boolean(tree, hf_rtcp_xr_stats_jitter_flag, tvb, offset, 1, flags);
1741 proto_tree_add_item(tree, hf_rtcp_xr_stats_ttl, tvb, offset, 1, FALSE);
1745 proto_tree_add_item(tree, hf_rtcp_xr_block_specific, tvb, offset, 1, FALSE);
1750 static gboolean validate_xr_block_length(tvbuff_t *tvb, packet_info *pinfo, int offset, guint block_type, guint block_len, proto_tree *tree)
1754 ti = proto_tree_add_uint(tree, hf_rtcp_xr_block_length, tvb, offset, 2, block_len);
1755 switch (block_type) {
1756 case RTCP_XR_REF_TIME:
1758 expert_add_info_format(pinfo, ti, PI_PROTOCOL, PI_WARN,
1759 "Invalid block length, should be 2");
1762 case RTCP_XR_STATS_SUMRY:
1764 expert_add_info_format(pinfo, ti, PI_PROTOCOL, PI_WARN,
1765 "Invalid block length, should be 9");
1768 case RTCP_XR_VOIP_METRCS:
1769 case RTCP_XR_BT_XNQ:
1771 expert_add_info_format(pinfo, ti, PI_PROTOCOL, PI_WARN,
1772 "Invalid block length, should be 8");
1782 dissect_rtcp_xr(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *tree, gint packet_len)
1784 guint block_num = 1;
1785 guint temp_value = 0; /* used when checking spare bits in block type 8 */
1787 /* Packet length should at least be 4 */
1788 if (packet_len < 4) {
1789 proto_tree_add_text(tree, tvb, offset, packet_len, "Missing Sender SSRC");
1790 return offset + packet_len;
1794 proto_tree_add_item( tree, hf_rtcp_ssrc_sender, tvb, offset, 4, FALSE );
1798 for(;packet_len > 0; block_num++) {
1799 guint block_type = tvb_get_guint8(tvb, offset), block_length = 0;
1800 gint content_length = 0;
1801 gboolean valid = TRUE;
1803 /* Create a subtree for this block, dont know the length yet*/
1804 proto_item *block = proto_tree_add_text(tree, tvb, offset, -1, "Block %u", block_num);
1805 proto_tree *xr_block_tree = proto_item_add_subtree(block, ett_xr_block);
1806 proto_item *contents = NULL;
1807 proto_item *content_tree = NULL;
1809 proto_tree_add_item(xr_block_tree, hf_rtcp_xr_block_type, tvb, offset, 1, FALSE);
1811 if (packet_len >= 2) {
1812 parse_xr_type_specific_field(tvb, offset + 1, block_type, xr_block_tree);
1813 if (packet_len >= 4) {
1814 block_length = tvb_get_ntohs(tvb, offset + 2);
1815 valid = validate_xr_block_length(tvb, pinfo, offset + 2, block_type, block_length, xr_block_tree);
1818 proto_tree_add_text(xr_block_tree, tvb, offset + 1, packet_len, "Missing Required Block Headers");
1819 return offset + packet_len;
1822 content_length = block_length * 4;
1823 proto_item_set_len(block, content_length + 4);
1825 if (content_length > packet_len) {
1826 proto_tree_add_text(xr_block_tree, tvb, offset + 2, 2, "Block length is greater than packet length");
1832 contents = proto_tree_add_text(xr_block_tree, tvb, offset, content_length, "Contents");
1833 content_tree = proto_item_add_subtree(contents, ett_xr_block_contents);
1835 switch (block_type) {
1836 case RTCP_XR_VOIP_METRCS: {
1837 guint fraction_rate;
1840 proto_tree_add_item(content_tree, hf_rtcp_ssrc_source, tvb, offset, 4, FALSE);
1844 fraction_rate = tvb_get_guint8(tvb, offset);
1845 proto_tree_add_uint_format(content_tree, hf_rtcp_ssrc_fraction, tvb, offset, 1,
1846 fraction_rate, "Fraction lost: %u / 256", fraction_rate);
1850 fraction_rate = tvb_get_guint8(tvb, offset);
1851 proto_tree_add_uint_format(content_tree, hf_rtcp_ssrc_discarded, tvb, offset, 1,
1852 fraction_rate, "Fraction Discarded: %u / 256", fraction_rate);
1856 proto_tree_add_item(content_tree, hf_rtcp_xr_voip_metrics_burst_density, tvb, offset, 1, FALSE);
1860 proto_tree_add_item(content_tree, hf_rtcp_xr_voip_metrics_gap_density, tvb, offset, 1, FALSE);
1863 /* Burst Duration */
1864 proto_tree_add_item(content_tree, hf_rtcp_xr_voip_metrics_burst_duration, tvb, offset, 2, FALSE);
1868 proto_tree_add_item(content_tree, hf_rtcp_xr_voip_metrics_gap_duration, tvb, offset, 2, FALSE);
1871 /* Round Trip Delay */
1872 proto_tree_add_item(content_tree, hf_rtcp_xr_voip_metrics_rtdelay, tvb, offset, 2, FALSE);
1875 /* End System Delay */
1876 proto_tree_add_item(content_tree, hf_rtcp_xr_voip_metrics_esdelay, tvb, offset, 2, FALSE);
1880 proto_tree_add_item(content_tree, hf_rtcp_xr_voip_metrics_siglevel, tvb, offset, 1, FALSE);
1884 proto_tree_add_item(content_tree, hf_rtcp_xr_voip_metrics_noiselevel, tvb, offset, 1, FALSE);
1888 proto_tree_add_item(content_tree, hf_rtcp_xr_voip_metrics_rerl, tvb, offset, 1, FALSE);
1892 proto_tree_add_item(content_tree, hf_rtcp_xr_voip_metrics_gmin, tvb, offset, 1, FALSE);
1896 proto_tree_add_item(content_tree, hf_rtcp_xr_voip_metrics_rfactor, tvb, offset, 1, FALSE);
1899 /* external R Factor */
1900 proto_tree_add_item(content_tree, hf_rtcp_xr_voip_metrics_extrfactor, tvb, offset, 1, FALSE);
1904 proto_tree_add_float(content_tree, hf_rtcp_xr_voip_metrics_moslq, tvb, offset, 1,
1905 (float) (tvb_get_guint8(tvb, offset) / 10.0));
1909 proto_tree_add_float(content_tree, hf_rtcp_xr_voip_metrics_moscq, tvb, offset, 1,
1910 (float) (tvb_get_guint8(tvb, offset) / 10.0));
1913 /* PLC, JB Adaptive, JB Rate */
1914 proto_tree_add_item(content_tree, hf_rtcp_xr_voip_metrics_plc, tvb, offset, 1, FALSE);
1915 proto_tree_add_item(content_tree, hf_rtcp_xr_voip_metrics_jbadaptive, tvb, offset, 1, FALSE);
1916 proto_tree_add_item(content_tree, hf_rtcp_xr_voip_metrics_jbrate, tvb, offset, 1, FALSE);
1917 offset += 2; /* skip over reseved bit */
1920 proto_tree_add_item(content_tree, hf_rtcp_xr_voip_metrics_jbnominal, tvb, offset, 2, FALSE);
1924 proto_tree_add_item(content_tree, hf_rtcp_xr_voip_metrics_jbmax, tvb, offset, 2, FALSE);
1928 proto_tree_add_item(content_tree, hf_rtcp_xr_voip_metrics_jbabsmax, tvb, offset, 2, FALSE);
1934 case RTCP_XR_STATS_SUMRY: {
1936 proto_tree_add_item(content_tree, hf_rtcp_ssrc_source, tvb, offset, 4, FALSE);
1940 proto_tree_add_item(content_tree, hf_rtcp_xr_beginseq, tvb, offset, 2, FALSE);
1944 proto_tree_add_item(content_tree, hf_rtcp_xr_endseq, tvb, offset, 2, FALSE);
1948 proto_tree_add_item(content_tree, hf_rtcp_xr_stats_lost, tvb, offset, 4, FALSE);
1952 proto_tree_add_item(content_tree, hf_rtcp_xr_stats_dups, tvb, offset, 4, FALSE);
1956 proto_tree_add_item(content_tree, hf_rtcp_xr_stats_minjitter, tvb, offset, 4, FALSE);
1960 proto_tree_add_item(content_tree, hf_rtcp_xr_stats_maxjitter, tvb, offset, 4, FALSE);
1964 proto_tree_add_item(content_tree, hf_rtcp_xr_stats_meanjitter, tvb, offset, 4, FALSE);
1968 proto_tree_add_item(content_tree, hf_rtcp_xr_stats_devjitter, tvb, offset, 4, FALSE);
1972 proto_tree_add_item(content_tree, hf_rtcp_xr_stats_minttl, tvb, offset, 1, FALSE);
1976 proto_tree_add_item(content_tree, hf_rtcp_xr_stats_maxttl, tvb, offset, 1, FALSE);
1980 proto_tree_add_item(content_tree, hf_rtcp_xr_stats_meanttl, tvb, offset, 1, FALSE);
1984 proto_tree_add_item(content_tree, hf_rtcp_xr_stats_devttl, tvb, offset, 1, FALSE);
1990 case RTCP_XR_REF_TIME: {
1991 guint32 ts_msw, ts_lsw;
1993 ts_msw = tvb_get_ntohl(tvb, offset);
1994 proto_tree_add_text(content_tree, tvb, offset, 4, "Timestamp, MSW: %u", ts_msw);
1996 ts_lsw = tvb_get_ntohl(tvb, offset);
1997 proto_tree_add_text(content_tree, tvb, offset, 4, "Timestamp, LSW: %u", ts_lsw);
2003 case RTCP_XR_DLRR: {
2004 /* Each report block is 12 bytes */
2005 gint sources = content_length / 12;
2007 for(counter = 0; counter < sources; counter++) {
2008 /* Create a new subtree for a length of 12 bytes */
2009 proto_tree *ti = proto_tree_add_text(content_tree, tvb, offset, 12, "Source %u", counter + 1);
2010 proto_tree *ssrc_tree = proto_item_add_subtree(ti, ett_xr_ssrc);
2012 /* SSRC_n source identifier, 32 bits */
2013 proto_tree_add_item(ssrc_tree, hf_rtcp_ssrc_source, tvb, offset, 4, FALSE);
2016 /* Last RR timestamp */
2017 proto_tree_add_item(ssrc_tree, hf_rtcp_xr_lrr, tvb, offset, 4, FALSE);
2020 /* Delay since last RR timestamp */
2021 proto_tree_add_item(ssrc_tree, hf_rtcp_xr_dlrr, tvb, offset, 4, FALSE);
2025 if (content_length % 12 != 0)
2026 offset += content_length % 12;
2030 case RTCP_XR_PKT_RXTIMES: {
2031 /* 8 bytes of fixed header */
2032 gint count = 0, skip = 8;
2036 proto_tree_add_item(content_tree, hf_rtcp_ssrc_source, tvb, offset, 4, FALSE);
2040 begin = tvb_get_ntohs(tvb, offset);
2041 proto_tree_add_item(content_tree, hf_rtcp_xr_beginseq, tvb, offset, 2, FALSE);
2045 proto_tree_add_item(content_tree, hf_rtcp_xr_endseq, tvb, offset, 2, FALSE);
2048 for(count = 0; skip < content_length; skip += 4, count++) {
2049 proto_tree_add_text(content_tree, tvb, offset, 4, "Seq: %u, Timestamp: %u",
2050 (begin + count) % 65536, FALSE);
2056 case RTCP_XR_LOSS_RLE:
2057 case RTCP_XR_DUP_RLE: {
2058 /* 8 bytes of fixed header */
2059 gint count = 0, skip = 8;
2061 proto_item *chunks_item;
2062 proto_tree *chunks_tree;
2065 proto_tree_add_item(content_tree, hf_rtcp_ssrc_source, tvb, offset, 4, FALSE);
2069 begin = tvb_get_ntohs(tvb, offset);
2070 proto_tree_add_item(content_tree, hf_rtcp_xr_beginseq, tvb, offset, 2, FALSE);
2074 proto_tree_add_item(content_tree, hf_rtcp_xr_endseq, tvb, offset, 2, FALSE);
2078 chunks_item = proto_tree_add_text(content_tree, tvb, offset, content_length,"Report Chunks");
2079 chunks_tree = proto_item_add_subtree(chunks_item, ett_xr_loss_chunk);
2081 for(count = 1; skip < content_length; skip += 2, count++) {
2082 guint value = tvb_get_ntohs(tvb, offset);
2085 proto_tree_add_text(chunks_tree, tvb, offset, 2,
2086 "Chunk: %u -- Null Terminator ",
2088 } else if ( ! ( value & 0x8000 )) {
2089 const gchar* run_type = (value & 0x4000) ? "1s" : "0s";
2091 proto_tree_add_text(chunks_tree, tvb, offset, 2,
2092 "Chunk: %u -- Length Run %s, length: %u",
2093 count, run_type, value);
2096 other_decode_bitfield_value(bits, value, 0x00007FFF, 16);
2097 proto_tree_add_text(chunks_tree, tvb, offset, 2,
2098 "Chunk: %u -- Bit Vector, bits: %s",
2106 case RTCP_XR_BT_XNQ: { /* BT XNQ block as defined in RFC5093 */
2108 proto_tree_add_item(content_tree, hf_rtcp_xr_btxnq_begseq, tvb, offset, 2, FALSE); /* Begin Sequence number */
2109 proto_tree_add_item(content_tree, hf_rtcp_xr_btxnq_endseq, tvb, offset+2, 2, FALSE); /* End Sequence number */
2112 proto_tree_add_item(content_tree, hf_rtcp_xr_btxnq_vmaxdiff, tvb, offset, 2, FALSE); /* vmaxdiff */
2113 proto_tree_add_item(content_tree, hf_rtcp_xr_btxnq_vrange, tvb, offset+2, 2, FALSE); /* vrange */
2116 proto_tree_add_item(content_tree, hf_rtcp_xr_btxnq_vsum, tvb, offset, 4, FALSE); /* vsum */
2119 proto_tree_add_item(content_tree, hf_rtcp_xr_btxnq_cycles, tvb, offset, 2, FALSE); /* cycle count */
2120 proto_tree_add_item(content_tree, hf_rtcp_xr_btxnq_jbevents, tvb, offset+2, 2, FALSE); /* jitter buffer events */
2123 temp_value = tvb_get_ntohl(tvb, offset); /* tDegNet */
2124 if( (temp_value & 0x0ff000000) != 0)
2125 proto_tree_add_string(content_tree, hf_rtcp_xr_btxnq_spare, tvb, offset, 1, "Warning - spare bits not 0");
2126 proto_tree_add_uint(content_tree, hf_rtcp_xr_btxnq_tdegnet, tvb, offset+1, 3, temp_value & 0x0ffffff);
2129 temp_value = tvb_get_ntohl(tvb, offset); /* tDegJit */
2130 if( (temp_value & 0x0ff000000) != 0)
2131 proto_tree_add_string(content_tree, hf_rtcp_xr_btxnq_spare, tvb, offset, 1, "Warning - spare bits not 0");
2132 proto_tree_add_uint(content_tree, hf_rtcp_xr_btxnq_tdegjit, tvb, offset+1, 3, temp_value & 0x0ffffff);
2135 temp_value = tvb_get_ntohl(tvb, offset); /* ES */
2136 if( (temp_value & 0x0ff000000) != 0)
2137 proto_tree_add_string(content_tree, hf_rtcp_xr_btxnq_spare, tvb, offset, 1, "Warning - spare bits not 0");
2138 proto_tree_add_uint(content_tree, hf_rtcp_xr_btxnq_es, tvb, offset+1, 3, temp_value & 0x0ffffff);
2141 temp_value = tvb_get_ntohl(tvb, offset); /* SES */
2142 if( (temp_value & 0x0ff000000) != 0)
2143 proto_tree_add_string(content_tree, hf_rtcp_xr_btxnq_spare, tvb, offset, 1, "Warning - spare bits not 0");
2144 proto_tree_add_uint(content_tree, hf_rtcp_xr_btxnq_ses, tvb, offset+1, 3, temp_value & 0x0ffffff);
2150 /* skip over the unknown block */
2151 offset += content_length;
2154 packet_len -= content_length;
2160 dissect_rtcp_rr( packet_info *pinfo, tvbuff_t *tvb, int offset, proto_tree *tree,
2161 unsigned int count, unsigned int packet_length )
2163 unsigned int counter = 1;
2164 proto_tree *ssrc_tree = (proto_tree*) NULL;
2165 proto_tree *ssrc_sub_tree = (proto_tree*) NULL;
2166 proto_tree *high_sec_tree = (proto_tree*) NULL;
2167 proto_item *ti = (proto_item*) NULL;
2169 int rr_offset = offset;
2172 while ( counter <= count ) {
2175 /* Create a new subtree for a length of 24 bytes */
2176 ti = proto_tree_add_text(tree, tvb, offset, 24,
2177 "Source %u", counter );
2178 ssrc_tree = proto_item_add_subtree( ti, ett_ssrc );
2180 /* SSRC_n source identifier, 32 bits */
2181 proto_tree_add_item( ssrc_tree, hf_rtcp_ssrc_source, tvb, offset, 4, FALSE );
2184 ti = proto_tree_add_text(ssrc_tree, tvb, offset, 20, "SSRC contents" );
2185 ssrc_sub_tree = proto_item_add_subtree( ti, ett_ssrc_item );
2187 /* Fraction lost, 8bits */
2188 rr_flt = tvb_get_guint8( tvb, offset );
2189 proto_tree_add_uint_format( ssrc_sub_tree, hf_rtcp_ssrc_fraction, tvb,
2190 offset, 1, rr_flt, "Fraction lost: %u / 256", rr_flt );
2193 /* Cumulative number of packets lost, 24 bits */
2194 proto_tree_add_item( ssrc_sub_tree, hf_rtcp_ssrc_cum_nr, tvb,
2198 /* Extended highest sequence nr received, 32 bits
2199 * Just for the sake of it, let's add another subtree
2200 * because this might be a little clearer
2202 ti = proto_tree_add_item( ssrc_tree, hf_rtcp_ssrc_ext_high_seq,
2203 tvb, offset, 4, FALSE );
2204 high_sec_tree = proto_item_add_subtree( ti, ett_ssrc_ext_high );
2205 /* Sequence number cycles */
2206 proto_tree_add_item( high_sec_tree, hf_rtcp_ssrc_high_cycles,
2207 tvb, offset, 2, FALSE );
2209 /* highest sequence number received */
2210 proto_tree_add_item( high_sec_tree, hf_rtcp_ssrc_high_seq,
2211 tvb, offset, 2, FALSE );
2214 /* Interarrival jitter */
2215 proto_tree_add_item( ssrc_tree, hf_rtcp_ssrc_jitter, tvb,
2219 /* Last SR timestamp */
2220 lsr = tvb_get_ntohl( tvb, offset );
2221 proto_tree_add_item( ssrc_tree, hf_rtcp_ssrc_lsr, tvb,
2225 /* Delay since last SR timestamp */
2226 dlsr = tvb_get_ntohl( tvb, offset );
2227 ti = proto_tree_add_item( ssrc_tree, hf_rtcp_ssrc_dlsr, tvb,
2229 proto_item_append_text(ti, " (%d milliseconds)",
2230 (int)(((double)dlsr/(double)65536) * 1000.0));
2233 /* Do roundtrip calculation */
2234 if (global_rtcp_show_roundtrip_calculation)
2236 /* Based on delay since SR was sent in other direction */
2237 calculate_roundtrip_delay(tvb, pinfo, ssrc_tree, lsr, dlsr);
2243 /* If length remaining, assume profile-specific extension bytes */
2244 if ((offset-rr_offset) < (int)packet_length)
2246 proto_tree_add_item(tree, hf_rtcp_profile_specific_extension, tvb, offset,
2247 packet_length - (offset - rr_offset), FALSE);
2248 offset = rr_offset + packet_length;
2255 dissect_rtcp_sr( packet_info *pinfo, tvbuff_t *tvb, int offset, proto_tree *tree,
2256 unsigned int count, unsigned int packet_length )
2259 guint32 ts_msw, ts_lsw;
2261 int sr_offset = offset;
2264 ts_msw = tvb_get_ntohl(tvb, offset);
2265 proto_tree_add_item(tree, hf_rtcp_ntp_msw, tvb, offset, 4, FALSE);
2267 ts_lsw = tvb_get_ntohl(tvb, offset+4);
2268 proto_tree_add_item(tree, hf_rtcp_ntp_lsw, tvb, offset+4, 4, FALSE);
2270 buff=ntp_fmt_ts(tvb_get_ptr( tvb, offset, 8 ));
2271 item = proto_tree_add_string_format( tree, hf_rtcp_ntp, tvb, offset, 8, buff, "MSW and LSW as NTP timestamp: %s", buff );
2272 PROTO_ITEM_SET_GENERATED(item);
2275 /* RTP timestamp, 32 bits */
2276 proto_tree_add_item( tree, hf_rtcp_rtp_timestamp, tvb, offset, 4, FALSE );
2278 /* Sender's packet count, 32 bits */
2279 proto_tree_add_item( tree, hf_rtcp_sender_pkt_cnt, tvb, offset, 4, FALSE );
2281 /* Sender's octet count, 32 bits */
2282 proto_tree_add_item( tree, hf_rtcp_sender_oct_cnt, tvb, offset, 4, FALSE );
2285 /* Record the time of this packet in the sender's conversation */
2286 if (global_rtcp_show_roundtrip_calculation)
2288 /* Use middle 32 bits of 64-bit time value */
2289 guint32 lsr = ((ts_msw & 0x0000ffff) << 16 | (ts_lsw & 0xffff0000) >> 16);
2291 /* Record the time that we sent this in appropriate conversation */
2292 remember_outgoing_sr(pinfo, lsr);
2295 /* The rest of the packet is equal to the RR packet */
2297 offset = dissect_rtcp_rr( pinfo, tvb, offset, tree, count, packet_length-(offset-sr_offset) );
2300 /* If length remaining, assume profile-specific extension bytes */
2301 if ((offset-sr_offset) < (int)packet_length)
2303 proto_tree_add_item(tree, hf_rtcp_profile_specific_extension, tvb, offset,
2304 packet_length - (offset - sr_offset), FALSE);
2305 offset = sr_offset + packet_length;
2312 /* Look for conversation info and display any setup info found */
2313 void show_setup_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2315 /* Conversation and current data */
2316 conversation_t *p_conv = NULL;
2317 struct _rtcp_conversation_info *p_conv_data = NULL;
2319 /* Use existing packet data if available */
2320 p_conv_data = p_get_proto_data(pinfo->fd, proto_rtcp);
2324 /* First time, get info from conversation */
2325 p_conv = find_conversation(pinfo->fd->num, &pinfo->net_dst, &pinfo->net_src,
2327 pinfo->destport, pinfo->srcport, NO_ADDR_B);
2331 /* Look for data in conversation */
2332 struct _rtcp_conversation_info *p_conv_packet_data;
2333 p_conv_data = conversation_get_proto_data(p_conv, proto_rtcp);
2337 /* Save this conversation info into packet info */
2338 p_conv_packet_data = se_alloc(sizeof(struct _rtcp_conversation_info));
2339 memcpy(p_conv_packet_data, p_conv_data,
2340 sizeof(struct _rtcp_conversation_info));
2342 p_add_proto_data(pinfo->fd, proto_rtcp, p_conv_packet_data);
2347 /* Create setup info subtree with summary info. */
2348 if (p_conv_data && p_conv_data->setup_method_set)
2350 proto_tree *rtcp_setup_tree;
2351 proto_item *ti = proto_tree_add_string_format(tree, hf_rtcp_setup, tvb, 0, 0,
2353 "Stream setup by %s (frame %u)",
2354 p_conv_data->setup_method,
2355 p_conv_data->setup_frame_number);
2356 PROTO_ITEM_SET_GENERATED(ti);
2357 rtcp_setup_tree = proto_item_add_subtree(ti, ett_rtcp_setup);
2358 if (rtcp_setup_tree)
2360 /* Add details into subtree */
2361 proto_item* item = proto_tree_add_uint(rtcp_setup_tree, hf_rtcp_setup_frame,
2362 tvb, 0, 0, p_conv_data->setup_frame_number);
2363 PROTO_ITEM_SET_GENERATED(item);
2364 item = proto_tree_add_string(rtcp_setup_tree, hf_rtcp_setup_method,
2365 tvb, 0, 0, p_conv_data->setup_method);
2366 PROTO_ITEM_SET_GENERATED(item);
2372 /* Update conversation data to record time that outgoing rr/sr was sent */
2373 static void remember_outgoing_sr(packet_info *pinfo, long lsr)
2375 conversation_t *p_conv = NULL;
2376 struct _rtcp_conversation_info *p_conv_data = NULL;
2377 struct _rtcp_conversation_info *p_packet_data = NULL;
2379 /* This information will be accessed when an incoming packet comes back to
2380 the side that sent this packet, so no use storing in the packet
2381 info. However, do store the fact that we've already set this info
2385 /**************************************************************************/
2386 /* First of all, see if we've already stored this information for this sr */
2388 /* Look first in packet info */
2389 p_packet_data = p_get_proto_data(pinfo->fd, proto_rtcp);
2390 if (p_packet_data && p_packet_data->last_received_set &&
2391 p_packet_data->last_received_frame_number >= pinfo->fd->num)
2393 /* We already did this, OK */
2398 /**************************************************************************/
2399 /* Otherwise, we want to find/create the conversation and update it */
2401 /* First time, get info from conversation.
2402 Even though we think of this as an outgoing packet being sent,
2403 we store the time as being received by the destination. */
2404 p_conv = find_conversation(pinfo->fd->num, &pinfo->net_dst, &pinfo->net_src,
2406 pinfo->destport, pinfo->srcport, NO_ADDR_B);
2408 /* If the conversation doesn't exist, create it now. */
2411 p_conv = conversation_new(pinfo->fd->num, &pinfo->net_dst, &pinfo->net_src, PT_UDP,
2412 pinfo->destport, pinfo->srcport,
2416 /* Give up if can't create it */
2422 /****************************************************/
2423 /* Now find/create conversation data */
2424 p_conv_data = conversation_get_proto_data(p_conv, proto_rtcp);
2427 /* Allocate memory for data */
2428 p_conv_data = se_alloc0(sizeof(struct _rtcp_conversation_info));
2430 /* Add it to conversation. */
2431 conversation_add_proto_data(p_conv, proto_rtcp, p_conv_data);
2434 /*******************************************************/
2435 /* Update conversation data */
2436 p_conv_data->last_received_set = TRUE;
2437 p_conv_data->last_received_frame_number = pinfo->fd->num;
2438 p_conv_data->last_received_timestamp = pinfo->fd->abs_ts;
2439 p_conv_data->last_received_ts = lsr;
2442 /****************************************************************/
2443 /* Update packet info to record conversation state */
2445 /* Will use/create packet info */
2448 p_packet_data = se_alloc0(sizeof(struct _rtcp_conversation_info));
2450 p_add_proto_data(pinfo->fd, proto_rtcp, p_packet_data);
2453 /* Copy current conversation data into packet info */
2454 p_packet_data->last_received_set = TRUE;
2455 p_packet_data->last_received_frame_number = p_conv_data->last_received_frame_number;
2459 /* Use received sr to work out what the roundtrip delay is
2460 (at least between capture point and the other endpoint involved in
2461 the conversation) */
2462 static void calculate_roundtrip_delay(tvbuff_t *tvb, packet_info *pinfo,
2463 proto_tree *tree, guint32 lsr, guint32 dlsr)
2465 /*****************************************************/
2466 /* This is called dissecting an SR. We need to:
2467 - look in the packet info for stored calculation. If found, use.
2468 - look up the conversation of the sending side to see when the
2469 'last SR' was detected (received)
2470 - calculate the network delay using the that packet time,
2471 this packet time, and dlsr
2472 *****************************************************/
2474 conversation_t *p_conv = NULL;
2475 struct _rtcp_conversation_info *p_conv_data = NULL;
2476 struct _rtcp_conversation_info *p_packet_data = NULL;
2479 /*************************************************/
2480 /* Look for previous result */
2481 p_packet_data = p_get_proto_data(pinfo->fd, proto_rtcp);
2482 if (p_packet_data && p_packet_data->lsr_matched)
2485 add_roundtrip_delay_info(tvb, pinfo, tree,
2486 p_packet_data->calculated_delay_used_frame,
2487 p_packet_data->calculated_delay_report_gap,
2488 p_packet_data->calculated_delay);
2493 /********************************************************************/
2494 /* Look for captured timestamp of last SR in conversation of sender */
2495 /* of this packet */
2496 p_conv = find_conversation(pinfo->fd->num, &pinfo->net_src, &pinfo->net_dst,
2498 pinfo->srcport, pinfo->destport, NO_ADDR_B);
2504 /* Look for conversation data */
2505 p_conv_data = conversation_get_proto_data(p_conv, proto_rtcp);
2511 if (p_conv_data->last_received_set)
2513 /* Store result of calculation in packet info */
2516 /* Create packet info if it doesn't exist */
2517 p_packet_data = se_alloc0(sizeof(struct _rtcp_conversation_info));
2519 /* Set as packet info */
2520 p_add_proto_data(pinfo->fd, proto_rtcp, p_packet_data);
2523 /* Don't allow match seemingly calculated from same (or later!) frame */
2524 if (pinfo->fd->num <= p_conv_data->last_received_frame_number)
2529 /* The previous report must match the lsr given here */
2530 if (p_conv_data->last_received_ts == lsr)
2532 /* Look at time of since original packet was sent */
2533 gint seconds_between_packets = (gint)
2534 (pinfo->fd->abs_ts.secs - p_conv_data->last_received_timestamp.secs);
2535 gint nseconds_between_packets =
2536 pinfo->fd->abs_ts.nsecs - p_conv_data->last_received_timestamp.nsecs;
2538 gint total_gap = (seconds_between_packets*1000) +
2539 (nseconds_between_packets / 1000000);
2540 gint dlsr_ms = (int)(((double)dlsr/(double)65536) * 1000.0);
2543 /* Delay is gap - dlsr (N.B. this is allowed to be -ve) */
2544 delay = total_gap - dlsr_ms;
2546 /* Record that the LSR matches */
2547 p_packet_data->lsr_matched = TRUE;
2549 /* No useful calculation can be done if dlsr not set... */
2552 p_packet_data->calculated_delay = delay;
2553 p_packet_data->calculated_delay_report_gap = total_gap;
2554 p_packet_data->calculated_delay_used_frame = p_conv_data->last_received_frame_number;
2558 add_roundtrip_delay_info(tvb, pinfo, tree,
2559 p_conv_data->last_received_frame_number,
2566 /* Show the calcaulted roundtrip delay info by adding protocol tree items
2567 and appending text to the info column */
2568 static void add_roundtrip_delay_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2569 guint frame, guint gap_between_reports,
2572 /* 'Last SR' frame used in calculation. Show this even if no delay shown */
2573 proto_item* item = proto_tree_add_uint(tree,
2574 hf_rtcp_last_sr_timestamp_frame,
2576 PROTO_ITEM_SET_GENERATED(item);
2578 /* Time elapsed since 'Last SR' time in capture */
2579 item = proto_tree_add_uint(tree,
2580 hf_rtcp_time_since_last_sr,
2581 tvb, 0, 0, gap_between_reports);
2582 PROTO_ITEM_SET_GENERATED(item);
2584 /* Don't report on calculated delays below the threshold.
2585 Will report delays less than -threshold, to highlight
2586 problems with generated reports */
2587 if (abs(delay) < (int)global_rtcp_show_roundtrip_calculation_minimum)
2592 /* Calculated delay in ms */
2593 item = proto_tree_add_int(tree, hf_rtcp_roundtrip_delay, tvb, 0, 0, delay);
2594 PROTO_ITEM_SET_GENERATED(item);
2596 /* Add to expert info */
2599 expert_add_info_format(pinfo, item,
2600 PI_SEQUENCE, PI_NOTE,
2601 "RTCP round-trip delay detected (%d ms)",
2606 expert_add_info_format(pinfo, item,
2607 PI_SEQUENCE, PI_ERROR,
2608 "Negative RTCP round-trip delay detected (%d ms)",
2612 /* Report delay in INFO column */
2613 col_append_fstr(pinfo->cinfo, COL_INFO,
2614 " (roundtrip delay <-> %s = %dms, using frame %u) ",
2615 ep_address_to_str(&pinfo->net_src), delay, frame);
2619 rtcp_packet_type_to_tree( int rtcp_packet_type)
2621 int tree = ett_rtcp;
2623 switch(rtcp_packet_type) {
2624 case RTCP_SR: tree = ett_rtcp_sr; break;
2625 case RTCP_RR: tree = ett_rtcp_rr; break;
2626 case RTCP_SDES: tree = ett_rtcp_sdes; break;
2627 case RTCP_BYE: tree = ett_rtcp_bye; break;
2628 case RTCP_APP: tree = ett_rtcp_app; break;
2629 case RTCP_RTPFB: tree = ett_rtcp_rtpfb; break;
2630 case RTCP_PSFB: tree = ett_rtcp_psfb; break;
2631 case RTCP_XR: tree = ett_rtcp_xr; break;
2632 case RTCP_FIR: tree = ett_rtcp_fir; break;
2633 case RTCP_NACK: tree = ett_rtcp_nack; break;
2634 default: tree = ett_rtcp;
2640 dissect_rtcp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree )
2642 proto_item *ti = NULL;
2643 proto_tree *rtcp_tree = NULL;
2644 unsigned int temp_byte = 0;
2645 unsigned int padding_set = 0;
2646 unsigned int elem_count = 0;
2647 unsigned int packet_type = 0;
2648 unsigned int offset = 0;
2649 guint16 packet_length = 0;
2650 guint16 total_packet_length = 0;
2651 guint8 padding_length;
2652 unsigned int padding_offset = 0;
2653 guint rtcp_subtype = 0;
2654 guint32 app_length = 0;
2655 gboolean srtcp_encrypted = FALSE;
2656 gboolean srtcp_now_encrypted = FALSE;
2657 conversation_t *p_conv = NULL;
2658 struct _rtcp_conversation_info *p_conv_data = NULL;
2659 struct srtp_info *srtcp_info = NULL;
2661 guint32 srtcp_offset = 0;
2662 guint32 srtcp_index = 0;
2664 /* first see if this conversation is encrypted SRTP, and if so do not try to dissect the payload(s) */
2665 p_conv = find_conversation(pinfo->fd->num, &pinfo->net_src, &pinfo->net_dst,
2667 pinfo->srcport, pinfo->destport, NO_ADDR_B);
2670 p_conv_data = conversation_get_proto_data(p_conv, proto_rtcp);
2671 if (p_conv_data && p_conv_data->srtcp_info)
2673 srtcp_info = p_conv_data->srtcp_info;
2674 /* get the offset to the start of the SRTCP fields at the end of the packet */
2675 srtcp_offset = tvb_length_remaining(tvb,offset) - srtcp_info->auth_tag_len - srtcp_info->mki_len - 4;
2676 /* It has been setup as SRTCP, but skip to the SRTCP E field at the end
2677 to see if this particular packet is encrypted or not. The E bit is the MSB. */
2678 srtcp_index = tvb_get_ntohl(tvb,srtcp_offset);
2679 e_bit = (srtcp_index & 0x80000000) ? TRUE : FALSE;
2680 srtcp_index &= 0x7fffffff;
2682 if (srtcp_info->encryption_algorithm!=SRTP_ENC_ALG_NULL) {
2683 /* just flag it for now - the first SR or RR header and SSRC are unencrypted */
2685 srtcp_encrypted = TRUE;
2690 col_set_str(pinfo->cinfo, COL_PROTOCOL, (srtcp_info) ? "SRTCP" : "RTCP");
2693 * Check if there are at least 4 bytes left in the frame,
2694 * the last 16 bits of those is the length of the current
2695 * RTCP message. The last compound message contains padding,
2696 * that enables us to break from the while loop.
2698 while ( !srtcp_now_encrypted && tvb_bytes_exist( tvb, offset, 4) ) {
2700 * First retrieve the packet_type
2702 packet_type = tvb_get_guint8( tvb, offset + 1 );
2705 * Check if it's a valid type
2707 if ( ( packet_type < 192 ) || ( packet_type > 207 ) )
2710 col_add_fstr(pinfo->cinfo, COL_INFO, "%s ",
2711 val_to_str(packet_type, rtcp_packet_type_vals, "Unknown"));
2714 * get the packet-length for the complete RTCP packet
2716 packet_length = ( tvb_get_ntohs( tvb, offset + 2 ) + 1 ) * 4;
2717 total_packet_length += packet_length;
2719 ti = proto_tree_add_item(tree, proto_rtcp, tvb, offset, packet_length, FALSE );
2720 proto_item_append_text(ti, " (%s)",
2721 val_to_str(packet_type,
2722 rtcp_packet_type_vals,
2725 rtcp_tree = proto_item_add_subtree( ti, rtcp_packet_type_to_tree(packet_type) );
2727 /* Conversation setup info */
2728 if (global_rtcp_show_setup_info)
2730 show_setup_info(tvb, pinfo, rtcp_tree);
2734 temp_byte = tvb_get_guint8( tvb, offset );
2736 proto_tree_add_item( rtcp_tree, hf_rtcp_version, tvb,
2738 padding_set = RTCP_PADDING( temp_byte );
2739 padding_offset = offset + packet_length - 1;
2741 proto_tree_add_boolean( rtcp_tree, hf_rtcp_padding, tvb,
2742 offset, 1, temp_byte );
2743 elem_count = RTCP_COUNT( temp_byte );
2745 switch ( packet_type ) {
2748 /* Receiver report count, 5 bits */
2749 proto_tree_add_uint( rtcp_tree, hf_rtcp_rc, tvb, offset, 1, temp_byte );
2751 /* Packet type, 8 bits */
2752 proto_tree_add_item( rtcp_tree, hf_rtcp_pt, tvb, offset, 1, FALSE );
2754 /* Packet length in 32 bit words MINUS one, 16 bits */
2755 offset = dissect_rtcp_length_field(rtcp_tree, tvb, offset);
2756 /* Sender Synchronization source, 32 bits */
2757 proto_tree_add_item( rtcp_tree, hf_rtcp_ssrc_sender, tvb, offset, 4, FALSE );
2760 if (srtcp_encrypted) { /* rest of the payload is encrypted - do not try to dissect */
2761 srtcp_now_encrypted = TRUE;
2765 if ( packet_type == RTCP_SR )
2766 offset = dissect_rtcp_sr( pinfo, tvb, offset, rtcp_tree, elem_count, packet_length-8 );
2768 offset = dissect_rtcp_rr( pinfo, tvb, offset, rtcp_tree, elem_count, packet_length-8 );
2771 /* Source count, 5 bits */
2772 proto_tree_add_uint( rtcp_tree, hf_rtcp_sc, tvb, offset, 1, temp_byte );
2774 /* Packet type, 8 bits */
2775 proto_tree_add_item( rtcp_tree, hf_rtcp_pt, tvb, offset, 1, FALSE );
2777 /* Packet length in 32 bit words MINUS one, 16 bits */
2778 offset = dissect_rtcp_length_field(rtcp_tree, tvb, offset);
2779 offset = dissect_rtcp_sdes( tvb, offset, rtcp_tree, elem_count );
2782 /* Source count, 5 bits */
2783 proto_tree_add_uint( rtcp_tree, hf_rtcp_sc, tvb, offset, 1, temp_byte );
2785 /* Packet type, 8 bits */
2786 proto_tree_add_item( rtcp_tree, hf_rtcp_pt, tvb, offset, 1, FALSE );
2788 /* Packet length in 32 bit words MINUS one, 16 bits */
2789 offset = dissect_rtcp_length_field(rtcp_tree, tvb, offset);
2790 offset = dissect_rtcp_bye( tvb, pinfo, offset, rtcp_tree, elem_count );
2793 /* Subtype, 5 bits */
2794 rtcp_subtype = elem_count;
2795 proto_tree_add_uint( rtcp_tree, hf_rtcp_subtype, tvb, offset, 1, elem_count );
2797 /* Packet type, 8 bits */
2798 proto_tree_add_item( rtcp_tree, hf_rtcp_pt, tvb, offset, 1, FALSE );
2800 /* Packet length in 32 bit words MINUS one, 16 bits */
2801 app_length = tvb_get_ntohs( tvb, offset ) <<2;
2802 offset = dissect_rtcp_length_field(rtcp_tree, tvb, offset);
2803 offset = dissect_rtcp_app( tvb, pinfo, offset,rtcp_tree, padding_set, packet_length - 4, rtcp_subtype, app_length);
2806 /* Reserved, 5 bits, Ignore */
2808 /* Packet type, 8 bits */
2809 proto_tree_add_item( rtcp_tree, hf_rtcp_pt, tvb, offset, 1, FALSE );
2811 /* Packet length in 32 bit words MINUS one, 16 bits */
2812 offset = dissect_rtcp_length_field(rtcp_tree, tvb, offset);
2813 offset = dissect_rtcp_xr( tvb, pinfo, offset, rtcp_tree, packet_length - 4 );
2816 offset = dissect_rtcp_fir( tvb, offset, rtcp_tree );
2819 offset = dissect_rtcp_nack( tvb, offset, rtcp_tree );
2822 offset = dissect_rtcp_rtpfb( tvb, offset, rtcp_tree, ti );
2825 offset = dissect_rtcp_psfb( tvb, offset, rtcp_tree, packet_length );
2829 * To prevent endless loops in case of an unknown message type
2830 * increase offset. Some time the while will end :-)
2836 col_set_fence(pinfo->cinfo, COL_INFO);
2838 /* If the padding bit is set, the last octet of the
2839 * packet contains the length of the padding
2840 * We only have to check for this at the end of the LAST RTCP message
2842 if ( padding_set ) {
2843 /* The last RTCP message in the packet has padding - find it.
2845 * The padding count is found at an offset of padding_offset; it
2846 * contains the number of padding octets, including the padding
2849 padding_length = tvb_get_guint8( tvb, padding_offset);
2851 /* This length includes the padding length byte itself, so 0 is not
2853 if (padding_length != 0) {
2854 proto_tree_add_item( rtcp_tree, hf_rtcp_padding_data, tvb, offset, padding_length - 1, FALSE );
2855 offset += padding_length - 1;
2857 proto_tree_add_item( rtcp_tree, hf_rtcp_padding_count, tvb, offset, 1, FALSE );
2861 /* If the payload was encrypted, the main payload was not dissected */
2862 if (srtcp_encrypted == TRUE) {
2863 proto_tree_add_text(rtcp_tree, tvb, offset, srtcp_offset-offset, "Encrypted RTCP Payload - not dissected");
2864 proto_tree_add_item(rtcp_tree, hf_srtcp_e, tvb, srtcp_offset, 4, FALSE);
2865 proto_tree_add_uint(rtcp_tree, hf_srtcp_index, tvb, srtcp_offset, 4, srtcp_index);
2867 if (srtcp_info->mki_len) {
2868 proto_tree_add_item(rtcp_tree, hf_srtcp_mki, tvb, srtcp_offset, srtcp_info->mki_len, FALSE);
2869 srtcp_offset += srtcp_info->mki_len;
2872 if (srtcp_info->auth_tag_len) {
2873 proto_tree_add_item(rtcp_tree, hf_srtcp_auth_tag, tvb, srtcp_offset, srtcp_info->auth_tag_len, FALSE);
2874 srtcp_offset += srtcp_info->auth_tag_len;
2877 /* offset should be total_packet_length by now... */
2878 else if (offset == (unsigned int)total_packet_length)
2880 ti = proto_tree_add_boolean_format_value(tree, hf_rtcp_length_check, tvb,
2881 0, 0, TRUE, "OK - %u bytes",
2883 /* Hidden might be less annoying here...? */
2884 PROTO_ITEM_SET_GENERATED(ti);
2888 ti = proto_tree_add_boolean_format_value(tree, hf_rtcp_length_check, tvb,
2890 "Wrong (expected %u bytes, found %d)",
2891 total_packet_length, offset);
2892 PROTO_ITEM_SET_GENERATED(ti);
2894 expert_add_info_format(pinfo, ti,
2895 PI_MALFORMED, PI_WARN,
2896 "Incorrect RTCP packet length information (expected %u bytes, found %d)",
2897 total_packet_length, offset);
2902 proto_register_rtcp(void)
2904 static hf_register_info hf[] =
2913 VALS(rtcp_version_vals),
2933 "Reception report count",
2961 VALS( rtcp_packet_type_vals ),
2975 "32-bit words (-1) in packet", HFILL
2979 &hf_rtcp_ssrc_sender,
2991 &hf_rtcp_ssrc_media_source,
2993 "Media source SSRC",
3006 "rtcp.timestamp.ntp.msw",
3018 "rtcp.timestamp.ntp.lsw",
3030 "rtcp.timestamp.ntp",
3039 &hf_rtcp_rtp_timestamp,
3042 "rtcp.timestamp.rtp",
3051 &hf_rtcp_sender_pkt_cnt,
3053 "Sender's packet count",
3054 "rtcp.sender.packetcount",
3063 &hf_rtcp_sender_oct_cnt,
3065 "Sender's octet count",
3066 "rtcp.sender.octetcount",
3075 &hf_rtcp_ssrc_source,
3078 "rtcp.ssrc.identifier",
3087 &hf_rtcp_ssrc_fraction,
3090 "rtcp.ssrc.fraction",
3099 &hf_rtcp_ssrc_cum_nr,
3101 "Cumulative number of packets lost",
3111 &hf_rtcp_ssrc_ext_high_seq,
3113 "Extended highest sequence number received",
3114 "rtcp.ssrc.ext_high",
3123 &hf_rtcp_ssrc_high_seq,
3125 "Highest sequence number received",
3126 "rtcp.ssrc.high_seq",
3135 &hf_rtcp_ssrc_high_cycles,
3137 "Sequence number cycles count",
3138 "rtcp.ssrc.high_cycles",
3147 &hf_rtcp_ssrc_jitter,
3149 "Interarrival jitter",
3161 "Last SR timestamp",
3173 "Delay since last SR timestamp",
3185 "SSRC / CSRC identifier",
3186 "rtcp.sdes.ssrc_csrc",
3201 VALS( rtcp_sdes_type_vals ),
3207 &hf_rtcp_sdes_length,
3231 &hf_rtcp_sdes_prefix_len,
3234 "rtcp.sdes.prefix.length",
3243 &hf_rtcp_sdes_prefix_string,
3246 "rtcp.sdes.prefix.string",
3267 &hf_rtcp_name_ascii,
3281 "Application specific data",
3293 "PoC1 Application specific data",
3303 &hf_rtcp_app_poc1_subtype,
3306 "rtcp.app.PoC1.subtype",
3309 VALS(rtcp_app_poc1_floor_cnt_type_vals),
3315 &hf_rtcp_app_poc1_sip_uri,
3318 "rtcp.app.poc1.sip.uri",
3327 &hf_rtcp_app_poc1_disp_name,
3330 "rtcp.app.poc1.disp.name",
3339 &hf_rtcp_app_poc1_priority,
3342 "rtcp.app.poc1.priority",
3345 VALS(rtcp_app_poc1_qsresp_priority_vals),
3351 &hf_rtcp_app_poc1_request_ts,
3353 "Talk Burst Request Timestamp",
3354 "rtcp.app.poc1.request.ts",
3363 &hf_rtcp_app_poc1_stt,
3365 "Stop talking timer",
3366 "rtcp.app.poc1.stt",
3375 &hf_rtcp_app_poc1_partic,
3377 "Number of participants",
3378 "rtcp.app.poc1.participants",
3387 &hf_rtcp_app_poc1_ssrc_granted,
3389 "SSRC of client granted permission to talk",
3390 "rtcp.app.poc1.ssrc.granted",
3399 &hf_rtcp_app_poc1_last_pkt_seq_no,
3401 "Sequence number of last RTP packet",
3402 "rtcp.app.poc1.last.pkt.seq.no",
3411 &hf_rtcp_app_poc1_ignore_seq_no,
3413 "Ignore sequence number field",
3414 "rtcp.app.poc1.ignore.seq.no",
3423 &hf_rtcp_app_poc1_reason_code1,
3426 "rtcp.app.poc1.reason.code",
3429 VALS(rtcp_app_poc1_reason_code1_vals),
3435 &hf_rtcp_app_poc1_reason1_phrase,
3438 "rtcp.app.poc1.reason.phrase",
3447 &hf_rtcp_app_poc1_reason_code2,
3450 "rtcp.app.poc1.reason.code",
3453 VALS(rtcp_app_poc1_reason_code2_vals),
3459 &hf_rtcp_app_poc1_new_time_request,
3461 "New time client can request (seconds)",
3462 "rtcp.app.poc1.new.time.request",
3467 "Time in seconds client can request for", HFILL
3471 &hf_rtcp_app_poc1_ack_subtype,
3474 "rtcp.app.poc1.ack.subtype",
3477 VALS(rtcp_app_poc1_floor_cnt_type_vals),
3483 &hf_rtcp_app_poc1_ack_reason_code,
3486 "rtcp.app.poc1.ack.reason.code",
3489 VALS(rtcp_app_poc1_reason_code_ack_vals),
3495 &hf_rtcp_app_poc1_qsresp_priority,
3498 "rtcp.app.poc1.qsresp.priority",
3501 VALS(rtcp_app_poc1_qsresp_priority_vals),
3507 &hf_rtcp_app_poc1_qsresp_position,
3509 "Position (number of clients ahead)",
3510 "rtcp.app.poc1.qsresp.position",
3519 &hf_rtcp_app_poc1_conn_content[0],
3521 "Identity of inviting client",
3522 "rtcp.app.poc1.conn.content.a.id",
3531 &hf_rtcp_app_poc1_conn_content[1],
3533 "Nick name of inviting client",
3534 "rtcp.app.poc1.conn.content.a.dn",
3543 &hf_rtcp_app_poc1_conn_content[2],
3546 "rtcp.app.poc1.conn.content.sess.id",
3555 &hf_rtcp_app_poc1_conn_content[3],
3558 "rtcp.app.poc1.conn.content.grp.dn",
3567 &hf_rtcp_app_poc1_conn_content[4],
3570 "rtcp.app.poc1.conn.content.grp.id",
3579 &hf_rtcp_app_poc1_conn_session_type,
3582 "rtcp.app.poc1.conn.session.type",
3585 VALS(rtcp_app_poc1_conn_sess_type_vals),
3591 &hf_rtcp_app_poc1_conn_add_ind_mao,
3593 "Manual answer override",
3594 "rtcp.app.poc1.conn.add.ind.mao",
3603 &hf_rtcp_app_poc1_conn_sdes_items[0],
3605 "Identity of inviting client",
3606 "rtcp.app.poc1.conn.sdes.a.id",
3615 &hf_rtcp_app_poc1_conn_sdes_items[1],
3617 "Nick name of inviting client",
3618 "rtcp.app.poc1.conn.sdes.a.dn",
3627 &hf_rtcp_app_poc1_conn_sdes_items[2],
3630 "rtcp.app.poc1.conn.sdes.sess.id",
3639 &hf_rtcp_app_poc1_conn_sdes_items[3],
3642 "rtcp.app.poc1.conn.sdes.grp.dn",
3651 &hf_rtcp_app_poc1_conn_sdes_items[4],
3654 "rtcp.app.poc1.conn.sdes.grp.id",
3665 "RtpMux Application specific data",
3675 &hf_rtcp_app_mux_mux,
3677 "Multiplexing supported",
3687 &hf_rtcp_app_mux_cp,
3689 "Header compression supported",
3699 &hf_rtcp_app_mux_selection,
3701 "Multiplexing selection",
3702 "rtcp.app.mux.selection",
3705 VALS(rtcp_app_mux_selection_vals),
3711 &hf_rtcp_app_mux_localmuxport,
3714 "rtcp.app.mux.muxport",
3725 "First sequence number",
3737 "Bitmask of following lost packets",
3747 &hf_rtcp_padding_count,
3750 "rtcp.padding.count",
3759 &hf_rtcp_padding_data,
3762 "rtcp.padding.data",
3771 &hf_rtcp_profile_specific_extension,
3773 "Profile-specific extension",
3774 "rtcp.profile-specific-extension",
3791 "Stream setup, method and frame number", HFILL
3795 &hf_rtcp_setup_frame,
3803 "Frame that set up this stream", HFILL
3807 &hf_rtcp_setup_method,
3810 "rtcp.setup-method",
3815 "Method used to set up this stream", HFILL
3819 &hf_rtcp_last_sr_timestamp_frame,
3821 "Frame matching Last SR timestamp",
3827 "Frame matching LSR field (used to calculate roundtrip delay)", HFILL
3831 &hf_rtcp_time_since_last_sr,
3833 "Time since Last SR captured",
3834 "rtcp.lsr-frame-captured",
3839 "Time since frame matching LSR field was captured", HFILL
3843 &hf_rtcp_roundtrip_delay,
3845 "Roundtrip Delay(ms)",
3846 "rtcp.roundtrip-delay",
3851 "Calculated roundtrip delay in ms", HFILL
3855 &hf_rtcp_xr_block_type,
3861 VALS(rtcp_xr_type_vals),
3867 &hf_rtcp_xr_block_specific,
3879 &hf_rtcp_xr_block_length,
3887 "Block Length", HFILL
3891 &hf_rtcp_ssrc_discarded,
3893 "Fraction discarded",
3894 "rtcp.ssrc.discarded",
3899 "Discard Rate", HFILL
3903 &hf_rtcp_xr_voip_metrics_burst_density,
3906 "rtcp.xr.voipmetrics.burstdensity",
3915 &hf_rtcp_xr_voip_metrics_gap_density,
3918 "rtcp.xr.voipmetrics.gapdensity",
3927 &hf_rtcp_xr_voip_metrics_burst_duration,
3929 "Burst Duration(ms)",
3930 "rtcp.xr.voipmetrics.burstduration",
3939 &hf_rtcp_xr_voip_metrics_gap_duration,
3942 "rtcp.xr.voipmetrics.gapduration",
3951 &hf_rtcp_xr_voip_metrics_rtdelay,
3953 "Round Trip Delay(ms)",
3954 "rtcp.xr.voipmetrics.rtdelay",
3963 &hf_rtcp_xr_voip_metrics_esdelay,
3965 "End System Delay(ms)",
3966 "rtcp.xr.voipmetrics.esdelay",
3975 &hf_rtcp_xr_voip_metrics_siglevel,
3978 "rtcp.xr.voipmetrics.signallevel",
3983 "Signal level of 127 indicates this parameter is unavailable", HFILL
3987 &hf_rtcp_xr_voip_metrics_noiselevel,
3990 "rtcp.xr.voipmetrics.noiselevel",
3995 "Noise level of 127 indicates this parameter is unavailable", HFILL
3999 &hf_rtcp_xr_voip_metrics_rerl,
4001 "Residual Echo Return Loss",
4002 "rtcp.xr.voipmetrics.rerl",
4011 &hf_rtcp_xr_voip_metrics_gmin,
4014 "rtcp.xr.voipmetrics.gmin",
4023 &hf_rtcp_xr_voip_metrics_rfactor,
4026 "rtcp.xr.voipmetrics.rfactor",
4031 "R Factor is in the range of 0 to 100; 127 indicates this parameter is unavailable", HFILL
4035 &hf_rtcp_xr_voip_metrics_extrfactor,
4037 "External R Factor",
4038 "rtcp.xr.voipmetrics.extrfactor",
4043 "R Factor is in the range of 0 to 100; 127 indicates this parameter is unavailable", HFILL
4047 &hf_rtcp_xr_voip_metrics_moslq,
4049 "MOS - Listening Quality",
4050 "rtcp.xr.voipmetrics.moslq",
4055 "MOS is in the range of 1 to 5; 127 indicates this parameter is unavailable", HFILL
4059 &hf_rtcp_xr_voip_metrics_moscq,
4061 "MOS - Conversational Quality",
4062 "rtcp.xr.voipmetrics.moscq",
4067 "MOS is in the range of 1 to 5; 127 indicates this parameter is unavailable", HFILL
4071 &hf_rtcp_xr_voip_metrics_plc,
4073 "Packet Loss Concealment Algorithm",
4074 "rtcp.xr.voipmetrics.plc",
4077 VALS(rtcp_xr_plc_algo_vals),
4083 &hf_rtcp_xr_voip_metrics_jbadaptive,
4085 "Adaptive Jitter Buffer Algorithm",
4086 "rtcp.xr.voipmetrics.jba",
4089 VALS(rtcp_xr_jb_adaptive_vals),
4095 &hf_rtcp_xr_voip_metrics_jbrate,
4097 "Jitter Buffer Rate",
4098 "rtcp.xr.voipmetrics.jbrate",
4107 &hf_rtcp_xr_voip_metrics_jbnominal,
4109 "Nominal Jitter Buffer Size",
4110 "rtcp.xr.voipmetrics.jbnominal",
4119 &hf_rtcp_xr_voip_metrics_jbmax,
4121 "Maximum Jitter Buffer Size",
4122 "rtcp.xr.voipmetrics.jbmax",
4131 &hf_rtcp_xr_voip_metrics_jbabsmax,
4133 "Absolute Maximum Jitter Buffer Size",
4134 "rtcp.xr.voipmetrics.jbabsmax",
4143 &hf_rtcp_xr_thinning,
4155 &hf_rtcp_xr_stats_loss_flag,
4158 "rtcp.xr.stats.lrflag",
4167 &hf_rtcp_xr_stats_dup_flag,
4169 "Duplicates Report Flag",
4170 "rtcp.xr.stats.dupflag",
4179 &hf_rtcp_xr_stats_jitter_flag,
4181 "Jitter Report Flag",
4182 "rtcp.xr.stats.jitterflag",
4191 &hf_rtcp_xr_stats_ttl,
4193 "TTL or Hop Limit Flag",
4194 "rtcp.xr.stats.ttl",
4197 VALS(rtcp_xr_ip_ttl_vals),
4205 "End Sequence Number",
4215 &hf_rtcp_xr_beginseq,
4217 "Begin Sequence Number",
4227 &hf_rtcp_xr_stats_lost,
4230 "rtcp.xr.stats.lost",
4239 &hf_rtcp_xr_stats_dups,
4241 "Duplicate Packets",
4242 "rtcp.xr.stats.dups",
4251 &hf_rtcp_xr_stats_minjitter,
4254 "rtcp.xr.stats.minjitter",
4263 &hf_rtcp_xr_stats_maxjitter,
4266 "rtcp.xr.stats.maxjitter",
4275 &hf_rtcp_xr_stats_meanjitter,
4278 "rtcp.xr.stats.meanjitter",
4287 &hf_rtcp_xr_stats_devjitter,
4289 "Standard Deviation of Jitter",
4290 "rtcp.xr.stats.devjitter",
4299 &hf_rtcp_xr_stats_minttl,
4301 "Minimum TTL or Hop Limit",
4302 "rtcp.xr.stats.minttl",
4311 &hf_rtcp_xr_stats_maxttl,
4313 "Maximum TTL or Hop Limit",
4314 "rtcp.xr.stats.maxttl",
4323 &hf_rtcp_xr_stats_meanttl,
4325 "Mean TTL or Hop Limit",
4326 "rtcp.xr.stats.meanttl",
4335 &hf_rtcp_xr_stats_devttl,
4337 "Standard Deviation of TTL",
4338 "rtcp.xr.stats.devttl",
4349 "Last RR timestamp",
4361 "Delay since last RR timestamp",
4371 &hf_rtcp_length_check,
4373 "RTCP frame length check",
4374 "rtcp.length_check",
4383 &hf_rtcp_bye_reason_not_padded,
4385 "BYE reason string not NULL padded",
4386 "rtcp.bye_reason_not_padded",
4391 "RTCP BYE reason string not padded", HFILL
4397 "RTCP Feedback message type (FMT)",
4401 VALS(rtcp_rtpfb_fmt_vals),
4409 "RTCP Feedback message type (FMT)",
4413 VALS(rtcp_psfb_fmt_vals),
4419 &hf_rtcp_rtpfb_nack_pid,
4421 "RTCP Transport Feedback NACK",
4431 &hf_rtcp_rtpfb_nack_blp,
4433 "RTCP Transport Feedback NACK BLP",
4434 "rtcp.rtpfb.nack.blp",
4445 "Feedback Control Information (FCI)",
4455 &hf_rtcp_psfb_fir_fci_ssrc,
4458 "rtcp.psfb.fir.fci.ssrc",
4467 &hf_rtcp_psfb_fir_fci_csn,
4469 "Command Sequence Number",
4470 "rtcp.psfb.fir.fci.csn",
4479 &hf_rtcp_psfb_fir_fci_reserved,
4482 "rtcp.psfb.fir.fci.reserved",
4491 &hf_rtcp_rtpfb_tmbbr_fci_ssrc,
4494 "rtcp.rtpfb.tmmbr.fci.ssrc",
4503 &hf_rtcp_rtpfb_tmbbr_fci_exp,
4506 "rtcp.rtpfb.tmmbr.fci.exp",
4515 &hf_rtcp_rtpfb_tmbbr_fci_mantissa,
4518 "rtcp.rtpfb.tmmbr.fci.mantissa",
4527 &hf_rtcp_rtpfb_tmbbr_fci_bitrate,
4529 "Maximum total media bit rate",
4530 "rtcp.rtpfb.tmmbr.fci.bitrate",
4539 &hf_rtcp_rtpfb_tmbbr_fci_measuredoverhead,
4541 "Measured Overhead",
4542 "rtcp.rtpfb.tmmbr.fci.measuredoverhead",
4561 "SRTCP Encryption Flag", HFILL
4585 "SRTCP Master Key Index", HFILL
4597 "SRTCP Authentication Tag", HFILL
4600 /* additions for BT XNQ block as defined in RFC5093 */
4602 &hf_rtcp_xr_btxnq_begseq,
4604 "Starting sequence number",
4605 "rtcp.xr.btxnq.begseq",
4614 &hf_rtcp_xr_btxnq_endseq,
4616 "Last sequence number",
4617 "rtcp.xr.btxnq.endseq",
4626 &hf_rtcp_xr_btxnq_vmaxdiff,
4628 "Maximum IPDV difference in 1 cycle",
4629 "rtcp.xr.btxnq.vmaxdiff",
4638 &hf_rtcp_xr_btxnq_vrange,
4640 "Maximum IPDV difference seen to date",
4641 "rtcp.xr.btxnq.vrange",
4650 &hf_rtcp_xr_btxnq_vsum,
4652 "Sum of peak IPDV differences to date",
4653 "rtcp.xr.btxnq.vsum",
4662 &hf_rtcp_xr_btxnq_cycles,
4664 "Number of cycles in calculation",
4665 "rtcp.xr.btxnq.cycles",
4674 &hf_rtcp_xr_btxnq_jbevents,
4676 "Number of jitter buffer adaptations to date",
4677 "rtcp.xr.btxnq.jbevents",
4686 &hf_rtcp_xr_btxnq_spare,
4688 "Spare/reserved bits",
4689 "rtcp.xr.btxnq.spare",
4698 &hf_rtcp_xr_btxnq_tdegnet,
4700 "Time degraded by packet loss or late delivery",
4701 "rtcp.xr.btxnq.tdegnet",
4710 &hf_rtcp_xr_btxnq_tdegjit,
4712 "Time degraded by jitter buffer adaptation events",
4713 "rtcp.xr.btxnq.tdegjit",
4722 &hf_rtcp_xr_btxnq_es,
4724 "ES due to unavailable packet events",
4734 &hf_rtcp_xr_btxnq_ses,
4736 "SES due to unavailable packet events",
4737 "rtcp.xr.btxnq.ses",
4747 static gint *ett[] =
4768 &ett_rtcp_roundtrip_delay,
4770 &ett_xr_block_contents,
4773 &ett_poc1_conn_contents,
4777 module_t *rtcp_module;
4779 proto_rtcp = proto_register_protocol("Real-time Transport Control Protocol",
4781 proto_register_field_array(proto_rtcp, hf, array_length(hf));
4782 proto_register_subtree_array(ett, array_length(ett));
4784 register_dissector("rtcp", dissect_rtcp, proto_rtcp);
4786 rtcp_module = prefs_register_protocol(proto_rtcp, NULL);
4788 prefs_register_bool_preference(rtcp_module, "show_setup_info",
4789 "Show stream setup information",
4790 "Where available, show which protocol and frame caused "
4791 "this RTCP stream to be created",
4792 &global_rtcp_show_setup_info);
4794 prefs_register_bool_preference(rtcp_module, "heuristic_rtcp",
4795 "Try to decode RTCP outside of conversations",
4796 "If call control SIP/H.323/RTSP/.. messages are missing in the trace, "
4797 "RTCP isn't decoded without this",
4800 prefs_register_bool_preference(rtcp_module, "show_roundtrip_calculation",
4801 "Show relative roundtrip calculations",
4802 "Try to work out network delay by comparing time between packets "
4803 "as captured and delays as seen by endpoint",
4804 &global_rtcp_show_roundtrip_calculation);
4806 prefs_register_uint_preference(rtcp_module, "roundtrip_min_threshhold",
4807 "Minimum roundtrip calculation to report (ms)",
4808 "Minimum (absolute) calculated roundtrip delay time in milliseconds that "
4809 "should be reported",
4810 10, &global_rtcp_show_roundtrip_calculation_minimum);
4812 /* Register table for sub-dissetors */
4813 rtcp_dissector_table = register_dissector_table("rtcp.app.name", "RTCP Application Name", FT_STRING, BASE_NONE);
4818 proto_reg_handoff_rtcp(void)
4821 * Register this dissector as one that can be selected by a
4824 rtcp_handle = find_dissector("rtcp");
4825 dissector_add_handle("udp.port", rtcp_handle);
4827 heur_dissector_add( "udp", dissect_rtcp_heur, proto_rtcp);
4828 heur_dissector_add("stun", dissect_rtcp_heur, proto_rtcp);