Fix Bug 9920 Buildbot crash due to SDP/RTP mismatch
For details see comments in Bug 9920. The executive summary: Bug 9920 is a crash caused by a couple of issues: 1) The memory ownership model for the rtp_dyn_payload hashtable is split: SDP creates the rtp_dyn_payload hashtable, but RTP can free it. Since there isn't *one* pointer to the hashtable, RTP freeing it means SDP has a dangling pointer. 2) Either the SDP dissector shouldn't be creating two separate, unique hashtables for multiple media channels of the same addr:port, or RTP shouldn't be free'ing the previous one. Change-Id: I436e67de6882f84aa82dcbdfe60bf313fe4fd99c Reviewed-on: https://code.wireshark.org/review/918 Reviewed-by: Hadriel Kaplan <hadrielk@yahoo.com> Reviewed-by: Anders Broman <a.broman58@gmail.com>
This commit is contained in:
parent
df80f3133c
commit
04c05a21e3
|
@ -341,8 +341,7 @@ static void update_unicast_addr(unicast_addr_t *req_addr, unicast_addr_t *ack_ad
|
|||
|
||||
static void h245_setup_channels(packet_info *pinfo, channel_info_t *upcoming_channel_lcl)
|
||||
{
|
||||
gint *key;
|
||||
GHashTable *rtp_dyn_payload = NULL;
|
||||
rtp_dyn_payload_t *rtp_dyn_payload = NULL;
|
||||
struct srtp_info *dummy_srtp_info = NULL;
|
||||
|
||||
if (!upcoming_channel_lcl) return;
|
||||
|
@ -359,13 +358,8 @@ static void h245_setup_channels(packet_info *pinfo, channel_info_t *upcoming_cha
|
|||
|
||||
/* (S)RTP, (S)RTCP */
|
||||
if (upcoming_channel_lcl->rfc2198 > 0) {
|
||||
encoding_name_and_rate_t *encoding_name_and_rate = wmem_new(wmem_file_scope(), encoding_name_and_rate_t);
|
||||
rtp_dyn_payload = g_hash_table_new(g_int_hash, g_int_equal);
|
||||
encoding_name_and_rate->encoding_name = wmem_strdup(wmem_file_scope(), "red");
|
||||
encoding_name_and_rate->sample_rate = 8000;
|
||||
key = wmem_new(wmem_file_scope(), gint);
|
||||
*key = upcoming_channel_lcl->rfc2198;
|
||||
g_hash_table_insert(rtp_dyn_payload, key, encoding_name_and_rate);
|
||||
rtp_dyn_payload = rtp_dyn_payload_new();
|
||||
rtp_dyn_payload_insert(rtp_dyn_payload, upcoming_channel_lcl->rfc2198, "red", 8000);
|
||||
}
|
||||
|
||||
if (upcoming_channel_lcl->srtp_flag) {
|
||||
|
|
|
@ -6905,11 +6905,9 @@ elem_a2p_bearer_format(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guin
|
|||
gboolean first_assigned_found;
|
||||
gboolean rtp_dyn_payload_used;
|
||||
guint8 rtp_payload_type;
|
||||
GHashTable *rtp_dyn_payload;
|
||||
gint *key;
|
||||
encoding_name_and_rate_t *encoding_name_and_rate;
|
||||
rtp_dyn_payload_t *rtp_dyn_payload;
|
||||
|
||||
rtp_dyn_payload = g_hash_table_new(g_int_hash, g_int_equal);
|
||||
rtp_dyn_payload = rtp_dyn_payload_new();
|
||||
rtp_dyn_payload_used = FALSE;
|
||||
|
||||
first_assigned_found = FALSE;
|
||||
|
@ -7066,14 +7064,7 @@ elem_a2p_bearer_format(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guin
|
|||
if (format_assigned &&
|
||||
(first_assigned_found == FALSE))
|
||||
{
|
||||
key = wmem_new(wmem_file_scope(), gint);
|
||||
*key = rtp_payload_type;
|
||||
|
||||
encoding_name_and_rate = wmem_new(wmem_file_scope(), encoding_name_and_rate_t);
|
||||
encoding_name_and_rate->encoding_name = wmem_strdup(wmem_file_scope(), mime_type);
|
||||
encoding_name_and_rate->sample_rate = sample_rate;
|
||||
|
||||
g_hash_table_insert(rtp_dyn_payload, key, encoding_name_and_rate);
|
||||
rtp_dyn_payload_insert(rtp_dyn_payload, rtp_payload_type, mime_type, sample_rate);
|
||||
rtp_dyn_payload_used = TRUE;
|
||||
|
||||
first_assigned_found = TRUE;
|
||||
|
@ -7083,14 +7074,7 @@ elem_a2p_bearer_format(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guin
|
|||
|
||||
if (in_band_format_assigned)
|
||||
{
|
||||
key = (gint *) wmem_alloc(wmem_file_scope(), sizeof(gint));
|
||||
*key = rtp_payload_type;
|
||||
|
||||
encoding_name_and_rate = wmem_new(wmem_file_scope(), encoding_name_and_rate_t);
|
||||
encoding_name_and_rate->encoding_name = wmem_strdup(wmem_file_scope(), "telephone-event");
|
||||
encoding_name_and_rate->sample_rate = sample_rate;
|
||||
|
||||
g_hash_table_insert(rtp_dyn_payload, key, encoding_name_and_rate);
|
||||
rtp_dyn_payload_insert(rtp_dyn_payload, rtp_payload_type, "telephone-event", sample_rate);
|
||||
rtp_dyn_payload_used = TRUE;
|
||||
}
|
||||
|
||||
|
@ -7099,7 +7083,7 @@ elem_a2p_bearer_format(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guin
|
|||
|
||||
if (rtp_dyn_payload_used == FALSE)
|
||||
{
|
||||
rtp_free_hash_dyn_payload(rtp_dyn_payload);
|
||||
rtp_dyn_payload_free(rtp_dyn_payload);
|
||||
}
|
||||
|
||||
EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
|
||||
|
|
|
@ -285,9 +285,7 @@ dissect_applemidi_heur( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, voi
|
|||
guint16 command;
|
||||
conversation_t *p_conv;
|
||||
/*struct _rtp_conversation_info *p_conv_data = NULL;*/
|
||||
encoding_name_and_rate_t *encoding_name_and_rate = NULL;
|
||||
GHashTable *rtp_dyn_payload = NULL;
|
||||
gint *key;
|
||||
rtp_dyn_payload_t *rtp_dyn_payload = NULL;
|
||||
|
||||
if ( tvb_length( tvb ) < 4)
|
||||
return FALSE; /* not enough bytes to check */
|
||||
|
@ -299,13 +297,8 @@ dissect_applemidi_heur( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, voi
|
|||
/* set dynamic payload-type 97 which is used by Apple for their RTP-MIDI implementation for this
|
||||
address/port-tuple to cause RTP-dissector to call the RTP-MIDI-dissector for payload-decoding */
|
||||
|
||||
encoding_name_and_rate = wmem_new(wmem_file_scope(), encoding_name_and_rate_t);
|
||||
rtp_dyn_payload = g_hash_table_new( g_int_hash, g_int_equal );
|
||||
encoding_name_and_rate->encoding_name = wmem_strdup( wmem_file_scope(), "rtp-midi" );
|
||||
encoding_name_and_rate->sample_rate = 10000;
|
||||
key = wmem_new(wmem_file_scope(), gint);
|
||||
*key = 97;
|
||||
g_hash_table_insert( rtp_dyn_payload, key, encoding_name_and_rate );
|
||||
rtp_dyn_payload = rtp_dyn_payload_new();
|
||||
rtp_dyn_payload_insert(rtp_dyn_payload, 97, "rtp-midi", 10000);
|
||||
rtp_add_address( pinfo, &pinfo->src, pinfo->srcport, 0, APPLEMIDI_DISSECTOR_SHORTNAME,
|
||||
pinfo->fd->num, FALSE, rtp_dyn_payload);
|
||||
|
||||
|
|
|
@ -472,8 +472,7 @@ static void update_unicast_addr(unicast_addr_t *req_addr, unicast_addr_t *ack_ad
|
|||
|
||||
static void h245_setup_channels(packet_info *pinfo, channel_info_t *upcoming_channel_lcl)
|
||||
{
|
||||
gint *key;
|
||||
GHashTable *rtp_dyn_payload = NULL;
|
||||
rtp_dyn_payload_t *rtp_dyn_payload = NULL;
|
||||
struct srtp_info *dummy_srtp_info = NULL;
|
||||
|
||||
if (!upcoming_channel_lcl) return;
|
||||
|
@ -490,13 +489,8 @@ static void h245_setup_channels(packet_info *pinfo, channel_info_t *upcoming_cha
|
|||
|
||||
/* (S)RTP, (S)RTCP */
|
||||
if (upcoming_channel_lcl->rfc2198 > 0) {
|
||||
encoding_name_and_rate_t *encoding_name_and_rate = wmem_new(wmem_file_scope(), encoding_name_and_rate_t);
|
||||
rtp_dyn_payload = g_hash_table_new(g_int_hash, g_int_equal);
|
||||
encoding_name_and_rate->encoding_name = wmem_strdup(wmem_file_scope(), "red");
|
||||
encoding_name_and_rate->sample_rate = 8000;
|
||||
key = wmem_new(wmem_file_scope(), gint);
|
||||
*key = upcoming_channel_lcl->rfc2198;
|
||||
g_hash_table_insert(rtp_dyn_payload, key, encoding_name_and_rate);
|
||||
rtp_dyn_payload = rtp_dyn_payload_new();
|
||||
rtp_dyn_payload_insert(rtp_dyn_payload, upcoming_channel_lcl->rfc2198, "red", 8000);
|
||||
}
|
||||
|
||||
if (upcoming_channel_lcl->srtp_flag) {
|
||||
|
@ -1926,7 +1920,7 @@ static int hf_h245_encrypted = -1; /* OCTET_STRING */
|
|||
static int hf_h245_encryptedAlphanumeric = -1; /* EncryptedAlphanumeric */
|
||||
|
||||
/*--- End of included file: packet-h245-hf.c ---*/
|
||||
#line 392 "../../asn1/h245/packet-h245-template.c"
|
||||
#line 386 "../../asn1/h245/packet-h245-template.c"
|
||||
|
||||
/* Initialize the subtree pointers */
|
||||
static int ett_h245 = -1;
|
||||
|
@ -2427,7 +2421,7 @@ static gint ett_h245_FlowControlIndication = -1;
|
|||
static gint ett_h245_MobileMultilinkReconfigurationIndication = -1;
|
||||
|
||||
/*--- End of included file: packet-h245-ett.c ---*/
|
||||
#line 397 "../../asn1/h245/packet-h245-template.c"
|
||||
#line 391 "../../asn1/h245/packet-h245-template.c"
|
||||
|
||||
/* Forward declarations */
|
||||
static int dissect_h245_MultimediaSystemControlMessage(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_);
|
||||
|
@ -14494,7 +14488,7 @@ static void dissect_OpenLogicalChannel_PDU(tvbuff_t *tvb _U_, packet_info *pinfo
|
|||
|
||||
|
||||
/*--- End of included file: packet-h245-fn.c ---*/
|
||||
#line 406 "../../asn1/h245/packet-h245-template.c"
|
||||
#line 400 "../../asn1/h245/packet-h245-template.c"
|
||||
|
||||
static void
|
||||
dissect_h245(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
|
||||
|
@ -20188,7 +20182,7 @@ void proto_register_h245(void) {
|
|||
NULL, HFILL }},
|
||||
|
||||
/*--- End of included file: packet-h245-hfarr.c ---*/
|
||||
#line 487 "../../asn1/h245/packet-h245-template.c"
|
||||
#line 481 "../../asn1/h245/packet-h245-template.c"
|
||||
};
|
||||
|
||||
/* List of subtrees */
|
||||
|
@ -20691,7 +20685,7 @@ void proto_register_h245(void) {
|
|||
&ett_h245_MobileMultilinkReconfigurationIndication,
|
||||
|
||||
/*--- End of included file: packet-h245-ettarr.c ---*/
|
||||
#line 494 "../../asn1/h245/packet-h245-template.c"
|
||||
#line 488 "../../asn1/h245/packet-h245-template.c"
|
||||
};
|
||||
module_t *h245_module;
|
||||
|
||||
|
|
|
@ -102,6 +102,17 @@ typedef struct _rtp_private_conv_info {
|
|||
wmem_tree_t *multisegment_pdus;
|
||||
} rtp_private_conv_info;
|
||||
|
||||
typedef struct {
|
||||
char *encoding_name;
|
||||
int sample_rate;
|
||||
} encoding_name_and_rate_t;
|
||||
|
||||
struct _rtp_dyn_payload_t
|
||||
{
|
||||
GHashTable *table;
|
||||
size_t ref_count;
|
||||
};
|
||||
|
||||
static reassembly_table rtp_reassembly_table;
|
||||
|
||||
static int hf_rtp_fragments = -1;
|
||||
|
@ -809,11 +820,11 @@ static const value_string srtp_auth_alg_vals[] =
|
|||
#ifdef DEBUG_CONVERSATION
|
||||
/* Called for each entry in the rtp_dyn_payload hash table. */
|
||||
static void
|
||||
rtp_dyn_payload_table_foreach_func (gpointer key, gpointer value, gpointer user_data _U_) {
|
||||
gint* pt = (gint*) key;
|
||||
rtp_dyn_payload_table_foreach_func(gpointer key, gpointer value, gpointer user_data _U_) {
|
||||
guint pt = GPOINTER_TO_UINT(key);
|
||||
encoding_name_and_rate_t *encoding = (encoding_name_and_rate_t*) value;
|
||||
|
||||
DPRINT2(("pt=%d",*pt));
|
||||
DPRINT2(("pt=%d",pt));
|
||||
if (encoding) {
|
||||
DPRINT2(("encoding_name=%s",
|
||||
encoding->encoding_name ? encoding->encoding_name : "NULL"));
|
||||
|
@ -822,19 +833,27 @@ rtp_dyn_payload_table_foreach_func (gpointer key, gpointer value, gpointer user_
|
|||
DPRINT2(("encoding=NULL"));
|
||||
}
|
||||
}
|
||||
static void rtp_dump_dyn_payload(GHashTable *rtp_dyn_payload) {
|
||||
|
||||
void
|
||||
rtp_dump_dyn_payload(rtp_dyn_payload_t *rtp_dyn_payload) {
|
||||
DPRINT2(("rtp_dyn_payload hash table contents:"));
|
||||
DINDENT();
|
||||
if (!rtp_dyn_payload) {
|
||||
DPRINT2(("null rtp_dyn_payload"));
|
||||
DENDENT();
|
||||
return;
|
||||
}
|
||||
if (g_hash_table_size(rtp_dyn_payload) == 0) {
|
||||
DPRINT2(("rtp_dyn_payload is empty"));
|
||||
} else {
|
||||
g_hash_table_foreach(rtp_dyn_payload, rtp_dyn_payload_table_foreach_func, NULL);
|
||||
}
|
||||
if (!rtp_dyn_payload) {
|
||||
DPRINT2(("null pointer to rtp_dyn_payload"));
|
||||
DENDENT();
|
||||
return;
|
||||
}
|
||||
DPRINT2(("ref_count=%" G_GSIZE_FORMAT, rtp_dyn_payload->ref_count));
|
||||
if (!rtp_dyn_payload->table) {
|
||||
DPRINT2(("null rtp_dyn_payload table"));
|
||||
DENDENT();
|
||||
return;
|
||||
}
|
||||
if (g_hash_table_size(rtp_dyn_payload->table) == 0) {
|
||||
DPRINT2(("rtp_dyn_payload has no entries"));
|
||||
} else {
|
||||
g_hash_table_foreach(rtp_dyn_payload->table, rtp_dyn_payload_table_foreach_func, NULL);
|
||||
}
|
||||
DENDENT();
|
||||
}
|
||||
#endif /* DEBUG_CONVERSATION */
|
||||
|
@ -847,14 +866,225 @@ rtp_fragment_init(void)
|
|||
&addresses_reassembly_table_functions);
|
||||
}
|
||||
|
||||
void
|
||||
rtp_free_hash_dyn_payload(GHashTable *rtp_dyn_payload)
|
||||
/* A single hash table to hold pointers to all the rtp_dyn_payload_t's we create/destroy.
|
||||
This is necessary because we need to g_hash_table_destroy() them, either individually or
|
||||
all at once at the end of the wmem file scope. Since rtp_dyn_payload_free() removes them
|
||||
individually, we need to remove those then; and when the file scope is over, we have a
|
||||
single registered callback walk this GHashTable and destroy each member as well as this
|
||||
GHashTable.
|
||||
*/
|
||||
static GHashTable *rtp_dyn_payloads = NULL;
|
||||
|
||||
/* the following is the GDestroyNotify function used when the individual rtp_dyn_payload_t
|
||||
GHashTables are destroyed */
|
||||
static void
|
||||
rtp_dyn_payload_value_destroy(gpointer data)
|
||||
{
|
||||
if (rtp_dyn_payload == NULL) return;
|
||||
g_hash_table_destroy(rtp_dyn_payload);
|
||||
rtp_dyn_payload = NULL;
|
||||
encoding_name_and_rate_t *encoding_name_and_rate_pt = (encoding_name_and_rate_t*) data;
|
||||
wmem_free(wmem_file_scope(), encoding_name_and_rate_pt->encoding_name);
|
||||
wmem_free(wmem_file_scope(), encoding_name_and_rate_pt);
|
||||
}
|
||||
|
||||
/* this gets called by wmem_rtp_dyn_payload_destroy_cb */
|
||||
static gboolean
|
||||
rtp_dyn_payloads_table_steal_func(gpointer key _U_, gpointer value, gpointer user_data _U_)
|
||||
{
|
||||
rtp_dyn_payload_t *rtp_dyn_payload = (rtp_dyn_payload_t *)value;
|
||||
|
||||
#ifdef DEBUG_CONVERSATION
|
||||
DPRINT(("about to steal_all and destroy the following:"));
|
||||
DINDENT();
|
||||
rtp_dump_dyn_payload(rtp_dyn_payload);
|
||||
DENDENT();
|
||||
#endif
|
||||
|
||||
if (rtp_dyn_payload->ref_count == 0) {
|
||||
/* this shouldn't happen */
|
||||
g_error("rtp_dyn_payload cannot be free'd because it should already have been!\n");
|
||||
}
|
||||
else if (rtp_dyn_payload->table) {
|
||||
/* each member was created with a wmem file scope, so there's no point in calling the
|
||||
destroy functions for the GHashTable entries, so we steal them instead */
|
||||
g_hash_table_steal_all(rtp_dyn_payload->table);
|
||||
g_hash_table_destroy(rtp_dyn_payload->table);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* the following is used as the wmem callback to destroy *all* alive rtp_dyn_payload_t's,
|
||||
which are pointed to by the single rtp_dyn_payloads GHashTable above.
|
||||
*/
|
||||
static gboolean
|
||||
wmem_rtp_dyn_payload_destroy_cb(wmem_allocator_t *allocator _U_, wmem_cb_event_t event _U_,
|
||||
void *user_data _U_)
|
||||
{
|
||||
g_assert(rtp_dyn_payloads);
|
||||
|
||||
DPRINT(("destroying %u remaining rtp_dyn_payload_t's", g_hash_table_size(rtp_dyn_payloads)));
|
||||
|
||||
/* each member was created with a wmem file scope, so there's no point in calling the
|
||||
destroy functions for the GHashTable entries, so we steal them instead */
|
||||
g_hash_table_foreach_steal(rtp_dyn_payloads, rtp_dyn_payloads_table_steal_func, NULL);
|
||||
g_hash_table_destroy(rtp_dyn_payloads);
|
||||
rtp_dyn_payloads = NULL;
|
||||
|
||||
/* remove this callback? */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* the following initializes the single GHashTable - this is invoked as an init_routine,
|
||||
but those are called both at init and cleanup times, and the cleanup time is before
|
||||
wmem scope is exited, so we ignore this if rtp_dyn_payloads is not NULL.
|
||||
*/
|
||||
static void
|
||||
rtp_dyn_payloads_init(void)
|
||||
{
|
||||
if (rtp_dyn_payloads == NULL) {
|
||||
rtp_dyn_payloads = g_hash_table_new(NULL, NULL);
|
||||
wmem_register_callback(wmem_file_scope(), wmem_rtp_dyn_payload_destroy_cb, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/* creates a new hashtable and sets ref_count to 1, returning the newly created object */
|
||||
rtp_dyn_payload_t* rtp_dyn_payload_new(void)
|
||||
{
|
||||
/* create the new entry */
|
||||
rtp_dyn_payload_t * rtp_dyn_payload = wmem_new(wmem_file_scope(), rtp_dyn_payload_t);
|
||||
rtp_dyn_payload->table = g_hash_table_new_full(NULL, NULL, NULL, rtp_dyn_payload_value_destroy);
|
||||
rtp_dyn_payload->ref_count = 1;
|
||||
|
||||
/* now put it in our single rtp_dyn_payloads GHashTable */
|
||||
g_hash_table_insert(rtp_dyn_payloads, rtp_dyn_payload, rtp_dyn_payload);
|
||||
|
||||
return rtp_dyn_payload;
|
||||
}
|
||||
|
||||
static rtp_dyn_payload_t*
|
||||
rtp_dyn_payload_ref(rtp_dyn_payload_t *rtp_dyn_payload)
|
||||
{
|
||||
if (rtp_dyn_payload) {
|
||||
rtp_dyn_payload->ref_count++;
|
||||
}
|
||||
return rtp_dyn_payload;
|
||||
}
|
||||
|
||||
/* Inserts the given payload type key, for the encoding name and sample rate, into the hash table.
|
||||
This makes copies of the encoding name, scoped to the life of the capture file or sooner if
|
||||
rtp_dyn_payload_free is called. */
|
||||
void
|
||||
rtp_dyn_payload_insert(rtp_dyn_payload_t *rtp_dyn_payload,
|
||||
const guint8 pt,
|
||||
const gchar* encoding_name,
|
||||
const int sample_rate)
|
||||
{
|
||||
if (rtp_dyn_payload && rtp_dyn_payload->table) {
|
||||
encoding_name_and_rate_t *encoding_name_and_rate_pt =
|
||||
wmem_new(wmem_file_scope(), encoding_name_and_rate_t);
|
||||
encoding_name_and_rate_pt->encoding_name = wmem_strdup(wmem_file_scope(), encoding_name);
|
||||
encoding_name_and_rate_pt->sample_rate = sample_rate;
|
||||
g_hash_table_insert(rtp_dyn_payload->table, GUINT_TO_POINTER(pt), encoding_name_and_rate_pt);
|
||||
}
|
||||
}
|
||||
|
||||
/* Replaces the given payload type key in the hash table, with the encoding name and sample rate.
|
||||
This makes copies of the encoding name, scoped to the life of the capture file or sooner if
|
||||
rtp_dyn_payload_free is called. */
|
||||
void
|
||||
rtp_dyn_payload_replace(rtp_dyn_payload_t *rtp_dyn_payload,
|
||||
const guint8 pt,
|
||||
const gchar* encoding_name,
|
||||
const int sample_rate)
|
||||
{
|
||||
if (rtp_dyn_payload && rtp_dyn_payload->table) {
|
||||
encoding_name_and_rate_t *encoding_name_and_rate_pt =
|
||||
wmem_new(wmem_file_scope(), encoding_name_and_rate_t);
|
||||
encoding_name_and_rate_pt->encoding_name = wmem_strdup(wmem_file_scope(), encoding_name);
|
||||
encoding_name_and_rate_pt->sample_rate = sample_rate;
|
||||
g_hash_table_replace(rtp_dyn_payload->table, GUINT_TO_POINTER(pt), encoding_name_and_rate_pt);
|
||||
}
|
||||
}
|
||||
|
||||
/* removes the given payload type */
|
||||
gboolean
|
||||
rtp_dyn_payload_remove(rtp_dyn_payload_t *rtp_dyn_payload, const guint8 pt)
|
||||
{
|
||||
return (rtp_dyn_payload && rtp_dyn_payload->table &&
|
||||
g_hash_table_remove(rtp_dyn_payload->table, GUINT_TO_POINTER(pt)));
|
||||
}
|
||||
|
||||
/* retrieves the encoding name for the given payload type */
|
||||
const gchar*
|
||||
rtp_dyn_payload_get_name(rtp_dyn_payload_t *rtp_dyn_payload, const guint8 pt)
|
||||
{
|
||||
encoding_name_and_rate_t *encoding_name_and_rate_pt;
|
||||
|
||||
if (!rtp_dyn_payload || !rtp_dyn_payload->table) return NULL;
|
||||
|
||||
encoding_name_and_rate_pt = (encoding_name_and_rate_t*)g_hash_table_lookup(rtp_dyn_payload->table,
|
||||
GUINT_TO_POINTER(pt));
|
||||
|
||||
return (encoding_name_and_rate_pt ? encoding_name_and_rate_pt->encoding_name : NULL);
|
||||
}
|
||||
|
||||
/* retrieves the encoding name and sample rate for the given payload type, returning TRUE if
|
||||
successful, else FALSE. The encoding string pointed to is only valid until the entry is
|
||||
replaced, removed, or the hash table is destroyed, so duplicate it if you need it long. */
|
||||
gboolean
|
||||
rtp_dyn_payload_get_full(rtp_dyn_payload_t *rtp_dyn_payload, const guint8 pt,
|
||||
const gchar **encoding_name, int *sample_rate)
|
||||
{
|
||||
encoding_name_and_rate_t *encoding_name_and_rate_pt;
|
||||
*encoding_name = NULL;
|
||||
*sample_rate = 0;
|
||||
|
||||
if (!rtp_dyn_payload || !rtp_dyn_payload->table) return FALSE;
|
||||
|
||||
encoding_name_and_rate_pt = (encoding_name_and_rate_t*)g_hash_table_lookup(rtp_dyn_payload->table,
|
||||
GUINT_TO_POINTER(pt));
|
||||
|
||||
if (encoding_name_and_rate_pt) {
|
||||
*encoding_name = encoding_name_and_rate_pt->encoding_name;
|
||||
*sample_rate = encoding_name_and_rate_pt->sample_rate;
|
||||
}
|
||||
|
||||
return (encoding_name_and_rate_pt != NULL);
|
||||
}
|
||||
|
||||
/* Free's and destroys the dyn_payload hash table; internally this decrements the ref_count
|
||||
and only free's it if the ref_count == 0. */
|
||||
void
|
||||
rtp_dyn_payload_free(rtp_dyn_payload_t *rtp_dyn_payload)
|
||||
{
|
||||
if (!rtp_dyn_payload) return;
|
||||
|
||||
if (rtp_dyn_payload->ref_count > 0)
|
||||
--(rtp_dyn_payload->ref_count);
|
||||
|
||||
if (rtp_dyn_payload->ref_count == 0) {
|
||||
|
||||
#ifdef DEBUG_CONVERSATION
|
||||
DPRINT(("free'ing the following rtp_dyn_payload:"));
|
||||
DINDENT();
|
||||
rtp_dump_dyn_payload(rtp_dyn_payload);
|
||||
DENDENT();
|
||||
#endif
|
||||
|
||||
/* remove it from the single rtp_dyn_payloads GHashTable */
|
||||
g_assert(rtp_dyn_payloads);
|
||||
if (!g_hash_table_remove(rtp_dyn_payloads, rtp_dyn_payload)) {
|
||||
g_error("rtp_dyn_payload not found in rtp_dyn_payloads table to remove!");
|
||||
}
|
||||
|
||||
/* destroy the table GHashTable in it - this automatically deletes the
|
||||
members too, because we used destroy function callbacks */
|
||||
if (rtp_dyn_payload->table)
|
||||
g_hash_table_destroy(rtp_dyn_payload->table);
|
||||
|
||||
/* free the object itself */
|
||||
wmem_free(wmem_file_scope(), rtp_dyn_payload);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
bluetooth_add_address(packet_info *pinfo, address *addr,
|
||||
|
@ -928,7 +1158,7 @@ bluetooth_add_address(packet_info *pinfo, address *addr,
|
|||
* Update the conversation data.
|
||||
*/
|
||||
/* Free the hash if already exists */
|
||||
rtp_free_hash_dyn_payload(p_conv_data->rtp_dyn_payload);
|
||||
rtp_dyn_payload_free(p_conv_data->rtp_dyn_payload);
|
||||
|
||||
g_strlcpy(p_conv_data->method, setup_method, MAX_RTP_SETUP_METHOD_SIZE+1);
|
||||
p_conv_data->frame_number = setup_frame_number;
|
||||
|
@ -941,7 +1171,7 @@ bluetooth_add_address(packet_info *pinfo, address *addr,
|
|||
void
|
||||
srtp_add_address(packet_info *pinfo, address *addr, int port, int other_port,
|
||||
const gchar *setup_method, guint32 setup_frame_number,
|
||||
gboolean is_video _U_, GHashTable *rtp_dyn_payload,
|
||||
gboolean is_video _U_, rtp_dyn_payload_t *rtp_dyn_payload,
|
||||
struct srtp_info *srtp_info)
|
||||
{
|
||||
address null_addr;
|
||||
|
@ -1022,13 +1252,16 @@ srtp_add_address(packet_info *pinfo, address *addr, int port, int other_port,
|
|||
* Update the conversation data.
|
||||
*/
|
||||
/* Free the hash if a different one already exists */
|
||||
if (p_conv_data->rtp_dyn_payload != rtp_dyn_payload)
|
||||
rtp_free_hash_dyn_payload(p_conv_data->rtp_dyn_payload);
|
||||
if (p_conv_data->rtp_dyn_payload != rtp_dyn_payload) {
|
||||
rtp_dyn_payload_free(p_conv_data->rtp_dyn_payload);
|
||||
p_conv_data->rtp_dyn_payload = rtp_dyn_payload_ref(rtp_dyn_payload);
|
||||
} else {
|
||||
DPRINT(("passed-in rtp_dyn_payload is the same as in the conversation"));
|
||||
}
|
||||
|
||||
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;
|
||||
p_conv_data->bta2dp_info = NULL;
|
||||
p_conv_data->btvdp_info = NULL;
|
||||
|
@ -1038,7 +1271,7 @@ srtp_add_address(packet_info *pinfo, address *addr, int port, int other_port,
|
|||
void
|
||||
rtp_add_address(packet_info *pinfo, address *addr, int port, int other_port,
|
||||
const gchar *setup_method, guint32 setup_frame_number,
|
||||
gboolean is_video , GHashTable *rtp_dyn_payload)
|
||||
gboolean is_video , rtp_dyn_payload_t *rtp_dyn_payload)
|
||||
{
|
||||
srtp_add_address(pinfo, addr, port, other_port, setup_method, setup_frame_number, is_video, rtp_dyn_payload, NULL);
|
||||
}
|
||||
|
@ -1163,13 +1396,8 @@ process_rtp_payload(tvbuff_t *newtvb, packet_info *pinfo, proto_tree *tree,
|
|||
payload_type >= PT_UNDF_96 && payload_type <= PT_UNDF_127) {
|
||||
/* if the payload type is dynamic, we check if the conv is set and we look for the pt definition */
|
||||
if (p_conv_data && p_conv_data->rtp_dyn_payload) {
|
||||
gchar *payload_type_str = NULL;
|
||||
encoding_name_and_rate_t *encoding_name_and_rate_pt = NULL;
|
||||
encoding_name_and_rate_pt = (encoding_name_and_rate_t *)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){
|
||||
const gchar *payload_type_str = rtp_dyn_payload_get_name(p_conv_data->rtp_dyn_payload, payload_type);
|
||||
if (payload_type_str) {
|
||||
found_match = dissector_try_string(rtp_dyn_pt_dissector_table,
|
||||
payload_type_str, newtvb, pinfo, tree, NULL);
|
||||
/* If payload type string set from conversation and
|
||||
|
@ -1452,7 +1680,7 @@ dissect_rtp_rfc2198(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
|||
rfc2198_hdr *hdr_last, *hdr_new;
|
||||
rfc2198_hdr *hdr_chain = NULL;
|
||||
struct _rtp_conversation_info *p_conv_data= NULL;
|
||||
gchar *payload_type_str;
|
||||
const gchar *payload_type_str;
|
||||
|
||||
/* Retrieve RTPs idea of a converation */
|
||||
p_conv_data = (struct _rtp_conversation_info *)p_get_proto_data(wmem_file_scope(), pinfo, proto_rtp, 0);
|
||||
|
@ -1477,11 +1705,7 @@ dissect_rtp_rfc2198(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
|||
/* if it is dynamic payload, let use the conv data to see if it is defined */
|
||||
if ((hdr_new->pt > 95) && (hdr_new->pt < 128)) {
|
||||
if (p_conv_data && p_conv_data->rtp_dyn_payload){
|
||||
encoding_name_and_rate_t *encoding_name_and_rate_pt = NULL;
|
||||
encoding_name_and_rate_pt = (encoding_name_and_rate_t *)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;
|
||||
}
|
||||
payload_type_str = rtp_dyn_payload_get_name(p_conv_data->rtp_dyn_payload, hdr_new->pt);
|
||||
}
|
||||
}
|
||||
/* Add a subtree for this header and add items */
|
||||
|
@ -1645,7 +1869,7 @@ dissect_rtp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_
|
|||
unsigned int csrc_count;
|
||||
gboolean marker_set;
|
||||
unsigned int payload_type;
|
||||
gchar *payload_type_str = NULL;
|
||||
const gchar *payload_type_str = NULL;
|
||||
gboolean is_srtp = FALSE;
|
||||
unsigned int i = 0;
|
||||
unsigned int hdr_extension_len= 0;
|
||||
|
@ -1826,24 +2050,20 @@ dissect_rtp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_
|
|||
|
||||
/* 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){
|
||||
encoding_name_and_rate_t *encoding_name_and_rate_pt = NULL;
|
||||
if (p_conv_data && p_conv_data->rtp_dyn_payload) {
|
||||
int sample_rate = 0;
|
||||
|
||||
#ifdef DEBUG_CONVERSATION
|
||||
rtp_dump_dyn_payload(p_conv_data->rtp_dyn_payload);
|
||||
#endif
|
||||
DPRINT(("looking up conversation data for dyn_pt=%d", payload_type));
|
||||
|
||||
encoding_name_and_rate_pt = (encoding_name_and_rate_t *)g_hash_table_lookup(p_conv_data->rtp_dyn_payload, &payload_type);
|
||||
|
||||
DPRINT(("did %sfind conversation data for dyn_pt=%d",
|
||||
encoding_name_and_rate_pt?"":"not ", payload_type));
|
||||
|
||||
if (encoding_name_and_rate_pt) {
|
||||
if (rtp_dyn_payload_get_full(p_conv_data->rtp_dyn_payload, payload_type,
|
||||
&payload_type_str, &sample_rate)) {
|
||||
DPRINT(("found conversation data for dyn_pt=%d, enc_name=%s",
|
||||
payload_type,encoding_name_and_rate_pt->encoding_name));
|
||||
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;
|
||||
payload_type, payload_type_str));
|
||||
rtp_info->info_payload_type_str = payload_type_str;
|
||||
rtp_info->info_payload_rate = sample_rate;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2316,15 +2536,18 @@ get_conv_info(packet_info *pinfo, struct _rtp_info *rtp_info)
|
|||
guint32 seqno;
|
||||
|
||||
/* Save this conversation info into packet info */
|
||||
/* XXX: why is this file pool not pinfo->pool? */
|
||||
p_conv_packet_data = wmem_new(wmem_file_scope(), struct _rtp_conversation_info);
|
||||
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;
|
||||
/* do not increment ref count for the rtp_dyn_payload */
|
||||
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;
|
||||
p_conv_packet_data->bta2dp_info = p_conv_data->bta2dp_info;
|
||||
p_conv_packet_data->btvdp_info = p_conv_data->btvdp_info;
|
||||
/* XXX: why is this file pool not pinfo->pool? */
|
||||
p_add_proto_data(wmem_file_scope(), pinfo, proto_rtp, 0, p_conv_packet_data);
|
||||
|
||||
/* calculate extended sequence number */
|
||||
|
@ -3338,6 +3561,7 @@ proto_register_rtp(void)
|
|||
&rtp_rfc2198_pt);
|
||||
|
||||
register_init_routine(rtp_fragment_init);
|
||||
register_init_routine(rtp_dyn_payloads_init);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -100,6 +100,72 @@ struct srtp_info
|
|||
#endif
|
||||
};
|
||||
|
||||
/* an opaque object holding the hash table - use accessor functions to create/destroy/find */
|
||||
typedef struct _rtp_dyn_payload_t rtp_dyn_payload_t;
|
||||
|
||||
/* RTP dynamic payload handling - use the following to create, insert, lookup, and free the
|
||||
dynamic payload information. Internally, RTP creates the GHashTable with a wmem file scope
|
||||
and increments the ref_count when it saves the info to conversations later. The calling
|
||||
dissector (SDP, H.245, etc.) uses these functions as an interface. If the calling dissector
|
||||
is done with the rtp_dyn_payload_t* for good, it should call rtp_dyn_payload_free() which
|
||||
will decrement the ref_count and free's it if the ref_count is 0. In the worst case, it
|
||||
will get free'd when the wmem file scope is over.
|
||||
|
||||
This was changed because there were too many bugs with SDP's handling of memory ownership
|
||||
of the GHashTable, with RTP freeing things SDP didn't think were free'ed. And also because
|
||||
the GHashTables never got free'd in many cases by several dissectors.
|
||||
*/
|
||||
|
||||
/* creates a new hashtable and sets ref_count to 1, returning the newly created object */
|
||||
WS_DLL_PUBLIC
|
||||
rtp_dyn_payload_t* rtp_dyn_payload_new(void);
|
||||
|
||||
/* Inserts the given payload type key, for the encoding name and sample rate, into the hash table.
|
||||
This makes copies of the encoding name, scoped to the life of the capture file or sooner if
|
||||
rtp_dyn_payload_free is called. */
|
||||
WS_DLL_PUBLIC
|
||||
void rtp_dyn_payload_insert(rtp_dyn_payload_t *rtp_dyn_payload,
|
||||
const guint8 pt,
|
||||
const gchar* encoding_name,
|
||||
const int sample_rate);
|
||||
|
||||
/* Replaces the given payload type key in the hash table, with the encoding name and sample rate.
|
||||
This makes copies of the encoding name, scoped to the life of the capture file or sooner if
|
||||
rtp_dyn_payload_free is called. The replaced encoding name is free'd immediately. */
|
||||
WS_DLL_PUBLIC
|
||||
void rtp_dyn_payload_replace(rtp_dyn_payload_t *rtp_dyn_payload,
|
||||
const guint8 pt,
|
||||
const gchar* encoding_name,
|
||||
const int sample_rate);
|
||||
|
||||
/* removes the given payload type */
|
||||
WS_DLL_PUBLIC
|
||||
gboolean rtp_dyn_payload_remove(rtp_dyn_payload_t *rtp_dyn_payload, const guint8 pt);
|
||||
|
||||
/* retrieves the encoding name for the given payload type; the string returned is only valid
|
||||
until the entry is replaced, removed, or the hash table is destroyed, so duplicate it if
|
||||
you need it long. */
|
||||
WS_DLL_PUBLIC
|
||||
const gchar* rtp_dyn_payload_get_name(rtp_dyn_payload_t *rtp_dyn_payload, const guint8 pt);
|
||||
|
||||
/* retrieves the encoding name and sample rate for the given payload type, returning TRUE if
|
||||
successful, else FALSE. The encoding string pointed to is only valid until the entry is
|
||||
replaced, removed, or the hash table is destroyed, so duplicate it if you need it long. */
|
||||
WS_DLL_PUBLIC
|
||||
gboolean rtp_dyn_payload_get_full(rtp_dyn_payload_t *rtp_dyn_payload, const guint8 pt,
|
||||
const gchar **encoding_name, int *sample_rate);
|
||||
|
||||
/* Free's and destroys the dyn_payload hash table; internally this decrements the ref_count
|
||||
and only free's it if the ref_count == 0. */
|
||||
WS_DLL_PUBLIC
|
||||
void rtp_dyn_payload_free(rtp_dyn_payload_t *rtp_dyn_payload);
|
||||
|
||||
|
||||
#ifdef DEBUG_CONVERSATION
|
||||
/* used for printing out debugging info, if DEBUG_CONVERSATION is defined */
|
||||
void rtp_dump_dyn_payload(rtp_dyn_payload_t *rtp_dyn_payload);
|
||||
#endif
|
||||
|
||||
/* Info to save in RTP conversation / packet-info */
|
||||
#define MAX_RTP_SETUP_METHOD_SIZE 7
|
||||
struct _rtp_conversation_info
|
||||
|
@ -107,7 +173,7 @@ struct _rtp_conversation_info
|
|||
gchar method[MAX_RTP_SETUP_METHOD_SIZE + 1];
|
||||
guint32 frame_number; /* the frame where this conversation is started */
|
||||
gboolean is_video;
|
||||
GHashTable *rtp_dyn_payload; /* a hash table with the dynamic RTP payload */
|
||||
rtp_dyn_payload_t *rtp_dyn_payload; /* the dynamic RTP payload info - see comments above */
|
||||
|
||||
guint32 extended_seqno; /* the sequence number, extended to a 32-bit
|
||||
* int to guarantee it increasing monotonically
|
||||
|
@ -121,11 +187,6 @@ struct _rtp_conversation_info
|
|||
btvdp_codec_info_t *btvdp_info;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
char *encoding_name;
|
||||
int sample_rate;
|
||||
} encoding_name_and_rate_t;
|
||||
|
||||
/* Add an RTP conversation with the given details */
|
||||
WS_DLL_PUBLIC
|
||||
void rtp_add_address(packet_info *pinfo,
|
||||
|
@ -134,7 +195,7 @@ void rtp_add_address(packet_info *pinfo,
|
|||
const gchar *setup_method,
|
||||
guint32 setup_frame_number,
|
||||
gboolean is_video,
|
||||
GHashTable *rtp_dyn_payload);
|
||||
rtp_dyn_payload_t *rtp_dyn_payload);
|
||||
|
||||
/* Add an SRTP conversation with the given details */
|
||||
WS_DLL_PUBLIC
|
||||
|
@ -144,7 +205,7 @@ void srtp_add_address(packet_info *pinfo,
|
|||
const gchar *setup_method,
|
||||
guint32 setup_frame_number,
|
||||
gboolean is_video,
|
||||
GHashTable *rtp_dyn_payload,
|
||||
rtp_dyn_payload_t *rtp_dyn_payload,
|
||||
struct srtp_info *srtp_info);
|
||||
|
||||
/* Add an Bluetooth conversation with the given details */
|
||||
|
@ -152,8 +213,3 @@ void
|
|||
bluetooth_add_address(packet_info *pinfo, address *addr,
|
||||
const gchar *setup_method, guint32 setup_frame_number,
|
||||
gboolean is_video, void *data);
|
||||
|
||||
/* Free and destroy the dyn_payload hash table */
|
||||
WS_DLL_PUBLIC
|
||||
void rtp_free_hash_dyn_payload(GHashTable *rtp_dyn_payload);
|
||||
|
||||
|
|
|
@ -41,6 +41,11 @@
|
|||
#include <epan/addr_resolv.h>
|
||||
|
||||
#include "packet-sdp.h"
|
||||
|
||||
/* un-comment the following as well as this line in conversation.c, to enable debug printing */
|
||||
/* #define DEBUG_CONVERSATION */
|
||||
#include "conversation_debug.h"
|
||||
|
||||
#include "packet-rtp.h"
|
||||
|
||||
#include "packet-rtcp.h"
|
||||
|
@ -52,10 +57,6 @@
|
|||
#include "packet-h264.h"
|
||||
#include "packet-mp4ves.h"
|
||||
|
||||
/* un-comment the following as well as this line in conversation.c, to enable debug printing */
|
||||
/* #define DEBUG_CONVERSATION */
|
||||
#include "conversation_debug.h"
|
||||
|
||||
void proto_register_sdp(void);
|
||||
void proto_reg_handoff_sdp(void);
|
||||
|
||||
|
@ -208,7 +209,7 @@ static expert_field ei_sdp_invalid_line = EI_INIT;
|
|||
typedef struct {
|
||||
gint32 pt[SDP_MAX_RTP_PAYLOAD_TYPES];
|
||||
gint8 pt_count;
|
||||
GHashTable *rtp_dyn_payload;
|
||||
rtp_dyn_payload_t *rtp_dyn_payload;
|
||||
gboolean set_rtp;
|
||||
} transport_media_pt_t;
|
||||
|
||||
|
@ -254,24 +255,6 @@ typedef struct {
|
|||
|
||||
/* here lie the debugging dumper functions */
|
||||
#ifdef DEBUG_CONVERSATION
|
||||
/* Called for each entry in the rtp_dyn_payload hash table. */
|
||||
static void
|
||||
rtp_dyn_payload_table_foreach_func (gpointer key, gpointer value, gpointer user_data _U_) {
|
||||
gint* pt = (gint*) key;
|
||||
encoding_name_and_rate_t *encoding = (encoding_name_and_rate_t*) value;
|
||||
|
||||
DPRINT2(("pt=%d",*pt));
|
||||
DINDENT();
|
||||
if (encoding) {
|
||||
DPRINT2(("encoding_name=%s",
|
||||
encoding->encoding_name ? encoding->encoding_name : "NULL"));
|
||||
DPRINT2(("sample_rate=%d", encoding->sample_rate));
|
||||
} else {
|
||||
DPRINT2(("encoding=NULL"));
|
||||
}
|
||||
DENDENT();
|
||||
}
|
||||
|
||||
static void sdp_dump_transport_media(const transport_media_pt_t* media) {
|
||||
int i;
|
||||
int count;
|
||||
|
@ -291,14 +274,7 @@ static void sdp_dump_transport_media(const transport_media_pt_t* media) {
|
|||
DENDENT();
|
||||
DPRINT2(("rtp_dyn_payload hashtable=%s", media->rtp_dyn_payload ? "YES" : "NO"));
|
||||
if (media->rtp_dyn_payload) {
|
||||
DPRINT2(("rtp_dyn_payload hash table contents:"));
|
||||
DINDENT();
|
||||
if (g_hash_table_size(media->rtp_dyn_payload) == 0) {
|
||||
DPRINT2(("rtp_dyn_payload is empty"));
|
||||
} else {
|
||||
g_hash_table_foreach(media->rtp_dyn_payload, rtp_dyn_payload_table_foreach_func, NULL);
|
||||
}
|
||||
DENDENT();
|
||||
rtp_dump_dyn_payload(media->rtp_dyn_payload);
|
||||
}
|
||||
DPRINT2(("set_rtp=%s", media->set_rtp ? "TRUE" : "FALSE"));
|
||||
DENDENT();
|
||||
|
@ -1289,7 +1265,6 @@ static void dissect_sdp_media_attribute(tvbuff_t *tvb, packet_info *pinfo, proto
|
|||
/*??guint8 *field_name;*/
|
||||
guint8 *payload_type;
|
||||
guint8 *attribute_value;
|
||||
gint *key;
|
||||
guint8 pt;
|
||||
gint sdp_media_attrbute_code;
|
||||
const char *msrp_res = "msrp://";
|
||||
|
@ -1297,7 +1272,6 @@ static void dissect_sdp_media_attribute(tvbuff_t *tvb, packet_info *pinfo, proto
|
|||
gboolean has_more_pars = TRUE;
|
||||
tvbuff_t *h245_tvb;
|
||||
guint8 master_key_length = 0, master_salt_length = 0;
|
||||
encoding_name_and_rate_t *encoding_name_and_rate;
|
||||
|
||||
offset = 0;
|
||||
|
||||
|
@ -1364,9 +1338,6 @@ static void dissect_sdp_media_attribute(tvbuff_t *tvb, packet_info *pinfo, proto
|
|||
return; /* Invalid */
|
||||
}
|
||||
|
||||
key = wmem_new(wmem_file_scope(), gint);
|
||||
*key = (gint)strtol((char*)payload_type, NULL, 10);
|
||||
|
||||
transport_info->encoding_name[pt] = (char*)tvb_get_string_enc(wmem_packet_scope(), tvb, offset, tokenlen, ENC_UTF_8|ENC_NA);
|
||||
|
||||
next_offset = next_offset + 1;
|
||||
|
@ -1399,30 +1370,17 @@ static void dissect_sdp_media_attribute(tvbuff_t *tvb, packet_info *pinfo, proto
|
|||
*/
|
||||
if (transport_info->media_count < 0) {
|
||||
for (n = 0; n < SDP_MAX_RTP_CHANNELS; n++) {
|
||||
encoding_name_and_rate = wmem_new(wmem_file_scope(), encoding_name_and_rate_t);
|
||||
encoding_name_and_rate->encoding_name = wmem_strdup(wmem_file_scope(), 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 = wmem_new(wmem_file_scope(), gint);
|
||||
*key2 = (gint)strtol((char*)payload_type, NULL, 10);
|
||||
g_hash_table_insert(transport_info->media[n].rtp_dyn_payload,
|
||||
key2, encoding_name_and_rate);
|
||||
}
|
||||
rtp_dyn_payload_insert(transport_info->media[n].rtp_dyn_payload,
|
||||
pt,
|
||||
transport_info->encoding_name[pt],
|
||||
transport_info->sample_rate[pt]);
|
||||
}
|
||||
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 = wmem_new(wmem_file_scope(), encoding_name_and_rate_t);
|
||||
}
|
||||
|
||||
encoding_name_and_rate->encoding_name = wmem_strdup(wmem_file_scope(), transport_info->encoding_name[pt]);
|
||||
encoding_name_and_rate->sample_rate = transport_info->sample_rate[pt];
|
||||
g_hash_table_insert(transport_info->media[ transport_info->media_count ].rtp_dyn_payload,
|
||||
key, encoding_name_and_rate);
|
||||
rtp_dyn_payload_insert(transport_info->media[ transport_info->media_count ].rtp_dyn_payload,
|
||||
pt, transport_info->encoding_name[pt], transport_info->sample_rate[pt]);
|
||||
break;
|
||||
case SDP_FMTP:
|
||||
if (sdp_media_attribute_tree) {
|
||||
|
@ -1917,8 +1875,7 @@ setup_sdp_transport(tvbuff_t *tvb, packet_info *pinfo, enum sdp_exchange_type ex
|
|||
transport_info->encoding_name[n] = (char*)UNKNOWN_ENCODING;
|
||||
}
|
||||
for (n = 0; n < SDP_MAX_RTP_CHANNELS; n++) {
|
||||
transport_info->media[n].rtp_dyn_payload =
|
||||
g_hash_table_new(g_int_hash, g_int_equal);
|
||||
transport_info->media[n].rtp_dyn_payload = rtp_dyn_payload_new();
|
||||
transport_info->media[n].set_rtp = FALSE;
|
||||
}
|
||||
|
||||
|
@ -1955,7 +1912,7 @@ setup_sdp_transport(tvbuff_t *tvb, packet_info *pinfo, enum sdp_exchange_type ex
|
|||
(transport_info->sdp_status == SDP_EXCHANGE_OFFER)) {
|
||||
for (n = start_transport_info_count; n < SDP_MAX_RTP_CHANNELS; n++) {
|
||||
if (!transport_info->media[n].rtp_dyn_payload)
|
||||
transport_info->media[n].rtp_dyn_payload = g_hash_table_new(g_int_hash, g_int_equal);
|
||||
transport_info->media[n].rtp_dyn_payload = rtp_dyn_payload_new();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2160,10 +2117,10 @@ setup_sdp_transport(tvbuff_t *tvb, packet_info *pinfo, enum sdp_exchange_type ex
|
|||
/* Free the hash table if we did't assigned it to a conv use it */
|
||||
if (!transport_info->media[n].set_rtp)
|
||||
{
|
||||
DPRINT(("set_rtp is not set, calling rtp_free_hash_dyn_payload, "
|
||||
DPRINT(("set_rtp is not set, calling rtp_dyn_payload_free, "
|
||||
"channel=%d, media_port=%d",
|
||||
n, transport_info->media_port[n]));
|
||||
rtp_free_hash_dyn_payload(transport_info->media[n].rtp_dyn_payload);
|
||||
rtp_dyn_payload_free(transport_info->media[n].rtp_dyn_payload);
|
||||
transport_info->media[n].rtp_dyn_payload = NULL;
|
||||
}
|
||||
|
||||
|
@ -2176,10 +2133,10 @@ setup_sdp_transport(tvbuff_t *tvb, packet_info *pinfo, enum sdp_exchange_type ex
|
|||
{
|
||||
if (!transport_info->media[n].set_rtp)
|
||||
{
|
||||
DPRINT(("media_count == -1, calling rtp_free_hash_dyn_payload, "
|
||||
DPRINT(("media_count == -1, calling rtp_dyn_payload_free, "
|
||||
"channel=%d, media_port=%d",
|
||||
n, transport_info->media_port[n]));
|
||||
rtp_free_hash_dyn_payload(transport_info->media[n].rtp_dyn_payload);
|
||||
rtp_dyn_payload_free(transport_info->media[n].rtp_dyn_payload);
|
||||
transport_info->media[n].rtp_dyn_payload = NULL;
|
||||
}
|
||||
}
|
||||
|
@ -2190,10 +2147,10 @@ setup_sdp_transport(tvbuff_t *tvb, packet_info *pinfo, enum sdp_exchange_type ex
|
|||
{
|
||||
if (!transport_info->media[n].set_rtp)
|
||||
{
|
||||
DPRINT(("media_count != -1, calling rtp_free_hash_dyn_payload, "
|
||||
DPRINT(("media_count != -1, calling rtp_dyn_payload_free, "
|
||||
"channel=%d, media_port=%d",
|
||||
n, transport_info->media_port[n]));
|
||||
rtp_free_hash_dyn_payload(transport_info->media[n].rtp_dyn_payload);
|
||||
rtp_dyn_payload_free(transport_info->media[n].rtp_dyn_payload);
|
||||
transport_info->media[n].rtp_dyn_payload = NULL;
|
||||
}
|
||||
}
|
||||
|
@ -2208,7 +2165,7 @@ setup_sdp_transport(tvbuff_t *tvb, packet_info *pinfo, enum sdp_exchange_type ex
|
|||
{
|
||||
if (!transport_info->media[n].set_rtp)
|
||||
{
|
||||
rtp_free_hash_dyn_payload(transport_info->media[n].rtp_dyn_payload);
|
||||
rtp_dyn_payload_free(transport_info->media[n].rtp_dyn_payload);
|
||||
transport_info->media[n].rtp_dyn_payload = NULL;
|
||||
}
|
||||
}
|
||||
|
@ -2281,8 +2238,7 @@ dissect_sdp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
|||
local_transport_info.encoding_name[n] = (char*)UNKNOWN_ENCODING;
|
||||
}
|
||||
for (n = 0; n < SDP_MAX_RTP_CHANNELS; n++) {
|
||||
local_transport_info.media[n].rtp_dyn_payload =
|
||||
g_hash_table_new(g_int_hash, g_int_equal);
|
||||
local_transport_info.media[n].rtp_dyn_payload = rtp_dyn_payload_new();
|
||||
local_transport_info.media[n].set_rtp = FALSE;
|
||||
}
|
||||
|
||||
|
@ -2559,14 +2515,13 @@ dissect_sdp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
|||
i, local_transport_info.media[n].pt[i]));
|
||||
/* if the payload type is dynamic (96 to 127), check the hash table to add the desc in the SDP summary */
|
||||
if ((local_transport_info.media[n].pt[i] >= 96) && (local_transport_info.media[n].pt[i] <= 127)) {
|
||||
encoding_name_and_rate_t *encoding_name_and_rate_pt =
|
||||
(encoding_name_and_rate_t *)g_hash_table_lookup(
|
||||
const gchar *payload_type_str = rtp_dyn_payload_get_name(
|
||||
local_transport_info.media[n].rtp_dyn_payload,
|
||||
&local_transport_info.media[n].pt[i]);
|
||||
if (encoding_name_and_rate_pt) {
|
||||
local_transport_info.media[n].pt[i]);
|
||||
if (payload_type_str) {
|
||||
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);
|
||||
g_strlcat(sdp_pi->summary_str, payload_type_str, 50);
|
||||
} else {
|
||||
char num_pt[10];
|
||||
g_snprintf(num_pt, 10, "%u", local_transport_info.media[n].pt[i]);
|
||||
|
@ -2589,7 +2544,7 @@ dissect_sdp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
|||
if ((transport_info == &local_transport_info) &&
|
||||
!transport_info->media[n].set_rtp)
|
||||
{
|
||||
rtp_free_hash_dyn_payload(transport_info->media[n].rtp_dyn_payload);
|
||||
rtp_dyn_payload_free(transport_info->media[n].rtp_dyn_payload);
|
||||
transport_info->media[n].rtp_dyn_payload = NULL;
|
||||
}
|
||||
|
||||
|
@ -2611,7 +2566,7 @@ dissect_sdp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
|||
{
|
||||
if (!transport_info->media[n].set_rtp)
|
||||
{
|
||||
rtp_free_hash_dyn_payload(transport_info->media[n].rtp_dyn_payload);
|
||||
rtp_dyn_payload_free(transport_info->media[n].rtp_dyn_payload);
|
||||
transport_info->media[n].rtp_dyn_payload = NULL;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -563,10 +563,9 @@ RTP_packet(void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, void cons
|
|||
/* Use existing packet info if available */
|
||||
p_conv_data = (struct _rtp_conversation_info *)p_get_proto_data(wmem_file_scope(), pinfo, proto_get_id_by_filter_name("rtp"), 0);
|
||||
if (p_conv_data && p_conv_data->rtp_dyn_payload) {
|
||||
encoding_name_and_rate_t *encoding_name_and_rate_pt = NULL;
|
||||
encoding_name_and_rate_pt = (encoding_name_and_rate_t *)g_hash_table_lookup(p_conv_data->rtp_dyn_payload, &strinfo->pt);
|
||||
if (encoding_name_and_rate_pt) {
|
||||
strinfo->pt_str = g_strdup(encoding_name_and_rate_pt->encoding_name);
|
||||
const gchar *encoding_name = rtp_dyn_payload_get_name(p_conv_data->rtp_dyn_payload, strinfo->pt);
|
||||
if (encoding_name) {
|
||||
strinfo->pt_str = g_strdup(encoding_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue