IPv4
The Internet Protocol, version 4, carries a packet from one machine to another across networks. Each router on the way reads the destination address, chooses the next hop, and wraps the packet in a new link-layer frame. The IP header itself travels end to end, apart from a few fields that routers update.
The header
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 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Identification |Flags| Fragment Offset |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Time to Live | Protocol | Header Checksum |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Source Address |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Destination Address |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Options (rare) | Padding |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Offset | Size | Field | Meaning |
|---|---|---|---|
| 0 | 4 bits | Version | 4 |
| 0 | 4 bits | IHL | Header length in 32-bit words: 5 (20 bytes) without options, up to 15 (60 bytes). |
| 1 | 6 + 2 bits | DSCP, ECN | Priority class, and Explicit Congestion Notification. Usually 0. |
| 2 | 2 | Total Length | Header + payload, in bytes. Lets the receiver ignore Ethernet's padding. |
| 4 | 2 | Identification | Groups the fragments of one packet. |
| 6 | 3 bits | Flags | bit 1: DF, "don't fragment"; bit 2: MF, "more fragments". |
| 6 | 13 bits | Fragment Offset | Where this fragment goes, in 8-byte units. |
| 8 | 1 | Time to Live | Decremented by each router; at 0 the packet is dropped, and an ICMP "time exceeded" goes back (that's how traceroute works). |
| 9 | 1 | Protocol | What the payload is: 1 ICMP, 2 IGMP, 6 TCP, 17 UDP, 47 GRE, 50 ESP... |
| 10 | 2 | Header Checksum | Covers the header only. Routers recompute it, since the TTL changes. |
| 12 | 4 | Source | 192.0.2.1 is c0 00 02 01. |
| 16 | 4 | Destination |
Example: the DNS query's IPv4 header
The 20 bytes after the Ethernet header of the DNS query (frame offset 0x0e):
45 00 00 50 09 52 00 00 40 11 ed 47 c0 00 02 01 c0 00 02 02
| Bytes | Field | Value |
|---|---|---|
45 |
Version, IHL | 4, 5 words = 20 bytes: no options |
00 |
DSCP, ECN | 0 |
00 50 |
Total Length | 80 bytes: 20 (IP) + 8 (UDP) + 52 (DNS) |
09 52 |
Identification | 0x0952 |
00 00 |
Flags, Offset | no DF, not a fragment |
40 |
TTL | 64, Linux's default |
11 |
Protocol | 17, UDP |
ed 47 |
Checksum | valid: the 16-bit ones' complement sum of the header is 0xffff |
c0 00 02 01 |
Source | 192.0.2.1 |
c0 00 02 02 |
Destination | 192.0.2.2 |
The server's answer starts with 45 00 00 49 5e e4 40 00: its flags byte is 40, so DF is set. Linux sets DF so that path MTU discovery works; dig turns that off for its own UDP socket, so its query has no DF.
The checksum
Add the header as 16-bit words with the checksum field included, folding each carry back in:
4500 + 0050 + 0952 + 0000 + 4011 + ed47 + c000 + 0201 + c000 + 0202 = 0x2fffd
0x2fffd → 0xfffd + 0x2 = 0xffff ✓
Fragmentation
A packet bigger than a link's MTU (1500 bytes on Ethernet) is split into fragments with the same Identification. All fragments but the last have MF set, and each carries its offset. Only the first fragment carries the TCP or UDP header. Modern stacks set DF and avoid fragmentation.
Addresses worth knowing
| Range | Use |
|---|---|
10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16 |
private networks (RFC 1918) |
127.0.0.0/8 |
loopback: this machine |
169.254.0.0/16 |
link-local, when DHCP fails |
224.0.0.0/4 |
multicast |
255.255.255.255 |
broadcast on the local network |
192.0.2.0/24, 198.51.100.0/24, 203.0.113.0/24 |
documentation (RFC 5737) |
In NetOtter
- Parsing:
parse_ipv4()(Parsers)- checks the version and IHL;
- skips options;
- cuts the payload at Total Length, so Ethernet padding isn't taken as data;
- passes the protocol on to the transport layer only for the first fragment.
l:192.0.2.1:37647 -> 192.0.2.2:53 ttl 64 UDP 60 B. The size is Total Length minus the header.i: shows Source, Destination, Protocol and TTL.- Filters:
ipv4src,ipv4dest,ipv4,proto,etype ipv4.
Read more
- RFC 791: Internet Protocol
- RFC 1071: computing the checksum
- RFC 1918: private addresses
- IANA protocol numbers
User guide
- Overview
- Installation
- Getting started
- Command-line options
- Interactive commands
- Display filters
- Analysis view
- Reverse DNS and privacy
- Anomaly detection
- Save files
- Memory and limits
- Troubleshooting
Developer documentation
- Overview
- Building
- Architecture
- OS backends
- Packet parsing
- Packet storage
- Save format
- Hostname learning
- Reverse DNS internals
- Filters and analysis internals
- Anomaly lab
- Coding conventions
- Function explorer
Learning