2010-11-11 12 views
12

Ich muss ein scapy Paket pickle. Die meiste Zeit funktioniert das, aber manchmal beschwert sich der Abbeißer über ein Funktionsobjekt. Als Faustregel gilt: ARP-Pakete picken gut. Einige UDP-Pakete sind problematisch.Wie man ein scapy Paket einläßt?

+0

Hintergrund ist die Nutzung in Verbindung mit dem 'multiprocessing' Modul. Es erfordert, dass Objekte auswählbar sind, wenn Sie sie durch eine "Warteschlange" übertragen möchten. –

+0

Kann jemand diese Frage beantworten, also kann ich das Kopfgeld vergeben? –

Antwort

7

Meine Lösung (wie von der scapy Mailingliste inspiriert) ist wie folgt:

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 

Überall ich scapyPacket durch eine Queue passieren möchte ich es einfach in einem PicklablePacket und __call__ es wickeln danach. Mir sind keine Daten bekannt, die auf diese Weise nicht gespeichert werden. Dieser Ansatz funktioniert jedoch nur mit Ethernet Paketen. (Alle Pakete, die auf einem normalen NIC (nicht WLAN) geschnüffelt werden, sind Ethernet.) Es könnte wahrscheinlich erweitert werden, um auch für andere Typen zu arbeiten.

+0

Danke für die Rückmeldung. Während ich deine genaue Lösung nicht brauchte, half es mir, mein eigenes zu finden. –

3

(Diese mehr als Referenz, so dass keine Stimmen erwartet)

Die scapy Liste [email protected] ist gut überwacht und sehr reaktionsschnell sein tendiert. Wenn Sie hier keine Antworten erhalten, versuchen Sie es auch.

+0

Oh, hier geht die Kommunikation weiter? Der Issue Tracker scheint ziemlich inaktiv zu sein. Mindestens einer meiner Käfer blieb dort ein halbes Jahr ohne Antwort. –

+1

als eine Randnotiz, 500 Pakete pro Sekunde könnte mehr sein als Scapy auch behandelt. Es ist für Flexibilität und Geschwindigkeit ausgelegt :) Fragen Sie auf der Liste.Ich benutze es nicht wirklich, also bin ich kein Experte. –

+0

Eigentlich kann ich bestätigen, dass scapy 500 Pakete pro Sekunde sehr gut verarbeitet. Zugegeben, ich benutze mehr als einen Thread und (nach dieser Frage) mehr als einen Prozess. –

4

Wenn Sie mit pickle meinen, generisch serialisieren, können Sie immer die pcap Import/Export-Methoden verwenden: rdpcap and wrpcap.

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

Oder Sie könnten Ihren Prozess starten und die Pakete in einem anderen Prozess greifen. Wenn es einige Muster können Sie übereinstimmen, sagen eine bekannte Port oder Quell-IP-tcpdump arbeiten:

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

Sie dann die erzeugte pcap in wie oben lesen können:

pkts = rdpcap('FOO.pcap') 
+0

1) Ich spreche über 500 Pakete pro Sekunde. –

+0

2) Diese Methode verliert tatsächlich Daten. Zum Beispiel ist der Zeitstempel gerundet. Dies ist nicht unbedingt ein Problem, muss aber berücksichtigt werden. –

+0

Kann Scrapy sogar 500 Pakete pro Sekunde ausstoßen? Ich habe festgestellt, dass es beim Senden von Paketen viel weniger ist. Sie könnten immer einen tcpdump in einem anderen Terminal ausführen. –

0

Sie die Packet monkeypatch können Klasse und injizieren __getstate__ und __setstate__ Methoden, die die Funktion im Objekt von und in eine Pickle-Darstellung konvertieren. Details finden Sie unter here.

def packet_getstate(self): 
    # todo 

def packet_setstate(self, state): 
    # todo 

from scapy.packet import Packet 
Packet.__getstate__ = packet_getstate 
Packet.__setstate__ = packet_setstate 
+1

Das ist für mich offensichtlich. Der nicht-offensichtliche Teil ist der Todo-Teil. –

+0

Interaktives Überprüfen eines 'Packet' -Objekts, das das Beizen nicht ausführt (' pprint.pprint (packet .__ dict __) ') würde leicht zeigen, was die Funktion ist, wenn es sich um eine Lambda-Funktion oder eine Instanzmethode handelt. Weißt du schon was für eine Funktion? – piro

+0

Der vollständige Traceback ist zu lang für einen Kommentar, aber Sie können diesen selbst leicht reproduzieren. Die letzte Zeile lautet: pickle.PicklingError: Kann bei 0x8bb2bc4> nicht pürieren: es wird nicht als scapy.layers.inet gefunden.

1

Wie von dieser question inspiriert kann man die dill Bibliothek (oder andere wie sPickle etc - siehe pypi search pickle), um scapy Pakete zu speichern. Z.B. Installieren Sie Dill mit sudo easy_install dill oder sudo pip install dill. Hier ist eine grundlegende Nutzungsszenario:

import dill as pickle 
# E.g. Dump an array of packets stored in variable mypackets to a file 
pickle.dump(mypackets, open('mypackets.dill-pickle', 'w')) 
# Restore them from the file 
mypackets = pickle.load(open('mypackets.dill-pickle', 'rb')) 

Auch eine natürlich kann nur scapy nativen Funktionen verwenden, um die Pakete zu einer pcap-Datei (lesbar tcpdump/wireshark usw.) zu entleeren - wenn man nur eine Reihe von Paketen hat:

wrpcap("packets_array.pcap",packets_array) 
0

die PicklabePacket Klasse um mit scapy zu arbeiten 3.0.0 Sie diese Klassendefinition verwenden können:

class PicklablePacket: 
"""A container for scapy packets that can be pickled (in contrast 
to scapy packets themselves). 
This works for python 3.5.1 and scapy 3.0.0 """ 

def __init__(self, pkt): 
    self.__contents = pkt.__bytes__() 
    self.__time = pkt.time 

def __call__(self): 
    """Get the original scapy packet.""" 
    pkt = scapy.all.Ether(self.__contents) 
    pkt.time = self.__time 
    return pkt 
Verwandte Themen