【问题标题】:Update TCP/IP checksum in headers更新标头中的 TCP/IP 校验和
【发布时间】:2014-03-12 20:27:50
【问题描述】:

我正在尝试在发送数据包时在内核中手动修改 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 层。

我做了很多debug,发现在正常过程中,当数据包到达时,skb->ip_summed一般是CHECKSUM_UNNECESSARY,但是如果我在发送端进行修改,那么到达接收端的时候这个值就是CHECKSUM_NONE .

谁能给我一些建议?谢谢。

【问题讨论】:

  • iph->tot_len 的分配不应该在__tcp_v4_send_check 之前吗?

标签: linux tcp linux-kernel ip


【解决方案1】:

至于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)在发送方和接收方之间连接,以查看捕获数据包中的校验和是否损坏。

【讨论】:

    猜你喜欢
    • 2014-03-09
    • 2015-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-09
    • 2011-05-18
    相关资源
    最近更新 更多