Thursday, September 13, 2012

Optimizing the Presence Detection with SNMP

So now, as described in this post, I've got some rudimentary presence detection going, and can generate events when my wife and I (or rather, our phones) come and go. However, I felt like the ssh-based method I was using was a bit of a kludge, and I really wanted a better way to go about it.

At some point in the past few weeks, I read a bit about SNMP, or Simple Network Management Protocol. It's not really all that simple. From what I read, however, it looked like a pretty useful way to get information from a device, and I stumbled across a few posts mentioning that it could be extended, like this one.


Intrigued, I decided to try installing snmpd on my OpenWRT router, a process which wasn't trivial, since my router was already pretty crammed full of stuff. See <<this post>> for more on that effort.

Eventually, though, I was able to get it running, and took a closer look at "extend" directive.  I noticed that by default, it was running /usr/bin/cat, with the argument /proc/sys/fs/file_nr, basically dumping the number of open file handles. I manually ran the command and took note of the output.

Then, a quick Google search turned up this Windows binary for snmpwalk functionality. I ran it, searched through the output, and lo and behold, I saw a string that looked suspiciously like the output to the script.  Running the program with the -op and -os args allowed me to trim down the output to just the parts I cared about. This was definitely the results of the script. Getting excited, i changed the configuration of snmpd to call my own script, the cleverly named 'test.sh' and crossed my fingers.

--test.sh--
#/bin/sh
echo "Hello, World"
--Output of snmpwalk--
C:\work>snmpwalk -r:192.168.1.1 -os:1.3.6.1.4.1.2021.8.1 -op:1.3.6.1.4.1.2021.8.2
SnmpWalk v1.01 - Copyright (C) 2009 SnmpSoft Company
[ More useful network tools on http://www.snmpsoft.com ]
OID=.1.3.6.1.4.1.2021.8.1.1.1, Type=Integer, Value=1
OID=.1.3.6.1.4.1.2021.8.1.2.1, Type=OctetString, Value=filedescriptors
OID=.1.3.6.1.4.1.2021.8.1.3.1, Type=OctetString, Value=/mnt/sda1/test.sh /proc/sys/fs/file-nr
OID=.1.3.6.1.4.1.2021.8.1.100.1, Type=Integer, Value=0
OID=.1.3.6.1.4.1.2021.8.1.101.1, Type=OctetString, Value=Hello, World
OID=.1.3.6.1.4.1.2021.8.1.102.1, Type=Integer, Value=0
OID=.1.3.6.1.4.1.2021.8.1.103.1, Type=OctetString, Value=Total: 7
Success!

After that, I wrote a quick script to output presence information for the two MAC addresses I cared about separated by a comma, and sure enough, the result was right there in OID.1.3.6.1.4.1.2021.8.1.101.1. That presence script, if you're interested, looks like this (with MAC's obscured to protect the innocent):
--presence.sh--
#!/bin/sh
mac1=`iw wlan0 station dump | grep -c '00:00:00:00:00:00'`
mac2=`iw wlan0 station dump | grep -c '00:00:00:00:00:01'`
macsum=$((mac1 + mac2 * 2))
echo $mac1,$mac2
exit $macsum
In case you were wondering, I'm using the exit code as a quick and dirty bitmask for the two connected users I'm curious about.

Now it's just a matter of getting a python or perl library that talks SNMP, and integrating this back into my presence script should be a piece of cake. The best news is that when I run this command, as opposed to ssh, it returns immediately, without any appreciable lag, which makes me feel better about running it more often, and having a more dynamic presence detection routine.

So there you have it.  Using SNMP for something a little out of the ordinary.  I'm sure there are better ways to accomplish the same thing, and I may not actually end up with this method for my presence detection after all is said and done. I'd really like to switch to a more event-driven rather than a polled system (If you have any suggestions, I'd love to hear them!).

No comments:

Post a Comment