Spass mit pyinotify

Heute schreibe ich ein wenig über die Python Bibliothek pyinotify, welche das Inotify Kernel Feature aufsetzt. Inotify ist ein Mechanismus welcher seit demKernel release 2.6.13 in den Vanilla Kernel Quellen vorhanden ist. Welcher eine permanente Überwachung von Dateien und Verzeichnissen ermöglicht. Ändert sich eine überwachte Datei oder Verzeichnis gibt Inotify eine Meldung aus, welche andere Programme zu bestimmten Tätigkeiten veranlassen kann. Quelle:Wikipedia.
Im folgenden wird Benutzung von pyinotify anhand eines kleinen Skriptes erklärt, welches Änderungen an der Datei “/proc/net/arp” überwacht. Sobald sich der Inhalt der Datei ändert wird ein Prozess des “arp” Tools gespawnt das die Änderung in die Arp-Tabelle einträgt. Das Skript benutzt scapy2.2.0 so wie den Pyinotify wrapper zum Skripten der Events.
Bei den neuesten Ubuntu Versionen sollte ein

sudo apt-get install python-scapy python-pyinotify

seinen Zweck erfüllen.
Auf älteren Systemen (Lucid Lynx) rate ich dazu Scapy aus dem Netz zu laden und selber zu Installieren.Das Skript auf welches ich mich hier beziehe besteht im Grunde aus zwei simplen Methoden und dem Konstruktor. Fangen wir mit der Erklärung des Konstruktors an:

class secMyass(object):
        def __init__(self):
               self.router = conf.route.routes[-1][-3]
	       self.mask = pyinotify.IN_MODIFY | pyinotify.IN_OPEN

Wie man sieht gestaltet sich der Konstruktor ziemlich simpel, self.router ruft conf.route.routes auf. Dies stellt ein Zweidimensionales Array da welches die Routen der Kernel-routingtabelle abbildet. Der Zweck des Aufrufes ist den Standard Gateway für des lokalen Netzwerkes zu ermitteln. Die self.mask Zuweisung gibt an auf welche notify Ereignisse später Überwacht werden soll. Die Methode set_gw_mac beschreibt das setzen des Gateway Eintrags. Entscheidend ist die erste Zeile nach dem Funktionskopf:

def set_gw_mac(self):
                child = pexpect.spawn("arp -s %s %s " % (self.router,getmacbyip(self.router)))
                child.logfile = sys.stderr
                child.readline()
                child.expect(pexpect.EOF)

child ist eine Zuweisung auf den Aufruf der pexpect Methode spawnt, welche das arp Programm im Hintergrund als Prozess spawnt. Der Formatstring formatiert die erste Stelle zu self.router welche die Standard Gateway IP zurück gibt. Die Zweite Stelle ruft die getmacbyip() Methode von scapy auf der nochmals self.router übergeben wird, was in der Rückgabe der Gateway MAC Adresse endet. Die übrigen drei Zeilen der Methode sollten relativ selbst sprechend sein.
Nun der interessante Teil welcher die Benutzung von pyinotify beschreibt:

        def fileWatcher(self):
                wm = pyinotify.WatchManager()
                notifier = pyinotify.ThreadedNotifier(wm)
                wm.add_watch('/proc/net/arp', self.mask,rec=False)
                if notifier.check_events():
                        self.set_gw_mac()
                        print "Gateway Mac changed!"

wm ist eine Zuweisung des Methoden Aufrufers WatchManager() die Operationen und Optionen anbietet für die Überwachung von Dateien und Verzeichnissen. Notifier ruft den ThreadedNotiefier auf und übergibt WachManager an diesen. Der ThreadedNotifier Klasse werden von Threading und der Notifier Klasse Methoden und Objekte vererbt. Die folgende Zeile welche über WatchManager die add_watch Methode aufruft definiert den eigentlichen Watchevent. Welcher das zu überwachende Verzeichnis übergeben bekommt und self.mask des Konstruktors, in dem die Events angegeben wurden auf die Überwacht werden sollen. Die if Verzweigung ruft über den Notifier die check_events Methode auf und geht den darauf folgenden Anweisungs Block durch wenn check_events “True” zurück gibt. Der Anweisungsblock startet den Überwachungsprozess. Und im Falle des Auftretens eines der im Konstruktor definierten Events, wird die set_gw_mac Methode ausgeführt sowie eine kurze Nachricht über die Änderung ausgegeben.
Natürlich gibt es noch zahllose andere Möglichkeiten was mit Inotify noch alles möglich ist, doch das würde den Rahmen dieses Artikels sprengen.
In diesem Sinne viel Spaß noch am Gerät…

Weblinks:

Pyinotify Homepage
Pyinotify Developer Repository
Bitbucket Repo Link zum Arp-Entry watch Skript