C编程TCP校验和

问题描述 投票:6回答:4

几天来,我一直在为TCP进行校验和时遇到麻烦。我查看了Internet上的许多资源,但没有看到的示例向您展示如何执行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;
}

此功能适用于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;
};

一旦我用正确的信息加载此结构,然后在整个伪头结构上使用校验和功能,并将TCP校验和分配给该值。您看到我提供的内容有什么问题吗?如果问题不在这里,则可能是我看不到的粗心错误。

c tcp checksum raw-sockets
4个回答
5
投票

[我在winpcap-users mailing list上找到了一个相当不错的示例,该示例应该可以解决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);
}

3
投票

我看到几件事:

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

2
投票

[RFC 793说:“如果段中包含奇数个要校验和的标题和文本八位字节,则在右边用零填充最后一个八位字节,以形成用于校验和目的的16位字。”您上面的代码无法处理这种情况。我认为循环条件应为i> 1,然后在循环外检查i == 1并对最后一个八位位组进行特殊处理。


0
投票

我也很难找到计算它的c ++ / c代码,直到找到How to Calculate IP/TCP/UDP Checksum–Part 2 Implementation – roman10,它才起作用!通过Wireshark的验证对其进行了测试。

UPDATE

Link同时中断,将其恢复为要点,How to Calculate IP/TCP/UDP Checksum

© www.soinside.com 2019 - 2024. All rights reserved.