summary history branches tags files
commit:aa640dccf28e9da450084a18362a30f70816e1df
author:Trevor Bentley
committer:Trevor Bentley
date:Tue May 7 02:40:57 2024 +0200
parents:de0cae508a3bad3278502deb88d8ca3f405c54b4
add ability to filter on direction and data contents
diff --git a/src/lib.rs b/src/lib.rs
line changes: +13/-4
index 0992c18..de4273d
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -58,6 +58,8 @@ pub type U8Cmp = fn(x: u8) -> bool;
 pub type U16Cmp = fn(x: u16) -> bool;
 pub type CIntCmp = fn(x: libc::c_int) -> bool;
 pub type CUintCmp = fn(x: libc::c_uint) -> bool;
+pub type SliceCmp = fn(x: &[u8]) -> bool;
+pub type BoolCmp = fn(x: bool) -> bool;
 
 #[derive(Default, Copy, Clone)]
 pub struct DeviceFilter {
@@ -82,6 +84,10 @@ pub struct UsbmonFilter {
     pub flag_data: Option<U8Cmp>,
     pub status: Option<CIntCmp>,
     pub data_len: Option<CUintCmp>,
+    pub dir_out: Option<BoolCmp>,
+
+    // USB data
+    pub data: Option<SliceCmp>,
 
     // Setup packet
     pub setup_request_type: Option<U8Cmp>,
@@ -372,7 +378,7 @@ impl UsbmonPacket {
         self.pkt_type != b'S' && self.status != 0
     }
 
-    fn match_filter(&self, f: Option<&UsbmonFilter>) -> bool {
+    fn match_filter(&self, f: Option<&UsbmonFilter>, data: &[u8]) -> bool {
         let mut matched = true;
         if f.is_none() {
             return true;
@@ -384,11 +390,14 @@ impl UsbmonPacket {
         matched &= f.epnum.map(|x| x(self.epnum())).unwrap_or(true);
         matched &= f.devnum.map(|x| x(self.devnum())).unwrap_or(true);
         matched &= f.busnum.map(|x| x(self.busnum())).unwrap_or(true);
+        matched &= f.dir_out.map(|x| x(self.dir_out())).unwrap_or(true);
         matched &= f.flag_setup.map(|x| x(self.flag_setup())).unwrap_or(true);
         matched &= f.flag_data.map(|x| x(self.flag_data())).unwrap_or(true);
         matched &= f.status.map(|x| x(self.status())).unwrap_or(true);
         matched &= f.data_len.map(|x| x(self.length())).unwrap_or(true);
 
+        matched &= f.data.map(|x| x(data)).unwrap_or(true);
+
         matched &= f.setup_request_type
             .map(|x| x(self.setup_packet()
                        .map(|s| s.request_type()).unwrap_or(0))).unwrap_or(true);
@@ -592,7 +601,7 @@ pub fn monitor(dev_filter: Option<&DeviceFilter>,
                 }
             }
 
-            if !capturing && (*hdr).match_filter(start_filter) {
+            if !capturing && (*hdr).match_filter(start_filter, &pkt_data) {
                 // If the start filter matches, begin capturing packets
                 capturing = true;
                 start_time = (*hdr).usec_since(0);
@@ -601,7 +610,7 @@ pub fn monitor(dev_filter: Option<&DeviceFilter>,
                 }
             }
             else if capturing {
-                if end_filter.is_some() && (*hdr).match_filter(end_filter) {
+                if end_filter.is_some() && (*hdr).match_filter(end_filter, &pkt_data) {
                     if !cli_args.quiet {
                         (*hdr).print(start_time, &pkt_data);
                     }
@@ -609,7 +618,7 @@ pub fn monitor(dev_filter: Option<&DeviceFilter>,
                         stop_capturing_count = Some(f.pkts_after);
                     }
                 }
-                else if (*hdr).match_filter(active_filter) {
+                else if (*hdr).match_filter(active_filter, &pkt_data) {
                     if !cli_args.quiet {
                         (*hdr).print(start_time, &pkt_data);
                     }