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

Posted

in

,

by

Tags:

Comments

4 responses to “Detect Wi-Fi Clients on your DD-WRT Router”

  1. jamen Avatar
    jamen

    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”)

    1. Chris Avatar
      Chris

      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.

  2. Hardy Avatar
    Hardy

    Hi Chris,
    Not sure if you’re still maintaining this but I thought I would try. The script works great, I’ve added an extra layer of IFTTT notification when the email is sent so I get updates if new connections are made. One thing I noticed is that in all of my notifications, the part after the MAC is blank like this:
    Alert new client found on TRENDnet MAC: A020A60AC83D ()
    Is there something I need to add to get the part inside the brackets? Also, are there other details that dd-wrt can pass along in the initial message – like the new IP address for example?
    Thanks for the awesome script!

  3. Kyle Silfer Avatar
    Kyle Silfer

    I put this script to use and thanks very much for sharing, but I discovered that the output of Status_Wireless.live.asp doesn’t properly show users connecting to a virtual interface (such as a guest network). The SSID and Mac address of the virtual interface are not distinguished from the physical interface. I was interested in recording connections to the physical interface and not the virtual, but it’s impossible to tell which is which. 🙁

Leave a Reply to Kyle Silfer Cancel reply

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.