skip to content

An IPv4 router must forward a 4,000-byte datagram with a 20-byte header onto a 1,500-byte MTU link; which fragments does it send?

level: middleimportance: should knowfreq 32%

answer

  1. header repeats in every fragment
  2. data cut on 8-byte boundaries
  3. offset counts 8-byte units
  4. MF set on all but last

basics

~20 s

Three fragments: 1,480 data bytes at offset 0 with MF set, 1,480 at offset 185 with MF set, and the last 1,020 at offset 370 with MF clear, all sharing one Identification. Only the destination reassembles; losing any fragment loses the datagram.

solid answer

~50 s

The datagram carries 4,000 - 20 = 3,980 data bytes. Each fragment needs its own 20-byte header, so at most 1,480 data bytes fit in 1,500, and 1,480 is a multiple of 8, which RFC 791 requires of every fragment but the last. `Fragment Offset` counts 8-byte units, so the offsets are 0, 1,480 / 8 = 185 and 2,960 / 8 = 370. The router sends `Total Length` 1,500 at offset 0 with `MF` set, 1,500 at offset 185 with `MF` set, and 1,040 (1,020 data bytes) at offset 370 with `MF` clear. All three keep the original `Identification`, source, destination and `Protocol`; that tuple is how the destination groups them. Only the destination reassembles, and IP never retransmits a piece: if one fragment is lost, the destination discards the rest when its reassembly timer expires, and the sender's transport must resend the entire datagram.

code

pseudocode · 13 lines
pseudocode
header_len = IHL * 4                              # 20
data_len   = total_length - header_len              # 3980
max_data   = floor((mtu - header_len) / 8) * 8      # 1480
sent = 0
while sent < data_len:
    size = min(max_data, data_len - sent)
    emit_fragment(
        Identification  = original.Identification,
        Total_Length    = header_len + size,       # 1500, 1500, 1040
        Fragment_Offset = sent / 8,                # 0, 185, 370
        MF              = (sent + size < data_len),  # 1, 1, 0
        data            = original.data[sent : sent + size])
    sent = sent + size

go deeper

for a junior

Recall that every fragment gets its own IP header and that the destination, never a router, puts the pieces back together.

for a middle

Work the arithmetic aloud: subtract the header, round the data per fragment down to a multiple of 8, divide by 8 for the offset, and set MF on every fragment except the last.

for a senior

Connect the numbers to production: three packets now carry one datagram, so loss exposure roughly triples, a single loss costs a full resend, and the receiver holds state until its timer expires.

for a principal

Use the arithmetic to argue design: a protocol that hands IP oversized datagrams pays header overhead, loss multiplication and reassembly state, which is why modern transports size messages to the path.

## Start from the data, not the total The `Total Length` field of an IPv4 header counts the **whole** datagram, header included. Fragmentation splits only the **data**: every fragment gets a fresh copy of the header. So the first step is always to subtract the header. - Original datagram: `Total Length` 4,000, header 20 bytes (`IHL` 5, no options). - Data to carry: 4,000 - 20 = **3,980 bytes**. - Next link's MTU: 1,500 bytes, which must hold a 20-byte header plus the fragment's data. ## Sizing each fragment RFC 791 adds one constraint beyond "fit the MTU": the `Fragment Offset` field is 13 bits and counts **8-byte units**, so every fragment except the last must carry a data length that is a multiple of 8. The sizing procedure: 1. Room for data per fragment = MTU - header = 1,500 - 20 = 1,480 bytes. 2. Round down to a multiple of 8: 1,480 / 8 = 185 exactly, so 1,480 stays. 3. Cut the 3,980 data bytes into 1,480 + 1,480 + 1,020. 4. Offset of each piece = its first data byte / 8. 5. Set `MF` (More Fragments) on every piece except the one that ends the datagram. ## The three fragments | Fragment | Data bytes carried | Total Length | Fragment Offset field | MF | |---|---|---|---|---| | 1 | 0 – 1,479 | 1,500 | 0 | 1 | | 2 | 1,480 – 2,959 | 1,500 | 185 | 1 | | 3 | 2,960 – 3,979 | 1,040 | 370 | 0 | Checks worth doing aloud: 1,480 + 1,480 + 1,020 = 3,980 data bytes; 370 x 8 = 2,960, where the last piece starts; the three fragments add up to 4,040 bytes of IP datagram, 40 more than the original, because the header was copied twice. All three carry the original **`Identification`**, source address, destination address and `Protocol`, with `DF` clear, and each has its own recomputed **`Header Checksum`**. ## What the destination does RFC 791 tells the receiver to group fragments by the four values **source, destination, protocol and Identification**. The offsets say where each piece goes; the `MF`-clear fragment says where the datagram ends. Reassembly is complete when every byte from 0 to the end is present. - Fragments can arrive **in any order**, because each was routed independently. - The receiver keeps a **reassembly timer**. RFC 791's example procedure suggested 15 seconds; RFC 1122 says there MUST be a timeout and recommends a fixed value between **60 and 120 seconds**. - When the timer expires, the partial datagram is discarded, and, if fragment zero had arrived, an ICMP Time Exceeded message goes back to the source. ## Why one lost fragment loses everything IP has **no retransmission**: neither the router that fragmented the datagram nor the destination can ask for a missing piece. The consequences: - One lost fragment means the destination discards the two that arrived, after holding them in memory until the timer ran out. - The sender's transport (TCP, or a UDP application that retries) must resend the **whole** datagram, which will be fragmented again. - With three fragments the datagram is exposed to roughly three times the per-packet loss rate, which is why heavy fragmentation hurts throughput far more than the 40 bytes of extra header suggest. ## Fragmenting a fragment A fragment is a normal IPv4 datagram, so a later router with a smaller MTU may split it again. The offsets of the new pieces stay **relative to the original datagram's data**, and every piece of a fragment that had `MF` set also carries `MF` set; only the piece that ends the original datagram has it clear. The destination never needs to know how many routers did the cutting. The pseudocode below captures the procedure for an unfragmented original without options; a real implementation also adds the original's own offset and copies only the options marked for copying.

  • What changes if the next link's MTU is 1,006 bytes instead of 1,500?
    Room for data is 1,006 - 20 = 986 bytes, which is not a multiple of 8, so each fragment carries 984 bytes (123 units). 3,980 = 4 x 984 + 44, so there are five fragments at offsets 0, 123, 246, 369 and 492. The first four have `Total Length` 1,004 and `MF` set; the last carries 44 bytes, `Total Length` 64, `MF` clear.
  • If a later router splits the second fragment again, how are the new pieces labelled?
    Their offsets stay relative to the original datagram's data, so the first piece keeps offset 185 and the next start higher. Because the fragment being split had `MF` set, every piece of it carries `MF` set too. `Identification`, source, destination and `Protocol` are unchanged, so the destination reassembles all pieces into one datagram as if one router had done the cutting.
  • Why does an IPv4 receiver need the Identification field when every fragment already has an offset?
    The offset says where a piece belongs; it does not say which datagram it belongs to. A host may have several fragmented datagrams from the same source in flight at once, all with pieces at offset 0 and 185. The receiver groups fragments by source, destination, `Protocol` and `Identification`, so the sender must keep that value unique for as long as fragments might be alive.

saying these in an interview costs you the question

  • The Fragment Offset field holds a byte count, so fragment two says 1,480.
  • Each fragment carries 1,500 data bytes because the header is shared.
  • The More Fragments flag is set on every fragment, including the last.
  • The router that fragmented the datagram resends only the missing piece.
  • Any fragment size works as long as it fits the MTU.