Discover
I created this script in order to use it as a feed for enterprise management tools such as Nagios. It’s a bit difficult to get a handle on auto-discovery tools within an enterprise management tool when it discovers what can be an overwhelming number of hosts. NMAP is smart enough to translate the MAC address into a vendor if it can.
This script called discover uses the NMAP tool on Linux (tested on Centos).
#! /bin/bash
#
# Name: discover
#
# Garland Joseph, garland.joseph@gmail.com
# Date: June 2017
#
# Auto-discover on subnet using nmap, can be fed into something like nagios
# as a seed file after proper formatting.
#
# ----
if [[ -z ${1} ]]
then
cat <<EOD
$0 <subnet>
where
subnet, by example, is something like 192.168.1.0/24
EOD
exit
fi
nmap -sn ${1} | awk '
BEGIN{ printf("%-16s| %-18s| %-35s| %-30s\n","IP","MAC","NAME","VENDOR") }
/^Nmap scan report/ {
NAME=$5
x=$NF
gsub("[()]","",x)
IP=x
}
/^MAC Address/ {
MAC=$3
split($0,a,"(")
split(a[2],b,")")
VENDOR=b[1]
printf("%-16s| %-18s| %-35s| %-30s\n",IP,MAC,NAME,VENDOR)
}'
Here is an example of the output
[root@localhost ~]# ./discover 192.168.1.0/24
IP | MAC | NAME | VENDOR
192.168.1.1 | C8:D7:19:DE:54:2E | NyaRaePrimary | Cisco Consumer Products
192.168.1.100 | B8:27:EB:72:2A:4A | kodi1.grandenetworks.net | Raspberry Pi Foundation
192.168.1.101 | 00:1F:3B:75:7F:EB | 192.168.1.101 | Intel Corporate
192.168.1.102 | 6C:3B:E5:76:96:A5 | HP-Printer.grandenetworks.net | Hewlett Packard
192.168.1.105 | A8:47:4A:AC:8F:89 | 192.168.1.105 | Unknown
192.168.1.106 | F0:7D:68:0A:7C:8A | OllieMaeJoseph.grandenetworks.net | D-Link
192.168.1.107 | 58:82:A8:81:C3:A6 | XboxOne | Unknown
192.168.1.109 | 28:56:5A:39:ED:FD | BRW28565A39EDFD.grandenetworks.net | Unknown
192.168.1.110 | 64:20:0C:90:24:D9 | Garlands-iPad.grandenetworks.net | Apple
192.168.1.112 | 7C:D1:C3:17:0C:58 | Apple-TV.grandenetworks.net | Apple
192.168.1.115 | B8:27:EB:12:DA:AC | kodi2.grandenetworks.net | Raspberry Pi Foundation
192.168.1.118 | A4:77:33:8E:CE:C2 | Chromecast.grandenetworks.net | Google
192.168.1.119 | 6C:AD:F8:5D:3A:D6 | 192.168.1.119 | Azurewave Technologies
192.168.1.131 | F0:7D:68:0A:7A:D5 | EmmaEdwards.grandenetworks.net | D-Link
192.168.1.135 | 28:10:7B:0C:3A:71 | EarlEdwards.grandenetworks.net | D-Link International
192.168.1.136 | 00:09:B0:D6:A8:2A | 192.168.1.136 | Onkyo
192.168.1.138 | 28:10:7B:0C:3A:74 | LeeJoseph.grandenetworks.net | D-Link International
192.168.1.145 | D4:3D:7E:EF:93:99 | obama | Micro-Star Int'l Co
192.168.1.147 | E4:3E:D7:44:21:8F | LGwebOSTV.grandenetworks.net | Unknown
Here is a Diagram of my home LAN as revealed by the Network Status Map in Nagios

This script is part of a series of scripts that perform packet capture between two endpoints. In this case the endpoints are two UNIX/LINUX machines. The script was tested with the “source endpoint” as a Redhat machine and a “target endpoint” as an Ubuntu machine. The circular traces are started on each machine and stopped whenever an event is detected. In this case the event is to monitor a file for a particular string.
Requirements: tcpdump
# Author: Garland R. Joseph, garland.joseph@gmail.com
# Date: May 2017
#
# This script is offered as is. It is designed to
# run a circular trace using tcpdump on UNIX systems.
#
# You will either have to manually enter the password
# for the root account on the remote system or setup
# ssh keys from prompt-less access.
#
# Default file size is 2 x 1 GB per endpoint.
#
# The traces will stop once a key string SEARCH_STRING is
# found in LOG_FILE.
#
# Note: Some UNIX systems line LINUX Fedora will
# result in permsission denied when using
# tcpdump -W and -C options and writing to / or /root.
#
# Tested on Source endpoint Redhat and Target endpoint Ubuntu.
# -----
#
# Defaults
#
USAGE="u2ucap [-v] [ -c capture_file ] [ -w secs ] -h remote_host -l log_file -s search_string"
DEBUG=false
CAPTURE_FILE="/tmp/capture"
SLEEP_TIME="5" #seconds
SEARCH_STRING=""
LOG_FILE=""
REMOTE_HOST=""
TCPDUMPCMD="tcpdump -C 1 -W 2 -w ${CAPTURE_FILE}"
#
# Process command line arguments
#
while getopts ":vc:w:l:s:h:" opts
do
case ${opts} in
v) DEBUG=true ;;
c) CAPTURE_FILE=${OPTARG} ;;
w) SLEEP_TIME=${OPTARG} ;;
s) SEARCH_STRING=${OPTARG} ;;
l) LOG_FILE=${OPTARG} ;;
h) REMOTE_HOST=${OPTARG} ;;
":") echo "Please specify a value for ${OPTARG}" ; exit ;;
\?) echo "${OPTARG} is not a valid switch" ; echo "${USAGE}" ; exit;;
esac
done
#
# Insure required values have been specified, check for existence of
# log file, getops should handle case of no values for -l and -s.
# A sanity check in the event getopts varies per unix
#
if [[ -z ${SEARCH_STRING} || -z ${LOG_FILE} || -z ${REMOTE_HOST} ]]
then
echo ${USAGE}
exit
fi
if ! [[ -f ${LOG_FILE} ]]
then
echo "File ${LOG_FILE} does not exist"
exit
fi
#
# Start trace on remote host
#
ssh root@${REMOTE_HOST} ${TCPDUMPCMD} 2>/dev/null 1>/dev/null &
REMOTE_PID=`ssh root@${REMOTE_HOST} ps -aef | egrep tcpdump | egrep -v grep | awk '{print $2}'`
${DEBUG} && echo "${0}-I-REMOTE_PID, remote pid is ${REMOTE_PID}."
#
# Start trace on this host
#
#${TCPDUMPCMD} 2>/dev/null 1>/dev/null &
exec ${TCPDUMPCMD} 2>/dev/null 1>/dev/null &
LOCAL_PID=$!
${DEBUG} && echo "${0}-I-LOCAL_PID, local pid is ${LOCAL_PID}."
#
# Monitor log file
#
old_count=`grep -c ${SEARCH_STRING} ${LOG_FILE}`
(( new_count=old_count ))
(( i = 0 ))
while (( old_count == new_count ))
do
(( i++ ))
${DEBUG} && echo "${0}-F-SLEEP, sleeping ${SLEEP_TIME}, iteration ${i}."
sleep ${SLEEP_TIME}
new_count=`grep -c ${SEARCH_STRING} ${LOG_FILE}`
done
#
# At this point, search string has been found, stop traces
#
###${DEBUG} && set -x
kill ${LOCAL_PID}
ssh root@${REMOTE_HOST} kill ${REMOTE_PID}
####${DEBUG} && set +x
#
# Verbose only reminders
#
####${DEBUG} && echo "Consult files ${CAPTURE_FILE} on local and remote host."
exit