Ethereal-dev: Re: [Ethereal-dev] Bug in tethereal: several capture filters [-f] don't work

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

From: Thomas Steffen <steffen.list.account@xxxxxxxxx>
Date: Mon, 8 Aug 2005 11:41:44 +0200
Ok, here is my patch. It does several things, and I can break it down
if necessary:

* only one -f option is allowed
* implicit capture filters (tethereal sctp) generate an error when
compiled without libpcap
* -X excludes the ssh traffic for the connection tethereal is on (see pod)

It works for me, and it should work on all platforms. My only question
is whether I can use g_strdup_printf, or whether that is not present
in all supported versions of glib.

If you like it, please apply. If not, tell me where I should do better :-)

I also feel like the argument handling could do with a cleanup, but
then again never touch a running system, so this patch is kept as
small as reasonable.

Thomas

On 8/8/05, Guy Harris <gharris@xxxxxxxxx> wrote:
> Thomas Steffen wrote:
> 
> > There are two possibilities: accept only one option -f, or combine the
> > arguments using "and" (I assume).
> 
> The former is correct.  The intent is to support a *single* capture filter.
> 
> _______________________________________________
> Ethereal-dev mailing list
> Ethereal-dev@xxxxxxxxxxxx
> http://www.ethereal.com/mailman/listinfo/ethereal-dev
>
Index: tethereal.c
===================================================================
--- tethereal.c	(revision 15243)
+++ tethereal.c	(working copy)
@@ -243,7 +243,7 @@
   fprintf(output, "\t[ -f <capture filter> ] [ -F <output file type> ] [ -i <capture interface> ]\n");
   fprintf(output, "\t[ -N <name resolving flags> ] [ -o <preference setting> ] ... [ -r <infile> ]\n");
   fprintf(output, "\t[ -R <read (display) filter> ] [ -s <capture snaplen> ] [ -t <time stamp format> ]\n");
-  fprintf(output, "\t[ -T pdml|ps|psml|text ] [ -w <savefile> ] [ -y <capture link type> ]\n");
+  fprintf(output, "\t[ -T pdml|ps|psml|text ] [ -w <savefile> ] [ -X ] [ -y <capture link type> ]\n");
   fprintf(output, "\t[ -z <statistics ]\n");
 #else
   fprintf(output, "\nt%s [ -vh ] [ -lnVx ]\n", PACKAGE);
@@ -655,6 +655,10 @@
   dfilter_t           *rfcode = NULL;
   e_prefs             *prefs;
   char                 badopt;
+  char                *filter_arg = NULL;
+  char                 buf[160] = "";
+  char                 remote_ip[80], local_ip[80];
+  unsigned int         remote_port, local_port;
 
   /* initialize memory allocation subsystem */
   ep_init_chunk();
@@ -776,12 +780,24 @@
   print_format = PR_FMT_TEXT;
 
   /* Now get our args */
-  while ((opt = getopt(argc, argv, "a:b:c:d:Df:F:hi:lLnN:o:pqr:R:s:St:T:vw:Vxy:z:")) != -1) {
+  while ((opt = getopt(argc, argv, "a:b:c:d:Df:F:hi:lLnN:o:pqr:R:s:St:T:vw:VxXy:z:")) != -1) {
     switch (opt) {
+      case 'f':        /* capture filter */
+#ifdef HAVE_LIBPCAP
+        if (filter_arg) {
+          fprintf(stderr,
+"tethereal: Several capture filters were specified with \"-f\"\n");
+          exit(2);
+        }
+        filter_arg = optarg;
+#else
+        capture_option_specified = TRUE;
+        arg_error = TRUE;
+#endif
+        break;
       case 'a':        /* autostop criteria */
       case 'b':        /* Ringbuffer option */
       case 'c':        /* Capture xxx packets */
-      case 'f':        /* capture filter */
       case 'p':        /* Don't capture in promiscuous mode */
       case 's':        /* Set the snapshot (capture) length */
       case 'y':        /* Set the pcap data link type */
@@ -792,6 +808,26 @@
         arg_error = TRUE;
 #endif
         break;
+      case 'X':        /* exclude own ssh traffic */
+#ifdef HAVE_LIBPCAP
+        if (getenv("SSH_CONNECTION") 
+            && strlen(getenv("SSH_CONNECTION")) < 80
+            && sscanf(getenv("SSH_CONNECTION"), "%s %u %s %u", 
+                     remote_ip, &remote_port, local_ip, &local_port) == 4) {
+          snprintf(buf, sizeof(buf) - 1, "not (ip host %s and tcp port %u "
+                   "and ip host %s and tcp port %u)", 
+                   remote_ip, remote_port, local_ip, local_port);
+        } else
+        {
+          fprintf(stderr, "Cannot determine ssh connection details, "
+                  "excluding all ssh traffic.\n");
+          snprintf(buf, sizeof(buf) - 1, "not (tcp port 22)");
+        }
+#else
+        capture_option_specified = TRUE;
+        arg_error = TRUE;
+#endif
+        break;
       case 'd':        /* Decode as rule */
         if (!add_decode_as(optarg))
           exit(1);
@@ -1054,18 +1090,29 @@
       rfilter = get_args_as_string(argc, argv, optind);
     } else {
 #ifdef HAVE_LIBPCAP
-      if (capture_filter_specified) {
+      if (filter_arg) {
         fprintf(stderr,
 "tethereal: Capture filters were specified both with \"-f\" and with additional command-line arguments\n");
         exit(2);
       }
-      capture_opts.cfilter = get_args_as_string(argc, argv, optind);
+      filter_arg = get_args_as_string(argc, argv, optind);
 #else
       capture_option_specified = TRUE;
+      arg_error = TRUE;
 #endif
     }
   }
 
+  if (filter_arg || buf[0]) {
+    if (buf[0] == 0) {
+      capture_opts.cfilter = filter_arg;
+    } else if (filter_arg == NULL) {
+      capture_opts.cfilter = g_strdup(buf);      
+    } else {
+      capture_opts.cfilter = g_strdup_printf("(%s) and (%s)", filter_arg, buf);
+    }
+  }
+
   /* See if we're writing a capture file and the file is a pipe */
 #ifdef HAVE_LIBPCAP
   ld.output_to_pipe = FALSE;
Index: doc/tethereal.pod
===================================================================
--- doc/tethereal.pod	(revision 15243)
+++ doc/tethereal.pod	(working copy)
@@ -32,6 +32,7 @@
 S<[ B<-V> ]>
 S<[ B<-w> savefile ]>
 S<[ B<-x> ]>
+S<[ B<-X> ]>
 S<[ B<-y> capture link type ]>
 S<[ B<-z> statistics ]>
 
@@ -504,6 +505,13 @@
 Cause B<Tethereal> to print a hex and ASCII dump of the packet data
 after printing the summary or details.
 
+=item -X
+
+Add an additional "and" clause to the capture filter that excludes the
+SSH traffic generated by B<Tethereal> itself. This uses the
+environment variable $SSH_CONNECTION. If it is not set, all SSH
+traffic is excluded.
+
 =item -y
 
 Set the data link type to use while capturing packets.  The values