How to send a WOL message to run a script


In this page I describe how to send a "Wake-On-Lan" message through the network in order to run a script on a router (Asus RT-AC56U) - we use some Entware packages, so please refer to this page on how to install Entware on a router.
Let's start with assumption that using a Wake-On-Lan message is certainly not recommended because anyone can send this message, just know the recipient's IP address, the MAC address of the network device to be turned on and the destination port. And to make matters worse, the Wake-On-Lan protocol does not provide a password. So we will use this procedure only to send non-significant messages, for example to run a script that allows you to enable a secondary functionality.
To send the Wake-On-Lan message we can use any program that supports Wake-On-Lan (refer to this page to use my application for Android operating system), instead to receive the above Wake-On-Lan message on the router we will use an Entware package called "socat".


How to install "socat" package on router

In order to install the "socat" daemon with the Entware packages, we need to execute the following command :
opkg install socat coreutils-od
The "socat" package contains only the "/opt/bin/socat" daemon, which we will analyze later. While the "coreutils-od" package contains "/opt/bin/od" command used by the script we will analyze later.


How to setup the program to send the Wake-On-Lan message

The program that sends the Wake-On-Lan message must be set using the following parameters:

  • MAC address : we will use this parameter not to "wake up" a network device, but we will use it as a unique code to perform a specific action within the script on the router. However, I recommend using a well-designed MAC address, even for security reasons.
  • IP address : here we will put the router's IP address (eventually using a DDNS address if we need to access the router outside the Local Area Network);
  • Port : here we will put the port number that we will use in the router as a parameter of the "socat" daemon. I recommend to avoid using the standard ports used by the Internet services, even more I discourage to use ports 7 and 9 used by the Wake-On-Lan protocol.

How to setup a script used by the "socat" daemon

As we will see later, the "socat" daemon will pass the received Wake-On-Lan message to a script and this script will be able to read the Wake-On-Lan message and perform certain actions. Here below we see an example of a script, we name it "wol_script.sh" (remember to properly set the execution permissions of the above script using the command "chmod + x wol_script.sh" otherwise the "socat" daemon will not be able to execute it):

#!/bin/bash

read MESSAGE
echo "PID: $$"
echo "$MESSAGE"

hexvar=$(echo $MESSAGE | /opt/bin/od -t x1)
echo $hexvar

# execute action 1
if echo $hexvar | grep -q -i "ff ff ff ff ff ff 11 22 33 44 55 66"; then
    # WOL message is received, we run a command
    echo "1 String contains hex is true."
else
    echo "1 String contains hex is not true."
fi

# execute action 2
if echo $hexvar | grep -q -i "ff ff ff ff ff ff 11 77 88 99 AA BB"; then
    # WOL message is received, we run a command
    echo "2 String contains hex is true."
else
    echo "2 String contains hex is not true."
fi

As is clear from the above-mentioned script, we perform the following operations:

  • with the command "read MESSAGE" we read the message passed from daemon "socat" on standard input and e we insert the above-mentioned message in the variable "$MESSAGE";
  • using the command "/opt/bin/od", the variable "$MESSAGE" is converted into hexadecimal format and the content is inserted in the variable "$hexvar";
  • so we check through an "if" statement if the above variable "$hexvar" starts with the string "ff ff ff ff ff ff 11 22 33 44 55 66". This string is nothing more than the initial string "ff ff ff ff ff ff" of each Wake-On-Lan message, besides the dummy MAC address "11 22 33 44 55 66" that we will have to insert in the program that sends the Wake-On-Lan message; if the condition is successful, then we can execute any command, for example execute another script, execute an instruction, etc ...

The "echo" instructions included in the script are only used for debugging issues, they can be deleted once the procedure is understood.
Obviously we can insert more "if" instructions with different MAC addresses, be careful to use a space character between a hexadecimal number and the next one. Practically, in the program that must send the Wake-On-Lan message, we can add more Wake-On-Lan entries, but the only thing that will change will be the value of the dummy MAC address; the values of the IP address of the router and the port will always remain the same.


How to run the "socat" daemon to receive the Wake-On-Lan message

Once we have set the program that should send the Wake-On-Lan message and once we have set the script that will receive the Wake-On-Lan message, we can run the "socat" daemon. A typical instruction we can perform is as follows:
/opt/bin/socat -u -T1 UDP-LISTEN:25000,fork system:/opt/etc/wol_script.sh
In the above-mentioned instruction we have the following parameters (for more information on the "socat" daemon refer to this page on Internet):

  • with the parameter "-u" we set the "socat" daemon in unidirectional mode, so we will have a first reading part, and a second writing part;
  • with the parameter "-T1" we set the inactivity timeout, ie when the "socat" is transferring data and nothing happens for N seconds (in this case 1 second), then it ends;
  • with the parameter "UDP-LISTEN:25000" we put the "socat" in the condition of "listen" to the UDP port 25000. This is the same port that we will have to use in the program that sends the message Wake-On-Lan;
  • with the parameter "fork" we set the "socat" to create a new "child" process every time it receives a connection and at the same time the "father" process of the "socat" continues to accept other connections;
  • with the parameter "system:/opt/etc/wol_script.sh" we set the "socat" to create a subprocess, using the above-mentioned "fork" parameter, which runs the script "/opt/etc/wol_script.sh". The "socat", after starting the script, writes the data on the standard input of the child process (this data will be read from the script, as highlighted in the previous paragraph) and reads the data from the standard output.

The above-mentioned instruction, if executed in the router's terminal, will be executed in debug mode as "root" user. For security reasons, I recommend running the "socat" daemon using the "nobody" user (obviously the script will run as "nobody" user, as well as all the commands executed within the script). To do this, you need to use the "daemonize" command, which can be installed via an Entware package with the "opkg install daemonize" instruction.
Therefore the "socat" daemon can be executed with the following instruction:
daemonize -u nobody /opt/bin/socat -u -T1 UDP-LISTEN:25000,fork system:/opt/etc/wol_script.sh