2012-09-10 263 views
1

即时计算我的数据包的正确ip校验和有问题。下面是代码,我会解释什么IM做的和什么错误..IP校验和计算不正确

所有的
u_short checkSum(u_short *data, int byteCount){ 
int i, sum = 0; 

for(i = 0; i < byteCount/2; i++){ 
    if(i == 5) continue; 
    sum += *data++; 
} 

while(sum >> 16) 
sum = (sum & 0xffff) + (sum >> 16); 
return (u_short)~sum; 
} 

首先,我的作用是一般用于计算发送数据的16位校验和。 ByteCount被假定为仅用于测试目的。总和是我保留32位和的变量(当16位总和溢出时,我可以将溢出保持在高16位一半)。用for循环遍历数据的16位数据块并对它们进行求和,将数据指针递增(16位为u_short),如果测试跳过头部的校验和部分,则有一个数据指针。可以看出在RFC 791中,校验和部分是头中的第6个16位块(在我的情况中是5,因为我从0开始计数)。在数据求和之后,我将高16位加到低16位,并将32位整数折成16位短路。最后,我反转这些位(补码)并将16位中的32位缩短并将其返回给调用者函数。

这不是提供从pcap发送给我的正确校验和(我用它来嗅探数据包)。这是我打电话给我的功能来比较结果..

if(etherHdr->ether_type == 8){ 
    ipHdr = (struct ip*) (packet + sizeof(struct ether_header)); 
    printf("chck: %04x mychck: %04x\n\n", ipHdr->ip_sum, checkSum((u_short*)ipHdr, sizeof(struct ip))); 
} 

IF是在滤除仅IP数据包(在以太网报头类型字段代码8)..

,这是输出时我跑我的程序..

CHCK:EF66 mychck:06ee

CHCK:3db8 mychck:0264

CHCK:9615 mychck:0000

CHCK:edef mychck:ff64

CHCK:59f1 mychck:0164

CHCK:49f1 mychck:0264

CHCK:a3d4 mychck:0c77

CHCK:e36b mychck:0264

CHCK:aad4 mychck:0c77

CHCK:46d1 mychck:0c77

CHCK:f40b mychck:0264

CHCK:a8d4 mychck:0c77

我下载在网络上跑来跑去其他代码示例和那些都给出了每一个IP报头包含在它的时候结果pcap转发数据包到我的代码..

请帮助,如果你可以,谢谢。

+0

您的网卡是否支持校验和卸载?如果是这样,你可能会收到错误的校验和。 HTTP://维基。wireshark.org/TCP_Checksum_Verification –

+0

卸载据我了解,意味着校验和是在数据包被注入网络之前计算的? – stefo0O0o

回答

1

正确的方法在RFC 1071中给出。你很近,但没有雪茄。

+0

这是否意味着rfc 791在校验和部分无关紧要? – stefo0O0o

+0

@ user1661352完全没有。你有没有证据表明他们不同意? – EJP

0

也许尝试此计算校验和的源代码,我正在使用它,它对我的​​软件非常有用。

  int 
checksum 
      (unsigned short * data, 
      int   length) 
{ 
    register int    nleft = length; 
    register unsigned short  * w = data; 
    register int    sum = 0; 
    unsigned short    answer = 0; 

    while (nleft > 1) 
    { 
     sum  += *w++; 
     nleft -= 2; 
    } 

    if (nleft == 1) 
    { 
     *(unsigned char *)(&answer) = *(unsigned char *)w; 
     sum+=answer; 
    } 

    sum = (sum>>16) + (sum & 0xffff); 
    sum += (sum>>16); 
    answer = ~sum; 

    return answer; 
} 
+0

虐待尝试,谢谢...但我认为我的代码是附近你写的这里.. – stefo0O0o

+0

不适合我..给我0000(十六进制)为每个包=/ – stefo0O0o

+0

谢谢,它的工作,我没有意识到我得到0的原因校验和折叠校验和字段中计算的校验和。我将它设置为0,我得到正确的校验和。再次感谢! – stefo0O0o