我正在编写一个简单的程序来发送/接收TCP数据包,并将其整合到一个更大的项目中。在校验和部分卡住了,我计算出来的数字与Wireshark中显示的校验和数字不匹配。
在校验和函数方面,我重新使用了Mike Muss的代码,如下所示:
我收到了一个数据包并将其存储在一个
然后我尝试使用上述函数计算校验和并将其打印出来:
我得到的是"My calculated checksym = 0x0",看起来IP头部没有任何东西。我猜可能没有正确传递in_cksum函数参数,但我不确定如何修复或者是否还有其他问题。
下面解决了IP校验和问题。然而,当我尝试计算TCP校验和时遇到了类似的问题。以下是我获取TCP头部的方式:
在此之后,我可以再次正确地阅读有关TCP头部的信息,例如
然后我尝试重新计算校验和,如下所示:
我在这里得到的结果与之前打印出来的不同。我认为我的问题可能是我传递给
在校验和函数方面,我重新使用了Mike Muss的代码,如下所示:
static int
in_cksum(u_short *addr, int len)
{
register int nleft = len;
register u_short *w = addr;
register int sum = 0;
u_short answer = 0;
/*
* Our algorithm is simple, using a 32 bit accumulator (sum), we add
* sequential 16 bit words to it, and at the end, fold back all the
* carry bits from the top 16 bits into the lower 16 bits.
*/
while (nleft > 1) {
sum += *w++;
nleft -= 2;
}
/* mop up an odd byte, if necessary */
if (nleft == 1) {
*(u_char *)(&answer) = *(u_char *)w ;
sum += answer;
}
/* add back carry outs from top 16 bits to low 16 bits */
sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
sum += (sum >> 16); /* add carry */
answer = ~sum; /* truncate to 16 bits */
return(answer);
}
我收到了一个数据包并将其存储在一个
char buffer[2048]
中。为了获取IP头,我执行以下操作:struct iphdr* ip;
ip = (struct iphdr*) buffer;
从这里开始,我可以正确地读取信息,例如ip->protocol
,ip->saddr
等,甚至可以像Wireshark中显示的那样打印出正确的校验和。
printf("Print checksum = 0x%x\n",ntohs(ip->check));
然后我尝试使用上述函数计算校验和并将其打印出来:
printf("My calculated checksum =0x%x\n",in_cksum ((unsigned short*) ip, sizeof(struct iphdr)));
我得到的是"My calculated checksym = 0x0",看起来IP头部没有任何东西。我猜可能没有正确传递in_cksum函数参数,但我不确定如何修复或者是否还有其他问题。
下面解决了IP校验和问题。然而,当我尝试计算TCP校验和时遇到了类似的问题。以下是我获取TCP头部的方式:
tcp=(struct tcphdr*) (buffer+sizeof(struct iphdr);
在此之后,我可以再次正确地阅读有关TCP头部的信息,例如
tcp->source
,tcp->dest
,甚至是 tcp->check
。然后我尝试重新计算校验和,如下所示:
tcp->check=0;
tcp->check=in_cksum((unsigned short*)tcp, ntohs(ip->tot_length)-(4*ip->ihl));
我在这里得到的结果与之前打印出来的不同。我认为我的问题可能是我传递给
cksum
函数的长度,但我不太确定如何修复它。
tcp = (struct tcphdr *)(ip + 4 * ip->ihl)
- 不要使用sizeof(struct iphdr)
。 - undefined