I need to pickle a scapy
packet. Most of the time this works, but sometimes the pickler complains about a function object. As a rule of thumb: ARP packets pickle fine. Some UDP packets are problematic.
My solution (as inspired by the scapy mailing list) is as follows:
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
Anywhere I wish to pass a scapy
Packet
through a Queue
I simply wrap it in a PicklablePacket
and __call__
it afterwards. I am not aware of data that is not retained this way. However this approach only works with Ethernet
packets. (All packets sniffed on a regular NIC (not WLAN) are Ethernet.) It could probably be extended to work for other types, too.
If by pickle you mean generically serialize you can always use the pcap import/export methods: rdpcap and wrpcap.
wrpcap("pkt.pcap",pkt)
pkt = rdpcap("pkt.pcap")
Or you could start up your process and grab the packets in another process. If there is some pattern you can match, say a known port or source IP tcpdump will work:
tcpdump -i eth0 -w FOO.pcap host 172.20.33.12 and \(udp or arp\)
You can then read the generated pcap in as above:
pkts = rdpcap('FOO.pcap')
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With