ftr 0.7.0

A fast, parallel ICMP traceroute with ASN lookup, reverse DNS, and ISP detection
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
# ftr (Fast TraceRoute)

[![Crates.io](https://img.shields.io/crates/v/ftr.svg)](https://crates.io/crates/ftr)
[![License](https://img.shields.io/crates/l/ftr.svg)](https://github.com/dweekly/ftr/blob/main/LICENSE)
[![CI](https://github.com/dweekly/ftr/workflows/CI/badge.svg)](https://github.com/dweekly/ftr/actions)
[![codecov](https://codecov.io/gh/dweekly/ftr/graph/badge.svg)](https://codecov.io/gh/dweekly/ftr)
[![docs.rs](https://docs.rs/ftr/badge.svg)](https://docs.rs/ftr)

A fast, parallel traceroute implementation with automatic ASN lookup. Available as both a command-line tool and a Rust library.

## Features

- **High-Performance** - Parallel probing and smart caching for faster results
- **Library API** - Full-featured async Rust library with structured error handling
- **ASN Enrichment** - Automatic AS number and organization lookup with caching
- **ISP Detection** - Identifies your ISP and classifies network segments
- **Cross-Platform** - Works on Linux, macOS, Windows, FreeBSD, and OpenBSD
- **Multiple Protocols** - ICMP and UDP support with automatic fallback
- **JSON Output** - Structured output for programmatic use
- **Minimal Dependencies** - Efficient design with focus on performance

## Quick Start

### As a CLI Tool

```bash
# Basic usage
ftr google.com

# With custom options
ftr --json --max-hops 20 google.com
```

### As a Library

```rust
use ftr::{Ftr, TracerouteConfig};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Create an Ftr instance
    let ftr = Ftr::new();
    
    // Simple trace
    let result = ftr.trace("google.com").await?;
    println!("Found {} hops", result.hop_count());
    
    // Custom configuration
    let config = TracerouteConfig::builder()
        .target("1.1.1.1")
        .max_hops(20)
        .build()?;
    let result = ftr.trace_with_config(config).await?;
    
    Ok(())
}
```

See [docs/LIBRARY_USAGE.md](docs/LIBRARY_USAGE.md) for comprehensive library documentation.

## Installation

### Windows

#### Installation Options

**Option 1: Download Pre-built Binary** (when available)
- Download the latest Windows binary from the [releases page]https://github.com/dweekly/ftr/releases/latest
- Extract and add to your PATH, or run directly

**Option 2: Build from Source**
```bash
git clone https://github.com/dweekly/ftr
cd ftr
cargo build --release
# The binary will be at target/release/ftr.exe
```

#### Windows-Specific Notes

**Timeout Recommendations:**
- For best reliability with enrichment enabled (default), use probe timeouts ≥ 100ms
- Short timeouts (< 100ms) may cause unreliable results when DNS/ASN lookups are active
- To use shorter timeouts reliably, disable enrichment: `ftr --no-enrich --no-rdns target`

**Example:**
```bash
# Reliable with enrichment
ftr --probe-timeout-ms 100 google.com

# For shorter timeouts, disable enrichment
ftr --probe-timeout-ms 30 --no-enrich --no-rdns google.com
```

For technical details about Windows async implementation, see [docs/WINDOWS_ASYNC_FINDINGS.md](docs/WINDOWS_ASYNC_FINDINGS.md).

### macOS

#### Using Homebrew

```bash
brew tap dweekly/ftr && brew install ftr
```

### Linux

#### Using APT Repository (Debian/Ubuntu)

If you are on a Debian-based Linux distribution (like Ubuntu, Debian, Mint, etc.), you can install ftr using our APT repository for easy installation and updates.

1. Update your package list and install prerequisites:

```bash
sudo apt-get update
sudo apt-get install -y curl gpg ca-certificates
```

2. Add the ftr repository GPG key:

```bash
# Create the directory for GPG keys if it doesn't exist
sudo mkdir -p /usr/share/keyrings

# Download and save the GPG key
sudo curl -sSL https://apt.networkweather.com/networkweather.noarmor.gpg -o /usr/share/keyrings/networkweather-archive-keyring.gpg
```

3. Add the ftr APT repository:

```bash
# Automatically detect your system architecture and add the appropriate repository
ARCH=$(dpkg --print-architecture)
echo "deb [signed-by=/usr/share/keyrings/networkweather-archive-keyring.gpg arch=$ARCH] https://apt.networkweather.com stable main" | sudo tee /etc/apt/sources.list.d/networkweather.list
```

4. Install ftr:

```bash
sudo apt-get update
sudo apt-get install ftr
```

Once installed, ftr will be updated along with your other system packages when you run `sudo apt-get upgrade`.

### Direct Download (Debian/Ubuntu)

Alternatively, you can download the .deb package directly from the [latest release](https://github.com/dweekly/ftr/releases/latest):

```bash
# For x86_64/amd64
wget https://github.com/dweekly/ftr/releases/latest/download/ftr_<version>_amd64.deb
sudo dpkg -i ftr_<version>_amd64.deb

# For ARM64/aarch64
wget https://github.com/dweekly/ftr/releases/latest/download/ftr_<version>_arm64.deb
sudo dpkg -i ftr_<version>_arm64.deb
```

### FreeBSD

#### Using pkg

```bash
# Install from FreeBSD ports (when available)
pkg install ftr
```

#### Building from Source

**Build Dependencies:**
```bash
# Required for building
pkg install -y rust openssl perl5 pkgconf

# Required for runtime functionality
pkg install -y ca_root_nss
```

**Build and Install:**
```bash
# Clone and build
git clone https://github.com/dweekly/ftr
cd ftr
cargo build --release

# Install the binary
sudo cp target/release/ftr /usr/local/bin/
```

**Important Notes:**
- FreeBSD requires **root privileges** for all traceroute operations (no unprivileged ICMP support)
- The `ca_root_nss` package is required for HTTPS connections (public IP detection and ASN lookups)
- Without `ca_root_nss`, you'll see "Warning: Failed to detect public IP"

**Usage on FreeBSD:**
```bash
# Must run as root
sudo ftr google.com

# Or make the binary setuid root
sudo chown root:wheel /usr/local/bin/ftr
sudo chmod u+s /usr/local/bin/ftr
# Then run normally
ftr google.com
```

### OpenBSD

#### Using pkg_add

```bash
# Install from OpenBSD ports (when available)
pkg_add ftr
```

#### Building from Source

**Build Dependencies:**
```bash
# Required for building
pkg_add rust git

# Optional but recommended
pkg_add rsync jq
```

**Build and Install:**
```bash
# Clone and build
git clone https://github.com/dweekly/ftr
cd ftr
cargo build --release

# Install the binary
doas cp target/release/ftr /usr/local/bin/
```

**Important Notes:**
- OpenBSD requires **root privileges** for all traceroute operations (no unprivileged ICMP support)
- Works identically to FreeBSD - requires root/doas for all operations

**Usage on OpenBSD:**
```bash
# Must run as root
doas ftr google.com

# Or make the binary setuid root
doas chown root:wheel /usr/local/bin/ftr
doas chmod u+s /usr/local/bin/ftr
# Then run normally
ftr google.com
```

### Using Cargo

```bash
cargo install ftr
```

*Note: Cargo installation will be available once ftr is published to crates.io.*

## Usage

Basic usage:
```bash
ftr google.com
```

With options:
```bash
ftr example.com -m 20 -W 5000
```

### Options

- `-s, --start-ttl <START_TTL>` - Starting TTL value (default: 1)
- `-m, --max-hops <MAX_HOPS>` - Maximum number of hops (default: 30)
- `--probe-timeout-ms <MS>` - Timeout for individual probes in milliseconds (default: 1000)
- `-i, --send-launch-interval-ms <MS>` - Interval between launching probes (default: 5)
- `-W, --overall-timeout-ms <MS>` - Overall timeout for the traceroute (default: 3000)
- `--no-enrich` - Disable ASN lookup and segment classification
- `--no-rdns` - Disable reverse DNS lookups

## Example Output

```
ftr to google.com (142.251.46.174), 30 max hops, 1000ms probe timeout, 3000ms overall timeout

Performing ASN lookups, reverse DNS lookups and classifying segments...
 1 [LAN   ] unifi.localdomain (192.168.1.1) [Private Network]    2.854 ms
 2 [ISP   ] lo0.bras2.rdcyca01.sonic.net (157.131.132.109) [AS46375 - AS-SONICTELECOM, US]    3.861 ms
 3 [ISP   ] 135-180-179-42.dsl.dynamic.sonic.net (135.180.179.42) [AS46375 - AS-SONICTELECOM, US]    6.342 ms
 4 [ISP   ] ae8.cr2.lsatca11.sonic.net (142.254.59.217) [AS46375 - AS-SONICTELECOM, US]   16.705 ms
 5 [ISP   ] ae2.cr1.lsatca11.sonic.net (157.131.209.161) [AS46375 - AS-SONICTELECOM, US]   12.469 ms
 6 [TRANSIT] be3402.ccr31.sjc04.atlas.cogentco.com (154.54.80.241) [AS174 - COGENT-174, US]    3.904 ms
 7 [TRANSIT] be3142.ccr41.sjc03.atlas.cogentco.com (154.54.42.89) [AS174 - COGENT-174, US]    3.989 ms
 8 [TRANSIT] tata.sjc03.atlas.cogentco.com (154.54.13.62) [AS174 - COGENT-174, US]    3.177 ms
 9 [DESTINATION] 72.14.195.206 [AS15169 - GOOGLE, US]    6.174 ms
10 [DESTINATION] 108.170.252.33 [AS15169 - GOOGLE, US]    5.316 ms
11 [DESTINATION] 142.250.49.206 [AS15169 - GOOGLE, US]    4.892 ms
12 [DESTINATION] sfo07s16-in-f14.1e100.net (142.251.46.174) [AS15169 - GOOGLE, US]    3.275 ms
Detected ISP from public IP 192.184.165.158: AS46375 (AS-SONICTELECOM, US)
```

## Requirements

- Rust 1.85.0 or later (for building from source)
- Platform-specific requirements:
  - **Linux**: Root privileges or configured ping_group_range for ICMP functionality
  - **macOS**: Root privileges may be required for raw socket access
  - **Windows**: No additional requirements (uses native Windows ICMP API)
    - Note: Windows Firewall may prompt for permission on first run
    - **CI/Cloud Limitation**: GitHub Actions Windows runners and Azure VMs block inbound ICMP packets, preventing traceroute from receiving responses. This is an Azure network-level restriction that cannot be bypassed with firewall rules. Consider using self-hosted runners for full network testing on Windows.
  - **FreeBSD**: Root privileges required for ICMP (no DGRAM ICMP support)
  - **OpenBSD**: Root privileges required for ICMP (no DGRAM ICMP support)

### Privilege Requirements

Privilege requirements vary by mode and platform:
- **ICMP modes**: Root or ping_group_range configuration
- **UDP mode**: 
  - Linux: No privileges required (uses `IP_RECVERR`)
  - Other platforms: Root (needs raw socket for ICMP responses)

On Linux, you can enable DGRAM ICMP for non-root users:
```bash
sudo sysctl -w net.ipv4.ping_group_range="0 65535"
```

## Building from Source

### Prerequisites

- **Rust**: Version 1.82.0 or later (install from [rustup.rs]https://rustup.rs/)
- **Platform-specific dependencies**:
  - **Linux**: Standard build tools (gcc/clang, make)
  - **macOS**: Xcode Command Line Tools
  - **Windows**: Visual Studio Build Tools or MinGW
  - **FreeBSD**: `pkg install -y rust openssl perl5 pkgconf rsync`
  - **OpenBSD**: `pkg_add rust`

### Build Steps

```bash
git clone https://github.com/dweekly/ftr
cd ftr

# Install git hooks (IMPORTANT: prevents issues caught by CI)
./.githooks/install-hooks.sh
# OR configure git to use .githooks directory:
# git config core.hooksPath .githooks

cargo build --release

# Binary will be at: target/release/ftr
```

### Platform-Specific Notes

- **All platforms**: The git hooks ensure code quality standards are met before commits

## How It Works

This traceroute implementation:
1. Sends ICMP Echo Request packets with increasing TTL values
2. Captures ICMP Time Exceeded messages from intermediate routers
3. Performs reverse DNS and ASN lookups for discovered hops
4. Uses parallel probing to significantly reduce total scan time

## Performance

Unlike traditional sequential traceroute implementations, this tool sends multiple probes in parallel, dramatically reducing the time needed to map a complete network path.

### Benchmarks

Typical performance improvements over traditional traceroute:
- **30-hop trace**: ~3 seconds vs ~30 seconds (10x faster)
- **15-hop trace**: ~1.5 seconds vs ~15 seconds (10x faster)

The parallel approach maintains accuracy while significantly reducing wait time.

## License

MIT License - see LICENSE file for details

### Segment Labels

When enrichment is enabled (default), each hop is labeled:
- `LAN`: local/private addresses
- `ISP`: your provider’s network (includes CGNAT range)
- `TRANSIT`: networks after ISP with different ASNs than the destination
- `DESTINATION`: networks in the destination’s ASN
- `UNKNOWN`: insufficient data to classify

## Documentation

| Document | Description |
|----------|-------------|
| [CHANGELOG.md]CHANGELOG.md | Release history and migration guides |
| [CONTRIBUTING.md]CONTRIBUTING.md | Contribution guidelines |
| [TODO.md]TODO.md | Active development tasks and roadmap |
| [CLAUDE.md]CLAUDE.md | AI agent instructions for working with this codebase |
| [docs/LIBRARY_USAGE.md]docs/LIBRARY_USAGE.md | Using ftr as a Rust library (API examples, configuration) |
| [docs/RELEASE_PROCESS.md]docs/RELEASE_PROCESS.md | Secure release workflow |
| [docs/MULTI_MODE.md]docs/MULTI_MODE.md | Multi-probe per hop feature |
| [docs/UDP_TRACEROUTE_LINUX.md]docs/UDP_TRACEROUTE_LINUX.md | Linux UDP traceroute and IP_RECVERR |
| [docs/TIMING_CONFIGURATION.md]docs/TIMING_CONFIGURATION.md | Timing system for performance tuning |
| [docs/WINDOWS_ASYNC_FINDINGS.md]docs/WINDOWS_ASYNC_FINDINGS.md | Windows async ICMP implementation analysis |
| [docs/IXP_DETECTION_PROPOSAL.md]docs/IXP_DETECTION_PROPOSAL.md | Proposed IXP/peering point detection (future) |
| [docs/WHOIS_ENHANCEMENT_PROPOSAL.md]docs/WHOIS_ENHANCEMENT_PROPOSAL.md | Proposed WHOIS fallback for network ownership (future) |
| [scripts/README.md]scripts/README.md | Cross-platform VM testing scripts |
| [scripts/vagrant-quick-start.md]scripts/vagrant-quick-start.md | Automated VM testing with Vagrant |
| [.githooks/README.md].githooks/README.md | Git hooks setup and usage |

## Contributing

Contributions are welcome! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.

## License

MIT License - see [LICENSE](LICENSE) file for details.

## Author

David Weekly ([dweekly](https://github.com/dweekly))