竭诚为您提供优质文档/双击可除linux,ip协议栈源代码分析,pdf篇一:netfilter源代码分析详解一、概述filter/iptables框架简介netfilter/iptables是继2.0.x的ipfwadm、2.2.x的ipchains之后,新一代的linux防火墙机制。
netfilter采用模块化设计,具有良好的可扩充性。
其重要工具模块iptables连接到netfilter的架构中,并允许使用者对数据报进行过滤、地址转换、处理等操作。
netfilter提供了一个框架,将对网络代码的直接干涉降到最低,并允许用规定的接口将其他包处理代码以模块的形式添加到内核中,具有极强的灵活性。
2.主要源代码文件linux内核版本:2.4.21netfilter主文件:net/core/netfilter.cnetfilter主头文件:include/linux/netfilter.hipv4相关:c文件:net/ipv4/netfilter/*.c头文件:include/linux/netfilter_ipv4.hinclude/linux/netfilter_ipv4/*.hipv4协议栈主体的部分c文件,特别是与数据报传送过程有关的部分:ip_input.c,ip_forward.c,ip_output.c,ip_fragment.c等二、netfilter/iptables-ipv4总体架构netfilter主要通过表、链实现规则,可以这么说,netfilter是表的容器,表是链的容器,链是规则的容器,最终形成对数据报处理规则的实现。
详细地说,netfilter/iptables的体系结构可以分为三个大部分:filter的hook机制netfilter的通用框架不依赖于具体的协议,而是为每种网络协议定义一套hook函数。
这些hook函数在数据报经过协议栈的几个关键点时被调用,在这几个点中,协议栈将数据报及hook函数标号作为参数,传递给netfilter框架。
对于它在网络堆栈中增加的这些hook,内核的任何模块可以对每种协议的一个或多个hook进行注册,实现挂接。
这样当某个数据报被传递给netfilter框架时,内核能检测到是否有任何模块对该协议和hook函数进行了注册。
若注册了,则调用该模块的注册时使用的回调函数,这样这些模块就有机会检查、修改、丢弃该数据报及指示netfilter将该数据报传入用户空间的队列。
这样,hook提供了一种方便的机制:在数据报通过linux 内核的不同位置上截获和操作处理数据报。
2.iptables基础模块iptables基础模块实现了三个表来筛选各种数据报,具体地讲,linux2.4内核提供的这三种数据报的处理功能是相互间独立的模块,都基于netfilter的hook函数和各种表、链实现。
这三个表包括:filter表,nat表以及mangle表。
3.具体功能模块1.1.数据报过滤模块2.连接跟踪模块(conntrack)3.网络地址转换模块(nat)4.数据报修改模块(mangle)5.其它高级功能模块于是,netfilter/iptables总体架构如图/photo/24896_061206192251. jpg所示三、hook的实现filter-ipv4中的hooknetfilter模块需要使用hook来启用函数的动态钩接,它在ipv4中定义了五个hook(位于文件include/linux/netfilter_ipv4.h,line39),分别对应0-4的hooknum简单地说,数据报经过各个hook的流程如下:数据报从进入系统,进行ip校验以后,首先经过第一个hook函数nF_ip_pRe_Routing进行处理;然后就进入路由代码,其决定该数据报是需要转发还是发给本机的;若该数据报是发被本机的,则该数据经过hook函数nF_ip_local_in处理以后然后传递给上层协议;若该数据报应该被转发则它被nF_ip_FoRwaRd处理;经过转发的数据报经过最后一个hook 函数nF_ip_post_Routing处理以后,再传输到网络上。
本地产生的数据经过hook函数nF_ip_local_out处理后,进行路由选择处理,然后经过nF_ip_post_Routing处理后发送出去。
总之,这五个hook所组成的netfilter-ipv4数据报筛选体系如图/photo/24896_061206192311. jpg:(注:下面所说netfilter/iptables均基于ipv4,不再赘述)详细地说,各个hook及其在ip数据报传递中的具体位置如图/photo/24896_061206192340. jpgnF_ip_pRe_Routing(0)数据报在进入路由代码被处理之前,数据报在ip数据报接收函数ip_rcv()(位于net/ipv4/ip_input.c,line379)的最后,也就是在传入的数据报被处理之前经过这个hook。
在ip_rcv()中挂接这个hook之前,进行的是一些与类型、长度、版本有关的检查。
经过这个hook处理之后,数据报进入ip_rcv_finish()(位于net/ipv4/ip_input.c,line306),进行查路由表的工作,并判断该数据报是发给本地机器还是进行转发。
在这个hook上主要是对数据报作报头检测处理,以捕获异常情况。
涉及功能(优先级顺序):conntrack(-200)、mangle(-150)、dnat(-100)nF_ip_local_in(1)目的地为本地主机的数据报在ip数据报本地投递函数ip_local_deliver()(位于net/ipv4/ip_input.c,line290)的最后经过这个hook。
经过这个hook处理之后,数据报进入ip_local_deliver_finish()(位于net/ipv4/ip_input.c,line219)这样,iptables模块就可以利用这个hook对应的input 规则链表来对数据报进行规则匹配的筛选了。
防火墙一般建立在这个hook上。
涉及功能:mangle(-150)、filter(0)、snat(100)、conntrack(int_max-1)nF_ip_FoRwaRd(2)目的地非本地主机的数据报,包括被nat修改过地址的数据报,都要在ip数据报转发函数ip_forward()(位于net/ipv4/ip_forward.c,line73)的最后经过这个hook。
经过这个hook处理之后,数据报进入ip_forward_finish()(位于net/ipv4/ip_forward.c,line44)另外,在net/ipv4/ipmr.c中的ipmr_queue_xmit()函数(line1119)最后也会经过这个hook。
(ipmr为多播相关,估计是在需要通过路由转发多播数据时的处理)这样,iptables模块就可以利用这个hook对应的FoRwaRd规则链表来对数据报进行规则匹配的筛选了。
涉及功能:mangle(-150)、filter(0)nF_ip_local_out(3)本地主机发出的数据报在ip数据报构建/发送函数ip_queue_xmit()(位于net/ipv4/ip_output.c,line339)、以及ip_build_and_send_pkt()(位于net/ipv4/ip_output.c,line122)的最后经过这个hook。
(在数据报处理中,前者最为常用,后者用于那些不传输有效数据的syn/ack包)经过这个hook处理后,数据报进入ip_queue_xmit2()(位于net/ipv4/ip_output.c,line281)另外,在ip_build_xmit_slow()(位于net/ipv4/ip_output.c,line429)和ip_build_xmit()(位于net/ipv4/ip_output.c,line638)中用于进行错误检测;在igmp_send_report()(位于net/ipv4/igmp.c,line195)的最后也经过了这个hook,进行多播时相关的处理。
这样,iptables模块就可以利用这个hook对应的output规则链表来对数据报进行规则匹配的筛选了。
涉及功能:conntrack(-200)、mangle(-150)、dnat(-100)、filter(0)nF_ip_post_Routing(4)所有数据报,包括源地址为本地主机和非本地主机的,在通过网络设备离开本地主机之前,在ip数据报发送函数ip_finish_output()(位于net/ipv4/ip_output.c,line184)的最后经过这个hook。
经过这个hook处理后,数据报进入ip_finish_output2()(位于net/ipv4/ip_output.c,line160)另外,在函数ip_mc_output()(位于net/ipv4/ip_output.c,line195)中在克隆新的网络缓存skb时,也经过了这个hook进行处理。
涉及功能:mangle(-150)、snat(100)、conntrack(int_max)其中,入口为net_rx_action()(位于net/core/dev.c,line1602),作用是将数据报一个个地从cpu的输入队列中拿出,然后传递给协议处理例程。
出口为dev_queue_xmit()(位于net/core/dev.c,line1035),这个函数被高层协议的实例使用,以数据结构structsk_buff*skb的形式在网络设备上发送数据报。
2.hook的调用hook的调用是通过宏nF_hook实现的,其定义位于include/linux/netfilter.h,line122:#definenF_hook(pf,hook,skb,indev,outdev,okfn)/(list_empty(/*userid*/structlist_headlist;}。