Python MAC address manipulation

Every vendor has their favourite format for MAC addresses and it is common to need to create strings to pass as CLI commands. This post shows to check the string is a valid address and how to convert between formats.

If you run HPE/Aruba switches the discussion on custom formats will be useful.

The python library netaddr manipulates IP and MAC addresses. The code below uses it together with some validation to show how you can get a different format of MAC address from an input. The input here is via a prompt to demonstrate the code but this could easily be a variable. You can easily imagine, given a MAC address in a variable, that the CLI command needed for both a cisco and HP switch could be created.

There is a validation in the netaddr library through the valid_mac function which does validate to an extent but with results that I didn’t like. For example it would validate as true a string of 11 characters (e.g. 12345678901):

print (valid_mac(input("mac?")))

user@net-ansible:$ python macfind2.py
mac?12345678901
True

The netaddr library doesn’t validate for regular functions such as when you change format and so you could in theory enter a MAC address “0123” at it be interpreted as “00-00-00-00-00-7B”

The CheckMac function in my code checks that the number of characters is 12 and that there are no non-hex characters. This might help in rare cases to ensure the input is truly correct rather than mathematically correct.

The main function (printMacs) validates the input string and then prints each of the formats, including the two custom ones. It then prints the OUI details if an entry in the database is found. This is a crude way to work out the manufacturer of a NIC card and might be a useful clue if providing info to a user.

from netaddr import *

class mac_comware(mac_cisco): pass
mac_comware.word_sep = '-'
mac_comware.word_size = 16

class mac_procurve(mac_pgsql): pass
mac_procurve.word_sep = '-'
mac_procurve.word_size = 24

hexChars = ["0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"]

def CheckMac(mac1):  #returns false if valid
    badMac=False
    mac2=mac1.translate(str.maketrans('', '',  '-:_'))  #strips normal chars
    if len(mac2) < 12:
        badMac=True
    for i in mac2.lower():
        if i not in hexChars :
            badMac=True
    return badMac

def printMacs(mac1):
    if CheckMac(mac1) == True:
        print(mac1 + " is NOT a valid MAC")
    else:
        print ("original: " + str(mac1))
        print ("mac_cisco: " + str(EUI(mac1, dialect = mac_cisco)))
        print ("mac_unix_expanded: " + str(EUI(mac1, dialect = mac_unix_expanded)))
        print ("mac_bare: " + str(EUI(mac1, dialect = mac_bare)))
        print ("mac_pgsql: " + str(EUI(mac1, dialect = mac_pgsql)))
        print ("mac_unix: " + str(EUI(mac1, dialect = mac_unix)))
        print ("mac_eui: " + str(EUI(mac1)))
        print ("mac_comware: " + str(EUI(mac1, dialect = mac_comware)))
        print ("mac_procurve: " + str(EUI(mac1, dialect = mac_procurve)))
        try:   #needed because easy to get an exception when a MAC isn't registered in OUI db
            print (EUI(mac1).oui.registration().org)
        except Exception:
            pass
            print ("can't find MAC in database")


printMacs(input("mac?"))

You can create your own dialects as per the two examples in my code. These use two other dialects and alter (in this case changing the character between blocks of the MAC address). A little documentation is found here.

A couple of example outputs below:


user@net-ansible:$ python macfind2.py
mac?005000112233
original: 005000112233
mac_cisco: 0050.0011.2233
mac_unix_expanded: 00:50:00:11:22:33
mac_bare: 005000112233
mac_pgsql: 005000:112233
mac_unix: 0:50:0:11:22:33
mac_eui: 00-50-00-11-22-33
mac_comware: 0050-0011-2233
mac_procurve: 005000-112233
NEXO COMMUNICATIONS, INC.


mac?123456789123
original: 123456789123
mac_cisco: 1234.5678.9123
mac_unix_expanded: 12:34:56:78:91:23
mac_bare: 123456789123
mac_pgsql: 123456:789123
mac_unix: 12:34:56:78:91:23
mac_eui: 12-34-56-78-91-23
mac_comware: 1234-5678-9123
mac_procurve: 123456-789123
can't find MAC in database

mac?12345678901
12345678901 is NOT a valid MAC

mac?000000000000t
000000000000t is NOT a valid MAC

2 thoughts on “Python MAC address manipulation

Add yours

  1. Many thanks for your reference, it helped to change Cisco Mac to Aruba Mac when quarantine ip address on Aruba switch. 🙂 Lifesaver !

    Like

Leave a Reply

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

WordPress.com Logo

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

Google photo

You are commenting using your Google 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 )

Connecting to %s

Create a website or blog at WordPress.com

Up ↑

Create your website with WordPress.com
Get started