MAC Address from IP across network
Question: 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


Answer: 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](http://en.wikipedia.org/wiki/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](http://stackoverflow.com/questions/156853/what-
is-the-best-snmp-implementation-for-python) might help with finding python
library code to help in this endeavor.

