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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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
56 * The part of this dissector for IDMS XR blocks was written by
57 * Torsten Loebner (loebnert@googlemail.com) in the context of a graduation
58 * project with the research organization TNO in Delft, Netherland.
59 * The extension is based on the RTCP XR block specified in
60 * ETSI TS 182 063 v3.5.2 Annex W (http://www.etsi.org/deliver/etsi_ts/183000_183099/183063/),
61 * which was registered by IANA as RTCP XR Block Type 12
62 * (http://www.iana.org/assignments/rtcp-xr-block-types/rtcp-xr-block-types.xml).
70 #include <epan/packet.h>
72 #include "packet-rtcp.h"
73 #include "packet-rtp.h"
74 #include "packet-ntp.h"
75 #include <epan/conversation.h>
77 #include <epan/prefs.h>
78 #include <epan/expert.h>
79 #include <epan/strutil.h>
80 #include <epan/wmem/wmem.h>
82 /* Version is the first 2 bits of the first octet*/
83 #define RTCP_VERSION(octet) ((octet) >> 6)
85 /* Padding is the third bit; no need to shift, because true is any value
87 #define RTCP_PADDING(octet) ((octet) & 0x20)
89 /* Receiver/ Sender count is the 5 last bits */
90 #define RTCP_COUNT(octet) ((octet) & 0x1F)
92 static dissector_handle_t rtcp_handle
;
94 /* add dissector table to permit sub-protocol registration */
95 static dissector_table_t rtcp_dissector_table
;
96 static dissector_table_t rtcp_psfb_dissector_table
;
97 static dissector_table_t rtcp_rtpfb_dissector_table
;
99 static const value_string rtcp_version_vals
[] =
101 { 2, "RFC 1889 Version" },
102 { 0, "Old VAT Version" },
103 { 1, "First Draft Version" },
107 #define RTCP_PT_MIN 192
108 /* Supplemental H.261 specific RTCP packet types according to Section C.3.5 */
110 #define RTCP_NACK 193
111 #define RTCP_SMPTETC 194
113 /* RTCP packet types according to Section A.11.1 */
114 /* And http://www.iana.org/assignments/rtp-parameters */
117 #define RTCP_SDES 202
120 #define RTCP_RTPFB 205
121 #define RTCP_PSFB 206
125 #define RTCP_TOKEN 210
127 #define RTCP_PT_MAX 210
129 static const value_string rtcp_packet_type_vals
[] =
131 { RTCP_SR
, "Sender Report" },
132 { RTCP_RR
, "Receiver Report" },
133 { RTCP_SDES
, "Source description" },
134 { RTCP_BYE
, "Goodbye" },
135 { RTCP_APP
, "Application specific" },
136 { RTCP_RTPFB
, "Generic RTP Feedback" },
137 { RTCP_PSFB
, "Payload-specific" },
138 { RTCP_XR
, "Extended report (RFC 3611)"},
139 { RTCP_AVB
, "AVB RTCP packet (IEEE1733)" },
140 { RTCP_RSI
, "Receiver Summary Information" },
141 { RTCP_TOKEN
, "Port Mapping" },
142 { RTCP_FIR
, "Full Intra-frame Request (H.261)" },
143 { RTCP_NACK
, "Negative Acknowledgement (H.261)" },
144 { RTCP_SMPTETC
, "SMPTE time-code mapping" },
145 { RTCP_IJ
, "Extended inter-arrival jitter report" },
149 /* RTCP SDES types (Section A.11.2) */
150 #define RTCP_SDES_END 0
151 #define RTCP_SDES_CNAME 1
152 #define RTCP_SDES_NAME 2
153 #define RTCP_SDES_EMAIL 3
154 #define RTCP_SDES_PHONE 4
155 #define RTCP_SDES_LOC 5
156 #define RTCP_SDES_TOOL 6
157 #define RTCP_SDES_NOTE 7
158 #define RTCP_SDES_PRIV 8
159 #define RTCP_SDES_H323_CADDR 9
160 #define RTCP_SDES_APSI 10
162 static const value_string rtcp_sdes_type_vals
[] =
164 { RTCP_SDES_END
, "END" },
165 { RTCP_SDES_CNAME
, "CNAME (user and domain)" },
166 { RTCP_SDES_NAME
, "NAME (common name)" },
167 { RTCP_SDES_EMAIL
, "EMAIL (e-mail address)" },
168 { RTCP_SDES_PHONE
, "PHONE (phone number)" },
169 { RTCP_SDES_LOC
, "LOC (geographic location)" },
170 { RTCP_SDES_TOOL
, "TOOL (name/version of source app)" },
171 { RTCP_SDES_NOTE
, "NOTE (note about source)" },
172 { RTCP_SDES_PRIV
, "PRIV (private extensions)" },
173 { RTCP_SDES_H323_CADDR
, "H323-CADDR (H.323 callable address)" },
174 { RTCP_SDES_APSI
, "Application Specific Identifier" },
178 /* RTCP XR Blocks (Section 4, RTC 3611)
179 * or http://www.iana.org/assignments/rtcp-xr-block-types */
180 #define RTCP_XR_LOSS_RLE 1
181 #define RTCP_XR_DUP_RLE 2
182 #define RTCP_XR_PKT_RXTIMES 3
183 #define RTCP_XR_REF_TIME 4
184 #define RTCP_XR_DLRR 5
185 #define RTCP_XR_STATS_SUMRY 6
186 #define RTCP_XR_VOIP_METRCS 7
187 #define RTCP_XR_BT_XNQ 8
188 #define RTCP_XR_TI_VOIP 9
189 #define RTCP_XR_PR_LOSS_RLE 10
190 #define RTCP_XR_MC_ACQ 11
191 #define RTCP_XR_IDMS 12
193 static const value_string rtcp_xr_type_vals
[] =
195 { RTCP_XR_LOSS_RLE
, "Loss Run Length Encoding Report Block" },
196 { RTCP_XR_DUP_RLE
, "Duplicate Run Length Encoding Report Block" },
197 { RTCP_XR_PKT_RXTIMES
, "Packet Receipt Times Report Block" },
198 { RTCP_XR_REF_TIME
, "Receiver Reference Time Report Block" },
199 { RTCP_XR_DLRR
, "DLRR Report Block" },
200 { RTCP_XR_STATS_SUMRY
, "Statistics Summary Report Block" },
201 { RTCP_XR_VOIP_METRCS
, "VoIP Metrics Report Block" },
202 { RTCP_XR_BT_XNQ
, "BT XNQ RTCP XR (RFC5093) Report Block" },
203 { RTCP_XR_TI_VOIP
, "Texas Instruments Extended VoIP Quality Block" },
204 { RTCP_XR_PR_LOSS_RLE
, "Post-repair Loss RLE Report Block" },
205 { RTCP_XR_MC_ACQ
, "Multicast Acquisition Report Block" },
206 { RTCP_XR_IDMS
, "Inter-destination Media Synchronization Block" }, /* [http://www.etsi.org/deliver/etsi_ts/183000_183099/183063/][ETSI 183 063][Miguel_Angel_Reina_Ortega] */
210 /* XR VoIP Metrics Block - PLC Algorithms */
211 static const value_string rtcp_xr_plc_algo_vals
[] =
213 { 0, "Unspecified" },
220 /* XR VoIP Metrics Block - JB Adaptive */
221 static const value_string rtcp_xr_jb_adaptive_vals
[] =
225 { 2, "Non-Adaptive" },
230 /* XR Stats Summary Block - IP TTL or Hop Limit */
231 static const value_string rtcp_xr_ip_ttl_vals
[] =
233 { 0, "No TTL Values" },
240 /* XR IDMS synchronization packet sender type */
241 static const value_string rtcp_xr_idms_spst
[] =
262 /* RTCP Application PoC1 Value strings
263 * OMA-TS-PoC-UserPlane-V1_0-20060609-A
266 #define TBCP_BURST_REQUEST 0
267 #define TBCP_BURST_GRANTED 1
268 #define TBCP_BURST_TAKEN_EXPECT_NO_REPLY 2
269 #define TBCP_BURST_DENY 3
270 #define TBCP_BURST_RELEASE 4
271 #define TBCP_BURST_IDLE 5
272 #define TBCP_BURST_REVOKE 6
273 #define TBCP_BURST_ACKNOWLEDGMENT 7
274 #define TBCP_QUEUE_STATUS_REQUEST 8
275 #define TBCP_QUEUE_STATUS_RESPONSE 9
276 #define TBCP_DISCONNECT 11
277 #define TBCP_CONNECT 15
278 #define TBCP_BURST_TAKEN_EXPECT_REPLY 18
281 static const value_string rtcp_app_poc1_floor_cnt_type_vals
[] =
283 { TBCP_BURST_REQUEST
, "TBCP Talk Burst Request"},
284 { TBCP_BURST_GRANTED
, "TBCP Talk Burst Granted"},
285 { TBCP_BURST_TAKEN_EXPECT_NO_REPLY
, "TBCP Talk Burst Taken (no ack expected)"},
286 { TBCP_BURST_DENY
, "TBCP Talk Burst Deny"},
287 { TBCP_BURST_RELEASE
, "TBCP Talk Burst Release"},
288 { TBCP_BURST_IDLE
, "TBCP Talk Burst Idle"},
289 { TBCP_BURST_REVOKE
, "TBCP Talk Burst Revoke"},
290 { TBCP_BURST_ACKNOWLEDGMENT
, "TBCP Talk Burst Acknowledgement"},
291 { TBCP_QUEUE_STATUS_REQUEST
, "TBCP Queue Status Request"},
292 { TBCP_QUEUE_STATUS_RESPONSE
, "TBCP Queue Status Response"},
293 { TBCP_DISCONNECT
, "TBCP Disconnect"},
294 { TBCP_CONNECT
, "TBCP Connect"},
295 { TBCP_BURST_TAKEN_EXPECT_REPLY
, "TBCP Talk Burst Taken (ack expected)"},
299 static const value_string rtcp_app_poc1_reason_code1_vals
[] =
301 { 1, "Another PoC User has permission"},
302 { 2, "Internal PoC server error"},
303 { 3, "Only one participant in the group"},
304 { 4, "Retry-after timer has not expired"},
309 static const value_string rtcp_app_poc1_reason_code2_vals
[] =
311 { 1, "Only one user"},
312 { 2, "Talk burst too long"},
313 { 3, "No permission to send a Talk Burst"},
314 { 4, "Talk burst pre-empted"},
318 static const value_string rtcp_app_poc1_reason_code_ack_vals
[] =
322 { 2, "Not accepted"},
325 static const value_string rtcp_app_poc1_conn_sess_type_vals
[] =
330 { 3, "Pre-arranged"},
335 static const value_string rtcp_app_poc1_qsresp_priority_vals
[] =
337 { 0, "No priority (un-queued)"},
338 { 1, "Normal priority"},
339 { 2, "High priority"},
340 { 3, "Pre-emptive priority"},
344 /* 3GPP 29.414 RTP Multiplexing */
345 static const value_string rtcp_app_mux_selection_vals
[] =
347 { 0, "No multiplexing applied"},
348 { 1, "Multiplexing without RTP header compression applied"},
349 { 2, "Multiplexing with RTP header compression applied"},
354 /* RFC 4585 and RFC 5104 */
355 static const value_string rtcp_rtpfb_fmt_vals
[] =
357 { 1, "Generic negative acknowledgement (NACK)"},
358 { 3, "Temporary Maximum Media Stream Bit Rate Request (TMMBR)"},
359 { 4, "Temporary Maximum Media Stream Bit Rate Notification (TMMBN)"},
360 { 31, "Reserved for future extensions"},
364 static const value_string rtcp_psfb_fmt_vals
[] =
366 { 1, "Picture Loss Indication"},
367 { 2, "Slice Loss Indication"},
368 { 3, "Reference Picture Selection Indication"},
369 { 4, "Full Intra Request (FIR) Command"},
370 { 5, "Temporal-Spatial Trade-off Request (TSTR)"},
371 { 6, "Temporal-Spatial Trade-off Notification (TSTN)"},
372 { 7, "Video Back Channel Message (VBCM)"},
373 { 15, "Application Layer Feedback"},
374 { 31, "Reserved for future extensions"},
378 /* RTCP header fields */
379 static int proto_rtcp
= -1;
380 static int hf_rtcp_version
= -1;
381 static int hf_rtcp_padding
= -1;
382 static int hf_rtcp_rc
= -1;
383 static int hf_rtcp_sc
= -1;
384 static int hf_rtcp_pt
= -1;
385 static int hf_rtcp_length
= -1;
386 static int hf_rtcp_ssrc_sender
= -1;
387 static int hf_rtcp_ssrc_media_source
= -1;
388 static int hf_rtcp_ntp
= -1;
389 static int hf_rtcp_ntp_msw
= -1;
390 static int hf_rtcp_ntp_lsw
= -1;
391 static int hf_rtcp_rtp_timestamp
= -1;
392 static int hf_rtcp_sender_pkt_cnt
= -1;
393 static int hf_rtcp_sender_oct_cnt
= -1;
394 static int hf_rtcp_ssrc_source
= -1;
395 static int hf_rtcp_ssrc_fraction
= -1;
396 static int hf_rtcp_ssrc_cum_nr
= -1;
397 static int hf_rtcp_ssrc_discarded
= -1;
398 /* First the 32 bit number, then the split
399 * up 16 bit values */
400 /* These two are added to a subtree */
401 static int hf_rtcp_ssrc_ext_high_seq
= -1;
402 static int hf_rtcp_ssrc_high_seq
= -1;
403 static int hf_rtcp_ssrc_high_cycles
= -1;
404 static int hf_rtcp_ssrc_jitter
= -1;
405 static int hf_rtcp_ssrc_lsr
= -1;
406 static int hf_rtcp_ssrc_dlsr
= -1;
407 /* static int hf_rtcp_ssrc_csrc = -1; */
408 static int hf_rtcp_sdes_type
= -1;
409 static int hf_rtcp_sdes_length
= -1;
410 static int hf_rtcp_sdes_text
= -1;
411 static int hf_rtcp_sdes_prefix_len
= -1;
412 static int hf_rtcp_sdes_prefix_string
= -1;
413 static int hf_rtcp_subtype
= -1;
414 static int hf_rtcp_name_ascii
= -1;
415 static int hf_rtcp_app_data
= -1;
416 static int hf_rtcp_fsn
= -1;
417 static int hf_rtcp_blp
= -1;
418 static int hf_rtcp_padding_count
= -1;
419 static int hf_rtcp_padding_data
= -1;
420 static int hf_rtcp_profile_specific_extension
= -1;
421 static int hf_rtcp_app_poc1
= -1;
422 static int hf_rtcp_app_poc1_subtype
= -1;
423 static int hf_rtcp_app_poc1_sip_uri
= -1;
424 static int hf_rtcp_app_poc1_disp_name
= -1;
425 static int hf_rtcp_app_poc1_priority
= -1;
426 static int hf_rtcp_app_poc1_request_ts
= -1;
427 static int hf_rtcp_app_poc1_stt
= -1;
428 static int hf_rtcp_app_poc1_partic
= -1;
429 static int hf_rtcp_app_poc1_ssrc_granted
= -1;
430 static int hf_rtcp_app_poc1_last_pkt_seq_no
= -1;
431 static int hf_rtcp_app_poc1_ignore_seq_no
= -1;
432 static int hf_rtcp_app_poc1_reason_code1
= -1;
433 static int hf_rtcp_app_poc1_reason1_phrase
= -1;
434 static int hf_rtcp_app_poc1_reason_code2
= -1;
435 static int hf_rtcp_app_poc1_new_time_request
= -1;
436 static int hf_rtcp_app_poc1_ack_subtype
= -1;
437 static int hf_rtcp_app_poc1_ack_reason_code
= -1;
438 static int hf_rtcp_app_poc1_qsresp_priority
= -1;
439 static int hf_rtcp_app_poc1_qsresp_position
= -1;
440 static int hf_rtcp_app_poc1_conn_content
[5] = { -1, -1, -1, -1, -1 };
441 static int hf_rtcp_app_poc1_conn_session_type
= -1;
442 static int hf_rtcp_app_poc1_conn_add_ind_mao
= -1;
443 static int hf_rtcp_app_poc1_conn_sdes_items
[5] = { -1, -1, -1, -1, -1 };
444 static int hf_rtcp_app_mux
= -1;
445 static int hf_rtcp_app_mux_mux
= -1;
446 static int hf_rtcp_app_mux_cp
= -1;
447 static int hf_rtcp_app_mux_selection
= -1;
448 static int hf_rtcp_app_mux_localmuxport
= -1;
449 static int hf_rtcp_xr_block_type
= -1;
450 static int hf_rtcp_xr_block_specific
= -1;
451 static int hf_rtcp_xr_block_length
= -1;
452 static int hf_rtcp_xr_thinning
= -1;
453 static int hf_rtcp_xr_voip_metrics_burst_density
= -1;
454 static int hf_rtcp_xr_voip_metrics_gap_density
= -1;
455 static int hf_rtcp_xr_voip_metrics_burst_duration
= -1;
456 static int hf_rtcp_xr_voip_metrics_gap_duration
= -1;
457 static int hf_rtcp_xr_voip_metrics_rtdelay
= -1;
458 static int hf_rtcp_xr_voip_metrics_esdelay
= -1;
459 static int hf_rtcp_xr_voip_metrics_siglevel
= -1;
460 static int hf_rtcp_xr_voip_metrics_noiselevel
= -1;
461 static int hf_rtcp_xr_voip_metrics_rerl
= -1;
462 static int hf_rtcp_xr_voip_metrics_gmin
= -1;
463 static int hf_rtcp_xr_voip_metrics_rfactor
= -1;
464 static int hf_rtcp_xr_voip_metrics_extrfactor
= -1;
465 static int hf_rtcp_xr_voip_metrics_moslq
= -1;
466 static int hf_rtcp_xr_voip_metrics_moscq
= -1;
467 static int hf_rtcp_xr_voip_metrics_plc
= -1;
468 static int hf_rtcp_xr_voip_metrics_jbadaptive
= -1;
469 static int hf_rtcp_xr_voip_metrics_jbrate
= -1;
470 static int hf_rtcp_xr_voip_metrics_jbnominal
= -1;
471 static int hf_rtcp_xr_voip_metrics_jbmax
= -1;
472 static int hf_rtcp_xr_voip_metrics_jbabsmax
= -1;
473 static int hf_rtcp_xr_stats_loss_flag
= -1;
474 static int hf_rtcp_xr_stats_dup_flag
= -1;
475 static int hf_rtcp_xr_stats_jitter_flag
= -1;
476 static int hf_rtcp_xr_stats_ttl
= -1;
477 static int hf_rtcp_xr_beginseq
= -1;
478 static int hf_rtcp_xr_endseq
= -1;
479 static int hf_rtcp_xr_receipt_time_seq
= -1;
480 static int hf_rtcp_xr_stats_lost
= -1;
481 static int hf_rtcp_xr_stats_dups
= -1;
482 static int hf_rtcp_xr_stats_minjitter
= -1;
483 static int hf_rtcp_xr_stats_maxjitter
= -1;
484 static int hf_rtcp_xr_stats_meanjitter
= -1;
485 static int hf_rtcp_xr_stats_devjitter
= -1;
486 static int hf_rtcp_xr_stats_minttl
= -1;
487 static int hf_rtcp_xr_stats_maxttl
= -1;
488 static int hf_rtcp_xr_stats_meanttl
= -1;
489 static int hf_rtcp_xr_stats_devttl
= -1;
490 static int hf_rtcp_xr_lrr
= -1;
491 static int hf_rtcp_xr_dlrr
= -1;
492 static int hf_rtcp_xr_idms_spst
= -1;
493 static int hf_rtcp_xr_idms_pt
= -1;
494 static int hf_rtcp_xr_idms_msci
= -1;
495 static int hf_rtcp_xr_idms_source_ssrc
= -1;
496 static int hf_rtcp_xr_idms_ntp_rcv_ts_msw
= -1;
497 static int hf_rtcp_xr_idms_ntp_rcv_ts_lsw
= -1;
498 static int hf_rtcp_xr_idms_rtp_ts
= -1;
499 static int hf_rtcp_xr_idms_ntp_pres_ts
= -1;
500 static int hf_rtcp_length_check
= -1;
501 static int hf_rtcp_rtpfb_fmt
= -1;
502 static int hf_rtcp_rtpfb_nack_pid
= -1;
503 static int hf_rtcp_rtpfb_nack_blp
= -1;
504 static int hf_rtcp_psfb_fmt
= -1;
505 static int hf_rtcp_fci
= -1;
506 static int hf_rtcp_psfb_fir_fci_ssrc
= -1;
507 static int hf_rtcp_psfb_fir_fci_csn
= -1;
508 static int hf_rtcp_psfb_fir_fci_reserved
= -1;
509 static int hf_rtcp_rtpfb_tmbbr_fci_ssrc
= -1;
510 static int hf_rtcp_rtpfb_tmbbr_fci_exp
= -1;
511 static int hf_rtcp_rtpfb_tmbbr_fci_mantissa
= -1;
512 static int hf_rtcp_rtpfb_tmbbr_fci_bitrate
= -1;
513 static int hf_rtcp_rtpfb_tmbbr_fci_measuredoverhead
= -1;
514 static int hf_srtcp_e
= -1;
515 static int hf_srtcp_index
= -1;
516 static int hf_srtcp_mki
= -1;
517 static int hf_srtcp_auth_tag
= -1;
518 static int hf_rtcp_xr_btxnq_begseq
= -1; /* added for BT XNQ block (RFC5093) */
519 static int hf_rtcp_xr_btxnq_endseq
= -1;
520 static int hf_rtcp_xr_btxnq_vmaxdiff
= -1;
521 static int hf_rtcp_xr_btxnq_vrange
= -1;
522 static int hf_rtcp_xr_btxnq_vsum
= -1;
523 static int hf_rtcp_xr_btxnq_cycles
= -1;
524 static int hf_rtcp_xr_btxnq_jbevents
= -1;
525 static int hf_rtcp_xr_btxnq_tdegnet
= -1;
526 static int hf_rtcp_xr_btxnq_tdegjit
= -1;
527 static int hf_rtcp_xr_btxnq_es
= -1;
528 static int hf_rtcp_xr_btxnq_ses
= -1;
529 static int hf_rtcp_xr_btxnq_spare
= -1;
531 /* RTCP setup fields */
532 static int hf_rtcp_setup
= -1;
533 static int hf_rtcp_setup_frame
= -1;
534 static int hf_rtcp_setup_method
= -1;
536 /* RTCP roundtrip delay fields */
537 static int hf_rtcp_last_sr_timestamp_frame
= -1;
538 static int hf_rtcp_time_since_last_sr
= -1;
539 static int hf_rtcp_roundtrip_delay
= -1;
543 /* RTCP fields defining a sub tree */
544 static gint ett_rtcp
= -1;
545 static gint ett_rtcp_sr
= -1;
546 static gint ett_rtcp_rr
= -1;
547 static gint ett_rtcp_sdes
= -1;
548 static gint ett_rtcp_bye
= -1;
549 static gint ett_rtcp_app
= -1;
550 static gint ett_rtcp_rtpfb
= -1;
551 static gint ett_rtcp_psfb
= -1;
552 static gint ett_rtcp_xr
= -1;
553 static gint ett_rtcp_fir
= -1;
554 static gint ett_rtcp_nack
= -1;
555 static gint ett_ssrc
= -1;
556 static gint ett_ssrc_item
= -1;
557 static gint ett_ssrc_ext_high
= -1;
558 static gint ett_sdes
= -1;
559 static gint ett_sdes_item
= -1;
560 static gint ett_PoC1
= -1;
561 static gint ett_mux
= -1;
562 static gint ett_rtcp_setup
= -1;
563 static gint ett_rtcp_roundtrip_delay
= -1;
564 static gint ett_xr_block
= -1;
565 static gint ett_xr_block_contents
= -1;
566 static gint ett_xr_ssrc
= -1;
567 static gint ett_xr_loss_chunk
= -1;
568 static gint ett_poc1_conn_contents
= -1;
569 static gint ett_rtcp_nack_blp
= -1;
571 static expert_field ei_rtcp_bye_reason_not_padded
= EI_INIT
;
572 static expert_field ei_rtcp_xr_block_length_bad
= EI_INIT
;
573 static expert_field ei_rtcp_roundtrip_delay
= EI_INIT
;
574 static expert_field ei_rtcp_length_check
= EI_INIT
;
575 static expert_field ei_rtcp_roundtrip_delay_negative
= EI_INIT
;
577 /* Main dissection function */
578 static void dissect_rtcp( tvbuff_t
*tvb
, packet_info
*pinfo
,
581 /* Heuristic dissection */
582 static gboolean global_rtcp_heur
= FALSE
;
584 /* Displaying set info */
585 static gboolean global_rtcp_show_setup_info
= TRUE
;
586 static void show_setup_info(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
);
588 /* Related to roundtrip calculation (using LSR and DLSR) */
589 static gboolean global_rtcp_show_roundtrip_calculation
= FALSE
;
590 #define MIN_ROUNDTRIP_TO_REPORT_DEFAULT 10
591 static guint global_rtcp_show_roundtrip_calculation_minimum
= MIN_ROUNDTRIP_TO_REPORT_DEFAULT
;
592 static void remember_outgoing_sr(packet_info
*pinfo
, guint32 lsr
);
593 static void calculate_roundtrip_delay(tvbuff_t
*tvb
, packet_info
*pinfo
,
594 proto_tree
*tree
, guint32 lsr
, guint32 dlsr
);
595 static void add_roundtrip_delay_info(tvbuff_t
*tvb
, packet_info
*pinfo
,
598 guint gap_between_reports
, gint delay
);
601 /* Set up an RTCP conversation using the info given */
602 void srtcp_add_address( packet_info
*pinfo
,
603 address
*addr
, int port
,
605 const gchar
*setup_method
, guint32 setup_frame_number
,
606 struct srtp_info
*srtcp_info
)
609 conversation_t
*p_conv
;
610 struct _rtcp_conversation_info
*p_conv_data
;
613 * If this isn't the first time this packet has been processed,
614 * we've already done this work, so we don't need to do it
617 if (pinfo
->fd
->flags
.visited
)
623 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
);
626 SET_ADDRESS(&null_addr
, AT_NONE
, 0, NULL
);
629 * Check if the ip address and port combination is not
630 * already registered as a conversation.
632 p_conv
= find_conversation( pinfo
->fd
->num
, addr
, &null_addr
, PT_UDP
, port
, other_port
,
633 NO_ADDR_B
| (!other_port
? NO_PORT_B
: 0));
636 * If not, create a new conversation.
639 p_conv
= conversation_new( pinfo
->fd
->num
, addr
, &null_addr
, PT_UDP
,
640 (guint32
)port
, (guint32
)other_port
,
641 NO_ADDR2
| (!other_port
? NO_PORT2
: 0));
645 conversation_set_dissector(p_conv
, rtcp_handle
);
648 * Check if the conversation has data associated with it.
650 p_conv_data
= (struct _rtcp_conversation_info
*)conversation_get_proto_data(p_conv
, proto_rtcp
);
653 * If not, add a new data item.
655 if ( ! p_conv_data
) {
656 /* Create conversation data */
657 p_conv_data
= wmem_new0(wmem_file_scope(), struct _rtcp_conversation_info
);
658 conversation_add_proto_data(p_conv
, proto_rtcp
, p_conv_data
);
662 * Update the conversation data.
664 p_conv_data
->setup_method_set
= TRUE
;
665 g_strlcpy(p_conv_data
->setup_method
, setup_method
, MAX_RTCP_SETUP_METHOD_SIZE
);
666 p_conv_data
->setup_frame_number
= setup_frame_number
;
667 p_conv_data
->srtcp_info
= srtcp_info
;
670 /* Set up an RTCP conversation using the info given */
671 void rtcp_add_address( packet_info
*pinfo
,
672 address
*addr
, int port
,
674 const gchar
*setup_method
, guint32 setup_frame_number
)
676 srtcp_add_address(pinfo
, addr
, port
, other_port
, setup_method
, setup_frame_number
, NULL
);
680 dissect_rtcp_heur( tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data _U_
)
682 unsigned int offset
= 0;
683 unsigned int first_byte
;
684 unsigned int packet_type
;
686 /* This is a heuristic dissector, which means we get all the UDP
687 * traffic not sent to a known dissector and not claimed by
688 * a heuristic dissector called before us!
691 if (!global_rtcp_heur
)
696 /* Was it sent to an odd-numbered port? */
697 if ((pinfo
->destport
% 2) == 0)
699 return FALSE
; /* no */
702 /* Look at first byte */
703 first_byte
= tvb_get_guint8(tvb
, offset
);
705 /* Are version bits set to 2? */
706 if (((first_byte
& 0xC0) >> 6) != 2)
711 /* Look at packet type */
712 packet_type
= tvb_get_guint8(tvb
, offset
+ 1);
714 /* First packet within compound packet is supposed to be a sender
716 - allow BYE because this happens anyway
717 - allow APP because TBCP ("PoC1") packets aren't compound... */
718 if (!((packet_type
== RTCP_SR
) || (packet_type
== RTCP_RR
) ||
719 (packet_type
== RTCP_BYE
) || (packet_type
== RTCP_APP
)))
724 /* Overall length must be a multiple of 4 bytes */
725 if (tvb_reported_length(tvb
) % 4)
730 /* OK, dissect as RTCP */
731 dissect_rtcp(tvb
, pinfo
, tree
);
735 /* Dissect the length field. Append to this field text indicating the number of
736 actual bytes this translates to (i.e. (raw value + 1) * 4) */
737 int dissect_rtcp_length_field( proto_tree
*tree
, tvbuff_t
*tvb
, int offset
)
740 unsigned short raw_length
= tvb_get_ntohs( tvb
, offset
);
742 ti
= proto_tree_add_item( tree
, hf_rtcp_length
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
743 proto_item_append_text(ti
, " (%u bytes)", (raw_length
+1)*4);
750 dissect_rtcp_nack( tvbuff_t
*tvb
, int offset
, proto_tree
*tree
)
752 /* Packet type = FIR (H261) */
753 proto_tree_add_item( tree
, hf_rtcp_rc
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
755 /* Packet type, 8 bits = APP */
756 proto_tree_add_item( tree
, hf_rtcp_pt
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
759 /* Packet length in 32 bit words minus one */
760 offset
= dissect_rtcp_length_field(tree
, tvb
, offset
);
763 proto_tree_add_item( tree
, hf_rtcp_ssrc_source
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
767 proto_tree_add_item( tree
, hf_rtcp_fsn
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
771 proto_tree_add_item( tree
, hf_rtcp_blp
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
778 dissect_rtcp_rtpfb_tmmbr( tvbuff_t
*tvb
, int offset
, proto_tree
*rtcp_tree
, proto_item
*top_item
, int num_fci
, int is_notification
)
784 proto_tree
*fci_tree
;
786 if (is_notification
== 1) {
787 ti
= proto_tree_add_text( rtcp_tree
, tvb
, offset
, 8, "TMMBN %d", num_fci
);
789 ti
= proto_tree_add_text( rtcp_tree
, tvb
, offset
, 8, "TMMBR %d", num_fci
);
792 fci_tree
= proto_item_add_subtree( ti
, ett_ssrc
);
794 proto_tree_add_item( fci_tree
, hf_rtcp_rtpfb_tmbbr_fci_ssrc
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
797 proto_tree_add_item( fci_tree
, hf_rtcp_rtpfb_tmbbr_fci_exp
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
798 exp
= (tvb_get_guint8(tvb
, offset
) & 0xfc) >> 2;
800 proto_tree_add_item( fci_tree
, hf_rtcp_rtpfb_tmbbr_fci_mantissa
, tvb
, offset
, 3, ENC_BIG_ENDIAN
);
801 mantissa
= (tvb_get_ntohl( tvb
, offset
) & 0x3fffe00) >> 9;
802 bitrate
= mantissa
<< exp
;
803 proto_tree_add_string_format_value( fci_tree
, hf_rtcp_rtpfb_tmbbr_fci_bitrate
, tvb
, offset
, 3, "", "%u", bitrate
);
806 proto_tree_add_item( fci_tree
, hf_rtcp_rtpfb_tmbbr_fci_measuredoverhead
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
809 if (top_item
!= NULL
) {
810 proto_item_append_text(top_item
, ": TMMBR: %u", bitrate
);
817 dissect_rtcp_rtpfb_nack( tvbuff_t
*tvb
, int offset
, proto_tree
*rtcp_tree
, proto_item
*top_item
)
820 int nack_num_frames_lost
;
821 proto_tree
*bitfield_tree
;
822 unsigned int rtcp_rtpfb_nack_pid
;
823 unsigned int rtcp_rtpfb_nack_blp
;
826 proto_tree_add_item(rtcp_tree
, hf_rtcp_rtpfb_nack_pid
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
827 rtcp_rtpfb_nack_pid
= tvb_get_ntohs(tvb
, offset
);
830 ti
= proto_tree_add_item(rtcp_tree
, hf_rtcp_rtpfb_nack_blp
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
831 rtcp_rtpfb_nack_blp
= tvb_get_ntohs(tvb
, offset
);
832 bitfield_tree
= proto_item_add_subtree(ti
, ett_rtcp_nack_blp
);
833 nack_num_frames_lost
= 1;
834 if (rtcp_rtpfb_nack_blp
) {
835 proto_item_append_text(ti
, " (Frames");
836 for (i
= 0; i
< 16; i
++) {
837 if (rtcp_rtpfb_nack_blp
& (1<<i
)) {
838 proto_tree_add_uint_format(bitfield_tree
, hf_rtcp_rtpfb_nack_pid
, tvb
, offset
, 2, rtcp_rtpfb_nack_pid
+ i
+ 1,
839 "Frame %u also lost", rtcp_rtpfb_nack_pid
+ i
+ 1);
840 proto_item_append_text(ti
, " %u", rtcp_rtpfb_nack_pid
+ i
+ 1);
841 nack_num_frames_lost
++;
844 proto_item_append_text(ti
, " lost)");
846 proto_item_append_text(ti
, " (No additional frames lost)");
850 if (top_item
!= NULL
) {
851 proto_item_append_text(top_item
, ": NACK: %d frames lost", nack_num_frames_lost
);
858 dissect_rtcp_rtpfb( tvbuff_t
*tvb
, int offset
, proto_tree
*rtcp_tree
, proto_item
*top_item
, packet_info
*pinfo
)
860 unsigned int counter
;
861 unsigned int rtcp_rtpfb_fmt
;
863 int start_offset
= offset
;
865 /* Transport layer FB message */
866 /* Feedback message type (FMT): 5 bits */
867 proto_tree_add_item( rtcp_tree
, hf_rtcp_rtpfb_fmt
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
868 rtcp_rtpfb_fmt
= (tvb_get_guint8(tvb
, offset
) & 0x1f);
871 /* Packet type, 8 bits */
872 proto_tree_add_item( rtcp_tree
, hf_rtcp_pt
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
875 /* Packet length in 32 bit words MINUS one, 16 bits */
876 packet_length
= (tvb_get_ntohs(tvb
, offset
) + 1) * 4;
877 offset
= dissect_rtcp_length_field(rtcp_tree
, tvb
, offset
);
879 /* SSRC of packet sender, 32 bits */
880 proto_tree_add_item( rtcp_tree
, hf_rtcp_ssrc_sender
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
883 /* SSRC of media source, 32 bits */
884 proto_tree_add_item( rtcp_tree
, hf_rtcp_ssrc_media_source
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
887 /* Check if we have a type specific dissector,
888 * if we do, just return from here
890 if (packet_length
> 12 &&
891 dissector_get_uint_handle (rtcp_rtpfb_dissector_table
, rtcp_rtpfb_fmt
)) {
892 tvbuff_t
*subtvb
= tvb_new_subset(tvb
, offset
, packet_length
- 12, packet_length
- 12);
894 if (dissector_try_uint (rtcp_rtpfb_dissector_table
, rtcp_rtpfb_fmt
,
895 subtvb
, pinfo
, rtcp_tree
))
896 return start_offset
+ packet_length
;
899 /* Transport-Layer Feedback Message Elements */
901 while ((offset
- start_offset
) < packet_length
) {
903 if (rtcp_rtpfb_fmt
== 1) {
904 offset
= dissect_rtcp_rtpfb_nack(tvb
, offset
, rtcp_tree
, top_item
);
905 } else if (rtcp_rtpfb_fmt
== 3) {
906 offset
= dissect_rtcp_rtpfb_tmmbr(tvb
, offset
, rtcp_tree
, top_item
, counter
, 0);
907 } else if (rtcp_rtpfb_fmt
== 4) {
908 offset
= dissect_rtcp_rtpfb_tmmbr(tvb
, offset
, rtcp_tree
, top_item
, counter
, 1);
911 proto_tree_add_item(rtcp_tree
, hf_rtcp_fci
, tvb
, offset
, start_offset
+ packet_length
- offset
, ENC_NA
);
912 offset
= start_offset
+ packet_length
;
919 dissect_rtcp_psfb( tvbuff_t
*tvb
, int offset
, proto_tree
*rtcp_tree
,
920 int packet_length
, packet_info
*pinfo _U_
)
922 unsigned int counter
;
923 unsigned int num_fci
;
924 unsigned int read_fci
;
925 proto_tree
*fci_tree
;
927 unsigned int rtcp_psfb_fmt
;
928 int base_offset
= offset
;
930 /* Payload-specific FB message */
931 /* Feedback message type (FMT): 5 bits */
932 proto_tree_add_item( rtcp_tree
, hf_rtcp_psfb_fmt
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
933 rtcp_psfb_fmt
= (tvb_get_guint8(tvb
, offset
) & 0x1f);
936 /* Packet type, 8 bits */
937 proto_tree_add_item( rtcp_tree
, hf_rtcp_pt
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
940 /* Packet length in 32 bit words MINUS one, 16 bits */
941 num_fci
= (tvb_get_ntohs(tvb
, offset
) - 2);
942 offset
= dissect_rtcp_length_field(rtcp_tree
, tvb
, offset
);
944 /* SSRC of packet sender, 32 bits */
945 proto_tree_add_item( rtcp_tree
, hf_rtcp_ssrc_sender
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
948 /* SSRC of media source, 32 bits */
949 proto_tree_add_item( rtcp_tree
, hf_rtcp_ssrc_media_source
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
952 /* Feedback Control Information (FCI) */
955 while ( read_fci
< num_fci
) {
957 if (rtcp_psfb_fmt
== 4) {
958 /* Create a new subtree for a length of 8 bytes */
959 ti
= proto_tree_add_text( rtcp_tree
, tvb
, offset
, 8, "FIR %u", ++counter
);
960 fci_tree
= proto_item_add_subtree( ti
, ett_ssrc
);
962 proto_tree_add_item( fci_tree
, hf_rtcp_psfb_fir_fci_ssrc
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
964 /* Command Sequence Number 8 bit*/
965 proto_tree_add_item( fci_tree
, hf_rtcp_psfb_fir_fci_csn
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
966 /*proto_tree_add_item( ssrc_tree, hf_rtcp_ssrc_source, tvb, offset, 4, ENC_BIG_ENDIAN );*/
969 proto_tree_add_item( fci_tree
, hf_rtcp_psfb_fir_fci_reserved
, tvb
, offset
, 3, ENC_BIG_ENDIAN
);
977 /* Append undecoded FCI information */
978 if ((packet_length
- (offset
- base_offset
)) > 0) {
979 proto_tree_add_item( rtcp_tree
, hf_rtcp_fci
, tvb
, offset
, packet_length
- (offset
- base_offset
), ENC_NA
);
980 offset
= base_offset
+ packet_length
;
986 dissect_rtcp_fir( tvbuff_t
*tvb
, int offset
, proto_tree
*tree
)
988 /* Packet type = FIR (H261) */
989 proto_tree_add_item( tree
, hf_rtcp_rc
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
991 /* Packet type, 8 bits = APP */
992 proto_tree_add_item( tree
, hf_rtcp_pt
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
995 /* Packet length in 32 bit words minus one */
996 offset
= dissect_rtcp_length_field(tree
, tvb
, offset
);
999 proto_tree_add_item( tree
, hf_rtcp_ssrc_source
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1006 dissect_rtcp_app( tvbuff_t
*tvb
,packet_info
*pinfo
, int offset
, proto_tree
*tree
,
1007 unsigned int padding
, unsigned int packet_len
, guint rtcp_subtype
,
1008 guint32 app_length
)
1010 unsigned int counter
;
1014 proto_tree
*PoC1_tree
;
1015 proto_item
*PoC1_item
;
1017 /* XXX If more application types are to be dissected it may be useful to use a table like in packet-sip.c */
1018 static const char poc1_app_name_str
[] = "PoC1";
1019 static const char mux_app_name_str
[] = "3GPP";
1023 proto_tree_add_item( tree
, hf_rtcp_ssrc_source
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1027 /* Application Name (ASCII) */
1028 for( counter
= 0; counter
< 4; counter
++ )
1029 ascii_name
[ counter
] = tvb_get_guint8( tvb
, offset
+ counter
);
1030 /* g_strlcpy( ascii_name, pd + offset, 4 ); */
1031 ascii_name
[4] = '\0';
1032 proto_tree_add_string( tree
, hf_rtcp_name_ascii
, tvb
, offset
, 4,
1035 /* See if we can handle this application type */
1036 if ( g_ascii_strncasecmp(ascii_name
, poc1_app_name_str
,4 ) == 0 )
1038 /* PoC1 Application */
1039 guint8 t2timer_code
, participants_code
;
1041 item
= proto_tree_add_uint( tree
, hf_rtcp_app_poc1_subtype
, tvb
, offset
- 8, 1, rtcp_subtype
);
1042 PROTO_ITEM_SET_GENERATED(item
);
1043 col_add_fstr(pinfo
->cinfo
, COL_INFO
,"(%s) %s",ascii_name
,
1044 val_to_str(rtcp_subtype
,rtcp_app_poc1_floor_cnt_type_vals
,"unknown (%u)") );
1047 if ( packet_len
== 0 )
1048 return offset
; /* No more data */
1049 /* Applications specific data */
1051 /* If there's padding present, we have to remove that from the data part
1052 * The last octet of the packet contains the length of the padding
1054 packet_len
-= tvb_get_guint8( tvb
, offset
+ packet_len
- 1 );
1056 /* Create a subtree for the PoC1 Application items; we don't yet know
1059 /* Top-level poc tree */
1060 PoC1_item
= proto_tree_add_item(tree
, hf_rtcp_app_poc1
, tvb
, offset
, packet_len
, ENC_NA
);
1061 PoC1_tree
= proto_item_add_subtree( PoC1_item
, ett_PoC1
);
1063 /* Dissect it according to its subtype */
1064 switch ( rtcp_subtype
) {
1066 case TBCP_BURST_REQUEST
:
1071 /* Both items here are optional */
1072 if (tvb_reported_length_remaining( tvb
, offset
) == 0)
1077 /* Look for a code in the first byte */
1078 code
= tvb_get_guint8(tvb
, offset
);
1082 /* Priority (optional) */
1085 item_len
= tvb_get_guint8(tvb
, offset
);
1088 if (item_len
!= 2) /* SHALL be 2 */
1091 priority
= tvb_get_ntohs(tvb
, offset
);
1092 proto_tree_add_item(PoC1_tree
, hf_rtcp_app_poc1_priority
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1096 col_append_fstr(pinfo
->cinfo
, COL_INFO
,
1098 val_to_str_const(priority
,
1099 rtcp_app_poc1_qsresp_priority_vals
,
1102 /* Look for (optional) next code */
1103 if (tvb_reported_length_remaining( tvb
, offset
) == 0)
1107 code
= tvb_get_guint8(tvb
, offset
);
1113 /* Request timestamp (optional) */
1118 item_len
= tvb_get_guint8(tvb
, offset
);
1121 if (item_len
!= 8) /* SHALL be 8 */
1124 proto_tree_add_item(PoC1_tree
, hf_rtcp_app_poc1_request_ts
,
1125 tvb
, offset
, 8, ENC_TIME_NTP
|ENC_BIG_ENDIAN
);
1126 buff
= tvb_ntp_fmt_ts(tvb
, offset
);
1131 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " ts=\"%s\"", buff
);
1136 case TBCP_BURST_GRANTED
:
1139 guint16 stop_talking_time
;
1140 guint16 participants
;
1142 /* Stop talking timer (now mandatory) */
1143 t2timer_code
= tvb_get_guint8(tvb
, offset
);
1146 if (t2timer_code
!= 101) /* SHALL be 101 */
1149 item_len
= tvb_get_guint8(tvb
, offset
);
1152 if (item_len
!= 2) /* SHALL be 2 */
1155 stop_talking_time
= tvb_get_ntohs(tvb
, offset
);
1156 ti
= proto_tree_add_item(PoC1_tree
, hf_rtcp_app_poc1_stt
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1158 /* Append text with meanings of value */
1159 switch (stop_talking_time
)
1162 proto_item_append_text(ti
, " unknown");
1165 proto_item_append_text(ti
, " infinity");
1168 proto_item_append_text(ti
, " seconds");
1172 packet_len
-= item_len
;
1174 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " stop-talking-time=%u",
1177 /* Participants (optional) */
1178 if (tvb_reported_length_remaining( tvb
, offset
) == 0)
1182 participants_code
= tvb_get_guint8(tvb
, offset
);
1185 if (participants_code
!= 100) /* SHALL be 100 */
1188 item_len
= tvb_get_guint8(tvb
, offset
);
1191 if (item_len
!= 2) /* SHALL be 2 */
1194 participants
= tvb_get_ntohs(tvb
, offset
);
1195 ti
= proto_tree_add_item(PoC1_tree
, hf_rtcp_app_poc1_partic
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1197 /* Append text with meanings of extreme values */
1198 switch (participants
)
1201 proto_item_append_text(ti
, " (not known)");
1204 proto_item_append_text(ti
, " (or more)");
1210 packet_len
-= item_len
;
1212 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " participants=%u",
1217 case TBCP_BURST_TAKEN_EXPECT_NO_REPLY
:
1218 case TBCP_BURST_TAKEN_EXPECT_REPLY
:
1220 guint16 participants
;
1223 /* SSRC of PoC client */
1224 proto_tree_add_item(PoC1_tree
, hf_rtcp_app_poc1_ssrc_granted
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1228 /* SDES type (must be CNAME) */
1229 sdes_type
= tvb_get_guint8( tvb
, offset
);
1230 proto_tree_add_item( PoC1_tree
, hf_rtcp_sdes_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1233 if (sdes_type
!= RTCP_SDES_CNAME
)
1239 item_len
= tvb_get_guint8( tvb
, offset
);
1240 /* Item len of 1 because it's an FT_UINT_STRING... */
1241 proto_tree_add_item(PoC1_tree
, hf_rtcp_app_poc1_sip_uri
,
1242 tvb
, offset
, 1, ENC_ASCII
|ENC_NA
);
1245 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " CNAME=\"%s\"",
1246 tvb_get_string(wmem_packet_scope(), tvb
, offset
, item_len
));
1249 packet_len
= packet_len
- item_len
- 1;
1251 /* In the application dependent data, the TBCP Talk Burst Taken message SHALL carry
1252 * a SSRC field and SDES items, CNAME and MAY carry SDES item NAME to identify the
1253 * PoC Client that has been granted permission to send a Talk Burst.
1255 * The SDES item NAME SHALL be included if it is known by the PoC Server.
1256 * Therefore the length of the packet will vary depending on number of SDES items
1257 * and the size of the SDES items.
1259 if ( packet_len
== 0 )
1262 /* SDES type (must be NAME if present) */
1263 sdes_type
= tvb_get_guint8( tvb
, offset
);
1264 if (sdes_type
== RTCP_SDES_NAME
) {
1265 proto_tree_add_item( PoC1_tree
, hf_rtcp_sdes_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1270 item_len
= tvb_get_guint8( tvb
, offset
);
1271 /* Item len of 1 because it's an FT_UINT_STRING... */
1272 proto_tree_add_item(PoC1_tree
, hf_rtcp_app_poc1_disp_name
,
1273 tvb
, offset
, 1, ENC_ASCII
|ENC_NA
);
1276 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " DISPLAY-NAME=\"%s\"",
1277 tvb_get_string(wmem_packet_scope(), tvb
, offset
, item_len
));
1280 packet_len
= packet_len
- item_len
- 1;
1282 if (packet_len
== 0) {
1286 /* Move onto next 4-byte boundary */
1288 int padding2
= (4-(offset
%4));
1290 packet_len
-= padding2
;
1294 /* Participants (optional) */
1295 if (tvb_reported_length_remaining( tvb
, offset
) == 0) {
1298 participants_code
= tvb_get_guint8(tvb
, offset
);
1301 if (participants_code
!= 100) { /* SHALL be 100 */
1304 item_len
= tvb_get_guint8(tvb
, offset
);
1307 if (item_len
!= 2) { /* SHALL be 2 */
1311 participants
= tvb_get_ntohs(tvb
, offset
);
1312 ti
= proto_tree_add_item(PoC1_tree
, hf_rtcp_app_poc1_partic
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1314 /* Append text with meanings of extreme values */
1315 switch (participants
) {
1317 proto_item_append_text(ti
, " (not known)");
1320 proto_item_append_text(ti
, " (or more)");
1326 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " Participants=%u",
1329 packet_len
-= item_len
;
1333 case TBCP_BURST_DENY
:
1338 reason_code
= tvb_get_guint8(tvb
, offset
);
1339 proto_tree_add_item( PoC1_tree
, hf_rtcp_app_poc1_reason_code1
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1343 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " reason-code=\"%s\"",
1344 val_to_str_const(reason_code
,
1345 rtcp_app_poc1_reason_code1_vals
,
1349 item_len
= tvb_get_guint8( tvb
, offset
);
1350 if ( item_len
!= 0 )
1351 proto_tree_add_item( PoC1_tree
, hf_rtcp_app_poc1_reason1_phrase
, tvb
, offset
, 1, ENC_ASCII
|ENC_NA
);
1353 offset
+= (item_len
+1);
1354 packet_len
-= (item_len
+1);
1358 case TBCP_BURST_RELEASE
:
1360 guint16 last_seq_no
;
1361 /*guint16 ignore_last_seq_no;*/
1363 /* Sequence number of last RTP packet in burst */
1364 proto_tree_add_item( PoC1_tree
, hf_rtcp_app_poc1_last_pkt_seq_no
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1365 last_seq_no
= tvb_get_ntohs(tvb
, offset
);
1367 /* Bit 16 is ignore flag */
1369 proto_tree_add_item(PoC1_tree
, hf_rtcp_app_poc1_ignore_seq_no
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1370 /*ignore_last_seq_no = (tvb_get_ntohs(tvb, offset) & 0x8000);*/
1372 /* XXX: Was the intention to also show the "ignore_last_seq_no' flag in COL_INFO ? */
1373 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " last_rtp_seq_no=%u",
1376 /* 15 bits of padding follows */
1383 case TBCP_BURST_IDLE
:
1386 case TBCP_BURST_REVOKE
:
1389 guint16 reason_code
= tvb_get_ntohs(tvb
, offset
);
1390 proto_tree_add_item( PoC1_tree
, hf_rtcp_app_poc1_reason_code2
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1392 /* The meaning of this field depends upon the reason code... */
1393 switch (reason_code
)
1395 case 1: /* Only one user */
1396 /* No additional info */
1398 case 2: /* Talk burst too long */
1399 /* Additional info is 16 bits with time (in seconds) client can request */
1400 proto_tree_add_item( PoC1_tree
, hf_rtcp_app_poc1_new_time_request
, tvb
, offset
+ 2, 2, ENC_BIG_ENDIAN
);
1402 case 3: /* No permission */
1403 /* No additional info */
1405 case 4: /* Pre-empted */
1406 /* No additional info */
1410 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " reason-code=\"%s\"",
1411 val_to_str_const(reason_code
,
1412 rtcp_app_poc1_reason_code2_vals
,
1419 case TBCP_BURST_ACKNOWLEDGMENT
:
1423 /* Code of message being acknowledged */
1424 subtype
= (tvb_get_guint8(tvb
, offset
) & 0xf8) >> 3;
1425 proto_tree_add_item( PoC1_tree
, hf_rtcp_app_poc1_ack_subtype
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1427 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " (for %s)",
1428 val_to_str_const(subtype
,
1429 rtcp_app_poc1_floor_cnt_type_vals
,
1432 /* Reason code only seen if subtype was Connect */
1433 if (subtype
== TBCP_CONNECT
)
1435 proto_tree_add_item( PoC1_tree
, hf_rtcp_app_poc1_ack_reason_code
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1438 /* 16 bits of padding follow */
1444 case TBCP_QUEUE_STATUS_REQUEST
:
1447 case TBCP_QUEUE_STATUS_RESPONSE
:
1453 proto_tree_add_item( PoC1_tree
, hf_rtcp_app_poc1_qsresp_priority
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1455 /* Queue position. 65535 indicates 'position not available' */
1456 position
= tvb_get_ntohs(tvb
, offset
+1);
1457 ti
= proto_tree_add_item( PoC1_tree
, hf_rtcp_app_poc1_qsresp_position
, tvb
, offset
+1, 2, ENC_BIG_ENDIAN
);
1460 proto_item_append_text(ti
, " (client is un-queued)");
1462 if (position
== 65535)
1464 proto_item_append_text(ti
, " (position not available)");
1467 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " position=%u", position
);
1469 /* 1 bytes of padding follows */
1476 case TBCP_DISCONNECT
:
1481 proto_item
*content
= proto_tree_add_text(PoC1_tree
, tvb
, offset
, 2, "SDES item content");
1482 gboolean contents
[5];
1484 guint8 items_set
= 0;
1486 proto_tree
*content_tree
= proto_item_add_subtree(content
, ett_poc1_conn_contents
);
1487 guint16 items_field
= tvb_get_ntohs(tvb
, offset
);
1489 /* Dissect each defined bit flag in the SDES item content */
1490 for ( i
= 0; i
< 5; i
++)
1492 proto_tree_add_item( content_tree
, hf_rtcp_app_poc1_conn_content
[i
], tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1493 contents
[i
] = items_field
& (1 << (15-i
));
1494 if (contents
[i
]) ++items_set
;
1497 /* Show how many flags were set */
1498 proto_item_append_text(content
, " (%u items)", items_set
);
1501 proto_tree_add_item( PoC1_tree
, hf_rtcp_app_poc1_conn_session_type
, tvb
, offset
+ 2, 1, ENC_BIG_ENDIAN
);
1503 /* Additional indications */
1504 proto_tree_add_item( PoC1_tree
, hf_rtcp_app_poc1_conn_add_ind_mao
, tvb
, offset
+ 3, 1, ENC_BIG_ENDIAN
);
1509 /* One SDES item for every set flag in contents array */
1510 for ( i
= 0; i
< array_length(contents
); ++i
) {
1511 if ( contents
[i
] ) {
1512 guint
/*sdes_type2,*/ sdes_len2
;
1513 /* (sdes_type2 not currently used...). Could complain if type
1514 doesn't match expected for item... */
1515 /*sdes_type2 = tvb_get_guint8( tvb, offset );*/
1517 sdes_len2
= tvb_get_guint8( tvb
, offset
);
1519 /* Add SDES field indicated as present */
1520 proto_tree_add_item( PoC1_tree
, hf_rtcp_app_poc1_conn_sdes_items
[i
], tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1522 /* Move past field */
1523 offset
+= sdes_len2
+ 1;
1524 packet_len
-= (sdes_len2
+ 2);
1533 if ((int)(offset
+ packet_len
) >= offset
)
1534 offset
+= packet_len
;
1537 else if ( g_ascii_strncasecmp(ascii_name
, mux_app_name_str
,4 ) == 0 )
1539 /* 3GPP Nb protocol extension (3GPP 29.414) for RTP Multiplexing */
1540 col_append_fstr(pinfo
->cinfo
, COL_INFO
,"( %s ) subtype=%u",ascii_name
, rtcp_subtype
);
1543 /* Applications specific data */
1545 /* If there's padding present, we have to remove that from the data part
1546 * The last octet of the packet contains the length of the padding
1548 packet_len
-= tvb_get_guint8( tvb
, offset
+ packet_len
- 1 );
1550 if (packet_len
== 4)
1552 guint16 local_port
= 0;
1554 proto_item
*mux_item
= proto_tree_add_item(tree
, hf_rtcp_app_mux
, tvb
, offset
, packet_len
, ENC_NA
);
1555 proto_tree
*mux_tree
= proto_item_add_subtree( mux_item
, ett_mux
);
1556 proto_tree_add_item( mux_tree
, hf_rtcp_app_mux_mux
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1557 proto_tree_add_item( mux_tree
, hf_rtcp_app_mux_cp
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1558 proto_tree_add_item( mux_tree
, hf_rtcp_app_mux_selection
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1559 local_port
= tvb_get_ntohs( tvb
, offset
+2 );
1560 proto_tree_add_uint( mux_tree
, hf_rtcp_app_mux_localmuxport
, tvb
, offset
+2, 2, local_port
*2 );
1564 /* fall back to just showing the data if it's the wrong length */
1565 proto_tree_add_item( tree
, hf_rtcp_app_data
, tvb
, offset
, packet_len
, ENC_NA
);
1567 if ((int)(offset
+ packet_len
) >= offset
)
1568 offset
+= packet_len
;
1573 tvbuff_t
*next_tvb
; /* tvb to pass to subdissector */
1574 /* tvb == Pass the entire APP payload so the subdissector can have access to the
1577 next_tvb
= tvb_new_subset(tvb
, offset
-8, app_length
+4, app_length
+4);
1578 /* look for registered sub-dissectors */
1579 if (dissector_try_string(rtcp_dissector_table
, ascii_name
, next_tvb
, pinfo
, tree
, NULL
)) {
1580 /* found subdissector - return tvb_length */
1584 /* If there's padding present, we have to remove that from the data part
1585 * The last octet of the packet contains the length of the padding
1587 packet_len
-= tvb_get_guint8( tvb
, offset
+ packet_len
- 1 );
1589 if ((int)(offset
+ packet_len
) >= offset
)
1590 offset
+= packet_len
;
1595 /* Unhandled application type, just show app name and raw data */
1596 col_append_fstr(pinfo
->cinfo
, COL_INFO
,"( %s ) subtype=%u",ascii_name
, rtcp_subtype
);
1599 /* Applications specific data */
1601 /* If there's padding present, we have to remove that from the data part
1602 * The last octet of the packet contains the length of the padding
1604 packet_len
-= tvb_get_guint8( tvb
, offset
+ packet_len
- 1 );
1606 proto_tree_add_item( tree
, hf_rtcp_app_data
, tvb
, offset
, packet_len
, ENC_NA
);
1607 if ((int)(offset
+ packet_len
) >= offset
)
1608 offset
+= packet_len
;
1617 dissect_rtcp_bye( tvbuff_t
*tvb
, packet_info
*pinfo
, int offset
, proto_tree
*tree
,
1618 unsigned int count
)
1621 unsigned int reason_length
= 0;
1622 gint reason_offset
= 0;
1625 while ( chunk
<= count
) {
1626 /* source identifier, 32 bits */
1627 proto_tree_add_item( tree
, hf_rtcp_ssrc_source
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1632 if ( tvb_reported_length_remaining( tvb
, offset
) > 0 ) {
1634 /* Bye reason consists of an 8 bit length l and a string with length l */
1635 reason_length
= tvb_get_guint8( tvb
, offset
);
1636 proto_tree_add_item( tree
, hf_rtcp_sdes_length
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1639 reason_offset
= offset
;
1640 reason_text
= (char*)tvb_get_string(wmem_packet_scope(), tvb
, offset
, reason_length
);
1641 proto_tree_add_string( tree
, hf_rtcp_sdes_text
, tvb
, offset
, reason_length
, reason_text
);
1642 offset
+= reason_length
;
1645 /* BYE packet padded out if string didn't fit in previous word */
1648 gint pad_size
= (4 - (offset
% 4));
1652 for (i
= 0; i
< pad_size
; i
++)
1654 if ((!(tvb_offset_exists(tvb
, offset
+ i
))) ||
1655 (tvb_get_guint8(tvb
, offset
+ i
) != 0))
1657 proto_tree_add_expert(tree
, pinfo
, &ei_rtcp_bye_reason_not_padded
, tvb
, reason_offset
, reason_length
);
1668 dissect_rtcp_sdes( tvbuff_t
*tvb
, int offset
, proto_tree
*tree
,
1669 unsigned int count
)
1672 proto_item
*sdes_item
;
1673 proto_tree
*sdes_tree
;
1674 proto_tree
*sdes_item_tree
;
1677 int items_start_offset
;
1679 unsigned int item_len
;
1680 unsigned int sdes_type
;
1681 unsigned int prefix_len
;
1684 while ( chunk
<= count
) {
1685 /* Create a subtree for this chunk; we don't yet know
1687 start_offset
= offset
;
1689 ssrc
= tvb_get_ntohl( tvb
, offset
);
1690 sdes_item
= proto_tree_add_text(tree
, tvb
, offset
, -1,
1691 "Chunk %u, SSRC/CSRC 0x%X", chunk
, ssrc
);
1692 sdes_tree
= proto_item_add_subtree( sdes_item
, ett_sdes
);
1694 /* SSRC_n source identifier, 32 bits */
1695 proto_tree_add_item( sdes_tree
, hf_rtcp_ssrc_source
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1698 /* Create a subtree for the SDES items; we don't yet know
1700 items_start_offset
= offset
;
1701 ti
= proto_tree_add_text(sdes_tree
, tvb
, offset
, -1,
1703 sdes_item_tree
= proto_item_add_subtree( ti
, ett_sdes_item
);
1706 * Not every message is ended with "null" bytes, so check for
1707 * end of frame as well.
1709 while ( tvb_reported_length_remaining( tvb
, offset
) > 0 ) {
1711 sdes_type
= tvb_get_guint8( tvb
, offset
);
1712 proto_tree_add_item( sdes_item_tree
, hf_rtcp_sdes_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1715 if ( sdes_type
== RTCP_SDES_END
) {
1720 /* Item length, 8 bits */
1721 item_len
= tvb_get_guint8( tvb
, offset
);
1722 proto_tree_add_item( sdes_item_tree
, hf_rtcp_sdes_length
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1725 if ( item_len
!= 0 ) {
1726 if ( sdes_type
== RTCP_SDES_PRIV
) {
1727 /* PRIV adds two items between the
1728 * SDES length and value - an 8 bit
1729 * length giving the length of a
1730 * "prefix string", and the string.
1732 prefix_len
= tvb_get_guint8( tvb
, offset
);
1733 if ( prefix_len
+ 1 > item_len
) {
1734 proto_tree_add_uint_format_value( sdes_item_tree
,
1735 hf_rtcp_sdes_prefix_len
, tvb
,
1736 offset
, 1, prefix_len
,
1737 "%u (bogus, must be <= %u)",
1738 prefix_len
, item_len
- 1);
1742 proto_tree_add_item( sdes_item_tree
, hf_rtcp_sdes_prefix_len
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1745 proto_tree_add_item( sdes_item_tree
, hf_rtcp_sdes_prefix_string
, tvb
, offset
, prefix_len
, ENC_ASCII
|ENC_NA
);
1746 offset
+= prefix_len
;
1747 item_len
-= prefix_len
+1;
1748 if ( item_len
== 0 )
1751 proto_tree_add_item( sdes_item_tree
, hf_rtcp_sdes_text
, tvb
, offset
, item_len
, ENC_ASCII
|ENC_NA
);
1756 /* Set the length of the items subtree. */
1757 proto_item_set_len(ti
, offset
- items_start_offset
);
1759 /* 32 bits = 4 bytes, so.....
1760 * If offset % 4 != 0, we divide offset by 4, add one and then
1761 * multiply by 4 again to reach the boundary
1763 if ( offset
% 4 != 0 )
1764 offset
= ((offset
/ 4) + 1 ) * 4;
1766 /* Set the length of this chunk. */
1767 proto_item_set_len(sdes_item
, offset
- start_offset
);
1775 static void parse_xr_type_specific_field(tvbuff_t
*tvb
, gint offset
, guint block_type
,
1776 proto_tree
*tree
, guint8
*thinning
)
1778 guint8 flags
= tvb_get_guint8(tvb
, offset
);
1780 switch (block_type
) {
1781 case RTCP_XR_LOSS_RLE
:
1782 case RTCP_XR_DUP_RLE
:
1783 case RTCP_XR_PKT_RXTIMES
:
1784 *thinning
= tvb_get_guint8(tvb
, offset
) & 0x0F;
1785 proto_tree_add_item(tree
, hf_rtcp_xr_thinning
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1788 case RTCP_XR_STATS_SUMRY
:
1789 proto_tree_add_boolean(tree
, hf_rtcp_xr_stats_loss_flag
, tvb
, offset
, 1, flags
);
1790 proto_tree_add_boolean(tree
, hf_rtcp_xr_stats_dup_flag
, tvb
, offset
, 1, flags
);
1791 proto_tree_add_boolean(tree
, hf_rtcp_xr_stats_jitter_flag
, tvb
, offset
, 1, flags
);
1792 proto_tree_add_item(tree
, hf_rtcp_xr_stats_ttl
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1796 proto_tree_add_item(tree
, hf_rtcp_xr_block_specific
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1801 static gboolean
validate_xr_block_length(tvbuff_t
*tvb
, packet_info
*pinfo
, int offset
, guint block_type
, guint block_len
, proto_tree
*tree
)
1805 ti
= proto_tree_add_uint(tree
, hf_rtcp_xr_block_length
, tvb
, offset
, 2, block_len
);
1806 switch (block_type
) {
1807 case RTCP_XR_REF_TIME
:
1809 expert_add_info_format(pinfo
, ti
, &ei_rtcp_xr_block_length_bad
, "Invalid block length, should be 2");
1812 case RTCP_XR_STATS_SUMRY
:
1814 expert_add_info_format(pinfo
, ti
, &ei_rtcp_xr_block_length_bad
, "Invalid block length, should be 9");
1817 case RTCP_XR_VOIP_METRCS
:
1818 case RTCP_XR_BT_XNQ
:
1820 expert_add_info_format(pinfo
, ti
, &ei_rtcp_xr_block_length_bad
, "Invalid block length, should be 8");
1825 expert_add_info_format(pinfo
, ti
, &ei_rtcp_xr_block_length_bad
, "Invalid block length, should be 7");
1835 dissect_rtcp_xr(tvbuff_t
*tvb
, packet_info
*pinfo
, int offset
, proto_tree
*tree
, gint packet_len
)
1839 /* Packet length should at least be 4 */
1840 if (packet_len
< 4) {
1841 proto_tree_add_text(tree
, tvb
, offset
, packet_len
, "Missing Sender SSRC");
1842 return offset
+ packet_len
;
1846 proto_tree_add_item( tree
, hf_rtcp_ssrc_sender
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1850 for( block_num
= 1; packet_len
> 0; block_num
++) {
1851 guint block_type
= tvb_get_guint8(tvb
, offset
), block_length
= 0;
1852 gint content_length
= 0;
1853 guint8 thinning
= 0;
1854 /*gboolean valid = TRUE;*/
1856 /* Create a subtree for this block, dont know the length yet*/
1857 proto_item
*block
= proto_tree_add_text(tree
, tvb
, offset
, -1, "Block %u", block_num
);
1858 proto_tree
*xr_block_tree
= proto_item_add_subtree(block
, ett_xr_block
);
1859 proto_item
*contents
;
1860 proto_tree
*content_tree
;
1862 proto_tree_add_item(xr_block_tree
, hf_rtcp_xr_block_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1864 if (packet_len
>= 2) {
1865 parse_xr_type_specific_field(tvb
, offset
+ 1, block_type
, xr_block_tree
, &thinning
);
1866 if (packet_len
>= 4) {
1867 block_length
= tvb_get_ntohs(tvb
, offset
+ 2);
1868 /* XXX: What if FALSE return from the following ?? */
1869 /*valid =*/ validate_xr_block_length(tvb
, pinfo
, offset
+ 2, block_type
, block_length
, xr_block_tree
);
1872 proto_tree_add_text(xr_block_tree
, tvb
, offset
+ 1, packet_len
, "Missing Required Block Headers");
1873 return offset
+ packet_len
;
1876 content_length
= block_length
* 4;
1877 proto_item_set_len(block
, content_length
+ 4);
1879 if (content_length
> packet_len
) {
1880 proto_tree_add_text(xr_block_tree
, tvb
, offset
+ 2, 2, "Block length is greater than packet length");
1886 contents
= proto_tree_add_text(xr_block_tree
, tvb
, offset
, content_length
, "Contents");
1887 content_tree
= proto_item_add_subtree(contents
, ett_xr_block_contents
);
1889 switch (block_type
) {
1890 case RTCP_XR_VOIP_METRCS
: {
1891 guint fraction_rate
;
1894 proto_tree_add_item(content_tree
, hf_rtcp_ssrc_source
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1898 fraction_rate
= tvb_get_guint8(tvb
, offset
);
1899 proto_tree_add_uint_format_value(content_tree
, hf_rtcp_ssrc_fraction
, tvb
, offset
, 1,
1900 fraction_rate
, "%u / 256", fraction_rate
);
1904 fraction_rate
= tvb_get_guint8(tvb
, offset
);
1905 proto_tree_add_uint_format_value(content_tree
, hf_rtcp_ssrc_discarded
, tvb
, offset
, 1,
1906 fraction_rate
, "%u / 256", fraction_rate
);
1910 proto_tree_add_item(content_tree
, hf_rtcp_xr_voip_metrics_burst_density
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1914 proto_tree_add_item(content_tree
, hf_rtcp_xr_voip_metrics_gap_density
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1917 /* Burst Duration */
1918 proto_tree_add_item(content_tree
, hf_rtcp_xr_voip_metrics_burst_duration
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1922 proto_tree_add_item(content_tree
, hf_rtcp_xr_voip_metrics_gap_duration
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1925 /* Round Trip Delay */
1926 proto_tree_add_item(content_tree
, hf_rtcp_xr_voip_metrics_rtdelay
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1929 /* End System Delay */
1930 proto_tree_add_item(content_tree
, hf_rtcp_xr_voip_metrics_esdelay
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1934 if (tvb_get_guint8(tvb
, offset
) == 0x7f)
1935 proto_tree_add_int_format_value(content_tree
, hf_rtcp_xr_voip_metrics_siglevel
, tvb
, offset
, 1, 0x7f, "Unavailable");
1937 proto_tree_add_item(content_tree
, hf_rtcp_xr_voip_metrics_siglevel
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1941 if (tvb_get_guint8(tvb
, offset
) == 0x7f)
1942 proto_tree_add_int_format_value(content_tree
, hf_rtcp_xr_voip_metrics_noiselevel
, tvb
, offset
, 1, 0x7f, "Unavailable");
1944 proto_tree_add_item(content_tree
, hf_rtcp_xr_voip_metrics_noiselevel
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1948 if (tvb_get_guint8(tvb
, offset
) == 0x7f)
1949 proto_tree_add_uint_format_value(content_tree
, hf_rtcp_xr_voip_metrics_rerl
, tvb
, offset
, 1, 0x7f, "Unavailable");
1951 proto_tree_add_item(content_tree
, hf_rtcp_xr_voip_metrics_rerl
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1955 proto_tree_add_item(content_tree
, hf_rtcp_xr_voip_metrics_gmin
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1959 if (tvb_get_guint8(tvb
, offset
) == 0x7f)
1960 proto_tree_add_uint_format_value(content_tree
, hf_rtcp_xr_voip_metrics_rfactor
, tvb
, offset
, 1, 0x7f, "Unavailable");
1962 proto_tree_add_item(content_tree
, hf_rtcp_xr_voip_metrics_rfactor
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1965 /* external R Factor */
1966 if (tvb_get_guint8(tvb
, offset
) == 0x7f)
1967 proto_tree_add_uint_format_value(content_tree
, hf_rtcp_xr_voip_metrics_extrfactor
, tvb
, offset
, 1, 0x7f, "Unavailable");
1969 proto_tree_add_item(content_tree
, hf_rtcp_xr_voip_metrics_extrfactor
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1973 if (tvb_get_guint8(tvb
, offset
) == 0x7f)
1974 proto_tree_add_float_format_value(content_tree
, hf_rtcp_xr_voip_metrics_moslq
, tvb
, offset
, 1, 0x7f, "Unavailable");
1976 proto_tree_add_float(content_tree
, hf_rtcp_xr_voip_metrics_moslq
, tvb
, offset
, 1,
1977 (float) (tvb_get_guint8(tvb
, offset
) / 10.0));
1981 if (tvb_get_guint8(tvb
, offset
) == 0x7f)
1982 proto_tree_add_float_format_value(content_tree
, hf_rtcp_xr_voip_metrics_moscq
, tvb
, offset
, 1, 0x7f, "Unavailable");
1984 proto_tree_add_float(content_tree
, hf_rtcp_xr_voip_metrics_moscq
, tvb
, offset
, 1,
1985 (float) (tvb_get_guint8(tvb
, offset
) / 10.0));
1988 /* PLC, JB Adaptive, JB Rate */
1989 proto_tree_add_item(content_tree
, hf_rtcp_xr_voip_metrics_plc
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1990 proto_tree_add_item(content_tree
, hf_rtcp_xr_voip_metrics_jbadaptive
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1991 proto_tree_add_item(content_tree
, hf_rtcp_xr_voip_metrics_jbrate
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1992 offset
+= 2; /* skip over reseved bit */
1995 proto_tree_add_item(content_tree
, hf_rtcp_xr_voip_metrics_jbnominal
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1999 proto_tree_add_item(content_tree
, hf_rtcp_xr_voip_metrics_jbmax
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2003 proto_tree_add_item(content_tree
, hf_rtcp_xr_voip_metrics_jbabsmax
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2009 case RTCP_XR_STATS_SUMRY
: {
2011 proto_tree_add_item(content_tree
, hf_rtcp_ssrc_source
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
2015 proto_tree_add_item(content_tree
, hf_rtcp_xr_beginseq
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2019 proto_tree_add_item(content_tree
, hf_rtcp_xr_endseq
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2023 proto_tree_add_item(content_tree
, hf_rtcp_xr_stats_lost
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
2027 proto_tree_add_item(content_tree
, hf_rtcp_xr_stats_dups
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
2031 proto_tree_add_item(content_tree
, hf_rtcp_xr_stats_minjitter
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
2035 proto_tree_add_item(content_tree
, hf_rtcp_xr_stats_maxjitter
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
2039 proto_tree_add_item(content_tree
, hf_rtcp_xr_stats_meanjitter
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
2043 proto_tree_add_item(content_tree
, hf_rtcp_xr_stats_devjitter
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
2047 proto_tree_add_item(content_tree
, hf_rtcp_xr_stats_minttl
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2051 proto_tree_add_item(content_tree
, hf_rtcp_xr_stats_maxttl
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2055 proto_tree_add_item(content_tree
, hf_rtcp_xr_stats_meanttl
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2059 proto_tree_add_item(content_tree
, hf_rtcp_xr_stats_devttl
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2065 case RTCP_XR_REF_TIME
: {
2066 guint32 ts_msw
, ts_lsw
;
2068 ts_msw
= tvb_get_ntohl(tvb
, offset
);
2069 proto_tree_add_text(content_tree
, tvb
, offset
, 4, "Timestamp, MSW: %u", ts_msw
);
2071 ts_lsw
= tvb_get_ntohl(tvb
, offset
);
2072 proto_tree_add_text(content_tree
, tvb
, offset
, 4, "Timestamp, LSW: %u", ts_lsw
);
2078 case RTCP_XR_DLRR
: {
2079 /* Each report block is 12 bytes */
2080 gint sources
= content_length
/ 12;
2082 for(counter
= 0; counter
< sources
; counter
++) {
2083 /* Create a new subtree for a length of 12 bytes */
2084 proto_tree
*ti
= proto_tree_add_text(content_tree
, tvb
, offset
, 12, "Source %u", counter
+ 1);
2085 proto_tree
*ssrc_tree
= proto_item_add_subtree(ti
, ett_xr_ssrc
);
2087 /* SSRC_n source identifier, 32 bits */
2088 proto_tree_add_item(ssrc_tree
, hf_rtcp_ssrc_source
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
2091 /* Last RR timestamp */
2092 proto_tree_add_item(ssrc_tree
, hf_rtcp_xr_lrr
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
2095 /* Delay since last RR timestamp */
2096 proto_tree_add_item(ssrc_tree
, hf_rtcp_xr_dlrr
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
2100 if (content_length
% 12 != 0)
2101 offset
+= content_length
% 12;
2105 case RTCP_XR_PKT_RXTIMES
: {
2106 /* 8 bytes of fixed header */
2108 gint count
= 0, skip
= 8;
2112 proto_tree_add_item(content_tree
, hf_rtcp_ssrc_source
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
2116 begin
= tvb_get_ntohs(tvb
, offset
);
2117 /* Apply Thinning value */
2118 begin
= (begin
+ ((1<<thinning
)-1)) & ~((1<<thinning
)-1);
2119 proto_tree_add_item(content_tree
, hf_rtcp_xr_beginseq
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2123 proto_tree_add_item(content_tree
, hf_rtcp_xr_endseq
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2126 for(count
= 0; skip
< content_length
; skip
+= 4, count
++) {
2127 rcvd_time
= tvb_get_ntohl(tvb
, offset
);
2128 proto_tree_add_uint_format(content_tree
, hf_rtcp_xr_receipt_time_seq
, tvb
,
2129 offset
, 4, rcvd_time
, "Seq: %u, Receipt Time: %u",
2130 (begin
+ (count
<<thinning
)) % 65536, rcvd_time
);
2136 case RTCP_XR_LOSS_RLE
:
2137 case RTCP_XR_DUP_RLE
: {
2138 /* 8 bytes of fixed header */
2139 gint count
= 0, skip
= 8;
2140 proto_item
*chunks_item
;
2141 proto_tree
*chunks_tree
;
2144 proto_tree_add_item(content_tree
, hf_rtcp_ssrc_source
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
2148 proto_tree_add_item(content_tree
, hf_rtcp_xr_beginseq
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2152 proto_tree_add_item(content_tree
, hf_rtcp_xr_endseq
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2156 chunks_item
= proto_tree_add_text(content_tree
, tvb
, offset
, content_length
,"Report Chunks");
2157 chunks_tree
= proto_item_add_subtree(chunks_item
, ett_xr_loss_chunk
);
2159 for(count
= 1; skip
< content_length
; skip
+= 2, count
++) {
2160 guint value
= tvb_get_ntohs(tvb
, offset
);
2163 proto_tree_add_text(chunks_tree
, tvb
, offset
, 2,
2164 "Chunk: %u -- Null Terminator ",
2166 } else if ( ! ( value
& 0x8000 )) {
2167 const gchar
*run_type
= (value
& 0x4000) ? "1s" : "0s";
2169 proto_tree_add_text(chunks_tree
, tvb
, offset
, 2,
2170 "Chunk: %u -- Length Run %s, length: %u",
2171 count
, run_type
, value
);
2174 other_decode_bitfield_value(bits
, value
, 0x00007FFF, 16);
2175 proto_tree_add_text(chunks_tree
, tvb
, offset
, 2,
2176 "Chunk: %u -- Bit Vector, bits: %s",
2184 case RTCP_XR_BT_XNQ
: { /* BT XNQ block as defined in RFC5093 */
2185 guint temp_value
; /* used when checking spare bits in block type 8 */
2187 proto_tree_add_item(content_tree
, hf_rtcp_xr_btxnq_begseq
, tvb
, offset
, 2, ENC_BIG_ENDIAN
); /* Begin Sequence number */
2188 proto_tree_add_item(content_tree
, hf_rtcp_xr_btxnq_endseq
, tvb
, offset
+2, 2, ENC_BIG_ENDIAN
); /* End Sequence number */
2191 proto_tree_add_item(content_tree
, hf_rtcp_xr_btxnq_vmaxdiff
, tvb
, offset
, 2, ENC_BIG_ENDIAN
); /* vmaxdiff */
2192 proto_tree_add_item(content_tree
, hf_rtcp_xr_btxnq_vrange
, tvb
, offset
+2, 2, ENC_BIG_ENDIAN
); /* vrange */
2195 proto_tree_add_item(content_tree
, hf_rtcp_xr_btxnq_vsum
, tvb
, offset
, 4, ENC_BIG_ENDIAN
); /* vsum */
2198 proto_tree_add_item(content_tree
, hf_rtcp_xr_btxnq_cycles
, tvb
, offset
, 2, ENC_BIG_ENDIAN
); /* cycle count */
2199 proto_tree_add_item(content_tree
, hf_rtcp_xr_btxnq_jbevents
, tvb
, offset
+2, 2, ENC_BIG_ENDIAN
); /* jitter buffer events */
2202 temp_value
= tvb_get_ntohl(tvb
, offset
); /* tDegNet */
2203 if ((temp_value
& 0x0ff000000) != 0)
2204 proto_tree_add_string(content_tree
, hf_rtcp_xr_btxnq_spare
, tvb
, offset
, 1, "Warning - spare bits not 0");
2205 proto_tree_add_uint(content_tree
, hf_rtcp_xr_btxnq_tdegnet
, tvb
, offset
+1, 3, temp_value
& 0x0ffffff);
2208 temp_value
= tvb_get_ntohl(tvb
, offset
); /* tDegJit */
2209 if ((temp_value
& 0x0ff000000) != 0)
2210 proto_tree_add_string(content_tree
, hf_rtcp_xr_btxnq_spare
, tvb
, offset
, 1, "Warning - spare bits not 0");
2211 proto_tree_add_uint(content_tree
, hf_rtcp_xr_btxnq_tdegjit
, tvb
, offset
+1, 3, temp_value
& 0x0ffffff);
2214 temp_value
= tvb_get_ntohl(tvb
, offset
); /* ES */
2215 if ((temp_value
& 0x0ff000000) != 0)
2216 proto_tree_add_string(content_tree
, hf_rtcp_xr_btxnq_spare
, tvb
, offset
, 1, "Warning - spare bits not 0");
2217 proto_tree_add_uint(content_tree
, hf_rtcp_xr_btxnq_es
, tvb
, offset
+1, 3, temp_value
& 0x0ffffff);
2220 temp_value
= tvb_get_ntohl(tvb
, offset
); /* SES */
2221 if ((temp_value
& 0x0ff000000) != 0)
2222 proto_tree_add_string(content_tree
, hf_rtcp_xr_btxnq_spare
, tvb
, offset
, 1, "Warning - spare bits not 0");
2223 proto_tree_add_uint(content_tree
, hf_rtcp_xr_btxnq_ses
, tvb
, offset
+1, 3, temp_value
& 0x0ffffff);
2228 case RTCP_XR_IDMS
: {
2230 int hour
,min
,sec
,msec
;
2233 proto_tree_add_item(content_tree
, hf_rtcp_xr_idms_spst
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2235 proto_tree_add_item(content_tree
, hf_rtcp_xr_idms_pt
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2237 proto_tree_add_item(content_tree
, hf_rtcp_xr_idms_msci
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
2239 proto_tree_add_item(content_tree
, hf_rtcp_xr_idms_source_ssrc
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
2241 proto_tree_add_item(content_tree
, hf_rtcp_xr_idms_ntp_rcv_ts_msw
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
2243 proto_tree_add_item(content_tree
, hf_rtcp_xr_idms_ntp_rcv_ts_lsw
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
2245 item
= proto_tree_add_item(content_tree
, hf_rtcp_ntp
, tvb
, offset
-8, 8, ENC_TIME_NTP
|ENC_BIG_ENDIAN
);
2246 PROTO_ITEM_SET_GENERATED(item
);
2248 proto_tree_add_item(content_tree
, hf_rtcp_xr_idms_rtp_ts
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
2250 proto_tree_add_item(content_tree
, hf_rtcp_xr_idms_ntp_pres_ts
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
2253 tmp_ts
= tvb_get_ntohl(tvb
,offset
-4);
2254 hour
= ( (int) ( tmp_ts
>> 16 ) ) / 3600;
2255 min
= (( (int) ( tmp_ts
>> 16 ) ) - hour
* 3600) / 60;
2256 sec
= (( (int) ( tmp_ts
>> 16 ) ) - hour
* 3600 - min
* 60);
2257 msec
= ( (int) ( tmp_ts
& 0x0000FFFF ) ) / 66;
2259 item
= proto_tree_add_text( content_tree
, tvb
, offset
-4, 4,
2260 "short NTP timestamp of presentation: %d:%02d:%02d:%03d [h:m:s:ms] ",
2262 PROTO_ITEM_SET_GENERATED(item
);
2266 /* skip over the unknown block */
2267 offset
+= content_length
;
2269 } /* switch (block_type) */
2270 packet_len
-= content_length
;
2271 } /* for (block_num = ...) */
2276 dissect_rtcp_avb( tvbuff_t
*tvb
, packet_info
*pinfo _U_
, int offset
, proto_tree
*tree
,
2277 unsigned int packet_length _U_
)
2280 proto_tree_add_item( tree
, hf_rtcp_ssrc_source
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
2284 proto_tree_add_item( tree
, hf_rtcp_name_ascii
, tvb
, offset
, 4, ENC_ASCII
);
2288 gmTimeBaseIndicator | gmIdentity - low 16 bit
2289 gmIdentity - mid 32 bit
2290 gmIdentity - high 32 bit
2291 stream_id - lower 32 bit
2292 stream_id - higher 32 bit
2297 /* RTP timestamp, 32 bits */
2298 proto_tree_add_item( tree
, hf_rtcp_rtp_timestamp
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
2305 dissect_rtcp_rsi( tvbuff_t
*tvb
, packet_info
*pinfo _U_
, int offset
, proto_tree
*tree
,
2306 unsigned int packet_length
)
2311 proto_tree_add_item( tree
, hf_rtcp_ssrc_source
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
2315 proto_tree_add_item( tree
, hf_rtcp_ssrc_source
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
2319 proto_tree_add_item(tree
, hf_rtcp_ntp_msw
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
2321 proto_tree_add_item(tree
, hf_rtcp_ntp_lsw
, tvb
, offset
+4, 4, ENC_BIG_ENDIAN
);
2323 item
= proto_tree_add_item(tree
, hf_rtcp_ntp
, tvb
, offset
, 8, ENC_TIME_NTP
|ENC_BIG_ENDIAN
);
2324 PROTO_ITEM_SET_GENERATED(item
);
2327 /* Sub report blocks */
2329 return offset
+ (packet_length
- 16);
2333 dissect_rtcp_token( tvbuff_t
*tvb
, packet_info
*pinfo _U_
, int offset
, proto_tree
*tree
,
2334 unsigned int packet_len
, guint rtcp_subtype _U_
)
2337 proto_tree_add_item( tree
, hf_rtcp_ssrc_source
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
2342 return offset
+ (packet_len
- 4);
2346 dissect_rtcp_rr( packet_info
*pinfo
, tvbuff_t
*tvb
, int offset
, proto_tree
*tree
,
2347 unsigned int count
, unsigned int packet_length
)
2349 unsigned int counter
;
2350 proto_tree
*ssrc_tree
;
2351 proto_tree
*ssrc_sub_tree
;
2352 proto_tree
*high_sec_tree
;
2355 int rr_offset
= offset
;
2359 while ( counter
<= count
) {
2362 /* Create a new subtree for a length of 24 bytes */
2363 ti
= proto_tree_add_text(tree
, tvb
, offset
, 24,
2364 "Source %u", counter
);
2365 ssrc_tree
= proto_item_add_subtree( ti
, ett_ssrc
);
2367 /* SSRC_n source identifier, 32 bits */
2368 proto_tree_add_item( ssrc_tree
, hf_rtcp_ssrc_source
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
2371 ti
= proto_tree_add_text(ssrc_tree
, tvb
, offset
, 20, "SSRC contents" );
2372 ssrc_sub_tree
= proto_item_add_subtree( ti
, ett_ssrc_item
);
2374 /* Fraction lost, 8bits */
2375 rr_flt
= tvb_get_guint8( tvb
, offset
);
2376 proto_tree_add_uint_format_value( ssrc_sub_tree
, hf_rtcp_ssrc_fraction
, tvb
,
2377 offset
, 1, rr_flt
, "%u / 256", rr_flt
);
2380 /* Cumulative number of packets lost, 24 bits */
2381 proto_tree_add_item( ssrc_sub_tree
, hf_rtcp_ssrc_cum_nr
, tvb
,
2382 offset
, 3, ENC_BIG_ENDIAN
);
2385 /* Extended highest sequence nr received, 32 bits
2386 * Just for the sake of it, let's add another subtree
2387 * because this might be a little clearer
2389 ti
= proto_tree_add_item( ssrc_tree
, hf_rtcp_ssrc_ext_high_seq
,
2390 tvb
, offset
, 4, ENC_BIG_ENDIAN
);
2391 high_sec_tree
= proto_item_add_subtree( ti
, ett_ssrc_ext_high
);
2392 /* Sequence number cycles */
2393 proto_tree_add_item( high_sec_tree
, hf_rtcp_ssrc_high_cycles
,
2394 tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2396 /* highest sequence number received */
2397 proto_tree_add_item( high_sec_tree
, hf_rtcp_ssrc_high_seq
,
2398 tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2401 /* Interarrival jitter */
2402 proto_tree_add_item( ssrc_tree
, hf_rtcp_ssrc_jitter
, tvb
,
2403 offset
, 4, ENC_BIG_ENDIAN
);
2406 /* Last SR timestamp */
2407 lsr
= tvb_get_ntohl( tvb
, offset
);
2408 proto_tree_add_item( ssrc_tree
, hf_rtcp_ssrc_lsr
, tvb
,
2409 offset
, 4, ENC_BIG_ENDIAN
);
2412 /* Delay since last SR timestamp */
2413 dlsr
= tvb_get_ntohl( tvb
, offset
);
2414 ti
= proto_tree_add_item( ssrc_tree
, hf_rtcp_ssrc_dlsr
, tvb
,
2415 offset
, 4, ENC_BIG_ENDIAN
);
2416 proto_item_append_text(ti
, " (%d milliseconds)",
2417 (int)(((double)dlsr
/(double)65536) * 1000.0));
2420 /* Do roundtrip calculation */
2421 if (global_rtcp_show_roundtrip_calculation
)
2423 /* Based on delay since SR was sent in other direction */
2424 calculate_roundtrip_delay(tvb
, pinfo
, ssrc_tree
, lsr
, dlsr
);
2430 /* If length remaining, assume profile-specific extension bytes */
2431 if ((offset
-rr_offset
) < (int)packet_length
)
2433 proto_tree_add_item(tree
, hf_rtcp_profile_specific_extension
, tvb
, offset
,
2434 packet_length
- (offset
- rr_offset
), ENC_NA
);
2435 offset
= rr_offset
+ packet_length
;
2442 dissect_rtcp_sr( packet_info
*pinfo
, tvbuff_t
*tvb
, int offset
, proto_tree
*tree
,
2443 unsigned int count
, unsigned int packet_length
)
2446 guint32 ts_msw
, ts_lsw
;
2447 int sr_offset
= offset
;
2450 ts_msw
= tvb_get_ntohl(tvb
, offset
);
2451 proto_tree_add_item(tree
, hf_rtcp_ntp_msw
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
2453 ts_lsw
= tvb_get_ntohl(tvb
, offset
+4);
2454 proto_tree_add_item(tree
, hf_rtcp_ntp_lsw
, tvb
, offset
+4, 4, ENC_BIG_ENDIAN
);
2456 item
= proto_tree_add_item(tree
, hf_rtcp_ntp
, tvb
, offset
, 8, ENC_TIME_NTP
|ENC_BIG_ENDIAN
);
2457 PROTO_ITEM_SET_GENERATED(item
);
2460 /* RTP timestamp, 32 bits */
2461 proto_tree_add_item( tree
, hf_rtcp_rtp_timestamp
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
2463 /* Sender's packet count, 32 bits */
2464 proto_tree_add_item( tree
, hf_rtcp_sender_pkt_cnt
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
2466 /* Sender's octet count, 32 bits */
2467 proto_tree_add_item( tree
, hf_rtcp_sender_oct_cnt
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
2470 /* Record the time of this packet in the sender's conversation */
2471 if (global_rtcp_show_roundtrip_calculation
)
2473 /* Use middle 32 bits of 64-bit time value */
2474 guint32 lsr
= ((ts_msw
& 0x0000ffff) << 16 | (ts_lsw
& 0xffff0000) >> 16);
2476 /* Record the time that we sent this in appropriate conversation */
2477 remember_outgoing_sr(pinfo
, lsr
);
2480 /* The rest of the packet is equal to the RR packet */
2482 offset
= dissect_rtcp_rr( pinfo
, tvb
, offset
, tree
, count
, packet_length
-(offset
-sr_offset
) );
2485 /* If length remaining, assume profile-specific extension bytes */
2486 if ((offset
-sr_offset
) < (int)packet_length
)
2488 proto_tree_add_item(tree
, hf_rtcp_profile_specific_extension
, tvb
, offset
,
2489 packet_length
- (offset
- sr_offset
), ENC_NA
);
2490 offset
= sr_offset
+ packet_length
;
2497 /* Look for conversation info and display any setup info found */
2498 void show_setup_info(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
)
2500 /* Conversation and current data */
2501 struct _rtcp_conversation_info
*p_conv_data
;
2503 /* Use existing packet data if available */
2504 p_conv_data
= (struct _rtcp_conversation_info
*)p_get_proto_data(pinfo
->fd
, proto_rtcp
, 0);
2508 conversation_t
*p_conv
;
2509 /* First time, get info from conversation */
2510 p_conv
= find_conversation(pinfo
->fd
->num
, &pinfo
->net_dst
, &pinfo
->net_src
,
2512 pinfo
->destport
, pinfo
->srcport
, NO_ADDR_B
);
2516 /* Look for data in conversation */
2517 struct _rtcp_conversation_info
*p_conv_packet_data
;
2518 p_conv_data
= (struct _rtcp_conversation_info
*)conversation_get_proto_data(p_conv
, proto_rtcp
);
2522 /* Save this conversation info into packet info */
2523 p_conv_packet_data
= (struct _rtcp_conversation_info
*)wmem_memdup(wmem_file_scope(),
2524 p_conv_data
, sizeof(struct _rtcp_conversation_info
));
2526 p_add_proto_data(pinfo
->fd
, proto_rtcp
, 0, p_conv_packet_data
);
2531 /* Create setup info subtree with summary info. */
2532 if (p_conv_data
&& p_conv_data
->setup_method_set
)
2534 proto_tree
*rtcp_setup_tree
;
2535 proto_item
*ti
= proto_tree_add_string_format(tree
, hf_rtcp_setup
, tvb
, 0, 0,
2537 "Stream setup by %s (frame %u)",
2538 p_conv_data
->setup_method
,
2539 p_conv_data
->setup_frame_number
);
2540 PROTO_ITEM_SET_GENERATED(ti
);
2541 rtcp_setup_tree
= proto_item_add_subtree(ti
, ett_rtcp_setup
);
2542 if (rtcp_setup_tree
)
2544 /* Add details into subtree */
2545 proto_item
*item
= proto_tree_add_uint(rtcp_setup_tree
, hf_rtcp_setup_frame
,
2546 tvb
, 0, 0, p_conv_data
->setup_frame_number
);
2547 PROTO_ITEM_SET_GENERATED(item
);
2548 item
= proto_tree_add_string(rtcp_setup_tree
, hf_rtcp_setup_method
,
2549 tvb
, 0, 0, p_conv_data
->setup_method
);
2550 PROTO_ITEM_SET_GENERATED(item
);
2556 /* Update conversation data to record time that outgoing rr/sr was sent */
2557 static void remember_outgoing_sr(packet_info
*pinfo
, guint32 lsr
)
2559 conversation_t
*p_conv
;
2560 struct _rtcp_conversation_info
*p_conv_data
;
2561 struct _rtcp_conversation_info
*p_packet_data
;
2563 /* This information will be accessed when an incoming packet comes back to
2564 the side that sent this packet, so no use storing in the packet
2565 info. However, do store the fact that we've already set this info
2569 /**************************************************************************/
2570 /* First of all, see if we've already stored this information for this sr */
2572 /* Look first in packet info */
2573 p_packet_data
= (struct _rtcp_conversation_info
*)p_get_proto_data(pinfo
->fd
, proto_rtcp
, 0);
2574 if (p_packet_data
&& p_packet_data
->last_received_set
&&
2575 (p_packet_data
->last_received_frame_number
>= pinfo
->fd
->num
))
2577 /* We already did this, OK */
2582 /**************************************************************************/
2583 /* Otherwise, we want to find/create the conversation and update it */
2585 /* First time, get info from conversation.
2586 Even though we think of this as an outgoing packet being sent,
2587 we store the time as being received by the destination. */
2588 p_conv
= find_conversation(pinfo
->fd
->num
, &pinfo
->net_dst
, &pinfo
->net_src
,
2590 pinfo
->destport
, pinfo
->srcport
, NO_ADDR_B
);
2592 /* If the conversation doesn't exist, create it now. */
2595 p_conv
= conversation_new(pinfo
->fd
->num
, &pinfo
->net_dst
, &pinfo
->net_src
, PT_UDP
,
2596 pinfo
->destport
, pinfo
->srcport
,
2600 /* Give up if can't create it */
2606 /****************************************************/
2607 /* Now find/create conversation data */
2608 p_conv_data
= (struct _rtcp_conversation_info
*)conversation_get_proto_data(p_conv
, proto_rtcp
);
2611 /* Allocate memory for data */
2612 p_conv_data
= wmem_new0(wmem_file_scope(), struct _rtcp_conversation_info
);
2614 /* Add it to conversation. */
2615 conversation_add_proto_data(p_conv
, proto_rtcp
, p_conv_data
);
2618 /*******************************************************/
2619 /* Update conversation data */
2620 p_conv_data
->last_received_set
= TRUE
;
2621 p_conv_data
->last_received_frame_number
= pinfo
->fd
->num
;
2622 p_conv_data
->last_received_timestamp
= pinfo
->fd
->abs_ts
;
2623 p_conv_data
->last_received_ts
= lsr
;
2626 /****************************************************************/
2627 /* Update packet info to record conversation state */
2629 /* Will use/create packet info */
2632 p_packet_data
= wmem_new0(wmem_file_scope(), struct _rtcp_conversation_info
);
2634 p_add_proto_data(pinfo
->fd
, proto_rtcp
, 0, p_packet_data
);
2637 /* Copy current conversation data into packet info */
2638 p_packet_data
->last_received_set
= TRUE
;
2639 p_packet_data
->last_received_frame_number
= p_conv_data
->last_received_frame_number
;
2643 /* Use received sr to work out what the roundtrip delay is
2644 (at least between capture point and the other endpoint involved in
2645 the conversation) */
2646 static void calculate_roundtrip_delay(tvbuff_t
*tvb
, packet_info
*pinfo
,
2647 proto_tree
*tree
, guint32 lsr
, guint32 dlsr
)
2649 /*****************************************************/
2650 /* This is called dissecting an SR. We need to:
2651 - look in the packet info for stored calculation. If found, use.
2652 - look up the conversation of the sending side to see when the
2653 'last SR' was detected (received)
2654 - calculate the network delay using the that packet time,
2655 this packet time, and dlsr
2656 *****************************************************/
2658 conversation_t
*p_conv
;
2659 struct _rtcp_conversation_info
*p_conv_data
;
2660 struct _rtcp_conversation_info
*p_packet_data
;
2663 /*************************************************/
2664 /* Look for previous result */
2665 p_packet_data
= (struct _rtcp_conversation_info
*)p_get_proto_data(pinfo
->fd
, proto_rtcp
, 0);
2666 if (p_packet_data
&& p_packet_data
->lsr_matched
)
2669 add_roundtrip_delay_info(tvb
, pinfo
, tree
,
2670 p_packet_data
->calculated_delay_used_frame
,
2671 p_packet_data
->calculated_delay_report_gap
,
2672 p_packet_data
->calculated_delay
);
2677 /********************************************************************/
2678 /* Look for captured timestamp of last SR in conversation of sender */
2679 /* of this packet */
2680 p_conv
= find_conversation(pinfo
->fd
->num
, &pinfo
->net_src
, &pinfo
->net_dst
,
2682 pinfo
->srcport
, pinfo
->destport
, NO_ADDR_B
);
2688 /* Look for conversation data */
2689 p_conv_data
= (struct _rtcp_conversation_info
*)conversation_get_proto_data(p_conv
, proto_rtcp
);
2695 if (p_conv_data
->last_received_set
)
2697 /* Store result of calculation in packet info */
2700 /* Create packet info if it doesn't exist */
2701 p_packet_data
= wmem_new0(wmem_file_scope(), struct _rtcp_conversation_info
);
2703 /* Set as packet info */
2704 p_add_proto_data(pinfo
->fd
, proto_rtcp
, 0, p_packet_data
);
2707 /* Don't allow match seemingly calculated from same (or later!) frame */
2708 if (pinfo
->fd
->num
<= p_conv_data
->last_received_frame_number
)
2713 /* The previous report must match the lsr given here */
2714 if (p_conv_data
->last_received_ts
== lsr
)
2716 /* Look at time of since original packet was sent */
2717 gint seconds_between_packets
= (gint
)
2718 (pinfo
->fd
->abs_ts
.secs
- p_conv_data
->last_received_timestamp
.secs
);
2719 gint nseconds_between_packets
=
2720 pinfo
->fd
->abs_ts
.nsecs
- p_conv_data
->last_received_timestamp
.nsecs
;
2722 gint total_gap
= (seconds_between_packets
*1000) +
2723 (nseconds_between_packets
/ 1000000);
2724 gint dlsr_ms
= (int)(((double)dlsr
/(double)65536) * 1000.0);
2727 /* Delay is gap - dlsr (N.B. this is allowed to be -ve) */
2728 delay
= total_gap
- dlsr_ms
;
2730 /* Record that the LSR matches */
2731 p_packet_data
->lsr_matched
= TRUE
;
2733 /* No useful calculation can be done if dlsr not set... */
2736 p_packet_data
->calculated_delay
= delay
;
2737 p_packet_data
->calculated_delay_report_gap
= total_gap
;
2738 p_packet_data
->calculated_delay_used_frame
= p_conv_data
->last_received_frame_number
;
2742 add_roundtrip_delay_info(tvb
, pinfo
, tree
,
2743 p_conv_data
->last_received_frame_number
,
2750 /* Show the calcaulted roundtrip delay info by adding protocol tree items
2751 and appending text to the info column */
2752 static void add_roundtrip_delay_info(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
,
2753 guint frame
, guint gap_between_reports
,
2756 /* 'Last SR' frame used in calculation. Show this even if no delay shown */
2757 proto_item
*item
= proto_tree_add_uint(tree
,
2758 hf_rtcp_last_sr_timestamp_frame
,
2760 PROTO_ITEM_SET_GENERATED(item
);
2762 /* Time elapsed since 'Last SR' time in capture */
2763 item
= proto_tree_add_uint(tree
,
2764 hf_rtcp_time_since_last_sr
,
2765 tvb
, 0, 0, gap_between_reports
);
2766 PROTO_ITEM_SET_GENERATED(item
);
2768 /* Don't report on calculated delays below the threshold.
2769 Will report delays less than -threshold, to highlight
2770 problems with generated reports */
2771 if (abs(delay
) < (int)global_rtcp_show_roundtrip_calculation_minimum
)
2776 /* Calculated delay in ms */
2777 item
= proto_tree_add_int(tree
, hf_rtcp_roundtrip_delay
, tvb
, 0, 0, delay
);
2778 PROTO_ITEM_SET_GENERATED(item
);
2780 /* Add to expert info */
2783 expert_add_info_format(pinfo
, item
, &ei_rtcp_roundtrip_delay
, "RTCP round-trip delay detected (%d ms)", delay
);
2787 expert_add_info_format(pinfo
, item
, &ei_rtcp_roundtrip_delay_negative
, "Negative RTCP round-trip delay detected (%d ms)", delay
);
2790 /* Report delay in INFO column */
2791 col_append_fstr(pinfo
->cinfo
, COL_INFO
,
2792 " (roundtrip delay <-> %s = %dms, using frame %u) ",
2793 ep_address_to_str(&pinfo
->net_src
), delay
, frame
);
2797 rtcp_packet_type_to_tree( int rtcp_packet_type
)
2801 switch(rtcp_packet_type
) {
2802 case RTCP_SR
: tree
= ett_rtcp_sr
; break;
2803 case RTCP_RR
: tree
= ett_rtcp_rr
; break;
2804 case RTCP_SDES
: tree
= ett_rtcp_sdes
; break;
2805 case RTCP_BYE
: tree
= ett_rtcp_bye
; break;
2806 case RTCP_APP
: tree
= ett_rtcp_app
; break;
2807 case RTCP_RTPFB
: tree
= ett_rtcp_rtpfb
; break;
2808 case RTCP_PSFB
: tree
= ett_rtcp_psfb
; break;
2809 case RTCP_XR
: tree
= ett_rtcp_xr
; break;
2810 case RTCP_FIR
: tree
= ett_rtcp_fir
; break;
2811 case RTCP_NACK
: tree
= ett_rtcp_nack
; break;
2812 default: tree
= ett_rtcp
;
2818 dissect_rtcp( tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
)
2821 proto_tree
*rtcp_tree
= NULL
;
2822 guint padding_set
= 0;
2824 guint total_packet_length
= 0;
2825 guint padding_offset
= 0;
2826 gboolean srtcp_encrypted
= FALSE
;
2827 gboolean srtcp_now_encrypted
= FALSE
;
2828 conversation_t
*p_conv
;
2829 struct srtp_info
*srtcp_info
= NULL
;
2830 guint32 srtcp_offset
= 0;
2831 guint32 srtcp_index
= 0;
2833 /* first see if this conversation is encrypted SRTP, and if so do not try to dissect the payload(s) */
2834 p_conv
= find_conversation(pinfo
->fd
->num
, &pinfo
->net_src
, &pinfo
->net_dst
,
2836 pinfo
->srcport
, pinfo
->destport
, NO_ADDR_B
);
2839 struct _rtcp_conversation_info
*p_conv_data
;
2840 p_conv_data
= (struct _rtcp_conversation_info
*)conversation_get_proto_data(p_conv
, proto_rtcp
);
2841 if (p_conv_data
&& p_conv_data
->srtcp_info
)
2844 srtcp_info
= p_conv_data
->srtcp_info
;
2845 /* get the offset to the start of the SRTCP fields at the end of the packet */
2846 srtcp_offset
= tvb_length_remaining(tvb
, offset
) - srtcp_info
->auth_tag_len
- srtcp_info
->mki_len
- 4;
2847 /* It has been setup as SRTCP, but skip to the SRTCP E field at the end
2848 to see if this particular packet is encrypted or not. The E bit is the MSB. */
2849 srtcp_index
= tvb_get_ntohl(tvb
,srtcp_offset
);
2850 e_bit
= (srtcp_index
& 0x80000000) ? TRUE
: FALSE
;
2851 srtcp_index
&= 0x7fffffff;
2853 if (srtcp_info
->encryption_algorithm
!=SRTP_ENC_ALG_NULL
) {
2854 /* just flag it for now - the first SR or RR header and SSRC are unencrypted */
2856 srtcp_encrypted
= TRUE
;
2861 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, (srtcp_info
) ? "SRTCP" : "RTCP");
2864 * Check if there are at least 4 bytes left in the frame,
2865 * the last 16 bits of those is the length of the current
2866 * RTCP message. The last compound message contains padding,
2867 * that enables us to break from the while loop.
2869 while ( !srtcp_now_encrypted
&& tvb_bytes_exist( tvb
, offset
, 4) ) {
2873 guint packet_length
;
2875 * First retrieve the packet_type
2877 packet_type
= tvb_get_guint8( tvb
, offset
+ 1 );
2880 * Check if it's a valid type
2882 if ( ( packet_type
< RTCP_PT_MIN
) || ( packet_type
> RTCP_PT_MAX
) )
2885 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "%s ",
2886 val_to_str_const(packet_type
, rtcp_packet_type_vals
, "Unknown"));
2889 * get the packet-length for the complete RTCP packet
2891 packet_length
= ( tvb_get_ntohs( tvb
, offset
+ 2 ) + 1 ) * 4;
2892 total_packet_length
+= packet_length
;
2894 ti
= proto_tree_add_item(tree
, proto_rtcp
, tvb
, offset
, packet_length
, ENC_NA
);
2895 proto_item_append_text(ti
, " (%s)",
2896 val_to_str_const(packet_type
,
2897 rtcp_packet_type_vals
,
2900 rtcp_tree
= proto_item_add_subtree( ti
, rtcp_packet_type_to_tree(packet_type
) );
2902 /* Conversation setup info */
2903 if (global_rtcp_show_setup_info
)
2905 show_setup_info(tvb
, pinfo
, rtcp_tree
);
2909 temp_byte
= tvb_get_guint8( tvb
, offset
);
2911 proto_tree_add_item( rtcp_tree
, hf_rtcp_version
, tvb
,
2912 offset
, 1, ENC_BIG_ENDIAN
);
2913 padding_set
= RTCP_PADDING( temp_byte
);
2914 padding_offset
= offset
+ packet_length
- 1;
2916 proto_tree_add_boolean( rtcp_tree
, hf_rtcp_padding
, tvb
,
2917 offset
, 1, temp_byte
);
2918 elem_count
= RTCP_COUNT( temp_byte
);
2920 switch ( packet_type
) {
2923 /* Receiver report count, 5 bits */
2924 proto_tree_add_uint( rtcp_tree
, hf_rtcp_rc
, tvb
, offset
, 1, temp_byte
);
2926 /* Packet type, 8 bits */
2927 proto_tree_add_item( rtcp_tree
, hf_rtcp_pt
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2929 /* Packet length in 32 bit words MINUS one, 16 bits */
2930 offset
= dissect_rtcp_length_field(rtcp_tree
, tvb
, offset
);
2931 /* Sender Synchronization source, 32 bits */
2932 proto_tree_add_item( rtcp_tree
, hf_rtcp_ssrc_sender
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
2935 if (srtcp_encrypted
) { /* rest of the payload is encrypted - do not try to dissect */
2936 srtcp_now_encrypted
= TRUE
;
2940 if ( packet_type
== RTCP_SR
)
2941 offset
= dissect_rtcp_sr( pinfo
, tvb
, offset
, rtcp_tree
, elem_count
, packet_length
-8 );
2943 offset
= dissect_rtcp_rr( pinfo
, tvb
, offset
, rtcp_tree
, elem_count
, packet_length
-8 );
2946 /* Source count, 5 bits */
2947 proto_tree_add_uint( rtcp_tree
, hf_rtcp_sc
, tvb
, offset
, 1, temp_byte
);
2949 /* Packet type, 8 bits */
2950 proto_tree_add_item( rtcp_tree
, hf_rtcp_pt
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2952 /* Packet length in 32 bit words MINUS one, 16 bits */
2953 offset
= dissect_rtcp_length_field(rtcp_tree
, tvb
, offset
);
2954 offset
= dissect_rtcp_sdes( tvb
, offset
, rtcp_tree
, elem_count
);
2957 /* Source count, 5 bits */
2958 proto_tree_add_uint( rtcp_tree
, hf_rtcp_sc
, tvb
, offset
, 1, temp_byte
);
2960 /* Packet type, 8 bits */
2961 proto_tree_add_item( rtcp_tree
, hf_rtcp_pt
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2963 /* Packet length in 32 bit words MINUS one, 16 bits */
2964 offset
= dissect_rtcp_length_field(rtcp_tree
, tvb
, offset
);
2965 offset
= dissect_rtcp_bye( tvb
, pinfo
, offset
, rtcp_tree
, elem_count
);
2968 /* Subtype, 5 bits */
2971 rtcp_subtype
= elem_count
;
2972 proto_tree_add_uint( rtcp_tree
, hf_rtcp_subtype
, tvb
, offset
, 1, elem_count
);
2974 /* Packet type, 8 bits */
2975 proto_tree_add_item( rtcp_tree
, hf_rtcp_pt
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2977 /* Packet length in 32 bit words MINUS one, 16 bits */
2978 app_length
= tvb_get_ntohs( tvb
, offset
) <<2;
2979 offset
= dissect_rtcp_length_field(rtcp_tree
, tvb
, offset
);
2980 offset
= dissect_rtcp_app( tvb
, pinfo
, offset
,rtcp_tree
, padding_set
, packet_length
- 4, rtcp_subtype
, app_length
);
2984 /* Reserved, 5 bits, Ignore */
2986 /* Packet type, 8 bits */
2987 proto_tree_add_item( rtcp_tree
, hf_rtcp_pt
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2989 /* Packet length in 32 bit words MINUS one, 16 bits */
2990 offset
= dissect_rtcp_length_field(rtcp_tree
, tvb
, offset
);
2991 offset
= dissect_rtcp_xr( tvb
, pinfo
, offset
, rtcp_tree
, packet_length
- 4 );
2994 /* Subtype, 5 bits */
2995 proto_tree_add_uint( rtcp_tree
, hf_rtcp_subtype
, tvb
, offset
, 1, elem_count
);
2997 /* Packet type, 8 bits */
2998 proto_tree_add_item( rtcp_tree
, hf_rtcp_pt
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3000 /* Packet length in 32 bit words MINUS one, 16 bits */
3001 offset
= dissect_rtcp_length_field(rtcp_tree
, tvb
, offset
);
3002 offset
= dissect_rtcp_avb( tvb
, pinfo
, offset
, rtcp_tree
, packet_length
- 4 );
3005 /* Reserved, 5 bits, Ignore */
3007 /* Packet type, 8 bits */
3008 proto_tree_add_item( rtcp_tree
, hf_rtcp_pt
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3010 /* Packet length in 32 bit words MINUS one, 16 bits */
3011 offset
= dissect_rtcp_length_field(rtcp_tree
, tvb
, offset
);
3012 offset
= dissect_rtcp_rsi( tvb
, pinfo
, offset
, rtcp_tree
, packet_length
- 4 );
3015 /* Subtype, 5 bits */
3017 rtcp_subtype
= elem_count
;
3018 proto_tree_add_uint( rtcp_tree
, hf_rtcp_subtype
, tvb
, offset
, 1, elem_count
);
3020 /* Packet type, 8 bits */
3021 proto_tree_add_item( rtcp_tree
, hf_rtcp_pt
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3023 /* Packet length in 32 bit words MINUS one, 16 bits */
3024 offset
= dissect_rtcp_length_field(rtcp_tree
, tvb
, offset
);
3025 offset
= dissect_rtcp_token( tvb
, pinfo
, offset
, rtcp_tree
, packet_length
- 4, rtcp_subtype
);
3029 offset
= dissect_rtcp_fir( tvb
, offset
, rtcp_tree
);
3032 offset
= dissect_rtcp_nack( tvb
, offset
, rtcp_tree
);
3035 offset
= dissect_rtcp_rtpfb( tvb
, offset
, rtcp_tree
, ti
, pinfo
);
3038 offset
= dissect_rtcp_psfb( tvb
, offset
, rtcp_tree
, packet_length
, pinfo
);
3042 * To prevent endless loops in case of an unknown message type
3043 * increase offset. Some time the while will end :-)
3049 col_set_fence(pinfo
->cinfo
, COL_INFO
);
3051 /* If the padding bit is set, the last octet of the
3052 * packet contains the length of the padding
3053 * We only have to check for this at the end of the LAST RTCP message
3055 if ( padding_set
) {
3056 guint padding_length
;
3057 /* The last RTCP message in the packet has padding - find it.
3059 * The padding count is found at an offset of padding_offset; it
3060 * contains the number of padding octets, including the padding
3063 padding_length
= tvb_get_guint8( tvb
, padding_offset
);
3065 /* This length includes the padding length byte itself, so 0 is not
3067 if (padding_length
!= 0) {
3068 proto_tree_add_item( rtcp_tree
, hf_rtcp_padding_data
, tvb
, offset
, padding_length
- 1, ENC_NA
);
3069 offset
+= padding_length
- 1;
3071 proto_tree_add_item( rtcp_tree
, hf_rtcp_padding_count
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3075 /* If the payload was encrypted, the main payload was not dissected */
3076 if (srtcp_encrypted
== TRUE
) {
3077 proto_tree_add_text(rtcp_tree
, tvb
, offset
, srtcp_offset
-offset
, "Encrypted RTCP Payload - not dissected");
3078 proto_tree_add_item(rtcp_tree
, hf_srtcp_e
, tvb
, srtcp_offset
, 4, ENC_BIG_ENDIAN
);
3079 proto_tree_add_uint(rtcp_tree
, hf_srtcp_index
, tvb
, srtcp_offset
, 4, srtcp_index
);
3081 if (srtcp_info
->mki_len
) {
3082 proto_tree_add_item(rtcp_tree
, hf_srtcp_mki
, tvb
, srtcp_offset
, srtcp_info
->mki_len
, ENC_NA
);
3083 srtcp_offset
+= srtcp_info
->mki_len
;
3086 if (srtcp_info
->auth_tag_len
) {
3087 proto_tree_add_item(rtcp_tree
, hf_srtcp_auth_tag
, tvb
, srtcp_offset
, srtcp_info
->auth_tag_len
, ENC_NA
);
3088 /*srtcp_offset += srtcp_info->auth_tag_len;*/
3091 /* offset should be total_packet_length by now... */
3092 else if (offset
== total_packet_length
)
3094 ti
= proto_tree_add_boolean_format_value(tree
, hf_rtcp_length_check
, tvb
,
3095 0, 0, TRUE
, "OK - %u bytes",
3097 /* Hidden might be less annoying here...? */
3098 PROTO_ITEM_SET_GENERATED(ti
);
3102 ti
= proto_tree_add_boolean_format_value(tree
, hf_rtcp_length_check
, tvb
,
3104 "Wrong (expected %u bytes, found %d)",
3105 total_packet_length
, offset
);
3106 PROTO_ITEM_SET_GENERATED(ti
);
3108 expert_add_info_format(pinfo
, ti
, &ei_rtcp_length_check
, "Incorrect RTCP packet length information (expected %u bytes, found %d)", total_packet_length
, offset
);
3113 proto_register_rtcp(void)
3115 static hf_register_info hf
[] = {
3123 VALS(rtcp_version_vals
),
3143 "Reception report count",
3171 VALS( rtcp_packet_type_vals
),
3185 "32-bit words (-1) in packet", HFILL
3189 &hf_rtcp_ssrc_sender
,
3201 &hf_rtcp_ssrc_media_source
,
3203 "Media source SSRC",
3216 "rtcp.timestamp.ntp.msw",
3228 "rtcp.timestamp.ntp.lsw",
3239 "MSW and LSW as NTP timestamp",
3240 "rtcp.timestamp.ntp",
3249 &hf_rtcp_rtp_timestamp
,
3252 "rtcp.timestamp.rtp",
3261 &hf_rtcp_sender_pkt_cnt
,
3263 "Sender's packet count",
3264 "rtcp.sender.packetcount",
3273 &hf_rtcp_sender_oct_cnt
,
3275 "Sender's octet count",
3276 "rtcp.sender.octetcount",
3285 &hf_rtcp_ssrc_source
,
3288 "rtcp.ssrc.identifier",
3297 &hf_rtcp_ssrc_fraction
,
3300 "rtcp.ssrc.fraction",
3309 &hf_rtcp_ssrc_cum_nr
,
3311 "Cumulative number of packets lost",
3321 &hf_rtcp_ssrc_ext_high_seq
,
3323 "Extended highest sequence number received",
3324 "rtcp.ssrc.ext_high",
3333 &hf_rtcp_ssrc_high_seq
,
3335 "Highest sequence number received",
3336 "rtcp.ssrc.high_seq",
3345 &hf_rtcp_ssrc_high_cycles
,
3347 "Sequence number cycles count",
3348 "rtcp.ssrc.high_cycles",
3357 &hf_rtcp_ssrc_jitter
,
3359 "Interarrival jitter",
3371 "Last SR timestamp",
3383 "Delay since last SR timestamp",
3396 "SSRC / CSRC identifier",
3397 "rtcp.sdes.ssrc_csrc",
3413 VALS( rtcp_sdes_type_vals
),
3419 &hf_rtcp_sdes_length
,
3443 &hf_rtcp_sdes_prefix_len
,
3446 "rtcp.sdes.prefix.length",
3455 &hf_rtcp_sdes_prefix_string
,
3458 "rtcp.sdes.prefix.string",
3479 &hf_rtcp_name_ascii
,
3493 "Application specific data",
3505 "PoC1 Application specific data",
3515 &hf_rtcp_app_poc1_subtype
,
3518 "rtcp.app.PoC1.subtype",
3521 VALS(rtcp_app_poc1_floor_cnt_type_vals
),
3527 &hf_rtcp_app_poc1_sip_uri
,
3530 "rtcp.app.poc1.sip.uri",
3539 &hf_rtcp_app_poc1_disp_name
,
3542 "rtcp.app.poc1.disp.name",
3551 &hf_rtcp_app_poc1_priority
,
3554 "rtcp.app.poc1.priority",
3557 VALS(rtcp_app_poc1_qsresp_priority_vals
),
3563 &hf_rtcp_app_poc1_request_ts
,
3565 "Talk Burst Request Timestamp",
3566 "rtcp.app.poc1.request.ts",
3575 &hf_rtcp_app_poc1_stt
,
3577 "Stop talking timer",
3578 "rtcp.app.poc1.stt",
3587 &hf_rtcp_app_poc1_partic
,
3589 "Number of participants",
3590 "rtcp.app.poc1.participants",
3599 &hf_rtcp_app_poc1_ssrc_granted
,
3601 "SSRC of client granted permission to talk",
3602 "rtcp.app.poc1.ssrc.granted",
3611 &hf_rtcp_app_poc1_last_pkt_seq_no
,
3613 "Sequence number of last RTP packet",
3614 "rtcp.app.poc1.last.pkt.seq.no",
3623 &hf_rtcp_app_poc1_ignore_seq_no
,
3625 "Ignore sequence number field",
3626 "rtcp.app.poc1.ignore.seq.no",
3635 &hf_rtcp_app_poc1_reason_code1
,
3638 "rtcp.app.poc1.reason.code",
3641 VALS(rtcp_app_poc1_reason_code1_vals
),
3647 &hf_rtcp_app_poc1_reason1_phrase
,
3650 "rtcp.app.poc1.reason.phrase",
3659 &hf_rtcp_app_poc1_reason_code2
,
3662 "rtcp.app.poc1.reason.code",
3665 VALS(rtcp_app_poc1_reason_code2_vals
),
3671 &hf_rtcp_app_poc1_new_time_request
,
3673 "New time client can request (seconds)",
3674 "rtcp.app.poc1.new.time.request",
3679 "Time in seconds client can request for", HFILL
3683 &hf_rtcp_app_poc1_ack_subtype
,
3686 "rtcp.app.poc1.ack.subtype",
3689 VALS(rtcp_app_poc1_floor_cnt_type_vals
),
3695 &hf_rtcp_app_poc1_ack_reason_code
,
3698 "rtcp.app.poc1.ack.reason.code",
3701 VALS(rtcp_app_poc1_reason_code_ack_vals
),
3707 &hf_rtcp_app_poc1_qsresp_priority
,
3710 "rtcp.app.poc1.qsresp.priority",
3713 VALS(rtcp_app_poc1_qsresp_priority_vals
),
3719 &hf_rtcp_app_poc1_qsresp_position
,
3721 "Position (number of clients ahead)",
3722 "rtcp.app.poc1.qsresp.position",
3731 &hf_rtcp_app_poc1_conn_content
[0],
3733 "Identity of inviting client",
3734 "rtcp.app.poc1.conn.content.a.id",
3743 &hf_rtcp_app_poc1_conn_content
[1],
3745 "Nick name of inviting client",
3746 "rtcp.app.poc1.conn.content.a.dn",
3755 &hf_rtcp_app_poc1_conn_content
[2],
3758 "rtcp.app.poc1.conn.content.sess.id",
3767 &hf_rtcp_app_poc1_conn_content
[3],
3770 "rtcp.app.poc1.conn.content.grp.dn",
3779 &hf_rtcp_app_poc1_conn_content
[4],
3782 "rtcp.app.poc1.conn.content.grp.id",
3791 &hf_rtcp_app_poc1_conn_session_type
,
3794 "rtcp.app.poc1.conn.session.type",
3797 VALS(rtcp_app_poc1_conn_sess_type_vals
),
3803 &hf_rtcp_app_poc1_conn_add_ind_mao
,
3805 "Manual answer override",
3806 "rtcp.app.poc1.conn.add.ind.mao",
3815 &hf_rtcp_app_poc1_conn_sdes_items
[0],
3817 "Identity of inviting client",
3818 "rtcp.app.poc1.conn.sdes.a.id",
3827 &hf_rtcp_app_poc1_conn_sdes_items
[1],
3829 "Nick name of inviting client",
3830 "rtcp.app.poc1.conn.sdes.a.dn",
3839 &hf_rtcp_app_poc1_conn_sdes_items
[2],
3842 "rtcp.app.poc1.conn.sdes.sess.id",
3851 &hf_rtcp_app_poc1_conn_sdes_items
[3],
3854 "rtcp.app.poc1.conn.sdes.grp.dn",
3863 &hf_rtcp_app_poc1_conn_sdes_items
[4],
3866 "rtcp.app.poc1.conn.sdes.grp.id",
3877 "RtpMux Application specific data",
3887 &hf_rtcp_app_mux_mux
,
3889 "Multiplexing supported",
3899 &hf_rtcp_app_mux_cp
,
3901 "Header compression supported",
3911 &hf_rtcp_app_mux_selection
,
3913 "Multiplexing selection",
3914 "rtcp.app.mux.selection",
3917 VALS(rtcp_app_mux_selection_vals
),
3923 &hf_rtcp_app_mux_localmuxport
,
3926 "rtcp.app.mux.muxport",
3937 "First sequence number",
3949 "Bitmask of following lost packets",
3959 &hf_rtcp_padding_count
,
3962 "rtcp.padding.count",
3971 &hf_rtcp_padding_data
,
3974 "rtcp.padding.data",
3983 &hf_rtcp_profile_specific_extension
,
3985 "Profile-specific extension",
3986 "rtcp.profile-specific-extension",
4003 "Stream setup, method and frame number", HFILL
4007 &hf_rtcp_setup_frame
,
4015 "Frame that set up this stream", HFILL
4019 &hf_rtcp_setup_method
,
4022 "rtcp.setup-method",
4027 "Method used to set up this stream", HFILL
4031 &hf_rtcp_last_sr_timestamp_frame
,
4033 "Frame matching Last SR timestamp",
4039 "Frame matching LSR field (used to calculate roundtrip delay)", HFILL
4043 &hf_rtcp_time_since_last_sr
,
4045 "Time since Last SR captured",
4046 "rtcp.lsr-frame-captured",
4051 "Time since frame matching LSR field was captured", HFILL
4055 &hf_rtcp_roundtrip_delay
,
4057 "Roundtrip Delay(ms)",
4058 "rtcp.roundtrip-delay",
4063 "Calculated roundtrip delay in ms", HFILL
4067 &hf_rtcp_xr_block_type
,
4073 VALS(rtcp_xr_type_vals
),
4079 &hf_rtcp_xr_block_specific
,
4091 &hf_rtcp_xr_block_length
,
4099 "Block Length", HFILL
4103 &hf_rtcp_ssrc_discarded
,
4105 "Fraction discarded",
4106 "rtcp.ssrc.discarded",
4111 "Discard Rate", HFILL
4115 &hf_rtcp_xr_voip_metrics_burst_density
,
4118 "rtcp.xr.voipmetrics.burstdensity",
4127 &hf_rtcp_xr_voip_metrics_gap_density
,
4130 "rtcp.xr.voipmetrics.gapdensity",
4139 &hf_rtcp_xr_voip_metrics_burst_duration
,
4141 "Burst Duration(ms)",
4142 "rtcp.xr.voipmetrics.burstduration",
4151 &hf_rtcp_xr_voip_metrics_gap_duration
,
4154 "rtcp.xr.voipmetrics.gapduration",
4163 &hf_rtcp_xr_voip_metrics_rtdelay
,
4165 "Round Trip Delay(ms)",
4166 "rtcp.xr.voipmetrics.rtdelay",
4175 &hf_rtcp_xr_voip_metrics_esdelay
,
4177 "End System Delay(ms)",
4178 "rtcp.xr.voipmetrics.esdelay",
4187 &hf_rtcp_xr_voip_metrics_siglevel
,
4190 "rtcp.xr.voipmetrics.signallevel",
4199 &hf_rtcp_xr_voip_metrics_noiselevel
,
4202 "rtcp.xr.voipmetrics.noiselevel",
4211 &hf_rtcp_xr_voip_metrics_rerl
,
4213 "Residual Echo Return Loss",
4214 "rtcp.xr.voipmetrics.rerl",
4223 &hf_rtcp_xr_voip_metrics_gmin
,
4226 "rtcp.xr.voipmetrics.gmin",
4235 &hf_rtcp_xr_voip_metrics_rfactor
,
4238 "rtcp.xr.voipmetrics.rfactor",
4243 "R Factor is in the range of 0 to 100", HFILL
4247 &hf_rtcp_xr_voip_metrics_extrfactor
,
4249 "External R Factor",
4250 "rtcp.xr.voipmetrics.extrfactor",
4255 "R Factor is in the range of 0 to 100", HFILL
4259 &hf_rtcp_xr_voip_metrics_moslq
,
4261 "MOS - Listening Quality",
4262 "rtcp.xr.voipmetrics.moslq",
4267 "MOS is in the range of 1 to 5", HFILL
4271 &hf_rtcp_xr_voip_metrics_moscq
,
4273 "MOS - Conversational Quality",
4274 "rtcp.xr.voipmetrics.moscq",
4279 "MOS is in the range of 1 to 5", HFILL
4283 &hf_rtcp_xr_voip_metrics_plc
,
4285 "Packet Loss Concealment Algorithm",
4286 "rtcp.xr.voipmetrics.plc",
4289 VALS(rtcp_xr_plc_algo_vals
),
4295 &hf_rtcp_xr_voip_metrics_jbadaptive
,
4297 "Adaptive Jitter Buffer Algorithm",
4298 "rtcp.xr.voipmetrics.jba",
4301 VALS(rtcp_xr_jb_adaptive_vals
),
4307 &hf_rtcp_xr_voip_metrics_jbrate
,
4309 "Jitter Buffer Rate",
4310 "rtcp.xr.voipmetrics.jbrate",
4319 &hf_rtcp_xr_voip_metrics_jbnominal
,
4321 "Nominal Jitter Buffer Size",
4322 "rtcp.xr.voipmetrics.jbnominal",
4331 &hf_rtcp_xr_voip_metrics_jbmax
,
4333 "Maximum Jitter Buffer Size",
4334 "rtcp.xr.voipmetrics.jbmax",
4343 &hf_rtcp_xr_voip_metrics_jbabsmax
,
4345 "Absolute Maximum Jitter Buffer Size",
4346 "rtcp.xr.voipmetrics.jbabsmax",
4355 &hf_rtcp_xr_thinning
,
4367 &hf_rtcp_xr_stats_loss_flag
,
4370 "rtcp.xr.stats.lrflag",
4379 &hf_rtcp_xr_stats_dup_flag
,
4381 "Duplicates Report Flag",
4382 "rtcp.xr.stats.dupflag",
4391 &hf_rtcp_xr_stats_jitter_flag
,
4393 "Jitter Report Flag",
4394 "rtcp.xr.stats.jitterflag",
4403 &hf_rtcp_xr_stats_ttl
,
4405 "TTL or Hop Limit Flag",
4406 "rtcp.xr.stats.ttl",
4409 VALS(rtcp_xr_ip_ttl_vals
),
4417 "End Sequence Number",
4427 &hf_rtcp_xr_beginseq
,
4429 "Begin Sequence Number",
4439 &hf_rtcp_xr_receipt_time_seq
,
4442 "rtcp.xr.receipt_time_seq",
4451 &hf_rtcp_xr_stats_lost
,
4454 "rtcp.xr.stats.lost",
4463 &hf_rtcp_xr_stats_dups
,
4465 "Duplicate Packets",
4466 "rtcp.xr.stats.dups",
4475 &hf_rtcp_xr_stats_minjitter
,
4478 "rtcp.xr.stats.minjitter",
4487 &hf_rtcp_xr_stats_maxjitter
,
4490 "rtcp.xr.stats.maxjitter",
4499 &hf_rtcp_xr_stats_meanjitter
,
4502 "rtcp.xr.stats.meanjitter",
4511 &hf_rtcp_xr_stats_devjitter
,
4513 "Standard Deviation of Jitter",
4514 "rtcp.xr.stats.devjitter",
4523 &hf_rtcp_xr_stats_minttl
,
4525 "Minimum TTL or Hop Limit",
4526 "rtcp.xr.stats.minttl",
4535 &hf_rtcp_xr_stats_maxttl
,
4537 "Maximum TTL or Hop Limit",
4538 "rtcp.xr.stats.maxttl",
4547 &hf_rtcp_xr_stats_meanttl
,
4549 "Mean TTL or Hop Limit",
4550 "rtcp.xr.stats.meanttl",
4559 &hf_rtcp_xr_stats_devttl
,
4561 "Standard Deviation of TTL",
4562 "rtcp.xr.stats.devttl",
4573 "Last RR timestamp",
4585 "Delay since last RR timestamp",
4595 &hf_rtcp_length_check
,
4597 "RTCP frame length check",
4598 "rtcp.length_check",
4609 "RTCP Feedback message type (FMT)",
4613 VALS(rtcp_rtpfb_fmt_vals
),
4621 "RTCP Feedback message type (FMT)",
4625 VALS(rtcp_psfb_fmt_vals
),
4631 &hf_rtcp_rtpfb_nack_pid
,
4633 "RTCP Transport Feedback NACK PID",
4634 "rtcp.rtpfb.nack_pid",
4643 &hf_rtcp_rtpfb_nack_blp
,
4645 "RTCP Transport Feedback NACK BLP",
4646 "rtcp.rtpfb.nack_blp",
4657 "Feedback Control Information (FCI)",
4667 &hf_rtcp_xr_idms_spst
,
4669 "Syncronization Packet Sender Type",
4670 "rtcp.xr.idms.spst",
4673 VALS(rtcp_xr_idms_spst
),
4679 &hf_rtcp_xr_idms_pt
,
4691 &hf_rtcp_xr_idms_msci
,
4693 "Media Stream Correlation Identifier",
4694 "rtcp.xr.idms.msci",
4703 &hf_rtcp_xr_idms_source_ssrc
,
4706 "rtcp.xr.idms.source_ssrc",
4715 &hf_rtcp_xr_idms_ntp_rcv_ts_msw
,
4717 "NTP Timestamp of packet reception (msw)",
4718 "rtcp.xr.idms.ntp_rcv_ts_msw",
4727 &hf_rtcp_xr_idms_ntp_rcv_ts_lsw
,
4729 "NTP Timestamp of packet reception (lsw)",
4730 "rtcp.xr.idms.ntp_rcv_ts_lsw",
4739 &hf_rtcp_xr_idms_rtp_ts
,
4741 "RTP Timestamp of packet",
4742 "rtcp.xr.idms.rtp_ts",
4751 &hf_rtcp_xr_idms_ntp_pres_ts
,
4753 "NTP Timestamp of presentation",
4754 "rtcp.xr.idms.ntp_pres_ts",
4763 &hf_rtcp_psfb_fir_fci_ssrc
,
4766 "rtcp.psfb.fir.fci.ssrc",
4775 &hf_rtcp_psfb_fir_fci_csn
,
4777 "Command Sequence Number",
4778 "rtcp.psfb.fir.fci.csn",
4787 &hf_rtcp_psfb_fir_fci_reserved
,
4790 "rtcp.psfb.fir.fci.reserved",
4799 &hf_rtcp_rtpfb_tmbbr_fci_ssrc
,
4802 "rtcp.rtpfb.tmmbr.fci.ssrc",
4811 &hf_rtcp_rtpfb_tmbbr_fci_exp
,
4814 "rtcp.rtpfb.tmmbr.fci.exp",
4823 &hf_rtcp_rtpfb_tmbbr_fci_mantissa
,
4826 "rtcp.rtpfb.tmmbr.fci.mantissa",
4835 &hf_rtcp_rtpfb_tmbbr_fci_bitrate
,
4837 "Maximum total media bit rate",
4838 "rtcp.rtpfb.tmmbr.fci.bitrate",
4847 &hf_rtcp_rtpfb_tmbbr_fci_measuredoverhead
,
4849 "Measured Overhead",
4850 "rtcp.rtpfb.tmmbr.fci.measuredoverhead",
4869 "SRTCP Encryption Flag", HFILL
4893 "SRTCP Master Key Index", HFILL
4905 "SRTCP Authentication Tag", HFILL
4908 /* additions for BT XNQ block as defined in RFC5093 */
4910 &hf_rtcp_xr_btxnq_begseq
,
4912 "Starting sequence number",
4913 "rtcp.xr.btxnq.begseq",
4922 &hf_rtcp_xr_btxnq_endseq
,
4924 "Last sequence number",
4925 "rtcp.xr.btxnq.endseq",
4934 &hf_rtcp_xr_btxnq_vmaxdiff
,
4936 "Maximum IPDV difference in 1 cycle",
4937 "rtcp.xr.btxnq.vmaxdiff",
4946 &hf_rtcp_xr_btxnq_vrange
,
4948 "Maximum IPDV difference seen to date",
4949 "rtcp.xr.btxnq.vrange",
4958 &hf_rtcp_xr_btxnq_vsum
,
4960 "Sum of peak IPDV differences to date",
4961 "rtcp.xr.btxnq.vsum",
4970 &hf_rtcp_xr_btxnq_cycles
,
4972 "Number of cycles in calculation",
4973 "rtcp.xr.btxnq.cycles",
4982 &hf_rtcp_xr_btxnq_jbevents
,
4984 "Number of jitter buffer adaptations to date",
4985 "rtcp.xr.btxnq.jbevents",
4994 &hf_rtcp_xr_btxnq_spare
,
4996 "Spare/reserved bits",
4997 "rtcp.xr.btxnq.spare",
5006 &hf_rtcp_xr_btxnq_tdegnet
,
5008 "Time degraded by packet loss or late delivery",
5009 "rtcp.xr.btxnq.tdegnet",
5018 &hf_rtcp_xr_btxnq_tdegjit
,
5020 "Time degraded by jitter buffer adaptation events",
5021 "rtcp.xr.btxnq.tdegjit",
5030 &hf_rtcp_xr_btxnq_es
,
5032 "ES due to unavailable packet events",
5042 &hf_rtcp_xr_btxnq_ses
,
5044 "SES due to unavailable packet events",
5045 "rtcp.xr.btxnq.ses",
5055 static gint
*ett
[] =
5076 &ett_rtcp_roundtrip_delay
,
5078 &ett_xr_block_contents
,
5081 &ett_poc1_conn_contents
,
5085 static ei_register_info ei
[] = {
5086 { &ei_rtcp_bye_reason_not_padded
, { "rtcp.bye_reason_not_padded", PI_MALFORMED
, PI_WARN
, "Reason string is not NULL padded (see RFC3550, section 6.6)", EXPFILL
}},
5087 { &ei_rtcp_xr_block_length_bad
, { "rtcp.invalid_block_length", PI_PROTOCOL
, PI_WARN
, "Invalid block length, should be 2", EXPFILL
}},
5088 { &ei_rtcp_roundtrip_delay
, { "rtcp.roundtrip-delay.expert", PI_SEQUENCE
, PI_NOTE
, "RTCP round-trip delay detected (%d ms)", EXPFILL
}},
5089 { &ei_rtcp_roundtrip_delay_negative
, { "rtcp.roundtrip-delay.negative", PI_SEQUENCE
, PI_ERROR
, "Negative RTCP round-trip delay detected (%d ms)", EXPFILL
}},
5090 { &ei_rtcp_length_check
, { "rtcp.length_check.bad", PI_MALFORMED
, PI_WARN
, "Incorrect RTCP packet length information (expected %u bytes, found %d)", EXPFILL
}},
5093 module_t
*rtcp_module
;
5094 expert_module_t
* expert_rtcp
;
5096 proto_rtcp
= proto_register_protocol("Real-time Transport Control Protocol",
5098 proto_register_field_array(proto_rtcp
, hf
, array_length(hf
));
5099 proto_register_subtree_array(ett
, array_length(ett
));
5100 expert_rtcp
= expert_register_protocol(proto_rtcp
);
5101 expert_register_field_array(expert_rtcp
, ei
, array_length(ei
));
5103 register_dissector("rtcp", dissect_rtcp
, proto_rtcp
);
5105 rtcp_module
= prefs_register_protocol(proto_rtcp
, NULL
);
5107 prefs_register_bool_preference(rtcp_module
, "show_setup_info",
5108 "Show stream setup information",
5109 "Where available, show which protocol and frame caused "
5110 "this RTCP stream to be created",
5111 &global_rtcp_show_setup_info
);
5113 prefs_register_bool_preference(rtcp_module
, "heuristic_rtcp",
5114 "Try to decode RTCP outside of conversations",
5115 "If call control SIP/H.323/RTSP/.. messages are missing in the trace, "
5116 "RTCP isn't decoded without this",
5119 prefs_register_bool_preference(rtcp_module
, "show_roundtrip_calculation",
5120 "Show relative roundtrip calculations",
5121 "Try to work out network delay by comparing time between packets "
5122 "as captured and delays as seen by endpoint",
5123 &global_rtcp_show_roundtrip_calculation
);
5125 prefs_register_uint_preference(rtcp_module
, "roundtrip_min_threshhold",
5126 "Minimum roundtrip calculation to report (ms)",
5127 "Minimum (absolute) calculated roundtrip delay time in milliseconds that "
5128 "should be reported",
5129 10, &global_rtcp_show_roundtrip_calculation_minimum
);
5131 /* Register table for sub-dissetors */
5132 rtcp_dissector_table
= register_dissector_table("rtcp.app.name", "RTCP Application Name", FT_STRING
, BASE_NONE
);
5133 rtcp_psfb_dissector_table
= register_dissector_table("rtcp.psfb.fmt", "RTCP Payload Specific Feedback Message Format", FT_UINT8
, BASE_DEC
);
5134 rtcp_rtpfb_dissector_table
= register_dissector_table("rtcp.rtpfb.fmt", "RTCP Generic RTP Feedback Message Format", FT_UINT8
, BASE_DEC
);
5138 proto_reg_handoff_rtcp(void)
5141 * Register this dissector as one that can be selected by a
5144 rtcp_handle
= find_dissector("rtcp");
5145 dissector_add_handle("udp.port", rtcp_handle
);
5147 heur_dissector_add( "udp", dissect_rtcp_heur
, proto_rtcp
);
5148 heur_dissector_add("stun", dissect_rtcp_heur
, proto_rtcp
);