Linux 中的網絡數據包捕獲


Linux 中的網絡數據包捕獲 Ashish Chaurasia, 工程師 簡介: 本教程介紹了捕獲和操縱數據包的不同機制。安全應用程序,如 VPN、防火牆和嗅探器,以及網絡應用程序,如路由程序,都依賴類似於本文描述的方 法來完成工作。一旦接觸到它們,您將會離不開它們。 標記本文! 發布日期: 2004 5 31 日 級別: 初級 訪問情況 8870 次瀏覽 建議: 2 (查看或添加評論 ) 1 star2 stars3 stars4 stars5 stars 平均分 (共 9 個評分) 開始之前 關於本教程 目前,信息要通過管道(也就是網絡)傳輸,需要花很多時間封裝在數據包中。在本教程中,我們將在這些數據包傳輸過程中捕獲它們,捕獲數據包所采用的平台是 Linux。 大多數網絡應用程序――從虛擬專用網( VPN)到路由程序,再到嗅探器――都具有某種數據包捕獲機制。因此,編寫此類軟件的任何人都可以從本教程中受益。 由於我們將要研究的幾種數據包過濾機制都是內核模塊,所以還將簡要地介紹這些模塊以 及內核編譯。 我們還將回顧一些我沒有成功使用的機制:我只能獲得數據包的一個副本而無法截獲最初的數據包。這里的討論不僅能省去您重復我所做工作的麻煩,而且還對編寫網絡應用程序(如嗅探器) 很有用。 除大致熟悉不同的數據包捕獲機制(如防火牆鈎子、 divert socket netfilter)外; 讀者還應具備有關 Linux 網絡和 TCP/IP 協議棧方面的知識。開始之前最好了解一些源代 碼的知識。 回頁首 前提條件 本教程最適合那些以前在系統編程、 Linux 網絡和 Linux 內核模塊方面至少有一些經驗的讀者。但是,本教程盡可能簡單地給出一些概念,並在適當的時候給予詳細解釋,因此,即使讀者缺少一種或多種這方面的知識,也能從本文的討論中獲益。 簡介 數據包捕獲 TCP/IP 協議棧是 Linux 網絡的重要支柱,其體系結構設計得非常優美。數據包 是 TCP/IP 協議棧中信息流的載體。在 Linux 網絡編程中,許多有意義的工作都包括了捕獲這些信息豐富的數據包、提取或操作這些數據包所包含的信息。 數據包捕獲 對我們而言意味着某種機制,即獲取一個數據包,直到達到所要求的目的后才將其釋放,以便該數據包能夠按照常規路徑通過其余的任何處理。其他相同或相似 操作的術語有 數據包過濾、數據包嗅探、網絡嗅探 以及 數據包 或 網絡監視。 數據包過濾是許多網絡軟件的基礎,這些軟件有網絡監視工具、 VPN、網絡分析程序、路由 程序、入侵監測系統( Intrusion Detection SystemsIDS)和嗅探器。 Linux 提供了多處可以捕獲數據包的位置,既包括用戶空間,又包括內核空間。下圖展示了網絡數據包流過 TCP/IP 協議棧的路徑: 圖 1. 網絡數據包通過協議棧的路徑 網絡數據包通過協議棧的路徑 如上圖所示,流入的數據包通過以太網層、網絡層、 TCP 協議棧並穿過套接字層,然后才能被復制到用戶空間中。在所有這些斷點處,數據包都很容易被捕獲到。本教程討 論的方法大多在網絡層和用戶空間中有效。 然而,由於 Linux Linux 內核在不斷發展,這里討論的某些數據包捕獲方法僅在特定 的內核中有效。例如, divert socket 對打過補丁的 2.2.12 內核有效,而 netfilter 對 內核 2.4.x 2.6.x 有效。在討論各種方法時始終要注意這些細節。 Linux 可加載的內核模塊( LKM)概述 捕獲數據包的模塊 本教程探討的大多數數據包捕獲機制都是以 Linux 內核模塊的方式工作的,因此我們現在簡 要討論一下這些模塊。如果您有很強的 LKM 背景,則可以跳至下一節 編譯內核 。 回頁首 什么是 LKM? 可加載內核模塊 是內核的擴展,可以在需要時附加到內核中,或從內核中刪除。 LKM 基本上是設備驅動程序的軟件實現,它與真實的或者虛擬的硬件設備協同工作。當 LKM 加載到內核中時,它們監聽和處理對設備的任何請求。由於只加載所需的 LKM,因此使 用 LKM 可使內核變得輕便、模塊化、靈活和可伸縮。 回頁首 LKM 體系結構 編寫 Linux 內核模塊的體系結構如下: init_module 這個 LKM 初始化函數是強制執行的。當 LKM 加載到內核時觸發該函數,因此 所有初始化工作都是在這個函數中完成的。 處理特定的函數 這些函數執行實際的工作,如讀、寫、打開、關閉設備,等等。 cleanup_module 當從內核中刪除 LKM 時,調用 LKM 的這個強制執行函數。因此,所有清除工作 如釋放內存等都應在這個函數中執行。 回頁首 編譯 LKM 編寫 LKM 后,可以采用下列命令編譯它: gcc -c -g <module_name>.c -I/usr/src/linux/include 該命令產生一個名為 <module_name>.o 的文件,它就是 LKM,可以使用下列命令將它加載到 內核中: insmod -f <module_name>.o -f 選項意味着強制加載。) 如果在加載模塊時遇到任何內核版本問題,可以通過在加載 LKM 時包含這個特定內核 的頭文件來解決問題。因此,在編譯內核時,請使用 -I/usr/src/linux/include。 還可以使用 Makefile 來解決此類版本問題,但這超出了本教程的范圍。在本教程的末 尾,您還可以在 參考資源 中找到有關 LKM 編程的更多信息。 回頁首 卸載 LKM 一旦模塊加載到內核中,它將開始執行預定的功能。使用命令 lsmod 可 以看到當前所有加載的 LKM 的列表。 可以使用 rmmod <module_name> 從內核中加載或刪除模塊。 編譯內核 回顧 本教程討論的許多機制都要求設置某些內核選項,然后重新編譯內核。因此在開始前,我們將復習內核編譯的步驟。如果您已經了解內核編譯,則可以跳至下一 節 數據包截獲:防火牆鈎子 ,在那里開始復習數據包捕獲機制。 回頁首 步驟 重新編譯內核: make xconfig 允許設置不同的內核選項。(也可以使用 make menuconfig make config;這只是個人偏好問題。) make dep 解決內核編譯的文件依賴性。 make bzImage 編譯( make)內核映像並將其存儲在 vmlinuz 中。 make installvmlinuz 復制到 /boot 目錄中,並將二進制文件復制到正確的位置。 make modules 編譯所有內核模塊。 make modules_install 在正確的位置安裝模塊(通常位於 /lib/modules/<kernel-version> )。 接着,您應將關於最近編譯內核的信息添加到 /etc/lilo.conf(如果不在該位置的話),然后重新啟動機器。您會在重新啟動過程的開始看到列出的新內核選項。 數據包截獲:防火牆鈎子 概述 防火牆鈎子( Firewall hook) 已引入到 2.2.16 內核中,它是 2.2.x 內核運行的數據包截獲方法。防火牆鈎子在 TCP/IP 協議棧的 IP 層截獲數據包。 防火牆鈎子在功能上充當 Linux 可加載內核模塊( LKM)或偽設備驅動程序,可以根據 需要從內核中加載或卸載。 要使用防火牆鈎子,請在內核編譯期間啟用 firewalling 選項 (在 Networking 選項下列出)。 您可以使用該數據包截獲機制來開發路由程序、 VPN、數據包嗅探器或位於網絡邊緣且要求實時捕獲數據包的任何其他網絡應用程序。 回頁首 填充結構 內核定義的 firewall_ops 結構是防火牆鈎子的基礎。可以用這些結構來指定各種數據包策略,這些策略可以是非常特殊的,也可以是很普通的。 firewall_ops 結構位於 /usr/src/linux/include/linux/firewall.h 中,類似如下: struct firewall_ops { struct firewall_ops next; int (*fw_forward)(struct firewall_ops *this, int pf, struct device *dev, void *phdr, void *arg, struct sk_buff **pskb); int (*fw_input)(struct firewall_ops *this, int pf, struct device *dev, void *phdr, void *arg, struct sk_buff **pskb); int (*fw_output)(struct firewall_ops *this, int pf, struct device *dev, void *phdr, void *arg, struct sk_buff **pskb); int fw_pf; int fw_priority; }; 這種機制是作為 LKM 來實現的。同樣,它需要 init_module(用於初始化模塊)、 cleanup_module 和某些特定處理的函數: next 指向下一個鈎子的指針 fw_forward 轉發數據包的函數指針 fw_input 流入數據包的函數指針 fw_output 流出數據包的函數指針 fw_pf 協議簇 fw_priority 所選防火牆的優先權 這些都是實際的函數指針;相應的函數在下一個屏中定義。 回頁首 函數 為了處理數據包,需要定義三個函數: 流入的數據包處理: static int fw_input(struct firewall_ops *this,int pf,struct device *dev,void *phdr,void *arg,struct sk_buff **pskb) 對所有流入的數據包都要調用該函數。如果需要對流入的數據包進行任何處理(也稱為 "mangling"),如添加額外的字段,可以在此進行處理。 流出的數據包處理: static int fw_output(struct firewall_ops *this,int pf,struct device *dev,void *phdr,void *arg,struct sk_buff **pskb) 對所有流出的數據包(源自主機)調用該函數。可以在這里對此類數據包進行任何額外處理。 轉發數據包處理: static int fw_forward(struct firewall_ops *this,int pf,struct device *dev,void *phdr,void *arg,struct sk_buff **pskb) 對所有轉發的數據包調用該函數。 下面是在上述函數中傳遞參數的詳細信息。 *this 指向防火牆鈎子結構的指針 pf 代表協議簇 *dev 指向以太網卡設備結構的指針 card *phdr 指向 IP 地址緩沖區的指針 *arg 額外的參數,在需要時傳遞給函數 function **pskb 指向 TCP_IP 協議棧的 sk_buff 層的指針 對於上述每個函數,數據包的返回值(或對數據包的操作)可以是: Accept 該操作由 FW_ACCEPT 宏完成。它接受數據包並且數據包遵循正常的 TCP/IP 協議棧路徑。 Reject 該操作由 FW_REJECT 宏完成。它拒絕所有數據包,既沒有網絡流量流出, 又沒有網絡流量流入。 Redirect 該操作由 FW_REDIRECT 宏完成。它將數據包重定向到特定的主機。 回頁首 函數(續) 現在,我們將把上一屏中定義的函數賦值給 firewall_ops 結構中的指針。一旦賦值 完成, firewall_ops 結構將被填充,函數將由系統本身調用――這就是術語 回調函 數。 下面是要填充的字段: struct firewall_ops * next; int fw_pf; int fw_priority; 現在,防火牆結構與下面的代碼類似: static struct firewall_ops myOps = {NULL, fw_forward, fw_input, fw_output, PF_INET, 1 }; 回頁首 Kernel 注冊 現在,您需要將 firewall_ops 結構注冊到內核: register_firewall(protocol family, struct firewall_ops *);LKM init_module 代碼中進行注冊。 回頁首 取消注冊 firewall_ops 結構 當卸載 LKM 時, cleanup_module 函數應包含 unregister_firewall(protocol family, struct firewall_ops *);LKM 進行編碼、編譯並加載到內核后,您的數據包攔截器就准備工作了。 完成在接下來的兩屏中給出的這個 LKM 的源代碼和使用說明。 回頁首 源代碼:防火牆鈎子程序 #define MODULE #define __KERNEL__ #include<linux/config.h> #include<linux/module.h> #include<linux/version.h> #include<linux/netdevice.h> #include<net/protocol.h> #include<net/pkt_sched.h> #include<net/tcp.h> #include<net/ip.h> #include<linux/if_ether.h> #include<linux/ip.h> #include<linux/tcp.h> #include<linux/skbuff.h> #include<linux/icmp.h> #include<linux/kernel.h> #include<linux/mm.h> #include<linux/file.h> #include<linux/firewall.h> #include<asm/uaccess.h> //Function for forwarded packets static int fw_forward(struct firewall_ops *this,int pf,struct device *dev,void *phdr,void *arg,struct sk_buff **pskb) { struct iphdr *hdr = (struct iphdr *)(*pskb)->h.ipiph; printk("\n\tfw_forward)() called..."); printk("\n\t\tThe source of this packet is: %s",in_ntoa(hdr->saddr)); return FW_ACCEPT; } static int fw_input(struct firewall_ops *this,int pf,struct device *dev,void *phdr,void *arg,struct sk_buff **pskb) { struct iphdr *iph; iph = (struct iphdr*)(*pskb)->h.ipiph; printk("\n\tfw_input() called..."); printk("\n\t\tThe source of this packet is: %s",in_ntoa(iph->saddr)); return FW_ACCEPT; } static int fw_output(struct firewall_ops *this,int pf,struct device *dev,void *phdr,void *arg,struct sk_buff **pskb) { struct iphdr *iph; iph = (struct iphdr*)(*pskb)->h.ipiph; printk("\n\tfw_output)() called..."); printk("\n\tThis packet is destined for: %s",in_ntoa(iph->daddr)); return FW_ACCEPT; } static struct firewall_ops myOps = {NULL,fw_forward,fw_input,fw_output,PF_INE int fw_pf; ,int fw_priority; T,1}; int init_module(void) { if(register_firewall(PF_INET,&myOps) < 0) { printk("\n\n\tERROR...firewall main aag lag gayee!!!"); return -1; } else { printk("\n\n\tFirewall registered"); } return 0; } void cleanup_module(void) { if(unregister_firewall(PF_INET,&myOps)<0) { printk("\n\n\tError....Firewall can't be unregistered"); } else { printk("\n\n\tFirewall unregistered"); } } 回頁首 使用防火牆鈎子程序 編譯和運行防火牆鈎子程序: gcc -c -O NetFWHook.c -I/usr/src/linux/include/ 您將得到一個名為 NetFWHook.o 的文件。請使用下列命令將其插入到內核中: /sbin/insmod -f NetFWHook.o 要查看由這個 LKM 生成的消息,請運行 dmesg 命令。 數據包截獲: Netfilter 概述 Netfilter 是由內核 2.4.x 2.6.x 提供的數據包截獲機制,它替代了內核 2.2.x 中 使用的 ipchains、防火牆鈎子和其他方法。 Netfilter 也可以作為 LKM 獲得。 要使用 netfilter,在內核編譯時設置 Packet Filtering 選項。 可以對采用防火牆鈎子機制的同類應用程序使用 netfilter 機制,這些應用程序有:路由程序、數據包嗅探器和其他位於網絡邊緣並訪問通信流的實體。 回頁首 使用 Netfilter Netfilter 可以在通過 TCP/IP 協議棧的路徑中的幾個定義良好的點上捕獲數據包: NF_IP_PRE_ROUTING 在對數據包進行初始正確性檢查(校驗和等)后,保存該數據包。 NF_IP_LOCAL_IN 如果數據包將要到達本地主機,則捕獲該數據包。 NF_IP_FORWARD 如果數據包將要到達某些其他主機,則捕獲該數據包。 NF_IP_LOCAL_OUT 在本地捕獲其目的地是外部的已創建的數據包。 NF_IP_POST_ROUTING 這是最后的鈎子,在此之后將傳輸數據包。 當數據包穿過 TCP/IP 協議棧后,協議調用帶有數據包和鈎子號的 netfilter 框架。鈎子也 可以指派優先級。 函數的返回值包括: NF_ACCEPT 數據包繼續在正常的 TCP/IP 路徑上傳輸。 NF_DROP 丟棄數據包;不進一步處理。 NF_STOLEN 已獲得數據包;不進一步處理。 NF_QUEUE 對數據包排隊(通常用於用戶空間處理)。 NF_REPEAT 再次觸發這個鈎子。 回頁首 步驟 Netfilter 的工作方式與防火牆鈎子非常相似。作為 LKM 注冊到內核的結構 調用特定於進程的函數。任何基於 netfilter 的數據包攔截器都必須遵循開發 LKM 所采 用的步驟。 回頁首 特定於進程的函數 特定於進程的函數(或鈎子)的原型如下所示: static unsigned int packet_interceptor_hook(unsigned int hook, struct sk_buff **pskb, const struct net_device *indev, const struct net_device *outdev, int (*okfn) (struct sk_buff *)) 您可以將字段定義為: hook 您感興趣的鈎子的編號;例如 NF_IP_LOCAL_OUTNF_IP_LOCAL_INNF_IP_ FORWARD 等。 **pskb 指向 TCP/IP 協議棧中數據包容器的指針;例如 sk_buff*indev & *outdev 指向流入和流出網絡設備的設備結構的指針。在內核中注冊的每種設備(例如,以太網卡)都 有一個由 IRQIO 地址等組成的設備結構。當機器只有一個網絡接口來處理流入和流出流量時,這兩個結構是相同的。當流入和流出的流量由兩種設備處理時,這兩種結構是 不同的。 (*okfn) (struct sk_buff *) 在激活鈎子時調用該函數。 回頁首 netfilter 結構 核心 netfilter 結構在 /usr/src/include/linux/netfilter.h 中定義,類似如下: struct nf_hook_ops { struct list_head list; nf_hookfn *hook; int pf; int hooknum; int priority; }; 參數是: list Netfilter 本身是一個鈎子鏈;它指向 netfilter 鈎子的頭部,通常設置為 { NULL, NULL }hook 該函數在數據包碰到鈎子點時被調用。該函數與前面描述的函數相同,它必須返回 NF_ACCEPTNF_DROP NF_QUEUE。如 果返回 NF_ACCEPT,則下一個鈎子將被附加到將要調用的點。如 果返回 NF_DROP,則數據包被丟棄。如果返回 NF_QUEUE,則對數據包進行排隊。 sk_buff 指針被傳遞到該函數中,並用數據包信息如 IP 報頭、 TCP 報頭等進 行填充。您可以使用 sk_buff 結構指針來操作或刪除數據包(要刪除數據包,只需將 skb 指 針設置為空即可)。 pf 協議簇;例如,適用於 IPv4 PF_INEThooknum 您感興趣的鈎子號;例如 NF_IP_LOCAL_IN 等。 回頁首 內核注冊 在 LKM init_module 函數中,需要注冊在內核中填充的結構: int nf_register_hook(struct nf_hook_ops *req); 這里, nf_hook_ops netfilter 操作結構。 一旦該結構注冊到內核中, Linux 將調用這里定義的函數來處理數據包。 回頁首 取消注冊 netfilter 結構 卸載 LKM 時, netfilter 結構需要從內核中取消注冊。這一操作在 cleanup_module 函數中完成: void nf_unregister_hook(struct nf_hook_ops *req); nf_hook_ops 也是 netfilter 操作結構。 數據包截獲: Divert socket 概述 2.2.12 內核的其中一個補丁引入了一種新類型的原始套接字( raw socket),稱 為 divert socket,該套接字按照防火牆規范過濾數據包,並將其發送到用戶空 間。數據包從這里開始進行處理或簡單地再放回到 TCP/IP 協議棧中。 Divert socket 是一種特殊類型的原始套接字,與任何其他套接字一樣,通過該套接字 可以接收和發送數據包。 Divert socket 使用 Linux 內核的 firewalling 功能:可以 將 Linux firewalling 設置為對流入、流出和轉發數據包應用受限的策略,然后將其重 定向到指定的端口。 Divert socket 將在該端口進行監聽,然后進一步重定向數據包。 使用 divert socket 的主要缺點是將數據包復制到用戶空間的開銷,這會占用時間 和資源,從而降低了網絡性能。 任何沒有對數據包實時處理施加硬性限制的聯網應用程序(如嗅探 器),您都可以使用 divert socket。 回頁首 內核編譯選項 Linux firewalling 是使用 divert socket 的先決條件,因此應在內核編譯時啟用該選項。某些選項已專門為 divert socket 引入到內核中,並應在編譯時設置它們: Firewalling 啟用內核的 firewalling 功能。 IP Firewalling 啟用內核的數據包過濾功能。 IP:divert sockets 在內核中啟用 divert socketIP:divert pass-through 如果已設置了該選項並且沒有應用程序正在監聽 divert socket 端口,則該數據包不轉 移,只按照正常的路徑傳輸。 IP:always defragment 如果設置該選項,則整理內核中的所有碎片,這會嚴重降低性能。 ipchains 控制網絡數據包傳輸的路徑。要將 ipchains divert socket 一起使用,應下載、編譯和安裝打了補丁的 ipchains 版本 ipchains-1.3.9。 在下一屏對 ipchains 進行一般性介紹。 回頁首 ipchains 簡介 Input chain 允許所有流入的數據包(目的地是主機的數據包和轉發的數據包)穿過。 Output chain 允許所有流出的數據包(源自主機的數據包和轉發的數據包)穿過。 Forward chain 只允許轉發的數據包穿過。 轉發的數據包按以下順序穿過鏈: 輸入 轉發 輸出 數據包截獲:內核改動 概述 在此,我們將操作內核源代碼以擴展內核本地數據包截獲能力。 內核源文件位於 /usr/src/linux,要修改的兩個主要文件 是 ip_input.c ip_output。這兩個文件位於 /usr/src/linux/net/ipv4/ 目錄中。 回頁首 源文件修改: ip_input.c ip_input.c 包含這兩個函數,可以為所有流入數據包調用它們: incoming packets: ip_local_deliver(struct sk_buff, struct device,struct packet_type) 為所有的流入數據包執行而不考慮目的地 ip_rcv(struct sk_buff, struct device,struct packet_type) 為目的地是本地機器的所有數據包進行調用 sk_buff TCP/IP 協議棧中數據包的容器。 device 設備結構。 packet_type 數據包的類型:流入或流出。 ip_rcv 執行 IP 層所需的幾個任務,包括重新裝配、校驗和計算等。 由於 ip_rcv 處理所有流入的 IP 數據包,因此這是一個添加要對流入數據包執行任何附加代碼的好地方。其他選項是用於編寫自己 的 ip_rcv 例程的。 回頁首 源文件修改: ip_output.cip_output 一樣, ip_output.c 位於 /usr/src/linux/net/ipv4/ 目錄中,它處理流出的數據包。它的四個函數是: ip_build_and_sent_pkt(struct sk_buff,struct sock,u32 saddr,u32 daddr, struct ip_options)IP 報頭添加到 sk_buff 並將其發送出去 ip_queue_xmit(struct sk_buff) 對要發送的數據包排隊 ip_build_xmit_slow() 構建和傳送數據包 ip_build_xmit() “快速”構建和傳送數據包,該選項只用於無需碎片整理的選項。 只有 ip_build_xmit_slow ip_build_xmit 處理所有 流出的 IP 數據包,因此任何額外處理均可在任何階段完成。對 於 ip_input.c,其他選項用於編寫自己的例程,然后從這些例程中調用最初的函數。您 選擇的策略依賴於您要實現的功能。 回頁首 使用 Makefiles 修改源代碼 可以使用 Makefiles 動態修改內核源代碼; Makefile 腳本確保對源代碼做必需的修改。可以使用一條命令( make install make uninstall)添加或刪除數據包攔截器,然后重新編譯內核並重新啟動機器。 由於該機制要求修改 Linux 內核源代碼,所以快速調試可能非常困難。而且,由於該方法要求重新編譯內核,所以這個過程是冗長、復雜且不靈活的。 數據包截獲:創建數據包的副本 概述 某些數據包捕獲機制僅提供數據包的副本而非數據包本身。但是,我們前面提到過,在開發網絡嗅探器應用程序時,數據包的副本仍然是很有用的。 回頁首 協議處理程序 協議處理程序是另一種充當 LKM 的機制。 協議處理程序對處理通過以太網卡傳來的數據包。為此,協議處理程序必須注冊到網絡設備中;在本例中,應該注冊到以太網卡的設備結構中。 網卡設備結構還包含一個指向 init 函數的指針,該函數初始化設備。 回頁首 實現協議處理程序 實現協議處理程序的步驟: 為以太網接口創建設備結構的實例,並將其注冊到內核中。 注冊處理程序例程,用於處理具有設備結構的數據包。 現在,通過以太網接口的任何數據包都能得到正確處理。對 數據包的副本 而非最初 的數據包進行處理。不可能通過 TCP/IP 協議棧轉移來自最初路徑的數據包,因此只有數據包的 副本到達協議處理程序本身。 回頁首 中斷處理程序 顧名思義,該機制是以中斷處理作為基礎的,也可以作為 LKM 來實現。不論何時,只要有數據包到達以太網卡,就會生成中斷。通過編寫自己的中斷處理程序,您就可以捕獲數據包 並對其進行任何必要的處理。 幸運的是,無論何時只要有數據包穿過 TCP/IP 協議棧,就會生成中斷,這會設置以太網卡中的標志,表示數據包是流入的還是流出的。這個中斷通常是中斷 9,因此,您可以編寫中斷處理程序 來處理中斷 9 的信號,然后處理數據包。 在這種情況下,由於有了協議處理程序,只有 數據包的副本 發送給中斷處理程序,而 最初的數據包未受任何阻礙,通過 TCP/IP 協議棧正常傳輸。 結束語和參考資料 數據包截獲機制的總結 機制 模塊? 可伸縮? 性能( TCP/IP 吞吐量) 可插入 /可刪除? 防火牆鈎子 是,可以將其作為 LKM 插入 是,可以通過更改 LKM 的源代碼並重新編譯來增強該性 能 降低大約 50% 是,使用 insmod 命令 Netfilter 是,可以作為 LKM 插入它 是,可以通過更改 LKM 的源代碼並重新編譯來增強該功能 下降大約 50% 是,使用 insmod 命令 Divert socket 否, divert socket 數據包必須直接應用到內核代碼 冗長乏味,因為整個內核需要編譯 太慢而無法度量 否,因為它不是模塊 內核改動 否,內核數據包攔截器代碼必須直接集成到內核源代碼中 冗長乏味,因為整個內核需要編譯 通常快於 LKM 方法(如果正確實現) 是,如果將 Makefile 用於安裝和卸載 防火牆鈎子和 netfilter 是模塊化的、靈活的和動態加載的(可刪除) ,它們只對系統的性能產生適度的影響。 對於預計流量很大且實時處理時有硬性限制的應用程序而言,最適合使用內核改動方法。 如果數據包處理沒有計時問題,則可以使用 Divert socketDivert socket 在用戶空間中是一種分析和控制網絡流量的非常有用的方法。 回頁首 反饋 請讓我們知道本教程是否對您有幫助,以及我們如何才能做得更好。我們 還希望了解您想要閱讀的其他教程主題。 如果對本教程的內容有疑問,請通過 achauras@in.ibm.com 與作者 Ashish Chaurasia 聯系。 參考資料 Linux Device Drivers, 2nd Edition ,作者: Alessandro Rubini Jonathan CorbetO'Reilly & Associates2001),該書討論了設備驅動程序編程;還討論了 使用 Makefiles 來解決版本問題(這已在 Linux 可加載的內核模塊( LKM)概述 中討論了)。 Linux Kernel Internals ,作者: Michael BeckHarold BohmeUlrich KunitzRobert MagnusMirko Dziadzka Dirk VerwornerACM1996),該書闡述了 Linux 的內部機制,內容包括從進程調度到內存管理和文件系統,還討論了內核本身。 Di vert Sockets mini-HOWTO,作者: Ilia Baldine2000 2 月),給出了這種數據包截獲方法的大量信息。 有關 Netfilter 的更多信息,請 參閱 netfilter Web site Netfilter summary of information(作者: V.R. Sundar Karthik Dantu)。另請參閱 Linux netfilter Hacking HOWTO。 對於較新的內核,則請參考 “ Linux 2.4 Packet Filtering HOWTO”,即 Rusty's Remarkably Unreliable Guides 之一(其他包括 Networking Concepts HOWTOLinux 2.4 NAT HOWTO 和 上面列出的 Netfilter Hacking HOWTO)。不過要注意,它們比系列名稱所暗示的那樣更可靠。 “ Linux iptables HOWTO”介紹 如何使用 iptable 來過濾出 Linux 內核 2.3.15 和更高版本的損壞數據包。 Linux iptables HOWTO: using iptables 也很有用。 Linux 2.4 Advanced Routing HOWTO 介紹了 iproute2 的使用――需要隧道時,選擇它就很好。 了解在 AIX 上如何將 IPSec 用作數據包過濾器來阻止未授權的用戶。 介紹 TCP/IP 並了解如何使用 Red Hat Linux 來設置 LANNetwork Address Monitoring and Messaging API Java API,用於監視接口地址並以編程方式對其更改進行響應。 Guide to IP Layer Network Administration with Linux 中的 Links to Documentation 一節很精彩,介紹從一般聯網到 iproute2netfilteripchains 以及更多內容。它們的 Links to Software 也非常精彩。 Phrack 雜志介紹了從安全問題到攻擊無線廣播和世界新聞等主題,以及有關 Linux 內核和內核模塊的許多很精采的文章。 詩句 “ If a packet hits a pocket on a socket on a port” 摘自 A Grandchild's Guide to Using Grandpa's Computer。 有關 LKM 的更多信息,請參閱論文 “ The Linux Kernel Module Programming Guide”Peter Jay Salzman Ori Pomerantz2001) 和 “ Linux Loadable Kernel Module HOWTO”Bryan Henderson2004)。 Fairly Fast Packet Filter (FFPF) 最大限度減少了數據包復制,准備用於替代 netfilterLinux Device Drivers, 2nd Edition 作者: Alessandro Rubini & Jonathan CorbetO'Reilly & Associates2001) 可在 O'Reilly xml.com 上在線獲得。本書的所有章節都很有用;特別 是 Chapter 9: Interrupt Handling 更是如此。 Linux 開發人員可以在 developerWorks Linux 專區 獲得更多資源。 在 Developer Bookstore Linux 區,可以找到很多有關 Linux 的書籍。 關於作者 Ashish Chaurasia 是一位計算機科學工程師,目前在 IBM India 致力於存儲區域網絡( Storage Area NetworkSAN)文件系統的研究。最近,他完成了一個虛擬專用網( VPN)項目,在此期間,他研究和搜集了一些資源,這些資源最后匯集成本教程。可以通過 achauras@in.ibm.com 與他聯系。 轉載自 http://www.ibm.com/developerworks/cn/education/linux/l-packet/index.html的系列文章


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM