* Copyright 2008, Ericsson AB
* By Balint Reczey <balint.reczey@ericsson.com>
*
- * most functions are copied from gtk/rtp_stream.c and gtk/rtp_analisys.c
+ * most functions are copied from ui/gtk/rtp_stream.c and ui/gtk/rtp_analisys.c
* Copyright 2003, Alcatel Business Systems
* By Lars Ruoff <lars.ruoff@gmx.net>
*
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
+#include "config.h"
#include <stdio.h>
#include <math.h>
#include "globals.h"
#include <epan/tap.h>
-#include "register.h"
#include <string.h>
#include <epan/rtp_pt.h>
#include <epan/addr_resolv.h>
#include <epan/dissectors/packet-rtp.h>
-#include "gtk/rtp_stream.h"
+#include "ui/gtk/rtp_stream.h"
#include "tap-rtp-common.h"
-
+/* XXX: are changes needed to properly handle situations where
+ info_all_data_present == FALSE ?
+ E.G., when captured frames are truncated.
+ */
/****************************************************************************/
/* GCompareFunc style comparison function for _rtp_stream_info */
gint rtp_stream_info_cmp(gconstpointer aa, gconstpointer bb)
{
- const struct _rtp_stream_info* a = aa;
- const struct _rtp_stream_info* b = bb;
+ const struct _rtp_stream_info* a = (const struct _rtp_stream_info*)aa;
+ const struct _rtp_stream_info* b = (const struct _rtp_stream_info*)bb;
if (a==b)
return 0;
void rtpstream_reset_cb(void *arg)
{
- rtpstream_reset(arg);
+ rtpstream_reset((rtpstream_tapinfo_t *)arg);
}
/*
/* whenever a RTP packet is seen by the tap listener */
int rtpstream_packet(void *arg, packet_info *pinfo, epan_dissect_t *edt _U_, const void *arg2)
{
- rtpstream_tapinfo_t *tapinfo = arg;
- const struct _rtp_info *rtpinfo = arg2;
+ 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;
GList* list;
tmp_strinfo.rtp_stats.time = 0;
tmp_strinfo.rtp_stats.reg_pt = PT_UNDEFINED;
- /* Get the Setup frame number who set this RTP stream */
- p_conv_data = p_get_proto_data(pinfo->fd, proto_get_id_by_filter_name("rtp"));
- if (p_conv_data)
+ /* Get the Setup frame number who set this RTP stream */
+ p_conv_data = (struct _rtp_conversation_info *)p_get_proto_data(pinfo->fd, proto_get_id_by_filter_name("rtp"));
+ if (p_conv_data)
tmp_strinfo.setup_frame_number = p_conv_data->frame_number;
- else
- tmp_strinfo.setup_frame_number = 0xFFFFFFFF;
+ else
+ tmp_strinfo.setup_frame_number = 0xFFFFFFFF;
- strinfo = g_malloc(sizeof(rtp_stream_info_t));
+ 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);
}
rtp_write_sample(&sample, tapinfo->save_file);
}
}
- /* TODO: This doesn't belong here. We really shouldn't refer to cf_mark_frame()
- * which only make sense if we're using the GTK UI backend. This effectively forces
- * tshark/rawshark to implement a cf_mark_frame() stub */
+#ifdef __GTK_H__
else if (tapinfo->mode == TAP_MARK) {
if (rtp_stream_info_cmp(&tmp_strinfo, tapinfo->filter_stream_fwd)==0
|| rtp_stream_info_cmp(&tmp_strinfo, tapinfo->filter_stream_rev)==0)
cf_mark_frame(&cfile, pinfo->fd);
}
}
-
+#endif
return 0;
}
/****************************************************************************/
int rtp_packet_analyse(tap_rtp_stat_t *statinfo,
- packet_info *pinfo,
- const struct _rtp_info *rtpinfo)
+ packet_info *pinfo,
+ const struct _rtp_info *rtpinfo)
{
double current_time;
double current_jitter;
/* Is this the first packet we got in this direction? */
if (statinfo->first_packet) {
+ /* Save the MAC address of the first RTP frame */
+ if( pinfo->dl_src.type == AT_ETHER){
+ COPY_ADDRESS(&(statinfo->first_packet_mac_addr), &(pinfo->dl_src));
+ }
statinfo->start_seq_nr = rtpinfo->info_seq_num;
statinfo->stop_seq_nr = rtpinfo->info_seq_num;
statinfo->seq_num = rtpinfo->info_seq_num;
/* Reset flags */
statinfo->flags = 0;
+ /* Chek for duplicates (src mac differs from first_packet_mac_addr) */
+ if( pinfo->dl_src.type == AT_ETHER){
+ if(!ADDRESSES_EQUAL(&(statinfo->first_packet_mac_addr), &(pinfo->dl_src))){
+ statinfo->flags |= STAT_FLAG_DUP_PKT;
+ statinfo->delta = current_time-(statinfo->time);
+ return 0;
+ }
+ }
+
/* When calculating expected rtp packets the seq number can wrap around
* so we have to count the number of cycles
* Variable cycles counts the wraps around in forwarding connection and
*/
if ( (statinfo->seq_num+1 == rtpinfo->info_seq_num) || (statinfo->flags & STAT_FLAG_FIRST) )
statinfo->seq_num = rtpinfo->info_seq_num;
- /* If the first one is 65535. XXX same problem as above: if seq 65535 or 0 is lost... */
+ /* If the first one is 65535 we wrap */
else if ( (statinfo->seq_num == 65535) && (rtpinfo->info_seq_num == 0) )
statinfo->seq_num = rtpinfo->info_seq_num;
- /* Lost packets */
- else if (statinfo->seq_num+1 < rtpinfo->info_seq_num) {
+ /* Lost packets. If the prev seq is enourmously larger than the cur seq
+ * we assume that instead of being massively late we lost the packet(s)
+ * that would have indicated the sequence number wrapping. An imprecise
+ * heuristic at best, but it seems to work well enough.
+ * https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=5958 */
+ else if (statinfo->seq_num+1 < rtpinfo->info_seq_num || statinfo->seq_num - rtpinfo->info_seq_num > 0xFF00) {
statinfo->seq_num = rtpinfo->info_seq_num;
statinfo->sequence++;
statinfo->flags |= STAT_FLAG_WRONG_SEQ;
clock_rate = 0;
statinfo->flags |= STAT_FLAG_PT_T_EVENT;
}else{
- clock_rate = get_dyn_pt_clock_rate(rtpinfo-> info_payload_type_str);
+ 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);
+ }
}
}else{
clock_rate = 0;
}
/* Can only analyze defined sampling rates */
- if (clock_rate != 0) {
+ if (clock_rate != 0) {
statinfo->clock_rate = clock_rate;
/* Convert from sampling clock to ms */
nominaltime = nominaltime /(clock_rate/1000);
statinfo->sumtTS += 1.0 * current_time * nominaltime;
}
- /* Calculate the BW in Kbps adding the IP+UDP header to the RTP -> 20bytes(IP)+8bytes(UDP) = 28bytes */
- statinfo->bw_history[statinfo->bw_index].bytes = rtpinfo->info_data_len + 28;
+ /* Calculate the BW in Kbps adding the IP+UDP header to the RTP -> IP header+8bytes(UDP) */
+ statinfo->bw_history[statinfo->bw_index].bytes = rtpinfo->info_data_len + pinfo->iphdrlen + 8;
statinfo->bw_history[statinfo->bw_index].time = current_time;
/* Check if there are more than 1sec in the history buffer to calculate BW in bps. If so, remove those for the calculation */
statinfo->bw_start_index++;
if (statinfo->bw_start_index == BUFF_BW) statinfo->bw_start_index=0;
};
- statinfo->total_bytes += rtpinfo->info_data_len + 28;
+ /* IP hdr + UDP + RTP */
+ statinfo->total_bytes += rtpinfo->info_data_len + pinfo->iphdrlen + 8;
statinfo->bandwidth = (double)(statinfo->total_bytes*8)/1000;
statinfo->bw_index++;
if (statinfo->bw_index == BUFF_BW) statinfo->bw_index = 0;
return 0;
}
-
+/*
+ * Editor modelines - http://www.wireshark.org/tools/modelines.html
+ *
+ * Local variables:
+ * c-basic-offset: 8
+ * tab-width: 8
+ * indent-tabs-mode: t
+ * End:
+ *
+ * vi: set shiftwidth=8 tabstop=8 noexpandtab:
+ * :indentSize=8:tabSize=8:noTabs=false:
+ */