Толик Панков
hex_laden
............ .................. ................
October 2025
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31

Определение IP и местоположения посетителя сайта 3.

Вот анон задает справедливый вопрос, до которого из парней догадался лишь умник-Ильюша, четырнадцатилетний переросток из Харькова. Из девок - никто.
Итак.
Q: Что будет, если нашему скрипту подсунуть валидный ip, но не с какой точки зрения смысла не имеющие: адреса частных сетей, адреса для "обратной петли" (LOOPBACK)
A: Будет нечто некрасивое: в геобазе закономерно нет частных ip, коих одинаковых миллионы на Земле, но вообще разработчики, конечно, недоработали. Надо штатный ответ на такой запрос.
Т.е. если просто передать частный IP геобазе, то она выдаст что-то типа такого:


Некрасиво и неправильно.

Так как же этого избежать, известить клиента о такой ситуации?
Известно, что в IANA определены группы адресов для LOOPBACK'а и локальных сетей: см. хотя-бы Википедию, а также известно, что нельзя использовать диапазон IP 0.0.0.0 - 0.255.255.255, заодно это закрыло дырку в регулярном выражении (пропускались конструкции вида 1.1.1.1.1). Надо было бы подправить регулярку, но мне влом, кто хочет - помогите и подправьте. Дам я вам за это ничерта, спасибо скажу только лишь.

Регулярка для валидации IP:
$ip_pattern="#(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)#";

Итак. Добавляем функцию, проверяющую, попал ли IP в диапазон:
function chkdiapip ($user_ip, $ip_from, $ip_to) //попадает ли ip в нужный диапазон
{
  return ( ip2long($user_ip)>=ip2long($ip_from) && ip2long($user_ip)<=ip2long($ip_to) );
}


И функцию, которая последовательно проверяет не попал ли наш IP в один из диапазонов:
function get_spec_diap ($user_ip) //определение, попал ли IP в специальный диапазон
{
  $ret=1;
  //Частные IP
  if (chkdiapip ($user_ip,'10.0.0.0','10.255.255.255'))
  {
    $ret="WRN|IP PRIVATE ADDRESS 10.0.0.0-10.255.255.255";
    return $ret;
  }
  if (chkdiapip ($user_ip,'172.16.0.0','172.31.255.255'))
  {
    $ret="WRN|IP PRIVATE ADDRESS 172.16.0.0-172.31.255.255";
    return $ret;
  }
  if (chkdiapip ($user_ip,'192.168.0.0','192.168.255.255'))
  {
    $ret="WRN|IP PRIVATE ADDRESS 192.168.0.0-192.168.255.255";
    return $ret;
  }
  //Wrong IP
  if (chkdiapip ($user_ip,'0.0.0.0','0.255.255.255'))
  {
    $ret="WRN|IP WRONG ADDRESS 0.0.0.0-0.255.255.255" ;
    return $ret;
  }
  //IP  LOOPBACK
  if (chkdiapip ($user_ip,'127.0.0.0','127.255.255.255'))
  {
    $ret="WRN|IP LOOPBACK ADDRESS 127.0.0.0-127.255.255.255";
    return $ret;
  }

  return $ret;
}

Если IP попал в один из диапазонов - функция возвращает строку с идентификатором события WRN (Внимание, некритичная ошибка или ситуация) и описанием, если IP не попадает ни в один диапазон, то функция возвращает 1.

Перед тем, как создавать объект, вставляем очередную проверку:
//проверяем, не попал ли IP в особый диапазон
$check_diap = get_spec_diap($ip);
if ($check_diap!=1)
{
  echo "IP|".$ip."\n";
  echo $check_diap;
  die();
}

Если попал - выводим сообщение и прерываем скрипт командой die();
Далее делаем, как в сериях 2 и 1, т.е. создаем объект SxGeo, обращаемся к нему и выводим данные в удобном виде.

Скачать можно здесь, посмотреть как работает тут. В качестве аргумента GET вставлен адрес из LOOPBACK-диапазона.


IP из частного диапазона.

Предыдущая серия Продолжение

From:
(will be screened)
Identity URL: 
имя пользователя:    
Вы должны предварительно войти в LiveJournal.com
 
E-mail для ответов: 
Вы сможете оставлять комментарии, даже если не введете e-mail.
Но вы не сможете получать уведомления об ответах на ваши комментарии!
Внимание: на указанный адрес будет выслано подтверждение.
Username:
Password:
Subject:
No HTML allowed in subject
Message:



Notice! This user has turned on the option that logs IP addresses of anonymous posters.