--- flow-filter.c.old	Fri Dec 28 23:39:25 2001
+++ flow-filter.c	Tue Apr 16 00:13:24 2002
@@ -91,6 +91,7 @@
   u_char tos_mask, tos, tcp_flags_mask, tcp_flags;
   u_int64 total_flows, xflag;
   char *rec;
+  int first_match = 0;
 
   /* init fterr */
   fterr_setid(argv[0]);
@@ -118,7 +119,7 @@
   filter_prot = filter_srcas = filter_dstas = filter_tos = 0;
   filter_tcp_flags = 0;
 
-  while ((i = getopt(argc, argv, "a:A:b:C:d:f:p:P:r:S:t:T:D:E:z:i:I:")) != -1)
+  while ((i = getopt(argc, argv, "a:A:b:C:d:f:p:P:r:S:t:T:D:E:z:i:I:o")) != -1)
     switch (i) {
 
     case 'a': /* src AS filter list */
@@ -270,6 +271,10 @@
         fterr_errx(1, "Compression level must be between 0 and 9");
       break;
 
+    case 'o': /* do logical OR between different statements (first match) */
+      first_match = 1;
+      break;
+
     default:
       usage();
       exit (1);
@@ -382,65 +387,116 @@
     ++ total_flows;
 
     /* filter on input interface */
-    if (filter_input) 
-      if (!in_tbl[*cur.input])
-        continue;
+    if (filter_input) {
+      if (!in_tbl[*cur.input]) {
+        if (!first_match)
+          continue;
+      } else if (first_match) {
+        goto found;
+      }
+    }
 
     /* filter on output interface */
-    if (filter_output)
-      if (!out_tbl[*cur.output])
-        continue;
+    if (filter_output) {
+      if (!out_tbl[*cur.output]) {
+        if (!first_match)
+          continue;
+      } else if (first_match) {
+        goto found;
+      }
+    }
 
     /* filter on src port */
-    if (filter_srcport)
-      if (!src_tbl[*cur.srcport])
-        continue;
+    if (filter_srcport) {
+      if (!src_tbl[*cur.srcport]) {
+        if (!first_match)
+          continue;
+      } else if (first_match) {
+        goto found;
+      }
+    }
 
     /* filter on dst port */
-    if (filter_dstport)
-      if (!dst_tbl[*cur.dstport])
-        continue;
+    if (filter_dstport) {
+      if (!dst_tbl[*cur.dstport]) {
+        if (!first_match)
+          continue;
+      } else if (first_match) {
+        goto found;
+      }
+    }
 
     /* filter on protocol */
-    if (filter_prot)
-      if (!prot_tbl[*cur.prot])
-        continue;
+    if (filter_prot) {
+      if (!prot_tbl[*cur.prot]) {
+        if (!first_match)
+          continue;
+      } else if (first_match) {
+        goto found;
+      }
+    }
 
     /* filter on ToS */
       if (filter_tos) {
         tos = *cur.tos & tos_mask;
-        if (!tos_tbl[tos])
-          continue;
+        if (!tos_tbl[tos]) {
+          if (!first_match)
+            continue;
+        } else if (first_match) {
+          goto found;
+        }
       }
 
     /* filter on tcp_flags */
       if (filter_tcp_flags && (*cur.prot == IPPROTO_TCP)) {
         tcp_flags = *cur.tcp_flags & tcp_flags_mask;
-        if (!tcp_flags_tbl[tcp_flags])
-          continue;
+        if (!tcp_flags_tbl[tcp_flags]) {
+          if (!first_match)
+            continue;
+        } else if (first_match) {
+          goto found;
+        }
       }
 
-    if (filter_srcas)
-      if (!srcas_tbl[*cur.src_as])
-        continue;
+    if (filter_srcas) {
+      if (!srcas_tbl[*cur.src_as]) {
+        if (!first_match)
+          continue;
+      } else if (first_match) {
+        goto found;
+      }
+    }
 
     /* filter on src AS */
-    if (filter_dstas)
-      if (!dstas_tbl[*cur.dst_as])
-        continue;
+    if (filter_dstas) {
+      if (!dstas_tbl[*cur.dst_as]) {
+        if (!first_match)
+          continue;
+      } else if (first_match) {
+        goto found;
+      }
+    }
 
     /* eval flow src addr and source standard acl */
     if (acl_std_src_index != -1) {
       ret = acl_eval_std(acl_list, acl_std_src_index2, *cur.srcaddr);
-      if (ret == 1)
-        continue;
+      if (ret == 1) {
+        if (!first_match)
+          continue;
+      } else if (first_match) {
+        goto found;
+      }
     }
 
     /* eval flow dst addr and destination standard acl */
     if (acl_std_dst_index != -1) {
       ret = acl_eval_std(acl_list, acl_std_dst_index2, *cur.dstaddr);
-      if (ret == 1)
-        continue;
+      if (ret == 1) {
+        if (!first_match)
+          continue;
+      } else if (first_match) {
+        goto found;
+      }
     }
 
     /* eval flow and extended acl */
@@ -462,14 +518,22 @@
       tmp_ext.dst_port = *cur.dstport;
 
       ret = acl_eval_ext(acl_list, acl_ext_index2, tmp_ext);
-      if (ret == 1)
-        continue;
+      if (ret == 1) {
+        if (!first_match)
+          continue;
+      } else if (first_match) {
+        goto found;
+      }
     }
 
+    if (first_match) /* No matches yet? next try.. */
+      continue;
+
     /*
      * made it by the filters, write it
      */
 
+found:
     if (ftio_write(&ftio_out, rec) < 0)
       fterr_errx(1, "ftio_write(): failed");
 
