Python Scapy wrpcap - 如何将数据包追加到pcap文件中?

14
我有一些软件可以模拟网络中的BER和延迟。我需要一种方法来测试该软件的BER模块,以确保它实际上可以正常工作。我的解决方案是创建一个程序,发送原始以太网帧,类型字段设置为未使用的类型。以太网帧内只包含随机位。对于每个发送的帧,我需要将其记录到pcap文件中。在网络链路的另一端将是一个接收应用程序,它将每个看到的数据包写入自己的pcap日志中。在测试运行完成后,将比较两个pcap日志以获取BER。
我正在使用Python模块Scapy,并且到目前为止它已经做了我需要的一切。我可以发送具有随机数据的原始以太网帧并在Wireshark中看到它们。但是,我不知道如何使wrpcap()方法附加到pcap文件而不是覆盖它。我知道我可以将数据包列表写入wrpcap,但是该应用程序需要能够运行无限长时间,并且我不想等到应用程序退出才将所有发送的数据包写入硬盘。因为那将占用很多内存,如果出现问题,我将不得不从头开始重新测试。
我的问题是:如何使用Scapy附加到pcap文件而不是覆盖pcap文件?它是否可能?如果不是,那么哪个模块可以做到我所需要的?在寻找具有Scapy功能的内容时,我遇到了dpkt,但是我没有找到太多的文档。dpkt能否满足我的要求,如果可以,那么在哪里可以找到一些好的文档?
4个回答

21

为了后代的利益,在scapy 2.2.0中,PcapWriter或RawPcapWriter似乎是处理这个问题更容易的方法。除了浏览源代码之外,我没有找到太多的文档。以下是一个简单的例子:

from scapy.utils import PcapWriter

pktdump = PcapWriter("banana.pcap", append=True, sync=True)

...
pktdump.write(pkt)
...

真遗憾没有Pcap写入文档。源代码中“append”参数的链接:scapy utils @ github。请注意,您需要使用“pkt=rdpcap(pcap_file)”来填充pkt变量,例如。 - Jaime M.
注意2:如果您想为追加数据包添加延迟。如果p是列表pkt中的每个数据包,您需要编写p.time = p.time + delay的代码。 - Jaime M.
文档在此处 FTR https://scapy.readthedocs.io/en/latest/api/scapy.utils.html#scapy.utils.PcapWriter - Cukic0d

8

有一种方法可以实现你想要的,但这意味着需要:

  • [使用一个大的pcap文件占用内存]: 用rdpcap()从磁盘中读取现有的pcap文件,并将帧写入PacketList中,按照接收到的顺序选择性地将中间PacketList保存到pcap文件中,不过我认为scapywrpcap()没有类似于追加的功能。如你所提到的,这种技术也意味着在完成之前,需要将整个PacketList保存在内存中。

  • [将各个小的pcap文件粘合起来]: 只需在内存中保留少量数据包的快照即可......每隔X分钟将pcap的快照保存到磁盘上,然后在脚本结束时将这些单独的文件聚合在一起。

你可以使用Linux中的wireshark软件包中的mergecappcap文件合并......以下命令将pak1.pcappak2.pcap合并成all_paks.pcap

mergecap -w all_paks.pcap pak1.pcap pak2.pcap

关于 dpkt,我查看了他们的源代码,可能可以逐步编写数据包,但是我无法确定他们的代码库稳定性和维护情况...从提交日志中看起来有点被忽视了(最后一次提交是2011年1月9日)。

2
wrpcap()函数可以用于追加,如果您包括关键字参数append=True。例如:
pkt = IP()
wrpcap('/path/to/filename.pcap', pkt, append=True)
pkt2 = IP()
wrpcap('/path/to/filename.pcap', pkt2, append=True)

rdpcap('/path/to/filename.pcap')

<filename.pcap: TCP:0 UDP:0 ICMP:0 Other:2>

顺便提一下:每次调用wrpcap时,它都会打开并关闭文件句柄。如果您有一个打开的pcap文件句柄,在调用wprcap()后,该句柄将被关闭。


0

我想我明白你的意思了。你想将被嗅探到的所有数据包写入单个pcap文件中,对吧?尽管无法将数据包追加到现有的pcap文件中,但是您可以将数据包追加到列表中,然后一次性将它们全部写入pcap文件。

如果我的回答没有解决问题或无法帮助你,请告诉我,我可以进行调整以满足您的需求。在这个例子中,我设置了阈值,每嗅探500个数据包就会创建一个新的pcap文件。请注意,如果您运行两次此操作,可能会覆盖您的pcap文件。

#!/usr/bin/python -tt

from scapy.all import *

pkts = []
iter = 0
pcapnum = 0

def makecap(x):
    global pkts
    global iter
    global pcapnum
    pkts.append(x)
    iter += 1
    if iter == 500:
        pcapnum += 1
        pname = "pcap%d.pcap" % pcapnum
        wrpcap(pname, pkts)
        pkts = []
        iter = 0

while 1:
    sniff(prn=makecap)

这应该会给你一些优势,但是最后几个数据包可能会丢失(降低if语句中的值以减轻此问题)。建议同时在两侧使用它,以便每个pcap都能对齐,稍后您可以像Mike建议的那样使用mergepcap。如果这对你有用,请告诉我。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接