TCP校验和计算更改 - 禁用tcp卸载

时间:2013-05-14 16:44:23

标签: c linux tcp checksum netfilter

我正在使用netfilter操作TCP数据包,所以我必须重新计算正常工作的TCP和IP校验和。

Wireshark报告校验和在离开服务器的路上是正确的(它与客户认为它们应该匹配的那样),但是当它们到达客户端时,校验和总是被替换为0xAA6A。

在post routing hook中,我在操作地址/端口后按如下方式计算TCP校验和。

 tcp_header->check = 0;
 tcp_header->check = tcp_v4_check(tcp_len,
   ip_header->saddr,
   ip_header->daddr,
   csum_partial((char *)tcp_header, tcp_len, 0));

使用

进行IP校验和
 ip_send_check(ip_header);

服务器没有为RX或TX启用TCP卸载,甚至不支持它,尝试启用或禁用时出现不支持的错误。

Offload parameters for eth0:
rx-checksumming: off
tx-checksumming: off
scatter-gather: off
tcp-segmentation-offload: off
udp-fragmentation-offload: off
generic-segmentation-offload: off
generic-receive-offload: on
large-receive-offload: off
rx-vlan-offload: off
tx-vlan-offload: off
ntuple-filters: off
receive-hashing: off

我不确定的另一个相关点......我还操纵服务器上的预路由挂钩中的数据包/端口,它们被传输层接受,无论什么都可以进入我的应用程序我似乎对TCP校验和做了,我假设如果在更改IP地址/和端口后没有更新TCP校验和,它们将被删除。

这种行为有没有明显的原因,或者我误解了网络堆栈的一部分?

更新

将ip_summed设置为CHECKSUM_NONE会在我的代码离开后停止重新计算校验和。我不确定的是为什么它被重新计算为不正确的固定值?如果我没有设置它,它将设置为CHECKSUM_PARTIAL。

1 个答案:

答案 0 :(得分:1)

如果另一方的值总是相同的,我会看到两种主要的可能性:1)你在此代码之后覆盖校验和2)tcp_len是错误的 您还应该检查是否在sockbuff dev->功能中设置了NETIF_F_V4_CSUM,因为在这种情况下内核会执行不同的操作