偶的毕业设计是基于Netfilter的东西,最近也就对Netfilter有了一些了解。
通过NetFilter这个名字,我感觉它是一个包过滤机制,然后分别在路有前后的几个关键点定义了一些钩子,允许内核的其他模块来对包进行处理。
内核模块通过调用nf_register_hook来注册钩子函数,注册时提供一个叫做nf_hook_ops 的结构体以告诉Netfilter足够的信息,该结构体有几个域:
hook :钩子函数名
hooknum:注册钩子的地点,有以下几种类型
NF_IP_PRE_ROUTING 在完整性校验之后,选路确定之前
NF_IP_LOCAL_IN 在选路确定之后,且数据包的目的是本地主机
NF_IP_FORWARD 目的地是其它主机地数据包
NF_IP_LOCAL_OUT 来自本机进程的数据包在其离开本地主机的过程中
NF_IP_POST_ROUTING 在数据包离开本地主机“上线”之前
pf : 指定协议族
priority :指定优先级
每个钩子函数完成之后,指示Netfilter作何种操作。
NF_ACCEPT: 允许数据包通过
NF_DROP: 丢弃该数据包
NF_STOLEN: 告诉内核,该数据包已被处理。
NF_QUEUE: 将数据包排入队列,通常是将数据包发送给用户进程空间处理NF_REPEAT: 再一次调用本HOOK
下面这个模块是一个非常简单的基于NetFilter的的模块,该模块在每一个包到来的时候都输出一个“a packet go through”信息,下面是这个模块的源代码。
#define __KERNEL__
#define MODULE
#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("a packet go through/n");
return NF_ACCEPT;
}
int init_module()
{
nfho.hook = hook_func;
nfho.hooknum = NF_IP_PRE_ROUTING;
nfho.pf = PF_INET;
nfho.priority = NF_IP_PRI_FIRST;
nf_register_hook(&nfho);
return 0;
}
void cleanup_module()
{
nf_unregister_hook(&nfho);
}
编译这个内核代码的时候,遇到些问题
/usr/include/linux/netfilter_ipv4.h:53: `INT_MIN' undeclared here (not in a function)
/usr/include/linux/netfilter_ipv4.h:53: enumerator value for `NF_IP_PRI_FIRST' not integer constant
/usr/include/linux/netfilter_ipv4.h:59: `INT_MAX' undeclared here (not in a function)
/usr/include/linux/netfilter_ipv4.h:59: enumerator value for `NF_IP_PRI_LAST' not integer constant
,这是因为内核头文件太少,后来我在Linux.org上下载了内核源代码,给Gcc增加 -I /usr/local/src/linux/include后,仍然有问题,好像是说nf_hook_ops 没有定义
我怀疑是没有配置内核支持Netfilter,在Linux源代码中用make menuconfig打开配置界面,在Network Option里面确实发现没有选中networking Packet filter,选上,再次编译通过。