Chinaunix首页 | 论坛 | 博客
  • 博客访问: 793049
  • 博文数量: 264
  • 博客积分: 592
  • 博客等级: 中士
  • 技术积分: 1574
  • 用 户 组: 普通用户
  • 注册时间: 2011-10-24 22:02
文章分类

全部博文(264)

文章存档

2019年(2)

2018年(1)

2017年(1)

2016年(4)

2015年(14)

2014年(57)

2013年(88)

2012年(97)

分类: LINUX

2013-03-06 22:51:20

转:http://blog.sina.com.cn/s/blog_a31ff26901013qlj.html
 

3.1 IP数据包处理流程


要想理解Netfilter的工作原理,必须从对Linux IP报文处理流程的分析开始,Netfilter正是将自己紧密地构建在这一流程之中的。IP 协议栈是Linux操作系统的主要组成部分,也是Linux的特色之一,素以高效稳定著称。NetfilterIP协议栈是密切结合在一起的,我们以接收报文为例,简要介绍一下IPv4协议栈(IP层)的报文处理过程。


报文接收从网卡驱动程序开始,当网卡收到一个报文时,会产生一个中断,其驱动程序中的中断服务程序将调用确定的接收函数来处理。流程分成两个阶段:驱动程序中断服务程序阶段和IP协议栈处理阶段,驱动程序的处理流程与本章的联系不是十分紧密,故不做详细的介绍,我们以下面的流程图简要介绍以下数据包的接收过程。


驱动程序处理报文时,会生成一个skb_buff,同时将其放入一个全局的存储结构当中,同时设置软中断NET_RX_SOFTIRQ等待内核处理,内核收到软中断后,报文便开始了协议栈之旅。我们用以下的流程图来表示接收报文时整个处理的流程:


从图3.1的流程可以看出,NetfilterNF_HOOK形式挂载到ip协议栈对报文的处理过程中,然后将相应的数据包转入到Netfilter中来处理,我们可以将IP协议栈中调用NF_HOOK的地方称之为挂载点。除了流程图中指出的几处挂载点,Netfitler还在ip协议栈的多处进行了挂载,可以具体参考内核网络部分的源码。


Netfilter源码分析--3、Netfilter内部处理流程


3.2 Netfilter对报文的处理流程



3.2.1、扩展机制


Netfilter的扩展通过对全局变量的注册来完成。所谓的注册其本质上就是将数据存储到全局变量中,为后续的调用做好准备,Netfilter的注册机制可以分为表注册,target注册,match注册,hook操作注册。


表注册就是将定义好的表存放到一个全局变量xttables成员变量中,这个成员变量为一个xt_af的结构体,定义如下:


*


*这是一个存放所有规则信息及表信息的数据结构


*/


struct xt_af {


struct mutex
mutex;


struct
list_head match;//
所有在内核中注册的match信息


struct
list_head target;//
所有在内核中注册的target信息


struct
list_head tables;//
所有表的信息


struct mutex
compat_mutex;


};


static struct xt_af
*xt;//
一个全局变量,存储了所有内核和用户空间需要的规则信息。


与表注册类似,target注册和match注册也是通过向全局变量xt的成员变量写入信息来完成的。Netfilter通过这种注册的方式来实现对其扩展机制,用户可以根据自己的需求来实现matchtarget,甚至是自己实现一个表,然后注册到相应的全局变量,当数据包进入Netfilter后,hook操作会查找对应的表,以实现对数据包的匹配和处理。


Hook操作的注册的地点与上面三个注册不同。先来看下什么是hook操作。Netfilter在不同的挂载点注册不同的操作函数,以达到为不同协议的不同挂载点的报文进行不同处理的目的,为实现这个目的Netfilter定义了一个叫做nf_hook_ops的结构体,具体定义如下:


struct nf_hook_ops


{


struct
list_head list;



nf_hookfn
*hook;//
函数指针,操作的具体执行者


struct module
*owner;


int
pf;//
协议族


int
hooknum;//hook
的类型



int
priority;//
该操作的优先级,插入时使用


};


其中hook成员变量的原型为:


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 *));//hook
函数原型


Netfilter将不同协议的不同挂载点的操作函数都存放在一个全无变量nf_hooks中,数据包进入Netfilter后,会查找相应的hook操作,nf_hook对应的定义如下:


struct list_head
nf_hooks[NPROTO][NF_MAX_HOOKS] __read_mostly;//
存放所有协议的hooks


综上所述,我们可以用如下的表来表示,netfilter的内部的整个数据和扩展流程:


Netfilter源码分析--3、Netfilter内部处理流程




3.2 内部扩展机制


3.2.2Netfilter包处理


数据包在IP协议栈处理的过程中在经过挂载点时,就会进入Netfilter对报文做处理,NF_HOOK的整个调用流程可用如下的流程表来表示:


1、 整个hook的调用流程如下:


Netfilter源码分析--3、Netfilter内部处理流程



3.3 Netfilter中包处理


其中NF_HOOK的定义如下:


#define NF_HOOK(pf, hook, skb, indev, outdev, okfn)
\


NF_HOOK_THRESH(pf,
hook, skb, indev, outdev, okfn, INT_MIN)

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