DHCP Server Log Analysis
A quick script to go through your DHCP server log and get a summary of MAC addresses and associated DHCP requests. The script will attempt to download the IEEE OUI list for identifying the manufacturers associated with the MAC addresses in your log. This is a fairly large text file, so the download may take a few minutes. Once downloaded, the script will not try to download the file again, unless it’s about three months old.
You may need to modify the f="/var/log/boot.log" to point to your DHCP server log file. Depending on the number of log entries, the script may take a while to run. Feel free to optimize it if you can. The output should look something like this:
MAC IP Status Manufacturer DHCPACK DHCPDISCOVER DHCPINFORM DHCPNAK DHCPOFFER DHCPRELEASE DHCPREQUEST 1c:99:4c:b0:e8:22 192.168.22.155 down Murata Manufacturi 1573 4 0 0 4 0 1575 20:d3:90:da:c2:6d 192.168.22.151 up Samsung Electronic 10288 1 0 0 1 0 10288 28:b2:bd:4a:71:03 192.168.22.150 down Intel Corporate 11662 31 0 25 30 0 11687 28:c6:71:06:4c:c3 192.168.22.159 up Yota Devices OY 9535 31 0 6 31 0 9541
You can download the script here: dhcp_log_stats.
#!/bin/bash
f="/var/log/boot.log"
if [ ! -r "${f}" ]
then
echo "Cannot access ${f}"
exit 1
fi
ouif="/var/tmp/oui.txt"
ouiurl="http://standards.ieee.org/regauth/oui/oui.txt"
howold=90
if [ ! -f "${ouif}" ] || test $(find "${ouif}" -mtime +${howold})
then
echo "Downloading IEEE Organizationally Unique Identifier. This will take a few minutes..."
wget -q -O "${ouif}" "${ouiurl}"
if [ -f "${ouif}" ]
then
sed -i 's/\r$//g' "${ouif}"
else
echo "Cannot download ${ouiurl}"
exit 1
fi
fi
IFS=$'\n' ; op_array=($(grep -oP "DHCP[A-Z]{1,}" "${f}" | sort -u)) ; unset IFS
IFS=$'\n' ; mac_array=($(grep -oE '([[:xdigit:]]{2}:){5}[[:xdigit:]]{2}' "${f}" | sort -u)) ; unset IFS
IFS=$'\n' ; ip_array=($(grep -oE "([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})" "${f}" | sort -u)) ; unset IFS
s1=$(echo "scale=0;`printf '%s\n' ${op_array[@]} | wc -L`+1"|bc)
printf "%-18s %-16s %-8s %-20s" "MAC" "IP" "Status" "Manufacturer"
for ((i = 0; i < ${#op_array[@]}; i++)) ; do printf "%-${s1}s" "${op_array[$i]}" ; done
printf "\n"
printf '%s\n' ${mac_array[@]} | while read mac
do
ip_address=$(tac "${f}" | grep -m1 "DHCPOFFER.*${mac}" | grep -oE "([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})")
if [ -z "${ip_address}" ] ; then ip_address="none" ; fi
if [ $(ping -q -c 1 -W 5 ${ip_address} > /dev/null 2>&1 ; echo $?) -eq 0 ]
then
ip_online="up"
else
ip_online="down"
fi
oui=$(echo ${mac//[:.- ]/} | tr "[a-f]" "[A-F]" | egrep -o "^[0-9A-F]{6}")
mfg="$(grep -m1 "^${oui}" "${ouif}" | cut -f3 -d$'\t' | cut -c1-18 | sed -e 's/,\.//g')"
if [ -z "${mfg}" ]; then mfg="Unknown" ; fi
printf "%-18s %-16s %-8s %-20s" "${mac}" "${ip_address}" "${ip_online}" "${mfg}"
printf '%s\n' ${op_array[@]} | while read op
do
c=$(grep -cE "${op} .* ${mac} " "${f}")
printf "%-${s1}s" ${c}
done
printf "\n"
done
