使用 scapy 解析 pcap 文件

svi*_*ink 7 python parsing scapy python-2.7 dpkt

我正在比较 scapy 和 dpkt 的速度。我有一个包含 pcap 文件的目录,我解析并计算每个文件中的 http 请求。这是 scapy 代码:

import time
from scapy.all import *

def parse(f):
 x = 0
 pcap = rdpcap(f)
 for p in pcap:
    try:
        if p.haslayer(TCP) and p.getlayer(TCP).dport == 80 and p.haslayer(Raw):
            x = x + 1
    except:
        continue
print x

if __name__ == '__main__':\

  path = '/home/pcaps'
  start = time.time()
  for file in os.listdir(path):
    current = os.path.join(path, file)
    print current
    f = open(current)
    parse(f)
    f.close()
 end = time.time()
 print (end - start)
Run Code Online (Sandbox Code Playgroud)

与 dpkt 版本相比,该脚本确实很慢(几分钟后就会卡住):

import dpkt
import time
from os import walk
import os
import sys


def parse(f):
 x = 0
 try:
    pcap = dpkt.pcap.Reader(f)
 except:
    print "Invalid Header"
    return
 for ts, buf in pcap:
        try:
            eth = dpkt.ethernet.Ethernet(buf)
        except:
            continue
        if eth.type != 2048:
             continue
        try:
            ip = eth.data
        except:
            continue

        if ip.p == 6:
            if type(eth.data) == dpkt.ip.IP:
                tcp = ip.data


                if tcp.dport == 80:
                    try:
                        http = dpkt.http.Request(tcp.data)
                        x = x+1
                    except:
                        continue

print x

if __name__ == '__main__':

path = '/home/pcaps'
start = time.time()
for file in os.listdir(path):
    current = os.path.join(path, file)
    print current
    f = open(current)
    parse(f)
    f.close()
end = time.time()
print (end - start)
Run Code Online (Sandbox Code Playgroud)

那么我使用 scapy 的方式有问题吗?或者只是 scapy 比 dpkt 慢?

Eva*_*van 1

你激励我进行比较。2 GB 投射电容。哑巴测试。简单地计算数据包的数量。

我预计 C++/libpcap 的时间单位为个位数分钟,仅基于类似大小文件的先前计时。但这是新事物。我想先制作原型。一般来说,我使用 Python 的速度比较快。

对于我的应用程序,流式传输是唯一的选择。我将同时阅读其中几个 PCAP,并根据其内容进行计算。不能只留在记忆里。所以我只是比较流式调用。

斯卡比 2.4.5:

from scapy.all import *
import datetime

i=0
print(datetime.datetime.now())
for packet in PcapReader("/my.pcap"):
    i+=1
else:
    print(i)
    print(datetime.datetime.now())
Run Code Online (Sandbox Code Playgroud)

数据包 1.9.7.2:

import datetime
import dpkt
print(datetime.datetime.now())
with open(pcap_file, 'rb') as f:
    pcap = dpkt.pcap.Reader(f)
    i=0
    for timestamp, buf in pcap:
        i+=1
    else:
        print(i)
        print(datetime.datetime.now())
Run Code Online (Sandbox Code Playgroud)

结果:

数据包计数相同。所以这样很好。:-)

dkpt - 不到 10 分钟。

scapy - 35 分钟。

dkpt 走在了前面。因此,如果磁盘缓存对某个包有帮助,那么它就是 scapy。我认为这可能是微乎其微的。我之前只用 scapy 做过这个,花了 40 多分钟。

总之,感谢您提出 5 年前的问题。今天它仍然具有现实意义。由于 scapy 的读取速度过长,我几乎放弃了 Python。dkpt 似乎性能更高。

旁注,替代包:

https://pypi.org/project/python-libpcap/ 不幸的是,我使用的是 python 3.10,0.4.0 对我来说似乎已经损坏了。

https://pypi.org/project/libpcap/ 我想将时间与此进行比较,但发现要获得一个最小的示例要困难得多。不过公平地说,我并没有花太多时间。