2 * RTP stream handler functions used by tshark and wireshark
6 * Copyright 2008, Ericsson AB
7 * By Balint Reczey <balint.reczey@ericsson.com>
9 * most functions are copied from gtk/rtp_stream.c and gtk/rtp_analisys.c
10 * Copyright 2003, Alcatel Business Systems
11 * By Lars Ruoff <lars.ruoff@gmx.net>
13 * Wireshark - Network traffic analyzer
14 * By Gerald Combs <gerald@wireshark.org>
15 * Copyright 1998 Gerald Combs
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.
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.
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
42 #include <epan/rtp_pt.h>
43 #include <epan/addr_resolv.h>
44 #include <epan/dissectors/packet-rtp.h>
45 #include "gtk/rtp_stream.h"
46 #include "tap-rtp-common.h"
50 /****************************************************************************/
51 /* GCompareFunc style comparison function for _rtp_stream_info */
52 gint rtp_stream_info_cmp(gconstpointer aa, gconstpointer bb)
54 const struct _rtp_stream_info* a = aa;
55 const struct _rtp_stream_info* b = bb;
59 if (a==NULL || b==NULL)
61 if (ADDRESSES_EQUAL(&(a->src_addr), &(b->src_addr))
62 && (a->src_port == b->src_port)
63 && ADDRESSES_EQUAL(&(a->dest_addr), &(b->dest_addr))
64 && (a->dest_port == b->dest_port)
65 && (a->ssrc == b->ssrc))
72 /****************************************************************************/
73 /* when there is a [re]reading of packet's */
74 void rtpstream_reset(rtpstream_tapinfo_t *tapinfo)
78 if (tapinfo->mode == TAP_ANALYSE) {
79 /* free the data items first */
80 list = g_list_first(tapinfo->strinfo_list);
84 list = g_list_next(list);
86 g_list_free(tapinfo->strinfo_list);
87 tapinfo->strinfo_list = NULL;
88 tapinfo->nstreams = 0;
89 tapinfo->npackets = 0;
92 ++(tapinfo->launch_count);
97 void rtpstream_reset_cb(void *arg)
103 * rtpdump file format
105 * The file starts with the tool to be used for playing this file,
106 * the multicast/unicast receive address and the port.
108 * #!rtpplay1.0 224.2.0.1/3456\n
110 * This is followed by one binary header (RD_hdr_t) and one RD_packet_t
111 * structure for each received packet. All fields are in network byte
112 * order. We don't need the source IP address since we can do mapping
113 * based on SSRC. This saves (a little) space, avoids non-IPv4
114 * problems and privacy/security concerns. The header is followed by
115 * the RTP/RTCP header and (optionally) the actual payload.
118 #define RTPFILE_VERSION "1.0"
121 * Write a header to the current output file.
122 * The header consists of an identifying string, followed
123 * by a binary structure.
125 void rtp_write_header(rtp_stream_info_t *strinfo, FILE *file)
127 guint32 start_sec; /* start of recording (GMT) (seconds) */
128 guint32 start_usec; /* start of recording (GMT) (microseconds)*/
129 guint32 source; /* network source (multicast address) */
131 guint16 port; /* UDP port */
132 guint16 padding; /* 2 padding bytes */
134 fprintf(file, "#!rtpplay%s %s/%u\n", RTPFILE_VERSION,
135 get_addr_name(&(strinfo->dest_addr)),
138 start_sec = g_htonl(strinfo->start_sec);
139 start_usec = g_htonl(strinfo->start_usec);
140 /* rtpdump only accepts guint32 as source, will be fake for IPv6 */
141 memset(&source, 0, sizeof source);
142 sourcelen = strinfo->src_addr.len;
143 if (sourcelen > sizeof source)
144 sourcelen = sizeof source;
145 memcpy(&source, strinfo->src_addr.data, sourcelen);
146 port = g_htons(strinfo->src_port);
149 if (fwrite(&start_sec, 4, 1, file) == 0)
151 if (fwrite(&start_usec, 4, 1, file) == 0)
153 if (fwrite(&source, 4, 1, file) == 0)
155 if (fwrite(&port, 2, 1, file) == 0)
157 if (fwrite(&padding, 2, 1, file) == 0)
161 /* utility function for writing a sample to file in rtpdump -F dump format (.rtp)*/
162 void rtp_write_sample(rtp_sample_t* sample, FILE* file)
164 guint16 length; /* length of packet, including this header (may
165 be smaller than plen if not whole packet recorded) */
166 guint16 plen; /* actual header+payload length for RTP, 0 for RTCP */
167 guint32 offset; /* milliseconds since the start of recording */
169 length = g_htons(sample->header.frame_length + 8);
170 plen = g_htons(sample->header.frame_length);
171 offset = g_htonl(sample->header.rec_time);
173 if (fwrite(&length, 2, 1, file) == 0)
175 if (fwrite(&plen, 2, 1, file) == 0)
177 if (fwrite(&offset, 4, 1, file) == 0)
179 if (fwrite(sample->frame, sample->header.frame_length, 1, file) == 0)
184 /****************************************************************************/
185 /* whenever a RTP packet is seen by the tap listener */
186 int rtpstream_packet(void *arg, packet_info *pinfo, epan_dissect_t *edt _U_, const void *arg2)
188 rtpstream_tapinfo_t *tapinfo = arg;
189 const struct _rtp_info *rtpinfo = arg2;
190 rtp_stream_info_t tmp_strinfo;
191 rtp_stream_info_t *strinfo = NULL;
195 struct _rtp_conversation_info *p_conv_data = NULL;
197 /* gather infos on the stream this packet is part of */
198 COPY_ADDRESS(&(tmp_strinfo.src_addr), &(pinfo->src));
199 tmp_strinfo.src_port = pinfo->srcport;
200 COPY_ADDRESS(&(tmp_strinfo.dest_addr), &(pinfo->dst));
201 tmp_strinfo.dest_port = pinfo->destport;
202 tmp_strinfo.ssrc = rtpinfo->info_sync_src;
203 tmp_strinfo.pt = rtpinfo->info_payload_type;
204 tmp_strinfo.info_payload_type_str = rtpinfo->info_payload_type_str;
206 if (tapinfo->mode == TAP_ANALYSE) {
207 /* check whether we already have a stream with these parameters in the list */
208 list = g_list_first(tapinfo->strinfo_list);
211 if (rtp_stream_info_cmp(&tmp_strinfo, (rtp_stream_info_t*)(list->data))==0)
213 strinfo = (rtp_stream_info_t*)(list->data); /*found!*/
216 list = g_list_next(list);
219 /* not in the list? then create a new entry */
221 tmp_strinfo.npackets = 0;
222 tmp_strinfo.first_frame_num = pinfo->fd->num;
223 tmp_strinfo.start_sec = (guint32) pinfo->fd->abs_ts.secs;
224 tmp_strinfo.start_usec = pinfo->fd->abs_ts.nsecs/1000;
225 tmp_strinfo.start_rel_sec = (guint32) pinfo->fd->rel_ts.secs;
226 tmp_strinfo.start_rel_usec = pinfo->fd->rel_ts.nsecs/1000;
227 tmp_strinfo.tag_vlan_error = 0;
228 tmp_strinfo.tag_diffserv_error = 0;
229 tmp_strinfo.vlan_id = 0;
230 tmp_strinfo.problem = FALSE;
232 /* reset RTP stats */
233 tmp_strinfo.rtp_stats.first_packet = TRUE;
234 tmp_strinfo.rtp_stats.max_delta = 0;
235 tmp_strinfo.rtp_stats.max_jitter = 0;
236 tmp_strinfo.rtp_stats.mean_jitter = 0;
237 tmp_strinfo.rtp_stats.delta = 0;
238 tmp_strinfo.rtp_stats.diff = 0;
239 tmp_strinfo.rtp_stats.jitter = 0;
240 tmp_strinfo.rtp_stats.bandwidth = 0;
241 tmp_strinfo.rtp_stats.total_bytes = 0;
242 tmp_strinfo.rtp_stats.bw_start_index = 0;
243 tmp_strinfo.rtp_stats.bw_index = 0;
244 tmp_strinfo.rtp_stats.timestamp = 0;
245 tmp_strinfo.rtp_stats.max_nr = 0;
246 tmp_strinfo.rtp_stats.total_nr = 0;
247 tmp_strinfo.rtp_stats.sequence = 0;
248 tmp_strinfo.rtp_stats.start_seq_nr = 0;
249 tmp_strinfo.rtp_stats.stop_seq_nr = 0;
250 tmp_strinfo.rtp_stats.cycles = 0;
251 tmp_strinfo.rtp_stats.under = FALSE;
252 tmp_strinfo.rtp_stats.start_time = 0;
253 tmp_strinfo.rtp_stats.time = 0;
254 tmp_strinfo.rtp_stats.reg_pt = PT_UNDEFINED;
256 /* Get the Setup frame number who set this RTP stream */
257 p_conv_data = p_get_proto_data(pinfo->fd, proto_get_id_by_filter_name("rtp"));
259 tmp_strinfo.setup_frame_number = p_conv_data->frame_number;
261 tmp_strinfo.setup_frame_number = 0xFFFFFFFF;
263 strinfo = g_malloc(sizeof(rtp_stream_info_t));
264 *strinfo = tmp_strinfo; /* memberwise copy of struct */
265 tapinfo->strinfo_list = g_list_append(tapinfo->strinfo_list, strinfo);
268 /* get RTP stats for the packet */
269 rtp_packet_analyse(&(strinfo->rtp_stats), pinfo, rtpinfo);
270 if (strinfo->rtp_stats.flags & STAT_FLAG_WRONG_TIMESTAMP
271 || strinfo->rtp_stats.flags & STAT_FLAG_WRONG_SEQ)
272 strinfo->problem = TRUE;
275 /* increment the packets counter for this stream */
276 ++(strinfo->npackets);
277 strinfo->stop_rel_sec = (guint32) pinfo->fd->rel_ts.secs;
278 strinfo->stop_rel_usec = pinfo->fd->rel_ts.nsecs/1000;
280 /* increment the packets counter of all streams */
281 ++(tapinfo->npackets);
283 return 1; /* refresh output */
285 else if (tapinfo->mode == TAP_SAVE) {
286 if (rtp_stream_info_cmp(&tmp_strinfo, tapinfo->filter_stream_fwd)==0) {
287 /* XXX - what if rtpinfo->info_all_data_present is
288 FALSE, so that we don't *have* all the data? */
289 sample.header.rec_time =
290 (pinfo->fd->abs_ts.nsecs/1000 + 1000000 - tapinfo->filter_stream_fwd->start_usec)/1000
291 + (guint32) (pinfo->fd->abs_ts.secs - tapinfo->filter_stream_fwd->start_sec - 1)*1000;
292 sample.header.frame_length = rtpinfo->info_data_len;
293 sample.frame = rtpinfo->info_data;
294 rtp_write_sample(&sample, tapinfo->save_file);
297 else if (tapinfo->mode == TAP_MARK) {
299 if (rtp_stream_info_cmp(&tmp_strinfo, tapinfo->filter_stream_fwd)==0
300 || rtp_stream_info_cmp(&tmp_strinfo, tapinfo->filter_stream_rev)==0)
302 cf_mark_frame(&cfile, pinfo->fd);
310 typedef struct _key_value {
316 /* RTP sampling clock rates for fixed payload types as defined in
317 http://www.iana.org/assignments/rtp-parameters */
318 static const key_value clock_map[] = {
324 {PT_DVI4_8000, 8000},
325 {PT_DVI4_16000, 16000},
329 {PT_L16_STEREO, 44100},
330 {PT_L16_MONO, 44100},
336 {PT_DVI4_11025, 11025},
337 {PT_DVI4_22050, 22050},
349 #define NUM_CLOCK_VALUES (sizeof clock_map / sizeof clock_map[0])
352 get_clock_rate(guint32 key)
356 for (i = 0; i < NUM_CLOCK_VALUES; i++) {
357 if (clock_map[i].key == key)
358 return clock_map[i].value;
363 typedef struct _mimetype_and_clock {
364 const gchar *pt_mime_name_str;
366 } mimetype_and_clock;
367 /* RTP sampling clock rates for
368 "In addition to the RTP payload formats (encodings) listed in the RTP
369 Payload Types table, there are additional payload formats that do not
370 have static RTP payload types assigned but instead use dynamic payload
371 type number assignment. Each payload format is named by a registered
373 http://www.iana.org/assignments/rtp-parameters.
375 NOTE: Please keep the mimetypes in case insensitive alphabetical order.
377 static const mimetype_and_clock mimetype_and_clock_map[] = {
378 {"AMR", 8000}, /* [RFC4867][RFC3267] */
379 {"AMR-WB", 16000}, /* [RFC4867][RFC3267] */
380 {"BMPEG", 90000}, /* [RFC2343],[RFC3555] */
381 {"BT656", 90000}, /* [RFC2431],[RFC3555] */
382 {"DV", 90000}, /* [RFC3189] */
383 {"EVRC", 8000}, /* [RFC3558] */
384 {"EVRC0", 8000}, /* [RFC4788] */
385 {"EVRC1", 8000}, /* [RFC4788] */
386 {"EVRCB", 8000}, /* [RFC4788] */
387 {"EVRCB0", 8000}, /* [RFC4788] */
388 {"EVRCB1", 8000}, /* [RFC4788] */
389 {"EVRCWB", 16000}, /* [RFC5188] */
390 {"EVRCWB0", 16000}, /* [RFC5188] */
391 {"EVRCWB1", 16000}, /* [RFC5188] */
392 {"G7221", 16000}, /* [RFC3047] */
393 {"G726-16", 8000}, /* [RFC3551][RFC4856] */
394 {"G726-24", 8000}, /* [RFC3551][RFC4856] */
395 {"G726-32", 8000}, /* [RFC3551][RFC4856] */
396 {"G726-40", 8000}, /* [RFC3551][RFC4856] */
397 {"G729D", 8000}, /* [RFC3551][RFC4856] */
398 {"G729E", 8000}, /* [RFC3551][RFC4856] */
399 {"GSM-EFR", 8000}, /* [RFC3551] */
400 {"H263-1998", 90000}, /* [RFC2429],[RFC3555] */
401 {"H263-2000", 90000}, /* [RFC2429],[RFC3555] */
402 {"H264", 90000}, /* [RFC3984] */
403 {"MP1S", 90000}, /* [RFC2250],[RFC3555] */
404 {"MP2P", 90000}, /* [RFC2250],[RFC3555] */
405 {"MP4V-ES", 90000}, /* [RFC3016] */
406 {"mpa-robust", 90000}, /* [RFC3119] */
407 {"pointer", 90000}, /* [RFC2862] */
408 {"raw", 90000}, /* [RFC4175] */
409 {"red", 1000}, /* [RFC4102] */
410 {"SMV", 8000}, /* [RFC3558] */
411 {"SMV0", 8000}, /* [RFC3558] */
412 {"t140", 1000}, /* [RFC4103] */
413 {"telephone-event", 8000}, /* [RFC4733] */
416 #define NUM_DYN_CLOCK_VALUES (sizeof mimetype_and_clock_map / sizeof mimetype_and_clock_map[0])
419 get_dyn_pt_clock_rate(gchar *payload_type_str)
423 /* Search for matching mimetype in reverse order to avoid false matches
424 * when pt_mime_name_str is the prefix of payload_type_str */
425 for (i = NUM_DYN_CLOCK_VALUES - 1; i > -1 ; i--) {
426 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)
427 return mimetype_and_clock_map[i].value;
433 /****************************************************************************/
434 int rtp_packet_analyse(tap_rtp_stat_t *statinfo,
436 const struct _rtp_info *rtpinfo)
439 double current_jitter;
441 double expected_time;
446 /* check payload type */
447 if (rtpinfo->info_payload_type == PT_CN
448 || rtpinfo->info_payload_type == PT_CN_OLD)
449 statinfo->flags |= STAT_FLAG_PT_CN;
450 if (statinfo->pt == PT_CN
451 || statinfo->pt == PT_CN_OLD)
452 statinfo->flags |= STAT_FLAG_FOLLOW_PT_CN;
453 if (rtpinfo->info_payload_type != statinfo->pt)
454 statinfo->flags |= STAT_FLAG_PT_CHANGE;
455 statinfo->pt = rtpinfo->info_payload_type;
457 * XXX - should "get_clock_rate()" return 0 for unknown
458 * payload types, presumably meaning that we should
459 * just ignore this packet?
461 if (statinfo->pt < 96 ){
462 clock_rate = get_clock_rate(statinfo->pt);
463 }else{ /* dynamic PT */
464 if ( rtpinfo->info_payload_type_str != NULL )
465 clock_rate = get_dyn_pt_clock_rate(rtpinfo-> info_payload_type_str);
470 /* Store the current time and calculate the current jitter(in ms) */
471 current_time = nstime_to_msec(&pinfo->fd->rel_ts);
472 /* Expected time is last arrival time + the timestamp difference divided by the sampling clock( /1000 to get ms) */
473 expected_time = statinfo->time + ((double)(rtpinfo->info_timestamp)-(double)(statinfo->timestamp))/(clock_rate/1000);
474 current_diff = fabs(current_time - expected_time);
475 current_jitter = (15 * statinfo->jitter + current_diff) / 16;
477 statinfo->delta = current_time-(statinfo->time);
478 statinfo->jitter = current_jitter;
479 statinfo->diff = current_diff;
481 /* calculate the BW in Kbps adding the IP+UDP header to the RTP -> 20bytes(IP)+8bytes(UDP) = 28bytes */
482 statinfo->bw_history[statinfo->bw_index].bytes = rtpinfo->info_data_len + 28;
483 statinfo->bw_history[statinfo->bw_index].time = current_time;
484 /* check if there are more than 1sec in the history buffer to calculate BW in bps. If so, remove those for the calculation */
485 while ((statinfo->bw_history[statinfo->bw_start_index].time+1000/* ms */)<current_time){
486 statinfo->total_bytes -= statinfo->bw_history[statinfo->bw_start_index].bytes;
487 statinfo->bw_start_index++;
488 if (statinfo->bw_start_index == BUFF_BW) statinfo->bw_start_index=0;
490 statinfo->total_bytes += rtpinfo->info_data_len + 28;
491 statinfo->bandwidth = (double)(statinfo->total_bytes*8)/1000;
492 statinfo->bw_index++;
493 if (statinfo->bw_index == BUFF_BW) statinfo->bw_index = 0;
496 /* is this the first packet we got in this direction? */
497 if (statinfo->first_packet) {
498 statinfo->start_seq_nr = rtpinfo->info_seq_num;
499 statinfo->start_time = current_time;
501 statinfo->jitter = 0;
503 statinfo->flags |= STAT_FLAG_FIRST;
504 statinfo->first_packet = FALSE;
506 /* is it a packet with the mark bit set? */
507 if (rtpinfo->info_marker_set) {
508 statinfo->delta_timestamp = rtpinfo->info_timestamp - statinfo->timestamp;
509 if (rtpinfo->info_timestamp > statinfo->timestamp){
510 statinfo->flags |= STAT_FLAG_MARKER;
513 statinfo->flags |= STAT_FLAG_WRONG_TIMESTAMP;
516 /* is it a regular packet? */
517 if (!(statinfo->flags & STAT_FLAG_FIRST)
518 && !(statinfo->flags & STAT_FLAG_MARKER)
519 && !(statinfo->flags & STAT_FLAG_PT_CN)
520 && !(statinfo->flags & STAT_FLAG_WRONG_TIMESTAMP)
521 && !(statinfo->flags & STAT_FLAG_FOLLOW_PT_CN)) {
522 /* include it in maximum delta calculation */
523 if (statinfo->delta > statinfo->max_delta) {
524 statinfo->max_delta = statinfo->delta;
525 statinfo->max_nr = pinfo->fd->num;
527 /* maximum and mean jitter calculation */
528 if (statinfo->jitter > statinfo->max_jitter) {
529 statinfo->max_jitter = statinfo->jitter;
531 statinfo->mean_jitter = (statinfo->mean_jitter*statinfo->total_nr + current_diff) / (statinfo->total_nr+1);
533 /* regular payload change? (CN ignored) */
534 if (!(statinfo->flags & STAT_FLAG_FIRST)
535 && !(statinfo->flags & STAT_FLAG_PT_CN)) {
536 if ((statinfo->pt != statinfo->reg_pt)
537 && (statinfo->reg_pt != PT_UNDEFINED)) {
538 statinfo->flags |= STAT_FLAG_REG_PT_CHANGE;
542 /* set regular payload*/
543 if (!(statinfo->flags & STAT_FLAG_PT_CN)) {
544 statinfo->reg_pt = statinfo->pt;
548 /* When calculating expected rtp packets the seq number can wrap around
549 * so we have to count the number of cycles
550 * Variable cycles counts the wraps around in forwarding connection and
551 * under is flag that indicates where we are
553 * XXX how to determine number of cycles with all possible lost, late
554 * and duplicated packets without any doubt? It seems to me, that
555 * because of all possible combination of late, duplicated or lost
556 * packets, this can only be more or less good approximation
558 * There are some combinations (rare but theoretically possible),
559 * where below code won't work correctly - statistic may be wrong then.
562 /* so if the current sequence number is less than the start one
563 * we assume, that there is another cycle running */
564 if ((rtpinfo->info_seq_num < statinfo->start_seq_nr) && (statinfo->under == FALSE)){
566 statinfo->under = TRUE;
568 /* what if the start seq nr was 0? Then the above condition will never
569 * be true, so we add another condition. XXX The problem would arise
570 * if one of the packets with seq nr 0 or 65535 would be lost or late */
571 else if ((rtpinfo->info_seq_num == 0) && (statinfo->stop_seq_nr == 65535) &&
572 (statinfo->under == FALSE)){
574 statinfo->under = TRUE;
576 /* the whole round is over, so reset the flag */
577 else if ((rtpinfo->info_seq_num > statinfo->start_seq_nr) && (statinfo->under != FALSE)) {
578 statinfo->under = FALSE;
581 /* Since it is difficult to count lost, duplicate or late packets separately,
582 * we would like to know at least how many times the sequence number was not ok */
584 /* if the current seq number equals the last one or if we are here for
585 * the first time, then it is ok, we just store the current one as the last one */
586 if ( (statinfo->seq_num+1 == rtpinfo->info_seq_num) || (statinfo->flags & STAT_FLAG_FIRST) )
587 statinfo->seq_num = rtpinfo->info_seq_num;
588 /* if the first one is 65535. XXX same problem as above: if seq 65535 or 0 is lost... */
589 else if ( (statinfo->seq_num == 65535) && (rtpinfo->info_seq_num == 0) )
590 statinfo->seq_num = rtpinfo->info_seq_num;
592 else if (statinfo->seq_num+1 < rtpinfo->info_seq_num) {
593 statinfo->seq_num = rtpinfo->info_seq_num;
594 statinfo->sequence++;
595 statinfo->flags |= STAT_FLAG_WRONG_SEQ;
597 /* late or duplicated */
598 else if (statinfo->seq_num+1 > rtpinfo->info_seq_num) {
599 statinfo->sequence++;
600 statinfo->flags |= STAT_FLAG_WRONG_SEQ;
602 statinfo->time = current_time;
603 statinfo->timestamp = rtpinfo->info_timestamp;
604 statinfo->stop_seq_nr = rtpinfo->info_seq_num;
605 statinfo->total_nr++;