1

我希望你们一切都好。

我想知道您是否可以帮助我或指出我正确的方向。我目前正在从事一个以网络管理为中心的项目。由于可能的时间限制,我正在使用开源代码。我遇到的问题是项目的一部分要求我能够捕获连接到网络的所有设备的 MAC 地址。

由于过去 4 年我一直在软件工程的其他领域工作,因此我对面向网络的编程知识有限。我采取的方法是使用nmap作为基础来获取我需要的ip地址和其他信息。MAC 地址不包含在 nmap 输出中,从我读过的内容来看,它似乎有点不稳定。(我可能是错的)。

因此,我尝试通过两阶段的方法来做到这一点,首先我从 nmap 获取包括 ip 地址的数据,它工作正常。我的下一步和我遇到的困难是我 ping 有效的 ip 地址(从我的 python 程序中)。但是如何从 IP 地址中获取 MAC 地址呢?我最初认为 ping ip 并从 ARP 中获取 MAC,但我认为只有当 IP 地址在同一子网上时才会起作用。为了使部署问题更加复杂,网络上可能需要记录多达 5000 台计算机。为了向您展示我的 python ping 方法,这是代码:

import pdb, os
import subprocess
import re
from subprocess import Popen, PIPE

# This will only work within the netmask of the machine the program is running on cross router MACs will be lost
ip ="192.168.0.4"

#PING to place target into system's ARP cache 
process = subprocess.Popen(["ping", "-c","4", ip], stdout=subprocess.PIPE)
process.wait()

result = process.stdout.read()
print(result)

#MAC address from IP
pid = Popen(["arp", "-n", ip], stdout=PIPE)
s = pid.communicate()[0]

# [a-fA-F0-9] = find any character A-F, upper and lower case, as well as any number
# [a-fA-F0-9]{2} = find that twice in a row
# [a-fA-F0-9]{2}[:|\-] = followed by either a ?:? or a ?-? character (the backslash escapes the hyphen, since the  # hyphen itself is a valid metacharacter for that type of expression; this tells the regex to look for the hyphen character, and ignore its role as an operator in this piece of the expression)
# [a-fA-F0-9]{2}[:|\-]? = make that final ?:? or ?-? character optional; since the last pair of characters won't be followed by anything, and we want them to be included, too; that's a chunk of 2 or 3 characters, so far
# ([a-fA-F0-9]{2}[:|\-]?){6} = find this type of chunk 6 times in a row

mac = re.search(r"([a-fA-F0-9]{2}[:|\-]?){6}", s).groups()[0] #LINUX VERSION ARP
mac = re.search(r"(([a-f\d]{1,2}\:){5}[a-f\d]{1,2})", s).groups()[0] #MAC VERSION ARP
print(mac)

我已经寻找了一些信息,但我发现的似乎有点模糊。如果您知道任何可能对我有帮助的想法或研究途径,我将不胜感激

干杯

克里斯

4

3 回答 3

3

您无法直接获取子网外机器的 MAC 地址。

网络管理应用程序的一个常见策略是使用 SNMP 查询具有此信息的机器例如连接机器的路由器和交换机。路由器有它们直接连接的子网的 arp 表(因为它们需要这个来完成他们的工作),并且可以从路由器获取此信息。

这个问题的答案可能有助于找到有助于这项工作的 python 库代码。

于 2011-03-02T12:04:59.507 回答
2

如果您没有连接到同一个子网,您将无法获得主机的原始 MAC 地址 - 您只会获得最后一个路由器的 MAC 地址。

获取所有 MAC 地址的唯一方法是设置一个服务器以在每个子网中捕获它们,但这在我看来有点疯狂。还要注意,现在很容易伪造 MAC 地址,而且根本不可靠。
总的来说,我认为您应该使用不同的方法;例如,有很多网络库存系统,您可以只使用其中一个,并与之交互。

于 2011-03-02T10:59:03.210 回答
0

您可以使用 python scapy模块获取 mac 地址

from scapy.all import *
def get_mac(ip_address):
    responses,unanswered = srp(Ether(dst="ff:ff:ff:ff:ff:ff")/ARP(pdst=ip_address),timeout=2,retry=10)
# return the MAC address from a response
    for s,r in responses:
        return r[Ether].src
    return None

get_mac("192.168.31.14")
于 2019-01-23T09:59:07.843 回答