This would be a pretty good interview question.

Suppose you’re on a system which is having trouble downloading the latest packages. You’re on the phone with the network team and they ask for a trace. But much to your dismay the traceroute command isn’t on the system. How do you proceed?

The Short Answer

#! /usr/bin/env bash

host=google.com
for i in `seq 1 256`; do
  ping -4 -c 1 -t $i $host | grep -iF 'from'
  [[ ${PIPESTATUS[0]} ]] && break
done

The Long Answer

In order to keep packets from erroneously bouncing around a network indefinitely IP packets, both IPv4 and IPv6, have an 8-bit field denoting the packets ‘time to live’ or TTL. This value is set initially by the sender and is decremented each time the packet passes though a router. When the value reaches zero the packet is dropped and the router sends a Time Exceeded message back to the sender.

The traceroute program uses this fact, along with the assumption that path though a network will remain relatively constant over a short period of time, to determine path taken though the network by sending a series of pings with an increasing TTL.

For example:

PING TTL=1 example.com -> Reply from first router.
PING TTL=2 example.com -> Reply from second router.
PING TTL=3 example.com -> Reply from third router.
...

Since the TTL is an 8 bit field we just need to loop until either we reach our destination or the TTL is 255 which is what the short answer does.

Comments

  • PIPESTATUS is a bash-ism that contains the exit status of the nth command in the previous pipe in an array.
  • ping returns 1 on a Time Exceeded message and 0 when it reaches the destination. When we see an exit status of 0 we can break out of the loop. There are other corner cases we might consider but this is good enough for a whiteboard question.
  • The lines we’re interested in from ping start either with From in the case of a Time Exceeded message or from when we reach our destination.