flowscope 0.1.0

Passive flow & session tracking for packet capture (runtime-free, cross-platform)
Documentation

flowscope

crates.io docs.rs CI

Passive flow & session tracking for packet capture.

flowscope is a runtime-free, cross-platform Rust library for observing what's happening on the wire. It pairs with any source of &[u8] frames: netring (Linux AF_PACKET / AF_XDP), pcap files, tun/tap, eBPF, embedded — anywhere bytes show up.

No tokio, no futures, no async runtime in the core. (For tokio integration, see netring's AsyncCapture::flow_stream etc., which consume this crate's traits.)

What's here

PacketView   →   FlowExtractor   →   FlowTracker   →   Reassembler   →   SessionParser / DatagramParser
   ↑                                                                              ↓
   anything                                                              typed L7 messages

Core (always on):

  • FlowExtractor trait + built-in extractors (5-tuple, IP-pair, MAC-pair) + decap combinators (VLAN, MPLS, VXLAN, GTP-U, GRE) + AutoDetectEncap combinator + FlowLabel IPv6 augmentation.
  • FlowTracker — bidirectional flow accounting, TCP state machine, idle timeouts, LRU eviction.
  • Reassembler — sync per-(flow, side) hook for TCP byte streams.
  • SessionParser / DatagramParser — typed L7 message parsing per flow.

Protocol parsers (each behind its own feature):

Feature What you get
http HTTP/1.x request/response parsing — both HttpFactory (callback) and HttpParser (SessionParser)
tls TLS handshake observer (ClientHello/ServerHello/Alert) — passive only, no decryption
ja3 JA3 client fingerprinting (sub-feature of tls)
dns DNS message parser, per-flow query/response correlator. UDP via DnsUdpParser (DatagramParser); TCP via DnsTcpParser (SessionParser, RFC 1035 §4.2.2 length-framed)
pcap pcap file source for offline replay
full All of the above

Quick start

[dependencies]
flowscope = { version = "0.1", features = ["full"] }
use flowscope::extract::FiveTuple;
use flowscope::pcap::PcapFlowSource;
use flowscope::FlowEvent;

# fn main() -> Result<(), Box<dyn std::error::Error>> {
for evt in PcapFlowSource::open("trace.pcap")?.with_extractor(FiveTuple::bidirectional()) {
    if let FlowEvent::Started { key, .. } = evt? {
        println!("flow started: {key:?}");
    }
}
# Ok(()) }

For HTTP / TLS / DNS examples and the typed SessionParser / DatagramParser APIs, see examples/ and the per-module documentation on docs.rs.

Tokio integration

flowscope itself is runtime-free. To consume a live capture into a stream of FlowEvent / SessionEvent via tokio, use netring:

use netring::AsyncCapture;
use flowscope::extract::FiveTuple;
use flowscope::http::HttpParser;
use futures::StreamExt;

# async fn ex() -> Result<(), Box<dyn std::error::Error>> {
let mut s = AsyncCapture::open("eth0")?
    .flow_stream(FiveTuple::bidirectional())
    .session_stream(HttpParser::default());
while let Some(evt) = s.next().await { /* ... */ }
# Ok(()) }

Status

0.1.0 published — the API is settled. The core flow APIs (FlowExtractor, FlowTracker, Reassembler) and SessionParser / DatagramParser traits are stable; future additions will be additive. Major breaking changes will require a 1.0 / 0.2 bump.

See docs/SESSION_GUIDE.md for the decision-flow on which API to pick.

License

MIT OR Apache-2.0, your choice.