ebpfsieve
Byte-frequency prefilter for read-heavy scanning pipelines, with optional eBPF offload.
What it does
ebpfsieve slides a fixed-size window over byte streams and reports candidate windows where all required byte-count thresholds are met. The idea is to cheaply reject data before handing it to a more expensive verifier.
- Userspace filtering — pure Rust, no dependencies on kernel features.
- Lazy iteration —
matching_windows_iteryields matches one at a time without allocating aVec. - Chunked readers — attach the filter to any
Readimpl and get per-chunk candidate ranges with automatic carry-over across chunk boundaries. - Optional eBPF — on Linux with the right features enabled, compile and load classic BPF socket filters or
aya-basedfentry/vfs_readprobes.
Quick start
use ;
let filter = new?
.with_window_size?;
let matches = filter.matching_windows;
assert_eq!; // "yzaaa"
Filtering model
A ByteFrequencyFilter is built from one or more ByteThreshold values. A window matches when every threshold is satisfied. Counts are maintained in a u16 histogram with saturating arithmetic, so very long windows are safe from overflow.
Reading files in chunks
use ;
use File;
let filter = new?
.with_window_size?
.with_chunk_size?;
let mut file = open?;
let matches = filter.scan_file?;
Lazy iteration
For internet-scale scanning, avoid collecting all matches into a Vec:
let filter = new?;
let mut iter = filter.matching_windows_iter;
if let Some = iter.next
Optional features
serde— load filter rules from TOML withfrom_toml_str/from_toml_file.socket-bpf— compile and load classicBPF_PROG_TYPE_SOCKET_FILTERprograms viaebpfkit(Linux only).kernel-bpf— loadaya-basedfentry/vfs_readprobes (Linux ≥ 5.8, BTF, root required).
Errors
All fallible operations return ebpfsieve::Result<T>. Errors carry actionable messages, for example:
invalid filter configuration: window_size cannot be zero. Fix: provide a window_size of at least 1
License
MIT