版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
Netfilter分析:這是完整的Netfilter源碼分析
一、概述
1.Netfi1ter/TPTables框架簡(jiǎn)介
2.直要源代碼文獻(xiàn)
二、Netfilter/IPTables-IPv4總體架構(gòu)
1.NetfilterHOOK機(jī)制
2.IPTables基礎(chǔ)模塊
3.詳細(xì)功能模塊
三、HOOK的實(shí)現(xiàn)
1.Netfilter-IPv4中的HOOK
2.HOOKH勺調(diào)用
3.HOOK點(diǎn)的實(shí)現(xiàn)
4.HOOKH勺注冊(cè)和注銷
四、IPTables系統(tǒng)
1.表一規(guī)則系統(tǒng)
2.表的實(shí)現(xiàn)
3.規(guī)則的實(shí)現(xiàn)
4.規(guī)則的使用
5.規(guī)則的擴(kuò)展
五、數(shù)據(jù)報(bào)過(guò)濾模塊一一filter表
1.概述
2.filter表的定義和初始化
3filter表的實(shí)現(xiàn)
六、連接跟蹤模塊(Conntrack)
1.概述
2.連接狀態(tài)的管理
3.連接跟蹤時(shí)實(shí)現(xiàn)
4.協(xié)議的擴(kuò)展
七、網(wǎng)絡(luò)地址轉(zhuǎn)換模塊(NetworkAddressTranslation)
1.概述
2.基于連接跟蹤的有關(guān)數(shù)據(jù)構(gòu)造
3.nat表口勺實(shí)現(xiàn)
4.協(xié)議的擴(kuò)展
八、數(shù)據(jù)報(bào)修改模塊---mangle表
L概述
2.mangle表的實(shí)現(xiàn)
3.數(shù)據(jù)報(bào)的修改
九、其他高級(jí)功能模塊
一、概述
1.Netfilter/IPTables框架簡(jiǎn)介
Netfilter/IPTables是繼2.0.x的IPfwadm.2.2.x的IPchains之后,新一代日勺Linux防火墻機(jī)制。
Netfilter采用模塊化設(shè)計(jì),具有貪好H勺可擴(kuò)充性。其重要工具模塊IPTables連接到Netfilter的架構(gòu)
中,并容許使用者對(duì)數(shù)據(jù)報(bào)進(jìn)行過(guò)濾、地址轉(zhuǎn)換、處理等操作。
Netfilter提供了一種框架,將對(duì)網(wǎng)絡(luò)代碼日勺直接干涉降到最低,并容許用規(guī)定的接口將其他包處
理代碼以模塊的形式添加到內(nèi)核中,具有極強(qiáng)的靈活性。
2.重要源代碼文獻(xiàn)
Netfilter主文獻(xiàn):net/core/netfiIter,c
Netfilter主頭文獻(xiàn):includc/linux/nctfilter.h
IPv4有關(guān):c文獻(xiàn):net/ipv4/netfilter/*.c
頭文獻(xiàn):include/linux/netfiltcr_ipv4.h
include/linux/netfilter_ipv4/*.h
IPv4協(xié)議棧主體的部分c文獻(xiàn),尤其是與數(shù)據(jù)報(bào)傳送過(guò)程有關(guān)的部分:
ipinput.c,ip_forward.c,ip_output.c,ip_fragment.c等
二、Nctfiltcr/IPTablcs-IPv4總體架構(gòu)
Netfilter重要通過(guò)表、鏈實(shí)現(xiàn)規(guī)則,可以這樣說(shuō),Netfilter是表的容器,表是鏈口勺容器,鏈
是規(guī)則日勺容器,最終形成對(duì)數(shù)據(jù)報(bào)處理規(guī)則日勺實(shí)現(xiàn)。
詳細(xì)地說(shuō),Netfilter/IPTables的體系構(gòu)造可以分為三個(gè)大部分:
1.NetfilterHOOK機(jī)制
Netfilter的J通用框架不依賴于詳細(xì)的J協(xié)議,而是為每種網(wǎng)絡(luò)協(xié)議定義一套HOOK函數(shù)。這些
HOOK函數(shù)在數(shù)據(jù)報(bào)通過(guò)協(xié)議棧的幾種要點(diǎn)時(shí)被調(diào)用,在這幾種點(diǎn)中,協(xié)議棧將數(shù)據(jù)報(bào)及HOOK函數(shù)標(biāo)號(hào)
作為參數(shù),傳遞給Netfilter框架。
對(duì)于它在網(wǎng)絡(luò)堆棧中增長(zhǎng)的這些HOOK,內(nèi)核的任何模塊可以對(duì)每種協(xié)議日勺一種或多種HOOK進(jìn)
行注冊(cè),實(shí)現(xiàn)掛接。這樣當(dāng)某個(gè)數(shù)據(jù)報(bào)被傳遞給Netfilter框架時(shí),內(nèi)核能檢測(cè)到與否有任何模塊對(duì)該
協(xié)議和HOOK函數(shù)進(jìn)行了注冊(cè)。若注冊(cè)了,則調(diào)用該模塊日勺注冊(cè)時(shí)使用的回調(diào)函數(shù),這樣這些模塊就有機(jī)
會(huì)檢查、修改、丟棄該數(shù)據(jù)報(bào)及指示Netfilter將該數(shù)據(jù)報(bào)傳入顧客空間的隊(duì)列。
這樣,HOOK提供了一種以便的機(jī)制:在數(shù)據(jù)報(bào)通過(guò)Linux內(nèi)核的不一樣位置上截獲和操作處理數(shù)據(jù)
報(bào)。
2.IPTables基礎(chǔ)模塊
IPTables基礎(chǔ)模塊實(shí)現(xiàn)了三個(gè)表來(lái)篩選多種數(shù)據(jù)報(bào),詳細(xì)地講,Linux2.4內(nèi)核提供日勺這三種數(shù)
據(jù)報(bào)的處理功能是互相間獨(dú)立的模塊,都基于Netfilter的HOOK函數(shù)和多種表、鏈實(shí)現(xiàn)。這三個(gè)表包括:
filter表,nat表以及mangle表。
3.詳細(xì)功能模塊
數(shù)據(jù)報(bào)過(guò)濾模塊
連接跟蹤模塊(Conntrack)
網(wǎng)絡(luò)地址轉(zhuǎn)換模塊(NAT)
數(shù)據(jù)報(bào)修改模塊(mangle)
其他高級(jí)功能模塊
于是,于是ilter/IPTables總體架構(gòu)如圖所示
Netfilter/IPTables
三、HOOK時(shí)實(shí)現(xiàn)
1.Netfilter-IPv4中的HOOK
Netfilter模塊需要使用HOOK來(lái)啟用函數(shù)的動(dòng)態(tài)鉤接,它在IPv4中定義了五個(gè)HOOK(位于文
include/linux/netfilter_ipv4.h,Line39),分別對(duì)應(yīng)0-4日勺hooknum
簡(jiǎn)樸地說(shuō),數(shù)據(jù)報(bào)通過(guò)各個(gè)HOOK的流程如下:
數(shù)據(jù)報(bào)從進(jìn)入系統(tǒng),進(jìn)行IP校驗(yàn)后來(lái),首先通過(guò)第一種HOOK函數(shù)NF」P_PRE_RO【ITING進(jìn)行處理:
然后就進(jìn)入路由代碼,其決定該數(shù)據(jù)報(bào)是需要轉(zhuǎn)發(fā)還是發(fā)給本機(jī)的;若該薪據(jù)報(bào)是發(fā)被本機(jī)口勺,則該數(shù)
據(jù)通過(guò)HOOK函數(shù)NF_IP_LOCAL_IN處理后來(lái)然后傳遞給上層協(xié)議;若該數(shù)據(jù)報(bào)應(yīng)當(dāng)被轉(zhuǎn)發(fā)則它被
NF_TP_FORWARD處理;施后轉(zhuǎn)發(fā)而數(shù)據(jù)報(bào)通過(guò)最終一種HOOK函數(shù)NF」P_POST_ROUTING處理后來(lái),再傳
播到網(wǎng)絡(luò)上。當(dāng)?shù)禺a(chǎn)生日勺數(shù)據(jù)通過(guò)HOOK函數(shù)NF」P_LOCAL_OUT處理后,進(jìn)行路由選擇處理,然后通過(guò)
NF」P_POST_ROUTING處理后發(fā)送出去。
總之,這五個(gè)HOOK所構(gòu)成的Netfilter-IPv4數(shù)據(jù)報(bào)篩選體系如圖(注:下面所說(shuō)
Netfilter/IPTables均基于IPv4,不再贅述)
圖2.Netfilter-IPv4的數(shù)據(jù)報(bào)篩選體系
詳細(xì)地說(shuō),各個(gè)HOOK及其在IP數(shù)據(jù)報(bào)傳遞中口勺詳細(xì)位置如圖
NF」P_PRE_ROUTING(0)
數(shù)據(jù)報(bào)在進(jìn)入路由代碼被處理之前,數(shù)據(jù)報(bào)在IP數(shù)據(jù)報(bào)接受函數(shù)ii-rcvO(位于
net/ipv4/ip_input.c,Line379)的最終,也就是在傳入日勺數(shù)據(jù)報(bào)被處理之前通過(guò)這個(gè)HDOK。在ip_rcv()
中掛接這個(gè)HOOK之前,進(jìn)行日勺是其些與類型、長(zhǎng)度、版本有關(guān)的檢查。
通過(guò)這個(gè)HOOK處理之后,數(shù)據(jù)報(bào)進(jìn)入ip_rcv_finish()(位于net/ipv4/ip_input.c,Line306),進(jìn)
行查路曰表的工作,并判斷該數(shù)據(jù)報(bào)是發(fā)給當(dāng)?shù)丶悠鬟€是進(jìn)行轉(zhuǎn)發(fā)。
在這個(gè)HOOK上重要是對(duì)數(shù)據(jù)報(bào)作報(bào)頭檢測(cè)處理,以捕捉異常狀況。
波及功能(優(yōu)先級(jí)次序):Conntrack(-200),mangle(-150),DNAT(-IOO)
NF」P_LOCAL_IN(1)
目的地為當(dāng)?shù)刂鳈C(jī)的數(shù)據(jù)報(bào)在IP數(shù)據(jù)報(bào)當(dāng)?shù)赝哆f函數(shù)ip_local_deliver()(位于
net/ipv4/ipinput.c,Line290)H勺最終通過(guò)這個(gè)HOOK。
通過(guò)這個(gè)HOOK處理之后,數(shù)據(jù)報(bào)進(jìn)入ip_local_deliver_finish()(位于net/ipv4/ip_input.c,
Line219)
這樣,IPTables模塊就可以運(yùn)用這個(gè)HOOK對(duì)應(yīng)H勺INPUT規(guī)則鏈表來(lái)對(duì)數(shù)據(jù)報(bào)進(jìn)行規(guī)則匹配的篩
選了。防火墻一般建立在這個(gè)HOOK上。
波及功能:mangle(-150)>filter(O).SNAT(IOO),Conntrack(INTJIAX-1)
NF」P_FORWARD(2)
目口勺地非當(dāng)?shù)刂鳈C(jī)口勺數(shù)據(jù)報(bào),包括被NAT修改正地址的數(shù)據(jù)報(bào),都要在TP數(shù)據(jù)報(bào)轉(zhuǎn)發(fā)函數(shù)
ip_forward()(位于net/ipv4/ip_forward.c,Line73)區(qū)|最終通過(guò)這個(gè)HOOK。
通過(guò)這個(gè)HOOK處理之后,數(shù)據(jù)報(bào)進(jìn)入ip_forward_finish()(位于net/ipv4/ip_forward.c,
Line44)
此外,在net/ipv4/ipmr.c中日勺ipmr_queue_xmit()函數(shù)(LinellI9)最終也會(huì)通過(guò)這個(gè)HOOK°(ipmr
為多播有關(guān),估計(jì)是在需要通過(guò)路由轉(zhuǎn)發(fā)少播數(shù)屬時(shí)的處理)
這樣,IPTables模塊就可以運(yùn)用這個(gè)HOOK對(duì)應(yīng)的FORWARD規(guī)則鏈表來(lái)對(duì)數(shù)據(jù)報(bào)進(jìn)行規(guī)則匹配的篩
選了。
波及功能:mangle(-150)>filter(O)
NF_IP_LOCAL_OUT(3)
當(dāng)?shù)刂鳈C(jī)發(fā)出日勺數(shù)據(jù)報(bào)在IP數(shù)據(jù)報(bào)構(gòu)建/發(fā)送函數(shù)ip_queue_xmit()(位于net/ipv4/ip_output.c,
Line339)>以及ip_build_and_send_pkt()(位于net/ipv4/ip_output.c,Linel22)日勺最終通過(guò)這個(gè)
HOOKo(在數(shù)據(jù)報(bào)處理中,前者最為常用,后者用于那些不傳播有效數(shù)據(jù)的SYN/ACK包)
通過(guò)這個(gè)HOOK處理后,數(shù)據(jù)報(bào)進(jìn)入ipqucue_xmit2()(位于net/ipv4/ipoutput,c,Line281)
此外,在ipbuildxmit_slow()(位于net/ipv4/ipoutput,c,Line429)和ipbuildxmit()(位
于net/ipv4/ip_output.c,Line638)中用于進(jìn)行錯(cuò)誤檢測(cè);在igmp_send_report()(位于
net/ipv4/igmp.c,Linel95)的最終也通過(guò)了這個(gè)HOOK,進(jìn)行多播時(shí)有關(guān)的處理。
這樣,IPTables模塊就可以運(yùn)用這個(gè)HOOK對(duì)應(yīng)的OUTPUT規(guī)則鏈表來(lái)對(duì)數(shù)據(jù)報(bào)進(jìn)行規(guī)則匹配H勺篩選
了。
波及功能:Conntrack(-200)mangle(-150)>DNAT功能0)、filter(0)
NF_IP_POST_ROUTING(4)
所有數(shù)據(jù)報(bào),包括源地址為當(dāng)?shù)刂鳈C(jī)和非當(dāng)?shù)刂鳈C(jī)的I,在通過(guò)網(wǎng)絡(luò)設(shè)備離開(kāi)當(dāng)?shù)刂鳈C(jī)之前,在IP
數(shù)據(jù)報(bào)發(fā)送函數(shù)ip_finish_output()(位于net/ipv4/ip_output.c,Linel84)聆|最終通過(guò)這個(gè)HOOK。
通過(guò)這個(gè)HOOK處理后,數(shù)據(jù)報(bào)進(jìn)入ipfinish_output2:)(位于net/ipv4/ip_output.c,Linel60)
此外,在函數(shù)ip_mc_output()(位于net/ipv4/ip_output.c,Linel95)中在克隆新的I網(wǎng)絡(luò)緩存skb時(shí),
也通過(guò)"這個(gè)HOOKil行處理。
波及功能:mangle(-150)>SNAT(lOO),Conntrack(INT_MAX)
其中,入口為net_rx_action:)(位于net/core/dev.c,Linel602),作用是將數(shù)據(jù)報(bào)-一種個(gè)地從
CPU的輸入隊(duì)列中拿出,然后傳遞給協(xié)議處理例程。
出口為dev_queue_xmit()(位于net/core/dev.c,Linel035),這個(gè)函數(shù)被高層協(xié)議日勺實(shí)例使用,以
數(shù)據(jù)構(gòu)造structsk_buff*skb的形式在網(wǎng)絡(luò)設(shè)備上發(fā)送數(shù)據(jù)報(bào)。
2.HOOK的調(diào)用
HOOK的調(diào)用是通過(guò)宏NF_HOOK實(shí)現(xiàn)H勺,其定義位于include/linux/Netfilter.h,Linel22:
SdefineNFJ100K(pf,hook,skb,indev,outdev,okfn)\
(list_empty(&nf_hooks[(pf)][(hook)])\
?(okfn)(skb)\
:nf_hook_slow((pf),(hook),(skb),(indev),(outdev),(okfn)))
這旦先調(diào)用list_empty函數(shù)檢查HOOK點(diǎn)存儲(chǔ)數(shù)組nf_hooks與否為空,為空則表達(dá)沒(méi)有HOOK注冊(cè),
則直接調(diào)用。kfn繼續(xù)處理。假如人為空,則轉(zhuǎn)入nf_hook_s:ow()函數(shù)。
nf_hook_slow()函數(shù)(位于net/core/netfilter.c,Line449)日勺工作重要是讀nf_hook數(shù)組遍歷所有
的Jnf_hook_ops構(gòu)造,并調(diào)用nf_hookfn()處理各個(gè)數(shù)據(jù)報(bào)。
即HOOK口勺調(diào)用過(guò)程如圖示
圖4.HOOK的調(diào)用過(guò)程
下面闡明一下NFJ00K的各個(gè)參數(shù):
pf:協(xié)議族標(biāo)識(shí),有關(guān)H勺有效協(xié)議族列表位于include/linux/socket.h,Line178。對(duì)于IPv4,應(yīng)當(dāng)使
用協(xié)議族PFINET;
hook:HOOK標(biāo)識(shí),即前面所說(shuō)5個(gè)HOOK對(duì)應(yīng)的Jhooknum;
skb:是具有需要被處理包的skbuuff數(shù)據(jù)構(gòu)造Rj指針。skbuff是Linux網(wǎng)絡(luò)緩存,指那些linux內(nèi)
核處理IP分組報(bào)文的緩存,即套接字緩沖區(qū)。
網(wǎng)卡收到IP分組報(bào)文后,將它們放入sk,buff,然后再傳送給網(wǎng)絡(luò)堆棧,網(wǎng)絡(luò)堆棧幾乎一直要用到
skbuffo其定義在include/linux/skbuff.h,Line129,下面列出我認(rèn)為對(duì)分析故意義的)部提組員:
structsock*sk;':韋向創(chuàng)立分組報(bào)文/、Jsocket;
structtimcvalstamp;':分組報(bào)文抵達(dá)系統(tǒng)的時(shí)間;
下面是三個(gè)union,寄存的是各層中多種協(xié)議的I報(bào)文頭指針:
h對(duì)應(yīng)傳播層的報(bào)頭
nh對(duì)應(yīng)網(wǎng)絡(luò)層的報(bào)頭
mac對(duì)應(yīng)MAC層的報(bào)頭
'unsignedintlen;':套接字緩存所代表的I報(bào)文長(zhǎng)度,即從unsignedchar*data;'的)位置算起H勺目前
有效報(bào)文長(zhǎng)度。
unsignedcharpkttype,:表達(dá)報(bào)文的類型,詳細(xì)類型定義在include/1imix/ifpacket,h,
Line24:
^definePACKETJ1OST0//發(fā)送到本機(jī)的報(bào)文
#definePACKET_BROADCAST1//廣播報(bào)文
#definePACKETJ1ULTICAST2//多播報(bào)文
#definePACKET_OTHER11OST3//表達(dá)目的地非本機(jī)但被本機(jī)接受時(shí)報(bào)文
#definePACKET_OUTGOING4//離開(kāi)本機(jī)日勺報(bào)文
/*Theseonesareinvisiblebyuserlevel*/
#definePACKET_LOOPBACK5//本機(jī)發(fā)給自己日勺報(bào)文
^defineEACKEIJASTKOUTE6//迅速路由報(bào)文
indev:輸入設(shè)備,收到數(shù)據(jù)報(bào)口勺網(wǎng)絡(luò)設(shè)備的net.device數(shù)據(jù)構(gòu)造指針,即數(shù)
據(jù)報(bào)抵達(dá)的接口。
用于NF_IPPREROUTING和NF」P_LOCAL」N兩個(gè)HOOK
outdev:輸出設(shè)備,數(shù)據(jù)報(bào)離開(kāi)當(dāng)?shù)厮褂萌丈拙W(wǎng)絡(luò)設(shè)備日勺net_device數(shù)據(jù)構(gòu)
造指針。
用于NF_IP_LOCAL_OUT和NF_IP_POST_ROUTING兩個(gè)HOOK
注意:在一般狀況下,在一次HOOK調(diào)用中,indev和outdev中只有一種參數(shù)會(huì)被使用
okfn:下一步要處理的函數(shù)。即假如有HOOK函數(shù),則處理完所有的HOOK函數(shù),且所有向該HOOK注
冊(cè)過(guò)的篩選函數(shù)都返回調(diào)用這個(gè)函數(shù)繼續(xù)處理;假如沒(méi)有注冊(cè)任何HOOK,則直接調(diào)
用此函數(shù)。其5個(gè)參數(shù)將由宏NF」IOOK傳入。
3.HOOK點(diǎn)的實(shí)現(xiàn)
對(duì)應(yīng)于各個(gè)不一樣協(xié)議的不一樣HOOK點(diǎn)是由一種二維數(shù)組nf_hooks存儲(chǔ)日勺(位于
net/core/netfilter.c,Line47),詳細(xì)日勺HOOK點(diǎn)則由數(shù)據(jù)構(gòu)造nf_hook_ops(位于
include/linux/netfilter.h,Line44)實(shí)現(xiàn)。如圖所示:
圖5.HOOK點(diǎn)的實(shí)現(xiàn)
其中,nf_hook_ops組員中:
intpriority;priority值越小,優(yōu)先級(jí)越高,有關(guān)優(yōu)先級(jí)在include/linux/netfilter_ipv4.h,
Line52中枚舉定義:
enumNF_IP_hook_priorities{
NF_IP_PRI_F1RST=INTJHN,
NF_IP_PRI_CONNTRACK=-200,
NF_IP_PRI_MANGLE=-150,
NF」P_PRI_NAT_DST=-100,
NF_ZP_PRI_FILTER=0,
NFIPPRINATSRC=100,
NF_:P_PRI_LAST=INT_MAX,
};
nf_hookfn*hook;為處理函數(shù)的指針,其函數(shù)指針類型定
義位于include/linux/netfilter.h,Line38,為:
typedefunsignedintnfhookfn(unsignedinthooknum,
structskbuff**skb,
conststructnet^device*in,
conststructnetdevice*out,
int(*okfn)(structskbuff*));
這是nf_hook_ops中最關(guān)鍵的組員,其五個(gè)參數(shù)分別對(duì)應(yīng)前面所解釋的NFJ100K中第2到6個(gè)參數(shù)
調(diào)用HOOK的包篩選函數(shù)必須返回特定時(shí)值,這些值以宏的形式定義于頭文獻(xiàn)
include/linux/netfilter.h41(Linel5),分別為:
NF_DROP(O):丟棄此數(shù)據(jù)報(bào),嚴(yán)禁包繼續(xù)傳遞,不進(jìn)入此后的處理流程;
NF_ACCEPT(1):接受此數(shù)據(jù)報(bào),容許包繼續(xù)傳遞,直至傳遞到鏈表最終,而進(jìn)入okfn函數(shù);
以上兩個(gè)返回值最為常見(jiàn)
NF_STOLEN(2):數(shù)據(jù)報(bào)被篩選函數(shù)截獲,嚴(yán)禁包繼續(xù)傳遞,但并不釋放數(shù)據(jù)報(bào)的資源,這個(gè)數(shù)據(jù)報(bào)
及其占有的sk_buff仍然有效(c.g.將分片的數(shù)據(jù)報(bào)一一截獲,然后將其裝配起來(lái)再進(jìn)行其他處理);
NF_QUEQUE(3):將數(shù)據(jù)報(bào)加入顧客空間隊(duì)列,使顧客空間的程序可以直接進(jìn)行處理;
在nf_hook_slow()以及nf_reinject()函數(shù)(位于net/core/netfilter.c,Line449,Line505)中,當(dāng)
由調(diào)用nf_iterate()函數(shù)(位于net/core/netfilter.c,Line339,作用為遍歷所有注冊(cè)的HOOK函數(shù),
并返回對(duì)應(yīng)的NF_XX值)而返回的verdict值為NF_QUEUE時(shí)(即目前正在執(zhí)行l(wèi)f、J這個(gè)HOOK篩選函數(shù)規(guī)
定將數(shù)據(jù)報(bào)加入顧客空間隊(duì)列),會(huì)調(diào)用nf_queue()困數(shù)(位于net/core/netfliter,c,Line407),
nfqueue。函數(shù)將這個(gè)數(shù)據(jù)報(bào)加入顧客空間隊(duì)列nfinfo(位于include/linux/netfilter.h,Line77),
并保留其設(shè)備信息以備用
NF_REPEAT(4):再次調(diào)用目前這個(gè)HOOK日勺篩選函數(shù),進(jìn)行反兔處理。
4.HOOK的注冊(cè)和注銷
HOOK注冊(cè)和注銷分別是通過(guò)nfregisterhook()函數(shù)和nfunregisterhook()函數(shù)(分別
位于net/core/netfilter.c,Line60,76)實(shí)現(xiàn)『、J,其參數(shù)均為一種nf_hookops構(gòu)造,兩者『、J實(shí)現(xiàn)也
非常簡(jiǎn)樸。
nf_register_hook()的工作是首先遍歷nf_hools[][],由HOOK的優(yōu)先級(jí)確定在HOOK鏈表中的
位置,然后坂據(jù)優(yōu)先級(jí)將該HOOK日勺nf_hook_ops加入鏈表;
nfunregisterhook()[fj工作愈加簡(jiǎn)樸,其實(shí)就是將該HOOK/、Jnfhookops從鏈表中刪除。
四、IPTables系統(tǒng)
1.表一規(guī)則系統(tǒng)
IPTables是基于Netfilter基本架構(gòu)實(shí)現(xiàn)的一種可于展H勺數(shù)據(jù)報(bào)高級(jí)管理系統(tǒng),運(yùn)用table,
chain、rule二級(jí)來(lái)存儲(chǔ)數(shù)據(jù)報(bào)的J多種規(guī)則。系統(tǒng)預(yù)定義了二個(gè)table;
filter:數(shù)據(jù)報(bào)過(guò)濾表(文獻(xiàn)net/ipv4/netfilter/iptable_filter.c)
監(jiān)聽(tīng)NF」P_LOCAL」N、NF_1P_FORWARD和NF」P_LOCAL_OUT三個(gè)HOOK,作用是在所有數(shù)據(jù)報(bào)傳遞日勺要點(diǎn)
上對(duì)其虛行過(guò)濾。
nat:網(wǎng)絡(luò)地址轉(zhuǎn)換表
監(jiān)聽(tīng)NF」P_PRE_ROUTING、NF_IP_POST_ROUTING和NF_IP_LOCAL_OUT三個(gè)HOOK,作用是當(dāng)新連接日勺第一
種數(shù)據(jù)報(bào)通過(guò)時(shí),在nat表6決定對(duì)其H勺轉(zhuǎn)換操作;相酉面的其他數(shù)據(jù)報(bào)都將根據(jù)第一種數(shù)據(jù)報(bào)H勺成果
進(jìn)行相似的轉(zhuǎn)換處理。
mangle:數(shù)據(jù)報(bào)修改表(位于net/ipv4/netfilter/iptablemangle,c)
監(jiān)聽(tīng)NF_IP_PRE_ROUTING和NF」P_LOCAL_OUT兩個(gè)HOOK,作用是修改數(shù)據(jù)報(bào)報(bào)頭中的某些值。
2.表的實(shí)現(xiàn)
表日勺基石數(shù)據(jù)構(gòu)造是ipttable(位于include/linux/netfilter_ipv4/ip_tables.h,Line413):
structipttable
structlist_headlist;//一種雙向鏈表
charname[IPTTABLEMAXNAMELEN];//被顧客空間使用的表函數(shù)的名字
structipt_replacestable;//表初始化歐I模板,定義了一種初始化用的該表口勺所默認(rèn)
的HOOK所包括的規(guī)則等信息,顧客通過(guò)系統(tǒng)調(diào)用進(jìn)行表的替代時(shí)也要用
unsignedintvalid_hooks;//表所監(jiān)聽(tīng)/、JHOOK,實(shí)質(zhì)是一種位圖
rwlock_tlock;//整個(gè)表口勺讀/寫(xiě)自旋鎖
structipt_table_info*private;//表所存儲(chǔ)的數(shù)據(jù)信息,也就是實(shí)際住)數(shù)據(jù)區(qū),僅在處
理ipt_table口勺代碼內(nèi)部使用
structmodule*me;//假如是模塊,那么取THISMODULE,否則取NULL
};
其中:
unsignedintvalid_hooks;這個(gè)位圖有兩個(gè)作用:一是檢查NetfiIter中哪些HOOK對(duì)應(yīng)著合法日勺
entries;二是用來(lái)為iptmatch以及ipttarget數(shù)據(jù)構(gòu)造中的checkentry()函數(shù)核算也許的IHOOK。
structmodule*n】e;當(dāng)取值為T(mén)HIS_MODULE時(shí),可以制止顧客rmmod一種仍然被某個(gè)規(guī)則指向的)模塊的
嘗試。
structipt.replacestable;的數(shù)據(jù)構(gòu)造是被顧客空間用來(lái)替代一種表的,其定義位于
include/linux/netfilter_ipv4/ip_tables.h,Line230:
structipt_replace
(
charname[IPT_TABLE_MAXNAMELEN];
unsignedintvalid_hooks;
unsignedintnumcntrics;//規(guī)則表入口的數(shù)量
unsignedintsize;//新的規(guī)則表的J總大小
/.Hoo.entr.points.*/
unsignedinthookentry[NF_IP_NUMHOOKS];//表所監(jiān)聽(tīng)HOOK的J規(guī)則入口,是對(duì)于cntriesE]
M扁移
unsignedintunderflow[NF_ZP_NUMHOOKS];//規(guī)則表/、J最大卜界
unsignedintnumcounters;//IH膚J計(jì)數(shù)器數(shù)目,即目前歐I舊entries隹J數(shù)目
structipt_countcrs"counters;//舊口勺計(jì)數(shù)器
structipt_entryentries[0];//規(guī)則表入口
);
上文所提到的filter,nat和mangle表分別是ipt_table這個(gè)數(shù)據(jù)構(gòu)造的三個(gè)實(shí)例:
packet_filter(位于net/ipv4/netfilter/iptable_filter.c,Line84)、
nattable(位于net/ipv4/netfi:ter/ipnatrule,c,Linel04)
packet_mangler(位于net/ipv4/netfilter/iptable_mangle.c,Linel17)
ipttableinfo(位于net/ipv4/netfilter/iptables,c,IJne86)是實(shí)際描述規(guī)則表的I數(shù)據(jù)構(gòu)造:
structipt_table_info
(
unsignedintsize;
unsignedintnumber;//表項(xiàng)的數(shù)目
unsignedintinitial_entries;//初始表項(xiàng)數(shù)目
unsignedinthook_entry[NF_IP_NUMHOOKS];//所監(jiān)聽(tīng)HOOK的規(guī)則入口
unsignedintunderflow[NF_ZP_NUMHOOKS];//規(guī)則表的J最大下界
charentries[0];//規(guī)則表入口,即真正日勺規(guī)則存儲(chǔ)構(gòu)造ipt_entry
構(gòu)成塊日勺起始地址,對(duì)多CPU,每個(gè)CPU對(duì)應(yīng)一種
};
3.規(guī)則的實(shí)現(xiàn)
IPTables中日勺規(guī)則表可以在顧客空間中使用,但它所采用的數(shù)據(jù)構(gòu)造與內(nèi)核空間中日勺是同樣的,
只不過(guò)有些組員不會(huì)在顧客空間中使用。
一種完整H勺規(guī)則由三個(gè)數(shù)據(jù)構(gòu)造共同實(shí)現(xiàn),分別是:
1個(gè)ipjentry構(gòu)造,存儲(chǔ)規(guī)則的整體信息;
0或多種ipt_entry_match構(gòu)造,寄存多種match,每個(gè)構(gòu)造都可以寄存任意日勺數(shù)據(jù),這樣也就擁有了良
好日勺可擴(kuò)展性;
1個(gè)ipt_ent門(mén)「target構(gòu)造,寄存規(guī)則日勺target,類似的,每個(gè)構(gòu)造也可以寄存任意日勺數(shù)據(jù)。
下面將依次對(duì)這三個(gè)數(shù)據(jù)構(gòu)造進(jìn)行分析:
存儲(chǔ)規(guī)則整體日勺構(gòu)造ipt_entry,其形式是一種鏈表(位于
include/1inux/netfi1ter_ipv4/iptables.h,Linel22):
structipt_entry
structipt_ipip;
unsignedintnfcache;
uint!6ttargetoffset;
uintl6tnextoffset;
unsignedintcomefrom;
structipt_counterscounters;
unsignedcharelems[0];
};
其組員如下:
structipt_ipip;:這是對(duì)其將要進(jìn)行匹配動(dòng)作日勺TP數(shù)據(jù)報(bào)報(bào)頭日勺描述,其定義于
include/linux/netfilter_ipv4/ip_tables.h,Linel22,其組員包括源/目的IIP及其掩碼,出入端口及
其掩碼,協(xié)議族、標(biāo)志/取反flag?信息。
unsignedintnfcache;:HOOK函數(shù)返回cache標(biāo)識(shí),用以闡明通過(guò)這個(gè)規(guī)則后數(shù)據(jù)報(bào)『、J狀態(tài),其也
許值有三個(gè),定義于include/linux/netfilter.h,Line23:
#defineNFC_ALTERED0x8000〃已變化
#defineNFC_UNKNOWN0x4000〃萬(wàn)確定
另一種乜許值是0,即沒(méi)有變化.
u_intl6_ttargetoffset;:指出了target日勺數(shù)據(jù)構(gòu)造ipt_cntry_targct%J起始位置,即從ipt_cntry
的起始地址到match存儲(chǔ)結(jié)束的位置
u_intl6_tncxt_offsct;:指出了整條規(guī)則的大小,也就是下一條規(guī)則H勺起始地址,即ipt_cntry的)起
始地址到match偏移再到target存儲(chǔ)結(jié)束的位置
unsignedintcomefrom;:所謂『、J"backpointer”,據(jù)引用此變量『、J代碼(重要是
net/ipv4/netfilter/ip_tables.c中)來(lái)看,它應(yīng)當(dāng)是指向數(shù)據(jù)報(bào)所經(jīng)歷『、J上一種規(guī)則地址,由此實(shí)現(xiàn)
對(duì)數(shù)據(jù)報(bào)行為的跟蹤
structipt_counterscounters;:闡明了匹配這個(gè)規(guī)則日勺數(shù)據(jù)報(bào)日勺計(jì)數(shù)以及字節(jié)計(jì)數(shù)(定義于
ine1ndp/linnx/nntfi1t.pripv4/ip_tah1PS.h,I.inpl00)
unsignedcharelems[0];:表達(dá)擴(kuò)展的malch開(kāi)始口勺詳細(xì)位置(由于它是大小不確定的),當(dāng)然,假如
不存在擴(kuò)展的Imatch那么就是target日勺開(kāi)始位置
擴(kuò)展match日勺存儲(chǔ)構(gòu)造ipt_entry_match,位于include/linux/netfilter_ipv4/ip_tables.h,Line48:
structiptentrymatch
(
union{
struct{
uintl6tmatchsize;
charname[IPT_FUNCT:ON^MAXNAMELEN];
}user;
struct{
u_intl6_tmatch_size;
structipt_match*match;
}kernel;
u_intl6_tmatch_size;//總長(zhǎng)度
}u:
unsignedchardata[0];
);
其中描述match大小的match_size;',從波及這個(gè)變量日勺源碼看來(lái),在使用H勺時(shí)候需要
注意使月一種宏IPT_ALIGN(位于includc/linux/netfiltcr_ipv4/ip_tables.h,Linc445)來(lái)進(jìn)行4
的對(duì)齊處理(0x3&Oxfffffffc),這應(yīng)當(dāng)是由于match、target擴(kuò)展后大小的不確定性決定的J。
在構(gòu)造中,顧客空間與內(nèi)核空間為不一樣的J實(shí)現(xiàn),內(nèi)核空間中的描述擁有更多歐J信息。在顧客空間
中寄存的僅僅是match日勺名稱,而在內(nèi)核空間中寄存的則是一種指向iptjnatch構(gòu)造的指針
構(gòu)造ipt_match位于include/linux/netfilter_ipv4/ip_tables.h,Line342:
structiptjnatch
structlistheadlist;
constcharname[IPTFUNCTION_MAXNAMELEN];
int(*match)(conststructskbuff*skb,
conststructnetdevice*in,
conststructnetdevice*out,
constvoid*matchinfo,//指向規(guī)則中match數(shù)據(jù)的指針,詳細(xì)是什么數(shù)據(jù)構(gòu)造依狀
況而定
intoffset,//TP數(shù)據(jù)報(bào)的偏移
constvoid*hdr,//指向協(xié)議頭口勺指針
u_intl6_tdatalen,//實(shí)際數(shù)據(jù)長(zhǎng)度,即數(shù)據(jù)報(bào)長(zhǎng)度TP頭長(zhǎng)度
int*hotdrop);
int(*checkentry)(constchar*tablename,//可用口勺表
conststructipt_ip*ip,
void*matchinfo,
unsignedintmatchinfosize,
unsignedinthookmask);//對(duì)應(yīng)HOOKH勺位圖
void("destroy)(void*matchinfo,unsignedintmatchinfosize);
structmodule
);
其中幾種重要組員:
int(*match)(....);:指向用該natch進(jìn)行匹配時(shí)『、J匹配函數(shù)的指針,match有關(guān)的J關(guān)鍵實(shí)現(xiàn)。返回0
時(shí)hotdrop置1,立即丟棄數(shù)據(jù)報(bào);返回非0表達(dá)匹配成功。
int(*checkentry)(....);:當(dāng)試圖插入新的Imatch表項(xiàng)時(shí)調(diào)用這個(gè)指針?biāo)赶虻膢函數(shù),對(duì)新的Jmatch
表項(xiàng)進(jìn)行有效性檢查,即檢查參數(shù)與否合法;假如返回false,規(guī)則就不會(huì)被接受(譬如,一種TCP的
match只會(huì)TCP包,而不會(huì)接受其他)。
void("destroy)(....);:當(dāng)試圖刪除一種使用這個(gè)match日勺表項(xiàng)時(shí),即模塊釋放時(shí),調(diào)用這個(gè)指針?biāo)?/p>
指向的函數(shù)。我們可以在checkentry中動(dòng)態(tài)地分派資源,并在destroy中將其釋放。
擴(kuò)展target的J存儲(chǔ)構(gòu)造ipt_entry_target,位于include/linux/netfilter_ipv4/ip_tables.h,
Line71,這個(gè)構(gòu)造與ipt_entrymatch構(gòu)造類似。
同步其中描述內(nèi)核空間target時(shí)構(gòu)造ipt_target(位于include/linux/netfilter_ipv4/ip_tables.h,
Line375)也與ipt_match類似,只不過(guò)其中口勺target()函數(shù)返回值不是0/1,而是verdict。
而target的實(shí)際使用中,是用一種構(gòu)造ipt_standard_target專門(mén)來(lái)描述,這才是實(shí)際的target
描述數(shù)據(jù)構(gòu)造(位于include/1inux/netfilter_ipv4/ip_tables.h,Line94),它實(shí)際上就是一種
ipt_entry_target力口——種verdict。
其中組員verdict這個(gè)變量是一種很巧妙的設(shè)計(jì),也是一種非常重要的東東,其值日勺正負(fù)有著不一樣的
意義.我沒(méi)有找到這個(gè)變量H勺中文名稱,在內(nèi)核開(kāi)發(fā)者日勺新聞組中稱這個(gè)變量為“amagicnumberL它
時(shí)也許值包括IPT_C0NTINUE>IPT_RETURN以及前文所述的INF_DR0P等值,那么它日勺作月是什么呢?
由于IPTablcs是在顧客空間中執(zhí)行的,也就是說(shuō)Nctfiltcr/IPTablcs這個(gè)框架需要顧客態(tài)與內(nèi)核態(tài)之
間日勺數(shù)據(jù)互換以及識(shí)別。而在詳細(xì)日勺程序中,verdict作為'structipt_standard_target'及J一種組員,
也是對(duì)于struclipt_entrytarget'中口勺target()函數(shù)Rj返回值。這個(gè)返回值標(biāo)識(shí)的是target()所對(duì)
應(yīng)日勺執(zhí)行動(dòng)作,包括系統(tǒng)的I默認(rèn)動(dòng)作以及外部提交的自定義動(dòng)作。
不過(guò),在顧客空間中提交的I數(shù)據(jù)往往是類似于“ACCPET”之類的I字符串,在程序處理時(shí)則是以^define
NF_ACCEPT1'日勺形式來(lái)進(jìn)行的;而實(shí)際上,以上那些執(zhí)行動(dòng)作是以鏈表H勺數(shù)據(jù)構(gòu)造進(jìn)行存儲(chǔ)H勺,在內(nèi)核
空間中體現(xiàn)為偏移。
于是,verdict實(shí)際上描述了兩個(gè)本質(zhì)相似但實(shí)現(xiàn)不一樣的值:一種是顧客空間中的執(zhí)行動(dòng)作,另一種
則是內(nèi)核空間中在鏈表中的偏移一而這就出現(xiàn)了沖突。
處理這種沖突日勺措施就是:用正值表達(dá)內(nèi)核中歐I偏移,而用負(fù)值來(lái)表達(dá)數(shù)據(jù)報(bào)歐I那些默認(rèn)動(dòng)作,而外部
提交的自定義動(dòng)作則也是用正值來(lái)表達(dá)。這樣,在實(shí)際使用這個(gè)verdict時(shí),我們就可以通過(guò)判斷值的
正負(fù)來(lái)進(jìn)行對(duì)應(yīng)時(shí)處理了。
位于net/ipv4/netfilter/ip_tables.h中的)函數(shù)ipt_do_table()中有一種經(jīng)典的verdict使用
(Line335,其中v是一種verdict歐J實(shí)例):
if(v!=IPT_RETURN){
verdict=(unsigned)(-v)-1;
break;
其中MJTT其TURN定義為:
SdefineTPTRETURN(-NFMAXVERDICT-1)
而宏NF_MAX_VERDICT實(shí)際上就是:
#defineNF_MAX_VERDICTNF_REPEAT
這樣,實(shí)際上TPTRETURN口勺值就是-NFREPEAT7,也就是對(duì)應(yīng)REPEAT,這就是對(duì)執(zhí)行動(dòng)作的實(shí)際
描述;而我們可以看到,在下面對(duì)verdict進(jìn)行賦值時(shí),它所使用日勺值是'(unsigned)(-v)-1',這就
是在內(nèi)核中實(shí)際對(duì)偏移進(jìn)行定位時(shí)所使用的值。
那么總之呢,表和規(guī)則的實(shí)現(xiàn)如圖所示:
圖6.表和規(guī)則的實(shí)現(xiàn)
從上圖中不難發(fā)現(xiàn),match的)定位如下:
起始地址為:目前規(guī)則(起始)地址+sizeof(structipt_entry);
結(jié)束地址為:目前規(guī)則(起始)地址+ipt_entry->target_offset;
每一種natch日勺大小為:ipt_entry_match->u.matchesizeo
target的定位則為:
起始地址為match日勺結(jié)束地址,即:目前規(guī)則(起始)地址一ipt_entry->target_offset;
結(jié)束地址為下一條規(guī)則日勺起始地址,即:目前規(guī)則(起始)地址+ipt_entry->next_offset;
每一種target的大小為:iptentrytarget->u.targetsize。
這些對(duì)于理解match以及target有關(guān)函數(shù)的實(shí)現(xiàn)是很有必要明確H勺。
同步,include/linux/netfilter_ipv4/ip_tables.h中提供了三個(gè)"helperfunctions”,可用于
使對(duì)于entry、tartget和matchH勺操作變得以便,分別是:
函數(shù)ipt_get_target():Line274,作用是獲得target日勺起始地址,也就是上面所說(shuō)的目前規(guī)則(起始)
地址+iptentry->targetoffset;
宏中1'_"八花也"£1^^():小區(qū)28:,作用是遍歷規(guī)則的所有g(shù)1:2,并執(zhí)行同一種(參數(shù)中)給定的函
數(shù)。其參數(shù)為一種ipt_entry_match構(gòu)造和一種函數(shù),以及函數(shù)需要時(shí)參數(shù)。當(dāng)返回值為0時(shí),表達(dá)遍
歷以及函數(shù)執(zhí)行順利完畢;返回非。值時(shí)則意味著出現(xiàn)問(wèn)題已終止。
宏小丁_£皿^丫」丁£!^^():一區(qū)300,作用是遍歷一種表中的)所有規(guī)則,并執(zhí)行同一種給定的函數(shù)。其參
數(shù)為一種ipl_enlry構(gòu)造、整個(gè)規(guī)則表口勺大小,以及一種函數(shù)和其所需參數(shù)。其返回值的意義與宏
IPT_MATCH_ITERATE()類似。
那么怎樣保證傳入日勺ipt_entry構(gòu)造是整個(gè)規(guī)則表歐I第一種構(gòu)造呢?據(jù)源碼看來(lái),實(shí)際調(diào)用這個(gè)宏的
時(shí)候傳入的第一種參數(shù)都是某個(gè)ipt_table_info構(gòu)造的實(shí)例所指向的entries組員,這樣就保證了對(duì)整
個(gè)規(guī)則表的完整遍歷。
4.規(guī)則的使用
當(dāng)一種特定的HOOK被激活時(shí),數(shù)據(jù)報(bào)就開(kāi)始進(jìn)入Netfilter/TPTables系統(tǒng)進(jìn)行遍歷,首先檢卷
'structipt_ipip',然后數(shù)據(jù)報(bào)將依次遍歷各個(gè)match,乜就是'structipt_entry_match',并執(zhí)行
對(duì)應(yīng)的match函數(shù),即ipt_match構(gòu)造中區(qū)|*match所指向H勺函數(shù)。當(dāng)match函數(shù)匹配不成功時(shí)返回0,或
者h(yuǎn)otdrop被置為1時(shí),遍歷將會(huì)停止。
對(duì)natch/、J遍歷完畢后,會(huì)開(kāi)始檢查'structipt_entry_targct',其中假如是一種原則『、Jtarget,
那么會(huì)檢查'structipt_standard_target'中的Jverdict,假如verdict值是正歐I而偏移卻指向不對(duì)的
的位置,那么ipl_entry中的comefrom組員就有了用武之地一一數(shù)據(jù)報(bào)返回所經(jīng)歷的上一種規(guī)則。對(duì)于
非原則日勺target呢,就會(huì)調(diào)用target()函數(shù),然后根據(jù)其返回值進(jìn)行背面日勺處理。
5.規(guī)則的擴(kuò)展
Netfilter/IPTables提供了對(duì)規(guī)則進(jìn)行擴(kuò)展日勺機(jī)制:可以寫(xiě)一種LKM來(lái)擴(kuò)展內(nèi)核空間的功能,
也可以寫(xiě)一種共享庫(kù)來(lái)擴(kuò)展顧客空間中IPTables曰勺功能。
內(nèi)核H勺擴(kuò)展
要對(duì)內(nèi)核空間口勺功能進(jìn)行擴(kuò)展,實(shí)際上就是寫(xiě)一種具有表、match以及target增長(zhǎng)功能口勺模塊,有
關(guān)日勺函數(shù)為(位于net/ipv4/netf[lter/ip_tables.c,Linel318to1444):
ipt_register_table()>ipt_unregister_table(),參數(shù)為structipt_table*。
ipt_register_table()函數(shù)是這三對(duì)函數(shù)中最復(fù)雜的一種,波及了內(nèi)存、信號(hào)量等方方面面口勺東西,但
總起來(lái)說(shuō)就做了初始化表以及加入雙向鏈表兩件事。
其復(fù)雜一是由于波及到多CPU的處理(每個(gè)CPU擁有各自獨(dú)立的“規(guī)則空間”),需要首先將新日勺entries
放入第一種CPU空間,在檢查完畢后再?gòu)?fù)制到其他CPU中;二是就是上面所說(shuō)對(duì)新tab*各個(gè)entry的
檢查,包括邊界檢查以及完整性檢查等。
其中的重要函數(shù)有這樣幾種:
translate_table()(位于net/ipv4/netfilter/ip_tables.c,Line797):這個(gè)函數(shù)聆)重要作用是檢查
并應(yīng)用顧容空間傳來(lái)的規(guī)則:
對(duì)新表進(jìn)行邊界檢查(由宏1PT_ENTRY_ITERATE()調(diào)用函數(shù)check_entry_size_and_Dlocks(),位于
net/ipv4/netfilter/iptables.c,Line732),包括對(duì)齊、過(guò)大過(guò)小等,尤其是保證賦給hookentries
和underflows值日勺對(duì)歐I性。
調(diào)用函數(shù)make_source_chains()(位于net/ipv4/netfilter/ip_tables.c,Line499)檢查新歐I表中與
否存在規(guī)則環(huán),同步將HOOKH勺規(guī)則遍歷次序存入comefrom變量。(這個(gè)函數(shù)我沒(méi)有仔細(xì)看,只是大概略
了一下)
對(duì)ipt_entry依次進(jìn)行ipt_ip頭、match以及target的完整性檢查(由宏IPT_ENTRY」TERATE()調(diào)用函
數(shù)check_entry(),位于net/ipv4/netfilter/ip_tables.c,Line676),保證ipt_entry對(duì)時(shí)性。
將龍?日勺的ipt_tablcs復(fù)制給其他的CPU。
這個(gè)函數(shù)此外還在do_replace()函數(shù)(僅在一種源碼中沒(méi)有被調(diào)用過(guò)H勺函數(shù)中被調(diào)用,不予分析)中被
調(diào)用。
replacetable0(位于net/ipv4/netfilter/iptables.c,Line877):這個(gè)函數(shù)的J重要作用是:將得
到模塊初始值日勺ipt_table_info構(gòu)造(newinfo)中日勺值傳給ipt_table中歐)private,并返回ip_table
中舊aJprivate0
list_prepend()(位于include/linux/netfilter_ipv4/listhelp.h,Line75):在這個(gè)函數(shù)被調(diào)用之
前,火人初始化的過(guò)程就已經(jīng)結(jié)束了,這個(gè)函數(shù)『、金要作用是:互斥地調(diào)用Linux源碼中的list_add()
函數(shù)(位于include/linux/list.h,Line55),將新的Itable加入到雙向鏈表之中。
ipt_registerjnatch()>ipt_unregister_match(),參數(shù)為structipt_match*。
ipt_registertarget()Nipt_unregistertarget(),參數(shù)為structipt_target*0
這三對(duì)函數(shù)除了ipt_register_table()外的5個(gè)函數(shù)重要就是互斥地將table/match/target加入
到雙向鏈表中或者從雙向鏈表中刪除。
其中向雙向鏈表中加入新節(jié)點(diǎn)是通過(guò)調(diào)用list_named_inscrt()函數(shù)(位于
include/linux/netfilter_ipv4/listhelp.h,LinelOl)實(shí)現(xiàn)的I。這個(gè)函數(shù)H勺重要工作是首先確定待插
入的match名字與否已經(jīng)加在,只有不存在時(shí)才進(jìn)行插入的操作。
顧客空間口勺擴(kuò)展
顧客空間中的擴(kuò)展用的是共享庫(kù)配合libiptc庫(kù)的機(jī)制,但這種機(jī)制是在單獨(dú)日勺IPTbales程序中提
供日勺,內(nèi)核源碼中并沒(méi)有提供,這里就不做分析了。
五、數(shù)據(jù)報(bào)過(guò)濾模塊一一filter表
1.概述
filter表日勺功能僅僅是本數(shù)據(jù)報(bào)進(jìn)行過(guò)濾,并不對(duì)數(shù)據(jù)報(bào)進(jìn)行任何日勺修改。
filter模塊在Netfilter中是基于下列HOOK點(diǎn)的J:
NF_IP_LOCAL_IN
NF_IP_FORWARD
NF_IP_LOCAL_OUT
這幾種HOOK分別對(duì)應(yīng)著filter表中的INPUT>FORWARD.OUTPUT三條規(guī)則鏈,對(duì)于任何一種數(shù)
據(jù)報(bào)都會(huì)通過(guò)這3個(gè)HOOK之一。
filter模塊的I接口位于文獻(xiàn)net/ipv4/netfilter/iptables_filter.c中。
2.filter表的定義和初始化
filter表是前面所述數(shù)據(jù)構(gòu)造ipt_tablc的一種實(shí)例,它的定義和初始化位于
net/ipv4/netfilter/iptable_fiIter,c,Line84:
staticstructipt_tablepacket_filter={
{NULL,NULL),
&initial_table.repl,//對(duì)應(yīng)replace數(shù)據(jù)構(gòu)造
FILTER_VALID_HOOKS,
RW_LOCK_UNLOCKED,
NULL,//對(duì)應(yīng)private數(shù)據(jù)構(gòu)造
THISMODULE
};
對(duì)照構(gòu)造ipt_table的定義,我們可以發(fā)現(xiàn),filter表日勺初始化數(shù)據(jù)為:
鏈表初始化為空
表名為filter
初始化日勺模板為&init:al_table.repl:
初始化的模板表定義于net/ipv4/netfi1ter/iptable_fi1ter.c,Line30,是一種很簡(jiǎn)樸日勺數(shù)據(jù)構(gòu)造,
只是賦值有些復(fù)雜,由于要對(duì)所波及的各個(gè)HOOK進(jìn)行示一樣日勺處理:
staticstruct
(
structipt_replacerepl;
structipt_standardentries[3];
structipt_errorterm;
}initial_table={
//對(duì)構(gòu)造structipt_replacerepl;初始化
{“filter”,
FILTER_VAL1D_HOOKS,
4,
sizeof(structipt_standard)*3+sizeof(structipt_error),
{[NF_IP_LOCAL_IN]0,
[NF_IP_FORWARD]sizeof(structipt_standard),
[NF_IP_LOCAL_OUT]sizeof(structipt_standard)*2
{[NFIPLOCALIN]0,
[NFIPFORWARD]sizeof(structiptstandard;,
[NF_IPLOCALOUT]sizeof(structipt_standard)*2
},
0,
NULL,
(}
},
//對(duì)構(gòu)造structiptstandardentries[。];初始化
(
/*LOCAL_IN*/
{0},
{0},
{0},
{0},
〃〃
X*A*
{0},
{0},
0,
0,
0
),
0,
sizeof(structiptentry),
sizeof(structiptstandard),
0,
{0,0},
(}
),
iptALIGN(sizeof(structiptstandardtarget)),
()
),
-NH_ACCEET-1
)
},
//對(duì)構(gòu)造structipt_standardentries[l];初始化
/*FORWARD*/
{{{{0},{0},{0},{0},〃〃,〃〃,{0},{0},0,0,0},
0,
sizeof(structipt_entry),
sizeof(structiptstandard),
0,{0,0},{1},
{{{{iptALIGN(sizeof(structiptstandardtarget)),〃〃}},{}},
-NF_ACCEPT-1)},
//對(duì)構(gòu)造structipt_standardentries[2];初始化
/*L0CAL_0UT*/
{{{{0},{0},{0},{0},”,〃〃,{0},{0},0,0,0},
0,
sizeof(structipt_entry),
sizeof(structipt_standard),
0,{0,0},{}},
{{{{ipt_ALIGN(sizeof(structipt_standard_target)),〃”}},{}},
-NF_ACCEPT-1)}
),
//對(duì)構(gòu)造structipt_errortern;初始化
/*ERROR*/
{{{{0},{0},{0},{0},〃〃,〃〃,{0},{0},0,0,0},
0,
sizeof(structipt_entry),
sizeof(structipterror),
0,{0,0},{1},
{{{{ipt_ALIGN(sizeof(structipt_error_target)),ipt_ERRORTARGET}),
{)},
“ERROR”
}
}
1:
我們可以看到,一種initial_table包括三個(gè)組員:
structipt_replacercpl;:是對(duì)一種表進(jìn)行初始化的I最重要
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 網(wǎng)外包合同范本
- 切割機(jī)合同協(xié)議書(shū)
- 社聯(lián)助理協(xié)議書(shū)
- 正規(guī)破產(chǎn)協(xié)議書(shū)
- 員工擔(dān)保人協(xié)議書(shū)
- 聘用解約協(xié)議書(shū)
- 商場(chǎng)用地合同范本
- 自動(dòng)磨光協(xié)議書(shū)
- 研學(xué)訓(xùn)練協(xié)議書(shū)
- 細(xì)胞采集協(xié)議書(shū)
- 初二勞技試題及答案上冊(cè)
- 員工宿舍分配管理制度
- 話劇社團(tuán)筆試題及答案解析
- 2025《安全生產(chǎn)法》培訓(xùn)課件
- 網(wǎng)絡(luò)安全意識(shí)提升培訓(xùn)課件
- 專業(yè)倫理與職業(yè)素養(yǎng)-計(jì)算機(jī)、大數(shù)據(jù)與人工智能課件:計(jì)算的學(xué)科與職業(yè)
- 《機(jī)器人用力觸覺(jué)傳感器分級(jí)規(guī)范》
- 兒童心理健康教育的實(shí)施策略
- 鋼軌探傷鋼軌探傷試塊課件
- 監(jiān)理單位工程項(xiàng)目廉潔教育
- 頸椎病的中醫(yī)診治課件
評(píng)論
0/150
提交評(píng)論