avatar_Телега

Как узнать MAC-адрес с помощью PHP для MU Online

Автор Телега, 2013 Авг. 11, 06:39

« назад - далее »

0 Пользователи и 1 гость просматривают эту тему.

Ключевые слова [SEO] mu onlineсерверные файлы MUпомощь

Телега

Подскажите пожалуйста, можно ли как-то посредством PHP узнать mac адрес сетевой карты?
Мне это нужно для того чтобы при регистрации не делали левых аккаунтов, тоесть в базу будет заноситься мак адрес, и при регистрации проверяться.
Так же хочу при регистрации выдавать энное количество кредитов, здесь тоже эта функция пригодилась бы, чтобы был только один аккаунт.

Если есть какие-то другие идеи, посоветуйте пожалуйста.

epmak

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)
{
$rgLongs=array_map(create_function('$ip', 'return sprintf("%u", ip2long($ip));'), $rgIPs);
$rgSubnets=range(sprintf("%u", ip2long($rgSubnet['net']))+1, sprintf("%u", ip2long($rgSubnet['net']))+pow(2,32-$rgSubnet['mask'])-1);
$rgResult=array_diff($rgSubnets, $rgLongs);
if(!count($rgResult))
{
return null;
}
return long2ip(array_shift($rgResult));
}
/**
* 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)
{
$rgLongs=array_map(create_function('$ip', 'return sprintf("%u", ip2long($ip));'), $rgIPs);
$rgSubnets=range(sprintf("%u", ip2long($rgSubnet['net']))+1, sprintf("%u", ip2long($rgSubnet['net']))+pow(2,32-$rgSubnet['mask'])-1);
$rgResult=array_diff($rgSubnets, $rgLongs);
$rgResult=array_map(create_function('$ip', 'return long2ip($ip);'), $rgResult);
if(!count($rgResult))
{
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;
$rgMatches=array();
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)
{
preg_match($sMacTemplate, $value, $rgMatches);
break;
}
};
}
else
{
exec("arp -a | grep $ip", $rgResult);
if(count($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;
if(!preg_match('/^[d]+$/', $rgSubnet['mask']))
{
$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']));
return (substr_compare($binIP,$binNet,0,$rgSubnet['mask']) === 0);
}
/**
*
* @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           = explode('/', $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))
{
$rgFilter           = explode('-', $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
*/
public function ip2Long($ip=null)
{
//lazy:
if(!$ip && !$this->sCurrentIP)
{
return null;
}
$ip=$ip?$ip:$this->sCurrentIP;
return sprintf("%u", ip2long($ip));
}
//arp may be unreachable due to system security; we still rely on 'which' command
protected function _arp_allowed()
{
if(PHP_OS=='WINNT')
{
return true;
}
$rgResult=array();
exec("which arp 2>&1", $rgResult);
if(!count($rgResult))
{
return false;
}
return !preg_match('/no arp/i',$rgResult[0]);
}

}

Как пример использования:
$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-адресом

так же, мак адрес можно получить только если компьютер в 1 локальной сети с сервером.
и еще, нужно лучше пользоваться поисковиками

Телега

А как вообще можно отследить уникальность компьютера посредством php?

epmak

куки/сессии
название железа (частично, пыха может кое что выдернуть)
но все это обходится, в общем-то...

Телега

сможешь написать подобный модуль?
при регистрации чтобы данные о компе записывало в базу.
а потом если уже комп с такими данными зарегистрирован, то не даст зарегистрироваться

epmak

возможно я не прав, но прежде чем что-то писать, всегда задаю себе вопрос: а зачем? какова цель? что эьл даст?

Телега

Смотри, я хочу привлечь игроков выдаванием кредитов новому игроку. тоесть хочу чтобы было так, человек регистрируется и получает на аккаунт кредиты.
Чтобы не делали много аккаунтов, нужен этот модуль.

epmak

таким способом не защитить. по определению. пхп - серверный язык все, чтобы ты не отправил клиенту можно убрать или изменить. чтобы делать такие вещи, нужно прикладывать к работе ланчер, который бы читал хдид.

Телега

такой лайунчер сколько стоить будет то?)

repsac

Итак, возможный способ осуществления поставленной задачи. Клиент при запуске игры отсылает на сервер свой логин(берется из реестра), свой HWID. Серверная сторона сверяет, нет ли такого HWID в черном списке, и пропускает дальше. Иначе, блокирует доступ этому логину и этому айпишнику.
Что для этого требуется? Встроить небольшое приложение в лаунчер(что бы запускалось до запуска игры), и на сервере вторая часть, которая будет контролировать. Не забываем про шифрование. Иначе грош цена всем работам, если можно перехватить и подделать пакеты.

Сколько это будет стоить? Думаю за 10$ никто и браться не станет, а если станет - выйдет дыряво и криво. Потому что надо не забывать, это установка защиты. А любую защиту будут пытаться взломать.
з.ы. Я этим не занимаюсь, и сам программы писать не умею. Просто немного логически подумал.

Похожие темы (5)