linux 内核抓包功能实现基础(一)设计思路
linux平臺下面已經有了抓包工具tcpdump, 非常經典,使用起來也非常方便。但是因為某些系統架構上或者其它方面的原因,有時候tcpdump并不能滿足產品實際需要,公司的產品是電信運營商相關的軟硬件集成產品,平常在使用的時候經常需要抓包來分析、定位問題,之前的抓包功能是基于tcpdump的基礎上的,但是因為系統架構方面的原因,抓包功能始終無法抓到所有進出報文,每次只能抓到特定一部分報文,此外因為抓包之后生成的文件是臨時存儲在flash中,抓包文件大小就會受到系統存儲空間制約,每次抓包只能抓去少量報文。對于電信級通信產品,吞吐量巨大,稍稍抓下包生成的文件大小就會超出限制。有了上述種種不便之處,決定開發一個新的抓包功能,基本功能要求有下面幾點:
1. 能夠抓到所有報文
2. 能夠設置過濾條件進行抓包,包括端口、ip地址和協議類型(TCP、UDP、ARP和ICMP)
3. 具備遠程抓包功能。
遠程抓包功能就是存在一臺抓包服務器,產品抓到的報文能夠送到服務器上存儲,這樣能夠使得抓包文件大小不受限制,只要遠程服務器存儲空間夠大。想象這樣一個場景:產品在機房運行,運維人員需要抓包分析問題的時候,只需要使用任意一臺連接到機房產品的PC,開啟遠端抓包功能后,產品能夠將報文發送到指定的PC機上,這時PC機就相當于抓包服務器,抓包文件大小只受PC存儲空間限制。
這樣的功能需要實現兩個方面,一個是抓包服務器的實現,另一個就是抓包功能的實現。本篇博客以及接下來的博客就詳細介紹相關功能的原理、實現以及所遇到的問題。
首先來看一下抓包功能的實現。在linux平臺下面,內核抓包功能實現大致有兩種(可能還有其它方式,有知道的同學還請告訴我),一種是借助netfilter框架,另一種是使用dev_add_pack注冊協議處理函數。對了,這里講的都是內核抓包,用戶層也是可以抓的,使用lipcap就可以很方便的抓取,這個先不提,等講到抓包服務器實現的時候再來將libpcap的使用。
我們使用的抓包方式是前一種,即netfilter框架,至于后面那一個 dev_add_pack方式,還有一些問題尚未解決,咱先討論netfilter。
先簡介一下netfilter框架,如下圖:
netfilter在網絡層(IP層)設置了五個hook點,如圖中紅色方框顯示,
1.??????NF_IP_PRE_ROUTING : (剛剛進入網絡層的數據包通過此點)
2.??????NF_IP_LOCAL_IN : (經路由查找后,送往本機的通過此檢查點)
3.??????NF_IP_FORWARD : (要轉發的包通過此檢測點)
4.??????NF_IP_LOCAL_OUT : (本機進程發出的包通過此檢測點)
5.??????NF_IP_POST_ROUTING : (通過網絡設備出去的包通過此檢測點)
因為我們要抓進出的報文,所以分別在報文進出的入口(PRE_ROUTING)和出口(POST_ROUTING)添加了兩個鉤子函數,如上圖綠色方框顯示。有了這兩個函數,偶就可以對進出的報文做處理了。怎么處理呢,對符合條件的報文該怎么抓呢,抓到之后又該怎么處理?先看下圖:
這個圖就回答了上面那幾個問題,首先抓到報文后,要抓取其L2層以上數據,也就是MAC層之上,其次抓到之后,需要把它送出去,送到服務器上,這時候需要添加新的UDP、IP首部,用來設置遠端服務器的地址信息等。UDP的數據部分就是抓到的報文。等到封裝好之后,我們就可以把它發送出去,這時候遠端服務器收到報文之后就可以讀取了。就像下面這樣:設置遠端服務器地址192.168.11.12:1112,當抓到報文后就將報文復制一份發送到這個地址。下面數據部分可以看到以太網層、IP層首都被封裝成UDP數據部分,這樣當服務器端收到這樣報文后,讀取其數據部分,封裝成wireshark格式就可以直接讀取了。
今天先講到這,下一篇博客將討論netfilter的實現部分。
ps:創建了一個linux內核、應用程序開發討論交流群,歡迎感興趣的同學加入,群號:745510310,熱烈歡迎哈
總結
以上是生活随笔為你收集整理的linux 内核抓包功能实现基础(一)设计思路的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 晟怎么读。?
- 下一篇: linux 内核抓包功能实现基础(二)