如何获取 LAN 上远程主机的 MAC 地址?我正在使用 Python 和 Linux。
7 回答
您可以尝试运行命令arp -a
这是一些关于 Mac 地址抓取的链接(未测试)
在 Linux/Unix 中,arping、
http://www.ibm.com/developerworks/aix/library/au-pythocli/
在 Windows 中,通过 ctypes 使用 IP Helper API
使用这些命令:
arp -n <IP Address>|awk '/<ip address>/ {print $3}'
例如,如果你想要 192.168.10.1 的 mac 地址:
#arp -n 192.168.10.1|awk '/192.168.10.1/ {print $3}'
#00:0c:29:68:8f:a4
arp 条目可能永远不会正确,我尝试多次 ping 主机但 arp -a 不会给我它的 MAC/以太网地址。(不用担心处于活动状态的 Windows 代码 BTW)
Linux(和 *nix)上的可靠方法是使用 arping 或 scappy(参见http://en.wikipedia.org/wiki/Arping)然后解析输出。这是我使用的代码。您必须是 root 或使用 sudo 才能运行 arping。
cmd = '/sbin/arping -c 1 ' + remotehost
p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
output, errors = p.communicate()
if output is not None :
mac_addr = re.findall(r'(\[.*\])', output)[0].replace('[', '').replace(']', '')
如果你只是想查询操作系统的 arp 缓存,最近的 linux 内核支持这个:
import os, sys
host = sys.argv[1]
# ping is optional (sends a WHO_HAS request)
os.popen('ping -c 1 %s' % host)
# grep with a space at the end of IP address to make sure you get a single line
fields = os.popen('grep "%s " /proc/net/arp' % host).read().split()
if len(fields) == 6 and fields[3] != "00:00:00:00:00:00":
print fields[3]
else:
print 'no response from', host
许多年前,我的任务是从企业园区的所有机器中收集各种机器信息。一个需要的信息是 MAC 地址,它很难在跨越多个子网的网络上获取。当时,我使用了 Windows 内置的“nbtstat”命令。
今天有一个名为“nbtscan”的 Unix 实用程序可以提供类似的信息。如果您不想使用外部工具,也许有 Python 的 NetBIOS 库可以用来为您收集信息?
你可以在 win32 或 linux 上使用它
import subprocess
import sys
remotehost="192.168.0.122"
cmd="arp -a"
p=subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
output, errors = p.communicate()
if output is not None :
if sys.platform in ['linux','linux2']:
for i in output.split("\n"):
if remotehost in i:
for j in i.split():
if ":" in j:
print "%s--> %s" % (remotehost,j)
elif sys.platform in ['win32']:
item = output.split("\n")[-2]
if remotehost in item:
print "%s--> %s" %(remotehost, item.split()[1])
注意:arp 条目会在一段时间后消失,您需要“淹没您的网络”,例如 ping,以便 arp -a 显示您的远程主机。
嗨,这是对 python3 的快速修复
import subprocess
import sys
remotehost="192.168.0.122"
cmd="arp -a"
p=subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
output, errors = p.communicate()
if output is not None :
output = output.decode('ascii')
if sys.platform in ['linux','linux2']:
for i in output.split("\n"):
if remotehost in i:
for j in i.split():
if ":" in j:
print( "%s--> %s" % (remotehost,j))
elif sys.platform in ['win32']:
item = output.split("\n")[-2]
if remotehost in item:
print("%s--> %s" %(remotehost, item.split()[1]))