首頁 > 軟體

python3使用libpcap庫進行抓包及資料處理的操作方法

2022-11-01 14:03:16

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)。

pypi地址:https://pypi.org/project/libpcap/

github 地址:https://github.com/karpierz/libpcap

一、安裝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'DeviceNPF_{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

      範例程式碼及執行效果:

      三、資源下載

      本文涉及libpcap原始碼及whl檔案,可從百度網路硬碟獲取:

      連結: https://pan.baidu.com/s/1u6MtBVUa2aM-C-Xq-EGU3Q?pwd=pwrq

      提取碼: pwrq 

      到此這篇關於python3使用libpcap庫進行抓包及資料處理的操作方法的文章就介紹到這了,更多相關python libpcap庫抓包資料處理內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


      IT145.com E-mail:sddin#qq.com