Ethereal-dev: Re: [Ethereal-dev] Display filter as stop condition

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

Date: Tue, 28 Oct 2003 08:27:46 -0800 (PST)
New and improved!  Now with scrubbing bubbles!

Still only for tethereal.

Usage:
  tethereal -a "rfilter:STOP-RD-FILTER"

Files modified:
  cfile.c cfile.h file.c tethereal.c
  doc/tethereal.pod.template doc/tethereal.pod

If somebody could implement -a "cfilter:STOP-CAP-FILTER", I would be
eternally grateful.  I going to try to find the memory leak when doing
read filters.

Still curious if anybody has an idea of why it drops packets WITHOUT
DETECTING IT when name resolution is used during capture.

"diff -u" output (with ".." containing modified files):

--- cfile.c	Fri Sep  6 18:14:04 2002
+++ ../cfile.c	Fri Oct 24 12:38:02 2003
@@ -50,6 +50,7 @@
   cf->user_saved	= FALSE;
   cf->is_tempfile	= FALSE;
   cf->rfcode		= NULL;
+  cf->hfcode		= NULL;
   cf->dfilter		= NULL;
   cf->dfcode		= NULL;
 #ifdef HAVE_LIBPCAP

-------------------------------------------------------------------------------

--- cfile.h	Thu Sep  4 21:09:35 2003
+++ ../cfile.h	Fri Oct 24 12:38:02 2003
@@ -66,6 +66,7 @@
   int          save_file_fd; /* File descriptor for saved file */
   wtap        *wth;       /* Wiretap session */
   dfilter_t   *rfcode;    /* Compiled read filter program */
+  dfilter_t   *hfcode;    /* Compiled halt filter program */
   gchar       *dfilter;   /* Display filter string */
   dfilter_t   *dfcode;    /* Compiled display filter program */
 #ifdef HAVE_LIBPCAP

-------------------------------------------------------------------------------

--- file.c	Mon Sep  8 20:22:22 2003
+++ ../file.c	Fri Oct 24 12:38:02 2003
@@ -256,6 +256,10 @@
     dfilter_free(cf->rfcode);
     cf->rfcode = NULL;
   }
+  if (cf->hfcode != NULL) {
+    dfilter_free(cf->hfcode);
+    cf->hfcode = NULL;
+  }
   cf->plist = NULL;
   cf->plist_end = NULL;
   unselect_packet(cf);	/* nothing to select */

-------------------------------------------------------------------------------

--- tethereal.c	Sun Sep  7 22:11:33 2003
+++ ../tethereal.c	Mon Oct 27 11:34:11 2003
@@ -190,6 +190,8 @@
 	gboolean has_autostop_filesize;	/* TRUE if maximum capture file size
 					   is specified */
 	gint32 autostop_filesize;	/* Maximum capture file size */
+	gboolean has_autostop_rfilter;	/* TRUE if halt rfilter is specified */
+	gchar *autostop_rfilter;        /* halt filter string */
 	gboolean ringbuffer_on;		/* TRUE if ring buffer in use */
 	guint32 ringbuffer_num_files;	/* Number of ring buffer files */
 	gboolean has_ring_duration;	/* TRUE if ring duration specified */
@@ -208,6 +210,9 @@
 	FALSE,				/* maximum capture file size not
 					   specified by default */
 	0,				/* maximum capture file size */
+	FALSE,				/* halt filter not specified by
+					   default */
+	NULL,				/* halt filter string */
 	FALSE,				/* ring buffer off by default */
 	RINGBUFFER_MIN_NUM_FILES,	/* default number of ring buffer
 					   files */
@@ -337,6 +342,9 @@
   } else if (strcmp(autostoparg,"filesize") == 0) {
     capture_opts.has_autostop_filesize = TRUE;
     capture_opts.autostop_filesize = get_positive_int(p,"autostop filesize");
+  } else if (strcmp(autostoparg,"rfilter") == 0) {
+    capture_opts.has_autostop_rfilter = TRUE;
+    capture_opts.autostop_rfilter = strdup(p);
   } else {
     return FALSE;
   }
@@ -794,6 +802,7 @@
   gchar               *if_text;
 #endif
   dfilter_t           *rfcode = NULL;
+  dfilter_t           *hfcode = NULL;
   e_prefs             *prefs;
   char                 badopt;
   ethereal_tap_list *tli;
@@ -1141,12 +1150,12 @@
                runtime_info_str->str);
         exit(0);
         break;
-      case 'w':        /* Write to capture file xxx */
-        cfile.save_file = g_strdup(optarg);
-	break;
       case 'V':        /* Verbose */
         verbose = TRUE;
         break;
+      case 'w':        /* Write to capture file xxx */
+        cfile.save_file = g_strdup(optarg);
+	break;
       case 'x':        /* Print packet data in hex (and ASCII) */
         print_hex = TRUE;
         break;
@@ -1335,12 +1344,21 @@
 
   if (rfilter != NULL) {
     if (!dfilter_compile(rfilter, &rfcode)) {
-      fprintf(stderr, "tethereal: %s\n", dfilter_error_msg);
+      fprintf(stderr, "tethereal: display filter: %s\n", dfilter_error_msg);
       epan_cleanup();
       exit(2);
     }
   }
   cfile.rfcode = rfcode;
+  if (capture_opts.has_autostop_rfilter) {
+    if (!dfilter_compile(capture_opts.autostop_rfilter, &hfcode)) {
+      fprintf(stderr, "tethereal: halt filter: %s\n", dfilter_error_msg);
+      epan_cleanup();
+      exit(2);
+    }
+  }
+  cfile.hfcode = hfcode;
+
   if (cf_name) {
     err = open_cap_file(cf_name, FALSE, &cfile);
     if (err != 0) {
@@ -1626,7 +1644,8 @@
 
   /* initialize capture stop conditions */
   init_capture_stop_conditions();
-  /* create stop conditions */
+  /* create stop conditions (except for halt filter, which is handled
+     in wtap_dispatch_cb_write()) */
   if (capture_opts.has_autostop_filesize)
     cnd_stop_capturesize = cnd_new((const char*)CND_CLASS_CAPTURESIZE,
                                    (long)capture_opts.autostop_filesize * 1000);
@@ -1671,6 +1690,8 @@
     int loop_err = 0;
     int packet_count_prev = 0;
 
+    /* Most stop conditions are checked here.  But the halt filter is
+       handled in wtap_dispatch_cb_write().  See "hfcode". */
     if (cnd_stop_capturesize == NULL && cnd_stop_timeout == NULL) {
       /* We're not stopping at a particular capture file size, and we're
          not stopping after some particular amount of time has expired,
@@ -2175,10 +2196,11 @@
   cb_args_t    *args = (cb_args_t *) user;
   capture_file *cf = args->cf;
   wtap_dumper  *pdh = args->pdh;
-  frame_data    fdata;
+  frame_data    fdata, hfdata;
   int           err;
   gboolean      passed;
   epan_dissect_t *edt;
+  epan_dissect_t *hedt;
 
 #ifdef HAVE_LIBPCAP
 #ifdef SIGINFO
@@ -2192,6 +2214,18 @@
 #endif /* HAVE_LIBPCAP */
 
   cf->count++;
+  /* check halt condition */
+  if (cf->hfcode) {
+    fill_in_fdata(&hfdata, cf, phdr, offset);
+    hedt = epan_dissect_new(TRUE, FALSE);
+    epan_dissect_prime_dfilter(hedt, cf->hfcode);
+    epan_dissect_run(hedt, pseudo_header, buf, &hfdata, NULL);
+    if (dfilter_apply_edt(cf->hfcode, hedt)) {
+      ld.go = FALSE;
+    }
+  } else {
+    hedt = NULL;
+  }
   if (cf->rfcode) {
     fill_in_fdata(&fdata, cf, phdr, offset);
     edt = epan_dissect_new(TRUE, FALSE);
@@ -2224,6 +2258,10 @@
       exit(2);
     }
   }
+  if (hedt != NULL)
+    epan_dissect_free(hedt);
+  if (cf->hfcode)
+    clear_fdata(&hfdata);
   if (edt != NULL)
     epan_dissect_free(edt);
   if (cf->rfcode)

-------------------------------------------------------------------------------

--- doc/tethereal.pod.template	Sat Sep  6 18:22:37 2003
+++ ../doc/tethereal.pod.template	Mon Oct 27 08:32:41 2003
@@ -165,6 +165,11 @@
 Stop writing to a capture file after it reaches a size of I<value>
 kilobytes (where a kilobyte is 1000 bytes, not 1024 bytes).
 
+=item rfilter
+
+Stop writing to a capture file after a packet is received that satisfies
+I<value> (where I<value> is a string with syntax of a "read" filter).
+
 =for man .RE
 
 =for html </DL>

-------------------------------------------------------------------------------

--- doc/tethereal.pod	Thu Oct 23 15:17:21 2003
+++ ../doc/tethereal.pod	Mon Oct 27 09:53:10 2003
@@ -165,6 +165,11 @@
 Stop writing to a capture file after it reaches a size of I<value>
 kilobytes (where a kilobyte is 1000 bytes, not 1024 bytes).
 
+=item rfilter
+
+Stop writing to a capture file after a packet is received that satisfies
+I<value> (where I<value> is a string with syntax of a "read" filter).
+
 =for man .RE
 
 =for html </DL>