无法正确计算IP校验和

时间:2014-02-02 14:18:48

标签: c++ c networking

已经困在这个问题好几天了。有人可以帮我吗?

核心代码:

IP标头

ip_hdr
{
    unsigned char   h_ver;
    unsigned char   tos;
    unsigned short  tot_len;
    unsigned short  id;
    unsigned short
        zero:1,
        frag:1,
        more_frag:1,    
        frag_off:13;            
    unsigned char   ttl;
    unsigned char   protocol;
    unsigned short  checkSum;
    unsigned long   saddr;
    unsigned long   daddr;
}

校验和功能

它来自linux的源代码,所以我认为它可以正常工作。

unsigned short checkSum(unsigned char * buff, int wlen)
{
    unsigned long sum = 0;

    if (wlen) {
        unsigned long bogus;
        __asm__("clc\n"
            "1:\t"
            "lodsl\n\t"
            "adcl %3, %0\n\t"
            "decl %2\n\t"
            "jne 1b\n\t"
            "adcl $0, %0\n\t"
            "movl %0, %3\n\t"
            "shrl $16, %3\n\t"
            "addw %w3, %w0\n\t"
            "adcw $0, %w0"
            : "=r" (sum), "=S" (buff), "=r" (wlen), "=a" (bogus)
            : "0"  (sum),  "1" (buff),  "2" (wlen));
    }
return (~sum) & 0xffff;
}    

生成IP数据报

int IPGen(ip_hdr *hdr,unsigned long srcIP,unsigned long dstIP)
{
    hdr->h_ver=(4<<4 | sizeof(ip_hdr)/sizeof(unsigned int));
    hdr->tos=0;
    hdr->tot_len=sizeof(ip_hdr)+sizeof(tcp_hdr);
    hdr->id=0;
    hdr->zero=0;
    hdr->frag=0;
    hdr->more_frag=0;
    hdr->frag_off=0;
    hdr->ttl=64;
    hdr->protocol=IP_TCP;
    hdr->saddr=srcIP;
    hdr->daddr=dstIP;

    hdr->saddr=htonl(hdr->saddr);
    hdr->daddr=htonl(hdr->daddr);
    hdr->tot_len=htons(hdr->tot_len);

    hdr->checkSum=0;
    hdr->checkSum=checkSum((short*)hdr,sizeof(ip_hdr));

    return 0;
}

以这种方式生成的数据包被wireshark视为invalid ...当红色占据大部分空间时的辉煌

这是最奇怪的事情,我使用wireshark捕获了一个数据包,然后计算其校验和,我发现我得到的结果与数据包中包含的结果不相等。

0 个答案:

没有答案