Consolidate RTP stream structs.

Consolidate the three different RTP stream structs in ui/rtp_stream.h,
ui/gtk/rtp_player.c, and ui/voip_calls.c into one. Make the member names
a bit more consistent. Document what each GList contains. Use nstime_t
for timestamps since that's what we get from the frame data. Use g_new0
to initialize our structs.

Change-Id: I2b3f8f2051394a6a98a5c7bc49c117f07161d031
Reviewed-on: https://code.wireshark.org/review/5843
Petri-Dish: Gerald Combs <gerald@wireshark.org>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Gerald Combs <gerald@wireshark.org>
This commit is contained in:
Gerald Combs 2014-12-16 14:36:04 -08:00
parent 79b5bb418b
commit 2bb8255e29
7 changed files with 169 additions and 246 deletions

View File

@ -84,15 +84,15 @@ rtp_streams_stat_draw(void *arg _U_)
strinfo = (rtp_stream_info_t*)(list->data);
/* payload type */
if (strinfo->pt > 95) {
if (strinfo->info_payload_type_str != NULL) {
payload_type = g_strdup(strinfo->info_payload_type_str);
if (strinfo->payload_type > 95) {
if (strinfo->payload_type_name != NULL) {
payload_type = g_strdup(strinfo->payload_type_name);
}else{
payload_type = g_strdup_printf("Unknown(%u)", strinfo->pt);
payload_type = g_strdup_printf("Unknown(%u)", strinfo->payload_type);
}
}else{
payload_type = g_strdup(val_to_str_ext(strinfo->pt, &rtp_payload_type_vals_ext,
payload_type = g_strdup(val_to_str_ext(strinfo->payload_type, &rtp_payload_type_vals_ext,
"Unknown (%u)"));
}
@ -113,7 +113,7 @@ rtp_streams_stat_draw(void *arg _U_)
strinfo->dest_port,
strinfo->ssrc,
payload_type,
strinfo->npackets,
strinfo->packet_count,
lost, perc,
strinfo->rtp_stats.max_delta,
strinfo->rtp_stats.max_jitter,

View File

@ -66,7 +66,9 @@
#include <codecs/codecs.h>
#include "../globals.h"
#include "globals.h"
#include "ui/rtp_stream.h"
#include "ui/simple_dialog.h"
#include "ui/voip_calls.h"
@ -153,28 +155,10 @@ static PortAudioStream *pa_stream;
static PaStream *pa_stream;
#endif /* PORTAUDIO_API_1 */
/* defines a RTP stream */
typedef struct _rtp_stream_info {
address src_addr;
guint16 src_port;
address dest_addr;
guint16 dest_port;
guint32 ssrc;
guint32 first_frame_number; /* first RTP frame for the stream */
double start_time; /* RTP stream start time in ms */
nstime_t start_time_abs;
gboolean play;
guint16 call_num;
GList* rtp_packets_list; /* List of RTP packets in the stream */
guint32 num_packets;
} rtp_stream_info_t;
/* defines the RTP streams to be played in an audio channel */
typedef struct _rtp_channel_info {
double start_time; /* RTP stream start time in ms */
nstime_t start_time_abs;
double end_time; /* RTP stream end time in ms */
nstime_t stop_time_abs;
GArray *samples; /* the array with decoded audio */
guint16 call_num;
gboolean selected;
@ -268,20 +252,20 @@ static void
rtp_stream_value_destroy(gpointer rsi_arg)
{
rtp_stream_info_t *rsi = (rtp_stream_info_t *)rsi_arg;
GList* rtp_packets_list;
GList* rtp_packet_list;
rtp_packet_t *rp;
rtp_packets_list = g_list_first(rsi->rtp_packets_list);
while (rtp_packets_list)
rtp_packet_list = g_list_first(rsi->rtp_packet_list);
while (rtp_packet_list)
{
rp = (rtp_packet_t *)rtp_packets_list->data;
rp = (rtp_packet_t *)rtp_packet_list->data;
g_free(rp->info);
g_free(rp->payload_data);
g_free(rp);
rp = NULL;
rtp_packets_list = g_list_next(rtp_packets_list);
rtp_packet_list = g_list_next(rtp_packet_list);
}
g_free((void *)(rsi->src_addr.data));
g_free((void *)(rsi->dest_addr.data));
@ -378,19 +362,14 @@ add_rtp_packet(const struct _rtp_info *rtp_info, packet_info *pinfo)
/* if it is not in the hash table, create a new stream */
if (stream_info==NULL) {
stream_info = g_new(rtp_stream_info_t,1);
stream_info = g_new0(rtp_stream_info_t, 1);
COPY_ADDRESS(&(stream_info->src_addr), &(pinfo->src));
stream_info->src_port = pinfo->srcport;
COPY_ADDRESS(&(stream_info->dest_addr), &(pinfo->dst));
stream_info->dest_port = pinfo->destport;
stream_info->ssrc = rtp_info->info_sync_src;
stream_info->rtp_packets_list = NULL;
stream_info->first_frame_number = pinfo->fd->num;
stream_info->start_time = nstime_to_msec(&pinfo->rel_ts);
stream_info->start_time_abs = pinfo->fd->abs_ts;
stream_info->call_num = 0;
stream_info->play = FALSE;
stream_info->num_packets = 0;
stream_info->start_fd = pinfo->fd;
stream_info->start_rel_time = pinfo->rel_ts;
g_hash_table_insert(rtp_streams_hash, g_strdup(key_str->str), stream_info);
@ -399,14 +378,14 @@ add_rtp_packet(const struct _rtp_info *rtp_info, packet_info *pinfo)
}
/* increment the number of packets in this stream, this is used for the progress bar and statistics */
stream_info->num_packets++;
stream_info->packet_count++;
/* Add the RTP packet to the list */
new_rtp_packet = g_new(rtp_packet_t,1);
new_rtp_packet = g_new0(rtp_packet_t, 1);
new_rtp_packet->info = (struct _rtp_info *)g_malloc(sizeof(struct _rtp_info));
memcpy(new_rtp_packet->info, rtp_info, sizeof(struct _rtp_info));
new_rtp_packet->arrive_offset = nstime_to_msec(&pinfo->rel_ts) - stream_info->start_time;
new_rtp_packet->arrive_offset = nstime_to_msec(&pinfo->rel_ts) - nstime_to_msec(&stream_info->start_rel_time);
/* copy the RTP payload to the rtp_packet to be decoded later */
if (rtp_info->info_all_data_present && (rtp_info->info_payload_len != 0)) {
new_rtp_packet->payload_data = (guint8 *)g_malloc(rtp_info->info_payload_len);
@ -415,7 +394,7 @@ add_rtp_packet(const struct _rtp_info *rtp_info, packet_info *pinfo)
new_rtp_packet->payload_data = NULL;
}
stream_info->rtp_packets_list = g_list_append(stream_info->rtp_packets_list, new_rtp_packet);
stream_info->rtp_packet_list = g_list_append(stream_info->rtp_packet_list, new_rtp_packet);
g_string_free(key_str, TRUE);
}
@ -435,14 +414,14 @@ mark_rtp_stream_to_play(gchar *key _U_ , rtp_stream_info_t *rsi, gpointer ptr _U
/* Reset the "to be play" value because the user can close and reopen the RTP Player window
* and the streams are not reset in that case
*/
rsi->play = FALSE;
rsi->decode = FALSE;
/* and associate the RTP stream with a call using the first RTP packet in the stream */
graph_list = g_queue_peek_nth_link(voip_calls->graph_analysis->items, 0);
while (graph_list)
{
graph_item = (seq_analysis_item_t *)graph_list->data;
if (rsi->first_frame_number == graph_item->fd->num) {
if (rsi->start_fd->num == graph_item->fd->num) {
rsi->call_num = graph_item->conv_num;
/* if it is in the graph list, then check if the voip_call is selected */
voip_calls_list = g_queue_peek_nth_link(voip_calls->callsinfos, 0);
@ -450,8 +429,8 @@ mark_rtp_stream_to_play(gchar *key _U_ , rtp_stream_info_t *rsi, gpointer ptr _U
{
tmp_voip_call = (voip_calls_info_t *)voip_calls_list->data;
if ( (tmp_voip_call->call_num == rsi->call_num) && (tmp_voip_call->selected == TRUE) ) {
rsi->play = TRUE;
total_packets += rsi->num_packets;
rsi->decode = TRUE;
total_packets += rsi->packet_count;
break;
}
voip_calls_list = g_list_next(voip_calls_list);
@ -467,10 +446,10 @@ mark_rtp_stream_to_play(gchar *key _U_ , rtp_stream_info_t *rsi, gpointer ptr _U
* RTP player from the "RTP Analysis" window
*/
static void
mark_all_rtp_stream_to_play(gchar *key _U_ , rtp_stream_info_t *rsi, gpointer ptr _U_)
mark_all_rtp_stream_to_decode(gchar *key _U_ , rtp_stream_info_t *rsi, gpointer ptr _U_)
{
rsi->play = TRUE;
total_packets += rsi->num_packets;
rsi->decode = TRUE;
total_packets += rsi->packet_count;
}
/****************************************************************************/
@ -551,7 +530,7 @@ decode_rtp_stream(rtp_stream_info_t *rsi, gpointer ptr)
GString *key_str = NULL;
rtp_channel_info_t *rci;
gboolean first = TRUE;
GList* rtp_packets_list;
GList* rtp_packet_list;
rtp_packet_t *rp;
int i;
@ -577,6 +556,7 @@ decode_rtp_stream(rtp_stream_info_t *rsi, gpointer ptr)
SAMPLE *out_buff = NULL;
sample_t silence;
sample_t sample;
nstime_t sample_delta;
guint8 status;
guint32 start_timestamp;
GHashTable *decoders_hash = NULL;
@ -590,7 +570,7 @@ decode_rtp_stream(rtp_stream_info_t *rsi, gpointer ptr)
silence.status = S_NORMAL;
/* skip it if we are not going to play it */
if (rsi->play == FALSE) {
if (rsi->decode == FALSE) {
return;
}
@ -611,44 +591,25 @@ decode_rtp_stream(rtp_stream_info_t *rsi, gpointer ptr)
}
/* lookup for this stream in the channel hash table */
rci = (rtp_channel_info_t *)g_hash_table_lookup( rtp_channels_hash, key_str->str);
rci = (rtp_channel_info_t *)g_hash_table_lookup( rtp_channels_hash, key_str->str);
/* ..if it is not in the hash, create an entry */
if (rci == NULL) {
rci = g_new(rtp_channel_info_t,1);
rci = g_new0(rtp_channel_info_t, 1);
rci->call_num = rsi->call_num;
rci->start_time = rsi->start_time;
rci->start_time_abs = rsi->start_time_abs;
rci->end_time = rsi->start_time;
rci->selected = FALSE;
rci->frame_index = 0;
rci->drop_by_jitter_buff = 0;
rci->out_of_seq = 0;
rci->wrong_timestamp = 0;
rci->max_frame_index = 0;
rci->start_time_abs = rsi->start_fd->abs_ts;
rci->stop_time_abs = rsi->start_fd->abs_ts;
rci->samples = g_array_new (FALSE, FALSE, sizeof(sample_t));
rci->check_bt = NULL;
rci->separator = NULL;
rci->draw_area = NULL;
#if GTK_CHECK_VERSION(2,22,0)
rci->surface = NULL;
#else
rci->pixmap = NULL;
#endif
rci->h_scrollbar_adjustment = NULL;
rci->cursor_pixbuf = NULL;
rci->cursor_prev = 0;
rci->cursor_catch = FALSE;
rci->first_stream = rsi;
rci->num_packets = rsi->num_packets;
rci->num_packets = rsi->packet_count;
g_hash_table_insert(rtp_channels_hash, g_strdup(key_str->str), rci);
} else {
/* Add silence between the two streams if needed */
silence_frames = (gint32)( ((rsi->start_time - rci->end_time)/1000)*sample_rate );
silence_frames = (gint32)((nstime_to_msec(&rsi->start_fd->abs_ts) - nstime_to_msec(&rci->stop_time_abs)) * sample_rate);
for (i = 0; i< silence_frames; i++) {
g_array_append_val(rci->samples, silence);
}
rci->num_packets += rsi->num_packets;
rci->num_packets += rsi->packet_count;
}
/* decode the RTP stream */
@ -677,8 +638,8 @@ decode_rtp_stream(rtp_stream_info_t *rsi, gpointer ptr)
status = S_NORMAL;
rtp_packets_list = g_list_first(rsi->rtp_packets_list);
while (rtp_packets_list)
rtp_packet_list = g_list_first(rsi->rtp_packet_list);
while (rtp_packet_list)
{
if (progbar_count >= progbar_nextstep) {
@ -692,7 +653,7 @@ decode_rtp_stream(rtp_stream_info_t *rsi, gpointer ptr)
}
rp = (rtp_packet_t *)rtp_packets_list->data;
rp = (rtp_packet_t *)rtp_packet_list->data;
if (first == TRUE) {
/* defined start_timestmp to avoid overflow in timestamp. TODO: handle the timestamp correctly */
/* XXX: if timestamps (RTP) are missing/ignored try use packet arrive time only (see also "rtp_time") */
@ -820,11 +781,13 @@ decode_rtp_stream(rtp_stream_info_t *rsi, gpointer ptr)
g_free(out_buff);
out_buff = NULL;
}
rtp_packets_list = g_list_next (rtp_packets_list);
rtp_packet_list = g_list_next (rtp_packet_list);
progbar_count++;
}
rci->max_frame_index = rci->samples->len;
rci->end_time = rci->start_time + ((double)rci->samples->len/sample_rate)*1000;
sample_delta.secs = rci->samples->len / sample_rate;
sample_delta.nsecs = (rci->samples->len % sample_rate) * 1000000000;
nstime_sum(&rci->stop_time_abs, &rci->start_time_abs, &sample_delta);
g_string_free(key_str, TRUE);
g_hash_table_destroy(decoders_hash);
@ -1115,22 +1078,26 @@ init_rtp_channels_vals(void)
/* if the two channels are to be played, then we need to sync both based on the start/end time of each one */
} else {
rpci->max_frame_index = (guint32)(sample_rate/1000) * (guint32)(MAX(rpci->rci[0]->end_time, rpci->rci[1]->end_time) -
(guint32)MIN(rpci->rci[0]->start_time, rpci->rci[1]->start_time));
double start_time_0 = nstime_to_msec(&rpci->rci[0]->start_time_abs);
double start_time_1 = nstime_to_msec(&rpci->rci[1]->start_time_abs);
double stop_time_0 = nstime_to_msec(&rpci->rci[0]->stop_time_abs);
double stop_time_1 = nstime_to_msec(&rpci->rci[1]->stop_time_abs);
rpci->max_frame_index = (guint32)(sample_rate/1000) * (guint32)(MAX(stop_time_0, stop_time_1) -
(guint32)MIN(start_time_0, start_time_1));
if (rpci->rci[0]->start_time < rpci->rci[1]->start_time) {
if (nstime_cmp(&rpci->rci[0]->start_time_abs, &rpci->rci[1]->start_time_abs) < 0) {
rpci->start_index[0] = 0;
rpci->start_index[1] = (guint32)(sample_rate/1000) * (guint32)(rpci->rci[1]->start_time - rpci->rci[0]->start_time);
rpci->start_index[1] = (guint32)(sample_rate/1000) * (guint32)(start_time_1 - start_time_0);
} else {
rpci->start_index[1] = 0;
rpci->start_index[0] = (guint32)(sample_rate/1000) * (guint32)(rpci->rci[0]->start_time - rpci->rci[1]->start_time);
rpci->start_index[0] = (guint32)(sample_rate/1000) * (guint32)(start_time_0 - start_time_1);
}
if (rpci->rci[0]->end_time < rpci->rci[1]->end_time) {
rpci->end_index[0] = rpci->max_frame_index - ((guint32)(sample_rate/1000) * (guint32)(rpci->rci[1]->end_time - rpci->rci[0]->end_time));
if (nstime_cmp(&rpci->rci[0]->stop_time_abs, &rpci->rci[1]->stop_time_abs) < 0) {
rpci->end_index[0] = rpci->max_frame_index - ((guint32)(sample_rate/1000) * (guint32)(stop_time_1 - stop_time_0));
rpci->end_index[1] = rpci->max_frame_index;
} else {
rpci->end_index[1] = rpci->max_frame_index - ((guint32)(sample_rate/1000) * (guint32)(rpci->rci[0]->end_time - rpci->rci[1]->end_time));
rpci->end_index[1] = rpci->max_frame_index - ((guint32)(sample_rate/1000) * (guint32)(stop_time_0 - stop_time_1));
rpci->end_index[0] = rpci->max_frame_index;
}
}
@ -1301,7 +1268,7 @@ static void channel_draw(rtp_channel_info_t* rci)
pango_layout_set_font_description(small_layout, pango_font_description_from_string("Helvetica,Sans,Bold 7"));
/* calculated the pixel offset to display integer seconds */
offset = ((double)rci->start_time/1000 - floor((double)rci->start_time/1000))*sample_rate/MULT;
offset = (nstime_to_sec(&rci->start_time_abs) - floor(nstime_to_sec(&rci->start_time_abs)))*sample_rate/MULT;
cr = cairo_create (rci->surface);
cairo_set_line_width (cr, 1.0);
@ -1408,7 +1375,7 @@ static void channel_draw(rtp_channel_info_t* rci)
timestamp = localtime(&seconds);
g_snprintf(label_string, MAX_TIME_LABEL, "%02d:%02d:%02d", timestamp->tm_hour, timestamp->tm_min, timestamp->tm_sec);
} else {
g_snprintf(label_string, MAX_TIME_LABEL, "%.0f s", floor(rci->start_time/1000) + i*MULT/sample_rate);
g_snprintf(label_string, MAX_TIME_LABEL, "%.0f s", floor(nstime_to_sec(&rci->start_time_abs)) + i*MULT/sample_rate);
}
pango_layout_set_text(small_layout, label_string, -1);
@ -1652,18 +1619,18 @@ configure_event_channels(GtkWidget *widget, GdkEventConfigure *event _U_, gpoint
};
#endif
static GdkRGBA col[MAX_NUM_COL_CONV+1] = {
/* Red, Green, Blue Alpha */
{0.0039, 0.0039, 1.0000, 1.0},
{0.5664, 0.6289, 0.5664, 1.0},
{1.0000, 0.6289, 0.4805, 1.0},
{1.0000, 0.7148, 0.7578, 1.0},
{0.9805, 0.9805, 0.8242, 1.0},
{1.0000, 1.0000, 0.2031, 1.0},
{0.4023, 0.8046, 0.6680, 1.0},
{0.8789, 1.0000, 1.0000, 1.0},
{0.6914, 0.7695, 0.8710, 1.0},
{0.8281, 0.8281, 0.8281, 1.0},
static GdkRGBA col[MAX_NUM_COL_CONV+1] = {
/* Red, Green, Blue Alpha */
{0.0039, 0.0039, 1.0000, 1.0},
{0.5664, 0.6289, 0.5664, 1.0},
{1.0000, 0.6289, 0.4805, 1.0},
{1.0000, 0.7148, 0.7578, 1.0},
{0.9805, 0.9805, 0.8242, 1.0},
{1.0000, 1.0000, 0.2031, 1.0},
{0.4023, 0.8046, 0.6680, 1.0},
{0.8789, 1.0000, 1.0000, 1.0},
{0.6914, 0.7695, 0.8710, 1.0},
{0.8281, 0.8281, 0.8281, 1.0},
};
#if GTK_CHECK_VERSION(2,22,0)
@ -2215,7 +2182,7 @@ decode_streams(void)
if (voip_calls)
g_hash_table_foreach( rtp_streams_hash, (GHFunc)mark_rtp_stream_to_play, NULL);
else
g_hash_table_foreach( rtp_streams_hash, (GHFunc)mark_all_rtp_stream_to_play, NULL);
g_hash_table_foreach( rtp_streams_hash, (GHFunc)mark_all_rtp_stream_to_decode, NULL);
}
/* Decode the RTP streams and add them to the RTP channels to be played */
@ -2388,7 +2355,7 @@ rtp_player_dlg_create(void)
gtk_widget_set_size_request(main_scrolled_window, CHANNEL_WIDTH, 0);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (main_scrolled_window), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
gtk_box_pack_start(GTK_BOX(main_vb), main_scrolled_window, TRUE, TRUE, 0);
gtk_box_pack_start(GTK_BOX(main_vb), main_scrolled_window, TRUE, TRUE, 0);
channels_vb = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 0, FALSE);
gtk_container_set_border_width (GTK_CONTAINER (channels_vb), 2);

View File

@ -400,10 +400,10 @@ rtpstream_on_filter(GtkButton *button _U_, gpointer user_data _U_)
filter_string_fwd = g_strdup_printf(
"(ip%s.src==%s && udp.srcport==%u && ip%s.dst==%s && udp.dstport==%u && rtp.ssrc==0x%X)",
ip_version,
ep_address_to_str(&(selected_stream_fwd->src_addr)),
address_to_str(wmem_packet_scope(), &(selected_stream_fwd->src_addr)),
selected_stream_fwd->src_port,
ip_version,
ep_address_to_str(&(selected_stream_fwd->dest_addr)),
address_to_str(wmem_packet_scope(), &(selected_stream_fwd->dest_addr)),
selected_stream_fwd->dest_port,
selected_stream_fwd->ssrc);
@ -420,10 +420,10 @@ rtpstream_on_filter(GtkButton *button _U_, gpointer user_data _U_)
filter_string_rev = g_strdup_printf(
"(ip%s.src==%s && udp.srcport==%u && ip%s.dst==%s && udp.dstport==%u && rtp.ssrc==0x%X)",
ip_version,
ep_address_to_str(&(selected_stream_rev->src_addr)),
address_to_str(wmem_packet_scope(), &(selected_stream_rev->src_addr)),
selected_stream_rev->src_port,
ip_version,
ep_address_to_str(&(selected_stream_rev->dest_addr)),
address_to_str(wmem_packet_scope(), &(selected_stream_rev->dest_addr)),
selected_stream_rev->dest_port,
selected_stream_rev->ssrc);
@ -691,10 +691,10 @@ add_to_list_store(rtp_stream_info_t* strinfo)
data[2] = g_strdup(ep_address_to_display(&(strinfo->dest_addr)));
data[3] = NULL;
data[4] = g_strdup_printf("0x%X", strinfo->ssrc);
if (strinfo->info_payload_type_str != NULL) {
data[5] = g_strdup(strinfo->info_payload_type_str);
if (strinfo->payload_type_name != NULL) {
data[5] = g_strdup(strinfo->payload_type_name);
} else {
data[5] = g_strdup(val_to_str_ext(strinfo->pt, &rtp_payload_type_short_vals_ext,
data[5] = g_strdup(val_to_str_ext(strinfo->payload_type, &rtp_payload_type_short_vals_ext,
"Unknown (%u)"));
}
data[6] = NULL;
@ -731,7 +731,7 @@ add_to_list_store(rtp_stream_info_t* strinfo)
RTP_COL_DST_PORT, strinfo->dest_port,
RTP_COL_SSRC, data[4],
RTP_COL_PAYLOAD, data[5],
RTP_COL_PACKETS, strinfo->npackets,
RTP_COL_PACKETS, strinfo->packet_count,
RTP_COL_LOST, data[7],
RTP_COL_MAX_DELTA, strinfo->rtp_stats.max_delta,
RTP_COL_MAX_JITTER, strinfo->rtp_stats.max_jitter,

View File

@ -35,7 +35,7 @@
/****************************************************************************/
/* type for storing rtp frame information */
typedef struct st_rtp_sample_header {
guint32 rec_time; /**< milliseconds since start of recording */
double rec_time; /**< milliseconds since start of recording */
guint16 frame_length; /**< number of bytes in *frame */
} rtp_sample_header_t;
@ -55,22 +55,28 @@ typedef struct _rtp_stream_info {
address dest_addr;
guint32 dest_port;
guint32 ssrc;
guint8 pt;
const gchar *info_payload_type_str;
guint32 npackets;
guint32 first_frame_num; /**< frame number of first frame */
guint8 payload_type; /**< Numeric payload type */
gchar *payload_type_name; /**< Payload type name */
gboolean is_srtp;
guint32 packet_count;
gboolean end_stream; /**< Used to track streams across payload types */
int rtp_event;
guint16 call_num; /**< Used to match call_num in voip_calls_info_t */
guint32 setup_frame_number; /**< frame number of setup message */
/* start of recording (GMT) of this stream */
guint32 start_sec; /**< seconds */
guint32 start_usec; /**< microseconds */
gboolean tag_vlan_error;
guint32 start_rel_sec; /**< start stream rel seconds */
guint32 start_rel_usec; /**< start stream rel microseconds */
guint32 stop_rel_sec; /**< stop stream rel seconds */
guint32 stop_rel_usec; /**< stop stream rel microseconds */
gboolean tag_diffserv_error;
/* Start and stop packets needed for .num and .abs_ts */
frame_data *start_fd;
frame_data *stop_fd;
nstime_t start_rel_time; /**< relative start time from pinfo */
nstime_t stop_rel_time; /**< relative stop time from pinfo */
guint16 vlan_id;
gboolean tag_vlan_error;
gboolean tag_diffserv_error;
gboolean decode; /**< Decode this stream */
GList *rtp_packet_list; /**< List of RTP rtp_packet_t */
tap_rtp_stat_t rtp_stats; /**< here goes the RTP statistics info */
gboolean problem; /**< if the streams had wrong sequence numbers or wrong timerstamps */

View File

@ -134,8 +134,8 @@ void rtp_write_header(rtp_stream_info_t *strinfo, FILE *file)
ep_address_to_display(&(strinfo->dest_addr)),
strinfo->dest_port);
start_sec = g_htonl(strinfo->start_sec);
start_usec = g_htonl(strinfo->start_usec);
start_sec = g_htonl(strinfo->start_fd->abs_ts.secs);
start_usec = g_htonl(strinfo->start_fd->abs_ts.nsecs / 1000000);
/* rtpdump only accepts guint32 as source, will be fake for IPv6 */
memset(&source, 0, sizeof source);
sourcelen = strinfo->src_addr.len;
@ -186,95 +186,67 @@ int rtpstream_packet(void *arg, packet_info *pinfo, epan_dissect_t *edt _U_, con
{
rtpstream_tapinfo_t *tapinfo = (rtpstream_tapinfo_t *)arg;
const struct _rtp_info *rtpinfo = (const struct _rtp_info *)arg2;
rtp_stream_info_t tmp_strinfo;
rtp_stream_info_t *strinfo = NULL;
rtp_stream_info_t new_stream_info;
rtp_stream_info_t *stream_info = NULL;
GList* list;
rtp_sample_t sample;
struct _rtp_conversation_info *p_conv_data = NULL;
/* gather infos on the stream this packet is part of */
COPY_ADDRESS(&(tmp_strinfo.src_addr), &(pinfo->src));
tmp_strinfo.src_port = pinfo->srcport;
COPY_ADDRESS(&(tmp_strinfo.dest_addr), &(pinfo->dst));
tmp_strinfo.dest_port = pinfo->destport;
tmp_strinfo.ssrc = rtpinfo->info_sync_src;
tmp_strinfo.pt = rtpinfo->info_payload_type;
tmp_strinfo.info_payload_type_str = rtpinfo->info_payload_type_str;
memset(&new_stream_info, 0, sizeof(rtp_stream_info_t));
COPY_ADDRESS(&(new_stream_info.src_addr), &(pinfo->src));
new_stream_info.src_port = pinfo->srcport;
COPY_ADDRESS(&(new_stream_info.dest_addr), &(pinfo->dst));
new_stream_info.dest_port = pinfo->destport;
new_stream_info.ssrc = rtpinfo->info_sync_src;
new_stream_info.payload_type = rtpinfo->info_payload_type;
new_stream_info.payload_type_name = g_strdup(rtpinfo->info_payload_type_str);
if (tapinfo->mode == TAP_ANALYSE) {
/* check whether we already have a stream with these parameters in the list */
list = g_list_first(tapinfo->strinfo_list);
while (list)
{
if (rtp_stream_info_cmp(&tmp_strinfo, (rtp_stream_info_t*)(list->data))==0)
if (rtp_stream_info_cmp(&new_stream_info, (rtp_stream_info_t*)(list->data))==0)
{
strinfo = (rtp_stream_info_t*)(list->data); /*found!*/
stream_info = (rtp_stream_info_t*)(list->data); /*found!*/
break;
}
list = g_list_next(list);
}
/* not in the list? then create a new entry */
if (!strinfo) {
tmp_strinfo.npackets = 0;
tmp_strinfo.first_frame_num = pinfo->fd->num;
tmp_strinfo.start_sec = (guint32) pinfo->fd->abs_ts.secs;
tmp_strinfo.start_usec = pinfo->fd->abs_ts.nsecs/1000;
tmp_strinfo.start_rel_sec = (guint32) pinfo->rel_ts.secs;
tmp_strinfo.start_rel_usec = pinfo->rel_ts.nsecs/1000;
tmp_strinfo.tag_vlan_error = 0;
tmp_strinfo.tag_diffserv_error = 0;
tmp_strinfo.vlan_id = 0;
tmp_strinfo.problem = FALSE;
if (!stream_info) {
new_stream_info.start_fd = pinfo->fd;
new_stream_info.start_rel_time = pinfo->rel_ts;
/* reset RTP stats */
tmp_strinfo.rtp_stats.first_packet = TRUE;
tmp_strinfo.rtp_stats.max_delta = 0;
tmp_strinfo.rtp_stats.max_jitter = 0;
tmp_strinfo.rtp_stats.mean_jitter = 0;
tmp_strinfo.rtp_stats.delta = 0;
tmp_strinfo.rtp_stats.diff = 0;
tmp_strinfo.rtp_stats.jitter = 0;
tmp_strinfo.rtp_stats.bandwidth = 0;
tmp_strinfo.rtp_stats.total_bytes = 0;
tmp_strinfo.rtp_stats.bw_start_index = 0;
tmp_strinfo.rtp_stats.bw_index = 0;
tmp_strinfo.rtp_stats.timestamp = 0;
tmp_strinfo.rtp_stats.max_nr = 0;
tmp_strinfo.rtp_stats.total_nr = 0;
tmp_strinfo.rtp_stats.sequence = 0;
tmp_strinfo.rtp_stats.start_seq_nr = 0;
tmp_strinfo.rtp_stats.stop_seq_nr = 0;
tmp_strinfo.rtp_stats.cycles = 0;
tmp_strinfo.rtp_stats.under = FALSE;
tmp_strinfo.rtp_stats.start_time = 0;
tmp_strinfo.rtp_stats.time = 0;
tmp_strinfo.rtp_stats.reg_pt = PT_UNDEFINED;
new_stream_info.rtp_stats.first_packet = TRUE;
new_stream_info.rtp_stats.reg_pt = PT_UNDEFINED;
/* Get the Setup frame number who set this RTP stream */
p_conv_data = (struct _rtp_conversation_info *)p_get_proto_data(wmem_file_scope(), pinfo, proto_get_id_by_filter_name("rtp"), 0);
if (p_conv_data)
tmp_strinfo.setup_frame_number = p_conv_data->frame_number;
new_stream_info.setup_frame_number = p_conv_data->frame_number;
else
tmp_strinfo.setup_frame_number = 0xFFFFFFFF;
new_stream_info.setup_frame_number = 0xFFFFFFFF;
strinfo = g_new(rtp_stream_info_t,1);
*strinfo = tmp_strinfo; /* memberwise copy of struct */
tapinfo->strinfo_list = g_list_append(tapinfo->strinfo_list, strinfo);
stream_info = g_new(rtp_stream_info_t,1);
*stream_info = new_stream_info; /* memberwise copy of struct */
tapinfo->strinfo_list = g_list_append(tapinfo->strinfo_list, stream_info);
}
/* get RTP stats for the packet */
rtp_packet_analyse(&(strinfo->rtp_stats), pinfo, rtpinfo);
if (strinfo->rtp_stats.flags & STAT_FLAG_WRONG_TIMESTAMP
|| strinfo->rtp_stats.flags & STAT_FLAG_WRONG_SEQ)
strinfo->problem = TRUE;
rtp_packet_analyse(&(stream_info->rtp_stats), pinfo, rtpinfo);
if (stream_info->rtp_stats.flags & STAT_FLAG_WRONG_TIMESTAMP
|| stream_info->rtp_stats.flags & STAT_FLAG_WRONG_SEQ)
stream_info->problem = TRUE;
/* increment the packets counter for this stream */
++(strinfo->npackets);
strinfo->stop_rel_sec = (guint32) pinfo->rel_ts.secs;
strinfo->stop_rel_usec = pinfo->rel_ts.nsecs/1000;
++(stream_info->packet_count);
stream_info->stop_rel_time = pinfo->rel_ts;
/* increment the packets counter of all streams */
++(tapinfo->npackets);
@ -282,12 +254,11 @@ int rtpstream_packet(void *arg, packet_info *pinfo, epan_dissect_t *edt _U_, con
return 1; /* refresh output */
}
else if (tapinfo->mode == TAP_SAVE) {
if (rtp_stream_info_cmp(&tmp_strinfo, tapinfo->filter_stream_fwd)==0) {
if (rtp_stream_info_cmp(&new_stream_info, tapinfo->filter_stream_fwd)==0) {
/* XXX - what if rtpinfo->info_all_data_present is
FALSE, so that we don't *have* all the data? */
sample.header.rec_time =
(pinfo->fd->abs_ts.nsecs/1000 + 1000000 - tapinfo->filter_stream_fwd->start_usec)/1000
+ (guint32) (pinfo->fd->abs_ts.secs - tapinfo->filter_stream_fwd->start_sec - 1)*1000;
sample.header.rec_time = nstime_to_msec(&pinfo->fd->abs_ts) -
nstime_to_msec(&tapinfo->filter_stream_fwd->start_fd->abs_ts);
sample.header.frame_length = rtpinfo->info_data_len;
sample.frame = rtpinfo->info_data;
rtp_write_sample(&sample, tapinfo->save_file);
@ -587,7 +558,7 @@ int rtp_packet_analyse(tap_rtp_stat_t *statinfo,
if(rtpinfo->info_payload_rate !=0){
clock_rate = rtpinfo->info_payload_rate;
}else{
clock_rate = get_dyn_pt_clock_rate(rtpinfo-> info_payload_type_str);
clock_rate = get_dyn_pt_clock_rate(rtpinfo->info_payload_type_str);
}
}
}else{

View File

@ -62,6 +62,7 @@
#include "epan/rtp_pt.h"
#include "ui/alert_box.h"
#include "ui/rtp_stream.h"
#include "ui/simple_dialog.h"
#include "ui/tap-sequence-analysis.h"
#include "ui/ui_util.h"
@ -152,28 +153,6 @@ typedef struct _h245_labels {
graph_str labels[H245_MAX];
} h245_labels_t;
/* defines a RTP stream */
typedef struct _voip_rtp_stream_info {
address src_addr;
guint16 src_port;
address dest_addr;
guint16 dest_port;
guint32 ssrc;
guint32 pt;
gchar *pt_str;
gboolean is_srtp;
guint32 npackets;
gboolean end_stream;
guint32 setup_frame_number; /* frame number of setup message */
/* The frame_data struct holds the frame number and timing information needed. */
frame_data *start_fd;
nstime_t start_rel_ts;
frame_data *stop_fd;
nstime_t stop_rel_ts;
gint32 rtp_event;
} voip_rtp_stream_info_t;
static void actrace_calls_init_tap(voip_calls_tapinfo_t *tap_id_base);
static void h225_calls_init_tap(voip_calls_tapinfo_t *tap_id_base);
static void h245dg_calls_init_tap(voip_calls_tapinfo_t *tap_id_base);
@ -273,7 +252,7 @@ void
voip_calls_reset_all_taps(voip_calls_tapinfo_t *tapinfo)
{
voip_calls_info_t *callsinfo;
voip_rtp_stream_info_t *strinfo;
rtp_stream_info_t *strinfo;
GList *list = NULL;
/* free the data items first */
@ -310,8 +289,8 @@ voip_calls_reset_all_taps(voip_calls_tapinfo_t *tapinfo)
list = g_list_first(tapinfo->rtp_stream_list);
while(list)
{
strinfo = (voip_rtp_stream_info_t *)list->data;
g_free(strinfo->pt_str);
strinfo = (rtp_stream_info_t *)list->data;
g_free(strinfo->payload_type_name);
list = g_list_next(list);
}
g_list_free(tapinfo->rtp_stream_list);
@ -595,8 +574,8 @@ static gboolean
rtp_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt, void const *rtp_info_ptr)
{
voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_rtp_);
voip_rtp_stream_info_t *tmp_listinfo;
voip_rtp_stream_info_t *strinfo = NULL;
rtp_stream_info_t *tmp_listinfo;
rtp_stream_info_t *strinfo = NULL;
GList *list;
struct _rtp_conversation_info *p_conv_data = NULL;
@ -615,15 +594,15 @@ rtp_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt, void c
list = g_list_first(tapinfo->rtp_stream_list);
while (list)
{
tmp_listinfo=(voip_rtp_stream_info_t *)list->data;
tmp_listinfo=(rtp_stream_info_t *)list->data;
if ( (tmp_listinfo->setup_frame_number == rtp_info->info_setup_frame_num)
&& (tmp_listinfo->ssrc == rtp_info->info_sync_src) && (tmp_listinfo->end_stream == FALSE)) {
/* if the payload type has changed, we mark the stream as finished to create a new one
this is to show multiple payload changes in the Graph for example for DTMF RFC2833 */
if ( tmp_listinfo->pt != rtp_info->info_payload_type ) {
if ( tmp_listinfo->payload_type != rtp_info->info_payload_type ) {
tmp_listinfo->end_stream = TRUE;
} else {
strinfo = (voip_rtp_stream_info_t*)(list->data);
strinfo = (rtp_stream_info_t*)(list->data);
break;
}
}
@ -637,40 +616,39 @@ rtp_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt, void c
/* not in the list? then create a new entry */
if (strinfo==NULL) {
strinfo = (voip_rtp_stream_info_t *)g_malloc(sizeof(voip_rtp_stream_info_t));
strinfo = (rtp_stream_info_t *)g_malloc(sizeof(rtp_stream_info_t));
COPY_ADDRESS(&(strinfo->src_addr), &(pinfo->src));
strinfo->src_port = pinfo->srcport;
COPY_ADDRESS(&(strinfo->dest_addr), &(pinfo->dst));
strinfo->dest_port = pinfo->destport;
strinfo->ssrc = rtp_info->info_sync_src;
strinfo->end_stream = FALSE;
strinfo->pt = rtp_info->info_payload_type;
strinfo->pt_str = NULL;
strinfo->payload_type = rtp_info->info_payload_type;
strinfo->payload_type_name = NULL;
strinfo->is_srtp = rtp_info->info_is_srtp;
/* if it is dynamic payload, let use the conv data to see if it is defined */
if ( (strinfo->pt >= PT_UNDF_96) && (strinfo->pt <= PT_UNDF_127) ) {
if ( (strinfo->payload_type >= PT_UNDF_96) && (strinfo->payload_type <= PT_UNDF_127) ) {
/* Use existing packet info if available */
p_conv_data = (struct _rtp_conversation_info *)p_get_proto_data(wmem_file_scope(), pinfo, proto_get_id_by_filter_name("rtp"), 0);
if (p_conv_data && p_conv_data->rtp_dyn_payload) {
const gchar *encoding_name = rtp_dyn_payload_get_name(p_conv_data->rtp_dyn_payload, strinfo->pt);
const gchar *encoding_name = rtp_dyn_payload_get_name(p_conv_data->rtp_dyn_payload, strinfo->payload_type);
if (encoding_name) {
strinfo->pt_str = g_strdup(encoding_name);
strinfo->payload_type_name = g_strdup(encoding_name);
}
}
}
if (!strinfo->pt_str) strinfo->pt_str = g_strdup(val_to_str_ext(strinfo->pt, &rtp_payload_type_short_vals_ext, "%u"));
strinfo->npackets = 0;
if (!strinfo->payload_type_name) strinfo->payload_type_name = g_strdup(val_to_str_ext(strinfo->payload_type, &rtp_payload_type_short_vals_ext, "%u"));
strinfo->packet_count = 0;
strinfo->start_fd = pinfo->fd;
strinfo->start_rel_ts = pinfo->rel_ts;
strinfo->start_rel_time = pinfo->rel_ts;
strinfo->setup_frame_number = rtp_info->info_setup_frame_num;
strinfo->rtp_event = -1;
tapinfo->rtp_stream_list = g_list_prepend(tapinfo->rtp_stream_list, strinfo);
}
/* Add the info to the existing RTP stream */
strinfo->npackets++;
strinfo->packet_count++;
strinfo->stop_fd = pinfo->fd;
strinfo->stop_rel_ts = pinfo->rel_ts;
/* process RTP Event */
if (tapinfo->rtp_evt_frame_num == pinfo->fd->num) {
@ -692,7 +670,7 @@ rtp_draw(void *tap_offset_ptr)
{
voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_rtp_);
GList *rtp_streams_list;
voip_rtp_stream_info_t *rtp_listinfo;
rtp_stream_info_t *rtp_listinfo;
/* GList *voip_calls_graph_list; */
seq_analysis_item_t *gai = NULL;
seq_analysis_item_t *new_gai;
@ -704,7 +682,7 @@ rtp_draw(void *tap_offset_ptr)
rtp_streams_list = g_list_first(tapinfo->rtp_stream_list);
while (rtp_streams_list)
{
rtp_listinfo = (voip_rtp_stream_info_t *)rtp_streams_list->data;
rtp_listinfo = (rtp_stream_info_t *)rtp_streams_list->data;
/* using the setup frame number of the RTP stream, we get the call number that it belongs to*/
/* voip_calls_graph_list = g_list_first(tapinfo->graph_analysis->list); */
@ -712,15 +690,16 @@ rtp_draw(void *tap_offset_ptr)
gai = (seq_analysis_item_t *)g_hash_table_lookup(tapinfo->graph_analysis->ht, &rtp_listinfo->setup_frame_number);
}
if(gai != NULL) {
const char *comment_fmt = "%s, %u packets. Duration: %u.%03us SSRC: 0x%X";
/* Found the setup frame*/
conv_num = gai->conv_num;
/* if RTP was already in the Graph, just update the comment information */
gai = (seq_analysis_item_t *)g_hash_table_lookup(tapinfo->graph_analysis->ht, &rtp_listinfo->start_fd->num);
if (gai != NULL) {
duration = (guint32)(nstime_to_msec(&rtp_listinfo->stop_rel_ts) - nstime_to_msec(&rtp_listinfo->start_rel_ts));
duration = (guint32)(nstime_to_msec(&rtp_listinfo->stop_rel_time) - nstime_to_msec(&rtp_listinfo->start_rel_time));
g_free(gai->comment);
gai->comment = g_strdup_printf("%s Num packets:%u Duration:%u.%03us SSRC:0x%X",
(rtp_listinfo->is_srtp)?"SRTP":"RTP", rtp_listinfo->npackets,
gai->comment = g_strdup_printf(comment_fmt,
(rtp_listinfo->is_srtp)?"SRTP":"RTP", rtp_listinfo->packet_count,
duration/1000,(duration%1000), rtp_listinfo->ssrc);
} else {
new_gai = (seq_analysis_item_t *)g_malloc(sizeof(seq_analysis_item_t));
@ -729,14 +708,14 @@ rtp_draw(void *tap_offset_ptr)
COPY_ADDRESS(&(new_gai->dst_addr),&(rtp_listinfo->dest_addr));
new_gai->port_src = rtp_listinfo->src_port;
new_gai->port_dst = rtp_listinfo->dest_port;
duration = (guint32)(nstime_to_msec(&rtp_listinfo->stop_rel_ts) - nstime_to_msec(&rtp_listinfo->start_rel_ts));
duration = (guint32)(nstime_to_msec(&rtp_listinfo->stop_rel_time) - nstime_to_msec(&rtp_listinfo->start_rel_time));
new_gai->frame_label = g_strdup_printf("%s (%s) %s",
(rtp_listinfo->is_srtp)?"SRTP":"RTP",
rtp_listinfo->pt_str,
rtp_listinfo->payload_type_name,
(rtp_listinfo->rtp_event == -1)?
"":val_to_str_ext_const(rtp_listinfo->rtp_event, &rtp_event_type_values_ext, "Unknown RTP Event"));
new_gai->comment = g_strdup_printf("%s Num packets:%u Duration:%u.%03us SSRC:0x%X",
(rtp_listinfo->is_srtp)?"SRTP":"RTP", rtp_listinfo->npackets,
new_gai->comment = g_strdup_printf(comment_fmt,
(rtp_listinfo->is_srtp)?"SRTP":"RTP", rtp_listinfo->packet_count,
duration/1000,(duration%1000), rtp_listinfo->ssrc);
new_gai->conv_num = conv_num;
set_fd_time(tapinfo->session, new_gai->fd, time_str);
@ -760,7 +739,7 @@ rtp_packet_draw(void *tap_offset_ptr)
{
voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_rtp_);
GList *rtp_streams_list;
voip_rtp_stream_info_t *rtp_listinfo;
rtp_stream_info_t *rtp_listinfo;
GList *voip_calls_graph_list;
guint item;
seq_analysis_item_t *gai;
@ -813,7 +792,7 @@ rtp_packet_draw(void *tap_offset_ptr)
duration = (guint32)(nstime_to_msec(&rtp_listinfo->stop_fd->rel_ts) - nstime_to_msec(&rtp_listinfo->start_fd->rel_ts));
new_gai->frame_label = g_strdup_printf("%s (%s) %s",
(rtp_listinfo->is_srtp)?"SRTP":"RTP",
rtp_listinfo->pt_str,
rtp_listinfo->payload_type_str,
(rtp_listinfo->rtp_event == -1)?
"":val_to_str_ext_const(rtp_listinfo->rtp_event, &rtp_event_type_values_ext, "Unknown RTP Event"));
new_gai->comment = g_strdup_printf("%s Num packets:%u Duration:%u.%03us SSRC:0x%X",
@ -2895,7 +2874,7 @@ h248_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt,
}
add_to_graph(tapinfo, pinfo, edt, cmd->str ? cmd->str : "unknown Msg",
ep_strdup_printf("TrxId = %u, CtxId = %.8x",cmd->trx->id,cmd->ctx->id),
wmem_strdup_printf(wmem_packet_scope(), "TrxId = %u, CtxId = %.8x",cmd->trx->id,cmd->ctx->id),
callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
++(tapinfo->npackets);

View File

@ -199,7 +199,7 @@ typedef struct _voip_calls_tapinfo {
seq_analysis_info_t* graph_analysis;
epan_t *session; /**< epan session */
int nrtp_streams; /**< number of rtp streams */
GList* rtp_stream_list; /**< list with the rtp streams */
GList* rtp_stream_list; /**< list of rtp_stream_info_t */
guint32 rtp_evt_frame_num;
guint8 rtp_evt;
gboolean rtp_evt_end;