除了Pyshark,如何更快速地读取.cap文件而不是使用Scapy的rdpcap()?
我一直在寻找一种方法,把802.11数据包从.cap文件中提取到一个数组里。目前我发现了以下几种工具:
Scapy:这个工具还不错,有文档可以参考,但速度太慢了。当我尝试打开一个超过40MB的文件时,它会一直卡住,直到把我所有的内存(16GB)都用完,这样我的电脑就会死机,我不得不重启。
Pyshark:这个工具没有Scapy的问题,但文档太少,我找不到处理和获取802.11数据包属性的方法。
所以我在想,可能还有更好的解决方案,或者有人对pyshark有经验吗?
from scapy.all import *
import pyshark
from collections import defaultdict
import sys
import math
import numpy as np
counter=0
Stats = np.zeros((14))
filename='cap.cap'
a = rdpcap(filename)
print len(a)
for p in a:
pkt = p.payload
#Management packets
if p.haslayer(Dot11) and p.type == 0:
ipcounter = ipcounter +1
Stats[p.subtype] = Stats[p.subtype] + 1
print Stats
注意:当我用一个10MB的输入文件启动程序时,大约需要20秒左右,但它确实能工作。我在想这是为什么,为什么和pyshark差别这么大,它到底在做什么计算?
6 个回答
你试过 dpkt
吗?它有一个很不错的读取器接口,似乎可以懒加载数据包(我用它加载过超过100MB的pcap文件,没问题)。
示例:
from dpkt.pcap import Reader
with open(...) as f:
for pkt in Reader(f):
...
with PcapReader('filename.pcapng') as pcap_reader:
for pkt in pcap_reader:
#do something with the packet
...
这个效果很好!
PcapReader就像把xrange()替换成range()一样
如果pyshark满足你的需求,你可以这样使用它:
cap = pyshark.FileCapture('/tmp/mycap.cap')
for packet in cap:
my_layer = packet.layer_name # or packet['layer name'] or packet[layer_index]
想要查看有哪些可用的层和它们的属性,只需打印出来(或者使用layer/packet.pretty_print()),或者使用自动补全功能,或者查看packet.layer._all_fields。例如,你可以使用packet.udp.srcport。
文档中缺少了什么呢?
请注意,你还可以在FileCapture实例中添加一个过滤器作为参数(可以是显示过滤器或BPF过滤器,具体可以查看文档)。
Scapy会把所有的数据包加载到你的内存中,并创建一个packetList的实例。我觉得你可以通过两种方法来解决这个问题。
- 使用过滤器来捕获数据包。在我的工作中,我从来没有捕获过超过2MB的数据包,因为我只在一个无线频道上捕获一次。
- 把大的数据包文件分成几个小部分,然后再处理它们。
希望这些建议对你有帮助。
你可以对一个叫做 utils.py 的 scapy 文件进行修改,这样它就不会把所有东西都加载到内存里。
把:
def read_all(self,count=-1):
"""return a list of all packets in the pcap file
"""
res=[]
while count != 0:
count -= 1
p = self.read_packet()
if p is None:
break
res.append(p)
return res
改成
def read_all(self,count=-1):
"""return an iterable of all packets in the pcap file
"""
while count != 0:
count -= 1
p = self.read_packet()
if p is None:
break
yield p
return
感谢来源于: http://comments.gmane.org/gmane.comp.security.scapy.general/4462
不过这个链接现在已经失效了。