aboutsummaryrefslogtreecommitdiffstats
path: root/epan
diff options
context:
space:
mode:
authorHadriel Kaplan <hadrielk@yahoo.com>2014-04-02 02:07:16 -0400
committerAnders Broman <a.broman58@gmail.com>2014-04-03 04:40:20 +0000
commit04c05a21e34cec326f1aff2f5f8a6e74e1ced984 (patch)
tree6db27e328578c12b6c1c4841a708e12eec0f4c24 /epan
parentdf80f3133cc3b128ea989ad6830511c378fa0b63 (diff)
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>
Diffstat (limited to 'epan')
-rw-r--r--epan/dissectors/packet-ansi_a.c26
-rw-r--r--epan/dissectors/packet-applemidi.c13
-rw-r--r--epan/dissectors/packet-h245.c22
-rw-r--r--epan/dissectors/packet-rtp.c322
-rw-r--r--epan/dissectors/packet-rtp.h82
-rw-r--r--epan/dissectors/packet-sdp.c107
6 files changed, 389 insertions, 183 deletions
diff --git a/epan/dissectors/packet-ansi_a.c b/epan/dissectors/packet-ansi_a.c
index 47bddc4c66..edd778d7b8 100644
--- a/epan/dissectors/packet-ansi_a.c
+++ b/epan/dissectors/packet-ansi_a.c
@@ -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);
diff --git a/epan/dissectors/packet-applemidi.c b/epan/dissectors/packet-applemidi.c
index 750dac641f..21443e4767 100644
--- a/epan/dissectors/packet-applemidi.c
+++ b/epan/dissectors/packet-applemidi.c
@@ -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);
diff --git a/epan/dissectors/packet-h245.c b/epan/dissectors/packet-h245.c
index 6b3dc986ae..3591fec176 100644
--- a/epan/dissectors/packet-h245.c
+++ b/epan/dissectors/packet-h245.c
@@ -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;
diff --git a/epan/dissectors/packet-rtp.c b/epan/dissectors/packet-rtp.c
index c32607f219..24e622400b 100644
--- a/epan/dissectors/packet-rtp.c
+++ b/epan/dissectors/packet-rtp.c
@@ -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);
}
+/* 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)
+{
+ 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_free_hash_dyn_payload(GHashTable *rtp_dyn_payload)
+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)
{
- if (rtp_dyn_payload == NULL) return;
- g_hash_table_destroy(rtp_dyn_payload);
- rtp_dyn_payload = NULL;
+ 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
diff --git a/epan/dissectors/packet-rtp.h b/epan/dissectors/packet-rtp.h
index 28f54baf9f..f2454d4fcd 100644
--- a/epan/dissectors/packet-rtp.h
+++ b/epan/dissectors/packet-rtp.h
@@ -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);
-
diff --git a/epan/dissectors/packet-sdp.c b/epan/dissectors/packet-sdp.c
index 2fa3efd39d..a1494c434f 100644
--- a/epan/dissectors/packet-sdp.c
+++ b/epan/dissectors/packet-sdp.c
@@ -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;
}
}