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

14 投票
4 回答
31642 浏览
提问于 2025-04-17 03:13

我有一些软件可以模拟网络上的比特错误率(BER)和延迟。我需要一种方法来测试这个软件的BER模块,以确保它能正常工作。我的解决方案是创建一个程序,发送原始的以太网帧,并把类型字段设置为一个未使用的类型。在这个以太网帧里只是一些随机的比特。每发送一个帧,我需要把这个帧记录到一个pcap文件里。在网络连接的另一端,会有一个接收应用程序,它会把看到的每一个数据包都写入自己的pcap日志。测试结束后,我会比较这两个pcap日志,以计算BER。

我正在使用Python的Scapy模块,到目前为止,它能满足我的所有需求。我可以发送带有随机数据的原始以太网帧,并在Wireshark中看到它们。然而,我不知道怎么让wrpcap()方法在pcap文件中追加内容,而不是覆盖它。我知道可以把一个数据包列表写入wrpcap,但这个应用程序需要无限期运行,我不想等到应用程序退出后再把所有发送的数据包写入硬盘。因为那样会占用很多内存,如果发生什么事情,我就得从头开始测试。

我的问题是:如何使用scapypcap文件追加内容,而不是覆盖它?这可能吗?如果不行,那有什么模块可以满足我的需求?

在寻找Scapy功能时,我遇到了dpkt,但没有找到很多相关文档。dpkt能做到我想要的功能吗?如果可以,在哪里可以找到好的文档呢?

4 个回答

3

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文件的句柄,在调用wrpcap()之后,它会被关闭。

21

为了将来参考,PcapWriter 或者 RawPcapWriter 在 scapy 2.2.0 中似乎是处理这个问题的更简单的方法。不过,除了查看源代码,我没找到太多文档。这里有一个简单的例子:

from scapy.utils import PcapWriter

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

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

有一种方法可以实现你想要的,但这意味着你需要选择以下两种方式之一:

  • [占用内存较多,使用一个大pcap文件]:从磁盘读取现有的pcap文件,使用rdpcap()将其加载到scapyPacketList()中,然后在接收到数据包时将它们写入这个PacketList。你可以选择性地将中间的PacketList保存到pcap文件中,但我认为scapywrpcap()没有追加的功能。正如你提到的,这种方法也意味着在完成之前,你需要将整个PacketList保存在内存中。

  • [将单个pcap文件合并]:只在内存中保留小的快照...你应该每隔几分钟将pcap快照保存到磁盘,然后在脚本完成时将这些单独的文件合并在一起。

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

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

至于dpkt,我查看了它的源代码,它可能能够逐步写入数据包,但我不能保证它的代码库有多稳定或维护得多好...从提交记录来看,它看起来有点被忽视(最后一次提交是在2011年1月9日)。

撰写回答