php通过ARP地址解析协议获取用户设备的mac地址

一、ARP地址解析协议

ARP的功能是在32bit的ip地址和采用不同网络技术的硬件地址之间提供动态映射。
ARP高速运行的关键是由于每个主机上都有一个ARP高速缓存,这个高速缓存存放了最近Internet地址到硬件地址之间的映射记录。
可以在linux中通过命令arp -a查看,参数-a的意思是显示高速缓存中所有的内容

1
2
3
4
5
6
7
# arp -a
? (192.168.31.53) at f4:60:e2:a7:f7:60 [ether] on enp4s0
? (192.168.31.109) at 94:bf:2d:52:42:34 [ether] on enp4s0
gateway (192.168.31.1) at 84:5b:12:4b:14:41 [ether] on enp4s0
? (192.168.31.152) at 3c:52:82:67:8d:b9 [ether] on enp4s0
这里列举了最近20分钟访问的ip及ip对应的mac地址

二、php代码实现

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
<?php
/**
* 获取客户端IP地址
* @param integer $type 返回类型 0 返回IP地址 1 返回IPV4地址数字
* @return mixed
*/
function getClientIp($type = 0)
{
$ip = "";
if (getenv('HTTP_CLIENT_IP') && strcasecmp(getenv('HTTP_CLIENT_IP'), 'unknown')) {
$ip = getenv('HTTP_CLIENT_IP');
} elseif (getenv('HTTP_X_FORWARDED_FOR') && strcasecmp(getenv('HTTP_X_FORWARDED_FOR'), 'unknown')) {
$ip = getenv('HTTP_X_FORWARDED_FOR');
} elseif (getenv('REMOTE_ADDR') && strcasecmp(getenv('REMOTE_ADDR'), 'unknown')) {
$ip = getenv('REMOTE_ADDR');
} elseif (isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], 'unknown')) {
$ip = $_SERVER['REMOTE_ADDR'];
}
return $ip;
}
/**
* 获得用户设备的mac地址
* 通过arp执行控制台程序,得到控制台的返回,然后处理控制台的信息,从ip查询得到mac地址
* @return unknown
*/
function getMac()
{
$ip = getClientIp();
$command = "arp";
$data = exec($command, $out);
$ipstr = "";
for ($i = 0; $i < count($out); $i++) {
if (strpos($out[$i], $ip) === 0) {
$ipstr = $out[$i];
}
}
if($ipstr != "") {
$strs = my_split($ipstr, " ");
return $strs[2];
} else {
return '找不到mac';
}
}
echo getMac();
exit;
?>

三、云服务器使用情况

1
在(某里、某度、某腾)云服务器中执行 arp -a 得到的映射记录并无最近的用户的访问ip,云服务器内部做了处理,所以无法获取到。