Skip to content

Instantly share code, notes, and snippets.

@syhe
Created May 15, 2020 09:48
Show Gist options
  • Save syhe/4879ac39d39d574d1ecbc56b3d48ec63 to your computer and use it in GitHub Desktop.
Save syhe/4879ac39d39d574d1ecbc56b3d48ec63 to your computer and use it in GitHub Desktop.
Dump of paraxor's maclookup.sh
#!/bin/sh
# maclookup.sh 0.2 by paraxor (Evan Teitelman)
# Looks up MAC addresses in the IEEE MA-L/OUI public listing.
# override with -f
oui_file=/usr/share/maclookup/oui.txt
# override with -a
additional_info=false
# override with -v
verbose=/dev/null
# override with -d
debug=/dev/null
# override with -u and -r
job=search
oui_url=http://standards-oui.ieee.org/oui.txt
version=0.2
err() {
echo >&2 "$*"
}
die() {
err "FATAL: $*"
exit 1
}
usage() {
echo "usage: `basename "$0"` [OPTIONS] <ADDRESSES|SEARCH>
OPTIONS
-h display this message
-u update the database
-r perform a reverse search (search by organization name)
-R generate a random MAC address based on a reverse search
-a display additional info (organization contact info)
-v be verbose
-d show debug info
-f set OUI listing file (default: $oui_file)
ADDRESSES
At least the first three bytes of an address must be present for a lookup. The
rest is ignored. All :, -, and . characters are ignored.
SEARCH
By passing the -r flag, you can perform a reverse search (search by
organization name). This search is case-insensitive.
AUTHOR
This was written by paraxor (Evan Teitelman).
Find me here: https://github.com/paraxor"
}
last_update_date() {
head -n1 "$oui_file" | sed 's/Generated: //'
}
check_oui_file() {
if [ ! -f "$oui_file" ] ; then
die "'$oui_file' does not exist. try running maclookup -u"
fi
if [ ! -r "$oui_file" ] ; then
die "cannot read '$oui_file'"
fi
}
perform_search() {
check_oui_file
first=true
for mac ; do
clean_mac=`echo "$mac" | sed 's/[-:.]//g' | tr 'a-z' 'A-Z'`
# validate address
if ! echo "$clean_mac" | grep -Eq '^[0-9A-F]+$' ; then
die "invalid MAC address: $mac"
fi
if [ `echo -n $clean_mac | wc -c` -lt 6 ] ; then
die "we need at least the first three bytes to perform a lookup. '$mac' is too short."
fi
if [ `echo -n $clean_mac | wc -c` -gt 12 ] ; then
die "'$mac' is too long to be a MAC address"
fi
# trim
clean_mac=`echo "$clean_mac" | head -c6`
if $additional_info ; then
info=`sed -n "/^ $clean_mac/,/^$/p" "$oui_file" | sed 's/^.*\t//g'`
if [ ! -z "$info" ] ; then
$first || echo
echo "$mac:"
echo "$info"
else
err 'no addresses found'
fi
else
info=`grep "^ $clean_mac" "$oui_file" | cut -d' ' -f3`
if [ ! -z "$info" ] ; then
echo "$mac $info"
else
err 'no addresses found'
fi
fi
$first && first=false
done
}
perform_reverse_search() {
search=$*
check_oui_file
# fix front anchors
search=`echo "$search" | sed 's/\^/ /'`
if $additional_info ; then
# this is gross
info=`sed -n "/(hex).*$search/I,/^$/p" "$oui_file" |
sed '/(base 16)/d; s/ (hex) /:\n/; s/ //g; s/^ //'`
if [ ! -z "$info" ] ; then
echo "$info"
fi
else
info=`grep -i "(hex).*$search" "$oui_file" |
sed 's/ (hex) / /; s/^ //'`
if [ ! -z "$info" ] ; then
echo "$info"
else
err 'no organizations found'
fi
fi
}
perform_reverse_search_gen() {
search=$*
prefix=`perform_reverse_search "$search" | cut -d' ' -f1 |
sort -R | head -n1 | sed 's/-/:/g'`
tail=`hexdump -Cn3 < /dev/urandom | head -n1 |
sed 's/[^ ]* \([^ ]*\) \([^ ]*\) \([^ ]*\).*/\1:\2:\3/' |
tr 'a-z' 'A-Z'`
echo "$prefix:$tail"
}
update_oui() {
dir=`dirname "$oui_file"`
mkdir -p $dir 2> $debug || die "failed to make '$dir'"
if [ -f "$oui_file" ] ; then
if [ ! -w "$oui_file" ] ; then
die "cannot write to '$oui_file'"
fi
else
touch "$oui_file" 2> $debug || die "cannot create '$oui_file'"
fi
curl -L "$oui_url" -o "$oui_file" \
2> $verbose
}
main() {
if [ $# -eq 0 ] ; then
usage
fi
while getopts hurRavdf: flag ; do
case "$flag" in
h) usage ;;
u) job=update ;;
r) job=reverse_search ;;
R) job=reverse_search_gen ;;
a) additional_info=true ;;
v) verbose=/dev/stdout ;;
d) debug=/dev/stdout; verbose=/dev/stdout ;;
f) oui_file=$OPTARG ;;
*) die "invalid option: $OPTARG" ;;
esac
done
shift `expr $OPTIND - 1`
if [ -z "$job" ] ; then
usage
fi
case "$job" in
search) perform_search "$@" ;;
reverse_search) perform_reverse_search "$@" ;;
reverse_search_gen) perform_reverse_search_gen "$@" ;;
update) update_oui ;;
esac
}
main "$@"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment