Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770
Форумы портала PHP.SU :: Версия для печати :: Определние IP пользователя
Форумы портала PHP.SU » » Вопросы новичков » Определние IP пользователя

Страниц (1): [1]
 

1. new01 - 08 Августа, 2012 - 21:31:29 - перейти к сообщению
Добрый вечер. Скрипт пользователя EuGen определения IP адреса пользователя.
PHP:
скопировать код в буфер обмена
  1.  
  2. <?PHP
  3. class Network_Simple
  4. {
  5.  
  6.     protected $sCurrentIP;    
  7.  
  8.     protected $rgLocalSubnets=array(
  9.  
  10.         array('net'=>'10.0.0.0',    'mask'=>8),
  11.  
  12.         array('net'=>'192.168.0.0', 'mask'=>16)
  13.  
  14.     );
  15.  
  16.  
  17.  
  18.     function __construct($sCurrentIp=null)
  19.  
  20.     {
  21.  
  22.         $this->sCurrentIp=$sCurrentIp?$sCurrentIp:$_SERVER['REMOTE_ADDR'];
  23.  
  24.     }
  25.  
  26.     /**
  27.  
  28.      * Useful for DHCP purposes. Returns first free IP in specified subnet
  29.  
  30.      * @param array $rgIPs List of busy IP
  31.  
  32.      * @param array $rgSubnet Subnet presentation. Must contain keys 'net' and 'mask'
  33.  
  34.      * @return mixed
  35.  
  36.      */
  37.  
  38.     public function leaseAddressDHCP($rgIPs, $rgSubnet)
  39.  
  40.     {
  41.  
  42.        $rgLongs=array_map(create_function('$ip', 'return sprintf("%u", ip2long($ip));'), $rgIPs);
  43.  
  44.        $rgSubnets=range(sprintf("%u", ip2long($rgSubnet['net']))+1, sprintf("%u", ip2long($rgSubnet['net']))+pow(2,32-$rgSubnet['mask'])-1);
  45.  
  46.        $rgResult=array_diff($rgSubnets, $rgLongs);
  47.  
  48.        if(!count($rgResult))
  49.  
  50.        {
  51.  
  52.           return null;
  53.  
  54.        }
  55.  
  56.        return long2ip(array_shift($rgResult));
  57.  
  58.     }
  59.  
  60.     /**
  61.  
  62.      * Returns full table of free IP addresses in $rgSubnet
  63.  
  64.      * @param array $rgIPs List of busy IP
  65.  
  66.      * @param array $rgSubnet Subnet presentation. Must contain keys 'net' and 'mask'
  67.  
  68.      * @return mixed
  69.  
  70.      */
  71.  
  72.     public function leaseTableDHCP($rgIPs, $rgSubnet)
  73.  
  74.     {
  75.  
  76.        $rgLongs=array_map(create_function('$ip', 'return sprintf("%u", ip2long($ip));'), $rgIPs);
  77.  
  78.        $rgSubnets=range(sprintf("%u", ip2long($rgSubnet['net']))+1, sprintf("%u", ip2long($rgSubnet['net']))+pow(2,32-$rgSubnet['mask'])-1);
  79.  
  80.        $rgResult=array_diff($rgSubnets, $rgLongs);
  81.  
  82.        $rgResult=array_map(create_function('$ip', 'return long2ip($ip);'), $rgResult);
  83.  
  84.        if(!count($rgResult))
  85.  
  86.        {
  87.  
  88.           return null;
  89.  
  90.        }
  91.  
  92.        return $rgResult;
  93.  
  94.     }
  95.  
  96.     /**
  97.  
  98.      * Returns MAC-address (Ethernet 2-level in OSI model address)
  99.  
  100.      * @param string $ip Address to search MAC for. If not set, IP-address from constructor'll be used
  101.  
  102.      * @return mixed
  103.  
  104.      */
  105.  
  106.     public function getMAC($ip=null)
  107.  
  108.     {
  109.  
  110.         if((!$ip && !$this->sCurrentIP) || !$this->_arp_allowed())
  111.  
  112.         {
  113.  
  114.             return null;
  115.  
  116.         }
  117.  
  118.         $ip=$ip?$ip:$this->sCurrentIP;
  119.  
  120.         $rgMatches=array();
  121.  
  122.         if(PHP_OS=='WINNT')
  123.  
  124.         {
  125.  
  126.            exec("arp -a", $rgResult);
  127.  
  128.            $sMacTemplate="/[\d|A-F]{2}\-[\d|A-F]{2}\-[\d|A-F]{2}\-[\d|A-F]{2}\-[\d|A-F]{2}\-[\d|A-F]{2}/i";
  129.  
  130.            foreach($rgResult as $key=>$value)
  131.  
  132.            {
  133.  
  134.               if (strpos($value, $ip)!==FALSE)
  135.  
  136.               {
  137.  
  138.                  preg_match($sMacTemplate, $value, $rgMatches);
  139.  
  140.                  break;
  141.  
  142.               }
  143.  
  144.            };
  145.  
  146.         }
  147.  
  148.         else
  149.  
  150.         {
  151.  
  152.            exec("arp -a | grep $ip", $rgResult);
  153.  
  154.            if(count($rgResult))
  155.  
  156.            {
  157.  
  158.                $sMacTemplate="/[\d|A-F]{2}\:[\d|A-F]{2}\:[\d|A-F]{2}\:[\d|A-F]{2}\:[\d|A-F]{2}\:[\d|A-F]{2}/i";
  159.  
  160.                preg_match($sMacTemplate, $rgResult[0], $rgMatches);
  161.  
  162.            }
  163.  
  164.         }
  165.  
  166.         return count($rgMatches)?$rgMatches[0]:null;
  167.  
  168.     }
  169.  
  170.     /**
  171.  
  172.      * Get client remote IP address
  173.  
  174.      * @param boolean $bReturnLocalIP If set to true, local subnet address'll be returned (if present)
  175.  
  176.      * @return string
  177.  
  178.      */
  179.  
  180.     public function getRemoteIP($bReturnLocalIP=false)
  181.  
  182.     {
  183.  
  184.         if($_SERVER['HTTP_X_FORWARDED_FOR'])
  185.  
  186.         {
  187.  
  188.             $rgIPs=preg_split('/\s+/s', $_SERVER['HTTP_X_FORWARDED_FOR'], -1, PREG_SPLIT_NO_EMPTY);
  189.  
  190.             foreach($rgIPs as $ip)
  191.  
  192.             {
  193.  
  194.                 if($bReturnLocalIP)
  195.  
  196.                 {
  197.  
  198.                     return $ip;
  199.  
  200.                 }
  201.  
  202.                 else
  203.  
  204.                 {
  205.  
  206.                     $bIsLocal=false;
  207.  
  208.                     foreach($this->rgLocalSubnets as $rgSubnet)
  209.  
  210.                     {
  211.  
  212.                         if($this->isInSubnet($rgSubnet, $ip))
  213.  
  214.                         {
  215.  
  216.                             $bIsLocal=true;
  217.  
  218.                         }
  219.  
  220.                     }
  221.  
  222.                     if(!$bIsLocal)
  223.  
  224.                     {
  225.  
  226.                         return $ip;
  227.  
  228.                     }
  229.  
  230.                 }
  231.  
  232.             }
  233.  
  234.         }
  235.  
  236.         return $_SERVER['REMOTE_ADDR'];
  237.  
  238.     }
  239.  
  240.     /**
  241.  
  242.      *
  243.  
  244.      * @param array $rgSubnet Subnet presentation. Must contain keys 'net' and 'mask'
  245.  
  246.      * @param string $ip IP address to compare with subnet
  247.  
  248.      * @return boolean
  249.  
  250.      */
  251.  
  252.     public function isInSubnet($rgSubnet, $ip=null)
  253.  
  254.     {
  255.  
  256.         if((!$ip && !$this->sCurrentIP)|| !is_array($rgSubnet))
  257.  
  258.         {
  259.  
  260.             return false;
  261.  
  262.         }
  263.  
  264.         $ip=$ip?$ip:$this->sCurrentIP;
  265.  
  266.         if(!is_int($rgSubnet['mask']))
  267.  
  268.         {
  269.  
  270.             $rgSubnet['mask']=(int)log(($this->ip2Long('255.255.255.255')-$this->ip2Long($rgSubnet['mask'])),2);
  271.  
  272.         }
  273.  
  274.         $binIP    = sprintf("%032b",$this->ip2Long($ip));
  275.  
  276.         $binNet   = sprintf("%032b",$this->ip2Long($rgSubnet['net']));
  277.  
  278.         return (substr_compare($binIP,$binNet,0,$rgSubnet['mask']) === 0);
  279.  
  280.     }
  281.  
  282.     /**
  283.  
  284.      *
  285.  
  286.      * @param string $ip Address to convert. If not set, IP-address from constructor'll be used
  287.  
  288.      * @return mixed
  289.  
  290.      */
  291.  
  292.     public function ip2Long($ip=null)
  293.  
  294.     {
  295.  
  296.         //lazy:
  297.  
  298.         if(!$ip && !$this->sCurrentIP)
  299.  
  300.         {
  301.  
  302.             return null;
  303.  
  304.         }
  305.  
  306.         $ip=$ip?$ip:$this->sCurrentIP;
  307.  
  308.         return sprintf("%u", ip2long($ip));
  309.  
  310.     }
  311.  
  312.     //arp may be unreachable due to system security; we still rely on 'which' command
  313.  
  314.     protected function _arp_allowed()
  315.  
  316.     {
  317.  
  318.         if(PHP_OS=='WINNT')
  319.  
  320.         {
  321.  
  322.             return true;
  323.  
  324.         }
  325.  
  326.         $rgResult=array();
  327.  
  328.         exec("which arp 2>&1", $rgResult);
  329.  
  330.         if(!count($rgResult))
  331.  
  332.         {
  333.  
  334.             return false;
  335.  
  336.         }
  337.  
  338.         return !preg_match('/no arp/i',$rgResult[0]);
  339.  
  340.     }
  341.  
  342.    
  343.  
  344. }
  345.  

Пример использования скрипта.
PHP:
скопировать код в буфер обмена
  1.  
  2.  
  3. $rgSubnet=array('net'=>'86.45.68.22', 'mask'=>30);
  4.  
  5. $rNet=new Network_Simple();
  6.  
  7. $sIP=$rNet->getRemoteIP();
  8.  
  9. if($rNet->isInSubnet($rgSubnet, $sIP)){
  10.      echo $sIP." был определен как принадлежащий подсети";
  11. }
  12. if($rNet->isInSubnet($rgSubnet)){
  13.      echo $_SERVER['REMOTE_ADDR']." был определен как принадлежащий подсети";
  14. }
  15.  
  16. $sMAC=$rNet->getMAC();
  17.  
  18. //операции с MAC-адресом
  19. ?>
  20.  


Вопросы:
1) Зачем вводится массив $rgSubnet. Переменные $rgSubnet['net'] и $rgSubnet['mask'] надо как-то подстраивать для себя?
2) Условия
PHP:
скопировать код в буфер обмена
  1. if($rNet->isInSubnet($rgSubnet, $sIP))
и
PHP:
скопировать код в буфер обмена
  1. if($rNet->isInSubnet($rgSubnet))
определяют используется ли прокси сервер?

Заранее спасибо.
2. EuGen - 08 Августа, 2012 - 22:47:50 - перейти к сообщению
new01 пишет:
$rgSubnet=array('net'=>'86.45.68.22', 'mask'=>30);

Это та сеть, на принадлежность к которой проверяется IP-адрес. Например, адрес 192.168.0.1 принадлежит сети, описываемой адресом сети 192.168.0.0 и маской 24, но не принадлежит сети, описываемой адресом сети 192.168.1.0 и маской 24.
Так как используется численное значение маски, то допустимо не только использование классовых сетей A,B,C но и, разумеется, CIDR-описателей.
new01 пишет:
if($rNet->isInSubnet($rgSubnet, $sIP))

Просто определяет, принадлежит ли $sIP сети $rgSubnet
new01 пишет:
if($rNet->isInSubnet($rgSubnet))

Покажет, принадлежит ли сети $rgSubnet IP-адрес клиента (так как по умолчанию, если не указан $sIP, будет использоваться REMOTE_ADDR)

 

Powered by ExBB FM 1.0 RC1