From Neil Piercy:
authoretxrab <etxrab@f5534014-38df-0310-8fa8-9805f1628bb7>
Fri, 28 Aug 2009 21:34:59 +0000 (21:34 +0000)
committeretxrab <etxrab@f5534014-38df-0310-8fa8-9805f1628bb7>
Fri, 28 Aug 2009 21:34:59 +0000 (21:34 +0000)
Add new protocol for 3GPP 29.414 (Nb interface RTP Mux).

- Don't use C++-style comments (comments beginning with "//")
- Don't declare variables in the middle of executable code; not all C
compilers support that.
- Dont register preferences when none present.
- Removed CHECK_COL

git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@29602 f5534014-38df-0310-8fa8-9805f1628bb7

epan/dissectors/Makefile.common
epan/dissectors/packet-nb_rtpmux.c [new file with mode: 0644]
epan/dissectors/packet-rtcp.c

index 4a3f20d684b75f3642804cbf40a3d848e8f5bf31..9fd10461b5d4ce3daefdc8ae58f1cc20aa6c77e3 100644 (file)
@@ -649,6 +649,7 @@ DISSECTOR_SRC = \
        packet-nas_eps.c        \
        packet-nasdaq-itch.c    \
        packet-nat-pmp.c        \
+       packet-nb_rtpmux.c      \
        packet-nbd.c            \
        packet-nbipx.c          \
        packet-nbns.c           \
diff --git a/epan/dissectors/packet-nb_rtpmux.c b/epan/dissectors/packet-nb_rtpmux.c
new file mode 100644 (file)
index 0000000..482debf
--- /dev/null
@@ -0,0 +1,218 @@
+/* packet-nb_rtpmux.c
+ * Routines for 3GPP RTP Multiplex dissection
+ * Copyright 2009, ip.access ltd <amp@ipaccess.com>
+ *
+ * $Id$
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <glib.h>
+
+#include <epan/packet.h>
+#include <epan/prefs.h>
+
+/* Forward declaration we need below */
+void proto_reg_handoff_nb_rtpmux(void);
+
+/* Initialize the protocol and registered fields */
+static int proto_nb_rtpmux = -1;
+static int hf_nb_rtpmux_compressed = -1;
+static int hf_nb_rtpmux_dstport    = -1;
+static int hf_nb_rtpmux_length     = -1;
+static int hf_nb_rtpmux_srcport    = -1;
+static int hf_nb_rtpmux_data       = -1;
+
+/* Initialize the subtree pointers */
+static gint ett_nb_rtpmux = -1;
+
+static dissector_handle_t rtpdissector;
+
+/* Code to actually dissect the packets */
+static int
+dissect_nb_rtpmux(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+
+/* Set up structures needed to add the protocol subtree and manage it */
+       proto_item *ti;
+       proto_tree *nb_rtpmux_tree;
+
+/*  First, if at all possible, do some heuristics to check if the packet cannot
+ *  possibly belong to your protocol.  This is especially important for
+ *  protocols directly on top of TCP or UDP where port collisions are
+ *  common place (e.g., even though your protocol uses a well known port,
+ *  someone else may set up, for example, a web server on that port which,
+ *  if someone analyzed that web server's traffic in Wireshark, would result
+ *  in Wireshark handing an HTTP packet to your dissector).  For example:
+ */
+       /* Check that there's enough data */
+       if (tvb_length(tvb) < 6)
+               return 0;
+
+/* Make entries in Protocol column and Info column on summary display */
+       col_set_str(pinfo->cinfo, COL_PROTOCOL, "Nb_RTPmux");
+
+       if (tree) {
+        unsigned int offset = 0;
+/* NOTE: The offset and length values in the call to
+   "proto_tree_add_item()" define what data bytes to highlight in the hex
+   display window when the line in the protocol tree display
+   corresponding to that item is selected.
+
+   Supplying a length of -1 is the way to highlight all data from the
+   offset to the end of the packet. */
+
+/* create display subtree for the protocol */
+
+        while (offset < tvb_length(tvb)-5)
+        {
+            guint16 dstport, srcport;
+            unsigned int length;
+            tvbuff_t* next_tvb;
+            
+            length = tvb_get_guint8(tvb, offset+2);
+                   ti = proto_tree_add_item(tree, proto_nb_rtpmux, tvb, offset, length == 0 ? -1:length+5, FALSE);
+               nb_rtpmux_tree = proto_item_add_subtree(ti, ett_nb_rtpmux);
+
+               proto_tree_add_item(nb_rtpmux_tree,
+                       hf_nb_rtpmux_compressed, tvb, offset, 1, FALSE);
+            dstport = (tvb_get_ntohs(tvb, offset) & 0x7fff) << 1;
+            proto_tree_add_uint(nb_rtpmux_tree, hf_nb_rtpmux_dstport, tvb, offset, 2, dstport );
+               proto_tree_add_item(nb_rtpmux_tree,
+                       hf_nb_rtpmux_length, tvb, offset+2, 1, FALSE);
+            srcport = (tvb_get_ntohs(tvb, offset+3) & 0x7fff) << 1;
+            proto_tree_add_uint(nb_rtpmux_tree, hf_nb_rtpmux_srcport, tvb, offset+3, 2, srcport );
+
+            if (rtpdissector)
+            {
+                next_tvb = tvb_new_subset(tvb, offset+5,
+                        MIN(tvb_length(tvb)-5-offset, length), length);
+
+               call_dissector(rtpdissector, next_tvb, pinfo, nb_rtpmux_tree);
+            }
+            else
+            {
+               proto_tree_add_item(nb_rtpmux_tree,
+                           hf_nb_rtpmux_data, tvb, offset+5, length == 0 ? -1:length, FALSE);
+            }
+            if (length == 0)
+                break;
+            offset += 5+length;
+        }
+       }
+
+/* If this protocol has a sub-dissector call it here, see section 1.8 */
+
+/* Return the amount of data this dissector was able to dissect */
+       return tvb_length(tvb);
+}
+
+
+/* Register the protocol with Wireshark */
+
+/* this format is require because a script is used to build the C function
+   that calls all the protocol registration.
+*/
+
+void
+proto_register_nb_rtpmux(void)
+{
+
+       static hf_register_info hf[] = {
+               { &hf_nb_rtpmux_compressed,
+                       { "Compressed headers", "nb_rtpmux.compressed",
+                        FT_BOOLEAN, BASE_NONE, NULL, 0x80,
+                       "", HFILL }
+               },
+               { &hf_nb_rtpmux_dstport,
+                       { "Dst port", "nb_rtpmux.dstport",
+                        FT_UINT16, BASE_DEC, NULL, 0x00,
+                       "", HFILL }
+               },
+               { &hf_nb_rtpmux_length,
+                       { "Length", "nb_rtpmux.length",
+                        FT_UINT8, BASE_DEC, NULL, 0x00,
+                       "", HFILL }
+               },
+               { &hf_nb_rtpmux_srcport,
+                       { "Src port", "nb_rtpmux.srcport",
+                        FT_UINT16, BASE_DEC, NULL, 0x00,
+                       "", HFILL }
+               },
+               { &hf_nb_rtpmux_data,
+                       { "RTP Packet", "nb_rtpmux.data",
+                        FT_BYTES, BASE_HEX, NULL, 0x00,
+                       "", HFILL }
+               }
+       };
+
+/* Setup protocol subtree array */
+       static gint *ett[] = {
+               &ett_nb_rtpmux
+       };
+
+/* Register the protocol name and description */
+       proto_nb_rtpmux = proto_register_protocol("3GPP Nb Interface RTP Multiplex",
+           "nb_rtpmux", "nb_rtpmux");
+
+/* Required function calls to register the header fields and subtrees used */
+       proto_register_field_array(proto_nb_rtpmux, hf, array_length(hf));
+       proto_register_subtree_array(ett, array_length(ett));
+
+}
+
+
+/* If this dissector uses sub-dissector registration add a registration routine.
+   This exact format is required because a script is used to find these
+   routines and create the code that calls these routines.
+
+   This function is also called by preferences whenever "Apply" is pressed
+   (see prefs_register_protocol above) so it should accommodate being called
+   more than once.
+*/
+void
+proto_reg_handoff_nb_rtpmux(void)
+{
+       static gboolean inited = FALSE;
+
+       if (!inited) {
+
+           dissector_handle_t nb_rtpmux_handle;
+
+/*  Use new_create_dissector_handle() to indicate that dissect_nb_rtpmux()
+ *  returns the number of bytes it dissected (or 0 if it thinks the packet
+ *  does not belong to PROTONAME).
+ */
+           nb_rtpmux_handle = new_create_dissector_handle(dissect_nb_rtpmux,
+               proto_nb_rtpmux);
+
+           dissector_add_handle("udp.port", nb_rtpmux_handle);
+        rtpdissector = find_dissector("rtp");
+           inited = TRUE;
+       }
+
+}
+
index dcb5d30d5bced667bb260b603a67aac8804e8e61..2e1b09faa2b5c8488f28ce14254c5ece2f735e4b 100644 (file)
@@ -279,6 +279,17 @@ static const value_string rtcp_app_poc1_qsresp_priority_vals[] =
        {  3,   "Pre-emptive priority"},
        {  0,   NULL }
 };
+
+/* 3GPP 29.414 RTP Multiplexing */
+static const value_string rtcp_app_mux_selection_vals[] =
+{
+    {  0,   "No multiplexing applied"},
+    {  1,   "Multiplexing without RTP header compression applied"},
+    {  2,   "Multiplexing with RTP header compression applied"},
+    {  3,   "Reserved"},
+    {  0,   NULL}
+};
+
 /* RFC 4585 */
 static const value_string rtcp_rtpfb_fmt_vals[] =
 {
@@ -362,6 +373,11 @@ static int hf_rtcp_app_poc1_conn_content[5] = { -1, -1, -1, -1, -1 };
 static int hf_rtcp_app_poc1_conn_session_type  = -1;
 static int hf_rtcp_app_poc1_conn_add_ind_mao   = -1;
 static int hf_rtcp_app_poc1_conn_sdes_items[5] = { -1, -1, -1, -1, -1 };
+static int hf_rtcp_app_mux           = -1;
+static int hf_rtcp_app_mux_mux       = -1;
+static int hf_rtcp_app_mux_cp        = -1;
+static int hf_rtcp_app_mux_selection = -1;
+static int hf_rtcp_app_mux_localmuxport = -1;
 static int hf_rtcp_xr_block_type     = -1;
 static int hf_rtcp_xr_block_specific = -1;
 static int hf_rtcp_xr_block_length   = -1;
@@ -458,6 +474,7 @@ static gint ett_ssrc_ext_high               = -1;
 static gint ett_sdes                   = -1;
 static gint ett_sdes_item              = -1;
 static gint ett_PoC1                   = -1;
+static gint ett_mux                    = -1;
 static gint ett_rtcp_setup             = -1;
 static gint ett_rtcp_roundtrip_delay   = -1;
 static gint ett_xr_block                = -1;
@@ -833,6 +850,7 @@ dissect_rtcp_app( tvbuff_t *tvb,packet_info *pinfo, int offset, proto_tree *tree
 
        /* XXX If more application types are to be dissected it may be useful to use a table like in packet-sip.c */
        static const char poc1_app_name_str[] = "PoC1";
+       static const char mux_app_name_str[] = "3GPP";
 
 
        /* SSRC / CSRC */
@@ -856,9 +874,8 @@ dissect_rtcp_app( tvbuff_t *tvb,packet_info *pinfo, int offset, proto_tree *tree
                proto_item *item;
                item = proto_tree_add_uint( tree, hf_rtcp_app_poc1_subtype, tvb, offset - 8, 1, rtcp_subtype );
                PROTO_ITEM_SET_GENERATED(item);
-               if (check_col(pinfo->cinfo, COL_INFO))
-                       col_add_fstr(pinfo->cinfo, COL_INFO,"(%s) %s",ascii_name,
-                                    val_to_str(rtcp_subtype,rtcp_app_poc1_floor_cnt_type_vals,"unknown (%u)") );
+               col_add_fstr(pinfo->cinfo, COL_INFO,"(%s) %s",ascii_name,
+                            val_to_str(rtcp_subtype,rtcp_app_poc1_floor_cnt_type_vals,"unknown (%u)") );
                offset += 4;
                packet_len -= 4;
                app_length = app_length -8;
@@ -912,14 +929,11 @@ dissect_rtcp_app( tvbuff_t *tvb,packet_info *pinfo, int offset, proto_tree *tree
                                        offset += 2;
                                        packet_len -= 2;
 
-                                       if (check_col(pinfo->cinfo, COL_INFO))
-                                       {
-                                               col_append_fstr(pinfo->cinfo, COL_INFO,
-                                                              " \"%s\"",
-                                                              val_to_str(priority,
-                                                                         rtcp_app_poc1_qsresp_priority_vals,
-                                                                         "Unknown"));
-                                       }
+                                       col_append_fstr(pinfo->cinfo, COL_INFO,
+                                                      " \"%s\"",
+                                                      val_to_str(priority,
+                                                                 rtcp_app_poc1_qsresp_priority_vals,
+                                                                 "Unknown"));
 
                                        /* Look for (optional) next code */
                                        if (tvb_reported_length_remaining( tvb, offset) == 0)
@@ -949,10 +963,7 @@ dissect_rtcp_app( tvbuff_t *tvb,packet_info *pinfo, int offset, proto_tree *tree
                                        offset += 8;
                                        packet_len -=8;
 
-                                       if (check_col(pinfo->cinfo, COL_INFO))
-                                       {
-                                               col_append_fstr(pinfo->cinfo, COL_INFO, " ts=\"%s\"", buff);
-                                       }
+                                       col_append_fstr(pinfo->cinfo, COL_INFO, " ts=\"%s\"", buff);
                                }
                                }
                                break;
@@ -995,11 +1006,8 @@ dissect_rtcp_app( tvbuff_t *tvb,packet_info *pinfo, int offset, proto_tree *tree
                                offset += item_len;
                                packet_len -= item_len;
 
-                               if (check_col(pinfo->cinfo, COL_INFO))
-                               {
-                                       col_append_fstr(pinfo->cinfo, COL_INFO, " stop-talking-time=%u",
-                                                       stop_talking_time);
-                               }
+                               col_append_fstr(pinfo->cinfo, COL_INFO, " stop-talking-time=%u",
+                                               stop_talking_time);
 
                                /* Participants (optional) */
                                if (tvb_reported_length_remaining( tvb, offset) == 0)
@@ -1036,12 +1044,8 @@ dissect_rtcp_app( tvbuff_t *tvb,packet_info *pinfo, int offset, proto_tree *tree
                                offset += item_len;
                                packet_len -= item_len;
 
-                               if (check_col(pinfo->cinfo, COL_INFO))
-                               {
-                                       col_append_fstr(pinfo->cinfo, COL_INFO, " participants=%u",
-                                                       participants);
-                               }
-
+                               col_append_fstr(pinfo->cinfo, COL_INFO, " participants=%u",
+                                               participants);
                                }
                                break;
 
@@ -1073,10 +1077,8 @@ dissect_rtcp_app( tvbuff_t *tvb,packet_info *pinfo, int offset, proto_tree *tree
                                                    tvb, offset, 1, FALSE );
                                offset++;
 
-                               if (check_col(pinfo->cinfo, COL_INFO)) {
-                                       col_append_fstr(pinfo->cinfo, COL_INFO, " CNAME=\"%s\"",
-                                                       tvb_get_ephemeral_string(tvb, offset, item_len));
-                               }
+                               col_append_fstr(pinfo->cinfo, COL_INFO, " CNAME=\"%s\"",
+                                               tvb_get_ephemeral_string(tvb, offset, item_len));
                                
                                offset += item_len;
                                packet_len = packet_len - item_len - 1;
@@ -1106,10 +1108,8 @@ dissect_rtcp_app( tvbuff_t *tvb,packet_info *pinfo, int offset, proto_tree *tree
                                                            tvb, offset, 1, FALSE);
                                        offset++;
 
-                                       if (check_col(pinfo->cinfo, COL_INFO)) {
-                                               col_append_fstr(pinfo->cinfo, COL_INFO, " DISPLAY-NAME=\"%s\"",
-                                                               tvb_get_ephemeral_string(tvb, offset, item_len));
-                                       }
+                                       col_append_fstr(pinfo->cinfo, COL_INFO, " DISPLAY-NAME=\"%s\"",
+                                                       tvb_get_ephemeral_string(tvb, offset, item_len));
 
                                        offset += item_len;
                                        packet_len = packet_len - item_len - 1;
@@ -1158,11 +1158,8 @@ dissect_rtcp_app( tvbuff_t *tvb,packet_info *pinfo, int offset, proto_tree *tree
                                                break;
                                }
 
-                               if (check_col(pinfo->cinfo, COL_INFO)) {
-                                       col_append_fstr(pinfo->cinfo, COL_INFO, " Participants=%u",
-                                                       participants);
-                               }
-
+                               col_append_fstr(pinfo->cinfo, COL_INFO, " Participants=%u",
+                                               participants);
                                offset += item_len;
                                packet_len -= item_len;
                                }
@@ -1178,13 +1175,10 @@ dissect_rtcp_app( tvbuff_t *tvb,packet_info *pinfo, int offset, proto_tree *tree
                                offset++;
                                packet_len--;
 
-                               if (check_col(pinfo->cinfo, COL_INFO))
-                               {
-                                       col_append_fstr(pinfo->cinfo, COL_INFO, " reason-code=\"%s\"",
-                                                       val_to_str(reason_code,
-                                                                  rtcp_app_poc1_reason_code1_vals,
-                                                                  "Unknown"));
-                               }
+                               col_append_fstr(pinfo->cinfo, COL_INFO, " reason-code=\"%s\"",
+                                               val_to_str(reason_code,
+                                                          rtcp_app_poc1_reason_code1_vals,
+                                                          "Unknown"));
 
                                /* Reason phrase */
                                item_len = tvb_get_guint8( tvb, offset );
@@ -1210,11 +1204,8 @@ dissect_rtcp_app( tvbuff_t *tvb,packet_info *pinfo, int offset, proto_tree *tree
                                proto_tree_add_item(PoC1_tree, hf_rtcp_app_poc1_ignore_seq_no, tvb, offset, 2, FALSE );
                                ignore_last_seq_no = (tvb_get_ntohs(tvb, offset) & 0x8000);
 
-                               if (!ignore_last_seq_no && check_col(pinfo->cinfo, COL_INFO))
-                               {
-                                       col_append_fstr(pinfo->cinfo, COL_INFO, " last_rtp_seq_no=%u",
-                                                       last_seq_no);
-                               }
+                               col_append_fstr(pinfo->cinfo, COL_INFO, " last_rtp_seq_no=%u",
+                                               last_seq_no);
 
                                /* 15 bits of padding follows */
 
@@ -1250,13 +1241,10 @@ dissect_rtcp_app( tvbuff_t *tvb,packet_info *pinfo, int offset, proto_tree *tree
                                                        break;
                                        }
 
-                                       if (check_col(pinfo->cinfo, COL_INFO))
-                                       {
-                                               col_append_fstr(pinfo->cinfo, COL_INFO, " reason-code=\"%s\"",
-                                                               val_to_str(reason_code,
-                                                                          rtcp_app_poc1_reason_code2_vals,
-                                                                          "Unknown"));
-                                       }
+                                       col_append_fstr(pinfo->cinfo, COL_INFO, " reason-code=\"%s\"",
+                                                       val_to_str(reason_code,
+                                                                  rtcp_app_poc1_reason_code2_vals,
+                                                                  "Unknown"));
                                        offset += 4;
                                        packet_len-=4;
                                }
@@ -1270,13 +1258,10 @@ dissect_rtcp_app( tvbuff_t *tvb,packet_info *pinfo, int offset, proto_tree *tree
                                subtype = (tvb_get_guint8(tvb, offset) & 0xf8) >> 3;
                                proto_tree_add_item( PoC1_tree, hf_rtcp_app_poc1_ack_subtype, tvb, offset, 1, FALSE );
 
-                               if (check_col(pinfo->cinfo, COL_INFO))
-                               {
-                                       col_append_fstr(pinfo->cinfo, COL_INFO, " (for %s)",
-                                                       val_to_str(subtype,
-                                                                  rtcp_app_poc1_floor_cnt_type_vals,
-                                                                  "Unknown"));
-                               }
+                               col_append_fstr(pinfo->cinfo, COL_INFO, " (for %s)",
+                                               val_to_str(subtype,
+                                                          rtcp_app_poc1_floor_cnt_type_vals,
+                                                          "Unknown"));
 
                                /* Reason code only seen if subtype was Connect */
                                if (subtype == TBCP_CONNECT)
@@ -1313,10 +1298,7 @@ dissect_rtcp_app( tvbuff_t *tvb,packet_info *pinfo, int offset, proto_tree *tree
                                        proto_item_append_text(ti, " (position not available)");
                                }
 
-                               if (check_col(pinfo->cinfo, COL_INFO))
-                               {
-                                       col_append_fstr(pinfo->cinfo, COL_INFO, " position=%u", position);
-                               }
+                               col_append_fstr(pinfo->cinfo, COL_INFO, " position=%u", position);
 
                                /* 1 bytes of padding  follows */
 
@@ -1390,11 +1372,44 @@ dissect_rtcp_app( tvbuff_t *tvb,packet_info *pinfo, int offset, proto_tree *tree
                offset += packet_len;
                return offset;
        }
+    else if ( g_ascii_strncasecmp(ascii_name, mux_app_name_str,4 ) == 0 )
+    {
+               /* 3GPP Nb protocol extension (3GPP 29.414) for RTP Multiplexing */
+               col_append_fstr(pinfo->cinfo, COL_INFO,"( %s ) subtype=%u",ascii_name, rtcp_subtype);
+               offset += 4;
+               packet_len -= 4;
+               /* Applications specific data */
+               if ( padding ) {
+                       /* If there's padding present, we have to remove that from the data part
+                       * The last octet of the packet contains the length of the padding
+                       */
+                       packet_len -= tvb_get_guint8( tvb, offset + packet_len - 1 );
+               }
+        if (packet_len == 4)
+        {
+            guint16 local_port = 0;
+
+                       proto_item* mux_item = proto_tree_add_item(tree, hf_rtcp_app_mux, tvb, offset, packet_len, FALSE);
+                   proto_tree* mux_tree = proto_item_add_subtree( mux_item, ett_mux );
+            proto_tree_add_item( mux_tree, hf_rtcp_app_mux_mux, tvb, offset, 1, FALSE );
+            proto_tree_add_item( mux_tree, hf_rtcp_app_mux_cp, tvb, offset, 1, FALSE );
+            proto_tree_add_item( mux_tree, hf_rtcp_app_mux_selection, tvb, offset, 1, FALSE );
+                       local_port = tvb_get_ntohs( tvb, offset+2 );
+            proto_tree_add_uint( mux_tree, hf_rtcp_app_mux_localmuxport, tvb, offset+2, 2, local_port*2 );
+        }
+        else
+        {
+            /* fall back to just showing the data if it's the wrong length */
+               proto_tree_add_item( tree, hf_rtcp_app_data, tvb, offset, packet_len, FALSE );
+        }
+               offset += packet_len;
+
+               return offset;
+    }
        else
        {
                /* Unhandled application type, just show app name and raw data */
-               if (check_col(pinfo->cinfo, COL_INFO))
-                       col_append_fstr(pinfo->cinfo, COL_INFO,"( %s ) subtype=%u",ascii_name, rtcp_subtype);
+               col_append_fstr(pinfo->cinfo, COL_INFO,"( %s ) subtype=%u",ascii_name, rtcp_subtype);
                offset += 4;
                packet_len -= 4;
                /* Applications specific data */
@@ -2478,12 +2493,9 @@ static void add_roundtrip_delay_info(tvbuff_t *tvb, packet_info *pinfo, proto_tr
        }
 
        /* Report delay in INFO column */
-       if (check_col(pinfo->cinfo, COL_INFO))
-       {
-               col_append_fstr(pinfo->cinfo, COL_INFO,
-                               " (roundtrip delay <-> %s = %dms, using frame %u)  ",
-                               address_to_str(&pinfo->net_src), delay, frame);
-       }
+       col_append_fstr(pinfo->cinfo, COL_INFO,
+                       " (roundtrip delay <-> %s = %dms, using frame %u)  ",
+                       address_to_str(&pinfo->net_src), delay, frame);
 }
 
 static int
@@ -2578,11 +2590,8 @@ dissect_rtcp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree )
         if ( ( packet_type < 192 ) || ( packet_type >  207 ) )
             break;
 
-        if (check_col(pinfo->cinfo, COL_INFO))
-        {
-            col_add_fstr(pinfo->cinfo, COL_INFO, "%s   ",
-                         val_to_str(packet_type, rtcp_packet_type_vals, "Unknown"));
-        }
+         col_add_fstr(pinfo->cinfo, COL_INFO, "%s   ",
+                      val_to_str(packet_type, rtcp_packet_type_vals, "Unknown"));
 
         /*
          * get the packet-length for the complete RTCP packet
@@ -3522,6 +3531,66 @@ proto_register_rtcp(void)
                                NULL, HFILL
                        }
                },
+               {
+                       &hf_rtcp_app_mux,
+                       {
+                               "RtpMux Application specific data",
+                               "rtcp.app.mux",
+                               FT_NONE,
+                               BASE_NONE,
+                               NULL,
+                               0x0,
+                               "", HFILL
+                       }
+               },
+        {
+            &hf_rtcp_app_mux_mux,
+                       {
+                               "Multiplexing supported",
+                               "rtcp.app.mux.mux",
+                               FT_BOOLEAN,
+                               BASE_NONE,
+                               NULL,
+                               0x80,
+                               "", HFILL
+                       }
+        },
+        {
+            &hf_rtcp_app_mux_cp,
+                       {
+                               "Header compression supported",
+                               "rtcp.app.mux.cp",
+                               FT_BOOLEAN,
+                               BASE_NONE,
+                               NULL,
+                               0x40,
+                               "", HFILL
+                       }
+        },
+        {
+            &hf_rtcp_app_mux_selection,
+            {
+                               "Multiplexing selection",
+                               "rtcp.app.mux.selection",
+                               FT_UINT8,
+                               BASE_DEC,
+                               VALS(rtcp_app_mux_selection_vals),
+                               0x30,
+                               "", HFILL
+                       }
+        },
+        {
+            &hf_rtcp_app_mux_localmuxport,
+            {
+                               "Local Mux Port",
+                               "rtcp.app.mux.muxport",
+                               FT_UINT16,
+                               BASE_DEC,
+                NULL,
+                               0x0,
+                               "", HFILL
+                       }
+        },
                {
                        &hf_rtcp_fsn,
                        {
@@ -4469,6 +4538,7 @@ proto_register_rtcp(void)
                &ett_sdes,
                &ett_sdes_item,
                &ett_PoC1,
+        &ett_mux,
                &ett_rtcp_setup,
                &ett_rtcp_roundtrip_delay,
                &ett_xr_block,