Chinaunix首页 | 论坛 | 博客
  • 博客访问: 330570
  • 博文数量: 243
  • 博客积分: 86
  • 博客等级: 民兵
  • 技术积分: 1045
  • 用 户 组: 普通用户
  • 注册时间: 2012-03-09 17:03
个人简介

稳重,成熟

文章分类

全部博文(243)

文章存档

2015年(2)

2013年(72)

2012年(169)

我的朋友

分类:

2012-09-20 19:19:32

原文地址: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

  1. #include  
  2. #include  
  3. #include  
  4. #include  
  5.   
  6. MODULE_LICENSE("Dual BSD/GPL");  
  7.   
  8. unsigned int hook_func(unsigned int hooknum, struct sk_buff *skb, const struct net_device *in, /  
  9.                        const struct net_device *out, int (*okfn)(struct sk_buff *) );  
  10.   
  11. static struct nf_hook_ops myops = { { NULL, NULL }, hook_func, THIS_MODULE, PF_INET, NF_INET_FORWARD, NF_IP_PRI_FILTER };  
  12.   
  13. unsigned int hook_func(unsigned int hooknum, struct sk_buff *skb, const struct net_device *in, /  
  14.                        const struct net_device *out, int (*okfn)(struct sk_buff *) )  
  15. {  
  16.         printk( KERN_ALERT "hook_func is called./n" );  
  17.         return NF_ACCEPT;  
  18. }  
  19.   
  20. int init_module(void)  
  21. {  
  22.         return nf_register_hook(&myops);  
  23. }  
  24.   
  25. void cleanup_module(void)  
  26. {  
  27.         nf_unregister_hook(&myops);  
  28. }  

 

Makefile 文件:

  1. obj-m:=test.o  
  2. KDIR:=/lib/modules/`uname -r`/build  
  3. PWD:=$(shell pwd)  
  4. default:  
  5.         make -C ${KDIR} M=${PWD} modules  
  6. clean:  
  7.         rm -f *.order *.symvers *.o *.ko *.mod.c  

 

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

阅读(264) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~