Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/57.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C语言编程TCP校验和_C_Tcp_Checksum_Raw Sockets - Fatal编程技术网

C语言编程TCP校验和

C语言编程TCP校验和,c,tcp,checksum,raw-sockets,C,Tcp,Checksum,Raw Sockets,我已经有麻烦做TCP校验和几天了。我已经看过了互联网上的很多资料,但是我所看到的例子都没有告诉你如何进行TCP校验和。我也看过了文件,但仍然有问题: 下面是我用来生成校验和的代码: unsigned short checksum(unsigned short * buffer, int bytes) { unsigned long sum = 0; unsigned short answer = 0; int i = bytes; while(i>0)

我已经有麻烦做TCP校验和几天了。我已经看过了互联网上的很多资料,但是我所看到的例子都没有告诉你如何进行TCP校验和。我也看过了文件,但仍然有问题:

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

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;
}
此函数用于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;
};
我一直在使用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;
};

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

我看到了以下几点:

  • 您不能用零填充奇数长度数据
  • 从数据包中读取每个字时,需要考虑网络字节顺序
  • 您对
    htonl(0x0000ffff)
    的使用似乎可疑。为什么要将常量转换为网络字节顺序,以便以主机字节顺序将其与数据组合

我在上找到了一个相当好的示例,它应该解决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);
}

表示“如果一个段包含奇数个要进行校验和的标题和文本八位字节,则最后一个八位字节在右侧用零填充,以形成一个16位字,用于校验和。”上面的代码不处理这种情况。我认为循环条件应该是I>1,然后检查循环外的I==1,并对最后一个八位字节进行特殊处理。

我也很难找到计算它的c++/c代码,直到我找到了,它工作了!通过Wireshark的验证进行了测试

更新

林克同时坏了,找回了它,并把它作为我账户的要点-

如何将信息加载到结构中,以及信息来自何处?链接已过时。@C、已恢复的站点和已更新的链接,请参阅更新。