§4.3.1IPv4 Datagram Format

Network layer Kurose & Ross pp. 330–332 · ~14 min read

  • datagram
  • ipv4 time-to-live
  • internet checksum

Where you are

  • Application layer
  • Transport layer
  • Network layer you are here
  • Link layer
  • Physical layer

Twenty bytes of header, and every field in it exists because something in the network needed to be told something.

Words you will meet

  • Datagram — the network layer’s packet. A header plus a payload, usually a transport-layer segment.
  • TTL (Time To Live) — how many more routers this datagram may cross before being dropped.
  • TOS (Type Of Service) — type of service, for distinguishing kinds of traffic.
  • Upper-layer protocol — which transport protocol gets the payload. 6 for TCP (Transmission Control Protocol) , 17 for UDP (User Datagram Protocol) .
  • Fragmentation — splitting a datagram too big for the next link, and reassembling it at the destination.
  • MTU (maximum transmission unit) — the largest payload a link will carry. 1,500 bytes on Ethernet.

Why this matters

The book is unusually direct about this section: every networking student and professional needs to see it, absorb it, and master it.

The reason is that this header is the only thing every device in the Internet agrees about. Section 4.5 draws the picture — a narrow waist, with enormous variety above and below and exactly one protocol in the middle. These twenty bytes of IPv4 (Internet Protocol version 4) header are that waist.

They are also where several earlier chapters land. The explicit congestion notification bits of section 3.7.2 live here. The Internet checksum of section 3.3 is computed here, over a different range and for a different reason. And the protocol number does for the network and transport layers exactly what a port number does for transport and application.

The datagram, field by field

Figure 4.17 — the IPv4 datagram
08162432bitVersion4 bitsHeader length4 bitsType of service8 bitsDatagram length16 bitsIdentifier16 bitsFlagsFragment offset13 bitsTime-to-live8 bitsUpper-layer protocol8 bitsHeader checksum16 bitsSource IP address32 bitsDestination IP address32 bitsOptions32 bitsData (payload)variable number of resource recordsusually a TCP or UDP segment

Click any box to read what that part of the message is for.

Every field, as text
  • Version — 4 bits — which IP this is (example: 4)
  • Header length — 4 bits — where the payload starts (example: 5)
  • Type of service — 8 bits — what kind of traffic this is (example: 0x00)
  • Datagram length — 16 bits — total size, header and data, in bytes (example: 1500)
  • Identifier — 16 bits — which original datagram this is a piece of (example: 0x2b01)
  • Flags — 3 bits — don’t fragment, and more fragments (example: 010)
  • Fragment offset — 13 bits — where this piece belongs, in units of 8 bytes (example: 0)
  • Time-to-live — 8 bits — how many more routers this may cross (example: 64)
  • Upper-layer protocol — 8 bits — which transport protocol gets the payload (example: 6)
  • Header checksum — 16 bits — detect bit errors in the header (example: 0x34d4)
  • Source IP address — 32 bits — who sent it (example: 192.168.1.24)
  • Destination IP address — 32 bits — where it is going (example: 198.51.100.7)
  • Options — 32 bits — rarely used extensions (example: (usually absent))

Twenty bytes, in five rows of 32 bits, when there are no options — which is nearly always. Click any field.

Three fields worth stopping on

Time-to-live. Decremented by one at every router; at zero the datagram is dropped. It exists because of routing loops — without it, a datagram caught in one would circulate for ever, consuming capacity nothing could reclaim. It is also the field that makes traceroute possible, which is how chapter 1.4.3 measured a path.

Upper-layer protocol. Read only at the final destination. No router in between cares which transport protocol is inside; that is the layering working. The book’s own framing is worth keeping:

The protocol number is the glue that binds the network and transport layers together, whereas the port number is the glue that binds the transport and application layers together.

Chapter 6 completes the set — the link-layer frame has a field binding the link layer to the network layer. You have already seen it in every capture on this site: EtherType 0x0800 (IPv4).

Header checksum. Computed over the header only, never the data. And it must be recomputed at every single router, because the time-to-live field has just changed. That is real work, on every datagram, at every hop — and it is one of the things IPv6 (Internet Protocol version 6) deletes.

Why check for errors twice?

TCP already checksums. Why does IP (Internet Protocol) checksum as well? The book gives two reasons, and they are better than “belt and braces”.

They cover different things. The IP checksum covers only the IP header. The TCP or UDP checksum covers the entire segment, header and data. Neither is a superset of the other, and a corrupted destination address would be caught by one and not the other.

They are not necessarily in the same stack. TCP can in principle run over a different network layer — the book names ATM (Asynchronous Transfer Mode) . And IP can carry payloads that never reach TCP or UDP at all, such as the ICMP (Internet Control Message Protocol) messages of section 5.6. A layer relying on a checksum from a neighbour it might not have would be relying on nothing.

Fragmentation, which the book leaves out

The book says plainly: “We’ll not cover fragmentation here; but readers can find a detailed discussion online, among the retired material from earlier versions of this book.”

This site covers it. Three of the header’s fields exist for nothing else, the chapter’s own review question R20 and several problems ask about it, and a reader who skips it cannot answer them. What follows is the standard mechanism from [RFC 791], worked on the canonical example.

Fragmentation — a 4,000-byte datagram meeting a 1,500-byte link
1 — The next link has a maximum transmission unit of 1,500 bytesstep 1 of 6
original datagram: 4,000 bytes = 20-byte header + 3,980 bytes of datahdr3,980 bytes of dataMTU = 1,500 bytes → 4,000 does not fit

The datagram is 4,000 bytes and will not fit. The router must either drop it — which is what the DF flag asks for — or break it into pieces that do fit.

The book leaves this out and then asks about it in R20 and the problems, so here it is. Step through and watch three fields do all the work: identifier, flags and fragment offset.

Read all steps as text
  1. 1 — The next link has a maximum transmission unit of 1,500 bytesThe datagram is 4,000 bytes and will not fit. The router must either drop it — which is what the DF flag asks for — or break it into pieces that do fit.
  2. 2 — How much data fits in one fragment?Every fragment needs its own 20-byte header, leaving 1,480 bytes for data. And the fragment offset field counts in units of 8 bytes, so every fragment except the last must carry a multiple of 8. 1,480 is a multiple of 8, so it is the answer exactly.
  3. 3 — Fragment 1: data bytes 0 to 1,479Total length 1,500. More-fragments flag set to 1, because two pieces follow. Fragment offset 0, because this piece starts at the beginning.
  4. 4 — Fragment 2: data bytes 1,480 to 2,959Same size. Offset is 1,480 ÷ 8 = 185. More fragments still follow, so MF is still 1. The identifier is the same as fragment 1 — that is what tells the destination these belong together.
  5. 5 — Fragment 3: data bytes 2,960 to 3,979Only 1,020 bytes are left, so this fragment is 1,040 bytes in total. Offset is 2,960 ÷ 8 = 370. MF is 0 — and that zero is the only thing telling the destination that the datagram is now complete.
  6. 6 — Reassembly happens only at the destinationNot at the next router, and not at any router afterwards. The three fragments are forwarded independently and may take different routes. Only the destination host puts them back together, and only then is the payload passed up to the transport layer.

In plain words

Different links carry different maximum sizes. Ethernet takes 1,500 bytes; some links take less. A datagram may arrive that is too big for the next link. The router then breaks it into fragments, each a complete datagram in its own right with its own 20-byte header.

Three fields do all of it:

  • Identifier — the same in every fragment of one original, so the destination knows which pieces go together.
  • Fragment offset — where this piece belongs, counted in 8-byte units. That unit is why every fragment but the last must carry a multiple of 8 bytes.
  • More fragments (MF) — 1 on every fragment but the last. The single 0 at the end is the only signal that the datagram is complete.

And the rule that surprises people: reassembly happens only at the destination host, never at the next router. The fragments are forwarded independently and may take different paths. A router that fragments is not undoing anyone’s work; it is creating work that only the far end can finish.

Why fragmentation is considered a mistake

The book drops it from IPv6 entirely, and mentions that in passing. It is worth saying why.

One lost fragment destroys the whole datagram. The destination cannot reassemble without every piece, so losing one 1,480-byte fragment wastes all 4,000 bytes. The loss rate a datagram experiences is effectively multiplied by the number of fragments.

It is expensive at exactly the wrong place. Fragmenting means allocating, copying and building new headers — per packet, in the data plane, where section 4.2.1 measured the budget at 5.12 nanoseconds.

It is a gift to attackers. Overlapping fragment offsets can be used to make a firewall and the destination host reassemble the same fragments into different datagrams.

The modern answer is path MTU discovery. The sender sets the DF flag; a router that cannot forward the datagram drops it and reports back; the sender tries a smaller size. Fragmentation moves to the one place that can do it cheaply — the source. IPv6 makes that the only option, as section 4.3.4 covers.

Twenty bytes, in proportion

What 20 bytes of header costs
bytesPayloadbytes

Cells marked ⓘ have an explanation — click to read it. Sortable columns have a ↕ in the heading.

Header overhead as a fraction of what is actually sent, for the datagram sizes the book mentions. Sort by overhead.

Two numbers from the table

1,500 bytes is not a coincidence. The book notes datagrams are rarely larger, because 1,500 is exactly what fits in the payload of a maximally sized Ethernet frame. The link layer’s limit, set decades ago, shapes the size of nearly every packet on the Internet.

A datagram carrying a TCP segment costs 40 bytes of header — 20 of IP plus 20 of TCP — before any application data at all. At 1,500 bytes that is 2.7 %, which is fine. At 40 bytes, for a pure acknowledgement, it is all of it: the packet is header and nothing else. Chapter 3’s capture is full of them.

Check yourself

Check yourself

0 of 7 answered
  1. 1.Why must a router recompute the header checksum for every datagram it forwards?

  2. 2.TCP already checksums its segments. Why does IP checksum as well?

  3. 3.predictA 4,000-byte datagram must cross a link with a 1,500-byte MTU. Why does each fragment carry 1,480 bytes of data rather than 1,484?

    What units does the fragment offset field count in?

  4. 4.predictWhere are the three fragments reassembled?

  5. 5.One of three fragments is lost. What reaches the destination's transport layer?

  6. 6.What does the upper-layer protocol field do, and who reads it?

  7. 7.predictA pure TCP acknowledgement carries no application data. How much of the 40-byte packet is header?

What to remember

  • Time-to-live stops routing loops, is decremented at every router, and is what makes traceroute work.
  • The header checksum covers the header only, and is recomputed at every hop, because the time-to-live has changed. Checking errors twice is not redundant: the two checksums cover different ranges, and the two layers need not be in the same stack.
  • Reassembly happens only at the destination. Fragments travel independently, and losing one wastes the whole datagram. This is why IPv6 removes fragmentation from routers entirely.