我试图解决问题。
让我们解释一下这个问题:我有两个客户端,每个客户端都在不同的nat之后,将ICMP ECHO REQUEST
发送到服务器。这样做没问题。服务器必须能够接收这些REQUEST
,以存储收到的每个ICMP ID
,并将ECHO REPLY
有效ID
的自定义ICMP
发送回每个设备。
使此服务器构建IP
和ICMP
标头。这是方案:
1) CLIENT A ----ECHO REQUEST----> SERVER
2) SERVER <----ECHO REQUEST----CLIENT B
3) CLIENT A <----ECHO REPLY---- SERVER ----ECHO REPLY---->CLIENT B
服务器从客户端A接收第一个echo请求,第二个从客户端B接收,然后发送回回复,但这里开始出现问题:
实际上第二个echo回复很好但是第一个没有,wireshark(我用它来嗅探包)给了我不正确的校验和。要发送和接收数据包,我使用相同的unsigned char buffer[2000]
,所以我认为问题是在第一个回复回复中我使用不正确的缓冲区来计算校验和。
此代码用于计算校验和:
struct icmp_header *icmphderp=(struct icmp_header *)(buffer + sizeof(struct iphdr));
//...
icmphderp->checksum = girashort(checksum((unsigned char *)icmphderp, sizeof(struct icmp_header)));
//...
unsigned short checksum(unsigned char * buffer, int len){
int i;
unsigned short * word16;
unsigned long totale;
word16 = (unsigned short *) buffer;
totale=0;
for(i=0;i<len/2;i++){
totale = totale + girashort(word16[i]);
if(totale & 0x10000)
totale = ((totale&0xFFFF) + 1);
}
return (unsigned short)(0xFFFF-(unsigned short) totale);
}
unsigned short int girashort(unsigned short int n){
unsigned char * p;
unsigned char tmp;
p = (unsigned char *) &n;
tmp = p[0];
p[0] = p[1];
p[1] = tmp;
return n;
}
我让memcpy(buf, buffer, 2000)
存储第一个收到的缓冲区,但似乎无效。有人可以建议我如何解决这个问题?