Freitag, 17. August 2018

Mit OpenWrt Presence Informationen ermitteln

Der zentrale Router weiß ja eigentlich am Besten was los ist im Netzwerk. Ich habe mal die Idee verfolgt auf dem OpenWrt einen Prozess zu starten, der aktuelle Information von Netzwerkgeräten nach "aussen" übermittelt. Als erstes Beispiel will ich mal einen bestimmten Wlan Client ermitteln.
Da die finale kurze Abfrage Schleife leicht unübersichtlich ist, erkläre ich erstmal die einzelnen Komponenten.

Ein paar Grundlagen

Je nach Wlan Hardware hat man unterschiedliche Tools um das Wlan abzufragen. Bei mir war iw und iwinfo vorhanden. Ich muss noch prüfen ob der Befehl ip auch (und ganz universell) zu gebrauchen wäre.
Die Ausgabe wird dann für die weitere Verarbeitung gefiltert. Diese beiden Befehle liefern das gleiche Ergebnis:
iwinfo |grep -oE "wlan\d-\d|wlan\d"
iw dev | grep Interface | cut -f 2 -s -d" "
Eine Liste der im Router definierten Wlan Netzwerke.
wlan0
wlan1
wlan1-1
wlan1-2
Eine List der angemeldeten Clients bekommt man mit einem dieser beiden Befehle:
iwinfo wlan1-1 assoclist
iw dev wlan1-1 station dump
In einer Schleife über alle Wlan Netzwerke und einem Ausgabe Filter bekommt man eine komplette Liste der MAC Adressen der aktiven Wlan Clients:
for w in $(iwinfo |grep -oE "wlan\d-\d|wlan\d"); do
   iwinfo $w assoclist | grep -o -E '([[:xdigit:]]{1,2}:){5}[[:xdigit:]]{1,2}'
done

Abfrage einer bestimmten MAC Adresse

Jetzt alles zusammengefasst mit einer Abfrage eine bestimmten MAC Adresse und als Resultat die Übergabe an einen Dummy in FHEM (API WEB ohne csrf Token!).
Das Script /root/loop.sh
#Die Verzögerungszeit der Abfrageschleife kann auch übergeben werden
WATCHDOG_SLEEP_SEC=${1:-2}
#Url zu FHEM
u=http://192.168.56.80:8088/fhem?cmd=set%20WL_Mi6%20
MAC_ADDRESS_1="80:AD:xx:xx:xx:xx"

while sleep $WATCHDOG_SLEEP_SEC; do
 if (
      for m in $(
                 for w in $(iwinfo |grep -oE "wlan\d-\d|wlan\d")
                 do
                   iwinfo $w assoclist | grep -o -E '([[:xdigit:]]{1,2}:){5}[[:xdigit:]]{1,2}'
                 done
                )
      do
        [ "$m" = "$MAC_ADDRESS_1" ] && exit 0
      done
      exit 1
    )
 then
   c=on
 else
   c=off
 fi

 # tue nur etwas wenn sich c geändert hat
 if [ "$c1" != "$c" ] ; then wget -qs $u$c ; c1=$c ; fi

done

Automatischer Start

Jetzt fehlt noch der automatische Start in OpenWrt. Dafür ist procd zuständig. Ich habe dazu ein init Script mit minimaler Funktion erstellt (siehe auch Erklärung unter dem Text):
cat <<EOF > /etc/init.d/loop
#!/bin/sh /etc/rc.common

USE_PROCD=1

START=99
STOP=01

start_service() {
    procd_open_instance
    procd_set_param command /bin/sh "/root/loop.sh"
    procd_set_param stdout 1
    procd_set_param stderr 1
    procd_close_instance
}
EOF 
Achtung! ich lerne ja selbst immer wieder dazu und habe diesen Code mal bewusst als Here Doc  dargestellt. Wenn man den Text, inklusive der ersten und letzten Zeile, einfach in die Eingabe des Terminals wirft, wird automatisch die Datei am richten Ort erzeugt, ohne das man einen Editor bemühen muss! 
Wer das nicht will, der kopiert den Text ohne die erste und letzte Zeile in den Editor seiner Wahl.

Das Ganze muss noch ausführbar gemacht und aktiviert werden:
chmod +x /etc/init.d/loop
/etc/init.d/loop enable
/etc/init.d/loop start 
Mit dem Befehl service kann man überprüfen ob der Dienst angekommen ist und ihn auch steuern.
root@wrt1900:~# service
service "" not found, the following services are available:
boot              dropbear          linksys_recovery  network           sysfixtime        uhttpd
cron              firewall          lm-sensors        odhcpd            sysntpd           umount
dnsmasq           gpio_switch       log               rpcd              system            urandom_seed
done              led               loop              sysctl            ucitrack

War es das schon?

Es gibt natürlich weitere Ideen:

  • Umstieg auf Eventbasierte Abarbeitung ähnlich wie im verlinkten Beispiel.
  • Konfigurierbare Abfrage mehrerer Clients
  • Auslesen aller Host und Übergabe an FHEM 
Aber jetzt will ich erstmal diesen Prozess eine Weile Probe laufen lassen und ein Monitoring des Routers einrichten.

Keine Kommentare:

Kommentar veröffentlichen