Skip to content

Instantly share code, notes, and snippets.

@endofline
Created September 30, 2015 03:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save endofline/87871f0ce1c02eb3a17b to your computer and use it in GitHub Desktop.
Save endofline/87871f0ce1c02eb3a17b to your computer and use it in GitHub Desktop.
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
@endofline
Copy link
Author

Populate a file known.txt with mac addresses and single-world (no spaces!) names, e.g.

00:00:00:00:00:00 PersonA
00:00:00:00:00:01 PersonB
00:00:00:00:00:02 PersonB

Use cron to execute this script every 1 minute, e.g.

* * * * * sudo /path/to/script

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 idled
  • online.txt - up-to-date list of MAC addresses online in last minute
  • unrecognised.txt - MAC addresses not in known.txt appended here with date and time (first seen) - the entry won't be removed if the MAC is subsequently added to known.txt, so don't forget to remove the entry manually, or remove the entire unrecognised.txt file to refresh
  • log.txt - logs MAC addresses and names going online and offline

An example of this script (running on a raspi) with a web-based front-end (using jQuery.ajax to retrieve the auto-updated presence.txt file containing known "names") can be found at Smartspace Kota Kinabalu.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment