0

我正在使用 netfilter 操作 TCP 数据包,因此我必须重新计算按预期工作的 TCP 和 IP 校验和。

Wireshark 报告校验和在离开服务器时是正确的(这也与客户端认为的正确),但是当它们到达客户端时,校验和总是被替换为 0xAA6A。

在后路由挂钩中,我正在计算 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。

4

1 回答 1

1

如果另一侧的值始终相同,我看到 2 个主要可能性:1)您稍后在此代码之后覆盖校验和 2)tcp_len 错误您还应该检查 NETIF_F_V4_CSUM 是否在 sockbuff dev->features 中设置,因为在这种情况下,内核做了一些不同的事情

于 2013-05-14T17:27:25.927 回答