Партнеры:
Полезное
Навигация
Поиск
Статьи / Наши статьи / Скрипт проверки наличия определенного адреса ряду сетей
Зачем это надо?? Ну я думаю что самый распрастраненный ответ на територии Украины - это проверка являеться ли заданый узел частью UA-IX или нет. Конечно, можно обойтись и без всякого скрипта, достаточно каждый интересующий Вас сайт резолвить, а потом просто смотреть на спиоск сетей http://www.colocall.net/ua/prefixes.txt и быстренько в уме персчитывать их, и проверять не является ли ваш хост частью одной из 892 сетей ( по состоянию на 10.03.07). Вы может скажете, зачем писать скрипт, если есть уже готовые, тогда можно с увереностью сказать, что эта статья не для Вас и можете не тратить время для продолжения ее чтения. Ну что ж, перейдем к делу.
Как уже упоминалось выше, по ссылке http://www.colocall.net/ua/prefixes.txt лежит файлик с сетями, которые официально являются частью UA-IX. Наш скрипт будет использовать его как источник информации. Формат его прост:
62.16.0.0/19
62.64.64.0/18
62.80.160.0/19
62.149.0.0/19
62.221.32.0/23
62.221.34.0/24
62.221.37.0/24
62.221.38.0/23
62.221.40.0/21
62.221.48.0/21
Обьясню, для тех, кто может быть не знает первая часть до "/" - это адрес подсети, а после - количество единичных бит в маске. Что нам делать с этим добром?? Лично я решил, что надо привести его к виду определенного диапазона ip адресов а потом уж проверять входит ли сюда интересующмий нас хост. Как это делать??
Для подсети 12.34.32.0/19 это выглядит так:
Адрес сети: 00001100 00100010 00100000 00000000 (12.34.32.0)
Маска подсети: 11111111 11111111 11100000 00000000 (/19)
тоесть /19 - значит первых 19 бит маски будут "1".
Итак идем дальше, нули в маске подсети указывает на количество возможных адресов в жаной подсети. В нашем случае их 13. Следовательно в это подсеть входят (2^13)-2 хостов. Теперь нам следует пересчитать, сколько сетей это будет в третьем октете. Делаеться это так: 8190 mod 256 = 31. Теперь это число нам надо прибавить к третьему октету нашей подсети, а к четвертому прибавляем 255, и получаем верх диапазона: 12.34.63.255, следовательно хосты из этой подсети будут иметь адрес в пределе от 12.34.32.0 до 12.34.63.255.
А теперь перейдем к практике. Писал скрипт я на PHP, потому что с perl-ом не дружу =).
<?
#выводим форму, в которую вводится интересующий нас адрес
echo "<form action=\"ua.php\" method=post>
<input type=text name=\"addr\"><input type=submit></form>";
#в случае если в форму было что-то введено
if (!empty($_POST['addr']))
{
#сохраняем ввод в переменную $host, понадобится потом при выводе
$host=$_POST['addr'];
#на всякий случай делаем gethostbyname, а вдруг введено было имя хоста.
$_POST['addr']=gethostbyname($_POST['addr']);
#сохраняем ip в переменную, понадобится при выводе
$tmp=$_POST['addr'];
#разбиваем наш ip на части, тоесть на октеты. Разделитель - "."
list($ad1,$ad2,$ad3,$ad4)=split('[.]',$_POST['addr']);
#Если введен ip за пределами ipv4, выводим об ошибке
if (($ad1>255)||($ad2>255)||($ad3>255)||($ad4>255)||($ad1<0)||($ad2<0)||($ad3<0)||($ad4<0)) {echo "С каких пор ip выходит за предел 0-255???"; exit;};
#Если хостер позволяет, то читаем оригинал файла с ua подсетями
$list=fopen("http://www.colocall.net/ua/prefixes.txt","r");
#Если хостер не позволяет, тогда строку выше коментим, строку ниже раскоменчиваем. Во втором случае придется скачать список сетей и положитьих в файл list
#$list =fopen("list","r");
#Пока не прочитаем все сети
while (!feof($list))
{
#считываем в переменную подсеть
$buffer = fgets($list, 128);
#разбиваем на октеты и подсеть
list($min1,$min2,$min3,$min4,$nm)=split('[/.]',$buffer);
#ниже моя функция возведения двойки в степень n, как сделатьпо другому, не знаю =)
$step= 1;
for ($i=1; $i<(32-$nm)+1;$i++)
$step=$step*2;
$step=$step-2;
#теперь считаем число 3 октетов
$tt= ($step-($step%256))/256;
#и прибавляем их к числу 3 октетов сети
$max3=$min3+$tt;
$found=0;
#если введенный ip в пределах этой подсети, в found пишем 1
if (($min1==$ad1)&&($min2==$ad2)&& (($min3<=$ad3)&&($max3>=$ad3)) ) {$found=1; break;}
}
#Если в found единичка, выводим сообщение о том, что хост в ua-ix, если нет, то выводим обратно
if ($found==1) echo "<font color=green>$host - $tmp is in UA-IX!!!</font><br>";
else echo "<font color=red>$host - $tmp is not in UA-IX</font><br>";
}
?>
Ну вот и все. Посмотреть пример работы скрипта можно по этой ссылке. Я не говорю, что написано тут все идеально, я уверен что все это дело можно упростить, но особо нет времени разбираться как это делать. Если кто знает, что тут можно улучшить, пишите мне.
Как уже упоминалось выше, по ссылке http://www.colocall.net/ua/prefixes.txt лежит файлик с сетями, которые официально являются частью UA-IX. Наш скрипт будет использовать его как источник информации. Формат его прост:
62.16.0.0/19
62.64.64.0/18
62.80.160.0/19
62.149.0.0/19
62.221.32.0/23
62.221.34.0/24
62.221.37.0/24
62.221.38.0/23
62.221.40.0/21
62.221.48.0/21
Обьясню, для тех, кто может быть не знает первая часть до "/" - это адрес подсети, а после - количество единичных бит в маске. Что нам делать с этим добром?? Лично я решил, что надо привести его к виду определенного диапазона ip адресов а потом уж проверять входит ли сюда интересующмий нас хост. Как это делать??
Для подсети 12.34.32.0/19 это выглядит так:
Адрес сети: 00001100 00100010 00100000 00000000 (12.34.32.0)
Маска подсети: 11111111 11111111 11100000 00000000 (/19)
тоесть /19 - значит первых 19 бит маски будут "1".
Итак идем дальше, нули в маске подсети указывает на количество возможных адресов в жаной подсети. В нашем случае их 13. Следовательно в это подсеть входят (2^13)-2 хостов. Теперь нам следует пересчитать, сколько сетей это будет в третьем октете. Делаеться это так: 8190 mod 256 = 31. Теперь это число нам надо прибавить к третьему октету нашей подсети, а к четвертому прибавляем 255, и получаем верх диапазона: 12.34.63.255, следовательно хосты из этой подсети будут иметь адрес в пределе от 12.34.32.0 до 12.34.63.255.
А теперь перейдем к практике. Писал скрипт я на PHP, потому что с perl-ом не дружу =).
<?
#выводим форму, в которую вводится интересующий нас адрес
echo "<form action=\"ua.php\" method=post>
<input type=text name=\"addr\"><input type=submit></form>";
#в случае если в форму было что-то введено
if (!empty($_POST['addr']))
{
#сохраняем ввод в переменную $host, понадобится потом при выводе
$host=$_POST['addr'];
#на всякий случай делаем gethostbyname, а вдруг введено было имя хоста.
$_POST['addr']=gethostbyname($_POST['addr']);
#сохраняем ip в переменную, понадобится при выводе
$tmp=$_POST['addr'];
#разбиваем наш ip на части, тоесть на октеты. Разделитель - "."
list($ad1,$ad2,$ad3,$ad4)=split('[.]',$_POST['addr']);
#Если введен ip за пределами ipv4, выводим об ошибке
if (($ad1>255)||($ad2>255)||($ad3>255)||($ad4>255)||($ad1<0)||($ad2<0)||($ad3<0)||($ad4<0)) {echo "С каких пор ip выходит за предел 0-255???"; exit;};
#Если хостер позволяет, то читаем оригинал файла с ua подсетями
$list=fopen("http://www.colocall.net/ua/prefixes.txt","r");
#Если хостер не позволяет, тогда строку выше коментим, строку ниже раскоменчиваем. Во втором случае придется скачать список сетей и положитьих в файл list
#$list =fopen("list","r");
#Пока не прочитаем все сети
while (!feof($list))
{
#считываем в переменную подсеть
$buffer = fgets($list, 128);
#разбиваем на октеты и подсеть
list($min1,$min2,$min3,$min4,$nm)=split('[/.]',$buffer);
#ниже моя функция возведения двойки в степень n, как сделатьпо другому, не знаю =)
$step= 1;
for ($i=1; $i<(32-$nm)+1;$i++)
$step=$step*2;
$step=$step-2;
#теперь считаем число 3 октетов
$tt= ($step-($step%256))/256;
#и прибавляем их к числу 3 октетов сети
$max3=$min3+$tt;
$found=0;
#если введенный ip в пределах этой подсети, в found пишем 1
if (($min1==$ad1)&&($min2==$ad2)&& (($min3<=$ad3)&&($max3>=$ad3)) ) {$found=1; break;}
}
#Если в found единичка, выводим сообщение о том, что хост в ua-ix, если нет, то выводим обратно
if ($found==1) echo "<font color=green>$host - $tmp is in UA-IX!!!</font><br>";
else echo "<font color=red>$host - $tmp is not in UA-IX</font><br>";
}
?>
Ну вот и все. Посмотреть пример работы скрипта можно по этой ссылке. Я не говорю, что написано тут все идеально, я уверен что все это дело можно упростить, но особо нет времени разбираться как это делать. Если кто знает, что тут можно улучшить, пишите мне.
С уважением,
boffin
boffin


