Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Detect new network devices connecting to OpenWrt and send text message

Add the following line in /etc/dnsmasq.conf

dhcp-script=/etc/detect_new_device.sh

Setup sendmail to send email to your text number.

Reference:

Create /etc/detect_new_device.sh with the following content

#!/bin/sh

# script to detect new dhcp lease

# this will be called by dnsmasq everytime a new device is connected
# with the following arguments
# $1 = add | old
# $2 = mac address
# $3 = ip address
# $4 = device name

notification_email="1234567890@txt.att.net"

if [ "$1" == "add" ]; then
  msg="New device on `uci get system.@system[0].hostname`.`uci get dhcp.@dnsmasq[0].domain` $*"
  echo `date` $msg >> /tmp/dhcpmasq.log

  # encode colon (:) and send email
  echo $msg | sed s/:/-/g | sendmail "$notification_email"
fi

Alternative script using whitelist

This script only sends alerts if the mac address is not in the list

#!/bin/sh

# script to detect new dhcp lease

# this will be called by dnsmasq everytime a new device is connected
# with the following arguments
# $1 = add | old
# $2 = mac address
# $3 = ip address
# $4 = device name

known_mac_addr="/etc/known_mac_addr"
notification_email="1234567890@txt.att.net"

# check if the mac is in known devices list
grep -q "$2" "$known_mac_addr"
unknown_mac_addr=$?

if [ "$1" == "add" ] && [ "$unknown_mac_addr" -ne 0 ]; then
  msg="New device on `uci get system.@system[0].hostname`.`uci get dhcp.@dnsmasq[0].domain` $*"
  echo `date` $msg >> /tmp/dhcpmasq.log

  # encode colon (:) and send email
  echo $msg | sed s/:/-/g | sendmail "$notification_email"
fi

When a new device is added, dnsmasq calls detect_new_device.sh with arguments add mac_addr ip_addr devicename. The script checks if the device is new (if the dhcp lease hasn't expired, it calls with old), then logs and emails (which eventually is a text message) the information.

@RogueIMP

This comment has been minimized.

Copy link

@RogueIMP RogueIMP commented Feb 11, 2018

This is fantastic! Thanks!
Do you know if there is a way to detect "Disconnect"?
I'm trying to execute a script when a specific MAC connects, then another when it disconnects. A slight modification allowed for the first, but I'm unable to find a way to detect the disconnect.

@jwalanta

This comment has been minimized.

Copy link
Owner Author

@jwalanta jwalanta commented Mar 15, 2018

@RogueIMP sorry for late reply, seems like Github doesn't send notifications for gist comments.

About detecting "disconnect", the method I use is based on the signal from dnsmasq which unfortunately doesn't care about disconnects. However, the benefit of using dnsmasq is that it works for both wired LAN and WiFi. For disconnect, there are methods for both separately.

For connected LAN, you can use hotplug. Check out the scripts under /etc/hotplug.d/iface in your OpenWRT installation. Everytime the LAN is connected or disconnected, the scripts in that folder is executed. See this for more details: https://wiki.openwrt.org/doc/techref/hotplug#examples

For WiFi, you need to install hostapd-utils.

opkg update
opkg install hostapd-utils

It comes with hostapd_cli which can run a script when the WiFi device connects / disconnects.

# hostapd_cli -a /path/to/script.sh -i wlan0

Run this in background with & (eg, hostapd_cli -a script.sh -i wlan0 &) or put it in your startup script. Do this for each wireless interface (wlan0, wlan1, etc)

It invokes the script with three arguments: interface name, connect/disconnect signal (AP-STA-CONNECTED or AP-STA-DISCONNECTED), and mac address. I found a pretty good example here: https://superuser.com/questions/1071354/hostapd-execute-a-command-when-there-is-new-connection-established

Hope that helps :)

@AmandaBeuno

This comment has been minimized.

Copy link

@AmandaBeuno AmandaBeuno commented Mar 19, 2018

@jwalanta. Thank you so much for the reply.

My problem is that whenever my phone screen goes off. HostAPD reports it disconnected. Is there anyway around that? Totally appreciate your knowledge.

@jwalanta

This comment has been minimized.

Copy link
Owner Author

@jwalanta jwalanta commented Mar 19, 2018

@AmandaBeuno Unfortunately, there's no way around it. WiFi clients can disconnect to save battery when not in use. If you're trying to see if the device is in the network, you can check how long it remains disconnected because phones periodically "wake up" to check on emails / messages.

@mavridis92

This comment has been minimized.

Copy link

@mavridis92 mavridis92 commented Feb 1, 2019

Hi, I think this script is very useful for network monitoring and I would like to implement something similar based on your script but, I face a problem.
I was watching the syslog output for debugging because the script did not respond and I discovered the following message:
dnsmasq[16811]: failed to execute /etc/test.sh: Permission denied
Any help is welcomed.

@rpugsley

This comment has been minimized.

Copy link

@rpugsley rpugsley commented Feb 6, 2019

Hello @jwalanta,

Thanks for the script.

Everything is working well except for this:
"$unknown_mac_addr" -ne 0 -ash: 1: not found
am I missing something here?

@lededude

This comment has been minimized.

Copy link

@lededude lededude commented Apr 25, 2019

@mavridis92
Answer to your question is, permission is denied, you need to enable the permission to execute with the following:

chmod 744 "/etc/test.sh"

... another question is, why would you put something directly to /etc? It is a guaranteed way to mess up the router.. if you delete something vital..

Make a new directory with following:
mkdir /usr/lib/scripts

Put all scripts in the new folder and make sure the permissions are correct by running this:

chmod -R 744 "/usr/lib/scripts/"

I would, in your case, make sure that I have a backup router set up properly in case the current one no longer works after testing.

@angelmartinezn

This comment has been minimized.

Copy link

@angelmartinezn angelmartinezn commented Sep 29, 2019

Thanks @jwalanta , this script was really helpfull.

I did a couple of quick changes to the second script, adding a case insensitive check to grep and adding a subject to the email

grep -iq "$2" "$known_mac_addr"

msg=echo $msg | sed s/:/-/g
echo -e "Subject: $subject\n\n$msg" | sendmail "$notification_email"

Hope this help anyone.

@alixyz

This comment has been minimized.

Copy link

@alixyz alixyz commented Jul 21, 2020

Thanks @jwalanta, love the script you wrote and shared. In the spirit of sharing, I'm sharing my tweaks for anyone which may be interested.

I made the following changes to the second script:

  • Changed MAC address to upper case and kept : as the separator
  • Pointed the known_mac_addr to the /etc/config/dhcp file which contains all the static leases.
  • Reporting on whether the device connected to my LAN or Guest network.
  • Included gmail smtp connection syntax with subject line. (I'm using it to email me updates vs text"
#!/bin/sh
                                                                                                                                                 
# script to detect new dhcp lease
                                                                                                                                                 
# this will be called by dnsmasq everytime a new device is connected
# with the following arguments
# $1 = add | old
# $2 = mac address
# $3 = ip address
# $4 = device name
                                                                                                                                                 
known_mac_addr="/etc/config/dhcp"
notification_email="1234567890@gmail.com" 
lan="192.168.1."                                                                                                                                 
guest="192.168.2."       
                                                                                                                                                 
#Convert MAC to uppercase                   
mac=$(echo "$2" | awk '{print toupper($0)}')                                                                                                     
                                                                                                                                                 
# check if the mac is in known devices list
grep -q "$mac" "$known_mac_addr"                                                                                                                 
unknown_mac_addr=$?                                        
                                                                                                                                                 
if [ "$1" == "add" ] && [ "$unknown_mac_addr" -ne 0 ]; then                                                  
  msg="New device on `uci get system.@system[0].hostname`.`uci get dhcp.@dnsmasq[0].domain` $1 $mac $3 $4"                                                                                                                                          
                                                                                                                                                 
  if test "${3#*$lan}" != "$3"; then                                                                                                             
    echo `date` "LAN" $msg >> /tmp/dhcpmasq.log                                                                                                  
    echo $msg | mailsend -smtp smtp.gmail.com -port 465 -t $notification_email -f root@openwrt -ssl -auth -sub "OpenWRT New LAN Device Connected" -user USER@gmail.com -pass "PASSWORD"
  fi                                                                                                                                             
                                                                                                                                                 
  if test "${3#*$guest}" != "$3"; then                                                                                                           
    echo `date` "Guest" $msg >> /tmp/dhcpmasq.log                                                                                                
    echo $msg | mailsend -smtp smtp.gmail.com -port 465 -t $notification_email -f root@openwrt -ssl -auth -sub "OpenWRT New LAN Device Connected" -user USER@gmail.com -pass "PASSWORD"
  fi                                                                                                                                             
fi  
@yesgeek1

This comment has been minimized.

Copy link

@yesgeek1 yesgeek1 commented Aug 12, 2020

@lededude I'm a bit of a newbie so bare with me. I am using OpenWrt Luci and I want to send an SMS every time a device that is not on my list is connected. Luci has plugins that can easily be installed so I'm wondering if there is one that can make it easier to install. I think the plugins just install a script without me having to ssh into the router.

Is there a plugin for OpenWrt that I can use to simplify the process?

Where do I type the commands into the LUCI GUI?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.