Kilka sposobów na adresy IP w Bashu
Często pracując bezpośrednio w Bashu istnieje potrzeba sprawdzenia np. czy dany adres IPv4 należy do zakresu wyznaczonego przez daną klasę adresową czy jet poza nią. W językach skryptowych typu np. Perl istnieją gotowe moduły wspomagające takie operacje. Poniżej przedstawię kilka sposobów w Bashu.
Sposób nr 1
W tym przypadku pomocna będzie funkcja zamieniająca adres IPv4 na liczbę całkowitą:
iptonum () {
local ip=$1
local ipnum=0
for (( i=0 ; i<4 ; ++i )); do
((ipnum+=${ip%%.*}*$((256**$((3-${i}))))))
ip=${ip#*.}
done
echo $ipnum
}
W powyszym przykładzie, trzeba sprawdzić czy adresy 10.1.1.1 oraz 192.168.1.1 zawierają się w sieci 192.168.0.0/16.
W pierwszym kroku przeliczam graniczne adresy sieci do postaci liczb całkowitych:
192.168.0.0 – 3232235520
192.168.255.255 – 3232301055
Następnie przeliczam zadane adresy IP:
10.1.1.1 – 167837953
192.168.1.1 – 3232235777
Gdy adresy brzegowe sieci oraz zadane adresy są przeliczone można sprawdzić zakresy.
Skrypt realizujący to zadanie:
#!/bin/bash
. plik_z_funkcja_iptonum
ipnum=`iptonum $1`
if [ "$ipnum" -ge 3232235520 -a "$ipnum" -le 3232301055 ]; then
echo "adres $1 zawiera sie w sieci 192.168.0.0/16"
else
echo "adres $1 nie zawiera sie w sieci 192.168.0.0/16"
fi
Wynik działania skryptu:
./skrypt.sh 10.1.1.1
adres 10.1.1.1 nie zawiera sie w sieci 192.168.0.0/16
./skrypt.sh 192.168.1.1
adres 192.168.1.1 zawiera sie w sieci 192.168.0.0/16
Dla porządku poniżej funkcja relizująca odwrotną operację, tj. konwersję liczby całkowitej na adres IP:
numtoip () {
echo -n $(($(($(($((${1}/256))/256))/256))%256)).
echo -n $(($(($((${1}/256))/256))%256)).
echo -n $(($((${1}/256))%256)).
echo $((${1}%256))
}
Sposób nr 2
Istnieje możliwość wykorzystania narzędzi z projektu IPset (obecnego w głównej linii kernela linux od wersji 2.6.39). Sposób ten należy traktować raczej jako szybki workaround wykorzystujący posiadane środowisko i to co jest akurat pod „ręką” niż docelowe rozwiązanie.
W pierwszym kroku tworzę odpowiedni IPset (jeżeli go jeszcze nie posiadamy):
ipset create testipset hash:net
Dodaję do IPseta klasę:
ipset add testipset 192.168.0.0/16
Testuję czy dane adresy należą do sieci:
ipset test testipset 10.1.1.1
10.1.1.1 is NOT in set testipset.
ipset test testipset 192.168.1.1
192.168.1.1 is in set testipset.
Wykorzystując tę metodę w skryptach, istnieje możliwość skorzystania z kodów wyjściowych programu ipset i zastosować parametr -q, żeby uniknąć tekstowego komunikatu zwrotnego.

Dodano dn. 3 lipca 2012 roku przez rob.