libpcap api接口及詳細教程

Libpcap是Packet Capture library的英文縮寫,即數據包捕獲函數庫,該庫提供的C函數接口用於捕獲經過指定網絡接口(通過將網卡設置爲混雜模式,可以捕獲所有經過該網絡接口的數據包)的數據包。

著名的TCPDUMP就是在Libpcap的基礎上開發而成的,Libpcap提供的接口函數主要實現和封裝了與數據包的採集、構造、發送等有關的功能。

Libpcap面向上層應用,提供了用戶級別的網絡數據包捕獲接口,在系統部署時充分考慮到應用程序的可以移植性。

Libpcap主要有如下功能:

(1)數據包捕獲

捕獲流經本網卡的所有原始數據包,甚至對交換設備中的數據包也能夠進行捕獲,本功能是嗅探器的基礎。

(2)自定義數據包發送

構造任意格式的原始數據包,併發送到目標網絡,本功能是新協議驗證、甚至攻擊驗證的基礎。

(3)流量採集與統計

對所採集到的網絡中的流量信息進行按照新規則分類,按指標進行統計,並輸出到指定終端。利用這項功能可以分析目標網絡的流量特性。

(4)規則過濾

Libpcap自帶規則過濾功能,並提供腳本編程接口,能夠按照用戶編程的方式對已經採集到的數據包進行過濾,以便提高分析的性能。

Libpcap的應用範圍:

由於擁有強大的功能,當前基於Libpcap的應用比較廣泛,有很多Unix上的流量相關的網絡系統都是基於Libpcap的,它的一些典型應用如下:

(1)網絡協議分析器

Libpcap應用最多的就是網絡協議分析器,也可以稱之爲網絡嗅探。

(2)網絡流量發生器

網絡流量發生器也是Libpcap的一大應用,它是基於Libpcap的數據構造與發送功能,可以有針對性的構造各種形式的數據包,並執行發送工作,這樣的組合便構成了網絡流量的產生工具。

(3)網絡入侵檢測系統

網絡入侵檢測系統(IDS)是發現網絡入侵行爲的關鍵,利用Libpcap所提供的數據包捕獲功能,可以進一步開發出IDS。

(4)網絡掃描器

這是基於Libpacp的數據包構造與發送功能。當前最著名的網絡掃描器Tcpdump就是基於Libpcap開發而成的。

(5)其他安全工具

利用Libpacp可以設計出其他的網絡安全工具。

不過有一點要提醒:Libpacp只是提供網絡數據包的監測以及發送功能,並不提供控制層面的服務,類似於防火牆那種數據包過濾的功能,Libpcap是無法實現的。

Libpcap工作原理介紹

Libpcap是Unix/Linux平臺下的網絡數據包捕獲數據庫。它是一個獨立於系統的用戶級數據包捕獲API接口,爲底層網絡監測提供了一個可以移植的框架。

(1) 工作原理

一個包捕獲機制包含三個主要部分,分別是面向底層的包捕獲引擎,面向中間層的數據包過濾器,面向應用層的用戶接口。

Linux操作系統對於數據包的處理流程是從底到上的方式,依次經歷網絡接口卡、網卡驅動層、數據鏈路層、IP層、傳輸層,最後到達應用程序。

Libpcap也是基於這種原理,Libpcap的捕獲機制並不影響Linux操作系統中網絡協議棧對數據包的處理。

對應用程序而言,Libpcap包捕獲機制只是提供了一個統一的API接口,用戶只需要按照相關的編程流程,簡單地調用若干函數就可以捕獲到感興趣的數據包。

具體來說,Libpcap庫主要由三個部分組成,網絡分接頭、數據包過濾器和用戶API。

(1)網絡分接頭

網絡分接頭(Network Tap)是一種鏈路層旁路機制,負責採集網卡數據包。

(2) 數據包過濾器

數據包過濾器(Packet Filter)是針對數據包的一種過濾機制,在Libpcap中採用BPF(BSD Packet Filter)算法對數據包執行過濾操作,這種算法的基本思想就是基於規則匹配,對伊符合條件的額數據包進行放行。

(3) 用戶API

用戶API是Libpcap面向上層應用程序提供的編程接口,用戶通過調用相關的函數實現數據包的捕獲或者發送。

具體來說,Libpcap的工作原理可以描述爲,當一個數據包到達網卡時,Libpcap利用創建的套接字從鏈路層驅動程序中獲得該數據包的拷貝,即旁路機制,同時通過Tap函數將數據包發給BPF過濾器。

BPF過濾器根據用戶已經定義好的過濾過則對數據包進行逐一匹配,若匹配成功則放入內核緩衝區,並傳遞給用戶緩衝區,匹配失敗則直接丟棄。如果沒有設置過濾規則,所有的數據包都將放入內核緩衝區,並傳遞給用戶緩衝區。

其具體的工作流程如下圖所示:

抓包流程

理解了Libpcap的工作原理,下面將介紹如何利用Libpcap庫進行數據包的捕獲。其具體的編程流程如下:

(1) 網絡設備查找

網絡設備查找的目的就是發現可用的網卡,它的實現函數是pcap_lookupdev(),如果當前有多個網卡,它會返回一個網絡設備名指針列表。

(2) 打開網絡設備

利用第一步的返回值,用戶可以決定Libpcap實用哪個網卡,當然打開這個網絡設備的函數是pcap_open_live(),它返回用於捕獲網絡數據包的數據包捕獲描述字。對於此網絡設備的任何操作都要基於這個描述字。

(3) 獲取網絡參數

利用pcap_lookupnet()函數,可以獲得指定網絡設備的IP地址和子網掩碼,當然這個步驟並不是必須,但是爲了顯示的完整性,有時候還是需要標記這些參數。

(4) 編譯過濾策略

Libpcap的一個功能就是提供數據包過濾,即只採集符合規則的數據包,此項功能由函數pcap_compile()來實現,這個函數的作用即使將用戶指定的過濾策略編譯到過濾程序中。

(5) 設置過濾器

這是上步驟的繼續,pcap_setfilter()函數用於設置上一步驟配置好的過濾器,當然要註明一點,步驟4和步驟5也不是必須的,如果不採用過濾,意味着程序會抓到所有的網絡數據包。

(6) 利用回調函數捕獲數據包

Libpcap提供的是一種回調的機制來獲取數據包,可以採用pcap_loop()和pcap_dispatch()函數來抓取數據包,當然,也可以調用pcap_next和pcap_next_ex()函數來完成同樣的工作。

若數據包捕獲到之後,應用程序就可以採用相應的方式進行數據包解析,分析其中感興趣的信息,當然分析工作往往是整個程序的關鍵。

(7) 關閉網絡設備

當應用程序工作完畢時,可以調用pcap_close()函數關閉網絡設備,釋放資源。

具體工作流程如下所示:

 

Libpcap庫主要函數說明

函數名稱:pcap_t *pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf) 
函數功能:獲得用於捕獲網絡數據包的數據包捕獲描述字。 
參數說明:device參數爲指定打開的網絡設備名。snaplen參數定義捕獲數據的最大字節數。promisc指定是否將網絡接口置於混雜模式。to_ms參數指*定超時時間(毫秒)。ebuf參數則僅在pcap_open_live()函數出錯返回NULL時用於傳遞錯誤消息。 

函數名稱:pcap_t *pcap_open_offline(char *fname, char *ebuf) 
函數功能:打開以前保存捕獲數據包的文件,用於讀取。 
參數說明:fname參數指定打開的文件名。該文件中的數據格式與tcpdump和tcpslice兼容。”-“爲標準輸入。ebuf參數則僅在pcap_open_offline()函數出錯返回NULL時用於傳遞錯誤消息。 

函數名稱:pcap_dumper_t *pcap_dump_open(pcap_t *p, char *fname) 
函數功能:打開用於保存捕獲數據包的文件,用於寫入。 
參數說明:fname參數爲”-“時表示標準輸出。出錯時返回NULL。p參數爲調用pcap_open_offline()或pcap_open_live()函數後返回的pcap結構指針。fname參數指定打開的文件名。如果返回NULL,則可調用pcap_geterr()函數獲取錯誤消 息。 

函數名稱:char *pcap_lookupdev(char *errbuf) 
函數功能:用於返回可被pcap_open_live()或pcap_lookupnet()函數調用的網絡設備名指針。參數說明:如果函數出錯,則返回NULL,同時errbuf中存放相關的錯誤消息。 

函數名稱:int pcap_lookupnet(char *device, bpf_u_int32 *netp,bpf_u_int32 *maskp, char *errbuf) 
函數功能:獲得指定網絡設備的網絡號和掩碼。 
參數說明:netp參數和maskp參數都是bpf_u_int32指針。如果函數出錯,則返回-1,同時errbuf中存放相關的錯誤消息。 

函數名稱:int pcap_dispatch(pcap_t *p, int cnt,pcap_handler callback, u_char *user) 
函數功能:捕獲並處理數據包。 
參數說明:cnt參數指定函數返回前所處理數據包的最大值。cnt=-1表示在一個緩衝區中處理所有的數據包。cnt=0表示處理所有數據包,直到產生以下錯誤之一:讀取到EOF;超時讀取。callback參數指定一個帶有三個參數的回調函數,這三個參數爲:一個從pcap_dispatch()函數傳遞過來的u_char指針,一個pcap_pkthdr結構的指針,和一個數據包大小的u_char指針。如果成功則返回讀取到的字節數。讀取到EOF時則返回零值。出錯時則返回-1,此時可調用pcap_perror()或pcap_geterr()函數獲取錯誤消息。 

函數名稱:int pcap_loop(pcap_t *p, int cnt,pcap_handler callback, u_char *user) 
函數功能:功能基本與pcap_dispatch()函數相同,只不過此函數在cnt個數據包被處理或出現錯誤時才返回,但讀取超時不會返回。而如果爲pcap_open_live()函數指定了一個非零值的超時設置,然後調用pcap_dispatch()函數,則當超時發生時pcap_dispatch()函數會返回。cnt參數爲負值時pcap_loop()函數將始終循環運行,除非出現錯誤。 

函數名稱:void pcap_dump(u_char *user, struct pcap_pkthdr *h,u_char *sp) 
函數功能:向調用pcap_dump_open()函數打開的文件輸出一個數據包。該函數可作爲pcap_dispatch()函數的回調函數。 

函數名稱:int pcap_compile(pcap_t *p, struct bpf_program *fp,char *str, int optimize, bpf_u_int32 netmask) 
函數功能:將str參數指定的字符串編譯到過濾程序中。 
參數說明:fp是一個bpf_program結構的指針,在pcap_compile()函數中被賦值。optimize參數控制結果代碼的優化。netmask參數指定本地網絡的網絡掩碼。 

函數名稱:int pcap_setfilter(pcap_t *p, struct bpf_program *fp) 
函數功能:指定一個過濾程序。 
參數說明:fp參數是bpf_program結構指針,通常取自pcap_compile()函數調用。出錯時返回-1;成功時返回0。 

函數名稱:u_char *pcap_next(pcap_t *p, struct pcap_pkthdr *h) 
函數功能:返回指向下一個數據包的u_char指針。 

函數名稱:int pcap_datalink(pcap_t *p) 
函數功能:返回數據鏈路層類型,例如DLT_EN10MB。 

函數名稱:int pcap_snapshot(pcap_t *p) 
函數功能:返回pcap_open_live被調用後的snapshot參數值。 

函數名稱:int pcap_is_swapped(pcap_t *p) 
函數功能:返回當前系統主機字節與被打開文件的字節順序是否不同。 

函數名稱:int pcap_major_version(pcap_t *p) 
函數功能:返回寫入被打開文件所使用的pcap函數的主版本號。 

函數名稱:int pcap_minor_version(pcap_t *p) 
函數功能:返回寫入被打開文件所使用的pcap函數的輔版本號。 

函數名稱:int pcap_stats(pcap_t *p, struct pcap_stat *ps) 
函數功能:向pcap_stat結構賦值。成功時返回0。這些數值包括了從開始捕獲數據以來至今共捕獲到的數據包統計。如果出錯或不支持數據包統計,則返回-1,且可調用pcap_perror()或pcap_geterr()函數來獲取錯誤消息。 

函數名稱:FILE *pcap_file(pcap_t *p) 
函數功能:返回被打開文件的文件名。 

函數名稱:int pcap_fileno(pcap_t *p) 
函數功能:返回被打開文件的文件描述字號碼。 

函數名稱:void pcap_perror(pcap_t *p, char *prefix) 
函數功能:在標準輸出設備上顯示最後一個pcap庫錯誤消息。以prefix參數指定的字符串爲消息頭。 

函數名稱:char *pcap_geterr(pcap_t *p) 
函數功能:返回最後一個pcap庫錯誤消息。 

函數名稱:char *pcap_strerror(int error) 
函數功能:如果strerror()函數不可用,則可調用pcap_strerror函數替代。 

函數名稱:void pcap_close(pcap_t *p) 
函數功能:關閉p參數相應的文件,並釋放資源。 

函數名稱:void pcap_dump_close(pcap_dumper_t *p) 
函數功能:關閉相應的被打開文件。 

發佈了81 篇原創文章 · 獲贊 61 · 訪問量 25萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章