Ethereal-dev: [Ethereal-dev] Re: Ethereal-dev Digest, Vol 1, Issue 1614 (Auto Reply)
Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.
From: "Jambunathan Jambunathan" <KJambunathan@xxxxxxxxxx>
Date: Thu, 15 May 2003 06:32:40 -0600
Hi ! I am on medical between May 12, 2003 - May 23, 2003. I will get in touch with you once I come back. In case of an urgent issue, kindly get in touch with Subrata Sarkar - ssarkar@xxxxxxxxxx. Regards, Jambunathan K. >>> ethereal-dev 05/15/03 18:01 >>> Send Ethereal-dev mailing list submissions to ethereal-dev@xxxxxxxxxxxx To subscribe or unsubscribe via the World Wide Web, visit http://www.ethereal.com/mailman/listinfo/ethereal-dev or, via email, send a message with subject or body 'help' to ethereal-dev-request@xxxxxxxxxxxx You can reach the person managing the list at ethereal-dev-owner@xxxxxxxxxxxx When replying, please edit your Subject line so it is more specific than "Re: Contents of Ethereal-dev digest..." Today's Topics: 1. Re: bug in ethereal version 0.9.11 concerning pflog (Guy Harris) 2. Re: tap registration and packet traversal (Lars Ruoff (Alplog)) 3. Re: OpenBSD pflog format change (Guy Harris) 4. Re: Check-in Request - colorfilters enhancement (Guy Harris) 5. Buiding on VC .NET solved yet? (Richard Urwin) 6. What's up with the heuristic RTP dissector? (Lars Ruoff) 7. Re: tap registration and packet traversal (Ronnie Sahlberg) 8. Conversations and Sessions (Biot Olivier) 9. RTP analysis (Miha Jemec) ---------------------------------------------------------------------- Message: 1 Date: Thu, 15 May 2003 00:13:22 -0700 From: Guy Harris <gharris@xxxxxxxxx> Subject: Re: [Ethereal-dev] bug in ethereal version 0.9.11 concerning pflog To: John Scarfone <kg4exy@xxxxxxxxxxx> Cc: ethereal-dev@xxxxxxxxxxxx Message-ID: <20030515001322.J337@xxxxxxxxxxxxxxxxxxx> Content-Type: text/plain; charset=us-ascii On Thu, May 01, 2003 at 09:21:50PM -0400, John Scarfone wrote: > Looks like you're correct. This did change between OpenBSD versions 3.2 and > 3.3. I was unaware of that. The change was made here: > http://www.openbsd.org/cgi-bin/cvsweb/src/sys/net/pfvar.h.diff?r1=1.123&r2=1.124&f=h > > So this isn't really an Ethereal bug. > > It would be nice though if eventually the Ethereal decoding was changed to > work with the latest OpenBSD version. Well, if by "the latest OpenBSD version" you mean "the pflog files in 3.3", it'd be nice for people running Ethereal on 3.3, but not so nice for people running it on earlier versions or with pflog files from earlier versions. It appears that 3.4 might use the DLT_PFLOG value assigned by tcpdump.org, allowing Ethereal (and tcpdump.org's tcpdump) to distinguish between the old and new file formats; Can Erkin Acar contributed a patch to handle both of them, so that should work for 3.2 and earlier systems, and for 3.4 - it doesn't help with 3.3, though, as they didn't change the DLT_ value. ------------------------------ Message: 2 Date: Thu, 15 May 2003 09:14:33 +0200 From: "Lars Ruoff (Alplog)" <lars.ruoff@xxxxxxxxxxxxxxxxxx> Subject: Re: [Ethereal-dev] tap registration and packet traversal To: "Ronnie Sahlberg" <ronnie_sahlberg@xxxxxxxxxxxxxx>, "Ethereal-Dev" <Ethereal-dev@xxxxxxxxxxxx> Message-ID: <002e01c31ab1$a2dd6de0$909f1aac@psostag10> Content-Type: text/plain; charset="iso-8859-1" Thank you. In a more general way of speaking, what is the best way to traverse all packets? I took the tap_rtp as an example, and what is done there is that a tap listener is registered, then redissect_packets is called, so that the tap function is called for each packet and finally the tap is unregistered again. However this is so slow, since all the protocol tree is being reconstructed again (is it?), although there is not really a need for it. Is there a faster method? It would be nice to have a version of redissect_packets, wich calls only the taps but not the proto-dissectors. Lars. ----- Original Message ----- From: "Ronnie Sahlberg" <ronnie_sahlberg@xxxxxxxxxxxxxx> To: "Lars Ruoff (Alplog)" <lars.ruoff@xxxxxxxxxxxxxxxxxx>; "Ethereal-Dev" <Ethereal-dev@xxxxxxxxxxxx> Sent: Wednesday, May 14, 2003 11:25 PM Subject: Re: [Ethereal-dev] tap registration and packet traversal > register_all_tap_listeners only registers that the tap is available > and the only thing it does is to tell ethereal/tethereal the tap > listener exists, i.e. tha thte command lines works and that ethereal will > put it on the menu. > > the tap itself is not activated at this point. it only tells ethereal that > it exists > and that it can be activated by the menu/commandline by calling a callback. > > tap listeners only receive packets when they are activated. > > ----- Original Message ----- > From: "Lars Ruoff (Alplog)" > Sent: Tuesday, May 13, 2003 6:31 PM > Subject: [Ethereal-dev] tap registration and packet traversal > > > > Hi everybody, > > > > I'm new to Ethereal-Dev. > > I'm working on a replacement for the RTP analysis tap for my own needs but > i > > have a very hard time to see clear in all that. > > There is one thing i haven't figured out about the tap system: > > In tap_rtp.c, in seems that the tap is registered only once the user has > > selected the "RTP Analysis..." menu item. > > On the other hand, all taps seems to get registered in the > > register_all_tap_listeners function from gtk/main.c > > So when do the tap listeners get registered/should be registered?? > > Do the other tap's packet_xxx-functions get called every time a packet is > > beeing dissected?? > > Indeed, i would like to have my tap running only while the user is in my > > dialog, cause it is quite cpu-intensive and there is no need for the tap > to > > be running otherwise. > > In fact, i use the tap system for the sole purpose of traversing all the > > captured packets and doing some calculation on it before displaying my > > dialog box. > > (but i don't want a time overhead for dissecting packets when the dialog > box > > is not active) > > Is this the way to do? > > > > help would be appreciated, > > thanks > > > > _______________________________________________ > > Ethereal-dev mailing list > > Ethereal-dev@xxxxxxxxxxxx > > http://www.ethereal.com/mailman/listinfo/ethereal-dev > ------------------------------ Message: 3 Date: Thu, 15 May 2003 00:15:24 -0700 From: Guy Harris <gharris@xxxxxxxxx> Subject: Re: [Ethereal-dev] OpenBSD pflog format change To: Can Erkin Acar <canacar@xxxxxxxxxxxxxxx> Cc: ethereal-dev@xxxxxxxxxxxx Message-ID: <20030515001524.K337@xxxxxxxxxxxxxxxxxxx> Content-Type: text/plain; charset=us-ascii On Wed, May 14, 2003 at 11:21:04PM +0300, Can Erkin Acar wrote: > The format of the log header (and link type) for > OpenBSD log files have changed yesterday. Attached > is a patch for parsing both formats in ethereal Checked in. (What about the change in 3.3? Unfortunately, that uses the same DLT_ value as earlier releases, but has a different header format.) ------------------------------ Message: 4 Date: Thu, 15 May 2003 00:44:53 -0700 From: Guy Harris <gharris@xxxxxxxxx> Subject: Re: [Ethereal-dev] Check-in Request - colorfilters enhancement To: Richard Urwin <richard@xxxxxxxxxxxxxxx> Cc: ethereal-dev@xxxxxxxxxxxx Message-ID: <20030515004453.M337@xxxxxxxxxxxxxxxxxxx> Content-Type: text/plain; charset=us-ascii On Sun, May 11, 2003 at 02:40:20AM +0100, Richard Urwin wrote: > Here is the first phase of the enhancement of color filters: Checked in. ------------------------------ Message: 5 Date: Thu, 15 May 2003 09:06:32 +0100 From: Richard Urwin <RUrwin@xxxxxxxxxxxxxx> Subject: [Ethereal-dev] Buiding on VC .NET solved yet? To: ethereal-dev@xxxxxxxxxxxx Message-ID: <090ED6DFF3D5D611A81400508B8B5A3F0F8DF4@SKYLLA> Content-Type: text/plain Has anyone managed to build ethereal on Visual C .NET? I get lots of unresolved symbols which are libc functions with a __imp__ prefix. Someone mentioned this back in September, but I can not now see a reply. ISTR it was said at the time that building Ethereal on .NET hadn't been checked-out yet and to use VC6. There is a thread in the curl archives saying that winmm.lib is required to solve this problem. Unfortunately it doesn't seem to solve it for Ethereal. So before I load up VC6, does anyone know how to get it to work with .NET? -- Richard Urwin, Software Design Engineer Schenck Test Automation Braemar Court, 1311b Melton Road, Syston, UK. rurwin@xxxxxxxxxxxxx ________________________________________________________________________ This email has been scanned for all viruses by the MessageLabs Email Security System. For more information on a proactive email security service working around the clock, around the globe, visit http://www.messagelabs.com ________________________________________________________________________ ------------------------------ Message: 6 Date: Thu, 15 May 2003 10:17:14 +0200 From: "Lars Ruoff" <lars.ruoff@xxxxxxxxxxxxxxxxxx> Subject: [Ethereal-dev] What's up with the heuristic RTP dissector? To: "Ethereal-Dev" <Ethereal-dev@xxxxxxxxxxxx> Message-ID: <004601c31aba$645a8900$909f1aac@psostag10> Content-Type: text/plain; charset="iso-8859-1" Hi I'm working a lot with RTP captures for VoIP analysis. So i wanted to change the fact that Ethereal did not automatically detect RTP, when present. I thought of coding a heuristic dissector, but then i saw that there was already something in packet-rtp. In packet-rtp.c, the dissect_rtp_heur dissector is registered in the rtp_add_address function. But the last seems to be never called from anywhere! (as far as i can see) How does it work? What does it do? (I'm working on the codebase of 0.9.12) ------------------------------ Message: 7 Date: Thu, 15 May 2003 19:49:48 +1000 From: "Ronnie Sahlberg" <ronnie_sahlberg@xxxxxxxxxxxxxx> Subject: Re: [Ethereal-dev] tap registration and packet traversal To: "Lars Ruoff (Alplog)" <lars.ruoff@xxxxxxxxxxxxxxxxxx>, "Ethereal-Dev" <Ethereal-dev@xxxxxxxxxxxx> Message-ID: <011b01c31ac7$52c2d460$6501010a@C5043436> Content-Type: text/plain; charset="iso-8859-1" Yes it is slow. However, tap listeners provide a filter string to control which packets they want to tap and in order to evaluate the filter, teh only method to do so is to first dissect the full packet before the filter can be evaluated. It is slow by design. That is why the filtering works so well-is so accurate. To get all packets in the entire capture create a tap listener that taps the "frame" tap )every single packet has "frame" and specify NULL or "" as the filter. ----- Original Message ----- From: "Lars Ruoff (Alplog)" Sent: Thursday, May 15, 2003 5:14 PM Subject: Re: [Ethereal-dev] tap registration and packet traversal > Thank you. > > In a more general way of speaking, what is the best way to traverse all > packets? > I took the tap_rtp as an example, and what is done there is that a tap > listener is registered, > then redissect_packets is called, so that the tap function is called for > each packet and finally the tap is unregistered again. > However this is so slow, since all the protocol tree is being reconstructed > again (is it?), although there is not really a need for it. > Is there a faster method? > It would be nice to have a version of redissect_packets, wich calls only the > taps but not the proto-dissectors. > > Lars. ------------------------------ Message: 8 Date: Thu, 15 May 2003 13:29:53 +0200 From: Biot Olivier <Olivier.Biot@xxxxxxxxxxx> Subject: [Ethereal-dev] Conversations and Sessions To: "Ethereal-Dev (E-mail)" <ethereal-dev@xxxxxxxxxxxx> Message-ID: <6B546A602AD2D211BFF00008C7A42889068317CC@xxxxxxxxxxxxxxxx> Content-Type: text/plain; charset="iso-8859-1" Skipped content of type multipart/alternative ------------------------------ Message: 9 Date: 15 May 2003 13:48:29 +0200 From: Miha Jemec <m.jemec@xxxxxxxxxxx> Subject: [Ethereal-dev] RTP analysis To: "ethereal-dev@xxxxxxxxxxxx" <ethereal-dev@xxxxxxxxxxxx> Message-ID: <1052999308.19966.31.camel@xxxxxxxxxxxxxxxxxx> Content-Type: text/plain; charset="us-ascii" Hi! I would like to do some further improvents on tap_rtp.c (add some new features). To make all new changes easier, I made some modifications to the existing tap_rtp.c first. Instead of 6 very similar parts of code in the rtp_packet() routine (for forward and reversed direction each with three cases: first packet, packet with mark bit set and normal packet) I replaced this part with the do_calculation() routine that does the same job for all cases. And now there are some 400 lines of code less. This will hopefully make any other changes much easier, since everything is now only in one place. There was also a problem that existing RTP analysis couldn't save voice in a file when there were padding, extension or CSRC fields enabled. This works now, but I had to do some minor changes to packet-rtp.c and .h. Attached are diffs for: tap_rtp.c packet-rtp.c packet-rtp.h Attached is also a sample RTP conversation (1 kHz, 3s), where the RTP packets have all the three options enabled: rtp_options.raw Hope the changes are acceptable, since this would make my further work much easier. Thanks and regards, Miha -------------- next part -------------- --- packet-rtp.c 2003-03-06 21:35:09.000000000 +0100 +++ packet-rtp.c-new 2003-05-15 10:20:39.000000000 +0200 @@ -450,124 +450,135 @@ /* Synchronization source identifier 32 bits (4 octets) */ proto_tree_add_uint( rtp_tree, hf_rtp_ssrc, tvb, offset, 4, sync_src ); offset += 4; - - /* CSRC list*/ - if ( csrc_count > 0 ) { + } else { + offset += 12; + } + /* CSRC list*/ + if ( csrc_count > 0 ) { + if ( tree ) { ti = proto_tree_add_text(rtp_tree, tvb, offset, csrc_count * 4, "Contributing Source identifiers"); rtp_csrc_tree = proto_item_add_subtree( ti, ett_csrc_list ); - for (i = 0; i < csrc_count; i++ ) { - csrc_item = tvb_get_ntohl( tvb, offset ); - proto_tree_add_uint_format( rtp_csrc_tree, - hf_rtp_csrc_item, tvb, offset, 4, - csrc_item, - "CSRC item %d: %u", - i, csrc_item ); - offset += 4; - } } + for (i = 0; i < csrc_count; i++ ) { + csrc_item = tvb_get_ntohl( tvb, offset ); + if ( tree ) proto_tree_add_uint_format( rtp_csrc_tree, + hf_rtp_csrc_item, tvb, offset, 4, + csrc_item, + "CSRC item %d: %u", + i, csrc_item ); + offset += 4; + } + } - /* Optional RTP header extension */ - if ( extension_set ) { - /* Defined by profile field is 16 bits (2 octets) */ - proto_tree_add_uint( rtp_tree, hf_rtp_prof_define, tvb, offset, 2, tvb_get_ntohs( tvb, offset ) ); - offset += 2; - - hdr_extension = tvb_get_ntohs( tvb, offset ); - proto_tree_add_uint( rtp_tree, hf_rtp_length, tvb, - offset, 2, hdr_extension); - offset += 2; - if ( hdr_extension > 0 ) { - ti = proto_tree_add_text(rtp_tree, tvb, offset, csrc_count * 4, "Header extensions"); - /* I'm re-using the old tree variable here - from the CSRC list!*/ - rtp_csrc_tree = proto_item_add_subtree( ti, - ett_hdr_ext ); - for (i = 0; i < hdr_extension; i++ ) { - proto_tree_add_uint( rtp_csrc_tree, hf_rtp_hdr_ext, tvb, offset, 4, tvb_get_ntohl( tvb, offset ) ); - offset += 4; - } + /* Optional RTP header extension */ + if ( extension_set ) { + /* Defined by profile field is 16 bits (2 octets) */ + if ( tree ) proto_tree_add_uint( rtp_tree, hf_rtp_prof_define, tvb, offset, 2, tvb_get_ntohs( tvb, offset ) ); + offset += 2; + + hdr_extension = tvb_get_ntohs( tvb, offset ); + if ( tree ) proto_tree_add_uint( rtp_tree, hf_rtp_length, tvb, + offset, 2, hdr_extension); + offset += 2; + if ( hdr_extension > 0 ) { + if ( tree ) { ti = proto_tree_add_text(rtp_tree, tvb, offset, csrc_count * 4, "Header extensions"); + /* I'm re-using the old tree variable here + from the CSRC list!*/ + rtp_csrc_tree = proto_item_add_subtree( ti, + ett_hdr_ext ); + } + for (i = 0; i < hdr_extension; i++ ) { + if ( tree ) proto_tree_add_uint( rtp_csrc_tree, hf_rtp_hdr_ext, tvb, offset, 4, tvb_get_ntohl( tvb, offset ) ); + offset += 4; } } + } - if ( padding_set ) { + if ( padding_set ) { + /* + * This RTP frame has padding - find it. + * + * The padding count is found in the LAST octet of + * the packet; it contains the number of octets + * that can be ignored at the end of the packet. + */ + if (tvb_length(tvb) < tvb_reported_length(tvb)) { /* - * This RTP frame has padding - find it. + * We don't *have* the last octet of the + * packet, so we can't get the padding + * count. * - * The padding count is found in the LAST octet of - * the packet; it contains the number of octets - * that can be ignored at the end of the packet. + * Put an indication of that into the + * tree, and just put in a raw data + * item. */ - if (tvb_length(tvb) < tvb_reported_length(tvb)) { - /* - * We don't *have* the last octet of the - * packet, so we can't get the padding - * count. - * - * Put an indication of that into the - * tree, and just put in a raw data - * item. - */ - proto_tree_add_text(rtp_tree, tvb, 0, 0, - "Frame has padding, but not all the frame data was captured"); - call_dissector(data_handle, - tvb_new_subset(tvb, offset, -1, -1), - pinfo, rtp_tree); - return; - } - - padding_count = tvb_get_guint8( tvb, - tvb_reported_length( tvb ) - 1 ); - data_len = - tvb_reported_length_remaining( tvb, offset ) - padding_count; - if (data_len > 0) { - /* - * There's data left over when you take out - * the padding; dissect it. - */ - dissect_rtp_data( tvb, pinfo, tree, rtp_tree, - offset, - data_len, - data_len, - payload_type ); - offset += data_len; - } else if (data_len < 0) { - /* - * The padding count is bigger than the - * amount of RTP payload in the packet! - * Clip the padding count. - * - * XXX - put an item in the tree to indicate - * that the padding count is bogus? - */ - padding_count = - tvb_reported_length_remaining(tvb, offset); - } - if (padding_count > 1) { - /* - * There's more than one byte of padding; - * show all but the last byte as padding - * data. - */ - proto_tree_add_item( rtp_tree, hf_rtp_padding_data, - tvb, offset, padding_count - 1, FALSE ); - offset += padding_count - 1; - } + if ( tree ) proto_tree_add_text(rtp_tree, tvb, 0, 0, + "Frame has padding, but not all the frame data was captured"); + call_dissector(data_handle, + tvb_new_subset(tvb, offset, -1, -1), + pinfo, rtp_tree); + return; + } + + padding_count = tvb_get_guint8( tvb, + tvb_reported_length( tvb ) - 1 ); + data_len = + tvb_reported_length_remaining( tvb, offset ) - padding_count; + + rtp_info.info_payload_offset = offset; + rtp_info.info_payload_len = tvb_length_remaining(tvb, offset); + rtp_info.info_padding_count = padding_count; + + if (data_len > 0) { /* - * Show the last byte in the PDU as the padding - * count. + * There's data left over when you take out + * the padding; dissect it. */ - proto_tree_add_item( rtp_tree, hf_rtp_padding_count, - tvb, offset, 1, FALSE ); + dissect_rtp_data( tvb, pinfo, tree, rtp_tree, + offset, + data_len, + data_len, + payload_type ); + offset += data_len; + } else if (data_len < 0) { + /* + * The padding count is bigger than the + * amount of RTP payload in the packet! + * Clip the padding count. + * + * XXX - put an item in the tree to indicate + * that the padding count is bogus? + */ + padding_count = + tvb_reported_length_remaining(tvb, offset); } - else { + if (padding_count > 1) { /* - * No padding. + * There's more than one byte of padding; + * show all but the last byte as padding + * data. */ - dissect_rtp_data( tvb, pinfo, tree, rtp_tree, offset, - tvb_length_remaining( tvb, offset ), - tvb_reported_length_remaining( tvb, offset ), - payload_type ); + if ( tree ) proto_tree_add_item( rtp_tree, hf_rtp_padding_data, + tvb, offset, padding_count - 1, FALSE ); + offset += padding_count - 1; } + /* + * Show the last byte in the PDU as the padding + * count. + */ + if ( tree ) proto_tree_add_item( rtp_tree, hf_rtp_padding_count, + tvb, offset, 1, FALSE ); + } + else { + /* + * No padding. + */ + dissect_rtp_data( tvb, pinfo, tree, rtp_tree, offset, + tvb_length_remaining( tvb, offset ), + tvb_reported_length_remaining( tvb, offset ), + payload_type ); + rtp_info.info_payload_offset = offset; + rtp_info.info_payload_len = tvb_length_remaining(tvb, offset); } tap_queue_packet(rtp_tap, pinfo, &rtp_info); } -------------- next part -------------- --- packet-rtp.h 2003-03-06 21:35:09.000000000 +0100 +++ packet-rtp.h-new 2003-05-15 10:01:07.000000000 +0200 @@ -36,6 +36,8 @@ guint32 info_timestamp; guint32 info_sync_src; guint info_data_len; + guint info_payload_offset; + guint info_payload_len; }; void rtp_add_address ( packet_info *pinfo, const unsigned char* ip_addr, int prt ); -------------- next part -------------- --- tap_rtp.c-1.10 2003-04-23 10:28:32.000000000 +0200 +++ tap_rtp.c 2003-05-15 13:18:27.000000000 +0200 @@ -1,7 +1,7 @@ /* * tap_rtp.c * - * $Id: tap_rtp.c,v 1.10 2003/04/23 08:20:06 guy Exp $ + * $Id: tap_rtp.c,v 1.8 2003/03/11 08:46:26 sahlberg Exp $ * * RTP analysing addition for ethereal * @@ -45,8 +45,7 @@ * data again. * The Save voice button opens the dialog where we can choose the file name, format (not yet) * and direction we want to save. Currently it works only with g711 alaw and ulaw, and if the - * length of captured packets is equal the length of packets on wire and if there are no padding - * bits. + * length of captured packets is equal the length of packets on wire * * To do: * - Support for saving voice in more different formats and with more different codecs: @@ -137,21 +136,49 @@ static GtkWidget *max; static GtkWidget *max_r; -static gboolean copy_file(gchar *, /*gint,*/ gint, void *); - static char f_tempname[100], r_tempname[100]; /* type of error when saving voice in a file didn't succeed */ typedef enum { TAP_RTP_WRONG_CODEC, TAP_RTP_WRONG_LENGTH, - TAP_RTP_PADDING_SET, + TAP_RTP_PADDING_ERROR, TAP_RTP_FILE_OPEN_ERROR, TAP_RTP_NO_DATA } error_type_t; -/* structure that holds the information about the forwarding and reversed connection */ -/* f_* always aplies to the forward direction and r_* to the reversed */ +typedef enum { + FIRST_PACKET, + MARK_SET, + NORMAL_PACKET +} packet_type; + +/* structure that holds the information about the forward and reversed connection */ +struct _info_direction { + gboolean first_packet; + guint16 seq_num; + guint32 timestamp; + guint32 delta_timestamp; + double delay; + double jitter; + double time; + double start_time; + double max_delay; + guint32 max_nr; + guint16 start_seq_nr; + guint16 stop_seq_nr; + guint32 total_nr; + guint32 sequence; + gboolean under; + gint cycles; + FILE *fp; + guint32 count; + error_type_t error_type; + gboolean saved; +}; + +/* structure that holds general information about the connection + * and structures for both directions */ typedef struct _info_stat { gchar source[16]; gchar destination[16]; @@ -163,48 +190,12 @@ gboolean search_ssrc; guint reversed_ip; guint reversed_ip_and_port; - gboolean f_first_packet; - gboolean r_first_packet; - guint16 f_seq_num; - guint16 r_seq_num; - guint32 f_timestamp; - guint32 r_timestamp; - guint32 f_delta_timestamp; - guint32 r_delta_timestamp; - double f_delay; - double r_delay; - double f_jitter; - double r_jitter; - double f_time; - double r_time; - double f_start_time; - double r_start_time; - double f_max_delay; - double r_max_delay; - guint32 f_max_nr; - guint32 r_max_nr; - guint16 f_start_seq_nr; - guint16 r_start_seq_nr; - guint16 f_stop_seq_nr; - guint16 r_stop_seq_nr; - guint32 f_total_nr; - guint32 r_total_nr; - guint32 f_sequence; - guint32 r_sequence; - gint f_cycles; - gint r_cycles; - gboolean f_under; - gboolean r_under; - FILE *f_fp; - FILE *r_fp; - gboolean f_saved; - gboolean r_saved; - error_type_t f_error_type; - error_type_t r_error_type; - guint32 f_count; - guint32 r_count; + struct _info_direction forward; + struct _info_direction reversed; } info_stat; +int do_calculation(gboolean direc, packet_type pkt_type, void *ptrs, void *vpri, void *vpinfo); +static gboolean copy_file(gchar *, /*gint,*/ gint, void *); /* when there is a [re]reading of packet's */ static void @@ -212,41 +203,49 @@ { info_stat *rs=prs; - rs->f_first_packet = TRUE; - rs->r_first_packet = TRUE; - rs->f_max_delay = 0; - rs->r_max_delay = 0; - rs->f_max_nr = 0; - rs->r_max_nr = 0; - rs->f_total_nr = 0; - rs->r_total_nr = 0; - rs->f_sequence = 0; - rs->r_sequence = 0; - rs->f_start_seq_nr = 0; - rs->r_start_seq_nr = 1; /* 1 is ok (for statistics in reversed direction) */ - rs->f_stop_seq_nr = 0; - rs->r_stop_seq_nr = 0; - rs->f_cycles = 0; - rs->r_cycles = 0; - rs->f_under = FALSE; - rs->r_under = FALSE; - rs->f_saved = FALSE; - rs->r_saved = FALSE; - rs->f_start_time = 0; - rs->r_start_time = 0; - rs->f_count = 0; - rs->r_count = 0; + rs->forward.first_packet = TRUE; + rs->reversed.first_packet = TRUE; + rs->forward.max_delay = 0; + rs->reversed.max_delay = 0; + rs->forward.delay = 0; + rs->reversed.delay = 0; + rs->forward.jitter = 0; + rs->reversed.jitter = 0; + rs->forward.timestamp = 0; + rs->reversed.timestamp = 0; + rs->forward.max_nr = 0; + rs->reversed.max_nr = 0; + rs->forward.total_nr = 0; + rs->reversed.total_nr = 0; + rs->forward.sequence = 0; + rs->reversed.sequence = 0; + rs->forward.start_seq_nr = 0; + rs->reversed.start_seq_nr = 1; /* 1 is ok (for statistics in reversed direction) */ + rs->forward.stop_seq_nr = 0; + rs->reversed.stop_seq_nr = 0; + rs->forward.cycles = 0; + rs->reversed.cycles = 0; + rs->forward.under = FALSE; + rs->reversed.under = FALSE; + rs->forward.saved = FALSE; + rs->reversed.saved = FALSE; + rs->forward.start_time = 0; + rs->reversed.start_time = 0; + rs->forward.time = 0; + rs->reversed.time = 0; + rs->forward.count = 0; + rs->reversed.count = 0; /* XXX check for error at fclose? */ - if (rs->f_fp != NULL) - fclose(rs->f_fp); - if (rs->r_fp != NULL) - fclose(rs->r_fp); - rs->f_fp = fopen(f_tempname, "wb"); - if (rs->f_fp == NULL) - rs->f_error_type = TAP_RTP_FILE_OPEN_ERROR; - rs->r_fp = fopen(r_tempname, "wb"); - if (rs->r_fp == NULL) - rs->r_error_type = TAP_RTP_FILE_OPEN_ERROR; + if (rs->forward.fp != NULL) + fclose(rs->forward.fp); + if (rs->reversed.fp != NULL) + fclose(rs->reversed.fp); + rs->forward.fp = fopen(f_tempname, "wb"); + if (rs->forward.fp == NULL) + rs->forward.error_type = TAP_RTP_FILE_OPEN_ERROR; + rs->reversed.fp = fopen(r_tempname, "wb"); + if (rs->reversed.fp == NULL) + rs->reversed.error_type = TAP_RTP_FILE_OPEN_ERROR; return; } @@ -262,24 +261,26 @@ { info_stat *rs=prs; gchar label_max[200]; - guint32 f_expected = (rs->f_stop_seq_nr + rs->f_cycles*65536) - rs->f_start_seq_nr + 1; - guint32 r_expected = (rs->r_stop_seq_nr + rs->r_cycles*65536) - rs->r_start_seq_nr + 1; - gint32 f_lost = f_expected - rs->f_total_nr; - gint32 r_lost = r_expected - rs->r_total_nr; + guint32 f_expected = (rs->forward.stop_seq_nr + rs->forward.cycles*65536) + - rs->forward.start_seq_nr + 1; + guint32 r_expected = (rs->reversed.stop_seq_nr + rs->reversed.cycles*65536) + - rs->reversed.start_seq_nr + 1; + gint32 f_lost = f_expected - rs->forward.total_nr; + gint32 r_lost = r_expected - rs->reversed.total_nr; g_snprintf(label_max, 199, "Max delay = %f sec at packet nr. %u \n\n" "Total RTP packets = %u (expected %u) Lost RTP packets = %d" " Sequence error = %u", - rs->f_max_delay, rs->f_max_nr, rs->f_total_nr, f_expected, - f_lost, rs->f_sequence); + rs->forward.max_delay, rs->forward.max_nr, rs->forward.total_nr, + f_expected, f_lost, rs->forward.sequence); gtk_label_set_text(GTK_LABEL(max), label_max); g_snprintf(label_max, 199, "Max delay = %f sec at packet nr. %u \n\n" "Total RTP packets = %u (expected %u) Lost RTP packets = %d" " Sequence error = %u", - rs->r_max_delay, rs->r_max_nr, rs->r_total_nr, r_expected, - r_lost, rs->r_sequence); + rs->reversed.max_delay, rs->reversed.max_nr, rs->reversed.total_nr, + r_expected, r_lost, rs->reversed.sequence); gtk_label_set_text(GTK_LABEL(max_r), label_max); @@ -287,7 +288,7 @@ /* if this is true, then we don't have any reversed connection, so the error type * will be no data. This applies only the reversed connection */ if (rs->reversed_ip_and_port == 0) - rs->r_error_type = TAP_RTP_NO_DATA; + rs->reversed.error_type = TAP_RTP_NO_DATA; return ; } @@ -327,25 +328,15 @@ * if yes, do we already have this SSRC stored * if not store it * 3) if not, is current packet matching the forward direction - * is it the first time we see a packet in this direction - * if yes, store some values, add a line to list and save the voice info - * in a temporary file if the codec is supported and the RTP data is ok - * if not, is it a packet with mark bit set (there was silence surpression) - * same as above, only we have to add some silence in front of the voice data - * if not, then this must be a normal packet - * store the values and voice data + * if yes, call the function that does the calculation and saves the voice info * 4) if not, is current packet matching the reversed connection - * (same as for number 3) + * if yes, call the function that does the calculation and saves the voice info */ static int rtp_packet(void *prs, packet_info *pinfo, epan_dissect_t *edt _U_, void *vpri) { info_stat *rs=prs; struct _rtp_info *pri=vpri; guint i; - double n_time; - double n_jitter; - guint8 *data; - gint16 tmp; /* we ignore packets that are not displayed */ if (pinfo->fd->flags.passed_dfilter == 0) @@ -391,603 +382,213 @@ } /* ok, we are not looking for SSRC of the reversed connection */ - /* is it the forward direction? - * if yes, there 3 possibilities: - * a) is this the first packet we got in this direction? - * b) or is it a packet with the mark bit set? - * c) if neither then it is a "normal" packet */ - else if (rs->ssrc_forward == pri->info_sync_src) { - /* first packet? */ - if (rs->f_first_packet != FALSE) { - /* we store all the values */ - rs->f_seq_num = pri->info_seq_num; - rs->f_delay = 0; - rs->f_jitter = 0; - rs->f_first_packet = FALSE; - rs->f_timestamp = pri->info_timestamp; - rs->f_start_seq_nr = pri->info_seq_num; - rs->f_stop_seq_nr = pri->info_seq_num; - rs->f_total_nr++; - rs->f_time = (double)pinfo->fd->rel_secs + - (double) pinfo->fd->rel_usecs/1000000; - rs->f_start_time = rs->f_time; - /* and add a row to clist; delay and jitter are 0 for the first packet */ - add_to_clist(TRUE, pinfo->fd->num, pri->info_seq_num, 0, 0, TRUE, FALSE); - - /* and now save the voice info */ - - /* if we couldn't open the tmp file for writing, then we set the flag */ - if (rs->f_fp == NULL) { - rs->f_saved = FALSE; - rs->f_error_type = TAP_RTP_FILE_OPEN_ERROR; - return 0; - } - /* if the captured length and packet length aren't equal, we quit - * because there is some information missing */ - if (pinfo->fd->pkt_len != pinfo->fd->cap_len) { - rs->f_saved = FALSE; - rs->f_error_type = TAP_RTP_WRONG_LENGTH; - return 0; - } - /* if padding bit is set, we don't do it yet */ - if (pri->info_padding_set != FALSE) { - rs->f_saved = FALSE; - rs->f_error_type = TAP_RTP_PADDING_SET; - return 0; - } - /* is it the ulaw? */ - if (pri->info_payload_type == 0) { - /* we put the pointer at the beggining of the RTP data, that is - * at the end of the current frame minus the length of the - * RTP field plus 12 for the RTP header */ - data = cfile.pd + (pinfo->fd->pkt_len - pri->info_data_len + 12); - for(i=0; i < (pri->info_data_len-12 ); i++, data++) { - tmp = (gint16 )ulaw2linear((unsigned char)*data); - fwrite(&tmp, 2, 1, rs->f_fp); - rs->f_count++; - } - rs->f_saved = TRUE; - return 0; - } - /* alaw? */ - else if (pri->info_payload_type == 8) { - data = cfile.pd + (pinfo->fd->pkt_len - pri->info_data_len + 12); - for(i=0; i < (pri->info_data_len -12 ); i++, data++) { - tmp = (gint16 )alaw2linear((unsigned char)*data); - fwrite(&tmp, 2, 1, rs->f_fp); - rs->f_count++; - } - rs->f_saved = TRUE; - return 0; - } - /* unsupported codec or other error */ - else { - rs->f_saved = FALSE; - rs->f_error_type = TAP_RTP_WRONG_CODEC; - return 0; - } - } - - /* packet with mark bit set? */ - if (pri->info_marker_set != FALSE) { - n_time = (double)pinfo->fd->rel_secs + - (double) pinfo->fd->rel_usecs/1000000; - /* jitter is calculated as for RCTP - RFC 1889 - * J = J + ( | D(i-1, i) | - J) / 16 - * XXX the output there should be in timestamp (probably miliseconds) - * units expressed as an unsigned integer, so should we do it the same? - * (currently we use seconds) - * - * XXX Packet loss in RTCP is calculated as the difference between the - * number of packets expected and actually received, where for actually - * received the number is simply the count of packets as they arrive, - * including any late or duplicate packets (this means that the number - * can be negative). For example, if the seq numbers of the arrived - * packets are: 1,2,3,4,5,5,7,7,9,10 the expected number is 10 and the - * the number of actually captured frames is also 10. So in upper - * calculation there would be no losses. But there are 2 losses and - * 2 duplicate packets. Because this kind of statistic is rather - * useless (or confusing) we add the information, that there was - * an error with sequence number each time the sequence number was - * not one bigger than the previous one - */ - - /* jitter calculation */ - n_jitter = rs->f_jitter + ( fabs(n_time-(rs->f_time) - - ((double)(pri->info_timestamp)- - (double)(rs->f_timestamp))/8000) - rs->f_jitter)/16; - - /* we add the information into the clist */ - add_to_clist(TRUE, pinfo->fd->num, pri->info_seq_num, n_time-(rs->f_time), - n_jitter, rs->f_seq_num+1 == pri->info_seq_num?TRUE:FALSE, TRUE); - - /* when calculating expected rtp packets the seq number can wrap around - * so we have to count the number of cycles - * f_cycles counts the wraps around in forwarding connection and - * f_under is flag that indicates where we are - * - * XXX how to determine number of cycles with all possible lost, late - * and duplicated packets without any doubt? It seems to me, that - * because of all possible combination of late, duplicated or lost - * packets, this can only be more or less good approximation - * - * There are some combinations (rare but theoretically possible), - * where below code won't work correctly - statistic may be wrong then. - */ - - /* so if the current sequence number is less than the start one - * we assume, that there is another cycle running */ - if ((pri->info_seq_num < rs->f_start_seq_nr) && (rs->f_under == FALSE)){ - rs->f_cycles++; - rs->f_under = TRUE; - } - /* what if the start seq nr was 0. Then the above condition will never - * be true, so we add another condition. XXX The problem would arise if - * if one of the packets with seq nr 0 or 65535 would be lost or late */ - else if ((pri->info_seq_num == 0) && (rs->f_stop_seq_nr == 65535) && - (rs->f_under == FALSE)){ - rs->f_cycles++; - rs->f_under = TRUE; - } - /* the whole round is over, so reset the flag */ - else if ((pri->info_seq_num>rs->f_start_seq_nr)&&(rs->f_under!=FALSE)){ - rs->f_under = FALSE; - } + /* is it the forward direction? */ + else if (rs->ssrc_forward == pri->info_sync_src) { + if (rs->forward.first_packet != FALSE) + /* first argument is the direction TRUE == forward */ + return do_calculation(TRUE, FIRST_PACKET, &rs->forward, pri, pinfo); + else if (pri->info_marker_set != FALSE) + return do_calculation(TRUE, MARK_SET, &rs->forward, pri, pinfo); + else + return do_calculation(TRUE, NORMAL_PACKET, &rs->forward, pri, pinfo); + } + /* is it the reversed direction? */ + else if (rs->ssrc_reversed == pri->info_sync_src) { + if (rs->reversed.first_packet != FALSE) + return do_calculation(FALSE, FIRST_PACKET, &rs->reversed, pri, pinfo); + else if (pri->info_marker_set != FALSE) + return do_calculation(FALSE, MARK_SET, &rs->reversed, pri, pinfo); + else + return do_calculation(FALSE, NORMAL_PACKET, &rs->reversed, pri, pinfo); + } - /* number of times where sequence number was not ok */ - if ( rs->f_seq_num+1 == pri->info_seq_num) - rs->f_seq_num = pri->info_seq_num; - /* XXX same problem as above */ - else if ( (rs->f_seq_num == 65535) && (pri->info_seq_num == 0) ) - rs->f_seq_num = pri->info_seq_num; - /* lost packets */ - else if (rs->f_seq_num+1 < pri->info_seq_num) { - rs->f_seq_num = pri->info_seq_num; - rs->f_sequence++; - } - /* late or duplicated */ - else if (rs->f_seq_num+1 > pri->info_seq_num) - rs->f_sequence++; - - rs->f_stop_seq_nr = pri->info_seq_num; - rs->f_time = n_time; - rs->f_jitter = n_jitter; - rs->f_delta_timestamp = pri->info_timestamp - rs->f_timestamp; - rs->f_timestamp = pri->info_timestamp; - rs->f_total_nr++; - - /* save the voice information */ - /* if there was already an error, we quit */ - if (rs->f_saved == FALSE) - return 0; - /* if the captured length and packet length aren't equal, we quit */ - if (pinfo->fd->pkt_len != pinfo->fd->cap_len) { - rs->f_saved = FALSE; - rs->f_error_type = TAP_RTP_WRONG_LENGTH; - return 0; - } - /* if padding bit is set, we don't do it yet */ - if (pri->info_padding_set != FALSE) { - rs->f_saved = FALSE; - rs->f_error_type = TAP_RTP_PADDING_SET; - return 0; - } - /* because the mark bit is set, we have to add some silence in front */ - /* is it the ulaw? */ - if (pri->info_payload_type == 0) { - /* we insert some silence */ - /* XXX the amount of silence should be the difference between - * the last timestamp and the current one minus x in the - * I am not sure if x is equal the amount of information - * current packet? */ - for(i=0; i<(rs->f_delta_timestamp-pri->info_data_len+12); i++) { - tmp = (gint16 )ulaw2linear((unsigned char)(0x55)); - fwrite(&tmp, 2, 1, rs->f_fp); - rs->f_count++; - } - data = cfile.pd + (pinfo->fd->pkt_len - pri->info_data_len + 12); - for(i=0; i < (pri->info_data_len-12 ); i++, data++) { - tmp = (gint16 )ulaw2linear((unsigned char)*data); - fwrite(&tmp, 2, 1, rs->f_fp); - rs->f_count++; - } - return 0; - } - /* alaw? */ - else if (pri->info_payload_type == 8) { - for(i=0; i < (rs->f_delta_timestamp-pri->info_data_len+12); i++) { - tmp = (gint16 )ulaw2linear((unsigned char)(0x55)); - fwrite(&tmp, 2, 1, rs->f_fp); - rs->f_count++; - } - data = cfile.pd + (pinfo->fd->pkt_len - pri->info_data_len + 12); - for(i=0; i < (pri->info_data_len -12 ); i++, data++) { - tmp = (gint16 )alaw2linear((unsigned char)*data); - fwrite(&tmp, 2, 1, rs->f_fp); - rs->f_count++; - } - return 0; - } - /* unsupported codec or other error */ - else { - rs->f_saved = FALSE; - rs->f_error_type = TAP_RTP_WRONG_CODEC; - return 0; - } - return 0; - } - - /* normal packet in forward connection */ - n_time = (double)pinfo->fd->rel_secs + - (double) pinfo->fd->rel_usecs/1000000; - n_jitter = rs->f_jitter + ( fabs (n_time-(rs->f_time) - - ((double)(pri->info_timestamp)- - (double)(rs->f_timestamp))/8000) - rs->f_jitter)/16; - rs->f_delay = n_time-(rs->f_time); - /* the delay is bigger than previous max delay, so store the delay and nr */ - if (rs->f_delay > rs->f_max_delay) { - rs->f_max_delay = rs->f_delay; - rs->f_max_nr = pinfo->fd->num; - } - add_to_clist(TRUE, pinfo->fd->num, pri->info_seq_num, n_time-(rs->f_time), - n_jitter, rs->f_seq_num+1 == pri->info_seq_num?TRUE:FALSE, FALSE); + return 0; +} - /* count the cycles */ - if ((pri->info_seq_num < rs->f_start_seq_nr) && (rs->f_under == FALSE)){ - rs->f_cycles++; - rs->f_under = TRUE; - } - else if ((pri->info_seq_num == 0) && (rs->f_stop_seq_nr == 65535) && - (rs->f_under == FALSE)){ - rs->f_cycles++; - rs->f_under = TRUE; - } - /* the whole round is over, so reset the flag */ - else if ((pri->info_seq_num>rs->f_start_seq_nr+1)&&(rs->f_under!=FALSE)){ - rs->f_under = FALSE; - } - /* number of times where sequence number was not ok */ - if ( rs->f_seq_num+1 == pri->info_seq_num) - rs->f_seq_num = pri->info_seq_num; - else if ( (rs->f_seq_num == 65535) && (pri->info_seq_num == 0) ) - rs->f_seq_num = pri->info_seq_num; - /* lost packets */ - else if (rs->f_seq_num+1 < pri->info_seq_num) { - rs->f_seq_num = pri->info_seq_num; - rs->f_sequence++; - } - /* late or duplicated */ - else if (rs->f_seq_num+1 > pri->info_seq_num) - rs->f_sequence++; - - rs->f_stop_seq_nr = pri->info_seq_num; - rs->f_time = n_time; - rs->f_jitter = n_jitter; - rs->f_timestamp = pri->info_timestamp; - rs->f_total_nr++; - - /* save the voice information */ - /* we do it only in following cases: - * - the codecs we support are g.711 alaw in ulaw - * - the captured length must equal the packet length - * - XXX we don't support it if there are padding bits - */ - /* if there was already an error, we quit */ - if (rs->f_saved == FALSE) - return 0; - /* if the captured length and packet length aren't equal, we quit */ - if (pinfo->fd->pkt_len != pinfo->fd->cap_len) { - rs->f_saved = FALSE; - rs->f_error_type = TAP_RTP_WRONG_LENGTH; - return 0; - } - /* if padding bit is set, we don't do it yet */ - if (pri->info_padding_set != FALSE) { - rs->f_saved = FALSE; - rs->f_error_type = TAP_RTP_PADDING_SET; - return 0; - } - /* is it the ulaw? */ - if (pri->info_payload_type == 0) { - /* cfile.pd points at the beggining of the actual packet. We have - * to move this pointer at the RTP data. This is the packet length, - * minus whole RTP data length (including the RTP header, that is - * why we add 12) */ - data = cfile.pd + (pinfo->fd->pkt_len - pri->info_data_len + 12); - for(i=0; i < (pri->info_data_len - 12); i++, data++) { - tmp = (gint16 )ulaw2linear((unsigned char)*data); - fwrite(&tmp, 2, 1, rs->f_fp); - rs->f_count++; - } - return 0; - } - /* alaw? */ - else if (pri->info_payload_type == 8) { - data = cfile.pd + (pinfo->fd->pkt_len - pri->info_data_len + 12); - for(i=0; i < (pri->info_data_len-12 ); i++, data++) { - tmp = (gint16 )alaw2linear((unsigned char)*data); - fwrite(&tmp, 2, 1, rs->f_fp); - rs->f_count++; - } - return 0; - } - /* unsupported codec or other error */ - else { - rs->f_saved = FALSE; - rs->f_error_type = TAP_RTP_WRONG_CODEC; - return 0; - } - } +int do_calculation(gboolean direc, packet_type pkt_type, void *ptrs, void *vpri, void *vpinfo) { - /* is it the reversed direction? */ - else if (rs->ssrc_reversed == pri->info_sync_src) { - /* first packet? */ - if (rs->r_first_packet !=FALSE) { - rs->r_seq_num = pri->info_seq_num; - rs->r_delay = 0; - rs->r_jitter = 0; - rs->r_first_packet = FALSE; - rs->r_timestamp = pri->info_timestamp; - rs->r_start_seq_nr = pri->info_seq_num; - rs->r_stop_seq_nr = pri->info_seq_num; - rs->r_total_nr++; - rs->r_time = (double)pinfo->fd->rel_secs + - (double) pinfo->fd->rel_usecs/1000000; - rs->r_start_time = rs->r_time; - add_to_clist(FALSE, pinfo->fd->num, pri->info_seq_num, 0, 0, TRUE, FALSE); - - /* save it */ - /* if we couldn't open the tmp file for writing, then we set the flag */ - if (rs->r_fp == NULL) { - rs->r_saved = FALSE; - return 0; - } - /* if the captured length and packet length aren't equal, we quit */ - if (pinfo->fd->pkt_len != pinfo->fd->cap_len) { - rs->r_saved = FALSE; - rs->r_error_type = TAP_RTP_WRONG_LENGTH; - return 0; - } - /* if padding bit is set, we don't do it yet */ - if (pri->info_padding_set != FALSE) { - rs->r_saved = FALSE; - rs->r_error_type = TAP_RTP_PADDING_SET; - return 0; - } - /* is it the ulaw? */ - if (pri->info_payload_type == 0) { - data = cfile.pd + (pinfo->fd->pkt_len - pri->info_data_len + 12); - for(i=0; i < (pri->info_data_len-12 ); i++, data++) { - tmp = (gint16 )ulaw2linear((unsigned char)*data); - fwrite(&tmp, 2, 1, rs->r_fp); - rs->r_count++; - } - rs->r_saved = TRUE; - return 0; - } - /* alaw? */ - else if (pri->info_payload_type == 8) { - data = cfile.pd + (pinfo->fd->pkt_len - pri->info_data_len + 12); - for(i=0; i < (pri->info_data_len -12 ); i++, data++) { - tmp = (gint16 )alaw2linear((unsigned char)*data); - fwrite(&tmp, 2, 1, rs->r_fp); - rs->r_count++; - } - rs->r_saved = TRUE; - return 0; - } - /* unsupported codec or other error */ - else { - rs->r_saved = FALSE; - rs->r_error_type = TAP_RTP_WRONG_CODEC; - return 0; - } - } - - /* packet with mark bit set? */ - if (pri->info_marker_set != FALSE) { - n_time = (double)pinfo->fd->rel_secs + - (double) pinfo->fd->rel_usecs/1000000; - n_jitter = rs->r_jitter + ( fabs (n_time-(rs->r_time) - - ((double)(pri->info_timestamp)- - (double)(rs->r_timestamp))/8000) - rs->r_jitter)/16; - add_to_clist(FALSE, pinfo->fd->num, pri->info_seq_num, n_time-(rs->r_time), - n_jitter, rs->r_seq_num+1 == pri->info_seq_num?TRUE:FALSE, TRUE); - - /* count the cycles */ - if ((pri->info_seq_num < rs->r_start_seq_nr) && (rs->r_under == FALSE)){ - rs->r_cycles++; - rs->r_under = TRUE; - } - else if ((pri->info_seq_num == 0) && (rs->r_stop_seq_nr == 65535) && - (rs->r_under == FALSE)){ - rs->r_cycles++; - rs->r_under = TRUE; - } - /* the whole round is over, so reset the flag */ - else if ((pri->info_seq_num>rs->r_start_seq_nr+1)&&(rs->r_under!=FALSE)){ - rs->r_under = FALSE; - } + struct _info_direction *ptr=ptrs; + struct _rtp_info *pri=vpri; + packet_info *pinfo = vpinfo; + guint i; + double current_time; + double current_jitter; + guint8 *data; + gint16 tmp; - /* number of times where sequence number was not ok */ - if ( rs->r_seq_num+1 == pri->info_seq_num) - rs->r_seq_num = pri->info_seq_num; - else if ( (rs->r_seq_num == 65535) && (pri->info_seq_num == 0) ) - rs->r_seq_num = pri->info_seq_num; - /* lost packets */ - else if (rs->r_seq_num+1 < pri->info_seq_num) { - rs->r_seq_num = pri->info_seq_num; - rs->r_sequence++; - } - /* late or duplicated */ - else if (rs->r_seq_num+1 > pri->info_seq_num) - rs->r_sequence++; - - rs->r_stop_seq_nr = pri->info_seq_num; - rs->r_time = n_time; - rs->r_jitter = n_jitter; - rs->r_delta_timestamp = pri->info_timestamp - rs->r_timestamp; - rs->r_timestamp = pri->info_timestamp; - rs->r_total_nr++; - - /* save the voice information */ - /* if there was already an error, we quit */ - if (rs->r_saved == FALSE) - return 0; - /* if the captured length and packet length aren't equal, we quit */ - if (pinfo->fd->pkt_len != pinfo->fd->cap_len) { - rs->r_saved = FALSE; - rs->r_error_type = TAP_RTP_WRONG_LENGTH; - return 0; - } - /* if padding bit is set, we don't do it yet */ - if (pri->info_padding_set != FALSE) { - rs->r_saved = FALSE; - rs->r_error_type = TAP_RTP_PADDING_SET; - return 0; - } - /* because the mark bit is set, we have to add some silence in front */ - /* is it the ulaw? */ - if (pri->info_payload_type == 0) { - /* we insert some silence */ - for(i=0; i<(rs->r_delta_timestamp-pri->info_data_len+12); i++) { - tmp = (gint16 )ulaw2linear((unsigned char)(0x55)); - fwrite(&tmp, 2, 1, rs->r_fp); - rs->r_count++; - } - data = cfile.pd + (pinfo->fd->pkt_len - pri->info_data_len + 12); - for(i=0; i < (pri->info_data_len-12 ); i++, data++) { - tmp = (gint16 )ulaw2linear((unsigned char)*data); - fwrite(&tmp, 2, 1, rs->r_fp); - rs->r_count++; - } - return 0; - } - /* alaw? */ - else if (pri->info_payload_type == 8) { - for(i=0; i < (rs->r_delta_timestamp-pri->info_data_len+12); i++) { - tmp = (gint16 )ulaw2linear((unsigned char)(0x55)); - fwrite(&tmp, 2, 1, rs->r_fp); - rs->r_count++; - } - data = cfile.pd + (pinfo->fd->pkt_len - pri->info_data_len + 12); - for(i=0; i < (pri->info_data_len -12 ); i++, data++) { - tmp = (gint16 )alaw2linear((unsigned char)*data); - fwrite(&tmp, 2, 1, rs->r_fp); - rs->r_count++; - } - return 0; - } - /* unsupported codec or other error */ - else { - rs->r_saved = FALSE; - rs->r_error_type = TAP_RTP_WRONG_CODEC; - return 0; - } - return 0; - } - - /* normal packet in reversed connection */ - n_time = (double)pinfo->fd->rel_secs + - (double) pinfo->fd->rel_usecs/1000000; - n_jitter = rs->r_jitter + ( fabs (n_time-(rs->r_time) - - ((double)(pri->info_timestamp)- - (double)(rs->r_timestamp))/8000) - rs->r_jitter)/16; - rs->r_delay = n_time-(rs->r_time); - if (rs->r_delay > rs->r_max_delay) { - rs->r_max_delay = rs->r_delay; - rs->r_max_nr = pinfo->fd->num; - } - add_to_clist(FALSE, pinfo->fd->num, pri->info_seq_num, n_time-(rs->r_time), - n_jitter, rs->r_seq_num+1 == pri->info_seq_num?TRUE:FALSE, FALSE); - /* count the cycles */ - if ((pri->info_seq_num < rs->r_start_seq_nr) && (rs->r_under == FALSE)){ - rs->r_cycles++; - rs->r_under = TRUE; - } - else if ((pri->info_seq_num == 0) && (rs->r_stop_seq_nr == 65535) && - (rs->r_under == FALSE)){ - rs->r_cycles++; - rs->r_under = TRUE; - } - /* the whole round is over, so reset the flag */ - else if ((pri->info_seq_num>rs->r_start_seq_nr+1)&&(rs->r_under!=FALSE)){ - rs->r_under = FALSE; + /* store the current time and calculate the current jitter */ + current_time = (double)pinfo->fd->rel_secs + (double) pinfo->fd->rel_usecs/1000000; + current_jitter = ptr->jitter + ( fabs (current_time - (ptr->time) - + ((double)(pri->info_timestamp)-(double)(ptr->timestamp))/8000)- ptr->jitter)/16; + ptr->delay = current_time-(ptr->time); + + /* We have 3 possibilities: + * is this the first packet we got in this direction? */ + if (pkt_type == FIRST_PACKET) { + ptr->first_packet = FALSE; + ptr->start_seq_nr = pri->info_seq_num; + ptr->start_time = current_time; + add_to_clist(direc, pinfo->fd->num, pri->info_seq_num, 0, + pri->info_marker_set? TRUE: FALSE, TRUE, FALSE); + if (ptr->fp == NULL) { + ptr->saved = FALSE; + ptr->error_type = TAP_RTP_FILE_OPEN_ERROR; + } + else + ptr->saved = TRUE; + } + /* or is it a packet with the mark bit set? */ + else if (pkt_type == MARK_SET) { + ptr->delta_timestamp = pri->info_timestamp - ptr->timestamp; + add_to_clist(direc, pinfo->fd->num, pri->info_seq_num, current_time - (ptr->time), + current_jitter, ptr->seq_num+1 == pri->info_seq_num? TRUE: FALSE, TRUE); + } + /* if neither then it is a "normal" packet pkt_type == NORMAL_PACKET */ + else { + if (ptr->delay > ptr->max_delay) { + ptr->max_delay = ptr->delay; + ptr->max_nr = pinfo->fd->num; } + add_to_clist(direc, pinfo->fd->num, pri->info_seq_num, current_time -(ptr->time), + current_jitter , ptr->seq_num+1 == pri->info_seq_num?TRUE:FALSE, FALSE); + } - /* number of times where sequence number was not ok */ - if ( rs->r_seq_num+1 == pri->info_seq_num) - rs->r_seq_num = pri->info_seq_num; - else if ( (rs->r_seq_num == 65535) && (pri->info_seq_num == 0) ) - rs->r_seq_num = pri->info_seq_num; - /* lost packets */ - else if (rs->r_seq_num+1 < pri->info_seq_num) { - rs->r_seq_num = pri->info_seq_num; - rs->r_sequence++; - } - /* late or duplicated */ - else if (rs->r_seq_num+1 > pri->info_seq_num) - rs->r_sequence++; - - rs->r_stop_seq_nr = pri->info_seq_num; - rs->r_time = n_time; - rs->r_jitter = n_jitter; - rs->r_timestamp = pri->info_timestamp; - rs->r_total_nr++; - - /* save the voice information */ - /* if there was already an error, we quit */ - if (rs->r_saved == FALSE) - return 0; - /* if the captured length and packet length aren't equal, we quit */ - if (pinfo->fd->pkt_len != pinfo->fd->cap_len) { - rs->r_saved = FALSE; - rs->r_error_type = TAP_RTP_WRONG_LENGTH; - return 0; - } - /* if padding bit is set, we don't do it yet */ - if (pri->info_padding_set != FALSE) { - rs->r_saved = FALSE; - rs->r_error_type = TAP_RTP_PADDING_SET; - return 0; - } - /* is it the ulaw? */ - if (pri->info_payload_type == 0) { - data = cfile.pd + (pinfo->fd->pkt_len - pri->info_data_len + 12); - for(i=0; i < (pri->info_data_len-12 ); i++, data++) { - tmp = (gint16 )ulaw2linear((unsigned char)*data); - fwrite(&tmp, 2, 1, rs->r_fp); - rs->r_count++; - } - 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 + * under is flag that indicates where we are + * + * XXX how to determine number of cycles with all possible lost, late + * and duplicated packets without any doubt? It seems to me, that + * because of all possible combination of late, duplicated or lost + * packets, this can only be more or less good approximation + * + * There are some combinations (rare but theoretically possible), + * where below code won't work correctly - statistic may be wrong then. + */ + + /* so if the current sequence number is less than the start one + * we assume, that there is another cycle running */ + if ((pri->info_seq_num < ptr->start_seq_nr) && (ptr->under == FALSE)){ + ptr->cycles++; + ptr->under = TRUE; + } + /* what if the start seq nr was 0? Then the above condition will never + * be true, so we add another condition. XXX The problem would arise + * if one of the packets with seq nr 0 or 65535 would be lost or late */ + else if ((pri->info_seq_num == 0) && (ptr->stop_seq_nr == 65535) && + (ptr->under == FALSE)){ + ptr->cycles++; + ptr->under = TRUE; + } + /* the whole round is over, so reset the flag */ + else if ((pri->info_seq_num > ptr->start_seq_nr) && (ptr->under != FALSE)) { + ptr->under = FALSE; + } + + /* Since it is difficult to count lost, duplicate or late packets separately, + * we would like to know at least how many times the sequence number was not ok */ + + /* if the current seq number equals the last one or if we are here for + * the first time, then it is ok, we just store the current one as the last one */ + if ( ( ptr->seq_num+1 == pri->info_seq_num) || (pkt_type == FIRST_PACKET) ) + ptr->seq_num = pri->info_seq_num; + /* if the first one is 65535. XXX same problem as above: if seq 65535 or 0 is lost... */ + else if ( (ptr->seq_num == 65535) && (pri->info_seq_num == 0) ) + ptr->seq_num = pri->info_seq_num; + /* lost packets */ + else if (ptr->seq_num+1 < pri->info_seq_num) { + ptr->seq_num = pri->info_seq_num; + ptr->sequence++; + } + /* late or duplicated */ + else if (ptr->seq_num+1 > pri->info_seq_num) + ptr->sequence++; + + ptr->time = current_time; + ptr->timestamp = pri->info_timestamp; + ptr->stop_seq_nr = pri->info_seq_num; + ptr->total_nr++; + + /* save the voice information */ + /* if there was already an error, we quit */ + if (ptr->saved == FALSE) + return 0; + + /* if the captured length and packet length aren't equal, we quit + * because there is some information missing */ + if (pinfo->fd->pkt_len != pinfo->fd->cap_len) { + ptr->saved = FALSE; + ptr->error_type = TAP_RTP_WRONG_LENGTH; + return 0; + } + + /* if padding bit is set, but the padding count is bigger + * then the whole RTP data - error with padding count */ + if ( (pri->info_padding_set != FALSE) && + (pri->info_padding_count > pri->info_payload_len) ) { + ptr->saved = FALSE; + ptr->error_type = TAP_RTP_PADDING_ERROR; + return 0; + } + + /* do we need to insert some silence? */ + if (pkt_type == MARK_SET) { + /* the amount of silence should be the difference between + * the last timestamp and the current one minus x + * x should equal the amount of information in the last frame + * XXX not done yet */ + for(i=0; i < (ptr->delta_timestamp - pri->info_payload_len - + pri->info_padding_count); i++) { + tmp = (gint16 )ulaw2linear((unsigned char)(0x55)); + fwrite(&tmp, 2, 1, ptr->fp); + ptr->count++; } - /* alaw? */ - else if (pri->info_payload_type == 8) { - data = cfile.pd + (pinfo->fd->pkt_len - pri->info_data_len + 12); - for(i=0; i < (pri->info_data_len -12 ); i++, data++) { - tmp = (gint16 )alaw2linear((unsigned char)*data); - fwrite(&tmp, 2, 1, rs->r_fp); - rs->r_count++; - } - return 0; + fflush(ptr->fp); + } + + /* is it the ulaw? */ + if (pri->info_payload_type == 0) { + /* we put the pointer at the beggining of the RTP data, that is + * at the end of the current frame minus the length of the + * padding count minus length of the RTP data */ + data = cfile.pd + (pinfo->fd->pkt_len - pri->info_payload_len); + for(i=0; i < (pri->info_payload_len - pri->info_padding_count); i++, data++) { + tmp = (gint16 )ulaw2linear((unsigned char)*data); + fwrite(&tmp, 2, 1, ptr->fp); + ptr->count++; } - /* unsupported codec or other error */ - else { - rs->r_saved = FALSE; - rs->r_error_type = TAP_RTP_WRONG_CODEC; - return 0; + fflush(ptr->fp); + ptr->saved = TRUE; + return 0; + } + + /* alaw? */ + else if (pri->info_payload_type == 8) { + data = cfile.pd + (pinfo->fd->pkt_len - pri->info_payload_len); + for(i=0; i < (pri->info_payload_len - pri->info_padding_count); i++, data++) { + tmp = (gint16 )alaw2linear((unsigned char)*data); + fwrite(&tmp, 2, 1, ptr->fp); + ptr->count++; } - } + fflush(ptr->fp); + ptr->saved = TRUE; + return 0; + } - return 0; + /* unsupported codec or XXX other error */ + else { + ptr->saved = FALSE; + ptr->error_type = TAP_RTP_WRONG_CODEC; + return 0; + } } /* XXX just copied from gtk/rpc_stat.c */ void protect_thread_critical_region(void); void unprotect_thread_critical_region(void); - /* here we close the rtp analysis dialog window and remove the tap listener */ static void rtp_destroy_cb(GtkWidget *win _U_, gpointer data _U_) { @@ -1001,10 +602,10 @@ g_free(rs->ssrc_tmp); g_free(rs); - if (rs->f_fp != NULL) - fclose(rs->f_fp); - if (rs->r_fp != NULL) - fclose(rs->r_fp); + if (rs->forward.fp != NULL) + fclose(rs->forward.fp); + if (rs->reversed.fp != NULL) + fclose(rs->reversed.fp); remove(f_tempname); remove(r_tempname); @@ -1132,32 +733,35 @@ */ /* we can not save in both dirctions */ - if ((rs->f_saved == FALSE) && (rs->r_saved == FALSE) && (GTK_TOGGLE_BUTTON (both)->active)) { + if ((rs->forward.saved == FALSE) && (rs->reversed.saved == FALSE) && (GTK_TOGGLE_BUTTON (both)->active)) { /* there are many combinations here, we just exit when first matches */ - if ((rs->f_error_type == TAP_RTP_WRONG_CODEC) || (rs->r_error_type == TAP_RTP_WRONG_CODEC)) + if ((rs->forward.error_type == TAP_RTP_WRONG_CODEC) || + (rs->reversed.error_type == TAP_RTP_WRONG_CODEC)) simple_dialog(ESD_TYPE_CRIT, NULL, - "Can't save in a file: Unsupported codec!"); - else if ((rs->f_error_type == TAP_RTP_WRONG_LENGTH) || (rs->r_error_type == TAP_RTP_WRONG_LENGTH)) + "Can't save in a file: Unsupported codec!"); + else if ((rs->forward.error_type == TAP_RTP_WRONG_LENGTH) || + (rs->reversed.error_type == TAP_RTP_WRONG_LENGTH)) simple_dialog(ESD_TYPE_CRIT, NULL, - "Can't save in a file: Wrong length of captured packets!"); - else if ((rs->f_error_type == TAP_RTP_PADDING_SET) || (rs->r_error_type == TAP_RTP_PADDING_SET)) + "Can't save in a file: Wrong length of captured packets!"); + else if ((rs->forward.error_type == TAP_RTP_PADDING_ERROR) || + (rs->reversed.error_type == TAP_RTP_PADDING_ERROR)) simple_dialog(ESD_TYPE_CRIT, NULL, - "Can't save in a file: RTP data with padding!"); + "Can't save in a file: RTP data with padding!"); else simple_dialog(ESD_TYPE_CRIT, NULL, - "Can't save in a file: File I/O problem!"); + "Can't save in a file: File I/O problem!"); return; } /* we can not save forward direction */ - else if ((rs->f_saved == FALSE) && ((GTK_TOGGLE_BUTTON (forw)->active) || + else if ((rs->forward.saved == FALSE) && ((GTK_TOGGLE_BUTTON (forw)->active) || (GTK_TOGGLE_BUTTON (both)->active))) { - if (rs->f_error_type == TAP_RTP_WRONG_CODEC) + if (rs->forward.error_type == TAP_RTP_WRONG_CODEC) simple_dialog(ESD_TYPE_CRIT, NULL, "Can't save forward direction in a file: Unsupported codec!"); - else if (rs->f_error_type == TAP_RTP_WRONG_LENGTH) + else if (rs->forward.error_type == TAP_RTP_WRONG_LENGTH) simple_dialog(ESD_TYPE_CRIT, NULL, "Can't save forward direction in a file: Wrong length of captured packets!"); - else if (rs->f_error_type == TAP_RTP_PADDING_SET) + else if (rs->forward.error_type == TAP_RTP_PADDING_ERROR) simple_dialog(ESD_TYPE_CRIT, NULL, "Can't save forward direction in a file: RTP data with padding!"); else @@ -1166,18 +770,18 @@ return; } /* we can not save reversed direction */ - else if ((rs->r_saved == FALSE) && ((GTK_TOGGLE_BUTTON (rev)->active) || + else if ((rs->reversed.saved == FALSE) && ((GTK_TOGGLE_BUTTON (rev)->active) || (GTK_TOGGLE_BUTTON (both)->active))) { - if (rs->r_error_type == TAP_RTP_WRONG_CODEC) + if (rs->reversed.error_type == TAP_RTP_WRONG_CODEC) simple_dialog(ESD_TYPE_CRIT, NULL, "Can't save reversed direction in a file: Unsupported codec!"); - else if (rs->r_error_type == TAP_RTP_WRONG_LENGTH) + else if (rs->reversed.error_type == TAP_RTP_WRONG_LENGTH) simple_dialog(ESD_TYPE_CRIT, NULL, "Can't save reversed direction in a file: Wrong length of captured packets!"); - else if (rs->r_error_type == TAP_RTP_PADDING_SET) + else if (rs->reversed.error_type == TAP_RTP_PADDING_ERROR) simple_dialog(ESD_TYPE_CRIT, NULL, "Can't save reversed direction in a file: RTP data with padding!"); - else if (rs->r_error_type == TAP_RTP_NO_DATA) + else if (rs->reversed.error_type == TAP_RTP_NO_DATA) simple_dialog(ESD_TYPE_CRIT, NULL, "Can't save reversed direction in a file: No RTP data!"); else @@ -1316,12 +920,12 @@ XXX this is not ok since the user can click the refresh button and cause changes but we can not update this window. So we move all the decision on the time the ok button is clicked - if (rs->f_saved == FALSE) { + if (rs->forward.saved == FALSE) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(reversed_rb), TRUE); gtk_widget_set_sensitive(forward_rb, FALSE); gtk_widget_set_sensitive(both_rb, FALSE); } - else if (rs->r_saved == FALSE) { + else if (rs->reversed.saved == FALSE) { gtk_widget_set_sensitive(reversed_rb, FALSE); gtk_widget_set_sensitive(both_rb, FALSE); } @@ -1697,7 +1301,7 @@ /* XXX compiler warning:passing arg 5 of `register_tap_listener' from incompatible pointer type */ error_string = register_tap_listener("rtp", rs, filter_text, rtp_reset, rtp_packet, rtp_draw); if (error_string != NULL) { - simple_dialog(ESD_TYPE_WARN, NULL, error_string->str); + simple_dialog(ESD_TYPE_WARN, NULL, error_string->str); /* XXX is this enough or do I have to free anything else? */ g_string_free(error_string, TRUE); g_free(rs); @@ -1719,8 +1323,8 @@ /* file names for storing sound data */ tmpnam(f_tempname); tmpnam(r_tempname); - rs->f_fp = NULL; - rs->r_fp = NULL; + rs->forward.fp = NULL; + rs->reversed.fp = NULL; redissect_packets(cf); @@ -1743,10 +1347,11 @@ register_ethereal_tap("rtp", rtp_analyse_init); } + void register_tap_menu_gtkrtp(void) { - register_tap_menu_item("RTP Analysis...", rtp_analyse_cb); + register_tap_menu_item("RTP Analysis...", rtp_analyse_cb); } @@ -1819,8 +1424,8 @@ switch (channels) { /* only forward direction */ case 1: { - progbar_count = rs->f_count; - progbar_quantum = rs->f_count/100; + progbar_count = rs->forward.count; + progbar_quantum = rs->forward.count/100; while ((fread = read(forw_fd, &f_pd, 2)) > 0) { if(stop_flag) break; @@ -1844,8 +1449,8 @@ } /* only reversed direction */ case 2: { - progbar_count = rs->r_count; - progbar_quantum = rs->r_count/100; + progbar_count = rs->reversed.count; + progbar_quantum = rs->reversed.count/100; while ((rread = read(rev_fd, &r_pd, 2)) > 0) { if(stop_flag) break; @@ -1869,16 +1474,19 @@ } /* both directions */ default: { - (rs->f_count > rs->r_count) ? (progbar_count = rs->f_count) : - (progbar_count = rs->r_count); + (rs->forward.count > rs->reversed.count) ? + (progbar_count = rs->forward.count) : + (progbar_count = rs->reversed.count); progbar_quantum = progbar_count/100; /* since conversation in one way can start later than in the other one, * we have to write some silence information for one channel */ - if (rs->f_start_time > rs->r_start_time) { - f_write_silence = (rs->f_start_time-rs->r_start_time)*8000; - } - else if (rs->f_start_time < rs->r_start_time) { - r_write_silence = (rs->r_start_time-rs->f_start_time)*8000; + if (rs->forward.start_time > rs->reversed.start_time) { + f_write_silence = + (rs->forward.start_time-rs->reversed.start_time)*8000; + } + else if (rs->forward.start_time < rs->reversed.start_time) { + r_write_silence = + (rs->reversed.start_time-rs->forward.start_time)*8000; } for(;;) { if(stop_flag) -------------- next part -------------- A non-text attachment was scrubbed... Name: rtp_options.raw Type: application/octet-stream Size: 34924 bytes Desc: not available Url : /pipermail/attachments/20030515/dfc8bf49/rtp_options.obj ------------------------------ _______________________________________________ Ethereal-dev mailing list Ethereal-dev@xxxxxxxxxxxx http://www.ethereal.com/mailman/listinfo/ethereal-dev End of Ethereal-dev Digest, Vol 1, Issue 1614 *********************************************
- Prev by Date: [Ethereal-dev] RTP analysis
- Next by Date: [Ethereal-dev] Ethereal With Visual C++6.0 Project
- Previous by thread: [Ethereal-dev] RTP analysis
- Next by thread: [Ethereal-dev] Ethereal With Visual C++6.0 Project
- Index(es):