views:

1034

answers:

4

How do I get the MAC address of a remote host on my LAN? I'm using Python and Linux.

+3  A: 

You can try running command arp -a

Here is few links about Mac Address grabbing (not tested)

In Linux/Unix, arping,

http://www.ibm.com/developerworks/aix/library/au-pythocli/

In Windows, using IP Helper API through ctypes

http://code.activestate.com/recipes/347812/

S.Mark
Or, `arp -n $IP`, to filter to just the desired IP address.
Chris Jester-Young
Thanks, In Windows, `arp -a $IP` just a note.
S.Mark
Keep in mind that this won't send a WHO_HAS message on the network - the address has to have been seen by your machine already, which it might not be if you have a large network (also old entries can get deleted if the cache gets too large).
Nick Bastin
Yes, Correct, for that case, may be should try to do something first like pinging, and find out arp cache.
S.Mark
So you reckon manualy execute the ping and arp commands using os.popen?There isn't any python modules to do this?
myk_raniu
I dont see arp on standard module
S.Mark
You can, of course, implement ARP yourself (it's RFC 826), build an arping style packet, open a raw socket, and send it yourself. But why do all the work to implement that yourself when you can just use the system component to do it?
Andrew McGregor
A: 

Many years ago, I was tasked with gathering various machine info from all machines on a corporate campus. One desired piece of info was the MAC address, which is difficult to get on a network that spanned multiple subnets. At the time, I used the Windows built-in "nbtstat" command.

Today there is a Unix utility called "nbtscan" that provides similar info. If you do not wish to use an external tool, maybe there are NetBIOS libraries for python that could be used to gather the info for you?

Geoff Fritz
A: 

you can use this on either win32 or linux

import subprocess
import sys
remotehost="192.168.0.122"
cmd="arp -a"
p=subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
output, errors = p.communicate()
if output is not None :
    if sys.platform in ['linux','linux2']:
        for i in output.split("\n"):
            if remotehost in i:
                for j in i.split():
                    if ":" in j:
                        print "%s--> %s" % (remotehost,j)
    elif sys.platform in ['win32']:
        item =  output.split("\n")[-2]
        if remotehost in item:
            print "%s-->  %s" %(remotehost, item.split()[1])

NB:arp entries goes off after a while, you need to "flood your network" eg ping, so that arp -a shows your remotehost.

ghostdog74
A: 

arp entries might never be right, I tried to ping a host several times but arp -a would not give me it's mac/ethernet address. (No worry with the windows code from active state BTW)

The reliable way on Linux (and *nix) is to use arping or scappy (see http://en.wikipedia.org/wiki/Arping) and then parse the output. Here's the code I used. You have to be root or use sudo to run arping.

cmd = '/sbin/arping -c 1 ' + remotehost       

p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)                               
output, errors = p.communicate()                                                            
if output is not None :                                                                     
    mac_addr = re.findall(r'(\[.*\])', output)[0].replace('[', '').replace(']', '')      
bsergean