NDAP
Rust core · Python plugin extensibility

Network detection, decoded from the wire up.

A modular platform for packet capture, flow tracking, rule-based detection, and threat intel — built as six independently verifiable crates, not one monolith pretending to be finished.

0 errors — cargo build --workspace
5/5 passed — ndap-intel (IOC, Sigma, YARA, MITRE)
1/1 passed — Rust↔Python plugin IPC round-trip
140/140 synthetic packets decoded, alerts fired correctly
01

Status by phase

Every phase below shipped real, working code in this pass — with one exception marked deliberately. Dot color tells you which is which.

Packet Enginendap-capture, ndap-protocol
pcap file parsing (big-endian + nanosecond variants), Ethernet/IPv4/IPv6/ARP/TCP/UDP decode. Verified against a synthetic 140-packet capture.
REAL
Protocol Frameworkndap-protocol
Dissector trait + ProtocolRegistry for per-port dissectors. Dynamic PluginLoader is still a no-op.
STUB LOADING
Flow Enginendap-flow
5-tuple conversation tracking, TCP reassembly — in-order and out-of-order buffering. No SACK yet.
REAL
Detection Enginendap-detect
Port scan, SYN flood, ARP spoof rules — each MITRE-tagged (T1046 / T1499 / T1557). Verified against synthetic attack traffic.
REAL
Threat Intelligencendap-intel
IOC store (JSON/CSV), Sigma-lite YAML evaluator, real YARA scanning via libyara. 5/5 unit tests passing.
REAL
Web UIndap-api
Axum REST API (/, /health, /analyze) serving an embedded htmx + Chart.js dashboard. No live-stream websocket yet.
REAL
Plugin Extensibilityplugins/python-sdk
Python detection rules run out-of-process via JSON-lines IPC. Verified round-trip: Rust spawns Python, sends a packet, gets a parsed alert back.
REAL
02

Decisions made this pass

Four previously-open questions, resolved and implemented — not left as TODOs.

01
Live capture, cross-platform
Uses the pcap crate — libpcap on Linux/macOS, npcap on Windows. LiveCapture trait now has a real PcapLiveCapture implementation plus list_interfaces().
02
Threat intel format
Plain JSON arrays or CSV (type,value) — no STIX/TAXII/MISP lock-in. Sigma support is a from-scratch minimal evaluator; no count()/timeframe aggregations. YARA is real, via libyara bindings.
03
Frontend stack
htmx + Chart.js from CDN, single embedded HTML file (api/static/dashboard.html, compiled in via include_str!) — stays a single deployable binary, no npm/webpack.
04
Python plugin runtime
Out-of-process, JSON-lines over stdin/stdout. A crashing or malicious plugin can only take down its own process, not the Rust core.
03

Deliberately not done yet

Gaps that need a decision, not more effort.

Dynamic dissector plugin loading
Phase 2's PluginLoader is still a no-op. Needs a decision: dylib loading vs. a scripting bridge.
Live-stream websocket
/analyze is request/response over a stored pcap; live capture isn't wired into the API yet.
Sigma aggregations / timeframes
e.g. count() by src_ip > 100 in 1m — the current evaluator only does per-event boolean matching.
IOC feed ingestion automation
Loaders exist; nothing pulls from a live feed URL yet.
04

Build & run

# requires libpcap-dev, libyara-dev, libclang-dev (yara crate bindgen)
$ sudo apt-get install libpcap-dev libyara-dev libclang-dev clang

$ cd ndap && cargo build --release
$ ./target/release/ndap path/to/capture.pcap

# web dashboard
$ cargo run -p ndap-api
# → http://localhost:8080, point it at a .pcap path on the server