Obtain MAC Address from Devices using Python
To answer the question with Python depends on your platform. I don't have Windows handy, so the following solution works on the Linux box I wrote it on. A small change to the regular expression will make it work in OS X.
First, you must ping the target. That will place the target -- as long as it's within your netmask, which it sounds like in this situation it will be -- in your system's ARP cache. Observe:
13:40 jsmith@undertow% ping 97.107.138.15PING 97.107.138.15 (97.107.138.15) 56(84) bytes of data.64 bytes from 97.107.138.15: icmp_seq=1 ttl=64 time=1.25 ms^C13:40 jsmith@undertow% arp -n 97.107.138.15Address HWtype HWaddress Flags Mask Iface97.107.138.15 ether fe:fd:61:6b:8a:0f C eth0
Knowing that, you do a little subprocess magic -- otherwise you're writing ARP cache checking code yourself, and you don't want to do that:
>>> from subprocess import Popen, PIPE>>> import re>>> IP = "1.2.3.4">>> # do_ping(IP)>>> # The time between ping and arp check must be small, as ARP may not cache long>>> pid = Popen(["arp", "-n", IP], stdout=PIPE)>>> s = pid.communicate()[0]>>> mac = re.search(r"(([a-f\d]{1,2}\:){5}[a-f\d]{1,2})", s).groups()[0]>>> mac"fe:fd:61:6b:8a:0f"
There was a similar question answered not too long ago on this site. As mentioned in the answer chosen by the asker of that question, Python doesn't have a built-in way to do it. You must either call a system command such as arp
to get ARP information, or generate your own packets using Scapy.
Edit: An example using Scapy from their website:
Here is another tool that will constantly monitor all interfaces on a machine and print all ARP request it sees, even on 802.11 frames from a Wi-Fi card in monitor mode. Note the store=0 parameter to sniff() to avoid storing all packets in memory for nothing.
#! /usr/bin/env pythonfrom scapy import *def arp_monitor_callback(pkt): if ARP in pkt and pkt[ARP].op in (1,2): #who-has or is-at return pkt.sprintf("%ARP.hwsrc% %ARP.psrc%")sniff(prn=arp_monitor_callback, filter="arp", store=0)
You could also do something similar to the verified answer. See https://scapy.readthedocs.io/en/latest/routing.html
>>> mac = getmacbyip("10.0.0.1")>>> mac'f3:ae:5e:76:31:9b'
This is fully cross platform.
Not exactly what you're looking for, but definitely on the right track. Enjoy!
A simple solution using scapy, to scan the 192.168.0.0/24 subnet is as follows:
from scapy.all import *ans,unans = arping("192.168.0.0/24", verbose=0)for s,r in ans: print("{} {}".format(r[Ether].src,s[ARP].pdst))