Saturday, February 17, 2007

Auto WOL on DD-WRT on Linksys WRT54GL

I am running a webserver on my desktop, to host a website from home. One of the problems I faced, is that I have to now leave my desktop "on" all the time. Between the higher electricity bill and depreciation on the desktop, I wondered if I was saving much hosting from home.

So when I bought the Linksys WRT54GL and installed DD-WRT on it recently, I thought I would try to set it up to wake up the computer on a Port 80 (http) access if it was in "sleep" mode.

For DD-WRT and Linksys routers, see http://www.dd-wrt.com/

DD-WRT allows you to write shell scripts on the router and I thought I would use this facility and use the builtin commands. Ideally I would want a trigger on a port 80 access on the router, but this might be a little inefficient since it would happen on every port 80 access and I could not find a way to trigger a script in DD-WRT.

So I thought instead that I would parse the syslog to detect port 80 activity. I could then control things like how often I check for activity etc. Here is the script I came up with

#!/bin/sh

INTERVAL=5
NUMP=3
OLD=""
WOL=/usr/sbin/wol
TARGET=192.168.1.100
MAC=00:00:00:00:00:00
logfile="/tmp/www/wol.log"

while sleep $INTERVAL
do
NEW=`cat /var/log/messages | grep ACCEPT | grep "DST=$TARGET" | grep "DPT=80" | tail -1 | awk '{print $3}'`
SRC=`cat /var/log/messages | grep ACCEPT | grep "DST=$TARGET" | grep "DPT=80" | tail -1 | awk '{print $10}' | sed -e "s/SRC=//g"`
LINE=`cat /var/log/messages | grep ACCEPT | grep "DST=$TARGET" | grep "DPT=80" | tail -1 `
if [ "$NEW" != "" -a "$NEW" != "$OLD" ]; then
echo "$SRC $LINE" >> $logfile
RET=`ping -c $NUMP $TARGET 2> /dev/null | awk '/packets received/ {print $4}'`
if [ "$RET" -ne "$NUMP" ]; then
echo "$SRC causes WOL at" `date` >> $logfile
$WOL -i 192.168.1.255 -p 7 $MAC >> $logfile
sleep 5
fi
OLD=$NEW
fi
done


TARGET is the LAN IP of your webserving machine, and MAC is its MAC Address. INTERVAL is how often you want to check for a transaction. To get the syslog in /var/log/messages, enable syslogd in DD-WRT with an empty field for IP address. I also had to set the log level to High and at least log all ACCEPT s in the log settings.

I create a logfile in /tmp/www to debug the script, the logfile references can be deleted if you want to make the script smaller to fit in nvram. The script does not send a WOL if the webserving machine is not in "sleep" mode. I use the built in WOL command on DD-WRT.

For more on DD-WRT scripts check http://www.dd-wrt.com/wiki/index.php/Index:Scripting

There is a lag now, when the computer is asleep to access a page on the computer. However I find that in most cases, the browser timeout is long enough to wake the computer up and deliver the webpage.

Comments and improvement suggestions are welcome.