Add HP Switch Protocol SAP value
[obnox/wireshark/wip.git] / epan / dissectors / packet-rtcp.c
1 /* packet-rtcp.c
2  *
3  * $Id$
4  *
5  * Routines for RTCP dissection
6  * RTCP = Real-time Transport Control Protocol
7  *
8  * Copyright 2000, Philips Electronics N.V.
9  * Written by Andreas Sikkema <h323@ramdyne.nl>
10  *
11  * Copyright 2004, Anders Broman <anders.broman@ericsson.com>
12  *
13  * Copyright 2005, Nagarjuna Venna <nvenna@brixnet.com>
14  *
15  * Wireshark - Network traffic analyzer
16  * By Gerald Combs <gerald@wireshark.org>
17  * Copyright 1998 Gerald Combs
18  *
19  * This program is free software; you can redistribute it and/or
20  * modify it under the terms of the GNU General Public License
21  * as published by the Free Software Foundation; either version 2
22  * of the License, or (at your option) any later version.
23  *
24  * This program is distributed in the hope that it will be useful,
25  * but WITHOUT ANY WARRANTY; without even the implied warranty of
26  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
27  * GNU General Public License for more details.
28  *
29  * You should have received a copy of the GNU General Public License
30  * along with this program; if not, write to the Free Software
31  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
32  */
33
34 /*
35  * This dissector tries to dissect the RTCP protocol according to Annex A
36  * of ITU-T Recommendation H.225.0 (02/98) and RFC 1889
37  * H.225.0 literally copies RFC 1889, but omitting a few sections.
38  *
39  * RTCP traffic is handled by an uneven UDP portnumber. This can be any
40  * port number, but there is a registered port available, port 5005
41  * See Annex B of ITU-T Recommendation H.225.0, section B.7
42  *
43  * Information on PoC can be found from http://www.openmobilealliance.org/
44  *
45  * RTCP XR is specified in RFC 3611.
46  *
47  * See also http://www.iana.org/assignments/rtp-parameters
48  */
49
50
51 #ifdef HAVE_CONFIG_H
52 # include "config.h"
53 #endif
54
55 #include <glib.h>
56 #include <epan/packet.h>
57
58 #include <stdio.h>
59 #include <string.h>
60
61 #include "packet-rtcp.h"
62 #include "packet-ntp.h"
63 #include <epan/conversation.h>
64
65 #include <epan/prefs.h>
66 #include <epan/emem.h>
67 #include <epan/expert.h>
68
69
70 /* Version is the first 2 bits of the first octet*/
71 #define RTCP_VERSION(octet)     ((octet) >> 6)
72
73 /* Padding is the third bit; no need to shift, because true is any value
74    other than 0! */
75 #define RTCP_PADDING(octet)     ((octet) & 0x20)
76
77 /* Receiver/ Sender count is the 5 last bits  */
78 #define RTCP_COUNT(octet)       ((octet) & 0x1F)
79
80 static dissector_handle_t rtcp_handle;
81
82 static const value_string rtcp_version_vals[] =
83 {
84         { 0, "Old VAT Version" },
85         { 1, "First Draft Version" },
86         { 2, "RFC 1889 Version" },
87         { 0, NULL },
88 };
89
90 /* RTCP packet types according to Section A.11.1 */
91 /* And http://www.iana.org/assignments/rtp-parameters */
92 #define RTCP_SR   200
93 #define RTCP_RR   201
94 #define RTCP_SDES 202
95 #define RTCP_BYE  203
96 #define RTCP_APP  204
97 #define RTCP_RTPFB  205
98 #define RTCP_PSFB  206
99 #define RTCP_XR   207
100 /* Supplemental H.261 specific RTCP packet types according to Section C.3.5 */
101 #define RTCP_FIR  192
102 #define RTCP_NACK 193
103
104 static const value_string rtcp_packet_type_vals[] =
105 {
106         { RTCP_SR,   "Sender Report" },
107         { RTCP_RR,   "Receiver Report" },
108         { RTCP_SDES, "Source description" },
109         { RTCP_BYE,  "Goodbye" },
110         { RTCP_APP,  "Application specific" },
111         { RTCP_FIR,  "Full Intra-frame Request (H.261)" },
112         { RTCP_NACK, "Negative Acknowledgement (H.261)" },
113         { RTCP_RTPFB, "Generic RTP Feedback" },
114         { RTCP_PSFB, "Payload-specific" },
115         { RTCP_XR,   "Extended report (RFC 3611)"},
116         { 0,         NULL },
117 };
118
119 /* RTCP SDES types (Section A.11.2) */
120 #define RTCP_SDES_END    0
121 #define RTCP_SDES_CNAME  1
122 #define RTCP_SDES_NAME   2
123 #define RTCP_SDES_EMAIL  3
124 #define RTCP_SDES_PHONE  4
125 #define RTCP_SDES_LOC    5
126 #define RTCP_SDES_TOOL   6
127 #define RTCP_SDES_NOTE   7
128 #define RTCP_SDES_PRIV   8
129 #define RTCP_SDES_H323_CADDR   9
130
131 static const value_string rtcp_sdes_type_vals[] =
132 {
133         { RTCP_SDES_END,   "END" },
134         { RTCP_SDES_CNAME, "CNAME (user and domain)" },
135         { RTCP_SDES_NAME,  "NAME (common name)" },
136         { RTCP_SDES_EMAIL, "EMAIL (e-mail address)" },
137         { RTCP_SDES_PHONE, "PHONE (phone number)" },
138         { RTCP_SDES_LOC,   "LOC (geographic location)" },
139         { RTCP_SDES_TOOL,  "TOOL (name/version of source app)" },
140         { RTCP_SDES_NOTE,  "NOTE (note about source)" },
141         { RTCP_SDES_PRIV,  "PRIV (private extensions)" },
142         { RTCP_SDES_H323_CADDR,"H323-CADDR (H.323 callable address)"},
143         { 0,               NULL },
144 };
145
146 /* RTCP XR Blocks (Section 4, RTC 3611) */
147 #define RTCP_XR_LOSS_RLE    1
148 #define RTCP_XR_DUP_RLE     2
149 #define RTCP_XR_PKT_RXTIMES 3
150 #define RTCP_XR_REF_TIME    4
151 #define RTCP_XR_DLRR        5
152 #define RTCP_XR_STATS_SUMRY 6
153 #define RTCP_XR_VOIP_METRCS 7
154
155 static const value_string rtcp_xr_type_vals[] = 
156 {
157         { RTCP_XR_LOSS_RLE,     "Loss Run Length Encoding Report Block" },
158         { RTCP_XR_DUP_RLE,      "Duplicate Run Length Encoding Report Block" },
159         { RTCP_XR_PKT_RXTIMES,  "Packet Receipt Times Report Block" },
160         { RTCP_XR_REF_TIME,     "Receiver Reference Time Report Block" },
161         { RTCP_XR_DLRR,         "DLRR Report Block" },
162         { RTCP_XR_STATS_SUMRY,  "Statistics Summary Report Block" },
163         { RTCP_XR_VOIP_METRCS,  "VoIP Metrics Report Block" },
164         { 0, NULL}
165 };
166
167 /* XR VoIP Metrics Block - PLC Algorithms */
168 static const value_string rtcp_xr_plc_algo_vals[] = 
169 {
170         { 0, "Unspecified" },
171         { 1, "Disabled" },
172         { 2, "Enhanced" },
173         { 3, "Standard" },
174         { 0, NULL }
175 };
176
177 /* XR VoIP Metrics Block - JB Adaptive */
178 static const value_string rtcp_xr_jb_adaptive_vals[] = 
179 {
180         { 0, "Unknown" },
181         { 1, "Reserved" },
182         { 2, "Non-Adaptive" },
183         { 3, "Adaptive" },
184         { 0, NULL }
185 };
186
187 /* XR Stats Summary Block - IP TTL or Hop Limit */
188 static const value_string rtcp_xr_ip_ttl_vals[] = 
189 {
190         { 0, "No TTL Values" },
191         { 1, "IPv4" },
192         { 2, "IPv6" },
193         { 3, "Undefined" },
194         { 0, NULL }
195 };
196
197 /* RTCP Application PoC1 Value strings 
198  * OMA-TS-PoC-UserPlane-V1_0-20060609-A
199  */
200  
201 #define TBCP_BURST_REQUEST                 0
202 #define TBCP_BURST_GRANTED                 1
203 #define TBCP_BURST_TAKEN_EXPECT_NO_REPLY   2
204 #define TBCP_BURST_DENY                    3
205 #define TBCP_BURST_RELEASE                 4
206 #define TBCP_BURST_IDLE                    5
207 #define TBCP_BURST_REVOKE                  6
208 #define TBCP_BURST_ACKNOWLEDGMENT          7
209 #define TBCP_QUEUE_STATUS_REQUEST          8
210 #define TBCP_QUEUE_STATUS_RESPONSE         9
211 #define TBCP_DISCONNECT                    11
212 #define TBCP_CONNECT                       15
213 #define TBCP_BURST_TAKEN_EXPECT_REPLY      18
214
215
216 static const value_string rtcp_app_poc1_floor_cnt_type_vals[] =
217 {
218         {  TBCP_BURST_REQUEST,                 "TBCP Talk Burst Request"},
219         {  TBCP_BURST_GRANTED,                 "TBCP Talk Burst Granted"},
220         {  TBCP_BURST_TAKEN_EXPECT_NO_REPLY,   "TBCP Talk Burst Taken (no ack expected)"},
221         {  TBCP_BURST_DENY,                    "TBCP Talk Burst Deny"},
222         {  TBCP_BURST_RELEASE,                 "TBCP Talk Burst Release"},
223         {  TBCP_BURST_IDLE,                    "TBCP Talk Burst Idle"},
224         {  TBCP_BURST_REVOKE,                  "TBCP Talk Burst Revoke"},
225         {  TBCP_BURST_ACKNOWLEDGMENT,          "TBCP Talk Burst Acknowledgement"},
226         {  TBCP_QUEUE_STATUS_REQUEST,          "TBCP Queue Status Request"},
227         {  TBCP_QUEUE_STATUS_RESPONSE,         "TBCP Queue Status Response"},
228         {  TBCP_DISCONNECT,                    "TBCP Disconnect"},
229         {  TBCP_CONNECT,                       "TBCP Connect"},
230         {  TBCP_BURST_TAKEN_EXPECT_REPLY,      "TBCP Talk Burst Taken (ack expected)"},
231         {  0,   NULL },
232 };
233
234 static const value_string rtcp_app_poc1_reason_code1_vals[] =
235 {
236         {  1,   "Another PoC User has permission"},
237         {  2,   "Internal PoC server error"},
238         {  3,   "Only one participant in the group"},
239         {  4,   "Retry-after timer has not expired"},
240         {  5,   "Listen only"},
241         {  0,   NULL },
242 };
243
244 static const value_string rtcp_app_poc1_reason_code2_vals[] =
245 {
246         {  1,   "Only one user"},
247         {  2,   "Talk burst too long"},
248         {  3,   "No permission to send a Talk Burst"},
249         {  4,   "Talk burst pre-empted"},
250         {  0,   NULL },
251 };
252
253 static const value_string rtcp_app_poc1_reason_code_ack_vals[] =
254 {
255         {  0,   "Accepted"},
256         {  1,   "Busy"},
257         {  2,   "Not accepted"},
258         {  0,   NULL },
259 };
260 static const value_string rtcp_app_poc1_conn_sess_type_vals[] =
261 {
262         {  0,   "None"},
263         {  1,   "1-to-1"},
264         {  2,   "Ad-hoc"},
265         {  3,   "Pre-arranged"},
266         {  4,   "Chat"},
267         {  0,   NULL },
268 };
269
270 static const value_string rtcp_app_poc1_qsresp_priority_vals[] =
271 {
272         {  0,   "No priority (un-queued)"},
273         {  1,   "Normal priority"},
274         {  2,   "High priority"},
275         {  3,   "Pre-emptive priority"},
276         {  0,   NULL },
277 };
278
279 /* RTCP header fields                   */
280 static int proto_rtcp                = -1;
281 static int hf_rtcp_version           = -1;
282 static int hf_rtcp_padding           = -1;
283 static int hf_rtcp_rc                = -1;
284 static int hf_rtcp_sc                = -1;
285 static int hf_rtcp_pt                = -1;
286 static int hf_rtcp_length            = -1;
287 static int hf_rtcp_ssrc_sender       = -1;
288 static int hf_rtcp_ntp               = -1;
289 static int hf_rtcp_ntp_msw           = -1;
290 static int hf_rtcp_ntp_lsw           = -1;
291 static int hf_rtcp_rtp_timestamp     = -1;
292 static int hf_rtcp_sender_pkt_cnt    = -1;
293 static int hf_rtcp_sender_oct_cnt    = -1;
294 static int hf_rtcp_ssrc_source       = -1;
295 static int hf_rtcp_ssrc_fraction     = -1;
296 static int hf_rtcp_ssrc_cum_nr       = -1;
297 static int hf_rtcp_ssrc_discarded    = -1;
298 /* First the 32 bit number, then the split
299  * up 16 bit values */
300 /* These two are added to a subtree */
301 static int hf_rtcp_ssrc_ext_high_seq = -1;
302 static int hf_rtcp_ssrc_high_seq     = -1;
303 static int hf_rtcp_ssrc_high_cycles  = -1;
304 static int hf_rtcp_ssrc_jitter       = -1;
305 static int hf_rtcp_ssrc_lsr          = -1;
306 static int hf_rtcp_ssrc_dlsr         = -1;
307 static int hf_rtcp_ssrc_csrc         = -1;
308 static int hf_rtcp_sdes_type         = -1;
309 static int hf_rtcp_sdes_length       = -1;
310 static int hf_rtcp_sdes_text         = -1;
311 static int hf_rtcp_sdes_prefix_len   = -1;
312 static int hf_rtcp_sdes_prefix_string= -1;
313 static int hf_rtcp_subtype           = -1;
314 static int hf_rtcp_name_ascii        = -1;
315 static int hf_rtcp_app_data          = -1;
316 static int hf_rtcp_fsn               = -1;
317 static int hf_rtcp_blp               = -1;
318 static int hf_rtcp_padding_count     = -1;
319 static int hf_rtcp_padding_data      = -1;
320 static int hf_rtcp_profile_specific_extension = -1;
321 static int hf_rtcp_app_poc1          = -1;
322 static int hf_rtcp_app_poc1_subtype  = -1;
323 static int hf_rtcp_app_poc1_sip_uri  = -1;
324 static int hf_rtcp_app_poc1_disp_name = -1;
325 static int hf_rtcp_app_poc1_priority    = -1;
326 static int hf_rtcp_app_poc1_request_ts  = -1;
327 static int hf_rtcp_app_poc1_stt                 = -1;
328 static int hf_rtcp_app_poc1_partic              = -1;
329 static int hf_rtcp_app_poc1_ssrc_granted        = -1;
330 static int hf_rtcp_app_poc1_last_pkt_seq_no = -1;
331 static int hf_rtcp_app_poc1_ignore_seq_no = -1;
332 static int hf_rtcp_app_poc1_reason_code1        = -1;
333 static int hf_rtcp_app_poc1_reason1_phrase      = -1;
334 static int hf_rtcp_app_poc1_reason_code2        = -1;
335 static int hf_rtcp_app_poc1_new_time_request    = -1;
336 static int hf_rtcp_app_poc1_ack_subtype         = -1;
337 static int hf_rtcp_app_poc1_ack_reason_code     = -1;
338 static int hf_rtcp_app_poc1_qsresp_priority     = -1;
339 static int hf_rtcp_app_poc1_qsresp_position     = -1;
340 static int hf_rtcp_app_poc1_conn_content[5] = { -1, -1, -1, -1, -1 };
341 static int hf_rtcp_app_poc1_conn_session_type   = -1;
342 static int hf_rtcp_app_poc1_conn_add_ind_mao    = -1;
343 static int hf_rtcp_app_poc1_conn_sdes_items[5] = { -1, -1, -1, -1, -1 };
344 static int hf_rtcp_xr_block_type     = -1;
345 static int hf_rtcp_xr_block_specific = -1;
346 static int hf_rtcp_xr_block_length   = -1;
347 static int hf_rtcp_xr_thinning       = -1;
348 static int hf_rtcp_xr_voip_metrics_burst_density = -1;
349 static int hf_rtcp_xr_voip_metrics_gap_density = -1;
350 static int hf_rtcp_xr_voip_metrics_burst_duration = -1;
351 static int hf_rtcp_xr_voip_metrics_gap_duration = -1;
352 static int hf_rtcp_xr_voip_metrics_rtdelay = -1;
353 static int hf_rtcp_xr_voip_metrics_esdelay = -1;
354 static int hf_rtcp_xr_voip_metrics_siglevel = -1;
355 static int hf_rtcp_xr_voip_metrics_noiselevel = -1;
356 static int hf_rtcp_xr_voip_metrics_rerl = -1;
357 static int hf_rtcp_xr_voip_metrics_gmin = -1;
358 static int hf_rtcp_xr_voip_metrics_rfactor = -1;
359 static int hf_rtcp_xr_voip_metrics_extrfactor = -1;
360 static int hf_rtcp_xr_voip_metrics_moslq = -1;
361 static int hf_rtcp_xr_voip_metrics_moscq = -1;
362 static int hf_rtcp_xr_voip_metrics_plc = -1;
363 static int hf_rtcp_xr_voip_metrics_jbadaptive = -1;
364 static int hf_rtcp_xr_voip_metrics_jbrate = -1;
365 static int hf_rtcp_xr_voip_metrics_jbnominal = -1;
366 static int hf_rtcp_xr_voip_metrics_jbmax = -1;
367 static int hf_rtcp_xr_voip_metrics_jbabsmax = -1;
368 static int hf_rtcp_xr_stats_loss_flag = -1;
369 static int hf_rtcp_xr_stats_dup_flag = -1;
370 static int hf_rtcp_xr_stats_jitter_flag = -1;
371 static int hf_rtcp_xr_stats_ttl = -1;
372 static int hf_rtcp_xr_beginseq = -1;
373 static int hf_rtcp_xr_endseq = -1;
374 static int hf_rtcp_xr_stats_lost = -1;
375 static int hf_rtcp_xr_stats_dups = -1;
376 static int hf_rtcp_xr_stats_minjitter = -1;
377 static int hf_rtcp_xr_stats_maxjitter = -1;
378 static int hf_rtcp_xr_stats_meanjitter = -1;
379 static int hf_rtcp_xr_stats_devjitter = -1;
380 static int hf_rtcp_xr_stats_minttl = -1;
381 static int hf_rtcp_xr_stats_maxttl = -1;
382 static int hf_rtcp_xr_stats_meanttl = -1;
383 static int hf_rtcp_xr_stats_devttl = -1;
384 static int hf_rtcp_xr_lrr = -1;
385 static int hf_rtcp_xr_dlrr = -1;
386 static int hf_rtcp_length_check = -1;
387
388 /* RTCP setup fields */
389 static int hf_rtcp_setup        = -1;
390 static int hf_rtcp_setup_frame  = -1;
391 static int hf_rtcp_setup_method = -1;
392
393 /* RTCP roundtrip delay fields */
394 static int hf_rtcp_last_sr_timestamp_frame  = -1;
395 static int hf_rtcp_roundtrip_delay  = -1;
396
397
398
399 /* RTCP fields defining a sub tree */
400 static gint ett_rtcp                    = -1;
401 static gint ett_ssrc                    = -1;
402 static gint ett_ssrc_item               = -1;
403 static gint ett_ssrc_ext_high           = -1;
404 static gint ett_sdes                    = -1;
405 static gint ett_sdes_item               = -1;
406 static gint ett_PoC1                    = -1;
407 static gint ett_rtcp_setup              = -1;
408 static gint ett_rtcp_roundtrip_delay    = -1;
409 static gint ett_xr_block                = -1;
410 static gint ett_xr_block_contents       = -1;
411 static gint ett_xr_ssrc                 = -1;
412 static gint  ett_xr_loss_chunk = -1;
413 static gint ett_poc1_conn_contents      = -1;
414
415 /* Protocol registration */
416 void proto_register_rtcp(void);
417 void proto_reg_handoff_rtcp(void);
418
419 /* Main dissection function */
420 static void dissect_rtcp( tvbuff_t *tvb, packet_info *pinfo,
421      proto_tree *tree );
422
423 /* Heuristic dissection */
424 static gboolean global_rtcp_heur = FALSE;
425 static gboolean dissect_rtcp_heur( tvbuff_t *tvb, packet_info *pinfo,
426     proto_tree *tree );
427
428 /* Displaying set info */
429 static gboolean global_rtcp_show_setup_info = TRUE;
430 static void show_setup_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
431
432 /* Related to roundtrip calculation (using LSR and DLSR) */
433 static gboolean global_rtcp_show_roundtrip_calculation = FALSE;
434 #define MIN_ROUNDTRIP_TO_REPORT_DEFAULT 10
435 static guint global_rtcp_show_roundtrip_calculation_minimum = MIN_ROUNDTRIP_TO_REPORT_DEFAULT;
436 static void remember_outgoing_sr(packet_info *pinfo, long lsr);
437 static void calculate_roundtrip_delay(tvbuff_t *tvb, packet_info *pinfo,
438                                       proto_tree *tree, guint32 lsr, guint32 dlsr);
439 static void add_roundtrip_delay_info(tvbuff_t *tvb, packet_info *pinfo,
440                                      proto_tree *tree, guint frame, guint delay);
441
442
443 /* Set up an RTCP conversation using the info given */
444 void rtcp_add_address( packet_info *pinfo,
445                        address *addr, int port,
446                        int other_port,
447                        const gchar *setup_method, guint32 setup_frame_number)
448 {
449         address null_addr;
450         conversation_t* p_conv;
451         struct _rtcp_conversation_info *p_conv_data = NULL;
452
453         /*
454          * If this isn't the first time this packet has been processed,
455          * we've already done this work, so we don't need to do it
456          * again.
457          */
458         if (pinfo->fd->flags.visited)
459         {
460                 return;
461         }
462
463         SET_ADDRESS(&null_addr, AT_NONE, 0, NULL);
464
465         /*
466          * Check if the ip address and port combination is not
467          * already registered as a conversation.
468          */
469         p_conv = find_conversation( pinfo->fd->num, addr, &null_addr, PT_UDP, port, other_port,
470                                     NO_ADDR_B | (!other_port ? NO_PORT_B : 0));
471
472         /*
473          * If not, create a new conversation.
474          */
475         if ( ! p_conv ) {
476                 p_conv = conversation_new( pinfo->fd->num, addr, &null_addr, PT_UDP,
477                                            (guint32)port, (guint32)other_port,
478                                            NO_ADDR2 | (!other_port ? NO_PORT2 : 0));
479         }
480
481         /* Set dissector */
482         conversation_set_dissector(p_conv, rtcp_handle);
483
484         /*
485          * Check if the conversation has data associated with it.
486          */
487         p_conv_data = conversation_get_proto_data(p_conv, proto_rtcp);
488
489         /*
490          * If not, add a new data item.
491          */
492         if ( ! p_conv_data ) {
493                 /* Create conversation data */
494                 p_conv_data = se_alloc(sizeof(struct _rtcp_conversation_info));
495                 if (!p_conv_data)
496                 {
497                         return;
498                 }
499                 memset(p_conv_data, 0, sizeof(struct _rtcp_conversation_info));
500                 conversation_add_proto_data(p_conv, proto_rtcp, p_conv_data);
501         }
502
503         /*
504          * Update the conversation data.
505          */
506         p_conv_data->setup_method_set = TRUE;
507         strncpy(p_conv_data->setup_method, setup_method, MAX_RTCP_SETUP_METHOD_SIZE);
508         p_conv_data->setup_method[MAX_RTCP_SETUP_METHOD_SIZE] = '\0';
509         p_conv_data->setup_frame_number = setup_frame_number;
510 }
511
512 static gboolean
513 dissect_rtcp_heur( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree )
514 {
515         unsigned int offset = 0;
516         unsigned int first_byte;
517         unsigned int packet_type;
518
519         /* This is a heuristic dissector, which means we get all the UDP
520          * traffic not sent to a known dissector and not claimed by
521          * a heuristic dissector called before us!
522          */
523
524         if (!global_rtcp_heur)
525         {
526                 return FALSE;
527         }
528
529         /* Was it sent between 2 odd-numbered ports? */
530         if (!(pinfo->srcport % 2) || !(pinfo->destport % 2))
531         {
532                 return FALSE;
533         }
534
535         /* Look at first byte */
536         first_byte = tvb_get_guint8(tvb, offset);
537
538         /* Are version bits set to 2? */
539         if (((first_byte & 0xC0) >> 6) != 2)
540         {
541                 return FALSE;
542         }
543
544         /* Look at packet type */
545         packet_type = tvb_get_guint8(tvb, offset + 1);
546
547         /* First packet within compound packet is supposed to be a sender
548            or receiver report.
549        - allow BYE because this happens anyway
550        - allow APP because TBCP ("PoC1") packets aren't compound... */
551         if (!((packet_type == RTCP_SR)  || (packet_type == RTCP_RR) ||
552            (packet_type == RTCP_BYE) || (packet_type == RTCP_APP)))
553         {
554                 return FALSE;
555         }
556
557         /* Overall length must be a multiple of 4 bytes */
558         if (tvb_length(tvb) % 4)
559         {
560                 return FALSE;
561         }
562
563         /* OK, dissect as RTCP */
564         dissect_rtcp(tvb, pinfo, tree);
565         return TRUE;
566 }
567
568
569 static int
570 dissect_rtcp_nack( tvbuff_t *tvb, int offset, proto_tree *tree )
571 {
572         /* Packet type = FIR (H261) */
573         proto_tree_add_uint( tree, hf_rtcp_rc, tvb, offset, 1, tvb_get_guint8( tvb, offset ) );
574         offset++;
575         /* Packet type, 8 bits  = APP */
576         proto_tree_add_item( tree, hf_rtcp_pt, tvb, offset, 1, FALSE );
577         offset++;
578
579         /* Packet length in 32 bit words minus one */
580         proto_tree_add_uint( tree, hf_rtcp_length, tvb, offset, 2, tvb_get_ntohs( tvb, offset ) );
581         offset += 2;
582
583         /* SSRC  */
584         proto_tree_add_uint( tree, hf_rtcp_ssrc_source, tvb, offset, 4, tvb_get_ntohl( tvb, offset ) );
585         offset += 4;
586
587         /* FSN, 16 bits */
588         proto_tree_add_uint( tree, hf_rtcp_fsn, tvb, offset, 2, tvb_get_ntohs( tvb, offset ) );
589         offset += 2;
590
591         /* BLP, 16 bits */
592         proto_tree_add_uint( tree, hf_rtcp_blp, tvb, offset, 2, tvb_get_ntohs( tvb, offset ) );
593         offset += 2;
594
595         return offset;
596 }
597
598 static int
599 dissect_rtcp_fir( tvbuff_t *tvb, int offset, proto_tree *tree )
600 {
601         /* Packet type = FIR (H261) */
602         proto_tree_add_uint( tree, hf_rtcp_rc, tvb, offset, 1, tvb_get_guint8( tvb, offset ) );
603         offset++;
604         /* Packet type, 8 bits  = APP */
605         proto_tree_add_item( tree, hf_rtcp_pt, tvb, offset, 1, FALSE );
606         offset++;
607
608         /* Packet length in 32 bit words minus one */
609         proto_tree_add_uint( tree, hf_rtcp_length, tvb, offset, 2, tvb_get_ntohs( tvb, offset ) );
610         offset += 2;
611
612         /* SSRC  */
613         proto_tree_add_uint( tree, hf_rtcp_ssrc_source, tvb, offset, 4, tvb_get_ntohl( tvb, offset ) );
614         offset += 4;
615
616         return offset;
617 }
618
619 static int
620 dissect_rtcp_app( tvbuff_t *tvb,packet_info *pinfo, int offset, proto_tree *tree,
621     unsigned int padding, unsigned int packet_len, guint rtcp_subtype, guint32 app_length )
622 {
623         unsigned int counter = 0;
624         char ascii_name[5];
625         guint sdes_type         = 0;
626         guint item_len          = 0;
627         guint items_start_offset;
628         proto_tree *PoC1_tree;
629         proto_item *PoC1_item;
630
631         /* XXX If more application types are to be dissected it may be useful to use a table like in packet-sip.c */
632         static const char poc1_app_name_str[] = "PoC1";
633
634
635         /* SSRC / CSRC */
636         proto_tree_add_uint( tree, hf_rtcp_ssrc_source, tvb, offset, 4, tvb_get_ntohl( tvb, offset ) );
637         offset += 4;
638         packet_len -= 4;
639
640         /* Application Name (ASCII) */
641         for( counter = 0; counter < 4; counter++ )
642             ascii_name[ counter ] = tvb_get_guint8( tvb, offset + counter );
643         /* strncpy( ascii_name, pd + offset, 4 ); */
644         ascii_name[4] = '\0';
645         proto_tree_add_string( tree, hf_rtcp_name_ascii, tvb, offset, 4,
646                                ascii_name );
647
648         /* See if we can handle this application type */
649         if ( strncasecmp(ascii_name, poc1_app_name_str,4 ) == 0 )
650         {
651                 /* PoC1 Application */
652                 guint8 t2timer_code, participants_code;
653                 proto_item *item;
654                 item = proto_tree_add_uint( tree, hf_rtcp_app_poc1_subtype, tvb, offset - 8, 1, rtcp_subtype );
655                 PROTO_ITEM_SET_GENERATED(item);
656                 if (check_col(pinfo->cinfo, COL_INFO))
657                         col_append_fstr(pinfo->cinfo, COL_INFO,"(%s) %s",ascii_name,
658                                         val_to_str(rtcp_subtype,rtcp_app_poc1_floor_cnt_type_vals,"unknown (%u)") );
659                 offset += 4;
660                 packet_len -= 4;
661                 app_length = app_length -8;
662                 if ( packet_len == 0 )
663                         return offset; /* No more data */
664                 /* Applications specific data */
665                 if ( padding ) {
666                         /* If there's padding present, we have to remove that from the data part
667                         * The last octet of the packet contains the length of the padding
668                         */
669                         packet_len -= tvb_get_guint8( tvb, offset + packet_len - 1 );
670                 }
671                 /* Create a subtree for the PoC1 Application items; we don't yet know
672                    the length */
673                 items_start_offset = offset;
674
675                 /* Top-level poc tree */
676                 PoC1_item = proto_tree_add_item(tree, hf_rtcp_app_poc1, tvb, offset, packet_len, FALSE);
677                 PoC1_tree = proto_item_add_subtree( PoC1_item, ett_PoC1 );
678
679                 /* Dissect it according to its subtype */
680                 switch ( rtcp_subtype ) {
681
682                         case TBCP_BURST_REQUEST:
683                                 {
684                                 guint8 code;
685                                 guint16 priority;
686
687                                 /* Both items here are optional */
688                                 if (tvb_reported_length_remaining( tvb, offset) == 0)
689                                 {
690                                         return offset;
691                                 }
692                                 
693                                 /* Look for a code in the first byte */
694                                 code = tvb_get_guint8(tvb, offset);
695                                 offset += 1;
696                                 packet_len -=1;
697
698                                 /* Priority (optional) */
699                                 if (code == 102)
700                                 {
701                                         item_len = tvb_get_guint8(tvb, offset);
702                                         offset += 1;
703                                         packet_len -= 1;
704                                         if (item_len != 2) /* SHALL be 2 */
705                                                 return offset;
706
707                                         priority = tvb_get_ntohs(tvb, offset);
708                                         proto_tree_add_item(PoC1_tree, hf_rtcp_app_poc1_priority, tvb, offset, 2, FALSE );
709                                         offset += 2;
710                                         packet_len -= 2;
711
712                                         if (check_col(pinfo->cinfo, COL_INFO))
713                                         {
714                                                 col_append_fstr(pinfo->cinfo, COL_INFO,
715                                                                " \"%s\"",
716                                                                val_to_str(priority,
717                                                                           rtcp_app_poc1_qsresp_priority_vals,
718                                                                           "Unknown"));
719                                         }
720
721                                         /* Look for (optional) next code */
722                                         if (tvb_reported_length_remaining( tvb, offset) == 0)
723                                         {
724                                                 return offset;
725                                         }
726                                         code = tvb_get_guint8(tvb, offset);
727                                         offset += 1;
728                                         packet_len -=1;
729
730                                 }
731
732                                 /* Request timestamp (optional) */
733                                 if (code == 103)
734                                 {
735                                         gchar *buff;
736                                         item_len = tvb_get_guint8(tvb, offset);
737                                         offset += 1;
738                                         packet_len -= 1;
739                                         if (item_len != 8) /* SHALL be 8 */
740                                                 return offset;
741
742                                         buff = ntp_fmt_ts(tvb_get_ptr(tvb, offset, 8));
743                                         proto_tree_add_string_format(PoC1_tree, hf_rtcp_app_poc1_request_ts,
744                                                                      tvb, offset, 8, ( const char* ) buff,
745                                                                      "Request timestamp: %s", buff );
746                                         offset += 8;
747                                         packet_len -=8;
748
749                                         if (check_col(pinfo->cinfo, COL_INFO))
750                                         {
751                                                 col_append_fstr(pinfo->cinfo, COL_INFO, " ts=\"%s\"", buff);
752                                         }
753                                 }
754                                 }
755                                 break;
756
757                         case TBCP_BURST_GRANTED:
758                                 {
759                                 proto_item *ti;
760                                 guint16 stop_talking_time;
761                                 guint16 participants;
762
763                                 /* Stop talking timer (now mandatory) */
764                                 t2timer_code = tvb_get_guint8(tvb, offset);
765                                 offset += 1;
766                                 packet_len -=1;
767                                 if (t2timer_code != 101) /* SHALL be 101 */
768                                         return offset;
769
770                                 item_len = tvb_get_guint8(tvb, offset);
771                                 offset += 1;
772                                 packet_len -= 1;
773                                 if (item_len != 2) /* SHALL be 2 */
774                                         return offset;
775
776                                 stop_talking_time = tvb_get_ntohs(tvb, offset);
777                                 ti = proto_tree_add_item(PoC1_tree, hf_rtcp_app_poc1_stt, tvb, offset, 2, FALSE );
778
779                                 /* Append text with meanings of value */
780                                 switch (stop_talking_time)
781                                 {
782                                         case 0:
783                                                 proto_item_append_text(ti, " unknown");
784                                                 break;
785                                         case 65535:
786                                                 proto_item_append_text(ti, " infinity");
787                                                 break;
788                                         default:
789                                                 proto_item_append_text(ti, " seconds");
790                                                 break;
791                                 }
792                                 offset += item_len;
793                                 packet_len -= item_len;
794
795                                 if (check_col(pinfo->cinfo, COL_INFO))
796                                 {
797                                         col_append_fstr(pinfo->cinfo, COL_INFO, " stop-talking-time=%u",
798                                                         stop_talking_time);
799                                 }
800
801                                 /* Participants (optional) */
802                                 if (tvb_reported_length_remaining( tvb, offset) == 0)
803                                 {
804                                         return offset;
805                                 }
806                                 participants_code = tvb_get_guint8(tvb, offset);
807                                 offset += 1;
808                                 packet_len -=1;
809                                 if (participants_code != 100) /* SHALL be 100 */
810                                         return offset;
811
812                                 item_len = tvb_get_guint8(tvb, offset);
813                                 offset += 1;
814                                 packet_len -= 1;
815                                 if (item_len != 2) /* SHALL be 2 */
816                                         return offset;
817
818                                 participants = tvb_get_ntohs(tvb, offset);
819                                 ti = proto_tree_add_item(PoC1_tree, hf_rtcp_app_poc1_partic, tvb, offset, 2, FALSE );
820
821                                 /* Append text with meanings of extreme values */
822                                 switch (participants)
823                                 {
824                                         case 0:
825                                                 proto_item_append_text(ti, " (not known)");
826                                                 break;
827                                         case 65535:
828                                                 proto_item_append_text(ti, " (or more)");
829                                                 break;
830                                         default:
831                                                 break;
832                                 }
833                                 offset += item_len;
834                                 packet_len -= item_len;
835
836                                 if (check_col(pinfo->cinfo, COL_INFO))
837                                 {
838                                         col_append_fstr(pinfo->cinfo, COL_INFO, " participants=%u",
839                                                         participants);
840                                 }
841
842                                 }
843                                 break;
844
845                         case TBCP_BURST_TAKEN_EXPECT_NO_REPLY:
846                         case TBCP_BURST_TAKEN_EXPECT_REPLY:
847                                 {
848                                 guint16 participants;
849                                 proto_item *ti;
850
851                                 /* SSRC of PoC client */
852                                 proto_tree_add_item(PoC1_tree, hf_rtcp_app_poc1_ssrc_granted, tvb, offset, 4, FALSE );
853                                 offset += 4;
854                                 packet_len -= 4;
855
856                                 /* SDES type (must be CNAME) */
857                                 sdes_type = tvb_get_guint8( tvb, offset );
858                                 proto_tree_add_item( PoC1_tree, hf_rtcp_sdes_type, tvb, offset, 1, FALSE );
859                                 offset++;
860                                 packet_len--;
861                                 if (sdes_type != RTCP_SDES_CNAME)
862                                 {
863                                         return offset;
864                                 }
865
866                                 /* Item length, 8 bits */
867                                 item_len = tvb_get_guint8( tvb, offset );
868                                 proto_tree_add_item( PoC1_tree, hf_rtcp_sdes_length, tvb, offset, 1, FALSE );
869                                 offset++;
870                                 packet_len--;
871
872                                 /* SIP URI */
873                                 proto_tree_add_item( PoC1_tree, hf_rtcp_app_poc1_sip_uri, tvb, offset, item_len, FALSE );
874
875                                 if (check_col(pinfo->cinfo, COL_INFO))
876                                 {
877                                         col_append_fstr(pinfo->cinfo, COL_INFO, " CNAME=\"%s\"",
878                                                         tvb_get_ephemeral_string(tvb, offset, item_len));
879                                 }
880                                 
881                                 offset = offset + item_len;
882                                 packet_len = packet_len - item_len;
883                                 
884                                 /* In the application dependent data, the TBCP Talk Burst Taken message SHALL carry
885                                  * a SSRC field and SDES items, CNAME and MAY carry SDES item NAME to identify the
886                                  * PoC Client that has been granted permission to send a Talk Burst.
887                                  *
888                                  * The SDES item NAME SHALL be included if it is known by the PoC Server. 
889                                  * Therefore the length of the packet will vary depending on number of SDES items 
890                                  * and the size of the SDES items.
891                                  */
892                                 if ( packet_len == 0 )
893                                         return offset;
894
895                                 /* SDES type (must be NAME if present) */
896                                 sdes_type = tvb_get_guint8( tvb, offset );
897                                 if (sdes_type == RTCP_SDES_NAME)
898                                 {
899                                         proto_tree_add_item( PoC1_tree, hf_rtcp_sdes_type, tvb, offset, 1, FALSE );
900                                         offset++;
901                                         packet_len--;
902         
903                                         /* Item length, 8 bits */
904                                         item_len = tvb_get_guint8( tvb, offset );
905                                         proto_tree_add_item( PoC1_tree, hf_rtcp_sdes_length, tvb, offset, 1, FALSE );
906                                         offset++;
907                                         packet_len--;
908         
909                                         /* Display name */
910                                         if ( item_len != 0 )
911                                                 proto_tree_add_item( PoC1_tree, hf_rtcp_app_poc1_disp_name, tvb, offset, item_len, FALSE );
912                                         offset = offset + item_len;
913                                         packet_len = packet_len - item_len;
914
915                                         if (packet_len == 0)
916                                                 return offset;
917                                 }
918
919                                 /* Participants (optional) */
920                                 if (tvb_reported_length_remaining( tvb, offset) == 0)
921                                 {
922                                         return offset;
923                                 }
924                                 participants_code = tvb_get_guint8(tvb, offset);
925                                 offset += 1;
926                                 packet_len -=1;
927                                 if (participants_code != 100) /* SHALL be 100 */
928                                         return offset;
929                                 item_len = tvb_get_guint8(tvb, offset);
930                                 offset += 1;
931                                 packet_len -= 1;
932                                 if (item_len != 2) /* SHALL be 2 */
933                                         return offset;
934
935                                 participants = tvb_get_ntohs(tvb, offset);
936                                 ti = proto_tree_add_item(PoC1_tree, hf_rtcp_app_poc1_partic, tvb, offset, 2, FALSE );
937
938                                 /* Append text with meanings of extreme values */
939                                 switch (participants)
940                                 {
941                                         case 0:
942                                                 proto_item_append_text(ti, " (not known)");
943                                                 break;
944                                         case 65535:
945                                                 proto_item_append_text(ti, " (or more)");
946                                                 break;
947                                         default:
948                                                 break;
949                                 }
950
951                                 offset += item_len;
952                                 packet_len -= item_len;
953                                 }
954                                 break;
955
956                         case TBCP_BURST_DENY:
957                                 {
958                                 guint8 reason_code;
959
960                                 /* Reason code */
961                                 reason_code = tvb_get_guint8(tvb, offset);
962                                 proto_tree_add_item( PoC1_tree, hf_rtcp_app_poc1_reason_code1, tvb, offset, 1, FALSE );
963                                 offset++;
964                                 packet_len--;
965
966                                 if (check_col(pinfo->cinfo, COL_INFO))
967                                 {
968                                         col_append_fstr(pinfo->cinfo, COL_INFO, " reason-code=\"%s\"",
969                                                         val_to_str(reason_code,
970                                                                    rtcp_app_poc1_reason_code1_vals,
971                                                                    "Unknown"));
972                                 }
973
974                                 /* Reason phrase */
975                                 item_len = tvb_get_guint8( tvb, offset );
976                                 if ( item_len != 0 )
977                                         proto_tree_add_item( PoC1_tree, hf_rtcp_app_poc1_reason1_phrase, tvb, offset, 1, FALSE );
978
979                                 offset += (item_len+1);
980                                 packet_len -= (item_len+1);
981                                 }
982                                 break;
983
984                         case TBCP_BURST_RELEASE:
985                                 {
986                                 guint16 last_seq_no;
987                                 guint8  ignore_last_seq_no;
988
989                                 /* Sequence number of last RTP packet in burst */
990                                 proto_tree_add_item( PoC1_tree, hf_rtcp_app_poc1_last_pkt_seq_no, tvb, offset, 2, FALSE );
991                                 last_seq_no = tvb_get_ntohs(tvb, offset);
992
993                                 /* Bit 16 is ignore flag */
994                                 offset += 2;
995                                 proto_tree_add_item(PoC1_tree, hf_rtcp_app_poc1_ignore_seq_no, tvb, offset, 2, FALSE );
996                                 ignore_last_seq_no = (tvb_get_ntohs(tvb, offset) & 0x8000);
997
998                                 if (!ignore_last_seq_no && check_col(pinfo->cinfo, COL_INFO))
999                                 {
1000                                         col_append_fstr(pinfo->cinfo, COL_INFO, " last_rtp_seq_no=%u",
1001                                                         last_seq_no);
1002                                 }
1003
1004                                 /* 15 bits of padding follows */
1005
1006                                 offset += 2;
1007                                 packet_len-=4;
1008                                 }
1009                                 break;
1010
1011                         case TBCP_BURST_IDLE:
1012                                 break;
1013
1014                         case TBCP_BURST_REVOKE:
1015                                 {
1016                                         /* Reason code */
1017                                         guint16 reason_code = tvb_get_ntohs(tvb, offset);
1018                                         proto_tree_add_item( PoC1_tree, hf_rtcp_app_poc1_reason_code2, tvb, offset, 2, FALSE );
1019
1020                                         /* The meaning of this field depends upon the reason code... */
1021                                         switch (reason_code)
1022                                         {
1023                                                 case 1: /* Only one user */
1024                                                         /* No additional info */
1025                                                         break;
1026                                                 case 2: /* Talk burst too long */
1027                                                         /* Additional info is 16 bits with time (in seconds) client can request */
1028                                                         proto_tree_add_item( PoC1_tree, hf_rtcp_app_poc1_new_time_request, tvb, offset + 2, 2, FALSE );
1029                                                         break;
1030                                                 case 3: /* No permission */
1031                                                         /* No additional info */
1032                                                         break;
1033                                                 case 4: /* Pre-empted */
1034                                                         /* No additional info */
1035                                                         break;
1036                                         }
1037
1038                                         if (check_col(pinfo->cinfo, COL_INFO))
1039                                         {
1040                                                 col_append_fstr(pinfo->cinfo, COL_INFO, " reason-code=\"%s\"",
1041                                                                 val_to_str(reason_code,
1042                                                                            rtcp_app_poc1_reason_code2_vals,
1043                                                                            "Unknown"));
1044                                         }
1045                                         offset += 4;
1046                                         packet_len-=4;
1047                                 }
1048                                 break;
1049
1050                         case TBCP_BURST_ACKNOWLEDGMENT:
1051                                 {
1052                                 guint8 subtype;
1053
1054                                 /* Code of message being acknowledged */
1055                                 subtype = (tvb_get_guint8(tvb, offset) & 0xf8) >> 3;
1056                                 proto_tree_add_item( PoC1_tree, hf_rtcp_app_poc1_ack_subtype, tvb, offset, 1, FALSE );
1057
1058                                 if (check_col(pinfo->cinfo, COL_INFO))
1059                                 {
1060                                         col_append_fstr(pinfo->cinfo, COL_INFO, " (for %s)",
1061                                                         val_to_str(subtype,
1062                                                                    rtcp_app_poc1_floor_cnt_type_vals,
1063                                                                    "Unknown"));
1064                                 }
1065
1066                                 /* Reason code only seen if subtype was Connect */
1067                                 if (subtype == TBCP_CONNECT)
1068                                 {
1069                                         proto_tree_add_item( PoC1_tree, hf_rtcp_app_poc1_ack_reason_code, tvb, offset, 2, FALSE );
1070                                 }
1071
1072                                 /* 16 bits of padding follow */ 
1073                                 offset += 4;
1074                                 packet_len -= 4;
1075                                 }
1076                                 break;
1077
1078                         case TBCP_QUEUE_STATUS_REQUEST:
1079                                 break;
1080
1081                         case TBCP_QUEUE_STATUS_RESPONSE:
1082                                 {
1083                                 guint16 position;
1084                                 proto_item *ti;
1085
1086                                 /* Priority */
1087                                 proto_tree_add_item( PoC1_tree, hf_rtcp_app_poc1_qsresp_priority, tvb, offset, 1, FALSE );
1088
1089                                 /* Queue position. 65535 indicates 'position not available' */
1090                                 position = tvb_get_ntohs(tvb, offset+1);
1091                                 ti = proto_tree_add_item( PoC1_tree, hf_rtcp_app_poc1_qsresp_position, tvb, offset+1, 2, FALSE );
1092                                 if (position == 0)
1093                                 {
1094                                         proto_item_append_text(ti, " (client is un-queued)");
1095                                 }
1096                                 if (position == 65535)
1097                                 {
1098                                         proto_item_append_text(ti, " (position not available)");
1099                                 }
1100
1101                                 if (check_col(pinfo->cinfo, COL_INFO))
1102                                 {
1103                                         col_append_fstr(pinfo->cinfo, COL_INFO, " position=%u", position);
1104                                 }
1105
1106                                 /* 1 bytes of padding  follows */
1107
1108                                 offset += 4;
1109                                 packet_len -= 4;
1110                                 }
1111                             break;
1112
1113                         case TBCP_DISCONNECT:
1114                                 break;
1115
1116                         case TBCP_CONNECT:
1117                                 {
1118                                 proto_item *content = proto_tree_add_text(PoC1_tree, tvb, offset, 2, "SDES item content");
1119                                 gboolean contents[5];
1120                                 unsigned int i;
1121                                 guint8 items_set = 0;
1122
1123                                 proto_tree *content_tree = proto_item_add_subtree(content, ett_poc1_conn_contents);
1124                                 guint16 items_field = tvb_get_ntohs(tvb, offset );
1125
1126                                 /* Dissect each defined bit flag in the SDES item content */
1127                                 for ( i = 0;
1128                                       i < sizeof(contents) / sizeof(contents[0]) &&
1129                                       i < sizeof(hf_rtcp_app_poc1_conn_content) /
1130                                           sizeof(hf_rtcp_app_poc1_conn_content[0]);
1131                                       ++i )
1132                                 {
1133                                         proto_tree_add_item( content_tree, hf_rtcp_app_poc1_conn_content[i], tvb, offset, 2, FALSE );
1134                                         contents[i] = items_field & (1 << (15-i));
1135                                         if (contents[i]) ++items_set;
1136                                 }
1137
1138                                 /* Show how many flags were set */
1139                                 proto_item_append_text(content, " (%u items)", items_set);
1140
1141                                 /* Session type */
1142                                 proto_tree_add_item( PoC1_tree, hf_rtcp_app_poc1_conn_session_type, tvb, offset + 2, 1, FALSE );
1143
1144                                 /* Additional indications */
1145                                 proto_tree_add_item( PoC1_tree, hf_rtcp_app_poc1_conn_add_ind_mao, tvb, offset + 3, 1, FALSE );
1146
1147                                 offset += 4;
1148                                 packet_len -= 4;
1149
1150                                 /* One SDES item for every set flag in contents array */
1151                                 for ( i = 0;
1152                                       i < sizeof(contents) / sizeof(contents[0]);
1153                                       ++i ) {
1154                                         if ( contents[i] ) {
1155                                                 guint sdes_type, sdes_len;
1156                                                 /* (sdes_type not currently used...).  Could complain if type
1157                                                    doesn't match expected for item... */
1158                                                 sdes_type = tvb_get_guint8( tvb, offset++ );
1159                                                 sdes_len = tvb_get_guint8( tvb, offset );
1160
1161                                                 /* Add SDES field indicated as present */
1162                                                 proto_tree_add_item( PoC1_tree, hf_rtcp_app_poc1_conn_sdes_items[i], tvb, offset, 1, FALSE );
1163
1164                                                 /* Move past field */
1165                                                 offset += sdes_len + 1;
1166                                                 packet_len -= (sdes_len + 2);
1167                                         }
1168                                 }
1169                             break;
1170                         }
1171
1172                         default:
1173                                 break;
1174                 }
1175                 offset += packet_len;
1176                 return offset;
1177         }
1178         else
1179         {
1180                 /* Unhandled application type, just show app name and raw data */
1181                 if (check_col(pinfo->cinfo, COL_INFO))
1182                         col_append_fstr(pinfo->cinfo, COL_INFO,"( %s ) subtype=%u",ascii_name, rtcp_subtype);
1183                 offset += 4;
1184                 packet_len -= 4;
1185                 /* Applications specific data */
1186                 if ( padding ) {
1187                         /* If there's padding present, we have to remove that from the data part
1188                         * The last octet of the packet contains the length of the padding
1189                         */
1190                         packet_len -= tvb_get_guint8( tvb, offset + packet_len - 1 );
1191                 }
1192                 proto_tree_add_item( tree, hf_rtcp_app_data, tvb, offset, packet_len, FALSE );
1193                 offset += packet_len;
1194
1195                 return offset;
1196         }
1197
1198 }
1199
1200
1201 static int
1202 dissect_rtcp_bye( tvbuff_t *tvb, int offset, proto_tree *tree,
1203     unsigned int count )
1204 {
1205         unsigned int chunk          = 1;
1206         unsigned int reason_length  = 0;
1207         char* reason_text = NULL;
1208
1209         while ( chunk <= count ) {
1210                 /* source identifier, 32 bits */
1211                 proto_tree_add_item( tree, hf_rtcp_ssrc_source, tvb, offset, 4, FALSE);
1212                 offset += 4;
1213                 chunk++;
1214         }
1215
1216         if ( tvb_reported_length_remaining( tvb, offset ) > 0 ) {
1217                 /* Bye reason consists of an 8 bit length l and a string with length l */
1218                 reason_length = tvb_get_guint8( tvb, offset );
1219                 proto_tree_add_item( tree, hf_rtcp_sdes_length, tvb, offset, 1, FALSE );
1220                 offset++;
1221
1222                 reason_text = (char*)tvb_get_ephemeral_string(tvb, offset, reason_length);
1223                 proto_tree_add_string( tree, hf_rtcp_sdes_text, tvb, offset, reason_length, reason_text );
1224                 /* Allow for terminating null character */
1225                 offset += (reason_length+1);
1226         }
1227
1228         /* BYE packet padded out if string (including null) didn't fit in previous word */
1229         if (offset % 4)
1230         {
1231                 offset += (4 - (offset % 4));
1232         }
1233
1234         return offset;
1235 }
1236
1237 static void
1238 dissect_rtcp_sdes( tvbuff_t *tvb, int offset, proto_tree *tree,
1239     unsigned int count )
1240 {
1241         unsigned int chunk          = 1;
1242         proto_item *sdes_item;
1243         proto_tree *sdes_tree;
1244         proto_tree *sdes_item_tree;
1245         proto_item *ti;
1246         int start_offset;
1247         int items_start_offset;
1248         guint32 ssrc;
1249         unsigned int item_len       = 0;
1250         unsigned int sdes_type      = 0;
1251         unsigned int prefix_len     = 0;
1252
1253         while ( chunk <= count ) {
1254                 /* Create a subtree for this chunk; we don't yet know
1255                    the length. */
1256                 start_offset = offset;
1257
1258                 ssrc = tvb_get_ntohl( tvb, offset );
1259                 sdes_item = proto_tree_add_text(tree, tvb, offset, -1,
1260                     "Chunk %u, SSRC/CSRC %u", chunk, ssrc);
1261                 sdes_tree = proto_item_add_subtree( sdes_item, ett_sdes );
1262
1263                 /* SSRC_n source identifier, 32 bits */
1264                 proto_tree_add_uint( sdes_tree, hf_rtcp_ssrc_source, tvb, offset, 4, ssrc );
1265                 offset += 4;
1266
1267                 /* Create a subtree for the SDES items; we don't yet know
1268                    the length */
1269                 items_start_offset = offset;
1270                 ti = proto_tree_add_text(sdes_tree, tvb, offset, -1,
1271                     "SDES items" );
1272                 sdes_item_tree = proto_item_add_subtree( ti, ett_sdes_item );
1273
1274                 /*
1275                  * Not every message is ended with "null" bytes, so check for
1276                  * end of frame as well.
1277                  */
1278                 while ( tvb_reported_length_remaining( tvb, offset ) > 0 ) {
1279                         /* ID, 8 bits */
1280                         sdes_type = tvb_get_guint8( tvb, offset );
1281                         proto_tree_add_item( sdes_item_tree, hf_rtcp_sdes_type, tvb, offset, 1, FALSE );
1282                         offset++;
1283
1284                         if ( sdes_type == RTCP_SDES_END ) {
1285                                 /* End of list */
1286                                 break;
1287                         }
1288
1289                         /* Item length, 8 bits */
1290                         item_len = tvb_get_guint8( tvb, offset );
1291                         proto_tree_add_item( sdes_item_tree, hf_rtcp_sdes_length, tvb, offset, 1, FALSE );
1292                         offset++;
1293
1294                         if ( item_len != 0 ) {
1295                                 if ( sdes_type == RTCP_SDES_PRIV ) {
1296                                         /* PRIV adds two items between the
1297                                          * SDES length and value - an 8 bit
1298                                          * length giving the length of a
1299                                          * "prefix string", and the string.
1300                                          */
1301                                         prefix_len = tvb_get_guint8( tvb, offset );
1302                                         if ( prefix_len + 1 > item_len ) {
1303                                                 proto_tree_add_uint_format( sdes_item_tree,
1304                                                     hf_rtcp_sdes_prefix_len, tvb,
1305                                                     offset, 1, prefix_len,
1306                                                     "Prefix length: %u (bogus, must be <= %u)",
1307                                                     prefix_len, item_len - 1);
1308                                                 offset += item_len;
1309                                                 continue;
1310                                         }
1311                                         proto_tree_add_item( sdes_item_tree, hf_rtcp_sdes_prefix_len, tvb, offset, 1, FALSE );
1312                                         offset++;
1313
1314                                         proto_tree_add_item( sdes_item_tree, hf_rtcp_sdes_prefix_string, tvb, offset, prefix_len, FALSE );
1315                                         offset += prefix_len;
1316                                         item_len -= prefix_len +1;
1317                                         if ( item_len == 0 )
1318                                                 continue;
1319                                 }
1320                                 proto_tree_add_item( sdes_item_tree, hf_rtcp_sdes_text, tvb, offset, item_len, FALSE );
1321                                 offset += item_len;
1322                         }
1323                 }
1324
1325                 /* Set the length of the items subtree. */
1326                 proto_item_set_len(ti, offset - items_start_offset);
1327
1328                 /* 32 bits = 4 bytes, so.....
1329                  * If offset % 4 != 0, we divide offset by 4, add one and then
1330                  * multiply by 4 again to reach the boundary
1331                  */
1332                 if ( offset % 4 != 0 )
1333                         offset = ((offset / 4) + 1 ) * 4;
1334
1335                 /* Set the length of this chunk. */
1336                 proto_item_set_len(sdes_item, offset - start_offset);
1337
1338                 chunk++;
1339         }
1340 }
1341
1342 static void parse_xr_type_specific_field(tvbuff_t *tvb, gint offset, guint block_type, proto_tree *tree)
1343 {
1344     guint8 flags = tvb_get_guint8(tvb, offset);
1345
1346     switch (block_type) {
1347     case RTCP_XR_LOSS_RLE:
1348     case RTCP_XR_DUP_RLE:
1349     case RTCP_XR_PKT_RXTIMES:
1350         proto_tree_add_uint(tree, hf_rtcp_xr_thinning, tvb, offset, 1, flags);
1351         break;
1352         
1353     case RTCP_XR_STATS_SUMRY:
1354         proto_tree_add_boolean(tree, hf_rtcp_xr_stats_loss_flag, tvb, offset, 1, flags);
1355         proto_tree_add_boolean(tree, hf_rtcp_xr_stats_dup_flag, tvb, offset, 1, flags);
1356         proto_tree_add_boolean(tree, hf_rtcp_xr_stats_jitter_flag, tvb, offset, 1, flags);
1357         proto_tree_add_uint(tree, hf_rtcp_xr_stats_ttl, tvb, offset, 1, flags);
1358         break;
1359
1360     default:
1361         proto_tree_add_uint(tree, hf_rtcp_xr_block_specific, tvb, offset, 1, flags);
1362         break;
1363     }
1364 }
1365
1366 static gboolean validate_xr_block_length(tvbuff_t *tvb, int offset, guint block_type, guint block_len, proto_tree *tree)
1367 {
1368     proto_tree_add_uint(tree, hf_rtcp_xr_block_length, tvb, offset, 2, block_len);
1369     switch (block_type) {
1370     case RTCP_XR_REF_TIME:
1371         if (block_len != 2)
1372             proto_tree_add_text(tree, tvb, offset, 2, "Invalid block length, should be 2");
1373         return FALSE;
1374
1375     case RTCP_XR_STATS_SUMRY:
1376         if (block_len != 9)
1377             proto_tree_add_text(tree, tvb, offset, 2, "Invalid block length, should be 9");
1378         return FALSE;
1379
1380     case RTCP_XR_VOIP_METRCS:
1381         if (block_len != 8)
1382             proto_tree_add_text(tree, tvb, offset, 2, "Invalid block length, should be 8");
1383         return FALSE;
1384
1385     default:
1386         break;
1387     }
1388     return TRUE;
1389 }
1390
1391 static int
1392 dissect_rtcp_xr(tvbuff_t *tvb, packet_info *pinfo _U_, int offset, proto_tree *tree, gint packet_len)
1393 {
1394     guint block_num = 1;
1395     
1396     /* Packet length should at least be 4 */
1397     if (packet_len < 4) {
1398         proto_tree_add_text(tree, tvb, offset, packet_len, "Missing Sender SSRC");
1399         return offset + packet_len;
1400     }
1401         
1402     /* SSRC */
1403     proto_tree_add_item( tree, hf_rtcp_ssrc_sender, tvb, offset, 4, FALSE );
1404     offset += 4;
1405     packet_len -= 4;
1406     
1407     for(;packet_len > 0; block_num++) {
1408         guint block_type = tvb_get_guint8(tvb, offset), block_length = 0;
1409         gint content_length = 0;
1410         gboolean valid = TRUE;
1411         
1412         /* Create a subtree for this block, dont know the length yet*/
1413         proto_item *block = proto_tree_add_text(tree, tvb, offset, -1, "Block %u", block_num);
1414         proto_tree *xr_block_tree = proto_item_add_subtree(block, ett_xr_block);
1415         proto_item *contents = NULL;
1416         proto_item *content_tree = NULL;
1417
1418         proto_tree_add_item(xr_block_tree, hf_rtcp_xr_block_type, tvb, offset, 1, FALSE);
1419         
1420         if (packet_len >= 2) {
1421             parse_xr_type_specific_field(tvb, offset + 1, block_type, xr_block_tree);
1422             if (packet_len >= 4) {
1423                 block_length = tvb_get_ntohs(tvb, offset + 2);
1424                 valid = validate_xr_block_length(tvb, offset + 2, block_type, block_length, xr_block_tree);
1425             }
1426         } else {
1427             proto_tree_add_text(xr_block_tree, tvb, offset + 1, packet_len, "Missing Required Block Headers");
1428             return offset + packet_len;
1429         }
1430                 
1431         content_length = block_length * 4;
1432         proto_item_set_len(block, content_length + 4);
1433         
1434         if (content_length > packet_len) {
1435             proto_tree_add_text(xr_block_tree, tvb, offset + 2, 2, "Block length is greater than packet length");
1436         }
1437                 
1438         offset += 4;
1439         packet_len -= 4;
1440
1441         contents = proto_tree_add_text(xr_block_tree, tvb, offset, content_length, "Contents");
1442         content_tree = proto_item_add_subtree(contents, ett_xr_block_contents);
1443             
1444         switch (block_type) {
1445         case RTCP_XR_VOIP_METRCS: {
1446             guint fraction_rate, value;
1447             
1448             /* Identifier */
1449             proto_tree_add_item(content_tree, hf_rtcp_ssrc_source, tvb, offset, 4, FALSE);
1450             offset += 4;
1451             
1452             /* Loss Rate */
1453             fraction_rate = tvb_get_guint8(tvb, offset);
1454             proto_tree_add_uint_format(content_tree, hf_rtcp_ssrc_fraction, tvb, offset, 1, 
1455                                        fraction_rate, "Fraction lost: %u / 256", fraction_rate);
1456             offset++;
1457             
1458             /* Discard Rate */
1459             fraction_rate = tvb_get_guint8(tvb, offset);
1460             proto_tree_add_uint_format(content_tree, hf_rtcp_ssrc_discarded, tvb, offset, 1, 
1461                                        fraction_rate, "Fraction Discarded: %u / 256", fraction_rate);
1462             offset++;
1463             
1464             /* Burst Density */
1465             proto_tree_add_item(content_tree, hf_rtcp_xr_voip_metrics_burst_density, tvb, offset, 1, FALSE);
1466             offset++;
1467             
1468             /* Gap Density */
1469             proto_tree_add_item(content_tree, hf_rtcp_xr_voip_metrics_gap_density, tvb, offset, 1, FALSE);
1470             offset++;
1471             
1472             /* Burst Duration */
1473             proto_tree_add_item(content_tree, hf_rtcp_xr_voip_metrics_burst_duration, tvb, offset, 2, FALSE);
1474             offset += 2;
1475             
1476             /* Gap Duration */
1477             proto_tree_add_item(content_tree, hf_rtcp_xr_voip_metrics_gap_duration, tvb, offset, 2, FALSE);
1478             offset += 2;
1479             
1480             /* Round Trip Delay */
1481             proto_tree_add_item(content_tree, hf_rtcp_xr_voip_metrics_rtdelay, tvb, offset, 2, FALSE);
1482             offset += 2;
1483             
1484             /* End System Delay */
1485             proto_tree_add_item(content_tree, hf_rtcp_xr_voip_metrics_esdelay, tvb, offset, 2, FALSE);
1486             offset += 2;
1487             
1488             /* Signal Level */
1489             proto_tree_add_item(content_tree, hf_rtcp_xr_voip_metrics_siglevel, tvb, offset, 1, FALSE);
1490             offset++;
1491             
1492             /* Noise Level */
1493             proto_tree_add_item(content_tree, hf_rtcp_xr_voip_metrics_noiselevel, tvb, offset, 1, FALSE);
1494             offset++;
1495             
1496             /* RERL */
1497             proto_tree_add_item(content_tree, hf_rtcp_xr_voip_metrics_rerl, tvb, offset, 1, FALSE);
1498             offset++;
1499             
1500             /* GMin */
1501             proto_tree_add_item(content_tree, hf_rtcp_xr_voip_metrics_gmin, tvb, offset, 1, FALSE);
1502             offset++;
1503             
1504             /* R factor */
1505             proto_tree_add_item(content_tree, hf_rtcp_xr_voip_metrics_rfactor, tvb, offset, 1, FALSE);
1506             offset++;
1507             
1508             /* external R Factor */
1509             proto_tree_add_item(content_tree, hf_rtcp_xr_voip_metrics_extrfactor, tvb, offset, 1, FALSE);
1510             offset++;
1511             
1512             /* MOS LQ */
1513             proto_tree_add_float(content_tree, hf_rtcp_xr_voip_metrics_moslq, tvb, offset, 1, 
1514                                  (gfloat)(int)(tvb_get_guint8(tvb, offset) / 10));
1515             offset++;
1516             
1517             /* MOS CQ */
1518             proto_tree_add_float(content_tree, hf_rtcp_xr_voip_metrics_moscq, tvb, offset, 1, 
1519                                  (gfloat)(int)(tvb_get_guint8(tvb, offset) / 10));
1520             offset++;
1521             
1522             /* PLC, JB Adaptive, JB Rate */
1523             value = tvb_get_guint8(tvb, offset);
1524             proto_tree_add_uint(content_tree, hf_rtcp_xr_voip_metrics_plc, tvb, offset, 1, value);
1525             proto_tree_add_uint(content_tree, hf_rtcp_xr_voip_metrics_jbadaptive, tvb, offset, 1, value);
1526             proto_tree_add_uint(content_tree, hf_rtcp_xr_voip_metrics_jbrate, tvb, offset, 1, value);
1527             offset += 2; /* skip over reseved bit */
1528             
1529             /* JB Nominal */
1530             proto_tree_add_item(content_tree, hf_rtcp_xr_voip_metrics_jbnominal, tvb, offset, 2, FALSE);
1531             offset += 2;
1532             
1533             /* JB Max */
1534             proto_tree_add_item(content_tree, hf_rtcp_xr_voip_metrics_jbmax, tvb, offset, 2, FALSE);
1535             offset += 2;
1536             
1537             /* JB Abs max */
1538             proto_tree_add_item(content_tree, hf_rtcp_xr_voip_metrics_jbabsmax, tvb, offset, 2, FALSE);
1539             offset += 2;
1540
1541             break;
1542         }
1543             
1544         case RTCP_XR_STATS_SUMRY: {
1545             /* Identifier */
1546             proto_tree_add_item(content_tree, hf_rtcp_ssrc_source, tvb, offset, 4, FALSE);
1547             offset += 4;
1548
1549             /* Begin Seq */
1550             proto_tree_add_item(content_tree, hf_rtcp_xr_beginseq, tvb, offset, 2, FALSE);
1551             offset += 2;
1552
1553             /* End Seq */
1554             proto_tree_add_item(content_tree, hf_rtcp_xr_endseq, tvb, offset, 2, FALSE);
1555             offset += 2;
1556
1557             /* Lost Pkts */
1558             proto_tree_add_item(content_tree, hf_rtcp_xr_stats_lost, tvb, offset, 4, FALSE);
1559             offset += 4;
1560
1561             /* Dup Pkts */
1562             proto_tree_add_item(content_tree, hf_rtcp_xr_stats_dups, tvb, offset, 4, FALSE);
1563             offset += 4;
1564
1565             /* Min Jitter */
1566             proto_tree_add_item(content_tree, hf_rtcp_xr_stats_minjitter, tvb, offset, 4, FALSE);
1567             offset += 4;
1568
1569             /* Max Jitter */
1570             proto_tree_add_item(content_tree, hf_rtcp_xr_stats_maxjitter, tvb, offset, 4, FALSE);
1571             offset += 4;
1572
1573             /* Mean Jitter */
1574             proto_tree_add_item(content_tree, hf_rtcp_xr_stats_meanjitter, tvb, offset, 4, FALSE);
1575             offset += 4;
1576
1577             /* Dev Jitter */
1578             proto_tree_add_item(content_tree, hf_rtcp_xr_stats_devjitter, tvb, offset, 4, FALSE);
1579             offset += 4;
1580
1581             /* Min TTL */
1582             proto_tree_add_item(content_tree, hf_rtcp_xr_stats_minttl, tvb, offset, 1, FALSE);
1583             offset ++;
1584
1585             /* Max TTL */
1586             proto_tree_add_item(content_tree, hf_rtcp_xr_stats_maxttl, tvb, offset, 1, FALSE);
1587             offset ++;
1588
1589             /* Mean TTL */
1590             proto_tree_add_item(content_tree, hf_rtcp_xr_stats_meanttl, tvb, offset, 1, FALSE);
1591             offset ++;
1592
1593             /* Dev TTL */
1594             proto_tree_add_item(content_tree, hf_rtcp_xr_stats_devttl, tvb, offset, 1, FALSE);
1595             offset ++;
1596
1597             break;
1598         }
1599
1600         case RTCP_XR_REF_TIME: {
1601             guint32 ts_msw, ts_lsw;
1602
1603             ts_msw = tvb_get_ntohl(tvb, offset);
1604             proto_tree_add_text(content_tree, tvb, offset, 4, "Timestamp, MSW: %u", ts_msw);
1605             offset += 4;
1606             ts_lsw = tvb_get_ntohl(tvb, offset);
1607             proto_tree_add_text(content_tree, tvb, offset, 4, "Timestamp, LSW: %u", ts_lsw);
1608             offset += 4;
1609             
1610             break;
1611         }
1612
1613         case RTCP_XR_DLRR: {
1614             /* Each report block is 12 bytes */
1615             gint sources = content_length / 12;
1616             gint counter = 0;
1617             for(counter = 0; counter < sources; counter++) {
1618                 /* Create a new subtree for a length of 12 bytes */
1619                 proto_tree *ti = proto_tree_add_text(content_tree, tvb, offset, 12, "Source %u", counter + 1);
1620                 proto_tree *ssrc_tree = proto_item_add_subtree(ti, ett_xr_ssrc);
1621                 
1622                 /* SSRC_n source identifier, 32 bits */
1623                 proto_tree_add_item(ssrc_tree, hf_rtcp_ssrc_source, tvb, offset, 4, FALSE);
1624                 offset += 4;
1625                 
1626                 /* Last RR timestamp */
1627                 proto_tree_add_item(ssrc_tree, hf_rtcp_xr_lrr, tvb, offset, 4, FALSE);
1628                 offset += 4;
1629                 
1630                 /* Delay since last RR timestamp */
1631                 proto_tree_add_item(ssrc_tree, hf_rtcp_xr_dlrr, tvb, offset, 4, FALSE);
1632                 offset += 4;
1633             }
1634             
1635             if (content_length % 12 != 0)
1636                 offset += content_length % 12;
1637             break;
1638         }
1639
1640         case RTCP_XR_PKT_RXTIMES: {
1641             /* 8 bytes of fixed header */
1642             gint count = 0, skip = 8;
1643             guint16 begin = 0;
1644
1645             /* Identifier */
1646             proto_tree_add_item(content_tree, hf_rtcp_ssrc_source, tvb, offset, 4, FALSE);
1647             offset += 4;
1648
1649             /* Begin Seq */
1650             begin = tvb_get_ntohs(tvb, offset);
1651             proto_tree_add_uint(content_tree, hf_rtcp_xr_beginseq, tvb, offset, 2, begin);
1652             offset += 2;
1653
1654             /* End Seq */
1655             proto_tree_add_item(content_tree, hf_rtcp_xr_endseq, tvb, offset, 2, FALSE);
1656             offset += 2;
1657
1658             for(count = 0; skip < content_length; skip += 4, count++) { 
1659                 proto_tree_add_text(content_tree, tvb, offset, 4, "Seq: %u, Timestamp: %u", 
1660                                     (begin + count) % 65536, FALSE);
1661                 offset += 4;
1662             }
1663             break;
1664         }
1665
1666         case RTCP_XR_LOSS_RLE:
1667         case RTCP_XR_DUP_RLE: {
1668             /* 8 bytes of fixed header */
1669             gint count = 0, skip = 8;
1670             guint16 begin = 0;
1671             proto_item *chunks_item;
1672             proto_tree *chunks_tree;
1673             
1674             /* Identifier */
1675             proto_tree_add_item(content_tree, hf_rtcp_ssrc_source, tvb, offset, 4, FALSE);
1676             offset += 4;
1677
1678             /* Begin Seq */
1679             begin = tvb_get_ntohs(tvb, offset);
1680             proto_tree_add_uint(content_tree, hf_rtcp_xr_beginseq, tvb, offset, 2, begin);
1681             offset += 2;
1682
1683             /* End Seq */
1684             proto_tree_add_item(content_tree, hf_rtcp_xr_endseq, tvb, offset, 2, FALSE);
1685             offset += 2;
1686
1687             /* report Chunks */
1688             chunks_item = proto_tree_add_text(content_tree, tvb, offset, content_length,"Report Chunks");
1689             chunks_tree = proto_item_add_subtree(chunks_item, ett_xr_loss_chunk);
1690
1691             for(count = 1; skip < content_length; skip += 2, count++) {
1692                 guint value = tvb_get_ntohs(tvb, offset);
1693                 
1694                 if (value == 0) {
1695                     proto_tree_add_text(chunks_tree, tvb, offset, 2,
1696                                         "Chunk: %u -- Null Terminator ",
1697                                         count);
1698                 } else if ( ! ( value & 0x8000 )) {
1699                     const gchar* run_type = (value & 0x4000) ? "1s" : "0s";
1700                     value &= 0x3FFF;
1701                     proto_tree_add_text(chunks_tree, tvb, offset, 2,
1702                                         "Chunk: %u -- Length Run %s, length: %u",
1703                                         count, run_type, value);
1704                 } else {
1705                     char bits[20+1];
1706                     other_decode_bitfield_value(bits, value, 0x00007FFF, 16);
1707                     proto_tree_add_text(chunks_tree, tvb, offset, 2,
1708                                         "Chunk: %u -- Bit Vector, bits: %s",
1709                                         count, bits );
1710                 }
1711                 offset += 2;
1712             }
1713             
1714             break;
1715         }
1716
1717         default:
1718             /* skip over the unknown block */
1719             offset += content_length;
1720             break;
1721         }
1722         packet_len -= content_length;
1723     }
1724     return offset;
1725 }
1726
1727 static int
1728 dissect_rtcp_rr( packet_info *pinfo, tvbuff_t *tvb, int offset, proto_tree *tree,
1729     unsigned int count, unsigned int packet_length )
1730 {
1731         unsigned int counter = 1;
1732         proto_tree *ssrc_tree = (proto_tree*) NULL;
1733         proto_tree *ssrc_sub_tree = (proto_tree*) NULL;
1734         proto_tree *high_sec_tree = (proto_tree*) NULL;
1735         proto_item *ti = (proto_item*) NULL;
1736         guint8 rr_flt;
1737         unsigned int cum_nr = 0;
1738         int rr_offset = offset; 
1739
1740         while ( counter <= count ) {
1741                 guint32 lsr, dlsr;
1742
1743                 /* Create a new subtree for a length of 24 bytes */
1744                 ti = proto_tree_add_text(tree, tvb, offset, 24,
1745                     "Source %u", counter );
1746                 ssrc_tree = proto_item_add_subtree( ti, ett_ssrc );
1747
1748                 /* SSRC_n source identifier, 32 bits */
1749                 proto_tree_add_item( ssrc_tree, hf_rtcp_ssrc_source, tvb, offset, 4, FALSE );
1750                 offset += 4;
1751
1752                 ti = proto_tree_add_text(ssrc_tree, tvb, offset, 20, "SSRC contents" );
1753                 ssrc_sub_tree = proto_item_add_subtree( ti, ett_ssrc_item );
1754
1755                 /* Fraction lost, 8bits */
1756                 rr_flt = tvb_get_guint8( tvb, offset );
1757                 proto_tree_add_uint_format( ssrc_sub_tree, hf_rtcp_ssrc_fraction, tvb,
1758                     offset, 1, rr_flt, "Fraction lost: %u / 256", rr_flt );
1759                 offset++;
1760
1761                 /* Cumulative number of packets lost, 24 bits */
1762                 cum_nr = tvb_get_ntohl( tvb, offset ) >> 8;
1763                 proto_tree_add_uint( ssrc_sub_tree, hf_rtcp_ssrc_cum_nr, tvb,
1764                     offset, 3, cum_nr );
1765                 offset += 3;
1766
1767                 /* Extended highest sequence nr received, 32 bits
1768                  * Just for the sake of it, let's add another subtree
1769                  * because this might be a little clearer
1770                  */
1771                 ti = proto_tree_add_uint( ssrc_tree, hf_rtcp_ssrc_ext_high_seq,
1772                     tvb, offset, 4, tvb_get_ntohl( tvb, offset ) );
1773                 high_sec_tree = proto_item_add_subtree( ti, ett_ssrc_ext_high );
1774                 /* Sequence number cycles */
1775                 proto_tree_add_item( high_sec_tree, hf_rtcp_ssrc_high_cycles,
1776                     tvb, offset, 2, FALSE );
1777                 offset += 2;
1778                 /* highest sequence number received */
1779                 proto_tree_add_item( high_sec_tree, hf_rtcp_ssrc_high_seq,
1780                     tvb, offset, 2, FALSE );
1781                 offset += 2;
1782
1783                 /* Interarrival jitter */
1784                 proto_tree_add_item( ssrc_tree, hf_rtcp_ssrc_jitter, tvb,
1785                     offset, 4, FALSE );
1786                 offset += 4;
1787
1788                 /* Last SR timestamp */
1789                 lsr = tvb_get_ntohl( tvb, offset );
1790                 proto_tree_add_uint( ssrc_tree, hf_rtcp_ssrc_lsr, tvb,
1791                                      offset, 4, lsr );
1792                 offset += 4;
1793
1794                 /* Delay since last SR timestamp */
1795                 dlsr = tvb_get_ntohl( tvb, offset );
1796                 proto_tree_add_uint( ssrc_tree, hf_rtcp_ssrc_dlsr, tvb,
1797                                      offset, 4, dlsr );
1798                 offset += 4;
1799
1800                 /* Do roundtrip calculation */
1801                 if (global_rtcp_show_roundtrip_calculation)
1802                 {
1803                         /* Based on delay since SR was sent in other direction */
1804                         calculate_roundtrip_delay(tvb, pinfo, ssrc_tree, lsr, dlsr);
1805                 }
1806
1807                 counter++;
1808         }
1809
1810         /* If length remaining, assume profile-specific extension bytes */
1811         if ((offset-rr_offset) < (int)packet_length)
1812         {
1813                 proto_tree_add_item(tree, hf_rtcp_profile_specific_extension, tvb, offset,
1814                                     packet_length - (offset - rr_offset), FALSE);
1815                 offset = rr_offset + packet_length;
1816         }
1817
1818         return offset;
1819 }
1820
1821 static int
1822 dissect_rtcp_sr( packet_info *pinfo, tvbuff_t *tvb, int offset, proto_tree *tree,
1823     unsigned int count, unsigned int packet_length )
1824 {
1825         proto_item* item;
1826         guint32 ts_msw, ts_lsw;
1827         gchar *buff;
1828         int sr_offset = offset;
1829
1830         /* NTP timestamp */
1831         ts_msw = tvb_get_ntohl(tvb, offset);
1832         proto_tree_add_item(tree, hf_rtcp_ntp_msw, tvb, offset, 4, FALSE);
1833
1834         ts_lsw = tvb_get_ntohl(tvb, offset+4);
1835         proto_tree_add_item(tree, hf_rtcp_ntp_lsw, tvb, offset+4, 4, FALSE);
1836
1837         buff=ntp_fmt_ts(tvb_get_ptr( tvb, offset, 8 ));
1838         item = proto_tree_add_string_format( tree, hf_rtcp_ntp, tvb, offset, 8, ( const char* ) buff, "MSW and LSW as NTP timestamp: %s", buff );
1839         PROTO_ITEM_SET_GENERATED(item);
1840         offset += 8;
1841
1842         /* RTP timestamp, 32 bits */
1843         proto_tree_add_uint( tree, hf_rtcp_rtp_timestamp, tvb, offset, 4, tvb_get_ntohl( tvb, offset ) );
1844         offset += 4;
1845         /* Sender's packet count, 32 bits */
1846         proto_tree_add_uint( tree, hf_rtcp_sender_pkt_cnt, tvb, offset, 4, tvb_get_ntohl( tvb, offset ) );
1847         offset += 4;
1848         /* Sender's octet count, 32 bits */
1849         proto_tree_add_uint( tree, hf_rtcp_sender_oct_cnt, tvb, offset, 4, tvb_get_ntohl( tvb, offset ) );
1850         offset += 4;
1851
1852         /* Record the time of this packet in the sender's conversation */
1853         if (global_rtcp_show_roundtrip_calculation)
1854         {
1855                 /* Use middle 32 bits of 64-bit time value */
1856                 guint32 lsr = ((ts_msw & 0x0000ffff) << 16 | (ts_lsw & 0xffff0000) >> 16);
1857
1858                 /* Record the time that we sent this in appropriate conversation */
1859                 remember_outgoing_sr(pinfo, lsr);
1860         }
1861
1862         /* The rest of the packet is equal to the RR packet */
1863         if ( count != 0 )
1864                 offset = dissect_rtcp_rr( pinfo, tvb, offset, tree, count, packet_length-(offset-sr_offset) );
1865         else
1866     {
1867                 /* If length remaining, assume profile-specific extension bytes */
1868                 if ((offset-sr_offset) < (int)packet_length)
1869                 {
1870                         proto_tree_add_item(tree, hf_rtcp_profile_specific_extension, tvb, offset,
1871                                             packet_length - (offset - sr_offset), FALSE);
1872                         offset = sr_offset + packet_length;
1873                 }
1874         }
1875
1876         return offset;
1877 }
1878
1879 /* Look for conversation info and display any setup info found */
1880 void show_setup_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1881 {
1882         /* Conversation and current data */
1883         conversation_t *p_conv = NULL;
1884         struct _rtcp_conversation_info *p_conv_data = NULL;
1885
1886         /* Use existing packet data if available */
1887         p_conv_data = p_get_proto_data(pinfo->fd, proto_rtcp);
1888
1889         if (!p_conv_data)
1890         {
1891                 /* First time, get info from conversation */
1892                 p_conv = find_conversation(pinfo->fd->num, &pinfo->net_dst, &pinfo->net_src,
1893                                            pinfo->ptype,
1894                                            pinfo->destport, pinfo->srcport, NO_ADDR_B);
1895
1896                 if (p_conv)
1897                 {
1898                         /* Look for data in conversation */
1899                         struct _rtcp_conversation_info *p_conv_packet_data;
1900                         p_conv_data = conversation_get_proto_data(p_conv, proto_rtcp);
1901
1902                         if (p_conv_data)
1903                         {
1904                                 /* Save this conversation info into packet info */
1905                                 p_conv_packet_data = se_alloc(sizeof(struct _rtcp_conversation_info));
1906                                 if (!p_conv_packet_data)
1907                                 {
1908                                         return;
1909                                 }
1910                                 memcpy(p_conv_packet_data, p_conv_data,
1911                                        sizeof(struct _rtcp_conversation_info));
1912
1913                                 p_add_proto_data(pinfo->fd, proto_rtcp, p_conv_packet_data);
1914                         }
1915                 }
1916         }
1917
1918         /* Create setup info subtree with summary info. */
1919         if (p_conv_data && p_conv_data->setup_method_set)
1920         {
1921                 proto_tree *rtcp_setup_tree;
1922                 proto_item *ti =  proto_tree_add_string_format(tree, hf_rtcp_setup, tvb, 0, 0,
1923                                                                "",
1924                                                                "Stream setup by %s (frame %u)",
1925                                                                p_conv_data->setup_method,
1926                                                                p_conv_data->setup_frame_number);
1927                 PROTO_ITEM_SET_GENERATED(ti);
1928                 rtcp_setup_tree = proto_item_add_subtree(ti, ett_rtcp_setup);
1929                 if (rtcp_setup_tree)
1930                 {
1931                         /* Add details into subtree */
1932                         proto_item* item = proto_tree_add_uint(rtcp_setup_tree, hf_rtcp_setup_frame,
1933                                                                tvb, 0, 0, p_conv_data->setup_frame_number);
1934                         PROTO_ITEM_SET_GENERATED(item);
1935                         item = proto_tree_add_string(rtcp_setup_tree, hf_rtcp_setup_method,
1936                                                      tvb, 0, 0, p_conv_data->setup_method);
1937                         PROTO_ITEM_SET_GENERATED(item);
1938                 }
1939         }
1940 }
1941
1942
1943 /* Update conversation data to record time that outgoing rr/sr was sent */
1944 static void remember_outgoing_sr(packet_info *pinfo, long lsr)
1945 {
1946         conversation_t *p_conv = NULL;
1947         struct _rtcp_conversation_info *p_conv_data = NULL;
1948         struct _rtcp_conversation_info *p_packet_data = NULL;
1949
1950         /* This information will be accessed when an incoming packet comes back to
1951            the side that sent this packet, so no use storing in the packet
1952            info.  However, do store the fact that we've already set this info
1953            before  */
1954
1955
1956         /**************************************************************************/
1957         /* First of all, see if we've already stored this information for this sr */
1958
1959         /* Look first in packet info */
1960         p_packet_data = p_get_proto_data(pinfo->fd, proto_rtcp);
1961         if (p_packet_data && p_packet_data->last_received_set &&
1962             p_packet_data->last_received_frame_number >= pinfo->fd->num)
1963         {
1964                 /* We already did this, OK */
1965                 return;
1966         }
1967
1968
1969         /**************************************************************************/
1970         /* Otherwise, we want to find/create the conversation and update it       */
1971
1972         /* First time, get info from conversation.
1973            Even though we think of this as an outgoing packet being sent,
1974            we store the time as being received by the destination. */
1975         p_conv = find_conversation(pinfo->fd->num, &pinfo->net_dst, &pinfo->net_src,
1976                                    pinfo->ptype,
1977                                    pinfo->destport, pinfo->srcport, NO_ADDR_B);
1978
1979         /* If the conversation doesn't exist, create it now. */
1980         if (!p_conv)
1981         {
1982                 p_conv = conversation_new(pinfo->fd->num, &pinfo->net_dst, &pinfo->net_src, PT_UDP,
1983                                           pinfo->destport, pinfo->srcport,
1984                                           NO_ADDR2);
1985                 if (!p_conv)
1986                 {
1987                         /* Give up if can't create it */
1988                         return;
1989                 }
1990         }
1991
1992
1993         /****************************************************/
1994         /* Now find/create conversation data                */
1995         p_conv_data = conversation_get_proto_data(p_conv, proto_rtcp);
1996         if (!p_conv_data)
1997         {
1998                 /* Allocate memory for data */
1999                 p_conv_data = se_alloc(sizeof(struct _rtcp_conversation_info));
2000                 if (!p_conv_data)
2001                 {
2002                         /* Give up if couldn't allocate space for memory */
2003                         return;
2004                 }
2005                 memset(p_conv_data, 0, sizeof(struct _rtcp_conversation_info));
2006
2007                 /* Add it to conversation. */
2008                 conversation_add_proto_data(p_conv, proto_rtcp, p_conv_data);
2009         }
2010
2011         /*******************************************************/
2012         /* Update conversation data                            */
2013         p_conv_data->last_received_set = TRUE;
2014         p_conv_data->last_received_frame_number = pinfo->fd->num;
2015         p_conv_data->last_received_timestamp = pinfo->fd->abs_ts;
2016         p_conv_data->last_received_ts = lsr;
2017
2018
2019         /****************************************************************/
2020         /* Update packet info to record conversation state              */
2021
2022         /* Will use/create packet info */
2023         if (!p_packet_data)
2024         {
2025                 p_packet_data = se_alloc(sizeof(struct _rtcp_conversation_info));
2026                 if (!p_packet_data)
2027                 {
2028                         /* Give up if allocation fails */
2029                         return;
2030                 }
2031                 memset(p_packet_data, 0, sizeof(struct _rtcp_conversation_info));
2032
2033                 p_add_proto_data(pinfo->fd, proto_rtcp, p_packet_data);
2034         }
2035
2036         /* Copy current conversation data into packet info */
2037         p_packet_data->last_received_set = TRUE;
2038         p_packet_data->last_received_frame_number = p_conv_data->last_received_frame_number;
2039         p_packet_data->last_received_timestamp = p_conv_data->last_received_timestamp;
2040 }
2041
2042
2043 /* Use received sr to work out what the roundtrip delay is
2044    (at least between capture point and the other endpoint involved in
2045     the conversation) */
2046 static void calculate_roundtrip_delay(tvbuff_t *tvb, packet_info *pinfo,
2047                                       proto_tree *tree, guint32 lsr, guint32 dlsr)
2048 {
2049         /*****************************************************/
2050         /* This is called dissecting an SR.  We need to:
2051            - look in the packet info for stored calculation.  If found, use.
2052            - look up the conversation of the sending side to see when the
2053              'last SR' was detected (received)
2054            - calculate the network delay using the that packet time,
2055              this packet time, and dlsr
2056         *****************************************************/
2057
2058         conversation_t *p_conv = NULL;
2059         struct _rtcp_conversation_info *p_conv_data = NULL;
2060         struct _rtcp_conversation_info *p_packet_data = NULL;
2061
2062
2063         /*************************************************/
2064         /* Look for previous result                      */
2065         p_packet_data = p_get_proto_data(pinfo->fd, proto_rtcp);
2066         if (p_packet_data && p_packet_data->lsr_matched)
2067         {
2068                 /* Show info. */
2069                 add_roundtrip_delay_info(tvb, pinfo, tree,
2070                                          p_packet_data->calculated_delay_used_frame,
2071                                          p_packet_data->calculated_delay);
2072                 return;
2073         }
2074
2075
2076         /********************************************************************/
2077         /* Look for captured timestamp of last SR in conversation of sender */
2078         /* of this packet                                                   */
2079         p_conv = find_conversation(pinfo->fd->num, &pinfo->net_src, &pinfo->net_dst,
2080                                    pinfo->ptype,
2081                                    pinfo->srcport, pinfo->destport, NO_ADDR_B);
2082         if (!p_conv)
2083         {
2084                 return;
2085         }
2086
2087         /* Look for conversation data  */
2088         p_conv_data = conversation_get_proto_data(p_conv, proto_rtcp);
2089         if (!p_conv_data)
2090         {
2091                 return;
2092         }
2093
2094         if (p_conv_data->last_received_set)
2095         {
2096                 /* Store result of calculation in packet info */
2097                 if (!p_packet_data)
2098                 {
2099                         /* Create packet info if it doesn't exist */
2100                         p_packet_data = se_alloc(sizeof(struct _rtcp_conversation_info));
2101                         if (!p_packet_data)
2102                         {
2103                                 /* Give up if allocation fails */
2104                                 return;
2105                         }
2106
2107                         memset(p_packet_data, 0, sizeof(struct _rtcp_conversation_info));
2108
2109                         /* Set as packet info */
2110                         p_add_proto_data(pinfo->fd, proto_rtcp, p_packet_data);
2111                 }
2112
2113                 /* Don't allow match seemingly calculated from same frame! */
2114                 if (pinfo->fd->num == p_conv_data->last_received_frame_number)
2115                 {
2116                         return;
2117                 }
2118         
2119                 /* Any previous report must match the lsr given here */
2120                 if (p_conv_data->last_received_ts == lsr)
2121                 {
2122                         /* Look at time of since original packet was sent */
2123                         gint seconds_between_packets =
2124                               pinfo->fd->abs_ts.secs - p_conv_data->last_received_timestamp.secs;
2125                         gint nseconds_between_packets =
2126                               pinfo->fd->abs_ts.nsecs - p_conv_data->last_received_timestamp.nsecs;
2127
2128                         gint total_gap = (seconds_between_packets*1000) +
2129                                          (nseconds_between_packets / 1000000);
2130                         gint dlsr_ms = (int)(((double)dlsr/(double)65536) * 1000.0);
2131                         gint delay;
2132
2133                         if (dlsr_ms > total_gap)
2134                         {
2135                                 delay = 0;
2136                         }
2137                         else
2138                         {
2139                                 /* Delay is gap - dlsr */
2140                                 delay = total_gap - dlsr_ms;
2141                         }
2142
2143                         /* Record that the LSR matches */
2144                         p_packet_data->lsr_matched = TRUE;
2145
2146                         /* No useful calculation can be done if dlsr not set... */
2147                         if (dlsr)
2148                         {
2149                                 p_packet_data->calculated_delay = delay;
2150                                 p_packet_data->calculated_delay_used_frame = p_conv_data->last_received_frame_number;
2151                         }
2152
2153                         /* Show info. */
2154                         add_roundtrip_delay_info(tvb, pinfo, tree, p_conv_data->last_received_frame_number, delay);
2155                 }
2156         }
2157 }
2158
2159 /* Show the calcaulted roundtrip delay info by adding protocol tree items
2160    and appending text to the info column */
2161 static void add_roundtrip_delay_info(tvbuff_t *tvb, packet_info *pinfo,
2162                                      proto_tree *tree, guint frame, guint delay)
2163 {
2164         /* 'Last SR' frame used in calculation.  Show this even if no delay shown */
2165         proto_item* item = proto_tree_add_uint(tree,
2166                                                hf_rtcp_last_sr_timestamp_frame,
2167                                                tvb, 0, 0, frame);
2168         PROTO_ITEM_SET_GENERATED(item);
2169
2170         /* Don't report on calculated delays below the threshold.
2171            Won't report a delay of 0 (which also indicates no valid
2172            calculated value to report) */
2173         if (delay < global_rtcp_show_roundtrip_calculation_minimum)
2174         {
2175                 return;
2176         }
2177
2178         /* Calculated delay in ms */
2179         item = proto_tree_add_uint(tree, hf_rtcp_roundtrip_delay, tvb, 0, 0, delay);
2180         PROTO_ITEM_SET_GENERATED(item);
2181
2182         /* Add to expert info */
2183         expert_add_info_format(pinfo, item,
2184                                PI_SEQUENCE, PI_NOTE,
2185                                "RTCP round-trip delay detected (%u ms)",
2186                                delay);
2187
2188         /* Report delay in INFO column */
2189         if (check_col(pinfo->cinfo, COL_INFO))
2190         {
2191                 if (delay > 0)
2192                 {
2193                         col_append_fstr(pinfo->cinfo, COL_INFO,
2194                                         " (roundtrip delay <-> %s = %ums, using frame %u)",
2195                                         address_to_str(&pinfo->net_src), delay, frame);
2196                 }
2197         }
2198 }
2199
2200
2201
2202 static void
2203 dissect_rtcp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree )
2204 {
2205         proto_item *ti           = NULL;
2206         proto_tree *rtcp_tree    = NULL;
2207         unsigned int temp_byte   = 0;
2208         unsigned int padding_set = 0;
2209         unsigned int elem_count  = 0;
2210         unsigned int packet_type = 0;
2211         unsigned int offset      = 0;
2212         guint16 packet_length    = 0;
2213         guint16 total_packet_length = 0;
2214         guint rtcp_subtype               = 0;
2215         guint32 app_length               = 0;
2216
2217         if ( check_col( pinfo->cinfo, COL_PROTOCOL ) )   {
2218                 col_set_str( pinfo->cinfo, COL_PROTOCOL, "RTCP" );
2219         }
2220
2221         if ( check_col( pinfo->cinfo, COL_INFO) ) {
2222                 /* The second octet contains the packet type */
2223                 /* switch ( pd[ offset + 1 ] ) { */
2224                 switch ( tvb_get_guint8( tvb, 1 ) ) {
2225                         case RTCP_SR:
2226                                 col_set_str( pinfo->cinfo, COL_INFO, "Sender Report");
2227                                 break;
2228                         case RTCP_RR:
2229                                 col_set_str( pinfo->cinfo, COL_INFO, "Receiver Report");
2230                                 break;
2231                         case RTCP_SDES:
2232                                 col_set_str( pinfo->cinfo, COL_INFO, "Source Description");
2233                                 break;
2234                         case RTCP_BYE:
2235                                 col_set_str( pinfo->cinfo, COL_INFO, "Goodbye");
2236                                 break;
2237                         case RTCP_APP:
2238                                 col_set_str( pinfo->cinfo, COL_INFO, "Application");
2239                                 break;
2240                         case RTCP_XR:
2241                                 col_set_str( pinfo->cinfo, COL_INFO, "Extended report");
2242                                 break;
2243                         case RTCP_FIR:
2244                                 col_set_str( pinfo->cinfo, COL_INFO, "Full Intra-frame Request (H.261)");
2245                                 break;
2246                         case RTCP_NACK:
2247                                 col_set_str( pinfo->cinfo, COL_INFO, "Negative Acknowledgement (H.261)");
2248                                 break;
2249                         default:
2250                                 col_set_str( pinfo->cinfo, COL_INFO, "Unknown packet type");
2251                                 break;
2252                 }
2253         }
2254
2255     /*
2256      * Check if there are at least 4 bytes left in the frame,
2257      * the last 16 bits of those is the length of the current
2258      * RTCP message. The last compound message contains padding,
2259      * that enables us to break from the while loop.
2260      */
2261     while ( tvb_bytes_exist( tvb, offset, 4) ) {
2262         /*
2263          * First retreive the packet_type
2264          */
2265         packet_type = tvb_get_guint8( tvb, offset + 1 );
2266
2267         /*
2268          * Check if it's a valid type
2269          */
2270         if ( ( packet_type < 192 ) || ( packet_type >  207 ) )
2271             break;
2272
2273         /*
2274          * get the packet-length for the complete RTCP packet
2275          */
2276                 packet_length = ( tvb_get_ntohs( tvb, offset + 2 ) + 1 ) * 4;
2277                 total_packet_length += packet_length;
2278
2279                 ti = proto_tree_add_item(tree, proto_rtcp, tvb, offset, packet_length, FALSE );
2280                 proto_item_append_text(ti, " (%s)",
2281                                        val_to_str(packet_type,
2282                                                   rtcp_packet_type_vals,
2283                                                   "Unknown"));
2284
2285                 rtcp_tree = proto_item_add_subtree( ti, ett_rtcp );
2286
2287                 /* Conversation setup info */
2288                 if (global_rtcp_show_setup_info)
2289                 {
2290                         show_setup_info(tvb, pinfo, rtcp_tree);
2291                 }
2292
2293
2294         temp_byte = tvb_get_guint8( tvb, offset );
2295
2296                 proto_tree_add_uint( rtcp_tree, hf_rtcp_version, tvb,
2297                                                          offset, 1, temp_byte);
2298         padding_set = RTCP_PADDING( temp_byte );
2299
2300                 proto_tree_add_boolean( rtcp_tree, hf_rtcp_padding, tvb,
2301                                                                 offset, 1, temp_byte );
2302         elem_count = RTCP_COUNT( temp_byte );
2303
2304         switch ( packet_type ) {
2305             case RTCP_SR:
2306             case RTCP_RR:
2307                 /* Receiver report count, 5 bits */
2308                 proto_tree_add_uint( rtcp_tree, hf_rtcp_rc, tvb, offset, 1, temp_byte );
2309                 offset++;
2310                 /* Packet type, 8 bits */
2311                 proto_tree_add_item( rtcp_tree, hf_rtcp_pt, tvb, offset, 1, FALSE );
2312                 offset++;
2313                 /* Packet length in 32 bit words MINUS one, 16 bits */
2314                 proto_tree_add_uint( rtcp_tree, hf_rtcp_length, tvb, offset, 2, tvb_get_ntohs( tvb, offset ) );
2315                 offset += 2;
2316                 /* Sender Synchronization source, 32 bits */
2317                 proto_tree_add_uint( rtcp_tree, hf_rtcp_ssrc_sender, tvb, offset, 4, tvb_get_ntohl( tvb, offset ) );
2318                 offset += 4;
2319
2320                 if ( packet_type == RTCP_SR )
2321                     offset = dissect_rtcp_sr( pinfo, tvb, offset, rtcp_tree, elem_count, packet_length-8 );
2322                 else
2323                     offset = dissect_rtcp_rr( pinfo, tvb, offset, rtcp_tree, elem_count, packet_length-8 );
2324                 break;
2325             case RTCP_SDES:
2326                 /* Source count, 5 bits */
2327                 proto_tree_add_uint( rtcp_tree, hf_rtcp_sc, tvb, offset, 1, temp_byte );
2328                 offset++;
2329                 /* Packet type, 8 bits */
2330                 proto_tree_add_item( rtcp_tree, hf_rtcp_pt, tvb, offset, 1, FALSE );
2331                 offset++;
2332                 /* Packet length in 32 bit words MINUS one, 16 bits */
2333                 proto_tree_add_uint( rtcp_tree, hf_rtcp_length, tvb, offset, 2, tvb_get_ntohs( tvb, offset ) );
2334                 offset += 2;
2335                 dissect_rtcp_sdes( tvb, offset, rtcp_tree, elem_count );
2336                 offset += packet_length - 4;
2337                 break;
2338             case RTCP_BYE:
2339                 /* Source count, 5 bits */
2340                 proto_tree_add_uint( rtcp_tree, hf_rtcp_sc, tvb, offset, 1, temp_byte );
2341                 offset++;
2342                 /* Packet type, 8 bits */
2343                 proto_tree_add_item( rtcp_tree, hf_rtcp_pt, tvb, offset, 1, FALSE );
2344                 offset++;
2345                 /* Packet length in 32 bit words MINUS one, 16 bits */
2346                 proto_tree_add_uint( rtcp_tree, hf_rtcp_length, tvb, offset, 2, tvb_get_ntohs( tvb, offset ) );
2347                 offset += 2;
2348                 offset = dissect_rtcp_bye( tvb, offset, rtcp_tree, elem_count );
2349                 break;
2350             case RTCP_APP:
2351                 /* Subtype, 5 bits */
2352                 rtcp_subtype = elem_count;
2353                 proto_tree_add_uint( rtcp_tree, hf_rtcp_subtype, tvb, offset, 1, elem_count );
2354                 offset++;
2355                 /* Packet type, 8 bits */
2356                 proto_tree_add_item( rtcp_tree, hf_rtcp_pt, tvb, offset, 1, FALSE );
2357                 offset++;
2358                 /* Packet length in 32 bit words MINUS one, 16 bits */
2359                 app_length = tvb_get_ntohs( tvb, offset ) <<2;
2360                 proto_tree_add_uint( rtcp_tree, hf_rtcp_length, tvb, offset, 2, tvb_get_ntohs( tvb, offset ) );
2361                 offset += 2;
2362                 offset = dissect_rtcp_app( tvb, pinfo, offset,rtcp_tree, padding_set, packet_length - 4, rtcp_subtype, app_length);
2363                 break;
2364             case RTCP_XR:
2365                 /* Reserved, 5 bits, Ignore */
2366                 offset++;
2367                 /* Packet type, 8 bits */
2368                 proto_tree_add_item( rtcp_tree, hf_rtcp_pt, tvb, offset, 1, FALSE );
2369                 offset++;
2370                 /* Packet length in 32 bit words MINUS one, 16 bits */
2371                 proto_tree_add_uint( rtcp_tree, hf_rtcp_length, tvb, offset, 2, tvb_get_ntohs( tvb, offset ) );
2372                 offset += 2;
2373                 offset = dissect_rtcp_xr( tvb, pinfo, offset, rtcp_tree, packet_length - 4 );
2374                 break;
2375             case RTCP_FIR:
2376                 offset = dissect_rtcp_fir( tvb, offset, rtcp_tree );
2377                 break;
2378             case RTCP_NACK:
2379                 offset = dissect_rtcp_nack( tvb, offset, rtcp_tree );
2380                 break;
2381             default:
2382                 /*
2383                  * To prevent endless loops in case of an unknown message type
2384                  * increase offset. Some time the while will end :-)
2385                  */
2386                 offset++;
2387                 break;
2388         }
2389     }
2390     /* If the padding bit is set, the last octet of the
2391      * packet contains the length of the padding
2392      * We only have to check for this at the end of the LAST RTCP message
2393      */
2394     if ( padding_set ) {
2395         /* If everything went according to plan offset should now point to the
2396          * first octet of the padding
2397          */
2398         proto_tree_add_item( rtcp_tree, hf_rtcp_padding_data, tvb, offset, tvb_length_remaining( tvb, offset) - 1, FALSE );
2399         offset += tvb_length_remaining( tvb, offset) - 1;
2400         proto_tree_add_item( rtcp_tree, hf_rtcp_padding_count, tvb, offset, 1, FALSE );
2401     }
2402
2403     /* offset should be total_packet_length by now... */
2404     if (offset == (int)total_packet_length)
2405     {
2406         ti = proto_tree_add_boolean_format_value(tree, hf_rtcp_length_check, tvb,
2407                                             0, 0, TRUE, "OK - %u bytes",
2408                                             offset);
2409         /* Hidden might be less annoying here...? */
2410         PROTO_ITEM_SET_GENERATED(ti);
2411     }
2412     else
2413     {
2414         ti = proto_tree_add_boolean_format_value(tree, hf_rtcp_length_check, tvb,
2415                                             0, 0, FALSE,
2416                                             "Wrong (expected %u bytes, found %d)",
2417                                             total_packet_length, offset);
2418         PROTO_ITEM_SET_GENERATED(ti);
2419
2420         expert_add_info_format(pinfo, ti,
2421                                PI_MALFORMED, PI_WARN,
2422                                "Incorrect RTCP packet length information (expected %u bytes, found %d)",
2423                                total_packet_length, offset);
2424     }
2425 }
2426
2427 void
2428 proto_register_rtcp(void)
2429 {
2430         static hf_register_info hf[] =
2431         {
2432                 {
2433                         &hf_rtcp_version,
2434                         {
2435                                 "Version",
2436                                 "rtcp.version",
2437                                 FT_UINT8,
2438                                 BASE_DEC,
2439                                 VALS(rtcp_version_vals),
2440                                 0xC0,
2441                                 "", HFILL
2442                         }
2443                 },
2444                 {
2445                         &hf_rtcp_padding,
2446                         {
2447                                 "Padding",
2448                                 "rtcp.padding",
2449                                 FT_BOOLEAN,
2450                                 8,
2451                                 NULL,
2452                                 0x20,
2453                                 "", HFILL
2454                         }
2455                 },
2456                 {
2457                         &hf_rtcp_rc,
2458                         {
2459                                 "Reception report count",
2460                                 "rtcp.rc",
2461                                 FT_UINT8,
2462                                 BASE_DEC,
2463                                 NULL,
2464                                 0x1F,
2465                                 "", HFILL
2466                         }
2467                 },
2468                 {
2469                         &hf_rtcp_sc,
2470                         {
2471                                 "Source count",
2472                                 "rtcp.sc",
2473                                 FT_UINT8,
2474                                 BASE_DEC,
2475                                 NULL,
2476                                 0x1F,
2477                                 "", HFILL
2478                         }
2479                 },
2480                 {
2481                         &hf_rtcp_pt,
2482                         {
2483                                 "Packet type",
2484                                 "rtcp.pt",
2485                                 FT_UINT8,
2486                                 BASE_DEC,
2487                                 VALS( rtcp_packet_type_vals ),
2488                                 0x0,
2489                                 "", HFILL
2490                         }
2491                 },
2492                 {
2493                         &hf_rtcp_length,
2494                         {
2495                                 "Length",
2496                                 "rtcp.length",
2497                                 FT_UINT16,
2498                                 BASE_DEC,
2499                                 NULL,
2500                                 0x0,
2501                                 "32-bit words (-1) in packet", HFILL
2502                         }
2503                 },
2504                 {
2505                         &hf_rtcp_ssrc_sender,
2506                         {
2507                                 "Sender SSRC",
2508                                 "rtcp.senderssrc",
2509                                 FT_UINT32,
2510                                 BASE_DEC,
2511                                 NULL,
2512                                 0x0,
2513                                 "", HFILL
2514                         }
2515                 },
2516                 {
2517                         &hf_rtcp_ntp_msw,
2518                         {
2519                                 "Timestamp, MSW",
2520                                 "rtcp.timestamp.ntp.msw",
2521                                 FT_UINT32,
2522                                 BASE_DEC_HEX,
2523                                 NULL,
2524                                 0x0,
2525                                 "", HFILL
2526                         }
2527                 },
2528                 {
2529                         &hf_rtcp_ntp_lsw,
2530                         {
2531                                 "Timestamp, LSW",
2532                                 "rtcp.timestamp.ntp.lsw",
2533                                 FT_UINT32,
2534                                 BASE_DEC_HEX,
2535                                 NULL,
2536                                 0x0,
2537                                 "", HFILL
2538                         }
2539                 },
2540                 {
2541                         &hf_rtcp_ntp,
2542                         {
2543                                 "NTP timestamp",
2544                                 "rtcp.timestamp.ntp",
2545                                 FT_STRING,
2546                                 BASE_NONE,
2547                                 NULL,
2548                                 0x0,
2549                                 "", HFILL
2550                         }
2551                 },
2552                 {
2553                         &hf_rtcp_rtp_timestamp,
2554                         {
2555                                 "RTP timestamp",
2556                                 "rtcp.timestamp.rtp",
2557                                 FT_UINT32,
2558                                 BASE_DEC,
2559                                 NULL,
2560                                 0x0,
2561                                 "", HFILL
2562                         }
2563                 },
2564                 {
2565                         &hf_rtcp_sender_pkt_cnt,
2566                         {
2567                                 "Sender's packet count",
2568                                 "rtcp.sender.packetcount",
2569                                 FT_UINT32,
2570                                 BASE_DEC,
2571                                 NULL,
2572                                 0x0,
2573                                 "", HFILL
2574                         }
2575                 },
2576                 {
2577                         &hf_rtcp_sender_oct_cnt,
2578                         {
2579                                 "Sender's octet count",
2580                                 "rtcp.sender.octetcount",
2581                                 FT_UINT32,
2582                                 BASE_DEC,
2583                                 NULL,
2584                                 0x0,
2585                                 "", HFILL
2586                         }
2587                 },
2588                 {
2589                         &hf_rtcp_ssrc_source,
2590                         {
2591                                 "Identifier",
2592                                 "rtcp.ssrc.identifier",
2593                                 FT_UINT32,
2594                                 BASE_DEC,
2595                                 NULL,
2596                                 0x0,
2597                                 "", HFILL
2598                         }
2599                 },
2600                 {
2601                         &hf_rtcp_ssrc_fraction,
2602                         {
2603                                 "Fraction lost",
2604                                 "rtcp.ssrc.fraction",
2605                                 FT_UINT8,
2606                                 BASE_DEC,
2607                                 NULL,
2608                                 0x0,
2609                                 "", HFILL
2610                         }
2611                 },
2612                 {
2613                         &hf_rtcp_ssrc_cum_nr,
2614                         {
2615                                 "Cumulative number of packets lost",
2616                                 "rtcp.ssrc.cum_nr",
2617                                 FT_UINT32,
2618                                 BASE_DEC,
2619                                 NULL,
2620                                 0x0,
2621                                 "", HFILL
2622                         }
2623                 },
2624                 {
2625                         &hf_rtcp_ssrc_ext_high_seq,
2626                         {
2627                                 "Extended highest sequence number received",
2628                                 "rtcp.ssrc.ext_high",
2629                                 FT_UINT32,
2630                                 BASE_DEC,
2631                                 NULL,
2632                                 0x0,
2633                                 "", HFILL
2634                         }
2635                 },
2636                 {
2637                         &hf_rtcp_ssrc_high_seq,
2638                         {
2639                                 "Highest sequence number received",
2640                                 "rtcp.ssrc.high_seq",
2641                                 FT_UINT16,
2642                                 BASE_DEC,
2643                                 NULL,
2644                                 0x0,
2645                                 "", HFILL
2646                         }
2647                 },
2648                 {
2649                         &hf_rtcp_ssrc_high_cycles,
2650                         {
2651                                 "Sequence number cycles count",
2652                                 "rtcp.ssrc.high_cycles",
2653                                 FT_UINT16,
2654                                 BASE_DEC,
2655                                 NULL,
2656                                 0x0,
2657                                 "", HFILL
2658                         }
2659                 },
2660                 {
2661                         &hf_rtcp_ssrc_jitter,
2662                         {
2663                                 "Interarrival jitter",
2664                                 "rtcp.ssrc.jitter",
2665                                 FT_UINT32,
2666                                 BASE_DEC,
2667                                 NULL,
2668                                 0x0,
2669                                 "", HFILL
2670                         }
2671                 },
2672                 {
2673                         &hf_rtcp_ssrc_lsr,
2674                         {
2675                                 "Last SR timestamp",
2676                                 "rtcp.ssrc.lsr",
2677                                 FT_UINT32,
2678                                 BASE_DEC_HEX,
2679                                 NULL,
2680                                 0x0,
2681                                 "", HFILL
2682                         }
2683                 },
2684                 {
2685                         &hf_rtcp_ssrc_dlsr,
2686                         {
2687                                 "Delay since last SR timestamp",
2688                                 "rtcp.ssrc.dlsr",
2689                                 FT_UINT32,
2690                                 BASE_DEC,
2691                                 NULL,
2692                                 0x0,
2693                                 "", HFILL
2694                         }
2695                 },
2696                 {
2697                         &hf_rtcp_ssrc_csrc,
2698                         {
2699                                 "SSRC / CSRC identifier",
2700                                 "rtcp.sdes.ssrc_csrc",
2701                                 FT_UINT32,
2702                                 BASE_DEC,
2703                                 NULL,
2704                                 0x0,
2705                                 "", HFILL
2706                         }
2707                 },
2708                 {
2709                         &hf_rtcp_sdes_type,
2710                         {
2711                                 "Type",
2712                                 "rtcp.sdes.type",
2713                                 FT_UINT8,
2714                                 BASE_DEC,
2715                                 VALS( rtcp_sdes_type_vals ),
2716                                 0x0,
2717                                 "", HFILL
2718                         }
2719                 },
2720                 {
2721                         &hf_rtcp_sdes_length,
2722                         {
2723                                 "Length",
2724                                 "rtcp.sdes.length",
2725                                 FT_UINT32,
2726                                 BASE_DEC,
2727                                 NULL,
2728                                 0x0,
2729                                 "", HFILL
2730                         }
2731                 },
2732                 {
2733                         &hf_rtcp_sdes_text,
2734                         {
2735                                 "Text",
2736                                 "rtcp.sdes.text",
2737                                 FT_STRING,
2738                                 BASE_NONE,
2739                                 NULL,
2740                                 0x0,
2741                                 "", HFILL
2742                         }
2743                 },
2744                 {
2745                         &hf_rtcp_sdes_prefix_len,
2746                         {
2747                                 "Prefix length",
2748                                 "rtcp.sdes.prefix.length",
2749                                 FT_UINT8,
2750                                 BASE_DEC,
2751                                 NULL,
2752                                 0x0,
2753                                 "", HFILL
2754                         }
2755                 },
2756                 {
2757                         &hf_rtcp_sdes_prefix_string,
2758                         {
2759                                 "Prefix string",
2760                                 "rtcp.sdes.prefix.string",
2761                                 FT_STRING,
2762                                 BASE_NONE,
2763                                 NULL,
2764                                 0x0,
2765                                 "", HFILL
2766                         }
2767                 },
2768                 {
2769                         &hf_rtcp_subtype,
2770                         {
2771                                 "Subtype",
2772                                 "rtcp.app.subtype",
2773                                 FT_UINT8,
2774                                 BASE_DEC,
2775                                 NULL,
2776                                 0x0,
2777                                 "", HFILL
2778                         }
2779                 },
2780                 {
2781                         &hf_rtcp_name_ascii,
2782                         {
2783                                 "Name (ASCII)",
2784                                 "rtcp.app.name",
2785                                 FT_STRING,
2786                                 BASE_NONE,
2787                                 NULL,
2788                                 0x0,
2789                                 "", HFILL
2790                         }
2791                 },
2792                 {
2793                         &hf_rtcp_app_data,
2794                         {
2795                                 "Application specific data",
2796                                 "rtcp.app.data",
2797                                 FT_BYTES,
2798                                 BASE_NONE,
2799                                 NULL,
2800                                 0x0,
2801                                 "", HFILL
2802                         }
2803                 },
2804                 {
2805                         &hf_rtcp_app_poc1,
2806                         {
2807                                 "PoC1 Application specific data",
2808                                 "rtcp.app.poc1",
2809                                 FT_NONE,
2810                                 BASE_NONE,
2811                                 NULL,
2812                                 0x0,
2813                                 "", HFILL
2814                         }
2815                 },
2816                 {
2817                         &hf_rtcp_app_poc1_subtype,
2818                         {
2819                                 "Subtype",
2820                                 "rtcp.app.PoC1.subtype",
2821                                 FT_UINT8,
2822                                 BASE_DEC,
2823                                 VALS(rtcp_app_poc1_floor_cnt_type_vals),
2824                                 0x0,
2825                                 "", HFILL
2826                         }
2827                 },
2828                 {
2829                         &hf_rtcp_app_poc1_sip_uri,
2830                         {
2831                                 "SIP URI",
2832                                 "rtcp.app.poc1.sip.uri",
2833                                 FT_STRING,
2834                                 BASE_NONE,
2835                                 NULL,
2836                                 0x0,
2837                                 "", HFILL
2838                         }
2839                 },
2840                 {
2841                         &hf_rtcp_app_poc1_disp_name,
2842                         {
2843                                 "Display Name",
2844                                 "rtcp.app.poc1.disp.name",
2845                                 FT_STRING,
2846                                 BASE_NONE,
2847                                 NULL,
2848                                 0x0,
2849                                 "", HFILL
2850                         }
2851                 },
2852                 {
2853                         &hf_rtcp_app_poc1_priority,
2854                         {
2855                                 "Priority",
2856                                 "rtcp.app.poc1.priority",
2857                                 FT_UINT8,
2858                                 BASE_DEC,
2859                                 VALS(rtcp_app_poc1_qsresp_priority_vals),
2860                                 0x0,
2861                                 "", HFILL
2862                         }
2863                 },
2864                 {
2865                         &hf_rtcp_app_poc1_request_ts,
2866                         {
2867                                 "Talk Burst Requst Timestamp",
2868                                 "rtcp.app.poc1.request.ts",
2869                                 FT_STRING,
2870                                 BASE_NONE,
2871                                 NULL,
2872                                 0x0,
2873                                 "", HFILL
2874                         }
2875                 },
2876                 {
2877                         &hf_rtcp_app_poc1_stt,
2878                         {
2879                                 "Stop talking timer",
2880                                 "rtcp.app.poc1.stt",
2881                                 FT_UINT16,
2882                                 BASE_DEC,
2883                                 NULL,
2884                                 0x0,
2885                                 "", HFILL
2886                         }
2887                 },
2888                 {
2889                         &hf_rtcp_app_poc1_partic,
2890                         {
2891                                 "Number of participants",
2892                                 "rtcp.app.poc1.participants",
2893                                 FT_UINT16,
2894                                 BASE_DEC,
2895                                 NULL,
2896                                 0x0,
2897                                 "", HFILL
2898                         }
2899                 },
2900                 {
2901                         &hf_rtcp_app_poc1_ssrc_granted,
2902                         {
2903                                 "SSRC of client granted permission to talk",
2904                                 "rtcp.app.poc1.ssrc.granted",
2905                                 FT_UINT32,
2906                                 BASE_DEC,
2907                                 NULL,
2908                                 0x0,
2909                                 "", HFILL
2910                         }
2911                 },
2912                 {
2913                         &hf_rtcp_app_poc1_last_pkt_seq_no,
2914                         {
2915                                 "Sequence number of last RTP packet",
2916                                 "rtcp.app.poc1.last.pkt.seq.no",
2917                                 FT_UINT16,
2918                                 BASE_DEC,
2919                                 NULL,
2920                                 0x0,
2921                                 "", HFILL
2922                         }
2923                 },
2924                 {
2925                         &hf_rtcp_app_poc1_ignore_seq_no,
2926                         {
2927                                 "Ignore sequence number field",
2928                                 "rtcp.app.poc1.ignore.seq.no",
2929                                 FT_UINT16,
2930                                 BASE_HEX,
2931                                 NULL,
2932                                 0x8000,
2933                                 "", HFILL
2934                         }
2935                 },
2936                 {
2937                         &hf_rtcp_app_poc1_reason_code1,
2938                         {
2939                                 "Reason code",
2940                                 "rtcp.app.poc1.reason.code",
2941                                 FT_UINT8,
2942                                 BASE_DEC,
2943                                 VALS(rtcp_app_poc1_reason_code1_vals),
2944                                 0x0,
2945                                 "", HFILL
2946                         }
2947                 },
2948                 {
2949                         &hf_rtcp_app_poc1_reason1_phrase,
2950                         {
2951                                 "Reason Phrase",
2952                                 "rtcp.app.poc1.reason.phrase",
2953                                 FT_UINT_STRING,
2954                                 BASE_NONE,
2955                                 NULL,
2956                                 0x0,
2957                                 "", HFILL
2958                         }
2959                 },
2960                 {
2961                         &hf_rtcp_app_poc1_reason_code2,
2962                         {
2963                                 "Reason code",
2964                                 "rtcp.app.poc1.reason.code",
2965                                 FT_UINT16,
2966                                 BASE_DEC,
2967                                 VALS(rtcp_app_poc1_reason_code2_vals),
2968                                 0x0,
2969                                 "", HFILL
2970                         }
2971                 },
2972                 {
2973                         &hf_rtcp_app_poc1_new_time_request,
2974                         {
2975                                 "New time client can request (seconds)",
2976                                 "rtcp.app.poc1.new.time.request",
2977                                 FT_UINT16,
2978                                 BASE_DEC,
2979                                 NULL,
2980                                 0x0,
2981                                 "Time in seconds client can request for", HFILL
2982                         }
2983                 },
2984                 {
2985                         &hf_rtcp_app_poc1_ack_subtype,
2986                         {
2987                                 "Subtype",
2988                                 "rtcp.app.poc1.ack.subtype",
2989                                 FT_UINT8,
2990                                 BASE_DEC,
2991                                 VALS(rtcp_app_poc1_floor_cnt_type_vals),
2992                                 0xf8,
2993                                 "", HFILL
2994                         }
2995                 },
2996                 {
2997                         &hf_rtcp_app_poc1_ack_reason_code,
2998                         {
2999                                 "Reason code",
3000                                 "rtcp.app.poc1.ack.reason.code",
3001                                 FT_UINT16,
3002                                 BASE_DEC,
3003                                 VALS(rtcp_app_poc1_reason_code_ack_vals),
3004                                 0x07ff,
3005                                 "", HFILL
3006                         }
3007                 },
3008                 {
3009                         &hf_rtcp_app_poc1_qsresp_priority,
3010                         {
3011                                 "Priority",
3012                                 "rtcp.app.poc1.qsresp.priority",
3013                                 FT_UINT8,
3014                                 BASE_DEC,
3015                                 VALS(rtcp_app_poc1_qsresp_priority_vals),
3016                                 0x0,
3017                                 "", HFILL
3018                         }
3019                 },
3020                 {
3021                         &hf_rtcp_app_poc1_qsresp_position,
3022                         {
3023                                 "Position (number of clients ahead)",
3024                                 "rtcp.app.poc1.qsresp.position",
3025                                 FT_UINT16,
3026                                 BASE_DEC,
3027                                 NULL,
3028                                 0x0,
3029                                 "", HFILL
3030                         }
3031                 },
3032                 {
3033                         &hf_rtcp_app_poc1_conn_content[0],
3034                         {
3035                                 "Identity of inviting client",
3036                                 "rtcp.app.poc1.conn.content.a.id",
3037                                 FT_BOOLEAN,
3038                                 16,
3039                                 NULL,
3040                                 0x8000,
3041                                 "", HFILL
3042                         }
3043                 },
3044                 {
3045                         &hf_rtcp_app_poc1_conn_content[1],
3046                         {
3047                                 "Nick name of inviting client",
3048                                 "rtcp.app.poc1.conn.content.a.dn",
3049                                 FT_BOOLEAN,
3050                                 16,
3051                                 NULL,
3052                                 0x4000,
3053                                 "", HFILL
3054                         }
3055                 },
3056                 {
3057                         &hf_rtcp_app_poc1_conn_content[2],
3058                         {
3059                                 "Session identity",
3060                                 "rtcp.app.poc1.conn.content.sess.id",
3061                                 FT_BOOLEAN,
3062                                 16,
3063                                 NULL,
3064                                 0x2000,
3065                                 "", HFILL
3066                         }
3067                 },
3068                 {
3069                         &hf_rtcp_app_poc1_conn_content[3],
3070                         {
3071                                 "Group name",
3072                                 "rtcp.app.poc1.conn.content.grp.dn",
3073                                 FT_BOOLEAN,
3074                                 16,
3075                                 NULL,
3076                                 0x1000,
3077                                 "", HFILL
3078                         }
3079                 },
3080                 {
3081                         &hf_rtcp_app_poc1_conn_content[4],
3082                         {
3083                                 "Group identity",
3084                                 "rtcp.app.poc1.conn.content.grp.id",
3085                                 FT_BOOLEAN,
3086                                 16,
3087                                 NULL,
3088                                 0x0800,
3089                                 "", HFILL
3090                         }
3091                 },
3092                 {
3093                         &hf_rtcp_app_poc1_conn_session_type,
3094                         {
3095                                 "Session type",
3096                                 "rtcp.app.poc1.conn.session.type",
3097                                 FT_UINT8,
3098                                 BASE_DEC,
3099                                 VALS(rtcp_app_poc1_conn_sess_type_vals),
3100                                 0x0,
3101                                 "", HFILL
3102                         }
3103                 },
3104                 {
3105                         &hf_rtcp_app_poc1_conn_add_ind_mao,
3106                         {
3107                                 "Manual answer override",
3108                                 "rtcp.app.poc1.conn.add.ind.mao",
3109                                 FT_BOOLEAN,
3110                                 8,
3111                                 NULL,
3112                                 0x80,
3113                                 "", HFILL
3114                         }
3115                 },
3116                 {
3117                         &hf_rtcp_app_poc1_conn_sdes_items[0],
3118                         {
3119                                 "Identity of inviting client",
3120                                 "rtcp.app.poc1.conn.sdes.a.id",
3121                                 FT_UINT_STRING,
3122                                 BASE_NONE,
3123                                 NULL,
3124                                 0x0,
3125                                 "", HFILL
3126                         }
3127                 },
3128                 {
3129                         &hf_rtcp_app_poc1_conn_sdes_items[1],
3130                         {
3131                                 "Nick name of inviting client",
3132                                 "rtcp.app.poc1.conn.sdes.a.dn",
3133                                 FT_UINT_STRING,
3134                                 BASE_NONE,
3135                                 NULL,
3136                                 0x0,
3137                                 "", HFILL
3138                         }
3139                 },
3140                 {
3141                         &hf_rtcp_app_poc1_conn_sdes_items[2],
3142                         {
3143                                 "Session identity",
3144                                 "rtcp.app.poc1.conn.sdes.sess.id",
3145                                 FT_UINT_STRING,
3146                                 BASE_NONE,
3147                                 NULL,
3148                                 0x0,
3149                                 "", HFILL
3150                         }
3151                 },
3152                 {
3153                         &hf_rtcp_app_poc1_conn_sdes_items[3],
3154                         {
3155                                 "Group Name",
3156                                 "rtcp.app.poc1.conn.sdes.grp.dn",
3157                                 FT_UINT_STRING,
3158                                 BASE_NONE,
3159                                 NULL,
3160                                 0x0,
3161                                 "", HFILL
3162                         }
3163                 },
3164                 {
3165                         &hf_rtcp_app_poc1_conn_sdes_items[4],
3166                         {
3167                                 "Group identity",
3168                                 "rtcp.app.poc1.conn.sdes.grp.id",
3169                                 FT_UINT_STRING,
3170                                 BASE_NONE,
3171                                 NULL,
3172                                 0x0,
3173                                 "", HFILL
3174                         }
3175                 },
3176                 {
3177                         &hf_rtcp_fsn,
3178                         {
3179                                 "First sequence number",
3180                                 "rtcp.nack.fsn",
3181                                 FT_UINT16,
3182                                 BASE_DEC,
3183                                 NULL,
3184                                 0x0,
3185                                 "", HFILL
3186                         }
3187                 },
3188                 {
3189                         &hf_rtcp_blp,
3190                         {
3191                                 "Bitmask of following lost packets",
3192                                 "rtcp.nack.blp",
3193                                 FT_UINT16,
3194                                 BASE_DEC,
3195                                 NULL,
3196                                 0x0,
3197                                 "", HFILL
3198                         }
3199                 },
3200                 {
3201                         &hf_rtcp_padding_count,
3202                         {
3203                                 "Padding count",
3204                                 "rtcp.padding.count",
3205                                 FT_UINT8,
3206                                 BASE_DEC,
3207                                 NULL,
3208                                 0x0,
3209                                 "", HFILL
3210                         }
3211                 },
3212                 {
3213                         &hf_rtcp_padding_data,
3214                         {
3215                                 "Padding data",
3216                                 "rtcp.padding.data",
3217                                 FT_BYTES,
3218                                 BASE_NONE,
3219                                 NULL,
3220                                 0x0,
3221                                 "", HFILL
3222                         }
3223                 },
3224                 {
3225                         &hf_rtcp_profile_specific_extension,
3226                         {
3227                                 "Profile-specific extension",
3228                                 "rtcp.profile-specific-extension",
3229                                 FT_BYTES,
3230                                 BASE_NONE,
3231                                 NULL,
3232                                 0x0,
3233                                 "Profile-specific extension", HFILL
3234                         }
3235                 },
3236                 {
3237                         &hf_rtcp_setup,
3238                         {
3239                                 "Stream setup",
3240                                 "rtcp.setup",
3241                                 FT_STRING,
3242                                 BASE_NONE,
3243                                 NULL,
3244                                 0x0,
3245                                 "Stream setup, method and frame number", HFILL
3246                         }
3247                 },
3248                 {
3249                         &hf_rtcp_setup_frame,
3250                         {
3251                                 "Setup frame",
3252                                 "rtcp.setup-frame",
3253                                 FT_FRAMENUM,
3254                                 BASE_NONE,
3255                                 NULL,
3256                                 0x0,
3257                                 "Frame that set up this stream", HFILL
3258                         }
3259                 },
3260                 {
3261                         &hf_rtcp_setup_method,
3262                         {
3263                                 "Setup Method",
3264                                 "rtcp.setup-method",
3265                                 FT_STRING,
3266                                 BASE_NONE,
3267                                 NULL,
3268                                 0x0,
3269                                 "Method used to set up this stream", HFILL
3270                         }
3271                 },
3272                 {
3273                         &hf_rtcp_last_sr_timestamp_frame,
3274                         {
3275                                 "Frame matching Last SR timestamp",
3276                                 "rtcp.lsr-frame",
3277                                 FT_FRAMENUM,
3278                                 BASE_NONE,
3279                                 NULL,
3280                                 0x0,
3281                                 "Frame matching LSR field (used to calculate roundtrip delay)", HFILL
3282                         }
3283                 },
3284                 {
3285                         &hf_rtcp_roundtrip_delay,
3286                         {
3287                                 "Roundtrip Delay(ms)",
3288                                 "rtcp.roundtrip-delay",
3289                                 FT_UINT32,
3290                                 BASE_DEC,
3291                                 NULL,
3292                                 0x0,
3293                                 "Calculated roundtrip delay in ms", HFILL
3294                         }
3295                 },
3296                 {
3297                         &hf_rtcp_xr_block_type,
3298                         {
3299                                 "Type",
3300                                 "rtcp.xr.bt",
3301                                 FT_UINT8,
3302                                 BASE_DEC,
3303                                 VALS(rtcp_xr_type_vals),
3304                                 0x0,
3305                                 "Block Type", HFILL
3306                         }
3307                 },
3308                 {
3309                         &hf_rtcp_xr_block_specific,
3310                         {
3311                                 "Type Specific",
3312                                 "rtcp.xr.bs",
3313                                 FT_UINT8,
3314                                 BASE_DEC,
3315                                 NULL,
3316                                 0x0,
3317                                 "Reserved", HFILL
3318                         }
3319                 },
3320                 {
3321                         &hf_rtcp_xr_block_length,
3322                         {
3323                                 "Length",
3324                                 "rtcp.xr.bl",
3325                                 FT_UINT16,
3326                                 BASE_DEC,
3327                                 NULL,
3328                                 0x0,
3329                                 "Block Length", HFILL
3330                         }
3331                 },
3332                 {
3333                         &hf_rtcp_ssrc_discarded,
3334                         {
3335                                 "Fraction discarded",
3336                                 "rtcp.ssrc.discarded",
3337                                 FT_UINT8,
3338                                 BASE_DEC,
3339                                 NULL,
3340                                 0x0,
3341                                 "Discard Rate", HFILL
3342                         }
3343                 },
3344                 {
3345                         &hf_rtcp_xr_voip_metrics_burst_density,
3346                         {
3347                                 "Burst Density",
3348                                 "rtcp.xr.voipmetrics.burstdensity",
3349                                 FT_UINT8,
3350                                 BASE_DEC,
3351                                 NULL,
3352                                 0x0,
3353                                 "", HFILL
3354                         }
3355                 },
3356                 {
3357                         &hf_rtcp_xr_voip_metrics_gap_density,
3358                         {
3359                                 "Gap Density",
3360                                 "rtcp.xr.voipmetrics.gapdensity",
3361                                 FT_UINT8,
3362                                 BASE_DEC,
3363                                 NULL,
3364                                 0x0,
3365                                 "", HFILL
3366                         }
3367                 },
3368                 {
3369                         &hf_rtcp_xr_voip_metrics_burst_duration,
3370                         {
3371                                 "Burst Duration(ms)",
3372                                 "rtcp.xr.voipmetrics.burstduration",
3373                                 FT_UINT16,
3374                                 BASE_DEC,
3375                                 NULL,
3376                                 0x0,
3377                                 "", HFILL
3378                         }
3379                 },
3380                 {
3381                         &hf_rtcp_xr_voip_metrics_gap_duration,
3382                         {
3383                                 "Gap Duration(ms)",
3384                                 "rtcp.xr.voipmetrics.gapduration",
3385                                 FT_UINT16,
3386                                 BASE_DEC,
3387                                 NULL,
3388                                 0x0,
3389                                 "", HFILL
3390                         }
3391                 },
3392                 {
3393                         &hf_rtcp_xr_voip_metrics_rtdelay,
3394                         {
3395                                 "Round Trip Delay(ms)",
3396                                 "rtcp.xr.voipmetrics.rtdelay",
3397                                 FT_UINT16,
3398                                 BASE_DEC,
3399                                 NULL,
3400                                 0x0,
3401                                 "", HFILL
3402                         }
3403                 },
3404                 {
3405                         &hf_rtcp_xr_voip_metrics_esdelay,
3406                         {
3407                                 "End System Delay(ms)",
3408                                 "rtcp.xr.voipmetrics.esdelay",
3409                                 FT_UINT16,
3410                                 BASE_DEC,
3411                                 NULL,
3412                                 0x0,
3413                                 "", HFILL
3414                         }
3415                 },
3416                 {
3417                         &hf_rtcp_xr_voip_metrics_siglevel,
3418                         {
3419                                 "Signal Level",
3420                                 "rtcp.xr.voipmetrics.signallevel",
3421                                 FT_INT8,
3422                                 BASE_DEC,
3423                                 NULL,
3424                                 0x0,
3425                                 "Signal level of 127 indicates this parameter is unavailable", HFILL
3426                         }
3427                 },
3428                 {
3429                         &hf_rtcp_xr_voip_metrics_noiselevel,
3430                         {
3431                                 "Noise Level",
3432                                 "rtcp.xr.voipmetrics.noiselevel",
3433                                 FT_INT8,
3434                                 BASE_DEC,
3435                                 NULL,
3436                                 0x0,
3437                                 "Noise level of 127 indicates this parameter is unavailable", HFILL
3438                         }
3439                 },
3440                 {
3441                         &hf_rtcp_xr_voip_metrics_rerl,
3442                         {
3443                                 "Residual Echo Return Loss",
3444                                 "rtcp.xr.voipmetrics.rerl",
3445                                 FT_UINT8,
3446                                 BASE_DEC,
3447                                 NULL,
3448                                 0x0,
3449                                 "", HFILL
3450                         }
3451                 },
3452                 {
3453                         &hf_rtcp_xr_voip_metrics_gmin,
3454                         {
3455                                 "Gmin",
3456                                 "rtcp.xr.voipmetrics.gmin",
3457                                 FT_UINT8,
3458                                 BASE_DEC,
3459                                 NULL,
3460                                 0x0,
3461                                 "", HFILL
3462                         }
3463                 },
3464                 {
3465                         &hf_rtcp_xr_voip_metrics_rfactor,
3466                         {
3467                                 "R Factor",
3468                                 "rtcp.xr.voipmetrics.rfactor",
3469                                 FT_UINT8,
3470                                 BASE_DEC,
3471                                 NULL,
3472                                 0x0,
3473                                 "R Factor is in the range of 0 to 100; 127 indicates this parameter is unavailable", HFILL
3474                         }
3475                 },
3476                 {
3477                         &hf_rtcp_xr_voip_metrics_extrfactor,
3478                         {
3479                                 "External R Factor",
3480                                 "rtcp.xr.voipmetrics.extrfactor",
3481                                 FT_UINT8,
3482                                 BASE_DEC,
3483                                 NULL,
3484                                 0x0,
3485                                 "R Factor is in the range of 0 to 100; 127 indicates this parameter is unavailable", HFILL
3486                         }
3487                 },
3488                 {
3489                         &hf_rtcp_xr_voip_metrics_moslq,
3490                         {
3491                                 "MOS - Listening Quality",
3492                                 "rtcp.xr.voipmetrics.moslq",
3493                                 FT_FLOAT,
3494                                 BASE_DEC,
3495                                 NULL,
3496                                 0x0,
3497                                 "MOS is in the range of 1 to 5; 127 indicates this parameter is unavailable", HFILL
3498                         }
3499                 },
3500                 {
3501                         &hf_rtcp_xr_voip_metrics_moscq,
3502                         {
3503                                 "MOS - Conversational Quality",
3504                                 "rtcp.xr.voipmetrics.moscq",
3505                                 FT_FLOAT,
3506                                 BASE_DEC,
3507                                 NULL,
3508                                 0x0,
3509                                 "MOS is in the range of 1 to 5; 127 indicates this parameter is unavailable", HFILL
3510                         }
3511                 },
3512                 {
3513                         &hf_rtcp_xr_voip_metrics_plc,
3514                         {
3515                                 "Packet Loss Conealment Algorithm",
3516                                 "rtcp.xr.voipmetrics.plc",
3517                                 FT_UINT8,
3518                                 BASE_DEC,
3519                                 VALS(rtcp_xr_plc_algo_vals),
3520                                 0xC0,
3521                                 "", HFILL
3522                         }
3523                 },
3524                 {
3525                         &hf_rtcp_xr_voip_metrics_jbadaptive,
3526                         {
3527                                 "Adaptive Jitter Buffer Algorithm",
3528                                 "rtcp.xr.voipmetrics.jba",
3529                                 FT_UINT8,
3530                                 BASE_DEC,
3531                                 VALS(rtcp_xr_jb_adaptive_vals),
3532                                 0x30,
3533                                 "", HFILL
3534                         }
3535                 },
3536                 {
3537                         &hf_rtcp_xr_voip_metrics_jbrate,
3538                         {
3539                                 "Jitter Buffer Rate",
3540                                 "rtcp.xr.voipmetrics.jbrate",
3541                                 FT_UINT8,
3542                                 BASE_DEC,
3543                                 NULL,
3544                                 0x0F,
3545                                 "", HFILL
3546                         }
3547                 },
3548                 {
3549                         &hf_rtcp_xr_voip_metrics_jbnominal,
3550                         {
3551                                 "Nominal Jitter Buffer Size",
3552                                 "rtcp.xr.voipmetrics.jbnominal",
3553                                 FT_UINT16,
3554                                 BASE_DEC,
3555                                 NULL,
3556                                 0x0,
3557                                 "", HFILL
3558                         }
3559                 },
3560                 {
3561                         &hf_rtcp_xr_voip_metrics_jbmax,
3562                         {
3563                                 "Maximum Jitter Buffer Size",
3564                                 "rtcp.xr.voipmetrics.jbmax",
3565                                 FT_UINT16,
3566                                 BASE_DEC,
3567                                 NULL,
3568                                 0x0,
3569                                 "", HFILL
3570                         }
3571                 },
3572                 {
3573                         &hf_rtcp_xr_voip_metrics_jbabsmax,
3574                         {
3575                                 "Absolute Maximum Jitter Buffer Size",
3576                                 "rtcp.xr.voipmetrics.jbabsmax",
3577                                 FT_UINT16,
3578                                 BASE_DEC,
3579                                 NULL,
3580                                 0x0,
3581                                 "", HFILL
3582                         }
3583                 },
3584                 {
3585                         &hf_rtcp_xr_thinning,
3586                         {
3587                                 "Thinning factor",
3588                                 "rtcp.xr.tf",
3589                                 FT_UINT8,
3590                                 BASE_DEC,
3591                                 NULL,
3592                                 0x0F,
3593                                 "", HFILL
3594                         }
3595                 },
3596                 {
3597                         &hf_rtcp_xr_stats_loss_flag,
3598                         {
3599                                 "Loss Report Flag",
3600                                 "rtcp.xr.stats.lrflag",
3601                                 FT_BOOLEAN,
3602                                 8,
3603                                 NULL,
3604                                 0x80,
3605                                 "", HFILL
3606                         }
3607                 },
3608                 {
3609                         &hf_rtcp_xr_stats_dup_flag,
3610                         {
3611                                 "Duplicates Report Flag",
3612                                 "rtcp.xr.stats.dupflag",
3613                                 FT_BOOLEAN,
3614                                 8,
3615                                 NULL,
3616                                 0x40,
3617                                 "", HFILL
3618                         }
3619                 },
3620                 {
3621                         &hf_rtcp_xr_stats_jitter_flag,
3622                         {
3623                                 "Jitter Report Flag",
3624                                 "rtcp.xr.stats.jitterflag",
3625                                 FT_BOOLEAN,
3626                                 8,
3627                                 NULL,
3628                                 0x20,
3629                                 "", HFILL
3630                         }
3631                 },
3632                 {
3633                         &hf_rtcp_xr_stats_ttl,
3634                         {
3635                                 "TTL or Hop Limit Flag",
3636                                 "rtcp.xr.stats.ttl",
3637                                 FT_UINT8,
3638                                 BASE_DEC,
3639                                 VALS(rtcp_xr_ip_ttl_vals),
3640                                 0x18,
3641                                 "", HFILL
3642                         }
3643                 },
3644                 {
3645                         &hf_rtcp_xr_endseq,
3646                         {
3647                                 "End Sequence Number",
3648                                 "rtcp.xr.endseq",
3649                                 FT_UINT16,
3650                                 BASE_DEC,
3651                                 NULL,
3652                                 0x0,
3653                                 "", HFILL
3654                         }
3655                 },
3656                 {
3657                         &hf_rtcp_xr_beginseq,
3658                         {
3659                                 "Begin Sequence Number",
3660                                 "rtcp.xr.beginseq",
3661                                 FT_UINT16,
3662                                 BASE_DEC,
3663                                 NULL,
3664                                 0x0,
3665                                 "", HFILL
3666                         }
3667                 },
3668                 {
3669                         &hf_rtcp_xr_stats_lost,
3670                         {
3671                                 "Lost Packets",
3672                                 "rtcp.xr.stats.lost",
3673                                 FT_UINT32,
3674                                 BASE_DEC,
3675                                 NULL,
3676                                 0x0,
3677                                 "", HFILL
3678                         }
3679                 },
3680                 {
3681                         &hf_rtcp_xr_stats_dups,
3682                         {
3683                                 "Duplicate Packets",
3684                                 "rtcp.xr.stats.dups",
3685                                 FT_UINT32,
3686                                 BASE_DEC,
3687                                 NULL,
3688                                 0x0,
3689                                 "", HFILL
3690                         }
3691                 },
3692                 {
3693                         &hf_rtcp_xr_stats_minjitter,
3694                         {
3695                                 "Minimum Jitter",
3696                                 "rtcp.xr.stats.minjitter",
3697                                 FT_UINT32,
3698                                 BASE_DEC,
3699                                 NULL,
3700                                 0x0,
3701                                 "", HFILL
3702                         }
3703                 },
3704                 {
3705                         &hf_rtcp_xr_stats_maxjitter,
3706                         {
3707                                 "Maximum Jitter",
3708                                 "rtcp.xr.stats.maxjitter",
3709                                 FT_UINT32,
3710                                 BASE_DEC,
3711                                 NULL,
3712                                 0x0,
3713                                 "", HFILL
3714                         }
3715                 },
3716                 {
3717                         &hf_rtcp_xr_stats_meanjitter,
3718                         {
3719                                 "Mean Jitter",
3720                                 "rtcp.xr.stats.meanjitter",
3721                                 FT_UINT32,
3722                                 BASE_DEC,
3723                                 NULL,
3724                                 0x0,
3725                                 "", HFILL
3726                         }
3727                 },
3728                 {
3729                         &hf_rtcp_xr_stats_devjitter,
3730                         {
3731                                 "Standard Deviation of Jitter",
3732                                 "rtcp.xr.stats.devjitter",
3733                                 FT_UINT32,
3734                                 BASE_DEC,
3735                                 NULL,
3736                                 0x0,
3737                                 "", HFILL
3738                         }
3739                 },
3740                 {
3741                         &hf_rtcp_xr_stats_minttl,
3742                         {
3743                                 "Minimum TTL or Hop Limit",
3744                                 "rtcp.xr.stats.minttl",
3745                                 FT_UINT8,
3746                                 BASE_DEC,
3747                                 NULL,
3748                                 0x0,
3749                                 "", HFILL
3750                         }
3751                 },
3752                 {
3753                         &hf_rtcp_xr_stats_maxttl,
3754                         {
3755                                 "Maximum TTL or Hop Limit",
3756                                 "rtcp.xr.stats.maxttl",
3757                                 FT_UINT8,
3758                                 BASE_DEC,
3759                                 NULL,
3760                                 0x0,
3761                                 "", HFILL
3762                         }
3763                 },
3764                 {
3765                         &hf_rtcp_xr_stats_meanttl,
3766                         {
3767                                 "Mean TTL or Hop Limit",
3768                                 "rtcp.xr.stats.meanttl",
3769                                 FT_UINT8,
3770                                 BASE_DEC,
3771                                 NULL,
3772                                 0x0,
3773                                 "", HFILL
3774                         }
3775                 },
3776                 {
3777                         &hf_rtcp_xr_stats_devttl,
3778                         {
3779                                 "Standard Deviation of TTL",
3780                                 "rtcp.xr.stats.devttl",
3781                                 FT_UINT8,
3782                                 BASE_DEC,
3783                                 NULL,
3784                                 0x0,
3785                                 "", HFILL
3786                         }
3787                 },
3788                 {
3789                         &hf_rtcp_xr_lrr,
3790                         {
3791                                 "Last RR timestamp",
3792                                 "rtcp.xr.lrr",
3793                                 FT_UINT32,
3794                                 BASE_DEC,
3795                                 NULL,
3796                                 0x0,
3797                                 "", HFILL
3798                         }
3799                 },
3800                 {
3801                         &hf_rtcp_xr_dlrr,
3802                         {
3803                                 "Delay since last RR timestamp",
3804                                 "rtcp.xr.dlrr",
3805                                 FT_UINT32,
3806                                 BASE_DEC,
3807                                 NULL,
3808                                 0x0,
3809                                 "", HFILL
3810                         }
3811                 },
3812                 {
3813                         &hf_rtcp_length_check,
3814                         {
3815                                 "RTCP frame length check",
3816                                 "rtcp.length_check",
3817                                 FT_BOOLEAN,
3818                                 BASE_NONE,
3819                                 NULL,
3820                                 0x0,
3821                                 "RTCP frame length check", HFILL
3822                         }
3823                 },
3824 };
3825
3826         static gint *ett[] =
3827         {
3828                 &ett_rtcp,
3829                 &ett_ssrc,
3830                 &ett_ssrc_item,
3831                 &ett_ssrc_ext_high,
3832                 &ett_sdes,
3833                 &ett_sdes_item,
3834                 &ett_PoC1,
3835                 &ett_rtcp_setup,
3836                 &ett_rtcp_roundtrip_delay,
3837                 &ett_xr_block,
3838                 &ett_xr_block_contents,
3839                 &ett_xr_ssrc,
3840                 &ett_xr_loss_chunk,
3841                 &ett_poc1_conn_contents
3842         };
3843
3844         module_t *rtcp_module;
3845
3846         proto_rtcp = proto_register_protocol("Real-time Transport Control Protocol",
3847             "RTCP", "rtcp");
3848         proto_register_field_array(proto_rtcp, hf, array_length(hf));
3849         proto_register_subtree_array(ett, array_length(ett));
3850
3851         register_dissector("rtcp", dissect_rtcp, proto_rtcp);
3852
3853         rtcp_module = prefs_register_protocol(proto_rtcp, NULL);
3854
3855         prefs_register_bool_preference(rtcp_module, "show_setup_info",
3856                 "Show stream setup information",
3857                 "Where available, show which protocol and frame caused "
3858                 "this RTCP stream to be created",
3859                 &global_rtcp_show_setup_info);
3860
3861         prefs_register_bool_preference(rtcp_module, "heuristic_rtcp",
3862                 "Try to decode RTCP outside of conversations ",
3863                 "If call control SIP/H.323/RTSP/.. messages are missing in the trace, "
3864                 "RTCP isn't decoded without this",
3865                 &global_rtcp_heur);
3866
3867         prefs_register_bool_preference(rtcp_module, "show_roundtrip_calculation",
3868                 "Show relative roundtrip calculations",
3869                 "Try to work out network delay by comparing time between packets "
3870                 "as captured and delays as seen by endpoint",
3871                 &global_rtcp_show_roundtrip_calculation);
3872
3873         prefs_register_uint_preference(rtcp_module, "roundtrip_min_threshhold",
3874                 "Minimum roundtrip calculations to report (ms)",
3875                 "Minimum calculated roundtrip delay time in milliseconds that "
3876                 "should be reported",
3877                 10, &global_rtcp_show_roundtrip_calculation_minimum);
3878
3879
3880 }
3881
3882 void
3883 proto_reg_handoff_rtcp(void)
3884 {
3885         /*
3886          * Register this dissector as one that can be selected by a
3887          * UDP port number.
3888          */
3889         rtcp_handle = find_dissector("rtcp");
3890         dissector_add_handle("udp.port", rtcp_handle);
3891
3892         heur_dissector_add( "udp", dissect_rtcp_heur, proto_rtcp);
3893 }