Blog. Just Blog
Проверка принадлежности IP-адреса заданному диапазону
Проверка вхождения IP в заданный диапазон может применяться во многих ситуациях. Например бан всей подсетки злоумышленника, принудительное ограничение скорости для зарубежного трафика, переадресация на различные разделы сайта в зависимости от провайдера пользователя и т.д. Я использую такие функции:Code (PHP) : Убрать нумерацию
- // ------------------------------------------------------------
- // Проверка вхождения IP в заданный диапазон
- // На входе:
- // $ip - массив октетов проверяемого IP
- // $ip_start - массив октетов начала интервала
- // $ip_end - массив октетов конца интервала
- // В интервалах допускаются маски '*'
- // На выходе: TRUE или FALSE, входит IP или нет в диапазон
- // ------------------------------------------------------------
- function chk_ips($ip,$ip_start,$ip_end) {
- for ($i=0; $i<4; $i++) {
- // Проверка используется или нет маска в диапазоне
- if ($ip_start[$i]=='*' || $ip_end[$i]=='*') {
- // Переходим к следующему октету
- continue;
- }
- // Поверяемый октет между начальным и конечным, значит весь IP-адрес
- // входит в проверяемый диапазон
- elseif ($ip[$i]>=$ip_start[$i] && $ip[$i]<$ip_end[$i]) {
- break;
- }
- // Проверяемый октет равен октету начала или конца диапазона
- elseif ($ip[$i]==$ip_start[$i] || $ip[$i]==$ip_end[$i]) {
- // Переходим к следующему октету
- continue;
- }
- else {
- // IP не входит в интервал
- return false;
- }
- }
- // Весь IP совпадает с началом или концом диапазона, или входит в него
- return true;
- }
Для разворачивания маски подсети используется вспомогательная функция:
Code (PHP) : Убрать нумерацию
- // ------------------------------------------------------------
- // Функция разворачивания маски подсети
- // На входе:
- // $ip - массив октетов начала диапазона
- // $mask - маска
- // На выходе:
- // массив IP конца диапазона
- // ------------------------------------------------------------
- function addip($ip,$mask) {
- // Количество IP в каждой маске
- $ip_count=Array(32=>0, 31=>1, 30=>3, 29=>7, 28=>15, 27=>31, 26=>63,
- 25=>127, 24=>255, 23=>511, 22=>1023, 21=>2047, 20=>4095,
- 19=>8191, 18=>16383, 17=>32767, 16=>65535, 15=>131071,
- 14=>262143, 13=>524287, 12=>1048575, 11=>2097151,
- 10=>4194303, 9=>8388607, 8=>16777215, 7=>33554431,
- 6=>67108863, 5=>134217727, 4=>268435455, 3=>536870911,
- 2=>1073741823);
- $x=Array();
- $ips=$ip_count[$mask];
- $x[0]=$ip[0]+intval($ips/(256*256*256));
- $ips=($ips%(256*256*256));
- $x[1]=$ip[1]+intval($ips/(256*256));
- $ips=($ips%(256*256));
- $x[2]=$ip[2]+intval($ips/(256));
- $ips=($ips%256);
- $x[3]=$ip[3]+$ips;
- return ($x);
- }
Code (PHP) : Убрать нумерацию
- // ------------------------------------------------------------
- // Парсер диапазонов IP
- // На входе:
- // $range - строка диапазона
- // На выходе:
- // Массив из двух массивов ([0]=>ip_start, [1]=>ip_end)
- // или FALSE если строка не является допустимым диапазоном
- // ------------------------------------------------------------
- function range_parser($range) {
- $range=trim($range);
- // Проверка диапазона вида x.x.x.x-y.y.y.y
- if (strpos($range,"-")) {
- $tmp=explode("-",$range);
- $ip_start=explode(".",$tmp[0]);
- $ip_end=explode(".",$tmp[1]);
- }
- // Проверка диапазона вида x.x.x.x/y
- elseif (strpos($range,"/")) {
- $tmp=explode("/",$range);
- $ip_start=explode(".",$tmp[0]);
- // Развернуть маску подсети
- $ip_end=addip($ip_start,$tmp[1]);
- }
- // Проверка диапазона вида x.x.*.* или одиночного IP
- else {
- $ip_start=$ip_end=explode(".",$range);
- }
- // Простенькая проверка на корректность полученных диапазонов
- if (count($ip_start)==4 && count($ip_end)==4) {
- return array($ip_start, $ip_end);
- }
- else {
- return false;
- }
- }
Code (PHP) : Убрать нумерацию
- $ip="127.0.12.7"; // IP для проверки
- $test_ip=explode(".",$ip);
- $range="127.0.0.0/22"; // Маска подсети
- $chk=range_parser($range);
- chk_ips($test_ip,$chk[0],$chk[1]); // FALSE
- $range="127.0.0.0-127.1.0.255"; // Интервал IP-адресов
- $chk=range_parser($range);
- chk_ips($test_ip,$chk[0],$chk[1]); // TRUE
- $range="127.0.12.2"; // Одиночный IP
- $chk=range_parser($range);
- chk_ips($test_ip,$chk[0],$chk[1]); // FALSE
- $range="127.*.*.*"; // Маска IP
- $chk=range_parser($range);
- chk_ips($test_ip,$chk[0],$chk[1]); // TRUE
Просмотров: 8317 | Комментариев: 3
Комментарии
Отзывы посетителей сайта о статье
Энто
(24.04.2012 в 21:59):
А не могли бы вы еще и написать где можно это дело откомпелированное скачать? или юзать онлайн?
pwn
(20.07.2010 в 01:43):
а можно еще проще. вместо того чтоб городить городушки с массивом,
число адресов можно посчитать такой простой формулой
$ips=pow(2,32-$mask); это как раз будет число адресов. Но так как у автора в массиве юзается то же, но только на единицу меньше, то чтоб в его функции это работало нужно сказать так
$ips=pow(2,32-$mask)-1;
число адресов можно посчитать такой простой формулой
$ips=pow(2,32-$mask); это как раз будет число адресов. Но так как у автора в массиве юзается то же, но только на единицу меньше, то чтоб в его функции это работало нужно сказать так
$ips=pow(2,32-$mask)-1;
Валерий
(09.06.2009 в 17:38):
Можно гораздо проще
//-- Разрешенные диапазоны
$Allow_Ip_Range = array('212.158.173.0/24','212.118.48.0/24','82.198.171.0/24');
//-------------------------------------------------------------------
//-- Функция проверки ip
//-------------------------------------------------------------------
function Check_Ip ($Ip_For_Search, $Allow_Ip_Range)
{
$ip_count = array(32=>0, 31=>1, 30=>3, 29=>7, 28=>15, 27=>31, 26=>63, 25=>127, 24=>255, 23=>511, 22=>1023, 21=>2047, 20=>4095,
19=>8191, 18=>16383, 17=>32767, 16=>65535, 15=>131071, 14=>262143, 13=>524287, 12=>1048575, 11=>2097151,
10=>4194303, 9=>8388607, 8=>16777215, 7=>33554431, 6=>67108863, 5=>134217727, 4=>268435455, 3=>536870911,
2=>1073741823);
$Ip_For_Search_Converted = ip2long($Ip_For_Search);
$Result = FALSE;
foreach ( $Allow_Ip_Range as $Value )
{
list($ip, $prefix) = preg_split('/\//',$Value);
$Range_Start = ip2long($ip);
$Range_End = $Range_Start + $ip_count["$prefix"];
echo "";
if ( $Ip_For_Search_Converted >= $Range_Start && $Ip_For_Search_Converted <= $Range_End )
{
return TRUE;
}
}
return $Result;
}
//-- Разрешенные диапазоны
$Allow_Ip_Range = array('212.158.173.0/24','212.118.48.0/24','82.198.171.0/24');
//-------------------------------------------------------------------
//-- Функция проверки ip
//-------------------------------------------------------------------
function Check_Ip ($Ip_For_Search, $Allow_Ip_Range)
{
$ip_count = array(32=>0, 31=>1, 30=>3, 29=>7, 28=>15, 27=>31, 26=>63, 25=>127, 24=>255, 23=>511, 22=>1023, 21=>2047, 20=>4095,
19=>8191, 18=>16383, 17=>32767, 16=>65535, 15=>131071, 14=>262143, 13=>524287, 12=>1048575, 11=>2097151,
10=>4194303, 9=>8388607, 8=>16777215, 7=>33554431, 6=>67108863, 5=>134217727, 4=>268435455, 3=>536870911,
2=>1073741823);
$Ip_For_Search_Converted = ip2long($Ip_For_Search);
$Result = FALSE;
foreach ( $Allow_Ip_Range as $Value )
{
list($ip, $prefix) = preg_split('/\//',$Value);
$Range_Start = ip2long($ip);
$Range_End = $Range_Start + $ip_count["$prefix"];
echo "";
if ( $Ip_For_Search_Converted >= $Range_Start && $Ip_For_Search_Converted <= $Range_End )
{
return TRUE;
}
}
return $Result;
}
Добавить комментарий
Заполните форму для добавления комментария
