我正在尝试在发送数据包时在内核中手动修改IP头中的源和目标地址。之后,我需要重新计算IP校验和和TCP校验和。
我是按照以下方式进行的。
iph = ip_hdr(skb);
iph->saddr = mysaddr;
iph->daddr = mydaddr;
tcph= tcp_hdr(skb);
__tcp_v4_send_check(skb, iph->saddr, iph->daddr);
iph->tot_len = htons(skb->len);
ip_send_check(iph);
但是在接收器处,校验和总是在TCP层失败,而它可以通过IP层。
我做了很多调试,发现在正常过程中,当数据包到达时,skb-> ip_summed通常是CHECKSUM_UNNECESSARY,但是如果我在发送者处进行修改,那么当到达时,该值将为CHECKSUM_NONE。接收器。
有人可以给我一些建议吗?感谢。
答案 0 :(得分:0)
至于CHECKSUM_UNNECESSARY和CHECKSUM_NONE,关于它们的细节太多,无法用简单的词语描述它们,更好的阅读:
<<Understanding.Linux.Network.Internals >> / 19.1.1.2. sk_buff structure.
在这里发布我的猜测(希望它有用):
Since at sender side, you see generally CHECKSUM_UNNECESSARY, this might means your network card is probably able to do checksum verification and computing checksum in hardware.
By default, if TCP stack seeing your network card has this hardware capability, it would not bother computing checksum itself in software. But set CHECKSUM_PARTIAL in egress packet, so that network interface driver would instruct its hardware to computing checksum.
In your case, you compute the checksum by yourself, and should set CHECKSUM_NONE, so network interface would not compute the checksum again for you ( if doing so, break your checksum of modified packet ).
您可以使用任何数据包捕获工具(如wireshark),并在发送方和接收方之间连接一个集线器,以查看捕获的数据包中的校验和是否已损坏。