For proto_tree_add_item(..., proto_xxx, ...)use ENC_NA as the encoding arg.
[obnox/wireshark/wip.git] / epan / dissectors / packet-rtp.c
index f4a545c92bba12207e9b3ec01d9211e5816686e4..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>
@@ -105,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;
@@ -114,28 +108,32 @@ 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 stun_handle;
-static dissector_handle_t stun_heur_handle;
+static dissector_handle_t classicstun_handle;
+static dissector_handle_t classicstun_heur_handle;
 static dissector_handle_t t38_handle;
 static dissector_handle_t zrtp_handle;
 
@@ -204,12 +202,12 @@ 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 or ZRTP packets", RTP0_INVALID },
-       { "stun", "STUN packets", RTP0_STUN },
+       { "classicstun", "CLASSIC-STUN packets", RTP0_CLASSICSTUN },
        { "t38", "T.38 packets", RTP0_T38 },
        { NULL, NULL, 0 }
 };
@@ -221,8 +219,6 @@ static dissector_handle_t data_handle;
 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);
@@ -259,9 +255,9 @@ static guint rtp_rfc2198_pt = 99;
 
 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 },
 };
 
@@ -274,37 +270,109 @@ 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" },
@@ -339,11 +407,13 @@ const value_string rtp_payload_type_vals[] =
        { 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" },
@@ -365,14 +435,85 @@ const value_string rtp_payload_type_short_vals[] =
        { 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" },
@@ -409,6 +550,8 @@ const value_string rtp_payload_type_short_vals[] =
 
        { 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[] =
 {
@@ -430,7 +573,6 @@ static const value_string srtp_auth_alg_vals[] =
 static void rtp_fragment_init(void)
 {
        fragment_table_init(&fragment_table);
-       fid_table = g_hash_table_new(g_direct_hash, g_direct_equal);
 }
 
 void
@@ -463,7 +605,7 @@ void srtp_add_address(packet_info *pinfo,
        }
 
 #ifdef DEBUG
-       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);
+       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);
@@ -532,11 +674,10 @@ void rtp_add_address(packet_info *pinfo,
 }
 
 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
@@ -558,16 +699,16 @@ dissect_rtp_heur( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree )
                        return TRUE;
                } else {
                        switch (global_rtp_version0_type) {
-                       case RTP0_STUN:
-                               return call_dissector_only(stun_heur_handle, tvb, pinfo, tree);
-                               
+                       case RTP0_CLASSICSTUN:
+                               return call_dissector_only(classicstun_heur_handle, tvb, pinfo, tree);
+
                        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 */
                        }
@@ -578,25 +719,24 @@ dissect_rtp_heur( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree )
        }
 
        /* Was it sent to an even-numbered port? */
-       if ((pinfo->destport % 2) != 0) {
+       if (check_destport && ((pinfo->destport % 2) != 0)) {
                return FALSE;
        }
 
-       /* Get the fields in the second octet */
-       octet2 = tvb_get_guint8( tvb, offset + 1 );
-       payload_type = RTP_PAYLOAD_TYPE( octet2 );
+       dissect_rtp( tvb, pinfo, tree );
+       return TRUE;
+}
 
-       /* Check for a sensible payload type
-          (recognised static and preferred dynamic ranges) */
-       if ((payload_type <= PT_H263) ||
-               /* Alex Lindberg - Modified range to use RTP Type Names */
-           (payload_type >= PT_UNDF_96 && payload_type <= PT_UNDF_127)) {
-               dissect_rtp( tvb, pinfo, tree );
-               return TRUE;
-       }
-       else {
-               return FALSE;
-       }
+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);
 }
 
 /*
@@ -630,18 +770,18 @@ process_rtp_payload(tvbuff_t *newtvb, packet_info *pinfo, proto_tree *tree,
 #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;
                }
        }
@@ -650,7 +790,11 @@ process_rtp_payload(tvbuff_t *newtvb, packet_info *pinfo, proto_tree *tree,
        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);
@@ -661,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;
                        }
 
@@ -669,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 );
 
 }
 
@@ -935,26 +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;
@@ -1011,8 +1159,8 @@ 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;
 
@@ -1033,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:
@@ -1060,13 +1208,11 @@ dissect_rtp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree )
                 */
                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,
@@ -1101,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?
@@ -1145,44 +1292,45 @@ dissect_rtp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree )
        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 */
@@ -1204,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++;
@@ -1233,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 );
                }
@@ -1259,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 );
                        }
 
@@ -1342,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;
                }
                /*
@@ -1350,7 +1498,7 @@ 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 {
                /*
@@ -1471,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, ptime, "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);
@@ -1502,7 +1649,7 @@ proto_register_pkt_ccc(void)
                                BASE_DEC,
                                NULL,
                                0x0,
-                               "CCC_ID", HFILL
+                               NULL, HFILL
                        }
                },
                {
@@ -1510,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
                        }
                },
 
@@ -1559,12 +1706,12 @@ proto_reg_handoff_pkt_ccc(void)
                initialized = TRUE;
        } else {
                if (saved_pkt_ccc_udp_port != 0) {
-                       dissector_delete("udp.port", saved_pkt_ccc_udp_port, pkt_ccc_handle);
+                       dissector_delete_uint("udp.port", saved_pkt_ccc_udp_port, pkt_ccc_handle);
                }
        }
 
        if (global_pkt_ccc_udp_port != 0) {
-               dissector_add("udp.port", global_pkt_ccc_udp_port, pkt_ccc_handle);
+               dissector_add_uint("udp.port", global_pkt_ccc_udp_port, pkt_ccc_handle);
        }
        saved_pkt_ccc_udp_port = global_pkt_ccc_udp_port;
 }
@@ -1861,7 +2008,7 @@ proto_register_rtp(void)
                                BASE_DEC,
                                NULL,
                                0xFFFC,
-                               "Timestamp Offset", HFILL
+                               NULL, HFILL
                        }
                },
                {
@@ -1873,7 +2020,7 @@ proto_register_rtp(void)
                                BASE_DEC,
                                NULL,
                                0x03FF,
-                               "Block Length", HFILL
+                               NULL, HFILL
                        }
                },
 
@@ -1917,11 +2064,22 @@ 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,
@@ -1995,7 +2153,8 @@ 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 or ZRTP 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,
@@ -2020,20 +2179,20 @@ proto_reg_handoff_rtp(void)
 
                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, proto_rtp);
-               heur_dissector_add("stun2", dissect_rtp_heur, proto_rtp);
+               heur_dissector_add( "udp", dissect_rtp_heur_udp,  proto_rtp);
+               heur_dissector_add("stun", dissect_rtp_heur_stun, proto_rtp);
 
                data_handle = find_dissector("data");
-               stun_handle = find_dissector("stun");
-               stun_heur_handle = find_dissector("stun-heur");
+               classicstun_handle = find_dissector("classicstun");
+               classicstun_heur_handle = find_dissector("classicstun-heur");
                t38_handle = find_dissector("t38");
                zrtp_handle = find_dissector("zrtp");
 
                rtp_prefs_initialized = TRUE;
        } else {
-               dissector_delete("rtp.pt", rtp_saved_rfc2198_pt, rtp_rfc2198_handle);
+               dissector_delete_uint("rtp.pt", rtp_saved_rfc2198_pt, rtp_rfc2198_handle);
        }
-       dissector_add("rtp.pt", rtp_rfc2198_pt, rtp_rfc2198_handle);
+       dissector_add_uint("rtp.pt", rtp_rfc2198_pt, rtp_rfc2198_handle);
        rtp_saved_rfc2198_pt = rtp_rfc2198_pt;
 }