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:
parent
9c5f199050
commit
a04f610989
|
@ -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 \
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 */
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 =
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue