Add debug printing functions for conversations, sip, sdp, rtp

There have been enough gnarly bus in sip/sdp/rtp that it needs
to have good debug printing. Using a debugger isn't good enough
because there's interaction across multiple frames and it's too
hard to follow what's going on without real printed data history.

Change-Id: Ifb5bb1fb580be81f988569ece79d238a9c030c34
Reviewed-on: https://code.wireshark.org/review/688
Reviewed-by: Hadriel Kaplan <hadrielk@yahoo.com>
Reviewed-by: Anders Broman <a.broman58@gmail.com>
This commit is contained in:
Hadriel Kaplan 2014-03-05 10:56:33 -05:00 committed by Anders Broman
parent 9c5f199050
commit a04f610989
6 changed files with 522 additions and 28 deletions

View File

@ -163,6 +163,7 @@ LIBWIRESHARK_INCLUDES = \
column-info.h \
column-utils.h \
conversation.h \
conversation_debug.h \
conv_id.h \
crc16-tvb.h \
crc32-tvb.h \

View File

@ -30,6 +30,14 @@
#include "emem.h"
#include "conversation.h"
/* define DEBUG_CONVERSATION for pretty debug printing */
/* #define DEBUG_CONVERSATION */
#include "conversation_debug.h"
#ifdef DEBUG_CONVERSATION
int _debug_conversation_indent = 0;
#endif
/*
* Hash table for conversations with no wildcards.
*/
@ -551,9 +559,11 @@ conversation_insert_into_hashtable(GHashTable *hashtable, conversation_t *conv)
conv->next = NULL;
conv->last = conv;
g_hash_table_insert(hashtable, conv->key_ptr, conv);
DPRINT(("created a new conversation chain"));
}
else {
/* There's an existing chain for this key */
DPRINT(("there's an existing conversation chain"));
chain_tail = chain_head->last;
@ -666,6 +676,10 @@ conversation_new(const guint32 setup_frame, const address *addr1, const address
conversation_t *conversation=NULL;
conversation_key *new_key;
DPRINT(("creating conversation for frame #%d: %s:%d -> %s:%d (ptype=%d)",
setup_frame, ep_address_to_str(addr1), port1,
ep_address_to_str(addr2), port2, ptype));
if (options & NO_ADDR2) {
if (options & (NO_PORT2|NO_PORT2_FORCE)) {
hashtable = conversation_hashtable_no_addr2_or_port2;
@ -705,7 +719,9 @@ conversation_new(const guint32 setup_frame, const address *addr1, const address
new_index++;
DINDENT();
conversation_insert_into_hashtable(hashtable, conversation);
DENDENT();
return conversation;
}
@ -720,12 +736,15 @@ conversation_set_port2(conversation_t *conv, const guint32 port)
DISSECTOR_ASSERT_HINT(!(conv->options & CONVERSATION_TEMPLATE),
"Use the conversation_create_from_template function when the CONVERSATION_TEMPLATE bit is set in the options mask");
DPRINT(("called for port=%d", port));
/*
* If the port 2 value is not wildcarded, don't set it.
*/
if ((!(conv->options & NO_PORT2)) || (conv->options & NO_PORT2_FORCE))
return;
DINDENT();
if (conv->options & NO_ADDR2) {
conversation_remove_from_hashtable(conversation_hashtable_no_addr2_or_port2, conv);
} else {
@ -738,6 +757,7 @@ conversation_set_port2(conversation_t *conv, const guint32 port)
} else {
conversation_insert_into_hashtable(conversation_hashtable_exact, conv);
}
DENDENT();
}
/*
@ -750,12 +770,15 @@ conversation_set_addr2(conversation_t *conv, const address *addr)
DISSECTOR_ASSERT_HINT(!(conv->options & CONVERSATION_TEMPLATE),
"Use the conversation_create_from_template function when the CONVERSATION_TEMPLATE bit is set in the options mask");
DPRINT(("called for addr=%s",ep_address_to_str(addr)));
/*
* If the address 2 value is not wildcarded, don't set it.
*/
if (!(conv->options & NO_ADDR2))
return;
DINDENT();
if (conv->options & NO_PORT2) {
conversation_remove_from_hashtable(conversation_hashtable_no_addr2_or_port2, conv);
} else {
@ -768,6 +791,7 @@ conversation_set_addr2(conversation_t *conv, const address *addr)
} else {
conversation_insert_into_hashtable(conversation_hashtable_exact, conv);
}
DENDENT();
}
/*
@ -868,12 +892,14 @@ find_conversation(const guint32 frame_num, const address *addr_a, const address
* Neither search address B nor search port B are wildcarded,
* start out with an exact match.
*/
DPRINT(("trying exact match"));
conversation =
conversation_lookup_hashtable(conversation_hashtable_exact,
frame_num, addr_a, addr_b, ptype,
port_a, port_b);
/* Didn't work, try the other direction */
if (conversation == NULL) {
DPRINT(("trying opposite direction"));
conversation =
conversation_lookup_hashtable(conversation_hashtable_exact,
frame_num, addr_b, addr_a, ptype,
@ -888,6 +914,7 @@ find_conversation(const guint32 frame_num, const address *addr_a, const address
frame_num, addr_b, addr_a, ptype,
port_a, port_b);
}
DPRINT(("exact match %sfound",conversation?"":"not "));
if (conversation != NULL)
return conversation;
}
@ -906,6 +933,7 @@ find_conversation(const guint32 frame_num, const address *addr_a, const address
* address and port.
* ("addr_b" doesn't take part in this lookup.)
*/
DPRINT(("trying wildcarded dest address"));
conversation =
conversation_lookup_hashtable(conversation_hashtable_no_addr2,
frame_num, addr_a, addr_b, ptype, port_a, port_b);
@ -930,6 +958,7 @@ find_conversation(const guint32 frame_num, const address *addr_a, const address
* don't get packets in a given direction coming from more than one
* address, unless the CONVERSATION_TEMPLATE option is set.)
*/
DPRINT(("wildcarded dest address match found"));
if (!(conversation->options & NO_ADDR_B) && ptype != PT_UDP)
{
if(!(conversation->options & CONVERSATION_TEMPLATE))
@ -956,6 +985,7 @@ find_conversation(const guint32 frame_num, const address *addr_a, const address
* ("addr_a" doesn't take part in this lookup.)
*/
if (!(options & NO_ADDR_B)) {
DPRINT(("trying dest addr:port as source addr:port with wildcarded dest addr"));
conversation =
conversation_lookup_hashtable(conversation_hashtable_no_addr2,
frame_num, addr_b, addr_a, ptype, port_b, port_a);
@ -968,6 +998,7 @@ find_conversation(const guint32 frame_num, const address *addr_a, const address
* wildcarded second address for this
* conversation.
*/
DPRINT(("match found"));
if (ptype != PT_UDP) {
if(!(conversation->options & CONVERSATION_TEMPLATE))
{
@ -998,6 +1029,7 @@ find_conversation(const guint32 frame_num, const address *addr_a, const address
* address and port.
* ("port_b" doesn't take part in this lookup.)
*/
DPRINT(("trying wildcarded dest port"));
conversation =
conversation_lookup_hashtable(conversation_hashtable_no_port2,
frame_num, addr_a, addr_b, ptype, port_a, port_b);
@ -1021,6 +1053,7 @@ find_conversation(const guint32 frame_num, const address *addr_a, const address
* get packets in a given direction coming from more than one port,
* unless the CONVERSATION_TEMPLATE option is set.)
*/
DPRINT(("match found"));
if (!(conversation->options & NO_PORT_B) && ptype != PT_UDP)
{
if(!(conversation->options & CONVERSATION_TEMPLATE))
@ -1047,6 +1080,7 @@ find_conversation(const guint32 frame_num, const address *addr_a, const address
* ("port_a" doesn't take part in this lookup.)
*/
if (!(options & NO_PORT_B)) {
DPRINT(("trying dest addr:port as source addr:port and wildcarded dest port"));
conversation =
conversation_lookup_hashtable(conversation_hashtable_no_port2,
frame_num, addr_b, addr_a, ptype, port_b, port_a);
@ -1059,6 +1093,7 @@ find_conversation(const guint32 frame_num, const address *addr_a, const address
* wildcarded second address for this
* conversation.
*/
DPRINT(("match found"));
if (ptype != PT_UDP)
{
if(!(conversation->options & CONVERSATION_TEMPLATE))
@ -1084,6 +1119,7 @@ find_conversation(const guint32 frame_num, const address *addr_a, const address
* and port A as the first address and port.
* (Neither "addr_b" nor "port_b" take part in this lookup.)
*/
DPRINT(("trying wildcarding dest addr:port"));
conversation =
conversation_lookup_hashtable(conversation_hashtable_no_addr2_or_port2,
frame_num, addr_a, addr_b, ptype, port_a, port_b);
@ -1101,6 +1137,7 @@ find_conversation(const guint32 frame_num, const address *addr_a, const address
* as that's the port that matched the wildcarded
* second port for this conversation.
*/
DPRINT(("match found"));
if (ptype != PT_UDP)
{
if(!(conversation->options & CONVERSATION_TEMPLATE))
@ -1128,6 +1165,7 @@ find_conversation(const guint32 frame_num, const address *addr_a, const address
* first packet in the conversation).
* (Neither "addr_a" nor "port_a" take part in this lookup.)
*/
DPRINT(("trying dest addr:port as source addr:port and wildcarding dest addr:port"));
if (addr_a->type == AT_FC)
conversation =
conversation_lookup_hashtable(conversation_hashtable_no_addr2_or_port2,
@ -1146,6 +1184,7 @@ find_conversation(const guint32 frame_num, const address *addr_a, const address
* that matched the wildcarded second port for this
* conversation.
*/
DPRINT(("match found"));
if (ptype != PT_UDP)
{
if(!(conversation->options & CONVERSATION_TEMPLATE))
@ -1161,6 +1200,8 @@ find_conversation(const guint32 frame_num, const address *addr_a, const address
return conversation;
}
DPRINT(("no matches found"));
/*
* We found no conversation.
*/
@ -1288,20 +1329,33 @@ find_or_create_conversation(packet_info *pinfo)
{
conversation_t *conv=NULL;
DPRINT(("called for frame #%d: %s:%d -> %s:%d (ptype=%d)",
pinfo->fd->num, ep_address_to_str(&pinfo->src), pinfo->srcport,
ep_address_to_str(&pinfo->dst), pinfo->destport, pinfo->ptype));
DINDENT();
/* Have we seen this conversation before? */
if((conv = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst,
pinfo->ptype, pinfo->srcport,
pinfo->destport, 0)) != NULL) {
DPRINT(("found previous conversation for frame #%d (last_frame=%d)",
pinfo->fd->num, conv->last_frame));
if (pinfo->fd->num > conv->last_frame) {
conv->last_frame = pinfo->fd->num;
}
} else {
/* No, this is a new conversation. */
DPRINT(("did not find previous conversation for frame #%d",
pinfo->fd->num));
DINDENT();
conv = conversation_new(pinfo->fd->num, &pinfo->src,
&pinfo->dst, pinfo->ptype,
pinfo->srcport, pinfo->destport, 0);
DENDENT();
}
DENDENT();
return conv;
}

47
epan/conversation_debug.h Normal file
View File

@ -0,0 +1,47 @@
/* a file of debug printing stuff for conversation-related things,
* although really anything can use this so long as it includes this
*
* define DEBUG_CONVERSATION before including this file to turn on printing
* and also define it in conversation.c (because it has the indent variable)
*/
#ifndef _CONVERSATION_DEBUG_H
#define _CONVERSATION_DEBUG_H
#ifdef DEBUG_CONVERSATION
#include <stdio.h>
#include "to_str.h"
extern int _debug_conversation_indent; /* the instance is in conversation.c */
#define DINDENT() _debug_conversation_indent += 4
#define DENDENT() _debug_conversation_indent -= 4
#define DPRINT(arg) \
g_printerr("%*.*s%s: ", \
_debug_conversation_indent,_debug_conversation_indent," ", \
G_STRLOC); \
g_printerr arg; \
g_printerr("\n")
#define DPRINT2(arg) \
g_printerr("%*.*s", \
_debug_conversation_indent,_debug_conversation_indent," "); \
g_printerr arg; \
g_printerr("\n")
#else /* !DEBUG_CONVERSATION */
/* a hack to let these defines be used with trailing semi-colon and not
* cause gcc extra-check pedantic warnings for extra colons
*/
#define DINDENT() (void)0
#define DENDENT() (void)0
#define DPRINT(arg) (void)0
#define DPRINT2(arg) (void)0
#endif /* DEBUG_CONVERSATION */
#endif /* _CONVERSATION_DEBUG_H */

View File

@ -70,7 +70,12 @@
#include <epan/wmem/wmem.h>
#include <epan/strutil.h>
/* un-comment the following as well as this line in conversation.c, to enable debug printing */
/* #define DEBUG_CONVERSATION */
#include "conversation_debug.h"
/* uncomment this to enable debugging of fragment reassembly */
/* #define DEBUG 1 */
/* #define DEBUG_FRAGMENTS 1 */
typedef struct _rfc2198_hdr {
@ -801,6 +806,39 @@ static const value_string srtp_auth_alg_vals[] =
};
#endif
#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));
if (encoding) {
DPRINT2(("encoding_name=%s",
encoding->encoding_name ? encoding->encoding_name : "NULL"));
DPRINT2(("sample_rate=%d", encoding->sample_rate));
} else {
DPRINT2(("encoding=NULL"));
}
}
static void rtp_dump_dyn_payload(GHashTable *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);
}
DENDENT();
}
#endif /* DEBUG_CONVERSATION */
/* initialisation routine */
static void
rtp_fragment_init(void)
@ -920,11 +958,10 @@ srtp_add_address(packet_info *pinfo, address *addr, int port, int other_port,
return;
}
#ifdef DEBUG
printf("#%u: %srtp_add_address(%s, %u, %u, %s, %u\n",
pinfo->fd->num, (srtp_info)?"s":"", ep_address_to_str(addr), port,
other_port, setup_method, setup_frame_number);
#endif
DPRINT(("#%u: %srtp_add_address(%s, %u, %u, %s, %u)",
pinfo->fd->num, (srtp_info)?"s":"", ep_address_to_str(addr), port,
other_port, setup_method, setup_frame_number));
DINDENT();
SET_ADDRESS(&null_addr, AT_NONE, 0, NULL);
@ -935,6 +972,9 @@ srtp_add_address(packet_info *pinfo, address *addr, int port, int other_port,
p_conv = find_conversation(setup_frame_number, addr, &null_addr, PT_UDP, port, other_port,
NO_ADDR_B | (!other_port ? NO_PORT_B : 0));
DENDENT();
DPRINT(("did %sfind conversation", p_conv?"":"NOT "));
/*
* If not, create a new conversation.
*/
@ -956,6 +996,8 @@ srtp_add_address(packet_info *pinfo, address *addr, int port, int other_port,
* If not, add a new data item.
*/
if (! p_conv_data) {
DPRINT(("creating new conversation data"));
/* Create conversation data */
p_conv_data = wmem_new(wmem_file_scope(), struct _rtp_conversation_info);
p_conv_data->rtp_dyn_payload = NULL;
@ -966,8 +1008,15 @@ srtp_add_address(packet_info *pinfo, address *addr, int port, int other_port,
p_conv_data->extended_seqno = 0x10000;
p_conv_data->rtp_conv_info = wmem_new(wmem_file_scope(), rtp_private_conv_info);
p_conv_data->rtp_conv_info->multisegment_pdus = wmem_tree_new(wmem_file_scope());
DINDENT();
conversation_add_proto_data(p_conv, proto_rtp, p_conv_data);
DENDENT();
}
#ifdef DEBUG_CONVERSATION
else {
DPRINT(("conversation already exists"));
}
#endif
/*
* Update the conversation data.
@ -1779,8 +1828,20 @@ dissect_rtp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_
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;
#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) {
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;
}

View File

@ -52,6 +52,10 @@
#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);
@ -247,6 +251,153 @@ typedef struct {
} disposable_media_info_t;
/* 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;
DPRINT2(("transport_media contents:"));
DINDENT();
if (!media) {
DPRINT2(("null transport_media_pt_t*"));
DENDENT();
return;
}
DPRINT2(("pt_count=%hhu",media->pt_count));
DINDENT();
for (i=0; i < media->pt_count; i++) {
DPRINT2(("pt=%d", media->pt[i]));
}
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();
}
DPRINT2(("set_rtp=%s", media->set_rtp ? "TRUE" : "FALSE"));
DENDENT();
}
static const value_string sdp_exchange_type_vs[] = {
{ SDP_EXCHANGE_OFFER, "SDP_EXCHANGE_OFFER" },
{ SDP_EXCHANGE_ANSWER_ACCEPT, "SDP_EXCHANGE_ANSWER_ACCEPT" },
{ SDP_EXCHANGE_ANSWER_REJECT, "SDP_EXCHANGE_ANSWER_REJECT" },
{ 0, NULL }
};
static void sdp_dump_transport_info(const transport_info_t* info) {
int i;
DPRINT2(("transport_info contents:"));
DINDENT();
if (!info) {
DPRINT2(("null transport_info_t*"));
DENDENT();
return;
}
DPRINT2(("sdp_status=%s",
val_to_str(info->sdp_status, sdp_exchange_type_vs, "SDP_EXCHANGE_UNKNOWN")));
DPRINT2(("payload type contents:"));
DINDENT();
for (i=0; i < SDP_NO_OF_PT; i++) {
/* don't print out unknown encodings */
if (info->encoding_name[i] &&
strcmp(UNKNOWN_ENCODING,info->encoding_name[i]) != 0) {
DPRINT2(("payload type #%d:",i));
DINDENT();
DPRINT2(("encoding_name=%s", info->encoding_name[i]));
DPRINT2(("sample_rate=%d", info->sample_rate[i]));
DENDENT();
}
}
DENDENT();
DPRINT2(("media_count=%hhd", info->media_count));
DPRINT2(("rtp channels:"));
DINDENT();
for (i=0; i <= info->media_count; i++) {
DPRINT2(("channel #%d:",i));
DINDENT();
DPRINT2(("src_addr=%s",
address_to_str(wmem_packet_scope(), &(info->src_addr[i]))));
DPRINT2(("media_port=%d", info->media_port[i]));
DPRINT2(("proto_bitmask=%x", info->proto_bitmask[i]));
sdp_dump_transport_media(&(info->media[i]));
DENDENT();
}
DENDENT();
DPRINT2(("encryption_algorithm=%u", info->encryption_algorithm));
DPRINT2(("auth_algorithm=%u", info->auth_algorithm));
if (info->encryption_algorithm || info->auth_algorithm) {
DPRINT2(("mki_len=%u", info->mki_len));
if (info->auth_algorithm) {
DPRINT2(("auth_tag_len=%u", info->auth_tag_len));
}
}
DENDENT();
}
static void sdp_dump_disposable_media_info(const disposable_media_info_t* info) {
int i;
DPRINT2(("disposable_media_info contents:"));
DINDENT();
if (!info) {
DPRINT2(("null disposable_media_info_t*"));
DENDENT();
return;
}
DPRINT2(("connection_address=%s",
info->connection_address ? info->connection_address : "NULL"));
DPRINT2(("connection_type=%s",
info->connection_type ? info->connection_type : "NULL"));
DPRINT2(("media_count=%hhu",info->media_count));
DINDENT();
for (i=0; i < info->media_count; i++) {
DPRINT2(("media #%d:",i));
DINDENT();
DPRINT2(("media_type=%s", info->media_type[i] ? info->media_type[i] : "NULL"));
DPRINT2(("media_port=%s", info->media_port[i] ? info->media_port[i] : "NULL"));
DPRINT2(("media_proto=%s", info->media_proto[i] ? info->media_proto[i] : "NULL"));
DENDENT();
}
DENDENT();
DPRINT2(("msrp_transport_address_set=%s",
info->msrp_transport_address_set ? "TRUE" : "FALSE"));
if (info->msrp_transport_address_set) {
DINDENT();
DPRINT2(("msrp_ipaddr=%u.%u.%u.%u",
info->msrp_ipaddr[0],info->msrp_ipaddr[1],
info->msrp_ipaddr[2],info->msrp_ipaddr[3]));
DPRINT2(("msrp_port_number=%hu",info->msrp_port_number));
DENDENT();
}
DENDENT();
}
#endif /* DEBUG_CONVERSATION */
/* key-mgmt dissector
* IANA registry:
* http://www.iana.org/assignments/sdp-parameters
@ -351,6 +502,7 @@ dissect_sdp_connection_info(tvbuff_t *tvb, proto_item* ti,
/* Save connection address type */
media_info->connection_type = (char*)tvb_get_string(wmem_packet_scope(), tvb, offset, tokenlen);
DPRINT(("parsed connection line type=%s", media_info->connection_type));
proto_tree_add_item(sdp_connection_info_tree,
hf_connection_info_address_type, tvb, offset, tokenlen,
@ -371,6 +523,8 @@ dissect_sdp_connection_info(tvbuff_t *tvb, proto_item* ti,
media_info->connection_address = (char*)tvb_get_string(wmem_packet_scope(), tvb, offset, tokenlen);
}
DPRINT(("parsed connection line address=%s", media_info->connection_address));
proto_tree_add_item(sdp_connection_info_tree,
hf_connection_info_connection_address, tvb, offset,
tokenlen, ENC_ASCII|ENC_NA);
@ -698,6 +852,10 @@ dissect_sdp_media(tvbuff_t *tvb, proto_item *ti,
media_info->media_type[media_info->media_count] = (char*)tvb_get_string(wmem_packet_scope(), tvb, offset, tokenlen);
DPRINT(("parsed media_type=%s, for media_count=%d",
media_info->media_type[media_info->media_count],
media_info->media_count));
offset = next_offset + 1;
next_offset = tvb_find_guint8(tvb, offset, -1, ' ');
@ -711,6 +869,10 @@ dissect_sdp_media(tvbuff_t *tvb, proto_item *ti,
/* Save port info */
media_info->media_port[media_info->media_count] = (char*)tvb_get_string(wmem_packet_scope(), tvb, offset, tokenlen);
DPRINT(("parsed media_port=%s, for media_count=%d",
media_info->media_port[media_info->media_count],
media_info->media_count));
proto_tree_add_uint(sdp_media_tree, hf_media_port, tvb, offset, tokenlen,
atoi((char*)tvb_get_string(wmem_packet_scope(), tvb, offset, tokenlen)));
offset = next_offset + 1;
@ -729,6 +891,9 @@ dissect_sdp_media(tvbuff_t *tvb, proto_item *ti,
tokenlen = next_offset - offset;
/* Save port info */
media_info->media_port[media_info->media_count] = (char*)tvb_get_string(wmem_packet_scope(), tvb, offset, tokenlen);
DPRINT(("parsed media_port=%s, for media_count=%d",
media_info->media_port[media_info->media_count],
media_info->media_count));
/* XXX Remember Port */
proto_tree_add_uint(sdp_media_tree, hf_media_port, tvb, offset, tokenlen,
atoi((char*)tvb_get_string(wmem_packet_scope(), tvb, offset, tokenlen)));
@ -744,6 +909,10 @@ dissect_sdp_media(tvbuff_t *tvb, proto_item *ti,
/* Save port protocol */
media_info->media_proto[media_info->media_count] = (char*)tvb_get_string(wmem_packet_scope(), tvb, offset, tokenlen);
DPRINT(("parsed media_proto=%s, for media_count=%d",
media_info->media_proto[media_info->media_count],
media_info->media_count));
/* XXX Remember Protocol */
proto_tree_add_item(sdp_media_tree, hf_media_proto, tvb, offset, tokenlen,
ENC_ASCII|ENC_NA);
@ -766,7 +935,10 @@ dissect_sdp_media(tvbuff_t *tvb, proto_item *ti,
tokenlen, val_to_str_ext((guint32)strtoul((char*)media_format, NULL, 10), &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] = (gint32)strtol((char*)media_format, NULL, 10);
if (idx < (SDP_MAX_RTP_PAYLOAD_TYPES-1))
DPRINT(("parsed media codec pt=%d, for media_count=%d",
transport_info->media[transport_info->media_count].pt[idx],
transport_info->media_count));
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,
@ -1592,6 +1764,8 @@ convert_disposable_media(transport_info_t* transport_info, disposable_media_info
transport_index = n+start_transport_info_count;
if (media_info->media_port[n] != NULL) {
transport_info->media_port[transport_index] = (int)strtol(media_info->media_port[n], NULL, 10);
DPRINT(("set transport_info media port number=%d, for transport_index=%d",
transport_info->media_port[transport_index], transport_index));
}
if (media_info->media_proto[n] != NULL) {
@ -1606,28 +1780,38 @@ convert_disposable_media(transport_info_t* transport_info, disposable_media_info
if (!strcmp(media_info->media_proto[n],"RTP/AVP")) {
transport_info->proto_bitmask[transport_index] |= SDP_RTP_PROTO;
proto_bitmask |= SDP_RTP_PROTO;
DPRINT(("set SDP_RTP_PROTO bitmask=%x, for transport_index=%d",
transport_info->proto_bitmask[transport_index], transport_index));
}
/* Check if media protocol is SRTP */
else if (!strcmp(media_info->media_proto[n],"RTP/SAVP")) {
transport_info->proto_bitmask[transport_index] |= SDP_SRTP_PROTO;
proto_bitmask |= SDP_SRTP_PROTO;
DPRINT(("set SDP_SRTP_PROTO bitmask=%x, for transport_index=%d",
transport_info->proto_bitmask[transport_index], transport_index));
}
/* Check if media protocol is T38 */
else if ((!strcmp(media_info->media_proto[n],"UDPTL")) ||
(!strcmp(media_info->media_proto[n],"udptl"))) {
transport_info->proto_bitmask[transport_index] |= SDP_T38_PROTO;
proto_bitmask |= SDP_T38_PROTO;
DPRINT(("set SDP_T38_PROTO bitmask=%x, for transport_index=%d",
transport_info->proto_bitmask[transport_index], transport_index));
}
/* Check if media protocol is MSRP/TCP */
else if (!strcmp(media_info->media_proto[n],"msrp/tcp")) {
transport_info->proto_bitmask[transport_index] |= SDP_MSRP_PROTO;
proto_bitmask |= SDP_MSRP_PROTO;
DPRINT(("set SDP_MSRP_PROTO bitmask=%x, for transport_index=%d",
transport_info->proto_bitmask[transport_index], transport_index));
}
/* Check if media protocol is SPRT */
else if ((!strcmp(media_info->media_proto[n],"UDPSPRT")) ||
(!strcmp(media_info->media_proto[n],"udpsprt"))) {
transport_info->proto_bitmask[transport_index] |= SDP_SPRT_PROTO;
proto_bitmask |= SDP_SPRT_PROTO;
DPRINT(("set SDP_SPRT_PROTO bitmask=%x, for transport_index=%d",
transport_info->proto_bitmask[transport_index], transport_index));
}
/* now check if this stream's port==0, in which case we need to disable its paired stream */
@ -1639,6 +1823,8 @@ convert_disposable_media(transport_info_t* transport_info, disposable_media_info
answer have a non-port=0 (though that would be illegal per the RFCs). */
if (start_transport_info_count > 0 && (proto_bitmask & transport_info->proto_bitmask[n])) {
transport_info->media_port[n] = 0;
DPRINT(("disabled media_port=%d, for transport_index=%d",
n, transport_index));
}
}
}
@ -1646,23 +1832,27 @@ convert_disposable_media(transport_info_t* transport_info, disposable_media_info
if ((media_info->connection_address != NULL) &&
(media_info->connection_type != NULL)) {
if (strcmp(media_info->connection_type, "IP4") == 0) {
transport_info->src_addr[transport_index].data = wmem_alloc(wmem_file_scope(), 4);
if (str_to_ip(media_info->connection_address, (void*)transport_info->src_addr[transport_index].data)) {
/* connection_address could be converted to a valid ipv4 address*/
transport_info->proto_bitmask[transport_index] |= SDP_IPv4;
transport_info->src_addr[transport_index].type = AT_IPv4;
transport_info->src_addr[transport_index].len = 4;
if (strcmp(media_info->connection_type, "IP4") == 0) {
transport_info->src_addr[transport_index].data = wmem_alloc(wmem_file_scope(), 4);
if (str_to_ip(media_info->connection_address, (void*)transport_info->src_addr[transport_index].data)) {
/* connection_address could be converted to a valid ipv4 address*/
transport_info->proto_bitmask[transport_index] |= SDP_IPv4;
transport_info->src_addr[transport_index].type = AT_IPv4;
transport_info->src_addr[transport_index].len = 4;
DPRINT(("set SDP_IPv4 bitmask=%x, for transport_index=%d",
transport_info->proto_bitmask[transport_index], transport_index));
}
} else if (strcmp(media_info->connection_type, "IP6") == 0) {
transport_info->src_addr[transport_index].data = wmem_alloc(wmem_file_scope(), 16);
if (str_to_ip6(media_info->connection_address, (void*)transport_info->src_addr[transport_index].data)) {
/* connection_address could be converted to a valid ipv6 address*/
transport_info->proto_bitmask[transport_index] |= SDP_IPv6;
transport_info->src_addr[transport_index].type = AT_IPv6;
transport_info->src_addr[transport_index].len = 16;
DPRINT(("set SDP_IPv6 bitmask=%x, for transport_index=%d",
transport_info->proto_bitmask[transport_index], transport_index));
}
}
} else if (strcmp(media_info->connection_type, "IP6") == 0) {
transport_info->src_addr[transport_index].data = wmem_alloc(wmem_file_scope(), 16);
if (str_to_ip6(media_info->connection_address, (void*)transport_info->src_addr[transport_index].data)) {
/* connection_address could be converted to a valid ipv6 address*/
transport_info->proto_bitmask[transport_index] |= SDP_IPv6;
transport_info->src_addr[transport_index].type = AT_IPv6;
transport_info->src_addr[transport_index].len = 16;
}
}
}
/* MSRP uses addresses discovered in attribute
@ -1679,6 +1869,8 @@ convert_disposable_media(transport_info_t* transport_info, disposable_media_info
if ((media_info->media_type[transport_index] != NULL) &&
(strcmp(media_info->media_type[transport_index], "video") == 0)) {
transport_info->proto_bitmask[transport_index] |= SDP_VIDEO;
DPRINT(("set SDP_VIDEO bitmask=%x, for transport_index=%d",
transport_info->proto_bitmask[transport_index], transport_index));
}
}
}
@ -1699,9 +1891,13 @@ setup_sdp_transport(tvbuff_t *tvb, packet_info *pinfo, enum sdp_exchange_type ex
struct srtp_info *srtp_info = NULL;
DPRINT2(("-------------------- setup_sdp_transport -------------------"));
/* Only do this once during first pass */
if (pinfo->fd->flags.visited)
return;
if (pinfo->fd->flags.visited) {
DPRINT(("already visited"));
return;
}
memset(&media_info, 0, sizeof(media_info));
@ -1723,6 +1919,12 @@ setup_sdp_transport(tvbuff_t *tvb, packet_info *pinfo, enum sdp_exchange_type ex
if (request_frame != 0)
wmem_tree_insert32(sdp_transport_reqs, request_frame, (void *)transport_info);
}
#ifdef DEBUG_CONVERSATION
else {
DPRINT(("found previous transport_info:"));
sdp_dump_transport_info(transport_info);
}
#endif
if (exchange_type != SDP_EXCHANGE_OFFER)
wmem_tree_insert32(sdp_transport_rsps, pinfo->fd->num, (void *)transport_info);
@ -1737,6 +1939,8 @@ setup_sdp_transport(tvbuff_t *tvb, packet_info *pinfo, enum sdp_exchange_type ex
if (transport_info->media_count > 0)
start_transport_info_count = transport_info->media_count;
DPRINT(("start_transport_info_count=%d", start_transport_info_count));
/* if we don't delay, and this is an answer after a previous offer, then
we free'd the unused media rtp_dyn_payload last time while processing
the offer, so we need to re-create them this time in case we need them.
@ -1789,6 +1993,9 @@ setup_sdp_transport(tvbuff_t *tvb, packet_info *pinfo, enum sdp_exchange_type ex
media_info.media_count++;
in_media_description = TRUE;
DPRINT(("in media description, transport_info->media_count=%d, "
"media_info.media_count=%d",
transport_info->media_count, media_info.media_count));
break;
case 'a':
if (in_media_description) {
@ -1804,11 +2011,13 @@ setup_sdp_transport(tvbuff_t *tvb, packet_info *pinfo, enum sdp_exchange_type ex
if (hf != hf_unknown)
{
DINDENT();
call_sdp_subdissector(tvb_new_subset(tvb, offset + tokenoffset,
linelen - tokenoffset,
linelen - tokenoffset),
pinfo,
hf, NULL, linelen-tokenoffset, transport_info, &media_info);
DENDENT();
}
offset = next_offset;
@ -1834,10 +2043,23 @@ setup_sdp_transport(tvbuff_t *tvb, packet_info *pinfo, enum sdp_exchange_type ex
media_info.media_count++;
}
#ifdef DEBUG_CONVERSATION
sdp_dump_disposable_media_info(&media_info);
#endif
DPRINT(("calling convert_disposable_media(), transport_info->media_count=%d, "
"media_info.media_count=%d, start_transport_info_count=%d",
transport_info->media_count, media_info.media_count, start_transport_info_count));
DINDENT();
/* Take all of the collected strings and convert them into something permanent
* for the life of the capture
*/
convert_disposable_media(transport_info, &media_info, start_transport_info_count);
DENDENT();
#ifdef DEBUG_CONVERSATION
sdp_dump_transport_info(transport_info);
#endif
/* We have a successful negotiation, apply data to their respective protocols */
if (!delay || ((exchange_type == SDP_EXCHANGE_ANSWER_ACCEPT) &&
@ -1860,26 +2082,42 @@ setup_sdp_transport(tvbuff_t *tvb, packet_info *pinfo, enum sdp_exchange_type ex
srtp_info->auth_tag_len = transport_info->auth_tag_len;
}
DPRINT(("calling srtp_add_address, channel=%d, media_port=%d",
n, transport_info->media_port[n]));
DINDENT();
/* srtp_add_address and rtp_add_address are given the request_frame's not this frame's number,
because that's where the RTP flow started, and thus conversation needs to check against */
srtp_add_address(pinfo, &transport_info->src_addr[n], transport_info->media_port[n], 0, "SDP", request_frame,
(transport_info->proto_bitmask[n] & SDP_VIDEO) ? TRUE : FALSE,
transport_info->media[n].rtp_dyn_payload, srtp_info);
DENDENT();
} else {
DPRINT(("calling rtp_add_address, channel=%d, media_port=%d",
n, transport_info->media_port[n]));
DINDENT();
rtp_add_address(pinfo, &transport_info->src_addr[n], transport_info->media_port[n], 0, "SDP", request_frame,
(transport_info->proto_bitmask[n] & SDP_VIDEO) ? TRUE : FALSE,
transport_info->media[n].rtp_dyn_payload);
}
DENDENT();
}
transport_info->media[n].set_rtp = TRUE;
/* SPRT might use the same port... */
current_rtp_port = transport_info->media_port[n];
if (rtcp_handle) {
if (transport_info->proto_bitmask[n] & SDP_SRTP_PROTO) {
DPRINT(("calling rtcp_add_address, channel=%d, media_port=%d",
n, transport_info->media_port[n]+1));
DINDENT();
srtcp_add_address(pinfo, &transport_info->src_addr[n], transport_info->media_port[n]+1, 0, "SDP", request_frame, srtp_info);
} else {
DENDENT();
} else {
DPRINT(("calling rtcp_add_address, channel=%d, media_port=%d",
n, transport_info->media_port[n]+1));
DINDENT();
rtcp_add_address(pinfo, &transport_info->src_addr[n], transport_info->media_port[n]+1, 0, "SDP", request_frame);
}
DENDENT();
}
}
}
@ -1916,6 +2154,9 @@ 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, "
"channel=%d, media_port=%d",
n, transport_info->media_port[n]));
rtp_free_hash_dyn_payload(transport_info->media[n].rtp_dyn_payload);
transport_info->media[n].rtp_dyn_payload = NULL;
}
@ -1929,6 +2170,9 @@ 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, "
"channel=%d, media_port=%d",
n, transport_info->media_port[n]));
rtp_free_hash_dyn_payload(transport_info->media[n].rtp_dyn_payload);
transport_info->media[n].rtp_dyn_payload = NULL;
}
@ -1940,6 +2184,9 @@ 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, "
"channel=%d, media_port=%d",
n, transport_info->media_port[n]));
rtp_free_hash_dyn_payload(transport_info->media[n].rtp_dyn_payload);
transport_info->media[n].rtp_dyn_payload = NULL;
}
@ -1995,6 +2242,8 @@ dissect_sdp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
sdp_packet_info *sdp_pi;
struct srtp_info *srtp_info = NULL;
DPRINT2(("----------------------- dissect_sdp ------------------------"));
/* Initialise packet info for passing to tap */
sdp_pi = wmem_new(wmem_packet_scope(), sdp_packet_info);
sdp_pi->summary_str[0] = '\0';
@ -2011,6 +2260,12 @@ dissect_sdp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
if (transport_info == NULL) {
transport_info = &local_transport_info;
}
#ifdef DEBUG_CONVERSATION
else {
DPRINT(("found previous transport_info:"));
sdp_dump_transport_info(transport_info);
}
#endif
/* Initialize local transport info */
memset(&local_transport_info, 0, sizeof(local_transport_info));
@ -2178,8 +2433,21 @@ dissect_sdp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
/* Take all of the collected strings and convert them into something permanent
* for the life of the capture
*/
if (transport_info == &local_transport_info)
if (transport_info == &local_transport_info) {
DPRINT(("no previous transport_info saved, calling convert_disposable_media()"));
DINDENT();
convert_disposable_media(transport_info, &media_info, 0);
DENDENT();
#ifdef DEBUG_CONVERSATION
sdp_dump_transport_info(transport_info);
#endif
}
#ifdef DEBUG_CONVERSATION
else {
DPRINT(("not overwriting previous transport_info, local_transport_info contents:"));
sdp_dump_transport_info(&local_transport_info);
}
#endif
for (n = 0; n < local_transport_info.media_count; n++)
{
@ -2203,13 +2471,21 @@ dissect_sdp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
srtp_info->mki_len = transport_info->mki_len;
srtp_info->auth_tag_len = transport_info->auth_tag_len;
}
DPRINT(("calling srtp_add_address for media_port=%d, for channel=%d",
transport_info->media_port[n],n));
DINDENT();
srtp_add_address(pinfo, &transport_info->src_addr[n], transport_info->media_port[n], 0, "SDP", pinfo->fd->num,
(transport_info->proto_bitmask[n] & SDP_VIDEO) ? TRUE : FALSE,
transport_info->media[n].rtp_dyn_payload, srtp_info);
DENDENT();
} else {
DPRINT(("calling rtp_add_address for media_port=%d, for channel=%d",
transport_info->media_port[n],n));
DINDENT();
rtp_add_address(pinfo, &transport_info->src_addr[n], transport_info->media_port[n], 0, "SDP", pinfo->fd->num,
(transport_info->proto_bitmask[n] & SDP_VIDEO) ? TRUE : FALSE,
transport_info->media[n].rtp_dyn_payload);
DENDENT();
}
transport_info->media[n].set_rtp = TRUE;
/* SPRT might use the same port... */
@ -2217,9 +2493,17 @@ dissect_sdp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
if (rtcp_handle) {
if (transport_info->proto_bitmask[n] & SDP_SRTP_PROTO) {
DPRINT(("calling srtcp_add_address for media_port=%d, for channel=%d",
transport_info->media_port[n],n));
DINDENT();
srtcp_add_address(pinfo, &transport_info->src_addr[n], transport_info->media_port[n]+1, 0, "SDP", pinfo->fd->num, srtp_info);
DENDENT();
} else {
DPRINT(("calling rtcp_add_address for media_port=%d, for channel=%d",
transport_info->media_port[n],n));
DINDENT();
rtcp_add_address(pinfo, &transport_info->src_addr[n], transport_info->media_port[n]+1, 0, "SDP", pinfo->fd->num);
DENDENT();
}
}
}
@ -2265,6 +2549,8 @@ dissect_sdp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
*/
for (i = 0; i < local_transport_info.media[n].pt_count; i++)
{
DPRINT(("in for-loop for voip call analysis setting for media #%d, pt=%d",
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 =

View File

@ -57,6 +57,10 @@
#include "packet-sdp.h" /* SDP needs a transport layer to determine request/response */
/* un-comment the following as well as this line in conversation.c, to enable debug printing */
/* #define DEBUG_CONVERSATION */
#include "conversation_debug.h"
#define TCP_PORT_SIP 5060
#define UDP_PORT_SIP 5060
#define TLS_PORT_SIP 5061
@ -2414,6 +2418,8 @@ dissect_sip_common(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tr
col_set_str(pinfo->cinfo, COL_PROTOCOL, "SIP");
DPRINT2(("------------------------------ dissect_sip_common ------------------------------"));
switch (line_type) {
case REQUEST_LINE:
@ -2422,6 +2428,8 @@ dissect_sip_common(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tr
col_add_fstr(pinfo->cinfo, COL_INFO, "%s: %s",
descr,
tvb_format_text(tvb, offset, linelen - SIP2_HDR_LEN - 1));
DPRINT(("got %s: %s", descr,
tvb_format_text(tvb, offset, linelen - SIP2_HDR_LEN - 1)));
break;
case STATUS_LINE:
@ -2429,12 +2437,15 @@ dissect_sip_common(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tr
col_add_fstr(pinfo->cinfo, COL_INFO, "Status: %s",
tvb_format_text(tvb, offset + SIP2_HDR_LEN + 1, linelen - SIP2_HDR_LEN - 1));
stat_info->reason_phrase = tvb_get_string(wmem_packet_scope(), tvb, offset + SIP2_HDR_LEN + 5, linelen - (SIP2_HDR_LEN + 5));
DPRINT(("got Response: %s",
tvb_format_text(tvb, offset + SIP2_HDR_LEN + 1, linelen - SIP2_HDR_LEN - 1)));
break;
case OTHER_LINE:
default: /* Squelch compiler complaints */
descr = "Continuation";
col_set_str(pinfo->cinfo, COL_INFO, "Continuation");
DPRINT(("got continuation"));
break;
}
@ -3509,41 +3520,74 @@ dissect_sip_common(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tr
/* Resends don't count */
if (resend_for_packet == 0) {
if (line_type == REQUEST_LINE) {
DPRINT(("calling setup_sdp_transport() SDP_EXCHANGE_OFFER frame=%d",
pinfo->fd->num));
DINDENT();
setup_sdp_transport(next_tvb, pinfo, SDP_EXCHANGE_OFFER, pinfo->fd->num, sip_delay_sdp_changes);
DENDENT();
} else if (line_type == STATUS_LINE) {
if (stat_info->response_code >= 400) {
DPRINT(("calling setup_sdp_transport() SDP_EXCHANGE_ANSWER_REJECT "
"request_frame=%d, this=%d",
request_for_response, pinfo->fd->num));
DINDENT();
/* SIP client request failed, so SDP offer should fail */
setup_sdp_transport(next_tvb, pinfo, SDP_EXCHANGE_ANSWER_REJECT, request_for_response, sip_delay_sdp_changes);
DENDENT();
}
else if ((stat_info->response_code >= 200) && (stat_info->response_code <= 299)) {
DPRINT(("calling setup_sdp_transport() SDP_EXCHANGE_ANSWER_ACCEPT "
"request_frame=%d, this=%d",
request_for_response, pinfo->fd->num));
DINDENT();
/* SIP success request, so SDP offer should be accepted */
setup_sdp_transport(next_tvb, pinfo, SDP_EXCHANGE_ANSWER_ACCEPT, request_for_response, sip_delay_sdp_changes);
DENDENT();
}
}
} else {
DPRINT(("calling setup_sdp_transport() resend_for_packet "
"request_frame=%d, this=%d",
request_for_response, pinfo->fd->num));
DINDENT();
setup_sdp_transport_resend(pinfo->fd->num, resend_for_packet);
DENDENT();
}
}
/* XXX: why is this called even if setup_sdp_transport() was called before? That will
parse the SDP a second time, for 'application/sdp' media MIME bodies */
DPRINT(("calling dissector_try_string()"));
DINDENT();
found_match = dissector_try_string(media_type_dissector_table,
media_type_str_lower_case,
next_tvb, pinfo,
message_body_tree, NULL);
DENDENT();
DPRINT(("done calling dissector_try_string() with found_match=%s",
found_match?"TRUE":"FALSE"));
if (!found_match &&
!strncmp(media_type_str_lower_case, "multipart/", sizeof("multipart/")-1)) {
DPRINT(("calling dissector_try_string() for multipart"));
DINDENT();
/* Try to decode the unknown multipart subtype anyway */
found_match = dissector_try_string(media_type_dissector_table,
"multipart/",
next_tvb, pinfo,
message_body_tree, NULL);
DENDENT();
DPRINT(("done calling dissector_try_string() with found_match=%s",
found_match?"TRUE":"FALSE"));
}
pinfo->private_data = save_private_data;
/* If no match dump as text */
}
if ( found_match != TRUE )
{
DPRINT(("calling dissector_try_heuristic() with found_match=%s",
found_match?"TRUE":"FALSE"));
DINDENT();
if (!(dissector_try_heuristic(heur_subdissector_list,
next_tvb, pinfo, message_body_tree, NULL))) {
int tmp_offset = 0;
@ -3558,6 +3602,7 @@ dissect_sip_common(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tr
tmp_offset = next_offset;
}/* end while */
}
DENDENT();
}
offset += datalen;
}