python3使用libpcap庫進行抓包及數據處理

python版本:python 3.9

libpcap版本:1.11.0b7

python libpcap庫是底層綁定c語言libpcap庫的開發包,旨在提供python應用可訪問的unix c libpcap庫API(以及爲win32系統提供的Npcap、WinPcap),直接使用底層c代碼,性能很好。
這裏記錄下Windows 10 環境下python3.9如何安裝及使用libpcap庫(Linux和mac系統可參考Windows)。

一、安裝libpcap庫

1、在線安裝

直接使用pip進行安裝:
pip install libpcap
默認安裝最新版本。

 

2、離線安裝

2.1 下載離線安裝文件

可以在pypi頁面源代碼或whl文件。

 2.2  執行離線安裝操作

1) 可以使用源碼進行安裝

解壓文件到當前目錄,然後執行安裝命令:

python -m pip install ./libpcap-1.11.0b7

 2)也可以使用whl文件進行離線安裝

安裝命令如下:

python -m pip install libpcap-1.11.0b7-py3-none-any.whl

二、使用libpcap庫

1、導入及指定pcap庫

import libpcap
libpcap.config(LIBPCAP="wpcap")

2、常用API介紹

tcpdump就是以libpcap爲基礎實現的,c語言libpcap的文檔可以在tcpdump官網找的:

https://www.tcpdump.org/manpages/pcap.3pcap.html

 

這裏描述下python常用接口。 

2.1  獲取網絡設備接口

  • lookupdev(errbuf)

功能:該函數用於查找網絡設備,返回的值可以被open_live函數直接調用。

參數:

    errbuf爲c語言字符串類型,用於獲取錯誤信息。

使用示例:

import ctypes as ct
import libpcap as pcap
errbuf = ct.create_string_buffer(pcap.PCAP_ERRBUF_SIZE + 1)
device = pcap.lookupdev(errbuf)
print(errbuf.value)
  • findalldevs(alldevs, errbuf)

功能:該函數用於查找所有網絡設備。

參數:

     alldevs爲pcap_if_t結構體指針,用於存儲查找到的所有網絡設備信息。

     errbuf爲c語言字符串類型,用於獲取錯誤信息。

使用示例:

import ctypes as ct
import libpcap as pcap
errbuf = ct.create_string_buffer(pcap.PCAP_ERRBUF_SIZE + 1)
alldevs = ct.POINTER(pcap.pcap_if_t)()    
pcap.findalldevs(ct.byref(alldevs), errbuf)
print(alldevs[0].name)
pcap.freealldevs(alldevs)

2.2 抓包接口

  • open_live(device:bytes,snaplen:int,promisc:int,to_ms:int,errbuf)

功能:該函數用於打開一個用於捕獲數據的網絡設備

參數:

    device爲網絡接口的名字,可通過api獲取,也可以人爲指定,如:"eth0"

    snaplen是捕獲數據包的長度,不能大於65535

    promise用於標記是否開啓混雜模式,1代表混雜模式,其它值代表非混雜模式

    to_ms代表需要等待的毫秒數,超過這個時間後,獲得數據包的函數會立即返回,0表示一直等待直到有數據包到來

    errbuf爲c語言字符串類型,用於獲取錯誤信息。

返回值:返回pcap_t類型指針,後面的所有操作都要使用這個指針。

使用示例:

import ctypes as ct
import libpcap as pcap
device = b'eth0' # linux 
errbuf = ct.create_string_buffer(pcap.PCAP_ERRBUF_SIZE + 1)
handle = pcap.open_live(device,4096,1,1000,errbuf)
if errbuf.value:
    print("hanle error :",errbuf.value)
  • open_offline(fname:bytes,errbuf)

功能:該函數用於打開離線抓包文件

參數:

    fname爲文件名稱,比如:b"/tmp/test1.cap"

    errbuf爲c語言字符串類型,用於獲取錯誤信息。

返回值:返回pcap_t類型指針,後面的所有操作都要使用這個指針。

使用示例:

import ctypes as ct
import libpcap as pcap
errbuf = ct.create_string_buffer(pcap.PCAP_ERRBUF_SIZE + 1)
handle = pcap.open_offline(fname,errbuf)
if errbuf.value:
    print("hanle error :",errbuf.value)

2.3 數據包獲取接口

  • next(handle,pheader)

功能:該函數用於獲取數據包,一次只獲取一個包。

參數:

    handle爲pcap_t類型指針

    pheader爲pcap_pkthdr結構體指針,可通過pkthdr函數創建

返回值:返回u_char類型指針,代表包數據,可使用struct.unpack函數解析

使用示例:

import libpcap as pcap

pheader = pcap.pkthdr()
packet = pcap.next(handle,pheader)

2.4 寫文件接口

  • dump_open(handle,fname:bytes)

功能:該函數用於打開文件,存儲獲取到的數據包。

參數:

    handle爲pcap_t類型指針

    fname爲文件名稱

返回值:返回pcap_dumper_t 類型指針,後面的所有操作都要使用這個指針。

使用示例:

import libpcap as pcap

fname = b"realtime1.cap"
fPcap = pcap.dump_open(handle,fname)
  • dump(handle,pheader,packet)

功能:該函數用於存儲獲取到的數據包。

參數:

    handle爲pcap_dumper_t類型指針

    pheader爲pcap_pkthdr結構體指針

    packet是數據包

返回值:無返回值

使用示例:

fPcapUbyte = ct.cast(fPcap,ct.POINTER(ct.c_ubyte))
pcap.dump(fPcapUbyte,pheader,packet)
  • dump_flush(handle)

功能:該函數用於將緩存的數據刷到磁盤

參數:

    handle爲pcap_dumper_t類型指針

返回值:錯誤碼,0代表成功,-1代表出錯

2.5 資源釋放接口 

  • close(handle)

功能:釋放pcap_t類型指針

參數:

    handle爲pcap_t類型指針

返回值:無返回值

  • dump_close(handle)

功能:釋放pcap_dumper_t類型指針

參數:

    handle爲pcap_dumper_t類型指針

返回值:無返回值 

3、典型使用場景

3.1、網卡實時抓包

可以使用libpcap庫進行網卡實時數據抓包,這裏進行簡單的示例:

1)首先需要獲取或指定抓包設備

方法1 :指定網卡接口名稱

device = b'\Device\NPF_{BFDBF91E-9848-417D-B8AB-D3ED19990717}' # windows

device = b'eth0' # linux

Windows網卡接口名稱可在wireshark的捕獲界面看到,具體如下:

 linux網卡名稱獲取:ifconfig

方法2 :使用lookupdev獲取網卡接口名稱

device = pcap.lookupdev(errbuf)

方法3 :使用findalldevs獲取網卡接口名稱

alldevs = ct.POINTER(pcap.pcap_if_t)()

pcap.findalldevs(ct.byref(alldevs), errbuf)

device =alldevs[0].name

2)使用open_live函數進行網卡抓包;

3)使用pkthdr函數創建header,獲取包頭信息(時間戳、包大小);

4)使用next函數循環讀取數據包,需要注意的是,獲取的packet對象的contents是C語言類型,需要使用它ctypes的pointer函數進行轉換;

5)數據包(比如IP頭)的解析可使用struct的unpack函數;

6)如果要將抓包數據存盤,可使用dump_open、dump、dump_flush系列函數進行操作,需要注意的是,dump_open函數的第二個參數必須是byte類型;

示例代碼及運行效果:

完整代碼獲取途徑:

關注微信公衆號(聊聊博文,文末可掃碼)後回覆 202210290101 獲取。

3.2、離線數據解析

可以使用libpcap庫進行離線抓包文件的解析,這裏進行簡單的示例:
1)首先需要使用open_offline函數打開pcap文件,需要注意的是,函數的第一個參數必須是byte類型;
2)使用pkthdr函數創建header,獲取包頭信息(時間戳、包大小)​;
3)使用next函數循環讀取數據包,需要注意的是,獲取的packet對象的contents是C語言類型,需要使用它ctypes的pointer函數進行轉換​;
4)數據包(比如IP頭)的解析可使用struct的unpack函數​;
 
示例代碼及運行效果:

完整代碼獲取途徑:

關注微信公衆號(聊聊博文,文末可掃碼)後回覆 202210290102 獲取。
 
3.3、使用過濾條件抓包

網卡實時抓包和離線數據解析時,可以設置過濾條件,避免數據量過大。

過濾條件示例:

1) 過濾IP

  • host 過濾某個ip的所有包

host 8.8.8.8

  • src 過濾源ip

src 8.8.8.8

  • dst過濾目的ip

dst  8.8.8.8

2)過濾端口

  • port進行單個端口過濾

port 22

  • portange進行多個端口過濾

portange 1-1024

  • 可使用src或dst指定端口方向

src port 22

dst port 22

3)指定協議

tcp

udp

icmp

4)使用組合條件

  • and 進行與邏輯

src localhost and dst port 22

src localhost && dst port 22

  • or 進行或邏輯

port 80 or 22

port 80 || 22

 

示例代碼及運行效果:

完整代碼獲取途徑:

關注微信公衆號(聊聊博文,文末可掃碼)後回覆 202210290103 獲取。

三、資源下載

本文涉及libpcap源代碼及whl文件,可從百度網盤獲取:
關注微信公衆號(聊聊博文,文末可掃碼)後回覆 2022102901 獲取。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章