Kleine Tools mit großer Wirkung
Motivation für diesen kleinen Helfer war die Notwendigkeit, anhand von MAC-Adressen den Verursacher einer versehentich doppelt vergebenen IP einzukreisen. Die Idee dahinter ist, daß MAC-Adressen (48 Bit) mit je 24 Bit Prefix an Hersteller vergeben werden. Es gibt bei IEEE eine Datei, die die Zuordnung dokumentiert, zB:
00-E0-18 (hex) ASUSTEK COMPUTER INC.
00E018 (base 16) ASUSTEK COMPUTER INC.
150 LI-TE RD.
PEITOU, TAIPEI
TAIWAN, REPUBLIC OF CHINA
Der Gedanke liegt nahe, dieses File automatisiert für eine Suche zu verwenden, das leistet das Script. Die Datei hat derzeit ca 1MB, weswegen es sinnvoll ist, sich eine lokale Kopie zu halten. Das Script prüft, ob das File bereits lokal vorhanden ist und lädt sie ggf zunächst herunter.
Der eigentliche Schritt ist es, die Schreibweisen für die MAC-Adresse in die
benötigte Form xx-yy-zz... zu bringen und dann mit einem eher
simplen Aufruf von grep in der Datei danach zu suchen.
#! /bin/sh
while [ "$1" ]; do C=~/.rfc/; U="http://rabe.uugrn.org/rfc.php?rfc=$1"
F=$C/rfc$1.txt;[ ! -f "$F" ]&&wget -vO "$F" "$U";more "$F";shift;done
# http://rabe.uugrn.org/scripts/rfc.sh by rabe@uugrn.org
Motivation für diesen winzigen Helfer war die Notwendigkeit, schnell und unkompliziert mal eben ein RFC für zwischendurch auf der Shell anzuzeigen. RFCs können durchaus auch mal etwas größere Dateien sein und von daher möchte man diese nicht für jeden Aufruf neu aus dem Netz laden, zumal sich RFCs in der Regel auch nach ihrer Veröffentlichung nicht ändern. Es ist also durchaus eine Methode, einmal abgeholte RFC-Textdateien lokal abzulegen, um sie für einen erneuten Aufruf parat zu haben.
Weiteres Ziel ist es, diesen Vorrat an RFCs mehreren Usern zugänglich zu halten (ein lokaler Cache würde zB nur im Homeverzeichnis des Users oder bestenfalls auf dem selben Rechner verfügbar sein). Die Idee war ein kleiner in PHP geschriebener Proxy, der seinerseits RFCs vorhält oder ggf direkt von ftp://ftp.rfc-editor.org/in-notes/ abholt.
Das Shellscript bedient sich nun des Proxies, um, falls keine lokale Version existiert, das File abzuholen.
Erster Aufruf:
$ lynx -dump -head http://rabe.uugrn.org/rfc.php?rfc=2322
HTTP/1.0 200 OK
X-RFC-Info-Cache: rfc2322.txt not in local cache, fetching from ftp://ftp.rfc-editor.org/in-notes/rfc2322.txt first.
X-RFC-Info-Fetch: Fetched from ftp://ftp.rfc-editor.org/in-notes/rfc2322.txt
Content-Length: 12665
Content-Disposition: attachment; filename="rfc2322.txt"
X-RFC-Info-Source: Original-URL ftp://ftp.rfc-editor.org/in-notes/rfc2322.txt
Zweiter Aufruf:
$ lynx -dump -head http://rabe.uugrn.org/rfc.php?rfc=2322
HTTP/1.0 200 OK
X-RFC-Info-Cache: rfc2322.txt served from local cache.
Content-Length: 12665
Content-Disposition: attachment; filename="rfc2322.txt"
X-RFC-Info-Source: Original-URL ftp://ftp.rfc-editor.org/in-notes/rfc2322.txt
D=${1:-foo.bar};N=${2:-192.168.0};kill -l|tr '\t)A-Z' '\n a-z'|
grep -v ^$|while read I S;do echo -e "$S.$D.\tIN\tA\t$N.$I";done
# http://rabe.uugrn.org/scripts/sig2zone.bash by rabe@uugrn.org
Dieser kleine Helfer gehört eigentlich eher in die Rubrik Fun, aber er ist dennoch recht nützlich, weswegen ich ihn hier vorstelle: Interressant ist dieses Script, wenn man mal auf die Schnelle eine handvoll Hosts nach einem Schema benennen muss. Hier bietet sich eigentlich alles an, wo es bereits feststehende Zuordnungen zwischen Nummern und Begriffen gibt. Das Script erzeugt aus der Ausgabe von kill -l ein Fragment für ein BIND-Zonefile.
kill -l (bash builtin);
1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL
5) SIGTRAP 6) SIGABRT 7) SIGEMT 8) SIGFPE
9) SIGKILL 10) SIGBUS 11) SIGSEGV 12) SIGSYS
13) SIGPIPE 14) SIGALRM 15) SIGTERM 16) SIGURG
17) SIGSTOP 18) SIGTSTP 19) SIGCONT 20) SIGCHLD
21) SIGTTIN 22) SIGTTOU 23) SIGIO 24) SIGXCPU
25) SIGXFSZ 26) SIGVTALRM 27) SIGPROF 28) SIGWINCH
29) SIGINFO 30) SIGUSR1 31) SIGUSR2
Daraus macht das Script dann etwas, was zB so aussieht:
$ bin/sig2zone.bash party.uugrn.org 192.168.2
sighup.party.uugrn.org. IN A 192.168.2.1
sigint.party.uugrn.org. IN A 192.168.2.2
sigquit.party.uugrn.org. IN A 192.168.2.3
sigill.party.uugrn.org. IN A 192.168.2.4
sigtrap.party.uugrn.org. IN A 192.168.2.5
sigabrt.party.uugrn.org. IN A 192.168.2.6
sigemt.party.uugrn.org. IN A 192.168.2.7
sigfpe.party.uugrn.org. IN A 192.168.2.8
sigkill.party.uugrn.org. IN A 192.168.2.9
sigbus.party.uugrn.org. IN A 192.168.2.10
[...]
Die beiden Optionalen Parameter sind zum einen der Domainpart, zB party.uugrn.org,
zum anderen ein IP-Bereich, hier zB 192.168.2. Läßt man die Parameter weg, werden
entsprechend die defaultwerte verwendet.
#! /bin/sh
I=${3:-0};D=${1:-foo.bar};N=${2:-192.168.0};kill -l|tr ' ' '\n'|
while read S;do I=$(($I+1));echo -e "sig$S.$D.\tIN\tA\t$N.$I";done
# http://rabe.uugrn.org/scripts/sig2zone.fbsd.sh by rabe@uugrn.org
Die FreeBSD /bin/kill -l Variante ist noch etwas flexibler, denn hier kann man als dritten optinalen Parameter einen Offset für die Host-IP angeben. Die Ausgabe von kill sieht in FreeBSD so aus:
$ /bin/kill -l
hup int quit ill trap abrt emt fpe kill bus segv sys pipe alrm term urg
stop tstp cont chld ttin ttou io xcpu xfsz vtalrm prof winch info usr1 usr2
Das Script muss hier im vergleich zur bash-Variante die IPs selbst mitzählen, hat aber ein etwas scriptfreundlicheres Ausgabeformat von kill -l
#! /bin/sh
while read H IN A IP;do IP=$(echo $IP|awk -F "." '{print $4"."$3"."$2"."$1;}')
echo -e "$IP.in-addr.arpa.\tIN\tPTR\t$H";done # by rabe@uugrn.org
# http://rabe.uugrn.org/scripts/zone2rev.sh
Die Ausgabe der beiden vorangegangenen Scripte kann man direkt in dieses Script hineinpipen und erhält die jeweiligen Reverse-Zonen, also zB:
$ bin/sig2zone.fbsd.sh bla.fasel 192.168.10 42 | head -n 5
sighup.bla.fasel. IN A 192.168.10.43
sigint.bla.fasel. IN A 192.168.10.44
sigquit.bla.fasel. IN A 192.168.10.45
sigill.bla.fasel. IN A 192.168.10.46
sigtrap.bla.fasel. IN A 192.168.10.47
$ bin/sig2zone.fbsd.sh bla.fasel 192.168.10 42 | head -n 5 | bin/zone2rev.sh
43.10.168.192.in-addr.arpa. IN PTR sighup.bla.fasel.
44.10.168.192.in-addr.arpa. IN PTR sigint.bla.fasel.
45.10.168.192.in-addr.arpa. IN PTR sigquit.bla.fasel.
46.10.168.192.in-addr.arpa. IN PTR sigill.bla.fasel.
47.10.168.192.in-addr.arpa. IN PTR sigtrap.bla.fasel.