---
title: IPv4 Protocol
url: https://doc.liz6.com/en/networking/02-l3-network-layer/01-ipv4-protocol
locale: en
area: networking
tags:
- networking
- l3-network-layer
date: 2026-06-30
modified: 2026-07-16
description: The foundational protocol of the Internet—32-bit address space, fragmentation and reassembly, TTL loop prevention, DSCP/ECN quality of service. Even as IPv6 advances, IPv4 still carries the vast majority of Internet traffic, and every field in it represents an engineering compromise.
---

# IPv4 Protocol

> The foundational protocol of the Internet—32-bit address space, fragmentation and reassembly, TTL loop prevention, DSCP/ECN quality of service. Even as IPv6 advances, IPv4 still carries the vast majority of Internet traffic, and every field in it represents an engineering compromise.

## Overview

IPv4 is the core network layer protocol of the Internet, defined in RFC 791 in 1981. It provides "best-effort" connectionless datagram delivery—no guarantee of delivery, no guarantee of order, and no guarantee against duplication. These guarantees are provided by upper-layer protocols such as TCP. The 32-bit address space of IPv4 (4.3 billion addresses) was exhausted in 2011, but has been extended through NAT and CIDR. This article focuses on header semantics, fragmentation/reassembly, PMTUD, and QoS markings (DSCP/ECN)—which form the foundation for understanding Internet traffic engineering and fault diagnosis.

## IPv4 Header Field-by-Field

```
 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|Version|  IHL  |   DSCP    |ECN|         Total Length          |
|        (4)    |   (6 bits)|(2)|          (16 bits)            |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|        Identification         |Flags|    Fragment Offset       |
|                               | R|DF|MF|    (13 bits, ×8)     |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|  Time to Live (8) | Protocol  |        Header Checksum        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                    Source Address (32 bits)                   |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                 Destination Address (32 bits)                 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                    Options (if IHL > 5)                       |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Version: 4 (fixed)
IHL:     Internet Header Length — measured in 4-byte words (minimum 5 = 20B, maximum 15 = 60B)
         IHL > 5 → IP options are present (rare)
DSCP:    DiffServ Code Point — QoS marking (6 bits, replaces the old TOS field)
ECN:     Explicit Congestion Notification (2 bits)
Total Length: Total length of the IP packet (including header + data, max 65535B)
Identification: Unique ID for each IP datagram (used for fragment reassembly, copied to all fragments)
Flags:
  bit 0: Reserved (always 0)
  bit 1: DF (Don't Fragment) — 1 = router must not fragment, returns ICMP "Frag Needed"
  bit 2: MF (More Fragments) — 1 = more fragments follow, 0 = last fragment
Fragment Offset: Position of this fragment within the original datagram (in 8-byte units)
TTL:     Time to Live — decremented by 1 at each hop; discarded and ICMP Time Exceeded sent when it reaches 0
Protocol: 1=ICMP, 2=IGMP, 6=TCP, 17=UDP, 47=GRE, 50=ESP, 89=OSPF
Header Checksum: Covers only the IP header (TCP/UDP have their own checksums covering the payload)
```

## Fragmentation

The need for fragmentation arises from the fact that "MTUs may differ along the path." However, modern networks strive to avoid IP-layer fragmentation—PMTUD allows endpoints to send packets that do not exceed the minimum MTU.

```
Fragmentation Rules:
  1. Each fragment contains a complete IP header (copied from the original datagram)
  2. First fragment: offset=0, MF=1 (unless it is the only fragment)
  3. Intermediate fragments: offset>0, MF=1
  4. Last fragment:    offset>0, MF=0
  5. Each fragment has the same Identification value
  6. Fragment offset is in units of 8 bytes — each fragment (except the last) must have a length that is a multiple of 8

Reassembly:
  The destination receives all fragments → 15s timeout → timeout = discard all
  Size of reassembled packet: max offset + Total Length of the last fragment
  Problem: If one fragment is lost → the entire datagram becomes unusable → retransmission is handled by L4 (TCP)
```

## PMTUD (Path MTU Discovery, RFC 1191)

```
Principle: Sender sets DF=1 → intermediate router with insufficient MTU → drops packet + sends ICMP "Frag Needed" (type 3, code 4)
     → ICMP contains the next-hop MTU → sender updates routing cache → retransmits smaller packet

PMTUD Black Hole:
  ICMP is filtered → DF=1 packets are dropped along the path → sender is unaware → TCP retransmits → still dropped → hang

Detection:
  ping -M do -s 1472 1.1.1.1
  If: ping succeeds (small packet) but fails with -s 1472 → MTU black hole
  With some probability: MSS clamping may be insufficient → some directions work, others do not

Mitigation:
  TCP MSS clamping: iptables -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
  → Even if ICMP is filtered, the MSS during SYN is reduced → subsequent data packets are smaller → no fragmentation needed
```

## DSCP and ECN

### DSCP (6 bits, RFC 2474)

```
Replaces the old IP Precedence (3 bits), backward compatible:

Default (CS0, 0x00):        best effort
CS1-CS7:                    backward compatible with IP Precedence 1-7
AF (Assured Forwarding):    4 classes × 3 drop precedences
  AF11 (0x0A) AF12 AF13, AF21...AF43
  → Under congestion, packets with lower drop probability have higher priority
EF (Expedited Forwarding):  0x2E → highest priority, low-latency queue (VoIP)
```

Linux: iptables -j DSCP --set-dscp 0x2e or tc filter with skbedit

### ECN (2 bits, RFC 3168)

```
ECN uses the low 2 bits of the DSCP field in the IP header + CWR/ECE flags in the TCP header:

00: Not ECN-capable
10: ECT(0) — ECN-capable transport, code point 0
01: ECT(1) — ECN-capable transport, code point 1
11: CE — Congestion Experienced (set by router!)

Process:
  Sender: Sets ECT(0) or ECT(1) on SYN → indicates "I support ECN"
  Router: Detects congestion (queue exceeds threshold) → changes ECT to CE (instead of dropping the packet!)
  Receiver: Sees CE → sets TCP header ECE flag in ACK
  Sender: Receives ECE → slows down (halves cwnd) + sets CWR flag → receiver stops setting ECE

Advantages of ECN over packet dropping:
  - No packet loss → no retransmission needed → lower latency
  - Suitable for data centers (DCTCP = data center TCP, uses ECN for congestion control)
```

## References

- **RFC**: 791, 1191, 2474, 3168
- **Source Code**: `net/ipv4/ip_input.c` (ip_rcv), `net/ipv4/ip_fragment.c` (fragmentation/reassembly)
- **Tools**: `ping -M do`, `tracepath`, `iptables DSCP`, `sysctl net.ipv4.tcp_ecn`

*Keywords: IPv4 header, fragmentation, DF bit, PMTUD, MTU black hole, DSCP, ECN, congestion notification*
