Netfilter

来源:互联网 发布:大华解码器软件 编辑:程序博客网 时间:2024/05/19 17:24

偶的毕业设计是基于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,选上,再次编译通过。