Ethereal-dev: [Ethereal-dev] [patch] tethereal and ring timeout

Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.

From: Matthijs Melchior <mmelchior@xxxxxxxxx>
Date: Thu, 25 Sep 2003 00:50:07 +0200
Hi,
   The attached patch makes a change to tethereal in the way it changes
to a next ring buffer.  The old behaviour is to write a packet to the
file, and than test for the switching critera.  For the time criterion
in a situation where there are long time spans of silence this has the
unpleasant effect to write the first packet of a new series of packets
as the last packet of a file.

This patch makes tethereal test for the time criterion just before
writing the packet, so the start of a new activity will cause a file
switch before writing the packet. Thus the whole new sequence of
packets will be in the same file.

The same kind of patch could be made for ethereal [in file capture.c]
but I think this is less nessecary since only tethereal is usefull
to capture packets in background, without a user interface, for a very
long time.

I have also been looking to make the -l switch work with saving to files,
so that the buffer is flushed to disk every second or so. This would
enable me to have tethereal in background looking at the network and
use ethereal to view the most recent history using the tethereal files.
Ethereal would need a mode to start polling its input file fore more
data [and to make it really clever to switch files when the capture
process switches...].

But that is future work, the current patch is useful already.

Please apply.

Thanks.

--
Regards,
----------------------------------------------------------------  -o)
Matthijs Melchior                                       Maarssen  /\\
mmelchior@xxxxxxxxx                                  Netherlands _\_v
---------------------------------------------------------------- ----

--- tethereal.c-ORG	2003-09-08 05:11:33.000000000 +0200
+++ tethereal.c	2003-09-24 23:53:20.000000000 +0200
@@ -1423,6 +1423,9 @@
 #ifdef HAVE_LIBPCAP
 /* Do the low-level work of a capture.
    Returns TRUE if it succeeds, FALSE otherwise. */
+
+static condition  *volatile cnd_ring_timeout = NULL; /* this must be visible in wtap_dispatch_cb_write */
+
 static int
 capture(int out_file_type)
 {
@@ -1440,7 +1443,6 @@
   char        errmsg[1024+1];
   condition  *volatile cnd_stop_capturesize = NULL;
   condition  *volatile cnd_stop_timeout = NULL;
-  condition  *volatile cnd_ring_timeout = NULL;
 #ifndef _WIN32
   static const char ppamsg[] = "can't find PPA for ";
   char       *libpcap_warn;
@@ -1716,15 +1718,6 @@
     } else if (cnd_stop_timeout != NULL && cnd_eval(cnd_stop_timeout)) {
       /* The specified capture time has elapsed; stop the capture. */
       ld.go = FALSE;
-    } else if (cnd_ring_timeout != NULL && cnd_eval(cnd_ring_timeout)) {
-      /* time elasped for this ring file, swith to the next */
-      if (ringbuf_switch_file(&cfile, &ld.pdh, &loop_err)) {
-	/* File switch succeeded: reset the condition */
-	cnd_reset(cnd_ring_timeout);
-      } else {
-	/* File switch failed: stop here */
-	ld.go = FALSE;
-      }
     } else if (inpkts > 0) {
       if (capture_opts.autostop_count != 0 &&
                  ld.packet_count >= capture_opts.autostop_count) {
@@ -2205,7 +2198,25 @@
   if (passed) {
     /* The packet passed the read filter. */
 #ifdef HAVE_LIBPCAP
+    int loop_err;
+
     ld.packet_count++;
+
+    /* The current packet may have arrived after a very long silence,
+     * way past the time to switch files.  In order not to have
+     * the first packet of a new series of events as the last
+     * [or only] packet in the file, switch before writing!
+     */
+    if (cnd_ring_timeout != NULL && cnd_eval(cnd_ring_timeout)) {
+      /* time elasped for this ring file, swith to the next */
+      if (ringbuf_switch_file(&cfile, &ld.pdh, &loop_err)) {
+	/* File switch succeeded: reset the condition */
+	cnd_reset(cnd_ring_timeout);
+      } else {
+	/* File switch failed: stop here */
+	ld.go = FALSE;
+      }
+    }
 #endif
     if (!wtap_dump(pdh, phdr, pseudo_header, buf, &err)) {
 #ifdef HAVE_LIBPCAP