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.
-
Raw ICMP (Highest privilege)
- Socket:
SOCK_RAWwithIPPROTO_ICMP - Requires: CAP_NET_RAW capability or root (except Windows)
- Features: Full control over IP and ICMP headers
- Platform: Linux, macOS, Windows, FreeBSD, OpenBSD
- Socket:
-
DGRAM ICMP (Medium privilege)
- Socket:
SOCK_DGRAMwithIPPROTO_ICMP - Requires: Root or configured ping_group_range (Linux), no root needed (macOS)
- Features: Kernel handles IP layer
- Platform: Linux, macOS (NOT supported on FreeBSD/OpenBSD)
- Socket:
- UDP (Platform dependent)
- Socket:
SOCK_DGRAMwithIPPROTO_UDP - Linux: No privileges required (uses
IP_RECVERR) - Other platforms: Requires root (needs raw ICMP socket)
- Features: Traditional UDP traceroute (ports 33434+)
- Platform: All
- Note: Linux can receive ICMP errors via
IP_RECVERRwithout root
- Socket:
- TCP SYN (Planned)
- Socket:
SOCK_RAWorSOCK_STREAM - Features: TCP-based traceroute
- Socket:
The socket factory automatically tries modes in order of capability:
ICMP Raw → ICMP DGRAM → UDP
For example:
- Running as root: Uses Raw ICMP for best performance
- Running as user with ping_group_range: Uses DGRAM ICMP
- Running as regular user: Falls back to UDP
# 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 443All 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
)?;- Socket abstraction layer
- Factory with fallback logic
- IPv4 Raw ICMP
- IPv4 DGRAM ICMP
- IPv4 UDP
- IPv6 support (v0.3.0)
- TCP support (v0.3.0)
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:
- Raw ICMP: Root or CAP_NET_RAW (except Windows which works without admin)
- DGRAM ICMP:
- Linux: Root or configured ping_group_range
- macOS: Works without root
- FreeBSD/OpenBSD: Not supported by OS
- UDP:
- Linux: No privileges required (uses
IP_RECVERR) - Other platforms: Root (needs raw ICMP socket for responses)
- Linux: No privileges required (uses
Key insights:
- Linux: UDP mode works completely without privileges
- macOS: DGRAM ICMP works without privileges
- Windows: Raw ICMP works without admin privileges
- FreeBSD/OpenBSD: All traceroute modes require root
This means none of the modes could get the required privileges. Solutions:
-
Run with sudo (works for all modes):
sudo ftr google.com
-
Configure ping_group_range (Linux only, enables DGRAM ICMP):
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.
- Linux: Supports all modes. Configure ping_group_range for unprivileged ICMP.
- macOS: Raw sockets require root. DGRAM ICMP works without root for all users.
- Windows: Uses native Windows ICMP API (IcmpCreateFile). Raw ICMP works without admin.
- FreeBSD: All modes require root. DGRAM ICMP is not supported by the OS.
- OpenBSD: All modes require root. DGRAM ICMP is not supported by the OS.