Principles and implementation of TCP checksum Calculation

Source: Internet
Author: User
1. Summary TCP Header verification and calculation: TCP Header + TCP Data + TCP pseudo header.
The TCP checksum overwrites the TCP header and TCP data, while the checksum in the IP header only overwrites the IP header and does not overwrite any data in the IP datagram.
The pseudo-header is used to increase the TCP checksum error checking capability. For example, it checks whether the TCP packet is received incorrectly (the destination IP address) and whether the transport layer protocol is correct (the transport layer protocol number. The pseudo header is from the IP header.
RFC 793 TCP checksum defines the checksum field is the 16 bit one's complement of the one's complement sum of all 16-bit words in the header and text. if a segment contains an odd number of header and text octets to be checksummed, the last octet is padded on the rightwith zeros to form a 16-bit word for checksum purposes. the pad is not transmitted as part of the segment. while computingthe checksum, the checks Um field itself is replaced with zeros. the preceding definition is clear: first, the pseudo-header, TCP header, and TCP data are divided into 16 characters. If the total length is an odd number of bytes, then, add a byte of 0 at the end. Set the checksum field in the TCP header to 0. Second, use the inverse code addition method to accumulate all 16 characters (carry must also be accumulated ). Finally, the preceding result is used as the TCP Checksum.
Verification example: In the checksum and inverse code summation process, 4 bits are used as an example for sending end computing: Data: 1000 0100 0000 checksum 0111 anti-code: 1011 1111 0111 overlay: 1011 + 1111 + 0010 = 0001 higher than 4 bits, stack to 4-bit lower 0001 + 0010 = 0011 is the checksum and acceptor calculation: Data: 1000 0100 test and 0011 reverse code: 0111 1011 1100 overlay: 0111 + 1011 + 1100 = 0001 1110 superimposed as 4-bit 1111. if the value is 1, it is correct.
2. implementation of checksum and anticode summation Sender: the original code is added, and the high position is superimposed to the low position, reverse is obtained, and the result of the anticode summation is obtained. Put the checksum receiver: all the original codes are added, and the high position is superimposed, if all values are 1, the correct code is as follows:
    USHORT checksum (USHORT *buffer,int size)    {        Unsigned long cksum=0;        While (size>1)        {            Cksum +=*buffer++;            size -=sizeof(USHORT);        }        If (size)        {            Cksum +=*(UCHAR *) buffer;        }// Convert 32-bit to 16-bit        While (cksum>>16)            Cksum = (cksum>>16) + (cksum & 0xffff);        return (USHORT) (~cksum);    }
Buffer is a pointer to the data buffer to be verified, and size is the total length (in bytes) of the data to be verified ). 4-8 lines of code accumulate and sum the data by 16 bits. Because the carry of the highest bits needs to be added to the forward bits, cksum must be of the 32-bit unsigned long type, and 16 bits are used to save the carry during the accumulate process; rows 9-11 are used to handle the case where the size is an odd number. 14 ~ The function of the 15 lines of code is to add the value of cksum with a height of 16 bits to a lower value of 16 bits, that is, to add the carry of the highest bit in the tired addition to the carry bit. Here, the while loop is used to determine whether the cksum is 16-bit high and non-zero, because during the execution of 16th lines of code, it is still possible to carry 16-bit high to cksum. In some cases, cksum = (cksum> 16) + (cksum & 0 xFFFF); cksum = (cksum> 16 ); here, we only perform the addition twice to ensure that the 16-bit height of cksum after the addition is 0. The effects of the two methods are the same. In fact, the above loop can be executed up to two times! The 16-line code is used to obtain the result of the 16-bit data accumulation. The result of the sum of the binary codes is obtained. Then the function returns this value.
3. Implementation in Linux kernel: csum is 32bit, stores the result of adding the original code, overlays the original code with a height of 16 bits to a height of 16 bits, and then returns the result of reverse code summation.
static inline __sum16 csum_fold(__wsum csum){    u32 sum = (__force u32)csum;Sum = (sum & 0 xFFFF) + (sum> 16); // overlay high 16 to low 16Sum = (sum & 0 xFFFF) + (sum> 16); // overwrites the generated carry to 16 lowerReturn (_ force _ sum16 )~ SUM; // returns the result of the sum of binary anticode.}

The preceding csum calculation is as follows: skb_add_data-> csum_partial: Calculate the checksum of the added data segment and place it in SKB-> csum to complete the TCP Data partial calculation. Tcp_transmit_skb (Unified exit function of the transport layer) adds a TCP header for SKB, and CALLS tcp_v4_send_check to complete the final checksum calculation of the TCP Header (TCP Header + TCP Data + TCP pseudo header ). Source code analysis: tcp_transmit_skb {icsk-> icsk_af_ops-> send_check (SK, SKB-> Len, SKB); // completes the calculation of TCP Header checksum ...... err = icsk-> icsk_af_ops-> queue_xmit (SKB, 0); // send it to the IP layer ip_queue_xmit} Where forward --> icsk-> icsk_af_ops-> send_check (Limit) tcp_v4_send_check {..... th-> check = tcp_v4_check (Len, iNet-> inet_saddr, iNet-> inet_daddr, csum_partial (th, th-> doff <2, SKB-> csum )); // sum the th header checksum and TCP Data Segment checksum ....} // define inline _ sum16 tcp_v4_check (INT Len, _ be32 saddr, _ be32 daddr, _ wsum base) {return csum_tcpudp_magic (saddr, daddr, Len, ipproto_tcp, base); // sum the TCP Header + TCP Data + TCP pseudo header three-part checksum, and calculate the 32bit csum (SKB-> csum) as a 16bit check, stored in th-> check (TCP Header checksum field) to generate the final checksum} // calculate the checksum of the pseudo header static inline _ sum16 csum_tcpudp_magic (_ be32 saddr, _ be32 daddr, unsigned short Len, unsigned short proto, _ wsum sum) {return csum_fold (csum_tcpudp_nofold (saddr, daddr, Len, proto, sum ));}
// Fold the high 16 bits of the 32-bit value into the low 16 bits, and then take the reverse output value, that is, the checksum that should be filled in by the sender. Static inline _ sum16 csum_fold (_ wsum csum) {u32 sum = (_ force u32) csum; sum = (sum & 0 xFFFF) + (sum> 16); // overlay high 16 to low 16 sum = (sum & 0 xFFFF) + (sum> 16 ); // overlay the generated carry to low 16 return (_ force _ sum16 )~ SUM; // returns the result of the sum of binary anticode}

Principles and implementation of TCP checksum Calculation

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.