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

Posted

技术标签:

【中文标题】Python Scapy wrpcap - 如何将数据包附加到 pcap 文件?【英文标题】:Python Scapy wrpcap - How do you append packets to a pcap file? 【发布时间】:2011-11-26 07:24:37 【问题描述】:

我有一些软件可以模拟网络上的 BER 和延迟。我需要一种方法来测试软件的 BER 模块,以确保它确实正常工作。我的解决方案是创建一个程序来发送原始以太网帧,并将类型字段设置为未使用的类型。以太网帧内部只是随机位。对于发送的每个帧,我需要将帧记录到pcap 文件中。在网络链接的另一端是一个接收应用程序,它简单地将它看到的每个数据包写入它自己的pcap 日志。测试完成后,将比较两个 pcap 日志以获取 BER。

我正在使用 python 模块Scapy,到目前为止它已经完成了我需要的一切。我可以发送带有随机数据的原始以太网帧,并在 Wireshark 中查看它们。但是,我不知道如何让 wrpcap() 方法附加到 pcap 文件,而不是覆盖。我知道我可以将数据包列表写入wrpcap,但是此应用程序需要能够无限期运行,我不想等到应用程序退出再写入发送到的所有数据包硬盘。因为要存储在内存中会很多,如果发生了什么事情,我将不得不从头开始测试。

我的问题是:如何使用scapy 附加到pcap 文件而不是覆盖pcap 文件?甚至可能吗?如果没有,那么什么模块可以做我需要的?

在寻找具有Scapy 功能的东西时,我遇到了dpkt,但我没有找到很多关于它的文档。 dpkt 可以按我的要求做吗?如果可以,我在哪里可以获得一些好的文档?

【问题讨论】:

【参考方案1】:

如果您包含关键字参数append=True,则可以使用wrpcap() 函数进行追加。例如:

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() 后关闭。

【讨论】:

【参考方案2】:

对于后代,PcapWriter 或 RawPcapWriter 看起来是在 scapy 2.2.0 中处理这个问题的更简单的方法。除了浏览源代码之外找不到太多文档。一个简单的例子:

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 变量,例如。 注 2:您可能想为附加数据包添加延迟。如果p 是列表pkt 中的每个数据包,您需要编码p.time = p.time + delay 文档在这里 FTR scapy.readthedocs.io/en/latest/api/…【参考方案3】:

我想我在跟踪你,因为数据包被嗅探你想让它们全部写入一个 pcap 文件吗?虽然您不能附加到 pcap,但您可以将数据包附加到列表中,然后一次将它们全部写入 pcap。

我不确定这是否能回答您的问题或是否有帮助,如果没有,请告诉我,我可以调整它以满足您的需求。在这个例子中,我设置了一个阈值,为每 500 个被嗅探的数据包创建一个新的 pcap。如果您运行两次,请小心,因为您的 pcaps 可能会在第二次运行时被覆盖。

#!/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。让我知道这是否适合您。

【讨论】:

【参考方案4】:

有一种方法可以做你想做的事,但这意味着:

[用一个大的pcap 占用内存]:用rdpcap() 从磁盘读取现有的pcapscapy PacketList(),然后在收到帧时将它们写入PacketList .您可以随意选择性地将中间PacketList 保存到pcap,但我认为scapywrpcap() 中没有类似附加功能。正如您所提到的,这种技术还意味着您将整个 PacketList 保留在内存中直到完成。

[将单个 pcap 文件粘合在一起]:仅将数据包的小快照保存在内存中...您应该每 X 分钟将 pcap 快照保存到磁盘,然后聚合这些单个脚本完成后将文件放在一起。

您可以将 linux 中的pcap 文件与wireshark 包中的mergecap 组合...以下命令将pak1.pcappak2.pcap 组合成all_paks.pcap

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

至于dpkt,我查看了他们的源代码,它可能能够增量写入数据包,但我不能说他们的代码库有多稳定或维护……它看起来有点被忽视了提交日志(最后一次提交是 2011 年 1 月 9 日)。

【讨论】:

以上是关于Python Scapy wrpcap - 如何将数据包附加到 pcap 文件?的主要内容,如果未能解决你的问题,请参考以下文章

使用 Python 2.7 在 Windows 上运行 Scapy

Scapy 和 Python 3.2

python scapy 能拿到请求与响应体吗

Python-Scapy 之类的-如何在数据包级别创建 HTTP GET 请求

scapy在Windows上的安装

在scapy中绑定自定义图层