2016-07-26 6 views
1

Ich muss lesen und analysieren. Pcap-Dateien, die zu groß sind, um in den Speicher geladen werden. Ich bin derzeit sniff im Offline-ModusWie scapy Leistung zu verbessern, große Dateien zu lesen

sniff(offline=file_in, prn=customAction, store=0) 

mit einer Custom Funktion, die in etwa wie folgt aussieht:

customAction(packet): 
    global COUNT 
    COUNT = COUNT + 1 
    # do some other stuff that takes practically 0 time 

Derzeit wird diese Pakete verarbeitet zu langsam. Ich benutze bereits Subprozess in einem 'Treiber' Programm, um dieses Skript auf mehreren Dateien gleichzeitig auf verschiedenen Kernen laufen zu lassen, aber ich muss wirklich die Single-Core-Leistung verbessern.

Ich versuchte mit Pypy und war enttäuscht, dass die Leistung mit Pypy weniger als 10% besser als mit python3 (Anaconda).

Durchschnittliche Zeit 50k Pakete mit PyPy ist 52,54 Sekunden laufen

Durchschnittliche Zeit zu laufen 50k Pakete mit python3 ist 56,93 Sekunden

Gibt es eine Möglichkeit, Dinge zu beschleunigen?

BEARBEITEN: Unten ist das Ergebnis von cProfile, wie Sie sehen können, ist der Code ein wenig langsamer, während profiliert wird, aber die ganze Zeit damit verbracht wird, Dinge zu tun, ist scapy.

66054791 function calls (61851423 primitive calls) in 85.482 seconds 

Ordered by: cumulative time 

ncalls   tottime percall cumtime percall filename:lineno(function) 
957/1    0.017 0.000 85.483 85.483 {built-in method builtins.exec} 
    1    0.001 0.001 85.483 85.483 parser-3.py:1(<module>) 
    1    0.336 0.336 83.039 83.039 sendrecv.py:542(sniff) 
50001    0.075 0.000 81.693 0.002 utils.py:817(recv) 
50001    0.379 0.000 81.618 0.002 utils.py:794(read_packet) 
795097/50003  3.937 0.000 80.140 0.002 base_classes.py:195(__call__) 
397549/50003  6.467 0.000 79.543 0.002 packet.py:70(__init__) 
397545/50000  1.475 0.000 76.451 0.002 packet.py:616(dissect) 
397397/50000  0.817 0.000 74.002 0.001 packet.py:598(do_dissect_payload) 
397545/200039  6.908 0.000 49.511 0.000 packet.py:580(do_dissect) 
199083   0.806 0.000 32.319 0.000 dns.py:144(getfield) 
104043   1.023 0.000 22.996 0.000 dns.py:127(decodeRR) 
397548   0.343 0.000 15.059 0.000 packet.py:99(init_fields) 
397549   6.043 0.000 14.716 0.000 packet.py:102(do_init_fields) 
6673299/6311213 6.832 0.000 13.259 0.000 packet.py:215(__setattr__) 
3099782/3095902 5.785 0.000 8.197 0.000 copy.py:137(deepcopy) 
3746538/2335718 4.181 0.000 6.980 0.000 packet.py:199(setfieldval) 
149866   1.885 0.000 6.678 0.000 packet.py:629(guess_payload_class) 
738212   5.730 0.000 6.311 0.000 fields.py:675(getfield) 
1756450   3.393 0.000 5.521 0.000 fields.py:78(getfield) 
49775    0.200 0.000 5.401 0.000 dns.py:170(decodeRR) 
1632614   2.275 0.000 4.591 0.000 packet.py:191(__getattr__) 
985050/985037  1.720 0.000 4.229 0.000 {built-in method builtins.hasattr} 
326681/194989  0.965 0.000 2.876 0.000 packet.py:122(add_payload) 
... 

EDIT 2: Vollständiges Codebeispiel:

from scapy.all import * 
from scapy.utils import PcapReader 
import time, sys, logging 


COUNT = 0 
def customAction(packet): 
global COUNT 
COUNT = COUNT + 1 

file_temp = sys.argv[1] 
path  = '/'.join(file_temp.split('/')[:-2]) 
file_in = '/'.join(file_temp.split('/')[-2:]) 
name  = file_temp.split('/')[-1:][0].split('.')[0] 


os.chdir(path) 
q_output_file = 'processed/q_' + name + '.csv' 
a_output_file = 'processed/a_' + name + '.csv' 
log_file  = 'log/' + name + '.log' 

logging.basicConfig(filename=log_file, level=logging.DEBUG) 

t0=time.time() 
sniff(offline=file_in, prn=customAction, lfilter=lambda x:x.haslayer(DNS), store=0) 
t1=time.time() 

logging.info("File '{}' took {:.2f} seconds to parse {} packets.".format(name, t1-t0, COUNT)) 
+0

Nach https://gist.github.com/dpifke/2244911 sollte defaultdict nicht der Grund sein, dass pypy langsamer als python3 ist. Durch den Prozess der Beseitigung scheint es, dass der offensichtliche Schuldige scapy + pypy ist. – deltap

+0

Können Sie ein konkretes Beispiel für PyPy geben? Wenn es wirklich langsamer ist (selbst für große Dateien), könnte das an einer fehlenden Optimierung in PyPy selbst liegen, die wir reparieren könnten. –

+0

Nach einigen Code-Optimierungen kann ich jetzt eine 10% ige Verbesserung der Ausführungsgeschwindigkeit mit Pypy erzielen. – deltap

Antwort

1

Es scheint, dass scapy verursacht PyPy des JIT Aufheizzeiten hoch sein, aber der JIT arbeitet immer noch, wenn Sie lange genug laufen. Hier sind die Ergebnisse Ich habe (auf Linux 64):

size of .pcap  CPython time  PyPy time 
2MB     4.9s    7.3s 
5MB     15.3s    9.1s 
15MB     1m15s    21s 
+0

Wie viele Pakete sind in diesen Dateien? Meine Dateien mit 50.000 Paketen sind ca. 8 MB groß und meine Laufzeiten sind deutlich länger als bei Ihnen. – deltap

+0

Ich habe in den Logs Nummern näher zu einem Dutzend "Pakete" gesehen. Auch hier bedeutet es, dass Sie uns nicht alles sagen, was wir wissen müssen. Bitte geben Sie ein vollständiges Beispiel an. Es kann eine öffentliche .pcap-Datei sein, die im Internet verfügbar ist. –

0

Ich denke, dass die kurze Antwort ist, dass scapy wie die Hölle nur langsam. Ich habe gerade versucht, eine pcap-Datei mit sniff() oder PcapReader zu scannen und nichts mit den Paketen zu tun. Der Prozess hat weniger als 3 MB/s von meiner SSD gelesen und die CPU-Auslastung betrug 100%. Es gibt andere Pcap-Reader-Bibliotheken für Python da draußen. Ich würde vorschlagen, mit einem davon zu experimentieren.

+0

Es wäre hilfreich, wenn Sie spezifische Bibliotheken erwähnt oder vorgeschlagen hätten. – charlesreid1

Verwandte Themen