You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Currently, the bssh ping command tests SSH connectivity by establishing a full SSH connection, authenticating, and executing a no-op command (true, see src/commands/ping.rs). While this is useful for verifying SSH service availability, it's relatively slow (2-5 seconds per host due to SSH handshake and authentication overhead).
Users often want to quickly check basic network connectivity across all cluster nodes without the SSH overhead, similar to the traditional ping command that uses ICMP packets and responds in milliseconds.
Proposed Solution
Add a new network-ping command that performs fast ICMP ping tests across all cluster nodes to verify basic network connectivity.
Implementation Details
CLI Changes
Add a new subcommand to the Commands enum in src/cli/bssh.rs (the old flat src/cli.rs was split into src/cli/{mod,bssh,pdsh}.rs in #105):
#[derive(Debug,Subcommand)]pubenumCommands{// ... existing commands ...#[command( visible_alias = "nping", about = "Test network connectivity using ICMP ping (fast)", long_about = "Sends ICMP echo requests to all target hosts in parallel.\nReports per-host packet loss and round-trip time statistics.\nDoes not open an SSH connection, so it does not verify SSH service availability or authentication.\n\nExit codes: 0 (all hosts answered), 1 (some hosts answered), 255 (no host answered, or bssh failed before sending)")]NetworkPing{#[arg( short = 'c', long = "count", default_value = "4", help = "Number of echo requests to send per host")]count:u32,#[arg( short = 'W', long = "timeout", default_value = "2", help = "Time to wait for a reply to each request, in seconds")]timeout:u64,#[arg( long = "interval", default_value = "0.2", help = "Interval between requests, in seconds (minimum 0.2)")]interval:f64,},}
Flag naming rationale (OpenSSH compatibility)
The original draft of this issue proposed -t for the timeout. That is rejected: the root Cli already binds -t to --tty (src/cli/bssh.rs:266), which is OpenSSH's "force pseudo-terminal allocation". Because no root argument is declared global = true, clap would not error, but -t would mean "force a TTY" before the subcommand and "timeout" after it. That is exactly the kind of positional ambiguity a drop-in SSH replacement must not introduce.
The rule adopted here: a subcommand short flag must not reuse a letter that the root Cli binds to a different meaning. Where the conventional ping short flag collides with an OpenSSH flag, the option becomes long-only.
Short flags already taken by the root Cli, nearly all with their OpenSSH meanings: -4 -6 -A -b -C -D -F -H -J -L -N -Q -R -S -T -f -i -k -l -o -p -q -t -v -x.
Option
Choice
Reason
Packet count
-c, --count
Matches ping -c. -c is free at the root (-C is --cluster, and clap is case sensitive).
Reply timeout
-W, --timeout
Matches iputils ping -W ("time to wait for a response"). -W is free at the root. Avoids the -t/--tty collision.
Interval
--interval (long only)
ping -i would shadow OpenSSH's -i (IdentityFile) at the root, so no short form is offered.
Address family
none; inherits root -4/-6
OpenSSH treats AddressFamily as a client-global setting, not a per-operation one. See the blocking dependency below.
Parallelism
none; inherits root --parallel
Same as ping, upload, and download, which all read ctx.max_parallel (default 10).
Two further constraints verified in the current code:
Existing variants (List, Ping, Upload, Download, Interactive, CacheStats) all use #[command(about = ..., long_about = ...)] prose rather than doc comments, so the new variant follows that style.
No subcommand in the codebase currently declares a clap alias, so visible_alias = "nping" would be the first. This is accepted deliberately: nping is short enough to be worth it, and the alias does not shadow anything.
Core Implementation
Create src/commands/network_ping.rs and register it in src/commands/mod.rs:
Use a Rust ICMP ping library (see options below)
Perform parallel ping tests across all nodes
Display results with latency statistics (min/avg/max/stddev)
Show packet loss percentage
Color-coded output (see thresholds below)
Reuse crate::ui::OutputFormatter::{format_command_header, format_summary} so the output matches ping, upload, and download.
Settled behavior
These points were unspecified in the original draft. They are now decided, following OpenSSH and iputils/BSD ping precedent.
Packet interval. Default 0.2 seconds, minimum 0.2 seconds. iputils ping permits intervals below 0.2s only for the superuser, so 0.2s is the safe unprivileged floor. With the default 4 packets this is roughly 0.6 seconds of wall clock per host, and hosts are probed in parallel.
Concurrency. No subcommand flag. The command reuses the global --parallel value (ctx.max_parallel, default 10), consistent with every other multi-node command.
Output modes. Normal output only. No TUI, no --stream, no --output-dir. This mirrors ping, whose implementation states "Use normal execution (no TUI, no streaming) for ping". A fixed-size result table gains nothing from streaming, and the run is short enough that progress monitoring is unnecessary.
pdsh compatibility mode. Not exposed. pdsh has no ICMP subcommand, and src/cli/pdsh.rs maps pdsh options onto bssh behavior rather than exposing bssh subcommands. network-ping stays bssh-only.
Latency color thresholds. There is no OpenSSH precedent here, so these are set as a starting point and may be tuned: green under 10 ms, yellow from 10 ms to 100 ms, red above 100 ms. Any packet loss forces red regardless of latency.
Statistics fields.min/avg/max/stddev, matching BSD ping's summary line. The original sample output omitted stddev; it is included below. (iputils prints mdev instead; stddev is chosen because it is the more widely understood label and the issue's own text already said stddev.)
Exit codes.0 when every targeted host answered at least one echo request. 1 when at least one host answered and at least one did not. 255 when no host answered, or when bssh failed before it could send anything (ICMP socket creation denied, no hosts resolved, bad arguments). The 255 case follows OpenSSH's convention that 255 means "ssh itself failed" rather than "the remote operation failed". This must stay consistent with #245, which settles the same question for the sibling ping command.
Suggested Libraries
Option 1: surge-ping (Recommended)
Pure Rust, async-friendly with tokio
Cross-platform (Linux, macOS, Windows)
No external dependencies
Supports both privileged and unprivileged ICMP
[dependencies]
surge-ping = "0.9"
Option 2: fastping-rs
Simple API, battle-tested
Requires raw sockets (may need elevated privileges)
Option 3: pnet (lower-level)
Full network protocol suite
More complex but very flexible
Requires privileged access
Example Implementation Skeleton
use anyhow::Result;use surge_ping::{Client,Config,ICMP,PingIdentifier,PingSequence};use std::net::IpAddr;use std::time::Duration;use tokio::time::timeout;pubasyncfnnetwork_ping_nodes(nodes:Vec<Node>,count:u32,ping_timeout:u64,interval:f64,max_parallel:usize,) -> Result<()>{// Create ICMP clientlet client = Client::new(&Config::default())?;// Create tasks for each nodelet tasks:Vec<_> = nodes.iter().map(|node| {let client = client.clone();let host = node.host.clone();
tokio::spawn(asyncmove{ping_host(&client,&host, count, ping_timeout).await})}).collect();// Execute with concurrency limit// ... parallel execution logic ...// Display results with statistics// ... formatting and output ...Ok(())}asyncfnping_host(client:&Client,host:&str,count:u32,timeout_secs:u64,) -> Result<PingStats>{// NOTE (2026-08-02): `Node.host` is a hostname string, not necessarily a// literal IP. Nothing in the current SSH path parses it as `IpAddr` (russh// and tokio resolve `(host, port)` for us), so this line must become a DNS// lookup (e.g. `tokio::net::lookup_host`) or every hostname-based node// fails to parse. Which resolved address to pick is an open decision, see// "Decisions still required" below.let addr:IpAddr = host.parse()?;letmut pinger = client.pinger(addr,PingIdentifier(rand::random())).await;letmut latencies = Vec::new();letmut lost = 0;for seq in0..count {matchtimeout(Duration::from_secs(timeout_secs),
pinger.ping(PingSequence(seq asu16),&[])).await{Ok(Ok((_, duration))) => latencies.push(duration),
_ => lost += 1,}}Ok(PingStats::from_latencies(latencies, lost, count))}
Note that Config::default() selects ICMPv4. Honoring the root -4/-6 flags requires selecting ICMP::V4 or ICMP::V6 explicitly, which is why the ICMP import above is currently unused.
Output Format
▶ Network Ping Test Results (12 nodes)
● 10.100.64.101 4/4 packets min/avg/max/stddev = 0.5/1.2/2.1/0.6 ms
● 10.100.64.102 4/4 packets min/avg/max/stddev = 0.8/1.5/2.3/0.5 ms
● 10.100.64.103 3/4 packets min/avg/max/stddev = 1.2/2.1/3.0/0.8 ms (25% loss)
● 10.100.64.104 0/4 packets - Host unreachable
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Summary: 3 reachable, 1 unreachable (25% success rate)
Average latency: 1.6 ms (mean of per-host averages)
Usage Examples
# Basic network ping to all cluster nodes
bssh -C production network-ping
# Custom packet count and reply timeout
bssh -C production network-ping -c 10 -W 1
# Slower probing
bssh -C production network-ping -c 10 --interval 1.0
# Force IPv6 (requires the -4/-6 wiring issue to land first)
bssh -6 -C production network-ping
# Quick alias
bssh -C production nping
# With specific hosts
bssh -H "host1,host2,host3" network-ping
Comparison: ping vs network-ping
Command
Purpose
Speed
Tests
ping
SSH connectivity test
2-5s per node
SSH service + auth
network-ping
Network connectivity test
~0.6s total at defaults (4 packets at 0.2s interval, hosts probed in parallel), plus up to -W per unresponsive host
ICMP reachability
The original draft claimed "<100ms per node", which is not achievable with a multi-packet probe: the floor is count * interval. The corrected figure reflects the settled defaults.
Command routing moved out of src/main.rs into src/app/dispatcher.rs in 5f3c320 (main.rs split, Phase 2, 2025-10-20). A new variant must be handled at four match sites in dispatcher.rs, not one:
the main match &cli.command dispatch arm
subcommand_name() (diagnostics label)
sudo_password_is_applicable() (should return false; ICMP has no sudo hook)
ssh_password_is_applicable() (should return false; ICMP opens no SSH connection)
Dependencies to Add
[dependencies]
surge-ping = "0.9"# ICMP ping library (0.9.0 released 2026-06-29)
rand is already a direct dependency (rand = "0.10"), so the rand::random() call in the skeleton needs no new dependency.
Security Considerations
ICMP Raw Sockets:
On Linux: May require CAP_NET_RAW capability or root privileges
On macOS: Generally works without special permissions
On Windows: Requires administrator privileges (not applicable: bssh does not build for Windows. nix is an unconditional dependency in Cargo.toml, and the release matrix ships only linux-gnu/musl x86_64+aarch64 and aarch64-apple-darwin.)
Solutions:
Use surge-ping with unprivileged mode (SOCK_DGRAM) when possible
Document privilege requirements in README
Fall back to TCP ping if ICMP is unavailable
Provide clear error messages if permissions are insufficient
Note that items 1, 3, and 4 are not yet a chosen strategy; see "Decisions still required".
Blocking dependency
Honoring -4/-6 requires those flags to actually work. They are currently parsed and then ignored: src/cli/bssh.rs:281-296 declares them, docs/man/bssh.1 documents them, and no code in the repository reads cli.ipv4 or cli.ipv6. #246 tracks wiring them into the connection path (along with the AddressFamily SSH config keyword, which is parsed and resolved but likewise never consumed). Until #246 lands, network-ping either hardcodes ICMPv4 or becomes the first consumer of the preference, which is a scheduling decision between the two issues.
Testing Plan
Unit Tests:
Ping parsing and statistics calculation (min/avg/max/stddev)
Timeout handling
Packet loss detection
Exit code mapping for the all-success, partial-failure, and total-failure cases
Integration Tests:
Single host ping
Multi-host parallel ping
Timeout scenarios
Unreachable hosts
Note: whether these can run in CI is unresolved, see "Decisions still required"
Manual Testing:
Test on Linux (various distros)
Test on macOS
Test with different privilege levels
Compare with system ping command
Alternative Implementations
If ICMP proves problematic, consider:
TCP Ping: Connect to SSH port without authentication
HTTP Ping: If nodes have web services
Hybrid: Try ICMP first, fall back to TCP
Decisions still required
Nothing below is settled. These need answering before or during implementation. They are recorded here so the decision can be made later from the issue alone.
Whether to build this at all. The issue is priority:low / status:backlog and its own closing paragraph notes that ping already covers SSH connectivity testing. No one has committed to the feature.
Which ICMP library. Three candidates are listed above with surge-ping marked "Recommended", but no evaluation has been done. Deciding factors: unprivileged SOCK_DGRAM support on both Linux and macOS, IPv6 support (needed for -6), and maintenance activity.
What happens when ICMP is unavailable. The four "Solutions" above are parallel options, not a strategy. The choice is material: adding an automatic TCP fallback changes what the command measures, so the comparison table's claim of "ICMP reachability" would no longer hold. Options: hard error with a clear message and exit 255; automatic fallback with the transport labeled per host in the output; or an explicit opt-in flag.
When, if ever, the TCP/HTTP/Hybrid alternatives trigger. Related to 3, but broader: "if ICMP proves problematic" has no defined trigger.
Jump host behavior. ICMP cannot traverse -J/--jump-host, which bssh supports. For a node reachable only through a jump host, network-ping must either report it unreachable (accurate for ICMP, misleading for the user), skip it with a notice, or fall back to a TCP probe tunneled through the jump host. This is the largest open question.
Which resolved address to probe. A hostname may resolve to several addresses. ping probes one. Options: first address in resolver order (matching the existing SSH connect loop's preference order), all addresses, or the address family forced by -4/-6. Interacts with fix: Wire up -4/-6 address family flags (currently parsed but ignored) #246.
CI feasibility. The integration tests need an ICMP socket. Whether GitHub's ubuntu-latest runners permit unprivileged ICMP (via net.ipv4.ping_group_range) has not been checked. If they do not, the integration tests must be feature-gated or moved to manual testing.
Low - Nice to have feature for quick network checks, though ping command already provides SSH connectivity testing.
Refresh log
2026-08-02 - Refreshed against main at c3b8ac2. Feature is still entirely unimplemented: no network_ping module, no NetworkPing variant, no surge-ping dependency. All items remain open.
Renamed references: 3. src/cli.rs to src/cli/bssh.rs (split in feat: Implement pdsh compatibility layer core infrastructure #105, 2025-12-17, after this issue was filed); src/main.rs routing to src/app/dispatcher.rs (5f3c320, 2025-10-20, which already predated this issue, so the original body was pointing at a stale path from the start); src/commands/mod.rs path re-nested under the tree.
Corrected facts: 3. ping executes true, not echo 'pong'; surge-ping bumped 0.8 to 0.9 (0.9.0, 2026-06-29); rand 0.10 is already a direct dependency.
Marked obsolete: 1. The Windows administrator-privileges bullet. bssh does not build for Windows (unconditional nix dependency) and ships no Windows release artifact.
Added implementation notes: dispatcher requires four match arms, not one; -t already means --tty at the root; no existing subcommand uses a clap alias; Node.host is a hostname so the skeleton's IpAddr parse needs a DNS lookup; docs targets are README "Built-in Commands" and docs/man/bssh.1.SH COMMANDS.
Surfaced (not added to scope): ICMP cannot traverse -J/--jump-host, which bssh supports. What network-ping should do for jump-host-reachable-only nodes is undecided and may deserve its own discussion before implementation.
2026-08-02 (second pass, verified against main at 0eb3fac; only Cargo.lock moved since c3b8ac2, so every Cargo.toml claim above still holds) - Resolved the flag collision and the previously unspecified behaviors, and separated what is now settled from what still needs a decision.
Flag set reworked for OpenSSH compatibility: -t rejected because the root Cli binds it to --tty. Timeout becomes -W, --timeout (iputils ping -W), interval becomes long-only --interval because ping -i would shadow OpenSSH's -i (IdentityFile), count stays -c. Address family and parallelism inherit the root flags rather than adding subcommand duplicates. The governing rule is stated in the body: a subcommand short flag must not reuse a root letter with a different meaning.
Settled 7 previously unspecified points: packet interval (0.2s default and floor, per iputils' unprivileged limit), concurrency (inherits --parallel), output modes (normal only, mirroring ping), pdsh exposure (none), color thresholds (10ms / 100ms), statistics fields (min/avg/max/stddev, sample output corrected), and exit codes (0/1/255 with 255 following OpenSSH's "ssh itself failed" convention).
Corrected the comparison table: "<100ms per node" is unachievable for a multi-packet probe whose floor is count * interval. Replaced with the actual figure at the settled defaults.
Added a "Decisions still required" section with 8 numbered items, so the remaining choices can be made later from the issue alone rather than rediscovered.
Problem
Currently, the
bssh pingcommand tests SSH connectivity by establishing a full SSH connection, authenticating, and executing a no-op command (true, seesrc/commands/ping.rs). While this is useful for verifying SSH service availability, it's relatively slow (2-5 seconds per host due to SSH handshake and authentication overhead).Users often want to quickly check basic network connectivity across all cluster nodes without the SSH overhead, similar to the traditional
pingcommand that uses ICMP packets and responds in milliseconds.Proposed Solution
Add a new
network-pingcommand that performs fast ICMP ping tests across all cluster nodes to verify basic network connectivity.Implementation Details
CLI Changes
Add a new subcommand to the
Commandsenum insrc/cli/bssh.rs(the old flatsrc/cli.rswas split intosrc/cli/{mod,bssh,pdsh}.rsin #105):Flag naming rationale (OpenSSH compatibility)
The original draft of this issue proposed
-tfor the timeout. That is rejected: the rootClialready binds-tto--tty(src/cli/bssh.rs:266), which is OpenSSH's "force pseudo-terminal allocation". Because no root argument is declaredglobal = true, clap would not error, but-twould mean "force a TTY" before the subcommand and "timeout" after it. That is exactly the kind of positional ambiguity a drop-in SSH replacement must not introduce.The rule adopted here: a subcommand short flag must not reuse a letter that the root
Clibinds to a different meaning. Where the conventionalpingshort flag collides with an OpenSSH flag, the option becomes long-only.Short flags already taken by the root
Cli, nearly all with their OpenSSH meanings:-4 -6 -A -b -C -D -F -H -J -L -N -Q -R -S -T -f -i -k -l -o -p -q -t -v -x.-c, --countping -c.-cis free at the root (-Cis--cluster, and clap is case sensitive).-W, --timeoutping -W("time to wait for a response").-Wis free at the root. Avoids the-t/--ttycollision.--interval(long only)ping -iwould shadow OpenSSH's-i(IdentityFile) at the root, so no short form is offered.-4/-6AddressFamilyas a client-global setting, not a per-operation one. See the blocking dependency below.--parallelping,upload, anddownload, which all readctx.max_parallel(default 10).Two further constraints verified in the current code:
List,Ping,Upload,Download,Interactive,CacheStats) all use#[command(about = ..., long_about = ...)]prose rather than doc comments, so the new variant follows that style.visible_alias = "nping"would be the first. This is accepted deliberately:npingis short enough to be worth it, and the alias does not shadow anything.Core Implementation
Create
src/commands/network_ping.rsand register it insrc/commands/mod.rs:Reuse
crate::ui::OutputFormatter::{format_command_header, format_summary}so the output matchesping,upload, anddownload.Settled behavior
These points were unspecified in the original draft. They are now decided, following OpenSSH and iputils/BSD
pingprecedent.Packet interval. Default 0.2 seconds, minimum 0.2 seconds. iputils
pingpermits intervals below 0.2s only for the superuser, so 0.2s is the safe unprivileged floor. With the default 4 packets this is roughly 0.6 seconds of wall clock per host, and hosts are probed in parallel.Concurrency. No subcommand flag. The command reuses the global
--parallelvalue (ctx.max_parallel, default 10), consistent with every other multi-node command.Output modes. Normal output only. No TUI, no
--stream, no--output-dir. This mirrorsping, whose implementation states "Use normal execution (no TUI, no streaming) for ping". A fixed-size result table gains nothing from streaming, and the run is short enough that progress monitoring is unnecessary.pdsh compatibility mode. Not exposed. pdsh has no ICMP subcommand, and
src/cli/pdsh.rsmaps pdsh options onto bssh behavior rather than exposing bssh subcommands.network-pingstays bssh-only.Latency color thresholds. There is no OpenSSH precedent here, so these are set as a starting point and may be tuned: green under 10 ms, yellow from 10 ms to 100 ms, red above 100 ms. Any packet loss forces red regardless of latency.
Statistics fields.
min/avg/max/stddev, matching BSDping's summary line. The original sample output omitted stddev; it is included below. (iputils printsmdevinstead;stddevis chosen because it is the more widely understood label and the issue's own text already said stddev.)Exit codes.
0when every targeted host answered at least one echo request.1when at least one host answered and at least one did not.255when no host answered, or when bssh failed before it could send anything (ICMP socket creation denied, no hosts resolved, bad arguments). The255case follows OpenSSH's convention that 255 means "ssh itself failed" rather than "the remote operation failed". This must stay consistent with #245, which settles the same question for the siblingpingcommand.Suggested Libraries
Option 1:
surge-ping(Recommended)Option 2:
fastping-rsOption 3:
pnet(lower-level)Example Implementation Skeleton
Note that
Config::default()selects ICMPv4. Honoring the root-4/-6flags requires selectingICMP::V4orICMP::V6explicitly, which is why theICMPimport above is currently unused.Output Format
Usage Examples
Comparison:
pingvsnetwork-pingpingnetwork-ping-Wper unresponsive hostThe original draft claimed "<100ms per node", which is not achievable with a multi-packet probe: the floor is
count * interval. The corrected figure reflects the settled defaults.Files to Modify/Create
Command routing moved out of
src/main.rsintosrc/app/dispatcher.rsin5f3c320(main.rs split, Phase 2, 2025-10-20). A new variant must be handled at four match sites indispatcher.rs, not one:match &cli.commanddispatch armsubcommand_name()(diagnostics label)sudo_password_is_applicable()(should returnfalse; ICMP has no sudo hook)ssh_password_is_applicable()(should returnfalse; ICMP opens no SSH connection)Dependencies to Add
randis already a direct dependency (rand = "0.10"), so therand::random()call in the skeleton needs no new dependency.Security Considerations
ICMP Raw Sockets:
CAP_NET_RAWcapability or root privilegesOn Windows: Requires administrator privileges(not applicable: bssh does not build for Windows.nixis an unconditional dependency inCargo.toml, and the release matrix ships only linux-gnu/musl x86_64+aarch64 and aarch64-apple-darwin.)Solutions:
surge-pingwith unprivileged mode (SOCK_DGRAM) when possibleNote that items 1, 3, and 4 are not yet a chosen strategy; see "Decisions still required".
Blocking dependency
Honoring
-4/-6requires those flags to actually work. They are currently parsed and then ignored:src/cli/bssh.rs:281-296declares them,docs/man/bssh.1documents them, and no code in the repository readscli.ipv4orcli.ipv6. #246 tracks wiring them into the connection path (along with theAddressFamilySSH config keyword, which is parsed and resolved but likewise never consumed). Until #246 lands,network-pingeither hardcodes ICMPv4 or becomes the first consumer of the preference, which is a scheduling decision between the two issues.Testing Plan
Unit Tests:
Integration Tests:
Manual Testing:
pingcommandAlternative Implementations
If ICMP proves problematic, consider:
Decisions still required
Nothing below is settled. These need answering before or during implementation. They are recorded here so the decision can be made later from the issue alone.
priority:low/status:backlogand its own closing paragraph notes thatpingalready covers SSH connectivity testing. No one has committed to the feature.surge-pingmarked "Recommended", but no evaluation has been done. Deciding factors: unprivileged SOCK_DGRAM support on both Linux and macOS, IPv6 support (needed for-6), and maintenance activity.-J/--jump-host, which bssh supports. For a node reachable only through a jump host,network-pingmust either report it unreachable (accurate for ICMP, misleading for the user), skip it with a notice, or fall back to a TCP probe tunneled through the jump host. This is the largest open question.pingprobes one. Options: first address in resolver order (matching the existing SSH connect loop's preference order), all addresses, or the address family forced by-4/-6. Interacts with fix: Wire up -4/-6 address family flags (currently parsed but ignored) #246.ubuntu-latestrunners permit unprivileged ICMP (vianet.ipv4.ping_group_range) has not been checked. If they do not, the integration tests must be feature-gated or moved to manual testing.pingand frames it as Option A (0/1 only, preserving the currently documented text) versus Option B (0/1/255, OpenSSH-aligned). Whichever option fix: ping always exits 0 despite documenting exit code 1 for unreachable hosts #245 adopts governs here too;network-pingshould not diverge from its sibling.Related Issues
pingcommand (SSH connectivity test)-4/-6address family flags are parsed but ignored) for address family supportpingexit code contract)Priority
Low - Nice to have feature for quick network checks, though
pingcommand already provides SSH connectivity testing.Refresh log
2026-08-02 - Refreshed against
mainatc3b8ac2. Feature is still entirely unimplemented: nonetwork_pingmodule, noNetworkPingvariant, nosurge-pingdependency. All items remain open.src/cli.rstosrc/cli/bssh.rs(split in feat: Implement pdsh compatibility layer core infrastructure #105, 2025-12-17, after this issue was filed);src/main.rsrouting tosrc/app/dispatcher.rs(5f3c320, 2025-10-20, which already predated this issue, so the original body was pointing at a stale path from the start);src/commands/mod.rspath re-nested under the tree.pingexecutestrue, notecho 'pong';surge-pingbumped 0.8 to 0.9 (0.9.0, 2026-06-29);rand 0.10is already a direct dependency.nixdependency) and ships no Windows release artifact.-talready means--ttyat the root; no existing subcommand uses a clap alias;Node.hostis a hostname so the skeleton'sIpAddrparse needs a DNS lookup; docs targets are README "Built-in Commands" anddocs/man/bssh.1.SH COMMANDS.-J/--jump-host, which bssh supports. Whatnetwork-pingshould do for jump-host-reachable-only nodes is undecided and may deserve its own discussion before implementation.2026-08-02 (second pass, verified against
mainat0eb3fac; onlyCargo.lockmoved sincec3b8ac2, so everyCargo.tomlclaim above still holds) - Resolved the flag collision and the previously unspecified behaviors, and separated what is now settled from what still needs a decision.-trejected because the rootClibinds it to--tty. Timeout becomes-W, --timeout(iputilsping -W), interval becomes long-only--intervalbecauseping -iwould shadow OpenSSH's-i(IdentityFile), count stays-c. Address family and parallelism inherit the root flags rather than adding subcommand duplicates. The governing rule is stated in the body: a subcommand short flag must not reuse a root letter with a different meaning.--parallel), output modes (normal only, mirroringping), pdsh exposure (none), color thresholds (10ms / 100ms), statistics fields (min/avg/max/stddev, sample output corrected), and exit codes (0/1/255 with 255 following OpenSSH's "ssh itself failed" convention).count * interval. Replaced with the actual figure at the settled defaults.-4/-6are declared atsrc/cli/bssh.rs:281-296and read by nothing, so address family support depends on fix: Wire up -4/-6 address family flags (currently parsed but ignored) #246.pingdocuments exit codes 0/1 but always exits 0) and fix: Wire up -4/-6 address family flags (currently parsed but ignored) #246 (-4/-6parsed but never consumed, along with theAddressFamilyconfig keyword). Both govern decisions listed here.