Skip to content

hop 12 of 32 · 5 min

What travels in front of every packet

Every IPv4 packet carries a 20 byte header. Several fields explain behaviour you can observe with ordinary tools.

The fields that matter

code
version | IHL | TOS |        total length         |
     identification      | flags |  fragment offset |
   TTL    |  protocol    |      header checksum     |
                  source address                    |
               destination address                  |

TTL, time to live: decremented by every router. At zero the packet is discarded and an ICMP message is sent back. It exists so a routing loop consumes a packet rather than circulating it forever.

Protocol: what the payload is. 6 is TCP, 17 is UDP, 1 is ICMP.

Total length: 16 bits, so a packet cannot exceed 65,535 bytes.

Header checksum: covers the header only, not the payload. Since TTL changes at every hop, it is recomputed at every hop, which is real work per packet and is why IPv6 removed it.

Fragmentation

A link with a 1500 byte MTU cannot carry a 4000 byte packet, so IPv4 splits it. The identification, flags and offset fields let the destination reassemble.

Reassembly happens only at the destination, never at an intermediate router, which has an unpleasant consequence: losing one fragment costs the entire packet, so a fragmented flow across a lossy link has a much higher effective loss rate.

Don't fragment can be set, in which case a router that cannot forward it replies with an ICMP message saying so, and the sender reduces its packet size. That is path MTU discovery, and it is why firewalls that block all ICMP cause connections that establish and then hang, a genuinely common and confusing failure.

IPv6 removed router fragmentation entirely. The sender must discover the path MTU and size accordingly.

Watching TTL work

code
$ traceroute example.com
 1  192.168.1.1      1.2 ms      <- sent with TTL 1
 2  10.24.0.1       8.4 ms      <- TTL 2
 3  172.16.8.1     12.1 ms      <- TTL 3

Traceroute sends packets with TTL 1, then 2, then 3. Each router that discards one identifies itself in the ICMP reply, so the path is revealed a hop at a time. It is a clever use of a field designed for something else entirely.