Every physical medium has a maximum size of packets it can send. This is called MTU (Maximum Transmission Unit). For Ethernet this is usually 1500 bytes. If we send packets that are larger than 1500 bytes fragmentation is needed. Fragmentation is the method of dividing one large packet into several smaller packets.
1500 bytes is the maximum size including headers which means we have 1500 – 20 – 8 = 1472 bytes. 20 bytes are used by the IP header and in this example 8 bytes for ICMP. The Ethernet header doesn’t apply to this limit. If we were using TCP instead we would have 1500 – 20 – 20 = 1460 bytes available. The MTU for my Ethernet card is 1300, this is because I have Ciscos VPN client installed, it sets the MTU to 1300 to have room for IPSEC encapsulation. To find out what your MTU is use “netsh interface ipv4 show interfaces”
Let’s take a look at an IPv4 header.
There are three fields that we are specially interested in. Identification, flags and fragment offset. The identification field is used primarily for identyfing fragments. Fragments which belong to the same original IP datagram will have the same number in the identification field. The flags field has three bits.
- Bit 0: Reserved; must be zero (Sometimes refered to as the evil bit, see RFC 3514)
- Bit 1: Don’t fragment bit
- Bit 2: More fragments bit
If bit 1 is set, fragmentation is not allowed. This is useful for finding out the max size payload we can send. Bit 2 is set to indicate more fragments. All fragments that belong to an IP datagram will have the more fragments bit set except for the final fragment. This is so the end hosts can know when it has collected all the fragments of the IP datagram. The fragment offset field specifies the offset of a fragment. The first fragment will have an offset of 0. The next fragment will have an offset of 1280 if MTU = 1300 is used.
To verify that the max size is 1272 I will ping a host with a payload of 1272 bytes and the DF flag set, 1273 bytes will fail.
The ping is successful. This is what the packet looks like:
The frame is 1314 bytes long (1272 + 8 + 20 +14). Total length = 1300 ( 1272 + 8 + 20). The DF bit is set, bit nr two of the flags field. We can also see the ICMP header further down. Now let’s see when we try to use 1273 bytes:
The frame is not allowed since it is too large. Now lets generate some fragments, we will ping with a payload of 2544 bytes. This should generate exactly two frames.
Lets take a look in Wireshark:
Notice the identification field (17987). Also notice that the more fragments bit is set and that the fragment offset is 0. This is what the following frame looks like and it contains the actual ICMP header:
The identification field is the same (17987). The more fragments bit is not set since it’s the last fragment. The fragment offset is 1280. The first frame had 1280 bytes of data. This post should give you some insight to IP fragmentation. In a following post I will talk about TCP MTU discovery.
Hi Daniel,
this is awesome !!
i really like your blog..it’s really helpfull
Thanks
Hi Daniel,
I was reading this whole thread and got confused on one lone
If we were using TCP instead we would have 1500 – 20 – 20 = 1460 bytes available.
in this line, as far as i understand the 20 is the tcp header but what is the next 20 for ??
Please confirm
Hi!
20 bytes for IP header and 20 bytes for TCP header.
IPv4 header is 20 bytes without options. The second 20 bytes is for TCP.
Very informative and helpful blog…
Hi Daniel
can you please explain why second fragment has total length value 1292 Bytes. It suppose to be 1244B + 20B IP Header + 8 Bytes ICMP header