MAC Address Lookup

I installed a rather useful utility on my kids' computers called iTalc which helps us better manage what the kids are doing when they are supposed to be working on assignments.  One of the limitations I ran into right away was that iTalc doesn't offer any sort of network discovery features -- at least none that I could get working easily.  This means that if I want a computer to show up, I have to add it specifically by its host name or IP address.  Though I can assign static IP addresses here at home, that would make iTalc only usable in my home network.  This doesn't conform to our needs to use this outside the home.  Making matters worse, my router is really not too good at managing local domain names, so using host names is out.  So what to do?

I wrote this script called "macscanner" which uses nmap to scan the whole subnet for active IP addresses.  I then take the MAC address of each active IP and set that as a host name in /etc/hosts such that name looks like MACxx-xx-xx-xx-xx-xx where xx-xx... is the mac address of the target machine.  Using this host name, I can then add the computers by host name instead of fixed IP and now my iTalc configuration works everywhere we go!  This script must be run as root (using sudo, etc) in order to get mac addresses from nmap and also to update the /etc/hosts file.  The subnet detection at the start is a little hackish, so you can just cut out the addressLine and follow-up if statement to set ipBase if you are on a network that doesn't change IP ranges -- for example just set IPBase, rangeStart and rangeEnd with fixed values to reduce the chance of error or confusion (especially if you are on a host with more than one IP address).  Lastly, I added logic to perform the nmap scan three times and then merge everything with sort and uniq before appending the hosts file.

#!/bin/bash

## Find IP Address scan range based on current IP address

ipBase="192.168.1"

ipRangeStart=1

ipRangeEnd=254

addressLine=`ifconfig | grep "inet addr" | grep -v 127.0.0.1`

if [[ $addressLine =~ .*inet.addr:([0-9]+.[0-9]+.[0-9]+).*Mask:([0-9]+.[0-9]+.[0-9]+.[0-9]+) ]] ; then

ipBase="${BASH_REMATCH[1]}"

mask="${BASH_REMATCH[2]}"

fi

echo Scanning IP Addresses in range $ipBase.$ipRangeStart-$ipRangeEnd

# Strip out previous results

grep -v "Added by macscan" /etc/hosts > /tmp/hosts

cp /tmp/hosts /etc

rm -f /tmp/hosts

for loop in 1 2 3

do

#Now run nmap to find hosts

rm -f /tmp/ips.txt

nmap -sP -n $ipBase.$ipRangeStart-$ipRangeEnd | grep -A 2 "scan report" >> /tmp/ips.txt

#Loop through results and add output

while read line

do

if [[ $line =~ report.for.([0-9]+.[0-9]+.[0-9]+.[0-9]+)$ ]] ; then

ip="${BASH_REMATCH[1]}"

fi

if [[ $line =~ MAC.Address:.([0-9A-F]{2}:[0-9A-F]{2}:[0-9A-F]{2}:[0-9A-F]{2}:[0-9A-F]{2}:[0-9A-F]{2}) ]] ; then

mac="${BASH_REMATCH[1]//:/-}"

echo "$ip     MAC$mac   # Added by macscan" >> /tmp/hosts

fi

done < /tmp/ips.txt

done

# Now merge all the results and sort them

# (sort has a handy way of sorting version numbers, which works nicely for IP addresses too)

sort -V < /tmp/hosts | uniq >> /etc/hosts

rm /tmp/ips.txt

rm /tmp/hosts