# Traceroute
A (partial) Traceroute re-implementation in Elixir.
Simply start the project with `iex -S mix` and run a trace:
```bash
iex> Traceroute.run("google.com", protocol: :udp, ip_protocol: :ipv4, probes: 3)
1 --redacted-- (--redacted--) 11.235ms 6.939ms 9.518ms
2 192.0.0.1 (192.0.0.1) 11.847ms 12.264ms 13.771ms
3 --redacted-- (--redacted--) 12.738ms 12.677ms 13.035ms
4 fra1901aihb001.versatel.de (62.214.42.58) 14.249ms 16.758ms
89.246.109.249 (89.246.109.249) 21.941ms
5 72.14.217.70 (72.14.217.70) 21.549ms 20.049ms
6 192.178.109.235 (192.178.109.235) 46.902ms 18.17ms 30.988ms
7 142.250.225.76 (142.250.225.76) 98.751ms
142.251.64.184 (142.251.64.184) 107.648ms
142.251.241.75 (142.251.241.75) 18.124ms
8 lcfraa-bt-in-f14.1e100.net (142.251.140.174) 16.132ms 16.391ms
```
For comparison, here's the output from `traceroute`:
```bash
$ traceroute -P udp -w 1 google.com
traceroute to google.com (142.251.140.174), 64 hops max, 40 byte packets
1 --redacted-- (--redacted--) 3.647 ms 3.184 ms 2.751 ms
2 192.0.0.1 (192.0.0.1) 8.222 ms 8.685 ms 8.126 ms
3 --redacted-- (--redacted--) 10.286 ms 9.180 ms 8.877 ms
4 fra1901aihb001.versatel.de (62.214.42.58) 14.209 ms
89.246.109.249 (89.246.109.249) 15.354 ms 15.556 ms
5 72.14.217.70 (72.14.217.70) 16.226 ms * 18.405 ms
6 192.178.109.153 (192.178.109.153) 17.366 ms *
192.178.109.235 (192.178.109.235) 19.176 ms
7 142.251.241.75 (142.251.241.75) 17.459 ms 16.791 ms
142.251.241.77 (142.251.241.77) 15.151 ms
8 142.251.241.75 (142.251.241.75) 15.695 ms 16.032 ms 18.588 ms
9 lcfraa-bt-in-f14.1e100.net (142.251.140.174) 14.811 ms
108.170.236.249 (108.170.236.249) 17.687 ms *
```
## Features
- Sends probes as `ICMP`, `UDP`, and `TCP` packets
- Supports `IPv4` and `IPv6` (use `ip_protocol: :ipv6`)
- Sends multiple probes in parallel with request staggering
- Automatically resolves hostnames for each hop's IP address
- Returns *all* the data in a structured format
## Configurable Options
- `protocol` - Choose between `:icmp`, `:udp`, or `:tcp` (default: `:udp`)
- `ip_protocol` - Choose between `:ipv4` or `:ipv6` (default: `:ipv4`)
- `max_hops` - Maximum number of hops before aborting (default: `20`)
- `max_retries` - Retry count per hop before moving on (default: `3`)
- `timeout` - Response timeout in seconds (default: `1`)
- `probes` - Number of parallel probes per TTL (default: `3`)
- `print_output` - Toggle console output (default: `true`)
## Caveats and Considerations
- This library is untested on Windows. Please report any issues for investigation.
- You may need to run as `sudo` depending on your OS, though try without it first. IPv6 ICMP probes on macOS definitely require sudo. If you get `:eperm` errors, use `sudo`.
- Running many parallel probes can cause performance issues since each ICMP socket receives (but filters) all ICMP replies. Contact me if this affects you. I have a potential fix which is not yet implemented.
## Useful `traceroute` commands to run comparisons
### IPv4
```bash
# Use 1s timeout and the ICMP protocol
traceroute -w 1 -P ICMP fly.io
# Use 1s timeout and the UDP protocol
traceroute -w 1 -P UDP fly.io
# Use 1s timeout and the TCP protocol
# First try without `sudo` but you most likely need elevated permissions
sudo traceroute -w 1 -P tcp google.com
```
### IPv6
```bash
# Use 1s timout and the ICMP protocol
traceroute6 -I -w 1 google.com
# Use 1s timeout and the UDP protocol
traceroute6 -U -w 1 google.com
# Use 1s timeout and the TCP protocol (might need sudo permissions)
traceroute6 -T -w 1 google.com
```
# TODOs
* [ ] De-duplicate ICMP sockets