Skip to content

eogod/wireprism

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

41 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

WirePrism

High-throughput network stream inspection for live traffic and PCAPs.

CI Rust 2024 MIT License

WirePrism turns captured packets into bounded, queryable stream state while traffic is still arriving. It combines capture, flow tracking, transport reassembly, protocol parsing, content transforms, pattern matching, a local API, and a dense Web UI in one Rust process.

The engine is built for workloads where correctness and predictable resource usage matter: large PCAPs, long-running live capture, protocol research, network forensics, and CTF traffic analysis.

Important

WirePrism is under active development. The capture, reassembly, parser, API, and UI paths are working, but APIs and output schemas may change before 1.0.

Highlights

  • Live and offline input through libpcap, with BPF filters, source drop counters, configurable capture buffers, and batched PCAP replay.
  • Stateful flow processing with canonical flow keys, TCP sequence tracking, bounded out-of-order reassembly, QUIC connection routing, and flow-sharded workers.
  • Protocol-aware streams with structured message indexes for HTTP, DNS, TLS, QUIC, WebSocket, and a growing set of text and binary services.
  • Content inspection with text, regex, and binary patterns; logical match offsets; highlighted slices; and text, hex, raw, or base64 copy formats.
  • On-demand transforms for URL encoding, gzip, HTTP chunked bodies, gzip HTTP bodies, and compressed WebSocket messages.
  • Bounded by design through explicit flow, parser, content, match, queue, and API retention limits instead of unbounded shared state.
  • Observable under load with queue pressure, routed bytes, fallback reasons, hot-flow telemetry, packet/byte skew, parser misses, and per-shard diagnostics.
  • Built-in local UI and API with live deltas, service filters, favorites, hidden streams, match navigation, and viewport-sized content reads.

Quick Start

Prerequisites

WirePrism currently targets macOS and Linux. You need a current stable Rust toolchain, libpcap development files, Clang, and CMake.

On macOS:

xcode-select --install
brew install cmake

On Ubuntu or Debian:

sudo apt-get update
sudo apt-get install -y build-essential pkg-config libpcap-dev clang cmake libclang-dev

Build the optimized binaries:

git clone https://github.com/eogod/wireprism.git
cd wireprism
cargo build --release

This produces:

  • target/release/wireprism - capture, analysis, API, and UI runtime.
  • target/release/wireprism-load - repeatable load and regression harness.

Inspect a PCAP

./target/release/wireprism \
  --pcap capture.pcap \
  --output findings.jsonl \
  --api-listen 127.0.0.1:33111

Open http://127.0.0.1:33111 while the process is running. After the PCAP finishes, the API remains available until Ctrl-C so the retained streams can still be inspected.

Capture Live Traffic

List interfaces first:

./target/release/wireprism --list-interfaces

Capture from an interface and open the live UI:

sudo ./target/release/wireprism \
  --iface en0 \
  --capture-filter 'tcp or udp' \
  --api-listen 127.0.0.1:33111 \
  --workers 0

Live capture requires permission to open the selected interface. Build as your normal user and elevate only the finished binary when elevated capture access is required.

--workers 0 means the runtime uses available parallelism. The main runtime accepts an integer worker count; the adaptive worker plan is provided by wireprism-load for benchmarking and capacity selection.

Inspection Workflows

Pattern Matching

Patterns are repeatable and can be combined in one run:

./target/release/wireprism \
  --pcap capture.pcap \
  --pattern 'token=' \
  --regex 'flag\{[^}]+\}' \
  --binary-pattern 'de ad be ef' \
  --api-listen 127.0.0.1:33111
  • --pattern performs byte-exact substring matching.
  • --regex matches byte-oriented regular expressions across chunk boundaries.
  • --binary-pattern accepts hexadecimal bytes with optional spaces, colons, underscores, dashes, or a 0x prefix.

Matches retain stream direction and logical offsets, allowing the API and UI to request only the content window needed for highlighting.

TLS and QUIC Secrets

Use an NSS/SSLKEYLOGFILE-compatible key log for modern TLS and QUIC captures:

./target/release/wireprism \
  --pcap capture.pcap \
  --tls-keylog /path/to/sslkeys.log \
  --api-listen 127.0.0.1:33111

Static-RSA TLS 1.0-1.2 captures can use one or more PEM private keys:

./target/release/wireprism \
  --pcap capture.pcap \
  --tls-rsa-key /path/to/server-key.pem

Static RSA keys cannot decrypt ECDHE sessions. Key logs and private keys contain sensitive material and should never be committed to the repository.

JSONL Output

Analysis mode emits bounded metadata and parser events without copying all retained payload content into the output stream:

./target/release/wireprism --pcap capture.pcap --output findings.jsonl

Packet dump mode emits packet-level dump events:

./target/release/wireprism \
  --pcap capture.pcap \
  --mode dump \
  --output packets.jsonl

Protocol Coverage

Layer Current coverage
Link and network Ethernet, Linux SLL, BSD loopback, raw IP, IPv4, and IPv6
Transport TCP, UDP, ICMP decode, TCP reassembly, and QUIC state
Structured messages HTTP/1-3, DNS over UDP/TCP, TLS, QUIC, and WebSocket
Text services SSH, FTP, SMTP, POP3, IMAP, Redis, and Memcached
Binary services MQTT, AMQP, Postgres, MySQL, MongoDB, LDAP, SMB2, and RDP
Datagram metadata DHCP, NTP, SNMP, SSDP, NetBIOS name service, and ICMPv4

Coverage is protocol-specific. A protocol listed under text, binary, or datagram services may currently provide detection, framing, and selected message metadata rather than a complete semantic decoder for every operation.

Architecture

flowchart LR
    A["PCAP file or live interface"] --> B["Batched ingest"]
    B --> C["Route-only dispatcher"]
    C --> D["Stateful flow placement"]

    subgraph S["Flow shard"]
        E["Decode once"] --> F["Flow and transport state"]
        F --> G["TCP / QUIC reassembly"]
        G --> H["Detection and parsers"]
        H --> I["Content, patterns, transforms"]
    end

    D --> S
    S --> J["Coordinator"]
    J --> K["JSONL sinks"]
    J --> L["Live API"]
    L --> M["Web UI"]
Loading

The hot path follows a few rules:

  1. Packets are decoded once inside their worker shard.
  2. Canonical flows retain an owner so reverse traffic reaches the same state.
  3. Heavy TCP stream work can use bounded offload lanes without moving flow ownership; eligible UDP elephant flows can be striped across workers.
  4. Worker input, output, and offload queues apply explicit backpressure.
  5. Stream content, parser state, match indexes, and UI deltas have independent memory caps and eviction policies.
  6. The coordinator owns query-facing view state, keeping slow UI clients away from worker-local mutable state.

Runtime Tuning

The defaults are conservative enough for local analysis. Large or long-running captures should set memory and queue budgets deliberately.

Option Default Purpose
--workers 0 Flow-shard workers; 0 uses available parallelism
--batch-size 4096 Packets read and dispatched per ingest batch
--worker-queue-depth 4096 Bounded input queue per worker
--event-queue-depth 4096 Bounded worker-to-coordinator event queue
--max-flows 1000000 Maximum retained flow states
--max-stream-content-bytes 268435456 Global retained content budget
--max-stream-content-bytes-per-stream 8388608 Per-stream content cap
--health-interval-ms 1000 Telemetry interval; 0 disables it

Example with explicit capacity limits:

./target/release/wireprism \
  --pcap capture.pcap \
  --workers 8 \
  --batch-size 8192 \
  --worker-queue-depth 8192 \
  --event-queue-depth 8192 \
  --max-flows 2000000 \
  --max-stream-content-bytes 536870912

Queue depth is not a substitute for throughput. Use the health endpoint and load harness to distinguish sustained worker saturation from short bursts, fallback routing, or one legitimately dominant flow.

Live API

The API is intended for local use and has no authentication. Keep it bound to a loopback address unless it is placed behind an authenticated proxy.

Endpoint Purpose
GET /api/health Pipeline, parser, queue, drop, and shard telemetry
GET /api/service-profiles Built-in and custom service profiles
GET /api/streams Cursor-based stream inventory and filters
GET /api/streams/{id} Stream metadata and current view state
GET /api/streams/{id}/messages Parsed protocol message index
GET /api/streams/{id}/matches Retained pattern match ranges
GET /api/streams/{id}/content Bounded text, hex, or raw content slice
GET /api/live/deltas Long-polling stream and telemetry updates
PATCH /api/streams/{id}/state Favorite or manually hide a stream
POST /api/view/hide-rules Add an in-memory hide rule

Examples:

curl http://127.0.0.1:33111/api/health
curl 'http://127.0.0.1:33111/api/streams?profile=http&limit=50'
curl 'http://127.0.0.1:33111/api/live/deltas?cursor=0&limit=1024&wait_ms=1000'
curl 'http://127.0.0.1:33111/api/streams/123/messages?protocol=http1&limit=128'
curl 'http://127.0.0.1:33111/api/streams/123/content?direction=a_to_b&start=0&len=65536&mode=text&transform=auto'

Stream IDs are also returned as stream_id_hex so browser clients can preserve the full 64-bit value without JavaScript number precision loss.

Service Profiles

Profiles group streams by protocol, service, port, content kind, or pattern ID. They can also define default views, transform chains, and hide-rule templates.

{
  "include_builtins": true,
  "profiles": [
    {
      "id": "admin_web",
      "name": "Admin web",
      "priority": 150,
      "protocol": "tcp",
      "ports": [8080, 18080],
      "services": ["http"],
      "default_mode": "text",
      "default_transform": "auto",
      "default_transforms": ["http_chunked", "http_gzip", "url_decode"],
      "hide_rules": [{ "kind": "port", "value": 18080 }]
    }
  ]
}

Load the file with:

./target/release/wireprism \
  --pcap capture.pcap \
  --service-profile-file profiles.json \
  --api-listen 127.0.0.1:33111

Performance Harness

wireprism-load runs reproducible synthetic or PCAP-backed suites across worker counts and reports packets/sec, bytes/sec, event throughput, shard skew, fallback ratios, flow distribution, and planner decisions.

./target/release/wireprism-load \
  --fixture http-requests \
  --flows 100000 \
  --workers 1,4,adaptive,0 \
  --runs 3 \
  --warmups 1 \
  --output perf-http.json

Available synthetic fixtures:

  • http-requests
  • out-of-order-http
  • http-keep-alive
  • mixed-services
  • udp-elephant
  • tcp-elephant

Replay a real capture:

./target/release/wireprism-load \
  --pcap capture.pcap \
  --workers 1,4,adaptive,0 \
  --runs 3 \
  --warmups 1 \
  --output perf-pcap.json

Use a saved JSON report as a regression baseline:

./target/release/wireprism-load \
  --fixture http-requests \
  --flows 100000 \
  --workers adaptive \
  --runs 5 \
  --warmups 2 \
  --baseline baselines/http.json \
  --max-regression-pct 10 \
  --fail-on-regression \
  --output perf-current.json

Warmups are excluded from summaries unless --include-warmups is set. A small fixture can make additional workers slower; compare packet, byte, and flow budgets per worker before treating worker-count results as a scaling regression.

Development

Run the same core checks used by CI:

cargo fmt --check
cargo test --all-targets --all-features
cargo clippy --all-targets --all-features -- -D warnings
cargo bench --bench packet_decode --no-run

Run a short end-to-end load smoke test:

cargo run --release --bin wireprism-load -- \
  --fixture http-requests \
  --flows 10000 \
  --workers 1,adaptive \
  --runs 1 \
  --warmups 0

Parser changes should be validated against the built-in protocol corpus and at least one real capture. Performance-sensitive changes should include before and after reports produced on the same machine with the same build profile.

Roadmap

  • Broaden malformed-input, fragmentation, and fuzz coverage across every parser.
  • Persist capture sessions, favorites, hide rules, and UI preferences.
  • Expand message-first navigation and protocol-specific views in the Web UI.
  • Add production-oriented storage and export sinks beyond JSONL.
  • Export long-running metrics in a machine-readable format.
  • Continue parser depth and encrypted-session coverage without weakening memory bounds or flow correctness.

Security

Capture files, payloads, key logs, private keys, and JSONL output may contain credentials or other sensitive data. Keep them outside version control. Only capture or decrypt traffic you are authorized to inspect.

License

WirePrism is licensed under the MIT License.

About

High-throughput network stream inspection for live traffic and PCAPs. Built in Rust with flow reassembly, protocol parsing, transforms, pattern matching, and a real-time Web UI.

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages