#!/usr/bin/perl -w use POSIX; # A simple perl script that takes a MAC address database as distribted # by the IEEE at http://standards.ieee.org/regauth/oui/oui.txt and # creates an nmap-mac-prefixes file, which is just a bunch of lines # like this (but without the initial "# ": # # 000072 Miniware Technology # 00012E PC Partner Ltd. # 080023 Panasonic Communications Co., Ltd. # sub usage() { print "usage: make-mac-prefixis.pl [infile] [outfile]\n" . "where infile is usually oui.txt as distributed from\n" . "http://standards.ieee.org/regauth/oui/oui.txt and outfile is usually\n" . "nmap-mac-prefixes. The output file will be overwritten if it already exists.\n"; exit 1; } # Un-capitalize an all-caps company name; sub decap($) { my $oldcomp = shift(); my $newcomp = ""; my @words = split /\s/, $oldcomp; foreach $word (@words) { if (length($word) > 3 && (length($word) > 5 or !($word =~ /[.,\!\$]/))) { $word = "\L$word\E"; $word = "\u$word"; } if ($newcomp) { $newcomp .= " $word"; } else {$newcomp = $word; } } return $newcomp; } # Rules to shorten the names a bit, such as eliminating Inc. sub shorten($) { my $comp = shift(); $comp =~ s/,.{1,6}$//; $comp =~ s/ (Corporation|Inc|Ltd|Corp|S\.A\.|Co\.|llc|pty|l\.l\.c\.|s\.p\.a\.|b\.v\.)(\.|\b)//gi; # Fix stupid entries like "DU PONT PIXEL SYSTEMS ." $comp =~ s/\s+.$//; return $comp; } my $infile = shift() || usage(); my $outfile = shift() || usage(); if (! -f $infile) { print "ERROR: Could not find input file $infile"; usage(); } open INFILE, "<$infile" or die "Could not open input file $infile"; open OUTFILE, ">$outfile" or die "Could not open output file $outfile"; print OUTFILE "# \$Id" . ": \$ generated with make-mac-prefixes.pl\n"; print OUTFILE "# Original data comes from http://standards.ieee.org/regauth/oui/oui.txt\n"; print OUTFILE "# These values are known as Organizationally Unique Identifiers (OUIs)\n"; print OUTFILE "# See http://standards.ieee.org/faqs/OUI.html\n"; print OUTFILE "# We have added a few unregistered OUIs at the end.\n"; while($ln = ) { if ($ln =~ /\s*([0-9a-fA-F]{2})-([0-9a-fA-F]{2})-([0-9a-fA-F]{2})\s+\(hex\)\s+(\S.*)$/) { my $prefix = "$1$2$3"; my $compname= $4; # This file often over-capitalizes company names if (!($compname =~ /[a-z]/) || $compname =~ /\b[A-Z]{4,}/) { $compname = decap($compname); } $compname = shorten($compname); print OUTFILE "$prefix $compname\n"; } # else { print "failed to match: $ln"; } } # Now add a few extras which aren't oficially registered ... print OUTFILE "525400 QEMU Virtual NIC\nB0C420 Bochs Virtual NIC\nDEADCA PearPC Virtual NIC\n";