Windows Netzwerke topologisieren – Linuxstyle

Wenn wir in einem Firmennetz den PCs per DHCP IPs zuweisen, dann kennt nur der DHCP Server die aktuelle Zuordnung aller von Ihm verwalteten Addresseranges und die kann sich dynamisch ändern. Also brauchen wir eine Methode wie wir eine aktuelle Übersicht bekommen.

Windows Netzwerke topologisieren – Linuxstyle

Oh ja.. endlich mal was ohne Corona schreiben, wie ich das vermisst habe 😀

Wir brauchen:

Einen Linux PC
NMAP Scanner
GREP, SED, AWK
nmblookup

nmblookup bekommt man für Fedora im Paket „samba-client“ und nmap natürlich im Paket „nmap„, wer hätte es gedacht 😉

Wir nehmen jetzt mal an, daß wir nur ein Netz haben: 192.168.1.0/24 und, daß Windows RDP offen hat, damit man da auch Remote drauf kann. RDP hat den Port 3389. Das hat den Vorteil, daß wir nur die PCs mit Port 3389 finden müssen:

nmap -n -sS -p 3389 192.168.1.0/24

das sieht dann so aus:

Nmap scan report for 192.168.1.24
Host is up (0.00040s latency).
PORT STATE SERVICE
3389/tcp open ms-wbt-server
MAC Address: A2:54:20:26:3D:7F (Unkown)

Aus der Ausgabe brauchen wir nur die mit offenen RDP Ports, also filtern wir nach „open“, es sei denn, Ihr habt eine Installation bei der das eingedeutscht wurde. Da müßt Ihr selbst ran 😉

nmap -n -sS -p 3389 192.168.1.0/24 | grep -B 3 open

Jetzt habe ich dem ersten grep nach „open“ gesagt, es soll auch die 3 Zeilen vor dem Treffer ausgeben. Dies ist wichtig, weil da die IP drin steht. Als nächstes  filter wir auf die IP Zeile:

nmap -n -sS -p 3389 192.168.1.0/24 | grep -B 3 open | grep „scan report“

und werfen alles außer der IP weg:

nmap -n -sS -p 3389 192.168.1.0/24 | grep -B 3 open | grep „scan report“ | sed -e „s/^.*for //g“

Diese Ausgabe müssen wir um den eigentlichen Befehl so erweitern, daß wir die Informationen vom PC bekommen und das geht mit „nmblookup -A <ip>“:

nmap -n -sS -p 3389 192.168.1.0/24 | grep -B 3 open | grep „scan report“ | sed -e „s/^.*for //g“ | awk ‚{print „nmblookup -A „$1;}’|bash

..Das Ergebnis der Mühe wert..

Das Ergebnis sieht dann so aus:

Looking up status of 192.168.1.2
W10-HEIST <00> – B <ACTIVE>
MOVIE <00> – <GROUP> B <ACTIVE>
W10-HEIST <20> – B <ACTIVE>

MAC Address = 52-54-00-48-D1-17

Looking up status of 192.168.1.87
No reply from 192.168.1.9

Looking up status of 192.168.1.188
AUTOCAD02 <00> – B <ACTIVE>
AUTOCAD02 <20> – B <ACTIVE>
INGENIEURE <00> – <GROUP> B <ACTIVE>

MAC Address = 90-1B-0E-53-5E-07

Jetzt habe ich die IP, den Namen, die Arbeitsgruppe und die Macaddresse von jedem Windows PC mit RDP. Jederzeit aktualisierbar. Live 🙂

Das war Teil 1 der Aufgabe, denn für den Fall, für den ich das so gemacht habe, war das das gewünschte Ergebnis. Wir können aber noch mehr machen. Wir haben die IP und die MAC eines PCs.

Was wäre, wenn man damit die Topologie ermitteln könnte?

Vorweg: Es gibt andere Methoden, z.b. snmp Abfragen am Switch und Router, die sind etabliert und funktionieren. Allerdings ist son snmpwalk abhängig davon was die einzelnen Geräte anbieten, da muß man einiges an Zeit reinstecken, wenn man das selbst bauen will.

Zeit ist aber das richtige Stichwort 🙂 Pakete laufen im Netz abhängig von der Strecke zwischen den PCs unterschiedlich lange. Wie bekomme ich das raus? Richtig mit Ping:

# ping -c 20 192.168.1.25
PING 192.168.1.25 (192.168.1.25) 56(84) bytes of data.
64 bytes from 192.168.1.25: icmp_seq=1 ttl=64 time=0.215 ms
64 bytes from 192.168.1.25: icmp_seq=2 ttl=64 time=0.195 ms
64 bytes from 192.168.1.25: icmp_seq=3 ttl=64 time=0.209 ms
64 bytes from 192.168.1.25: icmp_seq=4 ttl=64 time=0.204 ms
64 bytes from 192.168.1.25: icmp_seq=5 ttl=64 time=0.166 ms
64 bytes from 192.168.1.25: icmp_seq=6 ttl=64 time=0.204 ms
64 bytes from 192.168.1.25: icmp_seq=7 ttl=64 time=0.253 ms
64 bytes from 192.168.1.25: icmp_seq=8 ttl=64 time=0.158 ms
64 bytes from 192.168.1.25: icmp_seq=9 ttl=64 time=0.200 ms
64 bytes from 192.168.1.25: icmp_seq=10 ttl=64 time=0.184 ms
64 bytes from 192.168.1.25: icmp_seq=11 ttl=64 time=0.199 ms
64 bytes from 192.168.1.25: icmp_seq=12 ttl=64 time=0.249 ms
64 bytes from 192.168.1.25: icmp_seq=13 ttl=64 time=0.264 ms
64 bytes from 192.168.1.25: icmp_seq=14 ttl=64 time=0.225 ms
64 bytes from 192.168.1.25: icmp_seq=15 ttl=64 time=0.297 ms
64 bytes from 192.168.1.25: icmp_seq=16 ttl=64 time=0.255 ms
64 bytes from 192.168.1.25: icmp_seq=17 ttl=64 time=0.290 ms
64 bytes from 192.168.1.25: icmp_seq=18 ttl=64 time=0.328 ms
64 bytes from 192.168.1.25: icmp_seq=19 ttl=64 time=0.212 ms
64 bytes from 192.168.1.25: icmp_seq=20 ttl=64 time=0.229 ms

— 192.168.1.25 ping statistics —
20 packets transmitted, 20 received, 0% packet loss, time 19360ms
rtt min/avg/max/mdev = 0.158/0.226/0.328/0.047 ms

Wenn wir also statt nmblookup ping einbauen, können wir jeden dieser Pcs messen:

nmap -n -sS -p 3389 192.168.1.0/24 | grep -B 3 open | grep „scan report“ | sed -e „s/^.*for //g“ | awk ‚{print „ping -c 20 „$1;}’|bash | grep -E „(statistics|rtt)“ | sed -e „s/— //g“ -e „s/ ping.*$//g“ -e „s/rtt //“ -e „s/\/max\/mdev = /:/g“ -e „s/\//:/g“ | awk -F „:“ ‚{print $1″=“$3″ „$2″=“$4;}‘ | sed -e „s/= =//“

da kommt sowas bei raus:

192.168.1.21
min=0.624 avg=0.851

Wert ermittelt, jetzt muß er bewertet werden..

Jetzt kann man sich überlegen, inwieweit Ihr dem MIN Wert traut, denn der ist stark vom Netzwerkverkehr abhängig, wo hingegen avg so etwas bedingt ausbügelt. Man sollte die Messung zu verschiedenen Zeiten wiederholen und dann die Ergebnisse zusammenrechnen. Für diese Prinzipdarstellung reichts auch erstmal so 😉

Wir können aus den MIN-Daten folgendes ermitteln: Alle PCs mit der gleichen Antwortzeit sind gleich weit weg, oder der antwortende PC ist ne alte Krücke 😉 Gleich weit weg bedeutet in Wirklichkeit: diese PCs könnten in einem Zimmer stehen, aber die könnten auch in verschiedenen Zimmern stehen, die über gleich lange Kabel angeschlossen sind. Das ist der Knackpunkt.

Üblich ist, daß im Serverraum ein Patchfeld ist, von dem die Kabel in die einzelnen Regionen des Gebäudes abzweigen. Der Vorteil dabei ist der Datendurchsatz und das man PortSense benutzen kann, der Nachteil, daß viel mehr Kabel gezogen werden, als nötig wären.

Datenaustausch in einem Netzwerk

Jetzt überlegen wir mal, welchen Test wir noch machen können… hmm.. IP.. Name… MACAdressse… MACAdresse… hey, wir haben eine MACAdresse vom PC direkt.. vergleichen wir die doch mal mit dem was im Arptable steht 😀

Erstmal erklären: Der Datenaustausch findet in einem Netz nicht zwischen IPs statt, sondern zwischen MAC Adressen. Das sind die Adressen der Netzwerkkarten die da zum Einsatz kommen. Haben wir eine direkte Verbindung zu dem Austauschpartner, hat die IP im Arpcache die gleiche Macadresse wie die per nmblookup mitgeteilt wurde. Im ARP Cache, erreichbar über den Befehl apr, bekommen wir die für die Kommunikation zur IP genutzte Mac auf dieser Seite der Verbindung:

Looking up status of 192.168.1.51

MAC Address = B1-6E-FF-D3-42-B4

# arp |grep 1.51
192.168.1.51 ether b1:6e:ff:d3:42:b4 C eth0

Ist da aber ein anderes Gerät dazwischen ( z.B. Router ), dann hat das Arpcache bei uns eine andere MAC als das Gerät uns per nmblookup mitgeteilt hat. Hinweis: Switche geben Ihre eigenen MAcs nicht preis, die sind transparent was das betrifft. Ein Router könnte jetzt also ein Netzumsetzer, eine Bridge, Tunnel oder ähnliches sein:

Looking up status of 192.168.1.51

MAC Address = B1-6E-FF-D3-42-B4

# arp |grep 1.51
192.168.1.51 ether  A0:43:3d:3A:13:45 C eth0

Wenn man jetzt also mehrere IPs mit der gleichen MAC hat, weiß man, daß die zusammen auf entweder einer Hardware laufen, dann wären die Pingzeiten alle gleich, oder die laufen alle durch einen Router/Tunnel und haben unterschiedliche Laufzeiten, dann stehen die hinter dem Router an verschiedenen Stellen.

Andere Ergebiskombinationen

Jetzt gibts noch die Kombi, daß die Laufzeit für einige IP gleich ist, die Mac auch, aber die Mac noch bei anderen IPs auftaucht, die andere Laufzeiten haben, dann sind die IPs mit gleicher Laufzeit auch auf einer anderen Hardware hinter so einem Router platziert und der Rest steht irgendwo anders.

Wenn man nur von einem Standort aus scannt, bekommt man möglicherweise einen falschen Eindruck, weil wir die „Welt“ nur zweidimensional sehen. Wenn unserer erstes Zwischengerät seine MAC anzeigt, könnten da noch einige andere hinter liegen, die wir nicht mehr sehen können. Deswegen ist eine automatische Topologie zumindest mit dieser simplen Methode hier, bei komplexen Setups nicht ausreichend genau.

Das war natürlich jetzt nur eine theoretische Überlegung, ich hatte ja gesagt, daß es da etablierte Methoden gibt. Wann könnte das also noch mal wichtig sein? z.B. wenn man mit LAHA Audio zeitgleich ans Ziel streamen will: Multi-Netzwerk-Lautsprecher mit Linux

Hier wäre, wenn wir es schon eingebaut hätten, die Laufzeit eine wichtige Komponente, damit die Streams alle zeitgleich zu hören sind. Vielleicht baue ich das ja mal ein. Ich habe gerade erst AndroidStudio wieder zum Leben erwecken können 😀

Anmerkungen:

Alle MACs sind frei erfunden. Je nach Aufgabenstellung kann man auch andere Ports als Scankriterium für Nmap oder gleich einen PING-Scan benutzen. NMAP gibt u.U. einen aufgelösten Domainnamen zurück:

Starting Nmap 7.80 ( https://nmap.org ) at 2020-08-19 13:14 CEST
Nmap scan report for android-501a417bc9ee518.fritz.box (192.168.0.39)
Host is up (0.090s latency).

PORT STATE SERVICE
445/tcp closed microsoft-ds
MAC Address: 6C:F1:76:2D:3B:AA (Samsung Electronics)

da müßt Ihr die SED Anweisungen entsprechend ändern oder nmap die „-n“ Option verpassen, sonst passieren skurille Dinge :DD

 

LAHA jetzt auch auf Raspberry PI

Jetzt ist es also passiert, die LAHA Multiroom HomeAudio-Lösung läuft auf der Zielplattform Raspberry PI.

Was war jetzt LAHA nochmal?

Kurzform: Damit kann man Audio an mehrere Endgeräte streamen … verteilen, so daß es überall im Gleichklang erschallt. Hervorgegangen ist das aus einer einseitigen Wette mit den Heise Redakteuren, das man das auch ohne Bäng & Teufelschen Co. mit OpenSource hinbekommt : LAHA – Netzwerklautsprecher mit Linux . Wie sich herausgestellt hat, geht das auch, nur leider nicht ganz so wie anfangs geplant. Das es trotzdem geht, bedeutet natürlich einige Einschränkungen oder Umstellungen.

PulseAudio

Wenn man PulseAudio mit einem römischen Gott vergleichen wollte, wäre es Janus, der Gott mit den zwei Gesichtern. Auf der einen Seite ist PulseAudio echt super einfach, z.b. beim Abnehmen des Sounds vom Player und dem ins Netz stellen, auf der anderen Seite könnte ich dem Entwickler auch gern mal eins reinwürgen, weil die interne Latenzkontrolle Ihren Job nicht macht. Da letzteres nicht sauber klappt, könnte man auf AlsaPlay ( aplay ) ausweichen, aber das benutzt, sobald PulseAudio da ist, richtig geraten, PulseAudio als Backend, womit die Latenzfalle wieder da ist … ächtzzzz. Man hats nicht leicht mit der OpenSource-Plattform 🙂 Es nutzt ja auch nichts, daß es Open-Source ist, wenn bei so komplexen Dingen wie PulseAudio Modulen/Programmen zwar der Source lesbar ist, aber auf 1000 Zeilen Code genau 2 Kommentare kommen und dazu grober C UnFoo getrieben wird.

Das Raspberry PI

Nachdem Android und der lokale PAPLAY Backend soweit waren, daß man darüber was abspielen konnte, ohne das es gleich sofort zusammenbrach, war gestern das Raspberry PI dran. Eine genervte Viertelstunde brauchte es schon um das RasPI Image auf die 64GB SD zu bekommen, dazu morgen mehr, aber am Ende war das Pi dann doch kooperativ, bis .. ja bis PulseAudio installiert wurde 🙁 Das lief zwar auf dem PI und mit den nötigen Zusatzprogrammen war das auch nett, aber, und das ist entscheidend, die PI Devs haben der PulseAudio-Welt den Hardwarehack vorenthalten, mit dem Sie den Sound auf den Kopfhöreranschluß umlegen. Ums kurz zu machen, solange PulseAudio installiert und aktiv ist, geht das nicht über die Kopfhörerbuchse, sondern immer über HDMI raus, egal was die Oberfläche sagt.

Da gab es natürlich nur eine Lösung: Back to the Roots aka. PulseAudio wieder löschen, rebooten und Alsa als Backend benutzen. Wenn man dann dem PI erzählt, daß es den Kopfhörer nehmen soll, dann geht das auch.

Der Stand der Dinge

Wir haben jetzt also PI Playback und das auch synchron mit dem Desktop PC und Android. Android ist auch so eine Krankheit für sich, aber das nur neben bei. Es gibt schon Beweisvideos, allerdings war es bislang für Filmaufnahmen zu dunkel, Ihr müßt Euch nicht mehr gedulden, unten ist ein Video mit 4 Geräten zusehen. Damit Ihr Euch schon mal ein Bild davon machen könnt, wie das funktioniert, hier selbiges aus der LAHA Präsentationsfolie :

Der Aufbau von LAHA als Flußdiagramm

So war das bis gestern angedacht, nun muß der RasPi Teil aber auf ALSA als Backend umgebaut werden, weil PulseAudio ja nicht kann 😀

LAHA und die Latenzfalle

Kleines Update zu LAHA, dem Multiroom Sound und PulseAudio.

Stand der Dinge

Wie man es drehen und wenden will, die fertigen Tools zum Abspielen von PCM Sound haben alle irgendeine Macke.

PAPLAY benutzt PulseAudio. Das ist praktisch ein Todesurteil für eine stabile Latenz.
APLAY   benutzt Alsa, das defaultmäßig … PulseAudio benutzt. Siehe erstens 🙂
*JACK*  nun Jack möchte gern alleine tätig sein, ohne Konkurrenz. Fällt auch aus.

Da APLAY und PAPLAY per Default einen PA Stream zum Abspielen benutzen, haben beide in der Form das gleiche Problem: Die Audiolatenz des Playstreams steigt mit der Zeit an. d.b. alle anderen Geräte müßten mitwandern. Blöd nur, das Androids gar keine Latenzwanderung haben und selbst wenn Sie es hätten, wäre das eine blödsinnige Lösung. Jetzt fragt Ihr Euch natürlich: was labbert der da? Da muß man jetzt weiiiiiit ausholen.

Also, wenn man mit PAPLAY Sound ausgibt, geht PAPLAY zum PAServer und sagt dem, das DER eine Latenz wählen soll. Das macht der dann auch, nachdem die ersten Daten geflossen sind und die pegelt sich mit 16Bit Stereo und 48000″hz“ bei rund 1,9s ein. Richtig gelesen 1,9 Sekunden. Nach 40 Minuten sind wir bei knappen 5 Sekunden, wenns dumm läuft. Wenns gut läuft bei 2,4s . Das entscheidet PA selbst, ich nehme an, nach internen Fehlberechnungen aller gestarteten, gestoppten, bewegten etc. Streams die auf dem System drauf sind. Ich hab es noch nicht im Source gefunden. Es ist eigentlich das Ziel eines Audioservers die Latenz niedrig zu halten, aus irgendeinem Grund, ist dem PA-Latenzalgorithmus das egal.

Wenn man jetzt denkt, daß der Befehl ja eine OPTION für die gewünschte Latenz hat und sich schon freut, daß die dann ja als Ziel eingehalten wird .. ähm ja, also wie soll ich das Schreiben ohne verklagt zu werden??? Lieber nicht, hier ein Beispiel: 500ms angegeben, Latenz beginnt bei 320ms und wandert pö-â-pö so Richtung 500ms, durchbricht den Median, und verschwindet alsbald jenseits von Gut und Böse im Sekundenbereich.

Wenn man auf die glorreiche Idee kommt, da das anzugeben, was der Algo vorher selbst ausgerechnet hat, dann bekommt man nicht 1,9s , nö, mehr so 1s+- und dann kommt das gleiche Spiel wie vorher bei 500ms.
Ja, man könnte jetzt die PAPLAY-Routine kapern, den anderen Geräten die Latenzen mitteilen und denen somit zu einem Sync verhelfen. ABER.. die Latenz wird ja immer größer, was bedeutet, daß bei jedem neuen Sync mehr Zeit vergeht, bis man was hört. Also auch mal 5 Sekunden schwarzes nichts. Das ist hochgradig Inakzeptabel.

Bugreports sind raus, werden nicht helfen, weil (C) endet 2006 . Sieht nicht so aus, als wenn da wer dran arbeitet.

Kommen wir zu ALSA

APLAY kann ALSA-Devices direkt ansprechen. Warum nutzen wir dann nicht APLAY, statt PAPLAY ? Gesagt, getan. Versuchts mal, viel Glück dabei. Das geht mit etwas Glück genau einmal und auch nur auf einem Device, aus das PA grade nichts ausgibt. Ist auch klar, weil PA ja ALSA als Unterbau hat. Wir erinnern uns, daß PAPLAY 1,9s Latenz hatte. APLAY, wenn man ein Device findet, das geht, hat 0ms und das Startdelay ist nicht ganz so funktional, wie sich APLAY das wünscht aka. auch buggy. ABER, 0ms sind cool, weil Android auch 0ms haben kann, ohne dabei drauf zu gehen. Der Lesezugriff für Netzwerkdaten für „16 Bit Stereo 48k“ auf einem Android liegt bei 1ms. d.b. nimmt man ALSA als Player und bekommt das Device frei, hat man eine echt geile Latenz von 1-2ms und das hört man nicht!

Der Resync

Jetzt gibt es allerlei Hürden, die man umschiffen muß. Androids fliegt das eigene Multitasking um die Ohren, da fängt der Ton dann an zu stottern. Vorwarnung : keine. Gegenmaßnahmen: derzeit unbekannt.Das funktioniert auf dem Desktop etwas besser.

Bei 0ms Latenz ist der Resync instant, da könnte man versucht sein, einfach pauschal alle paar Sekunden mal helfend durch einen Socket.close();Socket.connect() einzugreifen. Könnte klappen, muß nicht.Ist aber eine Option, wenn der Wiedergabetask das nicht merkt. Geheimtip: Vorsicht vor doppelten Daten im AudioBuffer. Vergleicht mal, ob Ihr nach dem connect()+read() einen Teil davon schon habt und schmeißt den raus.

LAHA

Unser ControllCenter steuert jetzt bereits beliebig viele Devices, kann Audiostreams von laufenden Apps kapern, z.b. MPV, FireFox etc. , hat diverse Backends zum Abspielen auf dem Desktop, könnte verschiedene Musikplayer als Quelle nutzen und damit auch Last.FM, Spotify etc. realisieren. Er verschiebt Metadaten, findet neue Geräte im Netz, erlaubt Endgeräten mit Screen ihn fernzusteuern und hat bereits erfolgreich ein Handy als Drahtloskopfhörer für Videos laufen gehabt. Dank MPVs negativer Latenz und der frei einstellbaren Endgeräte Latenz, kann man alles perfekt ausrichten 🙂

Wir sind also auf dem richtigen Weg. Ob das allerdings vor Weihnachten 100% zuverlässig läuft, kann ich nicht garantieren. Trotz des ganzen Frustes mit den Bugs der Anderen, hat das Projekt endlich mal wieder Spaß beim Programmieren beschert. Und das ist doch, weswegen man es tut, oder nicht 😀

Multi-Netzwerk-Lautsprecher mit Linux

Wer den kleinen Rant über die selbstverschuldete Unselbstständigkeit der Heise-Redakteure gelesen hat, und aufmerksam am Ball geblieben ist, dem seit hiermit mitgeteilt, daß ich die geäußerte Drohung wahr gemacht habe 🙂

War jetzt nicht so richtig schwer

Ich habe ein Latenzgleiches Playback von QMMP an 3 Abnehmer realisiert – mit Bordmitteln!

PulseAudio-LautstärkenkontrolleDa ich natürlich nur begrenzt Rechner habe, habe ich als Abnehmer auch die Lokalen Audioschnittstellen benutzt (oben im Bild)  um die Latenzgleichheit zu testen.

Ein Laptop im WLAN diente als Kontrolle und es klappt bislang 1a 🙂

Ich werde jetzt wohl eine Steuersoftware bauen, die die nötigen Befehle kennt und Einstellungen bereitstellt, aber das ist kein Hexenwerk mehr, sondern reine Fleißarbeit.

PulseAudio und WLAN-Technik aus der POST-Avengers Ära machen es möglich.

Android ist schneller

Eine Probe mit Android als Abnehmer war auch erfolgreich, aber nicht synchron. Liegt vermutlich an dem kleineren Buffer der App im Vergleich zum PC-Programm. Da ich den Sourcecode habe… 😀 Ich muß da eh ran, also kein Aufwand.

@Heise: Told you so! OpenSource rulz.

Schaut mal in einige Wochen rein, obs was nettes zu Weihnachten für Euch gibt 😀

Falls einer eine praktikable Idee hat, wie man ein Fabrikneues Raspi in ein WLAN ohne Tastatur und Monitor bekommt ( WPS-Taste z.b. ) dann findet Ihr im Haupt-Impressum eine Kontaktemailadresse.

Kleine Anmerkung

Für Videos abspielen braucht man einen Player wie MPV mit dem man die -2900ms Audio/Videoversatz ausgleichen kann.