Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pickle a scapy packet?

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.

like image 731
Helmut Grohne Avatar asked Nov 11 '10 15:11

Helmut Grohne


2 Answers

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.

like image 195
Helmut Grohne Avatar answered Oct 14 '22 00:10

Helmut Grohne


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')
like image 37
Paul Rubel Avatar answered Oct 14 '22 02:10

Paul Rubel