C Programming TCP Checksum

試著忘記壹切 提交于 2019-11-28 11:25:20

I found a fairly good example on the winpcap-users mailing list which should address Greg's comment about odd length data and give you something to compare your code against.

USHORT CheckSum(USHORT *buffer, int size)
{
    unsigned long cksum=0;
    while(size >1)
    {
        cksum+=*buffer++;
        size -=sizeof(USHORT);
    }
    if(size)
        cksum += *(UCHAR*)buffer;

    cksum = (cksum >> 16) + (cksum & 0xffff);
    cksum += (cksum >>16);
    return (USHORT)(~cksum);
}

I see a couple of things:

  • You are not accounting for odd length data by padding with zero.
  • You will need to account for network byte order when reading each word from the packet.
  • Your use of htonl(0x0000ffff) seems suspicious. Why are you converting a constant to network byte order to combine it with data in host byte order?

RFC 793 says "If a segment contains an odd number of header and text octets to be checksummed, the last octet is padded on the right with zeros to form a 16 bit word for checksum purposes." Your code above does not handle that case. I think the loop conditional should be i > 1 and then check for i == 1 outside the loop and do the special handling for the last octet.

I too struggled to find c++/c code that computes it, until I found How to Calculate IP/TCP/UDP Checksum–Part 2 Implementation – roman10, and it worked! Tested it with Wireshark's validation.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!