C编程TCP校验和

Hud*_*den 6 c checksum tcp raw-sockets

我几天来一直无法为TCP做校验和.我在互联网上查看了很多来源,但我见过的所有示例都没有向您展示如何进行TCP校验和.我也查看了RFC文档,但仍遇到问题:

下面是我用来生成校验和的代码:

unsigned short checksum(unsigned short * buffer, int bytes)
{
    unsigned long sum = 0;
    unsigned short answer = 0;
    int i = bytes;
    while(i>0)
    {
            sum+=*buffer;
            buffer+=1;
            i-=2;
    }
    sum = (sum >> 16) + (sum & htonl(0x0000ffff));
    sum += (sum >> 16);
    return ~sum;
}
Run Code Online (Sandbox Code Playgroud)

此功能适用于IP校验和.

下面是我为TCP标头制作的结构:

struct tcp_header
{
    unsigned short tcp_sprt;
    unsigned short tcp_dprt;
    unsigned int tcp_seq;
    unsigned int tcp_ack;
    unsigned char tcp_res:4;
    unsigned char tcp_off:4;
    unsigned char tcp_flags;
    unsigned short tcp_win;
    unsigned short tcp_csum;
    unsigned short tcp_urp;
};
Run Code Online (Sandbox Code Playgroud)

我一直在使用Wireshark来测试这些数据包,唯一不对的就是校验和.

最后,这里是伪标头结构,我加载了TCP标头和来自IP标头的信息:

struct pseudoTcpHeader
{
    unsigned int ip_src;
    unsigned int ip_dst;
    unsigned char zero;//always zero
    unsigned char protocol;// = 6;//for tcp
    unsigned short tcp_len;
    struct tcp_header tcph;
};
Run Code Online (Sandbox Code Playgroud)

一旦我用正确的信息加载这个结构,我就在整个伪头结构上使用校验和函数,并将TCP校验和分配给该值.你看到我提供的东西有什么问题吗?如果问题不在这里,可能是我看不到的粗心错误.

syn*_*tel 5

我在winpcap-users邮件列表上找到了一个相当不错的例子,该列表应该解决Greg关于奇数长度数据的评论,并给你一些比较代码的东西.

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);
}
Run Code Online (Sandbox Code Playgroud)