来自IP跨网络的MAC地址

时间:2011-03-02 10:40:23

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

我希望你们一切顺利。

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

我已经找了一些信息,但我发现的内容似乎有些模糊。如果您知道任何可能对我有帮助的想法或途径,我会很高兴

干杯

克里斯

3 个答案:

答案 0 :(得分:3)

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

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

this question的答案可能有助于找到python库代码来帮助完成这项工作。

答案 1 :(得分:2)

如果未连接到同一子网,则无法获取主机的原始MAC地址 - 您只需获取最后一个路由器的MAC地址。

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

答案 2 :(得分: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")