ARP Presence Sensor

If anyone is using an EdgeRouter on EdgeOS, I've put together some scripts which can help determine if someone has arrived or left your network. This doesn't require you to ping devices. Of course there are some concerns around if people disable wireless on their device, but the same concerns work for the ping detection method.

I'd also recommend this be used with a tool for combining multiple presence sensors into a "master" presence to be more accurate:

Either Presence Governor or [RELEASE] Combined Presence.

There are also other ways of doing this if you are not using EdgeOS: [RELEASE] iPhone WiFi Presence Sensor is one option.

Another option which is related to ARP but doesn't require the wireless device to be on your network would be to sniff WiFi traffic and look for wireless probes. You need a Linux Device/RPi with a spare wireless adapter that supports monitor mode. The other gotcha here is some mobile devices mask their true MAC address for anonymous probes (they return an Admin OUI). Either way, this would be a router-agnostic way to solve this problem, however it needs someone to change the code (GitHub - bdwilson/wuds: Wireless User Detection System) and add the ability to expire devices that haven't been seen in X amount of time. This has been on my list but I haven't had time.

3 Likes

Arpwatch.

When can we expect you to write something similar using arpwatch for folks not on EdgeOS?

I can add that to my "to do" list when I rebuild this Linux server that handles some of my boring utility functions.

1 Like

I can supply the same kind of thing for Orbi routers. Please contact me directly. I'll put it up on Github soon.

The generic Linux version -- not specific to any wireless router -- is trivial, as in:

#! /bin/bash

# This script takes a list of [hostname|MAC|IP] and checks whether the specified device[s] are on the LAN.
# 
# Will fail miserably with non-CIDR routing, multi-homed hosts, etc.


if [ "X$1" = "X" ] ; then
	echo "$0 [hostname|MAC|IP]"
	echo ""
	echo "Checks whether the specified device[s] are on the LAN."
	exit 1
fi

defaultroute=`ip route show|grep default |sed -e "s/default via //" -e "s/\.[0-9][0-9]* .*//" `
subnet=`ip route show |sed -n -e "s,^\(${defaultroute}\.[0-9][0-9]*\)/[0-9].*,\1,p"`

exitval=0
for device in $*
do
	# inefficient, but simple
	ping -c 2 -W 2  -b $subnet 1> /dev/null 2>&1	# populate the ARP cache
	arp -a | grep -qiw $1 
	if [ $? = 0 ] ; then
		echo "Device $1 is present on the LAN ($subnet)"
	else
		echo "Device $1 is absent from the LAN ($subnet)"
		exitval=$((exitval + 1))	# unnecessary
	fi
	shift
done
exit $exitval

When can we expect you to write something similar using arpwatch for folks not on EdgeOS?

arpwatch is not router-brand specific.

1 Like

I use arping to do my presence testing. I’m not sure how different it is to the method you use in your script with ping and arp.

I did a bunch of testing with arping and 2 iPhones I have.

The longest an iPhone ever stopped responding to arping was 6s (I logged it for weeks arping every 5s) so I set the timeout for a minute when it left the network. When the phone connects back it picks it up almost instantly.

This was way better than any ping where an iPhone would stop responding for up to 15 minutes once it went to sleep.

I know; was simply pointing out that if folks are going to offer other options, please share them.

Conceptually, no difference. Really, I just wrote the script (in under 10min) as an example, not that it does anything elegant or unique.

You've got a method that works...no need to change it.

1 Like