|
我想自己编写一个可加载内核模块(LKM)来实现对转发的数据包进行重定向到某一个固定目标,模块中定义的一个函数名为packetdirect的钩子函数被添加到netfilter中的NF_IP_PRE_ROUTING钩子点上。为了在netfilter的NF_IP_PRE_ROUTING上对数据包重定向,此模块程序修改从局域网内客户机发送过来的数据包的目的地址,但是我在作局域网服务器网关的机器上装载了该模块后,它的客户机不但不能被重定向到目的地址上,而且不能再通过网关上网了!但是如果把处理函数packetdirect() 中的以下几行代码去掉后: __u32 newdaddr = in_aton("192.168.10.19”) ; (*skb)->nh.iph->check=mynat_cheat_check(~(*skb)->nh.iph->daddr, newdaddr, (*skb)->nh.iph ->check); (*skb)->nh.iph->daddr = newdaddr; 只留下return NF_ACCEPT;这一行代码,客户机就能通过网关上网!
我的源程序如下, 请问为什么不能实现重定向功能呢?是不是实现数据包重定向没有这么简单,或者还是需要其他的操作步骤? (以下源程序编译已经通过:我的编译方法是:gcc -O2 -Wall -c -I/usr/src/linux-2.4/include functionname.c)?
#define __KERNEL__ #define MODULE
#include<linux/kernel.h> #include<linux/module.h> #include<linux/netdevice.h> #include<linux/netfilter.h> #include<linux/netfilter_ipv4.h> #include<linux/inet.h > #include<linux/in.h> #include <linux/module.h> #include <linux/skbuff.h> #include <net/checksum.h>
static struct nf_hook_ops nfho; /*用于注册处理数据包函数的数据结构*/
/*ip校验和函数,该函数抄自/net/ipv4/netfilter/ip_nat_cheat_core.c:ip_cheat_check()*/ mynat_cheat_check(__u32 oldvalinv, __u32 newval, __u16 oldcheck)
{ __u32 diffs[] = { oldvalinv, newval }; return csum_fold(csum_partial((char *)diffs, sizeof(diffs),
oldcheck^0xFFFF)); }
static unsigned int /*我的数据包重定向的处理函数*/ packetdirect(unsigned int hooknum , struct sk_buff **skb , const struct net_device *in , const struct net_device *out, int (*okfn)(struct sk_buff *))
{
__u32 newdaddr = in_aton("192.168.10.19”) ;/*为重定向新修改的目标地址*/ (*skb)->nh.iph->check=mynat_cheat_check(~(*skb)->nh.iph->daddr, newdaddr, (*skb)->nh.iph ->check); /* 校验和*/ (*skb)->nh.iph->daddr = newdaddr; /*赋值新目标地址*/ return NF_ACCEPT; }
int init_module(void) { nfho.hook=packetdirect; nfho.hooknum=NF_IP_PRE_ROUTING; nfho.pf= PF_INET; nfho.priority=NF_IP_PRI_FIRST; return nf_register_hook(&nfho); return 0; }
void cleanup_module(void) { nf_unregister_hook(&nfho);
}
|