Detect Wi-Fi Clients on your DD-WRT Router

Here is a script I wrote that scrapes the web interface of a router running DD-WRT. The script looks for the MAC addresses of wireless users. When it sees a MAC address that it hasn’t logged before it issues an alert. To help identify the new equipment, a portion of the MAC address is sent to an IEEE OUI database search (Internet connection required) to determine the manufacturer name. This script is intended to be ran periodically from crond on a system other than the router. When the script detects a new MAC address it writes to STDOUT, in most cron configurations this will result in an email being generated to the local system user running the process, or to another address specified in the MAILTO variable.

Sample /etc/crontab entry

MAILTO="5558675309@sms.mobile.example.org"
* * * * *       root    /usr/local/sbin/wifi-macs.sh

Sample output generated when a new iPhone connects to the ‘MySSID’ network.

Alert new client found on MySSID MAC: 040CCECAFE00 (Apple, Inc.)

Download wifi-macs.sh

#!/bin/bash

#Set the username used for web access to the router
ROUTER_USER="root"
#Set the password used for web access to the router
ROUTER_PWD="admin"
#Set the IP address where the router can be reached, optional port
#number can be specified like 192.168.1.1:80
ROUTER_IP="192.168.1.1"

#If you have your router setup to support https, change to https
PROTO="http"

LOGS="/var/log/wifi"

read_macs () {
        while read line
        do
                if [ "${line//active_wireless/}" != "$line" ]; then
                        OFS="$IFS"
                        IFS="\'"
                        for word in ${line[@]}
                        do
                                if [ "${#word}" -eq "17" ]; then
                                mac="${word//:/}"
                                        if [ "${#mac}" -eq "12" ]; then
                                                echo "$mac"
                                        fi
                                fi
                        done
                        OFS="$IFS"
                        mac=""
                        word=""
                fi
        done
}

read_ssid () {
        while read line
        do
                if [ "${line//wl_ssid/}" != "$line" ]; then
                        line="${line##*"wl_ssid::"}"
                        line="${line%%"}"*}"
                        echo "
$line"
                fi
        done
}

read_company () {
        while read line
        do
                if [ "
${line//"(base 16)"/}" != "$line" ]; then
                        line="
${line##*'(base 16)'}"
                        line="
${line:2}"
                        echo "
$line"
                fi
        done
}


if ! [ -d "
$LOGS" ]; then
        echo "
Logs directory $LOGS does not exist" >&2
        exit 1
fi

wldata="
`curl -s --user $ROUTER_USER:$ROUTER_PWD $PROTO://$ROUTER_IP/Status_Wireless.live.asp`"
ssid="
`echo $wldata |read_ssid`"
macs=(`echo $wldata |read_macs`)

for mac in ${macs[@]}
do
        if ! [ -f "
$LOGS/$mac" ]; then
                company="
`curl -s "http://standards.ieee.org/cgi-bin/ouisearch?${mac:0:6}" |read_company`"
                echo "
Alert new client found on $ssid MAC: $mac ($company)"
                echo "
New MAC Address detected: `date`" >>$LOGS/$mac
                echo -e "
${mac:0:6}\t\t$company" >>$LOGS/$mac
                echo -e "
Additional Data:\n$wldata" >>$LOGS/$mac
        fi
done
This entry was posted in Bash, System Administration. Bookmark the permalink.

2 Responses to Detect Wi-Fi Clients on your DD-WRT Router

  1. jamen says:

    I can’t find a problem with the code, but when i run it with ./sh wifi-macs.sh I get

    wifi-macs.sh: 74: wifi-macs.sh: Syntax error: “(” unexpected (expecting “fi”)

  2. Chris says:

    Hi Jamen,

    You are running the script with /bin/sh, if you didn’t include the shebang (#!/bin/bash) in the script it will be using /bin/sh as the interpreter. This script is meant to be run on a computer with persistent storage and not on the dd-wrt device itself. If you are running this on the device, the busybox shell probably doesn’t understand the bashisms I’ve used. It would be cool to run it all on the device, and probably wouldn’t even require a password or scraping the web interface, but I didn’t take that approach.

Leave a Reply

Your email address will not be published. Required fields are marked *