分类:
2012-08-20 17:26:56
原文地址:linux中的netfilter 作者:kouyanghao
一、概述
netfilter, 是Linux内核(2.4.x和2.6.x)提供的数据包过滤框架,它提供了数据包的过滤 (packet filtering),网络地址转换(NAT and NAPT)和数据包修改(packet mangling)的功能。
在Linux内核中, netfilter是由一系列钩子(hook)组成的,它允许内核模块向网络协议栈注册回调函数。当数据包(skb_buff)在网络协议栈经过hook时,相应的已注册的回调函数将被调用,从而对数据包进行处理。
二、前期准备
由于编译netfilter模块,需要内核源码树。所以需要从下载最新内核源码并进行编译, 这里使用的是2.6.34版本
# uname -r
2.6.34
三、netfilter重要的数据结构和函数
1.数据结构
struct nf_hook_ops {
struct list_head list; //钩子链表
/* User fills in from here down. */
nf_hookfn *hook; //钩子处理函数
struct module *owner; //模块所有者
u_int8_t pf; //协议族
unsigned int hooknum; //钩子的位置值
/* Hooks are ordered in ascending priority. */
int priority;//钩子优先级
};
(1)list: 双向链表,一般可初始化为{NULL,NULL}
(2)hook: 要注册的hook函数名称
nf_hookfn定义如下
typedef unsigned int nf_hookfn(unsigned int hooknum,
struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *));
(3)owner: 模块名称,可初始化为THIS_MODULE
(4)pf: 协议族, 如PF_INET
(5)hooknum: hook编号,当前内核提供了下面几种
enum nf_inet_hooks {
NF_INET_PRE_ROUTING,
NF_INET_LOCAL_IN,
NF_INET_FORWARD,
NF_INET_LOCAL_OUT,
NF_INET_POST_ROUTING,
NF_INET_NUMHOOKS
};
(6)priority: 优先级
netfilter_ipv4.h中提供了下面几个值
enum nf_ip_hook_priorities {
NF_IP_PRI_FIRST = INT_MIN,
NF_IP_PRI_CONNTRACK_DEFRAG = -400,
NF_IP_PRI_RAW = -300,
NF_IP_PRI_SELINUX_FIRST = -225,
NF_IP_PRI_CONNTRACK = -200,
NF_IP_PRI_MANGLE = -150,
NF_IP_PRI_NAT_DST = -100,
NF_IP_PRI_FILTER = 0,
NF_IP_PRI_SECURITY = 50,
NF_IP_PRI_NAT_SRC = 100,
NF_IP_PRI_SELINUX_LAST = 225,
NF_IP_PRI_CONNTRACK_CONFIRM = INT_MAX,
NF_IP_PRI_LAST = INT_MAX,
};
2. 函数
(1)注册hook函数
int nf_register_hook(struct nf_hook_ops *reg);
一般在加载模块时调用
(2)注销hook函数
void nf_unregister_hook(struct nf_hook_ops *reg);
一般在卸载模块时调用
四、测试netfilter模块
test.c
Makefile 文件:
1. 编译模块
# make
make -C /lib/modules/`uname -r`/build M=/root/module/netfilter/test modules
make[1]: Entering directory `/usr/src/linux-2.6.34'
CC [M] /root/module/netfilter/test/test.o
Building modules, stage 2.
MODPOST 1 modules
CC /root/module/netfilter/test/test.mod.o
LD [M] /root/module/netfilter/test/test.ko
make[1]: Leaving directory `/usr/src/linux-2.6.34'
2. 加载模块
# insmod test.ko
# lsmod|grep test
test 582 0
3. 查看输出
有3种方法
(1)直接在终端查看内核输出
(2)#dmesg
(3)#tail /var/log/messages
可看到 hook_func is called.
4. 卸载模块
#rmmod test