问题
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
回答1:
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.
回答2:
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.
回答3:
You can use python scapy module to get mac address
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")
来源:https://stackoverflow.com/questions/5166280/mac-address-from-ip-across-network