Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Obtain MAC Address from Devices using Python

Tags:

I'm looking for a way (with python) to obtain the layer II address from a device on my local network. Layer III addresses are known.

The goal is to build a script that will poll a databases of IP addresses on regular intervals ensuring that the mac addresses have not changed and if they have, email alerts to myself.

like image 568
nfarrar Avatar asked Nov 17 '09 18:11

nfarrar


People also ask

How do I find a MAC address on all devices?

From Home, tap Menu > Settings > About Phone/Device. Tap either Status or Hardware Information. Scroll down to WiFi MAC address.

Is it possible to capture the MAC address for a device?

There isn't a way to find a stolen computer from the MAC address or to find the identity behind one of these addresses. Much like IP addresses, MAC addresses are assigned to network devices and are easy to determine with tools like Command Prompt.


2 Answers

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 python from 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!

like image 40
jathanism Avatar answered Nov 09 '22 03:11

jathanism


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.15 PING 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 ^C  13:40 jsmith@undertow% arp -n 97.107.138.15 Address                  HWtype  HWaddress           Flags Mask            Iface 97.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" 
like image 76
Jed Smith Avatar answered Nov 09 '22 01:11

Jed Smith