Oops: revert 49636. We tell a2x to use fop to generate the PDFs.
[metze/wireshark/wip.git] / tap-rtp-common.c
1 /* tap-rtp-common.c
2  * RTP stream handler functions used by tshark and wireshark
3  *
4  * $Id$
5  *
6  * Copyright 2008, Ericsson AB
7  * By Balint Reczey <balint.reczey@ericsson.com>
8  *
9  * most functions are copied from ui/gtk/rtp_stream.c and ui/gtk/rtp_analisys.c
10  * Copyright 2003, Alcatel Business Systems
11  * By Lars Ruoff <lars.ruoff@gmx.net>
12  *
13  * Wireshark - Network traffic analyzer
14  * By Gerald Combs <gerald@wireshark.org>
15  * Copyright 1998 Gerald Combs
16  *
17  * This program is free software; you can redistribute it and/or
18  * modify it under the terms of the GNU General Public License
19  * as published by the Free Software Foundation; either version 2
20  * of the License, or (at your option) any later version.
21  *
22  * This program is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
25  * GNU General Public License for more details.
26  *
27  * You should have received a copy of the GNU General Public License
28  * along with this program; if not, write to the Free Software
29  * Foundation,  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
30  */
31
32 #include "config.h"
33
34 #include <stdio.h>
35 #include <math.h>
36 #include "globals.h"
37
38 #include <epan/tap.h>
39 #include <string.h>
40 #include <epan/rtp_pt.h>
41 #include <epan/addr_resolv.h>
42 #include <epan/dissectors/packet-rtp.h>
43 #include "ui/gtk/rtp_stream.h"
44 #include "tap-rtp-common.h"
45
46 /* XXX: are changes needed to properly handle situations where
47         info_all_data_present == FALSE ?
48         E.G., when captured frames are truncated.
49  */
50
51 /****************************************************************************/
52 /* GCompareFunc style comparison function for _rtp_stream_info */
53 gint rtp_stream_info_cmp(gconstpointer aa, gconstpointer bb)
54 {
55         const struct _rtp_stream_info* a = (const struct _rtp_stream_info*)aa;
56         const struct _rtp_stream_info* b = (const struct _rtp_stream_info*)bb;
57
58         if (a==b)
59                 return 0;
60         if (a==NULL || b==NULL)
61                 return 1;
62         if (ADDRESSES_EQUAL(&(a->src_addr), &(b->src_addr))
63                 && (a->src_port == b->src_port)
64                 && ADDRESSES_EQUAL(&(a->dest_addr), &(b->dest_addr))
65                 && (a->dest_port == b->dest_port)
66                 && (a->ssrc == b->ssrc))
67                 return 0;
68         else
69                 return 1;
70 }
71
72
73 /****************************************************************************/
74 /* when there is a [re]reading of packet's */
75 void rtpstream_reset(rtpstream_tapinfo_t *tapinfo)
76 {
77         GList* list;
78
79         if (tapinfo->mode == TAP_ANALYSE) {
80                 /* free the data items first */
81                 list = g_list_first(tapinfo->strinfo_list);
82                 while (list)
83                 {
84                         g_free(list->data);
85                         list = g_list_next(list);
86                 }
87                 g_list_free(tapinfo->strinfo_list);
88                 tapinfo->strinfo_list = NULL;
89                 tapinfo->nstreams = 0;
90                 tapinfo->npackets = 0;
91         }
92
93         ++(tapinfo->launch_count);
94
95         return;
96 }
97
98 void rtpstream_reset_cb(void *arg)
99 {
100         rtpstream_reset((rtpstream_tapinfo_t *)arg);
101 }
102
103 /*
104 * rtpdump file format
105 *
106 * The file starts with the tool to be used for playing this file,
107 * the multicast/unicast receive address and the port.
108 *
109 * #!rtpplay1.0 224.2.0.1/3456\n
110 *
111 * This is followed by one binary header (RD_hdr_t) and one RD_packet_t
112 * structure for each received packet.  All fields are in network byte
113 * order.  We don't need the source IP address since we can do mapping
114 * based on SSRC.  This saves (a little) space, avoids non-IPv4
115 * problems and privacy/security concerns. The header is followed by
116 * the RTP/RTCP header and (optionally) the actual payload.
117 */
118
119 #define RTPFILE_VERSION "1.0"
120
121 /*
122 * Write a header to the current output file.
123 * The header consists of an identifying string, followed
124 * by a binary structure.
125 */
126 void rtp_write_header(rtp_stream_info_t *strinfo, FILE *file)
127 {
128         guint32 start_sec;     /* start of recording (GMT) (seconds) */
129         guint32 start_usec;    /* start of recording (GMT) (microseconds)*/
130         guint32 source;        /* network source (multicast address) */
131         size_t sourcelen;
132         guint16 port;          /* UDP port */
133         guint16 padding;       /* 2 padding bytes */
134
135         fprintf(file, "#!rtpplay%s %s/%u\n", RTPFILE_VERSION,
136                 get_addr_name(&(strinfo->dest_addr)),
137                 strinfo->dest_port);
138
139         start_sec = g_htonl(strinfo->start_sec);
140         start_usec = g_htonl(strinfo->start_usec);
141         /* rtpdump only accepts guint32 as source, will be fake for IPv6 */
142         memset(&source, 0, sizeof source);
143         sourcelen = strinfo->src_addr.len;
144         if (sourcelen > sizeof source)
145                 sourcelen = sizeof source;
146         memcpy(&source, strinfo->src_addr.data, sourcelen);
147         port = g_htons(strinfo->src_port);
148         padding = 0;
149
150         if (fwrite(&start_sec, 4, 1, file) == 0)
151                 return;
152         if (fwrite(&start_usec, 4, 1, file) == 0)
153                 return;
154         if (fwrite(&source, 4, 1, file) == 0)
155                 return;
156         if (fwrite(&port, 2, 1, file) == 0)
157                 return;
158         if (fwrite(&padding, 2, 1, file) == 0)
159                 return;
160 }
161
162 /* utility function for writing a sample to file in rtpdump -F dump format (.rtp)*/
163 void rtp_write_sample(rtp_sample_t* sample, FILE* file)
164 {
165         guint16 length;    /* length of packet, including this header (may
166                              be smaller than plen if not whole packet recorded) */
167         guint16 plen;      /* actual header+payload length for RTP, 0 for RTCP */
168         guint32 offset;    /* milliseconds since the start of recording */
169
170         length = g_htons(sample->header.frame_length + 8);
171         plen = g_htons(sample->header.frame_length);
172         offset = g_htonl(sample->header.rec_time);
173
174         if (fwrite(&length, 2, 1, file) == 0)
175                 return;
176         if (fwrite(&plen, 2, 1, file) == 0)
177                 return;
178         if (fwrite(&offset, 4, 1, file) == 0)
179                 return;
180         if (fwrite(sample->frame, sample->header.frame_length, 1, file) == 0)
181                 return;
182 }
183
184
185 /****************************************************************************/
186 /* whenever a RTP packet is seen by the tap listener */
187 int rtpstream_packet(void *arg, packet_info *pinfo, epan_dissect_t *edt _U_, const void *arg2)
188 {
189         rtpstream_tapinfo_t *tapinfo = (rtpstream_tapinfo_t *)arg;
190         const struct _rtp_info *rtpinfo = (const struct _rtp_info *)arg2;
191         rtp_stream_info_t tmp_strinfo;
192         rtp_stream_info_t *strinfo = NULL;
193         GList* list;
194         rtp_sample_t sample;
195
196         struct _rtp_conversation_info *p_conv_data = NULL;
197
198         /* gather infos on the stream this packet is part of */
199         COPY_ADDRESS(&(tmp_strinfo.src_addr), &(pinfo->src));
200         tmp_strinfo.src_port = pinfo->srcport;
201         COPY_ADDRESS(&(tmp_strinfo.dest_addr), &(pinfo->dst));
202         tmp_strinfo.dest_port = pinfo->destport;
203         tmp_strinfo.ssrc = rtpinfo->info_sync_src;
204         tmp_strinfo.pt = rtpinfo->info_payload_type;
205         tmp_strinfo.info_payload_type_str = rtpinfo->info_payload_type_str;
206
207         if (tapinfo->mode == TAP_ANALYSE) {
208                 /* check whether we already have a stream with these parameters in the list */
209                 list = g_list_first(tapinfo->strinfo_list);
210                 while (list)
211                 {
212                         if (rtp_stream_info_cmp(&tmp_strinfo, (rtp_stream_info_t*)(list->data))==0)
213                         {
214                                 strinfo = (rtp_stream_info_t*)(list->data);  /*found!*/
215                                 break;
216                         }
217                         list = g_list_next(list);
218                 }
219
220                 /* not in the list? then create a new entry */
221                 if (!strinfo) {
222                         tmp_strinfo.npackets = 0;
223                         tmp_strinfo.first_frame_num = pinfo->fd->num;
224                         tmp_strinfo.start_sec = (guint32) pinfo->fd->abs_ts.secs;
225                         tmp_strinfo.start_usec = pinfo->fd->abs_ts.nsecs/1000;
226                         tmp_strinfo.start_rel_sec = (guint32) pinfo->fd->rel_ts.secs;
227                         tmp_strinfo.start_rel_usec = pinfo->fd->rel_ts.nsecs/1000;
228                         tmp_strinfo.tag_vlan_error = 0;
229                         tmp_strinfo.tag_diffserv_error = 0;
230                         tmp_strinfo.vlan_id = 0;
231                         tmp_strinfo.problem = FALSE;
232
233                         /* reset RTP stats */
234                         tmp_strinfo.rtp_stats.first_packet = TRUE;
235                         tmp_strinfo.rtp_stats.max_delta = 0;
236                         tmp_strinfo.rtp_stats.max_jitter = 0;
237                         tmp_strinfo.rtp_stats.mean_jitter = 0;
238                         tmp_strinfo.rtp_stats.delta = 0;
239                         tmp_strinfo.rtp_stats.diff = 0;
240                         tmp_strinfo.rtp_stats.jitter = 0;
241                         tmp_strinfo.rtp_stats.bandwidth = 0;
242                         tmp_strinfo.rtp_stats.total_bytes = 0;
243                         tmp_strinfo.rtp_stats.bw_start_index = 0;
244                         tmp_strinfo.rtp_stats.bw_index = 0;
245                         tmp_strinfo.rtp_stats.timestamp = 0;
246                         tmp_strinfo.rtp_stats.max_nr = 0;
247                         tmp_strinfo.rtp_stats.total_nr = 0;
248                         tmp_strinfo.rtp_stats.sequence = 0;
249                         tmp_strinfo.rtp_stats.start_seq_nr = 0;
250                         tmp_strinfo.rtp_stats.stop_seq_nr = 0;
251                         tmp_strinfo.rtp_stats.cycles = 0;
252                         tmp_strinfo.rtp_stats.under = FALSE;
253                         tmp_strinfo.rtp_stats.start_time = 0;
254                         tmp_strinfo.rtp_stats.time = 0;
255                         tmp_strinfo.rtp_stats.reg_pt = PT_UNDEFINED;
256
257                         /* Get the Setup frame number who set this RTP stream */
258                         p_conv_data = (struct _rtp_conversation_info *)p_get_proto_data(pinfo->fd, proto_get_id_by_filter_name("rtp"), 0);
259                         if (p_conv_data)
260                                 tmp_strinfo.setup_frame_number = p_conv_data->frame_number;
261                         else
262                                 tmp_strinfo.setup_frame_number = 0xFFFFFFFF;
263
264                         strinfo = g_new(rtp_stream_info_t,1);
265                         *strinfo = tmp_strinfo;  /* memberwise copy of struct */
266                         tapinfo->strinfo_list = g_list_append(tapinfo->strinfo_list, strinfo);
267                 }
268
269                 /* get RTP stats for the packet */
270                 rtp_packet_analyse(&(strinfo->rtp_stats), pinfo, rtpinfo);
271                 if (strinfo->rtp_stats.flags & STAT_FLAG_WRONG_TIMESTAMP
272                         || strinfo->rtp_stats.flags & STAT_FLAG_WRONG_SEQ)
273                         strinfo->problem = TRUE;
274
275
276                 /* increment the packets counter for this stream */
277                 ++(strinfo->npackets);
278                 strinfo->stop_rel_sec = (guint32) pinfo->fd->rel_ts.secs;
279                 strinfo->stop_rel_usec = pinfo->fd->rel_ts.nsecs/1000;
280
281                 /* increment the packets counter of all streams */
282                 ++(tapinfo->npackets);
283
284                 return 1;  /* refresh output */
285         }
286         else if (tapinfo->mode == TAP_SAVE) {
287                 if (rtp_stream_info_cmp(&tmp_strinfo, tapinfo->filter_stream_fwd)==0) {
288                         /* XXX - what if rtpinfo->info_all_data_present is
289                            FALSE, so that we don't *have* all the data? */
290                         sample.header.rec_time =
291                                 (pinfo->fd->abs_ts.nsecs/1000 + 1000000 - tapinfo->filter_stream_fwd->start_usec)/1000
292                                 + (guint32) (pinfo->fd->abs_ts.secs - tapinfo->filter_stream_fwd->start_sec - 1)*1000;
293                         sample.header.frame_length = rtpinfo->info_data_len;
294                         sample.frame = rtpinfo->info_data;
295                         rtp_write_sample(&sample, tapinfo->save_file);
296                 }
297         }
298 #ifdef __GTK_H__
299         else if (tapinfo->mode == TAP_MARK) {
300                 if (rtp_stream_info_cmp(&tmp_strinfo, tapinfo->filter_stream_fwd)==0
301                         || rtp_stream_info_cmp(&tmp_strinfo, tapinfo->filter_stream_rev)==0)
302                 {
303                         cf_mark_frame(&cfile, pinfo->fd);
304                 }
305         }
306 #endif
307         return 0;
308 }
309
310
311 typedef struct _key_value {
312   guint32  key;
313   guint32  value;
314 } key_value;
315
316
317 /* RTP sampling clock rates for fixed payload types as defined in
318  http://www.iana.org/assignments/rtp-parameters */
319 static const key_value clock_map[] = {
320         {PT_PCMU,       8000},
321         {PT_1016,       8000},
322         {PT_G721,       8000},
323         {PT_GSM,        8000},
324         {PT_G723,       8000},
325         {PT_DVI4_8000,  8000},
326         {PT_DVI4_16000, 16000},
327         {PT_LPC,        8000},
328         {PT_PCMA,       8000},
329         {PT_G722,       8000},
330         {PT_L16_STEREO, 44100},
331         {PT_L16_MONO,   44100},
332         {PT_QCELP,      8000},
333         {PT_CN,         8000},
334         {PT_MPA,        90000},
335         {PT_G728,       8000},
336         {PT_G728,       8000},
337         {PT_DVI4_11025, 11025},
338         {PT_DVI4_22050, 22050},
339         {PT_G729,       8000},
340         {PT_CN_OLD,     8000},
341         {PT_CELB,       90000},
342         {PT_JPEG,       90000},
343         {PT_NV,         90000},
344         {PT_H261,       90000},
345         {PT_MPV,        90000},
346         {PT_MP2T,       90000},
347         {PT_H263,       90000},
348 };
349
350 #define NUM_CLOCK_VALUES        (sizeof clock_map / sizeof clock_map[0])
351
352 static guint32
353 get_clock_rate(guint32 key)
354 {
355         size_t i;
356
357         for (i = 0; i < NUM_CLOCK_VALUES; i++) {
358                 if (clock_map[i].key == key)
359                         return clock_map[i].value;
360         }
361         return 0;
362 }
363
364 typedef struct _mimetype_and_clock {
365         const gchar   *pt_mime_name_str;
366         guint32 value;
367 } mimetype_and_clock;
368 /*      RTP sampling clock rates for
369         "In addition to the RTP payload formats (encodings) listed in the RTP
370         Payload Types table, there are additional payload formats that do not
371         have static RTP payload types assigned but instead use dynamic payload
372         type number assignment.  Each payload format is named by a registered
373         MIME subtype"
374         http://www.iana.org/assignments/rtp-parameters.
375
376         NOTE: Please keep the mimetypes in case insensitive alphabetical order.
377 */
378 static const mimetype_and_clock mimetype_and_clock_map[] = {
379         {"AMR",         8000},                  /* [RFC4867][RFC3267] */
380         {"AMR-WB",      16000},                 /* [RFC4867][RFC3267] */
381         {"BMPEG",       90000},                 /* [RFC2343],[RFC3555] */
382         {"BT656",       90000},                 /* [RFC2431],[RFC3555] */
383         {"DV",          90000},                 /* [RFC3189] */
384         {"EVRC",        8000},                  /* [RFC3558] */
385         {"EVRC0",       8000},                  /* [RFC4788] */
386         {"EVRC1",       8000},                  /* [RFC4788] */
387         {"EVRCB",       8000},                  /* [RFC4788] */
388         {"EVRCB0",      8000},                  /* [RFC4788] */
389         {"EVRCB1",      8000},                  /* [RFC4788] */
390         {"EVRCWB",      16000},                 /* [RFC5188] */
391         {"EVRCWB0",     16000},                 /* [RFC5188] */
392         {"EVRCWB1",     16000},                 /* [RFC5188] */
393         {"G7221",       16000},                 /* [RFC3047] */
394         {"G726-16",     8000},                  /* [RFC3551][RFC4856] */
395         {"G726-24",     8000},                  /* [RFC3551][RFC4856] */
396         {"G726-32",     8000},                  /* [RFC3551][RFC4856] */
397         {"G726-40",     8000},                  /* [RFC3551][RFC4856] */
398         {"G729D",       8000},                  /* [RFC3551][RFC4856] */
399         {"G729E",       8000},                  /* [RFC3551][RFC4856] */
400         {"GSM-EFR",     8000},                  /* [RFC3551] */
401         {"H263-1998",   90000},         /* [RFC2429],[RFC3555] */
402         {"H263-2000",   90000},         /* [RFC2429],[RFC3555] */
403         {"H264",        90000},         /* [RFC3984] */
404         {"MP1S",        90000},                 /* [RFC2250],[RFC3555] */
405         {"MP2P",        90000},                 /* [RFC2250],[RFC3555] */
406         {"MP4V-ES",     90000},                 /* [RFC3016] */
407         {"mpa-robust",  90000},         /* [RFC3119] */
408         {"pointer",     90000},                 /* [RFC2862] */
409         {"raw",         90000},                 /* [RFC4175] */
410         {"red",         1000},                  /* [RFC4102] */
411         {"SMV",         8000},                  /* [RFC3558] */
412         {"SMV0",        8000},                  /* [RFC3558] */
413         {"t140",        1000},                  /* [RFC4103] */
414         {"telephone-event", 8000},  /* [RFC4733] */
415 };
416
417 #define NUM_DYN_CLOCK_VALUES    (sizeof mimetype_and_clock_map / sizeof mimetype_and_clock_map[0])
418
419 static guint32
420 get_dyn_pt_clock_rate(gchar *payload_type_str)
421 {
422         int i;
423
424         /* Search for matching mimetype in reverse order to avoid false matches
425          * when pt_mime_name_str is the prefix of payload_type_str */
426         for (i = NUM_DYN_CLOCK_VALUES - 1; i > -1 ; i--) {
427                 if (g_ascii_strncasecmp(mimetype_and_clock_map[i].pt_mime_name_str,payload_type_str,(strlen(mimetype_and_clock_map[i].pt_mime_name_str))) == 0)
428                         return mimetype_and_clock_map[i].value;
429         }
430
431         return 0;
432 }
433
434 /****************************************************************************/
435 int rtp_packet_analyse(tap_rtp_stat_t *statinfo,
436                        packet_info *pinfo,
437                        const struct _rtp_info *rtpinfo)
438 {
439         double current_time;
440         double current_jitter;
441         double current_diff = 0;
442         double nominaltime;
443         double arrivaltime;             /* Time relative to start_time */
444         double expected_time;
445         double absskew;
446         guint32 clock_rate;
447
448         /* Store the current time */
449         current_time = nstime_to_msec(&pinfo->fd->rel_ts);
450
451         /*  Is this the first packet we got in this direction? */
452         if (statinfo->first_packet) {
453                 /* Save the MAC address of the first RTP frame */
454                 if( pinfo->dl_src.type == AT_ETHER){
455                         COPY_ADDRESS(&(statinfo->first_packet_mac_addr), &(pinfo->dl_src));
456                 }
457                 statinfo->start_seq_nr = rtpinfo->info_seq_num;
458                 statinfo->stop_seq_nr = rtpinfo->info_seq_num;
459                 statinfo->seq_num = rtpinfo->info_seq_num;
460                 statinfo->start_time = current_time;
461                 statinfo->timestamp = rtpinfo->info_timestamp;
462                 statinfo->first_timestamp = rtpinfo->info_timestamp;
463                 statinfo->time = current_time;
464                 statinfo->lastnominaltime = 0;
465                 statinfo->pt = rtpinfo->info_payload_type;
466                 statinfo->reg_pt = rtpinfo->info_payload_type;
467                 statinfo->bw_history[statinfo->bw_index].bytes = rtpinfo->info_data_len + 28;
468                 statinfo->bw_history[statinfo->bw_index].time = current_time;
469                 statinfo->bw_index++;
470                 statinfo->total_bytes += rtpinfo->info_data_len + 28;
471                 statinfo->bandwidth = (double)(statinfo->total_bytes*8)/1000;
472                 /* Not needed ? initialised to zero? */
473                 statinfo->delta = 0;
474                 statinfo->jitter = 0;
475                 statinfo->diff = 0;
476
477                 statinfo->total_nr++;
478                 statinfo->flags |= STAT_FLAG_FIRST;
479                 if (rtpinfo->info_marker_set) {
480                         statinfo->flags |= STAT_FLAG_MARKER;
481                 }
482                 statinfo->first_packet = FALSE;
483                 return 0;
484         }
485
486         /* Reset flags */
487         statinfo->flags = 0;
488
489         /* Chek for duplicates (src mac differs from first_packet_mac_addr) */
490         if( pinfo->dl_src.type == AT_ETHER){
491                 if(!ADDRESSES_EQUAL(&(statinfo->first_packet_mac_addr), &(pinfo->dl_src))){
492                         statinfo->flags |= STAT_FLAG_DUP_PKT;
493                         statinfo->delta = current_time-(statinfo->time);
494                         return 0;
495                 }
496         }
497
498         /* When calculating expected rtp packets the seq number can wrap around
499          * so we have to count the number of cycles
500          * Variable cycles counts the wraps around in forwarding connection and
501          * under is flag that indicates where we are
502          *
503          * XXX How to determine number of cycles with all possible lost, late
504          * and duplicated packets without any doubt? It seems to me, that
505          * because of all possible combination of late, duplicated or lost
506          * packets, this can only be more or less good approximation
507          *
508          * There are some combinations (rare but theoretically possible),
509          * where below code won't work correctly - statistic may be wrong then.
510          */
511
512         /* So if the current sequence number is less than the start one
513          * we assume, that there is another cycle running
514          */
515         if ((rtpinfo->info_seq_num < statinfo->start_seq_nr) && (statinfo->under == FALSE)){
516                 statinfo->cycles++;
517                 statinfo->under = TRUE;
518         }
519         /* what if the start seq nr was 0? Then the above condition will never
520          * be true, so we add another condition. XXX The problem would arise
521          * if one of the packets with seq nr 0 or 65535 would be lost or late
522          */
523         else if ((rtpinfo->info_seq_num == 0) && (statinfo->stop_seq_nr == 65535) &&
524                 (statinfo->under == FALSE)){
525                 statinfo->cycles++;
526                 statinfo->under = TRUE;
527         }
528         /* the whole round is over, so reset the flag */
529         else if ((rtpinfo->info_seq_num > statinfo->start_seq_nr) && (statinfo->under != FALSE)) {
530                 statinfo->under = FALSE;
531         }
532
533         /* Since it is difficult to count lost, duplicate or late packets separately,
534          * we would like to know at least how many times the sequence number was not ok
535          */
536
537         /* If the current seq number equals the last one or if we are here for
538          * the first time, then it is ok, we just store the current one as the last one
539          */
540         if ( (statinfo->seq_num+1 == rtpinfo->info_seq_num) || (statinfo->flags & STAT_FLAG_FIRST) )
541                 statinfo->seq_num = rtpinfo->info_seq_num;
542         /* If the first one is 65535 we wrap */
543         else if ( (statinfo->seq_num == 65535) && (rtpinfo->info_seq_num == 0) )
544                 statinfo->seq_num = rtpinfo->info_seq_num;
545         /* Lost packets. If the prev seq is enourmously larger than the cur seq
546          * we assume that instead of being massively late we lost the packet(s)
547          * that would have indicated the sequence number wrapping. An imprecise
548          * heuristic at best, but it seems to work well enough.
549          * https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=5958 */
550         else if (statinfo->seq_num+1 < rtpinfo->info_seq_num || statinfo->seq_num - rtpinfo->info_seq_num > 0xFF00) {
551                 statinfo->seq_num = rtpinfo->info_seq_num;
552                 statinfo->sequence++;
553                 statinfo->flags |= STAT_FLAG_WRONG_SEQ;
554         }
555         /* Late or duplicated */
556         else if (statinfo->seq_num+1 > rtpinfo->info_seq_num) {
557                 statinfo->sequence++;
558                 statinfo->flags |= STAT_FLAG_WRONG_SEQ;
559         }
560
561         /* Check payload type */
562         if (rtpinfo->info_payload_type == PT_CN
563                 || rtpinfo->info_payload_type == PT_CN_OLD)
564                 statinfo->flags |= STAT_FLAG_PT_CN;
565         if (statinfo->pt == PT_CN
566                 || statinfo->pt == PT_CN_OLD)
567                 statinfo->flags |= STAT_FLAG_FOLLOW_PT_CN;
568         if (rtpinfo->info_payload_type != statinfo->pt)
569                 statinfo->flags |= STAT_FLAG_PT_CHANGE;
570         statinfo->pt = rtpinfo->info_payload_type;
571
572         /*
573          * Return 0 for unknown payload types
574          * Ignore jitter calculation for clockrate = 0
575          */
576         if (statinfo->pt < 96 ){
577                 clock_rate = get_clock_rate(statinfo->pt);
578         }else{ /* Dynamic PT */
579                 if ( rtpinfo->info_payload_type_str != NULL ){
580                         /* Is it a "telephone-event" ?
581                          * Timestamp is not increased for telepone-event packets impacting
582                          * calculation of Jitter Skew and clock drift.
583                          * see 2.2.1 of RFC 4733
584                          */
585                         if (g_ascii_strncasecmp("telephone-event",rtpinfo->info_payload_type_str,(strlen("telephone-event")))==0){
586                                 clock_rate = 0;
587                                 statinfo->flags |= STAT_FLAG_PT_T_EVENT;
588                         }else{
589                                 if(rtpinfo->info_payload_rate !=0){
590                                         clock_rate = rtpinfo->info_payload_rate;
591                                 }else{
592                                         clock_rate = get_dyn_pt_clock_rate(rtpinfo-> info_payload_type_str);
593                                 }
594                         }
595                 }else{
596                         clock_rate = 0;
597                 }
598         }
599
600                 /* Handle wraparound ? */
601         arrivaltime = current_time - statinfo->start_time;
602
603         if (statinfo->first_timestamp > rtpinfo->info_timestamp){
604                 /* Handle wraparound */
605                 nominaltime = (double)(rtpinfo->info_timestamp + 0xffffffff - statinfo->first_timestamp + 1);
606         }else{
607                 nominaltime = (double)(rtpinfo->info_timestamp - statinfo->first_timestamp);
608         }
609
610         /* Can only analyze defined sampling rates */
611         if (clock_rate != 0) {
612                 statinfo->clock_rate = clock_rate;
613                 /* Convert from sampling clock to ms */
614                 nominaltime = nominaltime /(clock_rate/1000);
615
616                 /* Calculate the current jitter(in ms) */
617                 if (!statinfo->first_packet) {
618                         expected_time = statinfo->time + (nominaltime - statinfo->lastnominaltime);
619                         current_diff = fabs(current_time - expected_time);
620                         current_jitter = (15 * statinfo->jitter + current_diff) / 16;
621
622                         statinfo->delta = current_time-(statinfo->time);
623                         statinfo->jitter = current_jitter;
624                         statinfo->diff = current_diff;
625                 }
626                 statinfo->lastnominaltime = nominaltime;
627                 /* Calculate skew, i.e. absolute jitter that also catches clock drift
628                  * Skew is positive if TS (nominal) is too fast
629                  */
630                 statinfo->skew    = nominaltime - arrivaltime;
631                 absskew = fabs(statinfo->skew);
632                 if(absskew > fabs(statinfo->max_skew)){
633                         statinfo->max_skew = statinfo->skew;
634                 }
635                 /* Gather data for calculation of average, minimum and maximum framerate based on timestamp */
636 #if 0
637                 if (numPackets > 0 && (!hardPayloadType || !alternatePayloadType)) {
638                         /* Skip first packet and possibly alternate payload type packets */
639                         double dt;
640                         dt     = nominaltime - statinfo->lastnominaltime;
641                         sumdt += 1.0 * dt;
642                         numdt += (dt != 0 ? 1 : 0);
643                         mindt  = (dt < mindt ? dt : mindt);
644                         maxdt  = (dt > maxdt ? dt : maxdt);
645                 }
646 #endif
647                 /* Gather data for calculation of skew least square */
648                 statinfo->sumt   += 1.0 * current_time;
649                 statinfo->sumTS  += 1.0 * nominaltime;
650                 statinfo->sumt2  += 1.0 * current_time * current_time;
651                 statinfo->sumtTS += 1.0 * current_time * nominaltime;
652         }
653
654         /* Calculate the BW in Kbps adding the IP+UDP header to the RTP -> IP header+8bytes(UDP) */
655         statinfo->bw_history[statinfo->bw_index].bytes = rtpinfo->info_data_len + pinfo->iphdrlen + 8;
656         statinfo->bw_history[statinfo->bw_index].time = current_time;
657
658         /* Check if there are more than 1sec in the history buffer to calculate BW in bps. If so, remove those for the calculation */
659         while ((statinfo->bw_history[statinfo->bw_start_index].time+1000/* ms */)<current_time){
660                 statinfo->total_bytes -= statinfo->bw_history[statinfo->bw_start_index].bytes;
661                 statinfo->bw_start_index++;
662                 if (statinfo->bw_start_index == BUFF_BW) statinfo->bw_start_index=0;
663         };
664         /* IP hdr + UDP + RTP */
665         statinfo->total_bytes += rtpinfo->info_data_len + pinfo->iphdrlen + 8;
666         statinfo->bandwidth = (double)(statinfo->total_bytes*8)/1000;
667         statinfo->bw_index++;
668         if (statinfo->bw_index == BUFF_BW) statinfo->bw_index = 0;
669
670
671         /* Is it a packet with the mark bit set? */
672         if (rtpinfo->info_marker_set) {
673                 statinfo->delta_timestamp = rtpinfo->info_timestamp - statinfo->timestamp;
674                 if (rtpinfo->info_timestamp > statinfo->timestamp){
675                         statinfo->flags |= STAT_FLAG_MARKER;
676                 }
677                 else{
678                         statinfo->flags |= STAT_FLAG_WRONG_TIMESTAMP;
679                 }
680         }
681         /* Is it a regular packet? */
682         if (!(statinfo->flags & STAT_FLAG_FIRST)
683                 && !(statinfo->flags & STAT_FLAG_MARKER)
684                 && !(statinfo->flags & STAT_FLAG_PT_CN)
685                 && !(statinfo->flags & STAT_FLAG_WRONG_TIMESTAMP)
686                 && !(statinfo->flags & STAT_FLAG_FOLLOW_PT_CN)) {
687                 /* Include it in maximum delta calculation */
688                 if (statinfo->delta > statinfo->max_delta) {
689                         statinfo->max_delta = statinfo->delta;
690                         statinfo->max_nr = pinfo->fd->num;
691                 }
692                 if (clock_rate != 0) {
693                         /* Maximum and mean jitter calculation */
694                         if (statinfo->jitter > statinfo->max_jitter) {
695                                 statinfo->max_jitter = statinfo->jitter;
696                         }
697                         statinfo->mean_jitter = (statinfo->mean_jitter*statinfo->total_nr + current_diff) / (statinfo->total_nr+1);
698                 }
699         }
700         /* Regular payload change? (CN ignored) */
701         if (!(statinfo->flags & STAT_FLAG_FIRST)
702                 && !(statinfo->flags & STAT_FLAG_PT_CN)) {
703                 if ((statinfo->pt != statinfo->reg_pt)
704                         && (statinfo->reg_pt != PT_UNDEFINED)) {
705                         statinfo->flags |= STAT_FLAG_REG_PT_CHANGE;
706                 }
707         }
708
709         /* Set regular payload*/
710         if (!(statinfo->flags & STAT_FLAG_PT_CN)) {
711                 statinfo->reg_pt = statinfo->pt;
712         }
713
714         statinfo->time = current_time;
715         statinfo->timestamp = rtpinfo->info_timestamp;
716         statinfo->stop_seq_nr = rtpinfo->info_seq_num;
717         statinfo->total_nr++;
718
719         return 0;
720 }
721
722 /*
723  * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
724  *
725  * Local variables:
726  * c-basic-offset: 8
727  * tab-width: 8
728  * indent-tabs-mode: t
729  * End:
730  *
731  * vi: set shiftwidth=8 tabstop=8 noexpandtab:
732  * :indentSize=8:tabSize=8:noTabs=false:
733  */