Bash Snippet: Friendly MAC Address Names

03 Apr 2015

This article is about adding manufacturer information when displaying MAC addresses in bash script output to create friendlier data for the user. A manufacturer name can suggest more about a device than just the MAC address alone. For example, if you saw a MAC address with an OUI of B8-27-EB it probably wouldn’t mean much to you, but if you saw the name “Raspberry Pi Foundation” you’d have a pretty good clue that the device in question was a Raspberry Pi.

As you may know, MAC address ranges are registered to manufacturers by the IEEE Standards Association. The IEEE-SA provides a web-based look-up form where you can see which OUI is assigned to a vendor, or vice versa. It’s possible for your script to scrap the IEEE-SA’s web look-up resource (in fact I’ve done that in a script to detect and report new Wi-Fi clients on my home network). This is a slow (and not very nice) process when dealing with a larger number of MAC addresses, and so an offline method would be preferable.

The IEEE-SA has a set of data files you could download for this purpose:

http://standards.ieee.org/develop/regauth/oui/oui.txt
http://standards.ieee.org/develop/regauth/iab/iab.txt
http://standards.ieee.org/develop/regauth/oui36/oui36.txt

That method requires occasionally freshening local copies of those files to make sure OUI assignment changes are reflected in the script output.

An alternative option, and the one I’m going to be using is to reference the data in the “manuf” file that Wireshark uses for this same purpose. Wireshark displays ethernet addresses by replacing the vendor/OUI portion of the MAC address with a shortened vendor name, but leaves the unique device portion of the address untouched. Here is an example screen shot taken from Wireshark:

wireshark_macs

You can see that the MAC address 1c:6f:65:95:2b:ad belongs to a device made by Giga-byte and it is talking to 00:07:50:52:86:d1, a device made by Cisco.

If you download Wireshark’s “manuf” file through your package manager, you should receive updates to this list as part of your normal update routines. It is not necessary to download a full copy of Wireshark. Under Ubuntu and probably other Debian-based systems the file is provided by the package libwireshark-data.

apt-get install libwireshark-data

On Ubuntu the manuf file resides in /usr/share/wireshark, but you might need to update the script for your system.

get_line() {
        while read line
        do
                if [ "${line//$1}" != "$line" ]; then
                        echo "$line"
                        break
                fi
        done
}

format_mac() {
        MAC="$1"
        if [ -f "/usr/share/wireshark/manuf" ]; then
                #prefix="$(grep -m1 "${MAC:0:8}" "/usr/share/wireshark/manuf")"
                prefix="$(get_line "${MAC:0:8}" <"/usr/share/wireshark/manuf")"
                prefix="${prefix#*$'\t'}"
                prefix="${prefix%%'#'*}"
                prefix="${prefix%% *}"
                if [ -n "$prefix" ]; then
                        MAC="${prefix}_${MAC: -8}"
                fi
        fi
        echo "$MAC"
}
$ format_mac "00:07:50:52:86:d1"
Cisco_52:86:d1

The above example uses shell built-ins, but if you do not care about the purity of your bash script you could use grep (as shown in the comment) and omit the get_line function from your script for faster results. Notice that this script doesn’t currently parse OUI ranges that are shared across manufacturer’s despite that information being available in the manuf file.

Original post by Chris - check out the source