如何对scapy数据包进行序列化?

12 投票
6 回答
4744 浏览
提问于 2025-04-16 06:55

我需要把一个scapy数据包进行序列化。大部分情况下这个过程都很顺利,但有时候序列化工具会对一个函数对象发出警告。一般来说,ARP数据包序列化得很好,而有些UDP数据包就比较麻烦。

6 个回答

3

(这只是供参考,所以不需要投票)

Scapy的邮件列表scapy.ml@secdev.org管理得很好,通常回复也很快。如果你在这里没有得到答案,可以去那里试试。

4

如果你说的“pickle”是指一般性的序列化,那你可以使用 pcap 的导入/导出方法:rdpcap 和 wrpcap

wrpcap("pkt.pcap",pkt)
pkt = rdpcap("pkt.pcap")

或者你可以启动一个进程,然后在另一个进程中抓取数据包。如果你能找到某种模式,比如一个已知的端口或源 IP,tcpdump 就可以派上用场:

tcpdump -i eth0 -w FOO.pcap host 172.20.33.12 and \(udp or arp\)

然后你可以像上面那样读取生成的 pcap 文件:

pkts = rdpcap('FOO.pcap')
7

我的解决方案(灵感来自scapy邮件列表)如下:

class PicklablePacket:
    """A container for scapy packets that can be pickled (in contrast
    to scapy packets themselves)."""
    def __init__(self, pkt):
        self.contents = bytes(pkt)
        self.time = pkt.time

    def __call__(self):
        """Get the original scapy packet."""
        pkt = scapy.Ether(self.contents)
        pkt.time = self.time
        return pkt

在我想通过一个Queue传递scapyPacket时,我只需把它包裹在一个PicklablePacket里,然后再调用__call__。我不知道有什么数据是不能这样保留的。不过,这种方法只适用于Ethernet数据包。(在普通网络接口卡(不是无线局域网)上捕获的所有数据包都是以太网数据包。)不过,这个方法可能也可以扩展到其他类型的数据包。

撰写回答