Script to update nmap-mac-prefixes with latest entries from the IEEE OUI database

Nmap includes useful functionality of listing MAC Address Vendor name during scans, but my version listed many as "Unknown". The source of this information is a file called "nmap-mac-prefixes", as discussed in Chapter 14 of the NMAP book. The upstream source is IEEE. Since NMAP doesn't seem to provide a way to update the MAC prefix file outside of normal application updates (and my version of nmap was up to date), I wrote a quick and dirty script to handle this for me.

First, here's example output with stock nmap-mac-prefixes as shipped with my version of nmap:

$ sudo nmap -F 192.168.0.1-100 | grep MAC
MAC Address: XX:XX:XX:XX:XX:XX (SMC Networks)
MAC Address: XX:XX:XX:XX:XX:XX (Cisco-Linksys)
MAC Address: XX:XX:XX:XX:XX:XX (Unknown)
MAC Address: XX:XX:XX:XX:XX:XX (Unknown)
MAC Address: XX:XX:XX:XX:XX:XX (Dell)
MAC Address: XX:XX:XX:XX:XX:XX (Hewlett-packard Company)
MAC Address: XX:XX:XX:XX:XX:XX (Unknown)
MAC Address: XX:XX:XX:XX:XX:XX (Unknown)
MAC Address: XX:XX:XX:XX:XX:XX (Unknown)

Update nmap-mac-prefixes:

$ update-nmap-oui.sh 
2013-05-27 15:28:56 update-nmap-oui.sh: INFO: downloading oui.txt

--2013-05-27 15:28:56--  http://standards.ieee.org/regauth/oui/oui.txt
Resolving standards.ieee.org (standards.ieee.org)... 140.98.193.16
Connecting to standards.ieee.org (standards.ieee.org)|140.98.193.16|:80... connected.
HTTP request sent, awaiting response... 301 Moved Permanently
Location: http://standards.ieee.org/develop/regauth/oui/oui.txt [following]
--2013-05-27 15:28:57--  http://standards.ieee.org/develop/regauth/oui/oui.txt
Reusing existing connection to standards.ieee.org:80.
HTTP request sent, awaiting response... 200 OK
Length: 2998066 (2.9M) [text/plain]
Saving to: `oui.txt'

100%[===============================================================>] 2,998,066   1.18M/s   in 2.4s    

2013-05-27 15:29:23 (111 KB/s) - `oui.txt' saved [2998066/2998066]

2013-05-27 15:29:23 update-nmap-oui.sh: INFO: extracting values from oui.txt...
2013-05-27 15:29:23 update-nmap-oui.sh: INFO: replacing empty Org with 'Private'...
2013-05-27 15:29:23 update-nmap-oui.sh: INFO: generating files for comparison...
2013-05-27 15:29:23 update-nmap-oui.sh: INFO: appending missing OUI to '/tmp/nmap-mac-prefixes'...

 Processing complete.

 Updated file saved as '/tmp/nmap-mac-prefixes'. It contains 4843 OUI
 entries missing from the original (/usr/share/nmap/nmap-mac-prefixes).

 You should manually review the updated version, if satisfied
 replace the original (/usr/share/nmap/nmap-mac-prefixes).

 Here are line counts from the original and updated versions:

 13074 /usr/share/nmap/nmap-mac-prefixes
 17919 /tmp/nmap-mac-prefixes

The script doesn't make any changes to /usr/share/nmap/nmap-mac-prefixes, instead placing the updated version in /tmp so user can review changes before replacing. To replace:

$ sudo mv /tmp/nmap-mac-prefixes /usr/share/nmap/nmap-mac-prefixes

If the script finds no difference between the latest OUI list and the one that nmap has, the output is:

2013-05-27 15:30:15 update-nmap-oui.sh: INFO: downloading oui.txt

--2013-05-27 15:30:15--  http://standards.ieee.org/regauth/oui/oui.txt
Resolving standards.ieee.org (standards.ieee.org)... 140.98.193.16
Connecting to standards.ieee.org (standards.ieee.org)|140.98.193.16|:80... connected.
HTTP request sent, awaiting response... 301 Moved Permanently
Location: http://standards.ieee.org/develop/regauth/oui/oui.txt [following]
--2013-05-27 15:30:16--  http://standards.ieee.org/develop/regauth/oui/oui.txt
Reusing existing connection to standards.ieee.org:80.
HTTP request sent, awaiting response... 200 OK
Length: 3005728 (2.9M) [text/plain]
Saving to: `oui.txt'

100%[===============================================================>] 3,005,728   1.25M/s   in 2.3s    

2013-05-27 15:30:18 (1.25 MB/s) - `oui.txt' saved [3005728/3005728]

2013-05-27 15:30:18 update-nmap-oui.sh: INFO: extracting values from oui.txt...
2013-05-27 15:30:18 update-nmap-oui.sh: INFO: replacing empty Org with 'Private'...
2013-05-27 15:30:18 update-nmap-oui.sh: INFO: generating files for comparison...

Your local nmap-mac-prefixes is up to date, nothing to do.

Nmap output with updated MAC prefix file:

$ sudo nmap -F 192.168.0.1-100 | grep MAC
MAC Address: XX:XX:XX:XX:XX:XX (SMC Networks)
MAC Address: XX:XX:XX:XX:XX:XX (Cisco-Linksys)
MAC Address: XX:XX:XX:XX:XX:XX (NETGEAR)
MAC Address: XX:XX:XX:XX:XX:XX (Roku, Inc)
MAC Address: XX:XX:XX:XX:XX:XX (Dell)
MAC Address: XX:XX:XX:XX:XX:XX (Hewlett-packard Company)
MAC Address: XX:XX:XX:XX:XX:XX (Dell Inc.)
MAC Address: XX:XX:XX:XX:XX:XX (Motorola Mobility, LLC.)
MAC Address: XX:XX:XX:XX:XX:XX (Dell Inc.)

Nice, no more "Unknown".

Here's the script:

#!/bin/bash

# Downloads latest Organizationally Unique Identifier (OUI) list from
# ieee.org in format suitable for use in nmap-mac-prefixes file.

err_exit()
{
 echo -e 1>&2
 exit 1
}

src="/usr/share/nmap/nmap-mac-prefixes"

UpdateNotice()
{
 cat << EOF

 Processing complete.

 Updated file saved as '$(pwd)/nmap-mac-prefixes'. It contains $missing OUI
 entries missing from the original ($src).

 You should manually review the updated version, if satisfied,
 replace the original ($src).

 Here are line counts from the original and updated versions:

EOF
}

LineCounts()
{
 wc -l $src $(pwd)/nmap-mac-prefixes | sed '/total$/d'
}

if ! [ -f $src ]; then
  echo "ERROR: required source file '$src' not found, I quit."
fi

if ! [ -x "$(type -P combine)" ]; then
  echo "Error: looks like 'combine' is not available"
  echo "Get it with e.g. 'apt-get install moreutils'"
  exit 1
fi

cd /tmp || err_exit 

for f in nmap-mac-prefixes oui.txt; do
  if [ -f $f ]; then
    rm $f || err_exit
  fi
done

cp $src . || err_exit

# get latest OUI file
echo "$(date +%F\ %T) $(basename $0): INFO: downloading oui.txt"
echo
wget http://standards.ieee.org/regauth/oui/oui.txt

if ! [ -f "oui.txt" ]; then
  echo "$(date +%F\ %T) $(basename $0): ERROR: oui.txt is missing"
  exit 1
fi

# save values from oui.txt in format used by nmap-mac-prefixes
echo "$(date +%F\ %T) $(basename $0): INFO: extracting values from oui.txt..."
grep "(base 16)" oui.txt | sed -r 's/( |\t)+/ /g;s/\(base 16\) //;s/^ //;' > nmap-oui

# if Org value is empty, set it to "Private"
echo "$(date +%F\ %T) $(basename $0): INFO: replacing empty Org with 'Private'..."
awk '{if ($2=="") $2="Private"; print}' nmap-oui > nmap-oui.tmp
mv nmap-oui.tmp nmap-oui

# extract just the OUI for comparison
echo "$(date +%F\ %T) $(basename $0): INFO: generating files for comparison..."
awk '{print$1}' nmap-oui > nmap-oui.id
awk '$1!="#" {print$1}' nmap-mac-prefixes > nmap-mac-prefixes.id

# generate a list of OUI present in oui.txt but missing in nmap-mac-prefixes
combine nmap-oui.id not nmap-mac-prefixes.id > missing.id

missing=$(cat missing.id | wc -l)

if [ "$missing" -eq 0 ]; then
  echo
  echo "Your local nmap-mac-prefixes is up to date, nothing to do."
else
  echo -e "\n# Appended from http://standards.ieee.org/regauth/oui/oui.txt" >> nmap-mac-prefixes
  sed -i '/^$/d' nmap-mac-prefixes
  # Append missing OUI to nmap-mac-prefixes
  echo "$(date +%F\ %T) $(basename $0): INFO: appending missing OUI to '$(pwd)/nmap-mac-prefixes'..."
  while read id; do
    grep $id nmap-oui >> nmap-mac-prefixes
  done < missing.id
  UpdateNotice
  LineCounts
fi

# cleanup
for f in oui.txt nmap-oui nmap-oui.id nmap-mac-prefixes.id missing.id; do
  if [ -f $f ]; then
    rm $f
  fi
done

3 Comments

  • 1. Mapes replies at 3rd June 2014, 11:51 am :

    Heya thanks works on OSX mavericks after macports moreutils install

  • 2. maymay replies at 29th August 2015, 5:40 pm :

    FYI, the “-r” option (for extended regular expression interpretation) to sed doesn’t exist on Mac OS X Yosemite, so you’ll need to change that to its equivalent “-E” option if using Apple’s built-in sed utility.

    If this script is on GitHub I’d be happy to supply a compatible patch (using -r and falling back to -E if sed issues an error).

  • 3. Alain Kelder replies at 4th June 2016, 9:36 am :

    You may prefer David Tonhofer’s version at https://github.com/dtonhofer/ieee_oui_downloader

Leave a comment

NOTE: Enclose quotes in <blockquote></blockquote>. Enclose code in <pre lang="LANG"></pre> (where LANG is one of these).