Add 'dtds' and 'fix' directories to the checklicense whitelist, they don't
[metze/wireshark/wip.git] / tap-rtp-common.c
index dd551fe2b4222a8fe85158e7dd2fb852f6c9aa3d..8bce5333092a0d3d930ea4a68ef78578539e6e36 100644 (file)
@@ -6,7 +6,7 @@
  * 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;
@@ -97,7 +97,7 @@ void rtpstream_reset(rtpstream_tapinfo_t *tapinfo)
 
 void rtpstream_reset_cb(void *arg)
 {
-       rtpstream_reset(arg);
+       rtpstream_reset((rtpstream_tapinfo_t *)arg);
 }
 
 /*
@@ -186,8 +186,8 @@ void rtp_write_sample(rtp_sample_t* sample, FILE* file)
 /* 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;
@@ -254,14 +254,14 @@ int rtpstream_packet(void *arg, packet_info *pinfo, epan_dissect_t *edt _U_, con
                        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);
                }
@@ -295,9 +295,7 @@ int rtpstream_packet(void *arg, packet_info *pinfo, epan_dissect_t *edt _U_, con
                        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)
@@ -305,7 +303,7 @@ int rtpstream_packet(void *arg, packet_info *pinfo, epan_dissect_t *edt _U_, con
                        cf_mark_frame(&cfile, pinfo->fd);
                }
        }
-
+#endif
        return 0;
 }
 
@@ -435,8 +433,8 @@ get_dyn_pt_clock_rate(gchar *payload_type_str)
 
 /****************************************************************************/
 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;
@@ -452,6 +450,10 @@ int rtp_packet_analyse(tap_rtp_stat_t *statinfo,
 
        /*  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;
@@ -484,6 +486,15 @@ int rtp_packet_analyse(tap_rtp_stat_t *statinfo,
        /* 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
@@ -528,11 +539,15 @@ int rtp_packet_analyse(tap_rtp_stat_t *statinfo,
         */
        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;
@@ -571,7 +586,11 @@ int rtp_packet_analyse(tap_rtp_stat_t *statinfo,
                                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;
@@ -589,7 +608,7 @@ int rtp_packet_analyse(tap_rtp_stat_t *statinfo,
        }
 
        /* 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);
@@ -632,8 +651,8 @@ int rtp_packet_analyse(tap_rtp_stat_t *statinfo,
                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 */
@@ -642,7 +661,8 @@ int rtp_packet_analyse(tap_rtp_stat_t *statinfo,
                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;
@@ -699,4 +719,15 @@ int rtp_packet_analyse(tap_rtp_stat_t *statinfo,
        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:
+ */