- 論壇徽章:
- 0
|
前一段時間看到這篇帖子,確實很經(jīng)典,于是翻出了英文原版再讀,順便再翻譯出來供大家學(xué)習(xí),這篇文章的中文版也早都有了,不過出于完全理解的目的,我還是將它翻譯了出來,加進了自己的代碼,雖然在上一周的翻譯過程中,我盡量保留文章的原汁原味,但錯誤肯定在所難免,在末尾附上原文和我自己調(diào)試通過的代碼,已經(jīng)夠構(gòu)運行,大家可以參考一下。ㄓ绣e誤之處請指出)
深入Linux內(nèi)核網(wǎng)絡(luò)堆棧
作者:bioforge alkerr@yifan.net
原名: <<Hacking the Linux Kernel Network Stack>>
翻譯,修改: duanjigang <duanjigang1983@126.com>
翻譯參考:raodan (raod_at_30san.com) 2003-08-22
第一章 簡介
本文將描述如何利用Linux網(wǎng)絡(luò)堆棧的竅門(不一定都是漏洞)來達到一些目的,或者是惡意的,或者是出于其它意圖的。文中會就后門通訊對Netfilter鉤子進行討論,并在本地機器上實現(xiàn)將這個傳輸從基于Libpcap的嗅探器(sniffer)中隱藏。
Netfilter是2.4內(nèi)核的一個子系統(tǒng)。Netfilter可以通過在內(nèi)核的網(wǎng)絡(luò)代碼中使用各種鉤子來實現(xiàn)數(shù)據(jù)包過濾,網(wǎng)絡(luò)地址轉(zhuǎn)換(NAT)和連接跟蹤等網(wǎng)絡(luò)欺騙。這些鉤子被放置在內(nèi)核代碼段,或者靜態(tài)編譯進內(nèi)核,或者作為一個可動態(tài)加載/卸載的可卸載模塊,然后就可以注冊稱之為網(wǎng)絡(luò)事件的函數(shù)(比如數(shù)據(jù)包的接收)。
1.1 本文論述的內(nèi)容
本文將講述內(nèi)核模塊的編寫者如何利用Netfilter的鉤子來達到任何目的,以及怎樣將網(wǎng)絡(luò)傳輸從一個Libpcap的應(yīng)用中隱藏掉。盡管Linux2.4支持對IPV4,IPV6以及DECnet的鉤子,本文只提及IPV4的鉤子。但是,對IPV4的大多數(shù)應(yīng)用內(nèi)容同樣也可以應(yīng)用于其他協(xié)議。出于教學(xué)目的,我們在附錄A給出了一個可以工作的內(nèi)核模塊,實現(xiàn)基本的數(shù)據(jù)包過濾功能。針對本文中所列技術(shù)的所有開發(fā)和試驗都在Intel機子上的Linux2.4.5系統(tǒng)上進行過。對Netfilte 鉤子行為的測試使用的是回環(huán)設(shè)備(Loopback device),以太網(wǎng)設(shè)備和一個點對點接口的調(diào)制解調(diào)器。
對Netfilter進行完全理解是我撰寫本文的另一個初衷。我不能保證這篇文章所附的代碼100%的沒有差錯,但是所列舉的所有代碼我都事先測試過了。我已經(jīng)飽嘗了內(nèi)核錯誤帶來的磨礪,而你卻不必再經(jīng)受這些。同樣,我不會為按照這篇文檔所說的任何東西進行的作所所為帶來的損失而負責(zé)。閱讀本篇文章的讀者最好熟悉C程序設(shè)計語言,并且對內(nèi)核可卸載模塊有一定的經(jīng)驗。
如果我在文中犯了任何錯誤的話,請告知我。我對于你們的建議和針對此文的改進或者其它的Netfilter應(yīng)用會傾心接受。
1.2 本文不會涉及到的方面
本文并不是Netfilter的完全貫穿(或者進進出出的講解)。也不是iptables命令的介紹。如果你想更好的學(xué)習(xí)iptables的命令,可以去咨詢man手冊。
讓我們從介紹Nerfilter的使用開始吧……….
第二章 各種NetFilter 鉤子及其用法
2.1 Linux內(nèi)核對數(shù)據(jù)包的處理
我將盡最大努力去分析內(nèi)核處理數(shù)據(jù)包的詳細內(nèi)幕,然而對于事件觸發(fā)處理以及之后的Netfilter 鉤子不做介紹。原因很簡單,因為Harald Welte 關(guān)于這個已經(jīng)寫了一篇再好不過的文章<<Journey of a Packet Through the Linux 2.4 Network Stack>>,如果你想獲取更多關(guān)于Linux對數(shù)據(jù)包的相關(guān)處理知識的話,我強烈建議你也閱讀一下這篇文章。目前,就認為數(shù)據(jù)包只是經(jīng)過了Linux內(nèi)核的網(wǎng)絡(luò)堆棧,它穿過幾層鉤子,在經(jīng)過這些鉤子時,數(shù)據(jù)包被解析,保留或者丟棄。這就是所謂的Netfilter 鉤子。
2.2 Ipv4中的Netfilter鉤子
Netfilter為IPV4定義了5個鉤子?梢栽 linux/netfilter-ipv4.h里面找到這些符號的定義,表2.1列出了這些鉤子。
表 2.1. ipv4中定義的鉤子
- 鉤子名稱 調(diào)用時機
- NF_IP_PRE_ROUTING 完整性校驗之后,路由決策之前
- NF_IP_LOCAL_IN 目的地為本機,路由決策之后
- NF_IP_FORWARD 數(shù)據(jù)包要到達另外一個接口去
- NF_IP_LOCAL_OUT 本地進程的數(shù)據(jù),發(fā)送出去的過程中
- NF_IP_POST_ROUTING 向外流出的數(shù)據(jù)上線之前
復(fù)制代碼
NF_IP_PRE_ROUTING 鉤子稱為是數(shù)據(jù)包接收后第一個調(diào)用的鉤子程序,這個鉤子在我們后面提到的模塊當(dāng)中將會被用到。其他的鉤子也很重要,但是目前我們只集中探討NF_IP_PRE_ROUTING這個鉤子。
不管鉤子函數(shù)對數(shù)據(jù)包做了哪些處理,它都必須返回表2.2中的一個預(yù)定義好的Netfilter返回碼。
表2.2 Netfilter 返回碼
- 返回碼 含義
- NF_DROP 丟棄這個數(shù)據(jù)包
- NF_ACCEPT 保留這個數(shù)據(jù)包
- NF_STOLEN 忘掉這個數(shù)據(jù)包
- NF_QUEUE 讓這個數(shù)據(jù)包在用戶空間排隊
- NF_REPEAT 再次調(diào)用這個鉤子函數(shù)
復(fù)制代碼
NF_DROP 表示要丟棄這個數(shù)據(jù)包,并且為這個數(shù)據(jù)包申請的所有資源都要得到釋放。NF_ACCEPT告訴Netfilter到目前為止,這個數(shù)據(jù)包仍然可以被接受,應(yīng)該將它移到網(wǎng)絡(luò)堆棧的下一層。NF_STOLEN是非常有趣的一個返回碼,它告訴Netfilter讓其忘掉這個數(shù)據(jù)包。也就是說鉤子函數(shù)會在這里對這個數(shù)據(jù)包進行完全的處理,而Netfilter就應(yīng)該放棄任何對它的處理了。然而這并不意味著為該數(shù)據(jù)包申請的所有資源都要釋放掉。這個數(shù)據(jù)包和它各自的sk_buff結(jié)構(gòu)體依然有效,只是鉤子函數(shù)從Netfilter奪取了對這個數(shù)據(jù)包的掌控權(quán)。不幸的是,我對于NF_QUEUE這個返回碼的真實作用還不是很清楚,所在目前不對它進行討論。最后一個返回值NF_REPEAT請求Netfilter再次調(diào)用這個鉤子函數(shù),很明顯,你應(yīng)該慎重的應(yīng)用這個返回值,以免程序陷入死循環(huán)。
第三章 注冊和注銷NetFilter 鉤子
注冊一個鉤子函數(shù)是一個圍繞nf_hook_ops結(jié)構(gòu)體的很簡單的過程,在linux/netfilter.h中有這個結(jié)構(gòu)體的定義,定義如下:
- struct nf_hook_ops
- {
- struct list_head list;
- /* User fills in from here down. */
- nf_hookfn *hook;
- int pf;
- int hooknum;
- /* Hooks are ordered in ascending priority. */
- int priority;
- };
復(fù)制代碼
這個結(jié)構(gòu)體的成員列表主要是用來維護注冊的鉤子函數(shù)列表的,對于用戶來說,在注冊時并沒有多么重要。hook是指向nf_hookfn函數(shù)的指針。也就是為這個鉤子將要調(diào)用的所有函數(shù)。nf_hookfn同樣定義在linux/netfilter.h這個文件中。pf字段指定了協(xié)議簇(protocol family)。Linux/socket.h中定義了可用的協(xié)議簇。但是對于IPV4我們只使用PF_INET。hooknum 域指名了為哪個特殊的鉤子安裝這個函數(shù),也就是表2.1中所列出的條目中的一個。Priority域表示在運行時這個鉤子函數(shù)執(zhí)行的順序。為了演示例子模塊,我們選擇NF_IP_PRI_FIRST這個優(yōu)先級。
注冊一個Netfilter鉤子要用到nf_hook_ops這個結(jié)構(gòu)體和nf_register_hook()函數(shù)。nf_register_hook()函數(shù)以一個nf_hook_ops結(jié)構(gòu)體的地址作為參數(shù),返回一個整型值。如果你閱讀了net/core/netfilter.c中nf_register_鉤子()的源代碼的話,你就會發(fā)現(xiàn)這個函數(shù)只返回了一個0。下面這個例子注冊了一個丟棄所有進入的數(shù)據(jù)包的函數(shù)。這段代碼同時會向你演示Netfilter的返回值是如何被解析的。
代碼列表1. Netfilter鉤子的注冊
- /* Sample code to install a Netfilter hook function that will
- * drop all incoming packets. */
- #define __KERNEL__
- #define MODULE
- #include <linux/module.h>
- #include <linux/kernel.h>
- #include <linux/netfilter.h>
- #include <linux/netfilter_ipv4.h>
- /* This is the structure we shall use to register our function */
- static struct nf_hook_ops nfho;
- /* This is the hook function itself */
- unsigned int hook_func(unsigned int hooknum,
- struct sk_buff **skb,
- const struct net_device *in,
- const struct net_device *out,
- int (*okfn)(struct sk_buff *))
- {
- return NF_DROP; /* Drop ALL packets */
- }
- /* Initialisation routine */
- int init_module()
- {
- /* Fill in our hook structure */
- nfho.hook = hook_func; /* Handler function */
- nfho.hooknum = NF_IP_PRE_ROUTING; /* First hook for IPv4 */
- nfho.pf = PF_INET;
- nfho.priority = NF_IP_PRI_FIRST; /* Make our function first */
- nf_register_hook(&nfho);
- return 0;
- }
- /* Cleanup routine */
- void cleanup_module()
- {
- nf_unregister_hook(&nfho);
- }
復(fù)制代碼
這就是注冊所要做的一切。從代碼列表1你可以看到注銷一個Netfilter鉤子也是很簡單的一件事情,只需要調(diào)用nf_unregister_hook()函數(shù),并將注冊時用到的結(jié)構(gòu)體地址再次作為注銷函數(shù)參數(shù)使用就可以了。
第四章 基本的NetFilter數(shù)據(jù)包過濾技術(shù)
4.1 鉤子函數(shù)近距離接觸
現(xiàn)在是我們來查看獲得的數(shù)據(jù)如何傳入鉤子函數(shù)并被用來進行過濾決策的時候了。所以,我們需要更多的關(guān)注于nf_hookfn函數(shù)的模型。Linux/netfilter.h給出了如下的接口定義:
- 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 *));
復(fù)制代碼
nf_hookfn函數(shù)的第一個參數(shù)指定了表2.1給出的鉤子類型中的一種。第二個參數(shù)更有趣,它是一個指向指針(這個指針指向一個sk_buff類型的結(jié)構(gòu)體)的指針,它是網(wǎng)絡(luò)堆棧用來描述數(shù)據(jù)包的結(jié)構(gòu)體。這個結(jié)構(gòu)體定義在linux/skbuff.h中,由于這個結(jié)構(gòu)體的定義很大,這里我只著重于它當(dāng)中更有趣的一些域。
或許sk_buff結(jié)構(gòu)體中最有用的域就是其中的三個聯(lián)合了,這三個聯(lián)合描述了傳輸層的頭信息(例如 UDP,TCP,ICMP,SPX),網(wǎng)絡(luò)層的頭信息(例如ipv4/6, IPX, RAW)和鏈路層的頭信息(Ethernet 或者RAW)。三個聯(lián)合相應(yīng)的名字分別為:h,nh和mac。根據(jù)特定數(shù)據(jù)包使用的不同協(xié)議,這些聯(lián)合包含了不同的結(jié)構(gòu)體。應(yīng)當(dāng)注意,傳輸層的頭和網(wǎng)絡(luò)層的頭極有可能在內(nèi)存中指向相同的內(nèi)存單元。在TCP數(shù)據(jù)包中也是這樣的情況,h和nh都是指向IP頭結(jié)構(gòu)體的指針。這就意味著,如果認為h->th指向TCP頭,從而想通過h->th來獲取一個值的話,將會導(dǎo)致錯誤發(fā)生。因為h->th實際指向IP頭,等同于nh->iph。
其他比較有趣的域就是len域和data域了。len表示包中從data開始的數(shù)據(jù)總長度。因此,現(xiàn)在我們就知道如何通過一個skbuff結(jié)構(gòu)體去訪問單個的協(xié)議頭或者數(shù)據(jù)包本身的數(shù)據(jù)。還有什么有趣的數(shù)據(jù)位對于Netfilter的鉤子函數(shù)而言是有用的呢?
跟在sk_buff之后的兩個參數(shù)都是指向net_device結(jié)構(gòu)體的指針。net_devices結(jié)構(gòu)體是Linux內(nèi)核用來描述各種網(wǎng)絡(luò)接口的。第一個結(jié)構(gòu)體,in,代表了數(shù)據(jù)包將要到達的接口,當(dāng)然 out就代表了數(shù)據(jù)包將要離開的接口。有很重要的一點必須認識到,那就是通常情況下這兩個參數(shù)最多只提供一個。 例如,in通常情況下只會被提供給NF_IP_PRE_ROUTING和NF_IP_LOCAL_IN鉤子。out通常只被提供給NF_IP_LOCAL_OUT和NF_IP_POST_ROUTING鉤子。在這個階段,我沒有測試他們中的那個對于NF_IP_FORWARD是可用的。如果你能在廢棄之前確認它們(in和out)不空的話,那么你很優(yōu)秀。
最后,傳給鉤子函數(shù)的最后一個參數(shù)是一個名為okfn的指向函數(shù)的指針,這個函數(shù)有一個sk_buff的結(jié)構(gòu)體作為參數(shù),返回一個整型值。我也不能確定這個函數(shù)做什么,在net/core/netfilter.c中有兩處對此函數(shù)的調(diào)用。這兩處調(diào)用就是在函數(shù)nf_hook_slow()和函數(shù)nf_reinject()里,在這兩個調(diào)用處當(dāng)Netfilter鉤子的返回值為NF_ACCEPT時,此函數(shù)被調(diào)用。如果有誰知道關(guān)于okfn更詳細的信息,請告訴我。
現(xiàn)在我們已經(jīng)對Netfilter接收到的數(shù)據(jù)中最有趣和最有用的部分進行了分析,下面就要開始介紹如何利用這些信息對數(shù)據(jù)包進行各種各樣的過濾。
4.2 基于接口的過濾
這將是我們能做的最簡單的過濾技術(shù)。是否還記得我們的鉤子函數(shù)接收到的net_device結(jié)構(gòu)體?利用net_device結(jié)構(gòu)體中的name鍵值,我們可以根據(jù)數(shù)據(jù)包的目的接口名或者源接口名來丟棄這些數(shù)據(jù)包。為了拋棄所有發(fā)向”eth0”的數(shù)據(jù),我們只需要比較一下“in->name”和“eth0”,如果匹配的話,鉤子函數(shù)返回NF_DROP,然后這個數(shù)據(jù)包就被銷毀了。它就是這樣的簡單。列表2給出了示例代碼。請注意輕量級防火墻(LWFW)會使用到這里提到的所有過濾方法。LWFW同時還包含了一個IOCTL方法來動態(tài)改變自身的行為。
列表2. 基于源接口(網(wǎng)卡名)的數(shù)據(jù)過濾技術(shù)
- /* Sample code to install a Netfilter hook function that will
- * drop all incoming packets from an IP address we specify */
- #define __KERNEL__
- #define MODULE
- #include <linux/module.h>
- #include <linux/kernel.h>
- #include <linux/skbuff.h>
- #include <linux/ip.h> /* For IP header */
- #include <linux/netfilter.h>
- #include <linux/netfilter_ipv4.h>
- /* This is the structure we shall use to register our function */
- static struct nf_hook_ops nfho;
- /* IP address we want to drop packets from, in NB order */
- static unsigned char *drop_ip = "\x7f\x00\x00\x01";
- /* This is the hook function itself */
- unsigned int hook_func(unsigned int hook_num,
- struct sk_buff **skb,
- const struct net_device *in,
- const struct net_device *out,
- int (*okfn)(struct sk_buff *))
- {
- struct sk_buff *sb = *skb;
- if (sb->nh.iph->saddr == drop_ip) {
- printk("Dropped packet from... %d.%d.%d.%d\n",
- *drop_ip, *(drop_ip + 1),
- *(drop_ip + 2), *(drop_ip + 3));
- return NF_DROP;
- } else {
- return NF_ACCEPT;
- }
- }
- /* Initialisation routine */
- int init_module()
- {
- /* Fill in our hook structure */
- nfho.hook = hook_func;
- /* Handler function */
- nfho.hook_num = NF_IP_PRE_ROUTING; /* First for IPv4 */
- nfho.pf = PF_INET;
- nfho.priority = NF_IP_PRI_FIRST; /* Make our func first */
-
- nf_register_hook(&nfho);
- return 0;
- }
-
- /* Cleanup routine */
- void cleanup_module()
- {
- nf_unregister_hook(&nfho);
- }
復(fù)制代碼
現(xiàn)在看看,是不是很簡單?下面讓我們看看基于IP地址的過濾技術(shù)。
4.3 基于IP地址的過濾
類似基于接口的數(shù)據(jù)包過濾技術(shù),基于源/目的IP地址的數(shù)據(jù)包過濾技術(shù)也很簡單。這次我們對sk_buff結(jié)構(gòu)體比較感興趣,F(xiàn)在應(yīng)該記起來,Skb參數(shù)是一個指向sk_buff結(jié)構(gòu)體的指針的指針。為了避免運行時出現(xiàn)錯誤,通常有一個好的習(xí)慣就是另外聲明一個指針指向sk_buff結(jié)構(gòu)體的指針,把它賦值為雙重指針?biāo)赶虻膬?nèi)容,像這樣:
- struct sk_buff *sb = *skb; /* Remove 1 level of indirection* /
復(fù)制代碼
然后你只需要引用一次就可以訪問結(jié)構(gòu)體中的成員了?梢允褂胹k_buff結(jié)構(gòu)體中的網(wǎng)絡(luò)層頭信息來獲取此數(shù)據(jù)包的IP頭信息。這個頭包含在一個聯(lián)合中,可以通過sk_buff->nh.iph來獲取。列表3的函數(shù)演示了當(dāng)給定一個數(shù)據(jù)包的sk_buff結(jié)構(gòu)時,如何根據(jù)給定的要拒絕的IP對這個數(shù)據(jù)包進行源IP地址的檢驗。這段代碼是直接從LWFW中拉出來的。唯一的不同之處就是LWFW中對LWFW統(tǒng)計量的更新被去掉了。
列表3.檢測接收到數(shù)據(jù)包的源IP地址
- unsigned char *deny_ip = "\x7f\x00\x00\x01"; /* 127.0.0.1 */
-
- ...
- static int check_ip_packet(struct sk_buff *skb)
- {
- /* We don't want any NULL pointers in the chain to
- * the IP header. */
- if (!skb )return NF_ACCEPT;
- if (!(skb->nh.iph)) return NF_ACCEPT;
- if (skb->nh.iph->saddr == *(unsigned int *)deny_ip)
- {
- return NF_DROP;
- }
- return NF_ACCEPT;
- }
復(fù)制代碼
如果源IP地址與我們想拋棄數(shù)據(jù)包的IP地址匹配的話,數(shù)據(jù)包就會被丟棄。為了使函數(shù)能正常工作,deny_ip的值應(yīng)該以網(wǎng)絡(luò)字節(jié)序的方式存儲(與intel相反的Big-endian格式)。盡管這個函數(shù)在被調(diào)用的時候有一個空指針作參數(shù)這種情況不太可能,但是稍微偏執(zhí)(小心)一點總不會有什么壞處。當(dāng)然,如果調(diào)用時出現(xiàn)了差錯的話,函數(shù)將會返回一個NF_ACCEPT值,以便于Netfilter能夠繼續(xù)處理這個數(shù)據(jù)包。列表4 展現(xiàn)了一個簡單的基于IP地址的數(shù)據(jù)包過濾的模塊,這個模塊是由基于接口的過濾模塊修改得到的。你可以修改IP地址來實現(xiàn)對指定IP地址發(fā)來的數(shù)據(jù)包的丟棄。
列表4. 基于數(shù)據(jù)包源IP地址的過濾技術(shù)
- /* Sample code to install a Netfilter hook function that will
- * drop all incoming packets from an IP address we specify */
- #define __KERNEL__
- #define MODULE
- #include <linux/module.h>
- #include <linux/kernel.h>
- #include <linux/skbuff.h>
- #include <linux/ip.h> /* For IP header */
- #include <linux/netfilter.h>
- #include <linux/netfilter_ipv4.h>
- /* This is the structure we shall use to register our function */
- static struct nf_hook_ops nfho;
- /* IP address we want to drop packets from, in NB order */
- static unsigned char *drop_ip = "\x7f\x00\x00\x01";
- /* This is the hook function itself */
- unsigned int hook_func(unsigned int hooknum,
- struct sk_buff **skb,
- const struct net_device *in,
- const struct net_device *out,
- int (*okfn)(struct sk_buff *))
- {
- struct sk_buff *sb = *skb;
- if (sb->nh.iph->saddr == drop_ip) {
- printk("Dropped packet from... %d.%d.%d.%d\n",
- *drop_ip, *(drop_ip + 1),
- *(drop_ip + 2), *(drop_ip + 3));
- return NF_DROP;
- } else {
- return NF_ACCEPT;
- }
- }
- /* Initialisation routine */
- int init_module()
- {
- /* Fill in our hook structure */
- nfho.hook = hook_func;
- /* Handler function */
- nfho.hooknum = NF_IP_PRE_ROUTING; /* First for IPv4 */
- nfho.pf = PF_INET;
- nfho.priority = NF_IP_PRI_FIRST; /* Make our func first */
- nf_register_hook(&nfho);
- return 0;
- }
- /* Cleanup routine */
- void cleanup_module()
- {
- nf_unregister_hook(&nfho);
- }
復(fù)制代碼
4.4 基于TCP端口的過濾
另外一個要執(zhí)行的簡單的規(guī)則就是基于TCP目的端口的數(shù)據(jù)包過濾。這比檢驗IP地址稍微復(fù)雜一點,因為我們要自己創(chuàng)建一個指向TCP頭的指針。還記得前面關(guān)于傳輸層頭和網(wǎng)絡(luò)層頭所做的討論嗎?獲得一個TCP頭指針很簡單,只需要申請一個指向tcphdr(定義在linux/tcp.h中)結(jié)構(gòu)體的指針,并將它指向包數(shù)據(jù)中的IP頭后面;蛟S一個例子就可以了。列表5展示了怎樣檢測一個數(shù)據(jù)包的TCP目的端口與我們想丟棄數(shù)據(jù)的指定端口是否一致。與列表3一樣,這段代碼也是從LWFW中拿出來的
列表5. 檢測接收到數(shù)據(jù)包的TCP目的端口
- unsigned char *deny_port = "\x00\x19"; /* port 25 */
- ...
- static int check_tcp_packet(struct sk_buff *skb)
- {
- struct tcphdr *thead;
- /* We don't want any NULL pointers in the chain
- * to the IP header. */
- if (!skb ) return NF_ACCEPT;
- if (!(skb->nh.iph)) return NF_ACCEPT;
- /* Be sure this is a TCP packet first */
- if (skb->nh.iph->protocol != IPPROTO_TCP) {
- return NF_ACCEPT;
- }
- thead = (struct tcphdr *)(skb->data + (skb->nh.iph->ihl * 4));
- /* Now check the destination port */
- if ((thead->dest) == *(unsigned short *)deny_port) {
- return NF_DROP;
- }
- return NF_ACCEPT;
- }
復(fù)制代碼
世紀上非常簡單。不要忘了deny_port是網(wǎng)絡(luò)字節(jié)序時,這個函數(shù)才能工作。數(shù)據(jù)包過濾技術(shù)的基礎(chǔ)就是:對于一個特定的數(shù)據(jù)包,你必須對怎樣到達你想要的信息段的方法非常了解。下面,我們將進入更有趣的世界。
[ 本帖最后由 duanjigang 于 2006-5-21 18:45 編輯 ] |
-
-
souce.rar
2006-05-21 09:43 上傳
點擊文件名下載附件
39.03 KB, 下載次數(shù): 202
|