nmap-based presence script
#!/bin/bash | |
SUDO="/usr/bin/sudo" | |
NMAP="/usr/bin/nmap" | |
DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) | |
MACS=$($SUDO $NMAP -sP -n $(ifconfig eth0 | awk '/inet addr:/{print $2;} ' | cut -c6- | awk -F"." '{ print $1"."$2"."$3".0/24" }') | grep "MAC *" | awk -F" " '{ print $3 }') | |
PRESENCE="$DIR/presence.txt" | |
UNRECOGNISED="$DIR/unrecognised.txt" | |
KNOWN="$DIR/known.txt" | |
ONLINE="$DIR/online.txt" | |
LOG="$DIR/log.txt" | |
DATETIME=$(date +%Y%m%d%H%M%S) | |
if [ ! -f "$PRESENCE" ]; then | |
touch "$PRESENCE" | |
fi | |
if [ ! -f "$LOG" ]; then | |
touch "$LOG" | |
fi | |
if [ ! -f "$UNRECOGNISED" ]; then | |
touch "$UNRECOGNISED" | |
fi | |
if [ ! -f "$ONLINE" ]; then | |
touch "$ONLINE" | |
fi | |
CURR_PRESENCE="|" | |
LIST=($MACS) | |
for MAC in "${LIST[@]}" | |
do | |
# track macs going online and offline | |
found=$(grep "$MAC" "$ONLINE") | |
if [ -z "$found" ]; then | |
echo "$MAC --> ONLINE" | |
echo "$DATETIME MAC ONLINE $MAC" >> "$LOG" | |
echo "$MAC" >> "$ONLINE" | |
fi | |
# track recognised macs | |
match=$(grep "$MAC" "$KNOWN") | |
if [ -n "$match" ] | |
then | |
NAME=$(echo $match | cut -c19-) | |
CURR_PRESENCE="$CURR_PRESENCE""$NAME""|" | |
already=$(grep "$NAME" "$PRESENCE") | |
if [ -z "$already" ]; then | |
echo "$NAME --> ONLINE" | |
echo "$NAME" >> "$PRESENCE" | |
echo "$DATETIME PRESENCE ONLINE $NAME" >> "$LOG" | |
fi | |
else | |
recorded=$(grep "$MAC" "$UNRECOGNISED") | |
if [ -z "$recorded" ]; then | |
echo "$DATETIME $MAC" >> "$UNRECOGNISED" | |
fi | |
fi | |
done | |
# track macs going offline | |
CHANGED="" | |
TMP="" | |
while read PREV_MAC; | |
do | |
if [[ "$MACS" == *"$PREV_MAC"* ]] | |
then | |
TMP="$TMP""$PREV_MAC"$'\n' | |
else | |
echo "$PREV_MAC --> OFFLINE" | |
echo "$DATETIME MAC OFFLINE $PREV_MAC" >> "$LOG" | |
CHANGED=1 | |
fi | |
done < "$ONLINE" | |
if [ -n "$CHANGED" ]; then | |
echo -n "$TMP" > "$ONLINE" | |
fi | |
# track presences going offline | |
CHANGED="" | |
TMP="" | |
while read PREV_PRESENCE; | |
do | |
_PRESENCE=($PREV_PRESENCE) | |
_NAME=${_PRESENCE[0]} | |
_IDLE=${_PRESENCE[1]} | |
if [[ "$CURR_PRESENCE" == *"|""$_NAME""|"* ]] | |
then | |
# user is active | |
TMP="$TMP""$_NAME"$'\n' | |
if [ -n "$_IDLE" ]; then | |
# reset previous idle | |
CHANGED=1 | |
fi | |
else | |
# user is inactive | |
if [ -z "$_IDLE" ] | |
then | |
# just started idling | |
TMP="$TMP""$_NAME"" 1"$'\n' | |
else | |
# already idling, increment the counter | |
_IDLE=$((_IDLE + 1)) | |
if [ "$_IDLE" -gt "10" ]; | |
then | |
echo "$_NAME --> OFFLINE" | |
echo "$DATETIME PRESENCE OFFLINE $_NAME" >> "$LOG" | |
else | |
TMP="$TMP""$_NAME"" ""$_IDLE"$'\n' | |
fi | |
fi | |
CHANGED=1 | |
fi | |
done < "$PRESENCE" | |
if [ -n "$CHANGED" ]; then | |
echo -n "$TMP" > "$PRESENCE" | |
fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This comment has been minimized.
Populate a file
known.txt
with mac addresses and single-world (no spaces!) names, e.g.Use
cron
to execute this script every 1 minute, e.g.Auto-generated files:
presence.txt
- up-to-date list of names detected on the network - any number following the name indicates the number of minutes the presence has idledonline.txt
- up-to-date list of MAC addresses online in last minuteunrecognised.txt
- MAC addresses not inknown.txt
appended here with date and time (first seen) - the entry won't be removed if the MAC is subsequently added toknown.txt
, so don't forget to remove the entry manually, or remove the entireunrecognised.txt
file to refreshlog.txt
- logs MAC addresses and names going online and offlineAn example of this script (running on a raspi) with a web-based front-end (using
jQuery.ajax
to retrieve the auto-updatedpresence.txt
file containing known "names") can be found at Smartspace Kota Kinabalu.