Add: description in help message
This commit is contained in:
37
README.md
37
README.md
@@ -73,41 +73,8 @@ wtfn calc overlap 10.0.0.0/24 10.0.1.0/24
|
||||
wtfn calc summarize 10.0.0.0/24 10.0.1.0/24
|
||||
```
|
||||
|
||||
## Supported flags
|
||||
Global flags:
|
||||
- `--json` / `--pretty`
|
||||
- `--no-color` / `--quiet`
|
||||
- `-v` / `-vv` / `--verbose`
|
||||
- `--log-level <error|warn|info|debug|trace>`
|
||||
- `--log-format <text|json>`
|
||||
- `--log-file <path>`
|
||||
- `NETTOOL_LOG_FILTER` or `RUST_LOG` can override log filters (ex: `maxminddb::decoder=debug`)
|
||||
|
||||
Command flags (implemented):
|
||||
- `sys ip`: `--all`, `--iface <name>`
|
||||
- `sys route`: `--ipv4`, `--ipv6`, `--to <ip>`
|
||||
- `ports listen`: `--tcp`, `--udp`, `--port <n>`
|
||||
- `neigh list`: `--ipv4`, `--ipv6`, `--iface <name>`
|
||||
- `ports conns`: `--top <n>`, `--by-process`
|
||||
- `cert baseline`: `<path>`
|
||||
- `cert diff`: `<path>`
|
||||
- `probe ping`: `--count <n>`, `--timeout-ms <n>`, `--interval-ms <n>`, `--no-geoip`
|
||||
- `probe tcping`: `--count <n>`, `--timeout-ms <n>`, `--socks5 <url>`, `--prefer-ipv4`, `--no-geoip`
|
||||
- `probe trace`: `--max-hops <n>`, `--per-hop <n>`, `--timeout-ms <n>`, `--udp`, `--port <n>`, `--rdns`, `--no-geoip`
|
||||
- `dns query`: `--server <ip[:port]>`, `--transport <udp|tcp|dot|doh>`, `--tls-name <name>`, `--socks5 <url>`, `--prefer-ipv4`, `--timeout-ms <n>`
|
||||
- `dns detect`: `--servers <csv>`, `--transport <udp|tcp|dot|doh>`, `--tls-name <name>`, `--socks5 <url>`, `--prefer-ipv4`, `--repeat <n>`, `--timeout-ms <n>`
|
||||
- `dns watch`: `--duration <Ns|Nms>`, `--iface <name>`, `--filter <pattern>`
|
||||
- `dns leak status`: `--profile <full-tunnel|proxy-stub|split>`, `--policy <path>`
|
||||
- `dns leak watch`: `--duration <Ns|Nms>`, `--iface <name>`, `--profile <full-tunnel|proxy-stub|split>`, `--policy <path>`, `--privacy <full|redacted|minimal>`, `--out <path>`, `--summary-only`
|
||||
- `dns leak watch`: `--iface-diag` (prints capture-capable interfaces)
|
||||
- `dns leak report`: `<path>`, `--privacy <full|redacted|minimal>`
|
||||
- `http head|get`: `--timeout-ms <n>`, `--follow-redirects <n>`, `--show-headers`, `--show-body`, `--max-body-bytes <n>`, `--http1-only`, `--http2-only`, `--http3` (feature `http3`), `--http3-only` (feature `http3`), `--geoip`, `--socks5 <url>`
|
||||
- `tls handshake|cert|verify|alpn`: `--sni <name>`, `--alpn <csv>`, `--timeout-ms <n>`, `--insecure`, `--socks5 <url>`, `--prefer-ipv4`, `--show-extensions`, `--ocsp`
|
||||
- `discover mdns`: `--duration <Ns|Nms>`, `--service <type>`
|
||||
- `discover ssdp`: `--duration <Ns|Nms>`
|
||||
- `discover llmnr`: `--duration <Ns|Nms>`, `--name <host>`
|
||||
- `discover nbns`: `--duration <Ns|Nms>`
|
||||
- `diag`: `--out <path>`, `--bundle <path>`, `--dns-detect <domain>`, `--dns-timeout-ms <n>`, `--dns-repeat <n>`
|
||||
## Command reference
|
||||
See `docs/COMMANDS.md` for the full list of commands and flags (with descriptions).
|
||||
|
||||
## GeoIP data files
|
||||
GeoLite2 mmdb files should live in `data/`.
|
||||
|
||||
@@ -16,21 +16,21 @@ use wtfnet_platform::{Platform, PlatformError};
|
||||
arg_required_else_help = true
|
||||
)]
|
||||
struct Cli {
|
||||
#[arg(long)]
|
||||
#[arg(long, help = "Emit JSON output")]
|
||||
json: bool,
|
||||
#[arg(long)]
|
||||
#[arg(long, help = "Pretty-print JSON output")]
|
||||
pretty: bool,
|
||||
#[arg(long)]
|
||||
#[arg(long, help = "Disable ANSI colors")]
|
||||
no_color: bool,
|
||||
#[arg(long)]
|
||||
#[arg(long, help = "Reduce stdout output")]
|
||||
quiet: bool,
|
||||
#[arg(short = 'v', long = "verbose", action = clap::ArgAction::Count)]
|
||||
#[arg(short = 'v', long = "verbose", action = clap::ArgAction::Count, help = "Increase log verbosity (-v, -vv)")]
|
||||
verbose: u8,
|
||||
#[arg(long)]
|
||||
#[arg(long, help = "Set log level (error|warn|info|debug|trace)")]
|
||||
log_level: Option<String>,
|
||||
#[arg(long)]
|
||||
#[arg(long, help = "Set log format (text|json)")]
|
||||
log_format: Option<String>,
|
||||
#[arg(long)]
|
||||
#[arg(long, help = "Write logs to a file")]
|
||||
log_file: Option<PathBuf>,
|
||||
#[command(subcommand)]
|
||||
command: Commands,
|
||||
@@ -38,98 +38,130 @@ struct Cli {
|
||||
|
||||
#[derive(Subcommand, Debug)]
|
||||
enum Commands {
|
||||
/// System snapshot: interfaces, IPs, routes, DNS
|
||||
Sys {
|
||||
#[command(subcommand)]
|
||||
command: SysCommand,
|
||||
},
|
||||
/// Ports and socket ownership
|
||||
Ports {
|
||||
#[command(subcommand)]
|
||||
command: PortsCommand,
|
||||
},
|
||||
/// Neighbor table (ARP/NDP)
|
||||
Neigh {
|
||||
#[command(subcommand)]
|
||||
command: NeighCommand,
|
||||
},
|
||||
/// Certificate roots and baselines
|
||||
Cert {
|
||||
#[command(subcommand)]
|
||||
command: CertCommand,
|
||||
},
|
||||
/// GeoIP lookup helpers
|
||||
Geoip {
|
||||
#[command(subcommand)]
|
||||
command: GeoIpCommand,
|
||||
},
|
||||
/// Probing tools (ping/tcping/trace)
|
||||
Probe {
|
||||
#[command(subcommand)]
|
||||
command: ProbeCommand,
|
||||
},
|
||||
/// DNS query, detect, watch, and leak detection
|
||||
Dns {
|
||||
#[command(subcommand)]
|
||||
command: DnsCommand,
|
||||
},
|
||||
/// Subnet calculator
|
||||
Calc {
|
||||
#[command(subcommand)]
|
||||
command: CalcCommand,
|
||||
},
|
||||
/// HTTP head/get diagnostics
|
||||
Http {
|
||||
#[command(subcommand)]
|
||||
command: HttpCommand,
|
||||
},
|
||||
/// TLS handshake and certificate analysis
|
||||
Tls {
|
||||
#[command(subcommand)]
|
||||
command: TlsCommand,
|
||||
},
|
||||
/// Local network discovery (mDNS/SSDP/LLMNR/NBNS)
|
||||
Discover {
|
||||
#[command(subcommand)]
|
||||
command: DiscoverCommand,
|
||||
},
|
||||
/// Bundle a diagnostic report
|
||||
Diag(DiagArgs),
|
||||
}
|
||||
|
||||
#[derive(Subcommand, Debug)]
|
||||
enum SysCommand {
|
||||
/// List network interfaces
|
||||
Ifaces,
|
||||
/// Show IP addresses
|
||||
Ip(SysIpArgs),
|
||||
/// Show route table
|
||||
Route(SysRouteArgs),
|
||||
/// Show DNS configuration
|
||||
Dns,
|
||||
}
|
||||
|
||||
#[derive(Subcommand, Debug)]
|
||||
enum PortsCommand {
|
||||
/// List listening sockets
|
||||
Listen(PortsListenArgs),
|
||||
/// Find socket owners for a port
|
||||
Who(PortsWhoArgs),
|
||||
/// List active TCP connections
|
||||
Conns(PortsConnsArgs),
|
||||
}
|
||||
|
||||
#[derive(Subcommand, Debug)]
|
||||
enum NeighCommand {
|
||||
/// List ARP/NDP neighbors
|
||||
List(NeighListArgs),
|
||||
}
|
||||
|
||||
#[derive(Subcommand, Debug)]
|
||||
enum CertCommand {
|
||||
/// List trusted root certificates
|
||||
Roots,
|
||||
/// Write a baseline file of trusted roots
|
||||
Baseline(CertBaselineArgs),
|
||||
/// Diff trusted roots against a baseline
|
||||
Diff(CertDiffArgs),
|
||||
}
|
||||
|
||||
#[derive(Subcommand, Debug)]
|
||||
enum GeoIpCommand {
|
||||
/// Lookup GeoIP for an IP address
|
||||
Lookup(GeoIpLookupArgs),
|
||||
/// Show GeoIP database status
|
||||
Status,
|
||||
}
|
||||
|
||||
#[derive(Subcommand, Debug)]
|
||||
enum ProbeCommand {
|
||||
/// ICMP ping
|
||||
Ping(ProbePingArgs),
|
||||
/// TCP ping (connect timing)
|
||||
Tcping(ProbeTcpingArgs),
|
||||
/// Traceroute
|
||||
Trace(ProbeTraceArgs),
|
||||
}
|
||||
|
||||
#[derive(Subcommand, Debug)]
|
||||
enum DnsCommand {
|
||||
/// DNS query
|
||||
Query(DnsQueryArgs),
|
||||
/// DNS poisoning detection (active)
|
||||
Detect(DnsDetectArgs),
|
||||
/// DNS passive watch (pcap)
|
||||
Watch(DnsWatchArgs),
|
||||
/// DNS leak detection
|
||||
Leak {
|
||||
#[command(subcommand)]
|
||||
command: DnsLeakCommand,
|
||||
@@ -138,345 +170,381 @@ enum DnsCommand {
|
||||
|
||||
#[derive(Subcommand, Debug)]
|
||||
enum DnsLeakCommand {
|
||||
/// Show current policy and interface snapshot
|
||||
Status(DnsLeakStatusArgs),
|
||||
/// Passive leak detection watch
|
||||
Watch(DnsLeakWatchArgs),
|
||||
/// Summarize a saved leak report
|
||||
Report(DnsLeakReportArgs),
|
||||
}
|
||||
|
||||
#[derive(Subcommand, Debug)]
|
||||
enum CalcCommand {
|
||||
/// Subnet info
|
||||
Subnet(CalcSubnetArgs),
|
||||
/// Check CIDR containment
|
||||
Contains(CalcContainsArgs),
|
||||
/// Check CIDR overlap
|
||||
Overlap(CalcOverlapArgs),
|
||||
/// Summarize CIDRs
|
||||
Summarize(CalcSummarizeArgs),
|
||||
}
|
||||
|
||||
#[derive(Subcommand, Debug)]
|
||||
enum HttpCommand {
|
||||
/// HTTP HEAD request
|
||||
Head(HttpRequestArgs),
|
||||
/// HTTP GET request
|
||||
Get(HttpRequestArgs),
|
||||
}
|
||||
|
||||
#[derive(Subcommand, Debug)]
|
||||
enum TlsCommand {
|
||||
/// TLS handshake summary
|
||||
Handshake(TlsArgs),
|
||||
/// TLS certificate details
|
||||
Cert(TlsArgs),
|
||||
/// TLS verification
|
||||
Verify(TlsArgs),
|
||||
/// TLS ALPN negotiation
|
||||
Alpn(TlsArgs),
|
||||
}
|
||||
|
||||
#[derive(Subcommand, Debug)]
|
||||
enum DiscoverCommand {
|
||||
/// mDNS discovery
|
||||
Mdns(DiscoverMdnsArgs),
|
||||
/// SSDP discovery
|
||||
Ssdp(DiscoverSsdpArgs),
|
||||
/// LLMNR discovery
|
||||
Llmnr(DiscoverLlmnrArgs),
|
||||
/// NBNS discovery
|
||||
Nbns(DiscoverNbnsArgs),
|
||||
}
|
||||
|
||||
#[derive(Parser, Debug, Clone)]
|
||||
struct SysIpArgs {
|
||||
#[arg(long)]
|
||||
#[arg(long, help = "Show all addresses (including link-local)")]
|
||||
all: bool,
|
||||
#[arg(long)]
|
||||
#[arg(long, help = "Filter by interface name")]
|
||||
iface: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Parser, Debug, Clone)]
|
||||
struct SysRouteArgs {
|
||||
#[arg(long)]
|
||||
#[arg(long, help = "Show IPv4 routes")]
|
||||
ipv4: bool,
|
||||
#[arg(long)]
|
||||
#[arg(long, help = "Show IPv6 routes")]
|
||||
ipv6: bool,
|
||||
#[arg(long)]
|
||||
#[arg(long, help = "Filter routes by destination")]
|
||||
to: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Parser, Debug, Clone)]
|
||||
struct PortsListenArgs {
|
||||
#[arg(long)]
|
||||
#[arg(long, help = "Show TCP listeners")]
|
||||
tcp: bool,
|
||||
#[arg(long)]
|
||||
#[arg(long, help = "Show UDP listeners")]
|
||||
udp: bool,
|
||||
#[arg(long)]
|
||||
#[arg(long, help = "Filter by port")]
|
||||
port: Option<u16>,
|
||||
}
|
||||
|
||||
#[derive(Parser, Debug, Clone)]
|
||||
struct PortsWhoArgs {
|
||||
#[arg(help = "Target port number")]
|
||||
target: String,
|
||||
}
|
||||
|
||||
#[derive(Parser, Debug, Clone)]
|
||||
struct PortsConnsArgs {
|
||||
#[arg(long)]
|
||||
#[arg(long, help = "Show top N remote endpoints")]
|
||||
top: Option<usize>,
|
||||
#[arg(long)]
|
||||
#[arg(long, help = "Group by process")]
|
||||
by_process: bool,
|
||||
}
|
||||
|
||||
#[derive(Parser, Debug, Clone)]
|
||||
struct NeighListArgs {
|
||||
#[arg(long)]
|
||||
#[arg(long, help = "Show IPv4 neighbors")]
|
||||
ipv4: bool,
|
||||
#[arg(long)]
|
||||
#[arg(long, help = "Show IPv6 neighbors")]
|
||||
ipv6: bool,
|
||||
#[arg(long)]
|
||||
#[arg(long, help = "Filter by interface name")]
|
||||
iface: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Parser, Debug, Clone)]
|
||||
struct GeoIpLookupArgs {
|
||||
#[arg(help = "Target IP address")]
|
||||
target: String,
|
||||
}
|
||||
|
||||
#[derive(Parser, Debug, Clone)]
|
||||
struct CertBaselineArgs {
|
||||
#[arg(help = "Path to write baseline JSON")]
|
||||
path: PathBuf,
|
||||
}
|
||||
|
||||
#[derive(Parser, Debug, Clone)]
|
||||
struct CertDiffArgs {
|
||||
#[arg(help = "Path to baseline JSON")]
|
||||
path: PathBuf,
|
||||
}
|
||||
|
||||
#[derive(Parser, Debug, Clone)]
|
||||
struct ProbePingArgs {
|
||||
#[arg(help = "Target hostname or IP")]
|
||||
target: String,
|
||||
#[arg(long, default_value_t = 4)]
|
||||
#[arg(long, default_value_t = 4, help = "Ping count")]
|
||||
count: u32,
|
||||
#[arg(long, default_value_t = 800)]
|
||||
#[arg(long, default_value_t = 800, help = "Timeout per ping (ms)")]
|
||||
timeout_ms: u64,
|
||||
#[arg(long, default_value_t = 200)]
|
||||
#[arg(long, default_value_t = 200, help = "Interval between pings (ms)")]
|
||||
interval_ms: u64,
|
||||
#[arg(long)]
|
||||
#[arg(long, help = "Disable GeoIP enrichment")]
|
||||
no_geoip: bool,
|
||||
}
|
||||
|
||||
#[derive(Parser, Debug, Clone)]
|
||||
struct ProbeTcpingArgs {
|
||||
#[arg(help = "Target host:port")]
|
||||
target: String,
|
||||
#[arg(long, default_value_t = 4)]
|
||||
#[arg(long, default_value_t = 4, help = "Ping count")]
|
||||
count: u32,
|
||||
#[arg(long, default_value_t = 800)]
|
||||
#[arg(long, default_value_t = 800, help = "Timeout per connect (ms)")]
|
||||
timeout_ms: u64,
|
||||
#[arg(long)]
|
||||
#[arg(long, help = "SOCKS5 proxy URL")]
|
||||
socks5: Option<String>,
|
||||
#[arg(long)]
|
||||
#[arg(long, help = "Prefer IPv4 resolution")]
|
||||
prefer_ipv4: bool,
|
||||
#[arg(long)]
|
||||
#[arg(long, help = "Disable GeoIP enrichment")]
|
||||
no_geoip: bool,
|
||||
}
|
||||
|
||||
#[derive(Parser, Debug, Clone)]
|
||||
struct ProbeTraceArgs {
|
||||
#[arg(help = "Target host:port")]
|
||||
target: String,
|
||||
#[arg(long, default_value_t = 30)]
|
||||
#[arg(long, default_value_t = 30, help = "Maximum hops")]
|
||||
max_hops: u8,
|
||||
#[arg(long, default_value_t = 3)]
|
||||
#[arg(long, default_value_t = 3, help = "Probes per hop")]
|
||||
per_hop: u32,
|
||||
#[arg(long, default_value_t = 800)]
|
||||
#[arg(long, default_value_t = 800, help = "Timeout per hop (ms)")]
|
||||
timeout_ms: u64,
|
||||
#[arg(long)]
|
||||
#[arg(long, help = "Use UDP traceroute")]
|
||||
udp: bool,
|
||||
#[arg(long, default_value_t = 33434)]
|
||||
#[arg(long, default_value_t = 33434, help = "Destination port for UDP/TCP trace")]
|
||||
port: u16,
|
||||
#[arg(long)]
|
||||
#[arg(long, help = "Reverse DNS lookup per hop")]
|
||||
rdns: bool,
|
||||
#[arg(long)]
|
||||
#[arg(long, help = "Disable GeoIP enrichment")]
|
||||
no_geoip: bool,
|
||||
}
|
||||
|
||||
#[derive(Parser, Debug, Clone)]
|
||||
struct DnsQueryArgs {
|
||||
#[arg(help = "Domain name to query")]
|
||||
domain: String,
|
||||
#[arg(help = "Record type (A, AAAA, MX, TXT, ...)")]
|
||||
record_type: String,
|
||||
#[arg(long)]
|
||||
#[arg(long, help = "DNS server IP[:port]")]
|
||||
server: Option<String>,
|
||||
#[arg(long, default_value = "udp")]
|
||||
#[arg(long, default_value = "udp", help = "Transport (udp|tcp|dot|doh)")]
|
||||
transport: String,
|
||||
#[arg(long)]
|
||||
#[arg(long, help = "TLS server name for DoT/DoH")]
|
||||
tls_name: Option<String>,
|
||||
#[arg(long)]
|
||||
#[arg(long, help = "SOCKS5 proxy URL")]
|
||||
socks5: Option<String>,
|
||||
#[arg(long)]
|
||||
#[arg(long, help = "Prefer IPv4 resolution")]
|
||||
prefer_ipv4: bool,
|
||||
#[arg(long, default_value_t = 2000)]
|
||||
#[arg(long, default_value_t = 2000, help = "Timeout (ms)")]
|
||||
timeout_ms: u64,
|
||||
}
|
||||
|
||||
#[derive(Parser, Debug, Clone)]
|
||||
struct DnsDetectArgs {
|
||||
#[arg(help = "Domain name to test")]
|
||||
domain: String,
|
||||
#[arg(long)]
|
||||
#[arg(long, help = "Comma-separated DNS servers")]
|
||||
servers: Option<String>,
|
||||
#[arg(long, default_value = "udp")]
|
||||
#[arg(long, default_value = "udp", help = "Transport (udp|tcp|dot|doh)")]
|
||||
transport: String,
|
||||
#[arg(long)]
|
||||
#[arg(long, help = "TLS server name for DoT/DoH")]
|
||||
tls_name: Option<String>,
|
||||
#[arg(long)]
|
||||
#[arg(long, help = "SOCKS5 proxy URL")]
|
||||
socks5: Option<String>,
|
||||
#[arg(long)]
|
||||
#[arg(long, help = "Prefer IPv4 resolution")]
|
||||
prefer_ipv4: bool,
|
||||
#[arg(long, default_value_t = 3)]
|
||||
#[arg(long, default_value_t = 3, help = "Repeat count per server")]
|
||||
repeat: u32,
|
||||
#[arg(long, default_value_t = 2000)]
|
||||
#[arg(long, default_value_t = 2000, help = "Timeout (ms)")]
|
||||
timeout_ms: u64,
|
||||
}
|
||||
|
||||
#[derive(Parser, Debug, Clone)]
|
||||
struct DnsWatchArgs {
|
||||
#[arg(long, default_value = "30s")]
|
||||
#[arg(long, default_value = "30s", help = "Capture duration")]
|
||||
duration: String,
|
||||
#[arg(long)]
|
||||
#[arg(long, help = "Capture interface name")]
|
||||
iface: Option<String>,
|
||||
#[arg(long)]
|
||||
#[arg(long, help = "Filter by domain substring")]
|
||||
filter: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Parser, Debug, Clone)]
|
||||
struct DnsLeakStatusArgs {
|
||||
#[arg(long)]
|
||||
#[arg(long, help = "Policy profile (full-tunnel|proxy-stub|split)")]
|
||||
profile: Option<String>,
|
||||
#[arg(long)]
|
||||
#[arg(long, help = "Path to policy JSON")]
|
||||
policy: Option<PathBuf>,
|
||||
}
|
||||
|
||||
#[derive(Parser, Debug, Clone)]
|
||||
struct DnsLeakWatchArgs {
|
||||
#[arg(long, default_value = "10s")]
|
||||
#[arg(long, default_value = "10s", help = "Capture duration")]
|
||||
duration: String,
|
||||
#[arg(long)]
|
||||
#[arg(long, help = "Capture interface name")]
|
||||
iface: Option<String>,
|
||||
#[arg(long)]
|
||||
#[arg(long, help = "Policy profile (full-tunnel|proxy-stub|split)")]
|
||||
profile: Option<String>,
|
||||
#[arg(long)]
|
||||
#[arg(long, help = "Path to policy JSON")]
|
||||
policy: Option<PathBuf>,
|
||||
#[arg(long, default_value = "redacted")]
|
||||
#[arg(long, default_value = "redacted", help = "Privacy mode (full|redacted|minimal)")]
|
||||
privacy: String,
|
||||
#[arg(long)]
|
||||
#[arg(long, help = "Write JSON report to file")]
|
||||
out: Option<PathBuf>,
|
||||
#[arg(long)]
|
||||
#[arg(long, help = "Only print summary (no events)")]
|
||||
summary_only: bool,
|
||||
#[arg(long)]
|
||||
#[arg(long, help = "List capture-capable interfaces and exit")]
|
||||
iface_diag: bool,
|
||||
}
|
||||
|
||||
#[derive(Parser, Debug, Clone)]
|
||||
struct DnsLeakReportArgs {
|
||||
#[arg(help = "Path to leak report JSON")]
|
||||
path: PathBuf,
|
||||
#[arg(long, default_value = "redacted")]
|
||||
#[arg(long, default_value = "redacted", help = "Privacy mode (full|redacted|minimal)")]
|
||||
privacy: String,
|
||||
}
|
||||
|
||||
#[derive(Parser, Debug, Clone)]
|
||||
struct CalcSubnetArgs {
|
||||
#[arg(help = "CIDR or IP + mask")]
|
||||
input: Vec<String>,
|
||||
}
|
||||
|
||||
#[derive(Parser, Debug, Clone)]
|
||||
struct CalcContainsArgs {
|
||||
#[arg(help = "CIDR A")]
|
||||
a: String,
|
||||
#[arg(help = "CIDR B")]
|
||||
b: String,
|
||||
}
|
||||
|
||||
#[derive(Parser, Debug, Clone)]
|
||||
struct CalcOverlapArgs {
|
||||
#[arg(help = "CIDR A")]
|
||||
a: String,
|
||||
#[arg(help = "CIDR B")]
|
||||
b: String,
|
||||
}
|
||||
|
||||
#[derive(Parser, Debug, Clone)]
|
||||
struct CalcSummarizeArgs {
|
||||
#[arg(help = "CIDR list to summarize")]
|
||||
cidrs: Vec<String>,
|
||||
}
|
||||
|
||||
#[derive(Parser, Debug, Clone)]
|
||||
struct HttpRequestArgs {
|
||||
#[arg(help = "Target URL")]
|
||||
url: String,
|
||||
#[arg(long, default_value_t = 3000)]
|
||||
#[arg(long, default_value_t = 3000, help = "Request timeout (ms)")]
|
||||
timeout_ms: u64,
|
||||
#[arg(long)]
|
||||
#[arg(long, help = "Follow redirects (limit)")]
|
||||
follow_redirects: Option<u32>,
|
||||
#[arg(long)]
|
||||
#[arg(long, help = "Include response headers")]
|
||||
show_headers: bool,
|
||||
#[arg(long)]
|
||||
#[arg(long, help = "Include response body")]
|
||||
show_body: bool,
|
||||
#[arg(long, default_value_t = 8192)]
|
||||
#[arg(long, default_value_t = 8192, help = "Max body bytes")]
|
||||
max_body_bytes: usize,
|
||||
#[arg(long)]
|
||||
#[arg(long, help = "Force HTTP/1.1 only")]
|
||||
http1_only: bool,
|
||||
#[arg(long)]
|
||||
#[arg(long, help = "Force HTTP/2 prior knowledge")]
|
||||
http2_only: bool,
|
||||
#[arg(long)]
|
||||
#[arg(long, help = "Enable HTTP/3 (feature gated)")]
|
||||
http3: bool,
|
||||
#[arg(long)]
|
||||
#[arg(long, help = "Require HTTP/3 (feature gated)")]
|
||||
http3_only: bool,
|
||||
#[arg(long)]
|
||||
#[arg(long, help = "Enable GeoIP enrichment")]
|
||||
geoip: bool,
|
||||
#[arg(long)]
|
||||
#[arg(long, help = "SOCKS5 proxy URL")]
|
||||
socks5: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Parser, Debug, Clone)]
|
||||
struct TlsArgs {
|
||||
#[arg(help = "Target host:port")]
|
||||
target: String,
|
||||
#[arg(long)]
|
||||
#[arg(long, help = "Override SNI")]
|
||||
sni: Option<String>,
|
||||
#[arg(long)]
|
||||
#[arg(long, help = "ALPN protocols (comma-separated)")]
|
||||
alpn: Option<String>,
|
||||
#[arg(long, default_value_t = 3000)]
|
||||
#[arg(long, default_value_t = 3000, help = "Timeout (ms)")]
|
||||
timeout_ms: u64,
|
||||
#[arg(long)]
|
||||
#[arg(long, help = "Skip TLS verification")]
|
||||
insecure: bool,
|
||||
#[arg(long)]
|
||||
#[arg(long, help = "SOCKS5 proxy URL")]
|
||||
socks5: Option<String>,
|
||||
#[arg(long)]
|
||||
#[arg(long, help = "Prefer IPv4 resolution")]
|
||||
prefer_ipv4: bool,
|
||||
#[arg(long)]
|
||||
#[arg(long, help = "Show X.509 extensions")]
|
||||
show_extensions: bool,
|
||||
#[arg(long)]
|
||||
#[arg(long, help = "Show OCSP stapling if available")]
|
||||
ocsp: bool,
|
||||
}
|
||||
|
||||
#[derive(Parser, Debug, Clone)]
|
||||
struct DiscoverMdnsArgs {
|
||||
#[arg(long, default_value = "3s")]
|
||||
#[arg(long, default_value = "3s", help = "Capture duration")]
|
||||
duration: String,
|
||||
#[arg(long)]
|
||||
#[arg(long, help = "Service type filter")]
|
||||
service: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Parser, Debug, Clone)]
|
||||
struct DiscoverSsdpArgs {
|
||||
#[arg(long, default_value = "3s")]
|
||||
#[arg(long, default_value = "3s", help = "Capture duration")]
|
||||
duration: String,
|
||||
}
|
||||
|
||||
#[derive(Parser, Debug, Clone)]
|
||||
struct DiscoverLlmnrArgs {
|
||||
#[arg(long, default_value = "3s")]
|
||||
#[arg(long, default_value = "3s", help = "Capture duration")]
|
||||
duration: String,
|
||||
#[arg(long)]
|
||||
#[arg(long, help = "Query name (default: wpad)")]
|
||||
name: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Parser, Debug, Clone)]
|
||||
struct DiscoverNbnsArgs {
|
||||
#[arg(long, default_value = "3s")]
|
||||
#[arg(long, default_value = "3s", help = "Capture duration")]
|
||||
duration: String,
|
||||
}
|
||||
|
||||
#[derive(Parser, Debug, Clone)]
|
||||
struct DiagArgs {
|
||||
#[arg(long)]
|
||||
#[arg(long, help = "Write JSON report to file")]
|
||||
out: Option<PathBuf>,
|
||||
#[arg(long)]
|
||||
#[arg(long, help = "Write zip bundle to file")]
|
||||
bundle: Option<PathBuf>,
|
||||
#[arg(long)]
|
||||
#[arg(long, help = "Run DNS detect on domain")]
|
||||
dns_detect: Option<String>,
|
||||
#[arg(long, default_value_t = 2000)]
|
||||
#[arg(long, default_value_t = 2000, help = "DNS detect timeout (ms)")]
|
||||
dns_timeout_ms: u64,
|
||||
#[arg(long, default_value_t = 3)]
|
||||
#[arg(long, default_value_t = 3, help = "DNS detect repeat count")]
|
||||
dns_repeat: u32,
|
||||
}
|
||||
|
||||
|
||||
@@ -3,36 +3,36 @@
|
||||
This document lists CLI commands and supported flags. Output defaults to text; use `--json` for structured output.
|
||||
|
||||
## Global flags
|
||||
- `--json` / `--pretty`
|
||||
- `--no-color` / `--quiet`
|
||||
- `-v` / `-vv` / `--verbose`
|
||||
- `--log-level <error|warn|info|debug|trace>`
|
||||
- `--log-format <text|json>`
|
||||
- `--log-file <path>`
|
||||
- `--json` / `--pretty`: emit JSON output (pretty-print if requested)
|
||||
- `--no-color` / `--quiet`: disable ANSI colors / reduce stdout output
|
||||
- `-v` / `-vv` / `--verbose`: increase log verbosity
|
||||
- `--log-level <error|warn|info|debug|trace>`: set log level
|
||||
- `--log-format <text|json>`: set log format
|
||||
- `--log-file <path>`: write logs to file
|
||||
- `NETTOOL_LOG_FILTER` or `RUST_LOG` can override log filters (ex: `maxminddb::decoder=debug`)
|
||||
|
||||
## sys
|
||||
- `sys ifaces`
|
||||
- `sys ip` flags: `--all`, `--iface <name>`
|
||||
- `sys route` flags: `--ipv4`, `--ipv6`, `--to <ip>`
|
||||
- `sys dns`
|
||||
- `sys ifaces`: list network interfaces
|
||||
- `sys ip` flags: `--all` (include link-local), `--iface <name>` (filter by interface)
|
||||
- `sys route` flags: `--ipv4`, `--ipv6`, `--to <ip>` (filter by destination)
|
||||
- `sys dns`: show DNS configuration
|
||||
|
||||
## ports
|
||||
- `ports listen` flags: `--tcp`, `--udp`, `--port <n>`
|
||||
- `ports who <port>`
|
||||
- `ports conns` flags: `--top <n>`, `--by-process`
|
||||
- `ports listen` flags: `--tcp`, `--udp`, `--port <n>` (filter by port)
|
||||
- `ports who <port>`: find owning processes for a port
|
||||
- `ports conns` flags: `--top <n>`, `--by-process` (summaries)
|
||||
|
||||
## neigh
|
||||
- `neigh list` flags: `--ipv4`, `--ipv6`, `--iface <name>`
|
||||
|
||||
## cert
|
||||
- `cert roots`
|
||||
- `cert baseline <path>`
|
||||
- `cert diff <path>`
|
||||
- `cert roots`: list trusted root certificates
|
||||
- `cert baseline <path>`: write baseline JSON
|
||||
- `cert diff <path>`: diff against baseline JSON
|
||||
|
||||
## geoip
|
||||
- `geoip lookup <ip>`
|
||||
- `geoip status`
|
||||
- `geoip lookup <ip>`: lookup GeoIP
|
||||
- `geoip status`: show GeoIP database status
|
||||
|
||||
## probe
|
||||
- `probe ping <host>` flags: `--count <n>`, `--timeout-ms <n>`, `--interval-ms <n>`, `--no-geoip`
|
||||
@@ -44,7 +44,7 @@ This document lists CLI commands and supported flags. Output defaults to text; u
|
||||
- `dns detect <domain>` flags: `--servers <csv>`, `--transport <udp|tcp|dot|doh>`, `--tls-name <name>`, `--socks5 <url>`, `--prefer-ipv4`, `--repeat <n>`, `--timeout-ms <n>`
|
||||
- `dns watch` flags: `--duration <Ns|Nms>`, `--iface <name>`, `--filter <pattern>`
|
||||
- `dns leak status` flags: `--profile <full-tunnel|proxy-stub|split>`, `--policy <path>`
|
||||
- `dns leak watch` flags: `--duration <Ns|Nms>`, `--iface <name>`, `--profile <full-tunnel|proxy-stub|split>`, `--policy <path>`, `--privacy <full|redacted|minimal>`, `--out <path>`, `--summary-only`, `--iface-diag`
|
||||
- `dns leak watch` flags: `--duration <Ns|Nms>`, `--iface <name>`, `--profile <full-tunnel|proxy-stub|split>`, `--policy <path>`, `--privacy <full|redacted|minimal>`, `--out <path>`, `--summary-only`, `--iface-diag` (list capture-capable interfaces)
|
||||
- `dns leak report` flags: `<path>`, `--privacy <full|redacted|minimal>`
|
||||
|
||||
## http
|
||||
|
||||
Reference in New Issue
Block a user