Starting with v0.2.1, ftr supports multiple probing modes with automatic fallback. This allows the tool to work in various permission environments and network configurations.
SOCK_RAW with IPPROTO_ICMPSOCK_DGRAM with IPPROTO_ICMPSOCK_DGRAM with IPPROTO_UDPIP_RECVERR)IP_RECVERR without rootSOCK_RAW or SOCK_STREAMThe socket factory automatically tries modes in order of capability:
ICMP Raw → ICMP DGRAM → UDP
For example:
# Default (automatic mode selection)
ftr google.com
# Force UDP mode
ftr -U google.com
# Force ICMP mode (will fail if insufficient permissions)
ftr -I google.com
# TCP mode (not yet implemented)
ftr -T google.com -p 443
All probe modes implement the ProbeSocket trait:
pub trait ProbeSocket: Send + Sync {
fn mode(&self) -> ProbeMode;
fn set_ttl(&self, ttl: u8) -> Result<()>;
fn send_probe(&self, target: IpAddr, probe_info: ProbeInfo) -> Result<()>;
fn recv_response(&self, timeout: Duration) -> Result<Option<ProbeResponse>>;
fn destination_reached(&self) -> bool;
}
The create_probe_socket function handles mode selection:
let socket = create_probe_socket(
target_ip,
Some(ProbeProtocol::Udp) // Preferred protocol
)?;
Run the socket test example:
# Test default mode selection
cargo run --example test_socket -- google.com
# Test UDP mode
cargo run --example test_socket -- google.com --udp
| Platform | Raw ICMP | DGRAM ICMP | UDP (send) | UDP (recv ICMP) | Non-root Option |
|---|---|---|---|---|---|
| Linux | Root | Root/ping_group | No root | No root (IP_RECVERR) | ✓ UDP or DGRAM |
| macOS | Root | No root | No root | Root | ✓ DGRAM ICMP |
| Windows | No admin | N/A | No admin | No admin | ✓ Raw ICMP |
| FreeBSD | Root | N/A | No root | Root | ✗ None |
| OpenBSD | Root | N/A | No root | Root | ✗ None |
Privilege requirements vary by mode and platform:
IP_RECVERR)Key insights:
This means none of the modes could get the required privileges. Solutions:
sudo ftr google.com
echo "net.ipv4.ping_group_range = 0 65535" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
After this, DGRAM ICMP mode will work without sudo.
UDP traceroute sends UDP packets (no privileges needed) but must receive ICMP “Port Unreachable” responses, which requires a raw socket. There’s no way around this requirement.