如何重新计算netfilter中的IP校验和?
问题描述:
我正在开发一个netfilter的内核模块中,我需要重新计算IP校验和。我用这个功能来计算IP校验(发现它的地方,互联网上):如何重新计算netfilter中的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"?)]
答
你在哪里捕获数据包?
IP校验和(以及TCP/UDP校验和)可以由网络卡本身来计算。如果你的卡上有这种情况(这是一个非常常见的功能),并且你正在捕获你的机器,我希望看到0个校验和。
答
如果定义IP报头是这样的:
struct iphdr *iph;
然后
iph = (struct iphdr *) skb_header_pointer(skb, 0, 0, NULL);
,那么你可以重新计算校验和,就像下面。
/* Calculation of IP header checksum */
iph->check = 0;
ip_send_check (iph);
你可以看看我的问题:How to append data on a packet from kernel space? 在那里,你可以在底部给出答案由我自己找到详细的代码。在那里,我不得不 重新计算IP和UDP标头校验和。
你实现C++中的Linux内核模块? – 2012-04-28 20:18:50
您在Linux内核模块中使用的代码是“您在互联网上找到的”?你明白什么是版权意味着什么?你是否理解“签名”意味着你发誓你写了所有的代码,或者拥有代码版权的人已经在GPLv2下授权了它? – 2012-04-28 20:21:11
定义“损坏的IP标头”。这是否意味着“不正确的校验和”或实际上“损坏的IP头”?如果是后者,那么你可能搞乱了别的东西。 – mfontanini 2012-04-28 20:48:16