如何计算TCP校验和[英] How to calculate TCP checksum

本文是小编为大家收集整理的关于如何计算TCP校验和的处理方法,想解了如何计算TCP校验和的问题怎么解决?如何计算TCP校验和问题的解决办法?那么可以参考本文帮助大家快速定位并解决问题。

问题描述

我正在编写一个内核模块,该内核模块使用NetFilter钩子修改了一些TCP标头信息,显然,在发送之前,我想重新计算校验和.
我还在接收侧编辑标题,因此我也需要在此处重新计算.

在网上搜索,我发现有人说我可以将其设置为0,它将为我计算,显然不起作用.
我还发现了这个功能

tcp_v4_send_check(struct sock *sk, struct sk_buff *skb);

尽管没有人解释如何使用它,以及我是否可以在接收/发送相同的方式上实际使用它.
我自己的尝试是将校验和设置为0,然后调用此功能通过我拥有的SKB和我拥有的SKB-> sk,仍然什么也没.

请,请什么可以直接计算TCP数据报的校验和的方法?

推荐答案

要重新计算校验和,您最好计算一个增量校验和 - 只需根据您更改的字段修改现有校验和,而不是读取整个数据包.

当您更改数据包时,必须完成此操作,当您知道旧值和存储的新值时.

基本思想是tcp->check += (new_val - old_val).
由于:
,这比这更复杂了. 1. old_val和new_val需要为16位值,在2个字节上对齐(例如,更改端口号).
2.校验和使用补充算术,因此您需要执行"随身反馈".这基本上意味着,如果tcp->check + new_val - old_val为负,则需要从结果中减1.

其他推荐答案

这是一个示例,该示例结合了NetFilter API + TCP的校验和校验(不是IP):

/a>

查看称为tcpsp_core.c.

的文件
    th->check = 0;
    th->check = csum_tcpudp_magic(iph->saddr, iph->daddr,
                                  datalen, iph->protocol,
                                  csum_partial((char *)th, datalen, 0));
    skb->ip_summed = CHECKSUM_UNNECESSARY;

(请注意,它首先分配为零,计算校验和,然后根据不需要表示IP校验和).

取决于哪个NetFilter模块U负载(有很多!!!)它们将在不同的层上工作,例如,在IP层上工作的工作如下(图像):

内容/图像/1-S2.0-S1389128608004040-gr3.jpg

其他推荐答案

@ugoren的答案并不精确.根据RFC1624 ,这有时会产生-0(0xffff),不允许.

正确计算校验和的正确方法应该是: new_tcp_check = ~(~old_tcp_check + ~old_val + new_val)

本文地址:https://www.itbaoku.cn/post/359298.html