IP Header Binary

The full 20-byte (160-bit) standard IPv4 header broken down field by field at the bit level — Version, IHL, TOS, Total Length, Identification, Flags, Fragment Offset, TTL, Protocol, Header Checksum, Source Address, and Destination Address.

Header Layout Version & IHL Flags & Fragment Offset Parsing an IP Header Protocol Field Header Checksum FAQ

The IPv4 Header Bit Layout

Every IPv4 packet that traverses the internet starts with a 20-byte (160-bit) header, and when I work with raw sockets or packet capture (pcap) files, this is the first thing I have to parse. The header is organized as a sequence of bitfields packed into 32-bit words, following RFC 791. Understanding this layout at the bit level is essential for anyone doing network programming, embedded networking, or security analysis.

The twelve fields of the standard IPv4 header occupy exactly 160 bits, arranged across five 32-bit rows. Here is the complete bit-level mapping:

I once wrote a packet parser from scratch to understand how IP headers work at the bit level. The version is the first 4 bits, the IHL is the next 4, and the total length field is 16 bits starting at offset 2. Parsing this structure with bit shifts gave me a deep appreciation for how efficiently IP headers are packed.

Offset (bytes)FieldSize (bits)Bit Positions
0Version40-3
0IHL (Header Length)44-7
1DSCP + ECN88-15
2-3Total Length1616-31
4-5Identification1632-47
6Flags348-50
6-7Fragment Offset1351-63
8Time to Live (TTL)864-71
9Protocol872-79
10-11Header Checksum1680-95
12-15Source Address3296-127
16-19Destination Address32128-159

In practice, when I am debugging a captured packet or writing a parser, I visualize the header as five 32-bit words read left to right, most significant bit first. The first word packs Version, IHL, DSCP/ECN, and the first 8 bits of Total Length. Every field occupies a fixed position, which makes extraction straightforward with bitwise operations.

Version and IHL — The First Byte

I always start parsing an IPv4 header at the very first 8 bits. The high nibble (bits 0-3) is the IP version — for IPv4 this is always 0100 (decimal 4). The low nibble (bits 4-7) is the Internet Header Length (IHL), which tells me how many 32-bit words the header occupies. For a standard header with no options, IHL is 0101 (decimal 5, meaning 5 × 32 bits = 20 bytes).

First Byte of a Standard IPv4 Header
Bit position: 0 1 2 3 | 4 5 6 7
Field:  Version  |   IHL     
Binary:  0 1 0 0 | 0 1 0 1
Hex:        0x4     |     0x5
First byte = 0x45 (IPv4, 5-word header)
If the very first byte of a packet is 0x45, it is almost certainly a standard IPv4 header with no options.

When I write a raw packet parser, I extract these two fields with a single byte read and two bit shifts. The Version is (first_byte >> 4) & 0x0F and the IHL is first_byte & 0x0F. Verifying that Version equals 4 and IHL is at least 5 is the first sanity check in any robust parser.

IHL and Header Size

Since IHL counts 32-bit words, the total header length in bytes is IHL × 4. An IHL of 5 means 20 bytes (standard). Values 6-15 indicate options are present, extending the header up to 60 bytes maximum. If you need help with the binary arithmetic for these calculations, try our Bitwise Calculator.

Flags and Fragment Offset — Packed into 16 Bits

The second word of the header (bytes 4-7) packs three pieces of information into 16 bits: the Identification field (16 bits starting at offset 32), followed by a tricky 16-bit region that holds Flags (3 bits) and Fragment Offset (13 bits). The Flags field itself has three sub-bits: bit 0 is reserved (always 0), bit 1 is the Don't Fragment (DF) flag, and bit 2 is the More Fragments (MF) flag.

Extracting Flags from Byte 6 (Word 2, Byte 2)
Raw bytes 4-7 as 32-bit word:
0x1234 4560

Byte 6 = 0x45 = 0100 0101 in binary
Flags occupy bits 0-2 of this byte (the high 3 bits):
  Bit 0 (reserved): 0
  Bit 1 (DF):   1 ← Don't Fragment set
  Bit 2 (MF):   0 ← Last fragment
Flags = 010b = 0x40 (only DF is set)
When DF=1, the packet cannot be fragmented. Routers will drop it with ICMP "Fragmentation Needed" if it exceeds the path MTU.

To extract Flags in code, I read byte 6 and shift right by 5 to align the three flag bits to the bottom: flags = byte6 >> 5. The Fragment Offset occupies the remaining 13 bits (bits 3-15 of the same byte plus the entire next byte). Fragment Offset is measured in 8-byte units, so the actual offset into the original datagram is fragment_offset * 8 bytes.

IP Fragmentation in Practice

Fragmentation occurs when a packet exceeds the Maximum Transmission Unit (MTU) of a link in the path. Ethernet's standard MTU is 1500 bytes. The Identification field ties all fragments of the same original packet together, and the Fragment Offset tells the receiver where each fragment belongs in the reconstructed datagram. Our Hex to ASCII tool is useful when inspecting raw hex dumps of fragmented packets.

Parsing an IPv4 Header in Code

When I need to parse a raw IPv4 header from bytes — whether from a pcap file, a raw socket, or a captured network buffer — I use bitwise operations to extract each field. Here is a practical C implementation that demonstrates the exact bit positions:

// Parse fields from the first 20 bytes of an IPv4 header
// buf[0..19] contains the raw 20-byte header

uint8_t version  = (buf[0] >> 4) & 0x0F;       // bits 0-3
uint8_t ihl      = buf[0] & 0x0F;               // bits 4-7
uint8_t dscp_ecn = buf[1];                      // bits 8-15

uint16_t total_length = (buf[2] << 8) | buf[3]; // bits 16-31
uint16_t ident        = (buf[4] << 8) | buf[5]; // bits 32-47

uint8_t flags_raw = buf[6] >> 5;                // bits 48-50
uint8_t df_flag   = (flags_raw >> 1) & 1;       // Don't Fragment
uint8_t mf_flag   = flags_raw & 1;              // More Fragments

uint16_t frag_offset = ((buf[6] & 0x1F) << 8) | buf[7]; // bits 51-63

uint8_t  ttl       = buf[8];                     // bits 64-71
uint8_t  protocol  = buf[9];                     // bits 72-79
uint16_t checksum  = (buf[10] << 8) | buf[11];   // bits 80-95

uint32_t src_ip = (buf[12] << 24) | (buf[13] << 16) |
                  (buf[14] << 8)  | buf[15];      // bits 96-127

uint32_t dst_ip = (buf[16] << 24) | (buf[17] << 16) |
                  (buf[18] << 8)  | buf[19];      // bits 128-159

Notice the Fragment Offset extraction: I mask off the top 3 flag bits from byte 6 with 0x1F, shift left by 8, then OR in byte 7. This reconstructs the full 13-bit offset value, which in a non-fragmented packet will be 0. Every single field requires either masking, shifting, or both — which is why a solid understanding of bitwise operations is non-negotiable for network programmers.

The Protocol Field — Identifying the Payload

The Protocol field at byte 9 in the IPv4 header is a single 8-bit value that tells the receiving host which transport-layer protocol is encapsulated in the data payload. I rely on this field constantly when demultiplexing packets — it is the dispatch key that routes the payload to the correct handler.

Value (Decimal)Value (Hex)ProtocolCommon Use
10x01ICMPPing, traceroute, error reporting
60x06TCPWeb, email, SSH, most applications
170x11UDPDNS, streaming, DHCP, VoIP
20x02IGMPMulticast group management
470x2FGREVPN tunneling (generic routing)
890x59OSPFRouting protocol updates

In binary, Protocol = 6 for TCP means byte 9 is 0000 0110. When I see that value in a raw packet dump, I know the next layer starts with a TCP header, and I can proceed to parse the TCP source port, destination port, sequence number, and flags at their fixed offsets. Combined with the Total Length field, I can determine exactly how many bytes of TCP data follow.

Header Checksum — One's Complement Verification

The Header Checksum at bytes 10-11 protects the integrity of the IPv4 header itself (but not the payload). The algorithm is one's complement addition over all 16-bit words in the header. When I verify a checksum, I sum every 16-bit word — including the checksum field itself (which the sender set to zero during computation) — and then take the one's complement. If the result is 0x0000, the header is intact.

// Verify IPv4 Header Checksum (20-byte header with no options)
// Assume buf[0..19] contains the raw header

uint32_t sum = 0;
for (int i = 0; i < 20; i += 2) {
    sum += (buf[i] << 8) | buf[i+1];
}

// Fold 32-bit sum to 16 bits (one's complement addition)
while (sum >> 16) {
    sum = (sum & 0xFFFF) + (sum >> 16);
}

uint16_t computed_checksum = ~(uint16_t)sum;

if (computed_checksum == 0x0000) {
    // Header checksum is valid
}

This loop processes the 20-byte header as ten 16-bit words. The while-loop handles the end-around carry — a characteristic of one's complement arithmetic. If the computed checksum equals 0x0000 (meaning the sum of all words including the stored checksum is 0xFFFF after one's complement), the header passed validation. I use this exact algorithm in my packet inspection tools and it has never let me down.

Network router with ports for IP header binary analysis

Source and Destination Addresses — 32 Bits Each

The last 64 bits of the standard IPv4 header (bytes 12-19) hold the source and destination IP addresses, each occupying a full 32-bit word. These are stored in network byte order (big-endian), meaning the first byte is the most significant octet of the address. For example, the address 192.168.1.1 is stored as 0xC0A80101 in the header bytes.

To convert the four bytes into a readable dotted-quad string, I extract each octet with bitwise operations: octet 1 is (ip >> 24) & 0xFF, octet 2 is (ip >> 16) & 0xFF, octet 3 is (ip >> 8) & 0xFF, and octet 4 is ip & 0xFF. This is the same color-channel extraction pattern used in graphics programming — just applied to network addresses instead of pixel data.

Converting Raw 32-bit Address to Dotted-Quad
32-bit raw: 0x0A00000F
Bytes: [10, 0, 0, 15]
Dotted-quad: 10.0.0.15

Bit extraction:
octet1 = (0x0A00000F >> 24) & 0xFF = 0x0A = 10
octet2 = (0x0A00000F >> 16) & 0xFF = 0x00 = 0
octet3 = (0x0A00000F >> 8) & 0xFF = 0x00 = 0
octet4 = (0x0A00000F >> 0) & 0xFF = 0x0F = 15
The raw hex 0x0A00000F decodes to the familiar 10.0.0.15.

Network Byte Order and Endianness

IP headers always use big-endian (network byte order). If you are parsing packets on a little-endian system like x86, you must convert with functions like ntohl() and ntohs() to get correct values. Our 64-bit programmer calculator supports byte-order conversion between big-endian and little-endian representations.

Work with Bit-Level Data

Use our interactive tools to explore binary representations, convert between number formats, and verify your bit-level calculations for IP header fields and other packed data structures.

Frequently Asked Questions About IPv4 Header Binary

How many bits is an IPv4 header?

The standard IPv4 header is 160 bits (20 bytes) without options. It consists of 12 fields: Version (4 bits), IHL (4 bits), DSCP/ECN (8 bits), Total Length (16 bits), Identification (16 bits), Flags (3 bits), Fragment Offset (13 bits), TTL (8 bits), Protocol (8 bits), Header Checksum (16 bits), Source Address (32 bits), and Destination Address (32 bits). Options can extend the header up to 60 bytes (480 bits) total.

What is the structure of the IPv4 header in binary?

The IPv4 header starts with 4 bits for the version field (always 0100 for IPv4), followed by 4 bits for IHL which encodes the header length in 32-bit words. Then comes the DSCP/ECN byte for QoS marking, followed by Total Length (16 bits), Identification (16 bits), Flags (3 bits with bit 0 reserved, bit 1 = Don't Fragment, bit 2 = More Fragments), Fragment Offset (13 bits), TTL (8 bits), Protocol (8 bits), Header Checksum (16 bits), Source Address (32 bits), and Destination Address (32 bits).

How do I interpret the Flags field in an IPv4 header?

The Flags field is 3 bits in the IPv4 header. Bit 0 (the most significant bit) is reserved and must be zero. Bit 1 is the Don't Fragment (DF) flag — when set to 1, the packet should not be fragmented. Bit 2 is the More Fragments (MF) flag — when set to 1, more fragments follow; when set to 0, this is the last fragment. These three bits appear at positions 8, 9, and 10 within the 16-bit word that also contains the Fragment Offset.

What does the Protocol field mean in an IPv4 header?

The Protocol field is an 8-bit value that identifies the next-level protocol encapsulated in the IPv4 packet's data payload. Common values include: 1 for ICMP, 6 for TCP, 17 for UDP, 2 for IGMP, 47 for GRE, 50 for ESP (IPsec), 51 for AH (IPsec), and 89 for OSPF. When parsing a raw IPv4 packet in binary, the Protocol byte at offset 9 tells you how to interpret the payload bytes that follow the header.

How is the Header Checksum calculated in IPv4?

The IPv4 Header Checksum is a 16-bit checksum computed over the entire IPv4 header only (not the payload). The algorithm treats the header as a sequence of 16-bit words, sums them using one's complement addition, then takes the one's complement of the result. The checksum field itself is set to zero during computation. This covers 20 bytes (10 words) for a standard header without options. Routers recompute the checksum on every hop because the TTL field changes.

Related Tools

Bitwise Calculator →

AND, OR, XOR, NOT, shifts

Bitwise Guide →

Complete operations reference

Hex to ASCII →

Decode hex strings

SHA256 Generator →

Compute hashes