6

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

myk_raniu
  • 150
  • 1
  • 1
  • 7

7 Answers7

4

Use these commands:

arp -n <IP Address>|awk '/<ip address>/ {print $3}'

for example, if you want mac address of 192.168.10.1:

#arp -n 192.168.10.1|awk '/192.168.10.1/ {print $3}'
#00:0c:29:68:8f:a4
Majid
  • 13,853
  • 15
  • 77
  • 113
hamSh
  • 1,163
  • 1
  • 13
  • 27
4

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/

YOU
  • 120,166
  • 34
  • 186
  • 219
  • 2
    Or, `arp -n $IP`, to filter to just the desired IP address. – C. K. Young Jan 06 '10 at 03:46
  • Thanks, In Windows, `arp -a $IP` just a note. – YOU Jan 06 '10 at 03:49
  • 1
    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 Jan 06 '10 at 03:56
  • Yes, Correct, for that case, may be should try to do something first like pinging, and find out arp cache. – YOU Jan 06 '10 at 04:11
  • So you reckon manualy execute the ping and arp commands using os.popen? There isn't any python modules to do this? – myk_raniu Jan 06 '10 at 04:13
  • I dont see arp on standard module – YOU Jan 06 '10 at 04:14
  • 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 Jan 06 '10 at 06:38
2

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
  • 81
  • 2
0

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
  • 402
  • 3
  • 7
0

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
  • 327,991
  • 56
  • 259
  • 343
0

If you just want to query the OS' arp cache, reasonably recent linux kernels support this:

import os, sys

host = sys.argv[1]

# ping is optional (sends a WHO_HAS request)
os.popen('ping -c 1 %s' % host)

# grep with a space at the end of IP address to make sure you get a single line
fields = os.popen('grep "%s " /proc/net/arp' % host).read().split()
if len(fields) == 6 and fields[3] != "00:00:00:00:00:00":
    print fields[3]
else:
    print 'no response from', host
Community
  • 1
  • 1
duanev
  • 936
  • 13
  • 17
0

Hi this is a quick fix to python3

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 :
    output = output.decode('ascii')
    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]))