Use Python to compute IP, TCP, UDP checksum

Source: Internet
Author: User
Tags bitwise


1.1 Calculation of IP checksum


IP check is for the IP header, that is, only the IP header, and for the IP data part of the verification, the corresponding four times the agreement to ensure that the IP head of the test and the field is 16bit.






The calculation principle is as follows:



1. Set the checksum field to 0



2. Calculate the sum of all 16bit words in the IP header



3. Reverse the obtained and bitwise in 2 and get the checksum.


Calculation principle of 1.2 TCP checksum


For the IP layer protocol, its checksum as long as the IP header can be computed, the relative, for the four layer protocol, its checksum needs to calculate four layers of head and four layer of data.



The TCP checksum needs to divide the IP pseudo header, TCP header, TCP data into 16-bit words, and then accumulate (if the total length is an odd number of bytes, then add a bit to 0 bytes at the end), and finally the cumulative and bitwise reverse.



The IP pseudo header includes the source IP address (4 bytes), the destination IP address (4 bytes), the protocol number (two bytes), the TCP Kanenaga (2 bytes), and a total of 12 bytes.





Calculation principle of 1.3 UDP checksum


The UDP checksum is basically consistent with the TCP checksum.



UDP checksum needs to divide the IP pseudo header, UDP header, UDP data into 16-bit words, and then accumulate (if the total length is an odd number of bytes, then add a bit to 0 bytes at the end), and finally the cumulative and bitwise reverse.



The IP pseudo header includes the source IP address (4 bytes), the destination IP address (4 bytes), the protocol number (two bytes), the TCP Kanenaga (2 bytes), and a total of 12 bytes.






The above is the IP, TCP, UDP checksum calculation principle, if we write the corresponding checksum function, the problem is not too large, as long as the basis of its calculation principle can be.



UDP checksum needs to calculate the UDP header plus data load, but also need to add a UDP pseudo-header.
This pseudo-header refers to the source address, destination address, UDP data length, protocol type (0X11), the protocol type is one byte, but needs to complement one byte of 0x0, constituting 12 bytes.
The pseudo-header +UDP header + data calculates the checksum together.

The UDP test and calculation methods are:
1. A 32-digit number according to the sum of each 16 bits;
2. If this 32-bit number, the high 16-bit is not 0, then the high 16-bit plus-low 16-bit is then given a 32-bit number;
3. Repeat the 2nd step until the high 16 bits are 0, the lower 16 bits are reversed, and the checksum is obtained.


The upd test and calculation is similar to the IP header check and, the UDP test and is an end-to-end test and is computed by the sender and then validated by the receiving end. The UDP datagram is discarded if the receiving end detects a test and has errors.   

Under the example of a UDP packet received by this computer, I analyze the UDP test and the calculation.  
0000:00  E0 4c A9 e0 0f 7d 1e ba (00 );
-xx-XX B-C0 a8 
0020:12  5c 1f 0f A0 34 + 2a 0f  2e 
0030:eb 3f  C4 B6 CB A3 B4 one A8 d3 
0040:93 D2 CF AC 1a B7 98 D4 AE, ed 24 
0050:BF C8 6f db 9a fa D8 C6 2a ca a2 BD 8b 
0060:96 03 
E0 4c A9-XX e0 0f 7d 1e BA----Ethernet frame Header (14 bytes)  
(20 bytes)  
1f 5c 0f A0 00 40 71, 6c EA DB, C0 A8,---- 2a----UDP Header (8 bytes), where 1f 40 represents the 16-bit source port number 8000;0f A0 represents the 16-bit destination port number 4000;00 40 indicates that the upd length is 64 bytes, and that 2a represents the UDP test and (this is the sender It will be used later in the calculation).  
0f ............ -----The remainder of the section is the UDP data section.  
Let's take a look at the tests together.  



The UDP datagram and TCP segment are set to a 12-byte long pseudo header in order to calculate the test. Because the length of a UDP datagram can be an odd number of sections, the test and algorithm add a number of three bits, so you can fill in the Padding byte field with 0, and the padding bytes that may increase are not transmitted.

Therefore, a pseudo-header of 12 bytes must be constructed: DB C0 A8 5c 00 11 00 40
After the construction is completed, the UDP test and the partial 0, and then the UDP per each of the binary inverse code summation, db85+2825+c0a8+125c+0011+0040 + 1f40+0fa0+0040+0000 +......+258b+9603=e8ec7
(0xe8ec7 >> +) + (0xe8ec7 & 0xFFFF) =0x8ed5
Finally, 0X8ED5+0X712A=0XFFFF
Thus, it can be judged that the above UDP datagram has no error in the transmission process.



To convert a hexadecimal string to a decimal number:
Python code
>>> print int (' FF ', 16)
255


 
1 # The original IP packet is split into a decimal list according to bytes
 2 IP_content = [69, 0, 1, 35, 127, 30, 0, 0, 64, 17, 213, 133, 10, 8, 136, 23, 10, 8, 136, 255, 214, 131, 214, 131, 1, 15, 95, 98, 0, 115, 104, 121, 121, 121, 102, 45, 103, 117, 116, 105, 110, 103, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 95, 39, 2, 0, 0, 0, 0, 48, 180, 159, 6, 0, 0, 0, 0, 51, 39, 0, 0, 0, 0, 0, 0, 16, 95, 39, 2, 0, 0, 0, 0, 192, 4, 110, 5, 0, 0, 0, 0, 124, 106, 122, 112, 0, 0, 0, 0, 152, 163, 218, 111, 0, 0, 0, 0, 89, 184, 159, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 112, 151, 218, 4, 0, 0, 0, 0, 164, 180, 159, 6, 0, 0, 0, 0, 192, 180, 159, 6, 0, 0, 0, 0, 168, 217, 122, 123, 97, 99, 54, 53, 100, 102, 100, 98, 45, 54, 50, 55, 52, 45, 52, 101, 101, 52, 45, 98, 99, 100, 100, 45, 52, 53, 98, 54, 97, 98, 99, 99, 55, 49, 54, 57, 125, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 160, 180, 159, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 53, 165, 138, 243]
 3
 4 #The original UDP message part is composed of a list in decimal
 5 [214, 131, 214, 131, 1, 15, 95, 98, 0, 115, 104, 121, 121, 121, 102, 45, 103, 117, 116, 105, 110, 103, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 95, 39, 2, 0, 0, 0, 0, 48, 180, 159, 6, 0, 0, 0, 0, 51, 39, 0, 0, 0, 0, 0, 0, 16, 95, 39, 2, 0, 0, 0, 0, 192, 4, 110, 5, 0, 0, 0, 0, 124, 106, 122, 112, 0, 0, 0, 0, 152, 163, 218, 111, 0, 0, 0, 0, 89, 184, 159, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 112, 151, 218, 4, 0, 0, 0, 0, 164, 180, 159, 6, 0, 0, 0, 0, 192, 180, 159, 6, 0, 0, 0, 0, 168, 217, 122, 123, 97, 99, 54, 53, 100, 102, 100, 98, 45, 54, 50, 55, 52, 45, 52, 101, 101, 52, 45, 98, 99, 100, 100, 45, 52, 53, 98, 54, 97, 98, 99, 99, 55, 49, 54, 57, 125, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 160, 180, 159, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 53, 165, 138, 243]
 6
 7 # Need to assemble and calculate the UDP checksum part
 8 udp_content = []
 9     
10 #IP source address is 13, 14, 15, 16 bytes of IP packet
11 udp_content.append (IP_content [12])
12 udp_content.append (IP_content [13])
13 udp_content.append (IP_content [14])
14 udp_content.append (IP_content [15])
15
16 #IP destination address is 17, 18, 19, and 20 bytes of the IP packet
17 udp_content.append (IP_content [16])
18 udp_content.append (IP_content [17])
19 udp_content.append (IP_content [18])
20 udp_content.append (IP_content [19])
twenty one 
22 #UDP data length is the 5th and 6th bytes in the UDP packet
23 udp_content.append (IP_content [IHL + 4])
24 udp_content.append (IP_content [IHL + 5])
25
26 #Protocol type is the 10th byte of the IP packet
27 udp_content.append (0x00)
28 udp_content.append (IP_content [9])
29
30 for i in range (UDP_Len):
31 udp_content.append (IP_content [IHL + i])
32
33 udp_content [18] = 0 #Set the original checksum to 0
34 udp_content [19] = 0
35
36 if UDP_Len% 2 == 1: #The length of the entire message is odd and needs to be added 0
37 udp_content.append (0x00)
38
39 print (‘The content of the UDP checksum to be calculated is:’ + str (udp_content))
40 manual_check = calc_checksum (udp_content)
41 print (manual_check)
42
43 #The result after assembly is displayed in decimal
44 udp_content = [10, 8, 136, 23, 10, 8, 136, 255, 1, 15, 0, 17, 214,131, 214, 131, 1, 15, 0, 0, 0, 115, 104, 121, 121, 121, 102, 45, 103, 117, 116, 105, 110, 103, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 95, 39, 2, 0, 0, 0, 0, 48, 180, 159, 6, 0, 0, 0, 0, 51, 39, 0, 0, 0, 0, 0, 0, 16, 95, 39, 2, 0, 0, 0, 0, 192, 4, 110, 5, 0, 0, 0, 0, 124, 106, 122, 112, 0, 0, 0, 0,152, 163, 218, 111, 0, 0, 0, 0, 89, 184, 159, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 112, 151, 218, 4, 0, 0, 0, 0, 164, 180, 159, 6, 0, 0, 0, 0, 192, 180, 159, 6, 0, 0, 0, 0, 168, 217, 122, 123, 97, 99, 54, 53, 100, 102, 100, 98, 45, 54, 50, 55, 52, 45, 52, 101, 101, 52, 45, 98, 99, 100, 100, 45, 52, 53, 98, 54, 97, 98, 99, 99, 55, 49, 54, 57, 125, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 160, 180, 159, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 53, 165, 138, 243, 0]
45
46 def calc_checksum (sum_data):
47 join_sum_data = []
48 for i in range (0, len (sum_data), 2): #First you need to combine the two numbers before and after into a 16-bit hexadecimal number
49 first_part = str (hex (sum_data [i])) [2:] # 10 hex converted to hexadecimal, the length is 8 bits
50 if len (first_part) <2: #If only 1 digit is needed after conversion to hexadecimal, high-order zero-fill operation is required
51 first_part = ‘0‘ + first_part
52
53 second_part = str (hex (sum_data [i + 1])) [2:] # 10 hex to hexadecimal, length 8 bits
54 if len (second_part) <2: #If only 1 digit is needed after conversion to hexadecimal, high-order zero-fill operation is required
55 second_part = ‘0‘ + second_part
56
57 total_part = first_part + second_part #Merge into 16-bit length
58
59 join_sum_data.append (int (total_part, 16)) # Re-convert hexadecimal to decimal
60 # join_sum_data.append (total_part)
61
62 #print (join_sum_data)
63
64 sum_result = 0
65 for single_value in join_sum_data:
66 sum_result = sum_result + single_value\
#Calculate the sum of all numbers
67
68 hex_sum_result = str (hex (sum_result)) [2:] #Transform to 4-byte 32-bit hexadecimal format
69
70 len_hex_sum = len (hex_sum_result) #Get the number of bytes
71
72 if len_hex_sum> 4: #If the summation result is greater than 2 bytes and 16 bits, divide it into two 2 bytes and 16 bits
73 first_part = int (hex_sum_result [: len_hex_sum-4], 16) #Separate the first and second byte hexadecimal digits, convert to decimal
74
75 second_part = int (hex_sum_result [len_hex_sum-4:], 16) #Separate the third and fourth byte hexadecimal digits, convert to decimal
76
77 last_check_sum = str (hex (0xffff-(first_part + second_part))) [2:] #The sum of two hexadecimal numbers is inverted
78 return last_check_sum
79 else:
80 last_check_sum = str (hex (65535-sum_result)) [2:] #only two bytes of hexadecimal numbers are directly inverted just fine
81 return last_check_sum





Use Python to compute IP, TCP, UDP checksum


Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.