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
for i in `seq 1 256`; do
  ping -4 -c 1 -t $i $host | grep -iF 'from'
  [[ ${PIPESTATUS[0]} ]] && break

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 -> Reply from first router.
PING TTL=2 -> Reply from second router.
PING TTL=3 -> 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.

Some comments on the short answer:

  • 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.