Skip to content

Repository files navigation

NetProbe

A real-time and offline network traffic analyzer built with Modern C++20, Npcap/libpcap, and Dear ImGui.

CI Platform Standard License

Every push is built on Windows, Linux, and macOS, run under AddressSanitizer and UndefinedBehaviorSanitizer, checked with clang-tidy, and fuzzed with libFuzzer.

Download

Download the ZIP for your platform from GitHub Releases. Windows releases require the Npcap driver for live capture and PCAP support. Linux and macOS releases require their system libpcap runtime.

Features

  • Live and offline capture: inspect an active adapter or drag a .pcap / .pcapng into the app (classic libpcap and modern PCAPNG both supported).
  • Link-layer aware: decodes Ethernet, VLAN/QinQ, Linux cooked captures (SLL/SLL2, as produced by the any device), BSD/OpenBSD loopback, and raw-IP captures. Exported PCAPs preserve the original link type.
  • Protocol insight: IPv4/IPv6, TCP, UDP, ARP, ICMP/ICMPv6, SCTP, and named non-IP frames (LLDP, EAPOL, PPPoE, MPLS).
  • Tunnel descent: transparently decodes GRE, IP-in-IP, 6in4, VXLAN, GENEVE, MPLS, and PPPoE, so flows are keyed on the real inner endpoints rather than the tunnel. Encrypted tunnels (ESP/IPsec, WireGuard, OpenVPN) are labelled as such instead of being silently misreported.
  • Deep application identification:
    • TLS SNI on any port (content-sniffed, not port-gated), with reassembly of ClientHellos split across TCP segments — required now that post-quantum key shares push the message past one MSS.
    • QUIC ClientHello SNI for v1 (RFC 9000) and v2 (RFC 9369) on any UDP port, decrypting Initial packets and reassembling CRYPTO frames across multiple Initials.
    • Cleartext HTTP: request line and Host: header, which names hosts even when no DNS was observed.
    • DNS/mDNS: A/AAAA/CNAME, plus PTR (names LAN devices that never appear in a forward lookup), SRV, TXT, and HTTPS/SVCB records.
  • Encrypted-DNS visibility: detects DoH/DoT/DoQ and Encrypted Client Hello, and tells you when name resolution has moved off the wire rather than silently showing bare IPs.
  • Packet detail pane: click any packet to see a structured Frame → Tunnel → Network → Transport → Application decode plus an xxd-style hex dump of the raw bytes.
  • Flows view: sortable per-connection byte totals, one-second rate, initial TCP RTT (from the SYN / SYN-ACK delta, color-coded by latency), duration, per-flow retransmission and out-of-order rates, service, hostname, owning process, Country, and ASN/organization, with a detail pane and live rate sparkline. Flow keys are canonical, so both directions of a peer-to-peer conversation collapse into a single row.
  • Statistics view: protocol hierarchy, top talkers by bytes, and name-resolution health.
  • Process resolution: the App column in both the packet list and the flows table shows the owning process on Windows (iphlpapi), Linux (/proc/net/* + /proc/<pid>/fd/), and macOS (proc_pidfdinfo). Flows capture the process while the socket is live, so the name persists after a short-lived connection closes. Running elevated widens coverage to other users' processes.
  • Filtering and export: live BPF capture filters such as tcp port 443, a separate display filter over captured packets, PCAP export, and flow export to CSV or JSON.
  • Light and dark themes, adjustable UI scale, and keyboard shortcuts — all persisted between runs.
  • Cross-platform backends: Npcap on Windows and libpcap on Linux/macOS.
Live packet analysis Connection flows Offline PCAP mode
Protocol, hostname, and per-packet hex Rate, service, GeoIP, and ASN No administrator rights required

Tech Stack

NetProbe technology stack: C++20 core surrounded by its FetchContent-pinned dependencies

  • Language: C++20
  • Packet Capture: Npcap SDK (Windows) / libpcap (Linux/macOS)
  • UI Framework: Dear ImGui + GLFW with docking
  • Plotting: ImPlot
  • Crypto (QUIC Initial decryption): Mbed TLS — HKDF-SHA256, AES-128-ECB, AES-128-GCM
  • GeoIP/ASN: libmaxminddb
  • File dialogs: Native File Dialog Extended
  • Build System: CMake (all third-party deps pinned via FetchContent)
  • Tests / fuzzing / analysis: GoogleTest + libFuzzer harness on the protocol parsers + clang-tidy

Prerequisites

NetProbe uses Npcap on Windows and libpcap on Linux/macOS.

  • Windows 10/11: Visual Studio 2022 with C++ Desktop Development, the Npcap driver, and the Npcap SDK extracted to C:\Npcap-SDK (Include and Lib directly inside).
  • Ubuntu/Debian: sudo apt install build-essential cmake libpcap-dev libgl1-mesa-dev libgtk-3-dev pkg-config
  • macOS: Xcode Command Line Tools and CMake. libpcap and OpenGL are provided by macOS; Native File Dialog uses Cocoa.

Build Instructions

# 1. Clone the repository
git clone https://github.com/YehiaGewily/netprobe-cpp.git
cd netprobe-cpp

# 2. Build via Script (Recommended)
.\build_project.bat

On Linux or macOS:

cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build --parallel
ctest --test-dir build --output-on-failure

To create the same ZIP layout used by Releases:

cpack --config build/CPackConfig.cmake -C Release -G ZIP -B package

Optional CMake flags

Flag Default What it does
-DBUILD_TESTING=ON ON when top-level Build the GoogleTest suite (NetProbeTests).
-DENABLE_SANITIZERS=ON OFF Build with -fsanitize=address,undefined (Clang/GCC only).
-DBUILD_FUZZERS=ON OFF Build the libFuzzer harness for the protocol parsers. Requires clang / clang-cl.

Usage

  1. Run the executable from the extracted release ZIP or build output directory.

  2. No admin? Try the sample first. The build emits data/sample.pcap (mixed ARP / DNS / TCP traffic: three resolvable hostnames, each with a full TLS handshake and a measurable RTT). Open it via File → Open PCAP… to exercise the full UI without elevation.

  3. Live capture usually requires elevated privileges. On Windows:

    Start-Process ".\build\Release\NetProbe.exe" -Verb RunAs
  4. Select a live adapter in the menu bar, or choose File → Open PCAP… / drop a PCAP file onto the window.

  5. Use Flows for per-connection activity, or enter a BPF filter such as tcp port 443 in the menu bar.

  6. Click a packet row in Live Packets to populate the Packet Detail pane with the layered decode and hex dump.

For GeoIP and ASN columns, place GeoLite2-Country.mmdb and GeoLite2-ASN.mmdb in data/. See data/README.md.

Headless CLI

netprobe-cli runs the same capture and analysis pipeline with no window, for servers, CI, and SSH sessions. It ships alongside the GUI in every release ZIP.

# List the adapters available for live capture
netprobe-cli --list-devices

# Replay a capture file and export its flows as JSON
netprobe-cli -r capture.pcap -o flows.json

# Capture live for 60 seconds, filtered, exporting CSV
netprobe-cli -i eth0 -f "tcp port 443" --duration 60 -o flows.csv

# Pipe JSON straight into jq
netprobe-cli -r capture.pcap -o - | jq '.flows[] | select(.bytes_down > 100000)'
Flag Purpose
-r, --read <file> Replay an offline capture
-i, --device <name> Capture live from an adapter (needs privileges)
-f, --filter <bpf> BPF capture filter, live capture only
-o, --output <path> Destination file, or - for stdout
--format <json|csv> Override the format inferred from the extension
--duration <sec> Stop after this many seconds, live capture only
--packet-count <n> Stop after this many packets, live capture only
--no-process Skip the owning-process lookup
--list-devices List the capture adapters and exit
-h, --help Show the full usage text and exit
-V, --version Show the version and exit

Ctrl+C stops a live capture and still writes the output. Exit codes are 0 success, 1 usage error, 2 runtime failure, so scripts can tell a bad invocation from a failed capture. Diagnostics go to stderr, which keeps -o - output clean for piping.

Architecture

NetProbe is built around a bounded producer-consumer pipeline. Capture runs on a backend-owned path, while the Dear ImGui frame loop drains packets, enriches them, and updates view models without blocking the capture thread.

Producer-consumer threading: capture thread pushes into a bounded queue, UI thread drains it

Figure 1: Runtime Component Map

NetProbe runtime architecture: capture, core, and UI layers

Figure 2: Packet Decode And Enrichment Pipeline

Packet decode pipeline: link, network, tunnel, transport, and application layers converging into flows

Figure 3: Live Capture Control Flow

Live capture sequence: user starts capture, engine opens device and spawns a thread, queue feeds the UI frame loop

Figure 4: Offline PCAP Path

flowchart LR
    file[".pcap / .pcapng file"] --> open["CaptureEngine::openFile"]
    open --> backend["pcap offline reader"]
    backend --> dlt["Snapshot link type<br/>for correct export DLT"]
    backend --> packets["Read packets until EOF"]
    packets --> session["Retain recent session packets"]
    packets --> queue["Push into PacketQueue"]
    queue --> ui["GuiLayer frame loop"]
    ui --> same["Same parser, DNS/SNI recovery,<br/>flow aggregation, and views as live mode"]
Loading

Main Modules

  • Capture backend (src/capture/): ICaptureBackend hides the Npcap and libpcap implementations. CaptureEngine owns the backend, live capture thread, BPF application, offline reads, and a capped session buffer for PCAP export.
  • Packet queue (src/core/PacketQueue.hpp): thread-safe bounded queue (std::mutex + std::condition_variable). On overflow it drops the oldest packets so the UI stays close to live traffic; the dropped count is surfaced in the control bar.
  • Protocol stack (src/core/):
    • LinkType maps libpcap DLT_* values to supported encapsulations, so cooked, loopback, raw-IP, and Ethernet-family captures are decoded intentionally.
    • ProtocolParser is the stateless fast path: link layer -> IPv4/IPv6 -> tunnel descent -> transport -> application hints and service classification.
    • TlsReassembler buffers split TCP ClientHellos with size and expiry caps.
    • QuicParser decrypts QUIC v1/v2 Initial packets with mbedTLS and extracts TLS ClientHello data from CRYPTO frames.
    • QuicTracker stitches CRYPTO fragments across multiple Initial packets, keyed by connection id.
    • DNSParser extracts DNS/mDNS/LLMNR answers, feeds HostnameCache, and flags advertised ECH configs.
    • FlowAggregator collapses both directions of a conversation into one canonical key, tracks rates and byte totals, and measures initial TCP RTT from SYN/SYN-ACK timing.
    • GeoIPResolver and ProcessResolver add country/ASN and process ownership where platform data is available.
    • AnalysisSession drives the whole per-packet pipeline — decode, cross-packet SNI recovery, DNS harvesting, hostname attribution, process lookup, flow aggregation — and owns the stateful reassemblers, the name cache, and the flow table. The GUI and the headless CLI both run this same object, which is what keeps them from drifting apart.
    • FlowExporter serializes a flow snapshot to CSV or JSON.
  • GUI layer (src/ui/): GuiLayer owns the Dear ImGui dockspace, capture controls, settings, queue drain, and bounded packet history, layered over an AnalysisSession. Dashboard, FlowsView, PacketView, PacketDetail, and StatsView render those derived models.
  • Headless CLI (src/cli/): the same CaptureEngine and AnalysisSession with no window, exporting flows for scripts and pipelines.

Quality

  • 89 unit and integration tests (GoogleTest) covering protocol parsing, link-type handling, tunnel descent, TLS/QUIC ClientHello reassembly, HTTP header extraction, DNS record coverage, canonical flow keying, RTT measurement, queue concurrency, GeoIP lookup, QUIC Initial decryption end-to-end, and both classic-PCAP + PCAPNG fixtures — including an end-to-end test that drives a crafted capture file through the same pipeline the UI runs, and end-to-end tests that run the real netprobe-cli binary over a capture file and validate the exported JSON and CSV.
  • Adversarial input suite: 40 named malformed-packet fixtures — headers claiming lengths the buffer does not contain, IPv4 IHL and total-length lies, IPv6 extension-header chains that overrun or self-reference, DNS compression-pointer loops and inflated record counts, truncated TLS records, QUIC connection-ID and token lengths beyond the packet — plus TCP option lengths of zero and options overrunning their header, and an exhaustive check that every prefix of a valid frame parses without crashing. Each fixture pins the degraded result it must produce, so a parser that starts inventing plausible answers fails the build rather than passing quietly. The same fixtures seed the fuzz corpus, taking it to 44 entries.
  • libFuzzer harness on ProtocolParser::parse, DNSParser::parseResponse, and the stateful TlsReassembler / QuicTracker, across every supported link type, with a deterministic seed corpus. CI fuzzes every push for 60 seconds on Ubuntu + Clang and uploads any crash inputs as build artifacts.
  • AddressSanitizer + UndefinedBehaviorSanitizer CI job runs the full test suite under ASan/UBSan on every push.
  • clang-tidy static analysis in CI over every first-party source, with WarningsAsErrors enabled: the tree is clean, so a new finding fails the build rather than scrolling past in a log. Checks are curated for signal — those that fire constantly on idiomatic code are disabled in .clang-tidy with the reasoning recorded there, rather than silenced case by case.
  • Three-platform CI matrix (Windows / Ubuntu / macOS) builds the app, builds and runs the test suite, and packages release ZIPs via CPack on tag pushes. Windows test runs use a 7-Zip-extracted Npcap user-mode DLL so the kernel-driver install is unnecessary in CI.

Contributing

Contributions are welcome. See CONTRIBUTING.md for build instructions on each platform, how to run the same checks CI runs (tests, sanitizers, clang-tidy, fuzzing), and what review looks for in a tool that parses hostile input. It also lists some good first issues.

License

This project is licensed under the MIT License — see LICENSE for the full text.

About

Cross-platform network traffic analyzer in C++20. Live capture (Npcap on Windows, libpcap on Linux/macOS) and offline PCAP/PCAPNG with QUIC ClientHello SNI decryption, per-flow GeoIP/ASN, initial-RTT, process attribution, BPF filters, and an interactive Dear ImGui dashboard.

Topics

Resources

Contributing

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages