Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ft_traceroute

A from-scratch reimplementation of the traceroute command in C, as required by the 42 ft_traceroute subject.

It maps the route IP packets take to a host by sending UDP probes with an increasing TTL: each router that drops a probe (TTL reached 0) answers with an ICMP Time Exceeded, and the destination answers with an ICMP Port Unreachable. Those replies, caught on a raw ICMP socket, reveal one hop per TTL. Output and indentation match the real traceroute.

Build

make            # builds ./ft_traceroute
make re         # rebuild from scratch
make clean      # remove object files
make fclean     # remove objects + binary

ft_traceroute needs raw-socket privileges (CAP_NET_RAW) for the ICMP receive socket: run it as root, with sudo, after setcap cap_net_raw+ep ./ft_traceroute, or inside the provided Docker container.

Run

sudo ./ft_traceroute 8.8.8.8
sudo ./ft_traceroute google.com
sudo ./ft_traceroute -m 10 8.8.8.8      # cap the trace at 10 hops

Output:

traceroute to 8.8.8.8 (8.8.8.8), 30 hops max, 60 byte packets
 1  172.22.0.1  0.151 ms  0.032 ms  0.026 ms
 2  192.168.1.1  4.491 ms  3.116 ms  3.120 ms
 3  80.10.4.65  5.424 ms  5.142 ms  4.995 ms
 4  * * *

How it works

  • Send socket — a UDP socket. Its TTL is bumped hop by hop with setsockopt(IP_TTL); each probe targets port base_port + n so a reply can be paired back to the exact probe that caused it.
  • Receive socket — a raw IPPROTO_ICMP socket. select() waits (up to 3 s) for the matching Time Exceeded / Unreachable error, whose quoted payload carries our original UDP header (source + destination ports) for identification.
  • No reverse DNS on hops — as the subject requires, hops print bare numeric addresses (inet_ntoa); only the destination is resolved once, for the header line.
  • fcntl, poll and ppoll are never used — reception is driven by select().

Options

Mandatory (per the subject): --help.

Flag Meaning
--help print the help list and exit

Bonus flags (man traceroute semantics):

Flag Meaning
-i device bind the probe socket to this network interface
-m max_ttl maximum number of hops (default 30)
-p port base destination port (default 33434)
-s src_addr use this source address
-t tos set the IP type of service

Values may be attached (-m10) or given as the next argument (-m 10).

Controlled environment (Docker / Debian)

docker/Dockerfile builds a Debian image with the system traceroute for side-by-side comparison and NET_RAW granted — ft_traceroute itself never calls any external traceroute.

make docker-build                                       # build the image
make up                                                 # start it in background
docker compose exec fttraceroute make re                # build inside it
docker compose exec fttraceroute ./ft_traceroute 8.8.8.8
docker compose exec fttraceroute traceroute -n 8.8.8.8  # system reference
make down                                               # stop / remove it

Layout

inc/ft_traceroute.h   public declarations
src/main.c            entry point
src/args.c            command-line parsing, help/usage
src/resolve.c         destination resolution (forward only)
src/traceroute.c      sockets, probe send/recv loop, per-hop printing
src/utils.c           time math, fatal errors
docker/Dockerfile     Debian build/compare environment

Resources:

https://datatracker.ietf.org/doc/html/rfc792 — ICMP https://man7.org/linux/man-pages/man8/traceroute.8.html https://networklessons.com/ip-routing/ipv4-packet-header

Contributors

Languages