Профессионал
Покинул форум
Сообщений всего: 9095
Дата рег-ции: Июнь 2007
Откуда: Berlin
Помог: 707 раз(а)
Представляю Вашему вниманию простой класс для работы с сетью. Класс предоставляет базовые методы по обработке и поиску адресов.
PHP:
скопировать код в буфер обмена
class Network_Simple
{
protected $sCurrentIP ;
protected $rgLocalSubnets = array ( array ( 'net' => '10.0.0.0' , 'mask' => 8
) , array ( 'net' => '192.168.0.0' , 'mask' => 16
) ) ;
function __construct( $sCurrentIp = null )
{
$this -> sCurrentIp = $sCurrentIp ?$sCurrentIp : $_SERVER [ 'REMOTE_ADDR' ] ;
}
/**
* Useful for DHCP purposes. Returns first free IP in specified subnet
* @param array $rgIPs List of busy IP
* @param array $rgSubnet Subnet presentation. Must contain keys 'net' and 'mask'
* @return mixed
*/
public function leaseAddressDHCP( $rgIPs , $rgSubnet )
{
{
return null ;
}
}
/**
* Returns full table of free IP addresses in $rgSubnet
* @param array $rgIPs List of busy IP
* @param array $rgSubnet Subnet presentation. Must contain keys 'net' and 'mask'
* @return mixed
*/
public function leaseTableDHCP( $rgIPs , $rgSubnet )
{
{
return null ;
}
return $rgResult ;
}
/**
* Returns MAC-address (Ethernet 2-level in OSI model address)
* @param string $ip Address to search MAC for. If not set, IP-address from constructor'll be used
* @return mixed
*/
public function getMAC( $ip = null )
{
if ( ( ! $ip && ! $this -> sCurrentIP ) || ! $this -> _arp_allowed( ) )
{
return null ;
}
$ip = $ip ?$ip : $this -> sCurrentIP ;
if ( PHP_OS == 'WINNT' )
{
exec ( "arp -a" , $rgResult ) ; $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" ;
foreach ( $rgResult as $key => $value )
{
if ( strpos ( $value , $ip ) !== FALSE ) {
break ;
}
} ;
}
else
{
exec ( "arp -a | grep $ip " , $rgResult ) ; {
$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" ;
preg_match ( $sMacTemplate , $rgResult [ 0
] , $rgMatches ) ; }
}
return count ( $rgMatches ) ?
$rgMatches [ 0
] : null ; }
/**
* Get client remote IP address
* @param boolean $bReturnLocalIP If set to true, local subnet address'll be returned (if present)
* @return string
*/
public function getRemoteIP( $bReturnLocalIP = false )
{
if ( $_SERVER [ 'HTTP_X_FORWARDED_FOR' ] )
{
$rgIPs = preg_split ( '/\s+/s' , $_SERVER [ 'HTTP_X_FORWARDED_FOR' ] , - 1
, PREG_SPLIT_NO_EMPTY
) ; foreach ( $rgIPs as $ip )
{
if ( $bReturnLocalIP )
{
return $ip ;
}
else
{
$bIsLocal = false ;
foreach ( $this -> rgLocalSubnets as $rgSubnet )
{
if ( $this -> isInSubnet ( $rgSubnet , $ip ) )
{
$bIsLocal = true ;
}
}
if ( ! $bIsLocal )
{
return $ip ;
}
}
}
}
return $_SERVER [ 'REMOTE_ADDR' ] ;
}
/**
*
* @param array $rgSubnet Subnet presentation. Must contain keys 'net' and 'mask'
* @param string $ip IP address to compare with subnet
* @return boolean
*/
public function isInSubnet( $rgSubnet , $ip = null )
{
if ( ( ! $ip && ! $this -> _current_ip
) || ! is_array ( $rgSubnet ) ) {
return false ;
}
$ip = $ip ?$ip : $this -> _current_ip;
{
$rgSubnet [ 'mask' ] = ( int
) log ( ( $this -> ip2Long ( '255.255.255.255' ) - $this -> ip2Long ( $rgSubnet [ 'mask' ] ) ) , 2
) ; }
else
{
$rgSubnet [ 'mask' ] = ( int) $rgSubnet [ 'mask' ] ;
}
if ( $rgSubnet [ 'mask' ] === 0)
{
return true ;
}
$binIP = sprintf ( "%032b " , $this -> ip2Long ( $ip ) ) ; $binNet = sprintf ( "%032b " , $this -> ip2Long ( $rgSubnet [ 'net' ] ) ) ; }
/**
*
* @param string $sFrom starting IP in range
* @param string $sTill ending IP in range
* @param string $ip optional ip for check
* @return boolean
*/
public function isInRange( $sFrom , $sTill , $ip = null )
{
if ( ( ! $ip && ! $this -> _current_ip) )
{
return false ;
}
$ip = $ip ?$ip : $this -> _current_ip;
return $this -> ip2Long ( $sFrom ) <= ip2long ( $ip ) && $this -> ip2Long ( $sTill ) >= ip2long ( $ip ) ; }
/**
*
* @param string $sHost remote host to be checked
* @param string $ip optional ip for check
* @return boolean
*/
public function isInHost( $sHost , $ip = null )
{
if ( ( ! $ip && ! $this -> _current_ip) )
{
return false ;
}
$ip = $ip ?$ip : $this -> _current_ip;
if ( $_SERVER [ 'REMOTE_HOST' ] == $sHost )
{
return true ;
}
return false ;
}
/**
* Check if IP is in wild-range of IP and/or subnets/ranges
* @param array $rgList an array of string representation for checks. .htaccess format is supported
* @param string $ip optional ip for check
* @return boolean
*/
public function isInList( $rgList , $ip = null )
{
if ( ( ! $ip && ! $this -> _current_ip) )
{
return false ;
}
$ip = $ip ?$ip : $this -> _current_ip;
foreach ( $rgList as $mData )
{
//subnet:
if ( preg_match ( '/^(\d+\.\d+\.\d+\.\d+)\/(.*?)$/' , $mData ) ) {
$rgFilter [ 'net' ] = $rgFilter [ 0] ;
$rgFilter [ 'mask' ] = $rgFilter [ 1] ;
if ( $this -> isInSubnet ( $rgFilter ) )
{
return true ;
}
}
//range
if ( preg_match ( '/^(\d+\.\d+\.\d+\.\d+)\-(\d+\.\d+\.\d+\.\d+)$/' , $mData ) ) {
if ( $this -> isInRange ( $rgFilter [ 0] , $rgFilter [ 1] ) )
{
return true ;
}
}
//address?
if ( $ip == $mData )
{
return true ;
}
//dns?
if ( $this -> isInHost ( $mData ) )
{
return true ;
}
}
return false ;
}
/**
*
* @param string $ip Address to convert. If not set, IP-address from constructor'll be used
* @return mixed
*/
{
//lazy:
if ( ! $ip && ! $this -> sCurrentIP )
{
return null ;
}
$ip = $ip ?$ip : $this -> sCurrentIP ;
}
//arp may be unreachable due to system security; we still rely on 'which' command
protected function _arp_allowed( )
{
if ( PHP_OS == 'WINNT' )
{
return true ;
}
exec ( "which arp 2>&1" , $rgResult ) ; {
return false ;
}
}
}
Как пример использования:
PHP:
скопировать код в буфер обмена
$rgSubnet = array ( 'net' => '86.45.68.22' , 'mask' => 30
) ; $rNet = new Network_Simple( ) ;
$sIP = $rNet -> getRemoteIP ( ) ;
if ( $rNet -> isInSubnet ( $rgSubnet , $sIP ) )
{
echo ( $sIP . " был определен как принадлежащий подсети" ) ;
}
if ( $rNet -> isInSubnet ( $rgSubnet ) )
{
echo ( $_SERVER [ 'REMOTE_ADDR' ] . " был определен как принадлежащий подсети" ) ;
}
$sMAC = $rNet -> getMAC ( ) ;
//операции с MAC-адресом
-----Есть в мире две бесконечные вещи - это Вселенная и человеческая глупость. Но насчет первой .. я не уверен.