Skip to main content

flowscope/
lib.rs

1//! `flowscope` — passive flow & session tracking for packet capture.
2//!
3//! Cross-platform, runtime-free library for **observing** what's
4//! happening on the wire. Pair with any source of `&[u8]` frames:
5//! `netring` (Linux AF_PACKET / AF_XDP), pcap files, tun-tap,
6//! eBPF, embedded.
7//!
8//! ## What's here
9//!
10//! Core (always on):
11//!
12//! - [`PacketView`] / [`Timestamp`] — the abstract input.
13//! - [`FlowExtractor`] — turn a frame into a flow descriptor.
14//! - [`FlowTracker`] — bidirectional flow accounting + TCP state
15//!   machine + idle/eviction policy. Hot-cache fast path on
16//!   monoflow workloads.
17//! - [`Reassembler`] — sync per-(flow, side) TCP byte stream hook.
18//!   The built-ins report unfillable holes as gaps ([`StreamChunks`])
19//!   instead of wedging; optional per-side buffer cap with
20//!   [`OverflowPolicy`] (sliding-window or drop-flow).
21//! - [`SessionParser`] / [`DatagramParser`] — typed L7 message
22//!   parsing per flow.
23//! - [`FlowDriver`] — sync wrapper combining the tracker with a
24//!   reassembler factory; optional anomaly emission via
25//!   [`FlowDriver::with_emit_anomalies`].
26//! - [`session::SessionDriver`] / [`session::DatagramDriver`] — one
27//!   parser type over a capture, ordered [`SessionEvent`] output.
28//! - [`driver::Driver`] — several parsers sharing one flow table;
29//!   register one session/datagram slot per protocol for typed L7
30//!   messages beside the flow-lifecycle event stream.
31//!
32//! The last two, and the [`pcap`] helpers, run one session engine:
33//! [`FlowTracker`] → [`FlowDriver`] (reassemblers, anomalies, memcap)
34//! → per-parser cores. Parser closes never end a flow, and gaps reach
35//! parsers explicitly ([`SessionParser::on_gap`]).
36//!
37//! Built-in extractors and decap combinators (`extractors` feature):
38//!
39//! - [`extract::FiveTuple`], [`extract::IpPair`], [`extract::MacPair`]
40//! - [`extract::StripVlan`], [`extract::StripMpls`],
41//!   [`extract::InnerVxlan`], [`extract::InnerGtpU`],
42//!   [`extract::InnerGre`], [`extract::AutoDetectEncap`],
43//!   [`extract::FlowLabel`]
44//!
45//! ## Cargo features
46//!
47//! Granular leaf flags compose into coarse umbrellas. Pick the smallest
48//! that fits; `--all-features` (docs.rs) turns on everything including the
49//! FoxIO-licensed `ja4plus`.
50//!
51//! **Umbrellas & tiers** — correct, coarse groupings (issue #87):
52//!
53//! | Feature         | Pulls |
54//! |-----------------|-------|
55//! | `full`          | `l7` + every license-clean capability (excludes FoxIO `ja4plus`) |
56//! | `l7`            | every license-clean wire parser (the three `parsers-*` tiers + `tls-fingerprints`) |
57//! | `parsers-core`  | `http` `http2` `tls` `dns` `icmp` |
58//! | `parsers-l2l3`  | `arp` `ndp` `lldp` `cdp` `dhcp` (L2/L3 asset discovery) |
59//! | `parsers-tier2` | the 19 Tier-2 parsers (`ssh` `ntp` `ssdp` `tftp` `mdns` `netbios-ns` `ftp` `smtp` `wireguard` `modbus` `stun` `rdp` `snmp` `radius` `quic` `smb` `ldap` `kerberos` `dnp3`) |
60//! | `nsm`           | network-security monitoring: `fingerprint` + `tls-fingerprints` + `analysis` |
61//! | `ml`            | `ml-features` + `ml-features-nprint` |
62//! | `export`        | `ipfix` + `ipfix-export` + the `emit*` writers |
63//!
64//! **Protocol parsers** (each behind its own feature):
65//!
66//! | Feature | Module | What you get |
67//! |---------|--------|--------------|
68//! | `http` | [`http`] | HTTP/1.x — passive parser plus the sans-IO streaming parser for inline proxies |
69//! | `http2` | [`http2`] | HTTP/2 frame layer + HPACK + per-stream routing; gRPC call and status |
70//! | `tls` | [`tls`] | TLS handshake observer (ClientHello/ServerHello/Alert) |
71//! | `dns` | [`dns`] | DNS-over-UDP/TCP parsers + query/response correlator |
72//! | `icmp` | [`icmp`] | ICMPv4/v6 decoder + inner-flow correlation |
73//! | `arp` | [`arp`] | ARP + `correlate::NeighborTable` binding tracker |
74//! | `ndp` | [`ndp`] | IPv6 Neighbor Discovery (ICMPv6 135/136) |
75//! | `dhcp` | [`dhcp`] | DHCP/BOOTP options + Fingerbank-style fingerprint |
76//! | `lldp` | [`lldp`] | LLDP (IEEE 802.1AB) L2 asset discovery |
77//! | `cdp` | [`cdp`] | Cisco Discovery Protocol |
78//! | `ssh` | [`ssh`] | SSH banner + KEXINIT + HASSH fingerprint |
79//! | `ntp` | [`ntp`] | NTP (UDP/123); monlist amplification signal |
80//! | `ssdp` | [`ssdp`] | SSDP/UPnP IoT discovery |
81//! | `tftp` | [`tftp`] | TFTP (UDP/69) device-config-theft visibility |
82//! | `mdns` | [`mdns`] | mDNS / DNS-SD service walker (pulls `dns`) |
83//! | `netbios-ns` | [`netbios_ns`] | NetBIOS Name Service (UDP/137) |
84//! | `ftp` | [`ftp`] | FTP control channel + AUTH-TLS upgrade |
85//! | `smtp` | [`smtp`] | SMTP + AUTH base64 decode + STARTTLS |
86//! | `wireguard` | [`wireguard`] | WireGuard handshake metadata |
87//! | `modbus` | [`modbus`] | Modbus/TCP (502) ICS visibility |
88//! | `stun` | [`stun`] | STUN (RFC 5389) WebRTC / NAT discovery |
89//! | `rdp` | [`rdp`] | RDP X.224 negotiation metadata |
90//! | `snmp` | [`snmp`] | SNMP v1/v2c (rusticata snmp-parser) |
91//! | `radius` | [`radius`] | RADIUS auth/accounting (rusticata radius-parser) |
92//! | `quic` | [`quic`] | QUIC Initial passive decrypt → SNI/ALPN |
93//! | `smb` | [`smb`] | SMB2/3 lateral-movement decode |
94//! | `ldap` | [`ldap`] | LDAP bind/search (rusticata ldap-parser) |
95//! | `kerberos` | [`kerberos`] | Kerberos AS/TGS/KRB-ERROR |
96//! | `dnp3` | [`dnp3`] | DNP3 (TCP/20000) OT/SCADA metadata |
97//!
98//! **Capabilities & output:**
99//!
100//! | Feature | Module | What you get |
101//! |---------|--------|--------------|
102//! | `asset` | [`asset`] | `Asset` + LRU `Inventory`; self-sufficient (pulls its discovery parsers) |
103//! | `analysis` | [`analysis`] | `FlowAnalyzer` → risk / IOC enriched flow records |
104//! | `tcp_fingerprint` | [`tcp_fingerprint`] | p0f-style passive TCP/IP OS fingerprint |
105//! | `fingerprint` | [`detect::fingerprint`] | encrypted-flow **behavioural** fingerprint (not the JA4+ facade — see below) |
106//! | `tls-fingerprints` | [`tls`] | JA3 + JA4 TLS *client* fingerprints (royalty-free) |
107//! | `ja4plus` | [`tls`] | JA4S/JA4X server fingerprints (**FoxIO License 1.1**, off by default) |
108//! | `ml-features` / `ml-features-nprint` | [`ml_features`] / [`nprint`] | CICFlowMeter vector / nPrint bit matrix |
109//! | `ipfix` / `ipfix-export` | [`ipfix`] | IANA IE vocabulary / RFC 7011 binary encoder |
110//! | `emit` / `emit-ndjson` / `emit-eve` | [`emit`] | CSV+Zeek / NDJSON / Suricata EVE writers |
111//! | `aggregate` | [`aggregate`] | `Histogram` + `Percentile` (t-digest) |
112//! | `file-hash` | [`detect::file`](detect) | streaming SHA-256/MD5 + MIME-class detection |
113//! | `community-id` | [`well_known`] | Corelight Community ID v1 flow hashing |
114//! | `chrono` | [`Timestamp`] | `chrono::DateTime<Utc>` interop |
115//! | `pcap` | [`pcap`] | pcap / pcapng source for offline replay (`PcapFlowSource`, `*_from_pcap` helpers) |
116//! | `pcap-reader` | [`pcap`] | just [`pcap::CaptureReader`] (pcap / pcapng, link-type normalisation, capture direction) — no extractors or tracker; `pcap` builds on it |
117//! | `serde` | — | `Serialize`/`Deserialize` on every public type (locks wire vocabulary) |
118//!
119//! **Always-on modules** (no feature gate):
120//!
121//! | Module | What you get |
122//! |--------|--------------|
123//! | [`fingerprint`] | unified JA4+ facade — one import site for the whole family, grouped by license (distinct from the `fingerprint`-feature behavioural detector above) |
124//! | [`app_proto`] | identify h2 / h3 + DoT / DoQ / DoH over an encrypted transport from ALPN / SNI / port (no decryption) |
125//! | [`ip_fragment`] | IP fragment reassembly (RFC 791 key, RFC 5722 overlap-drop) — defeats fragmentation-based L4/L7 evasion |
126//! | [`classify`] | what protocol is this, from the first bytes on the wire — the cleartext counterpart to [`app_proto`] |
127//!
128//! **Observability** (zero-cost when off):
129//!
130//! | Feature   | What you get |
131//! |-----------|--------------|
132//! | `metrics` | Prometheus / OpenTelemetry counters, gauges, histograms (see [`obs`]) |
133//! | `tracing` | Structured events on flow lifecycle + anomalies |
134//!
135//! ## Tokio integration
136//!
137//! For async iteration over flow / session / datagram events, see
138//! [`netring`](https://crates.io/crates/netring)'s `AsyncCapture::flow_stream`
139//! / `.session_stream` / `.datagram_stream`. Those depend on this
140//! crate's traits. The sync analogue is the typed [`driver::Driver`]
141//! with one session/datagram slot per protocol.
142//!
143//! ## Re-exporting flowscope types
144//!
145//! Crates that re-export flowscope types (`netring`, sister crates,
146//! internal forks) should write intra-doc links in the bare
147//! `` [`FlowDriver`] `` form, **not** the explicit
148//! `` [`FlowDriver`](flowscope::FlowDriver) `` form.
149//! The explicit path duplicates what rustdoc already resolves through
150//! the re-export and trips the `redundant_explicit_links` lint under
151//! `-D warnings`. See recipes.md's "Re-exporting flowscope types"
152//! section for the worked example.
153
154#![cfg_attr(docsrs, feature(doc_cfg))]
155
156// Typed detector identity + ATT&CK technique mapping (issue #133).
157pub mod detector_kind;
158mod error;
159// Compile-time guards on the `l7` / `full` feature umbrellas (issue #87).
160mod feature_umbrellas;
161pub mod mac_addr;
162pub mod parser_kind;
163pub mod rx_metadata;
164mod timestamp;
165mod view;
166
167pub use detector_kind::DetectorKind;
168pub use error::{Error, ErrorCode, ErrorKind, Module, Result};
169pub use mac_addr::MacAddr;
170pub use parser_kind::{ParserKind, SlotId};
171pub use rx_metadata::{ChecksumStatus, RssHashType, RxHash, RxMetadata, VlanProto, VlanTag};
172
173pub mod extractor;
174
175#[cfg(feature = "aggregate")]
176pub mod aggregate;
177
178pub mod classify;
179
180#[cfg(feature = "http2")]
181pub mod http2;
182
183pub mod detect;
184
185pub mod well_known;
186
187#[cfg(feature = "extractors")]
188pub mod extract;
189
190#[cfg(feature = "extractors")]
191pub mod layers;
192
193#[cfg(feature = "tracker")]
194pub mod anomaly;
195pub mod anomaly_fields;
196// Issue #76: Corelight Community ID v1 flow hashing. Gated by the
197// `community-id` feature (pulls SHA-1 + base64). The seed-fixed
198// `stable_hash` / `shard_index` helpers on `KeyFields` are always-on
199// and need no crypto, so they live in `anomaly_fields`, not here.
200#[cfg(feature = "community-id")]
201pub mod community_id;
202// Issue #77: JA4L / JA4LS latency fingerprint (FoxIO-licensed JA4+).
203#[cfg(feature = "ja4plus")]
204pub mod ja4l;
205// Issue #136: unified JA4+ fingerprint facade — one import site for
206// the whole family, grouped by license. Empty in a build with no
207// fingerprint features enabled.
208pub mod fingerprint;
209// Issue #138: application-protocol identification over encrypted
210// transports (h2/h3, DoT/DoQ/DoH) from ALPN / SNI / port.
211pub mod app_proto;
212// Issue #138: IP fragment reassembly — defeats fragmentation-based
213// L4/L7 evasion by reassembling the original datagram.
214pub mod ip_fragment;
215#[cfg(feature = "tracker")]
216pub use anomaly::{DetectorScore, OwnedAnomaly};
217// Issue #131 (0.21): unified detector trait + registry at the
218// crate root, beside the anomaly types they produce.
219#[cfg(feature = "tracker")]
220pub use detect::registry::{Detector, DetectorRegistry};
221#[cfg(feature = "tracker")]
222pub mod event;
223#[cfg(feature = "tracker")]
224pub mod history;
225#[cfg(all(feature = "tracker", any(test, feature = "test-helpers")))]
226pub mod tcp_state;
227#[cfg(all(feature = "tracker", not(any(test, feature = "test-helpers"))))]
228mod tcp_state;
229#[cfg(feature = "tracker")]
230pub mod tracker;
231
232#[cfg(feature = "tracker")]
233pub mod correlate;
234
235#[cfg(feature = "tracker")]
236pub mod obs;
237
238#[cfg(feature = "reassembler")]
239pub mod flow_driver;
240#[cfg(feature = "reassembler")]
241pub mod reassembler;
242
243#[cfg(feature = "reassembler")]
244pub mod segment_reassembler;
245
246#[cfg(feature = "reassembler")]
247pub use segment_reassembler::{SegmentBufferReassembler, SegmentBufferReassemblerFactory};
248
249#[cfg(feature = "tracker")]
250pub mod dedup;
251
252#[cfg(all(feature = "extractors", feature = "reassembler", feature = "session"))]
253pub mod driver;
254
255#[cfg(feature = "emit")]
256pub mod emit;
257
258pub mod prelude;
259
260#[cfg(feature = "session")]
261pub mod session;
262
263#[cfg(feature = "dns")]
264pub mod dns;
265#[cfg(feature = "http")]
266pub mod http;
267#[cfg(feature = "icmp")]
268pub mod icmp;
269// Plan 162 (0.14): top-level re-export for the unified
270// ICMPv4/v6 Destination Unreachable classification. Parallels
271// `pub use anomaly::OwnedAnomaly` (0.13) — frequently-imported
272// enum surfaced at the crate root.
273#[cfg(feature = "icmp")]
274pub use icmp::{DestUnreachableKind, MtuSignalKind};
275// Issue #1 (0.17): ARP visibility — opt-in via the `arp` feature.
276#[cfg(feature = "arp")]
277pub mod arp;
278#[cfg(feature = "arp")]
279pub use arp::{ArpMessage, ArpOp};
280// Issue #6 (0.18): NDP (IPv6 Neighbor Discovery) — the ARP
281// sibling. Pairs with the always-on `NeighborTable<Ipv6Addr,
282// MacAddr>` for binding tracking.
283#[cfg(feature = "ndp")]
284pub mod ndp;
285#[cfg(feature = "ndp")]
286pub use ndp::{NdpKind, NdpMessage};
287// Issue #11 (0.18): DHCP — UDP/67-68 BOOTP + RFC 2132 options
288// + Fingerbank-style option-55 + option-60 fingerprint.
289#[cfg(feature = "dhcp")]
290pub mod dhcp;
291#[cfg(feature = "dhcp")]
292pub use dhcp::{DhcpMessage, DhcpMessageType, DhcpOp};
293// Issue #23 (0.18): LLDP — IEEE 802.1AB-2016 L2 discovery.
294// Asset / rogue-switch visibility for infrastructure devices.
295#[cfg(feature = "lldp")]
296pub mod lldp;
297#[cfg(feature = "lldp")]
298pub use lldp::{ChassisId, LldpMessage, PortId, SystemCapabilities};
299// Issue #25 (0.18): CDP — Cisco Discovery Protocol, the LLDP
300// sibling. Asset / topology / rogue-switch visibility on
301// Cisco gear.
302#[cfg(feature = "cdp")]
303pub mod cdp;
304#[cfg(feature = "cdp")]
305pub use cdp::{CdpAddress, CdpCapabilities, CdpMessage};
306// Issue #14 sub-piece (0.18): NTP — UDP/123. Stratum / mode /
307// ref-id surface + NTP-amplification (monlist) detection.
308#[cfg(feature = "ntp")]
309pub mod ntp;
310#[cfg(feature = "ntp")]
311pub use ntp::{NtpLeapIndicator, NtpMessage, NtpMode, NtpTimestamp};
312// Issue #14 sub-piece (0.18): SSDP — UDP/1900. UPnP / DLNA /
313// IoT asset discovery.
314#[cfg(feature = "ssdp")]
315pub mod ssdp;
316#[cfg(feature = "ssdp")]
317pub use ssdp::{SsdpKind, SsdpMessage};
318// Issue #14 sub-piece (0.18): TFTP — UDP/69. Device-config
319// transfer visibility.
320#[cfg(feature = "tftp")]
321pub mod tftp;
322#[cfg(feature = "tftp")]
323pub use tftp::{TftpErrorCode, TftpMessage, TftpMode, TftpOpcode};
324// Issue #14 sub-piece (0.18): mDNS — UDP/5353. Wire-format
325// wrapper around `dns` + RFC 6763 service-discovery helpers.
326// Pairs with `asset` for IoT inventory enrichment.
327#[cfg(feature = "mdns")]
328pub mod mdns;
329#[cfg(feature = "mdns")]
330pub use mdns::{MdnsParser, ServiceRecord};
331// Issue #14 sub-piece (0.18): NetBIOS Name Service — UDP/137.
332// Windows-side counterpart to mDNS/SSDP; completes the
333// broadcast-name-service asset-discovery trio.
334#[cfg(feature = "netbios-ns")]
335pub mod netbios_ns;
336#[cfg(feature = "netbios-ns")]
337pub use netbios_ns::{NbnsMessage, NbnsOpcode, NbnsParser};
338// Issue #14 sub-piece (0.18): FTP — TCP/21 control channel.
339// Cleartext credential capture + AUTH-TLS upgrade detection +
340// transfer-command visibility.
341#[cfg(feature = "ftp")]
342pub mod ftp;
343#[cfg(feature = "ftp")]
344pub use ftp::{FtpCommand, FtpMessage, FtpParser, FtpReplyClass, TransferKind};
345// Issue #14 sub-piece (0.18): SMTP — TCP/25 + 587. Cleartext
346// AUTH PLAIN/LOGIN credential capture + named-exfil
347// (MAIL FROM / RCPT TO) + STARTTLS upgrade detection.
348#[cfg(feature = "smtp")]
349pub mod smtp;
350#[cfg(feature = "smtp")]
351pub use smtp::{SmtpCommand, SmtpMessage, SmtpParser};
352// Issue #14 sub-piece (0.18): WireGuard handshake detection.
353// Passive tunnel-fingerprint for shadow-VPN / mesh-VPN
354// evasion detection.
355#[cfg(feature = "wireguard")]
356pub mod wireguard;
357#[cfg(feature = "wireguard")]
358pub use wireguard::{WireGuardKind, WireGuardMessage, WireGuardParser};
359// Issue #14 sub-piece (0.18): Modbus/TCP. ICS passive
360// observability (the only safe mode for SCADA networks).
361#[cfg(feature = "modbus")]
362pub mod modbus;
363#[cfg(feature = "modbus")]
364pub use modbus::{ModbusExceptionCode, ModbusFunction, ModbusMessage, ModbusParser};
365// Issue #14 sub-piece (0.18): STUN — RFC 5389. WebRTC peer
366// detection, NAT-type discovery, TURN identification.
367#[cfg(feature = "stun")]
368pub mod stun;
369#[cfg(feature = "stun")]
370pub use stun::{StunClass, StunMessage, StunParser};
371// Issue #14 sub-piece (0.18): RDP — TCP/3389 X.224 negotiation
372// metadata-only (the lateral-movement T1021.001 vector).
373// Pairs with `tls` for the wrapper handshake.
374#[cfg(feature = "rdp")]
375pub mod rdp;
376#[cfg(feature = "rdp")]
377pub use rdp::{RdpFailureCode, RdpMessage, RdpParser, RdpProtocols};
378// Issue #14 sub-piece (0.18): SNMP v1/v2c — UDP/161 + UDP/162.
379// Asset enum + DDoS amplification detection + cleartext
380// community-string capture.
381#[cfg(feature = "snmp")]
382pub mod snmp;
383#[cfg(feature = "snmp")]
384pub use snmp::{SnmpMessage, SnmpParser, SnmpPduKind, SnmpVersion};
385// Issue #14 sub-piece (0.18): RADIUS — UDP/1812 + UDP/1813.
386// Identity correlation, NAC / wireless-auth visibility.
387#[cfg(feature = "radius")]
388pub mod radius;
389#[cfg(feature = "radius")]
390pub use radius::{RadiusCodeKind, RadiusMessage, RadiusParser};
391// Issue #29 (0.18): DNP3 — TCP/20000 OT visibility.
392// Metadata-only — link-layer reassembly out of scope to
393// avoid the Suricata CVE class.
394#[cfg(feature = "dnp3")]
395pub mod dnp3;
396#[cfg(feature = "dnp3")]
397pub use dnp3::{
398    DnpAppFunctionKind, DnpApplication, DnpInternalIndications, DnpLinkFunctionKind, DnpMessage,
399    DnpParser,
400};
401// Issue #27 (0.18): unified Asset record + Inventory over
402// the asset-discovery parsers.
403#[cfg(feature = "asset")]
404pub mod asset;
405#[cfg(feature = "asset")]
406pub use asset::{
407    Asset, AssetCapabilities, AssetFingerprints, AssetRole, AssetSourceSet, Inventory,
408};
409// Issue #83: analysis composition layer — wires detect/risk/IOC
410// to the flow lifecycle, producing enriched `AnalyzedFlow` records.
411#[cfg(feature = "analysis")]
412pub mod analysis;
413#[cfg(feature = "analysis")]
414pub use analysis::{AnalyzedFlow, FlowAnalyzer, L7Summary};
415// Issue #9 (0.18): p0f-style passive TCP/IP fingerprint.
416// License-clean alternative to FoxIO's JA4T / JA4TS.
417#[cfg(feature = "tcp_fingerprint")]
418pub mod tcp_fingerprint;
419#[cfg(feature = "tcp_fingerprint")]
420pub use tcp_fingerprint::{TcpDirection, TcpFingerprint};
421// Issue #16 sub-piece (0.18): IPFIX IE vocabulary. The full
422// FlowRecord re-key stays open in #16.
423#[cfg(feature = "ipfix")]
424pub mod ipfix;
425#[cfg(feature = "ipfix")]
426pub use ipfix::FlowRecord;
427// Issue #15 scoped sub-piece (0.18): CICFlowMeter-compatible
428// feature vector. Subset that's derivable from a finalised
429// FlowRecord alone (no per-packet IAT tracking). Gated on
430// ipfix (the FlowRecord source-of-truth).
431#[cfg(feature = "ml-features")]
432pub mod ml_features;
433#[cfg(feature = "ml-features")]
434pub use ml_features::CicFlowFeatures;
435// Issue #30 (0.18): nPrint per-packet ternary header-bit matrix
436// for model-agnostic ML pipelines. Separate Cargo feature
437// because per-packet storage is non-trivial (vs. ml-features
438// which is O(1) per flow).
439#[cfg(feature = "ml-features-nprint")]
440pub mod nprint;
441#[cfg(feature = "ml-features-nprint")]
442pub use nprint::{NPrintConfig, NPrintMatrix, NPrintRow};
443// Issue #13 (0.18): Kerberos passive metadata parser
444// (rusticata kerberos-parser).
445#[cfg(feature = "kerberos")]
446pub mod kerberos;
447#[cfg(feature = "kerberos")]
448pub use kerberos::{
449    KERBEROS_PORT, KerberosEtype, KerberosMessage, KerberosMessageKind, KerberosTcpParser,
450    KerberosUdpParser,
451};
452// Issue #13 (0.18): LDAP passive metadata parser
453// (rusticata ldap-parser).
454#[cfg(feature = "ldap")]
455pub mod ldap;
456#[cfg(feature = "ldap")]
457pub use ldap::{LDAP_PORT, LdapAuthKind, LdapMessage, LdapOperation, LdapParser};
458// Issue #12 (0.18): SMB2/3 passive parser (hand-rolled).
459#[cfg(feature = "smb")]
460pub mod smb;
461#[cfg(feature = "smb")]
462pub use smb::{
463    DceRpcInterfaceUuid, NtlmAuth, SMB_PORT, SmbCommand, SmbDialect, SmbMessage, SmbParser,
464};
465// Issue #3 (0.18): QUIC Initial parser — ClientHello
466// visibility via RFC 9001 §5.2 Initial-secret derivation
467// + AEAD decrypt (passive-decryptable).
468#[cfg(feature = "quic")]
469pub mod quic;
470#[cfg(feature = "quic")]
471pub use quic::{QUIC_PORT, QuicInitial, QuicUdpParser, QuicVersion};
472// Issue #7 (0.18): SSH handshake parser + HASSH fingerprint.
473#[cfg(feature = "ssh")]
474pub mod ssh;
475#[cfg(feature = "ssh")]
476pub use ssh::{SshKexInit, SshMessage, SshParser};
477#[cfg(feature = "pcap-reader")]
478pub mod pcap;
479#[cfg(feature = "tls")]
480pub mod tls;
481
482/// Parser stubs for downstream test crates. Gated by the
483/// `test-helpers` feature; not for production use.
484#[cfg(all(feature = "session", any(test, feature = "test-helpers")))]
485pub mod test_helpers;
486
487pub use timestamp::Timestamp;
488pub use view::{AsPacketView, OwnedPacketView, PacketView};
489
490// The deprecated `parser_kinds` string-constant module (soft-
491// deprecated in 0.18, slated for removal) was removed in 0.22
492// (issue #139) — use the typed [`ParserKind`] enum instead; its
493// `.as_str()` yields the same slug vocabulary.
494
495pub use anomaly_fields::{AnomalyFields, KeyFields};
496#[cfg(feature = "tracker")]
497pub use dedup::Dedup;
498#[cfg(feature = "tracker")]
499pub use event::{
500    AnomalyKind, EndReason, EventMask, FlowEvent, FlowSide, FlowState, FlowStats, MemcapPolicy,
501    OverflowPolicy, ReassemblyStop, TcpOverlapPolicy,
502};
503pub use extractor::{Extracted, FlowExtractor, L4Meta, L4Proto, Orientation, TcpFlags, TcpInfo};
504#[cfg(feature = "reassembler")]
505pub use flow_driver::{FlowDriver, PacketInfo};
506#[cfg(feature = "tracker")]
507pub use history::HistoryString;
508#[cfg(feature = "reassembler")]
509pub use reassembler::{
510    BufferedReassembler, BufferedReassemblerFactory, Chunk, Chunks, NoopReassembler,
511    NoopReassemblerFactory, Reassembler, ReassemblerFactory, StreamChunks,
512};
513#[cfg(feature = "session")]
514pub use session::{
515    AccumulatingSessionParser, BufferedFrameDrain, DatagramParser, DatagramParserFactory,
516    FrameDrainError, GapResponse, PerDatagramParser, SessionEvent, SessionParser,
517    SessionParserFactory, TemplateFactory, Transports,
518};
519#[cfg(all(feature = "session", feature = "extractors", feature = "reassembler"))]
520pub use session::{DatagramDriver, SessionDriver};
521#[cfg(feature = "tracker")]
522pub use tracker::{
523    FlowEntry, FlowEvents, FlowTracker, FlowTrackerConfig, FlowTrackerStats, PacketContext,
524};