|
PingDD 2.1.0
PingDD is a cross-platform TCP “ping” tool written in C.
|
PingDD is a cross-platform network reachability and diagnostics tool written in C that measures TCP/UDP/ICMP reachability. Where classic ping only answers "is the host up over ICMP," PingDD checks whether the service port is actually open over TCP, UDP, or ICMP, measures handshake latency to microsecond precision, and falls through IPv4/IPv6 addresses automatically. It probes many hosts, ports, protocols at once (sequentially or concurrently), reports min/max/avg, stddev and p50/p95/p99 percentiles, and runs live network-quality diagnostics: downtime, packet loss, jitter, latency spikes, bufferbloat, DNS timing distilled to a one-word HEALTHY/DEGRADED/DOWN verdict. Operator modes add continuous availability monitoring, load testing, and a resilience sweep. It also probes HTTP(S) endpoints (status code, latency, and TLS details over a bundled TLS stack), traces the network path hop by hop, and annotates addresses with reverse DNS and origin ASN. Output is human-colored, NDJSON, CSV, or Prometheus/OpenMetrics for keeping evidence across runs and feeding dashboards. Persistent options live in a small ~/.pingdd config file.
It began as a TCP "ping," which is where the name comes from. It now does considerably more than ping.
Classic ping answers exactly one question: can I reach this host over ICMP? In real troubleshooting, that is almost never the question you actually have. The real questions are:
ICMP answers none of those. A host can happily reply to pings while the service behind it is dead, and plenty of hosts drop ICMP entirely while serving traffic just fine. So PingDD checks the thing you actually care about: the port. It measures how long the connection takes, scores the quality of the path, watches over time, and keeps the evidence in JSON or CSV so you can prove what happened after the fact.
https://) the negotiated TLS version and cipher, over a bundled mbedTLS — no system OpenSSL required.HEALTHY, DEGRADED, or DOWN.--json), or logged to an auto-named file (--json-file) or CSV (--csv) for long runs, plus a Prometheus/OpenMetrics report (--prometheus) for scraping.~/.pingdd config file (or --config FILE) for persistent defaults.NO_COLOR.Install with Winget. It drops PingDD on your PATH automatically.
Grab the latest pingdd-<version>-windows-x86.zip (or -arm64) from the Releases page and unzip pingdd.exe.
Grab the latest binary from the Releases page:
https://github.com/darthdemono/PingDD/releases
If your distro is not in the release list, build it yourself. The only hard dependency is a C compiler and make. HTTPS support is provided by a vendored mbedTLS git submodule, so clone with --recursive (or initialise the submodule afterward).
If you already cloned without --recursive, pull the submodule in first:
Then put the binary on your PATH:
| Option | Description | Required | Default |
|---|---|---|---|
<host> ... | One or more target hostnames/IPs (IPv4 or IPv6) | Yes* | - |
-p, --port P | Port, comma list, or range (e.g. 80,443,8000-8010) | TCP/UDP | - |
-P, --protocol P | Protocol list: TCP, UDP, ICMP (comma-separated) | No | TCP |
-I, --interface X | Bind probes to a source IP or interface name | No | default route |
--target SPEC | Add a host:port/proto target (repeatable) | No | - |
--targets FILE | Read targets from a file, one per line | No | - |
--concurrent | Probe every target in parallel each cycle | No | sequential |
--resolve | Annotate addresses with reverse DNS and origin ASN | No | off |
--tos N | Set the IP ToS byte on probes (0–255) | No | OS default |
--dscp N | Set the DSCP class on probes (0–63) | No | OS default |
-t, --timeout N | Per-probe timeout in milliseconds | No | 1000 |
-c, --count N | Number of checks | No | infinite |
-r, --rate N | Delay between checks, in milliseconds | No | 50 |
-w, --deadline N | Stop after N milliseconds total | No | none |
-q, --quiet | Suppress per-probe lines, print the summary only | No | off |
-a, --audible | Ring the terminal bell on each success | No | off |
--json | Emit machine-readable JSON (implies no color) | No | off |
--json-file | Log NDJSON to an auto-named .json file | No | off |
--csv | Log every attempt to a CSV file | No | off |
--prometheus | Print a Prometheus/OpenMetrics report at the end | No | off |
--config FILE | Load options from a config file | No | ~/.pingdd |
--no-config | Ignore the implicit ~/.pingdd config file | No | off |
--color | Force colored output | No | auto (TTY) |
--no-color | Disable colored output | No | auto (TTY) |
-V, --version | Print the version | No | - |
-?, --help | Print help | No | - |
HTTP(S) and traceroute are separate modes with their own options:
| Option | Description | Mode | Default |
|---|---|---|---|
--http URL | Probe an http:///https:// URL | HTTP | - |
--http-method M | HTTP method for --http | HTTP | GET |
--http-status N | Require this exact status code (else any 2xx/3xx) | HTTP | any 2xx/3xx |
--traceroute | Trace the network path to a single target | Traceroute | - |
--max-hops N | Maximum hops to probe | Traceroute | 30 |
--queries N | Probes sent per hop | Traceroute | 3 |
--target or --targets works too. Give it several hosts, a port list or range, and a protocol list, and PingDD expands the combination into a full host × port × protocol matrix. ICMP targets ignore the port. Every target keeps its own statistics and diagnostics, and you get a combined roll-up at the end.Color is automatic: on when output is a terminal, off when it is piped or when the NO_COLOR environment variable is set.
ICMP mode uses no port, so -p is optional there. ICMP may need elevated privileges (CAP_NET_RAW) on systems that do not allow unprivileged ICMP datagram sockets.
PingDD does not just count drops; it tries to tell you whether a drop means anything.
A single failed probe surrounded by successes is noise. A network has bad seconds. So PingDD only calls a target DOWN after several consecutive failures, and it tracks how long the outage lasted and how many times it happened. One lost packet is not an outage. Three in a row is.
The summary grades the link from loss, jitter, and latency, estimates bufferbloat from how far the slow probes drift above the baseline, and times the DNS lookup separately so a slow resolver does not get blamed on the network. The result is a one-word verdict, HEALTHY, DEGRADED, or DOWN, plus the numbers behind it. With --monitor it also prints an availability percentage.
PingDD has three modes aimed at operators rather than one-off checks.
| Mode | Flag | What it does |
|---|---|---|
| Availability | --monitor | Probes continuously, raises outage and recovery alerts, reports uptime. |
| Load test | --load-test | Opens sustained concurrent connections to measure behavior under load. |
| Resilience | --resilience | Ramps concurrency in steps and reports where the service starts to degrade. |
Load-test and resilience take --concurrency N (1–256) and --duration N (seconds, 1–3600).
A word on what PingDD is not. It is not a DoS tool, and it will not become one. There is no packet flooding, no amplification, no reflection, no spoofing, and no filter bypass. None of it, by design. Load testing exists to measure your own service under pressure, nothing else. Concurrency is capped at 256 and duration at one hour. Use it on systems you own or have written permission to test. The rest is on you.
Check port 80 a hundred times:
Slow it down to one check every 500 milliseconds:
Log every attempt to CSV:
Probe two hosts across a port range and two protocols at once:
Compare the same target over wifi and ethernet by binding the source interface:
Probe explicit targets in parallel, or read them from a file:
A TCP connect tells you a port is open; it does not tell you the service behind it is healthy. --http goes one layer up: it sends a real HTTP request and parses the status line, so you learn whether the service actually answers.
For https:// URLs PingDD performs the TLS handshake with a bundled mbedTLS and reports the negotiated protocol version and cipher suite alongside the status and timing. The connection is treated as a reachability/diagnostic probe: the certificate chain is not verified, so do not rely on --http as a security check. A probe counts as a success when the status matches --http-status, or, if that is not set, when it is any 2xx/3xx.
--traceroute discovers the path to a single target by sending probes with an increasing TTL/hop-limit and recording the router that returns each "time exceeded" message. It works over IPv4 and IPv6 and defaults to ICMP, so no port is required.
On POSIX this needs a raw socket, so run it as root or grant CAP_NET_RAW to the binary. On Windows it uses the IP Helper API and needs no special privilege. Pass --resolve to reverse-resolve each hop to a name.
--resolve enriches each resolved address with its reverse-DNS (PTR) name and its origin Autonomous System, looked up through the Team Cymru IP-to-ASN service. It needs outbound DNS and is therefore opt-in.
The same data appears as rdns, asn, and asn_org fields in the JSON target line.
Persistent defaults can live in ~/.pingdd, or any file passed with --config FILE. It is a simple key = value list; lines beginning with # or ; are comments. Precedence is built-in defaults < config file < command-line flags, so a flag always wins over the file. Pass --no-config to ignore the implicit ~/.pingdd.
Recognised keys mirror the long options: port, protocol, interface, timeout, count, rate, deadline, color, quiet, audible, json, csv, concurrent, resolve, and tos. An unknown key is an error, so typos are not silently ignored.
With --csv, PingDD writes a timestamped file and records one row per successful probe:
IPAddress is the address actually probed, not just the first one resolved, so when fail-over picks a different address the log shows the truth. Feed the file to whatever you graph with, compare it against another network, or keep it as a record for the next time someone insists the service "was never down."
By default the output is colored and human-readable. Two alternatives exist for everything else:
--csv keeps a row per success, as above.--json prints one JSON object per probe plus a summary and a diagnostics object, with color disabled. It is line-delimited, so you can pipe it straight into jq or anything that reads NDJSON. --json-file logs the same NDJSON to an auto-named file.--prometheus prints a Prometheus/OpenMetrics exposition at the end of the run (pingdd_up, pingdd_probes_total, pingdd_failures_total, pingdd_loss_ratio, and pingdd_rtt_seconds), one series per target with target/host/ip/proto/port labels. Point it at a file for the node_exporter textfile collector, or scrape it via Pushgateway.The makefile targets Windows (x86 and ARM64) and Linux (x86_64, ARM, ARM64).
Cross-compiling needs the matching toolchain (i686-w64-mingw32-gcc for Windows, aarch64-linux-gnu-gcc for Linux ARM64, and so on). The Windows targets also need a resource compiler; the makefile finds windres on its own, whether it is the plain windres from MSYS2 or the cross-prefixed one from a Linux mingw package. Every target builds the vendored mbedTLS submodule in, so make sure it is checked out (git submodule update --init --recursive).
The makefile carries a set of quality targets in addition to the build:
CI runs these on every change to src/, tests/, the makefile, or the mbedTLS submodule.
PingDD keeps the code straightforward and readable. It prefers predictable behavior, clean output, and portability over clever tricks. Changes that improve reliability and cross-platform correctness win over changes that just look smart.
"An idiot admires complexity, a genius admires simplicity" — Terry A. Davis
Contributions are welcome.
MIT License. See LICENSE.