netchecker
A fast, cross-platform internet reachability checker. It probes your local
network infrastructure, DNS resolution, and a set of domestic / global /
filtered websites in parallel, and reports each as PASS / FAIL / INFO
with timings — in about 1–2 seconds total.
It was built for diagnosing a specific, annoying situation: "my internet is technically up, but which parts actually work — the ISP, DNS, the proxy, the filtered sites?" It's especially useful behind a VPN/proxy where the answer differs per route.
===============================================
netchecker — Network Standpoint Test
Running Mode: DIRECT
Local IP: 192.168.1.6
DNS resolvers: 192.168.1.1
Per-probe timeout: 2 seconds
===============================================
[*] Dispatching parallel probes...
[+] Infrastructure Standpoints:
[PASS] Local Network Interface - Active on en0 (192.168.1.6) — Wi-Fi SSID: home
[PASS] Ping Default Gateway (192.168.1.1) - reachable — 2 ms
[PASS] Ping Raw Global IP (1.1.1.1) - Global IP routing up — 4 ms
[+] DNS Resolution:
[PASS] www.google.com - Resolved to 142.251.153.119 — 21 ms
...
[*] Domestic Websites (DIRECT Route):
[PASS] digikala.com - HTTP 301 — 119 ms
...
Install
Or build from source:
Usage
- Direct mode pins every request to a pre-resolved IP and bypasses all proxies — it tests your raw ISP path.
- Proxy mode sends the global/filtered sites through your system proxy (auto-detected). Domestic sites always go direct.
How it works (and why)
-
DNS that can't wedge. On macOS,
getaddrinfo()goes through mDNSResponder; when the local resolver is bad or was just changed, that daemon serialises lookups and collapses "parallel" probes into a long stall. netchecker resolves names itself with [hickory-resolver], which talks to the configured nameservers directly over UDP/53 and never touches the OS resolver. A bad lookup fails fast instead of hanging everything. -
IP-pinned probes. On the direct route, each HTTP probe is handed the pre-resolved IP so it never calls the OS resolver — the same anti-wedge guarantee, end to end. Redirects aren't followed on the direct route (a cross-host redirect would trigger a fresh OS lookup); a
3xxstill counts as reachable. -
Reachability without root. No ICMP (which needs elevated privileges). netchecker uses TCP connects and races a few common ports — a
ConnectionRefusedstill proves the host answered, so it counts as reachable. Only a host that fails on every port is reported down. -
True egress detection. The active interface is found by asking the kernel which local address it would use to reach the internet (a UDP
connectthat sends nothing), not by a heuristic. This gets the right answer on split-tunnel VPNs, where the "default route" and the real internet path differ.
Platform support
The core — DNS bypass, HTTP probes, interface/gateway detection, TCP reachability — is native Rust and works the same on all three platforms:
| Feature | macOS | Linux | Windows |
|---|---|---|---|
| Infrastructure / DNS / probes | ✅ | ✅ | ✅ |
| Egress interface + gateway | ✅ | ✅ | ✅ |
| System proxy detection | ✅¹ | env² | env² |
| Wi-Fi SSID | ⚠️³ | ⚠️⁴ | ⚠️⁵ |
- Reads
scutil --proxy(catches GUI-configured proxies) plus env vars. - Reads
HTTPS_PROXY/ALL_PROXY/HTTP_PROXYenv vars. - Best-effort via
ipconfig/networksetup; on macOS 14+ the SSID is gated behind Location Services permission and may come back empty. - Best-effort via
nmcli/iwgetid(NetworkManager). - Best-effort via
netsh wlan show interfaces.
SSID is the one genuinely fragile piece — there is no dependable cross-platform API for it. When it can't be read, netchecker shows "SSID unavailable or wired" rather than failing.
Customising the site list
The domestic / global / filtered lists live in src/sites.rs.
Edit them to match the sites you care about and rebuild.
License
MIT — see LICENSE.