IPv4 Packet Header

The IPv4 Packet Header is found at the start of every IPv4 Packet. It is normally 20 bytes in length, but can have additional options after the Destination Address (this is very uncommon). Almost every bit (except the first of the three flag bits, after the Identification field) is accounted for.

ipv4 packet header

The Version field (4 bits) in all IPv4 packets contains the value 4. By comparison, the Version field in all IPv6 packets contains the value 6. In 4 bits you can represent decimal numbers from 0 to 15, and the values 0,1,2,3,4,5,6,7,8 and 9 have already been used. The next version of IP will therefore be IPv10.

The IHL (Internet Header Length) field (4 bits) indicates how long the IPv4 packet header is, in 32-bit, or 4-byte “words”. The minimum value allowed is 5 which would be 20 bytes (no options). The maximum value possible is 15, for a packet header length of 60 bytes (allowing a maximum of 40 bytes for “options”). If you skip “IHL” 32-bit words (or 4 times that many bytes) from the start of the packet, that is where the rest of the packet starts (usually an ICMPv4 or Transport header). IHL will only ever be greater than 5 if there are header options (which is extremely rare).

The Type of Service field (8 bits) is defined in RFC 2474, “Definition of the Differentiated Services Field (DS Field) in the IPv4 and IPv6 headers”, and RFC 2475, “An Architecture for Differentiated Services”, both December 1998. This is used to implement a fairly simple QoS (Quality of Service). QoS involves management of bandwidth by protocol, by sender, or by recipient. For example, you might want to give your VoIP connections a higher priority than your video downloads, or the traffic from your boss higher priority than your co-worker’s traffic. Without QoS, bandwidth is on a first-come-first served basis. 8 bits is not really enough to do a good job on QoS, and DiffServ is not widely implemented in current IPv4 networks. QoS is greatly improved in IPv6. The TOS bits only ask for certain kinds of priority – the actual prioritization is done in the routers, in terms of how packets are queued for retransmission. A router can also return packets with certain TOS bits as undeliverable if it is unable to provide the requested service level through ongoing paths.

The Total Length field (16 bits) contains the total length of the packet, including the packet header, in bytes. The minimum length is 20 (20 bytes of header plus 0 bytes of data), and the maximum is 65,535 bytes (since only 16 bits are available to specify this). All network links must be able to handle packets of at least 576 bytes, but a more typical packet size is 1508 bytes. With IPv4, it is possible for some devices (like routers) to fragment packets (break them apart into multiple smaller packets) if required to get them through a part of the network that can’t handle packets that big. Packets that are fragmented must be reassembled at at some point (usually by the destination node). Fragmentation and reassembly is one of the messy parts of IPv4, and it got cleaned up a lot in IPv6.

The Identification (Fragment ID) field (16 bits) identifies which original packet this fragment was from, to help in reassembling the fragmented packet later. Each original packet has a unique Identification value. Every fragment of a given packet will have the same Identification value. In IPv4, any node (sender or router in the path) can fragment a packet. Usually only the destination node reassembles fragments into complete packets. It is possible for a border firewall to reassemble packets in order to enforce filtering rules. In IPv6 packet fragmentation can only be done by the source node, and a fragmentation extension header contains the information needed for the destination node to reassemble complete packets.

The next three bits are flags related to fragmentation.

The first bit is reserved and must be zero. RFC 3514, “The Security Flag in the IPv4 Header”, 1 April 2003 defines this as the “evil” bit. Hackers are required to set this bit on any packets that are used to attack a target network, to make it easier for firewalls to detect such attacks. Please note the date this RFC was released (this is an “April Fool’s” joke).

The second bit is the DF (Don’t Fragment) flag.  If DF is set, the packet cannot be fragmented. If a packet with DF set reaches a gateway where the ongoing path can’t handle one that big, that packet is dropped (and non-delivery notification is returned to the sender).

The third bit is the MF (More Fragments) flag. If MF is set, there are more fragments to come. Unfragmented packets have the MF flag set to zero.

The Fragment Offset field (13 bits) is used in reassembly of fragmented packets. It is measured in 8 byte blocks. The first fragment of a set has an offset of 0. Re-assembly involves putting the fragments together in a buffer, with each new fragment located in the reassembly buffer starting at Fragment Offset * 8 bytes from the beginning of the buffer. If you had a 2500 byte packet, and were fragmenting it into chunks of 1020 bytes, you would have three fragments as follows (here “data size” includes the length of the ICMPv4 or transport layer header):

Fragment ID    MF Flag        Total Length    Data Size     Offset
1             1                1020          1000           0
2             1                1020          1000         125
3             0                 520           500         250

The Time To Live (TTL) field (8 bits) is to prevent packets from circling around indefinitely on a network with routing loops. It was originally intended to be lifetime in seconds, but it has come to be implemented as “hop count”.  This means that every time a packet crosses a switch or router, the TTL is decremented by one. If the TTL reaches zero, the packet is dropped. When a packet is dropped, an ICMPv4 non-delivery message (“time exceeded”) is returned to the packet sender. This mechanism is how the traceroute command works.

The Protocol field (8 bits) defines the next header, which is found immediately after the IPv4 Packet Header (actually the first part of the packet payload). Protocol numbers are not to be confused with ports. Some common protocol numbers for IPv4 are:

  1      ICMPv4     Internet Control Message Protocol for IPv4 (RFC 792)
  2      IGMP       Internet Group Management Protocol (RFCs 11122236 and 3376)
  4      IPv4       IPv4 in IPv4 encapsulation, “IP in IP” tunneling (RFC 2003)
  6      TCP        Transmission Control Protocol (RFC 793)
  8      EGP        Exterior Gatgeway Protocol (RFC 888)
17      UDP        User Datagram Protocol (RFC 768)
41      IPv6       IPv6 tunneled over IPv4, “6in4” tunneling (RFC 2473)
 50      IPSec      ESP Header (RFC 2406)
 51      IPSec      AH Header (RFC 2402)
89      OSPF       Open Shortest Path First routing (RFC 1583)
132      SCTP       Streams Control Transmission Protocol (RFC 4960)


The Header Checksum field (16 bits). The 16-bit ones’ complement of the ones’ complement sum of all 16 bit words in the header. When computing, the checksum field itself is taken as zero. To validate the checksum, add all 16 bit words in the header together including the transmitted checksum. The result should be ones’ complement “negative 0” (0xffff). If you get any other value, then at least one bit in the packet was corrupted. There are certain multiple bit errors that can cancel out, and hence bad packets can go undetected. Since the hop count (TTL) is decremented by one on each hop, the IP Header checksum must be recalculated at each hop. The IP Header Checksum was eliminated in IPv6. A simple 8-bit checksum would catch about 99.6% of all random bit errors. The 16-bit checksum used in IP will catch about 99.9985% of all random bit errors. On the other hand, anyone can easily calculate a new checksum from modified data, so it will not catch any malicious changes.

The Source Address field (32 bits) contains the IPv4 address of the sender (may be modified by NAT). This can be 0 (the unspecified address) in certain cases, but it can never be a multicast address.

The Destination Address field (32 bits) contains the IPv4 address of the recipient (may be modified by NAT in a reply packet). This can be a unicast or multicast IPv4 address, but it can never be 0 (the unspecified address).

Options (0 to 40 bytes) Very rarely used. For the details, see RFC 791 (IPv4).

The IPv4 Header is typically followed by either an ICMPv4 header or Transport Layer (UDP, TCP or SCTP) header, which in turn is usually followed by data. The number of bytes in the data field is the value of ‘Total Length’ minus the length of any other headers (ICMP or Transport Layer header), minus the value of ‘IHL’ (usually 20). So, a UDP Datagram might have a 20 byte IPv4 Packet Header, an 8 byte UDP Transport Layer header, and 500 bytes of data. In this case, ‘Total Length’ would be 528.

Officially there are no “Extension Headers” in IPv4 similar to the ones in IPv6, but if you look closely at the IPsec AH and ESP mechanisms in IPv4, they are similar in design and placement to the IPv6 Extension Headers.