The IPv4 Datagram
IPv4 is the internet's layer-3 workhorse: a 32-bit address space and a datagram header carrying the source, destination, time-to-live, protocol, and fragmentation fields a router needs to forward a packet. It is connectionless and best-effort — each datagram is forwarded independently, and the header holds everything required to route it and nothing about whether it arrives, in what order, or whether anyone retransmits it.
The header is small and deliberate. With no options it is 20 bytes, and almost every field exists so a router can make a forwarding decision in nanoseconds without holding per-connection state. Reliability, ordering, and flow control all live a layer up in TCP. Once you can name what each field does and which one changes per hop, the rest of routing — TTL expiry, QoS marking, fragmentation — stops being mysterious.
The IPv4 Header
The fixed part of the header is 20 bytes; options, rarely used, can extend it to 60. The fields that matter day to day are a handful: the 8-bit TTL that bounds a packet's lifetime, the 8-bit protocol number that says what's inside, the 6-bit DSCP and 2-bit ECN fields for quality of service, the 16-bit total length, and the source and destination addresses at 32 bits each. The header carries its own checksum, which every router must recompute because the TTL changed.
The 13-bit fragment offset and the flags exist because IPv4 lets a router fragment a datagram too big for the next link's MTU. Fragmentation is a performance and reliability tax — lose one fragment and the whole datagram is discarded — so modern stacks set the Don't Fragment bit and rely on path MTU discovery instead. You see the header laid out field by field in a capture.
# tcpdump -v decodes the IPv4 header fields directly tcpdump -n -v -i eth0 host 93.184.216.34 # IP (tos 0x0, ttl 63, id 54321, offset 0, flags [DF], # proto TCP (6), length 60) # 10.0.1.7.52344 > 93.184.216.34.443: Flags [S] ... # tos = DSCP+ECN | ttl = lifetime | proto 6 = TCP | DF = don't fragment
TTL and Loop Prevention
The TTL is a single byte — 0 to 255 — and every router that forwards a packet decrements it by one. When it hits zero, the router drops the packet and sends an ICMP time-exceeded back to the source. This is the only thing standing between a routing loop and a packet circulating forever: without TTL, one misconfigured route could melt a link with a packet that never dies.
That same mechanism is what traceroute exploits. It sends packets with TTL 1, then 2, then 3, and each router along the path obligingly drops one and identifies itself in the time-exceeded reply. The hops you see in a traceroute are not a feature — they are routers honoring the loop-prevention rule. A typical TTL starts at 64 on Linux or 128 on Windows, which is why a reply arriving with TTL 51 tells you roughly 13 hops of distance.
The Protocol Field
An IP packet's payload could be TCP, UDP, ICMP, or dozens of others, and the receiving host has to know which before it can hand the bytes to the right code. The 8-bit protocol field does that demultiplexing: 1 means ICMP, 6 means TCP, 17 means UDP. It is the layer-3 analog of the destination port at layer 4 — one number that selects which upper layer parses the rest.
This matters for more than parsing. Firewall rules, NAT tables, and load balancers all key on the protocol number to decide how to treat a flow — a rule that allows TCP says nothing about UDP or ICMP on the same addresses. Block ICMP wholesale and you also break path MTU discovery, because the "fragmentation needed" message that carries the correct MTU is an ICMP packet.
DSCP and ECN
The byte that used to be called the Type of Service is now split: the top 6 bits are DSCP, a quality-of-service marking, and the bottom 2 bits are ECN. DSCP lets you classify a packet — voice as expedited forwarding, bulk backup as best-effort — so routers with congestion can queue or drop by class. The marking is honored only inside a domain that agrees to it; the public internet routinely rewrites or ignores DSCP at the boundary.
ECN is the smarter half. Instead of dropping a packet to signal congestion, an ECN-aware router sets a bit, the receiver echoes it back in the TCP ACK, and the sender slows down without any loss at all. The catch is that it only works if both endpoints negotiated ECN and every router on the path respects the bits — one ECN-blind middlebox that clears them and the whole mechanism silently degrades to plain loss-based congestion control.
The IPv4 header is 20 bytes minimum and variable — options can push it to 60 — and it carries a header checksum plus fragmentation fields, because any router on the path may fragment a datagram. That variability and the per-hop checksum recomputation are the costs IPv6 set out to remove.
The IPv6 header is a fixed 40 bytes with no checksum and no router-side fragmentation — fragmentation, when it happens at all, is pushed to the endpoints. The header is larger in bytes but simpler to process, which is the whole point: predictable, fixed-cost forwarding at line rate.
- Reading a traceroute without accounting for TTL. The intermediate hops are routers dropping TTL-expired packets, not the destination; a star or timeout at one hop usually means that router rate-limits ICMP, not that the path is broken there.
- Assuming IP guarantees order or delivery. The header has no sequence number and no acknowledgment — an application that breaks on a reordered or lost packet is relying on a property IP never promised, and load will eventually expose it.
- Enabling ECN on one side and assuming it works. ECN needs both endpoints to negotiate it and every router on the path to preserve the bits; a single middlebox that clears them drops you back to loss-based congestion control with no warning.
- Blocking all ICMP at a firewall. That kills path MTU discovery, because the "fragmentation needed" message is ICMP — large packets then black-hole silently and connections hang instead of failing cleanly.
- Treating the protocol field as cosmetic. A firewall rule that permits TCP to a host says nothing about UDP or ICMP to the same host; each protocol number is a separate decision and must be scoped on purpose.
- Set the Don't Fragment bit and rely on path MTU discovery rather than letting routers fragment, since one lost fragment discards the whole datagram and fragment reassembly is a known attack surface.
- Read the starting TTL to fingerprint the source OS and estimate hop count — a reply with TTL 51 most likely started at 64 and traveled 13 hops, which localizes where latency or loss enters.
- Allow ICMP type 3 code 4 ("fragmentation needed") through every firewall even when you filter other ICMP, so path MTU discovery keeps working and large transfers don't hang.
- Mark DSCP only within a domain you control and trust to honor it, and assume the marking is stripped or rewritten at any internet boundary rather than expecting end-to-end QoS.
- Scope firewall and NAT rules by explicit protocol number, writing separate rules for TCP, UDP, and ICMP instead of assuming a single rule covers a host's whole traffic profile.
Knowledge Check
What does the IPv4 TTL field prevent, and how?
- Routing loops, by being decremented each hop and dropped at zero so a looping packet cannot circulate forever
- Out-of-order delivery, by timestamping each packet so the receiver can sort the arrivals back into their original sequence
- Oversized packets, by capping how many bytes a datagram may carry across a link
- Header corruption, by acting as a running checksum updated at every hop
What is the role of the 8-bit protocol field in the IPv4 header?
- It tells the receiver which upper-layer protocol — TCP, UDP, or ICMP — should parse the payload
- It identifies which specific host on the destination subnet should ultimately receive and process the datagram
- It counts how many protocol layers the packet has crossed for loop detection
- It encodes the packet's traffic class so routers can prioritize it under load
Why is ECN often ineffective on the public internet despite both endpoints supporting it?
- A single router or middlebox on the path that clears the ECN bits defeats it for the whole flow
- ECN is defined only for IPv6, so any IPv4 segment of the path cannot carry it
- ECN works by dropping marked packets, which the receiving endpoints then misread as line corruption rather than congestion
- ECN must be renegotiated on every packet, which adds too much overhead to sustain
You got correct