# 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/emem.h>
#include <epan/strutil.h>
-#include "log.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
} 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;
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;
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);
/* 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.
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 },
};
/* 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[] =
{
static void rtp_fragment_init(void)
{
fragment_table_init(&fragment_table);
- fid_table = g_hash_table_new(g_direct_hash, g_direct_equal);
}
void
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;
}
#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);
/* Free the hash if already exists */
rtp_free_hash_dyn_payload(p_conv_data->rtp_dyn_payload);
- g_strlcpy(p_conv_data->method, setup_method, MAX_RTP_SETUP_METHOD_SIZE);
+ 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;
}
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
version = RTP_VERSION( octet1 );
if (version == 0) {
- switch (global_rtp_version0_type) {
- case RTP0_STUN:
- call_dissector(stun_handle, tvb, pinfo, tree);
- return TRUE;
+ 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);
+ /* 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 */
+ }
}
} else if (version != 2) {
/* Unknown or unsupported version */
return FALSE;
}
- /* Was it sent between 2 even-numbered ports? */
- if ((pinfo->srcport % 2) || (pinfo->destport % 2)) {
+ /* Was it sent to an even-numbered port? */
+ 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) ||
- (payload_type >= 96 && payload_type <= 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);
}
/*
*/
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;
#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
* 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;
}
}
/* 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 );
}
*/
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;
/* 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) {
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
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
*/
#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
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
must_desegment = TRUE;
}
}
-
- /*
+
+ /*
* There were bytes left over that the higher protocol couldn't dissect so save them
*/
if(must_desegment)
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]");
}
}
/* 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;
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 */
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:
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) */
}
}
/*
* 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,
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;
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?
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 */
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++;
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 );
}
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 );
}
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;
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;
}
* 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;
}
/*
* 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);
}
/* 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;
{
/* 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 */
{
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);
BASE_DEC,
NULL,
0x0,
- "CCC_ID", HFILL
+ NULL, HFILL
}
},
{
{
"PacketCable CCC Timestamp",
"pkt_ccc.ts",
- FT_BYTES,
- BASE_NONE,
+ FT_ABSOLUTE_TIME,
+ ABSOLUTE_TIME_UTC,
NULL,
0x0,
- "Timestamp", HFILL
+ NULL, HFILL
}
},
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));
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",
* 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 */
BASE_DEC,
VALS(rtp_version_vals),
0xC0,
- "", HFILL
+ NULL, HFILL
}
},
{
8,
NULL,
0x20,
- "", HFILL
+ NULL, HFILL
}
},
{
8,
NULL,
0x10,
- "", HFILL
+ NULL, HFILL
}
},
{
BASE_DEC,
NULL,
0x0F,
- "", HFILL
+ NULL, HFILL
}
},
{
8,
NULL,
0x80,
- "", HFILL
+ NULL, HFILL
}
},
{
BASE_DEC,
NULL,
0x7F,
- "", HFILL
+ NULL, HFILL
}
},
{
BASE_DEC,
NULL,
0x0,
- "", HFILL
+ NULL, HFILL
}
},
{
BASE_DEC,
NULL,
0x0,
- "", HFILL
+ NULL, HFILL
}
},
{
BASE_DEC,
NULL,
0x0,
- "", HFILL
+ NULL, HFILL
}
},
{
BASE_HEX_DEC,
NULL,
0x0,
- "", HFILL
+ NULL, HFILL
}
},
{
BASE_DEC,
NULL,
0x0,
- "", HFILL
+ NULL, HFILL
}
},
{
BASE_DEC,
NULL,
0x0,
- "", HFILL
+ NULL, HFILL
}
},
{
BASE_NONE,
NULL,
0x0,
- "", HFILL
+ NULL, HFILL
}
},
{
BASE_HEX_DEC,
NULL,
0x0,
- "", HFILL
+ NULL, HFILL
}
},
{
BASE_NONE,
NULL,
0x0,
- "", HFILL
+ NULL, HFILL
}
},
{
BASE_DEC,
NULL,
0x0,
- "", HFILL
+ NULL, HFILL
}
},
{
"Payload",
"rtp.payload",
FT_BYTES,
- BASE_HEX,
+ BASE_NONE,
NULL,
0x0,
- "", HFILL
+ NULL, HFILL
}
},
{
"Padding data",
"rtp.padding.data",
FT_BYTES,
- BASE_HEX,
+ BASE_NONE,
NULL,
0x0,
- "", HFILL
+ NULL, HFILL
}
},
{
BASE_DEC,
NULL,
0x0,
- "", HFILL
+ NULL, HFILL
}
},
{
"rtp.follow",
FT_BOOLEAN,
8,
- TFS(&flags_set_truth),
+ TFS(&tfs_set_notset),
0x80,
"Next header follows", HFILL
}
BASE_DEC,
NULL,
0xFFFC,
- "Timestamp Offset", HFILL
+ NULL, HFILL
}
},
{
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,
"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",
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));
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);
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);
}
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);
}
/*