我希望你一切都好。
我想知道你是否可以帮助我或为我指明正确的方向。我目前正在开发一个以网络管理为中心的项目。由于严格的时间限制,我尽可能使用开源代码。我遇到的问题是该项目的一部分要求我能够捕获连接到网络的所有设备的 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)
我查找了一些信息,但我发现的内容似乎有点模糊。如果您知道任何可能对我有帮助的想法或研究途径,我将不胜感激,
干杯
克里斯
I hope you're all well.
I'm wondering if you could help me or point me in the right direction. I'm currently working on a project that centers around network management. Due to severe time constraints where possible I'm using opensource code. The issue I'm having is that part of the project requires me to be able to capture the MAC addresses of all of the devices that are connected to the network.
My knowledge of network orientated programming is limited as I have been working in other areas of software engineering for the past 4 years. The approach I have taken is to use nmap as a basis to get the ip address and other information I need. The MAC address is not included in the nmap out put and from what I have read it seems to be a bit flakey. (i could be wrong).
Therefore I have tried to do this in a two stage approach, firstly I get the data including ip address from nmap which works fine. My next step and the bit I'm having difficulty with is I ping the ip address (from within my python program) which works. But how do I get the MAC Address from the IP address? I initially thought ping the ip and grab the MAC from the ARP but I think that will only work if the IP address is on the same subnet. to compound the problem on deployment there could be up to 5000 computers on the network that needs to be logged. To show you my python ping approach this is the code:
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)
I have looked for some information but what I have found seems a bit vague. If you know of any ideas or avenues of research that may help me I would be greatful
Cheers
Chris
发布评论
评论(3)
您无法直接获取子网之外的计算机的 MAC 地址。
网络管理应用程序的常见策略是使用 SNMP。路由器有它们直接连接的子网的 arp 表(因为它们需要这个表来完成其工作),并且可以从路由器获取此信息。
这个问题的答案可能有助于查找 python 库代码为这一努力提供帮助。
You can't directly get the MAC address of a machine outside your subnet.
A common strategy for network management applications is to query machines that do have this information, such as the routers and switches connecting the machines, using SNMP. Routers have arp tables for the subnets to which they are directly connected (as they need this to do their job), and this information can be acquired from the router.
The answers to this question might help with finding python library code to help in this endeavor.
如果您没有连接到同一子网,则无法获得主机的原始 MAC 地址 - 您只能获得最后一个路由器的 MAC 地址。
获取所有 MAC 地址的唯一方法是设置一个服务器来捕获每个子网中的它们,但这在我看来有点疯狂。另请注意,现在 MAC 地址很容易被欺骗,而且根本不可靠。
总的来说,我认为你应该使用不同的方法;例如,有很多网络库存系统,您可以只使用其中之一,并与其交互。
You cannot get the original MAC address of the host if you are not connected to the same subnet - you would just get the MAC address of the last router.
The only way to get all MAC addresses would be to setup a server to catch them in each subnet, but this seems to me a bit crazy idea. Note also that nowadays it is very easy to spoof the MAC address, and it is not reliable at all.
Over all, I think you should use a different approach; for instance, there are plenty of network inventory systems, you could just use one of them, and interface with it.
您可以使用 python scapy 模块来获取 mac 地址
You can use python scapy module to get mac address