【问题标题】:MAC Address from IP across network跨网络 IP 的 MAC 地址
【发布时间】:2011-07-07 04:20:36
【问题描述】:

希望你一切都好。

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

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

干杯

克里斯

【问题讨论】:

  • 我很想被证明是错误的,但我怀疑你能否获得其他子网中的 MAC 地址。
  • 我运行你上面的代码,但出现错误...Traceback (most recent call last): File "Get_MacAddress_from_ip.py", line 26, in <module> mac = re.search(r"([a-fA-F0-9]{2}[:|\-]?){6}", s).groups()[0] AttributeError: 'NoneType' object has no attribute 'groups'

标签: python network-programming ip-address mac-address


【解决方案1】:

可以使用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")

【讨论】:

    【解决方案2】:

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

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

    this question 的答案可能有助于找到有助于这项工作的 Python 库代码。

    【讨论】:

    • 为您的回复和建议干杯。听起来这可能正是我一直在寻找的。​​span>
    【解决方案3】:

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

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

    【讨论】:

    • 感谢您的快速回复,我将不得不研究网络库存系统
    猜你喜欢
    • 1970-01-01
    • 2014-09-22
    • 2013-03-31
    • 2019-02-03
    • 1970-01-01
    • 1970-01-01
    • 2021-05-31
    • 2021-04-17
    • 1970-01-01
    相关资源
    最近更新 更多