Ethereal-dev: [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: Fri, 24 Oct 2003 12:23:10 -0700 (PDT)
I've added a "Halt" feature to tethereal that uses a display filter as
a stop condition.  It is supplied as a string argument to "-H".  It
can be very useful for troubleshooting to see what led up to a
particular condition (kindof like setting a breakpoint with an
emulator).  Combined with ring buffer, you can just start it, come
back the next morning and have a good snapshot.

I appologize for not adding the same feature to GUI ethereal (I
wouldn't even know how to start), but for my purposes, this is
exactly what the doctor ordered (capturing on a text-only box,
analyzing with a GUI).  I've tested it on Linux (RedHat 8.0) and
Windows (2K).

I'm not familliar with the code (I downloaded and saw it for the first
time this morning), but a few hour's examination led to the following
patch.  Hopefully it is not too much of an abomination.

Steve

--- ethereal-0.9.15/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

--- ethereal-0.9.15/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

--- ethereal-0.9.15/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 */

--- ethereal-0.9.15/tethereal.c	Sun Sep  7 22:11:33 2003
+++ ./tethereal.c	Fri Oct 24 13:03:22 2003
@@ -789,11 +789,12 @@
   gboolean             capture_option_specified = FALSE;
 #endif
   int                  out_file_type = WTAP_FILE_PCAP;
-  gchar               *cf_name = NULL, *rfilter = NULL;
+  gchar               *cf_name = NULL, *rfilter = NULL, *hfilter = NULL;
 #ifdef HAVE_LIBPCAP
   gchar               *if_text;
 #endif
   dfilter_t           *rfcode = NULL;
+  dfilter_t           *hfcode = NULL;
   e_prefs             *prefs;
   char                 badopt;
   ethereal_tap_list *tli;
@@ -899,7 +900,7 @@
   get_runtime_version_info(runtime_info_str);
 
   /* Now get our args */
-  while ((opt = getopt(argc, argv, "a:b:c:d:Df:F:hi:lnN:o:pqr:R:s:St:vw:Vxz:")) != -1) {
+  while ((opt = getopt(argc, argv, "a:b:c:d:Df:F:hH:i:lnN:o:pqr:R:s:St:vw:Vxz:")) != -1) {
     switch (opt) {
       case 'a':        /* autostop criteria */
 #ifdef HAVE_LIBPCAP
@@ -988,6 +989,9 @@
 	print_usage(TRUE);
 	exit(0);
         break;
+      case 'H':        /* Read file filter */
+        hfilter = optarg;
+        break;
       case 'i':        /* Use interface xxx */
 #ifdef HAVE_LIBPCAP
         /*
@@ -1141,12 +1145,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;
@@ -1340,7 +1344,15 @@
       exit(2);
     }
   }
+  if (hfilter != NULL) {
+    if (!dfilter_compile(hfilter, &hfcode)) {
+      fprintf(stderr, "tethereal: %s\n", dfilter_error_msg);
+      epan_cleanup();
+      exit(2);
+    }
+  }
   cfile.rfcode = rfcode;
+  cfile.hfcode = hfcode;
   if (cf_name) {
     err = open_cap_file(cf_name, FALSE, &cfile);
     if (err != 0) {
@@ -2175,10 +2187,12 @@
   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;
+  gboolean      halt;
   epan_dissect_t *edt;
+  epan_dissect_t *hedt;
 
 #ifdef HAVE_LIBPCAP
 #ifdef SIGINFO
@@ -2192,6 +2206,17 @@
 #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 +2249,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)