tcpdump als Datenvolumenlogger

Alles, was nicht direkt mit Python-Problemen zu tun hat. Dies ist auch der perfekte Platz für Jobangebote.
Antworten
Benutzeravatar
Domroon
User
Beiträge: 104
Registriert: Dienstag 3. November 2020, 10:27
Wohnort: Dortmund

Hi Leute,
ich weiß, dass hat nichts direkt mit Python zu tun deswegen stelle ich die Frage hier im Offtopic-Bereich..

Ich möchte einen LTE-Stick an einem Raspberry Pi betreiben und gerne mitschneiden wie viele Megabyte an Daten gesendet und empfangen werden um das Datenvolumen (mit einem Python Script?) zu berechnen welches in einem Monat schon verbraucht wurde. Die Datenpakete möchte ich mithilfe des Kommandozeilentools "tcpdump" mitschneiden und die wahrscheinlich im Ausgabestring enthaltene Datenpaketgröße "herausschneiden" und abspeichern. (bzw. die Eingabeparameter so weit anpassen bis mir nur noch die Datenpaketgröße ausgegeben wird wenn das geht)

Bevor ich mit dem programmieren anfange wollte ich einmal fragen ob dies grundsätzlich so möglich ist wie ich mir das Vorstelle und ob "tcpdump" überhaupt dafür geeignet ist. Oder gibts da vielleicht auch schon einen fertigen Datemvolumenberechner? Ich habe zumindest nirgends was gefunden..

Vielen Dank schonmal für eure Antworten ;)
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Das ist in etwa so als ob du zum zählen von Besuchern kein Drehkreuz, sondern immer erstmal eine Magendarmspiegelung vornimmst. Geht auch. Ist aber völlig unverhältnismäßig.

Der Kernel führt Buch über die Menge an Daten, die über ein Interface gegangen sind. Tools um sich das anzuschauen wären zb iostat, nmeter oder auch „nur“ die Ausgabe von ifconfig.
Benutzeravatar
Domroon
User
Beiträge: 104
Registriert: Dienstag 3. November 2020, 10:27
Wohnort: Dortmund

@__deets___
super! genau das was ich gesucht habe, cool das der Kernel von sich aus loggt ;) Vielen Dank!
Benutzeravatar
__blackjack__
User
Beiträge: 13003
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Wenn man das von Python aus abfragen möchte, geht das beispielsweise mit dem `psutils`-Modul mit der `net_io_counters()`-Funktion. Entweder für alle Schnittstellen, oder als Wörterbuch das Schnittstellennamen auf die Zählerstände für die jeweilige Schnittstelle abbildet.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Benutzeravatar
Domroon
User
Beiträge: 104
Registriert: Dienstag 3. November 2020, 10:27
Wohnort: Dortmund

@__blackjack__: noch besser! Die Funktion des Moduls werde ich auf jeden Fall verwenden. Ich will natürlich so viel wie geht in Python schreiben ;) Super, vielen Dank! Dann steht meinem Projekt ja nun nichts mehr im Wege :) Ich halte euch auf jeden Fall auf dem laufendem ;) Kann nur etwas dauern, da dies Teil eines größeren Projektes werden soll.
narpfel
User
Beiträge: 643
Registriert: Freitag 20. Oktober 2017, 16:10

Es gibt auch vnStat.
Benutzeravatar
Domroon
User
Beiträge: 104
Registriert: Dienstag 3. November 2020, 10:27
Wohnort: Dortmund

@narpfel: Danke auch Dir ;)

Mithilfe von psutil habe ich schonmal geschaut, dass ich die Internetgeschwindigkeit messen kann. Ich habe zum testen meines Programms den Google Speedtest mehrmals durchlaufen lassen. Scheint recht genau zu sein, falls ich nicht wieder einen gravierenden Rechenfehler gemacht habe wie ihr ihn so oft aufdeckt. Meistens sind die Dinge ja nicht so wie sie scheinen :D

Hier mein Code:

Code: Alles auswählen

import psutil
import time


def calculate_up_down_speed(interface):
    t1 = time.time()
    connection_statistics = psutil.net_io_counters(pernic=True)
    megabit_sent_first = (connection_statistics[interface].bytes_sent*8)/1000000
    megabit_recv_first = (connection_statistics[interface].bytes_recv*8)/1000000
    time.sleep(1)
    connection_statistics = psutil.net_io_counters(pernic=True)
    megabit_sent = (connection_statistics[interface].bytes_sent*8)/1000000
    megabit_recv = (connection_statistics[interface].bytes_recv*8)/1000000
    t2 = time.time()
    megabit_per_sec_sent = (megabit_sent - megabit_sent_first)/(t2-t1)
    megabit_per_sec_recv = (megabit_recv -megabit_recv_first)/(t2-t1)

    return megabit_per_sec_sent, megabit_per_sec_recv


def main():
    while True:
        upload_speed, download_speed = calculate_up_down_speed('WLAN 2')
        print(f"Upload: {round(upload_speed, 2)} Mbit/s")
        print(f"Download: {round(download_speed, 2)} Mbit/s")
        print()
        

if __name__ == '__main__':
    main()
rogerb
User
Beiträge: 878
Registriert: Dienstag 26. November 2019, 23:24

@Domroon,

Wenn es nur darum geht die Zahlenausgabe auf zwei Nachkommastellen zu runden, bietet die String - Format "Mini Language" mächtigere und performantere Möglichkeiten:
https://docs.python.org/3/library/strin ... i-language

Z.B.:

Code: Alles auswählen

 
print(f"Upload: {upload_speed:0.2f} Mbit/s")
print(f"Download: {download_speed:0.2f} Mbit/s")
Ich finde das auch wesentlich lesbarer.


Für Messungen von relative kurzen Zeitabständen bietet sich die präzisere Methode 'time.perf_counter()' an:
https://docs.python.org/3/library/time. ... rf_counter

Die zweite Zeitmessung würde ich direkt nach dem Holen der neuen Werte machen, da du sonst minimale Ungenauigkeit durch die zusätzliche Zeit für die Umrechnung bekommst.
Grundsätzlich würde ich die Umrechnungen auch ganz aus der Messung herausziehen und erst bei der Ausgabe vornehmen.
Die runden Klammern bei der Multiplikation und Division sind auch überflüssig.

1 B/s = 8E-6 Mbit/s

Viel Spass beim Messen!
Benutzeravatar
Domroon
User
Beiträge: 104
Registriert: Dienstag 3. November 2020, 10:27
Wohnort: Dortmund

@rogerb:
super, danke Dir für die Tipps ;)
Antworten