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

查看:27
本文介绍了如何计算 TCP 校验和的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个内核模块,它使用 Netfilter 钩子来修改一些 TCP 标头信息,显然,在发送之前,我想重新计算校验和.
我还在接收端编辑了标题,所以我也需要在那里重新计算.

I am writing a Kernel Module that uses Netfilter hooks to modify some of the TCP header information and obviously, before sending, I want to re-calculate the checksum.
I also edit the header at the receiving side, so I need to re-calculate it there too.

在网上搜索,我发现有人说我可以简单地将它设置为 0 并且它会为我计算,显然这不起作用.
我也发现了这个功能

Searching online, I found some people saying I can simply set it to 0 and it'll be calculated for me, apparently that didn't work.
I've also found this function

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

虽然没有人解释它是如何使用的,以及我是否可以在接收/发送时以同样的方式实际使用它.
我自己的尝试是将校验和设置为 0,然后调用这个函数,传递我拥有的 skb 和我拥有的 skb->sk,仍然没有.

Though no one explained how this is used, and whether I can actually use it at the receiving/sending the same way.
My own attempt was to set checksum to 0 then call this function passing the skb I have and the skb->sk I have, still nothing.

请问,计算 TCP 数据报校验和的简单方法是什么?

So please, what is a straightforward way to calculate the checksum of TCP datagrams?

推荐答案

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

To re-calculate the checksum, you better calculate an incremental checksum - just modify the existing checksum based on the fields you've changed, rather than reading the entire packet.

这必须在您更改数据包时完成,同时您知道您存储的旧值和新值.

This must be done while you're changing the packet, when you know both the old values and the new values you store.

基本思路是tcp->check += (new_val - old_val).
它比这更复杂一点,因为:
1. old_valnew_val 需要是 16 位值,在 2 个字节上对齐(例如更改端口号).
2.校验和使用补码算法,所以需要做进位反馈".这基本上意味着,如果 tcp->check + new_val - old_val 为负数,则需要从结果中减去 1.

The basic idea is tcp->check += (new_val - old_val).
It's a bit more complicated than this, becuase:
1. old_val and new_val need to be 16-bit values, which are aligned on 2 bytes (e.g. changing a port number).
2. The checksum uses ones complement arithmetic, so you need to do "carry feedback". This basically means, that if tcp->check + new_val - old_val is negative, you need to subtract 1 from the result.

这篇关于如何计算 TCP 校验和的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆