#!/usr/bin/env perl
#
# Copyright 2006-2013 Roy Hills
#
# This file is part of arp-scan.
#
# arp-scan is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# arp-scan is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with arp-scan. If not, see .
#
# $Id: get-iab 19550 2013-04-15 09:24:42Z rsh $
#
# get-iab -- Fetch the IAB file from the IEEE website
#
# Author: Roy Hills
# Date: 16 March 2006
#
# This script downloads the Ethernet IAB file from the IEEE website, and
# converts it to the format needed by arp-scan.
#
# This script assumes that all the IAB entries start with 00-50-C2. This
# is currently the case, and will probably be so for the foreseeable
# future.
#
use warnings;
use strict;
use Getopt::Std;
use LWP::Simple;
#
my $default_url = 'http://standards-oui.ieee.org/iab/iab.txt';
my $default_filename='ieee-iab.txt';
#
my $usage =
qq/Usage: get-iab [options]
Fetch the Ethernet IAB file from the IEEE website, and save it in the format
used by arp-scan.
'options' is one or more of:
-h Display this usage message.
-f FILE Specify the output IAB file. Default=$default_filename
-u URL Specify the URL to fetch the IAB data from.
Default=$default_url
-v Give verbose progress messages.
/;
my %opts;
my $verbose;
my $filename;
my $url;
my $lineno = 0;
my $iab_var;
my $vendor;
#
# Process options
#
die "$usage\n" unless getopts('hf:u:v',\%opts);
if ($opts{h}) {
print "$usage\n";
exit(0);
}
if (defined $opts{f}) {
$filename=$opts{f};
} else {
$filename=$default_filename;
}
if (defined $opts{u}) {
$url=$opts{u};
} else {
$url=$default_url;
}
$verbose=$opts{v} ? 1 : 0;
#
# If the output filename already exists, rename it to filename.bak before
# we create the new output file.
#
if (-f $filename) {
print "Renaming $filename to $filename.bak\n" if $verbose;
rename $filename, "$filename.bak" || die "Could not rename $filename to $filename.bak\n";
}
#
# Fetch the content from the URL
#
print "Fetching IAB data from $url\n" if $verbose;
my $content = get $url;
die "Could not get IAB data from $url\n" unless defined $content;
my $content_length = length($content);
die "Zero-sized response from from $url\n" unless ($content_length > 0);
print "Fetched $content_length bytes\n" if $verbose;
#
# Open the output file for writing.
#
print "Opening output file $filename\n" if $verbose;
open OUTPUT, ">$filename" || die "Could not open $filename for writing";
#
# Write the header comments to the output file.
#
my ($sec,$min,$hour,$mday,$mon,$year,undef,undef,undef) = localtime();
$year += 1900;
$mon++;
my $date_string = sprintf("%04d-%02d-%02d %02d:%02d:%02d", $year, $mon, $mday,
$hour, $min, $sec);
my $header_comments =
qq/# ieee-iab.txt -- Ethernet vendor IAB file for arp-scan
#
# This file contains the Ethernet vendor IABs for arp-scan. These are used
# to determine the vendor for a give Ethernet interface given the MAC address.
#
# Each line of this file contains an IAB-vendor mapping in the form:
#
#
#
# Where is the first 36 bits of the MAC address in hex, and
# is the name of the vendor.
#
# Blank lines and lines beginning with "#" are ignored.
#
# This file was automatically generated by get-iab at $date_string
# using data from $url
#
# Do not edit this file. If you want to add additional MAC-Vendor mappings,
# edit the file mac-vendor.txt instead.
#
/;
print OUTPUT $header_comments;
#
# Parse the content received from the URL, and write the IAB entries to the
# output file. Match lines that look like this:
# 000000-000FFF (base 16) T.L.S. Corp.
# and write them to the output file looking like this:
# 0050C2000 T.L.S. Corp.
#
# Note that the 0050C2 bit is a constant, and we take
# the next three hex digits from the IEEE data.
#
while ($content =~ m/^\s*(\w+)-\w+\s+\(base 16\)[ ]+(.*)$/gm) {
$iab_var = substr($1,0,3);
$vendor = $2;
$vendor = "PRIVATE" if length($vendor) == 0;
print OUTPUT "0050C2$iab_var\t$vendor\n";
$lineno++;
}
#
# All done. Close the output file and print IAB entry count
#
close OUTPUT || die "Error closing output file\n";
print "$lineno IAB entries written to file $filename\n" if $verbose;