IP Fragmentation Calculations: Mastering the Mathematics
Fragment Size
Read aloud is unavailable in this browser.
The Precision of Fragmentation
When an IP datagram exceeds the Maximum Transmission Unit (MTU) of an outgoing link, the router must fragment it into smaller pieces. But this isn't arbitrary slicing—it's a carefully constrained mathematical operation governed by precise rules. A single byte miscalculation can render an entire datagram undeliverable.
Consider a 4,500-byte datagram encountering a link with a 1,500-byte MTU. How large should each fragment be? Why can't we simply split it into three 1,500-byte pieces? What happens if we fragment incorrectly? These questions have definitive answers rooted in the IPv4 header's Fragment Offset field and the fundamental requirement that fragments must be reassemblable at the destination.
Understanding fragment size calculations is essential for network administrators diagnosing MTU-related issues, security professionals analyzing packet captures, and anyone designing networks that span heterogeneous link technologies.
By the end of this page, you will understand: (1) The fundamental constraints governing fragment sizes, (2) Why fragment data must be a multiple of 8 bytes, (3) How to calculate the maximum fragment data size for any MTU, (4) The relationship between MTU, header size, and payload capacity, and (5) Real-world implications of fragment size decisions.
Fragmentation Fundamentals Review
Before diving into calculations, let's establish the foundational concepts that govern IP fragmentation.
Why Fragmentation Exists:
Different network technologies support different maximum frame sizes. Ethernet typically supports 1,500 bytes of payload (MTU), while some WAN links support only 576 bytes, and jumbo frames can reach 9,000 bytes. When a datagram travels from a high-MTU network to a low-MTU network, it must be fragmented to fit.
The Fragmentation Process:
- Router receives datagram larger than outgoing link's MTU
- Router checks the Don't Fragment (DF) flag
- If DF=0, router divides datagram into fragments
- Each fragment becomes an independent IP datagram
- Fragments travel independently (possibly different routes)
- Destination host reassembles original datagram
| Field | Size | Purpose in Fragmentation |
|---|---|---|
| Identification | 16 bits | Groups fragments belonging to same original datagram |
| Flags (DF) | 1 bit | Don't Fragment—if set, datagram cannot be fragmented |
| Flags (MF) | 1 bit | More Fragments—indicates additional fragments follow |
| Fragment Offset | 13 bits | Position of this fragment's data in original datagram |
| Total Length | 16 bits | Size of this fragment (header + data) |
| Header Length (IHL) | 4 bits | Size of IP header in 32-bit words |
IP fragmentation occurs at routers (or the source host), never at switches or Layer 2 devices. The destination host—never an intermediate router—performs reassembly. This asymmetry means fragments may take different paths and arrive out of order.
The 8-Byte Alignment Constraint
The most critical rule in fragment size calculation is the 8-byte alignment requirement. This constraint emerges directly from the IPv4 header's Fragment Offset field design.
Why 8 Bytes?
The Fragment Offset field is only 13 bits wide, but it must be able to address byte positions within datagrams up to 65,535 bytes long (the maximum Total Length). With 13 bits, we can represent values from 0 to 8,191. To cover 65,535 byte positions with only 8,192 possible offset values, IPv4 designers made the Fragment Offset represent 8-byte units, not individual bytes.
The Mathematics:
Maximum addressable offset = 8,191 × 8 = 65,528 bytes
Maximum datagram size = 65,528 + maximum fragment size ≈ 65,535 bytes ✓
This design choice has a critical implication: every fragment except the last must contain a data payload that is a multiple of 8 bytes.
All fragments EXCEPT the final fragment must have data payloads that are exact multiples of 8 bytes. Violating this constraint makes it impossible to express the next fragment's offset correctly, leading to reassembly failure.
Visual Example:
Consider fragmenting a 3,000-byte datagram payload:
CORRECT FRAGMENTATION (8-byte aligned):
┌─────────────────────────────────────────────────────────────────┐
│ Fragment 1: Data bytes 0-1471 (1472 bytes = 184 × 8) ✓ │
│ Fragment 2: Data bytes 1472-2943 (1472 bytes = 184 × 8) ✓ │
│ Fragment 3: Data bytes 2944-2999 (56 bytes - last, any size OK) │
└─────────────────────────────────────────────────────────────────┘
Offsets: 0, 184 (×8=1472), 368 (×8=2944)
INCORRECT FRAGMENTATION (not 8-byte aligned):
┌─────────────────────────────────────────────────────────────────┐
│ Fragment 1: Data bytes 0-1499 (1500 bytes = 187.5 × 8) ✗ │
│ Fragment 2: Data bytes 1500-???? (Cannot express offset!) │
└─────────────────────────────────────────────────────────────────┘
Offset for Fragment 2 = 1500/8 = 187.5 (not an integer!)
- •Fragment Offset is measured in 8-byte units — The header field value is multiplied by 8 to get the actual byte position
- •All non-final fragments must have 8-byte aligned data — Data length must be divisible by 8 with no remainder
- •Only the last fragment can have unaligned data — Since no subsequent offset needs to reference it
- •Maximum representable offset is 65,528 bytes — 8,191 × 8 = 65,528
Calculating Maximum Fragment Data Size
Given an MTU, how much data can each fragment carry? This fundamental calculation considers both the MTU constraint and the 8-byte alignment requirement.
The Basic Formula:
Maximum Fragment Data = floor((MTU - IP Header Size) / 8) × 8
Step-by-Step Derivation:
- Start with MTU — Total bytes the link can carry
- Subtract IP header size — Each fragment needs its own header (minimum 20 bytes)
- Divide by 8 and floor — Find largest multiple of 8 that fits
- Multiply by 8 — Convert back to bytes
Standard Ethernet Example (MTU = 1500 bytes):
1234567891011121314151617181920
# Standard Ethernet MTU calculationMTU = 1500IP_HEADER_SIZE = 20 # Minimum IP header without options # Available space for dataavailable = MTU - IP_HEADER_SIZE # 1500 - 20 = 1480 bytes # Apply 8-byte alignmentmax_fragment_data = (available // 8) * 8 # (1480 // 8) * 8 = 1480 bytes print(f"MTU: {MTU} bytes")print(f"IP Header: {IP_HEADER_SIZE} bytes")print(f"Available for data: {available} bytes")print(f"Max fragment data (8-byte aligned): {max_fragment_data} bytes") # Output:# MTU: 1500 bytes# IP Header: 20 bytes# Available for data: 1480 bytes# Max fragment data (8-byte aligned): 1480 bytesIn this case, 1480 is already a multiple of 8 (1480 ÷ 8 = 185), so no adjustment is needed. Let's examine a case where alignment truncation occurs.
Non-Standard MTU Example (MTU = 1006 bytes):
123456789101112131415161718192021
# Non-standard MTU requiring alignment adjustmentMTU = 1006IP_HEADER_SIZE = 20 # Available space for dataavailable = MTU - IP_HEADER_SIZE # 1006 - 20 = 986 bytes # 986 ÷ 8 = 123.25 (not a whole number!)# We must round DOWN to 123, then multiply by 8max_fragment_data = (available // 8) * 8 # (986 // 8) * 8 = 123 * 8 = 984 bytes print(f"MTU: {MTU} bytes")print(f"Available for data: {available} bytes")print(f"Max fragment data: {max_fragment_data} bytes")print(f"Wasted bytes per fragment: {available - max_fragment_data}") # Output:# MTU: 1006 bytes# Available for data: 986 bytes# Max fragment data: 984 bytes# Wasted bytes per fragment: 2For common MTUs: Ethernet (1500) → 1480 bytes data, PPPoE (1492) → 1472 bytes data, Minimum IP (576) → 552 bytes data. Notice that 1480, 1472, and 552 are all divisible by 8. Network engineers designed these MTUs with fragmentation math in mind.
IP Options and Fragment Size Implications
The standard 20-byte IP header assumption works for most traffic, but IP options complicate fragment size calculations. When options are present, the header grows (up to 60 bytes maximum), reducing available payload space.
Header Size Range:
- Minimum: 20 bytes (no options, IHL = 5)
- Maximum: 60 bytes (maximum options, IHL = 15)
- IHL field: Header length in 32-bit words (4 bytes each)
Impact on Fragmentation:
| Header Size | IHL Value | Max Fragment Data | Data Reduction |
|---|---|---|---|
| 20 bytes | 5 | 1480 bytes | Baseline |
| 24 bytes | 6 | 1472 bytes | -8 bytes |
| 28 bytes | 7 | 1472 bytes | -8 bytes |
| 32 bytes | 8 | 1464 bytes | -16 bytes |
| 40 bytes | 10 | 1456 bytes | -24 bytes |
| 60 bytes | 15 | 1440 bytes | -40 bytes |
Critical Consideration: Option Handling During Fragmentation
Not all IP options are copied to every fragment. RFC 791 defines two categories:
-
Copied options: Must appear in every fragment
- Examples: Loose Source Routing, Strict Source Routing, Record Route
- These affect the header size of ALL fragments
-
Non-copied options: Appear only in the first fragment
- Examples: Timestamp (depending on implementation)
- Subsequent fragments have smaller headers
Practical Calculation with Options:
1234567891011121314151617181920212223
def calculate_fragment_data_size(mtu, header_size): """Calculate maximum fragment data size with arbitrary header.""" available = mtu - header_size return (available // 8) * 8 # Scenario: Record Route option adds 39 bytes to header# Header = 20 (base) + 39 (option) + 1 (padding) = 60 bytes# (Headers must be multiple of 4 bytes) MTU = 1500HEADER_WITH_OPTIONS = 60 # Maximum possible max_data = calculate_fragment_data_size(MTU, HEADER_WITH_OPTIONS)# (1500 - 60) // 8 * 8 = 1440 // 8 * 8 = 180 * 8 = 1440 bytes print(f"With 60-byte header: {max_data} bytes per fragment")print(f"Compared to no options: {calculate_fragment_data_size(MTU, 20)} bytes")print(f"Capacity reduction: {calculate_fragment_data_size(MTU, 20) - max_data} bytes") # Output:# With 60-byte header: 1440 bytes per fragment# Compared to no options: 1480 bytes# Capacity reduction: 40 bytesIP options are rarely used in modern networks—most firewalls and routers drop packets with options as a security precaution. However, understanding their impact on fragmentation remains important for comprehending the IPv4 specification and analyzing legacy or specialized systems.
Fragment Size Selection Strategy
While the maximum fragment data size is determined by MTU constraints, there are strategic considerations for choosing fragment sizes.
Strategy 1: Maximum Fragment Size (Most Common)
Use the largest possible 8-byte-aligned fragment data size for all fragments except the last. This minimizes the total number of fragments, reducing:
- Header overhead (fewer duplicate headers)
- Processing overhead at destination (fewer fragments to track)
- Network overhead (fewer packets to route)
Strategy 2: Equal-Sized Fragments
Divide the datagram into approximately equal-sized fragments. This can balance:
- Processing load across time
- Buffer requirements at destination
- Risk of loss (no single large fragment causes excessive retransmission)
However, equal sizing is rarely used in practice because it increases header overhead.
- •Minimizes fragment count — Fewer headers, less overhead
- •Standard implementation — What all operating systems do
- •Best throughput — Maximum payload per packet
- •Example: 4500 bytes → 1480 + 1480 + 1480 + 60
- •More fragments — Higher overhead
- •Academic interest only — Rarely implemented
- •Balanced loss impact — Each fragment carries similar data
- •Example: 4500 bytes → 4 × 1128 (approx)
The Last Fragment:
The last fragment carries whatever data remains after filling previous fragments. Its size:
- Is NOT required to be 8-byte aligned
- Can be as small as 1 byte
- Is identified by MF (More Fragments) flag = 0
Calculation for Last Fragment:
Last fragment data = Original payload - (Sum of previous fragments' data)
Complete Example:
Original datagram: 4000 bytes data, 20-byte header (4020 bytes total)
MTU: 1500 bytes
Max fragment data: 1480 bytes
Fragment 1: 1480 bytes data, offset 0, MF=1
Fragment 2: 1480 bytes data, offset 185, MF=1
Fragment 3: 1040 bytes data, offset 370, MF=0 (last fragment)
Verification: 1480 + 1480 + 1040 = 4000 bytes ✓
Practical Fragment Size Calculations
Let's work through several realistic scenarios to build calculation fluency.
Scenario 1: Standard Ethernet
Datagram: 5000 bytes (20-byte header + 4980 bytes data) MTU: 1500 bytes
1234567891011121314151617181920212223242526272829303132333435363738
# Scenario 1: Standard Ethernet fragmentationoriginal_data = 4980mtu = 1500header_size = 20 # Maximum data per fragment (8-byte aligned)max_data = ((mtu - header_size) // 8) * 8print(f"Max data per fragment: {max_data} bytes") # 1480 bytes # Number of full fragmentsfull_fragments = original_data // max_dataprint(f"Full fragments: {full_fragments}") # 3 fragments # Remaining data for last fragmentremaining = original_data % max_dataprint(f"Last fragment data: {remaining} bytes") # 540 bytes # Total fragmentstotal = full_fragments + (1 if remaining > 0 else 0)print(f"Total fragments: {total}") # 4 fragments # Fragment breakdownfor i in range(total): if i < full_fragments: data = max_data mf = 1 else: data = remaining mf = 0 offset = i * max_data offset_field = offset // 8 print(f"Fragment {i+1}: {data} bytes data, offset={offset_field} ({offset} bytes), MF={mf}") # Output:# Fragment 1: 1480 bytes data, offset=0 (0 bytes), MF=1# Fragment 2: 1480 bytes data, offset=185 (1480 bytes), MF=1# Fragment 3: 1480 bytes data, offset=370 (2960 bytes), MF=1# Fragment 4: 540 bytes data, offset=555 (4440 bytes), MF=0Scenario 2: PPPoE Over Ethernet
PPPoE adds 8 bytes of overhead, reducing effective MTU from 1500 to 1492 bytes.
Datagram: 2900 bytes (20-byte header + 2880 bytes data) MTU: 1492 bytes
12345678910111213141516171819202122232425262728293031
# Scenario 2: PPPoE fragmentationoriginal_data = 2880mtu = 1492header_size = 20 # Maximum data per fragmentmax_data = ((mtu - header_size) // 8) * 8 # (1472 // 8) * 8 = 1472print(f"Max data per fragment: {max_data} bytes") # Fragment calculationfull_fragments = original_data // max_data # 2880 // 1472 = 1remaining = original_data % max_data # 2880 % 1472 = 1408total = full_fragments + (1 if remaining > 0 else 0) # 2 fragments print(f"Fragmentation Result:")print(f"Fragment 1: {max_data} bytes, offset=0, MF=1")print(f"Fragment 2: {remaining} bytes, offset={max_data // 8}, MF=0") # Verificationprint(f"Verification: {max_data} + {remaining} = {max_data + remaining} bytes ✓") # Output:# Max data per fragment: 1472 bytes# # Fragmentation Result:# Fragment 1: 1472 bytes, offset=0, MF=1# Fragment 2: 1408 bytes, offset=184, MF=0## Verification: 1472 + 1408 = 2880 bytes ✓Ethernet: 1500 (1480 data), PPPoE: 1492 (1472 data), GRE Tunnel: 1476 (1456 data), IPsec Tunnel: 1400-1438 (varies), IPv6-in-IPv4: 1480 (1460 data), Minimum IP MTU: 576 (552 data). Always verify actual path MTU using Path MTU Discovery.
Fragment Size and Network Performance
Fragment size choices directly impact network performance, reliability, and security. Understanding these implications helps diagnose issues and design robust networks.
- •Header Overhead — Each fragment carries a complete IP header. For a 10,000-byte datagram fragmented into 7 fragments over Ethernet (MTU 1500), the header overhead is 7 × 20 = 140 bytes instead of 20 bytes—a 7× increase.
- •All-or-Nothing Reassembly — If ANY fragment is lost, the entire datagram must be retransmitted. With 7 fragments, losing any one causes 100% waste of the other 6 fragments' bandwidth.
- •Reassembly Timeout — Destinations hold fragments awaiting missing pieces. Linux default is 30 seconds. Memory is consumed during this window, enabling fragmentation-based DoS attacks.
- •Processing Overhead — Each fragment requires separate routing decisions, checksum calculations, and interface processing. Small fragments disproportionately load router CPUs.
- •Security Implications — Fragmentation can evade intrusion detection systems (IDS) that can't reassemble streams. Attackers craft overlapping fragments to exploit reassembly vulnerabilities.
| MTU | Fragment Data | Fragments | Header Overhead | Overhead % |
|---|---|---|---|---|
| 1500 | 1480 | 7 | 140 bytes | 1.4% |
| 1000 | 976 | 11 | 220 bytes | 2.2% |
| 576 | 552 | 19 | 380 bytes | 3.8% |
| 296 | 272 | 37 | 740 bytes | 7.4% |
Path MTU Discovery (PMTUD):
Modern systems prefer avoiding fragmentation entirely using Path MTU Discovery:
- Source sends datagrams with DF (Don't Fragment) flag set
- If datagram exceeds a link's MTU, router drops it and sends ICMP "Fragmentation Needed"
- Source reduces datagram size and retries
- Process repeats until path is traversed
This discovers the minimum MTU along the entire path, allowing sources to pre-fragment (or size datagrams appropriately) before transmission.
Why PMTUD Matters for Fragment Calculations:
While PMTUD exists, it's not always reliable—some firewalls block ICMP, causing "black holes" where oversized packets silently disappear. Understanding fragmentation calculations remains essential because:
- Fallback when PMTUD fails
- Analyzing packet captures
- Diagnosing MTU-related connectivity issues
- Designing networks with known MTU constraints
KEEP LEARNING
There’s more to understand.
You’re reading the introduction. Create a free account to read the complete lesson, save notes and keep track of your progress.