#include "config.h"
+#include <stdlib.h>
#include <string.h>
#include <ctype.h>
+#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
+#endif
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#endif
#ifdef HAVE_WINSOCK2_H
-#include <winsock2.h> /* needed to define AF_ values on Windows */
+#include <winsock2.h> /* needed to define AF_ values on Windows */
#endif
#ifdef NEED_INET_V6DEFS_H
-# include "inet_v6defs.h"
+# include "wsutil/inet_v6defs.h"
#endif
#include <glib.h>
#include <epan/packet.h>
-#include <epan/conversation.h>
#include <epan/strutil.h>
#include <epan/emem.h>
#include <epan/base64.h>
#include <epan/asn1.h>
-#include "tap.h"
+#include <epan/tap.h>
#include "packet-sdp.h"
#include "packet-rtp.h"
#include "packet-msrp.h"
#include "packet-per.h"
#include "packet-h245.h"
+#include "packet-h264.h"
+#include "packet-mp4ves.h"
-static dissector_handle_t rtp_handle=NULL;
-static dissector_handle_t rtcp_handle=NULL;
-static dissector_handle_t t38_handle=NULL;
-static dissector_handle_t msrp_handle=NULL;
+static dissector_handle_t rtp_handle = NULL;
+static dissector_handle_t rtcp_handle = NULL;
+static dissector_handle_t t38_handle = NULL;
+static dissector_handle_t msrp_handle = NULL;
+static dissector_handle_t h264_handle = NULL;
+static dissector_handle_t mp4ves_handle = NULL;
static int sdp_tap = -1;
static int hf_media_attribute_field = -1;
static int hf_media_attribute_value = -1;
static int hf_media_encoding_name = -1;
+static int hf_media_sample_rate = -1;
static int hf_media_format_specific_parameter = -1;
-static int hf_sdp_fmtp_profile_level_id = -1;
+static int hf_sdp_fmtp_mpeg4_profile_level_id = -1;
static int hf_sdp_fmtp_h263_profile = -1;
+static int hf_sdp_fmtp_h263_level = -1;
+static int hf_sdp_h264_packetization_mode = -1;
+static int hf_sdp_h264_sprop_parameter_sets = -1;
static int hf_SDPh223LogicalChannelParameters = -1;
/* hf_session_attribute hf_media_attribute subfields */
#define SDP_MAX_RTP_CHANNELS 4
#define SDP_MAX_RTP_PAYLOAD_TYPES 20
-
+#define SDP_NO_OF_PT 128
typedef struct {
gint32 pt[SDP_MAX_RTP_PAYLOAD_TYPES];
gint8 pt_count;
typedef struct {
char *connection_address;
char *connection_type;
- char *encoding_name;
+ char *media_type;
+ char *encoding_name[SDP_NO_OF_PT];
+ int sample_rate[SDP_NO_OF_PT];
char *media_port[SDP_MAX_RTP_CHANNELS];
char *media_proto[SDP_MAX_RTP_CHANNELS];
transport_media_pt_t media[SDP_MAX_RTP_CHANNELS];
/* static functions */
-static void call_sdp_subdissector(tvbuff_t *tvb, packet_info *pinfo, int hf, proto_tree* ti,
+static void call_sdp_subdissector(tvbuff_t *tvb, packet_info *pinfo, int hf, proto_tree* ti, int length,
transport_info_t *transport_info);
/* Subdissector functions */
static void dissect_sdp_session_attribute(tvbuff_t *tvb, packet_info *pinfo, proto_item *ti);
static void dissect_sdp_media(tvbuff_t *tvb, proto_item *ti,
transport_info_t *transport_info);
-static void dissect_sdp_media_attribute(tvbuff_t *tvb, packet_info *pinfo, proto_item *ti, transport_info_t *transport_info);
+static void dissect_sdp_media_attribute(tvbuff_t *tvb, packet_info *pinfo, proto_item *ti, int length,transport_info_t *transport_info);
+
+static void free_encoding_name_str (void *ptr)
+{
+ encoding_name_and_rate_t *encoding_name_and_rate = (encoding_name_and_rate_t *)ptr;
+
+ if (encoding_name_and_rate->encoding_name) {
+ g_free(encoding_name_and_rate->encoding_name);
+ }
+}
static void
dissect_sdp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
gboolean set_rtp=FALSE;
gboolean is_ipv4_addr=FALSE;
gboolean is_ipv6_addr=FALSE;
+ gboolean is_video=FALSE;
guint32 ipaddr[4];
gint n,i;
sdp_packet_info *sdp_pi;
+ gchar *unknown_encoding = ep_strdup("Unknown");
/* Initialise packet info for passing to tap */
sdp_pi = ep_alloc(sizeof(sdp_packet_info));
/* Initialise RTP channel info */
transport_info.connection_address=NULL;
transport_info.connection_type=NULL;
- transport_info.encoding_name=NULL;
+ transport_info.media_type=NULL;
+ for (n=0; n < SDP_NO_OF_PT; n++){
+ transport_info.encoding_name[n]=unknown_encoding;
+ transport_info.sample_rate[n] = 0;
+ }
for (n=0; n < SDP_MAX_RTP_CHANNELS; n++)
{
transport_info.media_port[n]=NULL;
transport_info.media_proto[n]=NULL;
transport_info.media[n].pt_count = 0;
-#if GLIB_MAJOR_VERSION < 2
- transport_info.media[n].rtp_dyn_payload = g_hash_table_new( g_int_hash,
- g_int_equal);
-#else
- transport_info.media[n].rtp_dyn_payload = g_hash_table_new_full( g_int_hash,
- g_int_equal, g_free, g_free);
-#endif
+ transport_info.media[n].rtp_dyn_payload =
+ g_hash_table_new_full( g_int_hash, g_int_equal, g_free, free_encoding_name_str);
}
transport_info.media_count = 0;
* what the protocol inside which the SDP stuff resides
* put there.
*/
- if (check_col(pinfo->cinfo, COL_PROTOCOL))
- col_append_str(pinfo->cinfo, COL_PROTOCOL, "/SDP");
+ col_append_str(pinfo->cinfo, COL_PROTOCOL, "/SDP");
- if (check_col(pinfo->cinfo, COL_INFO)) {
- /* XXX: Needs description. */
- col_append_str(pinfo->cinfo, COL_INFO, ", with session description");
- }
+ /* XXX: Needs description. */
+ col_append_str(pinfo->cinfo, COL_INFO, ", with session description");
ti = proto_tree_add_item(tree, proto_sdp, tvb, offset, -1, FALSE);
sdp_tree = proto_item_add_subtree(ti, ett_sdp);
type = tvb_get_guint8(tvb,offset);
delim = tvb_get_guint8(tvb,offset + 1);
if (delim != '=') {
- proto_item *ti = proto_tree_add_item(sdp_tree, hf_invalid, tvb, offset, linelen, FALSE);
- expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_NOTE,
+ proto_item *ti2 = proto_tree_add_item(sdp_tree, hf_invalid, tvb, offset, linelen, FALSE);
+ expert_add_info_format(pinfo, ti2, PI_MALFORMED, PI_NOTE,
"Invalid SDP line (no '=' delimiter)");
offset = next_offset;
continue;
call_sdp_subdissector(tvb_new_subset(tvb,offset+tokenoffset,
linelen-tokenoffset,
linelen-tokenoffset),
- pinfo,
- hf,sub_ti,&transport_info),
+ pinfo,
+ hf,sub_ti,linelen-tokenoffset,&transport_info),
offset = next_offset;
}
* and stream decoding is enabled in preferences
*/
if(global_sdp_establish_conversation){
- /* Check if media protocol is RTP */
- is_rtp = (strcmp(transport_info.media_proto[n],"RTP/AVP")==0);
- /* Check if media protocol is SRTP */
- is_srtp = (strcmp(transport_info.media_proto[n],"RTP/SAVP")==0);
- /* Check if media protocol is T38 */
- is_t38 = ( (strcmp(transport_info.media_proto[n],"UDPTL")==0) || (strcmp(transport_info.media_proto[n],"udptl")==0) );
- /* Check if media protocol is MSRP/TCP */
- is_msrp = (strcmp(transport_info.media_proto[n],"msrp/tcp")==0);
+ /* Check if media protocol is RTP */
+ is_rtp = (strcmp(transport_info.media_proto[n],"RTP/AVP")==0);
+ /* Check if media protocol is SRTP */
+ is_srtp = (strcmp(transport_info.media_proto[n],"RTP/SAVP")==0);
+ /* Check if media protocol is T38 */
+ is_t38 = ( (strcmp(transport_info.media_proto[n],"UDPTL")==0) ||
+ (strcmp(transport_info.media_proto[n],"udptl")==0) );
+ /* Check if media protocol is MSRP/TCP */
+ is_msrp = (strcmp(transport_info.media_proto[n],"msrp/tcp")==0);
}
}
}
}
}
+ if (strcmp(transport_info.media_type,"video")==0){
+ is_video = TRUE;
+ }
set_rtp = FALSE;
/* Add (s)rtp and (s)rtcp conversation, if available (overrides t38 if conversation already set) */
if((!pinfo->fd->flags.visited) && port!=0 && (is_rtp||is_srtp) && (is_ipv4_addr || is_ipv6_addr)){
if(rtp_handle){
if (is_srtp) {
struct srtp_info *dummy_srtp_info = se_alloc0(sizeof(struct srtp_info));
- srtp_add_address(pinfo, &src_addr, port, 0, "SDP", pinfo->fd->num,
+ srtp_add_address(pinfo, &src_addr, port, 0, "SDP", pinfo->fd->num, is_video,
transport_info.media[n].rtp_dyn_payload, dummy_srtp_info);
} else {
- rtp_add_address(pinfo, &src_addr, port, 0, "SDP", pinfo->fd->num,
+ rtp_add_address(pinfo, &src_addr, port, 0, "SDP", pinfo->fd->num, is_video,
transport_info.media[n].rtp_dyn_payload);
}
set_rtp = TRUE;
/* Add MSRP conversation. Uses addresses discovered in attribute
rather than connection information of media session line */
if (is_msrp ){
- if ((!pinfo->fd->flags.visited) && msrp_transport_address_set){
- if(msrp_handle){
- src_addr.type=AT_IPv4;
- src_addr.len=4;
- src_addr.data=(guint8*)&msrp_ipaddr;
- msrp_add_address(pinfo, &src_addr, msrp_port_number, "SDP", pinfo->fd->num);
- }
+ if ((!pinfo->fd->flags.visited) && msrp_transport_address_set){
+ if(msrp_handle){
+ src_addr.type=AT_IPv4;
+ src_addr.len=4;
+ src_addr.data=(guint8*)&msrp_ipaddr;
+ msrp_add_address(pinfo, &src_addr, msrp_port_number, "SDP", pinfo->fd->num);
}
+ }
}
- /* Create the RTP summary str for the Voip Call analysis */
- for (i = 0; i < transport_info.media[n].pt_count; i++)
- {
- /* if the payload type is dynamic (96 to 127), check the hash table to add the desc in the SDP summary */
- if ( (transport_info.media[n].pt[i] >=96) && (transport_info.media[n].pt[i] <=127) ) {
- gchar *str_dyn_pt = g_hash_table_lookup(transport_info.media[n].rtp_dyn_payload, &transport_info.media[n].pt[i]);
- if (str_dyn_pt)
- g_snprintf(sdp_pi->summary_str, 50, "%s %s", sdp_pi->summary_str, str_dyn_pt);
- else
- g_snprintf(sdp_pi->summary_str, 50, "%s %d", sdp_pi->summary_str, transport_info.media[n].pt[i]);
- } else
- g_snprintf(sdp_pi->summary_str, 50, "%s %s", sdp_pi->summary_str, val_to_str(transport_info.media[n].pt[i], rtp_payload_type_short_vals, "%u"));
+ if (port!=0) {
+ /* Create the RTP summary str for the Voip Call analysis */
+ for (i = 0; i < transport_info.media[n].pt_count; i++)
+ {
+ /* if the payload type is dynamic (96 to 127), check the hash table to add the desc in the SDP summary */
+ if ( (transport_info.media[n].pt[i] >=96) && (transport_info.media[n].pt[i] <=127) ) {
+ encoding_name_and_rate_t *encoding_name_and_rate_pt = g_hash_table_lookup(transport_info.media[n].rtp_dyn_payload, &transport_info.media[n].pt[i]);
+ if (encoding_name_and_rate_pt) {
+ if (strlen(sdp_pi->summary_str)) g_strlcat(sdp_pi->summary_str, " ", 50);
+ g_strlcat(sdp_pi->summary_str, encoding_name_and_rate_pt->encoding_name, 50);
+ } else {
+ char num_pt[10];
+ g_snprintf(num_pt, 10, "%u", transport_info.media[n].pt[i]);
+ if (strlen(sdp_pi->summary_str)) g_strlcat(sdp_pi->summary_str, " ", 50);
+ g_strlcat(sdp_pi->summary_str, num_pt, 50);
+ }
+ } else
+ if (strlen(sdp_pi->summary_str)) g_strlcat(sdp_pi->summary_str, " ", 50);
+ g_strlcat(sdp_pi->summary_str, val_to_str_ext(transport_info.media[n].pt[i], &rtp_payload_type_short_vals_ext, "%u"), 50);
+ }
}
/* Free the hash table if we did't assigned it to a conv use it */
rtp_free_hash_dyn_payload(transport_info.media[n].rtp_dyn_payload);
/* Create the T38 summary str for the Voip Call analysis */
- if (is_t38) g_snprintf(sdp_pi->summary_str, 50, "%s t38", sdp_pi->summary_str);
+ if (port!=0 && is_t38) {
+ if (strlen(sdp_pi->summary_str)) g_strlcat(sdp_pi->summary_str, " ", 50);
+ g_strlcat(sdp_pi->summary_str, "t38", 50);
+ }
}
/* Free the remainded hash tables not used */
}
static void
-call_sdp_subdissector(tvbuff_t *tvb, packet_info *pinfo, int hf, proto_tree* ti, transport_info_t *transport_info){
+call_sdp_subdissector(tvbuff_t *tvb, packet_info *pinfo, int hf, proto_tree* ti, int length,transport_info_t *transport_info){
if(hf == hf_owner){
dissect_sdp_owner(tvb,ti);
} else if ( hf == hf_connection_info) {
} else if ( hf == hf_media ) {
dissect_sdp_media(tvb,ti,transport_info);
} else if ( hf == hf_media_attribute ){
- dissect_sdp_media_attribute(tvb,pinfo,ti,transport_info);
+ dissect_sdp_media_attribute(tvb,pinfo,ti, length, transport_info);
}
}
item = proto_tree_add_item(sdp_bandwidth_tree, hf_bandwidth_modifier, tvb, offset,
tokenlen, FALSE);
if (tvb_strneql(tvb, offset, "CT", 2) == 0){
- proto_item_append_text(item, " [Conference Total(total bandwidth of all RTP sessions)]");
- unit_is_kbs = TRUE;
+ proto_item_append_text(item, " [Conference Total(total bandwidth of all RTP sessions)]");
+ unit_is_kbs = TRUE;
}else if (tvb_strneql(tvb, offset, "AS", 2) == 0){
- proto_item_append_text(item, " [Application Specific (RTP session bandwidth)]");
- unit_is_kbs = TRUE;
+ proto_item_append_text(item, " [Application Specific (RTP session bandwidth)]");
+ unit_is_kbs = TRUE;
}else if (tvb_strneql(tvb, offset, "TIAS", 4) == 0){
- proto_item_append_text(item, " [Transport Independent Application Specific maximum]");
- unit_is_bps = TRUE;
+ proto_item_append_text(item, " [Transport Independent Application Specific maximum]");
+ unit_is_bps = TRUE;
}
item = proto_tree_add_item(sdp_bandwidth_tree, hf_bandwidth_value, tvb, offset, -1,
FALSE);
if (unit_is_kbs == TRUE)
- proto_item_append_text(item, " kb/s");
+ proto_item_append_text(item, " kb/s");
if (unit_is_bps == TRUE)
- proto_item_append_text(item, " b/s");
+ proto_item_append_text(item, " b/s");
}
static void dissect_sdp_time(tvbuff_t *tvb, proto_item* ti){
tvb, offset, -1, FALSE);
}
-/* Return a tvb that contains the binary representation of a base64
- string */
-
-static tvbuff_t *
-base64_to_tvb(const char *base64)
-{
- tvbuff_t *tvb;
- char *data = g_strdup(base64);
- size_t len;
-
- len = epan_base64_decode(data);
- tvb = tvb_new_real_data((const guint8 *)data, len, len);
-
- tvb_set_free_cb(tvb, g_free);
-
- return tvb;
-}
-
-
static void dissect_key_mgmt(tvbuff_t *tvb, packet_info * pinfo, proto_item * ti){
- gchar *data = NULL;
+ gchar *data_p = NULL;
gchar *prtcl_id = NULL;
gint len;
tvbuff_t *keymgmt_tvb;
if (len < 0)
return;
- data = tvb_get_ephemeral_string(tvb, offset, len);
- keymgmt_tvb = base64_to_tvb(data);
- tvb_set_child_real_data_tvbuff(tvb, keymgmt_tvb);
+ data_p = tvb_get_ephemeral_string(tvb, offset, len);
+ keymgmt_tvb = base64_to_tvb(tvb, data_p);
add_new_data_source(pinfo, keymgmt_tvb, "Key Management Data");
if ( prtcl_id != NULL && key_mgmt_dissector_table != NULL ) {
found_match = dissector_try_string(key_mgmt_dissector_table,
- prtcl_id,
- keymgmt_tvb, pinfo,
- key_tree);
+ prtcl_id,
+ keymgmt_tvb, pinfo,
+ key_tree);
}
- if (found_match)
- proto_tree_add_item_hidden(key_tree, hf_key_mgmt_data,
- keymgmt_tvb, 0, -1, FALSE);
- else
+ if (found_match) {
+ proto_item *ti2 = proto_tree_add_item(key_tree, hf_key_mgmt_data,
+ keymgmt_tvb, 0, -1, FALSE);
+ PROTO_ITEM_SET_HIDDEN(ti2);
+ }
+ else {
proto_tree_add_item(key_tree, hf_key_mgmt_data,
- keymgmt_tvb, 0, -1, FALSE);
- return;
+ keymgmt_tvb, 0, -1, FALSE);
+ }
+
}
offset = next_offset + 1;
if (strcmp((char*)field_name, "ipbcp") == 0) {
- offset = tvb_pbrk_guint8(tvb,offset,-1,(guint8 *)"0123456789");
+ offset = tvb_pbrk_guint8(tvb,offset,-1,(guint8 *)"0123456789", NULL);
if (offset == -1)
return;
proto_tree_add_item(sdp_session_attribute_tree,hf_ipbcp_version,tvb,offset,tokenlen,FALSE);
- offset = tvb_pbrk_guint8(tvb,offset,-1,(guint8 *)"ABCDEFGHIJKLMNOPQRSTUVWXYZ");
+ offset = tvb_pbrk_guint8(tvb,offset,-1,(guint8 *)"ABCDEFGHIJKLMNOPQRSTUVWXYZ", NULL);
if (offset == -1)
return;
tvbuff_t *key_tvb;
proto_item *key_ti;
- key_tvb = tvb_new_subset(tvb, offset, -1, -1);
+ key_tvb = tvb_new_subset_remaining(tvb, offset);
key_ti = proto_tree_add_item(sdp_session_attribute_tree, hf_key_mgmt_att_value, key_tvb, 0, -1, FALSE);
dissect_key_mgmt(key_tvb, pinfo, key_ti);
}
}
+
+/* Dissect media description */
static void
dissect_sdp_media(tvbuff_t *tvb, proto_item *ti,
transport_info_t *transport_info){
proto_tree *sdp_media_tree;
- gint offset, next_offset, tokenlen, index;
+ gint offset, next_offset, tokenlen, idx;
guint8 *media_format;
offset = 0;
/* Re-initialise for a new media description */
msrp_transport_address_set = FALSE;
+ /* Create tree for media session */
sdp_media_tree = proto_item_add_subtree(ti,ett_sdp_media);
next_offset = tvb_find_guint8(tvb,offset, -1, ' ');
tokenlen = next_offset - offset;
+ /* Type of media session */
proto_tree_add_item(sdp_media_tree, hf_media_media, tvb, offset, tokenlen,
FALSE);
+ transport_info->media_type = (char*)tvb_get_ephemeral_string(tvb, offset, tokenlen);
+
offset = next_offset + 1;
next_offset = tvb_find_guint8(tvb,offset, -1, ' ');
proto_tree_add_item(sdp_media_tree, hf_media_proto, tvb, offset, tokenlen,
FALSE);
- do{
+ do {
offset = next_offset + 1;
next_offset = tvb_find_guint8(tvb,offset,-1,' ');
"RTP/AVP") == 0) {
media_format = tvb_get_ephemeral_string(tvb, offset, tokenlen);
proto_tree_add_string(sdp_media_tree, hf_media_format, tvb, offset,
- tokenlen, val_to_str(atol((char*)media_format), rtp_payload_type_vals, "%u"));
- index = transport_info->media[transport_info->media_count].pt_count;
- transport_info->media[transport_info->media_count].pt[index] = atol((char*)media_format);
- if (index < (SDP_MAX_RTP_PAYLOAD_TYPES-1))
+ tokenlen, val_to_str_ext(atol((char*)media_format), &rtp_payload_type_vals_ext, "%u"));
+ idx = transport_info->media[transport_info->media_count].pt_count;
+ transport_info->media[transport_info->media_count].pt[idx] = atol((char*)media_format);
+ if (idx < (SDP_MAX_RTP_PAYLOAD_TYPES-1))
transport_info->media[transport_info->media_count].pt_count++;
} else {
proto_tree_add_item(sdp_media_tree, hf_media_format, tvb, offset,
}
-/*
-14496-2, Annex G, Table G-1.
-Table G-1 FLC table for profile_and_level_indication Profile/Level Code
-*/
-static const value_string mpeg4es_level_indication_vals[] =
+static tvbuff_t *
+ascii_bytes_to_tvb(tvbuff_t *tvb, packet_info *pinfo, gint len, gchar *msg)
{
- { 0, "Reserved" },
- { 1, "Simple Profile/Level 1" },
- { 2, "Simple Profile/Level 2" },
- { 3, "Reserved" },
- { 4, "Reserved" },
- { 5, "Reserved" },
- { 6, "Reserved" },
- { 7, "Reserved" },
- { 8, "Simple Profile/Level 0" },
- { 9, "Simple Profile/Level 0b" },
- /* Reserved 00001001 - 00010000 */
- { 0x11, "Simple Scalable Profile/Level 1" },
- { 0x12, "Simple Scalable Profile/Level 2" },
- /* Reserved 00010011 - 00100000 */
- { 0x21, "Core Profile/Level 1" },
- { 0x22, "Core Profile/Level 2" },
- /* Reserved 00100011 - 00110001 */
- { 0x32, "Main Profile/Level 2" },
- { 0x33, "Main Profile/Level 3" },
- { 0x34, "Main Profile/Level 4" },
- /* Reserved 00110101 - 01000001 */
- { 0x42, "N-bit Profile/Level 2" },
- /* Reserved 01000011 - 01010000 */
- { 0x51, "Scalable Texture Profile/Level 1" },
- /* Reserved 01010010 - 01100000 */
- { 0x61, "Simple Face Animation Profile/Level 1" },
- { 0x62, "Simple Face Animation Profile/Level 2" },
- { 0x63, "Simple FBA Profile/Level 1" },
- { 0x64, "Simple FBA Profile/Level 2" },
- /* Reserved 01100101 - 01110000 */
- { 0x71, "Basic Animated Texture Profile/Level 1" },
- { 0x72, "Basic Animated Texture Profile/Level 2" },
- /* Reserved 01110011 - 10000000 */
- { 0x81, "Hybrid Profile/Level 1" },
- { 0x82, "Hybrid Profile/Level 2" },
- /* Reserved 10000011 - 10010000 */
- { 0x91, "Advanced Real Time Simple Profile/Level 1" },
- { 0x92, "Advanced Real Time Simple Profile/Level 2" },
- { 0x93, "Advanced Real Time Simple Profile/Level 3" },
- { 0x94, "Advanced Real Time Simple Profile/Level 4" },
- /* Reserved 10010101 - 10100000 */
- { 0xa1, "Core Scalable Profile/Level 1" },
- { 0xa2, "Core Scalable Profile/Level 2" },
- { 0xa3, "Core Scalable Profile/Level 3" },
- /* Reserved 10100100 - 10110000 */
- { 0xb1, "Advanced Coding Efficiency Profile/Level 1" },
- { 0xb2, "Advanced Coding Efficiency Profile/Level 2" },
- { 0xb3, "Advanced Coding Efficiency Profile/Level 3" },
- { 0xb4, "Advanced Coding Efficiency Profile/Level 4" },
- /* Reserved 10110101 - 11000000 */
- { 0xc1, "Advanced Core Profile/Level 1" },
- { 0xc2, "Advanced Core Profile/Level 2" },
- /* Reserved 11000011 - 11010000 */
- { 0xd1, "Advanced Scalable Texture/Level 1" },
- { 0xd2, "Advanced Scalable Texture/Level 2" },
- { 0xd3, "Advanced Scalable Texture/Level 3" },
- /* Reserved 11010100 - 11100000 */
- { 0xe1, "Simple Studio Profile/Level 1" },
- { 0xe2, "Simple Studio Profile/Level 2" },
- { 0xe3, "Simple Studio Profile/Level 3" },
- { 0xe4, "Simple Studio Profile/Level 4" },
- { 0xe5, "Core Studio Profile/Level 1" },
- { 0xe6, "Core Studio Profile/Level 2" },
- { 0xe7, "Core Studio Profile/Level 3" },
- { 0xe8, "Core Studio Profile/Level 4" },
- /* Reserved 11101001 - 11101111 */
- { 0xf0, "Advanced Simple Profile/Level 0" },
- { 0xf1, "Advanced Simple Profile/Level 1" },
- { 0xf2, "Advanced Simple Profile/Level 2" },
- { 0xf3, "Advanced Simple Profile/Level 3" },
- { 0xf4, "Advanced Simple Profile/Level 4" },
- { 0xf5, "Advanced Simple Profile/Level 5" },
- /* Reserved 11110110 - 11110111 */
- { 0xf8, "Fine Granularity Scalable Profile/Level 0" },
- { 0xf9, "Fine Granularity Scalable Profile/Level 1" },
- { 0xfa, "Fine Granularity Scalable Profile/Level 2" },
- { 0xfb, "Fine Granularity Scalable Profile/Level 3" },
- { 0xfc, "Fine Granularity Scalable Profile/Level 4" },
- { 0xfd, "Fine Granularity Scalable Profile/Level 5" },
- { 0xfe, "Reserved" },
- { 0xff, "Reserved for Escape" },
- { 0, NULL },
-};
+ guint8 *buf = g_malloc(10240);
+
+ /* arbitrary maximum length */
+ if(len<20480){
+ int i;
+ tvbuff_t *bytes_tvb;
+
+ /* first, skip to where the encoded pdu starts, this is
+ the first hex digit after the '=' char.
+ */
+ while(1){
+ if((*msg==0)||(*msg=='\n')){
+ return NULL;
+ }
+ if(*msg=='='){
+ msg++;
+ break;
+ }
+ msg++;
+ }
+ while(1){
+ if((*msg==0)||(*msg=='\n')){
+ return NULL;
+ }
+ if( ((*msg>='0')&&(*msg<='9'))
+ || ((*msg>='a')&&(*msg<='f'))
+ || ((*msg>='A')&&(*msg<='F'))){
+ break;
+ }
+ msg++;
+ }
+ i=0;
+ while( ((*msg>='0')&&(*msg<='9'))
+ ||((*msg>='a')&&(*msg<='f'))
+ ||((*msg>='A')&&(*msg<='F')) ){
+ int val;
+ if((*msg>='0')&&(*msg<='9')){
+ val=(*msg)-'0';
+ } else if((*msg>='a')&&(*msg<='f')){
+ val=(*msg)-'a'+10;
+ } else if((*msg>='A')&&(*msg<='F')){
+ val=(*msg)-'A'+10;
+ } else {
+ return NULL;
+ }
+ val<<=4;
+ msg++;
+ if((*msg>='0')&&(*msg<='9')){
+ val|=(*msg)-'0';
+ } else if((*msg>='a')&&(*msg<='f')){
+ val|=(*msg)-'a'+10;
+ } else if((*msg>='A')&&(*msg<='F')){
+ val|=(*msg)-'A'+10;
+ } else {
+ return NULL;
+ }
+ msg++;
+
+ buf[i]=(guint8)val;
+ i++;
+ }
+ if(i==0){
+ return NULL;
+ }
+ bytes_tvb = tvb_new_child_real_data(tvb, buf,i,i);
+ tvb_set_free_cb(bytes_tvb, g_free);
+ add_new_data_source(pinfo, bytes_tvb, "ASCII bytes to tvb");
+ return bytes_tvb;
+ }
+ return NULL;
+}
+
/* Annex X Profiles and levels definition */
static const value_string h263_profile_vals[] =
{
{ 0, NULL },
};
+
+/* RFC 4629 The level are described in table X.2 of H.263 annex X */
+static const value_string h263_level_vals[] =
+{
+ { 10, "QCIF (176 x 144), 1 x 64Kb/s" },
+ { 20, "CIF (352 x 288), 2 x 64Kb/s" },
+ { 30, "CIF (352 x 288), 6 x 64Kb/s" },
+ { 40, "CIF (352 x 288), 32 x 64Kb/s" },
+ { 45, "QCIF (176 x144) support of CPFMT, 2 x 64Kb/s" },
+ { 50, "CIF (352 x 288) support of CPFMT, 64 x 64Kb/s" },
+ { 60, "CPFMT: 720 x 288 support of CPFMT, 128 x 64Kb/s" },
+ { 70, "CPFMT: 720 x 576 support of CPFMT, 256 x 64Kb/s" },
+ { 0, NULL },
+};
+
+
+static const value_string h264_packetization_mode_vals[] =
+{
+ { 0, "Single NAL mode" },
+ { 1, "Non-interleaved mode" },
+ { 2, "Interleaved mode" },
+ { 0, NULL },
+};
+
/*
* TODO: Make this a more generic routine to dissect fmtp parameters depending on media types
*/
static void
-decode_sdp_fmtp(proto_tree *tree, tvbuff_t *tvb, gint offset, gint tokenlen, guint8 *mime_type){
+decode_sdp_fmtp(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, gint offset, gint tokenlen, char *mime_type){
gint next_offset;
gint end_offset;
guint8 *field_name;
- guint8 *format_specific_parameter;
+ gchar *format_specific_parameter;
proto_item *item;
+ tvbuff_t *data_tvb;
end_offset = offset + tokenlen;
+ /*
+ proto_tree_add_text(tree, tvb, offset, tokenlen, "Debug; Analysed string: '%s'",
+ tvb_get_ephemeral_string(tvb, offset, tokenlen));
+ */
+
/* Look for an '=' within this value - this may indicate that there is a
profile-level-id parameter to find if the MPEG4 media type is in use */
next_offset = tvb_find_guint8(tvb,offset,-1,'=');
/* Find the name of the parameter */
tokenlen = next_offset - offset;
field_name = tvb_get_ephemeral_string(tvb, offset, tokenlen);
+ /*proto_tree_add_text(tree, tvb, offset, tokenlen, "Debug; MIMEtype '%s'Parameter name: '%s'", mime_type, field_name); */
offset = next_offset;
/* Dissect the MPEG4 profile-level-id parameter if present */
- if (mime_type != NULL && strcmp((char*)mime_type, "MP4V-ES") == 0) {
+ if (mime_type != NULL && g_ascii_strcasecmp(mime_type, "MP4V-ES") == 0) {
if (strcmp((char*)field_name, "profile-level-id") == 0) {
offset++;
tokenlen = end_offset - offset;
format_specific_parameter = tvb_get_ephemeral_string(tvb, offset, tokenlen);
- item = proto_tree_add_uint(tree, hf_sdp_fmtp_profile_level_id, tvb, offset, tokenlen,
+ item = proto_tree_add_uint(tree, hf_sdp_fmtp_mpeg4_profile_level_id, tvb, offset, tokenlen,
atol((char*)format_specific_parameter));
PROTO_ITEM_SET_GENERATED(item);
+ } else if (strcmp((char*)field_name, "config") == 0) {
+ /* String including "=" */
+ tokenlen = end_offset - offset;
+ format_specific_parameter = tvb_get_ephemeral_string(tvb, offset, tokenlen);
+ /* ascii_bytes_to_tvb requires the "=" to be in the buffer */
+ data_tvb = ascii_bytes_to_tvb(tvb, pinfo, tokenlen, format_specific_parameter);
+ if(mp4ves_handle && data_tvb){
+ dissect_mp4ves_config(data_tvb, pinfo, tree);
+ }
}
}
/* Dissect the H263-2000 profile parameter if present */
- if (mime_type != NULL && strcmp((char*)mime_type, "H263-2000") == 0) {
+ if ((mime_type != NULL && g_ascii_strcasecmp(mime_type, "H263-2000") == 0)||(mime_type != NULL && g_ascii_strcasecmp(mime_type, "H263-1998") == 0)) {
if (strcmp((char*)field_name, "profile") == 0) {
offset++;
tokenlen = end_offset - offset;
item = proto_tree_add_uint(tree, hf_sdp_fmtp_h263_profile, tvb, offset, tokenlen,
atol((char*)format_specific_parameter));
PROTO_ITEM_SET_GENERATED(item);
+ } else if(strcmp((char*)field_name, "level") == 0) {
+ offset++;
+ tokenlen = end_offset - offset;
+ format_specific_parameter = tvb_get_ephemeral_string(tvb, offset, tokenlen);
+ item = proto_tree_add_uint(tree, hf_sdp_fmtp_h263_level, tvb, offset, tokenlen,
+ atol((char*)format_specific_parameter));
+ PROTO_ITEM_SET_GENERATED(item);
}
}
-#if 0
- /* TODO: Add code to dissect H264 fmtp parameters wehen an example can be found */
- if (mime_type != NULL && strcmp(mime_type, "H264") == 0) {
+
+ /* Dissect the H264 profile-level-id parameter
+ * RFC 3984:
+ * A base16 [6] (hexadecimal) representation of
+ * the following three bytes in the sequence
+ * parameter set NAL unit specified in [1]: 1)
+ * profile_idc, 2) a byte herein referred to as
+ * profile-iop, composed of the values of
+ * constraint_set0_flag, constraint_set1_flag,
+ * constraint_set2_flag, and reserved_zero_5bits
+ * in bit-significance order, starting from the
+ * most significant bit, and 3) level_idc.
+ */
+ if (mime_type != NULL && g_ascii_strcasecmp(mime_type, "H264") == 0) {
if (strcmp(field_name, "profile-level-id") == 0) {
- char **endptr;
+ int length = 0;
+ /* Length includes "=" as it's required by ascii_bytes_to_tvb()*/
+ tokenlen = end_offset - offset;
+ format_specific_parameter = tvb_get_ephemeral_string(tvb, offset, tokenlen);
+ data_tvb = ascii_bytes_to_tvb(tvb, pinfo, tokenlen, format_specific_parameter);
+ if(!data_tvb){
+ item = proto_tree_add_text(tree, tvb, offset, tokenlen, "Could not convert '%s' to 3 bytes",format_specific_parameter);
+ return;
+ }
+ length = tvb_length(data_tvb);
+ if (length == 3){
+ if(h264_handle && data_tvb){
+ dissect_h264_profile(data_tvb, pinfo, tree);
+ }
+ }else{
+ item = proto_tree_add_text(tree, tvb, offset, tokenlen, "Incorrectly coded, must be three bytes");
+ PROTO_ITEM_SET_GENERATED(item);
+ }
+ }else if (strcmp(field_name, "packetization-mode") == 0) {
offset++;
tokenlen = end_offset - offset;
format_specific_parameter = tvb_get_ephemeral_string(tvb, offset, tokenlen);
- proto_tree_add_text(tree, tvb, offset, tokenlen,
- "Test %u", strtoul(format_specific_parameter, endptr, 16));
- }
+ item = proto_tree_add_uint(tree, hf_sdp_h264_packetization_mode, tvb, offset, tokenlen,
+ atol((char*)format_specific_parameter));
+ PROTO_ITEM_SET_GENERATED(item);
+
+ }else if (strcmp(field_name, "sprop-parameter-sets") == 0) {
+ /* The value of the parameter is the
+ base64 [6] representation of the initial
+ parameter set NAL units as specified in
+ sections 7.3.2.1 and 7.3.2.2 of [1]. The
+ parameter sets are conveyed in decoding order,
+ and no framing of the parameter set NAL units
+ takes place. A comma is used to separate any
+ pair of parameter sets in the list.
+ */
+ gchar *data_p = NULL;
+ gint comma_offset;
+
+
+ /* Move past '=' */
+ offset++;
+ comma_offset = tvb_find_guint8(tvb,offset,-1,',');
+ if (comma_offset != -1){
+ tokenlen = comma_offset - offset;
+ }else{
+ tokenlen = end_offset - offset;
+ }
+
+ data_p = tvb_get_ephemeral_string(tvb, offset, tokenlen);
+ proto_tree_add_text(tree, tvb, offset, tokenlen, "NAL unit 1 string: %s", data_p);
+
+ /* proto_tree_add_text(tree, tvb, offset, tokenlen, "String %s",data_p); */
+ data_tvb = base64_to_tvb(tvb, data_p);
+ add_new_data_source(pinfo, data_tvb, "h264 prop-parameter-sets");
+
+ if(h264_handle && data_tvb){
+ dissect_h264_nal_unit(data_tvb, pinfo, tree);
+ if (comma_offset != -1){
+ /* Second NAL unit */
+ offset = comma_offset +1;
+ tokenlen = end_offset - offset;
+ data_p = tvb_get_ephemeral_string(tvb, offset, tokenlen);
+ proto_tree_add_text(tree, tvb, offset, tokenlen, "NAL unit 2 string: %s", data_p);
+ data_tvb = base64_to_tvb(tvb, data_p);
+ add_new_data_source(pinfo, data_tvb, "h264 prop-parameter-sets 2");
+ dissect_h264_nal_unit(data_tvb, pinfo, tree);
+ }
+ }
+ }
}
-#endif
+
}
typedef struct {
const char *name;
} sdp_names_t;
-#define SDP_RTPMAP 1
-#define SDP_FMTP 2
-#define SDP_PATH 3
-#define SDP_H248_ITEM 4
+#define SDP_RTPMAP 1
+#define SDP_FMTP 2
+#define SDP_PATH 3
+#define SDP_H248_ITEM 4
static const sdp_names_t sdp_media_attribute_names[] = {
- { "Unknown-name"}, /* 0 Pad so that the real headers start at index 1 */
- { "rtpmap"}, /* 1 */
- { "fmtp"}, /* 2 */
- { "path"}, /* 3 */
- { "h248item"}, /* 4 */
+ { "Unknown-name"}, /* 0 Pad so that the real headers start at index 1 */
+ { "rtpmap"}, /* 1 */
+ { "fmtp"}, /* 2 */
+ { "path"}, /* 3 */
+ { "h248item"}, /* 4 */
};
static gint find_sdp_media_attribute_names(tvbuff_t *tvb, int offset, guint len)
{
- guint i;
+ guint i;
- for (i = 1; i < array_length(sdp_media_attribute_names); i++) {
- if (len == strlen(sdp_media_attribute_names[i].name) &&
- tvb_strncaseeql(tvb, offset, sdp_media_attribute_names[i].name, len) == 0)
- return i;
- }
+ for (i = 1; i < array_length(sdp_media_attribute_names); i++) {
+ if (len == strlen(sdp_media_attribute_names[i].name) &&
+ tvb_strncaseeql(tvb, offset, sdp_media_attribute_names[i].name, len) == 0)
+ return i;
+ }
- return -1;
+ return -1;
}
-static void dissect_sdp_media_attribute(tvbuff_t *tvb, packet_info *pinfo, proto_item * ti, transport_info_t *transport_info){
+static void dissect_sdp_media_attribute(tvbuff_t *tvb, packet_info *pinfo, proto_item * ti, int length, transport_info_t *transport_info){
proto_tree *sdp_media_attribute_tree;
proto_item *fmtp_item, *media_format_item;
proto_tree *fmtp_tree;
- gint offset, next_offset, tokenlen, n;
+ gint offset, next_offset, tokenlen, n, colon_offset;
+ gint start_offset;
guint8 *field_name;
guint8 *payload_type;
guint8 *attribute_value;
gint *key;
- gint sdp_media_attrbute_code;
+ guint8 pt;
+ gint sdp_media_attrbute_code;
const char *msrp_res = "msrp://";
const char *h324ext_h223lcparm = "h324ext/h223lcparm";
+ gboolean has_more_pars = TRUE;
+ tvbuff_t *h245_tvb;
+ encoding_name_and_rate_t *encoding_name_and_rate;
offset = 0;
next_offset = 0;
sdp_media_attribute_tree = proto_item_add_subtree(ti,
ett_sdp_media_attribute);
/* Find end of field */
- next_offset = tvb_find_guint8(tvb,offset,-1,':');
+ colon_offset = tvb_find_guint8(tvb,offset,-1,':');
- if(next_offset == -1)
+ if(colon_offset == -1)
return;
/* Attribute field name is token before ':' */
- tokenlen = next_offset - offset;
+ tokenlen = colon_offset - offset;
proto_tree_add_item(sdp_media_attribute_tree,
hf_media_attribute_field,
tvb, offset, tokenlen, FALSE);
sdp_media_attrbute_code = find_sdp_media_attribute_names(tvb, offset, tokenlen);
/* Skip colon */
- offset = next_offset + 1;
+ offset = colon_offset + 1;
+ /* skip leading wsp */
+ offset = tvb_skip_wsp(tvb,offset,tvb_length_remaining(tvb,offset));
/* Value is the remainder of the line */
attribute_value = tvb_get_ephemeral_string(tvb, offset, tvb_length_remaining(tvb, offset));
switch (sdp_media_attrbute_code){
case SDP_RTPMAP:
- /* decode the rtpmap to see if it is DynamicPayload to dissect them automatic */
- next_offset = tvb_find_guint8(tvb,offset,-1,' ');
+ /* decode the rtpmap to see if it is DynamicPayload to dissect them automatic */
+ next_offset = tvb_find_guint8(tvb,offset,-1,' ');
- if(next_offset == -1)
- return;
+ if(next_offset == -1)
+ return;
- tokenlen = next_offset - offset;
+ tokenlen = next_offset - offset;
- proto_tree_add_item(sdp_media_attribute_tree, hf_media_format, tvb,
+ proto_tree_add_item(sdp_media_attribute_tree, hf_media_format, tvb,
offset, tokenlen, FALSE);
- payload_type = tvb_get_ephemeral_string(tvb, offset, tokenlen);
+ payload_type = tvb_get_ephemeral_string(tvb, offset, tokenlen);
- offset = next_offset + 1;
+ offset = next_offset + 1;
- next_offset = tvb_find_guint8(tvb,offset,-1,'/');
+ next_offset = tvb_find_guint8(tvb,offset,-1,'/');
- if(next_offset == -1){
- return;
- }
+ if(next_offset == -1){
+ return;
+ }
- tokenlen = next_offset - offset;
+ tokenlen = next_offset - offset;
- proto_tree_add_item(sdp_media_attribute_tree, hf_media_encoding_name, tvb,
+ start_offset = offset;
+ proto_tree_add_item(sdp_media_attribute_tree, hf_media_encoding_name, tvb,
offset, tokenlen, FALSE);
- /* get_string is needed here as the string is "saved" in a hashtable */
- transport_info->encoding_name = (char*)tvb_get_ephemeral_string(tvb, offset, tokenlen);
-
- key=g_malloc( sizeof(gint) );
- *key=atol((char*)payload_type);
-
- /* As per RFC2327 it is possible to have multiple Media Descriptions ("m=").
- For example:
-
- a=rtpmap:101 G726-32/8000
- m=audio 49170 RTP/AVP 0 97
- a=rtpmap:97 telephone-event/8000
- m=audio 49172 RTP/AVP 97 101
- a=rtpmap:97 G726-24/8000
-
- The Media attributes ("a="s) after the "m=" only apply for that "m=".
- If there is an "a=" before the first "m=", that attribute applies for
- all the session (all the "m="s).
- */
-
- /* so, if this "a=" appear before any "m=", we add it to all the dynamic
- * hash tables
- */
- if (transport_info->media_count == 0) {
- for (n=0; n < SDP_MAX_RTP_CHANNELS; n++) {
- if (n==0)
- g_hash_table_insert(transport_info->media[n].rtp_dyn_payload,
- key, g_strdup(transport_info->encoding_name));
- else { /* we create a new key and encoding_name to assign to the other hash tables */
- gint *key2;
- key2=g_malloc( sizeof(gint) );
- *key2=atol((char*)payload_type);
- g_hash_table_insert(transport_info->media[n].rtp_dyn_payload,
- key2, g_strdup(transport_info->encoding_name));
- }
- }
- return;
- /* if the "a=" is after an "m=", only apply to this "m=" */
- }else
- /* in case there is an overflow in SDP_MAX_RTP_CHANNELS, we keep always the last "m=" */
- if (transport_info->media_count == SDP_MAX_RTP_CHANNELS-1)
- g_hash_table_insert(transport_info->media[ transport_info->media_count ].rtp_dyn_payload,
- key, g_strdup(transport_info->encoding_name));
- else
- g_hash_table_insert(transport_info->media[ transport_info->media_count-1 ].rtp_dyn_payload,
- key, g_strdup(transport_info->encoding_name));
- return;
- break;
- case SDP_FMTP:
- /* Reading the Format parameter(fmtp) */
- next_offset = tvb_find_guint8(tvb,offset,-1,' ');
- if(next_offset == -1)
- return;
-
- tokenlen = next_offset - offset;
-
- /* Media format extends to the next space */
- media_format_item = proto_tree_add_item(sdp_media_attribute_tree,
- hf_media_format, tvb, offset,
- tokenlen, FALSE);
- /* Append encoding name to format if known */
- if (transport_info->encoding_name)
- proto_item_append_text(media_format_item, " [%s]",
- transport_info->encoding_name);
+ key=g_malloc( sizeof(gint) );
+ *key=atol((char*)payload_type);
+ pt = atoi((char*)payload_type);
+ if (pt >= SDP_NO_OF_PT) {
+ return; /* Invalid */
+ }
+ transport_info->encoding_name[pt] = (char*)tvb_get_ephemeral_string(tvb, offset, tokenlen);
- payload_type = tvb_get_ephemeral_string(tvb, offset, tokenlen);
+ next_offset = next_offset + 1;
+ offset = next_offset;
+ while (length-1 >= next_offset){
+ if(!isdigit(tvb_get_guint8(tvb, next_offset)))
+ break;
+ next_offset++;
+ }
+ tokenlen = next_offset - offset;
+ proto_tree_add_item(sdp_media_attribute_tree, hf_media_sample_rate, tvb,
+ offset, tokenlen, FALSE);
+ transport_info->sample_rate[pt] = atoi(tvb_get_ephemeral_string(tvb, offset, tokenlen));
+ /* As per RFC2327 it is possible to have multiple Media Descriptions ("m=").
+ For example:
+
+ a=rtpmap:101 G726-32/8000
+ m=audio 49170 RTP/AVP 0 97
+ a=rtpmap:97 telephone-event/8000
+ m=audio 49172 RTP/AVP 97 101
+ a=rtpmap:97 G726-24/8000
+
+ The Media attributes ("a="s) after the "m=" only apply for that "m=".
+ If there is an "a=" before the first "m=", that attribute applies for
+ all the session (all the "m="s).
+ */
+
+ /* so, if this "a=" appear before any "m=", we add it to all the dynamic
+ * hash tables
+ */
+ if (transport_info->media_count == 0) {
+ for (n=0; n < SDP_MAX_RTP_CHANNELS; n++) {
+ encoding_name_and_rate = g_malloc( sizeof(encoding_name_and_rate_t));
+ encoding_name_and_rate->encoding_name = g_strdup(transport_info->encoding_name[pt]);
+ encoding_name_and_rate->sample_rate = transport_info->sample_rate[pt];
+ if (n==0){
+ g_hash_table_insert(transport_info->media[n].rtp_dyn_payload,
+ key, encoding_name_and_rate);
+ }
+ else { /* we create a new key and encoding_name to assign to the other hash tables */
+ gint *key2;
+ key2=g_malloc( sizeof(gint) );
+ *key2=atol((char*)payload_type);
+ g_hash_table_insert(transport_info->media[n].rtp_dyn_payload,
+ key2, encoding_name_and_rate);
+ }
+ }
+ return;
+ /* if the "a=" is after an "m=", only apply to this "m=" */
+ }else
+ /* in case there is an overflow in SDP_MAX_RTP_CHANNELS, we keep always the last "m=" */
+ encoding_name_and_rate = g_malloc( sizeof(encoding_name_and_rate_t));
+
+ encoding_name_and_rate->encoding_name = g_strdup(transport_info->encoding_name[pt]);
+ encoding_name_and_rate->sample_rate = transport_info->sample_rate[pt];
+ if (transport_info->media_count == SDP_MAX_RTP_CHANNELS-1)
+ g_hash_table_insert(transport_info->media[ transport_info->media_count ].rtp_dyn_payload,
+ key, encoding_name_and_rate);
+ else
+ g_hash_table_insert(transport_info->media[ transport_info->media_count-1 ].rtp_dyn_payload,
+ key, encoding_name_and_rate);
+ break;
+ case SDP_FMTP:
+ if(sdp_media_attribute_tree){
+ guint8 media_format;
+ /* Reading the Format parameter(fmtp) */
+ /* Skip leading space, if any */
+ offset = tvb_skip_wsp(tvb,offset,tvb_length_remaining(tvb,offset));
+ /* Media format extends to the next space */
+ next_offset = tvb_find_guint8(tvb,offset,-1,' ');
- offset = next_offset + 1;
+ if(next_offset == -1)
+ return;
- /* There may be 2 parameters given
- * TODO: Handle arbitary number of parameters.
- */
- next_offset = tvb_find_guint8(tvb,offset,-1,';');
+ tokenlen = next_offset - offset;
- if(next_offset != -1){
- /* There are 2 - add the first parameter */
- tokenlen = next_offset - offset;
- fmtp_item = proto_tree_add_item(sdp_media_attribute_tree,
- hf_media_format_specific_parameter, tvb,
- offset, tokenlen, FALSE);
- fmtp_tree = proto_item_add_subtree(fmtp_item, ett_sdp_fmtp);
+ media_format_item = proto_tree_add_item(sdp_media_attribute_tree,
+ hf_media_format, tvb, offset,
+ tokenlen, FALSE);
+ media_format = atoi((char*)tvb_get_ephemeral_string(tvb, offset, tokenlen));
+ if (media_format >= SDP_NO_OF_PT) {
+ return; /* Invalid */
+ }
- decode_sdp_fmtp(fmtp_tree, tvb, offset, tokenlen,
- (guint8 *)transport_info->encoding_name);
+ /* Append encoding name to format if known */
+ proto_item_append_text(media_format_item, " [%s]",
+ transport_info->encoding_name[media_format]);
- offset = next_offset + 1;
- }
+ payload_type = tvb_get_ephemeral_string(tvb, offset, tokenlen);
+ /* Move offset past the payload type */
+ offset = next_offset + 1;
- /* Now add remaining (or only) parameter */
- tokenlen = tvb_find_line_end(tvb, offset, -1, &next_offset, FALSE);
+ while(has_more_pars==TRUE){
+ next_offset = tvb_find_guint8(tvb,offset,-1,';');
+ offset = tvb_skip_wsp(tvb,offset,tvb_length_remaining(tvb,offset));
- fmtp_item = proto_tree_add_item(sdp_media_attribute_tree,
- hf_media_format_specific_parameter, tvb,
- offset, tokenlen, FALSE);
+ if(next_offset == -1){
+ has_more_pars = FALSE;
+ next_offset= tvb_length(tvb);
+ }else{
- fmtp_tree = proto_item_add_subtree(fmtp_item, ett_sdp_fmtp);
+ }
- decode_sdp_fmtp(fmtp_tree, tvb, offset, tokenlen,
- (guint8 *)transport_info->encoding_name);
- return;
- break;
- case SDP_PATH:
- /* msrp attributes that contain address needed for conversation */
- if (strncmp((char*)attribute_value, msrp_res, strlen(msrp_res)) == 0){
- int address_offset, port_offset, port_end_offset;
+ /* There are at least 2 - add the first parameter */
+ tokenlen = next_offset - offset;
+ fmtp_item = proto_tree_add_item(sdp_media_attribute_tree,
+ hf_media_format_specific_parameter, tvb,
+ offset, tokenlen, FALSE);
- /* Address starts here */
- address_offset = offset + strlen(msrp_res);
+ fmtp_tree = proto_item_add_subtree(fmtp_item, ett_sdp_fmtp);
- /* Port is after next ':' */
- port_offset = tvb_find_guint8(tvb, address_offset, -1, ':');
+ decode_sdp_fmtp(fmtp_tree, tvb, pinfo, offset, tokenlen,
+ transport_info->encoding_name[media_format]);
+ /* Move offset past "; " and onto firts char */
+ offset = next_offset + 1;
+ }
+ }
+ break;
+ case SDP_PATH:
+ /* msrp attributes that contain address needed for conversation */
+ /* RFC 4975
+ * path = path-label ":" path-list
+ * path-label = "path"
+ * path-list= MSRP-URI *(SP MSRP-URI)
+ * MSRP-URI = msrp-scheme "://" authority
+ * ["/" session-id] ";" transport *( ";" URI-parameter)
+ * ; authority as defined in RFC3986
+ *
+ * msrp-scheme = "msrp" / "msrps"
+ * RFC 3986
+ * The authority component is preceded by a double slash ("//") and is terminated by
+ * the next slash ("/"), question mark ("?"), or number sign ("#") character, or by
+ * the end of the URI.
+ */
+
+ /* Check for "msrp://" */
+ if (strncmp((char*)attribute_value, msrp_res, strlen(msrp_res)) == 0){
+ int address_offset, port_offset, port_end_offset;
+
+ /* Address starts here */
+ address_offset = offset + (int)strlen(msrp_res);
+
+ /* Port is after next ':' */
+ port_offset = tvb_find_guint8(tvb, address_offset, -1, ':');
+ /* Check if port is present if not skipp */
+ if(port_offset!= -1){
/* Port ends with '/' */
port_end_offset = tvb_find_guint8(tvb, port_offset, -1, '/');
/* Attempt to convert address */
if (inet_pton(AF_INET, (char*)tvb_get_ephemeral_string(tvb, address_offset, port_offset-address_offset), &msrp_ipaddr) > 0) {
- /* Get port number */
- msrp_port_number = atoi((char*)tvb_get_ephemeral_string(tvb, port_offset+1, port_end_offset-port_offset-1));
- /* Set flag so this info can be used */
- msrp_transport_address_set = TRUE;
+ /* Get port number */
+ msrp_port_number = atoi((char*)tvb_get_ephemeral_string(tvb, port_offset+1, port_end_offset-port_offset-1));
+ /* Set flag so this info can be used */
+ msrp_transport_address_set = TRUE;
}
}
- break;
+ }
+ break;
case SDP_H248_ITEM:
- /* Decode h248 item ITU-T Rec. H.248.12 (2001)/Amd.1 (11/2002)*/
- if (strncmp((char*)attribute_value, h324ext_h223lcparm, strlen(msrp_res)) == 0){
- /* A.5.1.3 H.223 Logical channel parameters
- * This property indicates the H.245
- * H223LogicalChannelsParameters structure encoded by applying the PER specified in
- * ITU-T Rec. X.691. Value encoded as per A.5.1.2. For text encoding the mechanism defined
- * in ITU-T Rec. H.248.15 is used.
- */
- guint8 *buf = ep_alloc(256);
- gint len;
- asn1_ctx_t actx;
-
- len = strlen(attribute_value);
- /* arbitrary maximum length */
- if(len<20480){
- int i;
- tvbuff_t *h245_tvb;
-
- /* first, skip to where the encoded pdu starts, this is
- the first hex digit after the '=' char.
- */
- while(1){
- if((*attribute_value==0)||(*attribute_value=='\n')){
- return;
- }
- if(*attribute_value=='='){
- attribute_value++;
- break;
- }
- attribute_value++;
- }
- while(1){
- if((*attribute_value==0)||(*attribute_value=='\n')){
- return;
- }
- if( ((*attribute_value>='0')&&(*attribute_value<='9'))
- || ((*attribute_value>='a')&&(*attribute_value<='f'))
- || ((*attribute_value>='A')&&(*attribute_value<='F'))){
- break;
- }
- attribute_value++;
- }
- i=0;
- while( ((*attribute_value>='0')&&(*attribute_value<='9'))
- ||((*attribute_value>='a')&&(*attribute_value<='f'))
- ||((*attribute_value>='A')&&(*attribute_value<='F')) ){
- int val;
- if((*attribute_value>='0')&&(*attribute_value<='9')){
- val=(*attribute_value)-'0';
- } else if((*attribute_value>='a')&&(*attribute_value<='f')){
- val=(*attribute_value)-'a'+10;
- } else if((*attribute_value>='A')&&(*attribute_value<='F')){
- val=(*attribute_value)-'A'+10;
- } else {
- return;
- }
- val<<=4;
- attribute_value++;
- if((*attribute_value>='0')&&(*attribute_value<='9')){
- val|=(*attribute_value)-'0';
- } else if((*attribute_value>='a')&&(*attribute_value<='f')){
- val|=(*attribute_value)-'a'+10;
- } else if((*attribute_value>='A')&&(*attribute_value<='F')){
- val|=(*attribute_value)-'A'+10;
- } else {
- return;
- }
- attribute_value++;
-
- buf[i]=(guint8)val;
- i++;
- }
- if(i==0){
- return;
- }
- h245_tvb = tvb_new_real_data(buf,i,i);
- tvb_set_child_real_data_tvbuff(tvb,h245_tvb);
- add_new_data_source(pinfo, h245_tvb, "H.245 in SDP");
- /* should go through a handle, however, the two h245 entry
- points are different, one is over tpkt and the other is raw
- */
- asn1_ctx_init(&actx, ASN1_ENC_PER, TRUE, pinfo);
- dissect_h245_H223LogicalChannelParameters(h245_tvb, 0, &actx, sdp_media_attribute_tree, hf_SDPh223LogicalChannelParameters);
- }
-
- }
- break;
+ /* Decode h248 item ITU-T Rec. H.248.12 (2001)/Amd.1 (11/2002)*/
+ if (strncmp((char*)attribute_value, h324ext_h223lcparm, strlen(msrp_res)) == 0){
+ /* A.5.1.3 H.223 Logical channel parameters
+ * This property indicates the H.245
+ * H223LogicalChannelsParameters structure encoded by applying the PER specified in
+ * ITU-T Rec. X.691. Value encoded as per A.5.1.2. For text encoding the mechanism defined
+ * in ITU-T Rec. H.248.15 is used.
+ */
+ gint len;
+ asn1_ctx_t actx;
+
+ len = (gint)strlen(attribute_value);
+ h245_tvb = ascii_bytes_to_tvb(tvb, pinfo, len, attribute_value);
+ /* arbitrary maximum length */
+ /* should go through a handle, however, the two h245 entry
+ points are different, one is over tpkt and the other is raw
+ */
+ if (h245_tvb){
+ asn1_ctx_init(&actx, ASN1_ENC_PER, TRUE, pinfo);
+ dissect_h245_H223LogicalChannelParameters(h245_tvb, 0, &actx, sdp_media_attribute_tree, hf_SDPh223LogicalChannelParameters);
+ }
+ }
+ break;
default:
- /* No special treatment for values of this attribute type, just add as one item. */
- proto_tree_add_item(sdp_media_attribute_tree, hf_media_attribute_value,
- tvb, offset, -1, FALSE);
- break;
+ /* No special treatment for values of this attribute type, just add as one item. */
+ proto_tree_add_item(sdp_media_attribute_tree, hf_media_attribute_value,
+ tvb, offset, -1, FALSE);
+ break;
}
}
{ &hf_protocol_version,
{ "Session Description Protocol Version (v)",
"sdp.version", FT_STRING, BASE_NONE,NULL,0x0,
- "Session Description Protocol Version", HFILL }},
+ NULL, HFILL }},
{ &hf_owner,
{ "Owner/Creator, Session Id (o)",
"sdp.owner", FT_STRING, BASE_NONE, NULL, 0x0,
- "Owner/Creator, Session Id", HFILL}},
+ NULL, HFILL}},
{ &hf_session_name,
{ "Session Name (s)",
"sdp.session_name", FT_STRING, BASE_NONE,NULL, 0x0,
- "Session Name", HFILL }},
+ NULL, HFILL }},
{ &hf_session_info,
{ "Session Information (i)",
"sdp.session_info", FT_STRING, BASE_NONE, NULL, 0x0,
- "Session Information", HFILL }},
+ NULL, HFILL }},
{ &hf_uri,
{ "URI of Description (u)",
"sdp.uri", FT_STRING, BASE_NONE,NULL, 0x0,
- "URI of Description", HFILL }},
+ NULL, HFILL }},
{ &hf_email,
{ "E-mail Address (e)",
"sdp.email", FT_STRING, BASE_NONE, NULL, 0x0,
{ &hf_phone,
{ "Phone Number (p)",
"sdp.phone", FT_STRING, BASE_NONE, NULL, 0x0,
- "Phone Number", HFILL }},
+ NULL, HFILL }},
{ &hf_connection_info,
{ "Connection Information (c)",
"sdp.connection_info", FT_STRING, BASE_NONE, NULL, 0x0,
- "Connection Information", HFILL }},
+ NULL, HFILL }},
{ &hf_bandwidth,
{ "Bandwidth Information (b)",
"sdp.bandwidth", FT_STRING, BASE_NONE, NULL, 0x0,
- "Bandwidth Information", HFILL }},
+ NULL, HFILL }},
{ &hf_timezone,
{ "Time Zone Adjustments (z)",
"sdp.timezone", FT_STRING, BASE_NONE, NULL, 0x0,
- "Time Zone Adjustments", HFILL }},
+ NULL, HFILL }},
{ &hf_encryption_key,
{ "Encryption Key (k)",
"sdp.encryption_key", FT_STRING, BASE_NONE, NULL, 0x0,
- "Encryption Key", HFILL }},
+ NULL, HFILL }},
{ &hf_session_attribute,
{ "Session Attribute (a)",
"sdp.session_attr", FT_STRING, BASE_NONE, NULL, 0x0,
- "Session Attribute", HFILL }},
+ NULL, HFILL }},
{ &hf_media_attribute,
{ "Media Attribute (a)",
"sdp.media_attr", FT_STRING, BASE_NONE, NULL, 0x0,
- "Media Attribute", HFILL }},
+ NULL, HFILL }},
{ &hf_time,
{ "Time Description, active time (t)",
"sdp.time", FT_STRING, BASE_NONE, NULL, 0x0,
- "Time Description, active time", HFILL }},
+ NULL, HFILL }},
{ &hf_repeat_time,
{ "Repeat Time (r)",
"sdp.repeat_time", FT_STRING, BASE_NONE, NULL, 0x0,
- "Repeat Time", HFILL }},
+ NULL, HFILL }},
{ &hf_media,
{ "Media Description, name and address (m)",
"sdp.media", FT_STRING, BASE_NONE, NULL, 0x0,
- "Media Description, name and address", HFILL }},
+ NULL, HFILL }},
{ &hf_media_title,
{ "Media Title (i)",
"sdp.media_title",FT_STRING, BASE_NONE, NULL, 0x0,
{ &hf_unknown,
{ "Unknown",
"sdp.unknown",FT_STRING, BASE_NONE, NULL, 0x0,
- "Unknown", HFILL }},
+ NULL, HFILL }},
{ &hf_invalid,
{ "Invalid line",
"sdp.invalid",FT_STRING, BASE_NONE, NULL, 0x0,
- "Invalid line", HFILL }},
+ NULL, HFILL }},
{ &hf_owner_username,
{ "Owner Username",
"sdp.owner.username",FT_STRING, BASE_NONE, NULL, 0x0,
- "Owner Username", HFILL }},
+ NULL, HFILL }},
{ &hf_owner_sessionid,
{ "Session ID",
"sdp.owner.sessionid",FT_STRING, BASE_NONE, NULL, 0x0,
- "Session ID", HFILL }},
+ NULL, HFILL }},
{ &hf_owner_version,
{ "Session Version",
"sdp.owner.version",FT_STRING, BASE_NONE, NULL, 0x0,
- "Session Version", HFILL }},
+ NULL, HFILL }},
{ &hf_owner_network_type,
{ "Owner Network Type",
"sdp.owner.network_type",FT_STRING, BASE_NONE, NULL, 0x0,
- "Owner Network Type", HFILL }},
+ NULL, HFILL }},
{ &hf_owner_address_type,
{ "Owner Address Type",
"sdp.owner.address_type",FT_STRING, BASE_NONE, NULL, 0x0,
- "Owner Address Type", HFILL }},
+ NULL, HFILL }},
{ &hf_owner_address,
{ "Owner Address",
"sdp.owner.address",FT_STRING, BASE_NONE, NULL, 0x0,
- "Owner Address", HFILL }},
+ NULL, HFILL }},
{ &hf_connection_info_network_type,
{ "Connection Network Type",
"sdp.connection_info.network_type",FT_STRING, BASE_NONE, NULL, 0x0,
- "Connection Network Type", HFILL }},
+ NULL, HFILL }},
{ &hf_connection_info_address_type,
{ "Connection Address Type",
"sdp.connection_info.address_type",FT_STRING, BASE_NONE, NULL, 0x0,
- "Connection Address Type", HFILL }},
+ NULL, HFILL }},
{ &hf_connection_info_connection_address,
{ "Connection Address",
"sdp.connection_info.address",FT_STRING, BASE_NONE, NULL, 0x0,
- "Connection Address", HFILL }},
+ NULL, HFILL }},
{ &hf_connection_info_ttl,
{ "Connection TTL",
"sdp.connection_info.ttl",FT_STRING, BASE_NONE, NULL, 0x0,
- "Connection TTL", HFILL }},
+ NULL, HFILL }},
{ &hf_connection_info_num_addr,
{ "Connection Number of Addresses",
"sdp.connection_info.num_addr",FT_STRING, BASE_NONE, NULL, 0x0,
- "Connection Number of Addresses", HFILL }},
+ NULL, HFILL }},
{ &hf_bandwidth_modifier,
{ "Bandwidth Modifier",
"sdp.bandwidth.modifier",FT_STRING, BASE_NONE, NULL, 0x0,
- "Bandwidth Modifier", HFILL }},
+ NULL, HFILL }},
{ &hf_bandwidth_value,
{ "Bandwidth Value",
"sdp.bandwidth.value",FT_STRING, BASE_NONE, NULL, 0x0,
{ &hf_time_start,
{ "Session Start Time",
"sdp.time.start",FT_STRING, BASE_NONE, NULL, 0x0,
- "Session Start Time", HFILL }},
+ NULL, HFILL }},
{ &hf_time_stop,
{ "Session Stop Time",
"sdp.time.stop",FT_STRING, BASE_NONE, NULL, 0x0,
- "Session Stop Time", HFILL }},
+ NULL, HFILL }},
{ &hf_repeat_time_interval,
{ "Repeat Interval",
"sdp.repeat_time.interval",FT_STRING, BASE_NONE, NULL, 0x0,
- "Repeat Interval", HFILL }},
+ NULL, HFILL }},
{ &hf_repeat_time_duration,
{ "Repeat Duration",
"sdp.repeat_time.duration",FT_STRING, BASE_NONE, NULL, 0x0,
- "Repeat Duration", HFILL }},
+ NULL, HFILL }},
{ &hf_repeat_time_offset,
{ "Repeat Offset",
"sdp.repeat_time.offset",FT_STRING, BASE_NONE, NULL, 0x0,
- "Repeat Offset", HFILL }},
+ NULL, HFILL }},
{ &hf_timezone_time,
{ "Timezone Time",
"sdp.timezone.time",FT_STRING, BASE_NONE, NULL, 0x0,
- "Timezone Time", HFILL }},
+ NULL, HFILL }},
{ &hf_timezone_offset,
{ "Timezone Offset",
"sdp.timezone.offset",FT_STRING, BASE_NONE, NULL, 0x0,
- "Timezone Offset", HFILL }},
+ NULL, HFILL }},
{ &hf_encryption_key_type,
{ "Key Type",
"sdp.encryption_key.type",FT_STRING, BASE_NONE, NULL, 0x0,
- "Type", HFILL }},
+ NULL, HFILL }},
{ &hf_encryption_key_data,
{ "Key Data",
"sdp.encryption_key.data",FT_STRING, BASE_NONE, NULL, 0x0,
- "Data", HFILL }},
+ NULL, HFILL }},
{ &hf_session_attribute_field,
{ "Session Attribute Fieldname",
"sdp.session_attr.field",FT_STRING, BASE_NONE, NULL, 0x0,
- "Session Attribute Fieldname", HFILL }},
+ NULL, HFILL }},
{ &hf_session_attribute_value,
{ "Session Attribute Value",
"sdp.session_attr.value",FT_STRING, BASE_NONE, NULL, 0x0,
- "Session Attribute Value", HFILL }},
+ NULL, HFILL }},
{ &hf_media_media,
{ "Media Type",
"sdp.media.media",FT_STRING, BASE_NONE, NULL, 0x0,
- "Media Type", HFILL }},
+ NULL, HFILL }},
{ &hf_media_port,
{ "Media Port",
"sdp.media.port",FT_UINT16, BASE_DEC, NULL, 0x0,
- "Media Port", HFILL }},
+ NULL, HFILL }},
{ &hf_media_portcount,
{ "Media Port Count",
"sdp.media.portcount",FT_STRING, BASE_NONE, NULL, 0x0,
- "Media Port Count", HFILL }},
+ NULL, HFILL }},
{ &hf_media_proto,
- { "Media Proto",
+ { "Media Protocol",
"sdp.media.proto",FT_STRING, BASE_NONE, NULL, 0x0,
- "Media Protocol", HFILL }},
+ NULL, HFILL }},
{ &hf_media_format,
{ "Media Format",
"sdp.media.format",FT_STRING, BASE_NONE, NULL, 0x0,
- "Media Format", HFILL }},
+ NULL, HFILL }},
{ &hf_media_attribute_field,
{ "Media Attribute Fieldname",
"sdp.media_attribute.field",FT_STRING, BASE_NONE, NULL, 0x0,
- "Media Attribute Fieldname", HFILL }},
+ NULL, HFILL }},
{ &hf_media_attribute_value,
{ "Media Attribute Value",
"sdp.media_attribute.value",FT_STRING, BASE_NONE, NULL, 0x0,
- "Media Attribute Value", HFILL }},
- { &hf_media_encoding_name,
+ NULL, HFILL }},
+ { &hf_media_encoding_name,
{ "MIME Type",
"sdp.mime.type",FT_STRING, BASE_NONE, NULL, 0x0,
"SDP MIME Type", HFILL }},
- { &hf_media_format_specific_parameter,
+ { &hf_media_sample_rate,
+ { "Sample Rate",
+ "sdp.sample_rate",FT_STRING, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }},
+ { &hf_media_format_specific_parameter,
{ "Media format specific parameters",
"sdp.fmtp.parameter",FT_STRING, BASE_NONE, NULL, 0x0,
"Format specific parameter(fmtp)", HFILL }},
{ &hf_ipbcp_version,
{ "IPBCP Protocol Version",
"ipbcp.version",FT_STRING, BASE_NONE, NULL, 0x0,
- "IPBCP Protocol Version", HFILL }},
+ NULL, HFILL }},
{ &hf_ipbcp_type,
{ "IPBCP Command Type",
"ipbcp.command",FT_STRING, BASE_NONE, NULL, 0x0,
- "IPBCP Command Type", HFILL }},
- {&hf_sdp_fmtp_profile_level_id,
+ NULL, HFILL }},
+ {&hf_sdp_fmtp_mpeg4_profile_level_id,
{ "Level Code",
- "sdp.fmtp.profile_level_id",FT_UINT32, BASE_DEC,VALS(mpeg4es_level_indication_vals), 0x0,
- "Level Code", HFILL }},
- { &hf_sdp_fmtp_h263_profile,
+ "sdp.fmtp.profile_level_id",FT_UINT32, BASE_DEC,VALS(mp4ves_level_indication_vals), 0x0,
+ NULL, HFILL }},
+ { &hf_sdp_fmtp_h263_profile,
{ "Profile",
"sdp.fmtp.h263profile",FT_UINT32, BASE_DEC,VALS(h263_profile_vals), 0x0,
- "Profile", HFILL }},
+ NULL, HFILL }},
+ { &hf_sdp_fmtp_h263_level,
+ { "Level",
+ "sdp.fmtp.h263level",FT_UINT32, BASE_DEC,VALS(h263_level_vals), 0x0,
+ NULL, HFILL }},
+ { &hf_sdp_h264_packetization_mode,
+ { "Packetization mode",
+ "sdp.fmtp.h264_packetization_mode",FT_UINT32, BASE_DEC,VALS(h264_packetization_mode_vals), 0x0,
+ NULL, HFILL }},
+ { &hf_sdp_h264_sprop_parameter_sets,
+ { "Sprop_parameter_sets",
+ "sdp.h264.sprop_parameter_sets", FT_BYTES, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }},
{ &hf_SDPh223LogicalChannelParameters,
{ "h223LogicalChannelParameters", "sdp.h223LogicalChannelParameters",
FT_NONE, BASE_NONE, NULL, 0,
- "sdp.h223LogicalChannelParameters", HFILL }},
+ NULL, HFILL }},
{ &hf_key_mgmt_att_value,
{ "Key Management",
"sdp.key_mgmt", FT_STRING, BASE_NONE, NULL, 0x0,
- "Key Management", HFILL }},
+ NULL, HFILL }},
{ &hf_key_mgmt_prtcl_id,
{ "Key Management Protocol (kmpid)",
"sdp.key_mgmt.kmpid", FT_STRING, BASE_NONE, NULL, 0x0,
- "Key Management Protocol", HFILL }},
+ NULL, HFILL }},
{ &hf_key_mgmt_data,
{ "Key Management Data",
"sdp.key_mgmt.data", FT_BYTES, BASE_NONE, NULL, 0x0,
- "Key Management Data", HFILL }},
+ NULL, HFILL }},
};
static gint *ett[] = {
&ett_sdp,
proto_register_subtree_array(ett, array_length(ett));
key_mgmt_dissector_table = register_dissector_table("key_mgmt",
- "Key Management", FT_STRING, BASE_NONE);
+ "Key Management", FT_STRING, BASE_NONE);
/*
* Preferences registration
prefs_register_bool_preference(sdp_module, "establish_conversation",
"Establish Media Conversation",
"Specifies that RTP/RTCP/T.38/MSRP/etc streams are decoded based "
- "upon port numbers found in SIP/SDP payload",
+ "upon port numbers found in SDP payload",
&global_sdp_establish_conversation);
/*
rtcp_handle = find_dissector("rtcp");
msrp_handle = find_dissector("msrp");
t38_handle = find_dissector("t38");
+ h264_handle = find_dissector("h264");
+ mp4ves_handle = find_dissector("mp4ves");
sdp_handle = find_dissector("sdp");
dissector_add_string("media_type", "application/sdp", sdp_handle);