The Checksum algorithm of the grouping header is the inverse code after 16-bit accumulation and UDP data headers also use the same validation algorithm, but the data involved in the calculation is different from the IP grouping header.
The structure of the IPv4 group header is as follows:
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 4 5 6 7 8 9 01
+- +-+
| Version | IHL | type ofservice | totallength |
+- +-+
| Identification | flags | Fragment Offset |
+- +-+
| Time to live | Protocol | headerchecksum |
+- +-+
| Sourceaddress |
+- +-+
| Destinationaddress |
+- +-+
| Options | padding |
+- +-+
The "header checksum" field is the header checksum part. When an IPv4 packet header verification is to be calculated, the sender first sets it to 0, and then accumulates it to the IPv4 packet header one by one based on 16 bits, accumulating and saving it in a 32-bit value. If the total number of bytes is odd, the last byte is added separately. After the accumulation is complete, add the high 16 bits in the result to the low 16 bits. repeat this process until the high 16 bits are all 0. The following describes the entire calculation process using an IPv4 group (a package with data connected to the DLC) that is actually intercepted:
0x0000: 00 60 47 41 11 c900 09 6B 7A 5B 3B 0800 45 00
0x0010: 00 1C 74 68 0000 80 11 59 8f C0 A8 64 01 AB 46
0x0020: 9C E9 0f 3a04 05 00 08 7f C5 00 0000 00 00 00
0x0030: 00 00 00 00 00 00 00 00 00 00 00
In the preceding hexadecimal sampling, the start point is the beginning of the Ethernet frame (DLC package. The IPv4 group header starts from the address offset 0x000e. The first byte is 0x45, and the last byte is 0xe9, that is, the IPv4 group header ends with the target IP address. Based on the above algorithm description, we can perform the following calculations:
(1) 0x4500 + 0x001c + 0x7468 + 0x0000 + 0x8011 + 0x0000 (accumulate and set the position to 0 first)
+ 0xc0a8 + 0x6401 + 0xab46 + 0x9ce9 = 0x3a66d
(2) 0xa66d + 0x3 = 0xa670
(3) 0 xFFFF-0xa670 = 0x598f
Note that in the first step, we use 0x0000 to set the header checksum. We can see that the checksum of this grouping header is exactly the same as the received value. The preceding process is only used by the sender to calculate the initial checksum. In practice, for the intermediate forwarding router and the final receiver, you can directly add the received IPv4 packet header checksum part according to the same algorithm, if the result is 0 xFFFF, the verification is correct.
For TCP and UDP datagram, the header also contains a 16-bit checksum. The verification algorithm is exactly the same as that of the IPv4 packet header, but the data involved in the verification is different. In this case, the checksum not only contains the entire TCP/UDP datagram, but also overwrites a virtual header. The virtual header is defined as follows:
0 7 8 1516 23 24 31
+ -------- +
| Sourceaddress |
+ -------- +
| Destinationaddress |
+ -------- +
| Zero | Protocol | TCP/UDP length |
+ -------- +
There are IP source addresses, IP destination addresses, protocol numbers (TCP: 6/UDP: 17), and the total length of TCP or UDP datagram (header + data ). The purpose of adding a virtual header to the verification is to verify whether the datagram reaches the correct destination and prevent spoofing attacks ). The protocol type of the preceding packet at 0x0018 = hexadecimal 11, that is, the packet is a UDP packet, the length of the two bytes is stored at the beginning of 0x0027 (including the source port address 4 bytes + UDP length 2 bytes + checksum 2 bytes = 8 bytes, and the length of UDP data: therefore, the UDP data length of this packet is actually 0 bytes. The IP Source Address is stored in eight bytes from 0x0x1a to 0x0x21. First, set the two bytes at the checksum and 0x002a to 0, calculate the UDP packet checksum as follows:
(1)
0xc0a8 + 0x6401 (source IP address before) + 0xab46 + 0x9ce9 (destination IP address before) + 0x0011 (zero and Protocol) +
0x0008 (UDP length) + 0x0f3a (source port) + 0x0405 (destination port) + 0x0008 (UDP length) + 0x0000 (checksum preset is 0) +... (No data here: the UDP data length is actually 0 bytes) = 0x28038
(2)
0x28038 => 0x8038 + 0x0002 = 0x803a
(3)
0xffff-0x803a = 0x7fc5
The calculation result is the same as that at 0x0028. Note that the UDP length appears twice.