--- # README.md ````markdown # WTFnet **WTFnet** is a pure CLI toolbox for diagnosing network problems on **Linux (Debian/Ubuntu)** and **Windows**. > _"What the f\*ck is my networking doing?"_ It combines system network inspection, port/process visibility, DNS poisoning checks, HTTP/TLS diagnostics, GeoIP enrichment, ARP/NDP neighbor tables, and lightweight discovery tools — all in one consistent CLI. ## Goals - **Pure CLI** (no REPL / no TUI) - **Fast + scriptable** output (`--json` supported everywhere) - **First-class support:** Linux (Debian/Ubuntu), Windows - **Rust implementation** - **Graceful degradation** when OS APIs differ or privileges are missing ## Quickstart ### Show interfaces & IPs ```bash wtfnet sys ifaces wtfnet sys ip --all wtfnet sys route ```` ### Find which process owns port 443 ```bash wtfnet ports who 443 wtfnet ports listen --tcp ``` ### DNS poisoning detection (multi-resolver compare) ```bash wtfnet dns detect example.com wtfnet dns detect example.com --servers 1.1.1.1,8.8.8.8,9.9.9.9 --repeat 3 ``` ### HTTP + TLS diagnostics ```bash wtfnet http head https://example.com --show-headers --http2-only wtfnet tls handshake example.com:443 --show-chain wtfnet tls verify example.com:443 ``` ### GeoIP lookup (local GeoLite2 DBs) ```bash wtfnet geoip 8.8.8.8 wtfnet probe tcping example.com:443 --geoip ``` ### Neighbor table (ARP / NDP) ```bash wtfnet neigh list wtfnet neigh list --ipv4 wtfnet neigh list --ipv6 ``` ### Generate a diagnostic report bundle ```bash wtfnet diag --bundle out.zip ``` ## Output modes * Default: readable tables / summaries * Machine-readable: `--json` * Pretty JSON: `--json --pretty` * Logs go to **stderr** (JSON output stays clean) Example: ```bash wtfnet sys ip --json --pretty > ip.json ``` ## Logging ```bash wtfnet --log-level debug sys route wtfnet --log-format json sys dns wtfnet --log-file wtfnet.log diag ``` Environment variables: * `NETTOOL_LOG_LEVEL` * `NETTOOL_LOG_FORMAT` * `NETTOOL_LOG_FILE` ## License TBD ```` --- # REQUIREMENTS.md ```markdown # WTFnet — Requirements (v0.2) ## 1. Product overview ### 1.1 Purpose WTFnet is a **single-executable CLI toolbox** for diagnosing network problems: - inspect IP/interface/route/DNS - probe connectivity (ICMP/TCP/path) - detect **DNS poisoning** - inspect **trusted root certificates** - map **listening ports → processes** - run **HTTP/TLS diagnostics** - view **ARP/NDP neighbor cache** - perform lightweight **service discovery** - export a consistent report bundle for incident response ### 1.2 Design goals - Pure CLI: no REPL / no TUI - Script-friendly: stable output & exit codes - First-class support: **Linux (Debian/Ubuntu)** + **Windows** - Rust implementation - Works without admin where possible; warns clearly when privileges required --- ## 2. Platform support ### 2.1 First-class OS targets - Linux: Debian / Ubuntu - Windows 10/11 + Windows Server ### 2.2 Best-effort targets - macOS (not required for v0.x) --- ## 3. CLI UX requirements ### 3.1 Global flags All commands MUST support: - `--json` (machine output) - `--pretty` (pretty JSON) - `--no-color` - `--quiet` - `-v`, `-vv` (verbosity) - logging flags (see §4) ### 3.2 Exit codes - `0`: success - `1`: generic failure - `2`: invalid args - `3`: insufficient permissions - `4`: timeout/unreachable category - `5`: partial success (some checks failed; still produced results) --- ## 4. Logging requirements ### 4.1 Goals - Debug WTFnet itself in production environments - Preserve clean stdout for piping / JSON mode ### 4.2 Behavior - Logs MUST go to **stderr** - Command output MUST go to **stdout** - JSON output must remain valid even with debug logs enabled ### 4.3 Controls Flags: - `--log-level ` (default `info`) - `--log-format ` (default `text`) - `--log-file ` (optional; write logs there; may also tee stderr) Env vars: - `NETTOOL_LOG_LEVEL` - `NETTOOL_LOG_FORMAT` - `NETTOOL_LOG_FILE` ### 4.4 Sensitive logging policy - Do NOT log secrets by default (tokens, cookies, passwords) - HTTP response bodies are hidden by default - Provide explicit `--show-secrets` / `--show-body` gates where relevant --- ## 5. Functional requirements ### 5.1 System inspection (`sys`) #### 5.1.1 Interfaces & addresses Must provide: - interface name/index, state, MTU, MAC - IPv4/IPv6 addresses with prefix + scope - DNS servers + search domains (best-effort) - default gateway mapping (best-effort) Commands: - `wtfnet sys ifaces` - `wtfnet sys ip --all` - `wtfnet sys route` - `wtfnet sys dns` #### 5.1.2 Routing table Outputs: - destination/prefix, gateway/next hop, interface, metric --- ### 5.2 Certificate inspection (`cert`) Must list system-wide trusted roots: - subject, issuer - validity range - serial number - SHA1 + SHA256 fingerprint - key algorithm + size - OS store origin (Windows store / Linux path) Commands: - `wtfnet cert roots` - `wtfnet cert roots --filter subject="DigiCert"` - `wtfnet cert roots --export baseline.json` - `wtfnet cert roots --diff baseline.json` --- ### 5.3 Active probing (`probe`) #### 5.3.1 ping - IPv4/IPv6 - count/timeout/interval - summary: min/avg/max latency, packet loss #### 5.3.2 tcping - hostname or IP:port - resolution result - connect latency - failure classification #### 5.3.3 trace - hop list with RTT and IP - IPv4/IPv6 best-effort #### 5.3.4 GeoIP enrichment integration All probe commands must support: - `--geoip` to attach GeoIP info to targets/resolved IPs/hops --- ### 5.4 GeoIP (`geoip`) #### 5.4.1 Local DB support (GeoLite2 Country + ASN) - Country DB + ASN DB used offline - degrade gracefully if missing DB configuration: - flags: - `--country-db ` - `--asn-db ` - env vars: - `NETTOOL_GEOIP_COUNTRY_DB` - `NETTOOL_GEOIP_ASN_DB` Commands: - `wtfnet geoip ` - `wtfnet geoip status` Outputs: - country + ISO code if available - ASN number + org name - DB source/version timestamp if detectable --- ### 5.5 DNS diagnostics (`dns`) #### 5.5.1 Query Commands: - `wtfnet dns query [--server ] [--tcp]` Outputs: - rcode, answer set + TTL, timing, server used #### 5.5.2 Active poisoning detection Commands: - `wtfnet dns detect example.com` - `wtfnet dns detect example.com --servers 1.1.1.1,8.8.8.8 --repeat 5` Heuristics to flag suspicious: - major answer divergence across resolvers - abnormal TTL patterns - unexpected private/reserved results - NXDOMAIN injection patterns Output verdict: - `clean | suspicious | inconclusive` with evidence list #### 5.5.3 Passive watch (best-effort) Commands: - `wtfnet dns watch --duration 30s [--iface eth0] [--filter example.com]` Must: - be time-bounded - clearly document privilege requirements (pcap) --- ### 5.6 Ports & processes (`ports`) Must show listening sockets and owners: - proto, local addr:port, state - PID, PPID (best-effort), process name/path - user/owner (best-effort) Commands: - `wtfnet ports listen --tcp|--udp` - `wtfnet ports who ` (Optional) - `wtfnet ports conns` --- ### 5.7 Subnet calculator (`calc`) Commands: - `wtfnet calc subnet ` - `wtfnet calc contains ` - `wtfnet calc overlap ` - `wtfnet calc summarize ...` --- ### 5.8 HTTP diagnostics (`http`) Goals: - verify endpoint health and protocol negotiation - help debug redirect loops, TLS errors, HTTP version issues Commands: - `wtfnet http head ` - `wtfnet http get ` Flags: - `--http1-only` - `--http2-only` - `--http3` (best-effort optional) - `--timeout 3s` - `--follow-redirects [N]` - `--header "K: V"` (repeatable) - `--show-headers` - `--show-body` (off by default) - `--max-body ` - `--geoip` Required outputs: - resolved IP(s) - negotiated HTTP version (1.1/2/3) - status code - optional headers/body - timing breakdown (best-effort): - DNS - connect / QUIC handshake - TLS handshake - TTFB - total --- ### 5.9 TLS diagnostics (`tls`) Commands: - `wtfnet tls handshake ` - `wtfnet tls cert ` - `wtfnet tls verify ` - `wtfnet tls alpn ` Flags: - `--sni ` - `--alpn h2,http/1.1` - `--insecure` - `--show-chain` - `--geoip` Outputs: - TLS version + cipher - ALPN negotiated - chain summary (subject/issuer/validity/SAN best-effort) - verification verdict + error category --- ### 5.10 Neighbor table (`neigh`) Commands: - `wtfnet neigh list [--ipv4|--ipv6] [--iface eth0]` Outputs: - IP → MAC/LLADDR mapping - interface - state (reachable/stale/failed if available) --- ### 5.11 Discovery services (`discover`) Purpose: lightweight local discovery, bounded and safe. Commands: - `wtfnet discover mdns --duration 3s` - `wtfnet discover ssdp --duration 3s` (optional) - `wtfnet discover llmnr --duration 3s` - `wtfnet discover nbns --duration 3s` Outputs: - service/device name - IP/port if present - protocol and service type --- ### 5.12 Diagnostic bundle (`diag`) Commands: - `wtfnet diag` - `wtfnet diag --out report.json --json` - `wtfnet diag --bundle out.zip` Bundle must include: - sys snapshot - routes - dns config + optional detect check - ports listen - neighbor snapshot - meta.json (OS, version, timestamp, privilege hints) --- ## 6. Non-functional requirements - robust error handling (no panics) - partial results allowed (exit code `5`) - no indefinite hangs (timeouts everywhere) - privacy: never exfiltrate data; don’t log secrets by default --- ## 7. Acceptance criteria (v0.2) On Linux (Debian/Ubuntu) and Windows: - sys inspection works - cert roots listing/filter works - ping + tcping works (IPv4/IPv6 best-effort) - dns query + detect works with verdict+evidence - ports listen/who works (best-effort PID mapping) - http head/get works with HTTP/2 support - tls handshake/verify works with clear output - neigh list works (ARP/NDP snapshot) - logging behaves correctly without breaking JSON output ```` --- # COMMANDS.md ````markdown # WTFnet — Command Reference This file documents WTFnet CLI commands and flags. ## Global flags Applies to all commands: - `--json` : machine-readable output - `--pretty` : pretty JSON (requires `--json`) - `--no-color` : disable ANSI color - `--quiet` : minimal output - `-v`, `-vv` : verbose output - `--log-level ` - `--log-format ` - `--log-file ` Exit codes: see `REQUIREMENTS.md` --- ## sys ### `wtfnet sys ifaces` Show interface inventory. ### `wtfnet sys ip [--all] [--iface ]` Show IP addresses. ### `wtfnet sys route [--ipv4|--ipv6] [--to ]` Show routing table; optionally “route-to target”. ### `wtfnet sys dns` Show resolver configuration snapshot. --- ## cert ### `wtfnet cert roots` List trusted root certificates. Common filters: - `--filter subject="..."` - `--expired` - `--fingerprint ` Baseline tools: - `--export ` - `--diff ` --- ## probe ### `wtfnet probe ping [--count N] [--timeout 800ms] [--interval 200ms] [--geoip]` ICMP echo with stats. ### `wtfnet probe tcping [--count N] [--timeout 800ms] [--geoip]` TCP connect timing. ### `wtfnet probe trace [--max-hops N] [--timeout 800ms] [--geoip]` Traceroute-like path discovery. --- ## geoip ### `wtfnet geoip [--resolve]` Geo lookup (offline DB). ### `wtfnet geoip status` Show DB presence and detected paths. DB flags: - `--country-db ` - `--asn-db ` Env vars: - `NETTOOL_GEOIP_COUNTRY_DB` - `NETTOOL_GEOIP_ASN_DB` --- ## dns ### `wtfnet dns query [--server ] [--tcp] [--timeout 2s]` Dig-like query. Examples: ```bash wtfnet dns query example.com A wtfnet dns query example.com AAAA --server 1.1.1.1 wtfnet dns query example.com A --tcp ```` ### `wtfnet dns detect [--servers ] [--repeat N] [--timeout 2s]` Compare across resolvers and detect anomalies. ### `wtfnet dns watch [--iface ] [--duration 30s] [--filter ]` Passive watch (best-effort; may require privileges). --- ## ports ### `wtfnet ports listen [--tcp|--udp] [--port N]` Show listening sockets. ### `wtfnet ports who ` Find owning process. (Optional) ### `wtfnet ports conns [--top N]` Show active connections. --- ## calc ### `wtfnet calc subnet ` Subnet information. ### `wtfnet calc contains ` Containment check. ### `wtfnet calc overlap ` Overlap check. ### `wtfnet calc summarize ` Summarize multiple networks. --- ## http ### `wtfnet http head ` ### `wtfnet http get ` Core flags: * `--http1-only` * `--http2-only` * `--http3` (best-effort) * `--timeout 3s` * `--follow-redirects [N]` * `--header "K: V"` (repeatable) * `--show-headers` * `--show-body` * `--max-body ` * `--geoip` Examples: ```bash wtfnet http head https://example.com --http2-only --show-headers wtfnet http get https://example.com --follow-redirects 5 ``` --- ## tls ### `wtfnet tls handshake ` ### `wtfnet tls cert ` ### `wtfnet tls verify ` ### `wtfnet tls alpn ` Flags: * `--sni ` * `--alpn h2,http/1.1` * `--insecure` * `--show-chain` * `--geoip` Examples: ```bash wtfnet tls handshake example.com:443 --show-chain wtfnet tls verify example.com:443 ``` --- ## neigh ### `wtfnet neigh list [--ipv4|--ipv6] [--iface ]` Show neighbor table (ARP/NDP). --- ## discover ### `wtfnet discover mdns --duration 3s` ### `wtfnet discover ssdp --duration 3s` (Optional) ### `wtfnet discover llmnr --duration 3s` ### `wtfnet discover nbns --duration 3s` --- ## diag ### `wtfnet diag [--json] [--out ]` Generate report. ### `wtfnet diag --bundle ` Export support bundle. Examples: ```bash wtfnet diag --json --pretty --out report.json wtfnet diag --bundle out.zip ``` ```` --- # CONFIG.md ```markdown # WTFnet — Configuration WTFnet supports configuration via: Priority order: 1) CLI flags 2) Environment variables 3) Config file (optional) 4) Built-in defaults ## Config file location (proposed) Linux: - `$XDG_CONFIG_HOME/wtfnet/config.json` - fallback: `~/.config/wtfnet/config.json` Windows: - `%APPDATA%\wtfnet\config.json` ## Example config.json ```json { "geoip": { "country_db": "/opt/geoip/GeoLite2-Country.mmdb", "asn_db": "/opt/geoip/GeoLite2-ASN.mmdb" }, "dns": { "detect_servers": ["1.1.1.1", "8.8.8.8", "9.9.9.9"], "timeout_ms": 2000, "repeat": 3 }, "probe": { "timeout_ms": 800, "count": 4 }, "http": { "timeout_ms": 3000, "follow_redirects": 3, "max_body_bytes": 8192 }, "logging": { "level": "info", "format": "text", "file": null } } ```` ## Environment variables GeoIP: * `NETTOOL_GEOIP_COUNTRY_DB` * `NETTOOL_GEOIP_ASN_DB` Logging: * `NETTOOL_LOG_LEVEL` * `NETTOOL_LOG_FORMAT` * `NETTOOL_LOG_FILE` ```` --- # OUTPUT_SCHEMA.md ```markdown # WTFnet — JSON Output Conventions All commands support `--json`. ## General rules - Output must be valid JSON to stdout - Logs always go to stderr - Prefer stable keys; changes should be additive - Include metadata about tool version + timestamp ## Common wrapper schema (recommended) ```json { "meta": { "tool": "wtfnet", "version": "0.2.0", "timestamp": "2026-01-15T22:01:00-05:00", "os": "linux|windows", "arch": "x86_64", "privileges": { "is_admin": false, "notes": ["pcap capture requires elevated privileges"] } }, "command": { "name": "sys ip", "args": ["--all"] }, "data": {}, "warnings": [], "errors": [] } ```` ## Error representation * `errors[]` should contain structured objects: ```json { "code": "PERMISSION_DENIED|TIMEOUT|NOT_SUPPORTED|IO_ERROR", "message": "Human readable explanation", "details": { "hint": "Try running as admin" } } ``` ## Timing fields (for probe/http/tls) Use milliseconds: ```json { "timing_ms": { "dns_resolve": 12, "connect": 40, "tls_handshake": 55, "ttfb": 70, "total": 120 } } ``` ```` --- # ROADMAP.md ```markdown # WTFnet — Roadmap ## v0.1 (MVP) Focus: core sysadmin essentials - sys: ifaces/ip/route/dns - ports: listen/who - probe: ping + tcping - calc: subnet/contains/overlap - basic logging + --json everywhere ## v0.2 (this requirements set) - dns: query + detect + watch (best-effort) - geoip: local Country+ASN mmdb integration - http: head/get (HTTP/2 required; HTTP/3 best-effort optional) - tls: handshake/verify/cert/alpn - neigh: ARP/NDP snapshot - discover: mdns + ssdp (bounded) - diag: bundle export (zip) ## v0.3 (future upgrades) - richer trace output (reverse lookup, per-hop loss) - TLS extras: OCSP stapling indicator, more chain parsing - ports conns improvements (top talkers / summary) - better baseline/diff for system roots - smarter “diagnose ” workflow mode ```` --- # SECURITY.md ```markdown # WTFnet — Security & Privacy Notes ## Data handling - WTFnet performs local inspections and probes. - It does not upload anything automatically. ## Sensitive output defaults - HTTP bodies are not printed by default. - Secrets (Authorization/Cookies) are never logged by default. ## Capture-based features Some features (e.g. passive DNS watch) may require elevated privileges. WTFnet must clearly indicate when a feature is: - unavailable - permission-limited - OS-limited ``` --- # docs/platform-notes.md ```markdown # Platform Notes ## Linux (Debian/Ubuntu) - sys: netlink (/proc, /sys) sources - neigh: `ip neigh` equivalent via netlink - ports: `/proc/net/*` + process mapping ## Windows - sys: Win32 APIs (IP Helper API etc.) - ports/process mapping: Windows APIs (best-effort) - cert roots: Windows certificate store APIs ``` --- # docs/troubleshooting.md ```markdown # Troubleshooting ## `dns watch` shows permission errors Passive capture may require elevated privileges or pcap capabilities. Run as admin/root or configure capture permissions appropriately. ## `ping` not working without admin Some OS configurations restrict ICMP sockets. Use: - `wtfnet probe tcping ` as an alternative reachability test. ``` ---