Berechnen Bandbreite pro IP mit scapy, iftop-Stil
Ich bin mit scapy zu schnuppern ein mirror-port und generiert eine Liste der top 10 "der Sprecher", D. H. eine Liste der hosts mit den meisten Bandbreite in meinem Netzwerk. Ich bin mir bewusst von bereits vorhandenen Instrumenten wie iftop und ntop, aber ich brauche mehr Kontrolle über die Ausgabe.
Folgende Skript-Beispiele-Verkehr für 30 Sekunden und dann druckt eine Liste der top 10-talkers im format "Quell-host -> Ziel-host: Byte". Das ist großartig, aber wie kann ich berechnen Sie die Durchschnittliche bytes pro Sekunde?
Ich hatte das Gefühl, dass eine änderung sample_interval bis zu 1 Sekunde nicht für ein gutes sampling-Verkehr, so es scheint, ich muss den Durchschnitt aus. So habe ich versucht, diese am Ende des scripts:
bytes pro Sekunde = (Gesamtanzahl bytes /sample_interval)
aber die resultierenden Bytes/s scheint viel niedriger. Ich zum Beispiel erzeugt ein rsync zwischen zwei hosts, die auf eine gedrosselte rate von 1.5 MB/s, aber mit dem oben genannten Durchschnitt Berechnung, mein Skript gehalten die Berechnung der rate zwischen diesen hosts so um die 200 KB/s...viel niedriger als 1,5 MB/s als ich erwarten würde. Kann ich bestätigen mit iftop, dass 1,5 MB/s ist in der Tat die rate zwischen diesen beiden hosts.
Bin ich insgesamt bis Paketgrößen falsch mit scapy (siehe traffic_monitor_callbak-Funktion)? Oder ist das eine schlechte Lösung zusammen :)?
from scapy.all import *
from collections import defaultdict
import socket
from pprint import pprint
from operator import itemgetter
sample_interval = 30 # how long to capture traffic, in seconds
# initialize traffic dict
traffic = defaultdict(list)
# return human readable units given bytes
def human(num):
for x in ['bytes','KB','MB','GB','TB']:
if num < 1024.0:
return "%3.1f %s" % (num, x)
num /= 1024.0
# callback function to process each packet
# get total packets for each source->destination combo
def traffic_monitor_callbak(pkt):
if IP in pkt:
src = pkt.sprintf("%IP.src%")
dst = pkt.sprintf("%IP.dst%")
size = pkt.sprintf("%IP.len%")
# initialize
if (src, dst) not in traffic:
traffic[(src, dst)] = 0
else:
traffic[(src, dst)] += int(size)
sniff(iface="eth1", prn=traffic_monitor_callbak, store=0, timeout=sample_interval)
# sort by total bytes, descending
traffic_sorted = sorted(traffic.iteritems(), key=itemgetter(1), reverse=True)
# print top 10 talkers
for x in range(0, 10):
src = traffic_sorted[x][0][0]
dst = traffic_sorted[x][0][1]
host_total = traffic_sorted[x][3]
# get hostname from IP
try:
src_hostname = socket.gethostbyaddr(src)
except:
src_hostname = src
try:
dst_hostname = socket.gethostbyaddr(dst)
except:
dst_hostname = dst
print "%s: %s (%s) -> %s (%s)" % (human(host_total), src_hostname[0], src, dst_hostname[0], dst)
Ich bin mir nicht sicher, ob dies ist eine Programmier - (scapy/python) Frage oder mehr eine Allgemeine Netzwerk-Frage, also nenne ich es die ein Netzwerk-Programmierung in Frage.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Hi,
Zuerst von all, Sie haben einen Fehler in dem code, den Sie geschrieben haben: statt
host_total = traffic_sorted[x][3]
du meinst wohlhost_total = traffic_sorted[x][1]
.Dann, Sie haben einen Fehler: Sie vergessen, sich zu teilen
host_total
durch diesample_interval
Wert.Als Sie auch möchten, fügen Sie Empfänger-Absender Verkehrs-und sender-zu-Empfänger, ich denke, der beste Weg wäre, um eine "geordnete" Tupel (die Ordnung selbst ist nicht wirklich wichtig hier, lexikographische Ordnung wäre gut, Sie könnten aber auch arithmetische da, um IP-Adressen sind 4 Bytes Integer) als Schlüssel für die
Counter
Objekt. Dies scheint zu funktionieren:Ist es möglich, dass Scapy ist nicht schnell genug, um den job zu erledigen. Um sicher zu sein, können Sie mit z.B.
tcpdump -w
ist, erfassen Sie Ihren traffic auf eine Dateisample_interval
Sekunden, und führen Sie (durch die Art und Weise, einen Blick auf den Weg, um die Funktion anwenden, um die Pakete, ich denke, es ist eine gute Sache zu wissen, wenn Sie Scapy oft):iftop
's-Ausgabe,, ich kann sehen, es zeigt den kombinierten Verkehr zwischen zwei hosts. Was ist eine schöne pythonic Weise zu kombinieren, die Ergebnisse am Ende, D. H. kombinieren von Tupeln? Zum Beispiel, wenn Sie Ergebnisse in dertraffic
dict für (host1,host2) + (host2, host1).iftop
?iftop
scheint korrekt zu sein, basierend auf meiner gedrosselt rsync-tests. Vielleicht sample_interval sollte höher eingestellt werden, um sagen wir, 60 Sekunden? Ich Frage mich, wieiftop
ist, Dinge zu tun hinter den kulissen..., dass vielleicht das beste Beispiel, da ich ziemlich viel zu bauen versuchen, die gleiche Sache, aber mitscapy
.subprocess
Modul (undsubprocess.PIPE
alstcpdump -w
'sstdout
; ich denke, dass Scapy ist zu langsam, weil es Konstrukte, die ganzen Pakete und es wird immer noch zu langsam.IP.payload_guess = []
nur nach dem Import von Scapy. Das wird verhindern, dass Scapy von LeichenIP
Nutzlast und könnte etwas Zeit sparen.Das kann es nicht sein, aber sind Sie vielleicht die Vermischung mega*bits* pro Sekunde (Mb/s) und mega*bytes* pro Sekunde (MB/s)? Sie scheinen zu Messen, die Menge der gesendeten Daten in byte und dann die Umwandlung dieser zu MB/s, aber ich Frage mich, ob th rsync-Sie legen uo ws spec ' D in bits als 1,5 Mb/sec. Wenn also die Tatsache, dass Ihr Skript gibt Ihnen 200 kB/s ist zumindest in der richtigen ballpark bei 1,5 Mb/s...
--bwlimit=1500
option bei rsync.man rsync
sagt, das ist zulimit I/O bandwidth; KBytes per second
, so dass die rund 1,5 Megabyte/s. Kann ich bestätigen mit iftop sowie (Kakteen)[cacti.net/] Diagramme, die ich bin in der Tat drängen, dass die Menge des Verkehrs. Vielen Dank für die Klarstellung, obwohl.