For proto_tree_add_item(..., proto_xxx, ...)use ENC_NA as the encoding arg.
[obnox/wireshark/wip.git] / epan / dissectors / packet-rtp.c
index 9d75437e6e74375276921b24f26e7dc11b36ac20..a8f9fdf21b765e59dbbc9dcb62dfa626a85ce70b 100644 (file)
 # include "config.h"
 #endif
 
-#include <glib.h>
 #include <epan/packet.h>
 
-#include <stdio.h>
-#include <string.h>
-
 #include "packet-rtp.h"
 #include <epan/rtp_pt.h>
-#include "packet-ntp.h"
 #include <epan/conversation.h>
 #include <epan/reassemble.h>
 #include <epan/tap.h>
 
 #include <epan/prefs.h>
 #include <epan/emem.h>
-
-#include "log.h"
+#include <epan/strutil.h>
 
 /* uncomment this to enable debugging of fragment reassembly */
 /* #define DEBUG_FRAGMENTS   1 */
 
 typedef struct _rfc2198_hdr {
-  unsigned int pt;
-  int offset;
-  int len;
-  struct _rfc2198_hdr *next;
+       unsigned int pt;
+       int offset;
+       int len;
+       struct _rfc2198_hdr *next;
 } rfc2198_hdr;
 
 /* we have one of these for each pdu which spans more than one segment
@@ -106,7 +100,6 @@ typedef struct  _rtp_private_conv_info {
 } rtp_private_conv_info;
 
 static GHashTable *fragment_table = NULL;
-static GHashTable * fid_table = NULL;
 
 static int hf_rtp_fragments = -1;
 static int hf_rtp_fragment = -1;
@@ -115,31 +108,34 @@ static int hf_rtp_fragment_overlap_conflict = -1;
 static int hf_rtp_fragment_multiple_tails = -1;
 static int hf_rtp_fragment_too_long_fragment = -1;
 static int hf_rtp_fragment_error = -1;
+static int hf_rtp_fragment_count = -1;
 static int hf_rtp_reassembled_in = -1;
+static int hf_rtp_reassembled_length = -1;
 
 static gint ett_rtp_fragment = -1;
 static gint ett_rtp_fragments = -1;
 
 static const fragment_items rtp_fragment_items = {
-  &ett_rtp_fragment,
-  &ett_rtp_fragments,
-  &hf_rtp_fragments,
-  &hf_rtp_fragment,
-  &hf_rtp_fragment_overlap,
-  &hf_rtp_fragment_overlap_conflict,
-  &hf_rtp_fragment_multiple_tails,
-  &hf_rtp_fragment_too_long_fragment,
-  &hf_rtp_fragment_error,
-  &hf_rtp_reassembled_in,
-  "RTP fragments"
+       &ett_rtp_fragment,
+       &ett_rtp_fragments,
+       &hf_rtp_fragments,
+       &hf_rtp_fragment,
+       &hf_rtp_fragment_overlap,
+       &hf_rtp_fragment_overlap_conflict,
+       &hf_rtp_fragment_multiple_tails,
+       &hf_rtp_fragment_too_long_fragment,
+       &hf_rtp_fragment_error,
+       &hf_rtp_fragment_count,
+       &hf_rtp_reassembled_in,
+       &hf_rtp_reassembled_length,
+       "RTP fragments"
 };
 
 static dissector_handle_t rtp_handle;
-static dissector_handle_t rtp_rfc2198_handle;
-static dissector_handle_t stun_handle;
+static dissector_handle_t classicstun_handle;
+static dissector_handle_t classicstun_heur_handle;
 static dissector_handle_t t38_handle;
-
-static dissector_handle_t pkt_ccc_handle;
+static dissector_handle_t zrtp_handle;
 
 static int rtp_tap = -1;
 
@@ -202,28 +198,27 @@ static int hf_pkt_ccc_ts       = -1;
 static gint ett_pkt_ccc = -1;
 
 /* PacketCable CCC port preference */
-static gboolean global_pkt_ccc_udp_port = 0;
+static guint global_pkt_ccc_udp_port = 0;
 
 
 #define RTP0_INVALID 0
-#define RTP0_STUN    1
+#define RTP0_CLASSICSTUN    1
 #define RTP0_T38     2
 
 static enum_val_t rtp_version0_types[] = {
-       { "invalid", "Invalid RTP packets", RTP0_INVALID },
-       { "stun", "STUN packets", RTP0_STUN },
+       { "invalid", "Invalid or ZRTP packets", RTP0_INVALID },
+       { "classicstun", "CLASSIC-STUN packets", RTP0_CLASSICSTUN },
        { "t38", "T.38 packets", RTP0_T38 },
        { NULL, NULL, 0 }
 };
-static guint global_rtp_version0_type = 0;
+static gint global_rtp_version0_type = 0;
 
 static dissector_handle_t data_handle;
 
 /* Forward declaration we need below */
 void proto_reg_handoff_rtp(void);
+void proto_reg_handoff_pkt_ccc(void);
 
-static gboolean dissect_rtp_heur( tvbuff_t *tvb, packet_info *pinfo,
-    proto_tree *tree );
 static void dissect_rtp( tvbuff_t *tvb, packet_info *pinfo,
     proto_tree *tree );
 static void show_setup_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
@@ -240,7 +235,6 @@ static gboolean desegment_rtp = TRUE;
 
 /* RFC2198 Redundant Audio Data */
 static guint rtp_rfc2198_pt = 99;
-static guint rtp_saved_rfc2198_pt = 0;
 
 /*
  * Fields in the first octet of the RTP header.
@@ -261,9 +255,9 @@ static guint rtp_saved_rfc2198_pt = 0;
 
 static const value_string rtp_version_vals[] =
 {
+       { 2, "RFC 1889 Version" }, /* First for speed */
        { 0, "Old VAT Version" },
        { 1, "First Draft Version" },
-       { 2, "RFC 1889 Version" },
        { 0, NULL },
 };
 
@@ -276,71 +270,289 @@ static const value_string rtp_version_vals[] =
 
 /* Payload type is the last 7 bits */
 #define RTP_PAYLOAD_TYPE(octet)        ((octet) & 0x7F)
+/* http://www.iana.org/assignments/rtp-parameters */
 
-const value_string rtp_payload_type_vals[] =
+static const value_string rtp_payload_type_vals[] =
 {
-       { PT_PCMU,      "ITU-T G.711 PCMU" },
-       { PT_1016,      "USA Federal Standard FS-1016" },
-       { PT_G721,      "ITU-T G.721" },
-       { PT_GSM,       "GSM 06.10" },
-       { PT_G723,      "ITU-T G.723" },
-       { PT_DVI4_8000, "DVI4 8000 samples/s" },
-       { PT_DVI4_16000, "DVI4 16000 samples/s" },
-       { PT_LPC,       "Experimental linear predictive encoding from Xerox PARC" },
-       { PT_PCMA,      "ITU-T G.711 PCMA" },
-       { PT_G722,      "ITU-T G.722" },
-       { PT_L16_STEREO, "16-bit uncompressed audio, stereo" },
-       { PT_L16_MONO,  "16-bit uncompressed audio, monaural" },
-       { PT_QCELP,     "Qualcomm Code Excited Linear Predictive coding" },
-       { PT_CN,        "Comfort noise" },
-       { PT_MPA,       "MPEG-I/II Audio"},
-       { PT_G728,      "ITU-T G.728" },
-       { PT_DVI4_11025, "DVI4 11025 samples/s" },
-       { PT_DVI4_22050, "DVI4 22050 samples/s" },
-       { PT_G729,      "ITU-T G.729" },
-       { PT_CN_OLD,    "Comfort noise (old)" },
-       { PT_CELB,      "Sun CellB video encoding" },
-       { PT_JPEG,      "JPEG-compressed video" },
-       { PT_NV,        "'nv' program" },
-       { PT_H261,      "ITU-T H.261" },
-       { PT_MPV,       "MPEG-I/II Video"},
-       { PT_MP2T,      "MPEG-II transport streams"},
-       { PT_H263,      "ITU-T H.263" },
+/*  0 */       { PT_PCMU,                      "ITU-T G.711 PCMU" },
+/*  1 */       { PT_1016,                      "USA Federal Standard FS-1016" },
+/*  2 */       { PT_G721,                      "ITU-T G.721" },
+/*  3 */       { PT_GSM,                       "GSM 06.10" },
+/*  4 */       { PT_G723,                      "ITU-T G.723" },
+/*  5 */       { PT_DVI4_8000,         "DVI4 8000 samples/s" },
+/*  6 */       { PT_DVI4_16000,        "DVI4 16000 samples/s" },
+/*  7 */       { PT_LPC,                       "Experimental linear predictive encoding from Xerox PARC" },
+/*  8 */       { PT_PCMA,                      "ITU-T G.711 PCMA" },
+/*  9 */       { PT_G722,                      "ITU-T G.722" },
+/* 10 */       { PT_L16_STEREO,        "16-bit uncompressed audio, stereo" },
+/* 11 */       { PT_L16_MONO,          "16-bit uncompressed audio, monaural" },
+/* 12 */       { PT_QCELP,                     "Qualcomm Code Excited Linear Predictive coding" },
+/* 13 */       { PT_CN,                        "Comfort noise" },
+/* 14 */       { PT_MPA,                       "MPEG-I/II Audio"},
+/* 15 */       { PT_G728,                      "ITU-T G.728" },
+/* 16 */       { PT_DVI4_11025,        "DVI4 11025 samples/s" },
+/* 17 */       { PT_DVI4_22050,        "DVI4 22050 samples/s" },
+/* 18 */       { PT_G729,                      "ITU-T G.729" },
+/* 19 */       { PT_CN_OLD,            "Comfort noise (old)" },
+/* 20 */       { 20,                           "Unassigned" },
+/* 21 */       { 21,                           "Unassigned" },
+/* 22 */       { 22,                           "Unassigned" },
+/* 23 */       { 23,                           "Unassigned" },
+/* 24 */       { 24,                           "Unassigned" },
+/* 25 */       { PT_CELB,                      "Sun CellB video encoding" },
+/* 26 */       { PT_JPEG,                      "JPEG-compressed video" },
+/* 27 */       { 27,                           "Unassigned" },
+/* 28 */       { PT_NV,                        "'nv' program" },
+/* 29 */       { 29,                           "Unassigned" },
+/* 30 */       { 30,                           "Unassigned" },
+/* 31 */       { PT_H261,                      "ITU-T H.261" },
+/* 32 */       { PT_MPV,                       "MPEG-I/II Video"},
+/* 33 */       { PT_MP2T,                      "MPEG-II transport streams"},
+/* 34 */       { PT_H263,                      "ITU-T H.263" },
+/* 35-71     Unassigned  */
+/* 35 */       { 35,                           "Unassigned" },
+/* 36 */       { 36,                           "Unassigned" },
+/* 37 */       { 37,                           "Unassigned" },
+/* 38 */       { 38,                           "Unassigned" },
+/* 39 */       { 39,                           "Unassigned" },
+/* 40 */       { 40,                           "Unassigned" },
+/* 41 */       { 41,                           "Unassigned" },
+/* 42 */       { 42,                           "Unassigned" },
+/* 43 */       { 43,                           "Unassigned" },
+/* 44 */       { 44,                           "Unassigned" },
+/* 45 */       { 45,                           "Unassigned" },
+/* 46 */       { 46,                           "Unassigned" },
+/* 47 */       { 47,                           "Unassigned" },
+/* 48 */       { 48,                           "Unassigned" },
+/* 49 */       { 49,                           "Unassigned" },
+/* 50 */       { 50,                           "Unassigned" },
+/* 51 */       { 51,                           "Unassigned" },
+/* 52 */       { 52,                           "Unassigned" },
+/* 53 */       { 53,                           "Unassigned" },
+/* 54 */       { 54,                           "Unassigned" },
+/* 55 */       { 55,                           "Unassigned" },
+/* 56 */       { 56,                           "Unassigned" },
+/* 57 */       { 57,                           "Unassigned" },
+/* 58 */       { 58,                           "Unassigned" },
+/* 59 */       { 59,                           "Unassigned" },
+/* 60 */       { 60,                           "Unassigned" },
+/* 61 */       { 61,                           "Unassigned" },
+/* 62 */       { 62,                           "Unassigned" },
+/* 63 */       { 63,                           "Unassigned" },
+/* 64 */       { 64,                           "Unassigned" },
+/* 65 */       { 65,                           "Unassigned" },
+/* 66 */       { 66,                           "Unassigned" },
+/* 67 */       { 67,                           "Unassigned" },
+/* 68 */       { 68,                           "Unassigned" },
+/* 69 */       { 69,                           "Unassigned" },
+/* 70 */       { 70,                           "Unassigned" },
+/* 71 */       { 71,                           "Unassigned" },
+/* 72-76     Reserved for RTCP conflict avoidance                                  [RFC3551] */
+/* 72 */       { 72,                           "Reserved for RTCP conflict avoidance" },
+/* 73 */       { 73,                           "Reserved for RTCP conflict avoidance" },
+/* 74 */       { 74,                           "Reserved for RTCP conflict avoidance" },
+/* 75 */       { 75,                           "Reserved for RTCP conflict avoidance" },
+/* 76 */       { 76,                           "Reserved for RTCP conflict avoidance" },
+/* 77-95     Unassigned      ? */
+/* 77 */       { 77,                           "Unassigned" },
+/* 78 */       { 78,                           "Unassigned" },
+/* 79 */       { 79,                           "Unassigned" },
+/* 80 */       { 80,                           "Unassigned" },
+/* 81 */       { 81,                           "Unassigned" },
+/* 82 */       { 82,                           "Unassigned" },
+/* 83 */       { 83,                           "Unassigned" },
+/* 84 */       { 84,                           "Unassigned" },
+/* 85 */       { 85,                           "Unassigned" },
+/* 86 */       { 86,                           "Unassigned" },
+/* 87 */       { 87,                           "Unassigned" },
+/* 88 */       { 88,                           "Unassigned" },
+/* 89 */       { 89,                           "Unassigned" },
+/* 90 */       { 90,                           "Unassigned" },
+/* 91 */       { 91,                           "Unassigned" },
+/* 92 */       { 92,                           "Unassigned" },
+/* 93 */       { 93,                           "Unassigned" },
+/* 94 */       { 94,                           "Unassigned" },
+/* 95 */       { 95,                           "Unassigned" },
+       /* Alex Lindberg - Added to support addtional RTP payload types
+       See epan/rtp_pt.h */
+       { PT_UNDF_96,   "DynamicRTP-Type-96" },
+       { PT_UNDF_97,   "DynamicRTP-Type-97" },
+       { PT_UNDF_98,   "DynamicRTP-Type-98" },
+       { PT_UNDF_99,   "DynamicRTP-Type-99" },
+       { PT_UNDF_100,  "DynamicRTP-Type-100" },
+       { PT_UNDF_101,  "DynamicRTP-Type-101" },
+       { PT_UNDF_102,  "DynamicRTP-Type-102" },
+       { PT_UNDF_103,  "DynamicRTP-Type-103" },
+       { PT_UNDF_104,  "DynamicRTP-Type-104" },
+       { PT_UNDF_105,  "DynamicRTP-Type-105" },
+       { PT_UNDF_106,  "DynamicRTP-Type-106" },
+       { PT_UNDF_107,  "DynamicRTP-Type-107" },
+       { PT_UNDF_108,  "DynamicRTP-Type-108" },
+       { PT_UNDF_109,  "DynamicRTP-Type-109" },
+       { PT_UNDF_110,  "DynamicRTP-Type-110" },
+       { PT_UNDF_111,  "DynamicRTP-Type-111" },
+       { PT_UNDF_112,  "DynamicRTP-Type-112" },
+       { PT_UNDF_113,  "DynamicRTP-Type-113" },
+       { PT_UNDF_114,  "DynamicRTP-Type-114" },
+       { PT_UNDF_115,  "DynamicRTP-Type-115" },
+       { PT_UNDF_116,  "DynamicRTP-Type-116" },
+       { PT_UNDF_117,  "DynamicRTP-Type-117" },
+       { PT_UNDF_118,  "DynamicRTP-Type-118" },
+       { PT_UNDF_119,  "DynamicRTP-Type-119" },
+       { PT_UNDF_120,  "DynamicRTP-Type-120" },
+       { PT_UNDF_121,  "DynamicRTP-Type-121" },
+       { PT_UNDF_122,  "DynamicRTP-Type-122" },
+       { PT_UNDF_123,  "DynamicRTP-Type-123" },
+       { PT_UNDF_124,  "DynamicRTP-Type-124" },
+       { PT_UNDF_125,  "DynamicRTP-Type-125" },
+       { PT_UNDF_126,  "DynamicRTP-Type-126" },
+       { PT_UNDF_127,  "DynamicRTP-Type-127" },
+
        { 0,            NULL },
 };
 
-const value_string rtp_payload_type_short_vals[] =
+value_string_ext rtp_payload_type_vals_ext = VALUE_STRING_EXT_INIT(rtp_payload_type_vals);
+
+static const value_string rtp_payload_type_short_vals[] =
 {
-       { PT_PCMU,      "g711U" },
-       { PT_1016,      "fs-1016" },
-       { PT_G721,      "g721" },
-       { PT_GSM,       "GSM" },
-       { PT_G723,      "g723" },
-       { PT_DVI4_8000, "DVI4 8k" },
-       { PT_DVI4_16000, "DVI4 16k" },
-       { PT_LPC,       "Exp. from Xerox PARC" },
-       { PT_PCMA,      "g711A" },
-       { PT_G722,      "g722" },
-       { PT_L16_STEREO, "16-bit audio, stereo" },
-       { PT_L16_MONO,  "16-bit audio, monaural" },
-       { PT_QCELP,     "Qualcomm" },
-       { PT_CN,        "CN" },
-       { PT_MPA,       "MPEG-I/II Audio"},
-       { PT_G728,      "g728" },
-       { PT_DVI4_11025, "DVI4 11k" },
-       { PT_DVI4_22050, "DVI4 22k" },
-       { PT_G729,      "g729" },
-       { PT_CN_OLD,    "CN(old)" },
-       { PT_CELB,      "CellB" },
-       { PT_JPEG,      "JPEG" },
-       { PT_NV,        "NV" },
-       { PT_H261,      "h261" },
-       { PT_MPV,       "MPEG-I/II Video"},
-       { PT_MP2T,      "MPEG-II streams"},
-       { PT_H263,      "h263" },
-       { 0,            NULL },
+       { PT_PCMU,      "g711U" },
+       { PT_1016,      "fs-1016" },
+       { PT_G721,      "g721" },
+       { PT_GSM,       "GSM" },
+       { PT_G723,      "g723" },
+       { PT_DVI4_8000, "DVI4 8k" },
+       { PT_DVI4_16000, "DVI4 16k" },
+       { PT_LPC,       "Exp. from Xerox PARC" },
+       { PT_PCMA,      "g711A" },
+       { PT_G722,      "g722" },
+       { PT_L16_STEREO, "16-bit audio, stereo" },
+       { PT_L16_MONO,  "16-bit audio, monaural" },
+       { PT_QCELP,     "Qualcomm" },
+       { PT_CN,        "CN" },
+       { PT_MPA,       "MPEG-I/II Audio"},
+       { PT_G728,      "g728" },
+       { PT_DVI4_11025, "DVI4 11k" },
+       { PT_DVI4_22050, "DVI4 22k" },
+       { PT_G729,      "g729" },
+       { PT_CN_OLD,    "CN(old)" },
+/* 20 */       { 20,                           "Unassigned" },
+/* 21 */       { 21,                           "Unassigned" },
+/* 22 */       { 22,                           "Unassigned" },
+/* 23 */       { 23,                           "Unassigned" },
+/* 24 */       { 24,                           "Unassigned" },
+       { PT_CELB,      "CellB" },
+       { PT_JPEG,      "JPEG" },
+/* 27 */       { 27,                           "Unassigned" },
+       { PT_NV,        "NV" },
+/* 29 */       { 29,                           "Unassigned" },
+/* 30 */       { 30,                           "Unassigned" },
+       { PT_H261,      "h261" },
+       { PT_MPV,       "MPEG-I/II Video"},
+       { PT_MP2T,      "MPEG-II streams"},
+       { PT_H263,      "h263" },
+/* 35-71     Unassigned  */
+/* 35 */       { 35,                           "Unassigned" },
+/* 36 */       { 36,                           "Unassigned" },
+/* 37 */       { 37,                           "Unassigned" },
+/* 38 */       { 38,                           "Unassigned" },
+/* 39 */       { 39,                           "Unassigned" },
+/* 40 */       { 40,                           "Unassigned" },
+/* 41 */       { 41,                           "Unassigned" },
+/* 42 */       { 42,                           "Unassigned" },
+/* 43 */       { 43,                           "Unassigned" },
+/* 44 */       { 44,                           "Unassigned" },
+/* 45 */       { 45,                           "Unassigned" },
+/* 46 */       { 46,                           "Unassigned" },
+/* 47 */       { 47,                           "Unassigned" },
+/* 48 */       { 48,                           "Unassigned" },
+/* 49 */       { 49,                           "Unassigned" },
+/* 50 */       { 50,                           "Unassigned" },
+/* 51 */       { 51,                           "Unassigned" },
+/* 52 */       { 52,                           "Unassigned" },
+/* 53 */       { 53,                           "Unassigned" },
+/* 54 */       { 54,                           "Unassigned" },
+/* 55 */       { 55,                           "Unassigned" },
+/* 56 */       { 56,                           "Unassigned" },
+/* 57 */       { 57,                           "Unassigned" },
+/* 58 */       { 58,                           "Unassigned" },
+/* 59 */       { 59,                           "Unassigned" },
+/* 60 */       { 60,                           "Unassigned" },
+/* 61 */       { 61,                           "Unassigned" },
+/* 62 */       { 62,                           "Unassigned" },
+/* 63 */       { 63,                           "Unassigned" },
+/* 64 */       { 64,                           "Unassigned" },
+/* 65 */       { 65,                           "Unassigned" },
+/* 66 */       { 66,                           "Unassigned" },
+/* 67 */       { 67,                           "Unassigned" },
+/* 68 */       { 68,                           "Unassigned" },
+/* 69 */       { 69,                           "Unassigned" },
+/* 70 */       { 70,                           "Unassigned" },
+/* 71 */       { 71,                           "Unassigned" },
+/* 72-76     Reserved for RTCP conflict avoidance                                  [RFC3551] */
+/* 72 */       { 72,                           "Reserved for RTCP conflict avoidance" },
+/* 73 */       { 73,                           "Reserved for RTCP conflict avoidance" },
+/* 74 */       { 74,                           "Reserved for RTCP conflict avoidance" },
+/* 75 */       { 75,                           "Reserved for RTCP conflict avoidance" },
+/* 76 */       { 76,                           "Reserved for RTCP conflict avoidance" },
+/* 77-95     Unassigned      ? */
+/* 77 */       { 77,                           "Unassigned" },
+/* 78 */       { 78,                           "Unassigned" },
+/* 79 */       { 79,                           "Unassigned" },
+/* 80 */       { 80,                           "Unassigned" },
+/* 81 */       { 81,                           "Unassigned" },
+/* 82 */       { 82,                           "Unassigned" },
+/* 83 */       { 83,                           "Unassigned" },
+/* 84 */       { 84,                           "Unassigned" },
+/* 85 */       { 85,                           "Unassigned" },
+/* 86 */       { 86,                           "Unassigned" },
+/* 87 */       { 87,                           "Unassigned" },
+/* 88 */       { 88,                           "Unassigned" },
+/* 89 */       { 89,                           "Unassigned" },
+/* 90 */       { 90,                           "Unassigned" },
+/* 91 */       { 91,                           "Unassigned" },
+/* 92 */       { 92,                           "Unassigned" },
+/* 93 */       { 93,                           "Unassigned" },
+/* 94 */       { 94,                           "Unassigned" },
+/* 95 */       { 95,                           "Unassigned" },
+       /* Alex Lindberg - Short RTP types */
+       { PT_UNDF_96,   "RTPType-96" },
+       { PT_UNDF_97,   "RTPType-97" },
+       { PT_UNDF_98,   "RTPType-98" },
+       { PT_UNDF_99,   "RTPType-99" },
+       { PT_UNDF_100,  "RTPType-100" },
+       { PT_UNDF_101,  "RTPType-101" },
+       { PT_UNDF_102,  "RTPType-102" },
+       { PT_UNDF_103,  "RTPType-103" },
+       { PT_UNDF_104,  "RTPType-104" },
+       { PT_UNDF_105,  "RTPType-105" },
+       { PT_UNDF_106,  "RTPType-106" },
+       { PT_UNDF_107,  "RTPType-107" },
+       { PT_UNDF_108,  "RTPType-108" },
+       { PT_UNDF_109,  "RTPType-109" },
+       { PT_UNDF_110,  "RTPType-110" },
+       { PT_UNDF_111,  "RTPType-111" },
+       { PT_UNDF_112,  "RTPType-112" },
+       { PT_UNDF_113,  "RTPType-113" },
+       { PT_UNDF_114,  "RTPType-114" },
+       { PT_UNDF_115,  "RTPType-115" },
+       { PT_UNDF_116,  "RTPType-116" },
+       { PT_UNDF_117,  "RTPType-117" },
+       { PT_UNDF_118,  "RTPType-118" },
+       { PT_UNDF_119,  "RTPType-119" },
+       { PT_UNDF_120,  "RTPType-120" },
+       { PT_UNDF_121,  "RTPType-121" },
+       { PT_UNDF_122,  "RTPType-122" },
+       { PT_UNDF_123,  "RTPType-123" },
+       { PT_UNDF_124,  "RTPType-124" },
+       { PT_UNDF_125,  "RTPType-125" },
+       { PT_UNDF_126,  "RTPType-126" },
+       { PT_UNDF_127,  "RTPType-127" },
+
+       { 0,            NULL },
 };
+value_string_ext rtp_payload_type_short_vals_ext = VALUE_STRING_EXT_INIT(rtp_payload_type_short_vals);
 
+#if 0
 static const value_string srtp_encryption_alg_vals[] =
 {
        { SRTP_ENC_ALG_NULL,    "Null Encryption" },
@@ -355,13 +567,12 @@ static const value_string srtp_auth_alg_vals[] =
        { SRTP_AUTH_ALG_HMAC_SHA1,      "HMAC-SHA1" },
        { 0, NULL },
 };
-
+#endif
 
 /* initialisation routine */
 static void rtp_fragment_init(void)
 {
        fragment_table_init(&fragment_table);
-       fid_table = g_hash_table_new(g_direct_hash, g_direct_equal);
 }
 
 void
@@ -376,7 +587,7 @@ rtp_free_hash_dyn_payload(GHashTable *rtp_dyn_payload)
 void srtp_add_address(packet_info *pinfo,
                      address *addr, int port,
                      int other_port,
-                     const gchar *setup_method, guint32 setup_frame_number, GHashTable *rtp_dyn_payload,
+                     const gchar *setup_method, guint32 setup_frame_number, gboolean is_video _U_, GHashTable *rtp_dyn_payload,
                      struct srtp_info *srtp_info)
 {
        address null_addr;
@@ -393,7 +604,9 @@ void srtp_add_address(packet_info *pinfo,
                return;
        }
 
-       printf("#%u: %srtp_add_address(%s, %u, %u, %s, %u\n", pinfo->fd->num, (srtp_info)?"s":"", address_to_str(addr), port, other_port, setup_method, setup_frame_number);
+#ifdef DEBUG
+       printf("#%u: %srtp_add_address(%s, %u, %u, %s, %u\n", pinfo->fd->num, (srtp_info)?"s":"", ep_address_to_str(addr), port, other_port, setup_method, setup_frame_number);
+#endif
 
        SET_ADDRESS(&null_addr, AT_NONE, 0, NULL);
 
@@ -444,9 +657,9 @@ void srtp_add_address(packet_info *pinfo,
        /* Free the hash if already exists */
        rtp_free_hash_dyn_payload(p_conv_data->rtp_dyn_payload);
 
-       strncpy(p_conv_data->method, setup_method, MAX_RTP_SETUP_METHOD_SIZE);
-       p_conv_data->method[MAX_RTP_SETUP_METHOD_SIZE] = '\0';
+       g_strlcpy(p_conv_data->method, setup_method, MAX_RTP_SETUP_METHOD_SIZE+1);
        p_conv_data->frame_number = setup_frame_number;
+       p_conv_data->is_video = is_video;
        p_conv_data->rtp_dyn_payload = rtp_dyn_payload;
        p_conv_data->srtp_info = srtp_info;
 }
@@ -455,17 +668,16 @@ void srtp_add_address(packet_info *pinfo,
 void rtp_add_address(packet_info *pinfo,
                      address *addr, int port,
                      int other_port,
-                     const gchar *setup_method, guint32 setup_frame_number, GHashTable *rtp_dyn_payload)
+                     const gchar *setup_method, guint32 setup_frame_number, gboolean is_video , GHashTable *rtp_dyn_payload)
 {
-       srtp_add_address(pinfo, addr, port, other_port, setup_method, setup_frame_number, rtp_dyn_payload, NULL);
+       srtp_add_address(pinfo, addr, port, other_port, setup_method, setup_frame_number, is_video, rtp_dyn_payload, NULL);
 }
 
 static gboolean
-dissect_rtp_heur( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree )
+dissect_rtp_heur_common( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gboolean check_destport )
 {
-       guint8      octet1, octet2;
+       guint8       octet1;
        unsigned int version;
-       unsigned int payload_type;
        unsigned int offset = 0;
 
        /* This is a heuristic dissector, which means we get all the UDP
@@ -481,38 +693,50 @@ dissect_rtp_heur( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree )
        version = RTP_VERSION( octet1 );
 
        if (version == 0) {
-               switch (global_rtp_version0_type) {
-               case RTP0_STUN:
-                       call_dissector(stun_handle, tvb, pinfo, tree);
+               if (!(tvb_memeql(tvb, 4, "ZRTP", 4)))
+               {
+                       call_dissector_only(zrtp_handle, tvb, pinfo, tree);
                        return TRUE;
+               } else {
+                       switch (global_rtp_version0_type) {
+                       case RTP0_CLASSICSTUN:
+                               return call_dissector_only(classicstun_heur_handle, tvb, pinfo, tree);
 
-               case RTP0_T38:
-                       call_dissector(t38_handle, tvb, pinfo, tree);
-                       return TRUE;
+                       case RTP0_T38:
+                               /* XXX: Should really be calling a heuristic dissector for T38 ??? */
+                               call_dissector_only(t38_handle, tvb, pinfo, tree);
+                               return TRUE;
 
-               case RTP0_INVALID:
-               default:
-                       return FALSE; /* Unknown or unsupported version */
+                       case RTP0_INVALID:
+
+                       default:
+                               return FALSE; /* Unknown or unsupported version */
+                       }
                }
        } else if (version != 2) {
                /* Unknown or unsupported version */
                return FALSE;
        }
 
-       /* Get the fields in the second octet */
-       octet2 = tvb_get_guint8( tvb, offset + 1 );
-       payload_type = RTP_PAYLOAD_TYPE( octet2 );
-       /*      if (payload_type == PT_PCMU ||
-        *                   payload_type == PT_PCMA)
-        *           payload_type == PT_G729)
-        *       */
-       if (payload_type <= PT_H263) {
-               dissect_rtp( tvb, pinfo, tree );
-               return TRUE;
-       }
-       else {
-               return FALSE;
+       /* Was it sent to an even-numbered port? */
+       if (check_destport && ((pinfo->destport % 2) != 0)) {
+               return FALSE;
        }
+
+       dissect_rtp( tvb, pinfo, tree );
+       return TRUE;
+}
+
+static gboolean
+dissect_rtp_heur_udp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree )
+{
+       return dissect_rtp_heur_common(tvb, pinfo, tree, TRUE);
+}
+
+static gboolean
+dissect_rtp_heur_stun( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree )
+{
+       return dissect_rtp_heur_common(tvb, pinfo, tree, FALSE);
 }
 
 /*
@@ -520,8 +744,8 @@ dissect_rtp_heur( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree )
  */
 static void
 process_rtp_payload(tvbuff_t *newtvb, packet_info *pinfo, proto_tree *tree,
-    proto_tree *rtp_tree,
-    unsigned int payload_type)
+                   proto_tree *rtp_tree,
+                   unsigned int payload_type)
 {
        struct _rtp_conversation_info *p_conv_data = NULL;
        gboolean found_match = FALSE;
@@ -536,37 +760,44 @@ process_rtp_payload(tvbuff_t *newtvb, packet_info *pinfo, proto_tree *tree,
        if (p_conv_data && p_conv_data->srtp_info) {
                srtp_info = p_conv_data->srtp_info;
                payload_len -= srtp_info->mki_len + srtp_info->auth_tag_len;
-
+#if 0
+#error Currently the srtp_info structure contains no cypher data, see packet-sdp.c adding dummy_srtp_info structure
                if (p_conv_data->srtp_info->encryption_algorithm==SRTP_ENC_ALG_NULL) {
                        if (rtp_tree)
                                proto_tree_add_text(rtp_tree, newtvb, offset, payload_len, "SRTP Payload with NULL encryption");
                }
-               else {
+               else
+#endif
+               {
                        if (rtp_tree)
-                               proto_tree_add_item(rtp_tree, hf_srtp_encrypted_payload, newtvb, offset, payload_len, FALSE);
+                               proto_tree_add_item(rtp_tree, hf_srtp_encrypted_payload, newtvb, offset, payload_len, ENC_NA);
                        found_match = TRUE;     /* use this flag to prevent dissection below */
                }
                offset += payload_len;
 
                if (srtp_info->mki_len) {
-                       proto_tree_add_item(rtp_tree, hf_srtp_mki, newtvb, offset, srtp_info->mki_len, FALSE);
+                       proto_tree_add_item(rtp_tree, hf_srtp_mki, newtvb, offset, srtp_info->mki_len, ENC_NA);
                        offset += srtp_info->mki_len;
                }
 
                if (srtp_info->auth_tag_len) {
-                       proto_tree_add_item(rtp_tree, hf_srtp_auth_tag, newtvb, offset, srtp_info->auth_tag_len, FALSE);
+                       proto_tree_add_item(rtp_tree, hf_srtp_auth_tag, newtvb, offset, srtp_info->auth_tag_len, ENC_NA);
                        offset += srtp_info->auth_tag_len;
                }
        }
 
-       /* if the payload type is dynamic (96 to 127), we check if the conv is set and we look for the pt definition */
-       else if ( (payload_type >=96) && (payload_type <=127) ) {
+       /* if the payload type is dynamic, we check if the conv is set and we look for the pt definition */
+       else if ( (payload_type >= PT_UNDF_96 && payload_type <= PT_UNDF_127) ) {
                if (p_conv_data && p_conv_data->rtp_dyn_payload) {
                        gchar *payload_type_str = NULL;
-                       payload_type_str = g_hash_table_lookup(p_conv_data->rtp_dyn_payload, &payload_type);
+                       encoding_name_and_rate_t *encoding_name_and_rate_pt = NULL;
+                       encoding_name_and_rate_pt = g_hash_table_lookup(p_conv_data->rtp_dyn_payload, &payload_type);
+                       if (encoding_name_and_rate_pt) {
+                               payload_type_str = encoding_name_and_rate_pt->encoding_name;
+                       }
                        if (payload_type_str){
                                found_match = dissector_try_string(rtp_dyn_pt_dissector_table,
-                                                                                                       payload_type_str, newtvb, pinfo, tree);
+                                                                  payload_type_str, newtvb, pinfo, tree);
                                /* If payload type string set from conversation and
                                 * no matching dissector found it's probably because no subdissector
                                 * exists. Don't call the dissectors based on payload number
@@ -574,7 +805,7 @@ process_rtp_payload(tvbuff_t *newtvb, packet_info *pinfo, proto_tree *tree,
                                 * Just add it as data.
                                 */
                                if(found_match==FALSE)
-                                       proto_tree_add_item( rtp_tree, hf_rtp_data, newtvb, 0, -1, FALSE );
+                                       proto_tree_add_item( rtp_tree, hf_rtp_data, newtvb, 0, -1, ENC_NA );
                                return;
                        }
 
@@ -582,8 +813,8 @@ process_rtp_payload(tvbuff_t *newtvb, packet_info *pinfo, proto_tree *tree,
        }
 
        /* if we don't found, it is static OR could be set static from the preferences */
-       if (!found_match && !dissector_try_port(rtp_pt_dissector_table, payload_type, newtvb, pinfo, tree))
-               proto_tree_add_item( rtp_tree, hf_rtp_data, newtvb, 0, -1, FALSE );
+       if (!found_match && !dissector_try_uint(rtp_pt_dissector_table, payload_type, newtvb, pinfo, tree))
+               proto_tree_add_item( rtp_tree, hf_rtp_data, newtvb, 0, -1, ENC_NA );
 
 }
 
@@ -602,9 +833,9 @@ process_rtp_payload(tvbuff_t *newtvb, packet_info *pinfo, proto_tree *tree,
  */
 static void
 dissect_rtp_data( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
-    proto_tree *rtp_tree, int offset, unsigned int data_len,
-    unsigned int data_reported_len,
-       unsigned int payload_type )
+                 proto_tree *rtp_tree, int offset, unsigned int data_len,
+                 unsigned int data_reported_len,
+                 unsigned int payload_type )
 {
        tvbuff_t *newtvb;
        struct _rtp_conversation_info *p_conv_data= NULL;
@@ -616,7 +847,7 @@ dissect_rtp_data( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        /* Retrieve RTPs idea of a converation */
        p_conv_data = p_get_proto_data(pinfo->fd, proto_rtp);
 
-       if(p_conv_data != NULL) 
+       if(p_conv_data != NULL)
                finfo = p_conv_data->rtp_conv_info;
 
        if(finfo == NULL || !desegment_rtp) {
@@ -646,7 +877,7 @@ dissect_rtp_data( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        if(msp && msp->startseq < seqno && msp->endseq >= seqno) {
                guint32 fid = msp->startseq;
                fragment_data *fd_head;
-               
+
 #ifdef DEBUG_FRAGMENTS
                g_debug("\tContinues fragment %d", fid);
 #endif
@@ -669,7 +900,7 @@ dissect_rtp_data( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
                if(newtvb != NULL) {
                        /* Hand off to the subdissector */
                        process_rtp_payload(newtvb, pinfo, tree, rtp_tree, payload_type);
-            
+
                        /*
                         * Check to see if there were any complete fragments within the chunk
                         */
@@ -680,11 +911,11 @@ dissect_rtp_data( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
 #endif
                                /* Mark the fragments and not complete yet */
                                fragment_set_partial_reassembly(pinfo, fid, fragment_table);
-                                       
+
                                /* we must need another segment */
                                msp->endseq = MIN(msp->endseq,seqno) + 1;
                        }
-                       else 
+                       else
                        {
                                /*
                                 * Data was dissected so add the protocol tree to the display
@@ -697,33 +928,33 @@ dissect_rtp_data( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
                                if( frag_tree_item && rtp_tree_item )
                                        proto_tree_move_item( tree, rtp_tree_item, frag_tree_item );
 
-            
-                               if(pinfo->desegment_len) 
+
+                               if(pinfo->desegment_len)
                                {
                                        /* the higher-level dissector has asked for some more data - ie,
                                           the end of this segment does not coincide with the end of a
                                           higher-level PDU. */
                                        must_desegment = TRUE;
                                }
-                       }       
-               
-               } 
-       
-       } 
+                       }
+
+               }
+
+       }
        else
        {
                /*
                 * The segment is not the continuation of a fragmented segment
                 * so process it as normal
-                */               
+                */
 #ifdef DEBUG_FRAGMENTS
                g_debug("\tRTP non-fragment payload");
 #endif
                newtvb = tvb_new_subset( tvb, offset, data_len, data_reported_len );
-       
+
                /* Hand off to the subdissector */
                process_rtp_payload(newtvb, pinfo, tree, rtp_tree, payload_type);
-       
+
                if(pinfo->desegment_len) {
                        /* the higher-level dissector has asked for some more data - ie,
                           the end of this segment does not coincide with the end of a
@@ -731,8 +962,8 @@ dissect_rtp_data( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
                        must_desegment = TRUE;
                }
        }
-       
-       /* 
+
+       /*
         * There were bytes left over that the higher protocol couldn't dissect so save them
         */
        if(must_desegment)
@@ -740,70 +971,64 @@ dissect_rtp_data( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
                guint32 deseg_offset = pinfo->desegment_offset;
                guint32 frag_len = tvb_reported_length_remaining(newtvb, deseg_offset);
                fragment_data *fd_head = NULL;
-    
+
 #ifdef DEBUG_FRAGMENTS
                g_debug("\tRTP Must Desegment: tvb_len=%d ds_len=%d %d frag_len=%d ds_off=%d",
                        tvb_reported_length(newtvb),
                        pinfo->desegment_len,
                        pinfo->fd->flags.visited,
                        frag_len,
-                       deseg_offset); 
+                       deseg_offset);
 #endif
                /* allocate a new msp for this pdu */
                msp = se_alloc(sizeof(rtp_multisegment_pdu));
                msp->startseq = seqno;
                msp->endseq = seqno+1;
                se_tree_insert32(finfo->multisegment_pdus,seqno,msp);
-                       
+
                /*
                 * Add the fragment to the fragment table
-                */    
+                */
                fd_head = fragment_add_seq(newtvb,deseg_offset, pinfo, seqno, fragment_table, 0, frag_len,
                                           TRUE );
 
                if(fd_head != NULL)
                {
-                       if( fd_head->reassembled_in != 0 && !(fd_head->flags & FD_PARTIAL_REASSEMBLY) ) 
+                       if( fd_head->reassembled_in != 0 && !(fd_head->flags & FD_PARTIAL_REASSEMBLY) )
                        {
                                proto_item *rtp_tree_item;
                                rtp_tree_item = proto_tree_add_uint( tree, hf_rtp_reassembled_in,
                                                                     newtvb, deseg_offset, tvb_reported_length_remaining(newtvb,deseg_offset),
                                                                     fd_head->reassembled_in);
-                               PROTO_ITEM_SET_GENERATED(rtp_tree_item);          
+                               PROTO_ITEM_SET_GENERATED(rtp_tree_item);
 #ifdef DEBUG_FRAGMENTS
                                g_debug("\tReassembled in %d", fd_head->reassembled_in);
 #endif
-                       }         
-                       else 
+                       }
+                       else
                        {
 #ifdef DEBUG_FRAGMENTS
                                g_debug("\tUnfinished fragment");
 #endif
                                /* this fragment is never reassembled */
                                proto_tree_add_text( tree, tvb, deseg_offset, -1,"RTP fragment, unfinished");
-                       }       
+                       }
                }
                else
                {
-                       /* 
+                       /*
                         * This fragment was the first fragment in a new entry in the
                         * frag_table; we don't yet know where it is reassembled
-                        */      
+                        */
 #ifdef DEBUG_FRAGMENTS
                        g_debug("\tnew pdu");
 #endif
                }
-                       
-               if( pinfo->desegment_offset == 0 ) 
+
+               if( pinfo->desegment_offset == 0 )
                {
-                       if (check_col(pinfo->cinfo, COL_PROTOCOL))
-                       {
-                               col_set_str(pinfo->cinfo, COL_PROTOCOL, "RTP");
-                       }
-                       if (check_col(pinfo->cinfo, COL_INFO))
-                       {
-                               col_set_str(pinfo->cinfo, COL_INFO, "[RTP segment of a reassembled PDU]");
-                       }
+                       col_set_str(pinfo->cinfo, COL_PROTOCOL, "RTP");
+                       col_set_str(pinfo->cinfo, COL_INFO, "[RTP segment of a reassembled PDU]");
                }
        }
 
@@ -854,24 +1079,30 @@ dissect_rtp_rfc2198(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree )
                /* if it is dynamic payload, let use the conv data to see if it is defined */
                if ((hdr_new->pt > 95) && (hdr_new->pt < 128)) {
                        if (p_conv_data && p_conv_data->rtp_dyn_payload){
-                               payload_type_str = g_hash_table_lookup(p_conv_data->rtp_dyn_payload, &hdr_new->pt);
+                               encoding_name_and_rate_t *encoding_name_and_rate_pt = NULL;
+                               encoding_name_and_rate_pt = g_hash_table_lookup(p_conv_data->rtp_dyn_payload, &hdr_new->pt);
+                               if (encoding_name_and_rate_pt) {
+                                       payload_type_str = encoding_name_and_rate_pt->encoding_name;
+                               }
                        }
                }
                /* Add a subtree for this header and add items */
                ti = proto_tree_add_text(rfc2198_tree, tvb, offset, (hdr_follow)?4:1, "Header %u", cnt);
                rfc2198_hdr_tree = proto_item_add_subtree(ti, ett_rtp_rfc2198_hdr);
-               proto_tree_add_item(rfc2198_hdr_tree, hf_rtp_rfc2198_follow, tvb, offset, 1, FALSE );
+               proto_tree_add_item(rfc2198_hdr_tree, hf_rtp_rfc2198_follow, tvb, offset, 1, ENC_BIG_ENDIAN );
                proto_tree_add_uint_format(rfc2198_hdr_tree, hf_rtp_payload_type, tvb,
                    offset, 1, octet1, "Payload type: %s (%u)",
-                       payload_type_str ? payload_type_str : val_to_str(hdr_new->pt, rtp_payload_type_vals, "Unknown"),
+                       payload_type_str ? payload_type_str : val_to_str_ext(hdr_new->pt, &rtp_payload_type_vals_ext, "Unknown"),
                        hdr_new->pt);
-               proto_item_append_text(ti, ": PT=%s", payload_type_str ? payload_type_str : val_to_str(hdr_new->pt, rtp_payload_type_vals, "Unknown (%u)"));
+               proto_item_append_text(ti, ": PT=%s",
+                                      payload_type_str ? payload_type_str :
+                                                         val_to_str_ext(hdr_new->pt, &rtp_payload_type_vals_ext, "Unknown (%u)"));
                offset += 1;
 
                /* Timestamp offset and block length don't apply to last header */
                if (hdr_follow) {
-                       proto_tree_add_item(rfc2198_hdr_tree, hf_rtp_rfc2198_tm_off, tvb, offset, 2, FALSE );
-                       proto_tree_add_item(rfc2198_hdr_tree, hf_rtp_rfc2198_bl_len, tvb, offset + 1, 2, FALSE );
+                       proto_tree_add_item(rfc2198_hdr_tree, hf_rtp_rfc2198_tm_off, tvb, offset, 2, ENC_BIG_ENDIAN );
+                       proto_tree_add_item(rfc2198_hdr_tree, hf_rtp_rfc2198_bl_len, tvb, offset + 1, 2, ENC_BIG_ENDIAN );
                        hdr_new->len = tvb_get_ntohs(tvb, offset + 1) & 0x03FF;
                        proto_item_append_text(ti, ", len=%u", hdr_new->len);
                        offset += 3;
@@ -928,8 +1159,9 @@ dissect_rtp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree )
        guint32     sync_src;
        guint32     csrc_item;
        struct _rtp_conversation_info *p_conv_data = NULL;
-       struct srtp_info *srtp_info = NULL;
-       unsigned int srtp_offset;
+       /*struct srtp_info *srtp_info = NULL;*/
+       /*unsigned int srtp_offset;*/
+       unsigned int hdrext_offset = 0;
        tvbuff_t *newtvb = NULL;
 
        /* Can tap up to 4 RTP packets within same packet */
@@ -949,8 +1181,8 @@ dissect_rtp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree )
 
        if (version == 0) {
                switch (global_rtp_version0_type) {
-               case RTP0_STUN:
-                       call_dissector(stun_handle, tvb, pinfo, tree);
+               case RTP0_CLASSICSTUN:
+                       call_dissector(classicstun_handle, tvb, pinfo, tree);
                        return;
 
                case RTP0_T38:
@@ -958,8 +1190,13 @@ dissect_rtp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree )
                        return;
 
                case RTP0_INVALID:
+                       if (!(tvb_memeql(tvb, 4, "ZRTP", 4)))
+                       {
+                               call_dissector(zrtp_handle,tvb,pinfo,tree);
+                               return;
+                       }
                default:
-                       ; /* Unknown or unsupported version (let it fall through */
+                       ; /* Unknown or unsupported version (let it fall through) */
                }
        }
 
@@ -969,17 +1206,13 @@ dissect_rtp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree )
                /*
                 * Unknown or unsupported version.
                 */
-               if ( check_col( pinfo->cinfo, COL_PROTOCOL ) )   {
-                       col_set_str( pinfo->cinfo, COL_PROTOCOL, "RTP" );
-               }
+               col_set_str(pinfo->cinfo, COL_PROTOCOL, "RTP");
 
-               if ( check_col( pinfo->cinfo, COL_INFO) ) {
-                       col_add_fstr( pinfo->cinfo, COL_INFO,
-                           "Unknown RTP version %u", version);
-               }
+               col_add_fstr( pinfo->cinfo, COL_INFO,
+                   "Unknown RTP version %u", version);
 
                if ( tree ) {
-                       ti = proto_tree_add_item( tree, proto_rtp, tvb, offset, -1, FALSE );
+                       ti = proto_tree_add_item( tree, proto_rtp, tvb, offset, -1, ENC_NA );
                        rtp_tree = proto_item_add_subtree( ti, ett_rtp );
 
                        proto_tree_add_uint( rtp_tree, hf_rtp_version, tvb,
@@ -1006,6 +1239,7 @@ dissect_rtp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree )
        rtp_info->info_padding_set = padding_set;
        rtp_info->info_padding_count = 0;
        rtp_info->info_marker_set = marker_set;
+       rtp_info->info_is_video = FALSE;
        rtp_info->info_payload_type = payload_type;
        rtp_info->info_seq_num = seq_num;
        rtp_info->info_timestamp = timestamp;
@@ -1013,6 +1247,7 @@ dissect_rtp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree )
        rtp_info->info_is_srtp = FALSE;
        rtp_info->info_setup_frame_num = 0;
        rtp_info->info_payload_type_str = NULL;
+       rtp_info->info_payload_rate = 0;
 
        /*
         * Do we have all the data?
@@ -1051,45 +1286,51 @@ dissect_rtp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree )
        get_conv_info(pinfo, rtp_info);
        p_conv_data = p_get_proto_data(pinfo->fd, proto_rtp);
 
+       if (p_conv_data)
+               rtp_info->info_is_video = p_conv_data->is_video;
+
        if (p_conv_data && p_conv_data->srtp_info) is_srtp = TRUE;
        rtp_info->info_is_srtp = is_srtp;
 
-       if ( check_col( pinfo->cinfo, COL_PROTOCOL ) )   {
-               col_set_str( pinfo->cinfo, COL_PROTOCOL, (is_srtp) ? "SRTP" : "RTP" );
-       }
+       col_set_str( pinfo->cinfo, COL_PROTOCOL, (is_srtp) ? "SRTP" : "RTP" );
 
-       /* check if this is added as an SRTP stream - if so, don't try to dissector the payload data for now */
+       /* check if this is added as an SRTP stream - if so, don't try to dissect the payload data for now */
        p_conv_data = p_get_proto_data(pinfo->fd, proto_rtp);
+
+#if 0 /* XXX: srtp_offset never actually used ?? */
        if (p_conv_data && p_conv_data->srtp_info) {
                srtp_info = p_conv_data->srtp_info;
                if (rtp_info->info_all_data_present) {
                        srtp_offset = rtp_info->info_data_len - srtp_info->mki_len - srtp_info->auth_tag_len;
                }
        }
+#endif
 
        /* if it is dynamic payload, let use the conv data to see if it is defined */
        if ( (payload_type>95) && (payload_type<128) ) {
                if (p_conv_data && p_conv_data->rtp_dyn_payload){
-                       payload_type_str = g_hash_table_lookup(p_conv_data->rtp_dyn_payload, &payload_type);
-                       rtp_info->info_payload_type_str = payload_type_str;
+                       encoding_name_and_rate_t *encoding_name_and_rate_pt = NULL;
+                       encoding_name_and_rate_pt = g_hash_table_lookup(p_conv_data->rtp_dyn_payload, &payload_type);
+                       if (encoding_name_and_rate_pt) {
+                               rtp_info->info_payload_type_str = payload_type_str = encoding_name_and_rate_pt->encoding_name;
+                               rtp_info->info_payload_rate = encoding_name_and_rate_pt->sample_rate;
+                       }
                }
        }
 
-       if ( check_col( pinfo->cinfo, COL_INFO) ) {
-               col_add_fstr( pinfo->cinfo, COL_INFO,
-                   "PT=%s, SSRC=0x%X, Seq=%u, Time=%u%s",
-                       payload_type_str ? payload_type_str : val_to_str( payload_type, rtp_payload_type_vals,"Unknown (%u)" ),
-                   sync_src,
-                   seq_num,
-                   timestamp,
-                   marker_set ? ", Mark " : " ");
-       }
+       col_add_fstr( pinfo->cinfo, COL_INFO,
+           "PT=%s, SSRC=0x%X, Seq=%u, Time=%u%s",
+               payload_type_str ? payload_type_str : val_to_str_ext( payload_type, &rtp_payload_type_vals_ext,"Unknown (%u)" ),
+           sync_src,
+           seq_num,
+           timestamp,
+           marker_set ? ", Mark " : " ");
 
 
        if ( tree ) {
                proto_tree *item;
                /* Create RTP protocol tree */
-               ti = proto_tree_add_item(tree, proto_rtp, tvb, offset, -1, FALSE );
+               ti = proto_tree_add_item(tree, proto_rtp, tvb, offset, -1, ENC_NA );
                rtp_tree = proto_item_add_subtree(ti, ett_rtp );
 
                /* Conversation setup info */
@@ -1111,9 +1352,9 @@ dissect_rtp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree )
                proto_tree_add_boolean( rtp_tree, hf_rtp_marker, tvb, offset,
                    1, octet2 );
 
-               item = proto_tree_add_uint_format( rtp_tree, hf_rtp_payload_type, tvb,
+               proto_tree_add_uint_format( rtp_tree, hf_rtp_payload_type, tvb,
                    offset, 1, octet2, "Payload type: %s (%u)",
-                       payload_type_str ? payload_type_str : val_to_str( payload_type, rtp_payload_type_vals,"Unknown"),
+                       payload_type_str ? payload_type_str : val_to_str_ext( payload_type, &rtp_payload_type_vals_ext,"Unknown"),
                        payload_type);
 
                offset++;
@@ -1140,7 +1381,7 @@ dissect_rtp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree )
        if ( csrc_count > 0 ) {
                if ( tree ) {
                        ti = proto_tree_add_item(rtp_tree, hf_rtp_csrc_items, tvb, offset,
-                                                csrc_count * 4, FALSE);
+                                                csrc_count * 4, ENC_NA);
                        proto_item_append_text(ti, " (%u items)", csrc_count);
                        rtp_csrc_tree = proto_item_add_subtree( ti, ett_csrc_list );
                }
@@ -1166,7 +1407,7 @@ dissect_rtp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree )
                offset += 2;
                if ( hdr_extension > 0 ) {
                        if ( tree ) {
-                               ti = proto_tree_add_item(rtp_tree, hf_rtp_hdr_exts, tvb, offset, hdr_extension * 4, FALSE);
+                               ti = proto_tree_add_item(rtp_tree, hf_rtp_hdr_exts, tvb, offset, hdr_extension * 4, ENC_NA);
                                rtp_hext_tree = proto_item_add_subtree( ti, ett_hdr_ext );
                        }
 
@@ -1174,8 +1415,10 @@ dissect_rtp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree )
                        newtvb = tvb_new_subset(tvb, offset, hdr_extension * 4, hdr_extension * 4);
                        if ( !(rtp_info->info_payload_type_str && dissector_try_string(rtp_hdr_ext_dissector_table,
                                rtp_info->info_payload_type_str, newtvb, pinfo, rtp_hext_tree)) ) {
+                               hdrext_offset = offset;
                                for ( i = 0; i < hdr_extension; i++ ) {
-                                       if ( tree ) proto_tree_add_uint( rtp_hext_tree, hf_rtp_hdr_ext, tvb, offset, 4, tvb_get_ntohl( tvb, offset ) );
+                                       if ( tree ) proto_tree_add_uint( rtp_hext_tree, hf_rtp_hdr_ext, tvb, hdrext_offset, 4, tvb_get_ntohl( tvb, hdrext_offset ) );
+                                       hdrext_offset += 4;
                                }
                        }
                        offset += hdr_extension * 4;
@@ -1203,7 +1446,7 @@ dissect_rtp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree )
                        if ( tree ) proto_tree_add_text(rtp_tree, tvb, 0, 0,
                            "Frame has padding, but not all the frame data was captured");
                        call_dissector(data_handle,
-                           tvb_new_subset(tvb, offset, -1, -1),
+                           tvb_new_subset_remaining(tvb, offset),
                            pinfo, rtp_tree);
                        return;
                }
@@ -1247,7 +1490,7 @@ dissect_rtp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree )
                         * data.
                         */
                        if ( tree ) proto_tree_add_item( rtp_tree, hf_rtp_padding_data,
-                           tvb, offset, padding_count - 1, FALSE );
+                           tvb, offset, padding_count - 1, ENC_NA );
                        offset += padding_count - 1;
                }
                /*
@@ -1255,16 +1498,16 @@ dissect_rtp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree )
                 * count.
                 */
                if ( tree ) proto_tree_add_item( rtp_tree, hf_rtp_padding_count,
-                   tvb, offset, 1, FALSE );
+                   tvb, offset, 1, ENC_BIG_ENDIAN );
        }
        else {
                /*
                 * No padding.
                 */
                dissect_rtp_data( tvb, pinfo, tree, rtp_tree, offset,
-                   tvb_length_remaining( tvb, offset ),
-                   tvb_reported_length_remaining( tvb, offset ),
-                   payload_type );
+                                 tvb_length_remaining( tvb, offset ),
+                                 tvb_reported_length_remaining( tvb, offset ),
+                                 payload_type );
                rtp_info->info_payload_offset = offset;
                rtp_info->info_payload_len = tvb_length_remaining(tvb, offset);
        }
@@ -1315,9 +1558,9 @@ static void get_conv_info(packet_info *pinfo, struct _rtp_info *rtp_info)
 
                                /* Save this conversation info into packet info */
                                p_conv_packet_data = se_alloc(sizeof(struct _rtp_conversation_info));
-                               g_snprintf(p_conv_packet_data->method, MAX_RTP_SETUP_METHOD_SIZE+1, "%s", p_conv_data->method);
-                               p_conv_packet_data->method[MAX_RTP_SETUP_METHOD_SIZE]='\0';
+                               g_strlcpy(p_conv_packet_data->method, p_conv_data->method, MAX_RTP_SETUP_METHOD_SIZE+1);
                                p_conv_packet_data->frame_number = p_conv_data->frame_number;
+                               p_conv_packet_data->is_video = p_conv_data->is_video;
                                p_conv_packet_data->rtp_dyn_payload = p_conv_data->rtp_dyn_payload;
                                p_conv_packet_data->rtp_conv_info = p_conv_data->rtp_conv_info;
                                p_conv_packet_data->srtp_info = p_conv_data->srtp_info;
@@ -1341,7 +1584,7 @@ static void show_setup_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
 {
        /* Conversation and current data */
        struct _rtp_conversation_info *p_conv_data = NULL;
-               proto_tree *rtp_setup_tree;
+       proto_tree *rtp_setup_tree;
        proto_item *ti;
 
        /* Use existing packet info if available */
@@ -1376,15 +1619,14 @@ dissect_pkt_ccc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
 {
        proto_item *ti            = NULL;
        proto_tree *pkt_ccc_tree      = NULL;
-       const guint8 *ptime = tvb_get_ptr(tvb, 4, 8);
 
        if ( tree ) {
-               ti = proto_tree_add_item(tree, proto_pkt_ccc, tvb, 0, 12, FALSE);
+               ti = proto_tree_add_item(tree, proto_pkt_ccc, tvb, 0, 12, ENC_NA);
                pkt_ccc_tree = proto_item_add_subtree(ti, ett_pkt_ccc);
 
-               proto_tree_add_item(pkt_ccc_tree, hf_pkt_ccc_id, tvb, 0, 4, FALSE);
-               proto_tree_add_bytes_format(pkt_ccc_tree, hf_pkt_ccc_ts, tvb,
-                   4, 8, "NTP timestamp: %s", ntp_fmt_ts(ptime));
+               proto_tree_add_item(pkt_ccc_tree, hf_pkt_ccc_id, tvb, 0, 4, ENC_BIG_ENDIAN);
+               proto_tree_add_item(pkt_ccc_tree, hf_pkt_ccc_ts, tvb, 4, 8,
+                                   ENC_TIME_NTP|ENC_BIG_ENDIAN);
        }
 
        dissect_rtp(tvb, pinfo, tree);
@@ -1407,7 +1649,7 @@ proto_register_pkt_ccc(void)
                                BASE_DEC,
                                NULL,
                                0x0,
-                               "CCC_ID", HFILL
+                               NULL, HFILL
                        }
                },
                {
@@ -1415,11 +1657,11 @@ proto_register_pkt_ccc(void)
                        {
                                "PacketCable CCC Timestamp",
                                "pkt_ccc.ts",
-                               FT_BYTES,
-                               BASE_NONE,
+                               FT_ABSOLUTE_TIME,
+                               ABSOLUTE_TIME_UTC,
                                NULL,
                                0x0,
-                               "Timestamp", HFILL
+                               NULL, HFILL
                        }
                },
 
@@ -1432,7 +1674,6 @@ proto_register_pkt_ccc(void)
 
        module_t *pkt_ccc_module;
 
-
        proto_pkt_ccc = proto_register_protocol("PacketCable Call Content Connection",
            "PKT CCC", "pkt_ccc");
        proto_register_field_array(proto_pkt_ccc, hf, array_length(hf));
@@ -1440,7 +1681,7 @@ proto_register_pkt_ccc(void)
 
        register_dissector("pkt_ccc", dissect_pkt_ccc, proto_pkt_ccc);
 
-       pkt_ccc_module = prefs_register_protocol(proto_pkt_ccc, NULL);
+       pkt_ccc_module = prefs_register_protocol(proto_pkt_ccc, proto_reg_handoff_pkt_ccc);
 
        prefs_register_uint_preference(pkt_ccc_module, "udp_port",
                                       "UDP port",
@@ -1455,8 +1696,24 @@ proto_reg_handoff_pkt_ccc(void)
         * Register this dissector as one that can be selected by a
         * UDP port number.
         */
-       pkt_ccc_handle = find_dissector("pkt_ccc");
-       dissector_add_handle("udp.port", pkt_ccc_handle);
+       static gboolean initialized = FALSE;
+       static dissector_handle_t pkt_ccc_handle;
+       static guint saved_pkt_ccc_udp_port;
+
+       if (!initialized) {
+               pkt_ccc_handle = find_dissector("pkt_ccc");
+               dissector_add_handle("udp.port", pkt_ccc_handle);  /* for 'decode-as' */
+               initialized = TRUE;
+       } else {
+               if (saved_pkt_ccc_udp_port != 0) {
+                       dissector_delete_uint("udp.port", saved_pkt_ccc_udp_port, pkt_ccc_handle);
+               }
+       }
+
+       if (global_pkt_ccc_udp_port != 0) {
+               dissector_add_uint("udp.port", global_pkt_ccc_udp_port, pkt_ccc_handle);
+       }
+       saved_pkt_ccc_udp_port = global_pkt_ccc_udp_port;
 }
 
 /* Register RTP */
@@ -1475,7 +1732,7 @@ proto_register_rtp(void)
                                BASE_DEC,
                                VALS(rtp_version_vals),
                                0xC0,
-                               "", HFILL
+                               NULL, HFILL
                        }
                },
                {
@@ -1487,7 +1744,7 @@ proto_register_rtp(void)
                                8,
                                NULL,
                                0x20,
-                               "", HFILL
+                               NULL, HFILL
                        }
                },
                {
@@ -1499,7 +1756,7 @@ proto_register_rtp(void)
                                8,
                                NULL,
                                0x10,
-                               "", HFILL
+                               NULL, HFILL
                        }
                },
                {
@@ -1511,7 +1768,7 @@ proto_register_rtp(void)
                                BASE_DEC,
                                NULL,
                                0x0F,
-                               "", HFILL
+                               NULL, HFILL
                        }
                },
                {
@@ -1523,7 +1780,7 @@ proto_register_rtp(void)
                                8,
                                NULL,
                                0x80,
-                               "", HFILL
+                               NULL, HFILL
                        }
                },
                {
@@ -1535,7 +1792,7 @@ proto_register_rtp(void)
                                BASE_DEC,
                                NULL,
                                0x7F,
-                               "", HFILL
+                               NULL, HFILL
                        }
                },
                {
@@ -1547,7 +1804,7 @@ proto_register_rtp(void)
                                BASE_DEC,
                                NULL,
                                0x0,
-                               "", HFILL
+                               NULL, HFILL
                        }
                },
                {
@@ -1559,7 +1816,7 @@ proto_register_rtp(void)
                                BASE_DEC,
                                NULL,
                                0x0,
-                               "", HFILL
+                               NULL, HFILL
                        }
                },
                {
@@ -1571,7 +1828,7 @@ proto_register_rtp(void)
                                BASE_DEC,
                                NULL,
                                0x0,
-                               "", HFILL
+                               NULL, HFILL
                        }
                },
                {
@@ -1583,7 +1840,7 @@ proto_register_rtp(void)
                                BASE_HEX_DEC,
                                NULL,
                                0x0,
-                               "", HFILL
+                               NULL, HFILL
                        }
                },
                {
@@ -1595,7 +1852,7 @@ proto_register_rtp(void)
                                BASE_DEC,
                                NULL,
                                0x0,
-                               "", HFILL
+                               NULL, HFILL
                        }
                },
                {
@@ -1607,7 +1864,7 @@ proto_register_rtp(void)
                                BASE_DEC,
                                NULL,
                                0x0,
-                               "", HFILL
+                               NULL, HFILL
                        }
                },
                {
@@ -1619,7 +1876,7 @@ proto_register_rtp(void)
                                BASE_NONE,
                                NULL,
                                0x0,
-                               "", HFILL
+                               NULL, HFILL
                        }
                },
                {
@@ -1631,7 +1888,7 @@ proto_register_rtp(void)
                                BASE_HEX_DEC,
                                NULL,
                                0x0,
-                               "", HFILL
+                               NULL, HFILL
                        }
                },
                {
@@ -1643,7 +1900,7 @@ proto_register_rtp(void)
                                BASE_NONE,
                                NULL,
                                0x0,
-                               "", HFILL
+                               NULL, HFILL
                        }
                },
                {
@@ -1655,7 +1912,7 @@ proto_register_rtp(void)
                                BASE_DEC,
                                NULL,
                                0x0,
-                               "", HFILL
+                               NULL, HFILL
                        }
                },
                {
@@ -1664,10 +1921,10 @@ proto_register_rtp(void)
                                "Payload",
                                "rtp.payload",
                                FT_BYTES,
-                               BASE_HEX,
+                               BASE_NONE,
                                NULL,
                                0x0,
-                               "", HFILL
+                               NULL, HFILL
                        }
                },
                {
@@ -1676,10 +1933,10 @@ proto_register_rtp(void)
                                "Padding data",
                                "rtp.padding.data",
                                FT_BYTES,
-                               BASE_HEX,
+                               BASE_NONE,
                                NULL,
                                0x0,
-                               "", HFILL
+                               NULL, HFILL
                        }
                },
                {
@@ -1691,7 +1948,7 @@ proto_register_rtp(void)
                                BASE_DEC,
                                NULL,
                                0x0,
-                               "", HFILL
+                               NULL, HFILL
                        }
                },
                {
@@ -1737,7 +1994,7 @@ proto_register_rtp(void)
                                "rtp.follow",
                                FT_BOOLEAN,
                                8,
-                               TFS(&flags_set_truth),
+                               TFS(&tfs_set_notset),
                                0x80,
                                "Next header follows", HFILL
                        }
@@ -1751,7 +2008,7 @@ proto_register_rtp(void)
                                BASE_DEC,
                                NULL,
                                0xFFFC,
-                               "Timestamp Offset", HFILL
+                               NULL, HFILL
                        }
                },
                {
@@ -1763,19 +2020,19 @@ proto_register_rtp(void)
                                BASE_DEC,
                                NULL,
                                0x03FF,
-                               "Block Length", HFILL
+                               NULL, HFILL
                        }
                },
-        
+
                /* reassembly stuff */
                {&hf_rtp_fragments,
                 {"RTP Fragments", "rtp.fragments", FT_NONE, BASE_NONE, NULL, 0x0,
-                 "RTP Fragments", HFILL }
+                 NULL, HFILL }
                },
 
                {&hf_rtp_fragment,
                 {"RTP Fragment data", "rtp.fragment", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
-                 "RTP Fragment data", HFILL }
+                 NULL, HFILL }
                },
 
                {&hf_rtp_fragment_overlap,
@@ -1807,15 +2064,26 @@ proto_register_rtp(void)
                  "Defragmentation error due to illegal fragments", HFILL }
                },
 
+               {&hf_rtp_fragment_count,
+                {"Fragment count", "rtp.fragment.count",
+                 FT_UINT32, BASE_DEC, NULL, 0x0,
+                 NULL, HFILL }
+               },
+
                {&hf_rtp_reassembled_in,
                 {"RTP fragment, reassembled in frame", "rtp.reassembled_in",
                  FT_FRAMENUM, BASE_NONE, NULL, 0x0,
                  "This RTP packet is reassembled in this frame", HFILL }
                },
+               {&hf_rtp_reassembled_length,
+                {"Reassembled RTP length", "rtp.reassembled.length",
+                 FT_UINT32, BASE_DEC, NULL, 0x0,
+                 "The total length of the reassembled payload", HFILL }
+               },
                {&hf_srtp_encrypted_payload,
                 {"SRTP Encrypted Payload", "srtp.enc_payload",
                  FT_BYTES, BASE_NONE, NULL, 0x0,
-                 "SRTP Encrypted Payload", HFILL }
+                 NULL, HFILL }
                },
                {&hf_srtp_mki,
                 {"SRTP MKI", "srtp.mki",
@@ -1846,7 +2114,7 @@ proto_register_rtp(void)
 
 
        proto_rtp = proto_register_protocol("Real-Time Transport Protocol",
-           "RTP", "rtp");
+                                           "RTP", "rtp");
        proto_register_field_array(proto_rtp, hf, array_length(hf));
        proto_register_subtree_array(ett, array_length(ett));
 
@@ -1858,11 +2126,11 @@ proto_register_rtp(void)
        rtp_pt_dissector_table = register_dissector_table("rtp.pt",
                                                          "RTP payload type", FT_UINT8, BASE_DEC);
        rtp_dyn_pt_dissector_table = register_dissector_table("rtp_dyn_payload_type",
-                                                                                                   "Dynamic RTP payload type", FT_STRING, BASE_NONE);
+                                                             "Dynamic RTP payload type", FT_STRING, BASE_NONE);
 
 
-       rtp_hdr_ext_dissector_table = register_dissector_table("rtp_hdr_ext", 
-                                                                                                       "RTP header extension", FT_STRING, BASE_NONE);
+       rtp_hdr_ext_dissector_table = register_dissector_table("rtp_hdr_ext",
+                                                              "RTP header extension", FT_STRING, BASE_NONE);
 
        rtp_module = prefs_register_protocol(proto_rtp, proto_reg_handoff_rtp);
 
@@ -1885,15 +2153,16 @@ proto_register_rtp(void)
 
        prefs_register_enum_preference(rtp_module, "version0_type",
                                       "Treat RTP version 0 packets as",
-                                      "If an RTP version 0 packet is encountered, it can be treated as an invalid packet, a STUN packet, or a T.38 packet",
+                                      "If an RTP version 0 packet is encountered, it can be treated as "
+                                      "an invalid or ZRTP packet, a CLASSIC-STUN packet, or a T.38 packet",
                                       &global_rtp_version0_type,
                                       rtp_version0_types, FALSE);
-    prefs_register_uint_preference(rtp_module,
-                                   "rfc2198_payload_type", "Payload Type for RFC2198",
-                                   "Payload Type for RFC2198 Redundant Audio Data",
-                                   10,
-                                   &rtp_rfc2198_pt);
-    
+       prefs_register_uint_preference(rtp_module,
+                                      "rfc2198_payload_type", "Payload Type for RFC2198",
+                                      "Payload Type for RFC2198 Redundant Audio Data",
+                                      10,
+                                      &rtp_rfc2198_pt);
+
        register_init_routine(rtp_fragment_init);
 }
 
@@ -1901,30 +2170,30 @@ void
 proto_reg_handoff_rtp(void)
 {
        static gboolean rtp_prefs_initialized = FALSE;
+       static dissector_handle_t rtp_rfc2198_handle;
+       static guint rtp_saved_rfc2198_pt;
 
-       data_handle = find_dissector("data");
-       stun_handle = find_dissector("stun");
-       t38_handle = find_dissector("t38");
-       /*
-        * Register this dissector as one that can be selected by a
-        * UDP port number.
-        */
-       rtp_handle = find_dissector("rtp");
-       rtp_rfc2198_handle = find_dissector("rtp.rfc2198");
+       if (!rtp_prefs_initialized) {
+               rtp_handle = find_dissector("rtp");
+               rtp_rfc2198_handle = find_dissector("rtp.rfc2198");
 
-       dissector_add_handle("udp.port", rtp_handle);
+               dissector_add_handle("udp.port", rtp_handle);  /* for 'decode-as' */
+               dissector_add_string("rtp_dyn_payload_type", "red", rtp_rfc2198_handle);
+               heur_dissector_add( "udp", dissect_rtp_heur_udp,  proto_rtp);
+               heur_dissector_add("stun", dissect_rtp_heur_stun, proto_rtp);
 
-       dissector_add_string("rtp_dyn_payload_type", "red", rtp_rfc2198_handle);
+               data_handle = find_dissector("data");
+               classicstun_handle = find_dissector("classicstun");
+               classicstun_heur_handle = find_dissector("classicstun-heur");
+               t38_handle = find_dissector("t38");
+               zrtp_handle = find_dissector("zrtp");
 
-       if (rtp_prefs_initialized) {
-               dissector_delete("rtp.pt", rtp_saved_rfc2198_pt, rtp_rfc2198_handle);
-       } else {
                rtp_prefs_initialized = TRUE;
+       } else {
+               dissector_delete_uint("rtp.pt", rtp_saved_rfc2198_pt, rtp_rfc2198_handle);
        }
+       dissector_add_uint("rtp.pt", rtp_rfc2198_pt, rtp_rfc2198_handle);
        rtp_saved_rfc2198_pt = rtp_rfc2198_pt;
-       dissector_add("rtp.pt", rtp_saved_rfc2198_pt, rtp_rfc2198_handle);
-
-       heur_dissector_add( "udp", dissect_rtp_heur, proto_rtp);
 }
 
 /*