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

标签 c linux tcp checksum netfilter

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

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

在后路由 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

另一个我不确定的相关点......我还在服务器上的预路由 Hook 中操作数据包/端口,它们被传输层接受并且无论如何肯定会到达我的应用程序我似乎对 TCP 校验和做了处理,我假设如果在更改 IP 地址/和端口后未更新 TCP 校验和,它们将被删除。

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

更新:

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

最佳答案

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

关于c - TCP 校验和计算更改 - tcp 卸载已禁用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16548576/

相关文章:

c - 找出最大公约数为 1 的 C 系统中可表示为整数的最大一对数

linux - QThread::start(priority) 与 Linux

c - 当远程服务器可能在读取完成之前关闭套接字时,如何处理 C 中的套接字读取?

c - openssl api 函数引用问题

c++ - 没有溢出的无限递归 - 这可能吗?

javascript - 在 node.js 中捕获 tshark stdout 输出

linux - TCP/IP : set socket option for keep-alive after connection has been established

c - 调整 Linux 上 Web 服务器的接收 ACK 超时

c - 将 typedef 函数指针作为参数传递问题

java - Mingliu 字体不能在 linux 上工作