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