【发布时间】:2012-11-02 21:08:03
【问题描述】:
我正在开发一个 netfilter 内核模块,我需要在其中重新计算 IP 校验和。我用这个函数来计算 IP 校验和(在互联网上的某个地方找到):
unsigned short ComputeIPChecksum(unsigned char *data, int len)
{
long sum = 0; /* assume 32 bit long, 16 bit short */
unsigned short *temp = (unsigned short *)data;
while(len > 1){
sum += *temp++;
if(sum & 0x80000000) /* if high order bit set, fold */
sum = (sum & 0xFFFF) + (sum >> 16);
len -= 2;
}
if(len) /* take care of left over byte */
sum += (unsigned short) *((unsigned char *)temp);
while(sum>>16)
sum = (sum & 0xFFFF) + (sum >> 16);
return ~sum;
}
通过查看wireshark,我可以看到传入的数据包已成功接收,但对于传出的数据包,wireshark 显示不正确的IP 校验和。 这是我的钩子函数:
static unsigned int hook_func(unsigned int hooknum,
struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
sock_buff = skb;
if (sock_buff)
{
ip_header = (struct iphdr *)skb_network_header(sock_buff);
if (ip_header && ip_header->protocol == TCP)
{
ip_header->check = ComputeIPChecksum((unsigned char *)ip_header, ip_header->ihl*4);
}
}
return NF_ACCEPT;
}
这是主要的,我已经将相同的钩子函数绑定到 PRE_ROUTING 和 POST_ROUTING
static int __init init_main(void)
{
nfho.hook = hook_func;
nfho.hooknum = 0;
nfho.pf = PF_INET;
nfho.priority = NF_IP_PRI_FIRST;
nfho1.hook = hook_func;
nfho1.hooknum = 4;
nfho1.pf = PF_INET;
nfho1.priority = NF_IP_PRI_FIRST;
nf_register_hook(&nfho);
nf_register_hook(&nfho1);
return 0;
}
为什么传出数据包的 IP 校验和损坏???
wireshark中显示的错误:
Header checksum: 0x0000 [incorrect, should be 0x85de (maybe caused by "IP checksum offload"?)]
【问题讨论】:
-
你正在用 C++ 实现一个 Linux 内核模块?
-
您在 Linux 内核模块中使用“您在互联网上找到的”代码?你明白版权是什么意思吗?您是否理解“签署人”意味着您发誓您编写了所有代码,或者拥有代码版权的人已根据 GPLv2 对其进行许可?
-
定义“损坏的 IP 标头”。这是否意味着“不正确的校验和”或实际上是“损坏的 IP 标头”?如果是后者,那么您可能正在搞砸其他事情。
-
Header checksum: 0x0000 [不正确,应该是0x85de(可能是“IP checksum offload”引起的?)]
标签: c++ linux module kernel netfilter