Automated MAC to IP Address Mapping

ip-macI just hacked a little Linux specific python code that maps host names to MAC addresses and IP addresses. This is useful if you have machines on your local area network (e.g. wireless LAN) that are only identifiable by their MACs. For example, this would be the case if they’re getting their IP addresses via DHCP, which can allocate different IPs if the network is restarted.

I’m going to walk through the code so you can see how it works. First, the file starts with a she-bang that identifies the location of the python interpreter, followed by import statements for each of the libraries used:


import argparse
import json
import os
import re
import subprocess
import sys

Next I parse the command line arguments. You can specify a host name with -H and, optionally, a MAC address with -m. The MAC must be 12 hexadecimal digits, with each pair separated by colons. For example, 00:90:a9:ec:69:af. You can typically find it on a label on the case if your connecting to a stand alone device. On a Linux machine, you can find the MAC using the ifconfig command. Here’s the code:

argumentParser = argparse.ArgumentParser(description="Show the differences between a set of files and a backup copy")
argumentParser.add_argument("-H", "--hostname", help="name of the host; if no MAC specified, look up in ~/.hosttomac")
argumentParser.add_argument("-m", "--mac", help="ethernet MAC address; if specified write to ~/.hosttomac")
arguments = argumentParser.parse_args()

Next, I create an empty map of host names to MAC addresses, then look for a JSON file containing an existing map and, if found, read it in:

hostToMac = {}

    with open(os.getenv("HOME") + "/.hosttomac") as hostToMacFP:
        hostToMac = json.load(hostToMacFP)
except IOError as error:
    if os.path.exists(os.path.realpath(os.getenv("HOME") + "/.hosttomac")):
        raise error

Next, if a host name was specified and a MAC was too, if the host is already in the map, make sure the MACs match. If no MAC was specified, make sure there’s one in the map.

if arguments.hostname:
    if arguments.mac:
        if (hostToMac.get(arguments.hostname) and arguments.mac 
         != hostToMac[arguments.hostname]):
            sys.exit("Host " + arguments.hostname"
                        + " is already in ~/.hosttomac with MAC "
                        + hostToMac[arguments.hostname] + " but you specified "
                        + arguments.mac)

    elif hostToMac.get(arguments.hostname):
        arguments.mac = hostToMac[arguments.hostname]

     sys.exit("Host " + arguments.hostname 
                 + " specified without a MAC and not found in ~/.hosttomac")

Next, I grab the output of arp -n, which gives the mappings from IP to MAC address of all the devices the Linux machine knows about. I then go through it looking for lines that map an IP to a MAC, and see if there’s one with the MAC that matches the host, and if there is, record its IP.

output = subprocess.check_output(["arp", "-n"])
 linePat = re.compile(r'(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\s+ether\s+'
                                       + r'([\da-f][\da-f]:[\da-f][\da-f]:[\da-f][\da-f]:[\da-f][\da-f]:[\da-f][\da-f]:[\da-f][\da-f])')
 hostIp = None

for line in output.split('\n'):
    match = linePat.match(line)

    if match and == arguments.mac:
        hostIp =

if not hostIp:
     sys.exit("MAC address " + arguments.mac 
                 + " not found in arp -n output; try running: sudo arp-scan -l")

Finally, if the host wasn’t already in the map, add it along with the MAC and save the map file. This way, once the MAC has been confirmed as valid, it’s saved and you never have to specify it again.

if not hostToMac.get(arguments.hostname):
     hostToMac[arguments.hostname] = arguments.mac

    with open(os.getenv("HOME") + "/.hosttomac", "w") as hostToMacFP:
        json.dump(hostToMac, hostToMacFP)

You can then do what you want with your IP:

    print hostIp

About jimbelton

I'm a software developer, and a writer of both fiction and non-fiction, and I blog about movies, books, and philosophy. My interest in religious philosophy and the search for the truth inspires much of my writing.
This entry was posted in Uncategorized. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s