基于Netfilter hook功能的数据包拦截---有关DCN优化的碎碎念

futurezone 2012-08-24

接前一篇博客,我们需要拦截每一个收到或者发出的数据包,并对它进行处理,进过调研,实验(感谢实验室赵博,井大神),打算使用linux内核中的Netfilter模块实现这个功能。Netfilter中有一个hook的功能,可以在:

NF_IP_PRE_ROUTING              在完整性校验之后,选路确定之前

NF_IP_LOCAL_IN在选路确定之后,且数据包的目的是本地主机

NF_IP_FORWARD目的地是其它主机地数据包

NF_IP_LOCAL_OUT来自本机进程的数据包在其离开本地主机的过程中

NF_IP_POST_ROUTING            在数据包离开本地主机“上线”之前

5个地方安插钩子(hook),每一个通过这些点的函数都会被勾出来,然后调用预先设置好的处理函数进行处理,这正是我们做NAOpt想要实现的功能!

测试demo的代码如下:

#define _KERNEL_ #include<linux/module.h> #include<linux/kernel.h> #include<linux/netfilter.h> #include<linux/netfilter_ipv4.h> static struct nf_hook_ops nfho; 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*)) { printk("get it"); return NF_ACCEPT; } int init_module() { nfho.hook = hook_func; nfho.hooknum = NF_INET_PRE_ROUTING ; nfho.pf = PF_INET; nfho.priority = NF_IP_PRI_FIRST; nf_register_hook(&nfho); return 0; } void cleanup_module() { printk("over"); nf_unregister_hook(&nfho); }

  

写这个demo的时候遇到了2个问题:

1.如果在hook_function中不加入返回语句 return NF_ACCEPT,被勾住的数据包就不会被重新发送出去,网络传输是中断的,所以我们在编写NAOpt的时候,只要在hook函数中加入处理逻辑代码,最后在return NF_ACCEPT,就可以很好的完成封装任务;

2.nfho.hooknum = NF_INET_PRE_ROUTING  ,这里是NF_INET_PRE_ROUTING  而不是很多参考文献中所说的NF_IP_PRE_ROUTING,应为在linux/netfilter_ipv4.h这个头文件中有一个宏:  #define NF_IP_PRE_ROUTING NF_INET_PRE_ROUTING

 最后,附上demo的make文件

obj-m += test.o CURRENT_PATH := $(shell pwd) LINUX_KERNEL := $(shell uname -r) LINUX_KERNEL_PATH := /lib/modules/3.2.0-23-generic-pae/build all: make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) clean

相关推荐