Educational implementation of a traceroute-like tool (UDP probes with ICMP Time Exceeded / Destination Unreachable) written in C.
This repository provides:
- a
ft_traceroutebinary buildable withmake - a ready-to-use Docker environment (including the NET_RAW capability required for raw ICMP sockets)
- argument parsing based on argp, with options close to the standard
traceroute
make- a C compiler (
cc/gcc) - sufficient permissions to open raw sockets (see Permissions)
A Dockerfile and a docker-compose.yml are included to build and run the project inside a Debian container.
From the project root:
makeThe resulting binary is:
./ft_tracerouteThe Makefile provides a debug target enabling debug symbols and sanitizers:
make debugBasic usage:
./ft_traceroute <host>Examples:
./ft_traceroute 8.8.8.8
./ft_traceroute google.comThe argument parser currently supports:
-f FIRST_TTL,--first=FIRST_TTL: start from FIRST_TTL hop (default: 1)-m MAX_TTL,--max-hops=MAX_TTL: set maximum number of hops (default: 30)-p PORT,--port=PORT: set base UDP destination port (default: 33434)--help: display help message
Example:
./ft_traceroute -m 15 -f 3 google.comft_traceroute uses the classic UDP-based traceroute method:
- Sends UDP packets to high destination ports (starting at 33434) with increasing TTL values
- Each router along the path decrements the TTL; when it reaches 0, the router sends back an ICMP Time Exceeded message
- When the packet reaches the destination, the host responds with an ICMP Destination Unreachable (Port Unreachable) message
- The program measures the round-trip time (RTT) for each probe
For each TTL, 3 probes are sent to provide multiple RTT measurements and detect routing variations.
Receiving ICMP packets with a raw socket generally requires elevated privileges.
sudo ./ft_traceroute 8.8.8.8The Makefile attempts to apply this capability automatically after linking:
setcap cap_net_raw+ep ft_tracerouteIf needed, you can apply it manually:
sudo setcap cap_net_raw+ep ./ft_tracerouteYou can check capabilities with:
getcap ./ft_tracerouteNote: capabilities depend on your filesystem and distribution policies.
The provided compose configuration adds the required capability:
cap_add:
- NET_RAWThe Makefile includes Docker shortcuts:
make docker-build
make docker-up
make docker-enterAlso you can directly run:
make docker-enterOnce inside the container:
make
./ft_traceroute 8.8.8.8docker compose build
docker compose up -d
docker compose exec ft_traceroute bash$ ./ft_traceroute google.com
traceroute to google.com (216.58.214.78), 30 hops max, 60 byte packets
1 _gateway (10.1.2.1) 5.428 ms 5.379 ms 5.371 ms
2 10.0.2.2 7.609 ms 7.588 ms 7.586 ms
3 10.0.0.11 4.739 ms 4.687 ms 4.682 ms
4 194.199.3.1 5.915 ms 5.874 ms 5.871 ms
- Each line shows a hop number, the router's IP address, and 3 RTT measurements
*indicates a probe that timed out (no response received)- When multiple routers respond for the same TTL, their IPs are shown
You can capture ICMP and UDP traffic on a network interface such as eth0:
tcpdump -i eth0 -nn -s 0 -w traceroute.pcap 'icmp or (udp and portrange 33434-33500)'-i eth0: capture on the Ethernet interface-nn: disable name resolution (numeric output)-s 0: capture entire packets-w file.pcap: write to a pcap file for Wireshark analysis
You can list available interfaces with:
tcpdump -D- User Datagram Protocol: https://www.rfc-editor.org/rfc/rfc768
- ICMP (RFC 792): https://www.rfc-editor.org/rfc/rfc792
- IP Protocol (RFC 791): https://www.rfc-editor.org/rfc/rfc791
- traceroute from inetutils-manual: https://www.gnu.org/software/inetutils/manual/html_node/traceroute-invocation.html