End2End-Ping

Ein PING ist nicht wirklich eine sinnvoll messbare Größe, das die ICMP-Pakete sehr klein sind und man eine aktive Gegenstelle braucht. Man kann aber anhand der Laufzeit schon erkennen, ob es "Aussetzer" gibt, d.h. Pakete verloren gehen oder Engpässe einer WAN-Leitung ein Problem darstellen können. End2End-Ping hat mir auch bei Clustern schon öfter geholfen, wenn ich damit z.B. einen Ping zwischen den Heartbeat-Karten aktiviert habe, um hier speziell bei Clusterknoten mit etwas "Entfernung" Aussagen über die Zuverlässigkeit machen zu können.

Ping und PingPlotter

Das Programm "PingPlotter" zeigt auch in der "Free-Version" interaktiv schön die Bedeutung von PING. Allerdings auch hier nicht als "ein Ping zum Test" sondern sogar kontinuierliche Pings an die verschiedenen Zwischenstationen:

Sie sehen hier die einzelnen Stationen aber auch die Varianz, d.h. schnellste und langsamste Pings. Das kann ein Rückschluss auf die Performance der Teilstrecke sein. Unten ist dann die Roundtripzeit zu sehen. Sie sehen auch die Stufe (rot), als ich zuhause ein Teams Meeting gestartet habe und aufgrund der genutzten Bandbreite dann auch die PINGs etwas langsamer wurden. Kontinuierliche Messungen sind also durchaus interessant für die Qualitätsbestimmung.

Aber ich möchte das nicht als GUI sondern als Hintergrundprozess. Daher gibt es End2End-Ping und End2End-PathPing.

PING und Grenzen

Klassischerweise ist PING ein kleines Paket mit 64Bytes oder weniger, die von der Gegenseite einfach wieder zurück gesendet wird. Wenn niemand ICMP gesperrt hat und ICMP nicht "optimiert" oder anderweitig behandelt wird, dann können Sie damit sehr billig die Erreichbarkeit und die Laufzeit zwischen Systemen mit IP-Stack messen. Die Programme PING.EXE und PowerShell "Test-Connection" senden in der Regel drei PING-Pakete. Aber PING kann mehr. Wenn ich sehr engmaschig überwachen will, kann ich viel mehr Pings senden und die Ergebnisse auswerten. Hier mal ein Beispiel in meinem Heimnetzwerk mit einer Fritz!Box 7590 und Gigabit-Link mit einem Einzeiler und PowerShell 7

while ($true) {$null = Test-Connection 192.168.178.1 -Count 1 }

Per WireShark sehen sie, was da passiert. Meine Antwortzeiten sind 1-2ms und nach dem Empfang geht nach 2ms das nächste Paket raus.

WireShark zeigt aber auch noch, dass die Rate relativ gleich bleibt.

Der Einzeiler produziert bei mir ca. 60-70 Pakete/100m, also 600-700 Pakete/Sekunde mit 64 Bytes oder ca. 410kbit/Sek bei ca. 30% CPU-Last. Mehr Last kann ich einfach durch eine größere Buffersize generieren.

while ($true) {$null = Test-Connection 192.168.178.1 -Count 1 -BufferSize 60000}

Mit 60 kByte geht natürlich die Paketrate bei mir auf ca. 300 Pakete/Sek herunter und die CPU-Last ist schon bei 60% während das Netzwerk grade mal ca 80 MBit benutzt.

Einen richtigen "Dauerlasttest" mit "Maximalübertragung" ist mit einem einzelnen ICMP-Thread natürlich nicht möglich. PING wartet auf die Antwort, ehe das nächste Paket versendet wird und nutzt keine TCP-Windows. Mehrere parallele Pings in eigenen Powershell-Instanzen treiben die Bandbreite hoch. Interessanter Nebeneffekt. Über folgenden Befehl kann ich mehrere Jobs starten.

start-job {while ($true) {$null = Test-Connection 192.168.178.1 -Count 1 -BufferSize 60000 }}

Allerdings bin ich nicht über 180 Megabit gekommen und ab fünf parallelen Prozessen ist der Test eingebrochen. Von einem anderen Prozess aus konnte ich die Fritz!Box aber weiter anpingen. Ein Test gegen einen einfachen Gigabit-Switch hat nicht mehr als 2 Megabit geschafft, was aber auch an der Antwortzeit lag

Mit 230-260ms sind nun mal nur 4 Ping a 60kByte = 2,4Mbit möglich. Gegen eine auch schon vier Jahre alte Synology DS216j habe ich aber schon 300MBt Dauerlast erreicht. Damit ist nun aber klar, dass ein ICMP-Paket auch von der Größe und der Gegenseite abhängig ist. Auf der Fritz!Box haben meine Test weder den Stromverbrauch noch die CPU-Temperatur merklich erhöht.

Sie sollten daher die Ergebnisse immer mit der notwendigen kritischen Betrachtungsweise bewerten.

Funktionsweise

Das Skript sendet kontinuierlich (jede Sekunde) ein ICMP-Ping-Paket mit einstellbarer Paketgröße (Default 160 Bytes) und an eine bekannte Gegenstelle und wertet die Ergebnisse aus. Dazu fasst es eine Gruppe von Pings (Default: 15 Stück) zusammen und ermittelt Min, Max, Average, Anzahl und Loss.

Achtung
ICMP ist nur ein bedingt gültiger Test für VoIP-Qualität. Zum einen ist ICMP kein UDP und das Skript hier wartet auf die Antwort, ehe es das nächste Paket sendet. Insofern kann es keinen Dauerstrom mit 20ms Abstand senden. Die Paketrate ist niedriger und von der Roundtrip-Zeit abhängig.

Umsetzung

Das Skript testet erst mal genau ein Ziel und erwartet die Zwischenstationen im Fehlerfall als auch die Ausgabeziele als Parameter. Folgende Parameter sind verfügbar

  • hostname = internetbeacon.msedge.net
    Eine IP-Adresse oder der DNS-Name des Zielsystems. Die Adresse internetbeacon.msedge.net ist ein Standardservice von Microsoft, über den Clients prüfen, ob sie Verbindung zum Internet haben. Test-NetConnection nutzt diese Adresse auch als Default
  • Pingcount = 15
    Ich pinge im Abstand von 1 Sekunde insgesamt 15 Mal um die Ergebnisse dann zusammen zu sammeln.
  • PingTimeout = 200
    Nach 200ms wird ein Paket als "loss" gezählt. Ich denke, dass ein Ping in der Regel nicht länger dauern sollte
  • Buffersize(default 160)
    Größe des Buffers, der übertragen wird. Ich nutze hier 160 Byte als Default. Auch ein VoIP ist z.B. 160 Bytes groß.
  • csvfilename .(\end2end-ping.csv)
    Erlaubt die Angabe einer CSV-Datei, in der die Ergebnisse gespeichert werden. So können Sie diese auch später einmal auswerten.

Das Skript initialisiert das ICMP-Objekt und den Sendepuffer und versendet über eine Endlosschleife die ICMP-Pakete und sammelt die Ergebnisse ein. Die Laufzeit wird hinsichtlich Maximum und Minimum bewertet und über alle Pakete einer Gruppe wird ein Mittelwert (AVG) gebildet und die als "loss" definierten Pakete aufaddiert.

Ausgabe

Natürlich wollten wie ja noch wissen, wie die Ausgabe aussieht. In der PowerShell Box ist die Arbeit des Skripts zu sehen. Ich habe die Ausgabe etwas farbig gemacht. Hier eine schlechte Verbindung in einem Gäste-WLAN eines Kunden.

Im Gegenzug dazu eine recht ordentliche Verbindung an einem DSL100-Anschluss:

Etwas anders sieht die Ausgabe an einem Vodafone-Kabelanschluss aus (32MBIt Downstream) allerdings über WLAN.

b

Die PING-Zeiten sind im Vergleich zum DSL100 Anschluss mi 15-25ms etwas länger. Ob das nun aber allein am Übertragungsmedium "Kabel", dem Vodafone Netzwerk und Routing oder ein Stück weit auch am WLAN liegt, habe ich nicht weiter untersuchen können. Aber der PaketLoss (Rote "T"-Blöcke). ist mir schon deutlich zu hoch und dürfte auch die ein oder andere TCP-Verbindung aus dem Tritt bringen.

Sie können aber auch "Veränderungen" erkennen. Hier noch ein Ausschnitt bei mir zuhause am DSL-Anschluss, wenn ein Anwender sich das erste Mal an einem PC anmelden und OneDrive mit der Synchronisierung startet:

Interessanter ist natürlich, später die Ausgabe in der CSV-Datei auszuwerten. Auch hier erst mal nur die Textanzeige:

Eventuell ändere ich den Zeitstempel noch mal, um die Ausgabe "schöner" zu machen. Die Spalten zeigen an, welcher Wert welche Bedeutung hat. Einfacher ist natürlich der Import per PowerShell.

PS C:\> Import-Csv end2end-ping.csv

statusavg2min    : 0
Total            : 15
Lost             : 5
Avg              : 19
RemoteIP         : 13.107.4.52
timestamp        : 20181115041959
Min              : 27
Max              : 29
statuspacketloss : 1
statusmax2avg    : 0

Ihnen stehen alle Wege offen, z.B., nach Feldern wie "statuspacketloss" zu filtern oder auch die Auswertungen grafisch mit Excel oder Power Bi o.ä. aufzubereiten.

Download

Für die Ausführung sind keinerlei privilegierte Rechte erforderlich. Das Skript kann auf jedem PC mit PowerShell 2.0 ausgeführt werden.

end2end-ping.ps1.txt
Bitte nach dem Download die Erweiterung nach ps1 umstellen.
Mindestversion PowerShell 5 (Win2012R2 oder höher) wegen Resolve-DNSName. Sie können das umgehen, indem Sie über den Parameter "Hostname" eine IP-Adresse angeben.

Achtung
Wenn Sie sinnvolle Ergebnisse erhalten wollen, dann müssen Sie die Parameter an ihre Umgebung anpassen !!!

Hinweis:
Das Skript sendet die Ausgaben auch als Objekte in die Pipeline für eine weitere Verarbeitung, z.B. den Versand an PRTG o.ä. Damit diese Ausgaben nicht die Bildschirmausgabe stören, können Sie ein " | out-null" anhängen

Offen

Aktuell ist End2End-Ping ein "Single Threaded" Script, welches immer nur genau eine Gegenstelle anpingt. Sicher können Sie das Skript einfach mehrfach starten aber das kostet schon mehr Ressourcen. Interessanter könnte es sein, wenn ich parallel mehrere Systeme und auch sehr häufig anpingen könnte. Aktuell habe ich aber noch kein Skript, welches dies macht. Irgendwann müsste ich auch mal IPv6 integrieren.

Weitere Links